]> Pileus Git - ~andy/gtk/commitdiff
Added loader for jpeg->RGB.
authorMichael Zucci <zucchi@src.gnome.org>
Tue, 29 Jun 1999 11:13:31 +0000 (11:13 +0000)
committerMichael Zucci <zucchi@src.gnome.org>
Tue, 29 Jun 1999 11:13:31 +0000 (11:13 +0000)
Based really loosely on imlib's io-jpeg.c

gdk-pixbuf/Makefile.am
gdk-pixbuf/io-jpeg.c [new file with mode: 0644]

index acb7979975547f25ae8ced7f9e52cec4ea56589b..d299b1a420a0785d769b6a91c02f970d4b8b7429 100644 (file)
@@ -1,7 +1,8 @@
 
 lib_LTLIBRARIES =              \
        libgdk-pixbuf.la        \
-       libpixbuf-png.la
+       libpixbuf-png.la        \
+       libpixbuf-jpeg.la
 
 #
 # The GdkPixBuf library
@@ -19,4 +20,11 @@ libgdk_pixbufinclude_HEADERS =       \
 # The PNG plugin.
 #
 libpixbuf_png_la_SOURCES =     \
-       io-png.c
\ No newline at end of file
+       io-png.c
+
+#
+# The JPEG loader
+#
+libpixbuf_jpeg_la_SOURCES =    \
+       io-jpeg.c
+
diff --git a/gdk-pixbuf/io-jpeg.c b/gdk-pixbuf/io-jpeg.c
new file mode 100644 (file)
index 0000000..3ba9c36
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+  io-jpeg.c: GdkPixBuf loader for jpeg files.
+
+  Based on io-jpeg from gdk_imlib, but not much.
+
+  This code is licensed under the Lesser GNU
+  General Public License, version 2.1.
+
+  Author:
+    Michael Zucchi <zucchi@zedzone.mmc.com.au>
+*/
+
+#include <config.h>
+#include <stdio.h>
+#include <glib.h>
+#include <setjmp.h>
+#include "gdk-pixbuf.h"
+/*#include "gdk-pixbuf-io.h"*/
+#include <jpeglib.h>
+
+/* error handler data */
+struct iojpeg_JPEG_error_mgr
+{
+       struct jpeg_error_mgr pub;
+       sigjmp_buf          setjmp_buffer;
+};
+
+static void
+g_JPEGFatalErrorHandler(j_common_ptr cinfo)
+{
+       /* FIXME:
+        * We should somehow signal what error occurred to the caller so the
+        * caller can handle the error message */
+       struct iojpeg_JPEG_error_mgr *errmgr;
+
+       errmgr = (struct iojpeg_JPEG_error_mgr *) cinfo->err;
+       cinfo->err->output_message(cinfo);
+       siglongjmp(errmgr->setjmp_buffer, 1);
+       return;
+}
+
+GdkPixBuf *image_load(FILE *f)
+{
+       int w,h,i,j;
+       art_u8 *pixels=NULL, *dptr, *fptr, *pptr;
+       unsigned char *lines[4], /* Used to expand rows, via rec_outbuf_height, from
+                                 the header file:
+                                 "* Usually rec_outbuf_height will be 1 or 2, at most 4." */
+               **lptr;
+       struct jpeg_decompress_struct cinfo;
+       struct iojpeg_JPEG_error_mgr jerr;
+       GdkPixBuf *pixbuf;
+
+       /* setup error handler */
+       cinfo.err = jpeg_std_error(&(jerr.pub));
+       jerr.pub.error_exit = g_JPEGFatalErrorHandler;
+
+       if (sigsetjmp(jerr.setjmp_buffer, 1)) {
+               /* Whoops there was a jpeg error */
+               if (pixels != NULL)
+                       art_free(pixels);
+               jpeg_destroy_decompress(&cinfo);
+               return NULL;
+       }
+
+       /* load header, setup */
+       jpeg_create_decompress(&cinfo);
+       jpeg_stdio_src(&cinfo, f);
+       jpeg_read_header(&cinfo, TRUE);
+       cinfo.do_fancy_upsampling = FALSE;
+       cinfo.do_block_smoothing = FALSE;
+       w = cinfo.output_width;
+       h = cinfo.output_height;
+
+       pixels = art_alloc(h * w * 3);
+       if (pixels == NULL) {
+               jpeg_destroy_decompress(&cinfo);
+               return NULL;
+       }
+       dptr = pixels;
+
+       /* decompress all the lines, a few at a time */
+       jpeg_start_decompress(&cinfo);
+
+       while (cinfo.output_scanline < cinfo.output_height) {
+               lptr = lines;
+               for (i=0;i<cinfo.rec_outbuf_height;i++) {
+                       *lptr++=dptr;
+                       dptr+=w*3;
+               }
+               jpeg_read_scanlines(&cinfo, lines, cinfo.rec_outbuf_height);
+               if (cinfo.output_components==1) {
+                       /* expand grey->colour */
+                       /* expand from the end of the memory down, so we can use
+                          the same buffer */
+                       for (i=cinfo.rec_outbuf_height-1;i>=0;i--) {
+                               unsigned char *from, *to;
+                               from = lines[i]+w-1;
+                               to = lines[i]+w*3-3;
+                               for (j=w-1;j>=0;j++) {
+                                       to[0] = from[0];
+                                       to[1] = from[0];
+                                       to[2] = from[0];
+                                       to-=3;
+                                       from--;
+                               }
+                       }
+               }
+       }
+
+       jpeg_finish_decompress(&cinfo);
+       jpeg_destroy_decompress(&cinfo);
+
+       /* finish off, create the pixbuf */
+       pixbuf = g_new(GdkPixBuf, 1);
+       pixbuf->art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, (w * 3));
+       if (!(pixbuf->art_pixbuf))
+               return NULL;
+       pixbuf->ref_count = 0;
+       pixbuf->unref_func = NULL;
+
+       return pixbuf;
+}
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */