diff options
author | Jonathan Wright <jonathan.wright@arm.com> | 2020-08-05 11:42:22 +0100 |
---|---|---|
committer | Jonathan Wright <jonathan.wright@arm.com> | 2020-08-07 17:04:34 +0100 |
commit | db870dfef8ab97950b4bdf22c66dd6c18326460b (patch) | |
tree | 9862c1aa45d014815ec798992ecb43eff1bc8d42 /turbojpeg.c | |
parent | 341272d909285da90e44015ca41f956fd00b9dd8 (diff) |
Update libjpeg-turbo to v2.0.5
Update Chromium's copy of libjpeg-turbo to the latest stable upstream
release (v2.0.5) and reapply our local changes documented in
README.chromium. This update addresses three CVEs - CVE-2018-19664,
CVE-2018-20330, CVE-2018-20330 - that do not affect Chromium. The
fixes do, however, satisfy UBSan - allowing Chromium's libjpeg-turbo
to be used in AOSP.
Cherry-pick one additional change[1] from upstream to prevent AArch64
Windows builds from failing.
[1] https://github.com/libjpeg-turbo/libjpeg-turbo/commit/6ee5d5f568fda1a7c6a49dd8995f2d89866ee42d
Bug: 922430
Bug: https://issuetracker.google.com/135180511
Change-Id: I146fe82f7a016ce393eb0d37aebe0b7c2492a9da
Diffstat (limited to 'turbojpeg.c')
-rw-r--r-- | turbojpeg.c | 350 |
1 files changed, 192 insertions, 158 deletions
diff --git a/turbojpeg.c b/turbojpeg.c index 90a9ce6..e63d113 100644 --- a/turbojpeg.c +++ b/turbojpeg.c @@ -1,5 +1,5 @@ /* - * Copyright (C)2009-2018 D. R. Commander. All Rights Reserved. + * Copyright (C)2009-2020 D. R. Commander. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -43,6 +43,7 @@ #include "transupp.h" #include "./jpegcomp.h" #include "./cdjpeg.h" +#include "jconfigint.h" extern void jpeg_mem_dest_tj(j_compress_ptr, unsigned char **, unsigned long *, boolean); @@ -50,12 +51,12 @@ extern void jpeg_mem_src_tj(j_decompress_ptr, const unsigned char *, unsigned long); #define PAD(v, p) ((v + (p) - 1) & (~((p) - 1))) -#define isPow2(x) (((x) & (x - 1)) == 0) +#define IS_POW2(x) (((x) & (x - 1)) == 0) /* Error handling (based on example in example.txt) */ -static char errStr[JMSG_LENGTH_MAX] = "No error"; +static THREAD_LOCAL char errStr[JMSG_LENGTH_MAX] = "No error"; struct my_error_mgr { struct jpeg_error_mgr pub; @@ -164,20 +165,20 @@ static int cs2pf[JPEG_NUMCS] = { TJPF_UNKNOWN }; -#define _throwg(m) { \ +#define THROWG(m) { \ snprintf(errStr, JMSG_LENGTH_MAX, "%s", m); \ retval = -1; goto bailout; \ } -#define _throwunix(m) { \ +#define THROW_UNIX(m) { \ snprintf(errStr, JMSG_LENGTH_MAX, "%s\n%s", m, strerror(errno)); \ retval = -1; goto bailout; \ } -#define _throw(m) { \ +#define THROW(m) { \ snprintf(this->errStr, JMSG_LENGTH_MAX, "%s", m); \ - this->isInstanceError = TRUE; _throwg(m) \ + this->isInstanceError = TRUE; THROWG(m) \ } -#define getinstance(handle) \ +#define GET_INSTANCE(handle) \ tjinstance *this = (tjinstance *)handle; \ j_compress_ptr cinfo = NULL; \ j_decompress_ptr dinfo = NULL; \ @@ -190,7 +191,7 @@ static int cs2pf[JPEG_NUMCS] = { this->jerr.warning = FALSE; \ this->isInstanceError = FALSE; -#define getcinstance(handle) \ +#define GET_CINSTANCE(handle) \ tjinstance *this = (tjinstance *)handle; \ j_compress_ptr cinfo = NULL; \ \ @@ -202,7 +203,7 @@ static int cs2pf[JPEG_NUMCS] = { this->jerr.warning = FALSE; \ this->isInstanceError = FALSE; -#define getdinstance(handle) \ +#define GET_DINSTANCE(handle) \ tjinstance *this = (tjinstance *)handle; \ j_decompress_ptr dinfo = NULL; \ \ @@ -237,7 +238,9 @@ static int setCompDefaults(struct jpeg_compress_struct *cinfo, int pixelFormat, int subsamp, int jpegQual, int flags) { int retval = 0; +#ifndef NO_GETENV char *env = NULL; +#endif cinfo->in_color_space = pf2cs[pixelFormat]; cinfo->input_components = tjPixelSize[pixelFormat]; @@ -359,6 +362,23 @@ static int getSubsamp(j_decompress_ptr dinfo) retval = i; break; } } + /* Handle 4:4:4 images whose sampling factors are specified in + non-standard ways. */ + if (dinfo->comp_info[0].h_samp_factor * + dinfo->comp_info[0].v_samp_factor <= + D_MAX_BLOCKS_IN_MCU / pixelsize[i] && i == TJSAMP_444) { + int match = 0; + for (k = 1; k < dinfo->num_components; k++) { + if (dinfo->comp_info[k].h_samp_factor == + dinfo->comp_info[0].h_samp_factor && + dinfo->comp_info[k].v_samp_factor == + dinfo->comp_info[0].v_samp_factor) + match++; + if (match == dinfo->num_components - 1) { + retval = i; break; + } + } + } } } return retval; @@ -396,7 +416,7 @@ DLLEXPORT int tjGetErrorCode(tjhandle handle) DLLEXPORT int tjDestroy(tjhandle handle) { - getinstance(handle); + GET_INSTANCE(handle); if (setjmp(this->jerr.setjmp_buffer)) return -1; if (this->init & COMPRESS) jpeg_destroy_compress(cinfo); @@ -413,7 +433,7 @@ DLLEXPORT int tjDestroy(tjhandle handle) DLLEXPORT void tjFree(unsigned char *buf) { - if (buf) free(buf); + free(buf); } @@ -443,7 +463,7 @@ static tjhandle _tjInitCompress(tjinstance *this) if (setjmp(this->jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. */ - if (this) free(this); + free(this); return NULL; } @@ -472,11 +492,11 @@ DLLEXPORT tjhandle tjInitCompress(void) DLLEXPORT unsigned long tjBufSize(int width, int height, int jpegSubsamp) { - unsigned long retval = 0; + unsigned long long retval = 0; int mcuw, mcuh, chromasf; if (width < 1 || height < 1 || jpegSubsamp < 0 || jpegSubsamp >= NUMSUBOPT) - _throwg("tjBufSize(): Invalid argument"); + THROWG("tjBufSize(): Invalid argument"); /* This allows for rare corner cases in which a JPEG image can actually be larger than the uncompressed input (we wouldn't mention it if it hadn't @@ -484,36 +504,41 @@ DLLEXPORT unsigned long tjBufSize(int width, int height, int jpegSubsamp) mcuw = tjMCUWidth[jpegSubsamp]; mcuh = tjMCUHeight[jpegSubsamp]; chromasf = jpegSubsamp == TJSAMP_GRAY ? 0 : 4 * 64 / (mcuw * mcuh); - retval = PAD(width, mcuw) * PAD(height, mcuh) * (2 + chromasf) + 2048; + retval = PAD(width, mcuw) * PAD(height, mcuh) * (2ULL + chromasf) + 2048ULL; + if (retval > (unsigned long long)((unsigned long)-1)) + THROWG("tjBufSize(): Image is too large"); bailout: - return retval; + return (unsigned long)retval; } DLLEXPORT unsigned long TJBUFSIZE(int width, int height) { - unsigned long retval = 0; + unsigned long long retval = 0; if (width < 1 || height < 1) - _throwg("TJBUFSIZE(): Invalid argument"); + THROWG("TJBUFSIZE(): Invalid argument"); /* This allows for rare corner cases in which a JPEG image can actually be larger than the uncompressed input (we wouldn't mention it if it hadn't happened before.) */ - retval = PAD(width, 16) * PAD(height, 16) * 6 + 2048; + retval = PAD(width, 16) * PAD(height, 16) * 6ULL + 2048ULL; + if (retval > (unsigned long long)((unsigned long)-1)) + THROWG("TJBUFSIZE(): Image is too large"); bailout: - return retval; + return (unsigned long)retval; } DLLEXPORT unsigned long tjBufSizeYUV2(int width, int pad, int height, int subsamp) { - int retval = 0, nc, i; + unsigned long long retval = 0; + int nc, i; if (subsamp < 0 || subsamp >= NUMSUBOPT) - _throwg("tjBufSizeYUV2(): Invalid argument"); + THROWG("tjBufSizeYUV2(): Invalid argument"); nc = (subsamp == TJSAMP_GRAY ? 1 : 3); for (i = 0; i < nc; i++) { @@ -522,11 +547,13 @@ DLLEXPORT unsigned long tjBufSizeYUV2(int width, int pad, int height, int ph = tjPlaneHeight(i, height, subsamp); if (pw < 0 || ph < 0) return -1; - else retval += stride * ph; + else retval += (unsigned long long)stride * ph; } + if (retval > (unsigned long long)((unsigned long)-1)) + THROWG("tjBufSizeYUV2(): Image is too large"); bailout: - return retval; + return (unsigned long)retval; } DLLEXPORT unsigned long tjBufSizeYUV(int width, int height, int subsamp) @@ -545,10 +572,10 @@ DLLEXPORT int tjPlaneWidth(int componentID, int width, int subsamp) int pw, nc, retval = 0; if (width < 1 || subsamp < 0 || subsamp >= TJ_NUMSAMP) - _throwg("tjPlaneWidth(): Invalid argument"); + THROWG("tjPlaneWidth(): Invalid argument"); nc = (subsamp == TJSAMP_GRAY ? 1 : 3); if (componentID < 0 || componentID >= nc) - _throwg("tjPlaneWidth(): Invalid argument"); + THROWG("tjPlaneWidth(): Invalid argument"); pw = PAD(width, tjMCUWidth[subsamp] / 8); if (componentID == 0) @@ -566,10 +593,10 @@ DLLEXPORT int tjPlaneHeight(int componentID, int height, int subsamp) int ph, nc, retval = 0; if (height < 1 || subsamp < 0 || subsamp >= TJ_NUMSAMP) - _throwg("tjPlaneHeight(): Invalid argument"); + THROWG("tjPlaneHeight(): Invalid argument"); nc = (subsamp == TJSAMP_GRAY ? 1 : 3); if (componentID < 0 || componentID >= nc) - _throwg("tjPlaneHeight(): Invalid argument"); + THROWG("tjPlaneHeight(): Invalid argument"); ph = PAD(height, tjMCUHeight[subsamp] / 8); if (componentID == 0) @@ -585,11 +612,11 @@ bailout: DLLEXPORT unsigned long tjPlaneSizeYUV(int componentID, int width, int stride, int height, int subsamp) { - unsigned long retval = 0; + unsigned long long retval = 0; int pw, ph; if (width < 1 || height < 1 || subsamp < 0 || subsamp >= NUMSUBOPT) - _throwg("tjPlaneSizeYUV(): Invalid argument"); + THROWG("tjPlaneSizeYUV(): Invalid argument"); pw = tjPlaneWidth(componentID, width, subsamp); ph = tjPlaneHeight(componentID, height, subsamp); @@ -598,10 +625,12 @@ DLLEXPORT unsigned long tjPlaneSizeYUV(int componentID, int width, int stride, if (stride == 0) stride = pw; else stride = abs(stride); - retval = stride * (ph - 1) + pw; + retval = (unsigned long long)stride * (ph - 1) + pw; + if (retval > (unsigned long long)((unsigned long)-1)) + THROWG("tjPlaneSizeYUV(): Image is too large"); bailout: - return retval; + return (unsigned long)retval; } @@ -613,21 +642,21 @@ DLLEXPORT int tjCompress2(tjhandle handle, const unsigned char *srcBuf, int i, retval = 0, alloc = 1; JSAMPROW *row_pointer = NULL; - getcinstance(handle) + GET_CINSTANCE(handle) this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE; if ((this->init & COMPRESS) == 0) - _throw("tjCompress2(): Instance has not been initialized for compression"); + THROW("tjCompress2(): Instance has not been initialized for compression"); if (srcBuf == NULL || width <= 0 || pitch < 0 || height <= 0 || pixelFormat < 0 || pixelFormat >= TJ_NUMPF || jpegBuf == NULL || jpegSize == NULL || jpegSubsamp < 0 || jpegSubsamp >= NUMSUBOPT || jpegQual < 0 || jpegQual > 100) - _throw("tjCompress2(): Invalid argument"); + THROW("tjCompress2(): Invalid argument"); if (pitch == 0) pitch = width * tjPixelSize[pixelFormat]; if ((row_pointer = (JSAMPROW *)malloc(sizeof(JSAMPROW) * height)) == NULL) - _throw("tjCompress2(): Memory allocation failure"); + THROW("tjCompress2(): Memory allocation failure"); if (setjmp(this->jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. */ @@ -653,9 +682,9 @@ DLLEXPORT int tjCompress2(tjhandle handle, const unsigned char *srcBuf, jpeg_start_compress(cinfo, TRUE); for (i = 0; i < height; i++) { if (flags & TJFLAG_BOTTOMUP) - row_pointer[i] = (JSAMPROW)&srcBuf[(height - i - 1) * pitch]; + row_pointer[i] = (JSAMPROW)&srcBuf[(height - i - 1) * (size_t)pitch]; else - row_pointer[i] = (JSAMPROW)&srcBuf[i * pitch]; + row_pointer[i] = (JSAMPROW)&srcBuf[i * (size_t)pitch]; } while (cinfo->next_scanline < cinfo->image_height) jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], @@ -664,7 +693,7 @@ DLLEXPORT int tjCompress2(tjhandle handle, const unsigned char *srcBuf, bailout: if (cinfo->global_state > CSTATE_START) jpeg_abort_compress(cinfo); - if (row_pointer) free(row_pointer); + free(row_pointer); if (this->jerr.warning) retval = -1; this->jerr.stopOnWarning = FALSE; return retval; @@ -706,7 +735,7 @@ DLLEXPORT int tjEncodeYUVPlanes(tjhandle handle, const unsigned char *srcBuf, JSAMPLE *ptr; jpeg_component_info *compptr; - getcinstance(handle); + GET_CINSTANCE(handle); this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE; for (i = 0; i < MAX_COMPONENTS; i++) { @@ -715,17 +744,17 @@ DLLEXPORT int tjEncodeYUVPlanes(tjhandle handle, const unsigned char *srcBuf, } if ((this->init & COMPRESS) == 0) - _throw("tjEncodeYUVPlanes(): Instance has not been initialized for compression"); + THROW("tjEncodeYUVPlanes(): Instance has not been initialized for compression"); if (srcBuf == NULL || width <= 0 || pitch < 0 || height <= 0 || pixelFormat < 0 || pixelFormat >= TJ_NUMPF || !dstPlanes || !dstPlanes[0] || subsamp < 0 || subsamp >= NUMSUBOPT) - _throw("tjEncodeYUVPlanes(): Invalid argument"); + THROW("tjEncodeYUVPlanes(): Invalid argument"); if (subsamp != TJSAMP_GRAY && (!dstPlanes[1] || !dstPlanes[2])) - _throw("tjEncodeYUVPlanes(): Invalid argument"); + THROW("tjEncodeYUVPlanes(): Invalid argument"); if (pixelFormat == TJPF_CMYK) - _throw("tjEncodeYUVPlanes(): Cannot generate YUV images from CMYK pixels"); + THROW("tjEncodeYUVPlanes(): Cannot generate YUV images from CMYK pixels"); if (pitch == 0) pitch = width * tjPixelSize[pixelFormat]; @@ -750,7 +779,7 @@ DLLEXPORT int tjEncodeYUVPlanes(tjhandle handle, const unsigned char *srcBuf, to write the file headers, which could overflow the output buffer if the YUV image were very small. */ if (cinfo->global_state != CSTATE_START) - _throw("tjEncodeYUVPlanes(): libjpeg API is in the wrong state"); + THROW("tjEncodeYUVPlanes(): libjpeg API is in the wrong state"); (*cinfo->err->reset_error_mgr) ((j_common_ptr)cinfo); jinit_c_master_control(cinfo, FALSE); jinit_color_converter(cinfo); @@ -761,12 +790,12 @@ DLLEXPORT int tjEncodeYUVPlanes(tjhandle handle, const unsigned char *srcBuf, ph0 = PAD(height, cinfo->max_v_samp_factor); if ((row_pointer = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph0)) == NULL) - _throw("tjEncodeYUVPlanes(): Memory allocation failure"); + THROW("tjEncodeYUVPlanes(): Memory allocation failure"); for (i = 0; i < height; i++) { if (flags & TJFLAG_BOTTOMUP) - row_pointer[i] = (JSAMPROW)&srcBuf[(height - i - 1) * pitch]; + row_pointer[i] = (JSAMPROW)&srcBuf[(height - i - 1) * (size_t)pitch]; else - row_pointer[i] = (JSAMPROW)&srcBuf[i * pitch]; + row_pointer[i] = (JSAMPROW)&srcBuf[i * (size_t)pitch]; } if (height < ph0) for (i = height; i < ph0; i++) row_pointer[i] = row_pointer[height - 1]; @@ -778,11 +807,11 @@ DLLEXPORT int tjEncodeYUVPlanes(tjhandle handle, const unsigned char *srcBuf, compptr->h_samp_factor, 32) * cinfo->max_v_samp_factor + 32); if (!_tmpbuf[i]) - _throw("tjEncodeYUVPlanes(): Memory allocation failure"); + THROW("tjEncodeYUVPlanes(): Memory allocation failure"); tmpbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * cinfo->max_v_samp_factor); if (!tmpbuf[i]) - _throw("tjEncodeYUVPlanes(): Memory allocation failure"); + THROW("tjEncodeYUVPlanes(): Memory allocation failure"); for (row = 0; row < cinfo->max_v_samp_factor; row++) { unsigned char *_tmpbuf_aligned = (unsigned char *)PAD((size_t)_tmpbuf[i], 32); @@ -795,10 +824,10 @@ DLLEXPORT int tjEncodeYUVPlanes(tjhandle handle, const unsigned char *srcBuf, (JSAMPLE *)malloc(PAD(compptr->width_in_blocks * DCTSIZE, 32) * compptr->v_samp_factor + 32); if (!_tmpbuf2[i]) - _throw("tjEncodeYUVPlanes(): Memory allocation failure"); + THROW("tjEncodeYUVPlanes(): Memory allocation failure"); tmpbuf2[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * compptr->v_samp_factor); if (!tmpbuf2[i]) - _throw("tjEncodeYUVPlanes(): Memory allocation failure"); + THROW("tjEncodeYUVPlanes(): Memory allocation failure"); for (row = 0; row < compptr->v_samp_factor; row++) { unsigned char *_tmpbuf2_aligned = (unsigned char *)PAD((size_t)_tmpbuf2[i], 32); @@ -810,7 +839,7 @@ DLLEXPORT int tjEncodeYUVPlanes(tjhandle handle, const unsigned char *srcBuf, ph[i] = ph0 * compptr->v_samp_factor / cinfo->max_v_samp_factor; outbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph[i]); if (!outbuf[i]) - _throw("tjEncodeYUVPlanes(): Memory allocation failure"); + THROW("tjEncodeYUVPlanes(): Memory allocation failure"); ptr = dstPlanes[i]; for (row = 0; row < ph[i]; row++) { outbuf[i][row] = ptr; @@ -838,13 +867,13 @@ DLLEXPORT int tjEncodeYUVPlanes(tjhandle handle, const unsigned char *srcBuf, bailout: if (cinfo->global_state > CSTATE_START) jpeg_abort_compress(cinfo); - if (row_pointer) free(row_pointer); + free(row_pointer); for (i = 0; i < MAX_COMPONENTS; i++) { - if (tmpbuf[i] != NULL) free(tmpbuf[i]); - if (_tmpbuf[i] != NULL) free(_tmpbuf[i]); - if (tmpbuf2[i] != NULL) free(tmpbuf2[i]); - if (_tmpbuf2[i] != NULL) free(_tmpbuf2[i]); - if (outbuf[i] != NULL) free(outbuf[i]); + free(tmpbuf[i]); + free(_tmpbuf[i]); + free(tmpbuf2[i]); + free(_tmpbuf2[i]); + free(outbuf[i]); } if (this->jerr.warning) retval = -1; this->jerr.stopOnWarning = FALSE; @@ -860,12 +889,12 @@ DLLEXPORT int tjEncodeYUV3(tjhandle handle, const unsigned char *srcBuf, int pw0, ph0, strides[3], retval = -1; tjinstance *this = (tjinstance *)handle; - if (!this) _throwg("tjEncodeYUV3(): Invalid handle"); + if (!this) THROWG("tjEncodeYUV3(): Invalid handle"); this->isInstanceError = FALSE; - if (width <= 0 || height <= 0 || dstBuf == NULL || pad < 0 || !isPow2(pad) || - subsamp < 0 || subsamp >= NUMSUBOPT) - _throw("tjEncodeYUV3(): Invalid argument"); + if (width <= 0 || height <= 0 || dstBuf == NULL || pad < 0 || + !IS_POW2(pad) || subsamp < 0 || subsamp >= NUMSUBOPT) + THROW("tjEncodeYUV3(): Invalid argument"); pw0 = tjPlaneWidth(0, width, subsamp); ph0 = tjPlaneHeight(0, height, subsamp); @@ -922,7 +951,7 @@ DLLEXPORT int tjCompressFromYUVPlanes(tjhandle handle, JSAMPLE *_tmpbuf = NULL, *ptr; JSAMPROW *inbuf[MAX_COMPONENTS], *tmpbuf[MAX_COMPONENTS]; - getcinstance(handle) + GET_CINSTANCE(handle) this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE; for (i = 0; i < MAX_COMPONENTS; i++) { @@ -930,14 +959,14 @@ DLLEXPORT int tjCompressFromYUVPlanes(tjhandle handle, } if ((this->init & COMPRESS) == 0) - _throw("tjCompressFromYUVPlanes(): Instance has not been initialized for compression"); + THROW("tjCompressFromYUVPlanes(): Instance has not been initialized for compression"); if (!srcPlanes || !srcPlanes[0] || width <= 0 || height <= 0 || subsamp < 0 || subsamp >= NUMSUBOPT || jpegBuf == NULL || jpegSize == NULL || jpegQual < 0 || jpegQual > 100) - _throw("tjCompressFromYUVPlanes(): Invalid argument"); + THROW("tjCompressFromYUVPlanes(): Invalid argument"); if (subsamp != TJSAMP_GRAY && (!srcPlanes[1] || !srcPlanes[2])) - _throw("tjCompressFromYUVPlanes(): Invalid argument"); + THROW("tjCompressFromYUVPlanes(): Invalid argument"); if (setjmp(this->jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. */ @@ -976,7 +1005,7 @@ DLLEXPORT int tjCompressFromYUVPlanes(tjhandle handle, th[i] = compptr->v_samp_factor * DCTSIZE; tmpbufsize += iw[i] * th[i]; if ((inbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph[i])) == NULL) - _throw("tjCompressFromYUVPlanes(): Memory allocation failure"); + THROW("tjCompressFromYUVPlanes(): Memory allocation failure"); ptr = (JSAMPLE *)srcPlanes[i]; for (row = 0; row < ph[i]; row++) { inbuf[i][row] = ptr; @@ -985,11 +1014,11 @@ DLLEXPORT int tjCompressFromYUVPlanes(tjhandle handle, } if (usetmpbuf) { if ((_tmpbuf = (JSAMPLE *)malloc(sizeof(JSAMPLE) * tmpbufsize)) == NULL) - _throw("tjCompressFromYUVPlanes(): Memory allocation failure"); + THROW("tjCompressFromYUVPlanes(): Memory allocation failure"); ptr = _tmpbuf; for (i = 0; i < cinfo->num_components; i++) { if ((tmpbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * th[i])) == NULL) - _throw("tjCompressFromYUVPlanes(): Memory allocation failure"); + THROW("tjCompressFromYUVPlanes(): Memory allocation failure"); for (row = 0; row < th[i]; row++) { tmpbuf[i][row] = ptr; ptr += iw[i]; @@ -1034,10 +1063,10 @@ DLLEXPORT int tjCompressFromYUVPlanes(tjhandle handle, bailout: if (cinfo->global_state > CSTATE_START) jpeg_abort_compress(cinfo); for (i = 0; i < MAX_COMPONENTS; i++) { - if (tmpbuf[i]) free(tmpbuf[i]); - if (inbuf[i]) free(inbuf[i]); + free(tmpbuf[i]); + free(inbuf[i]); } - if (_tmpbuf) free(_tmpbuf); + free(_tmpbuf); if (this->jerr.warning) retval = -1; this->jerr.stopOnWarning = FALSE; return retval; @@ -1053,12 +1082,12 @@ DLLEXPORT int tjCompressFromYUV(tjhandle handle, const unsigned char *srcBuf, int pw0, ph0, strides[3], retval = -1; tjinstance *this = (tjinstance *)handle; - if (!this) _throwg("tjCompressFromYUV(): Invalid handle"); + if (!this) THROWG("tjCompressFromYUV(): Invalid handle"); this->isInstanceError = FALSE; if (srcBuf == NULL || width <= 0 || pad < 1 || height <= 0 || subsamp < 0 || subsamp >= NUMSUBOPT) - _throw("tjCompressFromYUV(): Invalid argument"); + THROW("tjCompressFromYUV(): Invalid argument"); pw0 = tjPlaneWidth(0, width, subsamp); ph0 = tjPlaneHeight(0, height, subsamp); @@ -1102,7 +1131,7 @@ static tjhandle _tjInitDecompress(tjinstance *this) if (setjmp(this->jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. */ - if (this) free(this); + free(this); return NULL; } @@ -1137,13 +1166,13 @@ DLLEXPORT int tjDecompressHeader3(tjhandle handle, { int retval = 0; - getdinstance(handle); + GET_DINSTANCE(handle); if ((this->init & DECOMPRESS) == 0) - _throw("tjDecompressHeader3(): Instance has not been initialized for decompression"); + THROW("tjDecompressHeader3(): Instance has not been initialized for decompression"); if (jpegBuf == NULL || jpegSize <= 0 || width == NULL || height == NULL || jpegSubsamp == NULL || jpegColorspace == NULL) - _throw("tjDecompressHeader3(): Invalid argument"); + THROW("tjDecompressHeader3(): Invalid argument"); if (setjmp(this->jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. */ @@ -1168,11 +1197,11 @@ DLLEXPORT int tjDecompressHeader3(tjhandle handle, jpeg_abort_decompress(dinfo); if (*jpegSubsamp < 0) - _throw("tjDecompressHeader3(): Could not determine subsampling type for JPEG image"); + THROW("tjDecompressHeader3(): Could not determine subsampling type for JPEG image"); if (*jpegColorspace < 0) - _throw("tjDecompressHeader3(): Could not determine colorspace of JPEG image"); + THROW("tjDecompressHeader3(): Could not determine colorspace of JPEG image"); if (*width < 1 || *height < 1) - _throw("tjDecompressHeader3(): Invalid data returned in header"); + THROW("tjDecompressHeader3(): Invalid data returned in header"); bailout: if (this->jerr.warning) retval = -1; @@ -1221,14 +1250,14 @@ DLLEXPORT int tjDecompress2(tjhandle handle, const unsigned char *jpegBuf, JSAMPROW *row_pointer = NULL; int i, retval = 0, jpegwidth, jpegheight, scaledw, scaledh; - getdinstance(handle); + GET_DINSTANCE(handle); this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE; if ((this->init & DECOMPRESS) == 0) - _throw("tjDecompress2(): Instance has not been initialized for decompression"); + THROW("tjDecompress2(): Instance has not been initialized for decompression"); if (jpegBuf == NULL || jpegSize <= 0 || dstBuf == NULL || width < 0 || pitch < 0 || height < 0 || pixelFormat < 0 || pixelFormat >= TJ_NUMPF) - _throw("tjDecompress2(): Invalid argument"); + THROW("tjDecompress2(): Invalid argument"); #ifndef NO_PUTENV if (flags & TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); @@ -1257,7 +1286,7 @@ DLLEXPORT int tjDecompress2(tjhandle handle, const unsigned char *jpegBuf, break; } if (i >= NUMSF) - _throw("tjDecompress2(): Could not scale down to desired image dimensions"); + THROW("tjDecompress2(): Could not scale down to desired image dimensions"); width = scaledw; height = scaledh; dinfo->scale_num = sf[i].num; dinfo->scale_denom = sf[i].denom; @@ -1267,16 +1296,16 @@ DLLEXPORT int tjDecompress2(tjhandle handle, const unsigned char *jpegBuf, if ((row_pointer = (JSAMPROW *)malloc(sizeof(JSAMPROW) * dinfo->output_height)) == NULL) - _throw("tjDecompress2(): Memory allocation failure"); + THROW("tjDecompress2(): Memory allocation failure"); if (setjmp(this->jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. */ retval = -1; goto bailout; } for (i = 0; i < (int)dinfo->output_height; i++) { if (flags & TJFLAG_BOTTOMUP) - row_pointer[i] = &dstBuf[(dinfo->output_height - i - 1) * pitch]; + row_pointer[i] = &dstBuf[(dinfo->output_height - i - 1) * (size_t)pitch]; else - row_pointer[i] = &dstBuf[i * pitch]; + row_pointer[i] = &dstBuf[i * (size_t)pitch]; } while (dinfo->output_scanline < dinfo->output_height) jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline], @@ -1285,7 +1314,7 @@ DLLEXPORT int tjDecompress2(tjhandle handle, const unsigned char *jpegBuf, bailout: if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); - if (row_pointer) free(row_pointer); + free(row_pointer); if (this->jerr.warning) retval = -1; this->jerr.stopOnWarning = FALSE; return retval; @@ -1345,12 +1374,12 @@ static int setDecodeDefaults(struct jpeg_decompress_struct *dinfo, } -int my_read_markers(j_decompress_ptr dinfo) +static int my_read_markers(j_decompress_ptr dinfo) { return JPEG_REACHED_SOS; } -void my_reset_marker_reader(j_decompress_ptr dinfo) +static void my_reset_marker_reader(j_decompress_ptr dinfo) { } @@ -1369,7 +1398,7 @@ DLLEXPORT int tjDecodeYUVPlanes(tjhandle handle, int (*old_read_markers) (j_decompress_ptr); void (*old_reset_marker_reader) (j_decompress_ptr); - getdinstance(handle); + GET_DINSTANCE(handle); this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE; for (i = 0; i < MAX_COMPONENTS; i++) { @@ -1377,14 +1406,14 @@ DLLEXPORT int tjDecodeYUVPlanes(tjhandle handle, } if ((this->init & DECOMPRESS) == 0) - _throw("tjDecodeYUVPlanes(): Instance has not been initialized for decompression"); + THROW("tjDecodeYUVPlanes(): Instance has not been initialized for decompression"); if (!srcPlanes || !srcPlanes[0] || subsamp < 0 || subsamp >= NUMSUBOPT || dstBuf == NULL || width <= 0 || pitch < 0 || height <= 0 || pixelFormat < 0 || pixelFormat >= TJ_NUMPF) - _throw("tjDecodeYUVPlanes(): Invalid argument"); + THROW("tjDecodeYUVPlanes(): Invalid argument"); if (subsamp != TJSAMP_GRAY && (!srcPlanes[1] || !srcPlanes[2])) - _throw("tjDecodeYUVPlanes(): Invalid argument"); + THROW("tjDecodeYUVPlanes(): Invalid argument"); if (setjmp(this->jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. */ @@ -1392,7 +1421,7 @@ DLLEXPORT int tjDecodeYUVPlanes(tjhandle handle, } if (pixelFormat == TJPF_CMYK) - _throw("tjDecodeYUVPlanes(): Cannot decode YUV images into CMYK pixels."); + THROW("tjDecodeYUVPlanes(): Cannot decode YUV images into CMYK pixels."); if (pitch == 0) pitch = width * tjPixelSize[pixelFormat]; dinfo->image_width = width; @@ -1404,6 +1433,9 @@ DLLEXPORT int tjDecodeYUVPlanes(tjhandle handle, else if (flags & TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); #endif + dinfo->progressive_mode = dinfo->inputctl->has_multiple_scans = FALSE; + dinfo->Ss = dinfo->Ah = dinfo->Al = 0; + dinfo->Se = DCTSIZE2 - 1; if (setDecodeDefaults(dinfo, pixelFormat, subsamp, flags) == -1) { retval = -1; goto bailout; } @@ -1428,12 +1460,12 @@ DLLEXPORT int tjDecodeYUVPlanes(tjhandle handle, if (pitch == 0) pitch = dinfo->output_width * tjPixelSize[pixelFormat]; if ((row_pointer = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph0)) == NULL) - _throw("tjDecodeYUVPlanes(): Memory allocation failure"); + THROW("tjDecodeYUVPlanes(): Memory allocation failure"); for (i = 0; i < height; i++) { if (flags & TJFLAG_BOTTOMUP) - row_pointer[i] = &dstBuf[(height - i - 1) * pitch]; + row_pointer[i] = &dstBuf[(height - i - 1) * (size_t)pitch]; else - row_pointer[i] = &dstBuf[i * pitch]; + row_pointer[i] = &dstBuf[i * (size_t)pitch]; } if (height < ph0) for (i = height; i < ph0; i++) row_pointer[i] = row_pointer[height - 1]; @@ -1444,10 +1476,10 @@ DLLEXPORT int tjDecodeYUVPlanes(tjhandle handle, (JSAMPLE *)malloc(PAD(compptr->width_in_blocks * DCTSIZE, 32) * compptr->v_samp_factor + 32); if (!_tmpbuf[i]) - _throw("tjDecodeYUVPlanes(): Memory allocation failure"); + THROW("tjDecodeYUVPlanes(): Memory allocation failure"); tmpbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * compptr->v_samp_factor); if (!tmpbuf[i]) - _throw("tjDecodeYUVPlanes(): Memory allocation failure"); + THROW("tjDecodeYUVPlanes(): Memory allocation failure"); for (row = 0; row < compptr->v_samp_factor; row++) { unsigned char *_tmpbuf_aligned = (unsigned char *)PAD((size_t)_tmpbuf[i], 32); @@ -1459,7 +1491,7 @@ DLLEXPORT int tjDecodeYUVPlanes(tjhandle handle, ph[i] = ph0 * compptr->v_samp_factor / dinfo->max_v_samp_factor; inbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph[i]); if (!inbuf[i]) - _throw("tjDecodeYUVPlanes(): Memory allocation failure"); + THROW("tjDecodeYUVPlanes(): Memory allocation failure"); ptr = (JSAMPLE *)srcPlanes[i]; for (row = 0; row < ph[i]; row++) { inbuf[i][row] = ptr; @@ -1488,11 +1520,11 @@ DLLEXPORT int tjDecodeYUVPlanes(tjhandle handle, bailout: if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); - if (row_pointer) free(row_pointer); + free(row_pointer); for (i = 0; i < MAX_COMPONENTS; i++) { - if (tmpbuf[i] != NULL) free(tmpbuf[i]); - if (_tmpbuf[i] != NULL) free(_tmpbuf[i]); - if (inbuf[i] != NULL) free(inbuf[i]); + free(tmpbuf[i]); + free(_tmpbuf[i]); + free(inbuf[i]); } if (this->jerr.warning) retval = -1; this->jerr.stopOnWarning = FALSE; @@ -1508,12 +1540,12 @@ DLLEXPORT int tjDecodeYUV(tjhandle handle, const unsigned char *srcBuf, int pw0, ph0, strides[3], retval = -1; tjinstance *this = (tjinstance *)handle; - if (!this) _throwg("tjDecodeYUV(): Invalid handle"); + if (!this) THROWG("tjDecodeYUV(): Invalid handle"); this->isInstanceError = FALSE; - if (srcBuf == NULL || pad < 0 || !isPow2(pad) || subsamp < 0 || + if (srcBuf == NULL || pad < 0 || !IS_POW2(pad) || subsamp < 0 || subsamp >= NUMSUBOPT || width <= 0 || height <= 0) - _throw("tjDecodeYUV(): Invalid argument"); + THROW("tjDecodeYUV(): Invalid argument"); pw0 = tjPlaneWidth(0, width, subsamp); ph0 = tjPlaneHeight(0, height, subsamp); @@ -1552,7 +1584,7 @@ DLLEXPORT int tjDecompressToYUVPlanes(tjhandle handle, JSAMPROW *outbuf[MAX_COMPONENTS], *tmpbuf[MAX_COMPONENTS]; int dctsize; - getdinstance(handle); + GET_DINSTANCE(handle); this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE; for (i = 0; i < MAX_COMPONENTS; i++) { @@ -1560,11 +1592,11 @@ DLLEXPORT int tjDecompressToYUVPlanes(tjhandle handle, } if ((this->init & DECOMPRESS) == 0) - _throw("tjDecompressToYUVPlanes(): Instance has not been initialized for decompression"); + THROW("tjDecompressToYUVPlanes(): Instance has not been initialized for decompression"); if (jpegBuf == NULL || jpegSize <= 0 || !dstPlanes || !dstPlanes[0] || width < 0 || height < 0) - _throw("tjDecompressToYUVPlanes(): Invalid argument"); + THROW("tjDecompressToYUVPlanes(): Invalid argument"); #ifndef NO_PUTENV if (flags & TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); @@ -1584,10 +1616,10 @@ DLLEXPORT int tjDecompressToYUVPlanes(tjhandle handle, this->headerRead = 0; jpegSubsamp = getSubsamp(dinfo); if (jpegSubsamp < 0) - _throw("tjDecompressToYUVPlanes(): Could not determine subsampling type for JPEG image"); + THROW("tjDecompressToYUVPlanes(): Could not determine subsampling type for JPEG image"); if (jpegSubsamp != TJSAMP_GRAY && (!dstPlanes[1] || !dstPlanes[2])) - _throw("tjDecompressToYUVPlanes(): Invalid argument"); + THROW("tjDecompressToYUVPlanes(): Invalid argument"); jpegwidth = dinfo->image_width; jpegheight = dinfo->image_height; if (width == 0) width = jpegwidth; @@ -1599,9 +1631,9 @@ DLLEXPORT int tjDecompressToYUVPlanes(tjhandle handle, break; } if (i >= NUMSF) - _throw("tjDecompressToYUVPlanes(): Could not scale down to desired image dimensions"); + THROW("tjDecompressToYUVPlanes(): Could not scale down to desired image dimensions"); if (dinfo->num_components > 3) - _throw("tjDecompressToYUVPlanes(): JPEG image must have 3 or fewer components"); + THROW("tjDecompressToYUVPlanes(): JPEG image must have 3 or fewer components"); width = scaledw; height = scaledh; dinfo->scale_num = sf[i].num; @@ -1617,15 +1649,13 @@ DLLEXPORT int tjDecompressToYUVPlanes(tjhandle handle, iw[i] = compptr->width_in_blocks * dctsize; ih = compptr->height_in_blocks * dctsize; - pw[i] = PAD(dinfo->output_width, dinfo->max_h_samp_factor) * - compptr->h_samp_factor / dinfo->max_h_samp_factor; - ph[i] = PAD(dinfo->output_height, dinfo->max_v_samp_factor) * - compptr->v_samp_factor / dinfo->max_v_samp_factor; + pw[i] = tjPlaneWidth(i, dinfo->output_width, jpegSubsamp); + ph[i] = tjPlaneHeight(i, dinfo->output_height, jpegSubsamp); if (iw[i] != pw[i] || ih != ph[i]) usetmpbuf = 1; th[i] = compptr->v_samp_factor * dctsize; tmpbufsize += iw[i] * th[i]; if ((outbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph[i])) == NULL) - _throw("tjDecompressToYUVPlanes(): Memory allocation failure"); + THROW("tjDecompressToYUVPlanes(): Memory allocation failure"); ptr = dstPlanes[i]; for (row = 0; row < ph[i]; row++) { outbuf[i][row] = ptr; @@ -1634,11 +1664,11 @@ DLLEXPORT int tjDecompressToYUVPlanes(tjhandle handle, } if (usetmpbuf) { if ((_tmpbuf = (JSAMPLE *)malloc(sizeof(JSAMPLE) * tmpbufsize)) == NULL) - _throw("tjDecompressToYUVPlanes(): Memory allocation failure"); + THROW("tjDecompressToYUVPlanes(): Memory allocation failure"); ptr = _tmpbuf; for (i = 0; i < dinfo->num_components; i++) { if ((tmpbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * th[i])) == NULL) - _throw("tjDecompressToYUVPlanes(): Memory allocation failure"); + THROW("tjDecompressToYUVPlanes(): Memory allocation failure"); for (row = 0; row < th[i]; row++) { tmpbuf[i][row] = ptr; ptr += iw[i]; @@ -1702,10 +1732,10 @@ DLLEXPORT int tjDecompressToYUVPlanes(tjhandle handle, bailout: if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); for (i = 0; i < MAX_COMPONENTS; i++) { - if (tmpbuf[i]) free(tmpbuf[i]); - if (outbuf[i]) free(outbuf[i]); + free(tmpbuf[i]); + free(outbuf[i]); } - if (_tmpbuf) free(_tmpbuf); + free(_tmpbuf); if (this->jerr.warning) retval = -1; this->jerr.stopOnWarning = FALSE; return retval; @@ -1719,12 +1749,12 @@ DLLEXPORT int tjDecompressToYUV2(tjhandle handle, const unsigned char *jpegBuf, int pw0, ph0, strides[3], retval = -1, jpegSubsamp = -1; int i, jpegwidth, jpegheight, scaledw, scaledh; - getdinstance(handle); + GET_DINSTANCE(handle); this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE; if (jpegBuf == NULL || jpegSize <= 0 || dstBuf == NULL || width < 0 || - pad < 1 || !isPow2(pad) || height < 0) - _throw("tjDecompressToYUV2(): Invalid argument"); + pad < 1 || !IS_POW2(pad) || height < 0) + THROW("tjDecompressToYUV2(): Invalid argument"); if (setjmp(this->jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. */ @@ -1735,7 +1765,7 @@ DLLEXPORT int tjDecompressToYUV2(tjhandle handle, const unsigned char *jpegBuf, jpeg_read_header(dinfo, TRUE); jpegSubsamp = getSubsamp(dinfo); if (jpegSubsamp < 0) - _throw("tjDecompressToYUV2(): Could not determine subsampling type for JPEG image"); + THROW("tjDecompressToYUV2(): Could not determine subsampling type for JPEG image"); jpegwidth = dinfo->image_width; jpegheight = dinfo->image_height; if (width == 0) width = jpegwidth; @@ -1748,7 +1778,7 @@ DLLEXPORT int tjDecompressToYUV2(tjhandle handle, const unsigned char *jpegBuf, break; } if (i >= NUMSF) - _throw("tjDecompressToYUV2(): Could not scale down to desired image dimensions"); + THROW("tjDecompressToYUV2(): Could not scale down to desired image dimensions"); pw0 = tjPlaneWidth(0, width, jpegSubsamp); ph0 = tjPlaneHeight(0, height, jpegSubsamp); @@ -1813,14 +1843,14 @@ DLLEXPORT int tjTransform(tjhandle handle, const unsigned char *jpegBuf, jvirt_barray_ptr *srccoefs, *dstcoefs; int retval = 0, i, jpegSubsamp, saveMarkers = 0; - getinstance(handle); + GET_INSTANCE(handle); this->jerr.stopOnWarning = (flags & TJFLAG_STOPONWARNING) ? TRUE : FALSE; if ((this->init & COMPRESS) == 0 || (this->init & DECOMPRESS) == 0) - _throw("tjTransform(): Instance has not been initialized for transformation"); + THROW("tjTransform(): Instance has not been initialized for transformation"); if (jpegBuf == NULL || jpegSize <= 0 || n < 1 || dstBufs == NULL || dstSizes == NULL || t == NULL || flags < 0) - _throw("tjTransform(): Invalid argument"); + THROW("tjTransform(): Invalid argument"); #ifndef NO_PUTENV if (flags & TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); @@ -1830,7 +1860,7 @@ DLLEXPORT int tjTransform(tjhandle handle, const unsigned char *jpegBuf, if ((xinfo = (jpeg_transform_info *)malloc(sizeof(jpeg_transform_info) * n)) == NULL) - _throw("tjTransform(): Memory allocation failure"); + THROW("tjTransform(): Memory allocation failure"); MEMZERO(xinfo, sizeof(jpeg_transform_info) * n); if (setjmp(this->jerr.setjmp_buffer)) { @@ -1868,19 +1898,20 @@ DLLEXPORT int tjTransform(tjhandle handle, const unsigned char *jpegBuf, jpeg_read_header(dinfo, TRUE); jpegSubsamp = getSubsamp(dinfo); if (jpegSubsamp < 0) - _throw("tjTransform(): Could not determine subsampling type for JPEG image"); + THROW("tjTransform(): Could not determine subsampling type for JPEG image"); for (i = 0; i < n; i++) { if (!jtransform_request_workspace(dinfo, &xinfo[i])) - _throw("tjTransform(): Transform is not perfect"); + THROW("tjTransform(): Transform is not perfect"); if (xinfo[i].crop) { if ((t[i].r.x % xinfo[i].iMCU_sample_width) != 0 || (t[i].r.y % xinfo[i].iMCU_sample_height) != 0) { - snprintf(errStr, JMSG_LENGTH_MAX, + snprintf(this->errStr, JMSG_LENGTH_MAX, "To crop this JPEG image, x must be a multiple of %d\n" "and y must be a multiple of %d.\n", xinfo[i].iMCU_sample_width, xinfo[i].iMCU_sample_height); + this->isInstanceError = TRUE; retval = -1; goto bailout; } } @@ -1935,7 +1966,7 @@ DLLEXPORT int tjTransform(tjhandle handle, const unsigned char *jpegBuf, for (y = 0; y < compptr->v_samp_factor; y++) { if (t[i].customFilter(barray[y][0], arrayRegion, planeRegion, ci, i, &t[i]) == -1) - _throw("tjTransform(): Error in custom filter"); + THROW("tjTransform(): Error in custom filter"); arrayRegion.y += DCTSIZE; } } @@ -1949,7 +1980,7 @@ DLLEXPORT int tjTransform(tjhandle handle, const unsigned char *jpegBuf, bailout: if (cinfo->global_state > CSTATE_START) jpeg_abort_compress(cinfo); if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); - if (xinfo) free(xinfo); + free(xinfo); if (this->jerr.warning) retval = -1; this->jerr.stopOnWarning = FALSE; return retval; @@ -1960,7 +1991,8 @@ DLLEXPORT unsigned char *tjLoadImage(const char *filename, int *width, int align, int *height, int *pixelFormat, int flags) { - int retval = 0, tempc, pitch; + int retval = 0, tempc; + size_t pitch; tjhandle handle = NULL; tjinstance *this; j_compress_ptr cinfo = NULL; @@ -1971,21 +2003,21 @@ DLLEXPORT unsigned char *tjLoadImage(const char *filename, int *width, if (!filename || !width || align < 1 || !height || !pixelFormat || *pixelFormat < TJPF_UNKNOWN || *pixelFormat >= TJ_NUMPF) - _throwg("tjLoadImage(): Invalid argument"); + THROWG("tjLoadImage(): Invalid argument"); if ((align & (align - 1)) != 0) - _throwg("tjLoadImage(): Alignment must be a power of 2"); + THROWG("tjLoadImage(): Alignment must be a power of 2"); if ((handle = tjInitCompress()) == NULL) return NULL; this = (tjinstance *)handle; cinfo = &this->cinfo; if ((file = fopen(filename, "rb")) == NULL) - _throwunix("tjLoadImage(): Cannot open input file"); + THROW_UNIX("tjLoadImage(): Cannot open input file"); if ((tempc = getc(file)) < 0 || ungetc(tempc, file) == EOF) - _throwunix("tjLoadImage(): Could not read input file") + THROW_UNIX("tjLoadImage(): Could not read input file") else if (tempc == EOF) - _throwg("tjLoadImage(): Input file contains no data"); + THROWG("tjLoadImage(): Input file contains no data"); if (setjmp(this->jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. */ @@ -1996,14 +2028,14 @@ DLLEXPORT unsigned char *tjLoadImage(const char *filename, int *width, else cinfo->in_color_space = pf2cs[*pixelFormat]; if (tempc == 'B') { if ((src = jinit_read_bmp(cinfo, FALSE)) == NULL) - _throwg("tjLoadImage(): Could not initialize bitmap loader"); + THROWG("tjLoadImage(): Could not initialize bitmap loader"); invert = (flags & TJFLAG_BOTTOMUP) == 0; } else if (tempc == 'P') { if ((src = jinit_read_ppm(cinfo)) == NULL) - _throwg("tjLoadImage(): Could not initialize bitmap loader"); + THROWG("tjLoadImage(): Could not initialize bitmap loader"); invert = (flags & TJFLAG_BOTTOMUP) != 0; } else - _throwg("tjLoadImage(): Unsupported file type"); + THROWG("tjLoadImage(): Unsupported file type"); src->input_file = file; (*src->start_input) (cinfo, src); @@ -2013,8 +2045,10 @@ DLLEXPORT unsigned char *tjLoadImage(const char *filename, int *width, *pixelFormat = cs2pf[cinfo->in_color_space]; pitch = PAD((*width) * tjPixelSize[*pixelFormat], align); - if ((dstBuf = (unsigned char *)malloc(pitch * (*height))) == NULL) - _throwg("tjLoadImage(): Memory allocation failure"); + if ((unsigned long long)pitch * (unsigned long long)(*height) > + (unsigned long long)((size_t)-1) || + (dstBuf = (unsigned char *)malloc(pitch * (*height))) == NULL) + THROWG("tjLoadImage(): Memory allocation failure"); if (setjmp(this->jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. */ @@ -2041,7 +2075,7 @@ DLLEXPORT unsigned char *tjLoadImage(const char *filename, int *width, bailout: if (handle) tjDestroy(handle); if (file) fclose(file); - if (retval < 0 && dstBuf) { free(dstBuf); dstBuf = NULL; } + if (retval < 0) { free(dstBuf); dstBuf = NULL; } return dstBuf; } @@ -2061,7 +2095,7 @@ DLLEXPORT int tjSaveImage(const char *filename, unsigned char *buffer, if (!filename || !buffer || width < 1 || pitch < 0 || height < 1 || pixelFormat < 0 || pixelFormat >= TJ_NUMPF) - _throwg("tjSaveImage(): Invalid argument"); + THROWG("tjSaveImage(): Invalid argument"); if ((handle = tjInitDecompress()) == NULL) return -1; @@ -2069,7 +2103,7 @@ DLLEXPORT int tjSaveImage(const char *filename, unsigned char *buffer, dinfo = &this->dinfo; if ((file = fopen(filename, "wb")) == NULL) - _throwunix("tjSaveImage(): Cannot open output file"); + THROW_UNIX("tjSaveImage(): Cannot open output file"); if (setjmp(this->jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. */ @@ -2084,11 +2118,11 @@ DLLEXPORT int tjSaveImage(const char *filename, unsigned char *buffer, ptr = strrchr(filename, '.'); if (ptr && !strcasecmp(ptr, ".bmp")) { if ((dst = jinit_write_bmp(dinfo, FALSE, FALSE)) == NULL) - _throwg("tjSaveImage(): Could not initialize bitmap writer"); + THROWG("tjSaveImage(): Could not initialize bitmap writer"); invert = (flags & TJFLAG_BOTTOMUP) == 0; } else { if ((dst = jinit_write_ppm(dinfo)) == NULL) - _throwg("tjSaveImage(): Could not initialize PPM writer"); + THROWG("tjSaveImage(): Could not initialize PPM writer"); invert = (flags & TJFLAG_BOTTOMUP) != 0; } |