gdk-pixbuf.c 42.7 KB
Newer Older
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2
/* GdkPixbuf library - Basic memory management
Arturo Espinosa's avatar
Arturo Espinosa committed
3
 *
4
5
6
7
8
9
10
 * Copyright (C) 1999 The Free Software Foundation
 *
 * Authors: Mark Crichton <crichton@gimp.org>
 *          Miguel de Icaza <miguel@gnu.org>
 *          Federico Mena-Quintero <federico@gimp.org>
 *
 * This library is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU Lesser General Public
12
13
14
15
16
17
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 * Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public
21
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
Arturo Espinosa's avatar
Arturo Espinosa committed
22
 */
23

24
#include "config.h"
Matthias Clasen's avatar
Matthias Clasen committed
25

Mark Crichton's avatar
Mark Crichton committed
26
#include <math.h>
27
#include <stdlib.h>
28
#include <string.h>
Matthias Clasen's avatar
Matthias Clasen committed
29

30
#define GDK_PIXBUF_C_COMPILATION
31
#include "gdk-pixbuf-private.h"
Matthias Clasen's avatar
Matthias Clasen committed
32
33
34
#include "gdk-pixbuf-features.h"
#include "gdk-pixbuf-enum-types.h"

35
36
/* Include the marshallers */
#include <glib-object.h>
37
#include <gio/gio.h>
38
#include "gdk-pixbuf-marshal.h"
Arturo Espinosa's avatar
Arturo Espinosa committed
39

40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/**
 * SECTION:creating
 * @Short_description: Creating a pixbuf from image data that is already in memory.
 * @Title: Image Data in Memory
 * @See_also: gdk_pixbuf_finalize().
 * 
 * The most basic way to create a pixbuf is to wrap an existing pixel
 * buffer with a #GdkPixbuf structure.  You can use the
 * gdk_pixbuf_new_from_data() function to do this You need to specify
 * the destroy notification function that will be called when the
 * data buffer needs to be freed; this will happen when a #GdkPixbuf
 * is finalized by the reference counting functions If you have a
 * chunk of static data compiled into your application, you can pass
 * in %NULL as the destroy notification function so that the data
 * will not be freed.
 * 
 * The gdk_pixbuf_new() function can be used as a convenience to
 * create a pixbuf with an empty buffer.  This is equivalent to
58
59
60
61
 * allocating a data buffer using malloc() and then wrapping it with
 * gdk_pixbuf_new_from_data(). The gdk_pixbuf_new() function will
 * compute an optimal rowstride so that rendering can be performed
 * with an efficient algorithm.
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
 * 
 * As a special case, you can use the gdk_pixbuf_new_from_xpm_data()
 * function to create a pixbuf from inline XPM image data.
 * 
 * You can also copy an existing pixbuf with the gdk_pixbuf_copy()
 * function.  This is not the same as just doing a g_object_ref()
 * on the old pixbuf; the copy function will actually duplicate the
 * pixel data in memory and create a new #GdkPixbuf structure for it.
 */

/**
 * SECTION:refcounting
 * @Short_description: Functions for reference counting and memory management on pixbufs.
 * @Title: Reference Counting and Memory Mangement
 * @See_also: #GdkPixbuf, gdk_pixbuf_new_from_data().
 * 
 * #GdkPixbuf structures are reference counted.  This means that an
 * application can share a single pixbuf among many parts of the
 * code.  When a piece of the program needs to keep a pointer to a
 * pixbuf, it should add a reference to it by calling g_object_ref().
 * When it no longer needs the pixbuf, it should subtract a reference
 * by calling g_object_unref().  The pixbuf will be destroyed when
 * its reference count drops to zero.  Newly-created #GdkPixbuf
 * structures start with a reference count of one.
 * 
87
88
89
 * > As #GdkPixbuf is derived from #GObject now, gdk_pixbuf_ref() and
 * > gdk_pixbuf_unref() are deprecated in favour of g_object_ref()
 * > and g_object_unref() resp.
90
 * 
91
92
93
94
95
96
97
98
99
 * Finalizing a pixbuf means to free its pixel data and to free the
 * #GdkPixbuf structure itself.  Most of the library functions that
 * create #GdkPixbuf structures create the pixel data by themselves
 * and define the way it should be freed; you do not need to worry
 * about those.
 *
 * To provide preallocated pixel data, use
 * gdk_pixbuf_new_from_bytes().  The gdk_pixbuf_new_from_data() API is
 * an older variant that predates the existence of #GBytes.
100
101
 */

102
103
104
105
106
107
108
109
110
static void gdk_pixbuf_finalize     (GObject        *object);
static void gdk_pixbuf_set_property (GObject        *object,
				     guint           prop_id,
				     const GValue   *value,
				     GParamSpec     *pspec);
static void gdk_pixbuf_get_property (GObject        *object,
				     guint           prop_id,
				     GValue         *value,
				     GParamSpec     *pspec);
