summaryrefslogtreecommitdiff
path: root/gdk-pixbuf
diff options
context:
space:
mode:
authorMichael Zucci <zucchi@src.gnome.org>1999-06-29 11:13:31 +0000
committerMichael Zucci <zucchi@src.gnome.org>1999-06-29 11:13:31 +0000
commita0b1a437cc85c638100517aa6037786d3c0e65e7 (patch)
treefe297fd8456261cea31c56174692e18142fae20e /gdk-pixbuf
parent42311804a42482bde8e34208cce943b0d85d454c (diff)
downloadgtk+-a0b1a437cc85c638100517aa6037786d3c0e65e7.tar.gz
Added loader for jpeg->RGB.
Based really loosely on imlib's io-jpeg.c
Diffstat (limited to 'gdk-pixbuf')
-rw-r--r--gdk-pixbuf/Makefile.am12
-rw-r--r--gdk-pixbuf/io-jpeg.c129
2 files changed, 139 insertions, 2 deletions
diff --git a/gdk-pixbuf/Makefile.am b/gdk-pixbuf/Makefile.am
index acb7979975..d299b1a420 100644
--- a/gdk-pixbuf/Makefile.am
+++ b/gdk-pixbuf/Makefile.am
@@ -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
index 0000000000..3ba9c36a0e
--- /dev/null
+++ b/gdk-pixbuf/io-jpeg.c
@@ -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:
+ */