diff options
author | Tim Janik <timj@gtk.org> | 2001-06-26 20:56:32 +0000 |
---|---|---|
committer | Tim Janik <timj@src.gnome.org> | 2001-06-26 20:56:32 +0000 |
commit | d4f0062f5e9c8a3fe8e4c7ba0daff28b5e76f69a (patch) | |
tree | cbec6c1be2f06e4fbe13852147b9554e02d70f83 | |
parent | 3704749e94a270a7101dce94d498c3649ceb6c3c (diff) | |
download | gtk+-d4f0062f5e9c8a3fe8e4c7ba0daff28b5e76f69a.tar.gz |
use gdk_pixbuf_new_from_stream(). fixed up item factory so inlined pixbufs
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.
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | ChangeLog.pre-2-0 | 6 | ||||
-rw-r--r-- | ChangeLog.pre-2-10 | 6 | ||||
-rw-r--r-- | ChangeLog.pre-2-2 | 6 | ||||
-rw-r--r-- | ChangeLog.pre-2-4 | 6 | ||||
-rw-r--r-- | ChangeLog.pre-2-6 | 6 | ||||
-rw-r--r-- | ChangeLog.pre-2-8 | 6 | ||||
-rw-r--r-- | demos/Makefile.am | 8 | ||||
-rw-r--r-- | demos/testpixbuf.c | 20 | ||||
-rw-r--r-- | docs/reference/gdk-pixbuf/tmpl/creating.sgml | 12 | ||||
-rw-r--r-- | docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf-unused.sgml | 11 | ||||
-rw-r--r-- | docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf.sgml | 3 | ||||
-rw-r--r-- | docs/reference/gtk/tmpl/gtkitemfactory.sgml | 1 | ||||
-rw-r--r-- | gdk-pixbuf/ChangeLog | 16 | ||||
-rw-r--r-- | gdk-pixbuf/Makefile.am | 36 | ||||
-rw-r--r-- | gdk-pixbuf/gdk-pixbuf-csource.c | 286 | ||||
-rw-r--r-- | gdk-pixbuf/gdk-pixbuf-data.c | 251 | ||||
-rw-r--r-- | gdk-pixbuf/gdk-pixbuf-private.h | 10 | ||||
-rw-r--r-- | gdk-pixbuf/gdk-pixbuf.h | 18 | ||||
-rw-r--r-- | gdk-pixbuf/gdk-pixdata.c | 817 | ||||
-rw-r--r-- | gdk-pixbuf/gdk-pixdata.h | 100 | ||||
-rw-r--r-- | gtk/gtkiconfactory.c | 10 | ||||
-rw-r--r-- | gtk/gtkitemfactory.c | 8 | ||||
-rw-r--r-- | gtk/gtkitemfactory.h | 8 |
24 files changed, 1342 insertions, 315 deletions
@@ -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: diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index c344a4091f..92498d5b78 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -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: diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index c344a4091f..92498d5b78 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -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: diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index c344a4091f..92498d5b78 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -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: diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index c344a4091f..92498d5b78 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -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: diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index c344a4091f..92498d5b78 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -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: diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index c344a4091f..92498d5b78 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -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: diff --git a/demos/Makefile.am b/demos/Makefile.am index 25eba72653..5bcf5023cb 100644 --- a/demos/Makefile.am +++ b/demos/Makefile.am @@ -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) diff --git a/demos/testpixbuf.c b/demos/testpixbuf.c index 0af6d368e9..a2ecbe1f08 100644 --- a/demos/testpixbuf.c +++ b/demos/testpixbuf.c @@ -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 { diff --git a/docs/reference/gdk-pixbuf/tmpl/creating.sgml b/docs/reference/gdk-pixbuf/tmpl/creating.sgml index 0bbce5405a..1d017da68a 100644 --- a/docs/reference/gdk-pixbuf/tmpl/creating.sgml +++ b/docs/reference/gdk-pixbuf/tmpl/creating.sgml @@ -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> diff --git a/docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf-unused.sgml b/docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf-unused.sgml index 910ccef35f..099d29a515 100644 --- a/docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf-unused.sgml +++ b/docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf-unused.sgml @@ -552,3 +552,14 @@ End: </para> +<!-- ##### FUNCTION gdk_pixbuf_new_from_inline ##### --> +<para> + +</para> + +@inline_pixbuf: +@copy_pixels: +@length: +@error: +@Returns: + diff --git a/docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf.sgml b/docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf.sgml index 403941efa9..ecc32bc201 100644 --- a/docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf.sgml +++ b/docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf.sgml @@ -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: diff --git a/docs/reference/gtk/tmpl/gtkitemfactory.sgml b/docs/reference/gtk/tmpl/gtkitemfactory.sgml index 18c4cc601d..abda892595 100644 --- a/docs/reference/gtk/tmpl/gtkitemfactory.sgml +++ b/docs/reference/gtk/tmpl/gtkitemfactory.sgml @@ -77,7 +77,6 @@ GtkItemFactory @callback_action: @item_type: @extra_data: -@extra_data2: <!-- ##### STRUCT GtkItemFactoryItem ##### --> <para> diff --git a/gdk-pixbuf/ChangeLog b/gdk-pixbuf/ChangeLog index a024030d23..992773220d 100644 --- a/gdk-pixbuf/ChangeLog +++ b/gdk-pixbuf/ChangeLog @@ -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 diff --git a/gdk-pixbuf/Makefile.am b/gdk-pixbuf/Makefile.am index cfe6316664..374ea905a3 100644 --- a/gdk-pixbuf/Makefile.am +++ b/gdk-pixbuf/Makefile.am @@ -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 index 0000000000..05bb685278 --- /dev/null +++ b/gdk-pixbuf/gdk-pixbuf-csource.c @@ -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" diff --git a/gdk-pixbuf/gdk-pixbuf-data.c b/gdk-pixbuf/gdk-pixbuf-data.c index 95903b527f..15f5aa8b82 100644 --- a/gdk-pixbuf/gdk-pixbuf-data.c +++ b/gdk-pixbuf/gdk-pixbuf-data.c @@ -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; -} - diff --git a/gdk-pixbuf/gdk-pixbuf-private.h b/gdk-pixbuf/gdk-pixbuf-private.h index 0bdae8715d..4393cbe336 100644 --- a/gdk-pixbuf/gdk-pixbuf-private.h +++ b/gdk-pixbuf/gdk-pixbuf-private.h @@ -130,16 +130,6 @@ struct _GdkPixbufAnimationIterClass { -#define GDK_PIXBUF_INLINE_MAGIC_NUMBER 0x47646B50 /* 'GdkP' */ - -typedef enum -{ - GDK_PIXBUF_INLINE_RAW = 0, - GDK_PIXBUF_INLINE_RLE = 1 -} GdkPixbufInlineFormat; - - - GdkPixbufAnimation* gdk_pixbuf_non_anim_new (GdkPixbuf *pixbuf); #endif diff --git a/gdk-pixbuf/gdk-pixbuf.h b/gdk-pixbuf/gdk-pixbuf.h index 32ab3a8f46..2a32c2fa2b 100644 --- a/gdk-pixbuf/gdk-pixbuf.h +++ b/gdk-pixbuf/gdk-pixbuf.h @@ -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 index 0000000000..bc1b6a6466 --- /dev/null +++ b/gdk-pixbuf/gdk-pixdata.c @@ -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 index 0000000000..92ef3ecec7 --- /dev/null +++ b/gdk-pixbuf/gdk-pixdata.h @@ -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__ */ diff --git a/gtk/gtkiconfactory.c b/gtk/gtkiconfactory.c index ae80f3180b..64c57b33b5 100644 --- a/gtk/gtkiconfactory.c +++ b/gtk/gtkiconfactory.c @@ -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, diff --git a/gtk/gtkitemfactory.c b/gtk/gtkitemfactory.c index ff3b8cdd4f..b47970e760 100644 --- a/gtk/gtkitemfactory.c +++ b/gtk/gtkitemfactory.c @@ -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) diff --git a/gtk/gtkitemfactory.h b/gtk/gtkitemfactory.h index 536d4ea7be..5132f9d1db 100644 --- a/gtk/gtkitemfactory.h +++ b/gtk/gtkitemfactory.h @@ -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 |