111

112

113
114
115
116
117
118
119
120
121
122
enum 
{
  PROP_0,
  PROP_COLORSPACE,
  PROP_N_CHANNELS,
  PROP_HAS_ALPHA,
  PROP_BITS_PER_SAMPLE,
  PROP_WIDTH,
  PROP_HEIGHT,
  PROP_ROWSTRIDE,
123
124
  PROP_PIXELS,
  PROP_PIXEL_BYTES
125
};
Arturo Espinosa's avatar
Arturo Espinosa committed
126

127
static void gdk_pixbuf_icon_iface_init (GIconIface *iface);
Ryan Lortie's avatar
Ryan Lortie committed
128
static void gdk_pixbuf_loadable_icon_iface_init (GLoadableIconIface *iface);
129
130

G_DEFINE_TYPE_WITH_CODE (GdkPixbuf, gdk_pixbuf, G_TYPE_OBJECT,
Ryan Lortie's avatar
Ryan Lortie committed
131
132
                         G_IMPLEMENT_INTERFACE (G_TYPE_ICON, gdk_pixbuf_icon_iface_init)
                         G_IMPLEMENT_INTERFACE (G_TYPE_LOADABLE_ICON, gdk_pixbuf_loadable_icon_iface_init))
133

Matthias Clasen's avatar
Matthias Clasen committed
134
135
static void 
gdk_pixbuf_init (GdkPixbuf *pixbuf)
136
{
137
138
139
140
  pixbuf->colorspace = GDK_COLORSPACE_RGB;
  pixbuf->n_channels = 3;
  pixbuf->bits_per_sample = 8;
  pixbuf->has_alpha = FALSE;
141
142
143
144
145
146
}

static void
gdk_pixbuf_class_init (GdkPixbufClass *klass)
{
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
147

148
        _gdk_pixbuf_init_gettext ();
149

150
        object_class->finalize = gdk_pixbuf_finalize;
151
152
        object_class->set_property = gdk_pixbuf_set_property;
        object_class->get_property = gdk_pixbuf_get_property;
153
154

#define PIXBUF_PARAM_FLAGS G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY|\
155
                           G_PARAM_EXPLICIT_NOTIFY|\
156
                           G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB
157
158
159
160
161
162
        /**
         * GdkPixbuf:n-channels:
         *
         * The number of samples per pixel. 
         * Currently, only 3 or 4 samples per pixel are supported.
         */
163
164
        g_object_class_install_property (object_class,
                                         PROP_N_CHANNELS,
165
                                         g_param_spec_int ("n-channels",
Bastien Nocera's avatar
Bastien Nocera committed
166
167
                                                           _("Number of Channels"),
                                                           _("The number of samples per pixel"),
168
169
170
                                                           0,
                                                           G_MAXINT,
                                                           3,
171
                                                           PIXBUF_PARAM_FLAGS));
172
173
174
175

        g_object_class_install_property (object_class,
                                         PROP_COLORSPACE,
                                         g_param_spec_enum ("colorspace",
Bastien Nocera's avatar
Bastien Nocera committed
176
177
                                                            _("Colorspace"),
                                                            _("The colorspace in which the samples are interpreted"),
178
179
                                                            GDK_TYPE_COLORSPACE,
                                                            GDK_COLORSPACE_RGB,
180
                                                            PIXBUF_PARAM_FLAGS));
181
182
183

        g_object_class_install_property (object_class,
                                         PROP_HAS_ALPHA,
184
                                         g_param_spec_boolean ("has-alpha",
Bastien Nocera's avatar
Bastien Nocera committed
185
186
                                                               _("Has Alpha"),
                                                               _("Whether the pixbuf has an alpha channel"),
187
                                                               FALSE,
188
                                                               PIXBUF_PARAM_FLAGS));
189

190
191
192
193
194
195
        /**
         * GdkPixbuf:bits-per-sample:
         *
         * The number of bits per sample. 
         * Currently only 8 bit per sample are supported.
         */
196
197
        g_object_class_install_property (object_class,
                                         PROP_BITS_PER_SAMPLE,
198
                                         g_param_spec_int ("bits-per-sample",
Bastien Nocera's avatar
Bastien Nocera committed
199
200
                                                           _("Bits per Sample"),
                                                           _("The number of bits per sample"),
201
202
203
                                                           1,
                                                           16,
                                                           8,
204
                                                           PIXBUF_PARAM_FLAGS));
205
206
207
208

        g_object_class_install_property (object_class,
                                         PROP_WIDTH,
                                         g_param_spec_int ("width",
Bastien Nocera's avatar
Bastien Nocera committed
209
210
                                                           _("Width"),
                                                           _("The number of columns of the pixbuf"),
211
212
213
                                                           1,
                                                           G_MAXINT,
                                                           1,
214
                                                           PIXBUF_PARAM_FLAGS));
215
216
217
218

        g_object_class_install_property (object_class,
                                         PROP_HEIGHT,
                                         g_param_spec_int ("height",
Bastien Nocera's avatar
Bastien Nocera committed
219
220
                                                           _("Height"),
                                                           _("The number of rows of the pixbuf"),
221
222
223
                                                           1,
                                                           G_MAXINT,
                                                           1,
224
                                                           PIXBUF_PARAM_FLAGS));
225

226
227
228
229
230
231
232
        /**
         * GdkPixbuf:rowstride:
         *
         * The number of bytes between the start of a row and 
         * the start of the next row. This number must (obviously)
         * be at least as large as the width of the pixbuf.
         */
233
234
235
        g_object_class_install_property (object_class,
                                         PROP_ROWSTRIDE,
                                         g_param_spec_int ("rowstride",
Bastien Nocera's avatar
Bastien Nocera committed
236
237
                                                           _("Rowstride"),
                                                           _("The number of bytes between the start of a row and the start of the next row"),
238
239
240
                                                           1,
                                                           G_MAXINT,
                                                           1,
241
                                                           PIXBUF_PARAM_FLAGS));
242
243
244
245

        g_object_class_install_property (object_class,
                                         PROP_PIXELS,
                                         g_param_spec_pointer ("pixels",
Bastien Nocera's avatar
Bastien Nocera committed
246
247
                                                               _("Pixels"),
                                                               _("A pointer to the pixel data of the pixbuf"),
248
                                                               PIXBUF_PARAM_FLAGS));
249
250
251
252
253
254
255
256
257
258
259
260

        /**
         * GdkPixbuf::pixel-bytes:
         *
         * If set, this pixbuf was created from read-only #GBytes.
         * Replaces GdkPixbuf::pixels.
         * 
         * Since: 2.32
         */
        g_object_class_install_property (object_class,
                                         PROP_PIXEL_BYTES,
                                         g_param_spec_boxed ("pixel-bytes",
Bastien Nocera's avatar
Bastien Nocera committed
261
262
                                                             _("Pixel Bytes"),
                                                             _("Readonly pixel data"),
263
264
                                                             G_TYPE_BYTES,
                                                             PIXBUF_PARAM_FLAGS));
265
266
}

