[gthumb: 59/129] started work on a cairo jpeg loader



commit 1ab80d2b6f3acacbcf100603fea560b296b06b3c
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sat Apr 23 00:51:16 2011 +0200

    started work on a cairo jpeg loader

 configure.ac                                    |    1 +
 extensions/Makefile.am                          |    1 +
 extensions/cairo_io/Makefile.am                 |   29 ++++
 extensions/cairo_io/cairo-io-jpeg.c             |  194 +++++++++++++++++++++++
 extensions/cairo_io/cairo-io-jpeg.h             |   40 +++++
 extensions/cairo_io/cairo_io.extension.in.in    |    7 +
 extensions/cairo_io/main.c                      |   54 +++++++
 extensions/image_viewer/gth-image-viewer-page.c |    2 +-
 gthumb/gth-main.c                               |    1 +
 9 files changed, 328 insertions(+), 1 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index ed6037f..32f7126 100644
--- a/configure.ac
+++ b/configure.ac
@@ -526,6 +526,7 @@ extensions/bookmarks/data/ui/Makefile
 extensions/burn_disc/Makefile
 extensions/burn_disc/data/Makefile
 extensions/burn_disc/data/ui/Makefile
+extensions/cairo_io/Makefile
 extensions/catalogs/Makefile
 extensions/catalogs/data/Makefile
 extensions/catalogs/data/ui/Makefile
diff --git a/extensions/Makefile.am b/extensions/Makefile.am
index 796b8b1..f967397 100644
--- a/extensions/Makefile.am
+++ b/extensions/Makefile.am
@@ -14,6 +14,7 @@ IMPORTERS = 			\
 	$(NULL)
 
 JPEG_TOOLS = 			\
+	cairo_io		\
 	image_rotation		\
 	importer		\
 	$(NULL)
