1 /* GdkPixbuf library - GdkPixdata - functions for inlined pixbuf handling
2 * Copyright (C) 1999, 2001 Tim Janik
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
19 #include "gdk-pixdata.h"
21 #include "gdk-pixbuf-private.h"
22 #include "gdk-pixbuf-i18n.h"
25 /* --- functions --- */
27 pixdata_get_length (const GdkPixdata *pixdata)
31 if ((pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGB)
33 else if ((pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGBA)
36 return 0; /* invalid format */
37 switch (pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK)
41 case GDK_PIXDATA_ENCODING_RAW:
42 length = pixdata->rowstride * pixdata->height;
44 case GDK_PIXDATA_ENCODING_RLE:
45 /* need an RLE walk to determine size */
46 max_length = pixdata->rowstride * pixdata->height;
47 rle_buffer = pixdata->pixel_data;
49 while (length < max_length)
51 guint chunk_length = *(rle_buffer++);
53 if (chunk_length & 128)
55 chunk_length = chunk_length - 128;
56 if (!chunk_length) /* RLE data corrupted */
58 length += chunk_length * bpp;
63 if (!chunk_length) /* RLE data corrupted */
66 length += chunk_length;
67 rle_buffer += chunk_length;
70 length = rle_buffer - pixdata->pixel_data;
80 * gdk_pixdata_serialize:
81 * @pixdata: A valid GdkPixdata structure to serialize
82 * @stream_length_p: Location to store the resulting stream length in
84 * Serialize a #GdkPixdata structure into a byte stream.
85 * The byte stream consists of a straight forward write out of the
86 * #GdkPixdata fields in network byte order, plus the pixel_data
87 * bytes the structure points to.
89 * Return value: A newly-allocated string containing the serialized
90 * GdkPixdata structure
92 guint8* /* free result */
93 gdk_pixdata_serialize (const GdkPixdata *pixdata,
94 guint *stream_length_p)
100 /* check args passing */
101 g_return_val_if_fail (pixdata != NULL, NULL);
102 g_return_val_if_fail (stream_length_p != NULL, NULL);
103 /* check pixdata contents */
104 g_return_val_if_fail (pixdata->magic == GDK_PIXBUF_MAGIC_NUMBER, NULL);
105 g_return_val_if_fail (pixdata->width > 0, NULL);
106 g_return_val_if_fail (pixdata->height > 0, NULL);
107 g_return_val_if_fail (pixdata->rowstride >= pixdata->width, NULL);
108 g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGB ||
109 (pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGBA, NULL);
110 g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_SAMPLE_WIDTH_MASK) == GDK_PIXDATA_SAMPLE_WIDTH_8, NULL);
111 g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK) == GDK_PIXDATA_ENCODING_RAW ||
112 (pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK) == GDK_PIXDATA_ENCODING_RLE, NULL);
113 g_return_val_if_fail (pixdata->pixel_data != NULL, NULL);
115 length = pixdata_get_length (pixdata);
117 /* check length field */
118 g_return_val_if_fail (length != 0, NULL);
120 stream = g_malloc (GDK_PIXDATA_HEADER_LENGTH + length);
121 istream = (guint32*) stream;
124 *istream++ = g_htonl (GDK_PIXBUF_MAGIC_NUMBER);
125 *istream++ = g_htonl (GDK_PIXDATA_HEADER_LENGTH + length);
126 *istream++ = g_htonl (pixdata->pixdata_type);
127 *istream++ = g_htonl (pixdata->rowstride);
128 *istream++ = g_htonl (pixdata->width);
129 *istream++ = g_htonl (pixdata->height);
131 /* copy pixel data */
132 s = (guint8*) istream;
133 memcpy (s, pixdata->pixel_data, length);
136 *stream_length_p = GDK_PIXDATA_HEADER_LENGTH + length;
137 g_assert (s - stream == *stream_length_p); /* paranoid */
142 #define return_header_corrupt(error) { \
143 g_set_error (error, GDK_PIXBUF_ERROR, \
144 GDK_PIXBUF_ERROR_HEADER_CORRUPT, _("Image header corrupt")); \
147 #define return_invalid_format(error) { \
148 g_set_error (error, GDK_PIXBUF_ERROR, \
149 GDK_PIXBUF_ERROR_UNKNOWN_FORMAT, _("Image format unknown")); \
152 #define return_pixel_corrupt(error) { \
153 g_set_error (error, GDK_PIXBUF_ERROR, \
154 GDK_PIXBUF_ERROR_PIXEL_CORRUPT, _("Image pixel data corrupt")); \
159 * gdk_pixdata_deserialize:
160 * @pixdata: A GdkPixdata structure to be filled in
161 * @stream_length: Length of the stream used for deserialization
162 * @stream: Stream of bytes containing a serialized pixdata structure
163 * @error: GError location to indicate failures (maybe NULL to ignore errors)
165 * Deserialize (reconstruct) a #GdkPixdata structure from a byte stream.
166 * The byte stream consists of a straight forward write out of the
167 * #GdkPixdata fields in network byte order, plus the pixel_data
168 * bytes the structure points to.
169 * The pixdata contents are reconstructed byte by byte and are checked
170 * for validity, due to the checks, this function may prematurely abort
171 * with errors, such as #GDK_PIXBUF_ERROR_HEADER_CORRUPT,
172 * #GDK_PIXBUF_ERROR_PIXEL_CORRUPT or #GDK_PIXBUF_ERROR_UNKNOWN_FORMAT.
174 * Return value: Upon successfull deserialization #TRUE is returned,
178 gdk_pixdata_deserialize (GdkPixdata *pixdata,
180 const guint8 *stream,
184 guint color_type, sample_width, encoding;
186 g_return_val_if_fail (pixdata != NULL, FALSE);
187 if (stream_length < GDK_PIXDATA_HEADER_LENGTH)
188 return_header_corrupt (error);
189 g_return_val_if_fail (stream != NULL, FALSE);
192 /* deserialize header */
193 istream = (guint32*) stream;
194 pixdata->magic = g_ntohl (*istream++);
195 pixdata->length = g_ntohl (*istream++);
196 if (pixdata->magic != GDK_PIXBUF_MAGIC_NUMBER || pixdata->length < GDK_PIXDATA_HEADER_LENGTH)
197 return_header_corrupt (error);
198 pixdata->pixdata_type = g_ntohl (*istream++);
199 pixdata->rowstride = g_ntohl (*istream++);
200 pixdata->width = g_ntohl (*istream++);
201 pixdata->height = g_ntohl (*istream++);
202 if (pixdata->width < 1 || pixdata->height < 1 ||
203 pixdata->rowstride < pixdata->width)
204 return_header_corrupt (error);
205 color_type = pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK;
206 sample_width = pixdata->pixdata_type & GDK_PIXDATA_SAMPLE_WIDTH_MASK;
207 encoding = pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK;
208 if ((color_type != GDK_PIXDATA_COLOR_TYPE_RGB &&
209 color_type != GDK_PIXDATA_COLOR_TYPE_RGBA) ||
210 sample_width != GDK_PIXDATA_SAMPLE_WIDTH_8 ||
211 (encoding != GDK_PIXDATA_ENCODING_RAW &&
212 encoding != GDK_PIXDATA_ENCODING_RLE))
213 return_invalid_format (error);
215 /* deserialize pixel data */
216 if (stream_length < pixdata->length - GDK_PIXDATA_HEADER_LENGTH)
217 return_pixel_corrupt (error);
218 pixdata->pixel_data = (guint8*) istream;
224 diff2_rgb (guint8 *ip)
226 return ip[0] != ip[3] || ip[1] != ip[4] || ip[2] != ip[5];
230 diff2_rgba (guint8 *ip)
232 return ip[0] != ip[4] || ip[1] != ip[5] || ip[2] != ip[6] || ip[3] != ip[7];
235 static guint8* /* dest buffer bound */
236 rl_encode_rgbx (guint8 *bp, /* dest buffer */
237 guint8 *ip, /* image pointer */
238 guint8 *limit, /* image upper bound */
241 gboolean (*diff2_pix) (guint8 *) = n_ch > 3 ? diff2_rgba : diff2_rgb;
242 guint8 *ilimit = limit - n_ch;
246 g_assert (ip < ilimit); /* paranoid */
254 while (l < 127 && ip < ilimit && diff2_pix (ip))
255 { ip += n_ch; l += 1; }
256 if (ip == ilimit && l < 127)
257 { ip += n_ch; l += 1; }
259 memcpy (bp, s_ip, l * n_ch);
267 while (l < 127 && ip < ilimit && !diff2_pix (ip))
268 { ip += n_ch; l += 1; }
270 memcpy (bp, ip, n_ch);
277 memcpy (bp, ip, n_ch);
287 gdk_pixdata_from_pixbuf (GdkPixdata *pixdata,
288 const GdkPixbuf *pixbuf,
291 gpointer free_me = NULL;
292 guint height, rowstride, encoding, bpp, length;
295 g_return_val_if_fail (pixdata != NULL, NULL);
296 g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
297 g_return_val_if_fail (pixbuf->bits_per_sample == 8, NULL);
298 g_return_val_if_fail ((pixbuf->n_channels == 3 && !pixbuf->has_alpha) ||
299 (pixbuf->n_channels == 4 && pixbuf->has_alpha), NULL);
300 g_return_val_if_fail (pixbuf->rowstride >= pixbuf->width, NULL);
302 height = pixbuf->height;
303 rowstride = pixbuf->rowstride;
304 encoding = use_rle ? GDK_PIXDATA_ENCODING_RLE : GDK_PIXDATA_ENCODING_RAW;
305 bpp = pixbuf->has_alpha ? 4 : 3;
307 if (encoding == GDK_PIXDATA_ENCODING_RLE)
309 guint pad, n_bytes = rowstride * height;
310 guint8 *img_buffer_end, *data;
313 pad = MAX (pad, 130 + n_bytes / 127);
314 data = g_new (guint8, pad + n_bytes);
317 img_buffer_end = rl_encode_rgbx (img_buffer,
318 pixbuf->pixels, pixbuf->pixels + n_bytes,
320 length = img_buffer_end - img_buffer;
324 img_buffer = pixbuf->pixels;
325 length = rowstride * height;
328 pixdata->magic = GDK_PIXBUF_MAGIC_NUMBER;
329 pixdata->length = GDK_PIXDATA_HEADER_LENGTH + length;
330 pixdata->pixdata_type = pixbuf->has_alpha ? GDK_PIXDATA_COLOR_TYPE_RGBA : GDK_PIXDATA_COLOR_TYPE_RGB;
331 pixdata->pixdata_type |= GDK_PIXDATA_SAMPLE_WIDTH_8;
332 pixdata->pixdata_type |= encoding;
333 pixdata->rowstride = rowstride;
334 pixdata->width = pixbuf->width;
335 pixdata->height = height;
336 pixdata->pixel_data = img_buffer;
342 gdk_pixbuf_from_pixdata (const GdkPixdata *pixdata,
343 gboolean copy_pixels,
349 g_return_val_if_fail (pixdata != NULL, NULL);
350 g_return_val_if_fail (pixdata->width > 0, NULL);
351 g_return_val_if_fail (pixdata->height > 0, NULL);
352 g_return_val_if_fail (pixdata->rowstride >= pixdata->width, NULL);
353 g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGB ||
354 (pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGBA, NULL);
355 g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_SAMPLE_WIDTH_MASK) == GDK_PIXDATA_SAMPLE_WIDTH_8, NULL);
356 g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK) == GDK_PIXDATA_ENCODING_RAW ||
357 (pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK) == GDK_PIXDATA_ENCODING_RLE, NULL);
358 g_return_val_if_fail (pixdata->pixel_data != NULL, NULL);
360 bpp = (pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGB ? 3 : 4;
361 encoding = pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK;
362 if (encoding == GDK_PIXDATA_ENCODING_RLE)
366 data = g_try_malloc (pixdata->rowstride * pixdata->height);
369 g_set_error (error, GDK_PIXBUF_ERROR,
370 GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
371 _("failed to allocate imagge buffer of %u bytes"),
372 pixdata->rowstride * pixdata->height);
376 if (encoding == GDK_PIXDATA_ENCODING_RLE)
378 const guint8 *rle_buffer = pixdata->pixel_data;
379 guint8 *image_buffer = data;
380 guint8 *image_limit = data + pixdata->rowstride * pixdata->height;
381 gboolean check_overrun = FALSE;
383 while (image_buffer < image_limit)
385 guint length = *(rle_buffer++);
389 length = length - 128;
390 check_overrun = image_buffer + length * bpp > image_limit;
392 length = (image_limit - image_buffer) / bpp;
393 if (bpp < 4) /* RGB */
396 memcpy (image_buffer, rle_buffer, 3);
403 memcpy (image_buffer, rle_buffer, 4);
412 check_overrun = image_buffer + length > image_limit;
414 length = image_limit - image_buffer;
415 memcpy (image_buffer, rle_buffer, length);
416 image_buffer += length;
417 rle_buffer += length;
423 g_set_error (error, GDK_PIXBUF_ERROR,
424 GDK_PIXBUF_ERROR_PIXEL_CORRUPT,
425 _("Image pixel data corrupt"));
429 else if (copy_pixels)
430 memcpy (data, pixdata->pixel_data, pixdata->rowstride * pixdata->height);
432 data = pixdata->pixel_data;
434 return gdk_pixbuf_new_from_data (data, GDK_COLORSPACE_RGB,
435 (pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGBA,
436 8, pixdata->width, pixdata->height, pixdata->rowstride,
437 copy_pixels ? (GdkPixbufDestroyNotify) g_free : NULL, data);
442 gboolean dump_stream;
443 gboolean dump_struct;
444 gboolean dump_macros;
445 gboolean dump_gtypes;
446 gboolean dump_rle_decoder;
447 const gchar *static_prefix;
448 const gchar *const_prefix;
456 save_uchar (CSourceData *cdata,
459 GString *gstring = cdata->gstring;
463 if (cdata->dump_struct || cdata->dump_stream)
465 g_string_append (gstring, "\"\n \"");
469 if (cdata->dump_macros)
471 g_string_append (gstring, "\" \\\n \"");
476 if (d < 33 || d > 126)
478 g_string_printfa (gstring, "\\%o", d);
479 cdata->pos += 1 + 1 + (d > 7) + (d > 63);
485 g_string_append (gstring, "\\\\");
490 g_string_append (gstring, "\\\"");
493 else if (cdata->pad && d >= '0' && d <= '9')
495 g_string_append (gstring, "\"\"");
496 g_string_append_c (gstring, d);
501 g_string_append_c (gstring, d);
509 save_rle_decoder (GString *gstring,
510 const gchar *macro_name,
512 const gchar *s_uint_8,
515 g_string_printfa (gstring, "#define %s_RUN_LENGTH_DECODE(image_buf, rle_data, size, bpp) do \\\n",
517 g_string_printfa (gstring, "{ %s __bpp; %s *__ip; const %s *__il, *__rd; \\\n", s_uint, s_uint_8, s_uint_8);
518 g_string_printfa (gstring, " __bpp = (bpp); __ip = (image_buf); __il = __ip + (size) * __bpp; \\\n");
520 g_string_printfa (gstring, " __rd = (rle_data); if (__bpp > 3) { /* RGBA */ \\\n");
522 g_string_printfa (gstring, " while (__ip < __il) { %s __l = *(__rd++); \\\n", s_uint);
523 g_string_printfa (gstring, " if (__l & 128) { __l = __l - 128; \\\n");
524 g_string_printfa (gstring, " do { memcpy (__ip, __rd, 4); __ip += 4; } while (--__l); __rd += 4; \\\n");
525 g_string_printfa (gstring, " } else { __l *= 4; memcpy (__ip, __rd, __l); \\\n");
526 g_string_printfa (gstring, " __ip += __l; __rd += __l; } } \\\n");
528 g_string_printfa (gstring, " } else { /* RGB */ \\\n");
530 g_string_printfa (gstring, " while (__ip < __il) { %s __l = *(__rd++); \\\n", s_uint);
531 g_string_printfa (gstring, " if (__l & 128) { __l = __l - 128; \\\n");
532 g_string_printfa (gstring, " do { memcpy (__ip, __rd, 3); __ip += 3; } while (--__l); __rd += 3; \\\n");
533 g_string_printfa (gstring, " } else { __l *= 3; memcpy (__ip, __rd, __l); \\\n");
534 g_string_printfa (gstring, " __ip += __l; __rd += __l; } } \\\n");
536 g_string_printfa (gstring, " } } while (0)\n");
540 gdk_pixdata_to_csource (GdkPixdata *pixdata,
542 GdkPixdataDumpType dump_type)
544 CSourceData cdata = { 0, };
545 gchar *s_uint_8, *s_uint_32, *s_uint, *s_char, *s_null;
546 guint bpp, width, height, rowstride;
547 gboolean rle_encoded;
549 guint8 *img_buffer, *img_buffer_end, *stream;
553 /* check args passing */
554 g_return_val_if_fail (pixdata != NULL, NULL);
555 g_return_val_if_fail (name != NULL, NULL);
556 /* check pixdata contents */
557 g_return_val_if_fail (pixdata->magic == GDK_PIXBUF_MAGIC_NUMBER, NULL);
558 g_return_val_if_fail (pixdata->width > 0, NULL);
559 g_return_val_if_fail (pixdata->height > 0, NULL);
560 g_return_val_if_fail (pixdata->rowstride >= pixdata->width, NULL);
561 g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGB ||
562 (pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGBA, NULL);
563 g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_SAMPLE_WIDTH_MASK) == GDK_PIXDATA_SAMPLE_WIDTH_8, NULL);
564 g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK) == GDK_PIXDATA_ENCODING_RAW ||
565 (pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK) == GDK_PIXDATA_ENCODING_RLE, NULL);
566 g_return_val_if_fail (pixdata->pixel_data != NULL, NULL);
568 img_buffer = pixdata->pixel_data;
569 if (pixdata->length < 1)
570 img_buffer_end = img_buffer + pixdata_get_length (pixdata);
572 img_buffer_end = img_buffer + pixdata->length - GDK_PIXDATA_HEADER_LENGTH;
573 g_return_val_if_fail (img_buffer < img_buffer_end, NULL);
575 bpp = (pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGB ? 3 : 4;
576 width = pixdata->width;
577 height = pixdata->height;
578 rowstride = pixdata->rowstride;
579 rle_encoded = (pixdata->pixdata_type & GDK_PIXDATA_ENCODING_RLE) > 0;
580 macro_name = g_strdup (name);
581 g_strup (macro_name);
583 cdata.dump_macros = (dump_type & GDK_PIXDATA_DUMP_MACROS) > 0;
584 cdata.dump_struct = (dump_type & GDK_PIXDATA_DUMP_PIXDATA_STRUCT) > 0;
585 cdata.dump_stream = !cdata.dump_macros && !cdata.dump_struct;
586 g_return_val_if_fail (cdata.dump_macros + cdata.dump_struct + cdata.dump_stream == 1, NULL);
588 cdata.dump_gtypes = (dump_type & GDK_PIXDATA_DUMP_CTYPES) == 0;
589 cdata.dump_rle_decoder = (dump_type & GDK_PIXDATA_DUMP_RLE_DECODER) > 0;
590 cdata.static_prefix = (dump_type & GDK_PIXDATA_DUMP_STATIC) ? "static " : "";
591 cdata.const_prefix = (dump_type & GDK_PIXDATA_DUMP_CONST) ? "const " : "";
592 gstring = g_string_new ("");
593 cdata.gstring = gstring;
595 if (!cdata.dump_macros && cdata.dump_gtypes)
597 s_uint_8 = "guint8 ";
598 s_uint_32 = "guint32";
603 else if (!cdata.dump_macros)
605 s_uint_8 = "unsigned char";
606 s_uint_32 = "unsigned int ";
607 s_uint = "unsigned int ";
609 s_null = "(char*) 0";
611 else if (cdata.dump_macros && cdata.dump_gtypes)
614 s_uint_32 = "guint32";
619 else /* cdata.dump_macros && !cdata.dump_gtypes */
621 s_uint_8 = "unsigned char";
622 s_uint_32 = "unsigned int";
623 s_uint = "unsigned int";
625 s_null = "(char*) 0";
630 g_string_printfa (gstring,
631 "/* GdkPixbuf %s C-Source image dump %s*/\n\n",
632 bpp > 3 ? "RGBA" : "RGB",
633 rle_encoded ? "1-byte-run-length-encoded " : "");
635 /* dump RLE decoder for structures
637 if (cdata.dump_rle_decoder && cdata.dump_struct)
638 save_rle_decoder (gstring,
640 cdata.dump_gtypes ? "guint" : "unsigned int",
641 cdata.dump_gtypes ? "guint8" : "unsigned char",
644 /* format & size blurbs
646 if (cdata.dump_macros)
648 g_string_printfa (gstring, "#define %s_ROWSTRIDE (%u)\n",
649 macro_name, rowstride);
650 g_string_printfa (gstring, "#define %s_WIDTH (%u)\n",
652 g_string_printfa (gstring, "#define %s_HEIGHT (%u)\n",
654 g_string_printfa (gstring, "#define %s_BYTES_PER_PIXEL (%u) /* 3:RGB, 4:RGBA */\n",
657 if (cdata.dump_struct)
659 g_string_printfa (gstring, "%s%sGdkPixdata %s = {\n",
660 cdata.static_prefix, cdata.const_prefix, name);
661 g_string_printfa (gstring, " 0x%x, /* Pixbuf magic: 'GdkP' */\n",
662 GDK_PIXBUF_MAGIC_NUMBER);
663 g_string_printfa (gstring, " %u + %u, /* header length + pixel_data length */\n",
664 GDK_PIXDATA_HEADER_LENGTH,
665 rle_encoded ? img_buffer_end - img_buffer : rowstride * height);
666 g_string_printfa (gstring, " 0x%x, /* pixdata_type */\n",
667 pixdata->pixdata_type);
668 g_string_printfa (gstring, " %u, /* rowstride */\n",
670 g_string_printfa (gstring, " %u, /* width */\n",
672 g_string_printfa (gstring, " %u, /* height */\n",
674 g_string_printfa (gstring, " /* pixel_data: */\n");
676 if (cdata.dump_stream)
678 guint pix_length = img_buffer_end - img_buffer;
680 stream = gdk_pixdata_serialize (pixdata, &stream_length);
681 img_buffer_end = stream + stream_length;
683 g_string_printfa (gstring, "%s%s%s %s[] = \n",
684 cdata.static_prefix, cdata.const_prefix,
685 cdata.dump_gtypes ? "guint8" : "unsigned char",
687 g_string_printfa (gstring, "( \"\"\n /* Pixbuf magic (0x%x) */\n \"",
688 GDK_PIXBUF_MAGIC_NUMBER);
690 save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
691 save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
692 g_string_printfa (gstring, "\"\n /* length: header (%u) + pixel_data (%u) */\n \"",
693 GDK_PIXDATA_HEADER_LENGTH,
694 rle_encoded ? pix_length : rowstride * height);
696 save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
697 save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
698 g_string_printfa (gstring, "\"\n /* pixdata_type (0x%x) */\n \"",
699 pixdata->pixdata_type);
701 save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
702 save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
703 g_string_printfa (gstring, "\"\n /* rowstride (%u) */\n \"",
706 save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
707 save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
708 g_string_printfa (gstring, "\"\n /* width (%u) */\n \"", width);
710 save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
711 save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
712 g_string_printfa (gstring, "\"\n /* height (%u) */\n \"", height);
714 save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
715 save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
716 g_string_printfa (gstring, "\"\n /* pixel_data: */\n");
722 if (cdata.dump_macros)
724 g_string_printfa (gstring, "#define %s_%sPIXEL_DATA ((%s*) \\\n",
726 rle_encoded ? "RLE_" : "",
728 g_string_printfa (gstring, " \"");
731 if (cdata.dump_struct)
733 g_string_printfa (gstring, " \"");
736 if (cdata.dump_stream)
738 g_string_printfa (gstring, " \"");
745 save_uchar (&cdata, *img_buffer++);
746 while (img_buffer < img_buffer_end);
748 /* pixel_data trailer
750 if (cdata.dump_macros)
751 g_string_printfa (gstring, "\")\n\n");
752 if (cdata.dump_struct)
753 g_string_printfa (gstring, "\",\n};\n\n");
754 if (cdata.dump_stream)
755 g_string_printfa (gstring, "\");\n\n");
757 /* dump RLE decoder for macros
759 if (cdata.dump_rle_decoder && cdata.dump_macros)
760 save_rle_decoder (gstring,
762 cdata.dump_gtypes ? "guint" : "unsigned int",
763 cdata.dump_gtypes ? "guint8" : "unsigned char",
774 * gdk_pixbuf_new_from_stream:
775 * @stream_length: Length in bytes of the @stream argument
776 * @stream: Byte stream containing a serialized GdkPixdata structure
777 * @copy_pixels: Whether to copy the pixels data, or keep direct pointers into the
778 * stream data for the resulting pixbuf
779 * @error: GError return location, may be NULL to ignore errors
781 * Create a #GdkPixbuf from a serialized GdkPixdata structure.
782 * Gtk+ ships with a program called gdk-pixbuf-csource which allowes
783 * for conversion of #GdkPixbufs into various kinds of C sources.
784 * This is useful if you want to ship a program with images, but
785 * don't want to depend on any external files.
787 * Since the inline pixbuf is read-only static data, you
788 * don't need to copy it unless you intend to write to it.
789 * For deserialization of streams that are run length encoded, the
790 * decoded data is always a copy of the input stream.
792 * If you create a pixbuf from const inline data compiled into your
793 * program, it's probably safe to ignore errors, since things will
794 * always succeed. For non-const inline data, you could get out of
795 * memory. For untrusted inline data located at runtime, you could
796 * have corrupt inline data in addition.
798 * Return value: A newly-created #GdkPixbuf structure with a reference count of
799 * 1, or NULL If error is set.
802 gdk_pixbuf_new_from_stream (gint stream_length,
803 const guint8 *stream,
804 gboolean copy_pixels,
809 if (stream_length != -1)
810 g_return_val_if_fail (stream_length > GDK_PIXDATA_HEADER_LENGTH, NULL);
811 g_return_val_if_fail (stream != NULL, NULL);
813 if (!gdk_pixdata_deserialize (&pixdata, stream_length, stream, error))
816 return gdk_pixbuf_from_pixdata (&pixdata, copy_pixels, error);