267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
static void
free_pixels (GdkPixbuf *pixbuf)
{
        g_assert (pixbuf->storage == STORAGE_PIXELS);

        if (pixbuf->s.pixels.pixels && pixbuf->s.pixels.destroy_fn) {
                (* pixbuf->s.pixels.destroy_fn) (pixbuf->s.pixels.pixels, pixbuf->s.pixels.destroy_fn_data);
        }

        pixbuf->s.pixels.pixels = NULL;
}

static void
free_bytes (GdkPixbuf *pixbuf)
{
        g_assert (pixbuf->storage == STORAGE_BYTES);

        g_clear_pointer (&pixbuf->s.bytes.bytes, g_bytes_unref);
}

287
288
289
290
static void
gdk_pixbuf_finalize (GObject *object)
{
        GdkPixbuf *pixbuf = GDK_PIXBUF (object);
291

292
293
294
295
296
297
298
299
300
301
        switch (pixbuf->storage) {
        case STORAGE_PIXELS:
                free_pixels (pixbuf);
                break;

        case STORAGE_BYTES:
                free_bytes (pixbuf);
                break;

        default:
Federico Mena Quintero's avatar
Federico Mena Quintero committed
302
                g_assert_not_reached ();
303
        }
304
        
Matthias Clasen's avatar
Matthias Clasen committed
305
        G_OBJECT_CLASS (gdk_pixbuf_parent_class)->finalize (object);
306
}
307

Matthias Clasen's avatar
Matthias Clasen committed
308
309

/**
Johan Dahlin's avatar
Johan Dahlin committed
310
 * gdk_pixbuf_ref: (skip)
Matthias Clasen's avatar
Matthias Clasen committed
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
 * @pixbuf: A pixbuf.
 *
 * Adds a reference to a pixbuf.
 *
 * Return value: The same as the @pixbuf argument.
 *
 * Deprecated: 2.0: Use g_object_ref().
 **/
GdkPixbuf *
gdk_pixbuf_ref (GdkPixbuf *pixbuf)
{
        return (GdkPixbuf *) g_object_ref (pixbuf);
}

/**
Johan Dahlin's avatar
Johan Dahlin committed
326
 * gdk_pixbuf_unref: (skip)
Matthias Clasen's avatar
Matthias Clasen committed
327
328
329
330
331
332
333
334
335
336
337
338
 * @pixbuf: A pixbuf.
 *
 * Removes a reference from a pixbuf.
 *
 * Deprecated: 2.0: Use g_object_unref().
 **/
void
gdk_pixbuf_unref (GdkPixbuf *pixbuf)
{
        g_object_unref (pixbuf);
}

