1 /* GdkPixbuf library - Image creation from in-memory buffers
3 * Copyright (C) 1999 The Free Software Foundation
5 * Author: Federico Mena-Quintero <federico@gimp.org>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
24 #include "gdk-pixbuf.h"
25 #include "gdk-pixbuf-private.h"
32 * gdk_pixbuf_new_from_data:
33 * @data: Image data in 8-bit/sample packed format.
34 * @colorspace: Colorspace for the image data.
35 * @has_alpha: Whether the data has an opacity channel.
36 * @bits_per_sample: Number of bits per sample.
37 * @width: Width of the image in pixels.
38 * @height: Height of the image in pixels.
39 * @rowstride: Distance in bytes between rows.
40 * @destroy_fn: Function used to free the data when the pixbuf's reference count
41 * drops to zero, or NULL if the data should not be freed.
42 * @destroy_fn_data: Closure data to pass to the destroy notification function.
44 * Creates a new #GdkPixbuf out of in-memory image data. Currently only RGB
45 * images with 8 bits per sample are supported.
47 * Return value: A newly-created #GdkPixbuf structure with a reference count of
51 gdk_pixbuf_new_from_data (const guchar *data, GdkColorspace colorspace, gboolean has_alpha,
52 int bits_per_sample, int width, int height, int rowstride,
53 GdkPixbufDestroyNotify destroy_fn, gpointer destroy_fn_data)
57 /* Only 8-bit/sample RGB buffers are supported for now */
59 g_return_val_if_fail (data != NULL, NULL);
60 g_return_val_if_fail (colorspace == GDK_COLORSPACE_RGB, NULL);
61 g_return_val_if_fail (bits_per_sample == 8, NULL);
62 g_return_val_if_fail (width > 0, NULL);
63 g_return_val_if_fail (height > 0, NULL);
65 pixbuf = g_object_new (GDK_TYPE_PIXBUF, NULL);
67 pixbuf->colorspace = colorspace;
68 pixbuf->n_channels = has_alpha ? 4 : 3;
69 pixbuf->bits_per_sample = bits_per_sample;
70 pixbuf->has_alpha = has_alpha ? TRUE : FALSE;
71 pixbuf->width = width;
72 pixbuf->height = height;
73 pixbuf->rowstride = rowstride;
74 pixbuf->pixels = (guchar *) data;
75 pixbuf->destroy_fn = destroy_fn;
76 pixbuf->destroy_fn_data = destroy_fn_data;
82 read_int (const guchar **p)
86 /* Note most significant bytes are first in the byte stream */
99 read_bool (const guchar **p)
101 gboolean val = **p != 0;
109 read_raw_inline (const guchar *data, gboolean copy_pixels, int length)
112 const guchar *p = data;
113 guint32 rowstride, width, height, colorspace,
114 n_channels, bits_per_sample;
117 if (length >= 0 && length < 12) {
118 /* Not enough buffer to hold the width/height/rowstride */
122 rowstride = read_int (&p);
123 width = read_int (&p);
124 height = read_int (&p);
126 if (rowstride < width)
127 return NULL; /* bad data from untrusted source. */
129 /* rowstride >= width, so we can trust width */
133 /* There's some better way like G_MAXINT/height > rowstride
134 * but I'm not sure it works, so stick to this for now.
136 if (((double)height) * ((double)rowstride) > (double)G_MAXINT)
137 return NULL; /* overflow */
140 length < (height * rowstride + 13)) {
141 /* Not enough buffer to hold the remaining header
142 * information plus the data.
148 /* Read the remaining 13 bytes of header information */
150 has_alpha = read_bool (&p) != FALSE;
151 colorspace = read_int (&p);
152 n_channels = read_int (&p);
153 bits_per_sample = read_int (&p);
155 if (colorspace != GDK_COLORSPACE_RGB)
158 if (bits_per_sample != 8)
161 if (has_alpha && n_channels != 4)
164 if (!has_alpha && n_channels != 3)
172 pixbuf = gdk_pixbuf_new (colorspace,
173 has_alpha, bits_per_sample,
176 pixels = gdk_pixbuf_get_pixels (pixbuf);
177 dest_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
179 for (row = 0; row < height; row++) {
180 memcpy (pixels, p, rowstride);
181 pixels += dest_rowstride;
185 pixbuf = gdk_pixbuf_new_from_data (p,
198 * gdk_pixbuf_new_from_inline:
199 * @data: An inlined GdkPixbuf
200 * @copy_pixels: whether to copy the pixels out of the inline data, or to use them in-place
202 * Create a #GdkPixbuf from a custom format invented to store pixbuf
203 * data in C program code. This library comes with a program called "make-inline-pixbuf"
204 * that can write out a variable definition containing an inlined pixbuf.
205 * This is useful if you want to ship a program with images, but
206 * don't want to depend on any external files.
208 * The inline data format contains the pixels in #GdkPixbuf's native
209 * format. Since the inline pixbuf is read-only static data, you
210 * don't need to copy it unless you intend to write to it.
212 * Return value: A newly-created #GdkPixbuf structure with a reference count of
216 gdk_pixbuf_new_from_inline (const guchar *inline_pixbuf,
217 gboolean copy_pixels,
222 GdkPixbufInlineFormat format;
224 if (length >= 0 && length < 8) {
225 /* not enough bytes to contain even the magic number
233 if (read_int (&p) != GDK_PIXBUF_INLINE_MAGIC_NUMBER) {
237 format = read_int (&p);
241 case GDK_PIXBUF_INLINE_RAW:
242 pixbuf = read_raw_inline (p, copy_pixels, length - 8);