]> Pileus Git - ~andy/gtk/blob - gdk-pixbuf/io-jpeg.c
b360190e4140db25ac016e6cf1cc4ade71faf323
[~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
472         jerr.error = error;
473         
474         if (sigsetjmp (jerr.setjmp_buffer, 1)) {
475                 /* Whoops there was a jpeg error */
476                 if (pixbuf)
477                         g_object_unref (pixbuf);
478
479                 jpeg_destroy_decompress (&cinfo);
480
481                 /* error should have been set by fatal_error_handler () */
482                 return NULL;
483         }
484
485         /* load header, setup */
486         jpeg_create_decompress (&cinfo);
487
488         cinfo.src = (struct jpeg_source_mgr *)
489           (*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT,
490                                   sizeof (stdio_source_mgr));
491         src = (stdio_src_ptr) cinfo.src;
492         src->buffer = (JOCTET *)
493           (*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT,
494                                       JPEG_PROG_BUF_SIZE * sizeof (JOCTET));
495
496         src->pub.init_source = stdio_init_source;
497         src->pub.fill_input_buffer = stdio_fill_input_buffer;
498         src->pub.skip_input_data = stdio_skip_input_data;
499         src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
500         src->pub.term_source = stdio_term_source;
501         src->infile = f;
502         src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
503         src->pub.next_input_byte = NULL; /* until buffer loaded */
504
505         jpeg_save_markers (&cinfo, EXIF_JPEG_MARKER, 0xffff);
506         jpeg_read_header (&cinfo, TRUE);
507
508         /* check for orientation tag */
509         is_otag = get_orientation (&cinfo);
510         
511         jpeg_start_decompress (&cinfo);
512         cinfo.do_fancy_upsampling = FALSE;
513         cinfo.do_block_smoothing = FALSE;
514
515         pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 
516                                  cinfo.out_color_components == 4 ? TRUE : FALSE, 
517                                  8, cinfo.output_width, cinfo.output_height);
518               
519         if (!pixbuf) {
520                 jpeg_destroy_decompress (&cinfo);
521
522                 /* broken check for *error == NULL for robustness against
523                  * crappy JPEG library
524                  */
525                 if (error && *error == NULL) {
526                         g_set_error_literal (error,
527                                              GDK_PIXBUF_ERROR,
528                                              GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
529                                              _("Insufficient memory to load image, try exiting some applications to free memory"));
530                 }
531                 
532                 return NULL;
533         }
534
535         /* if orientation tag was found set an option to remember its value */
536         if (is_otag) {
537                 g_snprintf (otag_str, sizeof (otag_str), "%d", is_otag);
538                 gdk_pixbuf_set_option (pixbuf, "orientation", otag_str);
539         }
540
541
542         dptr = pixbuf->pixels;
543
544         /* decompress all the lines, a few at a time */
545         while (cinfo.output_scanline < cinfo.output_height) {
546                 lptr = lines;
547                 for (i = 0; i < cinfo.rec_outbuf_height; i++) {
548                         *lptr++ = dptr;
549                         dptr += pixbuf->rowstride;
550                 }
551
552                 jpeg_read_scanlines (&cinfo, lines, cinfo.rec_outbuf_height);
553
554                 switch (cinfo.out_color_space) {
555                     case JCS_GRAYSCALE:
556                       explode_gray_into_buf (&cinfo, lines);
557                       break;
558                     case JCS_RGB:
559                       /* do nothing */
560                       break;
561                     case JCS_CMYK:
562                       convert_cmyk_to_rgb (&cinfo, lines);
563                       break;
564                     default:
565                       g_object_unref (pixbuf);
566                       if (error && *error == NULL) {
567                         g_set_error (error,
568                                      GDK_PIXBUF_ERROR,
569                                      GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
570                                      _("Unsupported JPEG color space (%s)"),
571                                      colorspace_name (cinfo.out_color_space)); 
572                       }
573                 
574                       jpeg_destroy_decompress (&cinfo);
575                       return NULL;
576                 }
577         }
578
579         jpeg_finish_decompress (&cinfo);
580         jpeg_destroy_decompress (&cinfo);
581
582         return pixbuf;
583 }
584
585
586 /**** Progressive image loading handling *****/
587
588 /* these routines required because we are acting as a source manager for */
589 /* libjpeg. */
590 static void
591 init_source (j_decompress_ptr cinfo)
592 {
593         my_src_ptr src = (my_src_ptr) cinfo->src;
594
595         src->skip_next = 0;
596 }
597
598
599 static void
600 term_source (j_decompress_ptr cinfo)
601 {
602         /* XXXX - probably should scream something has happened */
603 }
604
605
606 /* for progressive loading (called "I/O Suspension" by libjpeg docs) */
607 /* we do nothing except return "FALSE"                               */
608 static boolean
609 fill_input_buffer (j_decompress_ptr cinfo)
610 {
611         return FALSE;
612 }
613
614
615 static void
616 skip_input_data (j_decompress_ptr cinfo, long num_bytes)
617 {
618         my_src_ptr src = (my_src_ptr) cinfo->src;
619         long   num_can_do;
620
621         /* move as far as we can into current buffer */
622         /* then set skip_next to catch the rest      */
623         if (num_bytes > 0) {
624                 num_can_do = MIN (src->pub.bytes_in_buffer, num_bytes);
625                 src->pub.next_input_byte += (size_t) num_can_do;
626                 src->pub.bytes_in_buffer -= (size_t) num_can_do;
627
628                 src->skip_next = num_bytes - num_can_do;
629         }
630 }
631
632  
633 /* 
634  * func - called when we have pixmap created (but no image data)
635  * user_data - passed as arg 1 to func
636  * return context (opaque to user)
637  */
638
639 static gpointer
640 gdk_pixbuf__jpeg_image_begin_load (GdkPixbufModuleSizeFunc size_func,
641                                    GdkPixbufModulePreparedFunc prepared_func, 
642                                    GdkPixbufModuleUpdatedFunc updated_func,
643                                    gpointer user_data,
644                                    GError **error)
645 {
646         JpegProgContext *context;
647         my_source_mgr   *src;
648
649         context = g_new0 (JpegProgContext, 1);
650         context->size_func = size_func;
651         context->prepared_func = prepared_func;
652         context->updated_func  = updated_func;
653         context->user_data = user_data;
654         context->pixbuf = NULL;
655         context->got_header = FALSE;
656         context->did_prescan = FALSE;
657         context->src_initialized = FALSE;
658         context->in_output = FALSE;
659
660         /* create libjpeg structures */
661         jpeg_create_decompress (&context->cinfo);
662
663         context->cinfo.src = (struct jpeg_source_mgr *) g_try_malloc (sizeof (my_source_mgr));
664         if (!context->cinfo.src) {
665                 g_set_error_literal (error,
666                                      GDK_PIXBUF_ERROR,
667                                      GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
668                                      _("Couldn't allocate memory for loading JPEG file"));
669                 return NULL;
670         }
671         memset (context->cinfo.src, 0, sizeof (my_source_mgr));
672        
673         src = (my_src_ptr) context->cinfo.src;
674
675         context->cinfo.err = jpeg_std_error (&context->jerr.pub);
676         context->jerr.pub.error_exit = fatal_error_handler;
677         context->jerr.pub.output_message = output_message_handler;
678         context->jerr.error = error;
679         
680         src = (my_src_ptr) context->cinfo.src;
681         src->pub.init_source = init_source;
682         src->pub.fill_input_buffer = fill_input_buffer;
683         src->pub.skip_input_data = skip_input_data;
684         src->pub.resync_to_restart = jpeg_resync_to_restart;
685         src->pub.term_source = term_source;
686         src->pub.bytes_in_buffer = 0;
687         src->pub.next_input_byte = NULL;
688
689         context->jerr.error = NULL;
690         
691         return (gpointer) context;
692 }
693
694 /*
695  * context - returned from image_begin_load
696  *
697  * free context, unref gdk_pixbuf
698  */
699 static gboolean
700 gdk_pixbuf__jpeg_image_stop_load (gpointer data, GError **error)
701 {
702         JpegProgContext *context = (JpegProgContext *) data;
703         gboolean retval;
704
705         g_return_val_if_fail (context != NULL, TRUE);
706         
707         /* FIXME this thing needs to report errors if
708          * we have unused image data
709          */
710         
711         if (context->pixbuf)
712                 g_object_unref (context->pixbuf);
713         
714         /* if we have an error? */
715         context->jerr.error = error;
716         if (sigsetjmp (context->jerr.setjmp_buffer, 1)) {
717                 retval = FALSE;
718         } else {
719                 jpeg_finish_decompress (&context->cinfo);
720                 retval = TRUE;
721         }
722
723         jpeg_destroy_decompress (&context->cinfo);
724
725         if (context->cinfo.src) {
726                 my_src_ptr src = (my_src_ptr) context->cinfo.src;
727                 
728                 g_free (src);
729         }
730
731         g_free (context);
732
733         return retval;
734 }
735
736
737 static gboolean
738 gdk_pixbuf__jpeg_image_load_lines (JpegProgContext  *context,
739                                    GError          **error)
740 {
741         struct jpeg_decompress_struct *cinfo = &context->cinfo;
742         guchar *lines[4];
743         guchar **lptr;
744         guchar *rowptr;
745         gint   nlines, i;
746
747         /* keep going until we've done all scanlines */
748         while (cinfo->output_scanline < cinfo->output_height) {
749                 lptr = lines;
750                 rowptr = context->dptr;
751                 for (i=0; i < cinfo->rec_outbuf_height; i++) {
752                         *lptr++ = rowptr;
753                         rowptr += context->pixbuf->rowstride;
754                 }
755
756                 nlines = jpeg_read_scanlines (cinfo, lines,
757                                               cinfo->rec_outbuf_height);
758                 if (nlines == 0)
759                         break;
760
761                 switch (cinfo->out_color_space) {
762                 case JCS_GRAYSCALE:
763                         explode_gray_into_buf (cinfo, lines);
764                         break;
765                 case JCS_RGB:
766                         /* do nothing */
767                         break;
768                 case JCS_CMYK:
769                         convert_cmyk_to_rgb (cinfo, lines);
770                         break;
771                 default:
772                         if (error && *error == NULL) {
773                                 g_set_error (error,
774                                              GDK_PIXBUF_ERROR,
775                                              GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
776                                              _("Unsupported JPEG color space (%s)"),
777                                              colorspace_name (cinfo->out_color_space));
778                         }
779
780                         return FALSE;
781                 }
782
783                 context->dptr += nlines * context->pixbuf->rowstride;
784
785                 /* send updated signal */
786                 if (context->updated_func)
787                         (* context->updated_func) (context->pixbuf,
788                                                    0,
789                                                    cinfo->output_scanline - 1,
790                                                    cinfo->image_width,
791                                                    nlines,
792                                                    context->user_data);
793         }
794
795         return TRUE;
796 }
797
798
799 /*
800  * context - from image_begin_load
801  * buf - new image data
802  * size - length of new image data
803  *
804  * append image data onto inrecrementally built output image
805  */
806 static gboolean
807 gdk_pixbuf__jpeg_image_load_increment (gpointer data,
808                                        const guchar *buf, guint size,
809                                        GError **error)
810 {
811         JpegProgContext *context = (JpegProgContext *)data;
812         struct           jpeg_decompress_struct *cinfo;
813         my_src_ptr       src;
814         guint            num_left, num_copy;
815         guint            last_num_left, last_bytes_left;
816         guint            spinguard;
817         gboolean         first;
818         const guchar    *bufhd;
819         gint             width, height;
820         int              is_otag;
821         char             otag_str[5];
822
823         g_return_val_if_fail (context != NULL, FALSE);
824         g_return_val_if_fail (buf != NULL, FALSE);
825
826         src = (my_src_ptr) context->cinfo.src;
827
828         cinfo = &context->cinfo;
829
830         context->jerr.error = error;
831         
832         /* check for fatal error */
833         if (sigsetjmp (context->jerr.setjmp_buffer, 1)) {
834                 return FALSE;
835         }
836
837         /* skip over data if requested, handle unsigned int sizes cleanly */
838         /* only can happen if we've already called jpeg_get_header once   */
839         if (context->src_initialized && src->skip_next) {
840                 if (src->skip_next > size) {
841                         src->skip_next -= size;
842                         return TRUE;
843                 } else {
844                         num_left = size - src->skip_next;
845                         bufhd = buf + src->skip_next;
846                         src->skip_next = 0;
847                 }
848         } else {
849                 num_left = size;
850                 bufhd = buf;
851         }
852
853         if (num_left == 0)
854                 return TRUE;
855
856         last_num_left = num_left;
857         last_bytes_left = 0;
858         spinguard = 0;
859         first = TRUE;
860         while (TRUE) {
861
862                 /* handle any data from caller we haven't processed yet */
863                 if (num_left > 0) {
864                         if(src->pub.bytes_in_buffer && 
865                            src->pub.next_input_byte != src->buffer)
866                                 memmove(src->buffer, src->pub.next_input_byte,
867                                         src->pub.bytes_in_buffer);
868
869
870                         num_copy = MIN (JPEG_PROG_BUF_SIZE - src->pub.bytes_in_buffer,
871                                         num_left);
872
873                         memcpy(src->buffer + src->pub.bytes_in_buffer, bufhd,num_copy);
874                         src->pub.next_input_byte = src->buffer;
875                         src->pub.bytes_in_buffer += num_copy;
876                         bufhd += num_copy;
877                         num_left -= num_copy;
878                 }
879
880                 /* did anything change from last pass, if not return */
881                 if (first) {
882                         last_bytes_left = src->pub.bytes_in_buffer;
883                         first = FALSE;
884                 } else if (src->pub.bytes_in_buffer == last_bytes_left
885                            && num_left == last_num_left) {
886                         spinguard++;
887                 } else {
888                         last_bytes_left = src->pub.bytes_in_buffer;
889                         last_num_left = num_left;
890                 }
891
892                 /* should not go through twice and not pull bytes out of buf */
893                 if (spinguard > 2)
894                         return TRUE;
895
896                 /* try to load jpeg header */
897                 if (!context->got_header) {
898                         int rc;
899                 
900                         jpeg_save_markers (cinfo, EXIF_JPEG_MARKER, 0xffff);
901                         rc = jpeg_read_header (cinfo, TRUE);
902                         context->src_initialized = TRUE;
903                         
904                         if (rc == JPEG_SUSPENDED)
905                                 continue;
906                         
907                         context->got_header = TRUE;
908
909                         /* check for orientation tag */
910                         is_otag = get_orientation (cinfo);
911                 
912                         width = cinfo->image_width;
913                         height = cinfo->image_height;
914                         if (context->size_func) {
915                                 (* context->size_func) (&width, &height, context->user_data);
916                                 if (width == 0 || height == 0) {
917                                         g_set_error_literal (error,
918                                                              GDK_PIXBUF_ERROR,
919                                                              GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
920                                                              _("Transformed JPEG has zero width or height."));
921                                         return FALSE;
922                                 }
923                         }
924                         
925                         for (cinfo->scale_denom = 2; cinfo->scale_denom <= 8; cinfo->scale_denom *= 2) {
926                                 jpeg_calc_output_dimensions (cinfo);
927                                 if (cinfo->output_width < width || cinfo->output_height < height) {
928                                         cinfo->scale_denom /= 2;
929                                         break;
930                                 }
931                         }
932                         jpeg_calc_output_dimensions (cinfo);
933                         
934                         context->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 
935                                                           cinfo->output_components == 4 ? TRUE : FALSE,
936                                                           8, 
937                                                           cinfo->output_width,
938                                                           cinfo->output_height);
939
940                         if (context->pixbuf == NULL) {
941                                 g_set_error_literal (error,
942                                                      GDK_PIXBUF_ERROR,
943                                                      GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
944                                                      _("Couldn't allocate memory for loading JPEG file"));
945                                 return FALSE;
946                         }
947                 
948                         /* if orientation tag was found set an option to remember its value */
949                         if (is_otag) {
950                                 g_snprintf (otag_str, sizeof (otag_str), "%d", is_otag);
951                                 gdk_pixbuf_set_option (context->pixbuf, "orientation", otag_str);
952                         }
953
954                         /* Use pixbuf buffer to store decompressed data */
955                         context->dptr = context->pixbuf->pixels;
956                         
957                         /* Notify the client that we are ready to go */
958                         if (context->prepared_func)
959                                 (* context->prepared_func) (context->pixbuf,
960                                                             NULL,
961                                                             context->user_data);
962                         
963                 } else if (!context->did_prescan) {
964                         int rc;                 
965                         
966                         /* start decompression */
967                         cinfo->buffered_image = cinfo->progressive_mode;
968                         rc = jpeg_start_decompress (cinfo);
969                         cinfo->do_fancy_upsampling = FALSE;
970                         cinfo->do_block_smoothing = FALSE;
971
972                         if (rc == JPEG_SUSPENDED)
973                                 continue;
974
975                         context->did_prescan = TRUE;
976                 } else if (!cinfo->buffered_image) {
977                         /* we're decompressing unbuffered so
978                          * simply get scanline by scanline from jpeg lib
979                          */
980                         if (! gdk_pixbuf__jpeg_image_load_lines (context,
981                                                                  error))
982                                 return FALSE;
983
984                         if (cinfo->output_scanline >= cinfo->output_height)
985                                 return TRUE;
986                 } else {
987                         /* we're decompressing buffered (progressive)
988                          * so feed jpeg lib scanlines
989                          */
990
991                         /* keep going until we've done all passes */
992                         while (!jpeg_input_complete (cinfo)) {
993                                 if (!context->in_output) {
994                                         if (jpeg_start_output (cinfo, cinfo->input_scan_number)) {
995                                                 context->in_output = TRUE;
996                                                 context->dptr = context->pixbuf->pixels;
997                                         }
998                                         else
999                                                 break;
1000                                 }
1001
1002                                 /* get scanlines from jpeg lib */
1003                                 if (! gdk_pixbuf__jpeg_image_load_lines (context,
1004                                                                          error))
1005                                         return FALSE;
1006
1007                                 if (cinfo->output_scanline >= cinfo->output_height &&
1008                                     jpeg_finish_output (cinfo))
1009                                         context->in_output = FALSE;
1010                                 else
1011                                         break;
1012                         }
1013                         if (jpeg_input_complete (cinfo))
1014                                 /* did entire image */
1015                                 return TRUE;
1016                         else
1017                                 continue;
1018                 }
1019         }
1020 }
1021
1022 /* Save */
1023
1024 #define TO_FUNCTION_BUF_SIZE 4096
1025
1026 typedef struct {
1027         struct jpeg_destination_mgr pub;
1028         JOCTET             *buffer;
1029         GdkPixbufSaveFunc   save_func;
1030         gpointer            user_data;
1031         GError            **error;
1032 } ToFunctionDestinationManager;
1033
1034 void
1035 to_callback_init (j_compress_ptr cinfo)
1036 {
1037         ToFunctionDestinationManager *destmgr;
1038
1039         destmgr = (ToFunctionDestinationManager*) cinfo->dest;
1040         destmgr->pub.next_output_byte = destmgr->buffer;
1041         destmgr->pub.free_in_buffer = TO_FUNCTION_BUF_SIZE;
1042 }
1043
1044 static void
1045 to_callback_do_write (j_compress_ptr cinfo, gsize length)
1046 {
1047         ToFunctionDestinationManager *destmgr;
1048
1049         destmgr = (ToFunctionDestinationManager*) cinfo->dest;
1050         if (!destmgr->save_func (destmgr->buffer,
1051                                  length,
1052                                  destmgr->error,
1053                                  destmgr->user_data)) {
1054                 struct error_handler_data *errmgr;
1055         
1056                 errmgr = (struct error_handler_data *) cinfo->err;
1057                 /* Use a default error message if the callback didn't set one,
1058                  * which it should have.
1059                  */
1060                 if (errmgr->error && *errmgr->error == NULL) {
1061                         g_set_error_literal (errmgr->error,
1062                                              GDK_PIXBUF_ERROR,
1063                                              GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
1064                                              "write function failed");
1065                 }
1066                 siglongjmp (errmgr->setjmp_buffer, 1);
1067                 g_assert_not_reached ();
1068         }
1069 }
1070
1071 static boolean
1072 to_callback_empty_output_buffer (j_compress_ptr cinfo)
1073 {
1074         ToFunctionDestinationManager *destmgr;
1075
1076         destmgr = (ToFunctionDestinationManager*) cinfo->dest;
1077         to_callback_do_write (cinfo, TO_FUNCTION_BUF_SIZE);
1078         destmgr->pub.next_output_byte = destmgr->buffer;
1079         destmgr->pub.free_in_buffer = TO_FUNCTION_BUF_SIZE;
1080         return TRUE;
1081 }
1082
1083 void
1084 to_callback_terminate (j_compress_ptr cinfo)
1085 {
1086         ToFunctionDestinationManager *destmgr;
1087
1088         destmgr = (ToFunctionDestinationManager*) cinfo->dest;
1089         to_callback_do_write (cinfo, TO_FUNCTION_BUF_SIZE - destmgr->pub.free_in_buffer);
1090 }
1091
1092 static gboolean
1093 real_save_jpeg (GdkPixbuf          *pixbuf,
1094                 gchar             **keys,
1095                 gchar             **values,
1096                 GError            **error,
1097                 gboolean            to_callback,
1098                 FILE               *f,
1099                 GdkPixbufSaveFunc   save_func,
1100                 gpointer            user_data)
1101 {
1102         /* FIXME error handling is broken */
1103         
1104        struct jpeg_compress_struct cinfo;
1105        guchar *buf = NULL;
1106        guchar *ptr;
1107        guchar *pixels = NULL;
1108        JSAMPROW *jbuf;
1109        int y = 0;
1110        volatile int quality = 75; /* default; must be between 0 and 100 */
1111        int i, j;
1112        int w, h = 0;
1113        int rowstride = 0;
1114        int n_channels;
1115        struct error_handler_data jerr;
1116        ToFunctionDestinationManager to_callback_destmgr;
1117
1118        to_callback_destmgr.buffer = NULL;
1119
1120        if (keys && *keys) {
1121                gchar **kiter = keys;
1122                gchar **viter = values;
1123
1124                while (*kiter) {
1125                        if (strcmp (*kiter, "quality") == 0) {
1126                                char *endptr = NULL;
1127                                quality = strtol (*viter, &endptr, 10);
1128
1129                                if (endptr == *viter) {
1130                                        g_set_error (error,
1131                                                     GDK_PIXBUF_ERROR,
1132                                                     GDK_PIXBUF_ERROR_BAD_OPTION,
1133                                                     _("JPEG quality must be a value between 0 and 100; value '%s' could not be parsed."),
1134                                                     *viter);
1135
1136                                        return FALSE;
1137                                }
1138                                
1139                                if (quality < 0 ||
1140                                    quality > 100) {
1141                                        /* This is a user-visible error;
1142                                         * lets people skip the range-checking
1143                                         * in their app.
1144                                         */
1145                                        g_set_error (error,
1146                                                     GDK_PIXBUF_ERROR,
1147                                                     GDK_PIXBUF_ERROR_BAD_OPTION,
1148                                                     _("JPEG quality must be a value between 0 and 100; value '%d' is not allowed."),
1149                                                     quality);
1150
1151                                        return FALSE;
1152                                }
1153                        } else {
1154                                g_warning ("Unrecognized parameter (%s) passed to JPEG saver.", *kiter);
1155                        }
1156                
1157                        ++kiter;
1158                        ++viter;
1159                }
1160        }
1161        
1162        rowstride = gdk_pixbuf_get_rowstride (pixbuf);
1163        n_channels = gdk_pixbuf_get_n_channels (pixbuf);
1164
1165        w = gdk_pixbuf_get_width (pixbuf);
1166        h = gdk_pixbuf_get_height (pixbuf);
1167        pixels = gdk_pixbuf_get_pixels (pixbuf);
1168
1169        /* Allocate a small buffer to convert image data,
1170         * and a larger buffer if doing to_callback save.
1171         */
1172        buf = g_try_malloc (w * 3 * sizeof (guchar));
1173        if (!buf) {
1174                g_set_error_literal (error,
1175                                     GDK_PIXBUF_ERROR,
1176                                     GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
1177                                     _("Couldn't allocate memory for loading JPEG file"));
1178                return FALSE;
1179        }
1180        if (to_callback) {
1181                to_callback_destmgr.buffer = g_try_malloc (TO_FUNCTION_BUF_SIZE);
1182                if (!to_callback_destmgr.buffer) {
1183                        g_set_error_literal (error,
1184                                             GDK_PIXBUF_ERROR,
1185                                             GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
1186                                             _("Couldn't allocate memory for loading JPEG file"));
1187                        return FALSE;
1188                }
1189        }
1190
1191        /* set up error handling */
1192        jerr.pub.error_exit = fatal_error_handler;
1193        jerr.pub.output_message = output_message_handler;
1194        jerr.error = error;
1195        
1196        cinfo.err = jpeg_std_error (&(jerr.pub));
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 }