]> Pileus Git - ~andy/gtk/commitdiff
use gdk_pixbuf_new_from_stream(). fixed up item factory so inlined pixbufs
authorTim Janik <timj@gtk.org>
Tue, 26 Jun 2001 20:56:32 +0000 (20:56 +0000)
committerTim Janik <timj@src.gnome.org>
Tue, 26 Jun 2001 20:56:32 +0000 (20:56 +0000)
Tue Jun 26 10:04:30 2001  Tim Janik  <timj@gtk.org>

        * gtk/gtkiconfactory.c:
        * gtk/gtkitemfactory.c: use gdk_pixbuf_new_from_stream(). fixed up
        item factory so inlined pixbufs actually work.

Tue Jun 26 09:48:02 2001  Tim Janik  <timj@gtk.org>

        * Makefile.am (noinst_PROGRAMS): get rid of make-inline-pixbuf

        * gdk-pixbuf-data.[hc]: provide gdk_pixbuf_new_from_stream()
        instead from gdk_pixbuf_new_from_inline().

        * gdk-pixdata.[hc]: auxillary GdkPixdata structure, public
        installed API for applications that need to serialize/deserialize
        on their own (gimp, BEAST).

        * gdk-pixbuf/gdk-pixbuf-csource.c: provide publically installed
        program that can dump images in CSource format and Pixbuf
        stream format. supports RLE encoding, MACRO formatting etc...
        invoke with --help.

24 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
demos/Makefile.am
demos/testpixbuf.c
docs/reference/gdk-pixbuf/tmpl/creating.sgml
docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf-unused.sgml
docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf.sgml
docs/reference/gtk/tmpl/gtkitemfactory.sgml
gdk-pixbuf/ChangeLog
gdk-pixbuf/Makefile.am
gdk-pixbuf/gdk-pixbuf-csource.c [new file with mode: 0644]
gdk-pixbuf/gdk-pixbuf-data.c
gdk-pixbuf/gdk-pixbuf-private.h
gdk-pixbuf/gdk-pixbuf.h
gdk-pixbuf/gdk-pixdata.c [new file with mode: 0644]
gdk-pixbuf/gdk-pixdata.h [new file with mode: 0644]
gtk/gtkiconfactory.c
gtk/gtkitemfactory.c
gtk/gtkitemfactory.h

index c344a4091f47566c375c81bdc1288503badc9c9b..92498d5b7862209dd15634b541b91e935f67a55e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -24,6 +24,12 @@ Tue Jun 26 11:06:34 2001  Owen Taylor  <otaylor@redhat.com>
        with font lists in descriptions. (#56184, reported by
        Jonas Borgström)
 
+Tue Jun 26 10:04:30 2001  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkiconfactory.c:
+       * gtk/gtkitemfactory.c: use gdk_pixbuf_new_from_stream(). fixed up
+       item factory so inlined pixbufs actually work.
+
 2001-06-25  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktreeviewcolumn.h, gtk/gtktreeviewcolumn.c:
index c344a4091f47566c375c81bdc1288503badc9c9b..92498d5b7862209dd15634b541b91e935f67a55e 100644 (file)
@@ -24,6 +24,12 @@ Tue Jun 26 11:06:34 2001  Owen Taylor  <otaylor@redhat.com>
        with font lists in descriptions. (#56184, reported by
        Jonas Borgström)
 
+Tue Jun 26 10:04:30 2001  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkiconfactory.c:
+       * gtk/gtkitemfactory.c: use gdk_pixbuf_new_from_stream(). fixed up
+       item factory so inlined pixbufs actually work.
+
 2001-06-25  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktreeviewcolumn.h, gtk/gtktreeviewcolumn.c:
index c344a4091f47566c375c81bdc1288503badc9c9b..92498d5b7862209dd15634b541b91e935f67a55e 100644 (file)
@@ -24,6 +24,12 @@ Tue Jun 26 11:06:34 2001  Owen Taylor  <otaylor@redhat.com>
        with font lists in descriptions. (#56184, reported by
        Jonas Borgström)
 
+Tue Jun 26 10:04:30 2001  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkiconfactory.c:
+       * gtk/gtkitemfactory.c: use gdk_pixbuf_new_from_stream(). fixed up
+       item factory so inlined pixbufs actually work.
+
 2001-06-25  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktreeviewcolumn.h, gtk/gtktreeviewcolumn.c:
index c344a4091f47566c375c81bdc1288503badc9c9b..92498d5b7862209dd15634b541b91e935f67a55e 100644 (file)
@@ -24,6 +24,12 @@ Tue Jun 26 11:06:34 2001  Owen Taylor  <otaylor@redhat.com>
        with font lists in descriptions. (#56184, reported by
        Jonas Borgström)
 
+Tue Jun 26 10:04:30 2001  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkiconfactory.c:
+       * gtk/gtkitemfactory.c: use gdk_pixbuf_new_from_stream(). fixed up
+       item factory so inlined pixbufs actually work.
+
 2001-06-25  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktreeviewcolumn.h, gtk/gtktreeviewcolumn.c:
index c344a4091f47566c375c81bdc1288503badc9c9b..92498d5b7862209dd15634b541b91e935f67a55e 100644 (file)
@@ -24,6 +24,12 @@ Tue Jun 26 11:06:34 2001  Owen Taylor  <otaylor@redhat.com>
        with font lists in descriptions. (#56184, reported by
        Jonas Borgström)
 
+Tue Jun 26 10:04:30 2001  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkiconfactory.c:
+       * gtk/gtkitemfactory.c: use gdk_pixbuf_new_from_stream(). fixed up
+       item factory so inlined pixbufs actually work.
+
 2001-06-25  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktreeviewcolumn.h, gtk/gtktreeviewcolumn.c:
index c344a4091f47566c375c81bdc1288503badc9c9b..92498d5b7862209dd15634b541b91e935f67a55e 100644 (file)
@@ -24,6 +24,12 @@ Tue Jun 26 11:06:34 2001  Owen Taylor  <otaylor@redhat.com>
        with font lists in descriptions. (#56184, reported by
        Jonas Borgström)
 
+Tue Jun 26 10:04:30 2001  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkiconfactory.c:
+       * gtk/gtkitemfactory.c: use gdk_pixbuf_new_from_stream(). fixed up
+       item factory so inlined pixbufs actually work.
+
 2001-06-25  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktreeviewcolumn.h, gtk/gtktreeviewcolumn.c:
index c344a4091f47566c375c81bdc1288503badc9c9b..92498d5b7862209dd15634b541b91e935f67a55e 100644 (file)
@@ -24,6 +24,12 @@ Tue Jun 26 11:06:34 2001  Owen Taylor  <otaylor@redhat.com>
        with font lists in descriptions. (#56184, reported by
        Jonas Borgström)
 
+Tue Jun 26 10:04:30 2001  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkiconfactory.c:
+       * gtk/gtkitemfactory.c: use gdk_pixbuf_new_from_stream(). fixed up
+       item factory so inlined pixbufs actually work.
+
 2001-06-25  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktreeviewcolumn.h, gtk/gtktreeviewcolumn.c:
index 25eba726532215e09b6486b7c7b68d7b1c8c2b9e..5bcf5023cbb1d7ddd9bf04305db1351b40fad37c 100644 (file)
@@ -32,10 +32,12 @@ noinst_PROGRAMS =           \
 
 BUILT_SOURCES=test-inline-pixbufs.h
 
-test-inline-pixbufs.h: $(top_builddir)/gdk-pixbuf/make-inline-pixbuf apple-red.png gnome-foot.png
+test-inline-pixbufs.h: $(top_builddir)/gdk-pixbuf/gdk-pixbuf-csource apple-red.png gnome-foot.png
        (topdir=`cd $(top_builddir) && pwd` ; curdir=`pwd` ; \
-         cd $(srcdir) &&                                    \
-            GDK_PIXBUF_MODULEDIR=$$topdir/gdk-pixbuf/.libs $$topdir/gdk-pixbuf/make-inline-pixbuf $$curdir/test-inline-pixbufs.h  apple_red apple-red.png gnome_foot gnome-foot.png)
+         cd $(srcdir) &&                                    \
+           GDK_PIXBUF_MODULEDIR=$$topdir/gdk-pixbuf/.libs \
+             $$topdir/gdk-pixbuf/gdk-pixbuf-csource --build-list \
+               apple_red apple-red.png gnome_foot gnome-foot.png >$$curdir/test-inline-pixbufs.h)
 
 testpixbuf_DEPENDENCIES = $(DEPS)
 testpixbuf_drawable_DEPENDENCIES = $(DEPS)
index 0af6d368e93b40a764ccc5a70c9097feda094fc0..a2ecbe1f089615058ca68afe3c83321e850b4ce1 100644 (file)
@@ -543,7 +543,8 @@ main (int argc, char **argv)
        i = 1;
        if (argc == 1) {
                 const gchar*** xpmp;
-                
+                GError *error = NULL;
+               
                pixbuf = gdk_pixbuf_new_from_data (default_image, GDK_COLORSPACE_RGB, FALSE, 8,
                                                   DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_WIDTH * 3,
                                                   NULL, NULL);
@@ -557,11 +558,18 @@ main (int argc, char **argv)
                 }
 
                 /* Test loading from inline data. */
