[gthumb/ext] added ability to specify the file type options when saving images
- From: Paolo Bacchilega <paobac src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gthumb/ext] added ability to specify the file type options when saving images
- Date: Sun, 11 Oct 2009 20:59:06 +0000 (UTC)
commit 415a61cd7cb99a37abcc7879f87122aa76fcbc06
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sun Oct 11 21:08:42 2009 +0200
added ability to specify the file type options when saving images
configure.ac | 38 ++-
data/gthumb.schemas.in | 110 ----
data/ui/preferences.ui | 2 +-
extensions/Makefile.am | 2 +
extensions/exiv2/exiv2-utils.cpp | 8 +-
extensions/exiv2/exiv2-utils.h | 2 +-
extensions/exiv2/gth-metadata-provider-exiv2.c | 2 +-
extensions/image_rotation/Makefile.am | 12 -
.../image_rotation/image_rotation.extension.in.in | 1 +
extensions/image_rotation/rotation-utils.c | 8 +-
extensions/image_rotation/rotation-utils.h | 3 +-
extensions/image_viewer/gth-image-viewer-page.c | 8 +-
extensions/jpeg_utils/Makefile.am | 38 ++
.../{image_rotation => jpeg_utils}/jmemorydest.c | 0
.../jpeg_utils/jmemorydest.h | 22 +-
.../{image_rotation => jpeg_utils}/jmemorysrc.c | 0
.../jpeg_utils/jmemorysrc.h | 22 +-
extensions/jpeg_utils/jpeg_utils.extension.in.in | 6 +
.../{image_rotation => jpeg_utils}/jpegtran.c | 10 +-
.../{image_rotation => jpeg_utils}/jpegtran.h | 1 +
.../gthumb-error.c => extensions/jpeg_utils/main.c | 35 +-
.../{image_rotation => jpeg_utils}/transupp.c | 0
.../{image_rotation => jpeg_utils}/transupp.h | 0
extensions/list_tools/gth-script-editor-dialog.c | 4 +-
extensions/pixbuf_savers/Makefile.am | 67 +++
extensions/pixbuf_savers/data/Makefile.am | 18 +
.../data/gthumb-pixbuf-savers.schemas.in | 143 +++++
extensions/pixbuf_savers/data/ui/Makefile.am | 10 +
extensions/pixbuf_savers/data/ui/jpeg-options.ui | 120 +++++
extensions/pixbuf_savers/data/ui/png-options.ui | 55 ++
.../data/ui/save-options-preferences.ui | 167 ++++++
extensions/pixbuf_savers/data/ui/tga-options.ui | 26 +
extensions/pixbuf_savers/data/ui/tiff-options.ui | 280 ++++++++++
extensions/pixbuf_savers/gth-jpeg-saver.c | 512 ++++++++++++++++++
extensions/pixbuf_savers/gth-jpeg-saver.h | 57 ++
extensions/pixbuf_savers/gth-png-saver.c | 179 +++++++
extensions/pixbuf_savers/gth-png-saver.h | 57 ++
extensions/pixbuf_savers/gth-tga-saver.c | 414 +++++++++++++++
extensions/pixbuf_savers/gth-tga-saver.h | 57 ++
extensions/pixbuf_savers/gth-tiff-saver.c | 555 ++++++++++++++++++++
extensions/pixbuf_savers/gth-tiff-saver.h | 57 ++
extensions/pixbuf_savers/main.c | 61 +++
.../pixbuf_savers/pixbuf_savers.extension.in.in | 11 +
extensions/pixbuf_savers/preferences.c | 164 ++++++
extensions/pixbuf_savers/preferences.h | 55 ++
gthumb/Makefile.am | 12 +-
gthumb/gconf-utils.c | 4 +-
gthumb/gth-browser.c | 10 +-
gthumb/gth-buffer-data.c | 161 ++++++
gthumb/gth-buffer-data.h | 51 ++
gthumb/{gthumb-error.c => gth-error.c} | 6 +-
gthumb/{gthumb-error.h => gth-error.h} | 10 +-
gthumb/gth-extensions.c | 6 +-
gthumb/gth-image-loader.c | 8 +-
gthumb/gth-main.c | 28 +
gthumb/gth-main.h | 6 +-
gthumb/gth-pixbuf-list-task.c | 8 +-
gthumb/gth-pixbuf-saver.c | 158 ++++++
gthumb/gth-pixbuf-saver.h | 86 +++
gthumb/gth-preferences.h | 13 -
gthumb/gth-thumb-loader.c | 12 +-
gthumb/pixbuf-io.c | 34 +-
gthumb/pixbuf-io.h | 6 +-
po/POTFILES.in | 89 +++-
64 files changed, 3835 insertions(+), 272 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 9e2e845..7162a64 100644
--- a/configure.ac
+++ b/configure.ac
@@ -223,17 +223,40 @@ AC_MSG_CHECKING(JPEG Support)
AC_ARG_ENABLE([jpeg],
[AS_HELP_STRING([--disable-jpeg],[do not compile code that uses the libjpeg library])],,
[enable_jpeg=yes])
-AC_CHECK_LIB(jpeg, jpeg_destroy_decompress,
- [enable_jpeg=yes],
- [enable_jpeg=no])
if test "x$enable_jpeg" = "xyes"; then
- AC_DEFINE(HAVE_LIBJPEG, 1, [Define to 1 if libjpeg support is included])
- JPEG_LIBS='-ljpeg -lm -lz'
+ AC_CHECK_LIB(jpeg, jpeg_destroy_decompress,
+ [enable_jpeg=yes],
+ [enable_jpeg=no])
+ if test "x$enable_jpeg" = "xyes"; then
+ AC_DEFINE(HAVE_LIBJPEG, 1, [Define to 1 if libjpeg support is included])
+ JPEG_LIBS='-ljpeg -lm -lz'
+ fi
fi
AC_SUBST(JPEG_LIBS)
AM_CONDITIONAL(ENABLE_JPEG_TOOLS, test "x$enable_jpeg" = xyes)
AC_MSG_RESULT($enable_jpeg)
+
+dnl ===========================================================================
+
+AC_MSG_CHECKING(TIFF Support)
+AC_ARG_ENABLE([tiff],
+ [AC_HELP_STRING([--disable-tiff],[do not compile code that uses the libtiff library])],,
+ [enable_tiff=yes])
+if test x$enable_tiff = xyes ; then
+ AC_CHECK_LIB(tiff, TIFFWriteScanline,
+ [AC_CHECK_HEADER(tiffio.h,
+ [enable_tiff=yes],
+ [enable_tiff=no])],
+ [enable_tiff=no])
+ if test "x$enable_tiff" = "xyes"; then
+ AC_DEFINE(HAVE_LIBTIFF, 1, [Define to 1 if libtiff support is included])
+ TIFF_LIBS='-ltiff -lm -lz'
+ fi
+fi
+AC_SUBST(TIFF_LIBS)
+AC_MSG_RESULT($enable_tiff)
+
dnl ===========================================================================
AC_CONFIG_FILES([
@@ -272,12 +295,16 @@ extensions/image_rotation/Makefile
extensions/image_viewer/Makefile
extensions/image_viewer/data/Makefile
extensions/image_viewer/data/ui/Makefile
+extensions/jpeg_utils/Makefile
extensions/list_tools/Makefile
extensions/list_tools/data/Makefile
extensions/list_tools/data/ui/Makefile
extensions/photo_importer/Makefile
extensions/photo_importer/data/Makefile
extensions/photo_importer/data/ui/Makefile
+extensions/pixbuf_savers/Makefile
+extensions/pixbuf_savers/data/Makefile
+extensions/pixbuf_savers/data/ui/Makefile
extensions/red_eye_removal/Makefile
extensions/red_eye_removal/data/Makefile
extensions/red_eye_removal/data/ui/Makefile
@@ -313,5 +340,6 @@ Configuration:
Build tests : $ENABLE_TEST_SUITE
Exiv2 support : ${enable_exiv2}
JPEG tools : ${enable_jpeg}
+ TIFF tools : ${enable_tiff}
Clutter support : ${enable_clutter}
"
diff --git a/data/gthumb.schemas.in b/data/gthumb.schemas.in
index 3964c4c..855ab05 100644
--- a/data/gthumb.schemas.in
+++ b/data/gthumb.schemas.in
@@ -492,116 +492,6 @@
</locale>
</schema>
- <!-- JPEG Saver -->
-
- <schema>
- <key>/schemas/apps/gthumb/dialogs/jpeg_saver/quality</key>
- <applyto>/apps/gthumb/dialogs/jpeg_saver/quality</applyto>
- <owner>gthumb</owner>
- <type>int</type>
- <default>85</default>
- <locale name="C">
- <short></short>
- <long>
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/gthumb/dialogs/jpeg_saver/smoothing</key>
- <applyto>/apps/gthumb/dialogs/jpeg_saver/smoothing</applyto>
- <owner>gthumb</owner>
- <type>int</type>
- <default>0</default>
- <locale name="C">
- <short></short>
- <long>
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/gthumb/dialogs/jpeg_saver/optimize</key>
- <applyto>/apps/gthumb/dialogs/jpeg_saver/optimize</applyto>
- <owner>gthumb</owner>
- <type>bool</type>
- <default>true</default>
- <locale name="C">
- <short></short>
- <long>
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/gthumb/dialogs/jpeg_saver/pregressive</key>
- <applyto>/apps/gthumb/dialogs/jpeg_saver/pregressive</applyto>
- <owner>gthumb</owner>
- <type>bool</type>
- <default>false</default>
- <locale name="C">
- <short></short>
- <long>
- </long>
- </locale>
- </schema>
-
- <!-- TGA Saver -->
-
- <schema>
- <key>/schemas/apps/gthumb/dialogs/tga_saver/rle_compression</key>
- <applyto>/apps/gthumb/dialogs/tga_saver/rle_compression</applyto>
- <owner>gthumb</owner>
- <type>bool</type>
- <default>true</default>
- <locale name="C">
- <short></short>
- <long>
- </long>
- </locale>
- </schema>
-
- <!-- TIFF Saver -->
-
- <schema>
- <key>/schemas/apps/gthumb/dialogs/tiff_saver/compression</key>
- <applyto>/apps/gthumb/dialogs/tiff_saver/compression</applyto>
- <owner>gthumb</owner>
- <type>string</type>
- <default>deflate</default>
- <locale name="C">
- <short></short>
- <long> Possible values are: none, deflate, jpeg.
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/gthumb/dialogs/tiff_saver/horizontal_resolution</key>
- <applyto>/apps/gthumb/dialogs/tiff_saver/horizontal_resolution</applyto>
- <owner>gthumb</owner>
- <type>int</type>
- <default>72</default>
- <locale name="C">
- <short></short>
- <long>
- </long>
- </locale>
- </schema>
-
- <schema>
- <key>/schemas/apps/gthumb/dialogs/tiff_saver/vertical_resolution</key>
- <applyto>/apps/gthumb/dialogs/tiff_saver/vertical_resolution</applyto>
- <owner>gthumb</owner>
- <type>int</type>
- <default>72</default>
- <locale name="C">
- <short></short>
- <long>
- </long>
- </locale>
- </schema>
-
<!-- Messages -->
<schema>
diff --git a/data/ui/preferences.ui b/data/ui/preferences.ui
index 837d7ab..37bfe3d 100644
--- a/data/ui/preferences.ui
+++ b/data/ui/preferences.ui
@@ -185,8 +185,8 @@
<child>
<object class="GtkFileChooserButton" id="startup_dir_filechooserbutton">
<property name="visible">True</property>
- <property name="action">select-folder</property>
<property name="local_only">False</property>
+ <property name="action">select-folder</property>
<property name="title" translatable="yes">Choose startup folder</property>
</object>
<packing>
diff --git a/extensions/Makefile.am b/extensions/Makefile.am
index aa92000..9d4c532 100644
--- a/extensions/Makefile.am
+++ b/extensions/Makefile.am
@@ -7,8 +7,10 @@ SUBDIRS = \
file_viewer \
image_rotation \
image_viewer \
+ jpeg_utils \
list_tools \
photo_importer \
+ pixbuf_savers \
red_eye_removal \
rename_series \
resize_images \
diff --git a/extensions/exiv2/exiv2-utils.cpp b/extensions/exiv2/exiv2-utils.cpp
index 74b0fa7..739f15c 100644
--- a/extensions/exiv2/exiv2-utils.cpp
+++ b/extensions/exiv2/exiv2-utils.cpp
@@ -669,10 +669,10 @@ exiv2_write_metadata_private (Exiv2::Image::AutoPtr image,
extern "C"
gboolean
-exiv2_supports_writes (GthFileData *file_data)
+exiv2_supports_writes (const char *mime_type)
{
- return (g_content_type_equals (gth_file_data_get_mime_type (file_data), "image/jpeg") ||
- g_content_type_equals (gth_file_data_get_mime_type (file_data), "image/png"));
+ return (g_content_type_equals (mime_type, "image/jpeg") ||
+ g_content_type_equals (mime_type, "image/png"));
}
@@ -680,7 +680,7 @@ extern "C"
gboolean
exiv2_write_metadata (SavePixbufData *data)
{
- if (exiv2_supports_writes (data->file_data)) {
+ if (exiv2_supports_writes (data->mime_type)) {
try {
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open ((Exiv2::byte*) data->buffer, data->buffer_size);
g_assert (image.get() != 0);
diff --git a/extensions/exiv2/exiv2-utils.h b/extensions/exiv2/exiv2-utils.h
index c21dbf5..083e739 100644
--- a/extensions/exiv2/exiv2-utils.h
+++ b/extensions/exiv2/exiv2-utils.h
@@ -44,7 +44,7 @@ gboolean exiv2_write_metadata_to_buffer (void **buffer,
GFileInfo *info,
GdkPixbuf *pixbuf, /* optional */
GError **error);
-gboolean exiv2_supports_writes (GthFileData *file_data);
+gboolean exiv2_supports_writes (const char *mime_type);
G_END_DECLS
diff --git a/extensions/exiv2/gth-metadata-provider-exiv2.c b/extensions/exiv2/gth-metadata-provider-exiv2.c
index 86c694f..f611cd1 100644
--- a/extensions/exiv2/gth-metadata-provider-exiv2.c
+++ b/extensions/exiv2/gth-metadata-provider-exiv2.c
@@ -87,7 +87,7 @@ gth_metadata_provider_exiv2_write (GthMetadataProvider *self,
GError *error = NULL;
GObject *metadata;
- if (! exiv2_supports_writes (file_data))
+ if (! exiv2_supports_writes (gth_file_data_get_mime_type (file_data)))
return;
if (! g_load_file_in_buffer (file_data->file, &buffer, &size, &error))
diff --git a/extensions/image_rotation/Makefile.am b/extensions/image_rotation/Makefile.am
index c3b739b..7370a81 100644
--- a/extensions/image_rotation/Makefile.am
+++ b/extensions/image_rotation/Makefile.am
@@ -1,18 +1,6 @@
extensiondir = $(libdir)/gthumb-2.0/extensions
extension_LTLIBRARIES = libimage_rotation.la
-if ENABLE_JPEG_TOOLS
-JPEG_FILES = \
- jmemorydest.c \
- jmemorysrc.c \
- jpegtran.c \
- jpegtran.h \
- transupp.c \
- transupp.h
-else
-JPEG_FILES =
-endif
-
libimage_rotation_la_SOURCES = \
$(JPEG_FILES) \
actions.c \
diff --git a/extensions/image_rotation/image_rotation.extension.in.in b/extensions/image_rotation/image_rotation.extension.in.in
index 422caba..827c2d4 100644
--- a/extensions/image_rotation/image_rotation.extension.in.in
+++ b/extensions/image_rotation/image_rotation.extension.in.in
@@ -8,3 +8,4 @@ Version=1.0
[Loader]
Type=module
File=%LIBRARY%
+Requires=jpeg_utils
diff --git a/extensions/image_rotation/rotation-utils.c b/extensions/image_rotation/rotation-utils.c
index 8c691e3..17569b5 100644
--- a/extensions/image_rotation/rotation-utils.c
+++ b/extensions/image_rotation/rotation-utils.c
@@ -25,6 +25,7 @@
#include <sys/types.h>
#include <glib/gi18n.h>
#include <gio/gio.h>
+#include <extensions/jpeg_utils/jpegtran.h>
#include "rotation-utils.h"
@@ -303,7 +304,6 @@ file_buffer_ready_cb (void *buffer,
GInputStream *istream;
GdkPixbuf *original_pixbuf;
GdkPixbuf *transformed_pixbuf;
- char *pixbuf_type;
istream = g_memory_input_stream_new_from_data (buffer, count, NULL);
original_pixbuf = gdk_pixbuf_new_from_stream (istream, tdata->cancellable, &error);
@@ -314,16 +314,12 @@ file_buffer_ready_cb (void *buffer,
}
transformed_pixbuf = _gdk_pixbuf_transform (original_pixbuf, tdata->transform);
- pixbuf_type = get_pixbuf_type_from_mime_type (gth_file_data_get_mime_type (tdata->file_data));
_gdk_pixbuf_save_async (transformed_pixbuf,
tdata->file_data,
- pixbuf_type,
- NULL,
- NULL,
+ gth_file_data_get_mime_type (tdata->file_data),
pixbuf_saved_cb,
tdata);
- g_free (pixbuf_type);
g_object_unref (transformed_pixbuf);
g_object_unref (original_pixbuf);
g_object_unref (istream);
diff --git a/extensions/image_rotation/rotation-utils.h b/extensions/image_rotation/rotation-utils.h
index 0f153d9..a25efe0 100644
--- a/extensions/image_rotation/rotation-utils.h
+++ b/extensions/image_rotation/rotation-utils.h
@@ -26,7 +26,8 @@
#include <config.h>
#include <gtk/gtk.h>
#include <gthumb.h>
-#include "jpegtran.h"
+#include <extensions/jpeg_utils/jpegtran.h>
+
typedef void (*TrimResponseFunc) (JpegMcuAction action, gpointer user_data);
diff --git a/extensions/image_viewer/gth-image-viewer-page.c b/extensions/image_viewer/gth-image-viewer-page.c
index 6fe64a6..06f5f98 100644
--- a/extensions/image_viewer/gth-image-viewer-page.c
+++ b/extensions/image_viewer/gth-image-viewer-page.c
@@ -736,7 +736,6 @@ _gth_image_viewer_page_real_save (GthViewerPage *base,
{
GthImageViewerPage *self;
SaveData *data;
- char *pixbuf_type;
GthFileData *current_file;
self = (GthImageViewerPage *) base;
@@ -748,7 +747,6 @@ _gth_image_viewer_page_real_save (GthViewerPage *base,
if (mime_type == NULL)
mime_type = gth_file_data_get_mime_type (self->priv->file_data);
- pixbuf_type = get_pixbuf_type_from_mime_type (mime_type);
current_file = gth_browser_get_current_file (self->priv->browser);
data->original_file = gth_file_data_dup (current_file);
@@ -758,13 +756,9 @@ _gth_image_viewer_page_real_save (GthViewerPage *base,
_gdk_pixbuf_save_async (gth_image_viewer_get_current_pixbuf (GTH_IMAGE_VIEWER (self->priv->viewer)),
current_file,
- pixbuf_type,
- NULL,
- NULL,
+ mime_type,
image_saved_cb,
data);
-
- g_free (pixbuf_type);
}
diff --git a/extensions/jpeg_utils/Makefile.am b/extensions/jpeg_utils/Makefile.am
new file mode 100644
index 0000000..a6a447a
--- /dev/null
+++ b/extensions/jpeg_utils/Makefile.am
@@ -0,0 +1,38 @@
+extensiondir = $(libdir)/gthumb-2.0/extensions
+extension_LTLIBRARIES = libjpeg_utils.la
+
+if ENABLE_JPEG_TOOLS
+libjpeg_utils_la_SOURCES = \
+ jmemorydest.c \
+ jmemorydest.h \
+ jmemorysrc.c \
+ jmemorysrc.h \
+ jpegtran.c \
+ jpegtran.h \
+ main.c \
+ transupp.c \
+ transupp.h
+else
+libjpeg_utils_la_SOURCES =
+endif
+
+libjpeg_utils_la_CFLAGS = $(GTHUMB_CFLAGS) $(DISABLE_DEPRECATED) $(WARNINGS) -I$(top_srcdir) -I$(top_builddir)/gthumb
+libjpeg_utils_la_LDFLAGS = $(EXTENSION_LIBTOOL_FLAGS)
+libjpeg_utils_la_LIBADD = $(GTHUMB_LIBS) $(JPEG_LIBS)
+libjpeg_utils_la_DEPENDENCIES = $(top_builddir)/gthumb/gthumb$(EXEEXT)
+
+extensioninidir = $(extensiondir)
+extensionini_in_files = jpeg_utils.extension.in.in
+extensionini_DATA = $(extensionini_in_files:.extension.in.in=.extension)
+
+%.extension.in: %.extension.in.in $(extension_LTLIBRARIES)
+ sed -e "s|%LIBRARY%|`. ./$(extension_LTLIBRARIES) && echo $$dlname`|" \
+ $< > $@
+
+%.extension: %.extension.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
+
+EXTRA_DIST = $(extensionini_in_files)
+
+DISTCLEANFILES = $(extensionini_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/extensions/image_rotation/jmemorydest.c b/extensions/jpeg_utils/jmemorydest.c
similarity index 100%
rename from extensions/image_rotation/jmemorydest.c
rename to extensions/jpeg_utils/jmemorydest.c
diff --git a/gthumb/gthumb-error.c b/extensions/jpeg_utils/jmemorydest.h
similarity index 73%
copy from gthumb/gthumb-error.c
copy to extensions/jpeg_utils/jmemorydest.h
index 18e5578..00354cc 100644
--- a/gthumb/gthumb-error.c
+++ b/extensions/jpeg_utils/jmemorydest.h
@@ -3,7 +3,7 @@
/*
* GThumb
*
- * Copyright (C) 2001 The Free Software Foundation, Inc.
+ * Copyright (C) 2001-2009 The 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
@@ -20,16 +20,14 @@
* Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
*/
-#include "gthumb-error.h"
+#ifndef JMEMORYDEST_H
+#define JMEMORYDEST_H
+#include <jpeglib.h>
+#include <glib.h>
-GQuark
-gthumb_error_quark (void)
-{
- static GQuark quark;
-
- if (!quark)
- quark = g_quark_from_static_string ("gthumb_error");
-
- return quark;
-}
+void _jpeg_memory_dest (j_compress_ptr cinfo,
+ void **out_buffer,
+ gsize *out_buffer_size);
+
+#endif /* JMEMORYDEST_H */
diff --git a/extensions/image_rotation/jmemorysrc.c b/extensions/jpeg_utils/jmemorysrc.c
similarity index 100%
rename from extensions/image_rotation/jmemorysrc.c
rename to extensions/jpeg_utils/jmemorysrc.c
diff --git a/gthumb/gthumb-error.c b/extensions/jpeg_utils/jmemorysrc.h
similarity index 72%
copy from gthumb/gthumb-error.c
copy to extensions/jpeg_utils/jmemorysrc.h
index 18e5578..ba0fd69 100644
--- a/gthumb/gthumb-error.c
+++ b/extensions/jpeg_utils/jmemorysrc.h
@@ -3,7 +3,7 @@
/*
* GThumb
*
- * Copyright (C) 2001 The Free Software Foundation, Inc.
+ * Copyright (C) 2001-2009 The 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
@@ -20,16 +20,14 @@
* Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
*/
-#include "gthumb-error.h"
+#ifndef JMEMORYSRC_H
+#define JMEMORYSRC_H
+#include <jpeglib.h>
+#include <glib.h>
-GQuark
-gthumb_error_quark (void)
-{
- static GQuark quark;
-
- if (!quark)
- quark = g_quark_from_static_string ("gthumb_error");
-
- return quark;
-}
+void _jpeg_memory_src (j_decompress_ptr cinfo,
+ void *in_buffer,
+ gsize in_buffer_size);
+
+#endif /* JMEMORYSRC_H */
diff --git a/extensions/jpeg_utils/jpeg_utils.extension.in.in b/extensions/jpeg_utils/jpeg_utils.extension.in.in
new file mode 100644
index 0000000..9a557a4
--- /dev/null
+++ b/extensions/jpeg_utils/jpeg_utils.extension.in.in
@@ -0,0 +1,6 @@
+[Extension]
+Mandatory=true
+
+[Loader]
+Type=module
+File=%LIBRARY%
diff --git a/extensions/image_rotation/jpegtran.c b/extensions/jpeg_utils/jpegtran.c
similarity index 97%
rename from extensions/image_rotation/jpegtran.c
rename to extensions/jpeg_utils/jpegtran.c
index a71c370..5fc6350 100644
--- a/extensions/image_rotation/jpegtran.c
+++ b/extensions/jpeg_utils/jpegtran.c
@@ -49,6 +49,8 @@
#include <glib.h>
#include <gthumb.h>
#include "transupp.h"
+#include "jmemorydest.h"
+#include "jmemorysrc.h"
#include "jpegtran.h"
@@ -257,14 +259,6 @@ jpegtran_internal (struct jpeg_decompress_struct *srcinfo,
}
-void _jpeg_memory_src (j_decompress_ptr cinfo,
- void *in_buffer,
- gsize in_buffer_size);
-void _jpeg_memory_dest (j_compress_ptr cinfo,
- void **out_buffer,
- gsize *out_buffer_size);
-
-
gboolean
jpegtran (void *in_buffer,
gsize in_buffer_size,
diff --git a/extensions/image_rotation/jpegtran.h b/extensions/jpeg_utils/jpegtran.h
similarity index 98%
rename from extensions/image_rotation/jpegtran.h
rename to extensions/jpeg_utils/jpegtran.h
index ec62a5f..6c26139 100644
--- a/extensions/image_rotation/jpegtran.h
+++ b/extensions/jpeg_utils/jpegtran.h
@@ -25,6 +25,7 @@
#include <config.h>
#include <glib.h>
+#include <gthumb.h>
#include "transupp.h"
diff --git a/gthumb/gthumb-error.c b/extensions/jpeg_utils/main.c
similarity index 68%
copy from gthumb/gthumb-error.c
copy to extensions/jpeg_utils/main.c
index 18e5578..a30b86f 100644
--- a/gthumb/gthumb-error.c
+++ b/extensions/jpeg_utils/main.c
@@ -3,7 +3,7 @@
/*
* GThumb
*
- * Copyright (C) 2001 The Free Software Foundation, Inc.
+ * Copyright (C) 2009 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
@@ -20,16 +20,31 @@
* Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
*/
-#include "gthumb-error.h"
+#include <config.h>
+#include <gtk/gtk.h>
-GQuark
-gthumb_error_quark (void)
+
+G_MODULE_EXPORT void
+gthumb_extension_activate (void)
+{
+}
+
+
+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)
{
- static GQuark quark;
-
- if (!quark)
- quark = g_quark_from_static_string ("gthumb_error");
-
- return quark;
}
diff --git a/extensions/image_rotation/transupp.c b/extensions/jpeg_utils/transupp.c
similarity index 100%
rename from extensions/image_rotation/transupp.c
rename to extensions/jpeg_utils/transupp.c
diff --git a/extensions/image_rotation/transupp.h b/extensions/jpeg_utils/transupp.h
similarity index 100%
rename from extensions/image_rotation/transupp.h
rename to extensions/jpeg_utils/transupp.h
diff --git a/extensions/list_tools/gth-script-editor-dialog.c b/extensions/list_tools/gth-script-editor-dialog.c
index ab6eb1c..b2f1be0 100644
--- a/extensions/list_tools/gth-script-editor-dialog.c
+++ b/extensions/list_tools/gth-script-editor-dialog.c
@@ -238,13 +238,13 @@ gth_script_editor_dialog_get_script (GthScriptEditorDialog *self,
NULL);
if (g_strcmp0 (gth_script_get_display_name (script), "") == 0) {
- *error = g_error_new (GTHUMB_ERROR, 0, _("No name specified"));
+ *error = g_error_new (GTH_ERROR, 0, _("No name specified"));
g_object_unref (script);
return NULL;
}
if (g_strcmp0 (gth_script_get_command (script), "") == 0) {
- *error = g_error_new (GTHUMB_ERROR, 0, _("No command specified"));
+ *error = g_error_new (GTH_ERROR, 0, _("No command specified"));
g_object_unref (script);
return NULL;
}
diff --git a/extensions/pixbuf_savers/Makefile.am b/extensions/pixbuf_savers/Makefile.am
new file mode 100644
index 0000000..fac5059
--- /dev/null
+++ b/extensions/pixbuf_savers/Makefile.am
@@ -0,0 +1,67 @@
+SUBDIRS = data
+
+extensiondir = $(libdir)/gthumb-2.0/extensions
+extension_LTLIBRARIES = libpixbuf_savers.la
+
+ENUM_TYPES = \
+ enum-types.h \
+ enum-types.c
+
+HEADER_FILES = \
+ preferences.h
+
+enum-types.h: $(HEADER_FILES) $(GLIB_MKENUMS)
+ $(GLIB_MKENUMS) \
+ --fhead "#ifndef ENUM_TYPES_H\n#define ENUM_TYPES_H\n\n#include <glib-object.h>\n\nG_BEGIN_DECLS\n" \
+ --fprod "/* enumerations from \"@filename \" */\n" \
+ --vhead "GType @enum_name _get_type (void);\n#define GTH_TYPE_ ENUMSHORT@ (@enum_name _get_type())\n" \
+ --ftail "G_END_DECLS\n\n#endif /* ENUM_TYPES_H */" \
+ $^> xgen-$(@F) \
+ && (cmp -s xgen-$(@F) enum-types.h || cp xgen-$(@F) enum-types.h ) \
+ && rm -f xgen-$(@F)
+
+enum-types.c: $(HEADER_FILES) enum-types.h
+ $(GLIB_MKENUMS) \
+ --fhead "#include <glib-object.h>\n" \
+ --fprod "\n/* enumerations from \"@filename \" */\n#include \"@filename \"" \
+ --vhead "GType\n enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G Type@Value values[] = {" \
+ --vprod " { @VALUENAME@, \"@VALUENAME \", \"@valuenick \" }," \
+ --vtail " { 0, NULL, NULL }\n };\n etype = g_ type@_register_static (\"@EnumName \", values);\n }\n return etype;\n}\n" \
+ $^> xgen-$(@F) \
+ && (cmp -s xgen-$(@F) enum-types.c || cp xgen-$(@F) enum-types.c ) \
+ && rm -f xgen-$(@F)
+
+libpixbuf_savers_la_SOURCES = \
+ $(ENUM_TYPES) \
+ $(HEADER_FILES) \
+ gth-jpeg-saver.c \
+ gth-jpeg-saver.h \
+ gth-png-saver.c \
+ gth-png-saver.h \
+ gth-tga-saver.c \
+ gth-tga-saver.h \
+ gth-tiff-saver.c \
+ gth-tiff-saver.h \
+ main.c \
+ preferences.c
+
+libpixbuf_savers_la_CFLAGS = $(GTHUMB_CFLAGS) $(CLUTTER_CFLAGS) $(DISABLE_DEPRECATED) $(WARNINGS) -I$(top_srcdir) -I$(top_builddir)/gthumb
+libpixbuf_savers_la_LDFLAGS = $(EXTENSION_LIBTOOL_FLAGS)
+libpixbuf_savers_la_LIBADD = $(GTHUMB_LIBS) $(TIFF_LIBS)
+libpixbuf_savers_la_DEPENDENCIES = $(top_builddir)/gthumb/gthumb$(EXEEXT)
+
+extensioninidir = $(extensiondir)
+extensionini_in_files = pixbuf_savers.extension.in.in
+extensionini_DATA = $(extensionini_in_files:.extension.in.in=.extension)
+
+%.extension.in: %.extension.in.in $(extension_LTLIBRARIES)
+ sed -e "s|%LIBRARY%|`. ./$(extension_LTLIBRARIES) && echo $$dlname`|" \
+ $< > $@
+
+%.extension: %.extension.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
+
+EXTRA_DIST = $(extensionini_in_files)
+
+DISTCLEANFILES = $(extensionini_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/extensions/pixbuf_savers/data/Makefile.am b/extensions/pixbuf_savers/data/Makefile.am
new file mode 100644
index 0000000..5b8c51c
--- /dev/null
+++ b/extensions/pixbuf_savers/data/Makefile.am
@@ -0,0 +1,18 @@
+SUBDIRS = ui
+
+schemadir = @GCONF_SCHEMA_FILE_DIR@
+schema_in_files = gthumb-pixbuf-savers.schemas.in
+schema_DATA = $(schema_in_files:.schemas.in=.schemas)
+
+ INTLTOOL_SCHEMAS_RULE@
+
+if GCONF_SCHEMAS_INSTALL
+install-data-local:
+ GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(top_builddir)/extensions/pixbuf_savers/data/$(schema_DATA)
+endif
+
+EXTRA_DIST = $(schema_in_files)
+
+CLEANFILES = $(schema_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/extensions/pixbuf_savers/data/gthumb-pixbuf-savers.schemas.in b/extensions/pixbuf_savers/data/gthumb-pixbuf-savers.schemas.in
new file mode 100644
index 0000000..3e4fb41
--- /dev/null
+++ b/extensions/pixbuf_savers/data/gthumb-pixbuf-savers.schemas.in
@@ -0,0 +1,143 @@
+<gconfschemafile>
+ <schemalist>
+
+ <schema>
+ <key>/schemas/apps/gthumb/ext/save_options/ask_options</key>
+ <applyto>/apps/gthumb/ext/save_options/ask_options</applyto>
+ <owner>gthumb</owner>
+ <type>bool</type>
+ <default>true</default>
+ <locale name="C">
+ <short></short>
+ <long>
+ </long>
+ </locale>
+ </schema>
+
+ <!-- JPEG Options -->
+
+ <schema>
+ <key>/schemas/apps/gthumb/save_options/jpeg/quality</key>
+ <applyto>/apps/gthumb/save_options/jpeg/quality</applyto>
+ <owner>gthumb</owner>
+ <type>int</type>
+ <default>85</default>
+ <locale name="C">
+ <short></short>
+ <long>
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/gthumb/save_options/jpeg/smoothing</key>
+ <applyto>/apps/gthumb/save_options/jpeg/smoothing</applyto>
+ <owner>gthumb</owner>
+ <type>int</type>
+ <default>0</default>
+ <locale name="C">
+ <short></short>
+ <long>
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/gthumb/save_options/jpeg/optimize</key>
+ <applyto>/apps/gthumb/save_options/jpeg/optimize</applyto>
+ <owner>gthumb</owner>
+ <type>bool</type>
+ <default>true</default>
+ <locale name="C">
+ <short></short>
+ <long>
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/gthumb/save_options/jpeg/pregressive</key>
+ <applyto>/apps/gthumb/save_options/jpeg/pregressive</applyto>
+ <owner>gthumb</owner>
+ <type>bool</type>
+ <default>false</default>
+ <locale name="C">
+ <short></short>
+ <long>
+ </long>
+ </locale>
+ </schema>
+
+ <!-- PNG Options -->
+
+ <schema>
+ <key>/schemas/apps/gthumb/save_options/png/compression_level</key>
+ <applyto>/apps/gthumb/save_options/png/compression_level</applyto>
+ <owner>gthumb</owner>
+ <type>int</type>
+ <default>6</default>
+ <locale name="C">
+ <short></short>
+ <long>
+ </long>
+ </locale>
+ </schema>
+
+ <!-- TGA Options -->
+
+ <schema>
+ <key>/schemas/apps/gthumb/save_options/tga/rle_compression</key>
+ <applyto>/apps/gthumb/save_options/tga/rle_compression</applyto>
+ <owner>gthumb</owner>
+ <type>bool</type>
+ <default>true</default>
+ <locale name="C">
+ <short></short>
+ <long>
+ </long>
+ </locale>
+ </schema>
+
+ <!-- TIFF Options -->
+
+ <schema>
+ <key>/schemas/apps/gthumb/save_options/tiff/compression</key>
+ <applyto>/apps/gthumb/save_options/tiff/compression</applyto>
+ <owner>gthumb</owner>
+ <type>string</type>
+ <default>deflate</default>
+ <locale name="C">
+ <short></short>
+ <long> Possible values are: none, deflate, jpeg.
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/gthumb/save_options/tiff/horizontal_resolution</key>
+ <applyto>/apps/gthumb/save_options/tiff/horizontal_resolution</applyto>
+ <owner>gthumb</owner>
+ <type>int</type>
+ <default>72</default>
+ <locale name="C">
+ <short></short>
+ <long>
+ </long>
+ </locale>
+ </schema>
+
+ <schema>
+ <key>/schemas/apps/gthumb/save_options/tiff/vertical_resolution</key>
+ <applyto>/apps/gthumb/save_options/tiff/vertical_resolution</applyto>
+ <owner>gthumb</owner>
+ <type>int</type>
+ <default>72</default>
+ <locale name="C">
+ <short></short>
+ <long>
+ </long>
+ </locale>
+ </schema>
+
+ </schemalist>
+</gconfschemafile>
diff --git a/extensions/pixbuf_savers/data/ui/Makefile.am b/extensions/pixbuf_savers/data/ui/Makefile.am
new file mode 100644
index 0000000..cf1d274
--- /dev/null
+++ b/extensions/pixbuf_savers/data/ui/Makefile.am
@@ -0,0 +1,10 @@
+uidir = $(datadir)/gthumb-2.0/ui
+ui_DATA = \
+ jpeg-options.ui \
+ png-options.ui \
+ save-options-preferences.ui \
+ tga-options.ui \
+ tiff-options.ui
+EXTRA_DIST = $(ui_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/extensions/pixbuf_savers/data/ui/jpeg-options.ui b/extensions/pixbuf_savers/data/ui/jpeg-options.ui
new file mode 100644
index 0000000..cb0c07c
--- /dev/null
+++ b/extensions/pixbuf_savers/data/ui/jpeg-options.ui
@@ -0,0 +1,120 @@
+<?xml version="1.0"?>
+<interface>
+ <!-- interface-requires gtk+ 2.12 -->
+ <!-- interface-naming-policy toplevel-contextual -->
+ <object class="GtkAdjustment" id="jpeg_quality_adjustment">
+ <property name="value">75</property>
+ <property name="upper">100</property>
+ <property name="step_increment">0.5</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkAdjustment" id="jpeg_smooth_adjustment">
+ <property name="upper">100</property>
+ <property name="step_increment">0.5</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkTable" id="jpeg_options">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="n_rows">4</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkCheckButton" id="jpeg_optimize_checkbutton">
+ <property name="label" translatable="yes">Opti_mize</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="jpeg_progressive_checkbutton">
+ <property name="label" translatable="yes">_Progressive</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label127">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Quality:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">jpeg_quality_hscale</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHScale" id="jpeg_quality_hscale">
+ <property name="width_request">150</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">jpeg_quality_adjustment</property>
+ <property name="digits">0</property>
+ <property name="value_pos">left</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHScale" id="jpeg_smooth_hscale">
+ <property name="width_request">150</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">jpeg_smooth_adjustment</property>
+ <property name="digits">0</property>
+ <property name="value_pos">left</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label130">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Smoothing:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">jpeg_smooth_hscale</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/extensions/pixbuf_savers/data/ui/png-options.ui b/extensions/pixbuf_savers/data/ui/png-options.ui
new file mode 100644
index 0000000..96dcde0
--- /dev/null
+++ b/extensions/pixbuf_savers/data/ui/png-options.ui
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<interface>
+ <!-- interface-requires gtk+ 2.12 -->
+ <!-- interface-naming-policy toplevel-contextual -->
+ <object class="GtkAdjustment" id="png_compression_adjustment">
+ <property name="value">6</property>
+ <property name="upper">9</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">1</property>
+ </object>
+ <object class="GtkVBox" id="png_options">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkHBox" id="hbox64">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label126">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.89999997615814209</property>
+ <property name="label" translatable="yes">Compression _level:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">png_compression_hscale</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHScale" id="png_compression_hscale">
+ <property name="width_request">100</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">png_compression_adjustment</property>
+ <property name="digits">0</property>
+ <property name="value_pos">left</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/extensions/pixbuf_savers/data/ui/save-options-preferences.ui b/extensions/pixbuf_savers/data/ui/save-options-preferences.ui
new file mode 100644
index 0000000..65c6bd2
--- /dev/null
+++ b/extensions/pixbuf_savers/data/ui/save-options-preferences.ui
@@ -0,0 +1,167 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkListStore" id="file_type_liststore">
+ <columns>
+ <!-- column-name gint1 -->
+ <column type="gint"/>
+ <!-- column-name GObject1 -->
+ <column type="GObject"/>
+ <!-- column-name gchararray1 -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkVBox" id="preferences_page">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkCheckButton" id="ask_options_checkbutton">
+ <property name="label" translatable="yes">_Ask the options before saving a file</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Default options:</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHPaned" id="hpaned1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="position">100</property>
+ <property name="position_set">True</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="file_type_treeview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="model">file_type_liststore</property>
+ <property name="headers_visible">False</property>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">2</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="resize">False</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="file_type_options_box">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="file_type_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="size" value="10000"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHSeparator" id="hseparator1">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="padding">6</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkNotebook" id="options_notebook">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="show_tabs">False</property>
+ <property name="show_border">False</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child type="tab">
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child type="tab">
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child type="tab">
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="resize">True</property>
+ <property name="shrink">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <object class="GtkTreeViewColumn" id="file_type_treeviewcolumn"/>
+</interface>
diff --git a/extensions/pixbuf_savers/data/ui/tga-options.ui b/extensions/pixbuf_savers/data/ui/tga-options.ui
new file mode 100644
index 0000000..993e8f1
--- /dev/null
+++ b/extensions/pixbuf_savers/data/ui/tga-options.ui
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<interface>
+ <!-- interface-requires gtk+ 2.12 -->
+ <!-- interface-naming-policy toplevel-contextual -->
+ <object class="GtkVBox" id="tga_options">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkCheckButton" id="tga_rle_compression_checkbutton">
+ <property name="label" translatable="yes">_RLE compression</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/extensions/pixbuf_savers/data/ui/tiff-options.ui b/extensions/pixbuf_savers/data/ui/tiff-options.ui
new file mode 100644
index 0000000..a5151b6
--- /dev/null
+++ b/extensions/pixbuf_savers/data/ui/tiff-options.ui
@@ -0,0 +1,280 @@
+<?xml version="1.0"?>
+<interface>
+ <!-- interface-requires gtk+ 2.12 -->
+ <!-- interface-naming-policy toplevel-contextual -->
+ <object class="GtkAdjustment" id="tiff_hdpi_adjustment">
+ <property name="value">72</property>
+ <property name="lower">1</property>
+ <property name="upper">10000</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkAdjustment" id="tiff_vdpi_adjustment">
+ <property name="value">72</property>
+ <property name="lower">1</property>
+ <property name="upper">10000</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ </object>
+ <object class="GtkVBox" id="tiff_options">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkVBox" id="vbox43">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label128">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes"><b>Compression</b></property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox65">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkLabel" id="label129">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"> </property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox44">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkRadioButton" id="tiff_comp_none_radiobutton">
+ <property name="label" translatable="yes">_No compression</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="tiff_comp_deflate_radiobutton">
+ <property name="label" translatable="yes">No_rmal (Deflate)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">tiff_comp_none_radiobutton</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="tiff_comp_jpeg_radiobutton">
+ <property name="label" translatable="yes">_Loss compression (JPEG)</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">tiff_comp_none_radiobutton</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox48">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label132">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes"><b>Resolution</b></property>
+ <property name="use_markup">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox66">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkLabel" id="label131">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"> </property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkTable" id="table12">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label133">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Horizontal:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label134">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Vertical:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox67">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkSpinButton" id="tiff_hdpi_spinbutton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="adjustment">tiff_hdpi_adjustment</property>
+ <property name="climb_rate">1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label135">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">dpi</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox68">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkSpinButton" id="tiff_vdpi_spinbutton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="adjustment">tiff_vdpi_adjustment</property>
+ <property name="climb_rate">1</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label136">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">dpi</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/extensions/pixbuf_savers/gth-jpeg-saver.c b/extensions/pixbuf_savers/gth-jpeg-saver.c
new file mode 100644
index 0000000..3ccef70
--- /dev/null
+++ b/extensions/pixbuf_savers/gth-jpeg-saver.c
@@ -0,0 +1,512 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#ifdef HAVE_LIBJPEG
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <setjmp.h>
+#include <string.h>
+#include <jpeglib.h>
+#include <extensions/jpeg_utils/jmemorydest.h>
+#endif /* HAVE_LIBJPEG */
+#include <glib/gi18n.h>
+#include <gthumb.h>
+#include "gth-jpeg-saver.h"
+#include "preferences.h"
+
+
+struct _GthJpegSaverPrivate {
+ GtkBuilder *builder;
+};
+
+
+static gpointer parent_class = NULL;
+
+
+static void
+gth_jpeg_saver_init (GthJpegSaver *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_JPEG_SAVER, GthJpegSaverPrivate);
+}
+
+
+static void
+gth_jpeg_saver_finalize (GObject *object)
+{
+ GthJpegSaver *self = GTH_JPEG_SAVER (object);
+
+ _g_object_unref (self->priv->builder);
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static GtkWidget *
+gth_jpeg_saver_get_control (GthPixbufSaver *base)
+{
+ GthJpegSaver *self = GTH_JPEG_SAVER (base);
+
+ if (self->priv->builder == NULL)
+ self->priv->builder = _gtk_builder_new_from_file ("jpeg-options.ui", "pixbuf_savers");
+
+ gtk_adjustment_set_value (GTK_ADJUSTMENT (_gtk_builder_get_widget (self->priv->builder, "jpeg_quality_adjustment")),
+ eel_gconf_get_integer (PREF_JPEG_QUALITY, 85));
+ gtk_adjustment_set_value (GTK_ADJUSTMENT (_gtk_builder_get_widget (self->priv->builder, "jpeg_smooth_adjustment")),
+ eel_gconf_get_integer (PREF_JPEG_SMOOTHING, 0));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (_gtk_builder_get_widget (self->priv->builder, "jpeg_optimize_checkbutton")),
+ eel_gconf_get_boolean (PREF_JPEG_OPTIMIZE, TRUE));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (_gtk_builder_get_widget (self->priv->builder, "jpeg_progressive_checkbutton")),
+ eel_gconf_get_boolean (PREF_JPEG_PROGRESSIVE, FALSE));
+
+ return _gtk_builder_get_widget (self->priv->builder, "jpeg_options");
+}
+
+
+static void
+gth_jpeg_saver_save_options (GthPixbufSaver *base)
+{
+ GthJpegSaver *self = GTH_JPEG_SAVER (base);
+
+ eel_gconf_set_integer (PREF_JPEG_QUALITY, (int) gtk_adjustment_get_value (GTK_ADJUSTMENT (_gtk_builder_get_widget (self->priv->builder, "jpeg_quality_adjustment"))));
+ eel_gconf_set_integer (PREF_JPEG_SMOOTHING, (int) gtk_adjustment_get_value (GTK_ADJUSTMENT (_gtk_builder_get_widget (self->priv->builder, "jpeg_smooth_adjustment"))));
+ eel_gconf_set_boolean (PREF_JPEG_OPTIMIZE, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (_gtk_builder_get_widget (self->priv->builder, "jpeg_optimize_checkbutton"))));
+ eel_gconf_set_boolean (PREF_JPEG_PROGRESSIVE, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (_gtk_builder_get_widget (self->priv->builder, "jpeg_progressive_checkbutton"))));
+}
+
+
+static gboolean
+gth_jpeg_saver_can_save (GthPixbufSaver *self,
+ const char *mime_type)
+{
+#ifdef HAVE_LIBJPEG
+
+ return g_content_type_equals (mime_type, "image/jpeg");
+
+#else /* ! HAVE_LIBJPEG */
+
+ GSList *formats;
+ GSList *scan;
+ GdkPixbufFormat *jpeg_format;
+
+ if (! g_content_type_equals (mime_type, "image/jpeg"))
+ return FALSE;
+
+ formats = gdk_pixbuf_get_formats ();
+ jpeg_format = NULL;
+ for (scan = formats; (jpeg_format == NULL) && (scan != NULL); scan = g_slist_next (scan)) {
+ GdkPixbufFormat *format = scan->data;
+ char **mime_types;
+ int i;
+
+ mime_types = gdk_pixbuf_format_get_mime_types (format);
+ for (i = 0; mime_types[i] != NULL; i++)
+ if (g_content_type_equals (mime_types[i], "image/jpeg"))
+ break;
+
+ if (mime_types[i] == NULL)
+ continue;
+
+ if (! gdk_pixbuf_format_is_writable (format))
+ continue;
+
+ jpeg_format = format;
+ }
+
+ return jpeg_format != NULL;
+
+#endif /* HAVE_LIBJPEG */
+}
+
+
+#ifdef HAVE_LIBJPEG
+
+
+/* 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 */
+}
+
+
+static gboolean
+_gdk_pixbuf_save_as_jpeg (GdkPixbuf *pixbuf,
+ char **buffer,
+ gsize *buffer_size,
+ char **keys,
+ char **values,
+ GError **error)
+{
+ struct jpeg_compress_struct cinfo;
+ struct error_handler_data jerr;
+ guchar *buf = NULL;
+ guchar *ptr;
+ guchar *pixels = NULL;
+ volatile int quality = 85; /* default; must be between 0 and 100 */
+ volatile int smoothing = 0;
+ volatile gboolean optimize = FALSE;
+ volatile gboolean progressive = FALSE;
+ int i, j;
+ int w, h = 0;
+ int rowstride = 0;
+ volatile int bpp;
+
+ if (keys && *keys) {
+ char **kiter = keys;
+ char **viter = values;
+
+ while (*kiter) {
+ if (strcmp (*kiter, "quality") == 0) {
+ char *endptr = NULL;
+ quality = strtol (*viter, &endptr, 10);
+
+ if (endptr == *viter) {
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_BAD_OPTION,
+ "JPEG quality must be a value between 0 and 100; value '%s' could not be parsed.",
+ *viter);
+
+ return FALSE;
+ }
+
+ if (quality < 0 || quality > 100) {
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_BAD_OPTION,
+ "JPEG quality must be a value between 0 and 100; value '%d' is not allowed.",
+ quality);
+
+ return FALSE;
+ }
+ }
+ else if (strcmp (*kiter, "smooth") == 0) {
+ char *endptr = NULL;
+ smoothing = strtol (*viter, &endptr, 10);
+
+ if (endptr == *viter) {
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_BAD_OPTION,
+ "JPEG smoothing must be a value between 0 and 100; value '%s' could not be parsed.",
+ *viter);
+
+ return FALSE;
+ }
+
+ if (smoothing < 0 || smoothing > 100) {
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_BAD_OPTION,
+ "JPEG smoothing must be a value between 0 and 100; value '%d' is not allowed.",
+ smoothing);
+
+ return FALSE;
+ }
+ }
+ else if (strcmp (*kiter, "optimize") == 0) {
+ if (strcmp (*viter, "yes") == 0)
+ optimize = TRUE;
+ else if (strcmp (*viter, "no") == 0)
+ optimize = FALSE;
+ else {
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_BAD_OPTION,
+ "JPEG optimize option must be 'yes' or 'no', value is: %s", *viter);
+
+ return FALSE;
+ }
+ }
+ else if (strcmp (*kiter, "progressive") == 0) {
+ if (strcmp (*viter, "yes") == 0)
+ progressive = TRUE;
+ else if (strcmp (*viter, "no") == 0)
+ progressive = FALSE;
+ else {
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_BAD_OPTION,
+ "JPEG progressive option must be 'yes' or 'no', value is: %s", *viter);
+
+ return FALSE;
+ }
+ }
+ else {
+ g_warning ("Bad option name '%s' passed to JPEG saver", *kiter);
+ return FALSE;
+ }
+
+ ++kiter;
+ ++viter;
+ }
+ }
+
+ rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+ w = gdk_pixbuf_get_width (pixbuf);
+ h = gdk_pixbuf_get_height (pixbuf);
+ if (gdk_pixbuf_get_has_alpha (pixbuf))
+ bpp = 4;
+ else
+ bpp = 3;
+ pixels = gdk_pixbuf_get_pixels (pixbuf);
+ g_return_val_if_fail (pixels != NULL, FALSE);
+
+ /* allocate a small buffer to convert image data */
+
+ buf = g_try_malloc (w * bpp * sizeof (guchar));
+ if (! buf) {
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
+ "Couldn't allocate memory for loading JPEG file");
+ return FALSE;
+ }
+
+ /* set up error handling */
+
+ cinfo.err = jpeg_std_error (&(jerr.pub));
+ jerr.pub.error_exit = fatal_error_handler;
+ jerr.pub.output_message = output_message_handler;
+ jerr.error = error;
+ if (sigsetjmp (jerr.setjmp_buffer, 1)) {
+ jpeg_destroy_compress (&cinfo);
+ g_free (buf);
+ return FALSE;
+ }
+
+ /* setup compress params */
+
+ jpeg_create_compress (&cinfo);
+ _jpeg_memory_dest (&cinfo, (void **)buffer, buffer_size);
+
+ cinfo.image_width = w;
+ cinfo.image_height = h;
+ cinfo.input_components = 3;
+ cinfo.in_color_space = JCS_RGB;
+
+ /* set up jepg compression parameters */
+
+ jpeg_set_defaults (&cinfo);
+ jpeg_set_quality (&cinfo, quality, TRUE);
+ cinfo.smoothing_factor = smoothing;
+ cinfo.optimize_coding = optimize;
+
+#ifdef HAVE_PROGRESSIVE_JPEG
+ if (progressive)
+ jpeg_simple_progression (&cinfo);
+#endif /* HAVE_PROGRESSIVE_JPEG */
+
+ jpeg_start_compress (&cinfo, TRUE);
+ /* get the start pointer */
+ ptr = pixels;
+ /* go one scanline at a time... and save */
+ i = 0;
+ while (cinfo.next_scanline < cinfo.image_height) {
+ JSAMPROW *jbuf;
+
+ /* convert scanline from ARGB to RGB packed */
+ for (j = 0; j < w; j++)
+ memcpy (&(buf[j * 3]),
+ &(ptr[i * rowstride + j * bpp]),
+ 3);
+
+ /* write scanline */
+ jbuf = (JSAMPROW *)(&buf);
+ jpeg_write_scanlines (&cinfo, jbuf, 1);
+ i++;
+ }
+
+ /* finish off */
+
+ jpeg_finish_compress (&cinfo);
+ jpeg_destroy_compress(&cinfo);
+ g_free (buf);
+
+ return TRUE;
+}
+
+
+#endif /* HAVE_LIBJPEG */
+
+
+static gboolean
+gth_jpeg_saver_save_pixbuf (GthPixbufSaver *self,
+ GdkPixbuf *pixbuf,
+ char **buffer,
+ gsize *buffer_size,
+ const char *mime_type,
+ GError **error)
+{
+#ifdef HAVE_LIBJPEG
+
+ char **option_keys;
+ char **option_values;
+ int i = -1;
+ int i_value;
+ gboolean result;
+
+ option_keys = g_malloc (sizeof (char *) * 5);
+ option_values = g_malloc (sizeof (char *) * 5);
+
+ i++;
+ i_value = eel_gconf_get_integer (PREF_JPEG_QUALITY, 85);
+ option_keys[i] = g_strdup ("quality");
+ option_values[i] = g_strdup_printf ("%d", i_value);
+
+ i++;
+ i_value = eel_gconf_get_integer (PREF_JPEG_SMOOTHING, 0);
+ option_keys[i] = g_strdup ("smooth");
+ option_values[i] = g_strdup_printf ("%d", i_value);
+
+ i++;
+ i_value = eel_gconf_get_boolean (PREF_JPEG_OPTIMIZE, TRUE);
+ option_keys[i] = g_strdup ("optimize");
+ option_values[i] = g_strdup (i_value != 0 ? "yes" : "no");
+
+ i++;
+ i_value = eel_gconf_get_boolean (PREF_JPEG_PROGRESSIVE, TRUE);
+ option_keys[i] = g_strdup ("progressive");
+ option_values[i] = g_strdup (i_value != 0 ? "yes" : "no");
+
+ i++;
+ option_keys[i] = NULL;
+ option_values[i] = NULL;
+
+ result = _gdk_pixbuf_save_as_jpeg (pixbuf,
+ buffer,
+ buffer_size,
+ option_keys,
+ option_values,
+ error);
+
+ g_strfreev (option_keys);
+ g_strfreev (option_values);
+
+#else /* ! HAVE_LIBJPEG */
+
+ char *pixbuf_type;
+ gboolean result;
+
+ pixbuf_type = get_pixbuf_type_from_mime_type (mime_type);
+ result = gdk_pixbuf_save_to_bufferv (pixbuf,
+ buffer,
+ buffer_size,
+ pixbuf_type,
+ NULL,
+ NULL,
+ error);
+
+ g_free (pixbuf_type);
+
+#endif /* HAVE_LIBJPEG */
+
+ return result;
+}
+
+
+static void
+gth_jpeg_saver_class_init (GthJpegSaverClass *klass)
+{
+ GObjectClass *object_class;
+ GthPixbufSaverClass *pixbuf_saver_class;
+
+ parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (GthJpegSaverPrivate));
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gth_jpeg_saver_finalize;
+
+ pixbuf_saver_class = GTH_PIXBUF_SAVER_CLASS (klass);
+ pixbuf_saver_class->id = "jpeg";
+ pixbuf_saver_class->display_name = _("JPEG");
+ pixbuf_saver_class->get_control = gth_jpeg_saver_get_control;
+ pixbuf_saver_class->save_options = gth_jpeg_saver_save_options;
+ pixbuf_saver_class->can_save = gth_jpeg_saver_can_save;
+ pixbuf_saver_class->save_pixbuf = gth_jpeg_saver_save_pixbuf;
+}
+
+
+GType
+gth_jpeg_saver_get_type (void)
+{
+ static GType type = 0;
+
+ if (! type) {
+ GTypeInfo type_info = {
+ sizeof (GthJpegSaverClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gth_jpeg_saver_class_init,
+ NULL,
+ NULL,
+ sizeof (GthJpegSaver),
+ 0,
+ (GInstanceInitFunc) gth_jpeg_saver_init
+ };
+
+ type = g_type_register_static (GTH_TYPE_PIXBUF_SAVER,
+ "GthJpegSaver",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
diff --git a/extensions/pixbuf_savers/gth-jpeg-saver.h b/extensions/pixbuf_savers/gth-jpeg-saver.h
new file mode 100644
index 0000000..0592a4f
--- /dev/null
+++ b/extensions/pixbuf_savers/gth-jpeg-saver.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTH_JPEG_SAVER_H
+#define GTH_JPEG_SAVER_H
+
+#include <gtk/gtk.h>
+#include <gthumb.h>
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_JPEG_SAVER (gth_jpeg_saver_get_type ())
+#define GTH_JPEG_SAVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_JPEG_SAVER, GthJpegSaver))
+#define GTH_JPEG_SAVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_JPEG_SAVER_TYPE, GthJpegSaverClass))
+#define GTH_IS_JPEG_SAVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_JPEG_SAVER))
+#define GTH_IS_JPEG_SAVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_JPEG_SAVER))
+#define GTH_JPEG_SAVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTH_TYPE_JPEG_SAVER, GthJpegSaverClass))
+
+typedef struct _GthJpegSaver GthJpegSaver;
+typedef struct _GthJpegSaverClass GthJpegSaverClass;
+typedef struct _GthJpegSaverPrivate GthJpegSaverPrivate;
+
+struct _GthJpegSaver
+{
+ GthPixbufSaver __parent;
+ GthJpegSaverPrivate *priv;
+};
+
+struct _GthJpegSaverClass
+{
+ GthPixbufSaverClass __parent_class;
+};
+
+GType gth_jpeg_saver_get_type (void);
+
+G_END_DECLS
+
+#endif /* GTH_JPEG_SAVER_H */
diff --git a/extensions/pixbuf_savers/gth-png-saver.c b/extensions/pixbuf_savers/gth-png-saver.c
new file mode 100644
index 0000000..ce6996c
--- /dev/null
+++ b/extensions/pixbuf_savers/gth-png-saver.c
@@ -0,0 +1,179 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <glib/gi18n.h>
+#include <gthumb.h>
+#include "gth-png-saver.h"
+#include "preferences.h"
+
+
+struct _GthPngSaverPrivate {
+ GtkBuilder *builder;
+};
+
+
+static gpointer parent_class = NULL;
+
+
+static void
+gth_png_saver_init (GthPngSaver *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_PNG_SAVER, GthPngSaverPrivate);
+}
+
+
+static void
+gth_png_saver_finalize (GObject *object)
+{
+ GthPngSaver *self = GTH_PNG_SAVER (object);
+
+ _g_object_unref (self->priv->builder);
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static GtkWidget *
+gth_png_saver_get_control (GthPixbufSaver *base)
+{
+ GthPngSaver *self = GTH_PNG_SAVER (base);
+
+ if (self->priv->builder == NULL)
+ self->priv->builder = _gtk_builder_new_from_file ("png-options.ui", "pixbuf_savers");
+
+ gtk_adjustment_set_value (GTK_ADJUSTMENT (_gtk_builder_get_widget (self->priv->builder, "png_compression_adjustment")),
+ eel_gconf_get_integer (PREF_PNG_COMPRESSION_LEVEL, 6));
+
+ return _gtk_builder_get_widget (self->priv->builder, "png_options");
+}
+
+
+static void
+gth_png_saver_save_options (GthPixbufSaver *base)
+{
+ GthPngSaver *self = GTH_PNG_SAVER (base);
+
+ eel_gconf_set_integer (PREF_PNG_COMPRESSION_LEVEL, (int) gtk_adjustment_get_value (GTK_ADJUSTMENT (_gtk_builder_get_widget (self->priv->builder, "png_compression_adjustment"))));
+}
+
+
+static gboolean
+gth_png_saver_can_save (GthPixbufSaver *self,
+ const char *mime_type)
+{
+ return g_content_type_equals (mime_type, "image/png");
+}
+
+
+static gboolean
+gth_png_saver_save_pixbuf (GthPixbufSaver *self,
+ GdkPixbuf *pixbuf,
+ char **buffer,
+ gsize *buffer_size,
+ const char *mime_type,
+ GError **error)
+{
+ char *pixbuf_type;
+ char **option_keys;
+ char **option_values;
+ int i = -1;
+ int i_value;
+ gboolean result;
+
+ pixbuf_type = get_pixbuf_type_from_mime_type (mime_type);
+
+ option_keys = g_malloc (sizeof (char *) * 2);
+ option_values = g_malloc (sizeof (char *) * 2);
+
+ i++;
+ i_value = eel_gconf_get_integer (PREF_PNG_COMPRESSION_LEVEL, 6);
+ option_keys[i] = g_strdup ("compression");;
+ option_values[i] = g_strdup_printf ("%d", i_value);
+
+ i++;
+ option_keys[i] = NULL;
+ option_values[i] = NULL;
+
+ result = gdk_pixbuf_save_to_bufferv (pixbuf,
+ buffer,
+ buffer_size,
+ pixbuf_type,
+ option_keys,
+ option_values,
+ error);
+
+ g_strfreev (option_keys);
+ g_strfreev (option_values);
+ g_free (pixbuf_type);
+
+ return result;
+}
+
+
+static void
+gth_png_saver_class_init (GthPngSaverClass *klass)
+{
+ GObjectClass *object_class;
+ GthPixbufSaverClass *pixbuf_saver_class;
+
+ parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (GthPngSaverPrivate));
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gth_png_saver_finalize;
+
+ pixbuf_saver_class = GTH_PIXBUF_SAVER_CLASS (klass);
+ pixbuf_saver_class->id = "png";
+ pixbuf_saver_class->display_name = _("PNG");
+ pixbuf_saver_class->get_control = gth_png_saver_get_control;
+ pixbuf_saver_class->save_options = gth_png_saver_save_options;
+ pixbuf_saver_class->can_save = gth_png_saver_can_save;
+ pixbuf_saver_class->save_pixbuf = gth_png_saver_save_pixbuf;
+}
+
+
+GType
+gth_png_saver_get_type (void)
+{
+ static GType type = 0;
+
+ if (! type) {
+ GTypeInfo type_info = {
+ sizeof (GthPngSaverClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gth_png_saver_class_init,
+ NULL,
+ NULL,
+ sizeof (GthPngSaver),
+ 0,
+ (GInstanceInitFunc) gth_png_saver_init
+ };
+
+ type = g_type_register_static (GTH_TYPE_PIXBUF_SAVER,
+ "GthPngSaver",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
diff --git a/extensions/pixbuf_savers/gth-png-saver.h b/extensions/pixbuf_savers/gth-png-saver.h
new file mode 100644
index 0000000..a871fa6
--- /dev/null
+++ b/extensions/pixbuf_savers/gth-png-saver.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTH_PNG_SAVER_H
+#define GTH_PNG_SAVER_H
+
+#include <gtk/gtk.h>
+#include <gthumb.h>
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_PNG_SAVER (gth_png_saver_get_type ())
+#define GTH_PNG_SAVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_PNG_SAVER, GthPngSaver))
+#define GTH_PNG_SAVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_PNG_SAVER_TYPE, GthPngSaverClass))
+#define GTH_IS_PNG_SAVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_PNG_SAVER))
+#define GTH_IS_PNG_SAVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_PNG_SAVER))
+#define GTH_PNG_SAVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTH_TYPE_PNG_SAVER, GthPngSaverClass))
+
+typedef struct _GthPngSaver GthPngSaver;
+typedef struct _GthPngSaverClass GthPngSaverClass;
+typedef struct _GthPngSaverPrivate GthPngSaverPrivate;
+
+struct _GthPngSaver
+{
+ GthPixbufSaver __parent;
+ GthPngSaverPrivate *priv;
+};
+
+struct _GthPngSaverClass
+{
+ GthPixbufSaverClass __parent_class;
+};
+
+GType gth_png_saver_get_type (void);
+
+G_END_DECLS
+
+#endif /* GTH_PNG_SAVER_H */
diff --git a/extensions/pixbuf_savers/gth-tga-saver.c b/extensions/pixbuf_savers/gth-tga-saver.c
new file mode 100644
index 0000000..7fdc941
--- /dev/null
+++ b/extensions/pixbuf_savers/gth-tga-saver.c
@@ -0,0 +1,414 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <glib/gi18n.h>
+#include <gthumb.h>
+#include "gth-tga-saver.h"
+#include "preferences.h"
+
+
+struct _GthTgaSaverPrivate {
+ GtkBuilder *builder;
+};
+
+
+static gpointer parent_class = NULL;
+
+
+static void
+gth_tga_saver_init (GthTgaSaver *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_TGA_SAVER, GthTgaSaverPrivate);
+}
+
+
+static void
+gth_tga_saver_finalize (GObject *object)
+{
+ GthTgaSaver *self = GTH_TGA_SAVER (object);
+
+ _g_object_unref (self->priv->builder);
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static GtkWidget *
+gth_tga_saver_get_control (GthPixbufSaver *base)
+{
+ GthTgaSaver *self = GTH_TGA_SAVER (base);
+
+ if (self->priv->builder == NULL)
+ self->priv->builder = _gtk_builder_new_from_file ("tga-options.ui", "pixbuf_savers");
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (_gtk_builder_get_widget (self->priv->builder, "tga_rle_compression_checkbutton")),
+ eel_gconf_get_boolean (PREF_TGA_RLE_COMPRESSION, TRUE));
+
+ return _gtk_builder_get_widget (self->priv->builder, "tga_options");
+}
+
+
+static void
+gth_tga_saver_save_options (GthPixbufSaver *base)
+{
+ GthTgaSaver *self = GTH_TGA_SAVER (base);
+
+ eel_gconf_set_boolean (PREF_TGA_RLE_COMPRESSION, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (_gtk_builder_get_widget (self->priv->builder, "tga_rle_compression_checkbutton"))));
+}
+
+
+static gboolean
+gth_tga_saver_can_save (GthPixbufSaver *self,
+ const char *mime_type)
+{
+ return g_content_type_equals (mime_type, "image/tga") || g_content_type_equals (mime_type, "image/x-tga");
+}
+
+
+/* -- _gdk_pixbuf_save_as_tga -- */
+
+
+/* TRUEVISION-XFILE magic signature string */
+static guchar magic[18] = {
+ 0x54, 0x52, 0x55, 0x45, 0x56, 0x49, 0x53, 0x49, 0x4f,
+ 0x4e, 0x2d, 0x58, 0x46, 0x49, 0x4c, 0x45, 0x2e, 0x0
+};
+
+
+static gboolean
+rle_write (GthBufferData *buffer_data,
+ guchar *buffer,
+ guint width,
+ guint bytes,
+ GError **error)
+{
+ int repeat = 0;
+ int direct = 0;
+ guchar *from = buffer;
+ guint x;
+
+ for (x = 1; x < width; ++x) {
+ if (memcmp (buffer, buffer + bytes, bytes)) {
+ /* next pixel is different */
+ if (repeat) {
+ gth_buffer_data_putc (buffer_data, 128 + repeat, error);
+ gth_buffer_data_write (buffer_data, from, bytes, error);
+ from = buffer + bytes; /* point to first different pixel */
+ repeat = 0;
+ direct = 0;
+ }
+ else
+ direct += 1;
+ }
+ else {
+ /* next pixel is the same */
+ if (direct) {
+ gth_buffer_data_putc (buffer_data, direct - 1, error);
+ gth_buffer_data_write (buffer_data, from, bytes * direct, error);
+ from = buffer; /* point to first identical pixel */
+ direct = 0;
+ repeat = 1;
+ }
+ else
+ repeat += 1;
+ }
+
+ if (repeat == 128) {
+ gth_buffer_data_putc (buffer_data, 255, error);
+ gth_buffer_data_write (buffer_data, from, bytes, error);
+ from = buffer + bytes;
+ direct = 0;
+ repeat = 0;
+ }
+ else if (direct == 128) {
+ gth_buffer_data_putc (buffer_data, 127, error);
+ gth_buffer_data_write (buffer_data, from, bytes * direct, error);
+ from = buffer + bytes;
+ direct = 0;
+ repeat = 0;
+ }
+
+ buffer += bytes;
+ }
+
+ if (repeat > 0) {
+ gth_buffer_data_putc (buffer_data, 128 + repeat, error);
+ gth_buffer_data_write (buffer_data, from, bytes, error);
+ }
+ else {
+ gth_buffer_data_putc (buffer_data, direct, error);
+ gth_buffer_data_write (buffer_data, from, bytes * (direct + 1), error);
+ }
+
+ return TRUE;
+}
+
+
+static void
+bgr2rgb (guchar *dest,
+ guchar *src,
+ guint width,
+ guint bytes,
+ guint alpha)
+{
+ guint x;
+
+ if (alpha)
+ for (x = 0; x < width; x++) {
+ *(dest++) = src[2];
+ *(dest++) = src[1];
+ *(dest++) = src[0];
+ *(dest++) = src[3];
+
+ src += bytes;
+ }
+ else
+ for (x = 0; x < width; x++) {
+ *(dest++) = src[2];
+ *(dest++) = src[1];
+ *(dest++) = src[0];
+
+ src += bytes;
+ }
+}
+
+
+static gboolean
+_gdk_pixbuf_save_as_tga (GdkPixbuf *pixbuf,
+ char **buffer,
+ gsize *buffer_size,
+ char **keys,
+ char **values,
+ GError **error)
+{
+ GthBufferData *buffer_data;
+ int out_bpp = 0;
+ int row;
+ guchar header[18];
+ guchar footer[26];
+ gboolean rle_compression;
+ gboolean alpha;
+ guchar *pixels, *ptr, *buf;
+ int width, height;
+ int rowstride;
+
+ rle_compression = TRUE;
+
+ if (keys && *keys) {
+ char **kiter = keys;
+ char **viter = values;
+
+ while (*kiter) {
+ if (strcmp (*kiter, "compression") == 0) {
+ if (*viter == NULL) {
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_BAD_OPTION,
+ "Must specify a compression type");
+ return FALSE;
+ }
+
+ if (strcmp (*viter, "none") == 0)
+ rle_compression = FALSE;
+
+ else if (strcmp (*viter, "rle") == 0)
+ rle_compression = TRUE;
+
+ else {
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_BAD_OPTION,
+ "Unsupported compression type passed to the TGA saver");
+ return FALSE;
+ }
+ }
+ else {
+ g_warning ("Bad option name '%s' passed to the TGA saver", *kiter);
+ return FALSE;
+ }
+
+ ++kiter;
+ ++viter;
+ }
+ }
+
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+ alpha = gdk_pixbuf_get_has_alpha (pixbuf);
+ pixels = gdk_pixbuf_get_pixels (pixbuf);
+ rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+
+ buffer_data = gth_buffer_data_new ();
+
+ /* write the header */
+
+ header[0] = 0; /* No image identifier / description */
+ header[1] = 0;
+ header[2] = rle_compression ? 10 : 2;
+ header[3] = header[4] = header[5] = header[6] = header[7] = 0;
+ header[8] = header[9] = 0; /* xorigin */
+ header[10] = header[11] = 0; /* yorigin */
+ header[12] = width % 256;
+ header[13] = width / 256;
+ header[14] = height % 256;
+ header[15] = height / 256;
+ if (alpha) {
+ out_bpp = 4;
+ header[16] = 32; /* bpp */
+ header[17] = 0x28; /* alpha + orientation */
+ }
+ else {
+ out_bpp = 3;
+ header[16] = 24; /* bpp */
+ header[17] = 0x20; /* alpha + orientation */
+ }
+ gth_buffer_data_write (buffer_data, header, sizeof (header), error);
+
+ /* allocate a small buffer to convert image data */
+ buf = g_try_malloc (width * out_bpp * sizeof (guchar));
+ if (! buf) {
+ g_set_error_literal (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
+ _("Insufficient memory"));
+ return FALSE;
+ }
+
+ ptr = pixels;
+ for (row = 0; row < height; ++row) {
+ bgr2rgb (buf, ptr, width, out_bpp, alpha);
+
+ if (rle_compression)
+ rle_write (buffer_data, buf, width, out_bpp, error);
+ else
+ gth_buffer_data_write (buffer_data, buf, width * out_bpp, error);
+
+ ptr += rowstride;
+ }
+
+ g_free (buf);
+
+ /* write the footer */
+
+ memset (footer, 0, 8); /* No extensions, no developer directory */
+ memcpy (footer + 8, magic, sizeof (magic)); /* magic signature */
+ gth_buffer_data_write (buffer_data, footer, sizeof (footer), error);
+
+ gth_buffer_data_get (buffer_data, buffer, buffer_size);
+ gth_buffer_data_free (buffer_data, FALSE);
+
+ return TRUE;
+}
+
+
+static gboolean
+gth_tga_saver_save_pixbuf (GthPixbufSaver *self,
+ GdkPixbuf *pixbuf,
+ char **buffer,
+ gsize *buffer_size,
+ const char *mime_type,
+ GError **error)
+{
+ char *pixbuf_type;
+ char **option_keys;
+ char **option_values;
+ int i = -1;
+ int i_value;
+ gboolean result;
+
+ pixbuf_type = get_pixbuf_type_from_mime_type (mime_type);
+
+ option_keys = g_malloc (sizeof (char *) * 2);
+ option_values = g_malloc (sizeof (char *) * 2);
+
+ i++;
+ i_value = eel_gconf_get_integer (PREF_PNG_COMPRESSION_LEVEL, 6);
+ option_keys[i] = g_strdup ("compression");;
+ option_values[i] = g_strdup_printf ("%d", i_value);
+
+ i++;
+ option_keys[i] = NULL;
+ option_values[i] = NULL;
+
+ result = _gdk_pixbuf_save_as_tga (pixbuf,
+ buffer,
+ buffer_size,
+ option_keys,
+ option_values,
+ error);
+
+ g_strfreev (option_keys);
+ g_strfreev (option_values);
+ g_free (pixbuf_type);
+
+ return result;
+}
+
+
+static void
+gth_tga_saver_class_init (GthTgaSaverClass *klass)
+{
+ GObjectClass *object_class;
+ GthPixbufSaverClass *pixbuf_saver_class;
+
+ parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (GthTgaSaverPrivate));
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gth_tga_saver_finalize;
+
+ pixbuf_saver_class = GTH_PIXBUF_SAVER_CLASS (klass);
+ pixbuf_saver_class->id = "tga";
+ pixbuf_saver_class->display_name = _("TGA");
+ pixbuf_saver_class->get_control = gth_tga_saver_get_control;
+ pixbuf_saver_class->save_options = gth_tga_saver_save_options;
+ pixbuf_saver_class->can_save = gth_tga_saver_can_save;
+ pixbuf_saver_class->save_pixbuf = gth_tga_saver_save_pixbuf;
+}
+
+
+GType
+gth_tga_saver_get_type (void)
+{
+ static GType type = 0;
+
+ if (! type) {
+ GTypeInfo type_info = {
+ sizeof (GthTgaSaverClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gth_tga_saver_class_init,
+ NULL,
+ NULL,
+ sizeof (GthTgaSaver),
+ 0,
+ (GInstanceInitFunc) gth_tga_saver_init
+ };
+
+ type = g_type_register_static (GTH_TYPE_PIXBUF_SAVER,
+ "GthTgaSaver",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
diff --git a/extensions/pixbuf_savers/gth-tga-saver.h b/extensions/pixbuf_savers/gth-tga-saver.h
new file mode 100644
index 0000000..11f61a6
--- /dev/null
+++ b/extensions/pixbuf_savers/gth-tga-saver.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTH_TGA_SAVER_H
+#define GTH_TGA_SAVER_H
+
+#include <gtk/gtk.h>
+#include <gthumb.h>
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_TGA_SAVER (gth_tga_saver_get_type ())
+#define GTH_TGA_SAVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_TGA_SAVER, GthTgaSaver))
+#define GTH_TGA_SAVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_TGA_SAVER, GthTgaSaverClass))
+#define GTH_IS_TGA_SAVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_TGA_SAVER))
+#define GTH_IS_TGA_SAVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_TGA_SAVER))
+#define GTH_TGA_SAVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTH_TYPE_TGA_SAVER, GthTgaSaverClass))
+
+typedef struct _GthTgaSaver GthTgaSaver;
+typedef struct _GthTgaSaverClass GthTgaSaverClass;
+typedef struct _GthTgaSaverPrivate GthTgaSaverPrivate;
+
+struct _GthTgaSaver
+{
+ GthPixbufSaver __parent;
+ GthTgaSaverPrivate *priv;
+};
+
+struct _GthTgaSaverClass
+{
+ GthPixbufSaverClass __parent_class;
+};
+
+GType gth_tga_saver_get_type (void);
+
+G_END_DECLS
+
+#endif /* GTH_TGA_SAVER_H */
diff --git a/extensions/pixbuf_savers/gth-tiff-saver.c b/extensions/pixbuf_savers/gth-tiff-saver.c
new file mode 100644
index 0000000..933c96c
--- /dev/null
+++ b/extensions/pixbuf_savers/gth-tiff-saver.c
@@ -0,0 +1,555 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#ifdef HAVE_LIBTIFF
+#include <tiffio.h>
+#endif /* HAVE_LIBTIFF */
+#include <glib/gi18n.h>
+#include <gthumb.h>
+#include "enum-types.h"
+#include "gth-tiff-saver.h"
+#include "preferences.h"
+
+
+struct _GthTiffSaverPrivate {
+ GtkBuilder *builder;
+};
+
+
+static gpointer parent_class = NULL;
+
+
+static void
+gth_tiff_saver_init (GthTiffSaver *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_TIFF_SAVER, GthTiffSaverPrivate);
+}
+
+
+static void
+gth_tiff_saver_finalize (GObject *object)
+{
+ GthTiffSaver *self = GTH_TIFF_SAVER (object);
+
+ _g_object_unref (self->priv->builder);
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static GtkWidget *
+gth_tiff_saver_get_control (GthPixbufSaver *base)
+{
+#ifdef HAVE_LIBTIFF
+
+ GthTiffSaver *self = GTH_TIFF_SAVER (base);
+ GthTiffCompression compression_type;
+
+ if (self->priv->builder == NULL)
+ self->priv->builder = _gtk_builder_new_from_file ("tiff-options.ui", "pixbuf_savers");
+
+ compression_type = eel_gconf_get_enum (PREF_TIFF_COMPRESSION, GTH_TYPE_TIFF_COMPRESSION, GTH_TIFF_COMPRESSION_DEFLATE);
+ switch (compression_type) {
+ case GTH_TIFF_COMPRESSION_NONE:
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (_gtk_builder_get_widget (self->priv->builder, "tiff_comp_none_radiobutton")), TRUE);
+ break;
+ case GTH_TIFF_COMPRESSION_DEFLATE:
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (_gtk_builder_get_widget (self->priv->builder, "tiff_comp_deflate_radiobutton")), TRUE);
+ break;
+ case GTH_TIFF_COMPRESSION_JPEG:
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (_gtk_builder_get_widget (self->priv->builder, "tiff_comp_jpeg_radiobutton")), TRUE);
+ break;
+ }
+
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (_gtk_builder_get_widget (self->priv->builder, "tiff_hdpi_spinbutton")), eel_gconf_get_integer (PREF_TIFF_HORIZONTAL_RES, 72));
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (_gtk_builder_get_widget (self->priv->builder, "tiff_vdpi_spinbutton")), eel_gconf_get_integer (PREF_TIFF_VERTICAL_RES, 72));
+
+ return _gtk_builder_get_widget (self->priv->builder, "tiff_options");
+
+#else /* ! HAVE_LIBTIFF */
+
+ return GTH_PIXBUF_SAVER_CLASS (parent_class)->get_control (base);
+
+#endif /* HAVE_LIBTIFF */
+}
+
+
+static void
+gth_tiff_saver_save_options (GthPixbufSaver *base)
+{
+#ifdef HAVE_LIBTIFF
+
+ GthTiffSaver *self = GTH_TIFF_SAVER (base);
+ GthTiffCompression compression_type;
+
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (_gtk_builder_get_widget (self->priv->builder, "tiff_comp_none_radiobutton"))))
+ compression_type = GTH_TIFF_COMPRESSION_NONE;
+ else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (_gtk_builder_get_widget (self->priv->builder, "tiff_comp_deflate_radiobutton"))))
+ compression_type = GTH_TIFF_COMPRESSION_DEFLATE;
+ else
+ compression_type = GTH_TIFF_COMPRESSION_JPEG;
+ eel_gconf_set_enum (PREF_TIFF_COMPRESSION, GTH_TYPE_TIFF_COMPRESSION, compression_type);
+
+ eel_gconf_set_integer (PREF_TIFF_HORIZONTAL_RES, (int) gtk_spin_button_get_value (GTK_SPIN_BUTTON (_gtk_builder_get_widget (self->priv->builder, "tiff_hdpi_spinbutton"))));
+ eel_gconf_set_integer (PREF_TIFF_VERTICAL_RES, (int) gtk_spin_button_get_value (GTK_SPIN_BUTTON (_gtk_builder_get_widget (self->priv->builder, "tiff_vdpi_spinbutton"))));
+
+#endif /* HAVE_LIBTIFF */
+}
+
+
+static gboolean
+gth_tiff_saver_can_save (GthPixbufSaver *self,
+ const char *mime_type)
+{
+#ifdef HAVE_LIBTIFF
+
+ return g_content_type_equals (mime_type, "image/tiff");
+
+#else /* ! HAVE_LIBTIFF */
+
+ GSList *formats;
+ GSList *scan;
+ GdkPixbufFormat *tiff_format;
+
+ if (! g_content_type_equals (mime_type, "image/tiff"))
+ return FALSE;
+
+ formats = gdk_pixbuf_get_formats ();
+ tiff_format = NULL;
+ for (scan = formats; (tiff_format == NULL) && (scan != NULL); scan = g_slist_next (scan)) {
+ GdkPixbufFormat *format = scan->data;
+ char **mime_types;
+ int i;
+
+ mime_types = gdk_pixbuf_format_get_mime_types (format);
+ for (i = 0; mime_types[i] != NULL; i++)
+ if (g_content_type_equals (mime_types[i], "image/tiff"))
+ break;
+
+ if (mime_types[i] == NULL)
+ continue;
+
+ if (! gdk_pixbuf_format_is_writable (format))
+ continue;
+
+ tiff_format = format;
+ }
+
+ return tiff_format != NULL;
+
+#endif /* HAVE_LIBTIFF */
+}
+
+
+#ifdef HAVE_LIBTIFF
+
+
+/* -- gth_tiff_saver_save_pixbuf -- */
+
+
+#define TILE_HEIGHT 40 /* FIXME */
+
+
+static tsize_t
+tiff_save_read (thandle_t handle, tdata_t buf, tsize_t size)
+{
+ return -1;
+}
+
+
+static tsize_t
+tiff_save_write (thandle_t handle, tdata_t buf, tsize_t size)
+{
+ GthBufferData *buffer_data = (GthBufferData *)handle;
+
+ gth_buffer_data_write (buffer_data, buf, size, NULL);
+ return size;
+}
+
+
+static toff_t
+tiff_save_seek (thandle_t handle, toff_t offset, int whence)
+{
+ GthBufferData *buffer_data = (GthBufferData *)handle;
+
+ return gth_buffer_data_seek (buffer_data, offset, whence);
+}
+
+
+static int
+tiff_save_close (thandle_t context)
+{
+ return 0;
+}
+
+
+static toff_t
+tiff_save_size (thandle_t handle)
+{
+ return -1;
+}
+
+
+static gboolean
+_gdk_pixbuf_save_as_tiff (GdkPixbuf *pixbuf,
+ char **buffer,
+ gsize *buffer_size,
+ char **keys,
+ char **values,
+ GError **error)
+{
+ GthBufferData *buffer_data;
+ TIFF *tif;
+ int cols, col, rows, row;
+ glong rowsperstrip;
+ gushort compression;
+ int alpha;
+ gshort predictor;
+ gshort photometric;
+ gshort samplesperpixel;
+ gshort bitspersample;
+ int rowstride;
+ guchar *pixels, *buf, *ptr;
+ int success;
+ int horizontal_dpi = 72, vertical_dpi = 72;
+ gboolean save_resolution = FALSE;
+
+ compression = COMPRESSION_DEFLATE;
+
+ if (keys && *keys) {
+ char **kiter = keys;
+ char **viter = values;
+
+ while (*kiter) {
+ if (strcmp (*kiter, "compression") == 0) {
+ if (*viter == NULL) {
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_BAD_OPTION,
+ "Must specify a compression type");
+ return FALSE;
+ }
+
+ if (strcmp (*viter, "none") == 0)
+ compression = COMPRESSION_NONE;
+ else if (strcmp (*viter, "pack bits") == 0)
+ compression = COMPRESSION_PACKBITS;
+ else if (strcmp (*viter, "lzw") == 0)
+ compression = COMPRESSION_LZW;
+ else if (strcmp (*viter, "deflate") == 0)
+ compression = COMPRESSION_DEFLATE;
+ else if (strcmp (*viter, "jpeg") == 0)
+ compression = COMPRESSION_JPEG;
+ else {
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_BAD_OPTION,
+ "Unsupported compression type passed to the TIFF saver");
+ return FALSE;
+ }
+ }
+ else if (strcmp (*kiter, "vertical dpi") == 0) {
+ char *endptr = NULL;
+ vertical_dpi = strtol (*viter, &endptr, 10);
+ save_resolution = TRUE;
+
+ if (endptr == *viter) {
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_BAD_OPTION,
+ "TIFF vertical dpi must be a value greater than 0; value '%s' could not be parsed.",
+ *viter);
+ return FALSE;
+ }
+
+ if (vertical_dpi < 0) {
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_BAD_OPTION,
+ "TIFF vertical dpi must be a value greater than 0; value '%d' is not allowed.",
+ vertical_dpi);
+ return FALSE;
+ }
+ }
+ else if (strcmp (*kiter, "horizontal dpi") == 0) {
+ char *endptr = NULL;
+ horizontal_dpi = strtol (*viter, &endptr, 10);
+ save_resolution = TRUE;
+
+ if (endptr == *viter) {
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_BAD_OPTION,
+ "TIFF horizontal dpi must be a value greater than 0; value '%s' could not be parsed.",
+ *viter);
+ return FALSE;
+ }
+
+ if (horizontal_dpi < 0) {
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_BAD_OPTION,
+ "TIFF horizontal dpi must be a value greater than 0; value '%d' is not allowed.",
+ horizontal_dpi);
+ return FALSE;
+ }
+ }
+ else {
+ g_warning ("Bad option name '%s' passed to the TIFF saver", *kiter);
+ return FALSE;
+ }
+
+ ++kiter;
+ ++viter;
+ }
+ }
+
+ predictor = 0;
+ rowsperstrip = TILE_HEIGHT;
+
+ buffer_data = gth_buffer_data_new ();
+ tif = TIFFClientOpen ("gth-tiff-writer", "w", buffer_data,
+ tiff_save_read, tiff_save_write,
+ tiff_save_seek, tiff_save_close,
+ tiff_save_size,
+ NULL, NULL);
+ if (tif == NULL) {
+ g_set_error_literal (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
+ "Couldn't allocate memory for writing TIFF file");
+ return FALSE;
+ }
+
+ cols = gdk_pixbuf_get_width (pixbuf);
+ rows = gdk_pixbuf_get_height (pixbuf);
+ alpha = gdk_pixbuf_get_has_alpha (pixbuf);
+ pixels = gdk_pixbuf_get_pixels (pixbuf);
+ rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+
+ predictor = 2;
+ bitspersample = 8;
+ photometric = PHOTOMETRIC_RGB;
+
+ if (alpha)
+ samplesperpixel = 4;
+ else
+ samplesperpixel = 3;
+
+ /* Set TIFF parameters. */
+
+ TIFFSetField (tif, TIFFTAG_SUBFILETYPE, 0);
+ TIFFSetField (tif, TIFFTAG_IMAGEWIDTH, cols);
+ TIFFSetField (tif, TIFFTAG_IMAGELENGTH, rows);
+ TIFFSetField (tif, TIFFTAG_BITSPERSAMPLE, bitspersample);
+ TIFFSetField (tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
+ TIFFSetField (tif, TIFFTAG_COMPRESSION, compression);
+
+ if ((compression == COMPRESSION_LZW || compression == COMPRESSION_DEFLATE)
+ && (predictor != 0))
+ {
+ TIFFSetField (tif, TIFFTAG_PREDICTOR, predictor);
+ }
+
+ if (alpha) {
+ gushort extra_samples[1];
+
+ extra_samples [0] = EXTRASAMPLE_ASSOCALPHA;
+ TIFFSetField (tif, TIFFTAG_EXTRASAMPLES, 1, extra_samples);
+ }
+
+ TIFFSetField (tif, TIFFTAG_PHOTOMETRIC, photometric);
+ /*TIFFSetField (tif, TIFFTAG_DOCUMENTNAME, filename);*/
+ TIFFSetField (tif, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
+ TIFFSetField (tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
+ TIFFSetField (tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+
+ if (save_resolution) {
+ TIFFSetField (tif, TIFFTAG_XRESOLUTION, (double) horizontal_dpi);
+ TIFFSetField (tif, TIFFTAG_YRESOLUTION, (double) vertical_dpi);
+ TIFFSetField (tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
+ }
+
+ /* allocate a small buffer to convert image data */
+ buf = g_try_malloc (cols * samplesperpixel * sizeof (guchar));
+ if (! buf) {
+ g_set_error_literal (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
+ "Couldn't allocate memory for writing TIFF file");
+ return FALSE;
+ }
+
+ ptr = pixels;
+
+ /* Now write the TIFF data. */
+ for (row = 0; row < rows; row++) {
+ /* convert scanline from ARGB to RGB packed */
+ for (col = 0; col < cols; col++)
+ memcpy (&(buf[col * 3]), &(ptr[col * samplesperpixel]), 3);
+
+ success = TIFFWriteScanline (tif, buf, row, 0) >= 0;
+
+ if (! success) {
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_FAILED,
+ "TIFF Failed a scanline write on row %d",
+ row);
+ return FALSE;
+ }
+
+ ptr += rowstride;
+ }
+
+ TIFFFlushData (tif);
+ TIFFClose (tif);
+
+ g_free (buf);
+
+ gth_buffer_data_get (buffer_data, buffer, buffer_size);
+ gth_buffer_data_free (buffer_data, FALSE);
+
+ return TRUE;
+}
+
+
+#endif /* HAVE_LIBTIFF */
+
+
+static gboolean
+gth_tiff_saver_save_pixbuf (GthPixbufSaver *self,
+ GdkPixbuf *pixbuf,
+ char **buffer,
+ gsize *buffer_size,
+ const char *mime_type,
+ GError **error)
+{
+#ifdef HAVE_LIBTIFF
+
+ char **option_keys;
+ char **option_values;
+ int i = -1;
+ int i_value;
+ gboolean result;
+
+ option_keys = g_malloc (sizeof (char *) * 4);
+ option_values = g_malloc (sizeof (char *) * 4);
+
+ i++;
+ option_keys[i] = g_strdup ("compression");;
+ option_values[i] = eel_gconf_get_string (PREF_TIFF_COMPRESSION, "deflate");
+
+ i++;
+ i_value = eel_gconf_get_integer (PREF_TIFF_VERTICAL_RES, 72);
+ option_keys[i] = g_strdup ("vertical dpi");;
+ option_values[i] = g_strdup_printf ("%d", i_value);
+
+ i++;
+ i_value = eel_gconf_get_integer (PREF_TIFF_HORIZONTAL_RES, 72);
+ option_keys[i] = g_strdup ("horizontal dpi");;
+ option_values[i] = g_strdup_printf ("%d", i_value);
+
+ i++;
+ option_keys[i] = NULL;
+ option_values[i] = NULL;
+
+ result = _gdk_pixbuf_save_as_tiff (pixbuf,
+ buffer,
+ buffer_size,
+ option_keys,
+ option_values,
+ error);
+
+ g_strfreev (option_keys);
+ g_strfreev (option_values);
+
+#else /* ! HAVE_LIBTIFF */
+
+ char *pixbuf_type;
+ gboolean result;
+
+ pixbuf_type = get_pixbuf_type_from_mime_type (mime_type);
+ result = gdk_pixbuf_save_to_bufferv (pixbuf,
+ buffer,
+ buffer_size,
+ pixbuf_type,
+ NULL,
+ NULL,
+ error);
+
+ g_free (pixbuf_type);
+
+#endif /* HAVE_LIBTIFF */
+
+ return result;
+}
+
+
+static void
+gth_tiff_saver_class_init (GthTiffSaverClass *klass)
+{
+ GObjectClass *object_class;
+ GthPixbufSaverClass *pixbuf_saver_class;
+
+ parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (GthTiffSaverPrivate));
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gth_tiff_saver_finalize;
+
+ pixbuf_saver_class = GTH_PIXBUF_SAVER_CLASS (klass);
+ pixbuf_saver_class->id = "tiff";
+ pixbuf_saver_class->display_name = _("TIFF");
+ pixbuf_saver_class->get_control = gth_tiff_saver_get_control;
+ pixbuf_saver_class->save_options = gth_tiff_saver_save_options;
+ pixbuf_saver_class->can_save = gth_tiff_saver_can_save;
+ pixbuf_saver_class->save_pixbuf = gth_tiff_saver_save_pixbuf;
+}
+
+
+GType
+gth_tiff_saver_get_type (void)
+{
+ static GType type = 0;
+
+ if (! type) {
+ GTypeInfo type_info = {
+ sizeof (GthTiffSaverClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gth_tiff_saver_class_init,
+ NULL,
+ NULL,
+ sizeof (GthTiffSaver),
+ 0,
+ (GInstanceInitFunc) gth_tiff_saver_init
+ };
+
+ type = g_type_register_static (GTH_TYPE_PIXBUF_SAVER,
+ "GthTiffSaver",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
diff --git a/extensions/pixbuf_savers/gth-tiff-saver.h b/extensions/pixbuf_savers/gth-tiff-saver.h
new file mode 100644
index 0000000..fd818c4
--- /dev/null
+++ b/extensions/pixbuf_savers/gth-tiff-saver.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTH_TIFF_SAVER_H
+#define GTH_TIFF_SAVER_H
+
+#include <gtk/gtk.h>
+#include <gthumb.h>
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_TIFF_SAVER (gth_tiff_saver_get_type ())
+#define GTH_TIFF_SAVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_TIFF_SAVER, GthTiffSaver))
+#define GTH_TIFF_SAVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TIFF_SAVER_TYPE, GthTiffSaverClass))
+#define GTH_IS_TIFF_SAVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_TIFF_SAVER))
+#define GTH_IS_TIFF_SAVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_TIFF_SAVER))
+#define GTH_TIFF_SAVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTH_TYPE_TIFF_SAVER, GthTiffSaverClass))
+
+typedef struct _GthTiffSaver GthTiffSaver;
+typedef struct _GthTiffSaverClass GthTiffSaverClass;
+typedef struct _GthTiffSaverPrivate GthTiffSaverPrivate;
+
+struct _GthTiffSaver
+{
+ GthPixbufSaver __parent;
+ GthTiffSaverPrivate *priv;
+};
+
+struct _GthTiffSaverClass
+{
+ GthPixbufSaverClass __parent_class;
+};
+
+GType gth_tiff_saver_get_type (void);
+
+G_END_DECLS
+
+#endif /* GTH_TIFF_SAVER_H */
diff --git a/extensions/pixbuf_savers/main.c b/extensions/pixbuf_savers/main.c
new file mode 100644
index 0000000..f29741c
--- /dev/null
+++ b/extensions/pixbuf_savers/main.c
@@ -0,0 +1,61 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+
+#include <config.h>
+#include <gthumb.h>
+#include "gth-jpeg-saver.h"
+#include "gth-png-saver.h"
+#include "gth-tga-saver.h"
+#include "gth-tiff-saver.h"
+#include "preferences.h"
+
+
+G_MODULE_EXPORT void
+gthumb_extension_activate (void)
+{
+ gth_main_register_type ("pixbuf-saver", GTH_TYPE_JPEG_SAVER);
+ gth_main_register_type ("pixbuf-saver", GTH_TYPE_PNG_SAVER);
+ gth_main_register_type ("pixbuf-saver", GTH_TYPE_TGA_SAVER);
+ gth_main_register_type ("pixbuf-saver", GTH_TYPE_TIFF_SAVER);
+ gth_hook_add_callback ("dlg-preferences-construct", 30, G_CALLBACK (so__dlg_preferences_construct_cb), NULL);
+ gth_hook_add_callback ("dlg-preferences-apply", 10, G_CALLBACK (so__dlg_preferences_apply_cb), 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/pixbuf_savers/pixbuf_savers.extension.in.in b/extensions/pixbuf_savers/pixbuf_savers.extension.in.in
new file mode 100644
index 0000000..032c973
--- /dev/null
+++ b/extensions/pixbuf_savers/pixbuf_savers.extension.in.in
@@ -0,0 +1,11 @@
+[Extension]
+_Name=Save images
+_Description=Save images in common file formats such as JPEG, PNG and TIFF
+_Authors=gthumb development team
+Copyright=Copyright © 2009 The Free Software Foundation, Inc.
+Version=1.0
+
+[Loader]
+Type=module
+File=%LIBRARY%
+Requires=jpeg_utils
diff --git a/extensions/pixbuf_savers/preferences.c b/extensions/pixbuf_savers/preferences.c
new file mode 100644
index 0000000..c78311a
--- /dev/null
+++ b/extensions/pixbuf_savers/preferences.c
@@ -0,0 +1,164 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <glib/gi18n.h>
+#include <gthumb.h>
+#include "preferences.h"
+
+
+#define GET_WIDGET(name) _gtk_builder_get_widget (data->builder, (name))
+#define BROWSER_DATA_KEY "save-options-preference-data"
+
+
+enum {
+ FILE_TYPE_COLUMN_N,
+ FILE_TYPE_COLUMN_OBJ,
+ FILE_TYPE_COLUMN_DISPLAY_NAME
+};
+
+
+typedef struct {
+ GtkBuilder *builder;
+ GList *pixbuf_saver;
+} BrowserData;
+
+
+static void
+browser_data_free (BrowserData *data)
+{
+ _g_object_list_unref (data->pixbuf_saver);
+ g_object_unref (data->builder);
+ g_free (data);
+}
+
+
+static void
+treeselection_changed_cb (GtkTreeSelection *treeselection,
+ gpointer user_data)
+{
+ GtkWidget *dialog = user_data;
+ BrowserData *data;
+ GtkTreeIter iter;
+ int page_n;
+ GthPixbufSaver *pixbuf_saver;
+
+ data = g_object_get_data (G_OBJECT (dialog), BROWSER_DATA_KEY);
+ g_return_if_fail (data != NULL);
+
+ if (! gtk_tree_selection_get_selected (treeselection, NULL, &iter))
+ return;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (gtk_builder_get_object (data->builder, "file_type_liststore")), &iter,
+ FILE_TYPE_COLUMN_N, &page_n,
+ FILE_TYPE_COLUMN_OBJ, &pixbuf_saver,
+ -1);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (_gtk_builder_get_widget (data->builder, "options_notebook")), page_n);
+ gtk_label_set_text (GTK_LABEL (_gtk_builder_get_widget (data->builder, "file_type_label")), gth_pixbuf_saver_get_display_name (pixbuf_saver));
+
+ g_object_unref (pixbuf_saver);
+}
+
+
+void
+so__dlg_preferences_construct_cb (GtkWidget *dialog,
+ GthBrowser *browser,
+ GtkBuilder *dialog_builder)
+{
+ BrowserData *data;
+ GtkWidget *notebook;
+ GtkWidget *page;
+ GtkListStore *model;
+ GArray *pixbuf_saver_types;
+ int i;
+ GtkTreeSelection *treeselection;
+ GtkTreePath *path;
+ GtkWidget *label;
+
+ data = g_new0 (BrowserData, 1);
+ data->builder = _gtk_builder_new_from_file ("save-options-preferences.ui", "pixbuf_savers");
+
+ notebook = _gtk_builder_get_widget (dialog_builder, "notebook");
+
+ page = _gtk_builder_get_widget (data->builder, "preferences_page");
+ gtk_widget_show (page);
+
+ model = (GtkListStore *) gtk_builder_get_object (data->builder, "file_type_liststore");
+ pixbuf_saver_types = gth_main_get_type_set ("pixbuf-saver");
+ for (i = 0; (pixbuf_saver_types != NULL) && (i < pixbuf_saver_types->len); i++) {
+ GthPixbufSaver *pixbuf_saver;
+ GtkTreeIter iter;
+ GtkWidget *options;
+
+ pixbuf_saver = g_object_new (g_array_index (pixbuf_saver_types, GType, i), NULL);
+
+ gtk_list_store_append (model, &iter);
+ gtk_list_store_set (model, &iter,
+ FILE_TYPE_COLUMN_N, i,
+ FILE_TYPE_COLUMN_OBJ, pixbuf_saver,
+ FILE_TYPE_COLUMN_DISPLAY_NAME, gth_pixbuf_saver_get_display_name (pixbuf_saver),
+ -1);
+
+ options = gth_pixbuf_saver_get_control (pixbuf_saver);
+ gtk_widget_show (options);
+ gtk_notebook_append_page (GTK_NOTEBOOK (_gtk_builder_get_widget (data->builder, "options_notebook")), options, NULL);
+
+ data->pixbuf_saver = g_list_prepend (data->pixbuf_saver, pixbuf_saver);
+ }
+
+ treeselection = gtk_tree_view_get_selection (GTK_TREE_VIEW (_gtk_builder_get_widget (data->builder, "file_type_treeview")));
+ gtk_tree_selection_set_mode (treeselection, GTK_SELECTION_BROWSE);
+ g_signal_connect (treeselection,
+ "changed",
+ G_CALLBACK (treeselection_changed_cb),
+ dialog);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("ask_options_checkbutton")), eel_gconf_get_boolean (PREF_SAVE_OPTIONS_ASK_OPTIONS, TRUE));
+
+ label = gtk_label_new (_("Saving"));
+ gtk_widget_show (label);
+
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), page, label);
+ g_object_set_data_full (G_OBJECT (dialog), BROWSER_DATA_KEY, data, (GDestroyNotify) browser_data_free);
+
+ path = gtk_tree_path_new_first ();
+ gtk_tree_selection_select_path (treeselection, path);
+ gtk_tree_path_free (path);
+}
+
+
+void
+so__dlg_preferences_apply_cb (GtkWidget *dialog,
+ GthBrowser *browser,
+ GtkBuilder *builder)
+{
+ BrowserData *data;
+ GList *scan;
+
+ data = g_object_get_data (G_OBJECT (dialog), BROWSER_DATA_KEY);
+ g_return_if_fail (data != NULL);
+
+ for (scan = data->pixbuf_saver; scan; scan = scan->next) {
+ GthPixbufSaver *pixbuf_saver = scan->data;
+ gth_pixbuf_saver_save_options (pixbuf_saver);
+ }
+}
diff --git a/extensions/pixbuf_savers/preferences.h b/extensions/pixbuf_savers/preferences.h
new file mode 100644
index 0000000..da2d013
--- /dev/null
+++ b/extensions/pixbuf_savers/preferences.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef PREFERENCES_H
+#define PREFERENCES_H
+
+#include <gthumb.h>
+
+
+typedef enum {
+ GTH_TIFF_COMPRESSION_NONE,
+ GTH_TIFF_COMPRESSION_DEFLATE,
+ GTH_TIFF_COMPRESSION_JPEG
+} GthTiffCompression;
+
+
+#define PREF_SAVE_OPTIONS_ASK_OPTIONS "/apps/gthumb/ext/save_options/ask_options"
+#define PREF_JPEG_QUALITY "/apps/gthumb/save_options/jpeg/quality"
+#define PREF_JPEG_SMOOTHING "/apps/gthumb/save_options/jpeg/smoothing"
+#define PREF_JPEG_OPTIMIZE "/apps/gthumb/save_options/jpeg/optimize"
+#define PREF_JPEG_PROGRESSIVE "/apps/gthumb/save_options/jpeg/progressive"
+#define PREF_PNG_COMPRESSION_LEVEL "/apps/gthumb/save_options/png/compression_level"
+#define PREF_TGA_RLE_COMPRESSION "/apps/gthumb/save_options/tga/rle_compression"
+#define PREF_TIFF_COMPRESSION "/apps/gthumb/save_options/tiff/compression"
+#define PREF_TIFF_HORIZONTAL_RES "/apps/gthumb/save_options/tiff/horizontal_resolution"
+#define PREF_TIFF_VERTICAL_RES "/apps/gthumb/save_options/tiff/vertical_resolution"
+
+
+void so__dlg_preferences_construct_cb (GtkWidget *dialog,
+ GthBrowser *browser,
+ GtkBuilder *builder);
+void so__dlg_preferences_apply_cb (GtkWidget *dialog,
+ GthBrowser *browser,
+ GtkBuilder *builder);
+
+#endif /* PREFERENCES_H */
diff --git a/gthumb/Makefile.am b/gthumb/Makefile.am
index d4d1281..fa36212 100644
--- a/gthumb/Makefile.am
+++ b/gthumb/Makefile.am
@@ -30,6 +30,7 @@ PUBLIC_HEADER_FILES = \
glib-utils.h \
gnome-desktop-thumbnail.h \
gth-async-task.h \
+ gth-buffer-data.h \
gth-browser.h \
gth-cell-renderer-thumbnail.h \
gth-cursors.h \
@@ -38,8 +39,8 @@ PUBLIC_HEADER_FILES = \
gth-edit-metadata-dialog.h \
gth-embedded-dialog.h \
gth-empty-list.h \
- gth-enum-types.h \
gth-extensions.h \
+ gth-error.h \
gth-file-data.h \
gth-file-list.h \
gth-file-properties.h \
@@ -76,6 +77,7 @@ PUBLIC_HEADER_FILES = \
gth-overwrite-dialog.h \
gth-pixbuf-task.h \
gth-pixbuf-list-task.h \
+ gth-pixbuf-saver.h \
gth-preferences.h \
gth-progress-dialog.h \
gth-sidebar.h \
@@ -98,7 +100,6 @@ PUBLIC_HEADER_FILES = \
gth-user-dir.h \
gth-viewer-page.h \
gth-window.h \
- gthumb-error.h \
gtk-utils.h \
main.h \
pixbuf-cache.h \
@@ -142,6 +143,7 @@ gthumb_SOURCES = \
gth-async-task.c \
gth-browser.c \
gth-browser-actions-callbacks.c \
+ gth-buffer-data.c \
gth-cell-renderer-thumbnail.c \
gth-cursors.c \
gth-dumb-notebook.c \
@@ -149,6 +151,7 @@ gthumb_SOURCES = \
gth-edit-metadata-dialog.c \
gth-embedded-dialog.c \
gth-empty-list.c \
+ gth-error.c \
gth-extensions.c \
gth-file-data.c \
gth-file-list.c \
@@ -192,6 +195,7 @@ gthumb_SOURCES = \
gth-overwrite-dialog.c \
gth-pixbuf-task.c \
gth-pixbuf-list-task.c \
+ gth-pixbuf-saver.c \
gth-preferences.c \
gth-progress-dialog.c \
gth-sidebar.c \
@@ -214,7 +218,6 @@ gthumb_SOURCES = \
gth-viewer-page.c \
gth-window.c \
gth-window-actions-callbacks.c \
- gthumb-error.c \
gtk-utils.c \
main.c \
pixbuf-cache.c \
@@ -232,6 +235,7 @@ gthumb_LDADD = \
$(GTHUMB_LIBS) \
$(EXIV2_LIBS) \
$(JPEG_LIBS) \
+ $(TIFF_LIBS) \
$(CLUTTER_LIBS) \
$(NULL)
@@ -292,7 +296,7 @@ gth-marshal.c: gth-marshal.h gth-marshal.list $(GLIB_GENMARSHAL)
&& $(GLIB_GENMARSHAL) $(srcdir)/gth-marshal.list --body --prefix=gth_marshal >> $@
gthumb.h: make-header.sh gthumb.h.template Makefile.am
- $(srcdir)/make-header.sh $(srcdir)/gthumb.h.template $(PUBLIC_HEADER_FILES) > xgen-$(@F) \
+ $(srcdir)/make-header.sh $(srcdir)/gthumb.h.template $(PUBLIC_HEADER_FILES) gth-enum-types.h > xgen-$(@F) \
&& (cmp -s xgen-$(@F) gthumb.h || cp xgen-$(@F) gthumb.h ) \
&& rm -f xgen-$(@F)
diff --git a/gthumb/gconf-utils.c b/gthumb/gconf-utils.c
index 65c1e07..4541ce8 100644
--- a/gthumb/gconf-utils.c
+++ b/gthumb/gconf-utils.c
@@ -51,7 +51,7 @@
#include <gconf/gconf.h>
#include "gconf-utils.h"
#include "gtk-utils.h"
-#include "gthumb-error.h"
+#include "gth-error.h"
#include "glib-utils.h"
#define HOME_DIR "~"
@@ -129,7 +129,7 @@ check_type (const char *key,
{
if (val->type != t) {
g_set_error (err,
- GTHUMB_ERROR,
+ GTH_ERROR,
errno,
"Type mismatch for key %s",
key);
diff --git a/gthumb/gth-browser.c b/gthumb/gth-browser.c
index 0370ea4..65b9942 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -33,6 +33,7 @@
#include "gth-browser-ui.h"
#include "gth-duplicable.h"
#include "gth-enum-types.h"
+#include "gth-error.h"
#include "gth-file-list.h"
#include "gth-file-view.h"
#include "gth-file-selection.h"
@@ -54,7 +55,6 @@
#include "gth-window.h"
#include "gth-window-actions-callbacks.h"
#include "gth-window-actions-entries.h"
-#include "gthumb-error.h"
#include "main.h"
#define GTH_BROWSER_CALLBACK(f) ((GthBrowserCallback) (f))
@@ -1617,7 +1617,7 @@ _gth_browser_load (GthBrowser *browser,
char *uri;
uri = g_file_get_uri (location);
- error = g_error_new (GTHUMB_ERROR, 0, _("No suitable module found for %s"), uri);
+ error = g_error_new (GTH_ERROR, 0, _("No suitable module found for %s"), uri);
load_data_ready (load_data, NULL, error);
g_free (uri);
@@ -1644,7 +1644,7 @@ _gth_browser_load (GthBrowser *browser,
char *uri;
uri = g_file_get_uri (load_data->requested_folder->file);
- error = g_error_new (GTHUMB_ERROR, 0, _("No suitable module found for %s"), uri);
+ error = g_error_new (GTH_ERROR, 0, _("No suitable module found for %s"), uri);
load_data_ready (load_data, NULL, error);
g_free (uri);
@@ -4574,7 +4574,7 @@ load_file_attributes_ready_cb (GthFileSource *file_source,
char *uri;
uri = g_file_get_uri (data->location);
- error = g_error_new (GTHUMB_ERROR, 0, _("File type not supported %s"), uri);
+ error = g_error_new (GTH_ERROR, 0, _("File type not supported %s"), uri);
_gtk_error_dialog_from_gerror_show (GTK_WINDOW (browser), _("Could not load the position"), &error);
g_free (uri);
@@ -4612,7 +4612,7 @@ gth_browser_load_location (GthBrowser *browser,
char *uri;
uri = g_file_get_uri (data->location);
- error = g_error_new (GTHUMB_ERROR, 0, _("No suitable module found for %s"), uri);
+ error = g_error_new (GTH_ERROR, 0, _("No suitable module found for %s"), uri);
_gtk_error_dialog_from_gerror_show (GTK_WINDOW (browser), _("Could not load the position"), &error);
g_free (uri);
diff --git a/gthumb/gth-buffer-data.c b/gthumb/gth-buffer-data.c
new file mode 100644
index 0000000..00b5f0b
--- /dev/null
+++ b/gthumb/gth-buffer-data.c
@@ -0,0 +1,161 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <string.h>
+#include <stdio.h>
+#include <glib/gi18n.h>
+#include "gth-buffer-data.h"
+#include "gth-error.h"
+
+
+#define INITIAL_ALLOCATED_SIZE 1024
+
+
+struct _GthBufferData {
+ char *buffer;
+ gsize buffer_size;
+ gsize allocated_size;
+ goffset current_pos;
+};
+
+
+GthBufferData *
+gth_buffer_data_new (void)
+{
+ GthBufferData *buffer_data;
+
+ buffer_data = g_new (GthBufferData, 1);
+ buffer_data->buffer = g_try_malloc (INITIAL_ALLOCATED_SIZE);
+ buffer_data->buffer_size = 0;
+ buffer_data->allocated_size = INITIAL_ALLOCATED_SIZE;
+ buffer_data->current_pos = 0;
+
+ return buffer_data;
+}
+
+
+void
+gth_buffer_data_free (GthBufferData *buffer_data,
+ gboolean free_segment)
+{
+ if (free_segment)
+ g_free (buffer_data->buffer);
+ g_free (buffer_data);
+}
+
+
+static gboolean
+gth_buffer_data_alloc_new_space (GthBufferData *buffer_data,
+ gsize len,
+ GError **error)
+{
+ if (buffer_data->current_pos + len > buffer_data->buffer_size)
+ buffer_data->buffer_size = buffer_data->current_pos + len;
+
+ if (buffer_data->buffer_size > buffer_data->allocated_size) {
+ gsize new_allocated_size;
+ char *new_buffer;
+
+ new_allocated_size = MAX (buffer_data->allocated_size * 2, buffer_data->buffer_size + len);
+ new_buffer = g_try_realloc (buffer_data->buffer, new_allocated_size);
+ if (new_buffer == NULL) {
+ g_set_error_literal (error,
+ GTH_ERROR,
+ GTH_ERROR_GENERIC,
+ _("Insufficient memory"));
+ return FALSE;
+ }
+
+ buffer_data->buffer = new_buffer;
+ buffer_data->allocated_size = new_allocated_size;
+ }
+
+ return TRUE;
+}
+
+
+gboolean
+gth_buffer_data_write (GthBufferData *buffer_data,
+ void *buffer,
+ gsize len,
+ GError **error)
+{
+ if (len <= 0)
+ return TRUE;
+
+ if (! gth_buffer_data_alloc_new_space (buffer_data, len, error))
+ return FALSE;
+
+ memcpy (buffer_data->buffer + buffer_data->current_pos, buffer, len);
+ buffer_data->current_pos += len;
+
+ return TRUE;
+}
+
+
+gboolean
+gth_buffer_data_putc (GthBufferData *buffer_data,
+ int c,
+ GError **error)
+{
+ if (! gth_buffer_data_alloc_new_space (buffer_data, 1, error))
+ return FALSE;
+
+ buffer_data->buffer[buffer_data->current_pos] = (char) c;
+ buffer_data->current_pos += 1;
+
+ return TRUE;
+}
+
+
+goffset
+gth_buffer_data_seek (GthBufferData *buffer_data,
+ goffset offset,
+ int whence)
+{
+ switch (whence) {
+ case SEEK_SET:
+ buffer_data->current_pos = offset;
+ break;
+ case SEEK_CUR:
+ buffer_data->current_pos += offset;
+ break;
+ case SEEK_END:
+ buffer_data->current_pos = buffer_data->buffer_size + offset;
+ break;
+ default:
+ return -1;
+ }
+
+ return buffer_data->current_pos;
+}
+
+
+void
+gth_buffer_data_get (GthBufferData *buffer_data,
+ char **buffer,
+ gsize *buffer_size)
+{
+ *buffer = buffer_data->buffer;
+ *buffer_size = buffer_data->buffer_size;
+}
diff --git a/gthumb/gth-buffer-data.h b/gthumb/gth-buffer-data.h
new file mode 100644
index 0000000..f10b3b4
--- /dev/null
+++ b/gthumb/gth-buffer-data.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTH_BUFFER_DATA_H
+#define GTH_BUFFER_DATA_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GthBufferData GthBufferData;
+
+GthBufferData * gth_buffer_data_new (void);
+void gth_buffer_data_free (GthBufferData *buffer_data,
+ gboolean free_segment);
+gboolean gth_buffer_data_write (GthBufferData *buffer_data,
+ void *buffer,
+ gsize len,
+ GError **error);
+gboolean gth_buffer_data_putc (GthBufferData *buffer_data,
+ int c,
+ GError **error);
+goffset gth_buffer_data_seek (GthBufferData *buffer_data,
+ goffset offset,
+ int whence);
+void gth_buffer_data_get (GthBufferData *buffer_data,
+ char **buffer,
+ gsize *buffer_size);
+
+G_END_DECLS
+
+#endif /* GTH_BUFFER_DATA_H */
diff --git a/gthumb/gthumb-error.c b/gthumb/gth-error.c
similarity index 88%
rename from gthumb/gthumb-error.c
rename to gthumb/gth-error.c
index 18e5578..a338faa 100644
--- a/gthumb/gthumb-error.c
+++ b/gthumb/gth-error.c
@@ -20,16 +20,16 @@
* Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
*/
-#include "gthumb-error.h"
+#include "gth-error.h"
GQuark
-gthumb_error_quark (void)
+gth_error_quark (void)
{
static GQuark quark;
if (!quark)
- quark = g_quark_from_static_string ("gthumb_error");
+ quark = g_quark_from_static_string ("gth_error");
return quark;
}
diff --git a/gthumb/gthumb-error.h b/gthumb/gth-error.h
similarity index 86%
rename from gthumb/gthumb-error.h
rename to gthumb/gth-error.h
index 894230d..203d225 100644
--- a/gthumb/gthumb-error.h
+++ b/gthumb/gth-error.h
@@ -20,8 +20,8 @@
* Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
*/
-#ifndef __GTHUMB_ERROR_H__
-#define __GTHUMB_ERROR_H__
+#ifndef GTH_ERROR_H
+#define GTH_ERROR_H
#include <glib.h>
@@ -33,9 +33,9 @@ typedef enum {
GTH_ERROR_EXTENSION_DEPENDENCY
} GthErrorCode;
-#define GTHUMB_ERROR gthumb_error_quark ()
-GQuark gthumb_error_quark (void);
+#define GTH_ERROR gth_error_quark ()
+GQuark gth_error_quark (void);
G_END_DECLS
-#endif /* __GTHUMB_ERROR_H__ */
+#endif /* GTH_ERROR_H */
diff --git a/gthumb/gth-extensions.c b/gthumb/gth-extensions.c
index bee2e8c..e05c156 100644
--- a/gthumb/gth-extensions.c
+++ b/gthumb/gth-extensions.c
@@ -23,8 +23,8 @@
#include <config.h>
#include <glib/gi18n.h>
#include "glib-utils.h"
+#include "gth-error.h"
#include "gth-extensions.h"
-#include "gthumb-error.h"
#define EXTENSION_SUFFIX ".extension"
@@ -267,7 +267,7 @@ gth_extension_module_exec_generic_func (GthExtensionModule *self,
if (g_module_symbol (self->priv->module, function_name, (gpointer *)&func))
func();
else
- *error = g_error_new_literal (GTHUMB_ERROR, GTH_ERROR_GENERIC, g_module_error ());
+ *error = g_error_new_literal (GTH_ERROR, GTH_ERROR_GENERIC, g_module_error ());
g_free (function_name);
@@ -811,7 +811,7 @@ gth_extension_manager_deactivate (GthExtensionManager *manager,
GthExtensionDescription *child_description = scan->data;
if (gth_extension_description_is_active (child_description)) {
- *error = g_error_new (GTHUMB_ERROR, GTH_ERROR_EXTENSION_DEPENDENCY, _("The extension '%s' is required by the extension '%s'"), description->name, child_description->name);
+ *error = g_error_new (GTH_ERROR, GTH_ERROR_EXTENSION_DEPENDENCY, _("The extension '%s' is required by the extension '%s'"), description->name, child_description->name);
break;
}
}
diff --git a/gthumb/gth-image-loader.c b/gthumb/gth-image-loader.c
index e0b0702..61839e4 100644
--- a/gthumb/gth-image-loader.c
+++ b/gthumb/gth-image-loader.c
@@ -27,9 +27,9 @@
#include <gtk/gtk.h>
#include "gth-file-data.h"
#include "glib-utils.h"
+#include "gth-error.h"
#include "gth-image-loader.h"
#include "gth-main.h"
-#include "gthumb-error.h"
/*
#include "file-utils.h"
@@ -774,7 +774,7 @@ gth_image_loader_cancel_with_error (GthImageLoader *iloader,
gpointer done_func_data)
{
g_mutex_lock (iloader->priv->data_mutex);
- iloader->priv->error = g_error_new_literal (GTHUMB_ERROR, 0, "cancelled");
+ iloader->priv->error = g_error_new_literal (GTH_ERROR, 0, "cancelled");
g_mutex_unlock (iloader->priv->data_mutex);
_gth_image_loader_stop (iloader, done_func, done_func_data, TRUE, TRUE);
@@ -826,7 +826,7 @@ gth_image_loader_load_from_pixbuf_loader (GthImageLoader *iloader,
g_mutex_lock (iloader->priv->data_mutex);
if ((iloader->priv->pixbuf == NULL) && (iloader->priv->animation == NULL))
- error = g_error_new_literal (GTHUMB_ERROR, 0, "No image available");
+ error = g_error_new_literal (GTH_ERROR, 0, "No image available");
g_mutex_unlock (iloader->priv->data_mutex);
g_signal_emit (G_OBJECT (iloader), gth_image_loader_signals[READY], 0, error);
@@ -873,7 +873,7 @@ gth_image_loader_load_from_image_loader (GthImageLoader *to,
}
if ((to->priv->pixbuf == NULL) && (to->priv->animation == NULL))
- error = g_error_new_literal (GTHUMB_ERROR, 0, "No image available");
+ error = g_error_new_literal (GTH_ERROR, 0, "No image available");
g_mutex_unlock (to->priv->data_mutex);
g_mutex_unlock (from->priv->data_mutex);
diff --git a/gthumb/gth-main.c b/gthumb/gth-main.c
index 1e1a3b8..7e2f3b2 100644
--- a/gthumb/gth-main.c
+++ b/gthumb/gth-main.c
@@ -690,6 +690,32 @@ gth_main_get_file_loader (const char *mime_type)
}
+GthPixbufSaver *
+gth_main_get_pixbuf_saver (const char *mime_type)
+{
+ GArray *savers;
+ int i;
+
+ savers = gth_main_get_type_set ("pixbuf-saver");
+ if (savers == NULL)
+ return NULL;
+
+ for (i = 0; i < savers->len; i++) {
+ GType saver_type;
+ GthPixbufSaver *saver;
+
+ saver_type = g_array_index (savers, GType, i);
+ saver = g_object_new (saver_type, NULL);
+ if (gth_pixbuf_saver_can_save (saver, mime_type))
+ return saver;
+
+ g_object_unref (saver);
+ }
+
+ return NULL;
+}
+
+
GthTest *
gth_main_get_general_filter (void)
{
@@ -1123,6 +1149,7 @@ void
gth_main_activate_extensions (void)
{
const char *mandatory_extensions[] = { "file_viewer",
+ "jpeg_utils",
NULL };
const char *default_extensions[] = { "catalogs",
"comments",
@@ -1133,6 +1160,7 @@ gth_main_activate_extensions (void)
"image_viewer",
"list_tools",
"photo_importer",
+ "pixbuf_savers",
"red_eye_removal",
"rename_series",
"resize_images",
diff --git a/gthumb/gth-main.h b/gthumb/gth-main.h
index 79f21cb..6c3592a 100644
--- a/gthumb/gth-main.h
+++ b/gthumb/gth-main.h
@@ -3,7 +3,7 @@
/*
* GThumb
*
- * Copyright (C) 2008 Free Software Foundation, Inc.
+ * Copyright (C) 2008-2009 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
@@ -26,13 +26,14 @@
#include <glib.h>
#include <glib-object.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
-#include "gth-file-data.h"
#include "gth-extensions.h"
+#include "gth-file-data.h"
#include "gth-file-source.h"
#include "gth-filter-file.h"
#include "gth-hook.h"
#include "gth-metadata-provider.h"
#include "gth-monitor.h"
+#include "gth-pixbuf-saver.h"
#include "gth-tags-file.h"
#include "gth-test.h"
@@ -90,6 +91,7 @@ void gth_main_register_file_loader (FileLoader
const char *first_mime_type,
...);
FileLoader gth_main_get_file_loader (const char *mime_type);
+GthPixbufSaver * gth_main_get_pixbuf_saver (const char *mime_type);
GthTest * gth_main_get_general_filter (void);
GthTest * gth_main_add_general_filter (GthTest *filter);
void gth_main_register_object (GType superclass_type,
diff --git a/gthumb/gth-pixbuf-list-task.c b/gthumb/gth-pixbuf-list-task.c
index d3425c1..a27ac98 100644
--- a/gthumb/gth-pixbuf-list-task.c
+++ b/gthumb/gth-pixbuf-list-task.c
@@ -133,7 +133,6 @@ pixbuf_task_completed_cb (GthTask *task,
{
GthPixbufListTask *self = user_data;
GthFileData *file_data;
- char *pixbuf_type;
if (g_error_matches (error, GTH_TASK_ERROR, GTH_TASK_ERROR_SKIP_TO_NEXT_FILE)) {
process_next_file (self);
@@ -146,17 +145,12 @@ pixbuf_task_completed_cb (GthTask *task,
}
file_data = self->priv->current->data;
- pixbuf_type = get_pixbuf_type_from_mime_type (gth_file_data_get_mime_type (file_data));
self->priv->new_pixbuf = g_object_ref (GTH_PIXBUF_TASK (task)->dest);
_gdk_pixbuf_save_async (self->priv->new_pixbuf,
file_data,
- pixbuf_type,
- NULL,
- NULL,
+ gth_file_data_get_mime_type (file_data),
pixbuf_saved_cb,
self);
-
- g_free (pixbuf_type);
}
diff --git a/gthumb/gth-pixbuf-saver.c b/gthumb/gth-pixbuf-saver.c
new file mode 100644
index 0000000..deac3ab
--- /dev/null
+++ b/gthumb/gth-pixbuf-saver.c
@@ -0,0 +1,158 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include "gth-pixbuf-saver.h"
+
+
+static gpointer parent_class = NULL;
+
+
+static GtkWidget *
+base_get_control (GthPixbufSaver *self)
+{
+ return gtk_label_new (_("No options available for this file type"));
+}
+
+
+static void
+base_save_options (GthPixbufSaver *self)
+{
+ /* void */
+}
+
+
+static gboolean
+base_can_save (GthPixbufSaver *self,
+ const char *mime_type)
+{
+ return FALSE;
+}
+
+
+static gboolean
+base_save_pixbuf (GthPixbufSaver *self,
+ GdkPixbuf *pixbuf,
+ char **buffer,
+ gsize *buffer_size,
+ const char *mime_type,
+ GError **error)
+{
+ return FALSE;
+}
+
+
+static void
+gth_pixbuf_saver_class_init (GthPixbufSaverClass *klass)
+{
+ parent_class = g_type_class_peek_parent (klass);
+
+ klass->id = "";
+ klass->display_name = "";
+ klass->get_control = base_get_control;
+ klass->save_options = base_save_options;
+ klass->can_save = base_can_save;
+ klass->save_pixbuf = base_save_pixbuf;
+}
+
+
+GType
+gth_pixbuf_saver_get_type (void)
+{
+ static GType type = 0;
+
+ if (! type) {
+ GTypeInfo type_info = {
+ sizeof (GthPixbufSaverClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gth_pixbuf_saver_class_init,
+ NULL,
+ NULL,
+ sizeof (GthPixbufSaver),
+ 0,
+ (GInstanceInitFunc) NULL
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "GthPixbufSaver",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
+
+
+const char *
+gth_pixbuf_saver_get_id (GthPixbufSaver *self)
+{
+ return GTH_PIXBUF_SAVER_GET_CLASS (self)->id;
+}
+
+
+const char *
+gth_pixbuf_saver_get_display_name (GthPixbufSaver *self)
+{
+ return GTH_PIXBUF_SAVER_GET_CLASS (self)->display_name;
+}
+
+
+GtkWidget *
+gth_pixbuf_saver_get_control (GthPixbufSaver *self)
+{
+ return GTH_PIXBUF_SAVER_GET_CLASS (self)->get_control (self);
+}
+
+
+void
+gth_pixbuf_saver_save_options (GthPixbufSaver *self)
+{
+ GTH_PIXBUF_SAVER_GET_CLASS (self)->save_options (self);
+}
+
+
+gboolean
+gth_pixbuf_saver_can_save (GthPixbufSaver *self,
+ const char *mime_type)
+{
+ return GTH_PIXBUF_SAVER_GET_CLASS (self)->can_save (self, mime_type);
+}
+
+
+gboolean
+gth_pixbuf_saver_save_pixbuf (GthPixbufSaver *self,
+ GdkPixbuf *pixbuf,
+ char **buffer,
+ gsize *buffer_size,
+ const char *mime_type,
+ GError **error)
+{
+ return GTH_PIXBUF_SAVER_GET_CLASS (self)->save_pixbuf (self,
+ pixbuf,
+ buffer,
+ buffer_size,
+ mime_type,
+ error);
+}
diff --git a/gthumb/gth-pixbuf-saver.h b/gthumb/gth-pixbuf-saver.h
new file mode 100644
index 0000000..d64c569
--- /dev/null
+++ b/gthumb/gth-pixbuf-saver.h
@@ -0,0 +1,86 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTH_PIXBUF_SAVER_H
+#define GTH_PIXBUF_SAVER_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_PIXBUF_SAVER (gth_pixbuf_saver_get_type ())
+#define GTH_PIXBUF_SAVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_PIXBUF_SAVER, GthPixbufSaver))
+#define GTH_PIXBUF_SAVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_PIXBUF_SAVER, GthPixbufSaverClass))
+#define GTH_IS_PIXBUF_SAVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_PIXBUF_SAVER))
+#define GTH_IS_PIXBUF_SAVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_PIXBUF_SAVER))
+#define GTH_PIXBUF_SAVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTH_TYPE_PIXBUF_SAVER, GthPixbufSaverClass))
+
+typedef struct _GthPixbufSaver GthPixbufSaver;
+typedef struct _GthPixbufSaverClass GthPixbufSaverClass;
+typedef struct _GthPixbufSaverPrivate GthPixbufSaverPrivate;
+
+struct _GthPixbufSaver
+{
+ GObject __parent;
+ GthPixbufSaverPrivate *priv;
+};
+
+struct _GthPixbufSaverClass
+{
+ GObjectClass __parent_class;
+
+ /*< class attributes >*/
+
+ const char *id;
+ const char *display_name;
+
+ /*< virtual functions >*/
+
+ GtkWidget * (*get_control) (GthPixbufSaver *self);
+ void (*save_options) (GthPixbufSaver *self);
+ gboolean (*can_save) (GthPixbufSaver *self,
+ const char *mime_type);
+ gboolean (*save_pixbuf) (GthPixbufSaver *self,
+ GdkPixbuf *pixbuf,
+ char **buffer,
+ gsize *buffer_size,
+ const char *mime_type,
+ GError **error);
+};
+
+GType gth_pixbuf_saver_get_type (void);
+const char * gth_pixbuf_saver_get_id (GthPixbufSaver *self);
+const char * gth_pixbuf_saver_get_display_name (GthPixbufSaver *self);
+GtkWidget * gth_pixbuf_saver_get_control (GthPixbufSaver *self);
+void gth_pixbuf_saver_save_options (GthPixbufSaver *self);
+gboolean gth_pixbuf_saver_can_save (GthPixbufSaver *self,
+ const char *mime_type);
+gboolean gth_pixbuf_saver_save_pixbuf (GthPixbufSaver *self,
+ GdkPixbuf *pixbuf,
+ char **buffer,
+ gsize *buffer_size,
+ const char *mime_type,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* GTH_PIXBUF_SAVER_H */
diff --git a/gthumb/gth-preferences.h b/gthumb/gth-preferences.h
index 08f962c..da2dcd4 100644
--- a/gthumb/gth-preferences.h
+++ b/gthumb/gth-preferences.h
@@ -72,19 +72,6 @@ G_BEGIN_DECLS
#define PREF_UI_PROPERTIES_HEIGHT "/apps/gthumb/ui/properties_height"
#define PREF_UI_COMMENT_HEIGHT "/apps/gthumb/ui/comment_height"
-#define PREF_PNG_COMPRESSION_LEVEL "/apps/gthumb/dialogs/png_saver/compression_level"
-
-#define PREF_JPEG_QUALITY "/apps/gthumb/dialogs/jpeg_saver/quality"
-#define PREF_JPEG_SMOOTHING "/apps/gthumb/dialogs/jpeg_saver/smoothing"
-#define PREF_JPEG_OPTIMIZE "/apps/gthumb/dialogs/jpeg_saver/optimize"
-#define PREF_JPEG_PROGRESSIVE "/apps/gthumb/dialogs/jpeg_saver/progressive"
-
-#define PREF_TGA_RLE_COMPRESSION "/apps/gthumb/dialogs/tga_saver/rle_compression"
-
-#define PREF_TIFF_COMPRESSION "/apps/gthumb/dialogs/tiff_saver/compression"
-#define PREF_TIFF_HORIZONTAL_RES "/apps/gthumb/dialogs/tiff_saver/horizontal_resolution"
-#define PREF_TIFF_VERTICAL_RES "/apps/gthumb/dialogs/tiff_saver/vertical_resolution"
-
#define PREF_ADD_TO_CATALOG_LAST_CATALOG "/apps/gthumb/dialogs/add_to_catalog/last_catalog"
#define PREF_ADD_TO_CATALOG_VIEW "/apps/gthumb/dialogs/add_to_catalog/view"
diff --git a/gthumb/gth-thumb-loader.c b/gthumb/gth-thumb-loader.c
index 206889b..84bc227 100644
--- a/gthumb/gth-thumb-loader.c
+++ b/gthumb/gth-thumb-loader.c
@@ -33,10 +33,10 @@
#include "glib-utils.h"
#define GNOME_DESKTOP_USE_UNSTABLE_API
#include "gnome-desktop-thumbnail.h"
+#include "gth-error.h"
#include "gth-image-loader.h"
#include "gth-main.h"
#include "gth-thumb-loader.h"
-#include "gthumb-error.h"
#include "pixbuf-io.h"
#include "pixbuf-utils.h"
#include "typedefs.h"
@@ -416,7 +416,7 @@ watch_thumbnailer_cb (GPid pid,
tloader->priv->thumbnailer_watch = 0;
if (status != 0) {
- error = g_error_new_literal (GTHUMB_ERROR, 0, "cannot generate the thumbnail");
+ error = g_error_new_literal (GTH_ERROR, 0, "cannot generate the thumbnail");
image_loader_error (NULL, error, data);
return;
}
@@ -428,7 +428,7 @@ watch_thumbnailer_cb (GPid pid,
g_object_unref (pixbuf);
}
else {
- error = g_error_new_literal (GTHUMB_ERROR, 0, "cannot generate the thumbnail");
+ error = g_error_new_literal (GTH_ERROR, 0, "cannot generate the thumbnail");
image_loader_error (NULL, error, data);
}
}
@@ -474,7 +474,7 @@ image_loader_ready_cb (GthImageLoader *iloader,
}
else {
if (error == NULL)
- error = g_error_new_literal (GTHUMB_ERROR, 0, "cannot generate the thumbnail");
+ error = g_error_new_literal (GTH_ERROR, 0, "cannot generate the thumbnail");
image_loader_error (iloader, error, data);
}
@@ -515,7 +515,7 @@ thumb_loader (GthFileData *file,
g_object_unref (pixbuf);
}
else
- *error = g_error_new_literal (GTHUMB_ERROR, 0, "cannot generate the thumbnail");
+ *error = g_error_new_literal (GTH_ERROR, 0, "cannot generate the thumbnail");
return animation;
}
@@ -684,7 +684,7 @@ gth_thumb_loader_load__step2 (GthThumbLoader *tloader)
g_signal_emit (G_OBJECT (tloader),
gth_thumb_loader_signals[READY],
0,
- g_error_new_literal (GTHUMB_ERROR, 0, "failed thumbnail"));
+ g_error_new_literal (GTH_ERROR, 0, "failed thumbnail"));
g_free (uri);
return;
}
diff --git a/gthumb/pixbuf-io.c b/gthumb/pixbuf-io.c
index 8698d28..fd7a201 100644
--- a/gthumb/pixbuf-io.c
+++ b/gthumb/pixbuf-io.c
@@ -22,10 +22,14 @@
#include <config.h>
#include <string.h>
+#include <glib/gi18n.h>
#define GDK_PIXBUF_ENABLE_BACKEND 1
#include "gio-utils.h"
#include "glib-utils.h"
+#include "gth-error.h"
#include "gth-hook.h"
+#include "gth-main.h"
+#include "gth-pixbuf-saver.h"
#include "pixbuf-io.h"
@@ -147,24 +151,29 @@ save_files (SavePixbufData *data,
void
_gdk_pixbuf_save_async (GdkPixbuf *pixbuf,
GthFileData *file_data,
- const char *type,
- char **keys,
- char **values,
+ const char *mime_type,
GthFileDataFunc ready_func,
gpointer ready_data)
{
+ GthPixbufSaver *saver;
+ GError *error = NULL;
void *buffer;
gsize buffer_size;
- GError *error = NULL;
SavePixbufData *data;
- if (! gdk_pixbuf_save_to_bufferv (pixbuf,
- (char **)&buffer,
- &buffer_size,
- type,
- keys,
- values,
- &error))
+ saver = gth_main_get_pixbuf_saver (mime_type);
+ if (saver == NULL) {
+ error = g_error_new (GTH_ERROR, GTH_ERROR_GENERIC, _("Could not find a suitable module to save the image as \"%s\""), mime_type);
+ gth_file_data_ready_with_error (file_data, ready_func, ready_data, error);
+ return;
+ }
+
+ if (! gth_pixbuf_saver_save_pixbuf (saver,
+ pixbuf,
+ (char **)&buffer,
+ &buffer_size,
+ mime_type,
+ &error))
{
gth_file_data_ready_with_error (file_data, ready_func, ready_data, error);
return;
@@ -173,12 +182,11 @@ _gdk_pixbuf_save_async (GdkPixbuf *pixbuf,
data = g_new0 (SavePixbufData, 1);
data->file_data = g_object_ref (file_data);
data->pixbuf = g_object_ref (pixbuf);
- data->type = type;
+ data->mime_type = mime_type;
data->buffer = buffer;
data->buffer_size = buffer_size;
data->files = NULL;
data->error = NULL;
-
gth_hook_invoke ("save-pixbuf", data);
if (data->error == NULL) {
diff --git a/gthumb/pixbuf-io.h b/gthumb/pixbuf-io.h
index 63667d6..9f19945 100644
--- a/gthumb/pixbuf-io.h
+++ b/gthumb/pixbuf-io.h
@@ -42,7 +42,7 @@ typedef struct {
typedef struct {
GthFileData *file_data;
GdkPixbuf *pixbuf;
- const char *type;
+ const char *mime_type;
void *buffer;
gsize buffer_size;
GList *files; /* SavePixbufFile list */
@@ -52,9 +52,7 @@ typedef struct {
char * get_pixbuf_type_from_mime_type (const char *mime_type);
void _gdk_pixbuf_save_async (GdkPixbuf *pixbuf,
GthFileData *file_data,
- const char *type,
- char **keys,
- char **values,
+ const char *mime_type,
GthFileDataFunc ready_func,
gpointer data);
GdkPixbuf * gth_pixbuf_new_from_file (GthFileData *file,
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 9b44f5a..ff22581 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -8,8 +8,8 @@ copy-n-paste/eggsmclient.h
copy-n-paste/eggsmclient-private.h
copy-n-paste/eggsmclient-xsmp.c
data/gthumb.desktop.in.in
-data/gthumb.schemas.in
data/gthumb-import.desktop.in.in
+data/gthumb.schemas.in
[type: gettext/glade]data/ui/bookmarks.ui
[type: gettext/glade]data/ui/extensions.ui
[type: gettext/glade]data/ui/filter-editor.ui
@@ -61,14 +61,33 @@ extensions/file_manager/gth-duplicate-task.h
extensions/file_manager/gth-reorder-task.c
extensions/file_manager/gth-reorder-task.h
extensions/file_manager/main.c
+[type: gettext/glade]extensions/file_tools/data/ui/adjust-colors-options.ui
[type: gettext/glade]extensions/file_tools/data/ui/crop-options.ui
extensions/file_tools/file_tools.extension.in.in
+extensions/file_tools/gth-file-tool-adjust-colors.c
+extensions/file_tools/gth-file-tool-adjust-colors.h
extensions/file_tools/gth-file-tool-crop.c
extensions/file_tools/gth-file-tool-crop.h
extensions/file_tools/gth-file-tool-desaturate.c
extensions/file_tools/gth-file-tool-desaturate.h
+extensions/file_tools/gth-file-tool-enhance.c
+extensions/file_tools/gth-file-tool-enhance.h
+extensions/file_tools/gth-file-tool-equalize.c
+extensions/file_tools/gth-file-tool-equalize.h
+extensions/file_tools/gth-file-tool-flip.c
+extensions/file_tools/gth-file-tool-flip.h
+extensions/file_tools/gth-file-tool-mirror.c
+extensions/file_tools/gth-file-tool-mirror.h
+extensions/file_tools/gth-file-tool-negative.c
+extensions/file_tools/gth-file-tool-negative.h
extensions/file_tools/gth-file-tool-redo.c
extensions/file_tools/gth-file-tool-redo.h
+extensions/file_tools/gth-file-tool-rotate-left.c
+extensions/file_tools/gth-file-tool-rotate-left.h
+extensions/file_tools/gth-file-tool-rotate-right.c
+extensions/file_tools/gth-file-tool-rotate-right.h
+extensions/file_tools/gth-file-tool-save-as.c
+extensions/file_tools/gth-file-tool-save-as.h
extensions/file_tools/gth-file-tool-save.c
extensions/file_tools/gth-file-tool-save.h
extensions/file_tools/gth-file-tool-undo.c
@@ -85,15 +104,9 @@ extensions/image_rotation/callbacks.h
extensions/image_rotation/gth-transform-task.c
extensions/image_rotation/gth-transform-task.h
extensions/image_rotation/image_rotation.extension.in.in
-extensions/image_rotation/jmemorydest.c
-extensions/image_rotation/jmemorysrc.c
-extensions/image_rotation/jpegtran.c
-extensions/image_rotation/jpegtran.h
extensions/image_rotation/main.c
extensions/image_rotation/rotation-utils.c
extensions/image_rotation/rotation-utils.h
-extensions/image_rotation/transupp.c
-extensions/image_rotation/transupp.h
extensions/image_viewer/data/gthumb-image-viewer.schemas.in
[type: gettext/glade]extensions/image_viewer/data/ui/image-viewer-preferences.ui
extensions/image_viewer/gth-image-viewer-page.c
@@ -104,6 +117,16 @@ extensions/image_viewer/image_viewer.extension.in.in
extensions/image_viewer/main.c
extensions/image_viewer/preferences.c
extensions/image_viewer/preferences.h
+extensions/jpeg_utils/jmemorydest.c
+extensions/jpeg_utils/jmemorydest.h
+extensions/jpeg_utils/jmemorysrc.c
+extensions/jpeg_utils/jmemorysrc.h
+extensions/jpeg_utils/jpegtran.c
+extensions/jpeg_utils/jpegtran.h
+extensions/jpeg_utils/jpeg_utils.extension.in.in
+extensions/jpeg_utils/main.c
+extensions/jpeg_utils/transupp.c
+extensions/jpeg_utils/transupp.h
extensions/list_tools/actions.c
extensions/list_tools/actions.h
extensions/list_tools/callbacks.c
@@ -136,6 +159,29 @@ extensions/photo_importer/gth-import-task.h
extensions/photo_importer/main.c
extensions/photo_importer/photo_importer.extension.in.in
extensions/photo_importer/preferences.h
+extensions/pixbuf_savers/data/gthumb-pixbuf-savers.schemas.in
+[type: gettext/glade]extensions/pixbuf_savers/data/ui/jpeg-options.ui
+[type: gettext/glade]extensions/pixbuf_savers/data/ui/png-options.ui
+[type: gettext/glade]extensions/pixbuf_savers/data/ui/save-options-preferences.ui
+[type: gettext/glade]extensions/pixbuf_savers/data/ui/tga-options.ui
+[type: gettext/glade]extensions/pixbuf_savers/data/ui/tiff-options.ui
+extensions/pixbuf_savers/gth-jpeg-saver.c
+extensions/pixbuf_savers/gth-jpeg-saver.h
+extensions/pixbuf_savers/gth-png-saver.c
+extensions/pixbuf_savers/gth-png-saver.h
+extensions/pixbuf_savers/gth-tga-saver.c
+extensions/pixbuf_savers/gth-tga-saver.h
+extensions/pixbuf_savers/gth-tiff-saver.c
+extensions/pixbuf_savers/gth-tiff-saver.h
+extensions/pixbuf_savers/main.c
+extensions/pixbuf_savers/pixbuf_savers.extension.in.in
+extensions/pixbuf_savers/preferences.c
+extensions/pixbuf_savers/preferences.h
+[type: gettext/glade]extensions/red_eye_removal/data/ui/red-eye-removal-options.ui
+extensions/red_eye_removal/gth-file-tool-red-eye.c
+extensions/red_eye_removal/gth-file-tool-red-eye.h
+extensions/red_eye_removal/main.c
+extensions/red_eye_removal/red_eye_removal.extension.in.in
extensions/rename_series/actions.c
extensions/rename_series/actions.h
extensions/rename_series/callbacks.c
@@ -147,6 +193,17 @@ extensions/rename_series/gth-rename-task.c
extensions/rename_series/gth-rename-task.h
extensions/rename_series/main.c
extensions/rename_series/rename_series.extension.in.in
+extensions/resize_images/actions.c
+extensions/resize_images/actions.h
+extensions/resize_images/callbacks.c
+extensions/resize_images/callbacks.h
+extensions/resize_images/data/gthumb_resize_images.schemas.in
+[type: gettext/glade]extensions/resize_images/data/ui/resize-images.ui
+extensions/resize_images/dlg-resize-images.c
+extensions/resize_images/dlg-resize-images.h
+extensions/resize_images/main.c
+extensions/resize_images/preferences.h
+extensions/resize_images/resize_images.extension.in.in
extensions/search/actions.c
extensions/search/actions.h
extensions/search/callbacks.c
@@ -202,12 +259,16 @@ gthumb/glib-utils.h
gthumb/gnome-desktop-thumbnail.c
gthumb/gnome-desktop-thumbnail.h
gthumb/gnome-thumbnail-pixbuf-utils.c
+gthumb/gth-async-task.c
+gthumb/gth-async-task.h
gthumb/gth-browser-actions-callbacks.c
gthumb/gth-browser-actions-callbacks.h
gthumb/gth-browser-actions-entries.h
gthumb/gth-browser.c
gthumb/gth-browser.h
gthumb/gth-browser-ui.h
+gthumb/gth-buffer-data.c
+gthumb/gth-buffer-data.h
gthumb/gth-cell-renderer-thumbnail.c
gthumb/gth-cell-renderer-thumbnail.h
gthumb/gth-cursors.c
@@ -222,6 +283,8 @@ gthumb/gth-embedded-dialog.c
gthumb/gth-embedded-dialog.h
gthumb/gth-empty-list.c
gthumb/gth-empty-list.h
+gthumb/gth-error.c
+gthumb/gth-error.h
gthumb/gth-extensions.c
gthumb/gth-extensions.h
gthumb/gth-file-data.c
@@ -252,6 +315,10 @@ gthumb/gth-filter-file.h
gthumb/gth-filter.h
gthumb/gth-folder-tree.c
gthumb/gth-folder-tree.h
+gthumb/gth-histogram.c
+gthumb/gth-histogram.h
+gthumb/gth-histogram-view.c
+gthumb/gth-histogram-view.h
gthumb/gth-hook.c
gthumb/gth-hook.h
gthumb/gth-icon-cache.c
@@ -295,6 +362,10 @@ gthumb/gth-nav-window.c
gthumb/gth-nav-window.h
gthumb/gth-overwrite-dialog.c
gthumb/gth-overwrite-dialog.h
+gthumb/gth-pixbuf-list-task.c
+gthumb/gth-pixbuf-list-task.h
+gthumb/gth-pixbuf-saver.c
+gthumb/gth-pixbuf-saver.h
gthumb/gth-pixbuf-task.c
gthumb/gth-pixbuf-task.h
gthumb/gth-preferences.c
@@ -332,8 +403,6 @@ gthumb/gth-toggle-menu-tool-button.c
gthumb/gth-toggle-menu-tool-button.h
gthumb/gth-toolbox.c
gthumb/gth-toolbox.h
-gthumb/gthumb-error.c
-gthumb/gthumb-error.h
gthumb/gth-uri-list.c
gthumb/gth-uri-list.h
gthumb/gth-user-dir.c
@@ -349,6 +418,8 @@ gthumb/gtk-utils.c
gthumb/gtk-utils.h
gthumb/main.c
gthumb/main.h
+gthumb/pixbuf-cache.c
+gthumb/pixbuf-cache.h
gthumb/pixbuf-io.c
gthumb/pixbuf-io.h
gthumb/pixbuf-utils.c
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]