Ryan Lortie's avatar
Ryan Lortie committed
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
static GBytes *
gdk_pixbuf_make_bytes (GdkPixbuf  *pixbuf,
                       GError    **error)
{
  gchar *buffer;
  gsize size;

  if (!gdk_pixbuf_save_to_buffer (pixbuf, &buffer, &size, "png", error, NULL))
    return NULL;

  return g_bytes_new_take (buffer, size);
}

static GVariant *
gdk_pixbuf_serialize (GIcon *icon)
{
  GError *error = NULL;
  GVariant *result;
  GBytes *bytes;

  bytes = gdk_pixbuf_make_bytes (GDK_PIXBUF (icon), &error);
  if (!bytes)
    {
      g_critical ("Unable to serialise GdkPixbuf to png (via g_icon_serialize()): %s", error->message);
      g_error_free (error);
      return NULL;
    }
  result = g_variant_new_from_bytes (G_VARIANT_TYPE_BYTESTRING, bytes, TRUE);
  g_bytes_unref (bytes);

  return g_variant_new ("(sv)", "bytes", result);
}

static GInputStream *
gdk_pixbuf_load (GLoadableIcon  *icon,
                 int             size,
                 char          **type,
                 GCancellable   *cancellable,
                 GError        **error)
{
  GInputStream *stream;
  GBytes *bytes;

  bytes = gdk_pixbuf_make_bytes (GDK_PIXBUF (icon), error);
  if (!bytes)
    return NULL;

  stream = g_memory_input_stream_new_from_bytes (bytes);
  g_bytes_unref (bytes);

  if (type)
    *type = g_strdup ("image/png");

  return stream;
}

static void
gdk_pixbuf_load_async (GLoadableIcon       *icon,
                       int                  size,
                       GCancellable        *cancellable,
                       GAsyncReadyCallback  callback,
                       gpointer             user_data)
{
  GTask *task;

  task = g_task_new (icon, cancellable, callback, user_data);
  g_task_return_pointer (task, icon, NULL);
  g_object_unref (task);
}

static GInputStream *
gdk_pixbuf_load_finish (GLoadableIcon  *icon,
                        GAsyncResult   *res,
                        char          **type,
                        GError        **error)
{
  g_return_val_if_fail (g_task_is_valid (res, icon), NULL);

  if (!g_task_propagate_pointer (G_TASK (res), error))
    return NULL;

  return gdk_pixbuf_load (icon, 0, type, NULL, error);
}

static void
gdk_pixbuf_loadable_icon_iface_init (GLoadableIconIface *iface)
{
  iface->load = gdk_pixbuf_load;

  /* In theory encoding a png could be time-consuming but we're talking
   * about icons here, so assume it's probably going to be OK and handle
   * the async variant of the call in-thread instead of having the
   * default implementation dispatch it to a worker.
   */
  iface->load_async = gdk_pixbuf_load_async;
  iface->load_finish = gdk_pixbuf_load_finish;
}

437
438
439
static void
gdk_pixbuf_icon_iface_init (GIconIface *iface)
{
440
441
        iface->hash = (guint (*) (GIcon *)) g_direct_hash;
        iface->equal = (gboolean (*) (GIcon *, GIcon *)) g_direct_equal;
Ryan Lortie's avatar
Ryan Lortie committed
442
        iface->serialize = gdk_pixbuf_serialize;
443
}
Matthias Clasen's avatar
Matthias Clasen committed
444

445
/* Used as the destroy notification function for gdk_pixbuf_new() */
446
static void
447
free_buffer (guchar *pixels, gpointer data)
448
{
449
	g_free (pixels);
450
451
}

452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
/**
 * gdk_pixbuf_calculate_rowstride:
 * @colorspace: Color space for image
 * @has_alpha: Whether the image should have transparency information
 * @bits_per_sample: Number of bits per color sample
 * @width: Width of image in pixels, must be > 0
 * @height: Height of image in pixels, must be > 0
 *
 * Calculates the rowstride that an image created with those values would
 * have. This is useful for front-ends and backends that want to sanity
 * check image values without needing to create them.
 *
 * Return value: the rowstride for the given values, or -1 in case of error.
 *
 * Since: 2.36.8
 */
gint
gdk_pixbuf_calculate_rowstride (GdkColorspace colorspace,
				gboolean      has_alpha,
				int           bits_per_sample,
				int           width,
				int           height)
{
	unsigned int channels;

	g_return_val_if_fail (colorspace == GDK_COLORSPACE_RGB, -1);
	g_return_val_if_fail (bits_per_sample == 8, -1);
	g_return_val_if_fail (width > 0, -1);
	g_return_val_if_fail (height > 0, -1);

	channels = has_alpha ? 4 : 3;

	/* Overflow? */
	if (width > (G_MAXINT - 3) / channels)
		return -1;

	/* Always align rows to 32-bit boundaries */
	return (width * channels + 3) & ~3;
}