-                pixbuf = gdk_pixbuf_new_from_inline (apple_red, FALSE, -1, NULL);
-                new_testrgb_window (pixbuf, "Red apple from inline data");
-
-                pixbuf = gdk_pixbuf_new_from_inline (gnome_foot, TRUE, sizeof (gnome_foot), NULL);
-                new_testrgb_window (pixbuf, "Foot from inline data");
+                pixbuf = gdk_pixbuf_new_from_stream (-1, apple_red, FALSE, &error);
+               if (!pixbuf)
+                 {
+                   fprintf (stderr, "failed to construct \"red apple\" pixbuf: %s\n",
+                            error->message);
+                   g_error_free (error);
+                 }
+               else
+                 new_testrgb_window (pixbuf, "Red apple from inlined RLE data");
+
+                pixbuf = gdk_pixbuf_new_from_stream (sizeof (gnome_foot), gnome_foot, TRUE, NULL);
+                new_testrgb_window (pixbuf, "GNOME Foot from inlined RLE data");
                 
                found_valid = TRUE;
        } else {
index 0bbce5405a9051c6990701b10780d93c0ba5b556..1d017da68a77dd68f5cc58da808d65d3e0fc0fcf 100644 (file)
@@ -82,18 +82,6 @@ Creating a pixbuf from image data that is already in memory.
 @Returns: 
 
 
-<!-- ##### FUNCTION gdk_pixbuf_new_from_inline ##### -->
-<para>
-
-</para>
-
-@inline_pixbuf: 
-@copy_pixels: 
-@length: 
-@error: 
-@Returns: 
-
-
 <!-- ##### FUNCTION gdk_pixbuf_new_subpixbuf ##### -->
 <para>
 
index 910ccef35f1009950206d3a785cdd4d39ff765bd..099d29a515380532b5c628839e78ccd214e34760 100644 (file)
@@ -552,3 +552,14 @@ End:
   </para>
 
 
+<!-- ##### FUNCTION gdk_pixbuf_new_from_inline ##### -->
+<para>
+
+</para>
+
+@inline_pixbuf: 
+@copy_pixels: 
+@length: 
+@error: 
+@Returns: 
+
index 403941efa9fe2ebfcc5540aaf115b81f9c8c0bdc..ecc32bc201033748a02c124294f473d7ecff59f8 100644 (file)
@@ -20,6 +20,9 @@ Information that describes an image.
 
 </para>
 
+@GDK_PIXBUF_ERROR_HEADER_CORRUPT: 
+@GDK_PIXBUF_ERROR_PIXEL_CORRUPT: 
+@GDK_PIXBUF_ERROR_UNKNOWN_FORMAT: 
 @GDK_PIXBUF_ERROR_CORRUPT_IMAGE: 
 @GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY: 
 @GDK_PIXBUF_ERROR_BAD_OPTION_VALUE: 
index 18c4cc601d58ff130291db6a9105bf1ebd301200..abda892595f0435f91ce83eab19df0af73752262 100644 (file)
@@ -77,7 +77,6 @@ GtkItemFactory
 @callback_action: 
 @item_type: 
 @extra_data: 
-@extra_data2: 
 
 <!-- ##### STRUCT GtkItemFactoryItem ##### -->
 <para>
index a024030d23e7aa6d7b2ca9f22401e8be543093bf..992773220d11c038e1a080dc90fce8b740e139f1 100644 (file)
@@ -1,3 +1,19 @@
+Tue Jun 26 09:48:02 2001  Tim Janik  <timj@gtk.org>
+
+       * Makefile.am (noinst_PROGRAMS): get rid of make-inline-pixbuf
+
+       * gdk-pixbuf-data.[hc]: provide gdk_pixbuf_new_from_stream()
+       instead from gdk_pixbuf_new_from_inline().
+
+       * gdk-pixdata.[hc]: auxillary GdkPixdata structure, public
+       installed API for applications that need to serialize/deserialize
+       on their own (gimp, BEAST).
+       
+       * gdk-pixbuf/gdk-pixbuf-csource.c: provide publically installed
+       program that can dump images in CSource format and Pixbuf
+       stream format. supports RLE encoding, MACRO formatting etc...
+       invoke with --help.
+
 Mon Jun 25 00:28:11 2001  Owen Taylor  <otaylor@redhat.com>
 
        * Makefile.am: Actually update timestamps, so rules don't
index cfe6316664ffc116bde65d3b50ce3523e8b4c4ff..374ea905a3bfe73d98ba2d7d429b6a1b376e4471 100644 (file)
@@ -164,12 +164,15 @@ TESTS = test-gdk-pixbuf test-loaders
 noinst_PROGRAMS = $(TESTS)
 
 DEPS = libgdk_pixbuf-1.3.la
-INCLUDES = -I$(top_srcdir) -I$(top_builddir)   \
+INCLUDES = @STRIP_BEGIN@ \
+       -I$(top_srcdir) -I$(top_builddir)       \
        -I$(top_srcdir)/gdk-pixbuf              \
        -I$(top_builddir)/gdk-pixbuf            \
        @INCLUDED_LOADER_DEFINE@                \
        @GTK_DEBUG_FLAGS@                       \
-       @GDK_PIXBUF_DEP_CFLAGS@
+       @GDK_PIXBUF_DEP_CFLAGS@                 \
+@STRIP_END@
+
 AM_CPPFLAGS = "-DPIXBUF_LIBDIR=\"$(loaderdir)\"" "-DBUILT_MODULES_DIR=\"$(srcdir)/.libs\""
 
 LDADDS = libgdk_pixbuf-1.3.la
@@ -179,12 +182,13 @@ test_loaders_LDADD = $(LDADDS)
 
 test_loaders_SOURCES = test-loaders.c test-images.h
 
-bin_PROGRAMS=make-inline-pixbuf
-
-make_inline_pixbuf_SOURCES=make-inline-pixbuf.c
-
-make_inline_pixbuf_LDADD = $(LDADDS)
+#noinst_PROGRAMS=make-inline-pixbuf
+#make_inline_pixbuf_SOURCES=make-inline-pixbuf.c
+#make_inline_pixbuf_LDADD = $(LDADDS)
 
+bin_PROGRAMS = gdk-pixbuf-csource
+gdk_pixbuf_csource_SOURCES = gdk-pixbuf-csource.c
+gdk_pixbuf_csource_LDADD = $(LDADDS)
 
 
 #
@@ -195,7 +199,7 @@ BUILT_SOURCES=gdk-pixbuf-marshal.h gdk-pixbuf-marshal.c
 
 libgdk_pixbufincludedir = $(includedir)/gtk-2.0/gdk-pixbuf
 
-libgdk_pixbuf_1_3_la_SOURCES =         \
+libgdk_pixbuf_1_3_la_SOURCES = @STRIP_BEGIN@ \
        gdk-pixbuf-i18n.h       \
        gdk-pixbuf.c            \
        gdk-pixbuf-animation.c  \
@@ -203,20 +207,26 @@ libgdk_pixbuf_1_3_la_SOURCES =    \
        gdk-pixbuf-io.c         \
        gdk-pixbuf-loader.c     \
        gdk-pixbuf-scale.c      \
-       gdk-pixbuf-util.c
+       gdk-pixbuf-util.c       \
+       gdk-pixdata.c           \
+@STRIP_END@
+
 
 $(libgdk_pixbuf_1_3_la_OBJECTS): gdk-pixbuf-marshal.h gdk-pixbuf-marshal.c
 
-libgdk_pixbuf_1_3_la_LDFLAGS =                                         \
+libgdk_pixbuf_1_3_la_LDFLAGS = @STRIP_BEGIN@ \
        -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)    \
-       @LIBTOOL_EXPORT_OPTIONS@
+       @LIBTOOL_EXPORT_OPTIONS@                                \
+@STRIP_END@
+
 libgdk_pixbuf_1_3_la_LIBADD = pixops/libpixops.la $(builtin_objs) $(GDK_PIXBUF_DEP_LIBS)
 libgdk_pixbuf_1_3_la_DEPENDENCIES = $(builtin_objs)
 
-libgdk_pixbufinclude_HEADERS = \
+libgdk_pixbufinclude_HEADERS =  \
        gdk-pixbuf.h            \
        gdk-pixbuf-loader.h     \
-       gdk-pixbuf-features.h
+       gdk-pixbuf-features.h   \
+       gdk-pixdata.h
 
 noinst_HEADERS =               \
        gdk-pixbuf-io.h         \
