1 /* -*- mode: C; c-file-style: "linux" -*- */
2 /* GdkPixbuf library - JPEG image loader
4 * Copyright (C) 1999 Michael Zucchi
5 * Copyright (C) 1999 The Free Software Foundation
7 * Progressive loading code Copyright (C) 1999 Red Hat, Inc.
9 * Authors: Michael Zucchi <zucchi@zedzone.mmc.com.au>
10 * Federico Mena-Quintero <federico@gimp.org>
11 * Michael Fulbright <drmike@redhat.com>
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.
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.
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.
37 #include "gdk-pixbuf-private.h"
38 #include "gdk-pixbuf-io.h"
40 #ifndef HAVE_SIGSETJMP
41 #define sigjmp_buf jmp_buf
42 #define sigsetjmp(jb, x) setjmp(jb)
43 #define siglongjmp longjmp
47 /* we are a "source manager" as far as libjpeg is concerned */
48 #define JPEG_PROG_BUF_SIZE 65536
51 struct jpeg_source_mgr pub; /* public fields */
53 JOCTET buffer[JPEG_PROG_BUF_SIZE]; /* start of buffer */
54 long skip_next; /* number of bytes to skip next read */
58 typedef my_source_mgr * my_src_ptr;
60 /* error handler data */
61 struct error_handler_data {
62 struct jpeg_error_mgr pub;
63 sigjmp_buf setjmp_buffer;
67 /* progressive loader context */
69 GdkPixbufModuleSizeFunc size_func;
70 GdkPixbufModuleUpdatedFunc updated_func;
71 GdkPixbufModulePreparedFunc prepared_func;
75 guchar *dptr; /* current position in pixbuf */
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;
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,
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,
98 fatal_error_handler (j_common_ptr cinfo)
100 struct error_handler_data *errmgr;
101 char buffer[JMSG_LENGTH_MAX];
103 errmgr = (struct error_handler_data *) cinfo->err;
105 /* Create the message */
106 (* cinfo->err->format_message) (cinfo, buffer);
108 /* broken check for *error == NULL for robustness against
109 * crappy JPEG library
111 if (errmgr->error && *errmgr->error == NULL) {
112 g_set_error (errmgr->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)"),
121 siglongjmp (errmgr->setjmp_buffer, 1);
123 g_assert_not_reached ();
127 output_message_handler (j_common_ptr cinfo)
129 /* This method keeps libjpeg from dumping crap to stderr */
134 /* explode gray image data from jpeg library into rgb components in pixbuf */
136 explode_gray_into_buf (struct jpeg_decompress_struct *cinfo,
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);
146 /* Expand grey->colour. Expand from the end of the
147 * memory down, so we can use the same buffer.
149 w = cinfo->output_width;
150 for (i = cinfo->rec_outbuf_height - 1; i >= 0; i--) {
153 from = lines[i] + w - 1;
154 to = lines[i] + (w - 1) * 3;
155 for (j = w - 1; j >= 0; j--) {
167 convert_cmyk_to_rgb (struct jpeg_decompress_struct *cinfo,
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);
176 for (i = cinfo->rec_outbuf_height - 1; i >= 0; i--) {
180 for (j = 0; j < cinfo->output_width; j++) {
186 if (cinfo->saw_Adobe_marker) {
192 p[0] = (255 - k)*(255 - c) / 255;
193 p[1] = (255 - k)*(255 - m) / 255;
194 p[2] = (255 - k)*(255 - y) / 255;
203 struct jpeg_source_mgr pub; /* public fields */
205 FILE * infile; /* source stream */
206 JOCTET * buffer; /* start of buffer */
207 boolean start_of_file; /* have we gotten any data yet? */
210 typedef stdio_source_mgr * stdio_src_ptr;
213 stdio_init_source (j_decompress_ptr cinfo)
215 stdio_src_ptr src = (stdio_src_ptr)cinfo->src;
216 src->start_of_file = FALSE;
220 stdio_fill_input_buffer (j_decompress_ptr cinfo)
222 stdio_src_ptr src = (stdio_src_ptr) cinfo->src;
225 nbytes = fread (src->buffer, 1, JPEG_PROG_BUF_SIZE, src->infile);
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);
233 /* Insert a fake EOI marker */
234 src->buffer[0] = (JOCTET) 0xFF;
235 src->buffer[1] = (JOCTET) JPEG_EOI;
239 src->pub.next_input_byte = src->buffer;
240 src->pub.bytes_in_buffer = nbytes;
241 src->start_of_file = FALSE;
247 stdio_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
249 stdio_src_ptr src = (stdio_src_ptr) cinfo->src;
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);
256 src->pub.next_input_byte += (size_t) num_bytes;
257 src->pub.bytes_in_buffer -= (size_t) num_bytes;
262 stdio_term_source (j_decompress_ptr cinfo)
267 colorspace_name (const J_COLOR_SPACE jpeg_color_space)
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";
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
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)
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)
292 #define EXIF_JPEG_MARKER JPEG_APP0+1
293 #define EXIF_IDENT_STRING "Exif\000\000"
295 static unsigned short de_get16(void *ptr, guint endian)
299 memcpy(&val, ptr, sizeof(val));
300 val = DE_ENDIAN16(val);
305 static unsigned int de_get32(void *ptr, guint endian)
309 memcpy(&val, ptr, sizeof(val));
310 val = DE_ENDIAN32(val);
316 get_orientation (j_decompress_ptr cinfo)
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. */
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 */
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 */
335 /* check for Exif marker (also called the APP1 marker) */
337 cmarker = cinfo->marker_list;
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;
346 cmarker = cmarker->next;
349 /* Did we find the Exif APP1 marker? */
350 if (exif_marker == NULL)
353 /* Do we have enough data? */
354 if (exif_marker->data_length < 32)
357 /* Check for TIFF header and catch endianess */
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
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.
377 /* Little endian TIFF header */
378 if (memcmp (&exif_marker->data[i], leth, 4) == 0){
379 endian = G_LITTLE_ENDIAN;
382 /* Big endian TIFF header */
383 else if (memcmp (&exif_marker->data[i], beth, 4) == 0){
384 endian = G_BIG_ENDIAN;
387 /* Keep looking through buffer */
392 /* We have found either big or little endian TIFF header */
397 /* So did we find a TIFF header or did we just hit end of buffer? */
401 /* Endian the orientation tag ID, to locate it more easily */
402 orient_tag_id = ENDIAN16_IT(0x112);
404 /* Read out the offset pointer to IFD0 */
405 offset = de_get32(&exif_marker->data[i] + 4, endian);
408 /* Check that we still are within the buffer and can read the tag count */
409 if ((i + 2) > exif_marker->data_length)
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);
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)
423 /* Check through IFD0 for tags of interest */
425 type = de_get16(&exif_marker->data[i + 2], endian);
426 count = de_get32(&exif_marker->data[i + 4], endian);
428 /* Is this the orientation tag? */
429 if (memcmp (&exif_marker->data[i], (char *) &orient_tag_id, 2) == 0){
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;
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;
440 /* move the pointer to the next 12-byte tag field. */
444 return 0; /* No EXIF Orientation tag found */
448 /* Shared library entry point */
450 gdk_pixbuf__jpeg_image_load (FILE *f, GError **error)
455 GdkPixbuf * volatile pixbuf = NULL;
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,
463 struct jpeg_decompress_struct cinfo;
464 struct error_handler_data jerr;
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;
473 if (sigsetjmp (jerr.setjmp_buffer, 1)) {
474 /* Whoops there was a jpeg error */
476 g_object_unref (pixbuf);
478 jpeg_destroy_decompress (&cinfo);
480 /* error should have been set by fatal_error_handler () */
484 /* load header, setup */
485 jpeg_create_decompress (&cinfo);
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));
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;
501 src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
502 src->pub.next_input_byte = NULL; /* until buffer loaded */
504 jpeg_save_markers (&cinfo, EXIF_JPEG_MARKER, 0xffff);
505 jpeg_read_header (&cinfo, TRUE);
507 /* check for orientation tag */
508 is_otag = get_orientation (&cinfo);
510 jpeg_start_decompress (&cinfo);
511 cinfo.do_fancy_upsampling = FALSE;
512 cinfo.do_block_smoothing = FALSE;
514 pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
515 cinfo.out_color_components == 4 ? TRUE : FALSE,
516 8, cinfo.output_width, cinfo.output_height);
519 jpeg_destroy_decompress (&cinfo);
521 /* broken check for *error == NULL for robustness against
522 * crappy JPEG library
524 if (error && *error == NULL) {
525 g_set_error_literal (error,
527 GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
528 _("Insufficient memory to load image, try exiting some applications to free memory"));
534 /* if orientation tag was found set an option to remember its value */
536 g_snprintf (otag_str, sizeof (otag_str), "%d", is_otag);
537 gdk_pixbuf_set_option (pixbuf, "orientation", otag_str);
541 dptr = pixbuf->pixels;
543 /* decompress all the lines, a few at a time */
544 while (cinfo.output_scanline < cinfo.output_height) {
546 for (i = 0; i < cinfo.rec_outbuf_height; i++) {
548 dptr += pixbuf->rowstride;
551 jpeg_read_scanlines (&cinfo, lines, cinfo.rec_outbuf_height);
553 switch (cinfo.out_color_space) {
555 explode_gray_into_buf (&cinfo, lines);
561 convert_cmyk_to_rgb (&cinfo, lines);
564 g_object_unref (pixbuf);
565 if (error && *error == NULL) {
568 GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
569 _("Unsupported JPEG color space (%s)"),
570 colorspace_name (cinfo.out_color_space));
573 jpeg_destroy_decompress (&cinfo);
578 jpeg_finish_decompress (&cinfo);
579 jpeg_destroy_decompress (&cinfo);
585 /**** Progressive image loading handling *****/
587 /* these routines required because we are acting as a source manager for */
590 init_source (j_decompress_ptr cinfo)
592 my_src_ptr src = (my_src_ptr) cinfo->src;
599 term_source (j_decompress_ptr cinfo)
601 /* XXXX - probably should scream something has happened */
605 /* for progressive loading (called "I/O Suspension" by libjpeg docs) */
606 /* we do nothing except return "FALSE" */
608 fill_input_buffer (j_decompress_ptr cinfo)
615 skip_input_data (j_decompress_ptr cinfo, long num_bytes)
617 my_src_ptr src = (my_src_ptr) cinfo->src;
620 /* move as far as we can into current buffer */
621 /* then set skip_next to catch the rest */
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;
627 src->skip_next = num_bytes - num_can_do;
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)
639 gdk_pixbuf__jpeg_image_begin_load (GdkPixbufModuleSizeFunc size_func,
640 GdkPixbufModulePreparedFunc prepared_func,
641 GdkPixbufModuleUpdatedFunc updated_func,
645 JpegProgContext *context;
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;
659 /* create libjpeg structures */
660 jpeg_create_decompress (&context->cinfo);
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,
666 GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
667 _("Couldn't allocate memory for loading JPEG file"));
670 memset (context->cinfo.src, 0, sizeof (my_source_mgr));
672 src = (my_src_ptr) context->cinfo.src;
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;
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;
688 context->jerr.error = NULL;
690 return (gpointer) context;
694 * context - returned from image_begin_load
696 * free context, unref gdk_pixbuf
699 gdk_pixbuf__jpeg_image_stop_load (gpointer data, GError **error)
701 JpegProgContext *context = (JpegProgContext *) data;
704 g_return_val_if_fail (context != NULL, TRUE);
706 /* FIXME this thing needs to report errors if
707 * we have unused image data
711 g_object_unref (context->pixbuf);
713 /* if we have an error? */
714 context->jerr.error = error;
715 if (sigsetjmp (context->jerr.setjmp_buffer, 1)) {
718 jpeg_finish_decompress (&context->cinfo);
722 jpeg_destroy_decompress (&context->cinfo);
724 if (context->cinfo.src) {
725 my_src_ptr src = (my_src_ptr) context->cinfo.src;
737 gdk_pixbuf__jpeg_image_load_lines (JpegProgContext *context,
740 struct jpeg_decompress_struct *cinfo = &context->cinfo;
746 /* keep going until we've done all scanlines */
747 while (cinfo->output_scanline < cinfo->output_height) {
749 rowptr = context->dptr;
750 for (i=0; i < cinfo->rec_outbuf_height; i++) {
752 rowptr += context->pixbuf->rowstride;
755 nlines = jpeg_read_scanlines (cinfo, lines,
756 cinfo->rec_outbuf_height);
760 switch (cinfo->out_color_space) {
762 explode_gray_into_buf (cinfo, lines);
768 convert_cmyk_to_rgb (cinfo, lines);
771 if (error && *error == NULL) {
774 GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
775 _("Unsupported JPEG color space (%s)"),
776 colorspace_name (cinfo->out_color_space));
782 context->dptr += nlines * context->pixbuf->rowstride;
784 /* send updated signal */
785 if (context->updated_func)
786 (* context->updated_func) (context->pixbuf,
788 cinfo->output_scanline - 1,
799 * context - from image_begin_load
800 * buf - new image data
801 * size - length of new image data
803 * append image data onto inrecrementally built output image
806 gdk_pixbuf__jpeg_image_load_increment (gpointer data,
807 const guchar *buf, guint size,
810 JpegProgContext *context = (JpegProgContext *)data;
811 struct jpeg_decompress_struct *cinfo;
813 guint num_left, num_copy;
814 guint last_num_left, last_bytes_left;
822 g_return_val_if_fail (context != NULL, FALSE);
823 g_return_val_if_fail (buf != NULL, FALSE);
825 src = (my_src_ptr) context->cinfo.src;
827 cinfo = &context->cinfo;
829 context->jerr.error = error;
831 /* check for fatal error */
832 if (sigsetjmp (context->jerr.setjmp_buffer, 1)) {
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;
843 num_left = size - src->skip_next;
844 bufhd = buf + src->skip_next;
855 last_num_left = num_left;
861 /* handle any data from caller we haven't processed yet */
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);
869 num_copy = MIN (JPEG_PROG_BUF_SIZE - src->pub.bytes_in_buffer,
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;
876 num_left -= num_copy;
879 /* did anything change from last pass, if not return */
881 last_bytes_left = src->pub.bytes_in_buffer;
883 } else if (src->pub.bytes_in_buffer == last_bytes_left
884 && num_left == last_num_left) {
887 last_bytes_left = src->pub.bytes_in_buffer;
888 last_num_left = num_left;
891 /* should not go through twice and not pull bytes out of buf */
895 /* try to load jpeg header */
896 if (!context->got_header) {
899 jpeg_save_markers (cinfo, EXIF_JPEG_MARKER, 0xffff);
900 rc = jpeg_read_header (cinfo, TRUE);
901 context->src_initialized = TRUE;
903 if (rc == JPEG_SUSPENDED)
906 context->got_header = TRUE;
908 /* check for orientation tag */
909 is_otag = get_orientation (cinfo);
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,
918 GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
919 _("Transformed JPEG has zero width or height."));
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;
931 jpeg_calc_output_dimensions (cinfo);
933 context->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
934 cinfo->output_components == 4 ? TRUE : FALSE,
937 cinfo->output_height);
939 if (context->pixbuf == NULL) {
940 g_set_error_literal (error,
942 GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
943 _("Couldn't allocate memory for loading JPEG file"));
947 /* if orientation tag was found set an option to remember its value */
949 g_snprintf (otag_str, sizeof (otag_str), "%d", is_otag);
950 gdk_pixbuf_set_option (context->pixbuf, "orientation", otag_str);
953 /* Use pixbuf buffer to store decompressed data */
954 context->dptr = context->pixbuf->pixels;
956 /* Notify the client that we are ready to go */
957 if (context->prepared_func)
958 (* context->prepared_func) (context->pixbuf,
962 } else if (!context->did_prescan) {
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;
971 if (rc == JPEG_SUSPENDED)
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
979 if (! gdk_pixbuf__jpeg_image_load_lines (context,
983 if (cinfo->output_scanline >= cinfo->output_height)
986 /* we're decompressing buffered (progressive)
987 * so feed jpeg lib scanlines
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;
1001 /* get scanlines from jpeg lib */
1002 if (! gdk_pixbuf__jpeg_image_load_lines (context,
1006 if (cinfo->output_scanline >= cinfo->output_height &&
1007 jpeg_finish_output (cinfo))
1008 context->in_output = FALSE;
1012 if (jpeg_input_complete (cinfo))
1013 /* did entire image */
1023 #define TO_FUNCTION_BUF_SIZE 4096
1026 struct jpeg_destination_mgr pub;
1028 GdkPixbufSaveFunc save_func;
1031 } ToFunctionDestinationManager;
1034 to_callback_init (j_compress_ptr cinfo)
1036 ToFunctionDestinationManager *destmgr;
1038 destmgr = (ToFunctionDestinationManager*) cinfo->dest;
1039 destmgr->pub.next_output_byte = destmgr->buffer;
1040 destmgr->pub.free_in_buffer = TO_FUNCTION_BUF_SIZE;
1044 to_callback_do_write (j_compress_ptr cinfo, gsize length)
1046 ToFunctionDestinationManager *destmgr;
1048 destmgr = (ToFunctionDestinationManager*) cinfo->dest;
1049 if (!destmgr->save_func ((gchar *)destmgr->buffer,
1052 destmgr->user_data)) {
1053 struct error_handler_data *errmgr;
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.
1059 if (errmgr->error && *errmgr->error == NULL) {
1060 g_set_error_literal (errmgr->error,
1062 GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
1063 "write function failed");
1065 siglongjmp (errmgr->setjmp_buffer, 1);
1066 g_assert_not_reached ();
1071 to_callback_empty_output_buffer (j_compress_ptr cinfo)
1073 ToFunctionDestinationManager *destmgr;
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;
1083 to_callback_terminate (j_compress_ptr cinfo)
1085 ToFunctionDestinationManager *destmgr;
1087 destmgr = (ToFunctionDestinationManager*) cinfo->dest;
1088 to_callback_do_write (cinfo, TO_FUNCTION_BUF_SIZE - destmgr->pub.free_in_buffer);
1092 real_save_jpeg (GdkPixbuf *pixbuf,
1096 gboolean to_callback,
1098 GdkPixbufSaveFunc save_func,
1101 /* FIXME error handling is broken */
1103 struct jpeg_compress_struct cinfo;
1106 guchar *pixels = NULL;
1109 volatile int quality = 75; /* default; must be between 0 and 100 */
1114 struct error_handler_data jerr;
1115 ToFunctionDestinationManager to_callback_destmgr;
1117 to_callback_destmgr.buffer = NULL;
1119 if (keys && *keys) {
1120 gchar **kiter = keys;
1121 gchar **viter = values;
1124 if (strcmp (*kiter, "quality") == 0) {
1125 char *endptr = NULL;
1126 quality = strtol (*viter, &endptr, 10);
1128 if (endptr == *viter) {
1131 GDK_PIXBUF_ERROR_BAD_OPTION,
1132 _("JPEG quality must be a value between 0 and 100; value '%s' could not be parsed."),
1140 /* This is a user-visible error;
1141 * lets people skip the range-checking
1146 GDK_PIXBUF_ERROR_BAD_OPTION,
1147 _("JPEG quality must be a value between 0 and 100; value '%d' is not allowed."),
1153 g_warning ("Unrecognized parameter (%s) passed to JPEG saver.", *kiter);
1161 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
1162 n_channels = gdk_pixbuf_get_n_channels (pixbuf);
1164 w = gdk_pixbuf_get_width (pixbuf);
1165 h = gdk_pixbuf_get_height (pixbuf);
1166 pixels = gdk_pixbuf_get_pixels (pixbuf);
1168 /* Allocate a small buffer to convert image data,
1169 * and a larger buffer if doing to_callback save.
1171 buf = g_try_malloc (w * 3 * sizeof (guchar));
1173 g_set_error_literal (error,
1175 GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
1176 _("Couldn't allocate memory for loading JPEG file"));
1180 to_callback_destmgr.buffer = g_try_malloc (TO_FUNCTION_BUF_SIZE);
1181 if (!to_callback_destmgr.buffer) {
1182 g_set_error_literal (error,
1184 GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
1185 _("Couldn't allocate memory for loading JPEG file"));
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;
1197 if (sigsetjmp (jerr.setjmp_buffer, 1)) {
1198 jpeg_destroy_compress (&cinfo);
1200 g_free (to_callback_destmgr.buffer);
1204 /* setup compress params */
1205 jpeg_create_compress (&cinfo);
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;
1215 jpeg_stdio_dest (&cinfo, f);
1217 cinfo.image_width = w;
1218 cinfo.image_height = h;
1219 cinfo.input_components = 3;
1220 cinfo.in_color_space = JCS_RGB;
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 */
1228 /* go one scanline at a time... and save */
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);
1235 /* write scanline */
1236 jbuf = (JSAMPROW *)(&buf);
1237 jpeg_write_scanlines (&cinfo, jbuf, 1);
1244 jpeg_finish_compress (&cinfo);
1245 jpeg_destroy_compress(&cinfo);
1247 g_free (to_callback_destmgr.buffer);
1252 gdk_pixbuf__jpeg_image_save (FILE *f,
1258 return real_save_jpeg (pixbuf, keys, values, error,
1259 FALSE, f, NULL, NULL);
1263 gdk_pixbuf__jpeg_image_save_to_callback (GdkPixbufSaveFunc save_func,
1270 return real_save_jpeg (pixbuf, keys, values, error,
1271 TRUE, NULL, save_func, user_data);
1274 #ifndef INCLUDE_jpeg
1275 #define MODULE_ENTRY(function) G_MODULE_EXPORT void function
1277 #define MODULE_ENTRY(function) void _gdk_pixbuf__jpeg_ ## function
1280 MODULE_ENTRY (fill_vtable) (GdkPixbufModule *module)
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;
1290 MODULE_ENTRY (fill_info) (GdkPixbufFormat *info)
1292 static GdkPixbufModulePattern signature[] = {
1293 { "\xff\xd8", NULL, 100 },
1296 static gchar * mime_types[] = {
1300 static gchar * extensions[] = {
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";