summaryrefslogtreecommitdiff
path: root/gdk-pixbuf/io-jpeg.c
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2000-10-06 18:19:18 +0000
committerHavoc Pennington <hp@src.gnome.org>2000-10-06 18:19:18 +0000
commit6b9f9072708e6f1b41f9f75acd8d70191ad245ea (patch)
tree2a46c20b581be14650eb258c30ded238359a3c15 /gdk-pixbuf/io-jpeg.c
parenta7e20093e9d6623433e764bb2aac9e40693c783d (diff)
downloadgtk+-6b9f9072708e6f1b41f9f75acd8d70191ad245ea.tar.gz
Pixbuf saving, patch from David Welton.
2000-10-05 Havoc Pennington <hp@redhat.com> Pixbuf saving, patch from David Welton. * Makefile.am (GDK_PIXBUF_LIBS): add INTLLIBS (libgdk_pixbuf_1_3_la_SOURCES): add gdk-pixbuf-i18n.h * gdk-pixbuf-i18n.h: Add _() to gdk-pixbuf * io-png.c (gdk_pixbuf__png_image_save): PNG save routine. * io-jpeg.c (gdk_pixbuf__jpeg_image_save): JPEG save routine. * gdk-pixbuf-io.c (gdk_pixbuf_save): (gdk_pixbuf_savev): Implement pixbuf saving routines * gdk-pixbuf.c (gdk_pixbuf_error_quark): pixbuf error quark function * gdk-pixbuf.h: Add public save routines; add pixbuf error types * gdk-pixbuf-io.h: Add save function to GdkPixbufModule 2000-10-05 Havoc Pennington <hp@redhat.com> * demos/testpixbuf-save.c: add pixbuf save test * demos/Makefile.am: add testpixbuf-save.c
Diffstat (limited to 'gdk-pixbuf/io-jpeg.c')
-rw-r--r--gdk-pixbuf/io-jpeg.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/gdk-pixbuf/io-jpeg.c b/gdk-pixbuf/io-jpeg.c
index 06deb42f6c..89ca8d2015 100644
--- a/gdk-pixbuf/io-jpeg.c
+++ b/gdk-pixbuf/io-jpeg.c
@@ -565,3 +565,126 @@ gdk_pixbuf__jpeg_image_load_increment (gpointer data, guchar *buf, guint size)
return TRUE;
}
+
+gboolean
+gdk_pixbuf__jpeg_image_save (FILE *f,
+ GdkPixbuf *pixbuf,
+ gchar **keys,
+ gchar **values,
+ GError **error)
+{
+ /* FIXME error handling is broken */
+
+ struct jpeg_compress_struct cinfo;
+ guchar *buf = NULL;
+ guchar *ptr;
+ guchar *pixels = NULL;
+ JSAMPROW *jbuf;
+ int y = 0;
+ int quality = 75; /* default; must be between 0 and 100 */
+ int i, j;
+ int w, h = 0;
+ int rowstride = 0;
+ struct error_handler_data jerr;
+
+ if (keys && *keys) {
+ gchar **kiter = keys;
+ gchar **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_VALUE,
+ _("JPEG quality must be a value between 0 and 100; value '%s' could not be parsed."),
+ *viter);
+
+ return FALSE;
+ }
+
+ if (quality < 0 ||
+ quality > 100) {
+ /* This is a user-visible error;
+ * lets people skip the range-checking
+ * in their app.
+ */
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_BAD_OPTION_VALUE,
+ _("JPEG quality must be a value between 0 and 100; value '%d' is not allowed."),
+ quality);
+
+ 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);
+
+ /* no image data? abort */
+ pixels = gdk_pixbuf_get_pixels (pixbuf);
+ g_return_val_if_fail (pixels != NULL, FALSE);
+
+ /* allocate a small buffer to convert image data */
+ buf = malloc (w * 3 * sizeof (guchar));
+ g_return_val_if_fail (buf != NULL, FALSE);
+
+ /* set up error handling */
+ jerr.pub.error_exit = fatal_error_handler;
+
+ cinfo.err = jpeg_std_error (&(jerr.pub));
+ if (sigsetjmp (jerr.setjmp_buffer, 1)) {
+ jpeg_destroy_compress (&cinfo);
+ free (buf);
+ return FALSE;
+ }
+
+ /* setup compress params */
+ jpeg_create_compress (&cinfo);
+ jpeg_stdio_dest (&cinfo, f);
+ 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);
+ 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) {
+ /* convert scanline from ARGB to RGB packed */
+ for (j = 0; j < w; j++)
+ memcpy (&(buf[j*3]), &(ptr[i*rowstride + j*3]), 3);
+
+ /* write scanline */
+ jbuf = (JSAMPROW *)(&buf);
+ jpeg_write_scanlines (&cinfo, jbuf, 1);
+ i++;
+ y++;
+
+ }
+
+ /* finish off */
+ jpeg_finish_compress (&cinfo);
+ free (buf);
+ return TRUE;
+}