diff --git a/gdk-pixbuf/gdk-pixbuf-csource.c b/gdk-pixbuf/gdk-pixbuf-csource.c
new file mode 100644 (file)
index 0000000..05bb685
--- /dev/null
@@ -0,0 +1,286 @@
+/* Gdk-Pixbuf-CSource - GdkPixbuf based image CSource generator
+ * Copyright (C) 1999, 2001 Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "config.h"
+
+#include "../gtk/gtkcompat.h"  /* versioning */
+#include "gdk-pixbuf.h"
+#include "gdk-pixdata.h"
+#include <stdio.h>
+#include <string.h>
+
+
+/* --- defines --- */
+#undef G_LOG_DOMAIN
+#define        G_LOG_DOMAIN    "Gdk-Pixbuf-CSource"
+#define PRG_NAME        "gdk-pixbuf-csource"
+#define PKG_NAME        "Gtk+"
+#define PKG_HTTP_HOME   "http://www.gtk.org"
+
+
+/* --- prototypes --- */
+static void    parse_args      (gint    *argc_p,
+                                gchar ***argv_p);
+static void    print_blurb     (FILE    *bout,
+                                gboolean print_help);
+
+
+/* --- variables --- */
+static guint    gen_type = GDK_PIXDATA_DUMP_PIXDATA_STREAM;
+static guint    gen_ctype = GDK_PIXDATA_DUMP_GTYPES | GDK_PIXDATA_DUMP_STATIC | GDK_PIXDATA_DUMP_CONST;
+static gboolean use_rle = TRUE;
+static gboolean with_decoder = FALSE;
+static gchar   *image_name = "my_pixbuf";
+static gboolean        build_list = FALSE;
+
+
+/* --- functions --- */
+static void
+print_csource (FILE *f_out,
+              GdkPixbuf *pixbuf)
+{
+  GdkPixdata pixdata;
+  gpointer free_me;
+  GString *gstring;
+
+  free_me = gdk_pixdata_from_pixbuf (&pixdata, pixbuf, use_rle);
+  gstring = gdk_pixdata_to_csource (&pixdata, image_name,
+                                   gen_type | gen_ctype |
+                                   (with_decoder ? GDK_PIXDATA_DUMP_RLE_DECODER : 0));
+
+  fprintf (f_out, "%s\n", gstring->str);
+
+  g_free (free_me);
+}
+
+int
+main (int   argc,
+      char *argv[])
+{
+  GdkPixbuf *pixbuf;
+  GError *error = NULL;
+
+  /* initialize glib/GdkPixbuf */
+  g_type_init (0);
+
+  /* parse args and do fast exits */
+  parse_args (&argc, &argv);
+
+  if (!build_list)
+    {
+      if (argc != 2)
+       {
+         print_blurb (stderr, TRUE);
+         return 1;
+       }
+      
+      pixbuf = gdk_pixbuf_new_from_file (argv[1], &error);
+      if (!pixbuf)
+       {
+         fprintf (stderr, "failed to load \"%s\": %s\n",
+                  argv[1],
+                  error->message);
+         g_error_free (error);
+         return 1;
+       }
+      
+      print_csource (stdout, pixbuf);
+      gdk_pixbuf_unref (pixbuf);
+    }
+  else /* parse name, file pairs */
+    {
+      gchar **p = argv + 1;
+      guint j = argc - 1;
+      gboolean toggle = FALSE;
+
+      while (j--)
+       {
+         if (!toggle)
+           image_name = *p++;
+         else
+           {
+             pixbuf = gdk_pixbuf_new_from_file (*p, &error);
+             if (!pixbuf)
+               {
+                 fprintf (stderr, "failed to load \"%s\": %s\n",
+                          *p,
+                          error->message);
+                 g_error_free (error);
+                 return 1;
+               }
+             print_csource (stdout, pixbuf);
+             gdk_pixbuf_unref (pixbuf);
+             p++;
+           }
+         toggle = !toggle;
+       }
+    }
+  
+  return 0;
+}
+
+static void
+parse_args (gint    *argc_p,
+           gchar ***argv_p)
+{
+  guint argc = *argc_p;
+  gchar **argv = *argv_p;
+  guint i, e;
+
+  for (i = 1; i < argc; i++)
+    {
+      if (strcmp ("--macros", argv[i]) == 0)
+       {
+         gen_type = GDK_PIXDATA_DUMP_MACROS;
+         argv[i] = NULL;
+       }
+      else if (strcmp ("--struct", argv[i]) == 0)
+       {
+         gen_type = GDK_PIXDATA_DUMP_PIXDATA_STRUCT;
+         argv[i] = NULL;
+       }
+      else if (strcmp ("--stream", argv[i]) == 0)
+       {
+         gen_type = GDK_PIXDATA_DUMP_PIXDATA_STREAM;
+         argv[i] = NULL;
+       }
+      else if (strcmp ("--rle", argv[i]) == 0)
+       {
+         use_rle = TRUE;
+         argv[i] = NULL;
+       }
+      else if (strcmp ("--raw", argv[i]) == 0)
+       {
+         use_rle = FALSE;
+         argv[i] = NULL;
+       }
+      else if (strcmp ("--extern", argv[i]) == 0)
+       {
+         gen_ctype &= ~GDK_PIXDATA_DUMP_STATIC;
+         argv[i] = NULL;
+       }
+      else if (strcmp ("--static", argv[i]) == 0)
+       {
+         gen_ctype |= GDK_PIXDATA_DUMP_STATIC;
+         argv[i] = NULL;
+       }
+      else if (strcmp ("--decoder", argv[i]) == 0)
+       {
+         with_decoder = TRUE;
+         argv[i] = NULL;
+       }
+      else if ((strcmp ("--name", argv[i]) == 0) ||
+              (strncmp ("--name=", argv[i], 7) == 0))
+       {
+         gchar *equal = argv[i] + 6;
+
+         if (*equal == '=')
+           image_name = g_strdup (equal + 1);
+         else if (i + 1 < argc)
+           {
+             image_name = g_strdup (argv[i + 1]);
+             argv[i] = NULL;
+             i += 1;
+           }
+         argv[i] = NULL;
+       }
+      else if (strcmp ("--build-list", argv[i]) == 0)
+       {
+         build_list = TRUE;
+         argv[i] = NULL;
+       }
+      else if (strcmp ("-h", argv[i]) == 0 ||
+              strcmp ("--help", argv[i]) == 0)
+       {
+         print_blurb (stderr, TRUE);
+         argv[i] = NULL;
+         exit (0);
+       }
+      else if (strcmp ("-v", argv[i]) == 0 ||
+              strcmp ("--version", argv[i]) == 0)
+       {
+         print_blurb (stderr, FALSE);
+         argv[i] = NULL;
+         exit (0);
+       }
+      else if (strcmp (argv[i], "--g-fatal-warnings") == 0)
+       {
+         GLogLevelFlags fatal_mask;
+
+         fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
+         fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
+         g_log_set_always_fatal (fatal_mask);
+
+         argv[i] = NULL;
+       }
+    }
+
+  e = 0;
+  for (i = 1; i < argc; i++)
+    {
+      if (e)
+       {
+         if (argv[i])
+           {
+             argv[e++] = argv[i];
+             argv[i] = NULL;
+           }
+       }
+      else if (!argv[i])
+       e = i;
+    }
+  if (e)
+    *argc_p = e;
+}
+
+static void
+print_blurb (FILE    *bout,
+            gboolean print_help)
+{
+  if (!print_help)
+    {
+      fprintf (bout, "%s version ", PRG_NAME);
+      fprintf (bout, "%u.%u.%u", GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
+      fprintf (bout, "\n");
+      fprintf (bout, "%s comes with ABSOLUTELY NO WARRANTY.\n", PRG_NAME);
+      fprintf (bout, "You may redistribute copies of %s under the terms of\n", PRG_NAME);
+      fprintf (bout, "the GNU Lesser General Public License which can be found in the\n");
+      fprintf (bout, "%s source package. Sources, examples and contact\n", PKG_NAME);
+      fprintf (bout, "information are available at %s\n", PKG_HTTP_HOME);
+    }
+  else
+    {
+      fprintf (bout, "Usage: %s [options] [image]\n", PRG_NAME);
+      fprintf (bout, "       %s [options] --build-list [[name image]...]\n", PRG_NAME);
+      fprintf (bout, "  --stream                   generate pixbuf data stream\n");
+      fprintf (bout, "  --struct                   generate GdkPixdata structure\n");
+      fprintf (bout, "  --macros                   generate image size/pixel macros\n");
+      fprintf (bout, "  --rle                      use one byte run-length-encoding\n");
+      fprintf (bout, "  --raw                      provide raw image data copy\n");
+      fprintf (bout, "  --extern                   generate extern symbols\n");
+      fprintf (bout, "  --static                   generate static symbols\n");
+      fprintf (bout, "  --decoder                  provide rle decoder\n");
+      fprintf (bout, "  --name=identifier          C macro/variable name\n");
+      fprintf (bout, "  --build-list              parse (name, image) pairs\n");
+      fprintf (bout, "  -h, --help                 show this help message\n");
+      fprintf (bout, "  -v, --version              print version informations\n");
+      fprintf (bout, "  --g-fatal-warnings         make warnings fatal (abort)\n");
+    }
+}
+
+#include "x"
index 95903b527fb53e841ad7d1ce19c2f26c6b52675f..15f5aa8b82e3ad0da61e928bddf89d3b83d1ac8c 100644 (file)
@@ -78,254 +78,3 @@ gdk_pixbuf_new_from_data (const guchar *data, GdkColorspace colorspace, gboolean
 
        return pixbuf;
 }
-
-static guint32
-read_int (const guchar **p)
-{
-        guint32 num;
-
-        /* Note most significant bytes are first in the byte stream */
-        num =
-          (*p)[3]         |
-          ((*p)[2] << 8)  |
-          ((*p)[1] << 16) |
-          ((*p)[0] << 24);
-
-        *p += 4;
-
-        return num;
-}
-
-static gboolean
-read_bool (const guchar **p)
-{
-        gboolean val = **p != 0;
-        
-        ++(*p);
-        
-        return val;
-}
-
-static GdkPixbuf*
-read_raw_inline (const guchar *data,
-                 gboolean      copy_pixels,
-                 int           length,
-                 GError      **error)
-{
-        GdkPixbuf *pixbuf;
-        const guchar *p = data;
-        guint32 rowstride, width, height, colorspace,
-                n_channels, bits_per_sample;
-        gboolean has_alpha;
-        
-        if (length >= 0 && length < 12) {
-                /* Not enough buffer to hold the width/height/rowstride */
-                g_set_error (error,
-                             GDK_PIXBUF_ERROR,
-                             GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
-                             _("Image data is partially missing"));
-                
-                return NULL;
-        }
-
-        rowstride = read_int (&p);
-        width = read_int (&p);
-        height = read_int (&p);
-
-        if (rowstride < width) {
-                g_set_error (error,
-                             GDK_PIXBUF_ERROR,
-                             GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
-                             _("Image has an incorrect pixel rowstride, perhaps the data was corrupted somehow."));
-                return NULL; /* bad data from untrusted source. */
-        }
-        
-        /* rowstride >= width, so we can trust width */
-        
-        length -= 12;
-
-        /* There's some better way like G_MAXINT/height > rowstride
-         * but I'm not sure it works, so stick to this for now.
-         */
-        if (((double)height) * ((double)rowstride) > (double)G_MAXINT) {
-                g_set_error (error,
-                             GDK_PIXBUF_ERROR,
-                             GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
-                             _("Image size is impossibly large, perhaps the data was corrupted somehow"));
-                
-                return NULL; /* overflow */
-        }
-
-        if (length >= 0 &&
-            length < (height * rowstride + 13)) {
-                /* Not enough buffer to hold the remaining header
-                 * information plus the data.
-                 */
-                g_set_error (error,
-                             GDK_PIXBUF_ERROR,
-                             GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
-                             _("Image data is partially missing, probably it was corrupted somehow."));
-                
-                return NULL;
-        }
-
-        /* Read the remaining 13 bytes of header information */
-            
-        has_alpha = read_bool (&p) != FALSE;
-        colorspace = read_int (&p);
-        n_channels = read_int (&p);
-        bits_per_sample = read_int (&p);
-        
-        if (colorspace != GDK_COLORSPACE_RGB) {
-                g_set_error (error,
-                             GDK_PIXBUF_ERROR,
-                             GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
-                             _("Image has an unknown colorspace code (%d), perhaps the image data was corrupted"),
-                             colorspace);
-                return NULL;
-        }
-
-        if (bits_per_sample != 8) {
-                g_set_error (error,
-                             GDK_PIXBUF_ERROR,
-                             GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
-                             _("Image has an improper number of bits per sample (%d), perhaps the image data was corrupted"),
-                             bits_per_sample);
-                return NULL;
-        }
-        
-        if (has_alpha && n_channels != 4) {
-                g_set_error (error,
-                             GDK_PIXBUF_ERROR,
-                             GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
-                             _("Image has an improper number of channels (%d), perhaps the image data was corrupted"),
-                             n_channels);
-                return NULL;
-        }
-        
-        if (!has_alpha && n_channels != 3) {
-                g_set_error (error,
-                             GDK_PIXBUF_ERROR,
-                             GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
-                             _("Image has an improper number of channels (%d), perhaps the image data was corrupted"),
-                             n_channels);
-                return NULL;
-        }
-        
-        if (copy_pixels) {
-                guchar *pixels;
-                gint dest_rowstride;
-                gint row;
-                
-                pixbuf = gdk_pixbuf_new (colorspace,
-                                         has_alpha, bits_per_sample,
-                                         width, height);
-                
-                if (pixbuf == NULL) {
-                        g_set_error (error,
-                                     GDK_PIXBUF_ERROR,
-                                     GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
-                                     _("Not enough memory to store a %d by %d image; try exiting some applications to free memory."),
-                                     width, height);
-                        return NULL;
-                }
-                
-                pixels = gdk_pixbuf_get_pixels (pixbuf);
-                dest_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
-                
-                for (row = 0; row < height; row++) {
-                        memcpy (pixels, p, rowstride);
-                        pixels += dest_rowstride;
-                        p += rowstride;
-                }
-        } else {
-                pixbuf = gdk_pixbuf_new_from_data (p,
-                                                   colorspace,
-                                                   has_alpha,
-                                                   bits_per_sample,
-                                                   width, height,
-                                                   rowstride,
-                                                   NULL, NULL);
-        }
-        
-        return pixbuf;
-}
-
-/**
- * gdk_pixbuf_new_from_inline:
- * @inline_pixbuf: An inlined GdkPixbuf
- * @copy_pixels: whether to copy the pixels out of the inline data, or to use them in-place
- * @length: length of the inline data
- * @error: return location for error
- *
- * Create a #GdkPixbuf from a custom format invented to store pixbuf
- * data in C program code. This library comes with a program called
- * "make-inline-pixbuf" that can write out a variable definition
- * containing an inlined pixbuf.  This is useful if you want to ship a
- * program with images, but don't want to depend on any external
- * files.
- * 
- * The inline data format contains the pixels in #GdkPixbuf's native
- * format.  Since the inline pixbuf is read-only static data, you
- * don't need to copy it unless you intend to write to it.
- * 
- * If you create a pixbuf from const inline data compiled into your
- * program, it's probably safe to ignore errors, since things will
- * always succeed.  For non-const inline data, you could get out of
- * memory. For untrusted inline data located at runtime, you could
- * have corrupt inline data in addition.
- * 
- * Return value: A newly-created #GdkPixbuf structure with a reference count of
- * 1, or NULL If error is set.
- **/
-GdkPixbuf*
-gdk_pixbuf_new_from_inline   (const guchar *inline_pixbuf,
-                              gboolean      copy_pixels,
-                              int           length,
-                              GError      **error)
-{
-        const guchar *p;
-        GdkPixbuf *pixbuf;
-        GdkPixbufInlineFormat format;
-
-        if (length >= 0 && length < 8) {
-                /* not enough bytes to contain even the magic number
-                 * and format code.
-                 */
-                g_set_error (error,
-                             GDK_PIXBUF_ERROR,
-                             GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
-                             _("Image contained no data."));
-                return NULL;
-        }
-        
-        p = inline_pixbuf;
-
-        if (read_int (&p) != GDK_PIXBUF_INLINE_MAGIC_NUMBER) {
-                g_set_error (error,
-                             GDK_PIXBUF_ERROR,
-                             GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
-                             _("Image isn't in the correct format (inline GdkPixbuf format)"));
-                return NULL;
-        }
-
-        format = read_int (&p);
-
-        switch (format)
-        {
-        case GDK_PIXBUF_INLINE_RAW:
-                pixbuf = read_raw_inline (p, copy_pixels, length - 8, error);
-                break;
-
-        default:
-                g_set_error (error,
-                             GDK_PIXBUF_ERROR,
-                             GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
-                             _("This version of the software is unable to read images with type code %d"),
-                             format);
-                return NULL;
-        }
-
-        return pixbuf;
-}
-
index 0bdae8715de330279c7ae494a69b996b4bd2c57a..4393cbe336f977e6e85b38201f14ae2ff0612688 100644 (file)
@@ -130,16 +130,6 @@ struct _GdkPixbufAnimationIterClass {
       
 \f
 
-#define GDK_PIXBUF_INLINE_MAGIC_NUMBER 0x47646B50 /* 'GdkP' */
-
-typedef enum
-{
-  GDK_PIXBUF_INLINE_RAW = 0,
-  GDK_PIXBUF_INLINE_RLE = 1
-} GdkPixbufInlineFormat;
-
-\f
-
 GdkPixbufAnimation* gdk_pixbuf_non_anim_new (GdkPixbuf *pixbuf);
 
 #endif
index 32ab3a8f469e5e8dc74724337fc66a73cec8d925..2a32c2fa2b6c0bab0cd0f17290964103c79e7812 100644 (file)
@@ -75,6 +75,12 @@ typedef void (* GdkPixbufDestroyNotify) (guchar *pixels, gpointer data);
 #define GDK_PIXBUF_ERROR gdk_pixbuf_error_quark ()
 
 typedef enum {
+        /* stream header corrupt */
+       GDK_PIXBUF_ERROR_HEADER_CORRUPT,
+        /* stream pixel data corrupt */
+       GDK_PIXBUF_ERROR_PIXEL_CORRUPT,
+        /* stream header corrupt */
+       GDK_PIXBUF_ERROR_UNKNOWN_FORMAT,
         /* image data hosed */
         GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
         /* no mem to load image */
@@ -142,13 +148,11 @@ GdkPixbuf *gdk_pixbuf_new_from_data (const guchar *data,
                                     gpointer destroy_fn_data);
 
 GdkPixbuf *gdk_pixbuf_new_from_xpm_data (const char **data);
-
-/* Read an inline pixbuf */
-GdkPixbuf *gdk_pixbuf_new_from_inline   (const guchar *inline_pixbuf,
-                                         gboolean      copy_pixels,
-                                         int           length,
-                                         GError      **error);
-
+GdkPixbuf* gdk_pixbuf_new_from_stream  (gint          stream_length,
+                                        const guint8 *stream,
+                                        gboolean      copy_pixels,
+                                        GError      **error);
+       
 /* Mutations */
 void       gdk_pixbuf_fill              (GdkPixbuf    *pixbuf,
                                          guint32       pixel);
diff --git a/gdk-pixbuf/gdk-pixdata.c b/gdk-pixbuf/gdk-pixdata.c
new file mode 100644 (file)
index 0000000..bc1b6a6
--- /dev/null
@@ -0,0 +1,817 @@
+/* GdkPixbuf library - GdkPixdata - functions for inlined pixbuf handling
+ * Copyright (C) 1999, 2001 Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "gdk-pixdata.h"
+
+#include "gdk-pixbuf-private.h"
+#include "gdk-pixbuf-i18n.h"
+
+
+/* --- functions --- */
+static guint
+pixdata_get_length (const GdkPixdata *pixdata)
+{
+  guint bpp, length;
+
+  if ((pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGB)
+    bpp = 3;
+  else if ((pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGBA)
+    bpp = 4;
+  else
+    return 0;  /* invalid format */
+  switch (pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK)
+    {
+      guint8 *rle_buffer;
+      guint max_length;
+    case GDK_PIXDATA_ENCODING_RAW:
+      length = pixdata->rowstride * pixdata->height;
+      break;
+    case GDK_PIXDATA_ENCODING_RLE:
+      /* need an RLE walk to determine size */
+      max_length = pixdata->rowstride * pixdata->height;
+      rle_buffer = pixdata->pixel_data;
+      length = 0;
+      while (length < max_length)
+       {
+         guint chunk_length = *(rle_buffer++);
+
+         if (chunk_length & 128)
+           {
+             chunk_length = chunk_length - 128;
+             if (!chunk_length)        /* RLE data corrupted */
+               return 0;
+             length += chunk_length * bpp;
+             rle_buffer += bpp;
+           }
+         else
+           {
+             if (!chunk_length)        /* RLE data corrupted */
+               return 0;
+             chunk_length *= bpp;
+             length += chunk_length;
+             rle_buffer += chunk_length;
+           }
+       }
+      length = rle_buffer - pixdata->pixel_data;
+      break;
+    default:
+      length = 0;
+      break;
+    }
+  return length;
+}
+
+/**
+ * gdk_pixdata_serialize:
+ * @pixdata: A valid GdkPixdata structure to serialize
+ * @stream_length_p: Location to store the resulting stream length in
+ *
+ * Serialize a #GdkPixdata structure into a byte stream.
+ * The byte stream consists of a straight forward write out of the
+ * #GdkPixdata fields in network byte order, plus the pixel_data
+ * bytes the structure points to.
+ *
+ * Return value: A newly-allocated string containing the serialized
+ * GdkPixdata structure
+ **/
+guint8* /* free result */
+gdk_pixdata_serialize (const GdkPixdata *pixdata,
+                      guint            *stream_length_p)
+{
+  guint8 *stream, *s;
+  guint32 *istream;
+  guint length;
+
+  /* check args passing */
+  g_return_val_if_fail (pixdata != NULL, NULL);
+  g_return_val_if_fail (stream_length_p != NULL, NULL);
+  /* check pixdata contents */
+  g_return_val_if_fail (pixdata->magic == GDK_PIXBUF_MAGIC_NUMBER, NULL);
+  g_return_val_if_fail (pixdata->width > 0, NULL);
+  g_return_val_if_fail (pixdata->height > 0, NULL);
+  g_return_val_if_fail (pixdata->rowstride >= pixdata->width, NULL);
+  g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGB ||
+                       (pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGBA, NULL);
+  g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_SAMPLE_WIDTH_MASK) == GDK_PIXDATA_SAMPLE_WIDTH_8, NULL);
+  g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK) == GDK_PIXDATA_ENCODING_RAW ||
+                       (pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK) == GDK_PIXDATA_ENCODING_RLE, NULL);
+  g_return_val_if_fail (pixdata->pixel_data != NULL, NULL);
+
+  length = pixdata_get_length (pixdata);
+
+  /* check length field */
+  g_return_val_if_fail (length != 0, NULL);
+  
+  stream = g_malloc (GDK_PIXDATA_HEADER_LENGTH + length);
+  istream = (guint32*) stream;
+
+  /* store header */
+  *istream++ = g_htonl (GDK_PIXBUF_MAGIC_NUMBER);
+  *istream++ = g_htonl (GDK_PIXDATA_HEADER_LENGTH + length);
+  *istream++ = g_htonl (pixdata->pixdata_type);
+  *istream++ = g_htonl (pixdata->rowstride);
+  *istream++ = g_htonl (pixdata->width);
+  *istream++ = g_htonl (pixdata->height);
+
+  /* copy pixel data */
+  s = (guint8*) istream;
+  memcpy (s, pixdata->pixel_data, length);
+  s += length;
+
+  *stream_length_p = GDK_PIXDATA_HEADER_LENGTH + length;
+  g_assert (s - stream == *stream_length_p);   /* paranoid */
+
+  return stream;
+}
+
+#define        return_header_corrupt(error)    { \
+  g_set_error (error, GDK_PIXBUF_ERROR, \
+              GDK_PIXBUF_ERROR_HEADER_CORRUPT, _("Image header corrupt")); \
+  return FALSE; \
+}
+#define        return_invalid_format(error)    { \
+  g_set_error (error, GDK_PIXBUF_ERROR, \
+              GDK_PIXBUF_ERROR_UNKNOWN_FORMAT, _("Image format unknown")); \
+  return FALSE; \
+}
+#define        return_pixel_corrupt(error)     { \
+  g_set_error (error, GDK_PIXBUF_ERROR, \
+              GDK_PIXBUF_ERROR_PIXEL_CORRUPT, _("Image pixel data corrupt")); \
+  return FALSE; \
+}
+
+/**
+ * gdk_pixdata_deserialize:
+ * @pixdata: A GdkPixdata structure to be filled in
+ * @stream_length: Length of the stream used for deserialization
+ * @stream: Stream of bytes containing a serialized pixdata structure
+ * @error: GError location to indicate failures (maybe NULL to ignore errors)
+ *
+ * Deserialize (reconstruct) a #GdkPixdata structure from a byte stream.
+ * The byte stream consists of a straight forward write out of the
+ * #GdkPixdata fields in network byte order, plus the pixel_data
+ * bytes the structure points to.
+ * The pixdata contents are reconstructed byte by byte and are checked
+ * for validity, due to the checks, this function may prematurely abort
+ * with errors, such as #GDK_PIXBUF_ERROR_HEADER_CORRUPT,
+ * #GDK_PIXBUF_ERROR_PIXEL_CORRUPT or #GDK_PIXBUF_ERROR_UNKNOWN_FORMAT.
+ *
+ * Return value: Upon successfull deserialization #TRUE is returned,
+ * #FALSE otherwise
+ **/
+gboolean
+gdk_pixdata_deserialize (GdkPixdata   *pixdata,
+                        guint         stream_length,
+                        const guint8 *stream,
+                        GError      **error)
+{
+  guint32 *istream;
+  guint color_type, sample_width, encoding;
+
+  g_return_val_if_fail (pixdata != NULL, FALSE);
+  if (stream_length < GDK_PIXDATA_HEADER_LENGTH)
+    return_header_corrupt (error);
+  g_return_val_if_fail (stream != NULL, FALSE);
+
+
+  /* deserialize header */
+  istream = (guint32*) stream;
+  pixdata->magic = g_ntohl (*istream++);
+  pixdata->length = g_ntohl (*istream++);
+  if (pixdata->magic != GDK_PIXBUF_MAGIC_NUMBER || pixdata->length < GDK_PIXDATA_HEADER_LENGTH)
+    return_header_corrupt (error);
+  pixdata->pixdata_type = g_ntohl (*istream++);
+  pixdata->rowstride = g_ntohl (*istream++);
+  pixdata->width = g_ntohl (*istream++);
+  pixdata->height = g_ntohl (*istream++);
+  if (pixdata->width < 1 || pixdata->height < 1 ||
+      pixdata->rowstride < pixdata->width)
+    return_header_corrupt (error);
+  color_type = pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK;
+  sample_width = pixdata->pixdata_type & GDK_PIXDATA_SAMPLE_WIDTH_MASK;
+  encoding = pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK;
+  if ((color_type != GDK_PIXDATA_COLOR_TYPE_RGB &&
+       color_type != GDK_PIXDATA_COLOR_TYPE_RGBA) ||
+      sample_width != GDK_PIXDATA_SAMPLE_WIDTH_8 ||
+      (encoding != GDK_PIXDATA_ENCODING_RAW &&
+       encoding != GDK_PIXDATA_ENCODING_RLE))
+    return_invalid_format (error);
+
+  /* deserialize pixel data */
+  if (stream_length < pixdata->length - GDK_PIXDATA_HEADER_LENGTH)
+    return_pixel_corrupt (error);
+  pixdata->pixel_data = (guint8*) istream;
+
+  return TRUE;
+}
+
+static gboolean
+diff2_rgb (guint8 *ip)
+{
+  return ip[0] != ip[3] || ip[1] != ip[4] || ip[2] != ip[5];
+}
+
+static gboolean
+diff2_rgba (guint8 *ip)
+{
+  return ip[0] != ip[4] || ip[1] != ip[5] || ip[2] != ip[6] || ip[3] != ip[7];
+}
+
+static guint8*                 /* dest buffer bound */
+rl_encode_rgbx (guint8 *bp,    /* dest buffer */
+               guint8 *ip,     /* image pointer */
+               guint8 *limit,  /* image upper bound */
+               guint   n_ch)
+{
+  gboolean (*diff2_pix) (guint8 *) = n_ch > 3 ? diff2_rgba : diff2_rgb;
+  guint8 *ilimit = limit - n_ch;
+
+  while (ip < limit)
+    {
+      g_assert (ip < ilimit); /* paranoid */
+
+      if (diff2_pix (ip))
+       {
+         guint8 *s_ip = ip;
+         guint l = 1;
+
+         ip += n_ch;
+         while (l < 127 && ip < ilimit && diff2_pix (ip))
+           { ip += n_ch; l += 1; }
+         if (ip == ilimit && l < 127)
+           { ip += n_ch; l += 1; }
+         *(bp++) = l;
+         memcpy (bp, s_ip, l * n_ch);
+         bp += l * n_ch;
+       }
+      else
+       {
+         guint l = 2;
+
+         ip += n_ch;
+         while (l < 127 && ip < ilimit && !diff2_pix (ip))
+           { ip += n_ch; l += 1; }
+         *(bp++) = l | 128;
+         memcpy (bp, ip, n_ch);
+         ip += n_ch;
+         bp += n_ch;
+       }
+      if (ip == ilimit)
+       {
+         *(bp++) = 1;
+         memcpy (bp, ip, n_ch);
+         ip += n_ch;
+         bp += n_ch;
+       }
+    }
+
+  return bp;
+}
+
+gpointer
+gdk_pixdata_from_pixbuf (GdkPixdata      *pixdata,
+                        const GdkPixbuf *pixbuf,
+                        gboolean         use_rle)
+{
+  gpointer free_me = NULL;
+  guint height, rowstride, encoding, bpp, length;
+  guint8 *img_buffer;
+
+  g_return_val_if_fail (pixdata != NULL, NULL);
+  g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
+  g_return_val_if_fail (pixbuf->bits_per_sample == 8, NULL);
+  g_return_val_if_fail ((pixbuf->n_channels == 3 && !pixbuf->has_alpha) ||
+                       (pixbuf->n_channels == 4 && pixbuf->has_alpha), NULL);
+  g_return_val_if_fail (pixbuf->rowstride >= pixbuf->width, NULL);
+
+  height = pixbuf->height;
+  rowstride = pixbuf->rowstride;
+  encoding = use_rle ? GDK_PIXDATA_ENCODING_RLE : GDK_PIXDATA_ENCODING_RAW;
+  bpp = pixbuf->has_alpha ? 4 : 3;
+
+  if (encoding == GDK_PIXDATA_ENCODING_RLE)
+    {
+      guint pad, n_bytes = rowstride * height;
+      guint8 *img_buffer_end, *data;
+
+      pad = rowstride;
+      pad = MAX (pad, 130 + n_bytes / 127);
+      data = g_new (guint8, pad + n_bytes);
+      free_me = data;
+      img_buffer = data;
+      img_buffer_end = rl_encode_rgbx (img_buffer,
+                                      pixbuf->pixels, pixbuf->pixels + n_bytes,
+                                      bpp);
+      length = img_buffer_end - img_buffer;
+    }
+  else
+    {
+      img_buffer = pixbuf->pixels;
+      length = rowstride * height;
+    }
+
+  pixdata->magic = GDK_PIXBUF_MAGIC_NUMBER;
+  pixdata->length = GDK_PIXDATA_HEADER_LENGTH + length;
+  pixdata->pixdata_type = pixbuf->has_alpha ? GDK_PIXDATA_COLOR_TYPE_RGBA : GDK_PIXDATA_COLOR_TYPE_RGB;
+  pixdata->pixdata_type |= GDK_PIXDATA_SAMPLE_WIDTH_8;
+  pixdata->pixdata_type |= encoding;
+  pixdata->rowstride = rowstride;
+  pixdata->width = pixbuf->width;
+  pixdata->height = height;
+  pixdata->pixel_data = img_buffer;
+
+  return free_me;
+}
+
+GdkPixbuf*
+gdk_pixbuf_from_pixdata (const GdkPixdata *pixdata,
+                        gboolean          copy_pixels,
+                        GError          **error)
+{
+  guint encoding, bpp;
+  guint8 *data = NULL;
+
+  g_return_val_if_fail (pixdata != NULL, NULL);
+  g_return_val_if_fail (pixdata->width > 0, NULL);
+  g_return_val_if_fail (pixdata->height > 0, NULL);
+  g_return_val_if_fail (pixdata->rowstride >= pixdata->width, NULL);
+  g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGB ||
+                       (pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGBA, NULL);
+  g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_SAMPLE_WIDTH_MASK) == GDK_PIXDATA_SAMPLE_WIDTH_8, NULL);
+  g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK) == GDK_PIXDATA_ENCODING_RAW ||
+                       (pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK) == GDK_PIXDATA_ENCODING_RLE, NULL);
+  g_return_val_if_fail (pixdata->pixel_data != NULL, NULL);
+
+  bpp = (pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGB ? 3 : 4;
+  encoding = pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK;
+  if (encoding == GDK_PIXDATA_ENCODING_RLE)
+    copy_pixels = TRUE;
+  if (copy_pixels)
+    {
+      data = g_try_malloc (pixdata->rowstride * pixdata->height);
+      if (!data)
+       {
+         g_set_error (error, GDK_PIXBUF_ERROR,
+                      GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
+                      _("failed to allocate imagge buffer of %u bytes"),
+                      pixdata->rowstride * pixdata->height);
+         return NULL;
+       }
+    }
+  if (encoding == GDK_PIXDATA_ENCODING_RLE)
+    {
+      const guint8 *rle_buffer = pixdata->pixel_data;
+      guint8 *image_buffer = data;
+      guint8 *image_limit = data + pixdata->rowstride * pixdata->height;
+      gboolean check_overrun = FALSE;
+
+      while (image_buffer < image_limit)
+       {
+         guint length = *(rle_buffer++);
+
+         if (length & 128)
+           {
+             length = length - 128;
+             check_overrun = image_buffer + length * bpp > image_limit;
+             if (check_overrun)
+               length = (image_limit - image_buffer) / bpp;
+             if (bpp < 4)      /* RGB */
+               do
+                 {
+                   memcpy (image_buffer, rle_buffer, 3);
+                   image_buffer += 3;
+                 }
+               while (--length);
+             else              /* RGBA */
+               do
+                 {
+                   memcpy (image_buffer, rle_buffer, 4);
+                   image_buffer += 4;
+                 }
+               while (--length);
+             rle_buffer += bpp;
+           }
+         else
+           {
+             length *= bpp;
+             check_overrun = image_buffer + length > image_limit;
+             if (check_overrun)
+               length = image_limit - image_buffer;
+             memcpy (image_buffer, rle_buffer, length);
+             image_buffer += length;
+             rle_buffer += length;
+           }
+       }
+      if (check_overrun)
+       {
+         g_free (data);
+         g_set_error (error, GDK_PIXBUF_ERROR,
+                      GDK_PIXBUF_ERROR_PIXEL_CORRUPT,
+                      _("Image pixel data corrupt"));
+         return NULL;
+       }
+    }
+  else if (copy_pixels)
+    memcpy (data, pixdata->pixel_data, pixdata->rowstride * pixdata->height);
+  else
+    data = pixdata->pixel_data;
+
+  return gdk_pixbuf_new_from_data (data, GDK_COLORSPACE_RGB,
+                                  (pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGBA,
+                                  8, pixdata->width, pixdata->height, pixdata->rowstride,
+                                  copy_pixels ? (GdkPixbufDestroyNotify) g_free : NULL, data);
+}
+
+typedef struct {
+  /* config */
+  gboolean     dump_stream;
+  gboolean     dump_struct;
+  gboolean     dump_macros;
+  gboolean     dump_gtypes;
+  gboolean     dump_rle_decoder;
+  const gchar *static_prefix;
+  const gchar *const_prefix;
+  /* runtime */
+  GString *gstring;
+  guint    pos;
+  gboolean pad;
+} CSourceData;
+
+static inline void
+save_uchar (CSourceData *cdata,
+           guint8       d)
+{
+  GString *gstring = cdata->gstring;
+
+  if (cdata->pos > 70)
+    {
+      if (cdata->dump_struct || cdata->dump_stream)
+       {
+         g_string_append (gstring, "\"\n  \"");
+         cdata->pos = 3;
+         cdata->pad = FALSE;
+       }
+      if (cdata->dump_macros)
+       {
+         g_string_append (gstring, "\" \\\n  \"");
+         cdata->pos = 3;
+         cdata->pad = FALSE;
+       }
+    }
+  if (d < 33 || d > 126)
+    {
+      g_string_printfa (gstring, "\\%o", d);
+      cdata->pos += 1 + 1 + (d > 7) + (d > 63);
+      cdata->pad = d < 64;
+      return;
+    }
+  if (d == '\\')
+    {
+      g_string_append (gstring, "\\\\");
+      cdata->pos += 2;
+    }
+  else if (d == '"')
+    {
+      g_string_append (gstring, "\\\"");
+      cdata->pos += 2;
+    }
+  else if (cdata->pad && d >= '0' && d <= '9')
+    {
+      g_string_append (gstring, "\"\"");
+      g_string_append_c (gstring, d);
+      cdata->pos += 3;
+    }
+  else
+    {
+      g_string_append_c (gstring, d);
+      cdata->pos += 1;
+    }
+  cdata->pad = FALSE;
+  return;
+}
+
+static inline void
+save_rle_decoder (GString     *gstring,
+                 const gchar *macro_name,
+                 const gchar *s_uint,
+                 const gchar *s_uint_8,
+                 guint        n_ch)
+{
+  g_string_printfa (gstring, "#define %s_RUN_LENGTH_DECODE(image_buf, rle_data, size, bpp) do \\\n",
+                   macro_name);
+  g_string_printfa (gstring, "{ %s __bpp; %s *__ip; const %s *__il, *__rd; \\\n", s_uint, s_uint_8, s_uint_8);
+  g_string_printfa (gstring, "  __bpp = (bpp); __ip = (image_buf); __il = __ip + (size) * __bpp; \\\n");
+  
+  g_string_printfa (gstring, "  __rd = (rle_data); if (__bpp > 3) { /* RGBA */ \\\n");
+  
+  g_string_printfa (gstring, "    while (__ip < __il) { %s __l = *(__rd++); \\\n", s_uint);
+  g_string_printfa (gstring, "      if (__l & 128) { __l = __l - 128; \\\n");
+  g_string_printfa (gstring, "        do { memcpy (__ip, __rd, 4); __ip += 4; } while (--__l); __rd += 4; \\\n");
+  g_string_printfa (gstring, "      } else { __l *= 4; memcpy (__ip, __rd, __l); \\\n");
+  g_string_printfa (gstring, "               __ip += __l; __rd += __l; } } \\\n");
+  
+  g_string_printfa (gstring, "  } else { /* RGB */ \\\n");
+  
+  g_string_printfa (gstring, "    while (__ip < __il) { %s __l = *(__rd++); \\\n", s_uint);
+  g_string_printfa (gstring, "      if (__l & 128) { __l = __l - 128; \\\n");
+  g_string_printfa (gstring, "        do { memcpy (__ip, __rd, 3); __ip += 3; } while (--__l); __rd += 3; \\\n");
+  g_string_printfa (gstring, "      } else { __l *= 3; memcpy (__ip, __rd, __l); \\\n");
+  g_string_printfa (gstring, "               __ip += __l; __rd += __l; } } \\\n");
+  
+  g_string_printfa (gstring, "  } } while (0)\n");
+}
+
+GString*
+gdk_pixdata_to_csource (GdkPixdata        *pixdata,
+                       const gchar       *name,
+                       GdkPixdataDumpType dump_type)
+{
+  CSourceData cdata = { 0, };
+  gchar *s_uint_8, *s_uint_32, *s_uint, *s_char, *s_null;
+  guint bpp, width, height, rowstride;
+  gboolean rle_encoded;
+  gchar *macro_name;
+  guint8 *img_buffer, *img_buffer_end, *stream;
+  guint stream_length;
+  GString *gstring;
+  
+  /* check args passing */
+  g_return_val_if_fail (pixdata != NULL, NULL);
+  g_return_val_if_fail (name != NULL, NULL);
+  /* check pixdata contents */
+  g_return_val_if_fail (pixdata->magic == GDK_PIXBUF_MAGIC_NUMBER, NULL);
+  g_return_val_if_fail (pixdata->width > 0, NULL);
+  g_return_val_if_fail (pixdata->height > 0, NULL);
+  g_return_val_if_fail (pixdata->rowstride >= pixdata->width, NULL);
+  g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGB ||
+                       (pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGBA, NULL);
+  g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_SAMPLE_WIDTH_MASK) == GDK_PIXDATA_SAMPLE_WIDTH_8, NULL);
+  g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK) == GDK_PIXDATA_ENCODING_RAW ||
+                       (pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK) == GDK_PIXDATA_ENCODING_RLE, NULL);
+  g_return_val_if_fail (pixdata->pixel_data != NULL, NULL);
+
+  img_buffer = pixdata->pixel_data;
+  if (pixdata->length < 1)
+    img_buffer_end = img_buffer + pixdata_get_length (pixdata);
+  else
+    img_buffer_end = img_buffer + pixdata->length - GDK_PIXDATA_HEADER_LENGTH;
+  g_return_val_if_fail (img_buffer < img_buffer_end, NULL);
+
+  bpp = (pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGB ? 3 : 4;
+  width = pixdata->width;
+  height = pixdata->height;
+  rowstride = pixdata->rowstride;
+  rle_encoded = (pixdata->pixdata_type & GDK_PIXDATA_ENCODING_RLE) > 0;
+  macro_name = g_strdup (name);
+  g_strup (macro_name);
+
+  cdata.dump_macros = (dump_type & GDK_PIXDATA_DUMP_MACROS) > 0;
+  cdata.dump_struct = (dump_type & GDK_PIXDATA_DUMP_PIXDATA_STRUCT) > 0;
+  cdata.dump_stream = !cdata.dump_macros && !cdata.dump_struct;
+  g_return_val_if_fail (cdata.dump_macros + cdata.dump_struct + cdata.dump_stream == 1, NULL);
+
+  cdata.dump_gtypes = (dump_type & GDK_PIXDATA_DUMP_CTYPES) == 0;
+  cdata.dump_rle_decoder = (dump_type & GDK_PIXDATA_DUMP_RLE_DECODER) > 0;
+  cdata.static_prefix = (dump_type & GDK_PIXDATA_DUMP_STATIC) ? "static " : "";
+  cdata.const_prefix = (dump_type & GDK_PIXDATA_DUMP_CONST) ? "const " : "";
+  gstring = g_string_new ("");
+  cdata.gstring = gstring;
+
+  if (!cdata.dump_macros && cdata.dump_gtypes)
+    {
+      s_uint_8 =  "guint8 ";
+      s_uint_32 = "guint32";
+      s_uint =    "guint  ";
+      s_char =    "gchar  ";
+      s_null =    "NULL";
+    }
+  else if (!cdata.dump_macros)
+    {
+      s_uint_8 =  "unsigned char";
+      s_uint_32 = "unsigned int ";
+      s_uint =    "unsigned int ";
+      s_char =    "char         ";
+      s_null =    "(char*) 0";
+    }
+  else if (cdata.dump_macros && cdata.dump_gtypes)
+    {
+      s_uint_8 =  "guint8";
+      s_uint_32 = "guint32";
+      s_uint  =   "guint";
+      s_char =    "gchar";
+      s_null =    "NULL";
+    }
+  else /* cdata.dump_macros && !cdata.dump_gtypes */
+    {
+      s_uint_8 =  "unsigned char";
+      s_uint_32 = "unsigned int";
+      s_uint =    "unsigned int";
+      s_char =    "char";
+      s_null =    "(char*) 0";
+    }
+
+  /* initial comment
+   */
+  g_string_printfa (gstring,
+                   "/* GdkPixbuf %s C-Source image dump %s*/\n\n",
+                   bpp > 3 ? "RGBA" : "RGB",
+                   rle_encoded ? "1-byte-run-length-encoded " : "");
+
+  /* dump RLE decoder for structures
+   */
+  if (cdata.dump_rle_decoder && cdata.dump_struct)
+    save_rle_decoder (gstring,
+                     macro_name,
+                     cdata.dump_gtypes ? "guint" : "unsigned int",
+                     cdata.dump_gtypes ? "guint8" : "unsigned char",
+                     bpp);
+
+  /* format & size blurbs
+   */
+  if (cdata.dump_macros)
+    {
+      g_string_printfa (gstring, "#define %s_ROWSTRIDE (%u)\n",
+                       macro_name, rowstride);
+      g_string_printfa (gstring, "#define %s_WIDTH (%u)\n",
+                       macro_name, width);
+      g_string_printfa (gstring, "#define %s_HEIGHT (%u)\n",
+                       macro_name, height);
+      g_string_printfa (gstring, "#define %s_BYTES_PER_PIXEL (%u) /* 3:RGB, 4:RGBA */\n",
+                       macro_name, bpp);
+    }
+  if (cdata.dump_struct)
+    {
+      g_string_printfa (gstring, "%s%sGdkPixdata %s = {\n",
+                       cdata.static_prefix, cdata.const_prefix, name);
+      g_string_printfa (gstring, "  0x%x, /* Pixbuf magic: 'GdkP' */\n",
+                       GDK_PIXBUF_MAGIC_NUMBER);
+      g_string_printfa (gstring, "  %u + %u, /* header length + pixel_data length */\n",
+                       GDK_PIXDATA_HEADER_LENGTH,
+                       rle_encoded ? img_buffer_end - img_buffer : rowstride * height);
+      g_string_printfa (gstring, "  0x%x, /* pixdata_type */\n",
+                       pixdata->pixdata_type);
+      g_string_printfa (gstring, "  %u, /* rowstride */\n",
+                       rowstride);
+      g_string_printfa (gstring, "  %u, /* width */\n",
+                       width);
+      g_string_printfa (gstring, "  %u, /* height */\n",
+                       height);
+      g_string_printfa (gstring, "  /* pixel_data: */\n");
+    }
+  if (cdata.dump_stream)
+    {
+      guint pix_length = img_buffer_end - img_buffer;
+      
+      stream = gdk_pixdata_serialize (pixdata, &stream_length);
+      img_buffer_end = stream + stream_length;
+
+      g_string_printfa (gstring, "%s%s%s %s[] = \n",
+                       cdata.static_prefix, cdata.const_prefix,
+                       cdata.dump_gtypes ? "guint8" : "unsigned char",
+                       name);
+      g_string_printfa (gstring, "( \"\"\n  /* Pixbuf magic (0x%x) */\n  \"",
+                       GDK_PIXBUF_MAGIC_NUMBER);
+      cdata.pos = 3;
+      save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
+      save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
+      g_string_printfa (gstring, "\"\n  /* length: header (%u) + pixel_data (%u) */\n  \"",
+                       GDK_PIXDATA_HEADER_LENGTH,
+                       rle_encoded ? pix_length : rowstride * height);
+      cdata.pos = 3;
+      save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
+      save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
+      g_string_printfa (gstring, "\"\n  /* pixdata_type (0x%x) */\n  \"",
+                       pixdata->pixdata_type);
+      cdata.pos = 3;
+      save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
+      save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
+      g_string_printfa (gstring, "\"\n  /* rowstride (%u) */\n  \"",
+                       rowstride);
+      cdata.pos = 3;
+      save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
+      save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
+      g_string_printfa (gstring, "\"\n  /* width (%u) */\n  \"", width);
+      cdata.pos = 3;
+      save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
+      save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
+      g_string_printfa (gstring, "\"\n  /* height (%u) */\n  \"", height);
+      cdata.pos = 3;
+      save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
+      save_uchar (&cdata, *stream++); save_uchar (&cdata, *stream++);
+      g_string_printfa (gstring, "\"\n  /* pixel_data: */\n");
+      img_buffer = stream;
+    }
+
+  /* pixel_data intro
+   */
+  if (cdata.dump_macros)
+    {
+      g_string_printfa (gstring, "#define %s_%sPIXEL_DATA ((%s*) \\\n",
+                       macro_name,
+                       rle_encoded ? "RLE_" : "",
+                       s_uint_8);
+      g_string_printfa (gstring, "  \"");
+      cdata.pos = 2;
+    }
+  if (cdata.dump_struct)
+    {
+      g_string_printfa (gstring, "  \"");
+      cdata.pos = 3;
+    }
+  if (cdata.dump_stream)
+    {
+      g_string_printfa (gstring, "  \"");
+      cdata.pos = 3;
+    }
+    
+  /* pixel_data
+   */
+  do
+    save_uchar (&cdata, *img_buffer++);
+  while (img_buffer < img_buffer_end);
+
+  /* pixel_data trailer
+   */
+  if (cdata.dump_macros)
+    g_string_printfa (gstring, "\")\n\n");
+  if (cdata.dump_struct)
+    g_string_printfa (gstring, "\",\n};\n\n");
+  if (cdata.dump_stream)
+    g_string_printfa (gstring, "\");\n\n");
+
+  /* dump RLE decoder for macros
+   */
+  if (cdata.dump_rle_decoder && cdata.dump_macros)
+    save_rle_decoder (gstring,
+                     macro_name,
+                     cdata.dump_gtypes ? "guint" : "unsigned int",
+                     cdata.dump_gtypes ? "guint8" : "unsigned char",
+                     bpp);
+
+  /* cleanup
+   */
+  g_free (macro_name);
+  
+  return gstring;
+}
+
+/**
+ * gdk_pixbuf_new_from_stream:
+ * @stream_length: Length in bytes of the @stream argument
+ * @stream: Byte stream containing a serialized GdkPixdata structure
+ * @copy_pixels: Whether to copy the pixels data, or keep direct pointers into the
+ *               stream data for the resulting pixbuf
+ * @error: GError return location, may be NULL to ignore errors
+ *
+ * Create a #GdkPixbuf from a serialized GdkPixdata structure.
+ * Gtk+ ships with a program called gdk-pixbuf-csource which allowes
+ * for conversion of #GdkPixbufs into various kinds of C sources.
+ * This is useful if you want to ship a program with images, but
+ * don't want to depend on any external files.
+ *
+ * Since the inline pixbuf is read-only static data, you
+ * don't need to copy it unless you intend to write to it.
+ * For deserialization of streams that are run length encoded, the
+ * decoded data is always a copy of the input stream.
+ *
+ * If you create a pixbuf from const inline data compiled into your
+ * program, it's probably safe to ignore errors, since things will
+ * always succeed.  For non-const inline data, you could get out of
+ * memory. For untrusted inline data located at runtime, you could
+ * have corrupt inline data in addition.
+ *
+ * Return value: A newly-created #GdkPixbuf structure with a reference count of
+ * 1, or NULL If error is set.
+ **/
+GdkPixbuf*
+gdk_pixbuf_new_from_stream (gint          stream_length,
+                           const guint8 *stream,
+                           gboolean      copy_pixels,
+                           GError      **error)
+{
+  GdkPixdata pixdata;
+
+  if (stream_length != -1)
+    g_return_val_if_fail (stream_length > GDK_PIXDATA_HEADER_LENGTH, NULL);
+  g_return_val_if_fail (stream != NULL, NULL);
+
+  if (!gdk_pixdata_deserialize (&pixdata, stream_length, stream, error))
+    return NULL;
+
+  return gdk_pixbuf_from_pixdata (&pixdata, copy_pixels, error);
+}
diff --git a/gdk-pixbuf/gdk-pixdata.h b/gdk-pixbuf/gdk-pixdata.h
new file mode 100644 (file)
index 0000000..92ef3ec
--- /dev/null
@@ -0,0 +1,100 @@
+/* GdkPixbuf library - GdkPixdata - functions for inlined pixbuf handling
+ * Copyright (C) 1999, 2001 Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __GDK_PIXDATA_H__
+#define __GDK_PIXDATA_H__
+
+#include        <gdk-pixbuf/gdk-pixbuf.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GDK_PIXBUF_MAGIC_NUMBER (0x47646b50)    /* 'GdkP' */
+
+typedef enum
+{
+  /* colorspace + alpha */
+  GDK_PIXDATA_COLOR_TYPE_RGB    = 0x01,
+  GDK_PIXDATA_COLOR_TYPE_RGBA   = 0x02,
+  GDK_PIXDATA_COLOR_TYPE_MASK   = 0xff,
+  /* width, support 8bits only currently */
+  GDK_PIXDATA_SAMPLE_WIDTH_8    = 0x01 << 16,
+  GDK_PIXDATA_SAMPLE_WIDTH_MASK = 0x0f << 16,
+  /* encoding */
+  GDK_PIXDATA_ENCODING_RAW      = 0x01 << 24,
+  GDK_PIXDATA_ENCODING_RLE      = 0x02 << 24,
+  GDK_PIXDATA_ENCODING_MASK     = 0x0f << 24
+} GdkPixdataType;
+
+typedef struct _GdkPixdata GdkPixdata;
+struct _GdkPixdata
+{
+  guint32 magic;        /* GDK_PIXBUF_MAGIC_NUMBER */
+  gint32  length;       /* <1 to disable length checks, otherwise:
+                        * GDK_PIXDATA_HEADER_LENGTH + pixel_data length
+                        */
+  guint32 pixdata_type; /* GdkPixdataType */
+  guint32 rowstride;    /* maybe 0 to indicate non-padded data */
+  guint32 width;
+  guint32 height;
+  guint8 *pixel_data;
+};
+#define        GDK_PIXDATA_HEADER_LENGTH       (4 + 4 + 4 + 4 + 4 + 4)
+
+/* the returned stream is plain htonl of GdkPixdata members + pixel_data */
+guint8*                gdk_pixdata_serialize   (const GdkPixdata       *pixdata,
+                                        guint                  *stream_length_p);
+gboolean       gdk_pixdata_deserialize (GdkPixdata             *pixdata,
+                                        guint                   stream_length,
+                                        const guint8           *stream,
+                                        GError                **error);
+gpointer       gdk_pixdata_from_pixbuf (GdkPixdata             *pixdata,
+                                        const GdkPixbuf        *pixbuf,
+                                        gboolean                use_rle);
+GdkPixbuf*     gdk_pixbuf_from_pixdata (const GdkPixdata       *pixdata,
+                                        gboolean                copy_pixels,
+                                        GError                **error);
+typedef enum
+{
+  /* type of source to save */
+  GDK_PIXDATA_DUMP_PIXDATA_STREAM      = 0,
+  GDK_PIXDATA_DUMP_PIXDATA_STRUCT      = 1,
+  GDK_PIXDATA_DUMP_MACROS              = 2,
+  /* type of variables to use */
+  GDK_PIXDATA_DUMP_GTYPES              = 0,
+  GDK_PIXDATA_DUMP_CTYPES              = 1 << 8,
+  GDK_PIXDATA_DUMP_STATIC              = 1 << 9,
+  GDK_PIXDATA_DUMP_CONST               = 1 << 10,
+  /* save RLE decoder macro? */
+  GDK_PIXDATA_DUMP_RLE_DECODER         = 1 << 16,
+} GdkPixdataDumpType;
+  
+
+GString*       gdk_pixdata_to_csource  (GdkPixdata             *pixdata,
+                                        const gchar            *name,
+                                        GdkPixdataDumpType      dump_type);
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GDK_PIXDATA_H__ */
index ae80f3180ba5c0d61b2610d5775b8b82731a9c1b..64c57b33b52c54bf409f3b18cb8d6415b06108f3 100644 (file)
@@ -335,7 +335,7 @@ sized_icon_set_from_inline (const guchar *inline_data,
 
   set = gtk_icon_set_new ();
 
-  source.pixbuf = gdk_pixbuf_new_from_inline (inline_data, FALSE, -1, NULL);
+  source.pixbuf = gdk_pixbuf_new_from_stream (-1, inline_data, FALSE, NULL);
 
   g_assert (source.pixbuf);
 
@@ -361,7 +361,7 @@ sized_with_fallback_icon_set_from_inline (const guchar *fallback_data,
 
   set = gtk_icon_set_new ();
 
-  source.pixbuf = gdk_pixbuf_new_from_inline (inline_data, FALSE, -1, NULL);
+  source.pixbuf = gdk_pixbuf_new_from_stream (-1, inline_data, FALSE, NULL);
 
   g_assert (source.pixbuf);
 
@@ -371,7 +371,7 @@ sized_with_fallback_icon_set_from_inline (const guchar *fallback_data,
   
   source.any_size = TRUE;
 
-  source.pixbuf = gdk_pixbuf_new_from_inline (fallback_data, FALSE, -1, NULL);
+  source.pixbuf = gdk_pixbuf_new_from_stream (-1, fallback_data, FALSE, NULL);
 
   g_assert (source.pixbuf);
 
@@ -393,7 +393,7 @@ unsized_icon_set_from_inline (const guchar *inline_data)
 
   set = gtk_icon_set_new ();
 
-  source.pixbuf = gdk_pixbuf_new_from_inline (inline_data, FALSE, -1, NULL);
+  source.pixbuf = gdk_pixbuf_new_from_stream (-1, inline_data, FALSE, NULL);
 
   g_assert (source.pixbuf);
 
@@ -1090,7 +1090,7 @@ render_fallback_image (GtkStyle          *style,
   static GtkIconSource fallback_source = { NULL, NULL, 0, 0, 0, TRUE, TRUE, TRUE };
 
   if (fallback_source.pixbuf == NULL)
-    fallback_source.pixbuf = gdk_pixbuf_new_from_inline (MISSING_IMAGE_INLINE, FALSE, -1, NULL);
+    fallback_source.pixbuf = gdk_pixbuf_new_from_stream (-1, MISSING_IMAGE_INLINE, FALSE, NULL);
   
   return gtk_style_render_icon (style,
                                 &fallback_source,
index ff3b8cdd4fb0d3742575222536ef7e16cadbb616..b47970e76039dc0d9a9529f3e7d91696c56c8925 100644 (file)
@@ -228,8 +228,8 @@ gtk_item_factory_class_init (GtkItemFactoryClass  *class)
   quark_type_toggle_item       = g_quark_from_static_string ("<ToggleItem>");
   quark_type_image_item         = g_quark_from_static_string ("<ImageItem>");
   quark_type_stock_item         = g_quark_from_static_string ("<StockItem>");
-  quark_type_tearoff_item      = g_quark_from_static_string ("<Tearoff>");
   quark_type_separator_item    = g_quark_from_static_string ("<Separator>");
+  quark_type_tearoff_item      = g_quark_from_static_string ("<Tearoff>");
   quark_type_branch            = g_quark_from_static_string ("<Branch>");
   quark_type_last_branch       = g_quark_from_static_string ("<LastBranch>");
 }
@@ -1228,14 +1228,14 @@ gtk_item_factory_create_item (GtkItemFactory         *ifactory,
     gtk_radio_menu_item_set_group (GTK_RADIO_MENU_ITEM (widget), radio_group);
   if (GTK_IS_CHECK_MENU_ITEM (widget))
     gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (widget), TRUE);
-  if (GTK_IS_IMAGE_MENU_ITEM (widget))
+  if (type_id == quark_type_image_item)
     {
       GdkPixbuf *pixbuf = NULL;
       image = NULL;
 
-      pixbuf = gdk_pixbuf_new_from_inline (entry->extra_data,
+      pixbuf = gdk_pixbuf_new_from_stream (-1,
+                                          entry->extra_data,
                                           FALSE,
-                                          entry->extra_data2,
                                           NULL);
 
       if (pixbuf)
index 536d4ea7bebdb052a14a5307f2ebfcffcda0f2e6..5132f9d1dba4bcdf9211cb149a7f1ea6111b8cf2 100644 (file)
@@ -99,22 +99,24 @@ struct _GtkItemFactoryEntry
    * ""                        -> "<Item>"
    * "<Title>"         -> create a title item
    * "<Item>"          -> create a simple item
+   * "<ImageItem>"     -> create an item holding an image
+   * "<StockItem>"     -> create an item holding a stock image
    * "<CheckItem>"     -> create a check item
    * "<ToggleItem>"    -> create a toggle item
    * "<RadioItem>"     -> create a radio item
    * <path>            -> path of a radio item to link against
    * "<Separator>"     -> create a separator
+   * "<Tearoff>"       -> create a tearoff separator
    * "<Branch>"                -> create an item to hold sub items
    * "<LastBranch>"    -> create a right justified item to hold sub items
    */
   gchar                 *item_type;
 
   /* Extra data for some item types:
-   *  ImageItem  -> pointer to inline pixbuf + inline pixbuf length
+   *  ImageItem  -> pointer to inlined pixbuf stream
    *  StockItem  -> name of stock item
    */
-  gpointer extra_data;
-  guint    extra_data2;
+  gconstpointer extra_data;
 };
 
 struct _GtkItemFactoryItem