diff --git a/extensions/cairo_io/Makefile.am b/extensions/cairo_io/Makefile.am
new file mode 100644
index 0000000..ee2dfb2
--- /dev/null
+++ b/extensions/cairo_io/Makefile.am
@@ -0,0 +1,29 @@
+extensiondir = $(pkglibdir)/extensions
+extension_LTLIBRARIES = libcairo_io.la
+
+libcairo_io_la_SOURCES = 	\
+	cairo-io-jpeg.c		\
+	cairo-io-jpeg.h		\
+	main.c
+
+libcairo_io_la_CFLAGS = $(GTHUMB_CFLAGS) $(JPEG_CFLAGS) -I$(top_srcdir) -I$(top_builddir)/gthumb 
+libcairo_io_la_LDFLAGS = $(EXTENSION_LIBTOOL_FLAGS)
+libcairo_io_la_LIBADD = $(GTHUMB_LIBS) $(JPEG_LIBS) ../jpeg_utils/libjpeg_utils.la
+libcairo_io_la_DEPENDENCIES = $(top_builddir)/gthumb/gthumb$(EXEEXT)
+
+extensioninidir = $(extensiondir)
+extensionini_in_files = cairo_io.extension.in.in
+extensionini_DATA = $(extensionini_in_files:.extension.in.in=.extension)
+
+ GTHUMB_EXTENSION_IN_RULE@
+ GTHUMB_EXTENSION_RULE@
+
+EXTRA_DIST = $(extensionini_in_files) 
+DISTCLEANFILES = $(extensionini_DATA)
+BUILT_SOURCES = $(ENUM_TYPES)
+CLEANFILES = $(BUILT_SOURCES)
+
+dist-hook:
+	cd $(distdir); rm -f $(CLEANFILES)
+
+-include $(top_srcdir)/git.mk
diff --git a/extensions/cairo_io/cairo-io-jpeg.c b/extensions/cairo_io/cairo-io-jpeg.c
new file mode 100644
index 0000000..17c499b
--- /dev/null
+++ b/extensions/cairo_io/cairo-io-jpeg.c
@@ -0,0 +1,194 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2011 Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <setjmp.h>
+#include <jpeglib.h>
+#include <gthumb.h>
+#include <extensions/jpeg_utils/jmemorysrc.h>
+#include "cairo-io-jpeg.h"
+
+
+/* error handler data */
+
+struct error_handler_data {
+	struct jpeg_error_mgr   pub;
+	sigjmp_buf              setjmp_buffer;
+        GError                **error;
+};
+
+
+static void
+fatal_error_handler (j_common_ptr cinfo)
+{
+	struct error_handler_data *errmgr;
+        char buffer[JMSG_LENGTH_MAX];
+
+	errmgr = (struct error_handler_data *) cinfo->err;
+
+        /* Create the message */
+        (* cinfo->err->format_message) (cinfo, buffer);
+
+        /* broken check for *error == NULL for robustness against
+         * crappy JPEG library
+         */
+        if (errmgr->error && *errmgr->error == NULL) {
+                g_set_error (errmgr->error,
+                             GDK_PIXBUF_ERROR,
+                             GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
+			     "Error interpreting JPEG image file (%s)",
+                             buffer);
+        }
+
+	siglongjmp (errmgr->setjmp_buffer, 1);
+
+        g_assert_not_reached ();
+}
+
+
+static void
+output_message_handler (j_common_ptr cinfo)
+{
+	/* This method keeps libjpeg from dumping crap to stderr */
+	/* do nothing */
+}
+
+
+GthImage *
+_cairo_image_surface_create_from_jpeg (GthFileData   *file_data,
+				       int            requested_size,
+				       int           *original_width,
+				       int           *original_height,
+				       gpointer       user_data,
+				       GCancellable  *cancellable,
+				       GError       **error)
+{
+	GthImage                      *image;
+	void                          *in_buffer;
+	gsize                          in_buffer_size;
+	struct error_handler_data      jsrcerr;
+	struct jpeg_decompress_struct  srcinfo;
+	cairo_surface_t               *surface;
+	int                            surface_stride;
+	unsigned char                 *surface_row;
+	JSAMPARRAY                     buffer;
+	int                            buffer_stride;
+	JSAMPARRAY                     buffer_row;
+	unsigned char                 *p_surface;
+	unsigned char                 *p_buffer;
+	JDIMENSION                     nlines;
+	int                            x, l;
+
+	image = gth_image_new ();
+
+	srcinfo.err = jpeg_std_error (&(jsrcerr.pub));
+	jsrcerr.pub.error_exit = fatal_error_handler;
+	jsrcerr.pub.output_message = output_message_handler;
+	jsrcerr.error = error;
+
+	jpeg_create_decompress (&srcinfo);
+
+	if (sigsetjmp (jsrcerr.setjmp_buffer, 1)) {
+		jpeg_destroy_decompress (&srcinfo);
+		return image;
+	}
+
+	if (! g_load_file_in_buffer (file_data->file,
+			      	     &in_buffer,
+			      	     &in_buffer_size,
+			      	     error))
+	{
+		jpeg_destroy_decompress (&srcinfo);
+		return image;
+	}
+
+	_jpeg_memory_src (&srcinfo, in_buffer, in_buffer_size);
+
+	jpeg_read_header (&srcinfo, TRUE);
+
+	/* FIXME: read the orientation flags and rotate the image */
+
+	if (original_width != NULL)
+		*original_width = srcinfo.image_width;
+	if (original_height != NULL)
+		*original_height = srcinfo.image_height;
+
+	srcinfo.out_color_space = JCS_RGB;
+	/* FIXME
+	if (requested_size > 0) {
+		for (srcinfo.scale_denom = 16; srcinfo.scale_denom >= 1; srcinfo.scale_denom--) {
+			jpeg_calc_output_dimensions (&srcinfo);
+			if ((srcinfo.output_width < requested_size) || (srcinfo.output_height < requested_size)) {
+				srcinfo.scale_denom += 1;
+				break;
+			}
+		}
+
+		if (srcinfo.scale_denom == 0)
+			srcinfo.scale_denom = srcinfo.scale_num;
+	}
+	*/
+
+	jpeg_start_decompress (&srcinfo);
+
+	surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, srcinfo.output_width, srcinfo.output_height);
+	surface_stride = cairo_image_surface_get_stride (surface);
+	surface_row = cairo_image_surface_get_data (surface);
+
+	buffer_stride = srcinfo.output_width * srcinfo.output_components;
+	buffer = (*srcinfo.mem->alloc_sarray) ((j_common_ptr) &srcinfo, JPOOL_IMAGE, buffer_stride, srcinfo.rec_outbuf_height);
+
+	while (srcinfo.output_scanline < srcinfo.output_height) {
+		nlines = jpeg_read_scanlines (&srcinfo, buffer, srcinfo.rec_outbuf_height);
+		buffer_row = buffer;
+		for (l = 0; l < nlines; l++) {
+			p_surface = surface_row;
+			p_buffer = buffer_row[l];
+			for (x = 0; x < srcinfo.output_width; x++) {
+				p_surface[CAIRO_RED] = p_buffer[0];
+				p_surface[CAIRO_GREEN] = p_buffer[1];
+				p_surface[CAIRO_BLUE] = p_buffer[2];
+				p_surface[CAIRO_ALPHA] = 0xff;
+
+				p_surface += 4;
+				p_buffer += srcinfo.output_components;
+			}
+
+			surface_row += surface_stride;
+			buffer_row += buffer_stride;
+		}
+	}
+
+	jpeg_finish_decompress (&srcinfo);
+	jpeg_destroy_decompress (&srcinfo);
+
+	/* FIXME: scale to the requested size */
+
+	gth_image_set_cairo_surface (image, surface);
+
+	cairo_surface_destroy (surface);
+	g_free (in_buffer);
+
+	return image;
+}
diff --git a/extensions/cairo_io/cairo-io-jpeg.h b/extensions/cairo_io/cairo-io-jpeg.h
new file mode 100644
index 0000000..bb13a70
--- /dev/null
+++ b/extensions/cairo_io/cairo-io-jpeg.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2011 Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CAIRO_IO_JPEG_H
+#define CAIRO_IO_JPEG_H
+
+#include <gtk/gtk.h>
+#include <gthumb.h>
+
+G_BEGIN_DECLS
+
+GthImage *  _cairo_image_surface_create_from_jpeg (GthFileData   *file_data,
+						   int            requested_size,
+						   int           *original_width,
+						   int           *original_height,
+						   gpointer       user_data,
+						   GCancellable  *cancellable,
+						   GError       **error);
+
+G_END_DECLS
+
+#endif /* CAIRO_IO_JPEG_H */
diff --git a/extensions/cairo_io/cairo_io.extension.in.in b/extensions/cairo_io/cairo_io.extension.in.in
new file mode 100644
index 0000000..c164ce2
--- /dev/null
+++ b/extensions/cairo_io/cairo_io.extension.in.in
@@ -0,0 +1,7 @@
+[Extension]
+Hidden=true
+
+[Loader]
+Type=module
+File=%LIBRARY%
+Requires=jpeg_utils
diff --git a/extensions/cairo_io/main.c b/extensions/cairo_io/main.c
new file mode 100644
index 0000000..94abcaf
--- /dev/null
+++ b/extensions/cairo_io/main.c
@@ -0,0 +1,54 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2011 Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <config.h>
+#include <gthumb.h>
+#include "cairo-io-jpeg.h"
+
+
+G_MODULE_EXPORT void
+gthumb_extension_activate (void)
+{
+	gth_main_register_image_loader_func (_cairo_image_surface_create_from_jpeg,
+					     GTH_IMAGE_FORMAT_CAIRO_SURFACE,
+					     "image/jpeg",
+					     NULL);
+}
+
+
+G_MODULE_EXPORT void
+gthumb_extension_deactivate (void)
+{
+}
+
+
+G_MODULE_EXPORT gboolean
+gthumb_extension_is_configurable (void)
+{
+	return FALSE;
+}
+
+
+G_MODULE_EXPORT void
+gthumb_extension_configure (GtkWindow *parent)
+{
+}
diff --git a/extensions/image_viewer/gth-image-viewer-page.c b/extensions/image_viewer/gth-image-viewer-page.c
index 3b1bf81..43dcdd6 100644
--- a/extensions/image_viewer/gth-image-viewer-page.c
+++ b/extensions/image_viewer/gth-image-viewer-page.c
@@ -909,7 +909,7 @@ gth_image_viewer_page_real_update_sensitivity (GthViewerPage *base)
 	zoom = gth_image_viewer_get_zoom (GTH_IMAGE_VIEWER (self->priv->viewer));
 
 	_set_action_sensitive (self, "ImageViewer_View_Zoom100", zoom_enabled && ! FLOAT_EQUAL (zoom, 1.0));
-	_set_action_sensitive (self, "ImageViewer_View_ZoomOut", zoom_enabled && (zoom > 0.05));
+	_set_action_sensitive (self, "ImageViewer_View_ZoomOut", zoom_enabled && (zoom > 0.01));
 	_set_action_sensitive (self, "ImageViewer_View_ZoomIn", zoom_enabled && (zoom < 100.0));
 
 	fit_mode = gth_image_viewer_get_fit_mode (GTH_IMAGE_VIEWER (self->priv->viewer));
diff --git a/gthumb/gth-main.c b/gthumb/gth-main.c
index 28ea727..1d6022c 100644
--- a/gthumb/gth-main.c
+++ b/gthumb/gth-main.c
@@ -1246,6 +1246,7 @@ void
 gth_main_activate_extensions (void)
 {
 	const char *mandatory_extensions[] = {	"file_viewer",
+						"cairo_io",
 						NULL };
 	const char *default_extensions[] = {	"bookmarks",
 						"burn_disc",



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]