]> Pileus Git - ~andy/gtk/blob - gdk-pixbuf/io-jpeg.c
Cast to gchar* to fix a compilation warning
[~andy/gtk] / gdk-pixbuf / io-jpeg.c
1 /* -*- mode: C; c-file-style: "linux" -*- */
2 /* GdkPixbuf library - JPEG image loader
3  *
4  * Copyright (C) 1999 Michael Zucchi
5  * Copyright (C) 1999 The Free Software Foundation
6  * 
7  * Progressive loading code Copyright (C) 1999 Red Hat, Inc.
8  *
9  * Authors: Michael Zucchi <zucchi@zedzone.mmc.com.au>
10  *          Federico Mena-Quintero <federico@gimp.org>
11  *          Michael Fulbright <drmike@redhat.com>
12  *
13  * This library is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU Lesser General Public
15  * License as published by the Free Software Foundation; either
16  * version 2 of the License, or (at your option) any later version.
17  *
18  * This library is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21  * Lesser General Public License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public
24  * License along with this library; if not, write to the
25  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26  * Boston, MA 02111-1307, USA.
27  */
28
29
30 #include "config.h"
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <setjmp.h>
35 #include <jpeglib.h>
36 #include <jerror.h>
37 #include "gdk-pixbuf-private.h"
38 #include "gdk-pixbuf-io.h"
39
40 #ifndef HAVE_SIGSETJMP
41 #define sigjmp_buf jmp_buf
42 #define sigsetjmp(jb, x) setjmp(jb)
43 #define siglongjmp longjmp
44 #endif
45 \f
46
47 /* we are a "source manager" as far as libjpeg is concerned */
48 #define JPEG_PROG_BUF_SIZE 65536
49
50 typedef struct {
51         struct jpeg_source_mgr pub;   /* public fields */
52
53         JOCTET buffer[JPEG_PROG_BUF_SIZE];              /* start of buffer */
54         long  skip_next;              /* number of bytes to skip next read */
55         
56 } my_source_mgr;
57
58 typedef my_source_mgr * my_src_ptr;
59
60 /* error handler data */
61 struct error_handler_data {
62         struct jpeg_error_mgr pub;
63         sigjmp_buf setjmp_buffer;
64         GError **error;
65 };
66
67 /* progressive loader context */
68 typedef struct {
69         GdkPixbufModuleSizeFunc     size_func;
70         GdkPixbufModuleUpdatedFunc  updated_func;
71         GdkPixbufModulePreparedFunc prepared_func;
72         gpointer                    user_data;
73         
74         GdkPixbuf                *pixbuf;
75         guchar                   *dptr;   /* current position in pixbuf */
76
77         gboolean                 did_prescan;  /* are we in image data yet? */
78         gboolean                 got_header;  /* have we loaded jpeg header? */
79         gboolean                 src_initialized;/* TRUE when jpeg lib initialized */
80         gboolean                 in_output;   /* did we get suspended in an output pass? */
81         struct jpeg_decompress_struct cinfo;
82         struct error_handler_data     jerr;
83 } JpegProgContext;
84
85 static GdkPixbuf *gdk_pixbuf__jpeg_image_load (FILE *f, GError **error);
86 static gpointer gdk_pixbuf__jpeg_image_begin_load (GdkPixbufModuleSizeFunc           func0,
87                                                    GdkPixbufModulePreparedFunc func1, 
88                                                    GdkPixbufModuleUpdatedFunc func2,
89                                                    gpointer user_data,
90                                                    GError **error);
91 static gboolean gdk_pixbuf__jpeg_image_stop_load (gpointer context, GError **error);
92 static gboolean gdk_pixbuf__jpeg_image_load_increment(gpointer context,
93                                                       const guchar *buf, guint size,
94                                                       GError **error);
95
96
97 static void
98 fatal_error_handler (j_common_ptr cinfo)
99 {
100         struct error_handler_data *errmgr;
101         char buffer[JMSG_LENGTH_MAX];
102         
103         errmgr = (struct error_handler_data *) cinfo->err;
104         
105         /* Create the message */
106         (* cinfo->err->format_message) (cinfo, buffer);
107
108         /* broken check for *error == NULL for robustness against
109          * crappy JPEG library
110          */
111         if (errmgr->error && *errmgr->error == NULL) {
112                 g_set_error (errmgr->error,
113                              GDK_PIXBUF_ERROR,
114                              cinfo->err->msg_code == JERR_OUT_OF_MEMORY 
115                              ? GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY 
116                              : GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
117                              _("Error interpreting JPEG image file (%s)"),
118                              buffer);
119         }
120         
121         siglongjmp (errmgr->setjmp_buffer, 1);
122
123         g_assert_not_reached ();
124 }
125
126 static void
127 output_message_handler (j_common_ptr cinfo)
128 {
129   /* This method keeps libjpeg from dumping crap to stderr */
130
131   /* do nothing */
132 }
133
134 /* explode gray image data from jpeg library into rgb components in pixbuf */
135 static void
136 explode_gray_into_buf (struct jpeg_decompress_struct *cinfo,
137                        guchar **lines) 
138 {
139         gint i, j;
140         guint w;
141
142         g_return_if_fail (cinfo != NULL);
143         g_return_if_fail (cinfo->output_components == 1);
144         g_return_if_fail (cinfo->out_color_space == JCS_GRAYSCALE);
145
146         /* Expand grey->colour.  Expand from the end of the
147          * memory down, so we can use the same buffer.
148          */
149         w = cinfo->output_width;
150         for (i = cinfo->rec_outbuf_height - 1; i >= 0; i--) {
151                 guchar *from, *to;
152                 
153                 from = lines[i] + w - 1;
154                 to = lines[i] + (w - 1) * 3;
155                 for (j = w - 1; j >= 0; j--) {
156                         to[0] = from[0];
157                         to[1] = from[0];
158                         to[2] = from[0];
159                         to -= 3;
160                         from--;
161                 }
162         }
163 }
164
165
166 static void
167 convert_cmyk_to_rgb (struct jpeg_decompress_struct *cinfo,
168                      guchar **lines) 
169 {
170         gint i, j;
171
172         g_return_if_fail (cinfo != NULL);
173         g_return_if_fail (cinfo->output_components == 4);
174         g_return_if_fail (cinfo->out_color_space == JCS_CMYK);
175
176         for (i = cinfo->rec_outbuf_height - 1; i >= 0; i--) {
177                 guchar *p;
178                 
179                 p = lines[i];
180                 for (j = 0; j < cinfo->output_width; j++) {
181                         int c, m, y, k;
182                         c = p[0];
183                         m = p[1];
184                         y = p[2];
185                         k = p[3];
186                         if (cinfo->saw_Adobe_marker) {
187                                 p[0] = k*c / 255;
188                                 p[1] = k*m / 255;
189                                 p[2] = k*y / 255;
190                         }
191                         else {
192                                 p[0] = (255 - k)*(255 - c) / 255;
193                                 p[1] = (255 - k)*(255 - m) / 255;
194                                 p[2] = (255 - k)*(255 - y) / 255;
195                         }
196                         p[3] = 255;
197                         p += 4;
198                 }
199         }
200 }
201
202 typedef struct {
203   struct jpeg_source_mgr pub;   /* public fields */
204
205   FILE * infile;                /* source stream */
206   JOCTET * buffer;              /* start of buffer */
207   boolean start_of_file;        /* have we gotten any data yet? */
208 } stdio_source_mgr;
209
210 typedef stdio_source_mgr * stdio_src_ptr;
211
212 static void
213 stdio_init_source (j_decompress_ptr cinfo)
214 {
215   stdio_src_ptr src = (stdio_src_ptr)cinfo->src;
216   src->start_of_file = FALSE;
217 }
218
219 static boolean
220 stdio_fill_input_buffer (j_decompress_ptr cinfo)
221 {
222   stdio_src_ptr src = (stdio_src_ptr) cinfo->src;
223   size_t nbytes;
224
225   nbytes = fread (src->buffer, 1, JPEG_PROG_BUF_SIZE, src->infile);
226
227   if (nbytes <= 0) {
228 #if 0
229     if (src->start_of_file)     /* Treat empty input file as fatal error */
230       ERREXIT(cinfo, JERR_INPUT_EMPTY);
231     WARNMS(cinfo, JWRN_JPEG_EOF);
232 #endif
233     /* Insert a fake EOI marker */
234     src->buffer[0] = (JOCTET) 0xFF;
235     src->buffer[1] = (JOCTET) JPEG_EOI;
236     nbytes = 2;
237   }
238
239   src->pub.next_input_byte = src->buffer;
240   src->pub.bytes_in_buffer = nbytes;
241   src->start_of_file = FALSE;
242
243   return TRUE;
244 }
245
246 static void
247 stdio_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
248 {
249   stdio_src_ptr src = (stdio_src_ptr) cinfo->src;
250
251   if (num_bytes > 0) {
252     while (num_bytes > (long) src->pub.bytes_in_buffer) {
253       num_bytes -= (long) src->pub.bytes_in_buffer;
254       (void)stdio_fill_input_buffer(cinfo);
255     }
256     src->pub.next_input_byte += (size_t) num_bytes;
257     src->pub.bytes_in_buffer -= (size_t) num_bytes;
258   }
259 }
260
261 static void
262 stdio_term_source (j_decompress_ptr cinfo)
263 {
264 }
265
266 static gchar *
267 colorspace_name (const J_COLOR_SPACE jpeg_color_space) 
268 {
269         switch (jpeg_color_space) {
270             case JCS_UNKNOWN: return "UNKNOWN"; 
271             case JCS_GRAYSCALE: return "GRAYSCALE"; 
272             case JCS_RGB: return "RGB"; 
273             case JCS_YCbCr: return "YCbCr"; 
274             case JCS_CMYK: return "CMYK"; 
275             case JCS_YCCK: return "YCCK";
276             default: return "invalid";
277         }
278 }
279
280
281 const char leth[]  = {0x49, 0x49, 0x2a, 0x00};  // Little endian TIFF header
282 const char beth[]  = {0x4d, 0x4d, 0x00, 0x2a};  // Big endian TIFF header
283 const char types[] = {0x00, 0x01, 0x01, 0x02, 0x04, 0x08, 0x00, 
284                       0x08, 0x00, 0x04, 0x08};  // size in bytes for EXIF types
285  
286 #define DE_ENDIAN16(val) endian == G_BIG_ENDIAN ? GUINT16_FROM_BE(val) : GUINT16_FROM_LE(val)
287 #define DE_ENDIAN32(val) endian == G_BIG_ENDIAN ? GUINT32_FROM_BE(val) : GUINT32_FROM_LE(val)
288  
289 #define ENDIAN16_IT(val) endian == G_BIG_ENDIAN ? GUINT16_TO_BE(val) : GUINT16_TO_LE(val)
290 #define ENDIAN32_IT(val) endian == G_BIG_ENDIAN ? GUINT32_TO_BE(val) : GUINT32_TO_LE(val)
291  
292 #define EXIF_JPEG_MARKER   JPEG_APP0+1
293 #define EXIF_IDENT_STRING  "Exif\000\000"
294
295 static unsigned short de_get16(void *ptr, guint endian)
296 {
297        unsigned short val;
298
299        memcpy(&val, ptr, sizeof(val));
300        val = DE_ENDIAN16(val);
301
302        return val;
303 }
304
305 static unsigned int de_get32(void *ptr, guint endian)
306 {
307        unsigned int val;
308
309        memcpy(&val, ptr, sizeof(val));
310        val = DE_ENDIAN32(val);
311
312        return val;
313 }
314
315 static gint 
316 get_orientation (j_decompress_ptr cinfo)
317 {
318         /* This function looks through the meta data in the libjpeg decompress structure to
319            determine if an EXIF Orientation tag is present and if so return its value (1-8). 
320            If no EXIF Orientation tag is found 0 (zero) is returned. */
321
322         guint   i;              /* index into working buffer */
323         guint   orient_tag_id;  /* endianed version of orientation tag ID */
324         guint   ret;            /* Return value */
325         guint   offset;         /* de-endianed offset in various situations */
326         guint   tags;           /* number of tags in current ifd */
327         guint   type;           /* de-endianed type of tag used as index into types[] */
328         guint   count;          /* de-endianed count of elements in a tag */
329         guint   tiff = 0;       /* offset to active tiff header */
330         guint   endian = 0;     /* detected endian of data */
331
332         jpeg_saved_marker_ptr exif_marker;  /* Location of the Exif APP1 marker */
333         jpeg_saved_marker_ptr cmarker;      /* Location to check for Exif APP1 marker */
334
335         /* check for Exif marker (also called the APP1 marker) */
336         exif_marker = NULL;
337         cmarker = cinfo->marker_list;
338         while (cmarker) {
339                 if (cmarker->marker == EXIF_JPEG_MARKER) {
340                         /* The Exif APP1 marker should contain a unique
341                            identification string ("Exif\0\0"). Check for it. */
342                         if (!memcmp (cmarker->data, EXIF_IDENT_STRING, 6)) {
343                                 exif_marker = cmarker;
344                                 }
345                         }
346                 cmarker = cmarker->next;
347         }
348           
349         /* Did we find the Exif APP1 marker? */
350         if (exif_marker == NULL)
351                 return 0;
352
353         /* Do we have enough data? */
354         if (exif_marker->data_length < 32)
355                 return 0;
356
357         /* Check for TIFF header and catch endianess */
358         i = 0;
359
360         /* Just skip data until TIFF header - it should be within 16 bytes from marker start.
361            Normal structure relative to APP1 marker -
362                 0x0000: APP1 marker entry = 2 bytes
363                 0x0002: APP1 length entry = 2 bytes
364                 0x0004: Exif Identifier entry = 6 bytes
365                 0x000A: Start of TIFF header (Byte order entry) - 4 bytes  
366                         - This is what we look for, to determine endianess.
367                 0x000E: 0th IFD offset pointer - 4 bytes
368
369                 exif_marker->data points to the first data after the APP1 marker
370                 and length entries, which is the exif identification string.
371                 The TIFF header should thus normally be found at i=6, below,
372                 and the pointer to IFD0 will be at 6+4 = 10.
373         */
374                     
375         while (i < 16) {
376  
377                 /* Little endian TIFF header */
378                 if (memcmp (&exif_marker->data[i], leth, 4) == 0){ 
379                         endian = G_LITTLE_ENDIAN;
380                 }
381  
382                 /* Big endian TIFF header */
383                 else if (memcmp (&exif_marker->data[i], beth, 4) == 0){ 
384                         endian = G_BIG_ENDIAN;
385                 }
386  
387                 /* Keep looking through buffer */
388                 else {
389                         i++;
390                         continue;
391                 }
392                 /* We have found either big or little endian TIFF header */
393                 tiff = i;
394                 break;
395         }
396
397         /* So did we find a TIFF header or did we just hit end of buffer? */
398         if (tiff == 0) 
399                 return 0;
400  
401         /* Endian the orientation tag ID, to locate it more easily */
402         orient_tag_id = ENDIAN16_IT(0x112);
403  
404         /* Read out the offset pointer to IFD0 */
405         offset  = de_get32(&exif_marker->data[i] + 4, endian);
406         i       = i + offset;
407
408         /* Check that we still are within the buffer and can read the tag count */
409         if ((i + 2) > exif_marker->data_length)
410                 return 0;
411
412         /* Find out how many tags we have in IFD0. As per the TIFF spec, the first
413            two bytes of the IFD contain a count of the number of tags. */
414         tags    = de_get16(&exif_marker->data[i], endian);
415         i       = i + 2;
416
417         /* Check that we still have enough data for all tags to check. The tags
418            are listed in consecutive 12-byte blocks. The tag ID, type, size, and
419            a pointer to the actual value, are packed into these 12 byte entries. */
420         if ((i + tags * 12) > exif_marker->data_length)
421                 return 0;
422
423         /* Check through IFD0 for tags of interest */
424         while (tags--){
425                 type   = de_get16(&exif_marker->data[i + 2], endian);
426                 count  = de_get32(&exif_marker->data[i + 4], endian);
427
428                 /* Is this the orientation tag? */
429                 if (memcmp (&exif_marker->data[i], (char *) &orient_tag_id, 2) == 0){ 
430  
431                         /* Check that type and count fields are OK. The orientation field 
432                            will consist of a single (count=1) 2-byte integer (type=3). */
433                         if (type != 3 || count != 1) return 0;
434
435                         /* Return the orientation value. Within the 12-byte block, the
436                            pointer to the actual data is at offset 8. */
437                         ret =  de_get16(&exif_marker->data[i + 8], endian);
438                         return ret <= 8 ? ret : 0;
439                 }
440                 /* move the pointer to the next 12-byte tag field. */
441                 i = i + 12;
442         }
443
444         return 0; /* No EXIF Orientation tag found */
445 }
446
447
448 /* Shared library entry point */
449 static GdkPixbuf *
450 gdk_pixbuf__jpeg_image_load (FILE *f, GError **error)
451 {
452         gint   i;
453         int     is_otag;
454         char   otag_str[5];
455         GdkPixbuf * volatile pixbuf = NULL;
456         guchar *dptr;
457         guchar *lines[4]; /* Used to expand rows, via rec_outbuf_height, 
458                            * from the header file: 
459                            * " Usually rec_outbuf_height will be 1 or 2, 
460                            * at most 4."
461                            */
462         guchar **lptr;
463         struct jpeg_decompress_struct cinfo;
464         struct error_handler_data jerr;
465         stdio_src_ptr src;
466
467         /* setup error handler */
468         cinfo.err = jpeg_std_error (&jerr.pub);
469         jerr.pub.error_exit = fatal_error_handler;
470         jerr.pub.output_message = output_message_handler;
471         jerr.error = error;
472         
473         if (sigsetjmp (jerr.setjmp_buffer, 1)) {
474                 /* Whoops there was a jpeg error */
475                 if (pixbuf)
476                         g_object_unref (pixbuf);
477
478                 jpeg_destroy_decompress (&cinfo);
479
480                 /* error should have been set by fatal_error_handler () */
481                 return NULL;
482         }
483
484         /* load header, setup */
485         jpeg_create_decompress (&cinfo);
486
487         cinfo.src = (struct jpeg_source_mgr *)
488           (*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT,
489                                   sizeof (stdio_source_mgr));
490         src = (stdio_src_ptr) cinfo.src;
491         src->buffer = (JOCTET *)
492           (*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT,
493                                       JPEG_PROG_BUF_SIZE * sizeof (JOCTET));
494
495         src->pub.init_source = stdio_init_source;
496         src->pub.fill_input_buffer = stdio_fill_input_buffer;
497         src->pub.skip_input_data = stdio_skip_input_data;
498         src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
499         src->pub.term_source = stdio_term_source;
500         src->infile = f;
501         src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
502         src->pub.next_input_byte = NULL; /* until buffer loaded */
503
504         jpeg_save_markers (&cinfo, EXIF_JPEG_MARKER, 0xffff);
505         jpeg_read_header (&cinfo, TRUE);
506
507         /* check for orientation tag */
508         is_otag = get_orientation (&cinfo);
509         
510         jpeg_start_decompress (&cinfo);
511         cinfo.do_fancy_upsampling = FALSE;
512         cinfo.do_block_smoothing = FALSE;
513
514         pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 
515                                  cinfo.out_color_components == 4 ? TRUE : FALSE, 
516                                  8, cinfo.output_width, cinfo.output_height);
517               
518         if (!pixbuf) {
519                 jpeg_destroy_decompress (&cinfo);
520
521                 /* broken check for *error == NULL for robustness against
522                  * crappy JPEG library
523                  */
524                 if (error && *error == NULL) {
525                         g_set_error_literal (error,
526                                              GDK_PIXBUF_ERROR,
527                                              GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
528                                              _("Insufficient memory to load image, try exiting some applications to free memory"));
529                 }
530                 
531                 return NULL;
532         }
533
534         /* if orientation tag was found set an option to remember its value */
535         if (is_otag) {
536                 g_snprintf (otag_str, sizeof (otag_str), "%d", is_otag);
537                 gdk_pixbuf_set_option (pixbuf, "orientation", otag_str);
538         }
539
540
541         dptr = pixbuf->pixels;
542
543         /* decompress all the lines, a few at a time */
544         while (cinfo.output_scanline < cinfo.output_height) {
545                 lptr = lines;
546                 for (i = 0; i < cinfo.rec_outbuf_height; i++) {
547                         *lptr++ = dptr;
548                         dptr += pixbuf->rowstride;
549                 }
550
551                 jpeg_read_scanlines (&cinfo, lines, cinfo.rec_outbuf_height);
552
553                 switch (cinfo.out_color_space) {
554                     case JCS_GRAYSCALE:
555                       explode_gray_into_buf (&cinfo, lines);
556                       break;
557                     case JCS_RGB:
558                       /* do nothing */
559                       break;
560                     case JCS_CMYK:
561                       convert_cmyk_to_rgb (&cinfo, lines);
562                       break;
563                     default:
564                       g_object_unref (pixbuf);
565                       if (error && *error == NULL) {
566                         g_set_error (error,
567                                      GDK_PIXBUF_ERROR,
568                                      GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
569                                      _("Unsupported JPEG color space (%s)"),
570                                      colorspace_name (cinfo.out_color_space)); 
571                       }
572                 
573                       jpeg_destroy_decompress (&cinfo);
574                       return NULL;
575                 }
576         }
577
578         jpeg_finish_decompress (&cinfo);
579         jpeg_destroy_decompress (&cinfo);
580
581         return pixbuf;
582 }
583
584
585 /**** Progressive image loading handling *****/
586
587 /* these routines required because we are acting as a source manager for */
588 /* libjpeg. */
589 static void
590 init_source (j_decompress_ptr cinfo)
591 {
592         my_src_ptr src = (my_src_ptr) cinfo->src;
593
594         src->skip_next = 0;
595 }
596
597
598 static void
599 term_source (j_decompress_ptr cinfo)
600 {
601         /* XXXX - probably should scream something has happened */
602 }
603
604
605 /* for progressive loading (called "I/O Suspension" by libjpeg docs) */
606 /* we do nothing except return "FALSE"                               */
607 static boolean
608 fill_input_buffer (j_decompress_ptr cinfo)
609 {
610         return FALSE;
611 }
612
613
614 static void
615 skip_input_data (j_decompress_ptr cinfo, long num_bytes)
616 {
617         my_src_ptr src = (my_src_ptr) cinfo->src;
618         long   num_can_do;
619
620         /* move as far as we can into current buffer */
621         /* then set skip_next to catch the rest      */
622         if (num_bytes > 0) {
623                 num_can_do = MIN (src->pub.bytes_in_buffer, num_bytes);
624                 src->pub.next_input_byte += (size_t) num_can_do;
625                 src->pub.bytes_in_buffer -= (size_t) num_can_do;
626
627                 src->skip_next = num_bytes - num_can_do;
628         }
629 }
630
631  
632 /* 
633  * func - called when we have pixmap created (but no image data)
634  * user_data - passed as arg 1 to func
635  * return context (opaque to user)
636  */
637
638 static gpointer
639 gdk_pixbuf__jpeg_image_begin_load (GdkPixbufModuleSizeFunc size_func,
640                                    GdkPixbufModulePreparedFunc prepared_func, 
641                                    GdkPixbufModuleUpdatedFunc updated_func,
642                                    gpointer user_data,
643                                    GError **error)
644 {
645         JpegProgContext *context;
646         my_source_mgr   *src;
647
648         context = g_new0 (JpegProgContext, 1);
649         context->size_func = size_func;
650         context->prepared_func = prepared_func;
651         context->updated_func  = updated_func;
652         context->user_data = user_data;
653         context->pixbuf = NULL;
654         context->got_header = FALSE;
655         context->did_prescan = FALSE;
656         context->src_initialized = FALSE;
657         context->in_output = FALSE;
658
659         /* create libjpeg structures */
660         jpeg_create_decompress (&context->cinfo);
661
662         context->cinfo.src = (struct jpeg_source_mgr *) g_try_malloc (sizeof (my_source_mgr));
663         if (!context->cinfo.src) {
664                 g_set_error_literal (error,
665                                      GDK_PIXBUF_ERROR,
666                                      GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
667                                      _("Couldn't allocate memory for loading JPEG file"));
668                 return NULL;
669         }
670         memset (context->cinfo.src, 0, sizeof (my_source_mgr));
671        
672         src = (my_src_ptr) context->cinfo.src;
673
674         context->cinfo.err = jpeg_std_error (&context->jerr.pub);
675         context->jerr.pub.error_exit = fatal_error_handler;
676         context->jerr.pub.output_message = output_message_handler;
677         context->jerr.error = error;
678         
679         src = (my_src_ptr) context->cinfo.src;
680         src->pub.init_source = init_source;
681         src->pub.fill_input_buffer = fill_input_buffer;
682         src->pub.skip_input_data = skip_input_data;
683         src->pub.resync_to_restart = jpeg_resync_to_restart;
684         src->pub.term_source = term_source;
685         src->pub.bytes_in_buffer = 0;
686         src->pub.next_input_byte = NULL;
687
688         context->jerr.error = NULL;
689         
690         return (gpointer) context;
691 }
692
693 /*
694  * context - returned from image_begin_load
695  *
696  * free context, unref gdk_pixbuf
697  */
698 static gboolean
699 gdk_pixbuf__jpeg_image_stop_load (gpointer data, GError **error)
700 {
701         JpegProgContext *context = (JpegProgContext *) data;
702         gboolean retval;
703
704         g_return_val_if_fail (context != NULL, TRUE);
705         
706         /* FIXME this thing needs to report errors if
707          * we have unused image data
708          */
709         
710         if (context->pixbuf)
711                 g_object_unref (context->pixbuf);
712         
713         /* if we have an error? */
714         context->jerr.error = error;
715         if (sigsetjmp (context->jerr.setjmp_buffer, 1)) {
716                 retval = FALSE;
717         } else {
718                 jpeg_finish_decompress (&context->cinfo);
719                 retval = TRUE;
720         }
721
722         jpeg_destroy_decompress (&context->cinfo);
723
724         if (context->cinfo.src) {
725                 my_src_ptr src = (my_src_ptr) context->cinfo.src;
726                 
727                 g_free (src);
728         }
729
730         g_free (context);
731
732         return retval;
733 }
734
735
736 static gboolean
737 gdk_pixbuf__jpeg_image_load_lines (JpegProgContext  *context,
738                                    GError          **error)
739 {
740         struct jpeg_decompress_struct *cinfo = &context->cinfo;
741         guchar *lines[4];
742         guchar **lptr;
743         guchar *rowptr;
744         gint   nlines, i;
745
746         /* keep going until we've done all scanlines */
747         while (cinfo->output_scanline < cinfo->output_height) {
748                 lptr = lines;
749                 rowptr = context->dptr;
750                 for (i=0; i < cinfo->rec_outbuf_height; i++) {
751                         *lptr++ = rowptr;
752                         rowptr += context->pixbuf->rowstride;
753                 }
754
755                 nlines = jpeg_read_scanlines (cinfo, lines,
756                                               cinfo->rec_outbuf_height);
757                 if (nlines == 0)
758                         break;
759
760                 switch (cinfo->out_color_space) {
761                 case JCS_GRAYSCALE:
762                         explode_gray_into_buf (cinfo, lines);
763                         break;
764                 case JCS_RGB:
765                         /* do nothing */
766                         break;
767                 case JCS_CMYK:
768                         convert_cmyk_to_rgb (cinfo, lines);
769                         break;
770                 default:
771                         if (error && *error == NULL) {
772                                 g_set_error (error,
773                                              GDK_PIXBUF_ERROR,
774                                              GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
775                                              _("Unsupported JPEG color space (%s)"),
776                                              colorspace_name (cinfo->out_color_space));
777                         }
778
779                         return FALSE;
780                 }
781
782                 context->dptr += nlines * context->pixbuf->rowstride;
783
784                 /* send updated signal */
785                 if (context->updated_func)
786                         (* context->updated_func) (context->pixbuf,
787                                                    0,
788                                                    cinfo->output_scanline - 1,
789                                                    cinfo->image_width,
790                                                    nlines,
791                                                    context->user_data);
792         }
793
794         return TRUE;
795 }
796
797
798 /*
799  * context - from image_begin_load
800  * buf - new image data
801  * size - length of new image data
802  *
803  * append image data onto inrecrementally built output image
804  */
805 static gboolean
806 gdk_pixbuf__jpeg_image_load_increment (gpointer data,
807                                        const guchar *buf, guint size,
808                                        GError **error)
809 {
810         JpegProgContext *context = (JpegProgContext *)data;
811         struct           jpeg_decompress_struct *cinfo;
812         my_src_ptr       src;
813         guint            num_left, num_copy;
814         guint            last_num_left, last_bytes_left;
815         guint            spinguard;
816         gboolean         first;
817         const guchar    *bufhd;
818         gint             width, height;
819         int              is_otag;
820         char             otag_str[5];
821
822         g_return_val_if_fail (context != NULL, FALSE);
823         g_return_val_if_fail (buf != NULL, FALSE);
824
825         src = (my_src_ptr) context->cinfo.src;
826
827         cinfo = &context->cinfo;
828
829         context->jerr.error = error;
830         
831         /* check for fatal error */
832         if (sigsetjmp (context->jerr.setjmp_buffer, 1)) {
833                 return FALSE;
834         }
835
836         /* skip over data if requested, handle unsigned int sizes cleanly */
837         /* only can happen if we've already called jpeg_get_header once   */
838         if (context->src_initialized && src->skip_next) {
839                 if (src->skip_next > size) {
840                         src->skip_next -= size;
841                         return TRUE;
842                 } else {
843                         num_left = size - src->skip_next;
844                         bufhd = buf + src->skip_next;
845                         src->skip_next = 0;
846                 }
847         } else {
848                 num_left = size;
849                 bufhd = buf;
850         }
851
852         if (num_left == 0)
853                 return TRUE;
854
855         last_num_left = num_left;
856         last_bytes_left = 0;
857         spinguard = 0;
858         first = TRUE;
859         while (TRUE) {
860
861                 /* handle any data from caller we haven't processed yet */
862                 if (num_left > 0) {
863                         if(src->pub.bytes_in_buffer && 
864                            src->pub.next_input_byte != src->buffer)
865                                 memmove(src->buffer, src->pub.next_input_byte,
866                                         src->pub.bytes_in_buffer);
867
868
869                         num_copy = MIN (JPEG_PROG_BUF_SIZE - src->pub.bytes_in_buffer,
870                                         num_left);
871
872                         memcpy(src->buffer + src->pub.bytes_in_buffer, bufhd,num_copy);
873                         src->pub.next_input_byte = src->buffer;
874                         src->pub.bytes_in_buffer += num_copy;
875                         bufhd += num_copy;
876                         num_left -= num_copy;
877                 }
878
879                 /* did anything change from last pass, if not return */
880                 if (first) {
881                         last_bytes_left = src->pub.bytes_in_buffer;
882                         first = FALSE;
883                 } else if (src->pub.bytes_in_buffer == last_bytes_left
884                            && num_left == last_num_left) {
885                         spinguard++;
886                 } else {
887                         last_bytes_left = src->pub.bytes_in_buffer;
888                         last_num_left = num_left;
889                 }
890
891                 /* should not go through twice and not pull bytes out of buf */
892                 if (spinguard > 2)
893                         return TRUE;
894
895                 /* try to load jpeg header */
896                 if (!context->got_header) {
897                         int rc;
898                 
899                         jpeg_save_markers (cinfo, EXIF_JPEG_MARKER, 0xffff);
900                         rc = jpeg_read_header (cinfo, TRUE);
901                         context->src_initialized = TRUE;
902                         
903                         if (rc == JPEG_SUSPENDED)
904                                 continue;
905                         
906                         context->got_header = TRUE;
907
908                         /* check for orientation tag */
909                         is_otag = get_orientation (cinfo);
910                 
911                         width = cinfo->image_width;
912                         height = cinfo->image_height;
913                         if (context->size_func) {
914                                 (* context->size_func) (&width, &height, context->user_data);
915                                 if (width == 0 || height == 0) {
916                                         g_set_error_literal (error,
917                                                              GDK_PIXBUF_ERROR,
918                                                              GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
919                                                              _("Transformed JPEG has zero width or height."));
920                                         return FALSE;
921                                 }
922                         }
923                         
924                         for (cinfo->scale_denom = 2; cinfo->scale_denom <= 8; cinfo->scale_denom *= 2) {
925                                 jpeg_calc_output_dimensions (cinfo);
926                                 if (cinfo->output_width < width || cinfo->output_height < height) {
927                                         cinfo->scale_denom /= 2;
928                                         break;
929                                 }
930                         }
931                         jpeg_calc_output_dimensions (cinfo);
932                         
933                         context->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 
934                                                           cinfo->output_components == 4 ? TRUE : FALSE,
935                                                           8, 
936                                                           cinfo->output_width,
937                                                           cinfo->output_height);
938
939                         if (context->pixbuf == NULL) {
940                                 g_set_error_literal (error,
941                                                      GDK_PIXBUF_ERROR,
942                                                      GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
943                                                      _("Couldn't allocate memory for loading JPEG file"));
944                                 return FALSE;
945                         }
946                 
947                         /* if orientation tag was found set an option to remember its value */
948                         if (is_otag) {
949                                 g_snprintf (otag_str, sizeof (otag_str), "%d", is_otag);
950                                 gdk_pixbuf_set_option (context->pixbuf, "orientation", otag_str);
951                         }
952
953                         /* Use pixbuf buffer to store decompressed data */
954                         context->dptr = context->pixbuf->pixels;
955                         
956                         /* Notify the client that we are ready to go */
957                         if (context->prepared_func)
958                                 (* context->prepared_func) (context->pixbuf,
959                                                             NULL,
960                                                             context->user_data);
961                         
962                 } else if (!context->did_prescan) {
963                         int rc;                 
964                         
965                         /* start decompression */
966                         cinfo->buffered_image = cinfo->progressive_mode;
967                         rc = jpeg_start_decompress (cinfo);
968                         cinfo->do_fancy_upsampling = FALSE;
969                         cinfo->do_block_smoothing = FALSE;
970
971                         if (rc == JPEG_SUSPENDED)
972                                 continue;
973
974                         context->did_prescan = TRUE;
975                 } else if (!cinfo->buffered_image) {
976                         /* we're decompressing unbuffered so
977                          * simply get scanline by scanline from jpeg lib
978                          */
979                         if (! gdk_pixbuf__jpeg_image_load_lines (context,
980                                                                  error))
981                                 return FALSE;
982
983                         if (cinfo->output_scanline >= cinfo->output_height)
984                                 return TRUE;
985                 } else {
986                         /* we're decompressing buffered (progressive)
987                          * so feed jpeg lib scanlines
988                          */
989
990                         /* keep going until we've done all passes */
991                         while (!jpeg_input_complete (cinfo)) {
992                                 if (!context->in_output) {
993                                         if (jpeg_start_output (cinfo, cinfo->input_scan_number)) {
994                                                 context->in_output = TRUE;
995                                                 context->dptr = context->pixbuf->pixels;
996                                         }
997                                         else
998                                                 break;
999                                 }
1000
1001                                 /* get scanlines from jpeg lib */
1002                                 if (! gdk_pixbuf__jpeg_image_load_lines (context,
1003                                                                          error))
1004                                         return FALSE;
1005
1006                                 if (cinfo->output_scanline >= cinfo->output_height &&
1007                                     jpeg_finish_output (cinfo))
1008                                         context->in_output = FALSE;
1009                                 else
1010                                         break;
1011                         }
1012                         if (jpeg_input_complete (cinfo))
1013                                 /* did entire image */
1014                                 return TRUE;
1015                         else
1016                                 continue;
1017                 }
1018         }
1019 }
1020
1021 /* Save */
1022
1023 #define TO_FUNCTION_BUF_SIZE 4096
1024
1025 typedef struct {
1026         struct jpeg_destination_mgr pub;
1027         JOCTET             *buffer;
1028         GdkPixbufSaveFunc   save_func;
1029         gpointer            user_data;
1030         GError            **error;
1031 } ToFunctionDestinationManager;
1032
1033 void
1034 to_callback_init (j_compress_ptr cinfo)
1035 {
1036         ToFunctionDestinationManager *destmgr;
1037
1038         destmgr = (ToFunctionDestinationManager*) cinfo->dest;
1039         destmgr->pub.next_output_byte = destmgr->buffer;
1040         destmgr->pub.free_in_buffer = TO_FUNCTION_BUF_SIZE;
1041 }
1042
1043 static void
1044 to_callback_do_write (j_compress_ptr cinfo, gsize length)
1045 {
1046         ToFunctionDestinationManager *destmgr;
1047
1048         destmgr = (ToFunctionDestinationManager*) cinfo->dest;
1049         if (!destmgr->save_func ((gchar *)destmgr->buffer,
1050                                  length,
1051                                  destmgr->error,
1052                                  destmgr->user_data)) {
1053                 struct error_handler_data *errmgr;
1054         
1055                 errmgr = (struct error_handler_data *) cinfo->err;
1056                 /* Use a default error message if the callback didn't set one,
1057                  * which it should have.
1058                  */
1059                 if (errmgr->error && *errmgr->error == NULL) {
1060                         g_set_error_literal (errmgr->error,
1061                                              GDK_PIXBUF_ERROR,
1062                                              GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
1063                                              "write function failed");
1064                 }
1065                 siglongjmp (errmgr->setjmp_buffer, 1);
1066                 g_assert_not_reached ();
1067         }
1068 }
1069
1070 static boolean
1071 to_callback_empty_output_buffer (j_compress_ptr cinfo)
1072 {
1073         ToFunctionDestinationManager *destmgr;
1074
1075         destmgr = (ToFunctionDestinationManager*) cinfo->dest;
1076         to_callback_do_write (cinfo, TO_FUNCTION_BUF_SIZE);
1077         destmgr->pub.next_output_byte = destmgr->buffer;
1078         destmgr->pub.free_in_buffer = TO_FUNCTION_BUF_SIZE;
1079         return TRUE;
1080 }
1081
1082 void
1083 to_callback_terminate (j_compress_ptr cinfo)
1084 {
1085         ToFunctionDestinationManager *destmgr;
1086
1087         destmgr = (ToFunctionDestinationManager*) cinfo->dest;
1088         to_callback_do_write (cinfo, TO_FUNCTION_BUF_SIZE - destmgr->pub.free_in_buffer);
1089 }
1090
1091 static gboolean
1092 real_save_jpeg (GdkPixbuf          *pixbuf,
1093                 gchar             **keys,
1094                 gchar             **values,
1095                 GError            **error,
1096                 gboolean            to_callback,
1097                 FILE               *f,
1098                 GdkPixbufSaveFunc   save_func,
1099                 gpointer            user_data)
1100 {
1101         /* FIXME error handling is broken */
1102         
1103        struct jpeg_compress_struct cinfo;
1104        guchar *buf = NULL;
1105        guchar *ptr;
1106        guchar *pixels = NULL;
1107        JSAMPROW *jbuf;
1108        int y = 0;
1109        volatile int quality = 75; /* default; must be between 0 and 100 */
1110        int i, j;
1111        int w, h = 0;
1112        int rowstride = 0;
1113        int n_channels;
1114        struct error_handler_data jerr;
1115        ToFunctionDestinationManager to_callback_destmgr;
1116
1117        to_callback_destmgr.buffer = NULL;
1118
1119        if (keys && *keys) {
1120                gchar **kiter = keys;
1121                gchar **viter = values;
1122
1123                while (*kiter) {
1124                        if (strcmp (*kiter, "quality") == 0) {
1125                                char *endptr = NULL;
1126                                quality = strtol (*viter, &endptr, 10);
1127
1128                                if (endptr == *viter) {
1129                                        g_set_error (error,
1130                                                     GDK_PIXBUF_ERROR,
1131                                                     GDK_PIXBUF_ERROR_BAD_OPTION,
1132                                                     _("JPEG quality must be a value between 0 and 100; value '%s' could not be parsed."),
1133                                                     *viter);
1134
1135                                        return FALSE;
1136                                }
1137                                
1138                                if (quality < 0 ||
1139                                    quality > 100) {
1140                                        /* This is a user-visible error;
1141                                         * lets people skip the range-checking
1142                                         * in their app.
1143                                         */
1144                                        g_set_error (error,
1145                                                     GDK_PIXBUF_ERROR,
1146                                                     GDK_PIXBUF_ERROR_BAD_OPTION,
1147                                                     _("JPEG quality must be a value between 0 and 100; value '%d' is not allowed."),
1148                                                     quality);
1149
1150                                        return FALSE;
1151                                }
1152                        } else {
1153                                g_warning ("Unrecognized parameter (%s) passed to JPEG saver.", *kiter);
1154                        }
1155                
1156                        ++kiter;
1157                        ++viter;
1158                }
1159        }
1160        
1161        rowstride = gdk_pixbuf_get_rowstride (pixbuf);
1162        n_channels = gdk_pixbuf_get_n_channels (pixbuf);
1163
1164        w = gdk_pixbuf_get_width (pixbuf);
1165        h = gdk_pixbuf_get_height (pixbuf);
1166        pixels = gdk_pixbuf_get_pixels (pixbuf);
1167
1168        /* Allocate a small buffer to convert image data,
1169         * and a larger buffer if doing to_callback save.
1170         */
1171        buf = g_try_malloc (w * 3 * sizeof (guchar));
1172        if (!buf) {
1173                g_set_error_literal (error,
1174                                     GDK_PIXBUF_ERROR,
1175                                     GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
1176                                     _("Couldn't allocate memory for loading JPEG file"));
1177                return FALSE;
1178        }
1179        if (to_callback) {
1180                to_callback_destmgr.buffer = g_try_malloc (TO_FUNCTION_BUF_SIZE);
1181                if (!to_callback_destmgr.buffer) {
1182                        g_set_error_literal (error,
1183                                             GDK_PIXBUF_ERROR,
1184                                             GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
1185                                             _("Couldn't allocate memory for loading JPEG file"));
1186                        g_free (buf);
1187                        return FALSE;
1188                }
1189        }
1190
1191        /* set up error handling */
1192        cinfo.err = jpeg_std_error (&(jerr.pub));
1193        jerr.pub.error_exit = fatal_error_handler;
1194        jerr.pub.output_message = output_message_handler;
1195        jerr.error = error;
1196        
1197        if (sigsetjmp (jerr.setjmp_buffer, 1)) {
1198                jpeg_destroy_compress (&cinfo);
1199                g_free (buf);
1200                g_free (to_callback_destmgr.buffer);
1201                return FALSE;
1202        }
1203
1204        /* setup compress params */
1205        jpeg_create_compress (&cinfo);
1206        if (to_callback) {
1207                to_callback_destmgr.pub.init_destination    = to_callback_init;
1208                to_callback_destmgr.pub.empty_output_buffer = to_callback_empty_output_buffer;
1209                to_callback_destmgr.pub.term_destination    = to_callback_terminate;
1210                to_callback_destmgr.error = error;
1211                to_callback_destmgr.save_func = save_func;
1212                to_callback_destmgr.user_data = user_data;
1213                cinfo.dest = (struct jpeg_destination_mgr*) &to_callback_destmgr;
1214        } else {
1215                jpeg_stdio_dest (&cinfo, f);
1216        }
1217        cinfo.image_width      = w;
1218        cinfo.image_height     = h;
1219        cinfo.input_components = 3; 
1220        cinfo.in_color_space   = JCS_RGB;
1221
1222        /* set up jepg compression parameters */
1223        jpeg_set_defaults (&cinfo);
1224        jpeg_set_quality (&cinfo, quality, TRUE);
1225        jpeg_start_compress (&cinfo, TRUE);
1226        /* get the start pointer */
1227        ptr = pixels;
1228        /* go one scanline at a time... and save */
1229        i = 0;
1230        while (cinfo.next_scanline < cinfo.image_height) {
1231                /* convert scanline from ARGB to RGB packed */
1232                for (j = 0; j < w; j++)
1233                        memcpy (&(buf[j*3]), &(ptr[i*rowstride + j*n_channels]), 3);
1234
1235                /* write scanline */
1236                jbuf = (JSAMPROW *)(&buf);
1237                jpeg_write_scanlines (&cinfo, jbuf, 1);
1238                i++;
1239                y++;
1240
1241        }
1242        
1243        /* finish off */
1244        jpeg_finish_compress (&cinfo);
1245        jpeg_destroy_compress(&cinfo);
1246        g_free (buf);
1247        g_free (to_callback_destmgr.buffer);
1248        return TRUE;
1249 }
1250
1251 static gboolean
1252 gdk_pixbuf__jpeg_image_save (FILE          *f, 
1253                              GdkPixbuf     *pixbuf, 
1254                              gchar        **keys,
1255                              gchar        **values,
1256                              GError       **error)
1257 {
1258         return real_save_jpeg (pixbuf, keys, values, error,
1259                                FALSE, f, NULL, NULL);
1260 }
1261
1262 static gboolean
1263 gdk_pixbuf__jpeg_image_save_to_callback (GdkPixbufSaveFunc   save_func,
1264                                          gpointer            user_data,
1265                                          GdkPixbuf          *pixbuf, 
1266                                          gchar             **keys,
1267                                          gchar             **values,
1268                                          GError            **error)
1269 {
1270         return real_save_jpeg (pixbuf, keys, values, error,
1271                                TRUE, NULL, save_func, user_data);
1272 }
1273
1274 #ifndef INCLUDE_jpeg
1275 #define MODULE_ENTRY(function) G_MODULE_EXPORT void function
1276 #else
1277 #define MODULE_ENTRY(function) void _gdk_pixbuf__jpeg_ ## function
1278 #endif
1279
1280 MODULE_ENTRY (fill_vtable) (GdkPixbufModule *module)
1281 {
1282         module->load = gdk_pixbuf__jpeg_image_load;
1283         module->begin_load = gdk_pixbuf__jpeg_image_begin_load;
1284         module->stop_load = gdk_pixbuf__jpeg_image_stop_load;
1285         module->load_increment = gdk_pixbuf__jpeg_image_load_increment;
1286         module->save = gdk_pixbuf__jpeg_image_save;
1287         module->save_to_callback = gdk_pixbuf__jpeg_image_save_to_callback;
1288 }
1289
1290 MODULE_ENTRY (fill_info) (GdkPixbufFormat *info)
1291 {
1292         static GdkPixbufModulePattern signature[] = {
1293                 { "\xff\xd8", NULL, 100 },
1294                 { NULL, NULL, 0 }
1295         };
1296         static gchar * mime_types[] = {
1297                 "image/jpeg",
1298                 NULL
1299         };
1300         static gchar * extensions[] = {
1301                 "jpeg",
1302                 "jpe",
1303                 "jpg",
1304                 NULL
1305         };
1306
1307         info->name = "jpeg";
1308         info->signature = signature;
1309         info->description = N_("The JPEG image format");
1310         info->mime_types = mime_types;
1311         info->extensions = extensions;
1312         info->flags = GDK_PIXBUF_FORMAT_WRITABLE | GDK_PIXBUF_FORMAT_THREADSAFE;
1313         info->license = "LGPL";
1314 }