492
493
/**
 * gdk_pixbuf_new:
494
495
496
497
498
 * @colorspace: Color space for image
 * @has_alpha: Whether the image should have transparency information
 * @bits_per_sample: Number of bits per color sample
 * @width: Width of image in pixels, must be > 0
 * @height: Height of image in pixels, must be > 0
Federico Mena Quintero's avatar
Federico Mena Quintero committed
499
 *
500
501
502
 * Creates a new #GdkPixbuf structure and allocates a buffer for it.  The 
 * buffer has an optimal rowstride.  Note that the buffer is not cleared;
 * you will have to fill it completely yourself.
Federico Mena Quintero's avatar
Federico Mena Quintero committed
503
 *
504
 * Return value: (nullable): A newly-created #GdkPixbuf with a reference count of 1, or
Matthias Clasen's avatar
Matthias Clasen committed
505
 * %NULL if not enough memory could be allocated for the image buffer.
506
507
 **/
GdkPixbuf *
508
509
510
511
512
gdk_pixbuf_new (GdkColorspace colorspace, 
                gboolean      has_alpha,
                int           bits_per_sample,
                int           width,
                int           height)
513
{
514
	guchar *buf;
515
	int rowstride;
516

517
518
519
520
521
522
	rowstride = gdk_pixbuf_calculate_rowstride (colorspace,
						    has_alpha,
						    bits_per_sample,
						    width,
						    height);
	if (rowstride <= 0)
523
524
		return NULL;

525
	buf = g_try_malloc_n (height, rowstride);
526
527
	if (!buf)
		return NULL;
528

529
530
	return gdk_pixbuf_new_from_data (buf, colorspace, has_alpha, bits_per_sample,
					 width, height, rowstride,
531
532
					 free_buffer, NULL);
}
533

534
535
536
537
538
/**
 * gdk_pixbuf_copy:
 * @pixbuf: A pixbuf.
 * 
 * Creates a new #GdkPixbuf with a copy of the information in the specified
539
540
 * @pixbuf. Note that this does not copy the options set on the original #GdkPixbuf,
 * use gdk_pixbuf_copy_options() for this.
541
 * 
542
 * Return value: (nullable) (transfer full): A newly-created pixbuf with a reference count of 1, or %NULL if
543
544
545
546
547
548
549
550
 * not enough memory could be allocated.
 **/
GdkPixbuf *
gdk_pixbuf_copy (const GdkPixbuf *pixbuf)
{
	guchar *buf;
	int size;

551
	g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
552
553
554
555
556
557

	/* Calculate a semi-exact size.  Here we copy with full rowstrides;
	 * maybe we should copy each row individually with the minimum
	 * rowstride?
	 */

558
	size = gdk_pixbuf_get_byte_length (pixbuf);
559

560
	buf = g_try_malloc (size);
561
562
563
	if (!buf)
		return NULL;

564
	memcpy (buf, gdk_pixbuf_read_pixels (pixbuf), size);
565
566
567
568
569
570
571
572
573
574

	return gdk_pixbuf_new_from_data (buf,
					 pixbuf->colorspace, pixbuf->has_alpha,
					 pixbuf->bits_per_sample,
					 pixbuf->width, pixbuf->height,
					 pixbuf->rowstride,
					 free_buffer,
					 NULL);
}

575
576
577
578
579
580
581
582
/**
 * gdk_pixbuf_new_subpixbuf:
 * @src_pixbuf: a #GdkPixbuf
 * @src_x: X coord in @src_pixbuf
 * @src_y: Y coord in @src_pixbuf
 * @width: width of region in @src_pixbuf
 * @height: height of region in @src_pixbuf
 * 
583
584
585
586
587
588
589
590
591
 * Creates a new pixbuf which represents a sub-region of @src_pixbuf.
 * The new pixbuf shares its pixels with the original pixbuf, so
 * writing to one affects both.  The new pixbuf holds a reference to
 * @src_pixbuf, so @src_pixbuf will not be finalized until the new
 * pixbuf is finalized.
 *
 * Note that if @src_pixbuf is read-only, this function will force it
 * to be mutable.
 *
Johan Dahlin's avatar
Johan Dahlin committed
592
 * Return value: (transfer full): a new pixbuf 
593
594
595
596
597
598
599
600
601
602
603
604
605
606
 **/
