[gdk-pixbuf/resources: 3/4] Add pixbuf loader for GdkPixdata files
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gdk-pixbuf/resources: 3/4] Add pixbuf loader for GdkPixdata files
- Date: Tue, 31 Jan 2012 14:05:52 +0000 (UTC)
commit 8043382c29bb5998fd6df7472ba4b799cc015d80
Author: Alexander Larsson <alexl redhat com>
Date: Tue Jan 31 14:48:57 2012 +0100
Add pixbuf loader for GdkPixdata files
gdk-pixbuf/Makefile.am | 12 +++-
gdk-pixbuf/gdk-pixbuf-io.c | 16 +++-
gdk-pixbuf/io-pixdata.c | 192 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 216 insertions(+), 4 deletions(-)
---
diff --git a/gdk-pixbuf/Makefile.am b/gdk-pixbuf/Makefile.am
index 31e91eb..215c476 100644
--- a/gdk-pixbuf/Makefile.am
+++ b/gdk-pixbuf/Makefile.am
@@ -86,6 +86,11 @@ libpixbufloader_wbmp_la_LDFLAGS = -avoid-version -module $(no_undefined)
libpixbufloader_wbmp_la_LIBADD = $(module_libs)
#
+# The GdkPixdata loader, always built in
+#
+libstatic_pixbufloader_pixdata_la_SOURCES = io-pixdata.c
+
+#
# The GIF loader
#
libstatic_pixbufloader_gif_la_SOURCES = io-gif.c io-gif-animation.c io-gif-animation.h
@@ -456,6 +461,9 @@ else
QTIF_LIB = libpixbufloader-qtif.la
endif
+# Always included
+STATIC_PIXDATA_LIB = libstatic-pixbufloader-pixdata.la
+
if BUILD_DYNAMIC_MODULES
loader_LTLIBRARIES = \
@@ -482,6 +490,7 @@ loader_LTLIBRARIES = \
endif
noinst_LTLIBRARIES = \
+ $(STATIC_PIXDATA_LIB) \
$(STATIC_PNG_LIB) \
$(STATIC_BMP_LIB) \
$(STATIC_WBMP_LIB) \
@@ -501,8 +510,7 @@ noinst_LTLIBRARIES = \
$(STATIC_QTIF_LIB) \
$(STATIC_GDIPLUS_LIBS)
-builtin_objs = @INCLUDED_LOADER_OBJ@
-
+builtin_objs = @INCLUDED_LOADER_OBJ@ $(STATIC_PIXDATA_LIB)
DEPS = libgdk_pixbuf-$(GDK_PIXBUF_API_VERSION).la
INCLUDES = \
diff --git a/gdk-pixbuf/gdk-pixbuf-io.c b/gdk-pixbuf/gdk-pixbuf-io.c
index 4a8b9fd..da9705b 100644
--- a/gdk-pixbuf/gdk-pixbuf-io.c
+++ b/gdk-pixbuf/gdk-pixbuf-io.c
@@ -136,7 +136,6 @@
*/
-#ifndef GDK_PIXBUF_USE_GIO_MIME
static gint
format_check (GdkPixbufModule *module, guchar *buffer, int size)
{
@@ -188,7 +187,6 @@ format_check (GdkPixbufModule *module, guchar *buffer, int size)
}
return 0;
}
-#endif
G_LOCK_DEFINE_STATIC (init_lock);
G_LOCK_DEFINE_STATIC (threadunsafe_loader_lock);
@@ -436,6 +434,9 @@ gdk_pixbuf_io_init (void)
else \
g_free (builtin_module)
+ /* Always include GdkPixdata format */
+ load_one_builtin_module (pixdata);
+
#ifdef INCLUDE_ani
load_one_builtin_module (ani);
#endif
@@ -664,6 +665,7 @@ gdk_pixbuf_io_init (void)
extern void _gdk_pixbuf__##type##_fill_info (GdkPixbufFormat *info); \
extern void _gdk_pixbuf__##type##_fill_vtable (GdkPixbufModule *module)
+module (pixdata);
module (png);
module (jpeg);
module (gif);
@@ -711,6 +713,9 @@ gdk_pixbuf_load_module_unlocked (GdkPixbufModule *image_module,
fill_info = _gdk_pixbuf__##id##_fill_info; \
fill_vtable = _gdk_pixbuf__##id##_fill_vtable; \
}
+
+ try_module (pixdata,pixdata);
+
#ifdef INCLUDE_png
try_module (png,png);
#endif
@@ -918,6 +923,13 @@ _gdk_pixbuf_get_module (guchar *buffer, guint size,
}
g_free (type);
}
+
+ /* Make sure the builtin GdkPixdata support works even without mime sniffing */
+ if (strcmp (info->name, "GdkPixdata") == 0 &&
+ format_check (module, buffer, size) == 100) {
+ selected = module;
+ break;
+ }
}
g_free (mime_type);
#else
diff --git a/gdk-pixbuf/io-pixdata.c b/gdk-pixbuf/io-pixdata.c
new file mode 100644
index 0000000..08ae20b
--- /dev/null
+++ b/gdk-pixbuf/io-pixdata.c
@@ -0,0 +1,192 @@
+/* GdkPixdata loader
+ *
+ * Copyright (c) 2012 Alexander Larsson <alexl redhat com>
+ *
+ * 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 "gdk-pixbuf-private.h"
+#include "gdk-pixdata.h"
+
+G_MODULE_EXPORT void fill_vtable (GdkPixbufModule * module);
+G_MODULE_EXPORT void fill_info (GdkPixbufFormat * info);
+
+struct pixdata_context {
+ GdkPixbufModuleSizeFunc size_func;
+ GdkPixbufModuleUpdatedFunc updated_func;
+ GdkPixbufModulePreparedFunc prepared_func;
+ gpointer user_data;
+
+ GString *data;
+
+ GdkPixdata pixdata;
+ gboolean got_header;
+ gboolean got_pixbuf;
+};
+
+static void
+free_pixdata_context (struct pixdata_context *context)
+{
+ if (!context)
+ return;
+
+ g_free (context);
+}
+
+static gpointer
+pixdata_image_begin_load (GdkPixbufModuleSizeFunc size_func,
+ GdkPixbufModulePreparedFunc prepared_func,
+ GdkPixbufModuleUpdatedFunc updated_func,
+ gpointer user_data, GError **error)
+{
+ struct pixdata_context *context;
+
+ context = g_new0 (struct pixdata_context, 1);
+ if (!context)
+ return NULL;
+
+ context->size_func = size_func;
+ context->updated_func = updated_func;
+ context->prepared_func = prepared_func;
+ context->user_data = user_data;
+
+ context->data = g_string_new ("");
+
+ return context;
+}
+
+static gboolean try_load (struct pixdata_context *context, GError **error)
+{
+ GdkPixbuf *pixbuf;
+
+ if (context->got_pixbuf)
+ return TRUE;
+
+ if (!gdk_pixdata_deserialize (&context->pixdata,
+ context->data->len,
+ (guchar *)context->data->str,
+ error))
+ return FALSE;
+
+ pixbuf = gdk_pixbuf_from_pixdata (&context->pixdata,
+ TRUE, error);
+ if (pixbuf == NULL)
+ return FALSE;
+
+ context->got_pixbuf = TRUE;
+
+ if (context->prepared_func)
+ (* context->prepared_func) (pixbuf,
+ NULL,
+ context->user_data);
+ if (context->updated_func)
+ (* context->updated_func) (pixbuf, 0, 0, pixbuf->width, pixbuf->height, context->user_data);
+
+ return TRUE;
+}
+
+static gboolean
+pixdata_image_stop_load (gpointer data, GError **error)
+{
+ struct pixdata_context *context = (struct pixdata_context *) data;
+ gboolean res;
+
+ res = try_load (context, error);
+
+ g_string_free (context->data, TRUE);
+
+ free_pixdata_context (context);
+
+ return res;
+}
+
+static gboolean
+pixdata_image_load_increment (gpointer data, const guchar *buf, guint size, GError **error)
+{
+ struct pixdata_context *context = (struct pixdata_context *) data;
+
+ g_string_append_len (context->data, (char *)buf, size);
+
+ if (!context->got_header && context->data->len >= GDK_PIXDATA_HEADER_LENGTH)
+ {
+ /* This never reads past the header anyway, and we know we have at least
+ the header size, so we pass it a really large size to avoid any error reporting
+ due to missing data */
+ if (!gdk_pixdata_deserialize (&context->pixdata,
+ G_MAXUINT,
+ (guchar *)context->data->str,
+ error))
+ return FALSE;
+
+ context->got_header = TRUE;
+
+ if (context->size_func)
+ {
+ gint w = context->pixdata.width;
+ gint h = context->pixdata.height;
+ (* context->size_func) (&w, &h, context->user_data);
+
+ if (w == 0 || h == 0)
+ {
+ g_set_error_literal (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_FAILED,
+ _("Transformed pixbuf has zero width or height."));
+ return FALSE;
+ }
+ }
+ }
+
+ try_load (context, NULL);
+
+ return TRUE;
+}
+
+/* Always included */
+#define MODULE_ENTRY(function) void _gdk_pixbuf__pixdata_ ## function
+
+MODULE_ENTRY (fill_vtable) (GdkPixbufModule * module)
+{
+ module->begin_load = pixdata_image_begin_load;
+ module->stop_load = pixdata_image_stop_load;
+ module->load_increment = pixdata_image_load_increment;
+}
+
+MODULE_ENTRY (fill_info) (GdkPixbufFormat * info)
+{
+ static GdkPixbufModulePattern signature[] = {
+ { "GdkP", NULL, 100 }, /* file begins with 'GdkP' at offset 0 */
+ { NULL, NULL, 0 }
+ };
+ static gchar *mime_types[] = {
+ "image/x-gdkpixdata",
+ NULL
+ };
+ static gchar *extensions[] = {
+ "gdkp",
+ NULL
+ };
+
+ info->name = "GdkPixdata";
+ info->signature = signature;
+ info->description = N_("The GdkPixdata format");
+ info->mime_types = mime_types;
+ info->extensions = extensions;
+ info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
+ info->license = "LGPL";
+ info->disabled = FALSE;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]