1 /* GdkPixbuf library - JPEG image loader
3 * Copyright (C) 1999 Michael Zucchi
4 * Copyright (C) 1999 The Free Software Foundation
6 * Authors: Michael Zucchi <zucchi@zedzone.mmc.com.au>
7 * Federico Mena-Quintero <federico@gimp.org>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
29 #include "gdk-pixbuf.h"
33 /* error handler data */
34 struct error_handler_data {
35 struct jpeg_error_mgr pub;
36 sigjmp_buf setjmp_buffer;
40 fatal_error_handler (j_common_ptr cinfo)
43 * We should somehow signal what error occurred to the caller so the
44 * caller can handle the error message */
45 struct error_handler_data *errmgr;
47 errmgr = (struct error_handler_data *) cinfo->err;
48 cinfo->err->output_message (cinfo);
49 siglongjmp (errmgr->setjmp_buffer, 1);
53 /* Destroy notification function for the libart pixbuf */
55 free_buffer (gpointer user_data, gpointer data)
60 /* Shared library entry point */
65 guchar *pixels = NULL;
67 guchar *lines[4]; /* Used to expand rows, via rec_outbuf_height, from the header file:
68 * "* Usually rec_outbuf_height will be 1 or 2, at most 4."
71 struct jpeg_decompress_struct cinfo;
72 struct error_handler_data jerr;
75 /* setup error handler */
76 cinfo.err = jpeg_std_error (&jerr.pub);
77 jerr.pub.error_exit = fatal_error_handler;
79 if (sigsetjmp (jerr.setjmp_buffer, 1)) {
80 /* Whoops there was a jpeg error */
84 jpeg_destroy_decompress (&cinfo);
88 /* load header, setup */
89 jpeg_create_decompress (&cinfo);
90 jpeg_stdio_src (&cinfo, f);
91 jpeg_read_header (&cinfo, TRUE);
92 jpeg_start_decompress (&cinfo);
93 cinfo.do_fancy_upsampling = FALSE;
94 cinfo.do_block_smoothing = FALSE;
96 w = cinfo.output_width;
97 h = cinfo.output_height;
99 pixels = malloc (h * w * 3);
101 jpeg_destroy_decompress (&cinfo);
107 /* decompress all the lines, a few at a time */
109 while (cinfo.output_scanline < cinfo.output_height) {
111 for (i = 0; i < cinfo.rec_outbuf_height; i++) {
116 jpeg_read_scanlines (&cinfo, lines, cinfo.rec_outbuf_height);
117 if (cinfo.output_components == 1) {
118 /* Expand grey->colour. Expand from the end of the
119 * memory down, so we can use the same buffer.
121 for (i = cinfo.rec_outbuf_height - 1; i >= 0; i--) {
124 from = lines[i] + w - 1;
125 to = lines[i] + w * 3 - 3;
126 for (j = w - 1; j >= 0; j--) {
137 jpeg_finish_decompress (&cinfo);
138 jpeg_destroy_decompress (&cinfo);
140 return gdk_pixbuf_new_from_data (pixels, ART_PIX_RGB, FALSE,