GdkPixbuf*
gdk_pixbuf_new_subpixbuf (GdkPixbuf *src_pixbuf,
                          int        src_x,
                          int        src_y,
                          int        width,
                          int        height)
{
        guchar *pixels;
        GdkPixbuf *sub;

        g_return_val_if_fail (GDK_IS_PIXBUF (src_pixbuf), NULL);
        g_return_val_if_fail (src_x >= 0 && src_x + width <= src_pixbuf->width, NULL);
        g_return_val_if_fail (src_y >= 0 && src_y + height <= src_pixbuf->height, NULL);
607
608
        
        /* Note causes an implicit copy where src_pixbuf owns the data */
609
610
611
612
613
614
615
616
617
618
619
620
621
        pixels = (gdk_pixbuf_get_pixels (src_pixbuf)
                  + src_y * src_pixbuf->rowstride
                  + src_x * src_pixbuf->n_channels);

        sub = gdk_pixbuf_new_from_data (pixels,
                                        src_pixbuf->colorspace,
                                        src_pixbuf->has_alpha,
                                        src_pixbuf->bits_per_sample,
                                        width, height,
                                        src_pixbuf->rowstride,
                                        NULL, NULL);

        /* Keep a reference to src_pixbuf */
622
        g_object_ref (src_pixbuf);
623
624
625
626
627
628
629
630
631
  
        g_object_set_qdata_full (G_OBJECT (sub),
                                 g_quark_from_static_string ("gdk-pixbuf-subpixbuf-src"),
                                 src_pixbuf,
                                 (GDestroyNotify) g_object_unref);

        return sub;
}

Federico Mena Quintero's avatar
Federico Mena Quintero committed
632

633

634
/* Accessors */
Federico Mena Quintero's avatar
Federico Mena Quintero committed
635
636

/**
637
 * gdk_pixbuf_get_colorspace:
Federico Mena Quintero's avatar
Federico Mena Quintero committed
638
639
 * @pixbuf: A pixbuf.
 *
640
 * Queries the color space of a pixbuf.
Federico Mena Quintero's avatar
Federico Mena Quintero committed
641
 *
642
 * Return value: Color space.
Federico Mena Quintero's avatar
Federico Mena Quintero committed
643
 **/
644
645
GdkColorspace
gdk_pixbuf_get_colorspace (const GdkPixbuf *pixbuf)
646
{
647
	g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), GDK_COLORSPACE_RGB);
648

649
	return pixbuf->colorspace;
650
651
}

Federico Mena Quintero's avatar
Federico Mena Quintero committed
652
653
654
655
656
657
658
659
/**
 * gdk_pixbuf_get_n_channels:
 * @pixbuf: A pixbuf.
 *
 * Queries the number of channels of a pixbuf.
 *
 * Return value: Number of channels.
 **/
660
int
661
gdk_pixbuf_get_n_channels (const GdkPixbuf *pixbuf)
662
{
663
	g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), -1);
664

665
	return pixbuf->n_channels;
666
667
}

Federico Mena Quintero's avatar
Federico Mena Quintero committed
668
669
670
671
672
673
/**
 * gdk_pixbuf_get_has_alpha:
 * @pixbuf: A pixbuf.
 *
 * Queries whether a pixbuf has an alpha channel (opacity information).
 *
Matthias Clasen's avatar
Matthias Clasen committed
674
 * Return value: %TRUE if it has an alpha channel, %FALSE otherwise.
Federico Mena Quintero's avatar
Federico Mena Quintero committed
675
 **/
676
gboolean
677
gdk_pixbuf_get_has_alpha (const GdkPixbuf *pixbuf)
678
{
679
	g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), FALSE);
680

681
	return pixbuf->has_alpha ? TRUE : FALSE;
682
683
}

Federico Mena Quintero's avatar
Federico Mena Quintero committed
684
685
686
687
688
689
690
691
/**
 * gdk_pixbuf_get_bits_per_sample:
 * @pixbuf: A pixbuf.
 *
 * Queries the number of bits per color sample in a pixbuf.
 *
 * Return value: Number of bits per color sample.
 **/
692
int
693
gdk_pixbuf_get_bits_per_sample (const GdkPixbuf *pixbuf)
694
{
695
	g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), -1);
696

697
	return pixbuf->bits_per_sample;
698
699
}

Federico Mena Quintero's avatar
Federico Mena Quintero committed
700
701
702
703
704
705
/**
 * gdk_pixbuf_get_pixels:
 * @pixbuf: A pixbuf.
 *
 * Queries a pointer to the pixel data of a pixbuf.
 *
Matthias Clasen's avatar
Matthias Clasen committed
706
 * Return value: (array): A pointer to the pixbuf's pixel data.
707
 * Please see the section on [image data][image-data] for information
708
 * about how the pixel data is stored in memory.
709
710
711
 *
 * This function will cause an implicit copy of the pixbuf data if the
 * pixbuf was created from read-only data.
Federico Mena Quintero's avatar
Federico Mena Quintero committed
712
 **/
713
guchar *
714
gdk_pixbuf_get_pixels (const GdkPixbuf *pixbuf)
715
{
716
        return gdk_pixbuf_get_pixels_with_length (pixbuf, NULL);
717
718
}

