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, see <http://www.gnu.org/licenses/>.
25  */
26 
27 
28 #include "config.h"
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <setjmp.h>
33 #include <jpeglib.h>
34 #include <jerror.h>
35 #include <math.h>
36 #include <glib/gi18n-lib.h>
37 #include "gdk-pixbuf-io.h"
38 #include "fallback-c89.c"
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 
46 
47 /* Helper macros to convert between density units */
48 #define DPCM_TO_DPI(value) ((int) round ((value) * 2.54))
49 
50 /* we are a "source manager" as far as libjpeg is concerned */
51 #define JPEG_PROG_BUF_SIZE 65536
52 
53 typedef struct {
54 	struct jpeg_source_mgr pub;   /* public fields */
55 
56 	JOCTET buffer[JPEG_PROG_BUF_SIZE];              /* start of buffer */
57 	long  skip_next;              /* number of bytes to skip next read */
58 
59 } my_source_mgr;
60 
61 typedef my_source_mgr * my_src_ptr;
62 
63 /* error handler data */
64 struct error_handler_data {
65 	struct jpeg_error_mgr pub;
66 	sigjmp_buf setjmp_buffer;
67         GError **error;
68 };
69 
70 /* progressive loader context */
71 typedef struct {
72         GdkPixbufModuleSizeFunc     size_func;
73 	GdkPixbufModuleUpdatedFunc  updated_func;
74 	GdkPixbufModulePreparedFunc prepared_func;
75 	gpointer                    user_data;
76 
77 	GdkPixbuf                *pixbuf;
78 	guchar                   *dptr;   /* current position in pixbuf */
79 
80 	gboolean                 did_prescan;  /* are we in image data yet? */
81 	gboolean                 got_header;  /* have we loaded jpeg header? */
82 	gboolean                 src_initialized;/* TRUE when jpeg lib initialized */
83 	gboolean                 in_output;   /* did we get suspended in an output pass? */
84 	struct jpeg_decompress_struct cinfo;
85 	struct error_handler_data     jerr;
86 } JpegProgContext;
87 
88 /* EXIF context */
89 typedef struct {
90 	gint			 orientation;
91 	gchar			*icc_profile;
92 	gsize			 icc_profile_size;
93 	gsize			 icc_profile_size_allocated;
94 } JpegExifContext;
95 
96 static GdkPixbuf *gdk_pixbuf__jpeg_image_load (FILE *f, GError **error);
97 static gpointer gdk_pixbuf__jpeg_image_begin_load (GdkPixbufModuleSizeFunc           func0,
98                                                    GdkPixbufModulePreparedFunc func1,
99                                                    GdkPixbufModuleUpdatedFunc func2,
100                                                    gpointer user_data,
101                                                    GError **error);
102 static gboolean gdk_pixbuf__jpeg_image_stop_load (gpointer context, GError **error);
103 static gboolean gdk_pixbuf__jpeg_image_load_increment(gpointer context,
104                                                       const guchar *buf, guint size,
105                                                       GError **error);
106 static gboolean gdk_pixbuf__jpeg_image_load_lines (JpegProgContext  *context,
107                                                    GError          **error);
108 
109 static void
fatal_error_handler(j_common_ptr cinfo)110 fatal_error_handler (j_common_ptr cinfo)
111 {
112 	struct error_handler_data *errmgr;
113         char buffer[JMSG_LENGTH_MAX];
114 
115 	errmgr = (struct error_handler_data *) cinfo->err;
116 
117         /* Create the message */
118         (* cinfo->err->format_message) (cinfo, buffer);
119 
120         /* broken check for *error == NULL for robustness against
121          * crappy JPEG library
122          */
123         if (errmgr->error && *errmgr->error == NULL) {
124                 g_set_error (errmgr->error,
125                              GDK_PIXBUF_ERROR,
126                              cinfo->err->msg_code == JERR_OUT_OF_MEMORY
127 			     ? GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY
128 			     : GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
129                              _("Error interpreting JPEG image file (%s)"),
130                              buffer);
131         }
132 
133 	siglongjmp (errmgr->setjmp_buffer, 1);
134 
135         g_assert_not_reached ();
136 }
137 
138 static void
output_message_handler(j_common_ptr cinfo)139 output_message_handler (j_common_ptr cinfo)
140 {
141   /* This method keeps libjpeg from dumping crap to stderr */
142 
143   /* do nothing */
144 }
145 
146 /* explode gray image data from jpeg library into rgb components in pixbuf */
147 static void
explode_gray_into_buf(struct jpeg_decompress_struct * cinfo,guchar ** lines)148 explode_gray_into_buf (struct jpeg_decompress_struct *cinfo,
149 		       guchar **lines)
150 {
151 	gint i, j;
152 	guint w;
153 
154 	g_return_if_fail (cinfo != NULL);
155 	g_return_if_fail (cinfo->output_components == 1);
156 	g_return_if_fail (cinfo->out_color_space == JCS_GRAYSCALE);
157 
158 	/* Expand grey->colour.  Expand from the end of the
159 	 * memory down, so we can use the same buffer.
160 	 */
161 	w = cinfo->output_width;
162 	for (i = cinfo->rec_outbuf_height - 1; i >= 0; i--) {
163 		guchar *from, *to;
164 
165 		from = lines[i] + w - 1;
166 		to = lines[i] + (w - 1) * 3;
167 		for (j = w - 1; j >= 0; j--) {
168 			to[0] = from[0];
169 			to[1] = from[0];
170 			to[2] = from[0];
171 			to -= 3;
172 			from--;
173 		}
174 	}
175 }
176 
177 
178 static void
convert_cmyk_to_rgb(struct jpeg_decompress_struct * cinfo,guchar ** lines)179 convert_cmyk_to_rgb (struct jpeg_decompress_struct *cinfo,
180 		     guchar **lines)
181 {
182 	gint i, j;
183 
184 	g_return_if_fail (cinfo != NULL);
185 	g_return_if_fail (cinfo->output_components == 4);
186 	g_return_if_fail (cinfo->out_color_space == JCS_CMYK);
187 
188 	for (i = cinfo->rec_outbuf_height - 1; i >= 0; i--) {
189 		guchar *p;
190 
191 		p = lines[i];
192 		for (j = 0; j < cinfo->output_width; j++) {
193 			int c, m, y, k;
194 			c = p[0];
195 			m = p[1];
196 			y = p[2];
197 			k = p[3];
198 
199 			/* We now assume that all CMYK JPEG files
200 			 * use inverted CMYK, as Photoshop does
201 			 * See https://bugzilla.gnome.org/show_bug.cgi?id=618096 */
202 			p[0] = k*c / 255;
203 			p[1] = k*m / 255;
204 			p[2] = k*y / 255;
205 			p[3] = 255;
206 			p += 4;
207 		}
208 	}
209 }
210 
211 typedef struct {
212   struct jpeg_source_mgr pub;	/* public fields */
213 
214   FILE * infile;		/* source stream */
215   JOCTET * buffer;		/* start of buffer */
216   boolean start_of_file;	/* have we gotten any data yet? */
217 } stdio_source_mgr;
218 
219 typedef stdio_source_mgr * stdio_src_ptr;
220 
221 static void
stdio_init_source(j_decompress_ptr cinfo)222 stdio_init_source (j_decompress_ptr cinfo)
223 {
224   stdio_src_ptr src = (stdio_src_ptr)cinfo->src;
225   src->start_of_file = FALSE;
226 }
227 
228 static boolean
stdio_fill_input_buffer(j_decompress_ptr cinfo)229 stdio_fill_input_buffer (j_decompress_ptr cinfo)
230 {
231   stdio_src_ptr src = (stdio_src_ptr) cinfo->src;
232   size_t nbytes;
233 
234   nbytes = fread (src->buffer, 1, JPEG_PROG_BUF_SIZE, src->infile);
235 
236   if (nbytes <= 0) {
237 #if 0
238     if (src->start_of_file)	/* Treat empty input file as fatal error */
239       ERREXIT(cinfo, JERR_INPUT_EMPTY);
240     WARNMS(cinfo, JWRN_JPEG_EOF);
241 #endif
242     /* Insert a fake EOI marker */
243     src->buffer[0] = (JOCTET) 0xFF;
244     src->buffer[1] = (JOCTET) JPEG_EOI;
245     nbytes = 2;
246   }
247 
248   src->pub.next_input_byte = src->buffer;
249   src->pub.bytes_in_buffer = nbytes;
250   src->start_of_file = FALSE;
251 
252   return TRUE;
253 }
254 
255 static void
stdio_skip_input_data(j_decompress_ptr cinfo,long num_bytes)256 stdio_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
257 {
258   stdio_src_ptr src = (stdio_src_ptr) cinfo->src;
259 
260   if (num_bytes > 0) {
261     while (num_bytes > (long) src->pub.bytes_in_buffer) {
262       num_bytes -= (long) src->pub.bytes_in_buffer;
263       (void)stdio_fill_input_buffer(cinfo);
264     }
265     src->pub.next_input_byte += (size_t) num_bytes;
266     src->pub.bytes_in_buffer -= (size_t) num_bytes;
267   }
268 }
269 
270 static void
stdio_term_source(j_decompress_ptr cinfo)271 stdio_term_source (j_decompress_ptr cinfo)
272 {
273 }
274 
275 static gchar *
colorspace_name(const J_COLOR_SPACE jpeg_color_space)276 colorspace_name (const J_COLOR_SPACE jpeg_color_space)
277 {
278 	switch (jpeg_color_space) {
279 	    case JCS_UNKNOWN: return "UNKNOWN";
280 	    case JCS_GRAYSCALE: return "GRAYSCALE";
281 	    case JCS_RGB: return "RGB";
282 	    case JCS_YCbCr: return "YCbCr";
283 	    case JCS_CMYK: return "CMYK";
284 	    case JCS_YCCK: return "YCCK";
285 	    default: return "invalid";
286 	}
287 }
288 
289 #define DE_ENDIAN16(val) endian == G_BIG_ENDIAN ? GUINT16_FROM_BE(val) : GUINT16_FROM_LE(val)
290 #define DE_ENDIAN32(val) endian == G_BIG_ENDIAN ? GUINT32_FROM_BE(val) : GUINT32_FROM_LE(val)
291 
292 #define ENDIAN16_IT(val) endian == G_BIG_ENDIAN ? GUINT16_TO_BE(val) : GUINT16_TO_LE(val)
293 #define ENDIAN32_IT(val) endian == G_BIG_ENDIAN ? GUINT32_TO_BE(val) : GUINT32_TO_LE(val)
294 
de_get16(void * ptr,guint endian)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 
de_get32(void * ptr,guint endian)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 /* application specific data segment */
316 static gboolean
jpeg_parse_exif_app2_segment(JpegExifContext * context,jpeg_saved_marker_ptr marker)317 jpeg_parse_exif_app2_segment (JpegExifContext *context, jpeg_saved_marker_ptr marker)
318 {
319 	guint ret = FALSE;
320 	guint sequence_number;
321 	guint number_of_chunks;
322 	guint chunk_size;
323 	guint offset;
324 
325 	/* do we have enough data? */
326 	if (marker->data_length < 16)
327 		goto out;
328 
329 	/* unique identification string */
330 	if (memcmp (marker->data, "ICC_PROFILE\0", 12) != 0)
331 		goto out;
332 
333 	/* get data about this segment */
334 	sequence_number = marker->data[12];
335 	number_of_chunks = marker->data[13];
336 
337 	/* this is invalid, the base offset is 1 */
338 	if (sequence_number == 0)
339 		goto out;
340 
341 	/* this is invalid, the base offset is 1 */
342 	if (sequence_number > number_of_chunks)
343 		goto out;
344 
345 	/* size includes the id (12 bytes), length field (1 byte), and sequence field (1 byte) */
346 	chunk_size = marker->data_length - 14;
347 	offset = (sequence_number - 1) * 0xffef;
348 
349 	/* Deal with the trivial profile (99% of images) to avoid allocating
350 	 * 64kb when we might only use a few kb. */
351 	if (number_of_chunks == 1) {
352 		if (context->icc_profile_size_allocated > 0)
353 			goto out;
354 		context->icc_profile_size = chunk_size;
355 		context->icc_profile_size_allocated = chunk_size;
356 		context->icc_profile = g_new (gchar, chunk_size);
357 		/* copy the segment data to the profile space */
358 		memcpy (context->icc_profile, marker->data + 14, chunk_size);
359 		goto out;
360 	}
361 
362 	/* There is no promise the APP2 segments are going to be in order, so we
363 	 * have to allocate a huge swathe of memory and fill in the gaps when
364 	 * (if) we get the segment.
365 	 * Theoretically this could be as much as 16Mb, but display profiles are
366 	 * vary rarely above 100kb, and printer profiles are usually less than
367 	 * 2Mb */
368 	if (context->icc_profile_size_allocated == 0) {
369 		context->icc_profile_size_allocated = number_of_chunks * 0xffff;
370 		context->icc_profile = g_new0 (gchar, number_of_chunks * 0xffff);
371 	}
372 
373 	/* check the data will fit in our previously allocated buffer */
374 	if (offset + chunk_size > context->icc_profile_size_allocated)
375 		goto out;
376 
377 	/* copy the segment data to the profile space */
378 	memcpy (context->icc_profile + offset, marker->data + 14, chunk_size);
379 
380 	/* it's now this big plus the new data we've just copied */
381 	context->icc_profile_size += chunk_size;
382 
383 	/* success */
384 	ret = TRUE;
385 out:
386 	return ret;
387 }
388 
389 static gboolean
jpeg_parse_exif_app1(JpegExifContext * context,jpeg_saved_marker_ptr marker)390 jpeg_parse_exif_app1 (JpegExifContext *context, jpeg_saved_marker_ptr marker)
391 {
392 	guint i;
393 	guint ret = FALSE;
394 	guint offset;
395 	guint tags;	   /* number of tags in current ifd */
396 	guint endian = 0;	/* detected endian of data */
397 	const char leth[]  = {0x49, 0x49, 0x2a, 0x00};	// Little endian TIFF header
398 	const char beth[]  = {0x4d, 0x4d, 0x00, 0x2a};	// Big endian TIFF header
399 
400 	/* do we have enough data? */
401 	if (marker->data_length < 4)
402 		goto out;
403 
404 	/* unique identification string */
405 	if (memcmp (marker->data, "Exif", 4) != 0)
406 		goto out;
407 
408 	/* do we have enough data? */
409 	if (marker->data_length < 32)
410 		goto out;
411 
412 	/* Just skip data until TIFF header - it should be within 16 bytes from marker start.
413 	   Normal structure relative to APP1 marker -
414 		0x0000: APP1 marker entry = 2 bytes
415 		0x0002: APP1 length entry = 2 bytes
416 		0x0004: Exif Identifier entry = 6 bytes
417 		0x000A: Start of TIFF header (Byte order entry) - 4 bytes
418 			- This is what we look for, to determine endianess.
419 		0x000E: 0th IFD offset pointer - 4 bytes
420 
421 		marker->data points to the first data after the APP1 marker
422 		and length entries, which is the exif identification string.
423 		The TIFF header should thus normally be found at i=6, below,
424 		and the pointer to IFD0 will be at 6+4 = 10.
425 	*/
426 
427 	for (i=0; i<16; i++) {
428 		/* little endian TIFF header */
429 		if (memcmp (&marker->data[i], leth, 4) == 0) {
430 			endian = G_LITTLE_ENDIAN;
431 			ret = TRUE;
432 			break;
433 		}
434 
435 		/* big endian TIFF header */
436 		if (memcmp (&marker->data[i], beth, 4) == 0) {
437 			endian = G_BIG_ENDIAN;
438 			ret = TRUE;
439 			break;
440 		}
441 	}
442 
443 	/* could not find header */
444 	if (!ret)
445 		goto out;
446 
447 	/* read out the offset pointer to IFD0 */
448 	offset  = de_get32(&marker->data[i] + 4, endian);
449 	i = i + offset;
450 
451 	/* check that we still are within the buffer and can read the tag count */
452 	{
453 	    const size_t new_i = i + 2;
454 	    if (new_i < i || new_i > marker->data_length) {
455 		    ret = FALSE;
456 		    goto out;
457 	    }
458 
459 	    /* find out how many tags we have in IFD0. As per the TIFF spec, the first
460 	       two bytes of the IFD contain a count of the number of tags. */
461 	    tags = de_get16(&marker->data[i], endian);
462 	    i = new_i;
463 	}
464 
465 	/* check that we still have enough data for all tags to check. The tags
466 	   are listed in consecutive 12-byte blocks. The tag ID, type, size, and
467 	   a pointer to the actual value, are packed into these 12 byte entries. */
468 	{
469 	    const size_t new_i = i + tags * 12;
470 	    if (new_i < i || new_i > marker->data_length) {
471 		ret = FALSE;
472 		goto out;
473 	    }
474 	}
475 
476 	/* check through IFD0 for tags */
477 	while (tags--) {
478 		size_t new_i;
479 
480 		/* We check for integer overflow before the loop and
481 		 * at the end of each iteration */
482 		guint tag   = de_get16(&marker->data[i + 0], endian);
483 		guint type  = de_get16(&marker->data[i + 2], endian);
484 		guint count = de_get32(&marker->data[i + 4], endian);
485 
486 		/* orientation tag? */
487 		if (tag == 0x112){
488 
489 			/* The orientation field should consist of a single 2-byte integer,
490 			 * but might be a signed long.
491 			 * Values of types smaller than 4 bytes are stored directly in the
492 			 * Value Offset field */
493 			if (type == 0x3 && count == 1) {
494 				guint short_value = de_get16(&marker->data[i + 8], endian);
495 
496 				context->orientation = short_value <= 8 ? short_value : 0;
497 			} else if (type == 0x9 && count == 1) {
498 				guint long_value = de_get32(&marker->data[i + 8], endian);
499 
500 				context->orientation = long_value <= 8 ? long_value : 0;
501 			}
502 		}
503 		/* move the pointer to the next 12-byte tag field. */
504 		new_i = i + 12;
505 		if (new_i < i || new_i > marker->data_length) {
506 			ret = FALSE;
507 			goto out;
508 		}
509 		i = new_i;
510 	}
511 
512 out:
513 	return ret;
514 }
515 
516 static void
jpeg_parse_exif(JpegExifContext * context,j_decompress_ptr cinfo)517 jpeg_parse_exif (JpegExifContext *context, j_decompress_ptr cinfo)
518 {
519 	jpeg_saved_marker_ptr cmarker;
520 
521 	/* check for interesting Exif markers */
522 	cmarker = cinfo->marker_list;
523 	while (cmarker != NULL) {
524 		if (cmarker->marker == JPEG_APP0+1)
525 			jpeg_parse_exif_app1 (context, cmarker);
526 		else if (cmarker->marker == JPEG_APP0+2)
527 			jpeg_parse_exif_app2_segment (context, cmarker);
528 		cmarker = cmarker->next;
529 	}
530 }
531 
532 static gchar *
jpeg_get_comment(j_decompress_ptr cinfo)533 jpeg_get_comment (j_decompress_ptr cinfo)
534 {
535 	jpeg_saved_marker_ptr cmarker;
536 
537 	cmarker = cinfo->marker_list;
538 	while (cmarker != NULL) {
539 		if (cmarker->marker == JPEG_COM)
540 			return g_strndup ((const gchar *) cmarker->data, cmarker->data_length);
541 		cmarker = cmarker->next;
542 	}
543 
544 	return NULL;
545 }
546 
547 static void
jpeg_destroy_exif_context(JpegExifContext * context)548 jpeg_destroy_exif_context (JpegExifContext *context)
549 {
550 	g_free (context->icc_profile);
551 }
552 
553 /* Shared library entry point */
554 static GdkPixbuf *
gdk_pixbuf__jpeg_image_load(FILE * f,GError ** error)555 gdk_pixbuf__jpeg_image_load (FILE *f, GError **error)
556 {
557 	gint   i;
558 	char   otag_str[5];
559 	char  *density_str;
560 	GdkPixbuf * volatile pixbuf = NULL;
561 	guchar *dptr;
562 	guchar *lines[4]; /* Used to expand rows, via rec_outbuf_height,
563                            * from the header file:
564                            * " Usually rec_outbuf_height will be 1 or 2,
565                            * at most 4."
566 			   */
567 	guchar **lptr;
568 	struct jpeg_decompress_struct cinfo;
569 	struct error_handler_data jerr;
570 	stdio_src_ptr src;
571 	gchar *icc_profile_base64;
572 	gchar *comment;
573 	JpegExifContext exif_context = { 0, };
574 
575 	/* setup error handler */
576 	cinfo.err = jpeg_std_error (&jerr.pub);
577 	jerr.pub.error_exit = fatal_error_handler;
578         jerr.pub.output_message = output_message_handler;
579         jerr.error = error;
580 
581 	if (sigsetjmp (jerr.setjmp_buffer, 1)) {
582 		/* Whoops there was a jpeg error */
583 		if (pixbuf)
584 			g_object_unref (pixbuf);
585 
586 		jpeg_destroy_decompress (&cinfo);
587 		jpeg_destroy_exif_context (&exif_context);
588 
589 		/* error should have been set by fatal_error_handler () */
590 		return NULL;
591 	}
592 
593 	/* load header, setup */
594 	jpeg_create_decompress (&cinfo);
595 
596 	cinfo.src = (struct jpeg_source_mgr *)
597 	  (*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT,
598 				  sizeof (stdio_source_mgr));
599 	src = (stdio_src_ptr) cinfo.src;
600 	src->buffer = (JOCTET *)
601 	  (*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT,
602 				      JPEG_PROG_BUF_SIZE * sizeof (JOCTET));
603 
604 	src->pub.init_source = stdio_init_source;
605 	src->pub.fill_input_buffer = stdio_fill_input_buffer;
606 	src->pub.skip_input_data = stdio_skip_input_data;
607 	src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
608 	src->pub.term_source = stdio_term_source;
609 	src->infile = f;
610 	src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
611 	src->pub.next_input_byte = NULL; /* until buffer loaded */
612 
613 	jpeg_save_markers (&cinfo, JPEG_APP0+1, 0xffff);
614 	jpeg_save_markers (&cinfo, JPEG_APP0+2, 0xffff);
615 	jpeg_save_markers (&cinfo, JPEG_COM, 0xffff);
616 	jpeg_read_header (&cinfo, TRUE);
617 
618 	/* parse exif data */
619 	jpeg_parse_exif (&exif_context, &cinfo);
620 
621 	jpeg_start_decompress (&cinfo);
622 	cinfo.do_fancy_upsampling = FALSE;
623 	cinfo.do_block_smoothing = FALSE;
624 
625 	pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
626 				 cinfo.out_color_components == 4 ? TRUE : FALSE,
627 				 8, cinfo.output_width, cinfo.output_height);
628 
629 	if (!pixbuf) {
630                 /* broken check for *error == NULL for robustness against
631                  * crappy JPEG library
632                  */
633                 if (error && *error == NULL) {
634                         g_set_error_literal (error,
635                                              GDK_PIXBUF_ERROR,
636                                              GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
637                                              _("Insufficient memory to load image, try exiting some applications to free memory"));
638                 }
639 
640 		goto out;
641 	}
642 
643 	comment = jpeg_get_comment (&cinfo);
644 	if (comment != NULL) {
645 		gdk_pixbuf_set_option (pixbuf, "comment", comment);
646 		g_free (comment);
647 	}
648 
649 	switch (cinfo.density_unit) {
650 	case 1:
651 		/* Dots per inch (no conversion required) */
652 		density_str = g_strdup_printf ("%d", cinfo.X_density);
653 		gdk_pixbuf_set_option (pixbuf, "x-dpi", density_str);
654 		g_free (density_str);
655 		density_str = g_strdup_printf ("%d", cinfo.Y_density);
656 		gdk_pixbuf_set_option (pixbuf, "y-dpi", density_str);
657 		g_free (density_str);
658 		break;
659 	case 2:
660 		/* Dots per cm - convert into dpi */
661 		density_str = g_strdup_printf ("%d", DPCM_TO_DPI (cinfo.X_density));
662 		gdk_pixbuf_set_option (pixbuf, "x-dpi", density_str);
663 		g_free (density_str);
664 		density_str = g_strdup_printf ("%d", DPCM_TO_DPI (cinfo.Y_density));
665 		gdk_pixbuf_set_option (pixbuf, "y-dpi", density_str);
666 		g_free (density_str);
667 		break;
668 	}
669 
670 	/* if orientation tag was found */
671 	if (exif_context.orientation != 0) {
672 		g_snprintf (otag_str, sizeof (otag_str), "%d", exif_context.orientation);
673 		gdk_pixbuf_set_option (pixbuf, "orientation", otag_str);
674 	}
675 
676 	/* if icc profile was found */
677 	if (exif_context.icc_profile != NULL) {
678 		icc_profile_base64 = g_base64_encode ((const guchar *) exif_context.icc_profile, exif_context.icc_profile_size);
679 		gdk_pixbuf_set_option (pixbuf, "icc-profile", icc_profile_base64);
680 		g_free (icc_profile_base64);
681 	}
682 
683 	dptr = gdk_pixbuf_get_pixels (pixbuf);
684 
685 	/* decompress all the lines, a few at a time */
686 	while (cinfo.output_scanline < cinfo.output_height) {
687 		lptr = lines;
688 		for (i = 0; i < cinfo.rec_outbuf_height; i++) {
689 			*lptr++ = dptr;
690 			dptr += gdk_pixbuf_get_rowstride (pixbuf);
691 		}
692 
693 		jpeg_read_scanlines (&cinfo, lines, cinfo.rec_outbuf_height);
694 
695 		switch (cinfo.out_color_space) {
696 		    case JCS_GRAYSCALE:
697 		      explode_gray_into_buf (&cinfo, lines);
698 		      break;
699 		    case JCS_RGB:
700 		      /* do nothing */
701 		      break;
702 		    case JCS_CMYK:
703 		      convert_cmyk_to_rgb (&cinfo, lines);
704 		      break;
705 		    default:
706 		      g_clear_object (&pixbuf);
707                       g_set_error (error,
708                                    GDK_PIXBUF_ERROR,
709 				   GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
710 				   _("Unsupported JPEG color space (%s)"),
711 				   colorspace_name (cinfo.out_color_space));
712 		      goto out;
713 		}
714 	}
715 
716 out:
717 	jpeg_finish_decompress (&cinfo);
718 	jpeg_destroy_decompress (&cinfo);
719 	jpeg_destroy_exif_context (&exif_context);
720 
721 	return pixbuf;
722 }
723 
724 
725 /**** Progressive image loading handling *****/
726 
727 /* these routines required because we are acting as a source manager for */
728 /* libjpeg. */
729 static void
init_source(j_decompress_ptr cinfo)730 init_source (j_decompress_ptr cinfo)
731 {
732 	my_src_ptr src = (my_src_ptr) cinfo->src;
733 
734 	src->skip_next = 0;
735 }
736 
737 
738 static void
term_source(j_decompress_ptr cinfo)739 term_source (j_decompress_ptr cinfo)
740 {
741 	/* XXXX - probably should scream something has happened */
742 }
743 
744 
745 /* for progressive loading (called "I/O Suspension" by libjpeg docs) */
746 /* we do nothing except return "FALSE"                               */
747 static boolean
fill_input_buffer(j_decompress_ptr cinfo)748 fill_input_buffer (j_decompress_ptr cinfo)
749 {
750 	return FALSE;
751 }
752 
753 
754 static void
skip_input_data(j_decompress_ptr cinfo,long num_bytes)755 skip_input_data (j_decompress_ptr cinfo, long num_bytes)
756 {
757 	my_src_ptr src = (my_src_ptr) cinfo->src;
758 	long   num_can_do;
759 
760 	/* move as far as we can into current buffer */
761 	/* then set skip_next to catch the rest      */
762 	if (num_bytes > 0) {
763 		num_can_do = MIN (src->pub.bytes_in_buffer, num_bytes);
764 		src->pub.next_input_byte += (size_t) num_can_do;
765 		src->pub.bytes_in_buffer -= (size_t) num_can_do;
766 
767 		src->skip_next = num_bytes - num_can_do;
768 	}
769 }
770 
771 
772 /*
773  * func - called when we have pixmap created (but no image data)
774  * user_data - passed as arg 1 to func
775  * return context (opaque to user)
776  */
777 
778 static gpointer
gdk_pixbuf__jpeg_image_begin_load(GdkPixbufModuleSizeFunc size_func,GdkPixbufModulePreparedFunc prepared_func,GdkPixbufModuleUpdatedFunc updated_func,gpointer user_data,GError ** error)779 gdk_pixbuf__jpeg_image_begin_load (GdkPixbufModuleSizeFunc size_func,
780 				   GdkPixbufModulePreparedFunc prepared_func,
781 				   GdkPixbufModuleUpdatedFunc updated_func,
782 				   gpointer user_data,
783                                    GError **error)
784 {
785 	JpegProgContext *context;
786 	my_source_mgr   *src;
787 
788 	context = g_new0 (JpegProgContext, 1);
789 	context->size_func = size_func;
790 	context->prepared_func = prepared_func;
791 	context->updated_func  = updated_func;
792 	context->user_data = user_data;
793 	context->pixbuf = NULL;
794 	context->got_header = FALSE;
795 	context->did_prescan = FALSE;
796 	context->src_initialized = FALSE;
797 	context->in_output = FALSE;
798 
799         /* From jpeglib.h: "NB: you must set up the error-manager
800          * BEFORE calling jpeg_create_xxx". */
801 	context->cinfo.err = jpeg_std_error (&context->jerr.pub);
802 	context->jerr.pub.error_exit = fatal_error_handler;
803         context->jerr.pub.output_message = output_message_handler;
804         context->jerr.error = error;
805 
806         if (sigsetjmp (context->jerr.setjmp_buffer, 1)) {
807                 jpeg_destroy_decompress (&context->cinfo);
808                 g_free(context);
809                 /* error should have been set by fatal_error_handler () */
810                 return NULL;
811         }
812 
813 	/* create libjpeg structures */
814 	jpeg_create_decompress (&context->cinfo);
815 
816 	context->cinfo.src = (struct jpeg_source_mgr *) g_try_malloc (sizeof (my_source_mgr));
817 	if (!context->cinfo.src) {
818 		g_set_error_literal (error,
819                                      GDK_PIXBUF_ERROR,
820                                      GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
821                                      _("Couldn’t allocate memory for loading JPEG file"));
822 		return NULL;
823 	}
824 	memset (context->cinfo.src, 0, sizeof (my_source_mgr));
825 
826 	src = (my_src_ptr) context->cinfo.src;
827 	src->pub.init_source = init_source;
828 	src->pub.fill_input_buffer = fill_input_buffer;
829 	src->pub.skip_input_data = skip_input_data;
830 	src->pub.resync_to_restart = jpeg_resync_to_restart;
831 	src->pub.term_source = term_source;
832 	src->pub.bytes_in_buffer = 0;
833 	src->pub.next_input_byte = NULL;
834 
835         context->jerr.error = NULL;
836 
837 	return (gpointer) context;
838 }
839 
840 /*
841  * context - returned from image_begin_load
842  *
843  * free context, unref gdk_pixbuf
844  */
845 static gboolean
gdk_pixbuf__jpeg_image_stop_load(gpointer data,GError ** error)846 gdk_pixbuf__jpeg_image_stop_load (gpointer data, GError **error)
847 {
848 	JpegProgContext *context = (JpegProgContext *) data;
849 	struct           jpeg_decompress_struct *cinfo;
850         gboolean retval;
851 
852 	g_return_val_if_fail (context != NULL, TRUE);
853 
854 	cinfo = &context->cinfo;
855 
856 	context->jerr.error = error;
857 	if (!sigsetjmp (context->jerr.setjmp_buffer, 1)) {
858 		/* Try to finish loading truncated files */
859 		if (context->pixbuf &&
860 		    cinfo->output_scanline < cinfo->output_height) {
861 			my_src_ptr src = (my_src_ptr) cinfo->src;
862 
863 			/* But only if there's enough buffer space left */
864 			if (src->skip_next < sizeof(src->buffer) - 2) {
865 				/* Insert a fake EOI marker */
866 				src->buffer[src->skip_next] = (JOCTET) 0xFF;
867 				src->buffer[src->skip_next + 1] = (JOCTET) JPEG_EOI;
868 				src->pub.next_input_byte = src->buffer + src->skip_next;
869 				src->pub.bytes_in_buffer = 2;
870 
871 				gdk_pixbuf__jpeg_image_load_lines (context, NULL);
872 			}
873 		}
874 	}
875 
876         /* FIXME this thing needs to report errors if
877          * we have unused image data
878          */
879 
880 	if (context->pixbuf)
881 		g_object_unref (context->pixbuf);
882 
883 	/* if we have an error? */
884 	context->jerr.error = error;
885 	if (sigsetjmp (context->jerr.setjmp_buffer, 1)) {
886                 retval = FALSE;
887 	} else {
888 		jpeg_finish_decompress (cinfo);
889                 retval = TRUE;
890 	}
891 
892         jpeg_destroy_decompress (&context->cinfo);
893 
894 	if (cinfo->src) {
895 		my_src_ptr src = (my_src_ptr) cinfo->src;
896 		g_free (src);
897 	}
898 
899 	g_free (context);
900 
901         return retval;
902 }
903 
904 
905 static gboolean
gdk_pixbuf__jpeg_image_load_lines(JpegProgContext * context,GError ** error)906 gdk_pixbuf__jpeg_image_load_lines (JpegProgContext  *context,
907                                    GError          **error)
908 {
909         struct jpeg_decompress_struct *cinfo = &context->cinfo;
910         guchar *lines[4];
911         guchar **lptr;
912         guchar *rowptr;
913         gint   nlines, i;
914 
915         /* keep going until we've done all scanlines */
916         while (cinfo->output_scanline < cinfo->output_height) {
917                 lptr = lines;
918                 rowptr = context->dptr;
919                 for (i=0; i < cinfo->rec_outbuf_height; i++) {
920                         *lptr++ = rowptr;
921                         rowptr += gdk_pixbuf_get_rowstride (context->pixbuf);
922                 }
923 
924                 nlines = jpeg_read_scanlines (cinfo, lines,
925                                               cinfo->rec_outbuf_height);
926                 if (nlines == 0)
927                         break;
928 
929                 switch (cinfo->out_color_space) {
930                 case JCS_GRAYSCALE:
931                         explode_gray_into_buf (cinfo, lines);
932                         break;
933                 case JCS_RGB:
934                         /* do nothing */
935                         break;
936                 case JCS_CMYK:
937                         convert_cmyk_to_rgb (cinfo, lines);
938                         break;
939                 default:
940                         g_set_error (error,
941                                      GDK_PIXBUF_ERROR,
942                                      GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
943                                      _("Unsupported JPEG color space (%s)"),
944                                      colorspace_name (cinfo->out_color_space));
945 
946                         return FALSE;
947                 }
948 
949                 context->dptr += (gsize)nlines * gdk_pixbuf_get_rowstride (context->pixbuf);
950 
951                 /* send updated signal */
952 		if (context->updated_func)
953 			(* context->updated_func) (context->pixbuf,
954 						   0,
955 						   cinfo->output_scanline - 1,
956 						   cinfo->image_width,
957 						   nlines,
958 						   context->user_data);
959         }
960 
961         return TRUE;
962 }
963 
964 
965 /*
966  * context - from image_begin_load
967  * buf - new image data
968  * size - length of new image data
969  *
970  * append image data onto inrecrementally built output image
971  */
972 static gboolean
gdk_pixbuf__jpeg_image_load_increment(gpointer data,const guchar * buf,guint size,GError ** error)973 gdk_pixbuf__jpeg_image_load_increment (gpointer data,
974                                        const guchar *buf, guint size,
975                                        GError **error)
976 {
977 	JpegProgContext *context = (JpegProgContext *)data;
978 	struct           jpeg_decompress_struct *cinfo;
979 	my_src_ptr       src;
980 	guint            num_left, num_copy;
981 	guint            last_num_left, last_bytes_left;
982 	guint            spinguard;
983 	gboolean         first;
984 	const guchar    *bufhd;
985 	gint             width, height;
986 	char             otag_str[5];
987 	gchar 		*icc_profile_base64;
988 	char            *density_str;
989 	JpegExifContext  exif_context = { 0, };
990 	gboolean	 retval;
991 
992 	g_return_val_if_fail (context != NULL, FALSE);
993 	g_return_val_if_fail (buf != NULL, FALSE);
994 
995 	src = (my_src_ptr) context->cinfo.src;
996 
997 	cinfo = &context->cinfo;
998 
999         context->jerr.error = error;
1000 
1001 	/* check for fatal error */
1002 	if (sigsetjmp (context->jerr.setjmp_buffer, 1)) {
1003 		retval = FALSE;
1004 		goto out;
1005 	}
1006 
1007 	/* skip over data if requested, handle unsigned int sizes cleanly */
1008 	/* only can happen if we've already called jpeg_get_header once   */
1009 	if (context->src_initialized && src->skip_next) {
1010 		if (src->skip_next > size) {
1011 			src->skip_next -= size;
1012 			retval = TRUE;
1013 			goto out;
1014 		} else {
1015 			num_left = size - src->skip_next;
1016 			bufhd = buf + src->skip_next;
1017 			src->skip_next = 0;
1018 		}
1019 	} else {
1020 		num_left = size;
1021 		bufhd = buf;
1022 	}
1023 
1024 	if (num_left == 0) {
1025 		retval = TRUE;
1026 		goto out;
1027 	}
1028 
1029 	last_num_left = num_left;
1030 	last_bytes_left = 0;
1031 	spinguard = 0;
1032 	first = TRUE;
1033 	while (TRUE) {
1034 
1035 		/* handle any data from caller we haven't processed yet */
1036 		if (num_left > 0) {
1037 			if(src->pub.bytes_in_buffer &&
1038 			   src->pub.next_input_byte != src->buffer)
1039 				memmove(src->buffer, src->pub.next_input_byte,
1040 					src->pub.bytes_in_buffer);
1041 
1042 
1043 			num_copy = MIN (JPEG_PROG_BUF_SIZE - src->pub.bytes_in_buffer,
1044 					num_left);
1045 
1046 			memcpy(src->buffer + src->pub.bytes_in_buffer, bufhd,num_copy);
1047 			src->pub.next_input_byte = src->buffer;
1048 			src->pub.bytes_in_buffer += num_copy;
1049 			bufhd += num_copy;
1050 			num_left -= num_copy;
1051 		}
1052 
1053                 /* did anything change from last pass, if not return */
1054                 if (first) {
1055                         last_bytes_left = src->pub.bytes_in_buffer;
1056                         first = FALSE;
1057                 } else if (src->pub.bytes_in_buffer == last_bytes_left
1058 			   && num_left == last_num_left) {
1059                         spinguard++;
1060 		} else {
1061                         last_bytes_left = src->pub.bytes_in_buffer;
1062 			last_num_left = num_left;
1063 		}
1064 
1065 		/* should not go through twice and not pull bytes out of buf */
1066 		if (spinguard > 2) {
1067 			retval = TRUE;
1068 			goto out;
1069 		}
1070 
1071 		/* try to load jpeg header */
1072 		if (!context->got_header) {
1073 			int rc;
1074 			gchar* comment;
1075 			gboolean has_alpha;
1076 
1077 			jpeg_save_markers (cinfo, JPEG_APP0+1, 0xffff);
1078 			jpeg_save_markers (cinfo, JPEG_APP0+2, 0xffff);
1079 			jpeg_save_markers (cinfo, JPEG_COM, 0xffff);
1080 			rc = jpeg_read_header (cinfo, TRUE);
1081 			context->src_initialized = TRUE;
1082 
1083 			if (rc == JPEG_SUSPENDED)
1084 				continue;
1085 
1086 			context->got_header = TRUE;
1087 
1088 			/* parse exif data */
1089 			jpeg_parse_exif (&exif_context, cinfo);
1090 
1091 			width = cinfo->image_width;
1092 			height = cinfo->image_height;
1093 			if (context->size_func) {
1094 				(* context->size_func) (&width, &height, context->user_data);
1095 				if (width == 0 || height == 0) {
1096 					g_set_error_literal (error,
1097                                                              GDK_PIXBUF_ERROR,
1098                                                              GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
1099                                                              _("Transformed JPEG has zero width or height."));
1100 					retval = FALSE;
1101 					goto out;
1102 				}
1103 			}
1104 
1105 			cinfo->scale_num = 1;
1106 			for (cinfo->scale_denom = 2; cinfo->scale_denom <= 8; cinfo->scale_denom *= 2) {
1107 				jpeg_calc_output_dimensions (cinfo);
1108 				if (cinfo->output_width < width || cinfo->output_height < height) {
1109 					cinfo->scale_denom /= 2;
1110 					break;
1111 				}
1112 			}
1113 			jpeg_calc_output_dimensions (cinfo);
1114 
1115 			if (cinfo->output_components == 3) {
1116 				has_alpha = FALSE;
1117 			} else if (cinfo->output_components == 4) {
1118 				has_alpha = TRUE;
1119 			} else if (cinfo->output_components == 1 &&
1120 				   cinfo->out_color_space == JCS_GRAYSCALE) {
1121 				has_alpha = FALSE;
1122 			} else {
1123 				g_set_error (error,
1124 					     GDK_PIXBUF_ERROR,
1125 					     GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
1126 					     _("Unsupported number of color components (%d)"),
1127 					     cinfo->output_components);
1128 				retval = FALSE;
1129 				goto out;
1130 			}
1131 
1132 			context->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
1133 							  has_alpha,
1134 							  8,
1135 							  cinfo->output_width,
1136 							  cinfo->output_height);
1137 
1138 			if (context->pixbuf == NULL) {
1139                                 g_set_error_literal (error,
1140                                                      GDK_PIXBUF_ERROR,
1141                                                      GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
1142                                                      _("Couldn’t allocate memory for loading JPEG file"));
1143                                 retval = FALSE;
1144 				goto out;
1145 			}
1146 
1147 			comment = jpeg_get_comment (cinfo);
1148 			if (comment != NULL) {
1149 				gdk_pixbuf_set_option (context->pixbuf, "comment", comment);
1150 				g_free (comment);
1151 			}
1152 
1153 			switch (cinfo->density_unit) {
1154 			case 1:
1155 				/* Dots per inch (no conversion required) */
1156 				density_str = g_strdup_printf ("%d", cinfo->X_density);
1157 				gdk_pixbuf_set_option (context->pixbuf, "x-dpi", density_str);
1158 				g_free (density_str);
1159 				density_str = g_strdup_printf ("%d", cinfo->Y_density);
1160 				gdk_pixbuf_set_option (context->pixbuf, "y-dpi", density_str);
1161 				g_free (density_str);
1162 				break;
1163 			case 2:
1164 				/* Dots per cm - convert into dpi */
1165 				density_str = g_strdup_printf ("%d", DPCM_TO_DPI (cinfo->X_density));
1166 				gdk_pixbuf_set_option (context->pixbuf, "x-dpi", density_str);
1167 				g_free (density_str);
1168 				density_str = g_strdup_printf ("%d", DPCM_TO_DPI (cinfo->Y_density));
1169 				gdk_pixbuf_set_option (context->pixbuf, "y-dpi", density_str);
1170 				g_free (density_str);
1171 				break;
1172 			}
1173 
1174 		        /* if orientation tag was found set an option to remember its value */
1175 			if (exif_context.orientation != 0) {
1176 				g_snprintf (otag_str, sizeof (otag_str), "%d", exif_context.orientation);
1177 		                gdk_pixbuf_set_option (context->pixbuf, "orientation", otag_str);
1178 		        }
1179 			/* if icc profile was found */
1180 			if (exif_context.icc_profile != NULL) {
1181 				icc_profile_base64 = g_base64_encode ((const guchar *) exif_context.icc_profile, exif_context.icc_profile_size);
1182 				gdk_pixbuf_set_option (context->pixbuf, "icc-profile", icc_profile_base64);
1183 				g_free (icc_profile_base64);
1184 			}
1185 
1186 
1187 			/* Use pixbuf buffer to store decompressed data */
1188 			context->dptr = gdk_pixbuf_get_pixels (context->pixbuf);
1189 
1190 			/* Notify the client that we are ready to go */
1191 			if (context->prepared_func)
1192 				(* context->prepared_func) (context->pixbuf,
1193 							    NULL,
1194 							    context->user_data);
1195 
1196 		} else if (!context->did_prescan) {
1197 			int rc;
1198 
1199 			/* start decompression */
1200 			cinfo->buffered_image = cinfo->progressive_mode;
1201 			rc = jpeg_start_decompress (cinfo);
1202 			cinfo->do_fancy_upsampling = FALSE;
1203 			cinfo->do_block_smoothing = FALSE;
1204 
1205 			if (rc == JPEG_SUSPENDED)
1206 				continue;
1207 
1208 			context->did_prescan = TRUE;
1209 		} else if (!cinfo->buffered_image) {
1210                         /* we're decompressing unbuffered so
1211                          * simply get scanline by scanline from jpeg lib
1212                          */
1213                         if (! gdk_pixbuf__jpeg_image_load_lines (context,
1214                                                                  error)) {
1215                                 retval = FALSE;
1216 				goto out;
1217 			}
1218 
1219 			if (cinfo->output_scanline >= cinfo->output_height) {
1220 				retval = TRUE;
1221 				goto out;
1222 			}
1223 		} else {
1224                         /* we're decompressing buffered (progressive)
1225                          * so feed jpeg lib scanlines
1226                          */
1227 
1228 			/* keep going until we've done all passes */
1229 			while (!jpeg_input_complete (cinfo)) {
1230 				if (!context->in_output) {
1231 					if (jpeg_start_output (cinfo, cinfo->input_scan_number)) {
1232 						context->in_output = TRUE;
1233 						context->dptr = gdk_pixbuf_get_pixels (context->pixbuf);
1234 					}
1235 					else
1236 						break;
1237 				}
1238 
1239                                 /* get scanlines from jpeg lib */
1240                                 if (! gdk_pixbuf__jpeg_image_load_lines (context,
1241                                                                          error)) {
1242                                         retval = FALSE;
1243 					goto out;
1244 				}
1245 
1246 				if (cinfo->output_scanline >= cinfo->output_height &&
1247 				    jpeg_finish_output (cinfo))
1248 					context->in_output = FALSE;
1249 				else
1250 					break;
1251 			}
1252 			if (jpeg_input_complete (cinfo)) {
1253 				/* did entire image */
1254 				retval = TRUE;
1255 				goto out;
1256 			}
1257 			else
1258 				continue;
1259 		}
1260 	}
1261 out:
1262 	jpeg_destroy_exif_context (&exif_context);
1263 	return retval;
1264 }
1265 
1266 /* Save */
1267 
1268 #define TO_FUNCTION_BUF_SIZE 4096
1269 
1270 typedef struct {
1271 	struct jpeg_destination_mgr pub;
1272 	JOCTET             *buffer;
1273 	GdkPixbufSaveFunc   save_func;
1274 	gpointer            user_data;
1275 	GError            **error;
1276 } ToFunctionDestinationManager;
1277 
1278 void
to_callback_init(j_compress_ptr cinfo)1279 to_callback_init (j_compress_ptr cinfo)
1280 {
1281 	ToFunctionDestinationManager *destmgr;
1282 
1283 	destmgr	= (ToFunctionDestinationManager*) cinfo->dest;
1284 	destmgr->pub.next_output_byte = destmgr->buffer;
1285 	destmgr->pub.free_in_buffer = TO_FUNCTION_BUF_SIZE;
1286 }
1287 
1288 static void
to_callback_do_write(j_compress_ptr cinfo,gsize length)1289 to_callback_do_write (j_compress_ptr cinfo, gsize length)
1290 {
1291 	ToFunctionDestinationManager *destmgr;
1292 
1293 	destmgr	= (ToFunctionDestinationManager*) cinfo->dest;
1294         if (!destmgr->save_func ((gchar *)destmgr->buffer,
1295 				 length,
1296 				 destmgr->error,
1297 				 destmgr->user_data)) {
1298 		struct error_handler_data *errmgr;
1299 
1300 		errmgr = (struct error_handler_data *) cinfo->err;
1301 		/* Use a default error message if the callback didn't set one,
1302 		 * which it should have.
1303 		 */
1304 		if (errmgr->error && *errmgr->error == NULL) {
1305 			g_set_error_literal (errmgr->error,
1306                                              GDK_PIXBUF_ERROR,
1307                                              GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
1308                                              "write function failed");
1309 		}
1310 		siglongjmp (errmgr->setjmp_buffer, 1);
1311 		g_assert_not_reached ();
1312         }
1313 }
1314 
1315 static boolean
to_callback_empty_output_buffer(j_compress_ptr cinfo)1316 to_callback_empty_output_buffer (j_compress_ptr cinfo)
1317 {
1318 	ToFunctionDestinationManager *destmgr;
1319 
1320 	destmgr	= (ToFunctionDestinationManager*) cinfo->dest;
1321 	to_callback_do_write (cinfo, TO_FUNCTION_BUF_SIZE);
1322 	destmgr->pub.next_output_byte = destmgr->buffer;
1323 	destmgr->pub.free_in_buffer = TO_FUNCTION_BUF_SIZE;
1324 	return TRUE;
1325 }
1326 
1327 void
to_callback_terminate(j_compress_ptr cinfo)1328 to_callback_terminate (j_compress_ptr cinfo)
1329 {
1330 	ToFunctionDestinationManager *destmgr;
1331 
1332 	destmgr	= (ToFunctionDestinationManager*) cinfo->dest;
1333 	to_callback_do_write (cinfo, TO_FUNCTION_BUF_SIZE - destmgr->pub.free_in_buffer);
1334 }
1335 
1336 static gboolean
real_save_jpeg(GdkPixbuf * pixbuf,gchar ** keys,gchar ** values,GError ** error,gboolean to_callback,FILE * f,GdkPixbufSaveFunc save_func,gpointer user_data)1337 real_save_jpeg (GdkPixbuf          *pixbuf,
1338 		gchar             **keys,
1339 		gchar             **values,
1340 		GError            **error,
1341 		gboolean            to_callback,
1342 		FILE               *f,
1343 		GdkPixbufSaveFunc   save_func,
1344 		gpointer            user_data)
1345 {
1346         /* FIXME error handling is broken */
1347 
1348        struct jpeg_compress_struct cinfo;
1349        guchar *buf = NULL;
1350        guchar *ptr;
1351        guchar *pixels = NULL;
1352        JSAMPROW *jbuf;
1353        int y = 0;
1354        volatile int quality = 75; /* default; must be between 0 and 100 */
1355        int i, j;
1356        int w, h = 0;
1357        int rowstride = 0;
1358        int n_channels;
1359        struct error_handler_data jerr;
1360        ToFunctionDestinationManager to_callback_destmgr;
1361        int x_density = 0;
1362        int y_density = 0;
1363        gchar *icc_profile = NULL;
1364        gchar *data;
1365        gint retval = TRUE;
1366        gsize icc_profile_size = 0;
1367 
1368        to_callback_destmgr.buffer = NULL;
1369 
1370        if (keys && *keys) {
1371                gchar **kiter = keys;
1372                gchar **viter = values;
1373 
1374                while (*kiter) {
1375                        if (strcmp (*kiter, "quality") == 0) {
1376                                char *endptr = NULL;
1377                                quality = strtol (*viter, &endptr, 10);
1378 
1379                                if (endptr == *viter) {
1380                                        g_set_error (error,
1381                                                     GDK_PIXBUF_ERROR,
1382                                                     GDK_PIXBUF_ERROR_BAD_OPTION,
1383                                                     _("JPEG quality must be a value between 0 and 100; value “%s” could not be parsed."),
1384                                                     *viter);
1385 
1386                                        retval = FALSE;
1387                                        goto cleanup;
1388                                }
1389 
1390                                if (quality < 0 ||
1391                                    quality > 100) {
1392                                        /* This is a user-visible error;
1393                                         * lets people skip the range-checking
1394                                         * in their app.
1395                                         */
1396                                        g_set_error (error,
1397                                                     GDK_PIXBUF_ERROR,
1398                                                     GDK_PIXBUF_ERROR_BAD_OPTION,
1399                                                     _("JPEG quality must be a value between 0 and 100; value “%d” is not allowed."),
1400                                                     quality);
1401 
1402                                        retval = FALSE;
1403                                        goto cleanup;
1404                                }
1405                        } else if (strcmp (*kiter, "x-dpi") == 0) {
1406                                char *endptr = NULL;
1407                                x_density = strtol (*viter, &endptr, 10);
1408                                if (endptr == *viter)
1409                                        x_density = -1;
1410 
1411                                if (x_density <= 0 ||
1412                                    x_density > 65535) {
1413                                        /* This is a user-visible error;
1414                                         * lets people skip the range-checking
1415                                         * in their app.
1416                                         */
1417                                        g_set_error (error,
1418                                                     GDK_PIXBUF_ERROR,
1419                                                     GDK_PIXBUF_ERROR_BAD_OPTION,
1420                                                     _("JPEG x-dpi must be a value between 1 and 65535; value “%s” is not allowed."),
1421                                                     *viter);
1422 
1423                                        retval = FALSE;
1424                                        goto cleanup;
1425                                }
1426                        } else if (strcmp (*kiter, "y-dpi") == 0) {
1427                                char *endptr = NULL;
1428                                y_density = strtol (*viter, &endptr, 10);
1429                                if (endptr == *viter)
1430                                        y_density = -1;
1431 
1432                                if (y_density <= 0 ||
1433                                    y_density > 65535) {
1434                                        /* This is a user-visible error;
1435                                         * lets people skip the range-checking
1436                                         * in their app.
1437                                         */
1438                                        g_set_error (error,
1439                                                     GDK_PIXBUF_ERROR,
1440                                                     GDK_PIXBUF_ERROR_BAD_OPTION,
1441                                                     _("JPEG y-dpi must be a value between 1 and 65535; value “%s” is not allowed."),
1442                                                     *viter);
1443 
1444                                        retval = FALSE;
1445                                        goto cleanup;
1446                                }
1447                        } else if (strcmp (*kiter, "icc-profile") == 0) {
1448                                /* decode from base64 */
1449                                icc_profile = (gchar*) g_base64_decode (*viter, &icc_profile_size);
1450                                if (icc_profile_size < 127) {
1451                                        /* This is a user-visible error */
1452                                        g_set_error (error,
1453                                                     GDK_PIXBUF_ERROR,
1454                                                     GDK_PIXBUF_ERROR_BAD_OPTION,
1455                                                     _("Color profile has invalid length “%u”."),
1456                                                     (guint) icc_profile_size);
1457                                        retval = FALSE;
1458                                        goto cleanup;
1459                                }
1460                        } else {
1461                                g_warning ("Unrecognized parameter (%s) passed to JPEG saver.", *kiter);
1462                        }
1463 
1464                        ++kiter;
1465                        ++viter;
1466                }
1467        }
1468 
1469        rowstride = gdk_pixbuf_get_rowstride (pixbuf);
1470        n_channels = gdk_pixbuf_get_n_channels (pixbuf);
1471 
1472        w = gdk_pixbuf_get_width (pixbuf);
1473        h = gdk_pixbuf_get_height (pixbuf);
1474        pixels = gdk_pixbuf_get_pixels (pixbuf);
1475 
1476        /* Guaranteed by the caller. */
1477        g_assert (w >= 0);
1478        g_assert (h >= 0);
1479        g_assert (rowstride >= 0);
1480        g_assert (n_channels >= 0);
1481 
1482        /* Allocate a small buffer to convert image data,
1483 	* and a larger buffer if doing to_callback save.
1484 	*/
1485        buf = g_try_malloc (w * 3 * sizeof (guchar));
1486        if (!buf) {
1487 	       g_set_error_literal (error,
1488                                     GDK_PIXBUF_ERROR,
1489                                     GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
1490                                     _("Couldn’t allocate memory for loading JPEG file"));
1491 	       retval = FALSE;
1492 	       goto cleanup;
1493        }
1494        if (to_callback) {
1495 	       to_callback_destmgr.buffer = g_try_malloc (TO_FUNCTION_BUF_SIZE);
1496 	       if (!to_callback_destmgr.buffer) {
1497 		       g_set_error_literal (error,
1498                                             GDK_PIXBUF_ERROR,
1499                                             GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
1500                                             _("Couldn’t allocate memory for loading JPEG file"));
1501 		       retval = FALSE;
1502 		       goto cleanup;
1503 	       }
1504        }
1505 
1506        /* set up error handling */
1507        cinfo.err = jpeg_std_error (&(jerr.pub));
1508        jerr.pub.error_exit = fatal_error_handler;
1509        jerr.pub.output_message = output_message_handler;
1510        jerr.error = error;
1511 
1512        if (sigsetjmp (jerr.setjmp_buffer, 1)) {
1513                jpeg_destroy_compress (&cinfo);
1514 	       retval = FALSE;
1515 	       goto cleanup;
1516        }
1517 
1518        /* setup compress params */
1519        jpeg_create_compress (&cinfo);
1520        if (to_callback) {
1521 	       to_callback_destmgr.pub.init_destination    = to_callback_init;
1522 	       to_callback_destmgr.pub.empty_output_buffer = to_callback_empty_output_buffer;
1523 	       to_callback_destmgr.pub.term_destination    = to_callback_terminate;
1524 	       to_callback_destmgr.error = error;
1525 	       to_callback_destmgr.save_func = save_func;
1526 	       to_callback_destmgr.user_data = user_data;
1527 	       cinfo.dest = (struct jpeg_destination_mgr*) &to_callback_destmgr;
1528        } else {
1529 	       jpeg_stdio_dest (&cinfo, f);
1530        }
1531        cinfo.image_width      = w;
1532        cinfo.image_height     = h;
1533        cinfo.input_components = 3;
1534        cinfo.in_color_space   = JCS_RGB;
1535 
1536        /* set up jepg compression parameters */
1537        jpeg_set_defaults (&cinfo);
1538        jpeg_set_quality (&cinfo, quality, TRUE);
1539 
1540        /* set density information */
1541        if (x_density > 0 && y_density > 0) {
1542            cinfo.density_unit = 1; /* Dots per inch */
1543            cinfo.X_density = x_density;
1544            cinfo.Y_density = y_density;
1545        }
1546 
1547        jpeg_start_compress (&cinfo, TRUE);
1548 
1549 	/* write ICC profile data */
1550 	if (icc_profile != NULL) {
1551 		/* optimise for the common case where only one APP2 segment is required */
1552 		if (icc_profile_size < 0xffef) {
1553 			data = g_new (gchar, icc_profile_size + 14);
1554 			memcpy (data, "ICC_PROFILE\000\001\001", 14);
1555 			memcpy (data + 14, icc_profile, icc_profile_size);
1556 			jpeg_write_marker (&cinfo, JPEG_APP0+2, (const JOCTET *) data, icc_profile_size + 14);
1557 			g_free (data);
1558 		} else {
1559 			guint segments;
1560 			guint size = 0xffef;
1561 			guint offset;
1562 
1563 			segments = (guint) ceilf ((gfloat) icc_profile_size / (gfloat) 0xffef);
1564 			data = g_new (gchar, 0xffff);
1565 			memcpy (data, "ICC_PROFILE\000", 12);
1566 			data[13] = segments;
1567 			for (i=0; i<=segments; i++) {
1568 				data[12] = i;
1569 				offset = 0xffef * i;
1570 
1571 				/* last segment */
1572 				if (i == segments)
1573 					size = icc_profile_size % 0xffef;
1574 
1575 				memcpy (data + 14, icc_profile + offset, size);
1576 				jpeg_write_marker (&cinfo, JPEG_APP0+2, (const JOCTET *) data, size + 14);
1577 			}
1578 			g_free (data);
1579 		}
1580 	}
1581 
1582        /* get the start pointer */
1583        ptr = pixels;
1584        /* go one scanline at a time... and save */
1585        i = 0;
1586        while (cinfo.next_scanline < cinfo.image_height) {
1587                /* convert scanline from ARGB to RGB packed */
1588                for (j = 0; j < w; j++)
1589                        memcpy (&(buf[j*3]), &(ptr[(gsize)i*rowstride + j*n_channels]), 3);
1590 
1591                /* write scanline */
1592                jbuf = (JSAMPROW *)(&buf);
1593                if (jpeg_write_scanlines (&cinfo, jbuf, 1) == 0) {
1594                       jpeg_destroy_compress (&cinfo);
1595                       retval = FALSE;
1596                       goto cleanup;
1597                }
1598 
1599                i++;
1600                y++;
1601 
1602        }
1603 
1604        /* finish off */
1605        jpeg_finish_compress (&cinfo);
1606        jpeg_destroy_compress(&cinfo);
1607 cleanup:
1608 	g_free (buf);
1609 	g_free (to_callback_destmgr.buffer);
1610 	g_free (icc_profile);
1611 	return retval;
1612 }
1613 
1614 static gboolean
gdk_pixbuf__jpeg_image_save(FILE * f,GdkPixbuf * pixbuf,gchar ** keys,gchar ** values,GError ** error)1615 gdk_pixbuf__jpeg_image_save (FILE          *f,
1616                              GdkPixbuf     *pixbuf,
1617                              gchar        **keys,
1618                              gchar        **values,
1619                              GError       **error)
1620 {
1621 	return real_save_jpeg (pixbuf, keys, values, error,
1622 			       FALSE, f, NULL, NULL);
1623 }
1624 
1625 static gboolean
gdk_pixbuf__jpeg_image_save_to_callback(GdkPixbufSaveFunc save_func,gpointer user_data,GdkPixbuf * pixbuf,gchar ** keys,gchar ** values,GError ** error)1626 gdk_pixbuf__jpeg_image_save_to_callback (GdkPixbufSaveFunc   save_func,
1627 					 gpointer            user_data,
1628 					 GdkPixbuf          *pixbuf,
1629 					 gchar             **keys,
1630 					 gchar             **values,
1631 					 GError            **error)
1632 {
1633 	return real_save_jpeg (pixbuf, keys, values, error,
1634 			       TRUE, NULL, save_func, user_data);
1635 }
1636 
1637 static gboolean
gdk_pixbuf__jpeg_is_save_option_supported(const gchar * option_key)1638 gdk_pixbuf__jpeg_is_save_option_supported (const gchar *option_key)
1639 {
1640         if (g_strcmp0 (option_key, "quality") == 0 ||
1641             g_strcmp0 (option_key, "icc-profile") == 0)
1642                 return TRUE;
1643 
1644         return FALSE;
1645 }
1646 
1647 #ifndef INCLUDE_jpeg
1648 #define MODULE_ENTRY(function) G_MODULE_EXPORT void function
1649 #else
1650 #define MODULE_ENTRY(function) void _gdk_pixbuf__jpeg_ ## function
1651 #endif
1652 
MODULE_ENTRY(fill_vtable)1653 MODULE_ENTRY (fill_vtable) (GdkPixbufModule *module)
1654 {
1655 	module->load = gdk_pixbuf__jpeg_image_load;
1656 	module->begin_load = gdk_pixbuf__jpeg_image_begin_load;
1657 	module->stop_load = gdk_pixbuf__jpeg_image_stop_load;
1658 	module->load_increment = gdk_pixbuf__jpeg_image_load_increment;
1659 	module->save = gdk_pixbuf__jpeg_image_save;
1660 	module->save_to_callback = gdk_pixbuf__jpeg_image_save_to_callback;
1661         module->is_save_option_supported = gdk_pixbuf__jpeg_is_save_option_supported;
1662 }
1663 
MODULE_ENTRY(fill_info)1664 MODULE_ENTRY (fill_info) (GdkPixbufFormat *info)
1665 {
1666 	static const GdkPixbufModulePattern signature[] = {
1667 		{ "\xff\xd8", NULL, 100 },
1668 		{ NULL, NULL, 0 }
1669 	};
1670 	static const gchar *mime_types[] = {
1671 		"image/jpeg",
1672 		NULL
1673 	};
1674 	static const gchar *extensions[] = {
1675 		"jpeg",
1676 		"jpe",
1677 		"jpg",
1678 		NULL
1679 	};
1680 
1681 	info->name = "jpeg";
1682 	info->signature = (GdkPixbufModulePattern *) signature;
1683 	info->description = NC_("image format", "JPEG");
1684 	info->mime_types = (gchar **) mime_types;
1685 	info->extensions = (gchar **) extensions;
1686 	info->flags = GDK_PIXBUF_FORMAT_WRITABLE | GDK_PIXBUF_FORMAT_THREADSAFE;
1687 	info->license = "LGPL";
1688 }
1689