2 io-jpeg.c: GdkPixBuf loader for jpeg files.
4 Based on io-jpeg from gdk_imlib, but not much.
6 This code is licensed under the Lesser GNU
7 General Public License, version 2.1.
10 Michael Zucchi <zucchi@zedzone.mmc.com.au>
17 #include "gdk-pixbuf.h"
18 /*#include "gdk-pixbuf-io.h"*/
21 /* error handler data */
22 struct iojpeg_JPEG_error_mgr
24 struct jpeg_error_mgr pub;
25 sigjmp_buf setjmp_buffer;
29 g_JPEGFatalErrorHandler(j_common_ptr cinfo)
32 * We should somehow signal what error occurred to the caller so the
33 * caller can handle the error message */
34 struct iojpeg_JPEG_error_mgr *errmgr;
36 errmgr = (struct iojpeg_JPEG_error_mgr *) cinfo->err;
37 cinfo->err->output_message(cinfo);
38 siglongjmp(errmgr->setjmp_buffer, 1);
42 GdkPixBuf *image_load(FILE *f)
45 art_u8 *pixels=NULL, *dptr, *fptr, *pptr;
46 unsigned char *lines[4], /* Used to expand rows, via rec_outbuf_height, from
48 "* Usually rec_outbuf_height will be 1 or 2, at most 4." */
50 struct jpeg_decompress_struct cinfo;
51 struct iojpeg_JPEG_error_mgr jerr;
54 /* setup error handler */
55 cinfo.err = jpeg_std_error(&(jerr.pub));
56 jerr.pub.error_exit = g_JPEGFatalErrorHandler;
58 if (sigsetjmp(jerr.setjmp_buffer, 1)) {
59 /* Whoops there was a jpeg error */
62 jpeg_destroy_decompress(&cinfo);
66 /* load header, setup */
67 jpeg_create_decompress(&cinfo);
68 jpeg_stdio_src(&cinfo, f);
69 jpeg_read_header(&cinfo, TRUE);
70 jpeg_start_decompress(&cinfo);
71 cinfo.do_fancy_upsampling = FALSE;
72 cinfo.do_block_smoothing = FALSE;
74 w = cinfo.output_width;
75 h = cinfo.output_height;
76 g_print("w: %d h: %d\n", w, h);
78 pixels = art_alloc(h * w * 3);
80 jpeg_destroy_decompress(&cinfo);
85 /* decompress all the lines, a few at a time */
87 while (cinfo.output_scanline < cinfo.output_height) {
89 for (i=0;i<cinfo.rec_outbuf_height;i++) {
93 jpeg_read_scanlines(&cinfo, lines, cinfo.rec_outbuf_height);
94 if (cinfo.output_components==1) {
95 /* expand grey->colour */
96 /* expand from the end of the memory down, so we can use
98 for (i=cinfo.rec_outbuf_height-1;i>=0;i--) {
99 unsigned char *from, *to;
102 for (j=w-1;j>=0;j--) {
113 jpeg_finish_decompress(&cinfo);
114 jpeg_destroy_decompress(&cinfo);
116 /* finish off, create the pixbuf */
117 pixbuf = g_new(GdkPixBuf, 1);
118 pixbuf->art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, (w * 3));
119 if (!(pixbuf->art_pixbuf))
121 pixbuf->ref_count = 0;
122 pixbuf->unref_func = NULL;