719
720
721
722
723
724
725
726
static void
downgrade_to_pixels (const GdkPixbuf *pixbuf)
{
        switch (pixbuf->storage) {
        case STORAGE_PIXELS:
                return;

        case STORAGE_BYTES: {
Federico Mena Quintero's avatar
Federico Mena Quintero committed
727
                GdkPixbuf *mut_pixbuf = (GdkPixbuf *) pixbuf;
728
729
730
731
732
733
734
735
736
737
738
739
740
                gsize len;
                Pixels pixels;

                pixels.pixels = g_bytes_unref_to_data (pixbuf->s.bytes.bytes, &len);
                pixels.destroy_fn = free_buffer;
                pixels.destroy_fn_data = NULL;

                mut_pixbuf->storage = STORAGE_PIXELS;
                mut_pixbuf->s.pixels = pixels;
                break;
        }

        default:
Federico Mena Quintero's avatar
Federico Mena Quintero committed
741
                g_assert_not_reached ();
742
743
744
        }
}

745
/**
Bastien Nocera's avatar
Bastien Nocera committed
746
 * gdk_pixbuf_get_pixels_with_length: (rename-to gdk_pixbuf_get_pixels)
747
748
749
750
751
752
 * @pixbuf: A pixbuf.
 * @length: (out): The length of the binary data.
 *
 * Queries a pointer to the pixel data of a pixbuf.
 *
 * Return value: (array length=length): A pointer to the pixbuf's
753
 * pixel data.  Please see the section on [image data][image-data]
754
 * for information about how the pixel data is stored in memory.
755
 *
756
757
758
 * This function will cause an implicit copy of the pixbuf data if the
 * pixbuf was created from read-only data.
 *
Matthias Clasen's avatar
Matthias Clasen committed
759
760
 * Since: 2.26
 */
761
762
763
764
765
766
guchar *
gdk_pixbuf_get_pixels_with_length (const GdkPixbuf *pixbuf,
                                   guint           *length)
{
	g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);

767
768
        downgrade_to_pixels (pixbuf);
        g_assert (pixbuf->storage == STORAGE_PIXELS);
769

770
771
772
        if (length)
                *length = gdk_pixbuf_get_byte_length (pixbuf);

773
	return pixbuf->s.pixels.pixels;
774
775
}

776
777
778
779
/**
 * gdk_pixbuf_read_pixels:
 * @pixbuf: A pixbuf
 *
780
 * Provides a read-only pointer to the raw pixel data; must not be
781
782
783
784
 * modified.  This function allows skipping the implicit copy that
 * must be made if gdk_pixbuf_get_pixels() is called on a read-only
 * pixbuf.
 *
785
786
 * Returns: a read-only pointer to the raw pixel data
 *
787
788
789
790
791
792
 * Since: 2.32
 */
const guint8*
gdk_pixbuf_read_pixels (const GdkPixbuf  *pixbuf)
{
	g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
793
794
795
796
797
798

        switch (pixbuf->storage) {
        case STORAGE_PIXELS:
                return pixbuf->s.pixels.pixels;

        case STORAGE_BYTES: {
799
800
                gsize len;
                /* Ignore len; callers know the size via other variables */
801
802
803
804
805
806
                return g_bytes_get_data (pixbuf->s.bytes.bytes, &len);
        }

        default:
                g_assert_not_reached ();
                return NULL;
807
808
809
        }
}

810
811
812
813
/**
 * gdk_pixbuf_read_pixel_bytes:
 * @pixbuf: A pixbuf
 *
814
815
816
817
818
 * Provides a #GBytes buffer containing the raw pixel data; the data
 * must not be modified.  This function allows skipping the implicit
 * copy that must be made if gdk_pixbuf_get_pixels() is called on a
 * read-only pixbuf.
 *
819
 * Returns: (transfer full): A new reference to a read-only copy of
820
821
822
 *   the pixel data.  Note that for mutable pixbufs, this function will
 *   incur a one-time copy of the pixel data for conversion into the
 *   returned #GBytes.
823
824
825
826
827
828
829
830
 *
 * Since: 2.32
 */
GBytes *
gdk_pixbuf_read_pixel_bytes (const GdkPixbuf  *pixbuf)
{
        g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);

831
832
833
        switch (pixbuf->storage) {
        case STORAGE_PIXELS:
                return g_bytes_new (pixbuf->s.pixels.pixels,
834
                                    gdk_pixbuf_get_byte_length (pixbuf));
835
836
837
838
839

        case STORAGE_BYTES:
                return g_bytes_ref (pixbuf->s.bytes.bytes);

        default:
Federico Mena Quintero's avatar
Federico Mena Quintero committed
840
                g_assert_not_reached ();
841
842
843
        }
}

Federico Mena Quintero's avatar
Federico Mena Quintero committed
844
845
846
847
848
849
850
851
/**
 * gdk_pixbuf_get_width:
 * @pixbuf: A pixbuf.
 *
 * Queries the width of a pixbuf.
 *
 * Return value: Width in pixels.
 **/
852
int
853
gdk_pixbuf_get_width (const GdkPixbuf *pixbuf)
854
{
855
	g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), -1);
856

857
	return pixbuf->width;
858
859
}

