1 /*
2  * gd_jpeg.c: Read and write JPEG (JFIF) format image files using the
3  * gd graphics library (http://www.libgd.org).
4  *
5  * This software is based in part on the work of the Independent JPEG
6  * Group.  For more information on the IJG JPEG software (and JPEG
7  * documentation, etc.), see ftp://ftp.uu.net/graphics/jpeg/.
8  *
9  * NOTE: IJG 12-bit JSAMPLE (BITS_IN_JSAMPLE == 12) mode is not
10  * supported at all on read in gd 2.0, and is not supported on write
11  * except for palette images, which is sort of pointless (TBB). Even that
12  * has never been tested according to DB.
13  *
14  * Copyright 2000 Doug Becker, mailto:thebeckers@home.com
15  *
16  * Modification 4/18/00 TBB: JPEG_DEBUG rather than just DEBUG,
17  * so VC++ builds don't spew to standard output, causing
18  * major CGI brain damage
19  *
20  * 2.0.10: more efficient gdImageCreateFromJpegCtx, thanks to
21  * Christian Aberger
22  */
23 
24 /**
25  * File: JPEG IO
26  *
27  * Read and write JPEG images.
28  */
29 
30 #ifdef HAVE_CONFIG_H
31 #	include "config.h"
32 #endif
33 
34 #include <stdlib.h>
35 #include <setjmp.h>
36 #include <limits.h>
37 #include <string.h>
38 
39 #include "gd.h"
40 #include "gd_errors.h"
41 /* TBB: move this up so include files are not brought in */
42 /* JCE: arrange HAVE_LIBJPEG so that it can be set in gd.h */
43 #ifdef HAVE_LIBJPEG
44 #include "gdhelpers.h"
45 
46 #if defined(_WIN32) && defined(__MINGW32__)
47 # define HAVE_BOOLEAN
48 #endif
49 
50 /* 1.8.1: remove dependency on jinclude.h */
51 #include "jpeglib.h"
52 #include "jerror.h"
53 
54 static const char *const GD_JPEG_VERSION = "1.0";
55 
56 typedef struct _jmpbuf_wrapper {
57 	jmp_buf jmpbuf;
58         int ignore_warning;
59 }
60 jmpbuf_wrapper;
61 
jpeg_emit_message(j_common_ptr jpeg_info,int level)62 static void jpeg_emit_message(j_common_ptr jpeg_info, int level)
63 {
64 	char message[JMSG_LENGTH_MAX];
65 	jmpbuf_wrapper *jmpbufw;
66 	int ignore_warning = 0;
67 
68 	jmpbufw = (jmpbuf_wrapper *) jpeg_info->client_data;
69 
70 	if (jmpbufw != 0) {
71 		ignore_warning = jmpbufw->ignore_warning;
72 	}
73 
74 	(jpeg_info->err->format_message)(jpeg_info,message);
75 
76 	/* It is a warning message */
77 	if (level < 0) {
78 		/* display only the 1st warning, as would do a default libjpeg
79 		 * unless strace_level >= 3
80 		 */
81 		if ((jpeg_info->err->num_warnings == 0) || (jpeg_info->err->trace_level >= 3)) {
82 			if (!ignore_warning) {
83 				gd_error("gd-jpeg, libjpeg: recoverable error: %s\n", message);
84 			}
85 		}
86 
87 		jpeg_info->err->num_warnings++;
88 	} else {
89 		/* strace msg, Show it if trace_level >= level. */
90 		if (jpeg_info->err->trace_level >= level) {
91 			if (!ignore_warning) {
92 				gd_error("gd-jpeg, libjpeg: strace message: %s\n", message);
93 			}
94 		}
95 	}
96 }
97 
98 /* Called by the IJG JPEG library upon encountering a fatal error */
fatal_jpeg_error(j_common_ptr cinfo)99 static void fatal_jpeg_error(j_common_ptr cinfo)
100 {
101 	jmpbuf_wrapper *jmpbufw;
102 	char buffer[JMSG_LENGTH_MAX];
103 
104 	(*cinfo->err->format_message)(cinfo, buffer);
105 	gd_error_ex(GD_WARNING, "gd-jpeg: JPEG library reports unrecoverable error: %s", buffer);
106 
107 	jmpbufw = (jmpbuf_wrapper *)cinfo->client_data;
108 	jpeg_destroy(cinfo);
109 
110 	if(jmpbufw != 0) {
111 		longjmp(jmpbufw->jmpbuf, 1);
112 		gd_error_ex(GD_ERROR, "gd-jpeg: EXTREMELY fatal error: longjmp returned control; terminating\n");
113 	} else {
114 		gd_error_ex(GD_ERROR, "gd-jpeg: EXTREMELY fatal error: jmpbuf unrecoverable; terminating\n");
115 	}
116 
117 	exit(99);
118 }
119 
120 static int _gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality);
121 
122 /*
123  * Write IM to OUTFILE as a JFIF-formatted JPEG image, using quality
124  * QUALITY.  If QUALITY is in the range 0-100, increasing values
125  * represent higher quality but also larger image size.  If QUALITY is
126  * negative, the IJG JPEG library's default quality is used (which
127  * should be near optimal for many applications).  See the IJG JPEG
128  * library documentation for more details.
129  */
130 
131 
132 /*
133   Function: gdImageJpeg
134 
135     <gdImageJpeg> outputs the specified image to the specified file in
136     JPEG format. The file must be open for writing. Under MSDOS and
137     all versions of Windows, it is important to use "wb" as opposed to
138     simply "w" as the mode when opening the file, and under Unix there
139     is no penalty for doing so. <gdImageJpeg> does not close the file;
140     your code must do so.
141 
142     If _quality_ is negative, the default IJG JPEG quality value (which
143     should yield a good general quality / size tradeoff for most
144     situations) is used. Otherwise, for practical purposes, _quality_
145     should be a value in the range 0-95, higher quality values usually
146     implying both higher quality and larger image sizes.
147 
148     If you have set image interlacing using <gdImageInterlace>, this
149     function will interpret that to mean you wish to output a
150     progressive JPEG. Some programs (e.g., Web browsers) can display
151     progressive JPEGs incrementally; this can be useful when browsing
152     over a relatively slow communications link, for
153     example. Progressive JPEGs can also be slightly smaller than
154     sequential (non-progressive) JPEGs.
155 
156   Variants:
157 
158     <gdImageJpegCtx> stores the image using a <gdIOCtx> struct.
159 
160     <gdImageJpegPtr> stores the image to RAM.
161 
162   Parameters:
163 
164     im      - The image to save
165     outFile - The FILE pointer to write to.
166     quality - Compression quality (0-95, 0 means use the default).
167 
168   Returns:
169 
170     Nothing.
171 
172   Example:
173     (start code)
174 
175     gdImagePtr im;
176     int black, white;
177     FILE *out;
178     // Create the image
179     im = gdImageCreate(100, 100);
180     // Allocate background
181     white = gdImageColorAllocate(im, 255, 255, 255);
182     // Allocate drawing color
183     black = gdImageColorAllocate(im, 0, 0, 0);
184     // Draw rectangle
185     gdImageRectangle(im, 0, 0, 99, 99, black);
186     // Open output file in binary mode
187     out = fopen("rect.jpg", "wb");
188     // Write JPEG using default quality
189     gdImageJpeg(im, out, -1);
190     // Close file
191     fclose(out);
192     // Destroy image
193     gdImageDestroy(im);
194 
195     (end code)
196 */
197 
gdImageJpeg(gdImagePtr im,FILE * outFile,int quality)198 BGD_DECLARE(void) gdImageJpeg(gdImagePtr im, FILE *outFile, int quality)
199 {
200 	gdIOCtx *out = gdNewFileCtx(outFile);
201 	if (out == NULL) return;
202 	gdImageJpegCtx(im, out, quality);
203 	out->gd_free(out);
204 }
205 
206 /*
207   Function: gdImageJpegPtr
208 
209     Identical to <gdImageJpeg> except that it returns a pointer to a
210     memory area with the JPEG data. This memory must be freed by the
211     caller when it is no longer needed.
212 
213     The caller *must* invoke <gdFree>, not free().  This is because it
214     is not guaranteed that libgd will use the same implementation of
215     malloc, free, etc. as your proggram.
216 
217     The 'size' parameter receives the total size of the block of
218     memory.
219 
220   Parameters:
221 
222     im      - The image to write
223     size    - Output: the size of the resulting image.
224     quality - Compression quality.
225 
226   Returns:
227 
228     A pointer to the JPEG data or NULL if an error occurred.
229 
230 */
gdImageJpegPtr(gdImagePtr im,int * size,int quality)231 BGD_DECLARE(void *) gdImageJpegPtr(gdImagePtr im, int *size, int quality)
232 {
233 	void *rv;
234 	gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
235 	if (out == NULL) return NULL;
236 	if (!_gdImageJpegCtx(im, out, quality)) {
237 		rv = gdDPExtractData(out, size);
238 	} else {
239 		rv = NULL;
240 	}
241 	out->gd_free(out);
242 	return rv;
243 }
244 
245 void jpeg_gdIOCtx_dest(j_compress_ptr cinfo, gdIOCtx *outfile);
246 
247 /*
248   Function: gdImageJpegCtx
249 
250     Write the image as JPEG data via a <gdIOCtx>. See <gdImageJpeg>
251     for more details.
252 
253   Parameters:
254 
255     im      - The image to write.
256     outfile - The output sink.
257     quality - Image quality.
258 
259 */
gdImageJpegCtx(gdImagePtr im,gdIOCtx * outfile,int quality)260 BGD_DECLARE(void) gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality)
261 {
262 	_gdImageJpegCtx(im, outfile, quality);
263 }
264 
265 /* returns 0 on success, 1 on failure */
_gdImageJpegCtx(gdImagePtr im,gdIOCtx * outfile,int quality)266 static int _gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality)
267 {
268 	struct jpeg_compress_struct cinfo;
269 	struct jpeg_error_mgr jerr;
270 	int i, j, jidx;
271 	/* volatile so we can gdFree it on return from longjmp */
272 	volatile JSAMPROW row = 0;
273 	JSAMPROW rowptr[1];
274 	jmpbuf_wrapper jmpbufw;
275 	JDIMENSION nlines;
276 	char comment[255];
277 
278 #ifdef JPEG_DEBUG
279 	gd_error_ex(GD_DEBUG, "gd-jpeg: gd JPEG version %s\n", GD_JPEG_VERSION);
280 	gd_error_ex(GD_DEBUG, "gd-jpeg: JPEG library version %d, %d-bit sample values\n", JPEG_LIB_VERSION, BITS_IN_JSAMPLE);
281 	if (!im->trueColor) {
282 		for(i = 0; i < im->colorsTotal; i++) {
283 			if(!im->open[i]) {
284 				gd_error_ex(GD_DEBUG, "gd-jpeg: gd colormap index %d: (%d, %d, %d)\n", i, im->red[i], im->green[i], im->blue[i]);
285 			}
286 		}
287 	}
288 #endif /* JPEG_DEBUG */
289 
290 	memset(&cinfo, 0, sizeof(cinfo));
291 	memset(&jerr, 0, sizeof(jerr));
292 
293 	cinfo.err = jpeg_std_error(&jerr);
294 	cinfo.client_data = &jmpbufw;
295 
296 	if(setjmp(jmpbufw.jmpbuf) != 0) {
297 		/* we're here courtesy of longjmp */
298 		if(row) {
299 			gdFree(row);
300 		}
301 		return 1;
302 	}
303 
304 	cinfo.err->emit_message = jpeg_emit_message;
305 	cinfo.err->error_exit = fatal_jpeg_error;
306 
307 	jpeg_create_compress(&cinfo);
308 
309 	cinfo.image_width = im->sx;
310 	cinfo.image_height = im->sy;
311 	cinfo.input_components = 3; /* # of color components per pixel */
312 	cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
313 
314 	jpeg_set_defaults(&cinfo);
315 
316 	cinfo.density_unit = 1;
317 	cinfo.X_density = im->res_x;
318 	cinfo.Y_density = im->res_y;
319 
320 	if(quality >= 0) {
321 		jpeg_set_quality(&cinfo, quality, TRUE);
322 		if (quality >= 90) {
323 			cinfo.comp_info[0].h_samp_factor = 1;
324 			cinfo.comp_info[0].v_samp_factor = 1;
325 		}
326 	}
327 
328 	/* If user requests interlace, translate that to progressive JPEG */
329 	if(gdImageGetInterlaced(im)) {
330 #ifdef JPEG_DEBUG
331 		gd_error_ex(GD_DEBUG, "gd-jpeg: interlace set, outputting progressive JPEG image\n");
332 #endif
333 		jpeg_simple_progression(&cinfo);
334 	}
335 
336 	jpeg_gdIOCtx_dest(&cinfo, outfile);
337 
338 	row = (JSAMPROW)gdCalloc(1, cinfo.image_width * cinfo.input_components * sizeof(JSAMPLE));
339 	if(row == 0) {
340 		gd_error("gd-jpeg: error: unable to allocate JPEG row structure: gdCalloc returns NULL\n");
341 		jpeg_destroy_compress(&cinfo);
342 		return 1;
343 	}
344 
345 	rowptr[0] = row;
346 
347 	jpeg_start_compress(&cinfo, TRUE);
348 
349 	sprintf(comment, "CREATOR: gd-jpeg v%s (using IJG JPEG v%d),", GD_JPEG_VERSION, JPEG_LIB_VERSION);
350 
351 	if(quality >= 0) {
352 		sprintf (comment + strlen(comment), " quality = %d\n", quality);
353 	} else {
354 		strcat(comment + strlen(comment), " default quality\n");
355 	}
356 
357 	jpeg_write_marker(&cinfo, JPEG_COM, (unsigned char *) comment, (unsigned int)strlen(comment));
358 
359 	if(im->trueColor) {
360 #if BITS_IN_JSAMPLE == 12
361 		gd_error(
362 		        "gd-jpeg: error: jpeg library was compiled for 12-bit\n"
363 		        "precision. This is mostly useless, because JPEGs on the web are\n"
364 		        "8-bit and such versions of the jpeg library won't read or write\n"
365 		        "them. GD doesn't support these unusual images. Edit your\n"
366 		        "jmorecfg.h file to specify the correct precision and completely\n"
367 		        "'make clean' and 'make install' libjpeg again. Sorry.\n"
368 		       );
369 		goto error;
370 #endif /* BITS_IN_JSAMPLE == 12 */
371 		for(i = 0; i < im->sy; i++) {
372 			for(jidx = 0, j = 0; j < im->sx; j++) {
373 				int val = im->tpixels[i][j];
374 				row[jidx++] = gdTrueColorGetRed(val);
375 				row[jidx++] = gdTrueColorGetGreen(val);
376 				row[jidx++] = gdTrueColorGetBlue(val);
377 			}
378 
379 			nlines = jpeg_write_scanlines(&cinfo, rowptr, 1);
380 
381 			if(nlines != 1) {
382 				gd_error("gd_jpeg: warning: jpeg_write_scanlines returns %u -- expected 1\n", nlines);
383 			}
384 		}
385 	} else {
386 		for(i = 0; i < im->sy; i++) {
387 			for(jidx = 0, j = 0; j < im->sx; j++) {
388 				int idx = im->pixels[i][j];
389 
390 				/*
391 				 * NB: Although gd RGB values are ints, their max value is
392 				 * 255 (see the documentation for gdImageColorAllocate())
393 				 * -- perfect for 8-bit JPEG encoding (which is the norm)
394 				 */
395 #if BITS_IN_JSAMPLE == 8
396 				row[jidx++] = im->red[idx];
397 				row[jidx++] = im->green[idx];
398 				row[jidx++] = im->blue[idx];
399 #elif BITS_IN_JSAMPLE == 12
400 				row[jidx++] = im->red[idx] << 4;
401 				row[jidx++] = im->green[idx] << 4;
402 				row[jidx++] = im->blue[idx] << 4;
403 #else
404 #error IJG JPEG library BITS_IN_JSAMPLE value must be 8 or 12
405 #endif
406 			}
407 
408 			nlines = jpeg_write_scanlines(&cinfo, rowptr, 1);
409 			if(nlines != 1) {
410 				gd_error("gd_jpeg: warning: jpeg_write_scanlines"
411 				         " returns %u -- expected 1\n", nlines);
412 			}
413 		}
414 	}
415 
416 	jpeg_finish_compress(&cinfo);
417 	jpeg_destroy_compress(&cinfo);
418 	gdFree(row);
419 	return 0;
420 }
421 
422 
423 
424 
425 /*
426   Function: gdImageCreateFromJpeg
427 
428   See <gdImageCreateFromJpegEx>.
429 */
gdImageCreateFromJpeg(FILE * inFile)430 BGD_DECLARE(gdImagePtr) gdImageCreateFromJpeg(FILE *inFile)
431 {
432 	return gdImageCreateFromJpegEx(inFile, 1);
433 }
434 
435 
436 /*
437   Function: gdImageCreateFromJpegEx
438 
439     <gdImageCreateFromJpegEx> is called to load truecolor images from
440     JPEG format files. Invoke <gdImageCreateFromJpegEx> with an
441     already opened pointer to a file containing the desired
442     image. <gdImageCreateFromJpegEx> returns a <gdImagePtr> to the new
443     truecolor image, or NULL if unable to load the image (most often
444     because the file is corrupt or does not contain a JPEG
445     image). <gdImageCreateFromJpegEx> does not close the file.
446 
447     You can inspect the sx and sy members of the image to determine
448     its size. The image must eventually be destroyed using
449     <gdImageDestroy>.
450 
451     *The returned image is always a truecolor image.*
452 
453   Variants:
454 
455     <gdImageCreateFromJpegPtrEx> creates an image from JPEG data
456     already in memory.
457 
458     <gdImageCreateFromJpegCtxEx> reads its data via the function
459     pointers in a <gdIOCtx> structure.
460 
461     <gdImageCreateFromJpeg>, <gdImageCreateFromJpegPtr> and
462     <gdImageCreateFromJpegCtx> are equivalent to calling their
463     _Ex_-named counterparts with an ignore_warning set to 1
464     (i.e. TRUE).
465 
466   Parameters:
467 
468     infile          - The input FILE pointer.
469     ignore_warning  - Flag.  If true, ignores recoverable warnings.
470 
471   Returns:
472 
473     A pointer to the new *truecolor* image.  This will need to be
474     destroyed with <gdImageDestroy> once it is no longer needed.
475 
476     On error, returns NULL.
477 
478   Example:
479     (start code)
480 
481     gdImagePtr im;
482     FILE *in;
483     in = fopen("myjpeg.jpg", "rb");
484     im = gdImageCreateFromJpegEx(in, GD_TRUE);
485     fclose(in);
486     // ... Use the image ...
487     gdImageDestroy(im);
488 
489     (end code)
490 */
gdImageCreateFromJpegEx(FILE * inFile,int ignore_warning)491 BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegEx(FILE *inFile, int ignore_warning)
492 {
493 	gdImagePtr im;
494 	gdIOCtx *in = gdNewFileCtx(inFile);
495 	if (in == NULL) return NULL;
496 	im = gdImageCreateFromJpegCtxEx(in, ignore_warning);
497 	in->gd_free(in);
498 	return im;
499 }
500 
501 /*
502   Function: gdImageCreateFromJpegPtr
503 
504   Parameters:
505 
506     size    - size of JPEG data in bytes.
507     data    - pointer to JPEG data.
508 
509   See <gdImageCreateFromJpegEx>.
510 */
gdImageCreateFromJpegPtr(int size,void * data)511 BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegPtr(int size, void *data)
512 {
513 	return gdImageCreateFromJpegPtrEx(size, data, 1);
514 }
515 
516 /*
517   Function: gdImageCreateFromJpegPtrEx
518 
519   Parameters:
520 
521     size            - size of JPEG data in bytes.
522     data            - pointer to JPEG data.
523     ignore_warning  - if true, ignore recoverable warnings
524 
525   See <gdImageCreateFromJpegEx>.
526 */
gdImageCreateFromJpegPtrEx(int size,void * data,int ignore_warning)527 BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegPtrEx(int size, void *data, int ignore_warning)
528 {
529 	gdImagePtr im;
530 	gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0);
531 	if(!in) {
532 		return 0;
533 	}
534 	im = gdImageCreateFromJpegCtxEx(in, ignore_warning);
535 	in->gd_free(in);
536 	return im;
537 }
538 
539 void jpeg_gdIOCtx_src(j_decompress_ptr cinfo, gdIOCtx *infile);
540 
541 static int CMYKToRGB(int c, int m, int y, int k, int inverted);
542 
543 /*
544   Function: gdImageCreateFromJpegCtx
545 
546   See <gdImageCreateFromJpeg>.
547 */
gdImageCreateFromJpegCtx(gdIOCtx * infile)548 BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegCtx(gdIOCtx *infile)
549 {
550 	return gdImageCreateFromJpegCtxEx(infile, 1);
551 }
552 
553 /*
554   Function: gdImageCreateFromJpegCtxEx
555 
556   See <gdImageCreateFromJpeg>.
557 */
gdImageCreateFromJpegCtxEx(gdIOCtx * infile,int ignore_warning)558 BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegCtxEx(gdIOCtx *infile, int ignore_warning)
559 {
560 	struct jpeg_decompress_struct cinfo;
561 	struct jpeg_error_mgr jerr;
562 	jmpbuf_wrapper jmpbufw;
563 	/* volatile so we can gdFree them after longjmp */
564 	volatile JSAMPROW row = 0;
565 	volatile gdImagePtr im = 0;
566 	JSAMPROW rowptr[1];
567 	JDIMENSION i, j;
568 	int retval;
569 	JDIMENSION nrows;
570 	int channels = 3;
571 	int inverted = 0;
572 
573 #ifdef JPEG_DEBUG
574 	gd_error_ex(GD_DEBUG, "gd-jpeg: gd JPEG version %s\n", GD_JPEG_VERSION);
575 	gd_error_ex(GD_DEBUG, "gd-jpeg: JPEG library version %d, %d-bit sample values\n", JPEG_LIB_VERSION, BITS_IN_JSAMPLE);
576 	gd_error_ex(GD_DEBUG, "sizeof: %d\n", sizeof(struct jpeg_decompress_struct));
577 #endif
578 
579 	memset(&cinfo, 0, sizeof(cinfo));
580 	memset(&jerr, 0, sizeof(jerr));
581 
582 	jmpbufw.ignore_warning = ignore_warning;
583 
584 	cinfo.err = jpeg_std_error(&jerr);
585 	cinfo.client_data = &jmpbufw;
586 
587 	cinfo.err->emit_message = jpeg_emit_message;
588 
589 	if(setjmp(jmpbufw.jmpbuf) != 0) {
590 		/* we're here courtesy of longjmp */
591 		if(row) {
592 			gdFree(row);
593 		}
594 		if(im) {
595 			gdImageDestroy(im);
596 		}
597 		return 0;
598 	}
599 
600 	cinfo.err->error_exit = fatal_jpeg_error;
601 
602 	jpeg_create_decompress(&cinfo);
603 
604 	jpeg_gdIOCtx_src(&cinfo, infile);
605 
606 	/* 2.0.22: save the APP14 marker to check for Adobe Photoshop CMYK
607 	 * files with inverted components.
608 	 */
609 	jpeg_save_markers(&cinfo, JPEG_APP0 + 14, 256);
610 
611 	retval = jpeg_read_header(&cinfo, TRUE);
612 	if(retval != JPEG_HEADER_OK) {
613 		gd_error("gd-jpeg: warning: jpeg_read_header returns"
614 		         " %d, expected %d\n", retval, JPEG_HEADER_OK);
615 	}
616 
617 	if(cinfo.image_height > INT_MAX) {
618 		gd_error("gd-jpeg: warning: JPEG image height (%u) is"
619 		         " greater than INT_MAX (%d) (and thus greater than"
620 		         " gd can handle)", cinfo.image_height, INT_MAX);
621 	}
622 
623 	if(cinfo.image_width > INT_MAX) {
624 		gd_error("gd-jpeg: warning: JPEG image width (%u) is"
625 		         " greater than INT_MAX (%d) (and thus greater than"
626 		         " gd can handle)\n", cinfo.image_width, INT_MAX);
627 	}
628 
629 	im = gdImageCreateTrueColor((int)cinfo.image_width, (int)cinfo.image_height);
630 	if(im == 0) {
631 		gd_error("gd-jpeg error: cannot allocate gdImage struct\n");
632 		goto error;
633 	}
634 
635 	/* check if the resolution is specified */
636 	switch (cinfo.density_unit) {
637 	case 1:
638 		im->res_x = cinfo.X_density;
639 		im->res_y = cinfo.Y_density;
640 		break;
641 	case 2:
642 		im->res_x = DPCM2DPI(cinfo.X_density);
643 		im->res_y = DPCM2DPI(cinfo.Y_density);
644 		break;
645 	}
646 
647 	/* 2.0.22: very basic support for reading CMYK colorspace files. Nice for
648 	 * thumbnails but there's no support for fussy adjustment of the
649 	 * assumed properties of inks and paper.
650 	 */
651 	if((cinfo.jpeg_color_space == JCS_CMYK) || (cinfo.jpeg_color_space == JCS_YCCK)) {
652 		cinfo.out_color_space = JCS_CMYK;
653 	} else {
654 		cinfo.out_color_space = JCS_RGB;
655 	}
656 
657 	if(jpeg_start_decompress(&cinfo) != TRUE) {
658 		gd_error("gd-jpeg: warning: jpeg_start_decompress"
659 		        " reports suspended data source\n");
660 	}
661 
662 #ifdef JPEG_DEBUG
663 	gd_error_ex(GD_DEBUG, "gd-jpeg: JPEG image information:");
664 	if(cinfo.saw_JFIF_marker) {
665 		gd_error_ex(GD_DEBUG, " JFIF version %d.%.2d", (int)cinfo.JFIF_major_version, (int)cinfo.JFIF_minor_version);
666 	} else if(cinfo.saw_Adobe_marker) {
667 		gd_error_ex(GD_DEBUG, " Adobe format");
668 	} else {
669 		gd_error_ex(GD_DEBUG, " UNKNOWN format");
670 	}
671 
672 	gd_error_ex(GD_DEBUG, " %ux%u (raw) / %ux%u (scaled) %d-bit", cinfo.image_width,
673 		    cinfo.image_height, cinfo.output_width,
674 		    cinfo.output_height, cinfo.data_precision
675 		);
676 	gd_error_ex(GD_DEBUG, " %s", (cinfo.progressive_mode ? "progressive" : "baseline"));
677 	gd_error_ex(GD_DEBUG, " image, %d quantized colors, ", cinfo.actual_number_of_colors);
678 
679 	switch(cinfo.jpeg_color_space) {
680 	case JCS_GRAYSCALE:
681 		gd_error_ex(GD_DEBUG, "grayscale");
682 		break;
683 
684 	case JCS_RGB:
685 		gd_error_ex(GD_DEBUG, "RGB");
686 		break;
687 
688 	case JCS_YCbCr:
689 		gd_error_ex(GD_DEBUG, "YCbCr (a.k.a. YUV)");
690 		break;
691 
692 	case JCS_CMYK:
693 		gd_error_ex(GD_DEBUG, "CMYK");
694 		break;
695 
696 	case JCS_YCCK:
697 		gd_error_ex(GD_DEBUG, "YCbCrK");
698 		break;
699 
700 	default:
701 		gd_error_ex(GD_DEBUG, "UNKNOWN (value: %d)", (int)cinfo.jpeg_color_space);
702 		break;
703 	}
704 
705 	gd_error_ex(GD_DEBUG, " colorspace\n");
706 	fflush(stdout);
707 #endif /* JPEG_DEBUG */
708 
709 	/* REMOVED by TBB 2/12/01. This field of the structure is
710 	 * documented as private, and sure enough it's gone in the
711 	 * latest libjpeg, replaced by something else. Unfortunately
712 	 * there is still no right way to find out if the file was
713 	 * progressive or not; just declare your intent before you
714 	 * write one by calling gdImageInterlace(im, 1) yourself.
715 	 * After all, we're not really supposed to rework JPEGs and
716 	 * write them out again anyway. Lossy compression, remember? */
717 #if 0
718 	gdImageInterlace (im, cinfo.progressive_mode != 0);
719 #endif
720 	if(cinfo.out_color_space == JCS_RGB) {
721 		if(cinfo.output_components != 3) {
722 			gd_error("gd-jpeg: error: JPEG color quantization"
723 			         " request resulted in output_components == %d"
724 			         " (expected 3 for RGB)\n", cinfo.output_components);
725 			goto error;
726 		}
727 		channels = 3;
728 	} else if(cinfo.out_color_space == JCS_CMYK) {
729 		jpeg_saved_marker_ptr marker;
730 		if(cinfo.output_components != 4) {
731 			gd_error("gd-jpeg: error: JPEG color quantization"
732 			         " request resulted in output_components == %d"
733 			         " (expected 4 for CMYK)\n", cinfo.output_components);
734 			goto error;
735 		}
736 		channels = 4;
737 
738 		marker = cinfo.marker_list;
739 		while(marker) {
740 			if(	(marker->marker == (JPEG_APP0 + 14)) &&
741 			        (marker->data_length >= 12) &&
742 			        (!strncmp((const char *)marker->data, "Adobe", 5))) {
743 				inverted = 1;
744 				break;
745 			}
746 			marker = marker->next;
747 		}
748 	} else {
749 		gd_error("gd-jpeg: error: unexpected colorspace\n");
750 		goto error;
751 	}
752 #if BITS_IN_JSAMPLE == 12
753 	gd_error_ex(GD_ERROR,
754 		    "gd-jpeg: error: jpeg library was compiled for 12-bit\n"
755 		    "precision. This is mostly useless, because JPEGs on the web are\n"
756 		    "8-bit and such versions of the jpeg library won't read or write\n"
757 		    "them. GD doesn't support these unusual images. Edit your\n"
758 		    "jmorecfg.h file to specify the correct precision and completely\n"
759 		    "'make clean' and 'make install' libjpeg again. Sorry.\n");
760 	goto error;
761 #endif /* BITS_IN_JSAMPLE == 12 */
762 
763 	row = gdCalloc(cinfo.output_width *channels, sizeof(JSAMPLE));
764 	if(row == 0) {
765 		gd_error("gd-jpeg: error: unable to allocate row for"
766 		         " JPEG scanline: gdCalloc returns NULL\n");
767 		goto error;
768 	}
769 	rowptr[0] = row;
770 	if(cinfo.out_color_space == JCS_CMYK) {
771 		for(i = 0; i < cinfo.output_height; i++) {
772 			register JSAMPROW currow = row;
773 			register int *tpix = im->tpixels[i];
774 			nrows = jpeg_read_scanlines(&cinfo, rowptr, 1);
775 			if(nrows != 1) {
776 				gd_error("gd-jpeg: error: jpeg_read_scanlines"
777 				         " returns %u, expected 1\n", nrows);
778 				goto error;
779 			}
780 			for(j = 0; j < cinfo.output_width; j++, currow += 4, tpix++) {
781 				*tpix = CMYKToRGB(currow[0], currow[1], currow[2], currow[3], inverted);
782 			}
783 		}
784 	} else {
785 		for(i = 0; i < cinfo.output_height; i++) {
786 			register JSAMPROW currow = row;
787 			register int *tpix = im->tpixels[i];
788 			nrows = jpeg_read_scanlines(&cinfo, rowptr, 1);
789 			if(nrows != 1) {
790 				gd_error("gd-jpeg: error: jpeg_read_scanlines"
791 				         " returns %u, expected 1\n", nrows);
792 				goto error;
793 			}
794 			for(j = 0; j < cinfo.output_width; j++, currow += 3, tpix++) {
795 				*tpix = gdTrueColor(currow[0], currow[1], currow[2]);
796 			}
797 		}
798 	}
799 
800 	if(jpeg_finish_decompress (&cinfo) != TRUE) {
801 		gd_error("gd-jpeg: warning: jpeg_finish_decompress"
802 		         " reports suspended data source\n");
803 	}
804 	/* TBB 2.0.29: we should do our best to read whatever we can read, and a
805 	 * warning is a warning. A fatal error on warnings doesn't make sense. */
806 #if 0
807 	/* This was originally added by Truxton Fulton */
808 	if (cinfo.err->num_warnings > 0)
809 		goto error;
810 #endif
811 
812 	jpeg_destroy_decompress(&cinfo);
813 	gdFree(row);
814 	return im;
815 
816 error:
817 	jpeg_destroy_decompress(&cinfo);
818 
819 	if(row) {
820 		gdFree(row);
821 	}
822 	if(im) {
823 		gdImageDestroy(im);
824 	}
825 
826 	return 0;
827 }
828 
829 /* A very basic conversion approach, TBB */
830 
CMYKToRGB(int c,int m,int y,int k,int inverted)831 static int CMYKToRGB(int c, int m, int y, int k, int inverted)
832 {
833 	if(inverted) {
834 		c = 255 - c;
835 		m = 255 - m;
836 		y = 255 - y;
837 		k = 255 - k;
838 	}
839 
840 	return gdTrueColor(
841 	           (255 - c) * (255 - k) / 255,
842 	           (255 - m) * (255 - k) / 255,
843 	           (255 - y) * (255 - k) / 255
844 	       );
845 #if 0
846 	if (inverted) {
847 		c = 255 - c;
848 		m = 255 - m;
849 		y = 255 - y;
850 		k = 255 - k;
851 	}
852 	c = c * (255 - k) / 255 + k;
853 	if (c > 255) {
854 		c = 255;
855 	}
856 	if (c < 0) {
857 		c = 0;
858 	}
859 	m = m * (255 - k) / 255 + k;
860 	if (m > 255) {
861 		m = 255;
862 	}
863 	if (m < 0) {
864 		m = 0;
865 	}
866 	y = y * (255 - k) / 255 + k;
867 	if (y > 255) {
868 		y = 255;
869 	}
870 	if (y < 0) {
871 		y = 0;
872 	}
873 	c = 255 - c;
874 	m = 255 - m;
875 	y = 255 - y;
876 	return gdTrueColor (c, m, y);
877 #endif
878 }
879 
880 /*
881  * gdIOCtx JPEG data sources and sinks, T. Boutell
882  * almost a simple global replace from T. Lane's stdio versions.
883  */
884 
885 /* Expanded data source object for gdIOCtx input */
886 typedef struct {
887 	struct jpeg_source_mgr pub;	/* public fields */
888 	gdIOCtx *infile;			/* source stream */
889 	unsigned char *buffer;		/* start of buffer */
890 	boolean start_of_file;	/* have we gotten any data yet? */
891 }
892 my_source_mgr;
893 
894 typedef my_source_mgr *my_src_ptr;
895 
896 #define INPUT_BUF_SIZE	4096 /* choose an efficiently fread'able size */
897 
898 /*
899  * Initialize source --- called by jpeg_read_header
900  * before any data is actually read.
901  */
902 
init_source(j_decompress_ptr cinfo)903 void init_source(j_decompress_ptr cinfo)
904 {
905 	my_src_ptr src = (my_src_ptr)cinfo->src;
906 
907 	/* We reset the empty-input-file flag for each image,
908 	 * but we don't clear the input buffer.
909 	 * This is correct behavior for reading a series of images from one source.
910 	 */
911 	src->start_of_file = TRUE;
912 }
913 
914 
915 /*
916  * Fill the input buffer --- called whenever buffer is emptied.
917  *
918  * In typical applications, this should read fresh data into the buffer
919  * (ignoring the current state of next_input_byte & bytes_in_buffer),
920  * reset the pointer & count to the start of the buffer, and return TRUE
921  * indicating that the buffer has been reloaded.  It is not necessary to
922  * fill the buffer entirely, only to obtain at least one more byte.
923  *
924  * There is no such thing as an EOF return.  If the end of the file has been
925  * reached, the routine has a choice of ERREXIT() or inserting fake data into
926  * the buffer.  In most cases, generating a warning message and inserting a
927  * fake EOI marker is the best course of action --- this will allow the
928  * decompressor to output however much of the image is there.  However,
929  * the resulting error message is misleading if the real problem is an empty
930  * input file, so we handle that case specially.
931  *
932  * In applications that need to be able to suspend compression due to input
933  * not being available yet, a FALSE return indicates that no more data can be
934  * obtained right now, but more may be forthcoming later.  In this situation,
935  * the decompressor will return to its caller (with an indication of the
936  * number of scanlines it has read, if any).  The application should resume
937  * decompression after it has loaded more data into the input buffer.  Note
938  * that there are substantial restrictions on the use of suspension --- see
939  * the documentation.
940  *
941  * When suspending, the decompressor will back up to a convenient restart point
942  * (typically the start of the current MCU). next_input_byte & bytes_in_buffer
943  * indicate where the restart point will be if the current call returns FALSE.
944  * Data beyond this point must be rescanned after resumption, so move it to
945  * the front of the buffer rather than discarding it.
946  */
947 
948 #define END_JPEG_SEQUENCE "\r\n[*]--:END JPEG:--[*]\r\n"
949 
fill_input_buffer(j_decompress_ptr cinfo)950 boolean fill_input_buffer(j_decompress_ptr cinfo)
951 {
952 	my_src_ptr src = (my_src_ptr)cinfo->src;
953 	/* 2.0.12: signed size. Thanks to Geert Jansen */
954 	/* 2.0.14: some platforms (mingw-msys) don't have ssize_t. Call
955 	 * an int an int.
956 	 */
957 	int nbytes = 0;
958 	memset(src->buffer, 0, INPUT_BUF_SIZE);
959 
960 	while(nbytes < INPUT_BUF_SIZE) {
961 		int got = gdGetBuf(src->buffer + nbytes, INPUT_BUF_SIZE - nbytes, src->infile);
962 
963 		if((got == EOF) || (got == 0)) {
964 			/* EOF or error. If we got any data, don't worry about it.
965 			 * If we didn't, then this is unexpected. */
966 			if(!nbytes) {
967 				nbytes = -1;
968 			}
969 			break;
970 		}
971 		nbytes += got;
972 	}
973 
974 	if(nbytes <= 0) {
975 		if(src->start_of_file) {
976 			/* Treat empty input file as fatal error */
977 			ERREXIT(cinfo, JERR_INPUT_EMPTY);
978 		}
979 		WARNMS(cinfo, JWRN_JPEG_EOF);
980 		/* Insert a fake EOI marker */
981 		src->buffer[0] = (unsigned char)0xFF;
982 		src->buffer[1] = (unsigned char)JPEG_EOI;
983 		nbytes = 2;
984 	}
985 
986 	src->pub.next_input_byte = src->buffer;
987 	src->pub.bytes_in_buffer = nbytes;
988 	src->start_of_file = FALSE;
989 
990 	return TRUE;
991 }
992 
993 /*
994  * Skip data --- used to skip over a potentially large amount of
995  * uninteresting data (such as an APPn marker).
996  *
997  * Writers of suspendable-input applications must note that skip_input_data
998  * is not granted the right to give a suspension return.  If the skip extends
999  * beyond the data currently in the buffer, the buffer can be marked empty so
1000  * that the next read will cause a fill_input_buffer call that can suspend.
1001  * Arranging for additional bytes to be discarded before reloading the input
1002  * buffer is the application writer's problem.
1003  */
1004 
skip_input_data(j_decompress_ptr cinfo,long num_bytes)1005 void skip_input_data(j_decompress_ptr cinfo, long num_bytes)
1006 {
1007 	my_src_ptr src = (my_src_ptr)cinfo->src;
1008 
1009 	/* Just a dumb implementation for now. Not clear that being smart is worth
1010 	 * any trouble anyway --- large skips are infrequent.
1011 	 */
1012 	if(num_bytes > 0) {
1013 		while(num_bytes > (long)src->pub.bytes_in_buffer) {
1014 			num_bytes -= (long)src->pub.bytes_in_buffer;
1015 			(void)fill_input_buffer(cinfo);
1016 			/* note we assume that fill_input_buffer will never return FALSE,
1017 			 * so suspension need not be handled.
1018 			 */
1019 		}
1020 		src->pub.next_input_byte += (size_t)num_bytes;
1021 		src->pub.bytes_in_buffer -= (size_t)num_bytes;
1022 	}
1023 }
1024 
1025 /*
1026  * An additional method that can be provided by data source modules is the
1027  * resync_to_restart method for error recovery in the presence of RST markers.
1028  * For the moment, this source module just uses the default resync method
1029  * provided by the JPEG library.  That method assumes that no backtracking
1030  * is possible.
1031  */
1032 
1033 /*
1034  * Terminate source --- called by jpeg_finish_decompress
1035  * after all data has been read.  Often a no-op.
1036  *
1037  * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
1038  * application must deal with any cleanup that should happen even
1039  * for error exit.
1040  */
term_source(j_decompress_ptr cinfo)1041 void term_source(j_decompress_ptr cinfo)
1042 {
1043 	(void)cinfo;
1044 }
1045 
1046 
1047 /*
1048  * Prepare for input from a gdIOCtx stream.
1049  * The caller must have already opened the stream, and is responsible
1050  * for closing it after finishing decompression.
1051  */
1052 
jpeg_gdIOCtx_src(j_decompress_ptr cinfo,gdIOCtx * infile)1053 void jpeg_gdIOCtx_src(j_decompress_ptr cinfo, gdIOCtx *infile)
1054 {
1055 	my_src_ptr src;
1056 
1057 	/* The source object and input buffer are made permanent so that a series
1058 	 * of JPEG images can be read from the same file by calling jpeg_gdIOCtx_src
1059 	 * only before the first one.  (If we discarded the buffer at the end of
1060 	 * one image, we'd likely lose the start of the next one.)
1061 	 * This makes it unsafe to use this manager and a different source
1062 	 * manager serially with the same JPEG object.  Caveat programmer.
1063 	 */
1064 	if(cinfo->src == NULL) {
1065 		/* first time for this JPEG object? */
1066 		cinfo->src = (struct jpeg_source_mgr *)
1067 		             (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_PERMANENT,
1068 		                                        sizeof(my_source_mgr));
1069 		src = (my_src_ptr)cinfo->src;
1070 		src->buffer = (unsigned char *)
1071 		              (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_PERMANENT,
1072 		                      INPUT_BUF_SIZE * sizeof(unsigned char));
1073 	}
1074 
1075 	src = (my_src_ptr)cinfo->src;
1076 	src->pub.init_source = init_source;
1077 	src->pub.fill_input_buffer = fill_input_buffer;
1078 	src->pub.skip_input_data = skip_input_data;
1079 	src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
1080 	src->pub.term_source = term_source;
1081 	src->infile = infile;
1082 	src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
1083 	src->pub.next_input_byte = NULL; /* until buffer loaded */
1084 }
1085 
1086 /* Expanded data destination object for stdio output */
1087 typedef struct {
1088 	struct jpeg_destination_mgr pub; /* public fields */
1089 	gdIOCtx *outfile; /* target stream */
1090 	unsigned char *buffer; /* start of buffer */
1091 }
1092 my_destination_mgr;
1093 
1094 typedef my_destination_mgr *my_dest_ptr;
1095 
1096 #define OUTPUT_BUF_SIZE	4096 /* choose an efficiently fwrite'able size */
1097 
1098 /*
1099  * Initialize destination --- called by jpeg_start_compress
1100  * before any data is actually written.
1101  */
1102 
init_destination(j_compress_ptr cinfo)1103 void init_destination(j_compress_ptr cinfo)
1104 {
1105 	my_dest_ptr dest = (my_dest_ptr)cinfo->dest;
1106 
1107 	/* Allocate the output buffer --- it will be released when done with image */
1108 	dest->buffer = (unsigned char *)
1109 	               (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_IMAGE,
1110 	                       OUTPUT_BUF_SIZE * sizeof(unsigned char));
1111 
1112 	dest->pub.next_output_byte = dest->buffer;
1113 	dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
1114 }
1115 
1116 
1117 /*
1118  * Empty the output buffer --- called whenever buffer fills up.
1119  *
1120  * In typical applications, this should write the entire output buffer
1121  * (ignoring the current state of next_output_byte & free_in_buffer),
1122  * reset the pointer & count to the start of the buffer, and return TRUE
1123  * indicating that the buffer has been dumped.
1124  *
1125  * In applications that need to be able to suspend compression due to output
1126  * overrun, a FALSE return indicates that the buffer cannot be emptied now.
1127  * In this situation, the compressor will return to its caller (possibly with
1128  * an indication that it has not accepted all the supplied scanlines).  The
1129  * application should resume compression after it has made more room in the
1130  * output buffer.  Note that there are substantial restrictions on the use of
1131  * suspension --- see the documentation.
1132  *
1133  * When suspending, the compressor will back up to a convenient restart point
1134  * (typically the start of the current MCU). next_output_byte & free_in_buffer
1135  * indicate where the restart point will be if the current call returns FALSE.
1136  * Data beyond this point will be regenerated after resumption, so do not
1137  * write it out when emptying the buffer externally.
1138  */
1139 
empty_output_buffer(j_compress_ptr cinfo)1140 boolean empty_output_buffer(j_compress_ptr cinfo)
1141 {
1142 	my_dest_ptr dest = (my_dest_ptr)cinfo->dest;
1143 
1144 	if(gdPutBuf(dest->buffer, OUTPUT_BUF_SIZE, dest->outfile) != (size_t)OUTPUT_BUF_SIZE) {
1145 		ERREXIT(cinfo, JERR_FILE_WRITE);
1146 	}
1147 
1148 	dest->pub.next_output_byte = dest->buffer;
1149 	dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
1150 
1151 	return TRUE;
1152 }
1153 
1154 
1155 /*
1156  * Terminate destination --- called by jpeg_finish_compress
1157  * after all data has been written.  Usually needs to flush buffer.
1158  *
1159  * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
1160  * application must deal with any cleanup that should happen even
1161  * for error exit.
1162  */
1163 
term_destination(j_compress_ptr cinfo)1164 void term_destination(j_compress_ptr cinfo)
1165 {
1166 	my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
1167 	int datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
1168 
1169 	/* Write any data remaining in the buffer */
1170 	if(datacount > 0) {
1171 		if(gdPutBuf(dest->buffer, datacount, dest->outfile) != datacount) {
1172 			ERREXIT(cinfo, JERR_FILE_WRITE);
1173 		}
1174 	}
1175 }
1176 
1177 /*
1178  * Prepare for output to a stdio stream.
1179  * The caller must have already opened the stream, and is responsible
1180  * for closing it after finishing compression.
1181  */
1182 
jpeg_gdIOCtx_dest(j_compress_ptr cinfo,gdIOCtx * outfile)1183 void jpeg_gdIOCtx_dest(j_compress_ptr cinfo, gdIOCtx *outfile)
1184 {
1185 	my_dest_ptr dest;
1186 
1187 	/* The destination object is made permanent so that multiple JPEG images
1188 	 * can be written to the same file without re-executing jpeg_stdio_dest.
1189 	 * This makes it dangerous to use this manager and a different destination
1190 	 * manager serially with the same JPEG object, because their private object
1191 	 * sizes may be different.  Caveat programmer.
1192 	 */
1193 	if(cinfo->dest == NULL) {
1194 		/* first time for this JPEG object? */
1195 		cinfo->dest = (struct jpeg_destination_mgr *)
1196 		              (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_PERMANENT,
1197 		                      sizeof(my_destination_mgr));
1198 	}
1199 
1200 	dest = (my_dest_ptr)cinfo->dest;
1201 	dest->pub.init_destination = init_destination;
1202 	dest->pub.empty_output_buffer = empty_output_buffer;
1203 	dest->pub.term_destination = term_destination;
1204 	dest->outfile = outfile;
1205 }
1206 
1207 #else /* !HAVE_LIBJPEG */
1208 
_noJpegError(void)1209 static void _noJpegError(void)
1210 {
1211 	gd_error("JPEG image support has been disabled\n");
1212 }
1213 
gdImageJpeg(gdImagePtr im,FILE * outFile,int quality)1214 BGD_DECLARE(void) gdImageJpeg(gdImagePtr im, FILE *outFile, int quality)
1215 {
1216 	_noJpegError();
1217 }
1218 
gdImageJpegPtr(gdImagePtr im,int * size,int quality)1219 BGD_DECLARE(void *) gdImageJpegPtr(gdImagePtr im, int *size, int quality)
1220 {
1221 	_noJpegError();
1222 	return NULL;
1223 }
1224 
gdImageJpegCtx(gdImagePtr im,gdIOCtx * outfile,int quality)1225 BGD_DECLARE(void) gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality)
1226 {
1227 	_noJpegError();
1228 }
1229 
gdImageCreateFromJpeg(FILE * inFile)1230 BGD_DECLARE(gdImagePtr) gdImageCreateFromJpeg(FILE *inFile)
1231 {
1232 	_noJpegError();
1233 	return NULL;
1234 }
1235 
gdImageCreateFromJpegEx(FILE * inFile,int ignore_warning)1236 BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegEx(FILE *inFile, int ignore_warning)
1237 {
1238 	_noJpegError();
1239 	return NULL;
1240 }
1241 
gdImageCreateFromJpegPtr(int size,void * data)1242 BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegPtr(int size, void *data)
1243 {
1244 	_noJpegError();
1245 	return NULL;
1246 }
1247 
gdImageCreateFromJpegPtrEx(int size,void * data,int ignore_warning)1248 BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegPtrEx(int size, void *data, int ignore_warning)
1249 {
1250 	_noJpegError();
1251 	return NULL;
1252 }
1253 
gdImageCreateFromJpegCtx(gdIOCtx * infile)1254 BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegCtx(gdIOCtx *infile)
1255 {
1256 	_noJpegError();
1257 	return NULL;
1258 }
1259 
gdImageCreateFromJpegCtxEx(gdIOCtx * infile,int ignore_warning)1260 BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegCtxEx(gdIOCtx *infile, int ignore_warning)
1261 {
1262 	_noJpegError();
1263 	return NULL;
1264 }
1265 
1266 #endif /* HAVE_LIBJPEG */
1267