diff options
author | mattias <none@none> | 2007-12-21 21:21:16 +0000 |
---|---|---|
committer | mattias <none@none> | 2007-12-21 21:21:16 +0000 |
commit | 929d0df306929449d2519fa9785e50ab0c96518e (patch) | |
tree | 89b03fd215523a642483b2cd2e533126b093e21c /src/gd_jpeg.c | |
parent | 233501964edcff55728ad0191c11f3ab808d8383 (diff) | |
download | libgd-929d0df306929449d2519fa9785e50ab0c96518e.tar.gz |
- ws + cs
Diffstat (limited to 'src/gd_jpeg.c')
-rw-r--r-- | src/gd_jpeg.c | 1150 |
1 files changed, 549 insertions, 601 deletions
diff --git a/src/gd_jpeg.c b/src/gd_jpeg.c index 33eb826..f4bcbd1 100644 --- a/src/gd_jpeg.c +++ b/src/gd_jpeg.c @@ -22,7 +22,7 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +# include "config.h" #endif #include <stdio.h> @@ -51,37 +51,31 @@ static const char *const GD_JPEG_VERSION = "1.0"; typedef struct _jmpbuf_wrapper { - jmp_buf jmpbuf; + jmp_buf jmpbuf; } jmpbuf_wrapper; /* Called by the IJG JPEG library upon encountering a fatal error */ -static void -fatal_jpeg_error (j_common_ptr cinfo) +static void fatal_jpeg_error(j_common_ptr cinfo) { - jmpbuf_wrapper *jmpbufw; + jmpbuf_wrapper *jmpbufw; - fprintf (stderr, "gd-jpeg: JPEG library reports unrecoverable error: "); - (*cinfo->err->output_message) (cinfo); - fflush (stderr); + fprintf(stderr, "gd-jpeg: JPEG library reports unrecoverable error: "); + (*cinfo->err->output_message)(cinfo); + fflush(stderr); - jmpbufw = (jmpbuf_wrapper *) cinfo->client_data; - jpeg_destroy (cinfo); + jmpbufw = (jmpbuf_wrapper *)cinfo->client_data; + jpeg_destroy(cinfo); - if (jmpbufw != 0) - { - longjmp (jmpbufw->jmpbuf, 1); - fprintf (stderr, "gd-jpeg: EXTREMELY fatal error: longjmp" - " returned control; terminating\n"); - } - else - { - fprintf (stderr, "gd-jpeg: EXTREMELY fatal error: jmpbuf" - " unrecoverable; terminating\n"); - } + if(jmpbufw != 0) { + longjmp(jmpbufw->jmpbuf, 1); + fprintf(stderr, "gd-jpeg: EXTREMELY fatal error: longjmp returned control; terminating\n"); + } else { + fprintf(stderr, "gd-jpeg: EXTREMELY fatal error: jmpbuf unrecoverable; terminating\n"); + } - fflush (stderr); - exit (99); + fflush(stderr); + exit(99); } /* @@ -90,483 +84,471 @@ fatal_jpeg_error (j_common_ptr cinfo) * represent higher quality but also larger image size. If QUALITY is * negative, the IJG JPEG library's default quality is used (which * should be near optimal for many applications). See the IJG JPEG - * library documentation for more details. */ + * library documentation for more details. + */ -BGD_DECLARE(void) gdImageJpeg (gdImagePtr im, FILE * outFile, int quality) +BGD_DECLARE(void) gdImageJpeg(gdImagePtr im, FILE *outFile, int quality) { - gdIOCtx *out = gdNewFileCtx (outFile); - gdImageJpegCtx (im, out, quality); - out->gd_free (out); + gdIOCtx *out = gdNewFileCtx(outFile); + gdImageJpegCtx(im, out, quality); + out->gd_free(out); } -BGD_DECLARE(void *) gdImageJpegPtr (gdImagePtr im, int *size, int quality) +BGD_DECLARE(void *) gdImageJpegPtr(gdImagePtr im, int *size, int quality) { - void *rv; - gdIOCtx *out = gdNewDynamicCtx (2048, NULL); - gdImageJpegCtx (im, out, quality); - rv = gdDPExtractData (out, size); - out->gd_free (out); - return rv; + void *rv; + gdIOCtx *out = gdNewDynamicCtx(2048, NULL); + gdImageJpegCtx(im, out, quality); + rv = gdDPExtractData(out, size); + out->gd_free(out); + return rv; } -void jpeg_gdIOCtx_dest (j_compress_ptr cinfo, gdIOCtx * outfile); +void jpeg_gdIOCtx_dest(j_compress_ptr cinfo, gdIOCtx *outfile); -BGD_DECLARE(void) gdImageJpegCtx (gdImagePtr im, gdIOCtx * outfile, int quality) +BGD_DECLARE(void) gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality) { - struct jpeg_compress_struct cinfo; - struct jpeg_error_mgr jerr; - int i, j, jidx; - /* volatile so we can gdFree it on return from longjmp */ - volatile JSAMPROW row = 0; - JSAMPROW rowptr[1]; - jmpbuf_wrapper jmpbufw; - JDIMENSION nlines; - char comment[255]; + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + int i, j, jidx; + /* volatile so we can gdFree it on return from longjmp */ + volatile JSAMPROW row = 0; + JSAMPROW rowptr[1]; + jmpbuf_wrapper jmpbufw; + JDIMENSION nlines; + char comment[255]; #ifdef JPEG_DEBUG - printf ("gd-jpeg: gd JPEG version %s\n", GD_JPEG_VERSION); - printf ("gd-jpeg: JPEG library version %d, %d-bit sample values\n", - JPEG_LIB_VERSION, BITS_IN_JSAMPLE); - if (!im->trueColor) - { - for (i = 0; i < im->colorsTotal; i++) - { - if (!im->open[i]) - printf ("gd-jpeg: gd colormap index %d: (%d, %d, %d)\n", i, - im->red[i], im->green[i], im->blue[i]); + printf("gd-jpeg: gd JPEG version %s\n", GD_JPEG_VERSION); + printf("gd-jpeg: JPEG library version %d, %d-bit sample values\n", JPEG_LIB_VERSION, BITS_IN_JSAMPLE); + if (!im->trueColor) { + for(i = 0; i < im->colorsTotal; i++) { + if(!im->open[i]) { + printf ("gd-jpeg: gd colormap index %d: (%d, %d, %d)\n", i, im->red[i], im->green[i], im->blue[i]); + } + } } - } #endif /* JPEG_DEBUG */ - memset (&cinfo, 0, sizeof (cinfo)); - memset (&jerr, 0, sizeof (jerr)); + memset(&cinfo, 0, sizeof(cinfo)); + memset(&jerr, 0, sizeof(jerr)); - cinfo.err = jpeg_std_error (&jerr); - cinfo.client_data = &jmpbufw; - if (setjmp (jmpbufw.jmpbuf) != 0) - { - /* we're here courtesy of longjmp */ - if (row) - gdFree (row); - return; - } + cinfo.err = jpeg_std_error(&jerr); + cinfo.client_data = &jmpbufw; - cinfo.err->error_exit = fatal_jpeg_error; + if(setjmp(jmpbufw.jmpbuf) != 0) { + /* we're here courtesy of longjmp */ + if(row) { + gdFree(row); + } + return; + } - jpeg_create_compress (&cinfo); + cinfo.err->error_exit = fatal_jpeg_error; - cinfo.image_width = im->sx; - cinfo.image_height = im->sy; - cinfo.input_components = 3; /* # of color components per pixel */ - cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ - jpeg_set_defaults (&cinfo); - if (quality >= 0) - jpeg_set_quality (&cinfo, quality, TRUE); + jpeg_create_compress(&cinfo); - /* If user requests interlace, translate that to progressive JPEG */ - if (gdImageGetInterlaced (im)) - { + cinfo.image_width = im->sx; + cinfo.image_height = im->sy; + cinfo.input_components = 3; /* # of color components per pixel */ + cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ + + jpeg_set_defaults(&cinfo); + + if(quality >= 0) { + jpeg_set_quality(&cinfo, quality, TRUE); + } + + /* If user requests interlace, translate that to progressive JPEG */ + if(gdImageGetInterlaced(im)) { #ifdef JPEG_DEBUG - printf ("gd-jpeg: interlace set, outputting progressive" - " JPEG image\n"); + printf("gd-jpeg: interlace set, outputting progressive JPEG image\n"); #endif - jpeg_simple_progression (&cinfo); - } + jpeg_simple_progression(&cinfo); + } - jpeg_gdIOCtx_dest (&cinfo, outfile); + jpeg_gdIOCtx_dest(&cinfo, outfile); - row = (JSAMPROW) gdCalloc (1, cinfo.image_width * cinfo.input_components - * sizeof (JSAMPLE)); - if (row == 0) - { - fprintf (stderr, "gd-jpeg: error: unable to allocate JPEG row " - "structure: gdCalloc returns NULL\n"); - jpeg_destroy_compress (&cinfo); - return; - } + row = (JSAMPROW)gdCalloc(1, cinfo.image_width * cinfo.input_components * sizeof(JSAMPLE)); + if(row == 0) { + fprintf (stderr, "gd-jpeg: error: unable to allocate JPEG row structure: gdCalloc returns NULL\n"); + jpeg_destroy_compress(&cinfo); + return; + } - rowptr[0] = row; + rowptr[0] = row; - jpeg_start_compress (&cinfo, TRUE); + jpeg_start_compress(&cinfo, TRUE); - sprintf (comment, "CREATOR: gd-jpeg v%s (using IJG JPEG v%d),", - GD_JPEG_VERSION, JPEG_LIB_VERSION); - if (quality >= 0) - sprintf (comment + strlen (comment), " quality = %d\n", quality); - else - strcat (comment + strlen (comment), " default quality\n"); - jpeg_write_marker (&cinfo, JPEG_COM, (unsigned char *) comment, - (unsigned int) strlen (comment)); - if (im->trueColor) - { + sprintf(comment, "CREATOR: gd-jpeg v%s (using IJG JPEG v%d),", GD_JPEG_VERSION, JPEG_LIB_VERSION); + + if(quality >= 0) { + sprintf (comment + strlen(comment), " quality = %d\n", quality); + } else { + strcat(comment + strlen(comment), " default quality\n"); + } + + jpeg_write_marker(&cinfo, JPEG_COM, (unsigned char *) comment, (unsigned int)strlen(comment)); + + if(im->trueColor) { #if BITS_IN_JSAMPLE == 12 - fprintf (stderr, - "gd-jpeg: error: jpeg library was compiled for 12-bit\n" - "precision. This is mostly useless, because JPEGs on the web are\n" - "8-bit and such versions of the jpeg library won't read or write\n" - "them. GD doesn't support these unusual images. Edit your\n" - "jmorecfg.h file to specify the correct precision and completely\n" - "'make clean' and 'make install' libjpeg again. Sorry.\n"); - goto error; + fprintf(stderr, + "gd-jpeg: error: jpeg library was compiled for 12-bit\n" + "precision. This is mostly useless, because JPEGs on the web are\n" + "8-bit and such versions of the jpeg library won't read or write\n" + "them. GD doesn't support these unusual images. Edit your\n" + "jmorecfg.h file to specify the correct precision and completely\n" + "'make clean' and 'make install' libjpeg again. Sorry.\n" + ); + goto error; #endif /* BITS_IN_JSAMPLE == 12 */ - for (i = 0; i < im->sy; i++) - { - for (jidx = 0, j = 0; j < im->sx; j++) - { - int val = im->tpixels[i][j]; - row[jidx++] = gdTrueColorGetRed (val); - row[jidx++] = gdTrueColorGetGreen (val); - row[jidx++] = gdTrueColorGetBlue (val); - } - - nlines = jpeg_write_scanlines (&cinfo, rowptr, 1); - if (nlines != 1) - fprintf (stderr, "gd_jpeg: warning: jpeg_write_scanlines" - " returns %u -- expected 1\n", nlines); - } - } - else - { - for (i = 0; i < im->sy; i++) - { - for (jidx = 0, j = 0; j < im->sx; j++) - { - int idx = im->pixels[i][j]; - - /* - * NB: Although gd RGB values are ints, their max value is - * 255 (see the documentation for gdImageColorAllocate()) - * -- perfect for 8-bit JPEG encoding (which is the norm) - */ + for(i = 0; i < im->sy; i++) { + for(jidx = 0, j = 0; j < im->sx; j++) { + int val = im->tpixels[i][j]; + row[jidx++] = gdTrueColorGetRed(val); + row[jidx++] = gdTrueColorGetGreen(val); + row[jidx++] = gdTrueColorGetBlue(val); + } + + nlines = jpeg_write_scanlines(&cinfo, rowptr, 1); + + if(nlines != 1) { + fprintf (stderr, "gd_jpeg: warning: jpeg_write_scanlines returns %u -- expected 1\n", nlines); + } + } + } else { + for(i = 0; i < im->sy; i++) { + for(jidx = 0, j = 0; j < im->sx; j++) { + int idx = im->pixels[i][j]; + + /* + * NB: Although gd RGB values are ints, their max value is + * 255 (see the documentation for gdImageColorAllocate()) + * -- perfect for 8-bit JPEG encoding (which is the norm) + */ #if BITS_IN_JSAMPLE == 8 - row[jidx++] = im->red[idx]; - row[jidx++] = im->green[idx]; - row[jidx++] = im->blue[idx]; + row[jidx++] = im->red[idx]; + row[jidx++] = im->green[idx]; + row[jidx++] = im->blue[idx]; #elif BITS_IN_JSAMPLE == 12 - row[jidx++] = im->red[idx] << 4; - row[jidx++] = im->green[idx] << 4; - row[jidx++] = im->blue[idx] << 4; + row[jidx++] = im->red[idx] << 4; + row[jidx++] = im->green[idx] << 4; + row[jidx++] = im->blue[idx] << 4; #else #error IJG JPEG library BITS_IN_JSAMPLE value must be 8 or 12 #endif - } - - nlines = jpeg_write_scanlines (&cinfo, rowptr, 1); - if (nlines != 1) - fprintf (stderr, "gd_jpeg: warning: jpeg_write_scanlines" - " returns %u -- expected 1\n", nlines); + } + + nlines = jpeg_write_scanlines(&cinfo, rowptr, 1); + if(nlines != 1) { + fprintf (stderr, "gd_jpeg: warning: jpeg_write_scanlines" + " returns %u -- expected 1\n", nlines); + } + } } - } - jpeg_finish_compress (&cinfo); - jpeg_destroy_compress (&cinfo); - gdFree (row); + + jpeg_finish_compress(&cinfo); + jpeg_destroy_compress(&cinfo); + gdFree(row); } -BGD_DECLARE(gdImagePtr) gdImageCreateFromJpeg (FILE * inFile) +BGD_DECLARE(gdImagePtr) gdImageCreateFromJpeg(FILE *inFile) { - gdImagePtr im; - gdIOCtx *in = gdNewFileCtx (inFile); - im = gdImageCreateFromJpegCtx (in); - in->gd_free (in); - return im; + gdImagePtr im; + gdIOCtx *in = gdNewFileCtx(inFile); + im = gdImageCreateFromJpegCtx(in); + in->gd_free(in); + return im; } -BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegPtr (int size, void *data) +BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegPtr(int size, void *data) { - gdImagePtr im; - gdIOCtx *in = gdNewDynamicCtxEx (size, data, 0); - if(!in) - return 0; - im = gdImageCreateFromJpegCtx (in); - in->gd_free (in); - return im; + gdImagePtr im; + gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0); + if(!in) { + return 0; + } + im = gdImageCreateFromJpegCtx(in); + in->gd_free(in); + return im; } -void jpeg_gdIOCtx_src (j_decompress_ptr cinfo, gdIOCtx * infile); +void jpeg_gdIOCtx_src(j_decompress_ptr cinfo, gdIOCtx *infile); -static int CMYKToRGB (int c, int m, int y, int k, int inverted); +static int CMYKToRGB(int c, int m, int y, int k, int inverted); /* * Create a gd-format image from the JPEG-format INFILE. Returns the * image, or NULL upon error. */ -BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegCtx (gdIOCtx * infile) +BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegCtx(gdIOCtx *infile) { - struct jpeg_decompress_struct cinfo; - struct jpeg_error_mgr jerr; - jmpbuf_wrapper jmpbufw; - /* volatile so we can gdFree them after longjmp */ - volatile JSAMPROW row = 0; - volatile gdImagePtr im = 0; - JSAMPROW rowptr[1]; - int i, j, retval; - JDIMENSION nrows; - int channels = 3; - int inverted = 0; + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + jmpbuf_wrapper jmpbufw; + /* volatile so we can gdFree them after longjmp */ + volatile JSAMPROW row = 0; + volatile gdImagePtr im = 0; + JSAMPROW rowptr[1]; + int i, j, retval; + JDIMENSION nrows; + int channels = 3; + int inverted = 0; + #ifdef JPEG_DEBUG - printf ("gd-jpeg: gd JPEG version %s\n", GD_JPEG_VERSION); - printf ("gd-jpeg: JPEG library version %d, %d-bit sample values\n", - JPEG_LIB_VERSION, BITS_IN_JSAMPLE); + printf("gd-jpeg: gd JPEG version %s\n", GD_JPEG_VERSION); + printf("gd-jpeg: JPEG library version %d, %d-bit sample values\n", JPEG_LIB_VERSION, BITS_IN_JSAMPLE); #endif - memset (&cinfo, 0, sizeof (cinfo)); - memset (&jerr, 0, sizeof (jerr)); + memset(&cinfo, 0, sizeof(cinfo)); + memset(&jerr, 0, sizeof(jerr)); + + cinfo.err = jpeg_std_error(&jerr); + cinfo.client_data = &jmpbufw; + + if(setjmp(jmpbufw.jmpbuf) != 0) { + /* we're here courtesy of longjmp */ + if(row) { + gdFree(row); + } + if(im) { + gdImageDestroy(im); + } + return 0; + } - cinfo.err = jpeg_std_error (&jerr); - cinfo.client_data = &jmpbufw; - if (setjmp (jmpbufw.jmpbuf) != 0) - { - /* we're here courtesy of longjmp */ - if (row) - gdFree (row); - if (im) - gdImageDestroy (im); - return 0; - } + cinfo.err->error_exit = fatal_jpeg_error; - cinfo.err->error_exit = fatal_jpeg_error; + jpeg_create_decompress(&cinfo); - jpeg_create_decompress (&cinfo); + jpeg_gdIOCtx_src(&cinfo, infile); - jpeg_gdIOCtx_src (&cinfo, infile); + /* 2.0.22: save the APP14 marker to check for Adobe Photoshop CMYK + * files with inverted components. + */ + jpeg_save_markers(&cinfo, JPEG_APP0 + 14, 256); - /* 2.0.22: save the APP14 marker to check for Adobe Photoshop CMYK - files with inverted components. */ - jpeg_save_markers (&cinfo, JPEG_APP0 + 14, 256); + retval = jpeg_read_header(&cinfo, TRUE); + if(retval != JPEG_HEADER_OK) { + fprintf (stderr, "gd-jpeg: warning: jpeg_read_header returns" + " %d, expected %d\n", retval, JPEG_HEADER_OK); + } - retval = jpeg_read_header (&cinfo, TRUE); - if (retval != JPEG_HEADER_OK) - fprintf (stderr, "gd-jpeg: warning: jpeg_read_header returns" - " %d, expected %d\n", retval, JPEG_HEADER_OK); + if(cinfo.image_height > INT_MAX) { + fprintf (stderr, "gd-jpeg: warning: JPEG image height (%u) is" + " greater than INT_MAX (%d) (and thus greater than" + " gd can handle)", cinfo.image_height, INT_MAX); + } - if (cinfo.image_height > INT_MAX) - fprintf (stderr, "gd-jpeg: warning: JPEG image height (%u) is" - " greater than INT_MAX (%d) (and thus greater than" - " gd can handle)", cinfo.image_height, INT_MAX); + if(cinfo.image_width > INT_MAX) { + fprintf (stderr, "gd-jpeg: warning: JPEG image width (%u) is" + " greater than INT_MAX (%d) (and thus greater than" + " gd can handle)\n", cinfo.image_width, INT_MAX); + } - if (cinfo.image_width > INT_MAX) - fprintf (stderr, "gd-jpeg: warning: JPEG image width (%u) is" - " greater than INT_MAX (%d) (and thus greater than" - " gd can handle)\n", cinfo.image_width, INT_MAX); + im = gdImageCreateTrueColor((int)cinfo.image_width, (int)cinfo.image_height); + if(im == 0) { + fprintf (stderr, "gd-jpeg error: cannot allocate gdImage struct\n"); + goto error; + } - im = gdImageCreateTrueColor ((int) cinfo.image_width, - (int) cinfo.image_height); - if (im == 0) - { - fprintf (stderr, "gd-jpeg error: cannot allocate gdImage" " struct\n"); - goto error; - } - /* 2.0.22: very basic support for reading CMYK colorspace files. Nice for - thumbnails but there's no support for fussy adjustment of the - assumed properties of inks and paper. */ - if ((cinfo.jpeg_color_space == JCS_CMYK) || - (cinfo.jpeg_color_space == JCS_YCCK)) - { - cinfo.out_color_space = JCS_CMYK; - } - else - { - cinfo.out_color_space = JCS_RGB; - } + /* 2.0.22: very basic support for reading CMYK colorspace files. Nice for + * thumbnails but there's no support for fussy adjustment of the + * assumed properties of inks and paper. + */ + if((cinfo.jpeg_color_space == JCS_CMYK) || (cinfo.jpeg_color_space == JCS_YCCK)) { + cinfo.out_color_space = JCS_CMYK; + } else { + cinfo.out_color_space = JCS_RGB; + } - if (jpeg_start_decompress (&cinfo) != TRUE) - fprintf (stderr, "gd-jpeg: warning: jpeg_start_decompress" - " reports suspended data source\n"); + if(jpeg_start_decompress(&cinfo) != TRUE) { + fprintf(stderr, "gd-jpeg: warning: jpeg_start_decompress" + " reports suspended data source\n"); + } #ifdef JPEG_DEBUG - printf ("gd-jpeg: JPEG image information:"); - if (cinfo.saw_JFIF_marker) - printf (" JFIF version %d.%.2d", - (int) cinfo.JFIF_major_version, (int) cinfo.JFIF_minor_version); - else if (cinfo.saw_Adobe_marker) - printf (" Adobe format"); - else - printf (" UNKNOWN format"); - - printf (" %ux%u (raw) / %ux%u (scaled) %d-bit", cinfo.image_width, - cinfo.image_height, cinfo.output_width, - cinfo.output_height, cinfo.data_precision); - printf (" %s", (cinfo.progressive_mode ? "progressive" : "baseline")); - printf (" image, %d quantized colors, ", cinfo.actual_number_of_colors); - - switch (cinfo.jpeg_color_space) - { - case JCS_GRAYSCALE: - printf ("grayscale"); - break; - - case JCS_RGB: - printf ("RGB"); - break; - - case JCS_YCbCr: - printf ("YCbCr (a.k.a. YUV)"); - break; - - case JCS_CMYK: - printf ("CMYK"); - break; + printf("gd-jpeg: JPEG image information:"); + if(cinfo.saw_JFIF_marker) { + printf(" JFIF version %d.%.2d", (int)cinfo.JFIF_major_version, (int)cinfo.JFIF_minor_version); + } else if(cinfo.saw_Adobe_marker) { + printf(" Adobe format"); + } else { + printf(" UNKNOWN format"); + } - case JCS_YCCK: - printf ("YCbCrK"); - break; + printf(" %ux%u (raw) / %ux%u (scaled) %d-bit", cinfo.image_width, + cinfo.image_height, cinfo.output_width, + cinfo.output_height, cinfo.data_precision + ); + printf(" %s", (cinfo.progressive_mode ? "progressive" : "baseline")); + printf(" image, %d quantized colors, ", cinfo.actual_number_of_colors); + + switch(cinfo.jpeg_color_space) { + case JCS_GRAYSCALE: + printf("grayscale"); + break; + + case JCS_RGB: + printf("RGB"); + break; + + case JCS_YCbCr: + printf("YCbCr (a.k.a. YUV)"); + break; + + case JCS_CMYK: + printf("CMYK"); + break; + + case JCS_YCCK: + printf("YCbCrK"); + break; + + default: + printf("UNKNOWN (value: %d)", (int)cinfo.jpeg_color_space); + break; + } - default: - printf ("UNKNOWN (value: %d)", (int) cinfo.jpeg_color_space); - break; - } - printf (" colorspace\n"); - fflush (stdout); + printf(" colorspace\n"); + fflush(stdout); #endif /* JPEG_DEBUG */ - /* REMOVED by TBB 2/12/01. This field of the structure is - documented as private, and sure enough it's gone in the - latest libjpeg, replaced by something else. Unfortunately - there is still no right way to find out if the file was - progressive or not; just declare your intent before you - write one by calling gdImageInterlace(im, 1) yourself. - After all, we're not really supposed to rework JPEGs and - write them out again anyway. Lossy compression, remember? */ + /* REMOVED by TBB 2/12/01. This field of the structure is + * documented as private, and sure enough it's gone in the + * latest libjpeg, replaced by something else. Unfortunately + * there is still no right way to find out if the file was + * progressive or not; just declare your intent before you + * write one by calling gdImageInterlace(im, 1) yourself. + * After all, we're not really supposed to rework JPEGs and + * write them out again anyway. Lossy compression, remember? */ #if 0 - gdImageInterlace (im, cinfo.progressive_mode != 0); + gdImageInterlace (im, cinfo.progressive_mode != 0); #endif - if (cinfo.out_color_space == JCS_RGB) - { - if (cinfo.output_components != 3) - { - fprintf (stderr, "gd-jpeg: error: JPEG color quantization" - " request resulted in output_components == %d" - " (expected 3 for RGB)\n", cinfo.output_components); - goto error; - } - channels = 3; - } - else if (cinfo.out_color_space == JCS_CMYK) - { - jpeg_saved_marker_ptr marker; - if (cinfo.output_components != 4) - { - fprintf (stderr, "gd-jpeg: error: JPEG color quantization" - " request resulted in output_components == %d" - " (expected 4 for CMYK)\n", cinfo.output_components); - goto error; - } - channels = 4; - marker = cinfo.marker_list; - while (marker) - { - if ((marker->marker == (JPEG_APP0 + 14)) && - (marker->data_length >= 12) - && (!strncmp ((const char *) marker->data, "Adobe", 5))) - { - inverted = 1; - break; - } - marker = marker->next; + if(cinfo.out_color_space == JCS_RGB) { + if(cinfo.output_components != 3) { + fprintf (stderr, "gd-jpeg: error: JPEG color quantization" + " request resulted in output_components == %d" + " (expected 3 for RGB)\n", cinfo.output_components); + goto error; + } + channels = 3; + } else if(cinfo.out_color_space == JCS_CMYK) { + jpeg_saved_marker_ptr marker; + if(cinfo.output_components != 4) { + fprintf (stderr, "gd-jpeg: error: JPEG color quantization" + " request resulted in output_components == %d" + " (expected 4 for CMYK)\n", cinfo.output_components); + goto error; + } + channels = 4; + + marker = cinfo.marker_list; + while(marker) { + if( (marker->marker == (JPEG_APP0 + 14)) && + (marker->data_length >= 12) && + (!strncmp((const char *)marker->data, "Adobe", 5))) { + inverted = 1; + break; + } + marker = marker->next; + } + } else { + fprintf(stderr, "gd-jpeg: error: unexpected colorspace\n"); + goto error; } - } - else - { - fprintf (stderr, "gd-jpeg: error: unexpected colorspace\n"); - goto error; - } #if BITS_IN_JSAMPLE == 12 - fprintf (stderr, "gd-jpeg: error: jpeg library was compiled for 12-bit\n" - "precision. This is mostly useless, because JPEGs on the web are\n" - "8-bit and such versions of the jpeg library won't read or write\n" - "them. GD doesn't support these unusual images. Edit your\n" - "jmorecfg.h file to specify the correct precision and completely\n" - "'make clean' and 'make install' libjpeg again. Sorry.\n"); - goto error; + fprintf(stderr, "gd-jpeg: error: jpeg library was compiled for 12-bit\n" + "precision. This is mostly useless, because JPEGs on the web are\n" + "8-bit and such versions of the jpeg library won't read or write\n" + "them. GD doesn't support these unusual images. Edit your\n" + "jmorecfg.h file to specify the correct precision and completely\n" + "'make clean' and 'make install' libjpeg again. Sorry.\n"); + goto error; #endif /* BITS_IN_JSAMPLE == 12 */ - row = gdCalloc (cinfo.output_width * channels, sizeof (JSAMPLE)); - if (row == 0) - { - fprintf (stderr, "gd-jpeg: error: unable to allocate row for" - " JPEG scanline: gdCalloc returns NULL\n"); - goto error; - } - rowptr[0] = row; - if (cinfo.out_color_space == JCS_CMYK) - { - for (i = 0; i < cinfo.output_height; i++) - { - register JSAMPROW currow = row; - register int *tpix = im->tpixels[i]; - nrows = jpeg_read_scanlines (&cinfo, rowptr, 1); - if (nrows != 1) - { - fprintf (stderr, "gd-jpeg: error: jpeg_read_scanlines" - " returns %u, expected 1\n", nrows); - goto error; - } - for (j = 0; j < cinfo.output_width; j++, currow += 4, tpix++) - { - *tpix = - CMYKToRGB (currow[0], currow[1], currow[2], currow[3], - inverted); - } + row = gdCalloc(cinfo.output_width *channels, sizeof(JSAMPLE)); + if(row == 0) { + fprintf (stderr, "gd-jpeg: error: unable to allocate row for" + " JPEG scanline: gdCalloc returns NULL\n"); + goto error; } - } - else - { - for (i = 0; i < cinfo.output_height; i++) - { - register JSAMPROW currow = row; - register int *tpix = im->tpixels[i]; - nrows = jpeg_read_scanlines (&cinfo, rowptr, 1); - if (nrows != 1) - { - fprintf (stderr, "gd-jpeg: error: jpeg_read_scanlines" - " returns %u, expected 1\n", nrows); - goto error; - } - for (j = 0; j < cinfo.output_width; j++, currow += 3, tpix++) - { - *tpix = gdTrueColor (currow[0], currow[1], currow[2]); - } + rowptr[0] = row; + if(cinfo.out_color_space == JCS_CMYK) { + for(i = 0; i < cinfo.output_height; i++) { + register JSAMPROW currow = row; + register int *tpix = im->tpixels[i]; + nrows = jpeg_read_scanlines(&cinfo, rowptr, 1); + if(nrows != 1) { + fprintf (stderr, "gd-jpeg: error: jpeg_read_scanlines" + " returns %u, expected 1\n", nrows); + goto error; + } + for(j = 0; j < cinfo.output_width; j++, currow += 4, tpix++) { + *tpix = CMYKToRGB(currow[0], currow[1], currow[2], currow[3], inverted); + } + } + } else { + for(i = 0; i < cinfo.output_height; i++) { + register JSAMPROW currow = row; + register int *tpix = im->tpixels[i]; + nrows = jpeg_read_scanlines(&cinfo, rowptr, 1); + if(nrows != 1) { + fprintf (stderr, "gd-jpeg: error: jpeg_read_scanlines" + " returns %u, expected 1\n", nrows); + goto error; + } + for(j = 0; j < cinfo.output_width; j++, currow += 3, tpix++) { + *tpix = gdTrueColor(currow[0], currow[1], currow[2]); + } + } } - } - if (jpeg_finish_decompress (&cinfo) != TRUE) - fprintf (stderr, "gd-jpeg: warning: jpeg_finish_decompress" - " reports suspended data source\n"); - /* TBB 2.0.29: we should do our best to read whatever we can read, and a - warning is a warning. A fatal error on warnings doesn't make sense. */ + + if(jpeg_finish_decompress (&cinfo) != TRUE) { + fprintf(stderr, "gd-jpeg: warning: jpeg_finish_decompress" + " reports suspended data source\n"); + } + /* TBB 2.0.29: we should do our best to read whatever we can read, and a + * warning is a warning. A fatal error on warnings doesn't make sense. */ #if 0 /* This was originally added by Truxton Fulton */ if (cinfo.err->num_warnings > 0) goto error; #endif - jpeg_destroy_decompress (&cinfo); - gdFree (row); - return im; + jpeg_destroy_decompress(&cinfo); + gdFree(row); + return im; error: - jpeg_destroy_decompress (&cinfo); - if (row) - gdFree (row); - if (im) - gdImageDestroy (im); - return 0; + jpeg_destroy_decompress(&cinfo); + + if(row) { + gdFree(row); + } + if(im) { + gdImageDestroy(im); + } + + return 0; } /* A very basic conversion approach, TBB */ -static int -CMYKToRGB (int c, int m, int y, int k, int inverted) +static int CMYKToRGB(int c, int m, int y, int k, int inverted) { - if (inverted) - { - c = 255 - c; - m = 255 - m; - y = 255 - y; - k = 255 - k; - } - return gdTrueColor ((255 - c) * (255 - k) / 255, - (255 - m) * (255 - k) / 255, - (255 - y) * (255 - k) / 255); + if(inverted) { + c = 255 - c; + m = 255 - m; + y = 255 - y; + k = 255 - k; + } + + return gdTrueColor( + (255 - c) * (255 - k) / 255, + (255 - m) * (255 - k) / 255, + (255 - y) * (255 - k) / 255 + ); #if 0 if (inverted) { @@ -610,57 +592,52 @@ CMYKToRGB (int c, int m, int y, int k, int inverted) } /* - * gdIOCtx JPEG data sources and sinks, T. Boutell * almost a simple global replace from T. Lane's stdio versions. - * */ /* Different versions of libjpeg use either 'jboolean' or 'boolean', and - some platforms define 'boolean', and so forth. Deal with this - madness by typedeffing 'safeboolean' to 'boolean' if HAVE_BOOLEAN - is already set, because this is the test that libjpeg uses. - Otherwise, typedef it to int, because that's what libjpeg does - if HAVE_BOOLEAN is not defined. -TBB */ + * some platforms define 'boolean', and so forth. Deal with this + * madness by typedeffing 'safeboolean' to 'boolean' if HAVE_BOOLEAN + * is already set, because this is the test that libjpeg uses. + * Otherwise, typedef it to int, because that's what libjpeg does + * if HAVE_BOOLEAN is not defined. -TBB + */ #ifdef HAVE_BOOLEAN -typedef boolean safeboolean; + typedef boolean safeboolean; #else -typedef int safeboolean; + typedef int safeboolean; #endif /* HAVE_BOOLEAN */ /* Expanded data source object for gdIOCtx input */ - typedef struct { - struct jpeg_source_mgr pub; /* public fields */ - - gdIOCtx *infile; /* source stream */ - unsigned char *buffer; /* start of buffer */ - safeboolean start_of_file; /* have we gotten any data yet? */ - + struct jpeg_source_mgr pub; /* public fields */ + gdIOCtx *infile; /* source stream */ + unsigned char *buffer; /* start of buffer */ + safeboolean start_of_file; /* have we gotten any data yet? */ } my_source_mgr; typedef my_source_mgr *my_src_ptr; -#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ +#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ /* * Initialize source --- called by jpeg_read_header * before any data is actually read. */ -void -init_source (j_decompress_ptr cinfo) +void init_source(j_decompress_ptr cinfo) { - my_src_ptr src = (my_src_ptr) cinfo->src; + my_src_ptr src = (my_src_ptr)cinfo->src; - /* We reset the empty-input-file flag for each image, - * but we don't clear the input buffer. - * This is correct behavior for reading a series of images from one source. - */ - src->start_of_file = TRUE; + /* We reset the empty-input-file flag for each image, + * but we don't clear the input buffer. + * This is correct behavior for reading a series of images from one source. + */ + src->start_of_file = TRUE; } @@ -698,62 +675,50 @@ init_source (j_decompress_ptr cinfo) */ #define END_JPEG_SEQUENCE "\r\n[*]--:END JPEG:--[*]\r\n" -safeboolean -fill_input_buffer (j_decompress_ptr cinfo) -{ - my_src_ptr src = (my_src_ptr) cinfo->src; - /* 2.0.12: signed size. Thanks to Geert Jansen */ - /* 2.0.14: some platforms (mingw-msys) don't have ssize_t. Call - an int an int. */ - int nbytes = 0; - memset (src->buffer, 0, INPUT_BUF_SIZE); - - while (nbytes < INPUT_BUF_SIZE) - { - - int got = gdGetBuf (src->buffer + nbytes, - INPUT_BUF_SIZE - nbytes, - src->infile); - - if ((got == EOF) || (got == 0)) - { - - /* EOF or error. If we got any data, don't worry about it. - If we didn't, then this is unexpected. */ - if (!nbytes) - { - - nbytes = -1; - - } - - break; +safeboolean fill_input_buffer(j_decompress_ptr cinfo) +{ + my_src_ptr src = (my_src_ptr)cinfo->src; + /* 2.0.12: signed size. Thanks to Geert Jansen */ + /* 2.0.14: some platforms (mingw-msys) don't have ssize_t. Call + * an int an int. + */ + int nbytes = 0; + memset(src->buffer, 0, INPUT_BUF_SIZE); + + while(nbytes < INPUT_BUF_SIZE) { + int got = gdGetBuf(src->buffer + nbytes, INPUT_BUF_SIZE - nbytes, src->infile); + + if((got == EOF) || (got == 0)) { + /* EOF or error. If we got any data, don't worry about it. + * If we didn't, then this is unexpected. */ + if(!nbytes) { + nbytes = -1; + } + break; + } + nbytes += got; } - nbytes += got; - - } - - if (nbytes <= 0) - { - if (src->start_of_file) /* Treat empty input file as fatal error */ - ERREXIT (cinfo, JERR_INPUT_EMPTY); - WARNMS (cinfo, JWRN_JPEG_EOF); - /* Insert a fake EOI marker */ - src->buffer[0] = (unsigned char) 0xFF; - src->buffer[1] = (unsigned char) JPEG_EOI; - nbytes = 2; - } + if(nbytes <= 0) { + if(src->start_of_file) { + /* Treat empty input file as fatal error */ + ERREXIT(cinfo, JERR_INPUT_EMPTY); + } + WARNMS(cinfo, JWRN_JPEG_EOF); + /* Insert a fake EOI marker */ + src->buffer[0] = (unsigned char)0xFF; + src->buffer[1] = (unsigned char)JPEG_EOI; + nbytes = 2; + } - src->pub.next_input_byte = src->buffer; - src->pub.bytes_in_buffer = nbytes; - src->start_of_file = FALSE; + src->pub.next_input_byte = src->buffer; + src->pub.bytes_in_buffer = nbytes; + src->start_of_file = FALSE; - return TRUE; + return TRUE; } - /* * Skip data --- used to skip over a potentially large amount of * uninteresting data (such as an APPn marker). @@ -766,30 +731,26 @@ fill_input_buffer (j_decompress_ptr cinfo) * buffer is the application writer's problem. */ -void -skip_input_data (j_decompress_ptr cinfo, long num_bytes) +void skip_input_data(j_decompress_ptr cinfo, long num_bytes) { - my_src_ptr src = (my_src_ptr) cinfo->src; - - /* Just a dumb implementation for now. Not clear that being smart is worth - * any trouble anyway --- large skips are infrequent. - */ - if (num_bytes > 0) - { - while (num_bytes > (long) src->pub.bytes_in_buffer) - { - num_bytes -= (long) src->pub.bytes_in_buffer; - (void) fill_input_buffer (cinfo); - /* note we assume that fill_input_buffer will never return FALSE, - * so suspension need not be handled. - */ - } - src->pub.next_input_byte += (size_t) num_bytes; - src->pub.bytes_in_buffer -= (size_t) num_bytes; - } + my_src_ptr src = (my_src_ptr)cinfo->src; + + /* Just a dumb implementation for now. Not clear that being smart is worth + * any trouble anyway --- large skips are infrequent. + */ + if(num_bytes > 0) { + while(num_bytes > (long)src->pub.bytes_in_buffer) { + num_bytes -= (long)src->pub.bytes_in_buffer; + (void)fill_input_buffer(cinfo); + /* note we assume that fill_input_buffer will never return FALSE, + * so suspension need not be handled. + */ + } + src->pub.next_input_byte += (size_t)num_bytes; + src->pub.bytes_in_buffer -= (size_t)num_bytes; + } } - /* * An additional method that can be provided by data source modules is the * resync_to_restart method for error recovery in the presence of RST markers. @@ -798,7 +759,6 @@ skip_input_data (j_decompress_ptr cinfo, long num_bytes) * is possible. */ - /* * Terminate source --- called by jpeg_finish_decompress * after all data has been read. Often a no-op. @@ -807,15 +767,11 @@ skip_input_data (j_decompress_ptr cinfo, long num_bytes) * application must deal with any cleanup that should happen even * for error exit. */ - -void -term_source (j_decompress_ptr cinfo) +void term_source(j_decompress_ptr cinfo) { - #if 0 -/* never used */ - my_src_ptr src = (my_src_ptr) cinfo->src; - + /* never used */ + my_src_ptr src = (my_src_ptr) cinfo->src; #endif } @@ -826,72 +782,68 @@ term_source (j_decompress_ptr cinfo) * for closing it after finishing decompression. */ -void -jpeg_gdIOCtx_src (j_decompress_ptr cinfo, gdIOCtx * infile) +void jpeg_gdIOCtx_src(j_decompress_ptr cinfo, gdIOCtx *infile) { - my_src_ptr src; - - /* The source object and input buffer are made permanent so that a series - * of JPEG images can be read from the same file by calling jpeg_gdIOCtx_src - * only before the first one. (If we discarded the buffer at the end of - * one image, we'd likely lose the start of the next one.) - * This makes it unsafe to use this manager and a different source - * manager serially with the same JPEG object. Caveat programmer. - */ - if (cinfo->src == NULL) - { /* first time for this JPEG object? */ - cinfo->src = (struct jpeg_source_mgr *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - sizeof (my_source_mgr)); - src = (my_src_ptr) cinfo->src; - src->buffer = (unsigned char *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - INPUT_BUF_SIZE * sizeof (unsigned char)); - - } + my_src_ptr src; + + /* The source object and input buffer are made permanent so that a series + * of JPEG images can be read from the same file by calling jpeg_gdIOCtx_src + * only before the first one. (If we discarded the buffer at the end of + * one image, we'd likely lose the start of the next one.) + * This makes it unsafe to use this manager and a different source + * manager serially with the same JPEG object. Caveat programmer. + */ + if(cinfo->src == NULL) { + /* first time for this JPEG object? */ + cinfo->src = (struct jpeg_source_mgr *) + (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_PERMANENT, + sizeof(my_source_mgr)); + src = (my_src_ptr)cinfo->src; + src->buffer = (unsigned char *) + (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_PERMANENT, + INPUT_BUF_SIZE * sizeof(unsigned char)); + } - src = (my_src_ptr) cinfo->src; - src->pub.init_source = init_source; - src->pub.fill_input_buffer = fill_input_buffer; - src->pub.skip_input_data = skip_input_data; - src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ - src->pub.term_source = term_source; - src->infile = infile; - src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ - src->pub.next_input_byte = NULL; /* until buffer loaded */ + src = (my_src_ptr)cinfo->src; + src->pub.init_source = init_source; + src->pub.fill_input_buffer = fill_input_buffer; + src->pub.skip_input_data = skip_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ + src->pub.term_source = term_source; + src->infile = infile; + src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ + src->pub.next_input_byte = NULL; /* until buffer loaded */ } /* Expanded data destination object for stdio output */ - typedef struct { - struct jpeg_destination_mgr pub; /* public fields */ - gdIOCtx *outfile; /* target stream */ - unsigned char *buffer; /* start of buffer */ + struct jpeg_destination_mgr pub; /* public fields */ + gdIOCtx *outfile; /* target stream */ + unsigned char *buffer; /* start of buffer */ } my_destination_mgr; typedef my_destination_mgr *my_dest_ptr; -#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */ +#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */ /* * Initialize destination --- called by jpeg_start_compress * before any data is actually written. */ -void -init_destination (j_compress_ptr cinfo) +void init_destination(j_compress_ptr cinfo) { - my_dest_ptr dest = (my_dest_ptr) cinfo->dest; + my_dest_ptr dest = (my_dest_ptr)cinfo->dest; - /* Allocate the output buffer --- it will be released when done with image */ - dest->buffer = (unsigned char *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - OUTPUT_BUF_SIZE * sizeof (unsigned char)); + /* Allocate the output buffer --- it will be released when done with image */ + dest->buffer = (unsigned char *) + (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_IMAGE, + OUTPUT_BUF_SIZE * sizeof(unsigned char)); - dest->pub.next_output_byte = dest->buffer; - dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; } @@ -918,19 +870,18 @@ init_destination (j_compress_ptr cinfo) * write it out when emptying the buffer externally. */ -safeboolean -empty_output_buffer (j_compress_ptr cinfo) +safeboolean empty_output_buffer(j_compress_ptr cinfo) { - my_dest_ptr dest = (my_dest_ptr) cinfo->dest; + my_dest_ptr dest = (my_dest_ptr)cinfo->dest; - if (gdPutBuf (dest->buffer, OUTPUT_BUF_SIZE, dest->outfile) != - (size_t) OUTPUT_BUF_SIZE) - ERREXIT (cinfo, JERR_FILE_WRITE); + if(gdPutBuf(dest->buffer, OUTPUT_BUF_SIZE, dest->outfile) != (size_t)OUTPUT_BUF_SIZE) { + ERREXIT(cinfo, JERR_FILE_WRITE); + } - dest->pub.next_output_byte = dest->buffer; - dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; - return TRUE; + return TRUE; } @@ -943,50 +894,47 @@ empty_output_buffer (j_compress_ptr cinfo) * for error exit. */ -void -term_destination (j_compress_ptr cinfo) +void term_destination(j_compress_ptr cinfo) { - my_dest_ptr dest = (my_dest_ptr) cinfo->dest; - size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; - - /* Write any data remaining in the buffer */ - if (datacount > 0) - { - if (gdPutBuf (dest->buffer, datacount, dest->outfile) != datacount) - ERREXIT (cinfo, JERR_FILE_WRITE); - } + my_dest_ptr dest = (my_dest_ptr) cinfo->dest; + size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; + + /* Write any data remaining in the buffer */ + if(datacount > 0) { + if(gdPutBuf(dest->buffer, datacount, dest->outfile) != datacount) { + ERREXIT(cinfo, JERR_FILE_WRITE); + } + } } - /* * Prepare for output to a stdio stream. * The caller must have already opened the stream, and is responsible * for closing it after finishing compression. */ -void -jpeg_gdIOCtx_dest (j_compress_ptr cinfo, gdIOCtx * outfile) +void jpeg_gdIOCtx_dest(j_compress_ptr cinfo, gdIOCtx *outfile) { - my_dest_ptr dest; - - /* The destination object is made permanent so that multiple JPEG images - * can be written to the same file without re-executing jpeg_stdio_dest. - * This makes it dangerous to use this manager and a different destination - * manager serially with the same JPEG object, because their private object - * sizes may be different. Caveat programmer. - */ - if (cinfo->dest == NULL) - { /* first time for this JPEG object? */ - cinfo->dest = (struct jpeg_destination_mgr *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - sizeof (my_destination_mgr)); - } + my_dest_ptr dest; + + /* The destination object is made permanent so that multiple JPEG images + * can be written to the same file without re-executing jpeg_stdio_dest. + * This makes it dangerous to use this manager and a different destination + * manager serially with the same JPEG object, because their private object + * sizes may be different. Caveat programmer. + */ + if(cinfo->dest == NULL) { + /* first time for this JPEG object? */ + cinfo->dest = (struct jpeg_destination_mgr *) + (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_PERMANENT, + sizeof(my_destination_mgr)); + } - dest = (my_dest_ptr) cinfo->dest; - dest->pub.init_destination = init_destination; - dest->pub.empty_output_buffer = empty_output_buffer; - dest->pub.term_destination = term_destination; - dest->outfile = outfile; + dest = (my_dest_ptr)cinfo->dest; + dest->pub.init_destination = init_destination; + dest->pub.empty_output_buffer = empty_output_buffer; + dest->pub.term_destination = term_destination; + dest->outfile = outfile; } #endif /* HAVE_LIBJPEG */ |