Federico Mena Quintero's avatar
Federico Mena Quintero committed
860
861
862
863
864
865
866
867
/**
 * gdk_pixbuf_get_height:
 * @pixbuf: A pixbuf.
 *
 * Queries the height of a pixbuf.
 *
 * Return value: Height in pixels.
 **/
868
int
869
gdk_pixbuf_get_height (const GdkPixbuf *pixbuf)
870
{
871
	g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), -1);
872

873
	return pixbuf->height;
874
875
}

Federico Mena Quintero's avatar
Federico Mena Quintero committed
876
877
878
879
/**
 * gdk_pixbuf_get_rowstride:
 * @pixbuf: A pixbuf.
 *
880
881
 * Queries the rowstride of a pixbuf, which is the number of bytes between
 * the start of a row and the start of the next row.
Federico Mena Quintero's avatar
Federico Mena Quintero committed
882
 *
883
 * Return value: Distance between row starts.
Federico Mena Quintero's avatar
Federico Mena Quintero committed
884
 **/
885
int
886
gdk_pixbuf_get_rowstride (const GdkPixbuf *pixbuf)
887
{
888
	g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), -1);
889

890
	return pixbuf->rowstride;
891
}
892

893
894
/**
 * gdk_pixbuf_get_byte_length:
Matthias Clasen's avatar
Matthias Clasen committed
895
 * @pixbuf: A pixbuf
896
897
898
899
 *
 * Returns the length of the pixel data, in bytes.
 *
 * Return value: The length of the pixel data.
Matthias Clasen's avatar
Matthias Clasen committed
900
901
 *
 * Since: 2.26
902
 */
Matthias Clasen's avatar
Matthias Clasen committed
903
gsize
904
905
906
907
908
909
910
911
gdk_pixbuf_get_byte_length (const GdkPixbuf *pixbuf)
{
	g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), -1);

        return ((pixbuf->height - 1) * pixbuf->rowstride +
                pixbuf->width * ((pixbuf->n_channels * pixbuf->bits_per_sample + 7) / 8));
}

912

913

914
/* General initialization hooks */
915
916
917
const guint gdk_pixbuf_major_version = GDK_PIXBUF_MAJOR;
const guint gdk_pixbuf_minor_version = GDK_PIXBUF_MINOR;
const guint gdk_pixbuf_micro_version = GDK_PIXBUF_MICRO;
918

919
const char *gdk_pixbuf_version = GDK_PIXBUF_VERSION;
920

921
922
923
924
/* Error quark */
GQuark
gdk_pixbuf_error_quark (void)
{
Matthias Clasen's avatar
Matthias Clasen committed
925
  return g_quark_from_static_string ("gdk-pixbuf-error-quark");
926
}
927

928
929
930
/**
 * gdk_pixbuf_fill:
 * @pixbuf: a #GdkPixbuf
931
932
 * @pixel: RGBA pixel to clear to
 *         (0xffffffff is opaque white, 0x00000000 transparent black)
933
934
935
936
937
938
939
940
941
942
943
944
 *
 * Clears a pixbuf to the given RGBA value, converting the RGBA value into
 * the pixbuf's pixel format. The alpha will be ignored if the pixbuf
 * doesn't have an alpha channel.
 * 
 **/
void
gdk_pixbuf_fill (GdkPixbuf *pixbuf,
                 guint32    pixel)
{
        guchar *pixels;
        guint r, g, b, a;
945
        guchar *p;
946
        guint w, h;
947

948
949
        g_return_if_fail (GDK_IS_PIXBUF (pixbuf));

950
        if (pixbuf->width == 0 || pixbuf->height == 0)
951
                return;
952

953
954
        /* Force an implicit copy */
        pixels = gdk_pixbuf_get_pixels (pixbuf);
955
956
957
958
959
960

        r = (pixel & 0xff000000) >> 24;
        g = (pixel & 0x00ff0000) >> 16;
        b = (pixel & 0x0000ff00) >> 8;
        a = (pixel & 0x000000ff);

961
        h = pixbuf->height;
962
        
963
964
        while (h--) {
                w = pixbuf->width;
965
                p = pixels;
966
967
968
969
970
971
972

                switch (pixbuf->n_channels) {
                case 3:
                        while (w--) {
                                p[0] = r;
                                p[1] = g;
                                p[2] = b;
973
                                p += 3;
974
975
976
977
978
979
980
981
982
983
984
985
986
                        }
                        break;
                case 4:
                        while (w--) {
                                p[0] = r;
                                p[1] = g;
                                p[2] = b;
                                p[3] = a;
                                p += 4;
                        }
                        break;
                default:
                        break;
987
                }
988
989
                
                pixels += pixbuf->rowstride;
990
991
992
        }
}

993
994
995
996
997
998
999
1000


/**
 * gdk_pixbuf_get_option:
 * @pixbuf: a #GdkPixbuf
 * @key: a nul-terminated string.
 * 
 * Looks up @key in the list of options that may have been attached to the
For faster browsing, not all history is shown. View entire blame