diff options
author | Michael Zucci <zucchi@src.gnome.org> | 1999-06-29 11:13:31 +0000 |
---|---|---|
committer | Michael Zucci <zucchi@src.gnome.org> | 1999-06-29 11:13:31 +0000 |
commit | a0b1a437cc85c638100517aa6037786d3c0e65e7 (patch) | |
tree | fe297fd8456261cea31c56174692e18142fae20e /gdk-pixbuf | |
parent | 42311804a42482bde8e34208cce943b0d85d454c (diff) | |
download | gtk+-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.am | 12 | ||||
-rw-r--r-- | gdk-pixbuf/io-jpeg.c | 129 |
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: + */ |