diff options
Diffstat (limited to 'ext/gd/libgd/gd_jpeg.c')
-rw-r--r-- | ext/gd/libgd/gd_jpeg.c | 880 |
1 files changed, 365 insertions, 515 deletions
diff --git a/ext/gd/libgd/gd_jpeg.c b/ext/gd/libgd/gd_jpeg.c index 4c41124f61..7794dc890b 100644 --- a/ext/gd/libgd/gd_jpeg.c +++ b/ext/gd/libgd/gd_jpeg.c @@ -16,6 +16,9 @@ * Modification 4/18/00 TBB: JPEG_DEBUG rather than just DEBUG, * so VC++ builds don't spew to standard output, causing * major CGI brain damage + * + * 2.0.10: more efficient gdImageCreateFromJpegCtx, thanks to + * Christian Aberger */ #include <stdio.h> @@ -38,36 +41,30 @@ static const char *const GD_JPEG_VERSION = "1.0"; typedef struct _jmpbuf_wrapper - { - jmp_buf jmpbuf; - } -jmpbuf_wrapper; +{ + 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) { - jmpbuf_wrapper *jmpbufw; - - php_gd_error("gd-jpeg: JPEG library reports unrecoverable error: "); - (*cinfo->err->output_message) (cinfo); - - jmpbufw = (jmpbuf_wrapper *) cinfo->client_data; - jpeg_destroy (cinfo); - - if (jmpbufw != 0) - { - longjmp (jmpbufw->jmpbuf, 1); - php_gd_error_ex(E_ERROR, "gd-jpeg: EXTREMELY fatal error: longjmp" - " returned control; terminating\n"); - } - else - { - php_gd_error_ex(E_ERROR, "gd-jpeg: EXTREMELY fatal error: jmpbuf" - " unrecoverable; terminating\n"); - } - - exit (99); + jmpbuf_wrapper *jmpbufw; + + php_gd_error("gd-jpeg: JPEG library reports unrecoverable error: "); + (*cinfo->err->output_message) (cinfo); + + jmpbufw = (jmpbuf_wrapper *) cinfo->client_data; + jpeg_destroy (cinfo); + + if (jmpbufw != 0) { + longjmp (jmpbufw->jmpbuf, 1); + php_gd_error_ex(E_ERROR, "gd-jpeg: EXTREMELY fatal error: longjmp returned control; terminating"); + } else { + php_gd_error_ex(E_ERROR, "gd-jpeg: EXTREMELY fatal error: jmpbuf unrecoverable; terminating"); + } + + exit (99); } /* @@ -76,25 +73,27 @@ 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. + */ 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); } 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); @@ -102,168 +101,127 @@ void jpeg_gdIOCtx_dest (j_compress_ptr cinfo, gdIOCtx * outfile); 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]; - -#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]); + 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]; + + 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; } - } -#endif /* JPEG_DEBUG */ - - 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->error_exit = fatal_jpeg_error; - - jpeg_create_compress (&cinfo); - - 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"); -#endif - jpeg_simple_progression (&cinfo); - } - - jpeg_gdIOCtx_dest (&cinfo, outfile); - - row = (JSAMPROW) gdCalloc (1, cinfo.image_width * cinfo.input_components - * sizeof (JSAMPLE)); - if (row == 0) - { - php_gd_error("gd-jpeg: error: unable to allocate JPEG row " - "structure: gdCalloc returns NULL\n"); - jpeg_destroy_compress (&cinfo); - return; - } - - rowptr[0] = row; - - 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) - { + + cinfo.err->error_exit = fatal_jpeg_error; + + jpeg_create_compress (&cinfo); + + 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)) { + jpeg_simple_progression (&cinfo); + } + + jpeg_gdIOCtx_dest (&cinfo, outfile); + + row = (JSAMPROW) gdCalloc (1, cinfo.image_width * cinfo.input_components * sizeof (JSAMPLE)); + rowptr[0] = row; + + jpeg_start_compress (&cinfo, TRUE); + + if (quality >= 0) { + snprintf(comment, sizeof(comment)-1, "CREATOR: gd-jpeg v%s (using IJG JPEG v%d), quality = %d\n", GD_JPEG_VERSION, JPEG_LIB_VERSION, quality); + } else { + snprintf(comment, sizeof(comment)-1, "CREATOR: gd-jpeg v%s (using IJG JPEG v%d), default quality\n", GD_JPEG_VERSION, JPEG_LIB_VERSION); + } + jpeg_write_marker (&cinfo, JPEG_COM, (unsigned char *) comment, (unsigned int) strlen (comment)); + if (im->trueColor) { + #if BITS_IN_JSAMPLE == 12 - php_gd_error("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; + php_gd_error("gd-jpeg: error: jpeg library was compiled for 12-bit precision. This is mostly useless, because JPEGs on the web are 8-bit and such versions of the jpeg library won't read or write them. GD doesn't support these unusual images. Edit your jmorecfg.h file to specify the correct precision and completely 'make clean' and 'make install' libjpeg again. Sorry"); + 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) - php_gd_error_ex(E_WARNING, "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) { + php_gd_error_ex(E_WARNING, "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) - php_gd_error_ex(E_WARNING, "gd_jpeg: warning: jpeg_write_scanlines" - " returns %u -- expected 1\n", nlines); + nlines = jpeg_write_scanlines (&cinfo, rowptr, 1); + if (nlines != 1) { + php_gd_error_ex(E_WARNING, "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); } 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; } -void - jpeg_gdIOCtx_src (j_decompress_ptr cinfo, - gdIOCtx * infile); +void jpeg_gdIOCtx_src (j_decompress_ptr cinfo, gdIOCtx * infile); /* * Create a gd-format image from the JPEG-format INFILE. Returns the @@ -272,197 +230,122 @@ void 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]; - unsigned int i, j; - int retval; - JDIMENSION nrows; - -#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); -#endif + 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]; + unsigned int i, j; + int retval; + JDIMENSION nrows; + + 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; + } - memset (&cinfo, 0, sizeof (cinfo)); - memset (&jerr, 0, sizeof (jerr)); + cinfo.err->error_exit = fatal_jpeg_error; - 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; - - jpeg_create_decompress (&cinfo); - - jpeg_gdIOCtx_src (&cinfo, infile); - - retval = jpeg_read_header (&cinfo, TRUE); - if (retval != JPEG_HEADER_OK) - php_gd_error_ex(E_WARNING, "gd-jpeg: warning: jpeg_read_header returns" - " %d, expected %d\n", retval, JPEG_HEADER_OK); - - if (cinfo.image_height > INT_MAX) - php_gd_error_ex(E_WARNING, "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) - php_gd_error_ex(E_WARNING, "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) - { - php_gd_error("gd-jpeg error: cannot allocate gdImage" - " struct\n"); - goto error; - } - - /* - * Force the image into RGB colorspace, but don't - * reduce the number of colors anymore (GD 2.0) - */ - cinfo.out_color_space = JCS_RGB; - - if (jpeg_start_decompress (&cinfo) != TRUE) - php_gd_error("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; - - case JCS_YCCK: - printf ("YCbCrK"); - break; - - default: - printf ("UNKNOWN (value: %d)", (int) cinfo.jpeg_color_space); - break; - } - 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? */ + jpeg_create_decompress (&cinfo); + + jpeg_gdIOCtx_src (&cinfo, infile); + + retval = jpeg_read_header (&cinfo, TRUE); + if (retval != JPEG_HEADER_OK) { + php_gd_error_ex(E_WARNING, "gd-jpeg: warning: jpeg_read_header returned %d, expected %d", retval, JPEG_HEADER_OK); + } + + if (cinfo.image_height > INT_MAX) { + php_gd_error_ex(E_WARNING, "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) { + php_gd_error_ex(E_WARNING, "gd-jpeg: warning: JPEG image width (%u) is greater than INT_MAX (%d) (and thus greater than gd can handle)", cinfo.image_width, INT_MAX); + } + + im = gdImageCreateTrueColor ((int) cinfo.image_width, (int) cinfo.image_height); + if (im == 0) { + php_gd_error("gd-jpeg error: cannot allocate gdImage struct"); + goto error; + } + + /* Force the image into RGB colorspace, but don't reduce the number of colors anymore (GD 2.0) */ + cinfo.out_color_space = JCS_RGB; + + if (jpeg_start_decompress (&cinfo) != TRUE) { + php_gd_error("gd-jpeg: warning: jpeg_start_decompress reports suspended data source"); + } + + /* 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); #endif - if (cinfo.output_components != 3) - { - php_gd_error_ex(E_WARNING, "gd-jpeg: error: JPEG color quantization" - " request resulted in output_components == %d" - " (expected 3)\n", cinfo.output_components); - goto error; - } + + if (cinfo.output_components != 3) { + php_gd_error_ex(E_WARNING, "gd-jpeg: error: JPEG color quantization request resulted in output_components == %d (expected 3)", cinfo.output_components); + goto error; + } #if BITS_IN_JSAMPLE == 12 - php_gd_error("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; + php_gd_error("gd-jpeg: error: jpeg library was compiled for 12-bit precision. This is mostly useless, because JPEGs on the web are 8-bit and such versions of the jpeg library won't read or write them. GD doesn't support these unusual images. Edit your jmorecfg.h file to specify the correct precision and completely 'make clean' and 'make install' libjpeg again. Sorry."); + goto error; #endif /* BITS_IN_JSAMPLE == 12 */ - row = gdCalloc (cinfo.output_width * 3, sizeof (JSAMPLE)); - if (row == 0) - { - php_gd_error("gd-jpeg: error: unable to allocate row for" - " JPEG scanline: gdCalloc returns NULL\n"); - goto error; - } - rowptr[0] = row; - - for (i = 0; i < cinfo.output_height; i++) - { - nrows = jpeg_read_scanlines (&cinfo, rowptr, 1); - if (nrows != 1) - { - php_gd_error_ex(E_WARNING, "gd-jpeg: error: jpeg_read_scanlines" - " returns %u, expected 1\n", nrows); - goto error; + row = gdCalloc (cinfo.output_width * 3, sizeof (JSAMPLE)); + rowptr[0] = row; + + 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) { + php_gd_error_ex(E_WARNING, "gd-jpeg: error: jpeg_read_scanlines returns %u, expected 1", nrows); + goto error; + } + for (j = 0; j < cinfo.output_width; j++, currow += 3, tpix++) { + *tpix = gdTrueColor (currow[0], currow[1], currow[2]); + } } - for (j = 0; j < cinfo.output_width; j++) - im->tpixels[i][j] = gdTrueColor (row[j * 3], row[j * 3 + 1], - row[j * 3 + 2]); - } - - if (jpeg_finish_decompress (&cinfo) != TRUE) - php_gd_error("gd-jpeg: warning: jpeg_finish_decompress" - " reports suspended data source\n"); + if (jpeg_finish_decompress (&cinfo) != TRUE) { + php_gd_error("gd-jpeg: warning: jpeg_finish_decompress reports suspended data source"); + } + jpeg_destroy_decompress (&cinfo); + gdFree (row); - jpeg_destroy_decompress (&cinfo); - gdFree (row); - return im; + 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; } /* @@ -488,15 +371,13 @@ typedef int safeboolean; /* Expanded data source object for gdIOCtx input */ typedef struct - { - struct jpeg_source_mgr pub; /* public fields */ +{ + 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; + 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; @@ -510,13 +391,13 @@ typedef my_source_mgr *my_src_ptr; 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; } @@ -558,56 +439,42 @@ init_source (j_decompress_ptr cinfo) safeboolean fill_input_buffer (j_decompress_ptr cinfo) { - my_src_ptr src = (my_src_ptr) cinfo->src; - size_t nbytes = 0; + my_src_ptr src = (my_src_ptr) cinfo->src; + size_t nbytes = 0; - /* size_t got; */ - /* char *s; */ - memset (src->buffer, 0, INPUT_BUF_SIZE); + /* size_t got; */ + /* char *s; */ + memset (src->buffer, 0, INPUT_BUF_SIZE); - while (nbytes < INPUT_BUF_SIZE) - { - - int got = gdGetBuf (src->buffer + nbytes, - INPUT_BUF_SIZE - nbytes, - src->infile); + 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; - + 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; - } - - src->pub.next_input_byte = src->buffer; - src->pub.bytes_in_buffer = nbytes; - src->start_of_file = FALSE; - - return TRUE; + 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; + + return TRUE; } @@ -626,24 +493,22 @@ fill_input_buffer (j_decompress_ptr cinfo) 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. - */ + 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; } - src->pub.next_input_byte += (size_t) num_bytes; - src->pub.bytes_in_buffer -= (size_t) num_bytes; - } } @@ -668,11 +533,9 @@ skip_input_data (j_decompress_ptr cinfo, long num_bytes) 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 } @@ -684,50 +547,44 @@ term_source (j_decompress_ptr cinfo) */ void -jpeg_gdIOCtx_src (j_decompress_ptr cinfo, - gdIOCtx * infile) +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 */ -} -my_destination_mgr; + 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; @@ -741,15 +598,13 @@ typedef my_destination_mgr *my_dest_ptr; 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; } @@ -779,16 +634,16 @@ init_destination (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; } @@ -804,15 +659,13 @@ empty_output_buffer (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 ((size_t)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 && ((size_t)gdPutBuf (dest->buffer, datacount, dest->outfile) != datacount)) { + ERREXIT (cinfo, JERR_FILE_WRITE); + } } @@ -825,26 +678,23 @@ term_destination (j_compress_ptr cinfo) 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)); - } - - 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; + 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; } #endif /* HAVE_JPEG */ |