diff options
author | DRC <information@libjpeg-turbo.org> | 2019-09-11 14:27:47 -0700 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2019-09-11 14:27:47 -0700 |
commit | 5dcc997bd6f6f465490c94ade2aef535e51a706d (patch) | |
tree | 74ff998f72c18bdf7efba586b9b4a7a2f4075df9 | |
parent | 84c056eda93933da06d287573efd1f9eeb54bd33 (diff) | |
parent | 2596ecc57d8227273c2adf17409a6d7035db7de4 (diff) | |
download | libjpeg-turbo-5dcc997bd6f6f465490c94ade2aef535e51a706d.tar.gz |
[RESTRICT AUTOMERGE] TurboJPEG: Properly handle gigapixel images am: d8b95103b9
am: 2596ecc57d
Change-Id: I42527bac385e72154fea81324d76181618f1e39d
-rw-r--r-- | README.android | 4 | ||||
-rw-r--r-- | java/TJBench.java | 11 | ||||
-rw-r--r-- | tjbench.c | 123 | ||||
-rw-r--r-- | tjexample.c | 46 | ||||
-rw-r--r-- | tjunittest.c | 193 | ||||
-rw-r--r-- | turbojpeg-jni.c | 424 | ||||
-rw-r--r-- | turbojpeg.c | 257 |
7 files changed, 567 insertions, 491 deletions
diff --git a/README.android b/README.android index 12f476d1..2ec473ed 100644 --- a/README.android +++ b/README.android @@ -18,3 +18,7 @@ been moved into a dedicated rodata section. There's a pull request upstream for this as well. If that's accepted, this can be removed as an Android-specific modification. https://github.com/libjpeg-turbo/libjpeg-turbo/pull/318 + +(3) Cherry-pick of 2a9e3b and 15902850 from upstream + +These fix a bug in TurboJPEG's handling of gigapixel images. diff --git a/java/TJBench.java b/java/TJBench.java index 7829e53c..cc3178ea 100644 --- a/java/TJBench.java +++ b/java/TJBench.java @@ -121,6 +121,8 @@ final class TJBench { int rindex = TJ.getRedOffset(pixelFormat); int gindex = TJ.getGreenOffset(pixelFormat); int bindex = TJ.getBlueOffset(pixelFormat); + if ((long)w[0] * (long)h[0] * (long)ps > (long)Integer.MAX_VALUE) + throw new Exception("Image is too large"); byte[] dstBuf = new byte[w[0] * h[0] * ps]; int pixels = w[0] * h[0], dstPtr = 0, rgbPtr = 0; @@ -175,8 +177,11 @@ final class TJBench { tjd = new TJDecompressor(); - if (dstBuf == null) + if (dstBuf == null) { + if ((long)pitch * (long)scaledh > (long)Integer.MAX_VALUE) + throw new Exception("Image is too large"); dstBuf = new byte[pitch * scaledh]; + } /* Set the destination buffer to gray so we know whether the decompressor attempted to write to it */ @@ -331,6 +336,8 @@ final class TJBench { String pfStr = PIXFORMATSTR[pf]; YUVImage yuvImage = null; + if ((long)pitch * (long)h > (long)Integer.MAX_VALUE) + throw new Exception("Image is too large"); tmpBuf = new byte[pitch * h]; if (quiet == 0) @@ -491,6 +498,8 @@ final class TJBench { int tw, th, ttilew, ttileh, tntilesw, tntilesh, tsubsamp; FileInputStream fis = new FileInputStream(fileName); + if (fis.getChannel().size() > (long)Integer.MAX_VALUE) + throw new Exception("Image is too large"); int srcSize = (int)fis.getChannel().size(); srcBuf = new byte[srcSize]; fis.read(srcBuf, 0, srcSize); @@ -32,27 +32,28 @@ #include <ctype.h> #include <math.h> #include <errno.h> +#include <limits.h> #include <cdjpeg.h> #include "./tjutil.h" #include "./turbojpeg.h" -#define _throw(op, err) { \ +#define THROW(op, err) { \ printf("ERROR in line %d while %s:\n%s\n", __LINE__, op, err); \ retval = -1; goto bailout; \ } -#define _throwunix(m) _throw(m, strerror(errno)) +#define THROW_UNIX(m) THROW(m, strerror(errno)) char tjErrorStr[JMSG_LENGTH_MAX] = "\0", tjErrorMsg[JMSG_LENGTH_MAX] = "\0"; int tjErrorLine = -1, tjErrorCode = -1; -#define _throwtjg(m) { \ +#define THROW_TJG(m) { \ printf("ERROR in line %d while %s:\n%s\n", __LINE__, m, \ tjGetErrorStr2(NULL)); \ retval = -1; goto bailout; \ } -#define _throwtj(m) { \ +#define THROW_TJ(m) { \ int _tjErrorCode = tjGetErrorCode(handle); \ char *_tjErrorStr = tjGetErrorStr2(handle); \ \ @@ -157,11 +158,14 @@ int decomp(unsigned char *srcBuf, unsigned char **jpegBuf, } if ((handle = tjInitDecompress()) == NULL) - _throwtj("executing tjInitDecompress()"); + THROW_TJ("executing tjInitDecompress()"); if (dstBuf == NULL) { - if ((dstBuf = (unsigned char *)malloc(pitch * scaledh)) == NULL) - _throwunix("allocating destination buffer"); + if ((unsigned long long)pitch * (unsigned long long)scaledh > + (unsigned long long)((size_t)-1)) + THROW("allocating destination buffer", "Image is too large"); + if ((dstBuf = (unsigned char *)malloc((size_t)pitch * scaledh)) == NULL) + THROW_UNIX("allocating destination buffer"); dstBufAlloc = 1; } /* Set the destination buffer to gray so we know whether the decompressor @@ -171,10 +175,12 @@ int decomp(unsigned char *srcBuf, unsigned char **jpegBuf, if (doYUV) { int width = doTile ? tilew : scaledw; int height = doTile ? tileh : scaledh; - int yuvSize = tjBufSizeYUV2(width, yuvPad, height, subsamp); + unsigned long yuvSize = tjBufSizeYUV2(width, yuvPad, height, subsamp); + if (yuvSize == (unsigned long)-1) + THROW_TJ("allocating YUV buffer"); if ((yuvBuf = (unsigned char *)malloc(yuvSize)) == NULL) - _throwunix("allocating YUV buffer"); + THROW_UNIX("allocating YUV buffer"); memset(yuvBuf, 127, yuvSize); } @@ -197,16 +203,16 @@ int decomp(unsigned char *srcBuf, unsigned char **jpegBuf, if (tjDecompressToYUV2(handle, jpegBuf[tile], jpegSize[tile], yuvBuf, width, yuvPad, height, flags) == -1) - _throwtj("executing tjDecompressToYUV2()"); + THROW_TJ("executing tjDecompressToYUV2()"); startDecode = getTime(); if (tjDecodeYUV(handle, yuvBuf, yuvPad, subsamp, dstPtr2, width, pitch, height, pf, flags) == -1) - _throwtj("executing tjDecodeYUV()"); + THROW_TJ("executing tjDecodeYUV()"); if (iter >= 0) elapsedDecode += getTime() - startDecode; } else if (tjDecompress2(handle, jpegBuf[tile], jpegSize[tile], dstPtr2, width, pitch, height, pf, flags) == -1) - _throwtj("executing tjDecompress2()"); + THROW_TJ("executing tjDecompress2()"); } } elapsed += getTime() - start; @@ -220,7 +226,7 @@ int decomp(unsigned char *srcBuf, unsigned char **jpegBuf, } if (doYUV) elapsed -= elapsedDecode; - if (tjDestroy(handle) == -1) _throwtj("executing tjDestroy()"); + if (tjDestroy(handle) == -1) THROW_TJ("executing tjDestroy()"); handle = NULL; if (quiet) { @@ -260,19 +266,19 @@ int decomp(unsigned char *srcBuf, unsigned char **jpegBuf, qualStr, sizeStr, ext); if (tjSaveImage(tempStr, dstBuf, scaledw, 0, scaledh, pf, flags) == -1) - _throwtjg("saving bitmap"); + THROW_TJG("saving bitmap"); ptr = strrchr(tempStr, '.'); snprintf(ptr, 1024 - (ptr - tempStr), "-err.%s", ext); if (srcBuf && sf.num == 1 && sf.denom == 1) { if (!quiet) printf("Compression error written to %s.\n", tempStr); if (subsamp == TJ_GRAYSCALE) { - int index, index2; + unsigned long index, index2; for (row = 0, index = 0; row < h; row++, index += pitch) { for (col = 0, index2 = index; col < w; col++, index2 += ps) { - int rindex = index2 + tjRedOffset[pf]; - int gindex = index2 + tjGreenOffset[pf]; - int bindex = index2 + tjBlueOffset[pf]; + unsigned long rindex = index2 + tjRedOffset[pf]; + unsigned long gindex = index2 + tjGreenOffset[pf]; + unsigned long bindex = index2 + tjBlueOffset[pf]; int y = (int)((double)srcBuf[rindex] * 0.299 + (double)srcBuf[gindex] * 0.587 + (double)srcBuf[bindex] * 0.114 + 0.5); @@ -291,7 +297,7 @@ int decomp(unsigned char *srcBuf, unsigned char **jpegBuf, abs(dstBuf[pitch * row + col] - srcBuf[pitch * row + col]); } if (tjSaveImage(tempStr, dstBuf, w, 0, h, pf, flags) == -1) - _throwtjg("saving bitmap"); + THROW_TJG("saving bitmap"); } bailout: @@ -313,14 +319,17 @@ int fullTest(unsigned char *srcBuf, int w, int h, int subsamp, int jpegQual, *srcPtr2; double start, elapsed, elapsedEncode; int totalJpegSize = 0, row, col, i, tilew = w, tileh = h, retval = 0; - int iter, yuvSize = 0; - unsigned long *jpegSize = NULL; + int iter; + unsigned long *jpegSize = NULL, yuvSize = 0; int ps = tjPixelSize[pf]; int ntilesw = 1, ntilesh = 1, pitch = w * ps; const char *pfStr = pixFormatStr[pf]; - if ((tmpBuf = (unsigned char *)malloc(pitch * h)) == NULL) - _throwunix("allocating temporary image buffer"); + if ((unsigned long long)pitch * (unsigned long long)h > + (unsigned long long)((size_t)-1)) + THROW("allocating temporary image buffer", "Image is too large"); + if ((tmpBuf = (unsigned char *)malloc((size_t)pitch * h)) == NULL) + THROW_UNIX("allocating temporary image buffer"); if (!quiet) printf(">>>>> %s (%s) <--> JPEG %s Q%d <<<<<\n", pfStr, @@ -336,18 +345,20 @@ int fullTest(unsigned char *srcBuf, int w, int h, int subsamp, int jpegQual, if ((jpegBuf = (unsigned char **)malloc(sizeof(unsigned char *) * ntilesw * ntilesh)) == NULL) - _throwunix("allocating JPEG tile array"); + THROW_UNIX("allocating JPEG tile array"); memset(jpegBuf, 0, sizeof(unsigned char *) * ntilesw * ntilesh); if ((jpegSize = (unsigned long *)malloc(sizeof(unsigned long) * ntilesw * ntilesh)) == NULL) - _throwunix("allocating JPEG size array"); + THROW_UNIX("allocating JPEG size array"); memset(jpegSize, 0, sizeof(unsigned long) * ntilesw * ntilesh); if ((flags & TJFLAG_NOREALLOC) != 0) for (i = 0; i < ntilesw * ntilesh; i++) { + if (tjBufSize(tilew, tileh, subsamp) > (unsigned long)INT_MAX) + THROW("getting buffer size", "Image is too large"); if ((jpegBuf[i] = (unsigned char *) tjAlloc(tjBufSize(tilew, tileh, subsamp))) == NULL) - _throwunix("allocating JPEG tiles"); + THROW_UNIX("allocating JPEG tiles"); } /* Compression test */ @@ -358,12 +369,14 @@ int fullTest(unsigned char *srcBuf, int w, int h, int subsamp, int jpegQual, for (i = 0; i < h; i++) memcpy(&tmpBuf[pitch * i], &srcBuf[w * ps * i], w * ps); if ((handle = tjInitCompress()) == NULL) - _throwtj("executing tjInitCompress()"); + THROW_TJ("executing tjInitCompress()"); if (doYUV) { yuvSize = tjBufSizeYUV2(tilew, yuvPad, tileh, subsamp); + if (yuvSize == (unsigned long)-1) + THROW_TJ("allocating YUV buffer"); if ((yuvBuf = (unsigned char *)malloc(yuvSize)) == NULL) - _throwunix("allocating YUV buffer"); + THROW_UNIX("allocating YUV buffer"); memset(yuvBuf, 127, yuvSize); } @@ -387,17 +400,17 @@ int fullTest(unsigned char *srcBuf, int w, int h, int subsamp, int jpegQual, if (tjEncodeYUV3(handle, srcPtr2, width, pitch, height, pf, yuvBuf, yuvPad, subsamp, flags) == -1) - _throwtj("executing tjEncodeYUV3()"); + THROW_TJ("executing tjEncodeYUV3()"); if (iter >= 0) elapsedEncode += getTime() - startEncode; if (tjCompressFromYUV(handle, yuvBuf, width, yuvPad, height, subsamp, &jpegBuf[tile], &jpegSize[tile], jpegQual, flags) == -1) - _throwtj("executing tjCompressFromYUV()"); + THROW_TJ("executing tjCompressFromYUV()"); } else { if (tjCompress2(handle, srcPtr2, width, pitch, height, pf, &jpegBuf[tile], &jpegSize[tile], subsamp, jpegQual, flags) == -1) - _throwtj("executing tjCompress2()"); + THROW_TJ("executing tjCompress2()"); } totalJpegSize += jpegSize[tile]; } @@ -413,7 +426,7 @@ int fullTest(unsigned char *srcBuf, int w, int h, int subsamp, int jpegQual, } if (doYUV) elapsed -= elapsedEncode; - if (tjDestroy(handle) == -1) _throwtj("executing tjDestroy()"); + if (tjDestroy(handle) == -1) THROW_TJ("executing tjDestroy()"); handle = NULL; if (quiet == 1) printf("%-5d %-5d ", tilew, tileh); @@ -436,7 +449,7 @@ int fullTest(unsigned char *srcBuf, int w, int h, int subsamp, int jpegQual, if (doYUV) { printf("Encode YUV --> Frame rate: %f fps\n", (double)iter / elapsedEncode); - printf(" Output image size: %d bytes\n", yuvSize); + printf(" Output image size: %lu bytes\n", yuvSize); printf(" Compression ratio: %f:1\n", (double)(w * h * ps) / (double)yuvSize); printf(" Throughput: %f Megapixels/sec\n", @@ -460,9 +473,9 @@ int fullTest(unsigned char *srcBuf, int w, int h, int subsamp, int jpegQual, snprintf(tempStr, 1024, "%s_%s_Q%d.jpg", fileName, subName[subsamp], jpegQual); if ((file = fopen(tempStr, "wb")) == NULL) - _throwunix("opening reference image"); + THROW_UNIX("opening reference image"); if (fwrite(jpegBuf[0], jpegSize[0], 1, file) != 1) - _throwunix("writing reference image"); + THROW_UNIX("writing reference image"); fclose(file); file = NULL; if (!quiet) printf("Reference image written to %s\n", tempStr); } @@ -521,28 +534,28 @@ int decompTest(char *fileName) int tw, th, ttilew, ttileh, tntilesw, tntilesh, tsubsamp; if ((file = fopen(fileName, "rb")) == NULL) - _throwunix("opening file"); + THROW_UNIX("opening file"); if (fseek(file, 0, SEEK_END) < 0 || (srcSize = ftell(file)) == (unsigned long)-1) - _throwunix("determining file size"); + THROW_UNIX("determining file size"); if ((srcBuf = (unsigned char *)malloc(srcSize)) == NULL) - _throwunix("allocating memory"); + THROW_UNIX("allocating memory"); if (fseek(file, 0, SEEK_SET) < 0) - _throwunix("setting file position"); + THROW_UNIX("setting file position"); if (fread(srcBuf, srcSize, 1, file) < 1) - _throwunix("reading JPEG data"); + THROW_UNIX("reading JPEG data"); fclose(file); file = NULL; temp = strrchr(fileName, '.'); if (temp != NULL) *temp = '\0'; if ((handle = tjInitTransform()) == NULL) - _throwtj("executing tjInitTransform()"); + THROW_TJ("executing tjInitTransform()"); if (tjDecompressHeader3(handle, srcBuf, srcSize, &w, &h, &subsamp, &cs) == -1) - _throwtj("executing tjDecompressHeader3()"); + THROW_TJ("executing tjDecompressHeader3()"); if (w < 1 || h < 1) - _throw("reading JPEG header", "Invalid image dimensions"); + THROW("reading JPEG header", "Invalid image dimensions"); if (cs == TJCS_YCCK || cs == TJCS_CMYK) { pf = TJPF_CMYK; ps = tjPixelSize[pf]; } @@ -570,18 +583,21 @@ int decompTest(char *fileName) if ((jpegBuf = (unsigned char **)malloc(sizeof(unsigned char *) * ntilesw * ntilesh)) == NULL) - _throwunix("allocating JPEG tile array"); + THROW_UNIX("allocating JPEG tile array"); memset(jpegBuf, 0, sizeof(unsigned char *) * ntilesw * ntilesh); if ((jpegSize = (unsigned long *)malloc(sizeof(unsigned long) * ntilesw * ntilesh)) == NULL) - _throwunix("allocating JPEG size array"); + THROW_UNIX("allocating JPEG size array"); memset(jpegSize, 0, sizeof(unsigned long) * ntilesw * ntilesh); - if ((flags & TJFLAG_NOREALLOC) != 0 || !doTile) + if ((flags & TJFLAG_NOREALLOC) != 0 && + (doTile || xformOp != TJXOP_NONE || xformOpt != 0 || customFilter)) for (i = 0; i < ntilesw * ntilesh; i++) { + if (tjBufSize(tilew, tileh, subsamp) > (unsigned long)INT_MAX) + THROW("getting buffer size", "Image is too large"); if ((jpegBuf[i] = (unsigned char *) tjAlloc(tjBufSize(tilew, tileh, subsamp))) == NULL) - _throwunix("allocating JPEG tiles"); + THROW_UNIX("allocating JPEG tiles"); } tw = w; th = h; ttilew = tilew; ttileh = tileh; @@ -601,7 +617,7 @@ int decompTest(char *fileName) if (doTile || xformOp != TJXOP_NONE || xformOpt != 0 || customFilter) { if ((t = (tjtransform *)malloc(sizeof(tjtransform) * ntilesw * ntilesh)) == NULL) - _throwunix("allocating image transform array"); + THROW_UNIX("allocating image transform array"); if (xformOp == TJXOP_TRANSPOSE || xformOp == TJXOP_TRANSVERSE || xformOp == TJXOP_ROT90 || xformOp == TJXOP_ROT270) { @@ -647,7 +663,7 @@ int decompTest(char *fileName) start = getTime(); if (tjTransform(handle, srcBuf, srcSize, tntilesw * tntilesh, jpegBuf, jpegSize, t, flags) == -1) - _throwtj("executing tjTransform()"); + THROW_TJ("executing tjTransform()"); elapsed += getTime() - start; if (iter >= 0) { iter++; @@ -684,7 +700,7 @@ int decompTest(char *fileName) } } else { if (quiet == 1) printf("N/A N/A "); - tjFree(jpegBuf[0]); + if(jpegBuf[0]) tjFree(jpegBuf[0]); jpegBuf[0] = NULL; decompsrc = 1; } @@ -699,7 +715,8 @@ int decompTest(char *fileName) } else if (quiet == 1) printf("N/A\n"); for (i = 0; i < ntilesw * ntilesh; i++) { - tjFree(jpegBuf[i]); jpegBuf[i] = NULL; + if(jpegBuf[i]) tjFree(jpegBuf[i]); + jpegBuf[i] = NULL; } free(jpegBuf); jpegBuf = NULL; if (jpegSize) { free(jpegSize); jpegSize = NULL; } @@ -803,7 +820,7 @@ int main(int argc, char *argv[]) int minArg = 2, retval = 0, subsamp = -1; if ((scalingFactors = tjGetScalingFactors(&nsf)) == NULL || nsf == 0) - _throw("executing tjGetScalingFactors()", tjGetErrorStr()); + THROW("executing tjGetScalingFactors()", tjGetErrorStr()); if (argc < minArg) usage(argv[0]); @@ -961,7 +978,7 @@ int main(int argc, char *argv[]) if (!decompOnly) { if ((srcBuf = tjLoadImage(argv[1], &w, 1, &h, &pf, flags)) == NULL) - _throwtjg("loading bitmap"); + THROW_TJG("loading bitmap"); temp = strrchr(argv[1], '.'); if (temp != NULL) *temp = '\0'; } diff --git a/tjexample.c b/tjexample.c index 61200e60..0db2269d 100644 --- a/tjexample.c +++ b/tjexample.c @@ -44,14 +44,14 @@ #define strncasecmp strnicmp #endif -#define _throw(action, message) { \ +#define THROW(action, message) { \ printf("ERROR in line %d while %s:\n%s\n", __LINE__, action, message); \ retval = -1; goto bailout; \ } -#define _throwtj(action) _throw(action, tjGetErrorStr2(tjInstance)) +#define THROW_TJ(action) THROW(action, tjGetErrorStr2(tjInstance)) -#define _throwunix(action) _throw(action, strerror(errno)) +#define THROW_UNIX(action) THROW(action, strerror(errno)) #define DEFAULT_SUBSAMP TJSAMP_444 #define DEFAULT_QUALITY 95 @@ -172,7 +172,7 @@ int main(int argc, char **argv) tjhandle tjInstance = NULL; if ((scalingFactors = tjGetScalingFactors(&numScalingFactors)) == NULL) - _throwtj("getting scaling factors"); + THROW_TJ("getting scaling factors"); memset(&xform, 0, sizeof(tjtransform)); if (argc < 3) @@ -266,17 +266,17 @@ int main(int argc, char **argv) /* Read the JPEG file into memory. */ if ((jpegFile = fopen(argv[1], "rb")) == NULL) - _throwunix("opening input file"); + THROW_UNIX("opening input file"); if (fseek(jpegFile, 0, SEEK_END) < 0 || ((size = ftell(jpegFile)) < 0) || fseek(jpegFile, 0, SEEK_SET) < 0) - _throwunix("determining input file size"); + THROW_UNIX("determining input file size"); if (size == 0) - _throw("determining input file size", "Input file contains no data"); + THROW("determining input file size", "Input file contains no data"); jpegSize = (unsigned long)size; if ((jpegBuf = (unsigned char *)tjAlloc(jpegSize)) == NULL) - _throwunix("allocating JPEG buffer"); + THROW_UNIX("allocating JPEG buffer"); if (fread(jpegBuf, jpegSize, 1, jpegFile) < 1) - _throwunix("reading input file"); + THROW_UNIX("reading input file"); fclose(jpegFile); jpegFile = NULL; if (doTransform) { @@ -285,22 +285,22 @@ int main(int argc, char **argv) unsigned long dstSize = 0; if ((tjInstance = tjInitTransform()) == NULL) - _throwtj("initializing transformer"); + THROW_TJ("initializing transformer"); xform.options |= TJXOPT_TRIM; if (tjTransform(tjInstance, jpegBuf, jpegSize, 1, &dstBuf, &dstSize, &xform, flags) < 0) - _throwtj("transforming input image"); + THROW_TJ("transforming input image"); tjFree(jpegBuf); jpegBuf = dstBuf; jpegSize = dstSize; } else { if ((tjInstance = tjInitDecompress()) == NULL) - _throwtj("initializing decompressor"); + THROW_TJ("initializing decompressor"); } if (tjDecompressHeader3(tjInstance, jpegBuf, jpegSize, &width, &height, &inSubsamp, &inColorspace) < 0) - _throwtj("reading JPEG header"); + THROW_TJ("reading JPEG header"); printf("%s Image: %d x %d pixels, %s subsampling, %s colorspace\n", (doTransform ? "Transformed" : "Input"), width, height, @@ -312,9 +312,9 @@ int main(int argc, char **argv) /* Input image has been transformed, and no re-compression options have been selected. Write the transformed image to disk and exit. */ if ((jpegFile = fopen(argv[2], "wb")) == NULL) - _throwunix("opening output file"); + THROW_UNIX("opening output file"); if (fwrite(jpegBuf, jpegSize, 1, jpegFile) < 1) - _throwunix("writing output file"); + THROW_UNIX("writing output file"); fclose(jpegFile); jpegFile = NULL; goto bailout; } @@ -330,18 +330,18 @@ int main(int argc, char **argv) pixelFormat = TJPF_BGRX; if ((imgBuf = (unsigned char *)tjAlloc(width * height * tjPixelSize[pixelFormat])) == NULL) - _throwunix("allocating uncompressed image buffer"); + THROW_UNIX("allocating uncompressed image buffer"); if (tjDecompress2(tjInstance, jpegBuf, jpegSize, imgBuf, width, 0, height, pixelFormat, flags) < 0) - _throwtj("decompressing JPEG image"); + THROW_TJ("decompressing JPEG image"); tjFree(jpegBuf); jpegBuf = NULL; tjDestroy(tjInstance); tjInstance = NULL; } else { /* Input image is not a JPEG image. Load it into memory. */ if ((imgBuf = tjLoadImage(argv[1], &width, 1, &height, &pixelFormat, 0)) == NULL) - _throwtj("loading input image"); + THROW_TJ("loading input image"); if (outSubsamp < 0) { if (pixelFormat == TJPF_GRAY) outSubsamp = TJSAMP_GRAY; @@ -364,17 +364,17 @@ int main(int argc, char **argv) outQual); if ((tjInstance = tjInitCompress()) == NULL) - _throwtj("initializing compressor"); + THROW_TJ("initializing compressor"); if (tjCompress2(tjInstance, imgBuf, width, 0, height, pixelFormat, &jpegBuf, &jpegSize, outSubsamp, outQual, flags) < 0) - _throwtj("compressing image"); + THROW_TJ("compressing image"); tjDestroy(tjInstance); tjInstance = NULL; /* Write the JPEG image to disk. */ if ((jpegFile = fopen(argv[2], "wb")) == NULL) - _throwunix("opening output file"); + THROW_UNIX("opening output file"); if (fwrite(jpegBuf, jpegSize, 1, jpegFile) < 1) - _throwunix("writing output file"); + THROW_UNIX("writing output file"); tjDestroy(tjInstance); tjInstance = NULL; fclose(jpegFile); jpegFile = NULL; tjFree(jpegBuf); jpegBuf = NULL; @@ -383,7 +383,7 @@ int main(int argc, char **argv) directly to disk. */ printf("\n"); if (tjSaveImage(argv[2], imgBuf, width, 0, height, pixelFormat, 0) < 0) - _throwtj("saving output image"); + THROW_TJ("saving output image"); } bailout: diff --git a/tjunittest.c b/tjunittest.c index ae72e836..c92fea79 100644 --- a/tjunittest.c +++ b/tjunittest.c @@ -59,16 +59,16 @@ void usage(char *progName) } -#define _throwtj() { \ +#define THROW_TJ() { \ printf("TurboJPEG ERROR:\n%s\n", tjGetErrorStr()); \ - bailout() \ + BAILOUT() \ } -#define _tj(f) { if ((f) == -1) _throwtj(); } -#define _throw(m) { printf("ERROR: %s\n", m); bailout() } -#define _throwmd5(filename, md5sum, ref) { \ +#define TRY_TJ(f) { if ((f) == -1) THROW_TJ(); } +#define THROW(m) { printf("ERROR: %s\n", m); BAILOUT() } +#define THROW_MD5(filename, md5sum, ref) { \ printf("\n%s has an MD5 sum of %s.\n Should be %s.\n", filename, md5sum, \ ref); \ - bailout() \ + BAILOUT() \ } const char *subNameLong[TJ_NUMSAMP] = { @@ -93,7 +93,7 @@ const int _onlyRGB[] = { TJPF_RGB }; int doYUV = 0, alloc = 0, pad = 4; int exitStatus = 0; -#define bailout() { exitStatus = -1; goto bailout; } +#define BAILOUT() { exitStatus = -1; goto bailout; } void initBuf(unsigned char *buf, int w, int h, int pf, int flags) @@ -151,7 +151,7 @@ void initBuf(unsigned char *buf, int w, int h, int pf, int flags) } -#define checkval(v, cv) { \ +#define CHECKVAL(v, cv) { \ if (v < cv - 1 || v > cv + 1) { \ printf("\nComp. %s at %d,%d should be %d, not %d\n", #v, row, col, cv, \ v); \ @@ -159,14 +159,14 @@ void initBuf(unsigned char *buf, int w, int h, int pf, int flags) } \ } -#define checkval0(v) { \ +#define CHECKVAL0(v) { \ if (v > 1) { \ printf("\nComp. %s at %d,%d should be 0, not %d\n", #v, row, col, v); \ retval = 0; exitStatus = -1; goto bailout; \ } \ } -#define checkval255(v) { \ +#define CHECKVAL255(v) { \ if (v < 254) { \ printf("\nComp. %s at %d,%d should be 255, not %d\n", #v, row, col, v); \ retval = 0; exitStatus = -1; goto bailout; \ @@ -200,13 +200,13 @@ int checkBuf(unsigned char *buf, int w, int h, int pf, int subsamp, y = buf[index * ps + 2]; k = buf[index * ps + 3]; if (((row / blocksize) + (col / blocksize)) % 2 == 0) { - checkval255(c); checkval255(m); checkval255(y); - if (row < halfway) checkval255(k) - else checkval0(k) + CHECKVAL255(c); CHECKVAL255(m); CHECKVAL255(y); + if (row < halfway) CHECKVAL255(k) + else CHECKVAL0(k) } else { - checkval255(c); checkval0(y); checkval255(k); - if (row < halfway) checkval0(m) - else checkval255(m) + CHECKVAL255(c); CHECKVAL0(y); CHECKVAL255(k); + if (row < halfway) CHECKVAL0(m) + else CHECKVAL255(m) } } } @@ -225,26 +225,26 @@ int checkBuf(unsigned char *buf, int w, int h, int pf, int subsamp, a = aoffset >= 0 ? buf[index * ps + aoffset] : 0xFF; if (((row / blocksize) + (col / blocksize)) % 2 == 0) { if (row < halfway) { - checkval255(r); checkval255(g); checkval255(b); + CHECKVAL255(r); CHECKVAL255(g); CHECKVAL255(b); } else { - checkval0(r); checkval0(g); checkval0(b); + CHECKVAL0(r); CHECKVAL0(g); CHECKVAL0(b); } } else { if (subsamp == TJSAMP_GRAY) { if (row < halfway) { - checkval(r, 76); checkval(g, 76); checkval(b, 76); + CHECKVAL(r, 76); CHECKVAL(g, 76); CHECKVAL(b, 76); } else { - checkval(r, 226); checkval(g, 226); checkval(b, 226); + CHECKVAL(r, 226); CHECKVAL(g, 226); CHECKVAL(b, 226); } } else { if (row < halfway) { - checkval255(r); checkval0(g); checkval0(b); + CHECKVAL255(r); CHECKVAL0(g); CHECKVAL0(b); } else { - checkval255(r); checkval255(g); checkval0(b); + CHECKVAL255(r); CHECKVAL255(g); CHECKVAL0(b); } } } - checkval255(a); + CHECKVAL255(a); } } @@ -287,11 +287,11 @@ int checkBufYUV(unsigned char *buf, int w, int h, int subsamp, unsigned char y = buf[ypitch * row + col]; if (((row / blocksize) + (col / blocksize)) % 2 == 0) { - if (row < halfway) checkval255(y) - else checkval0(y); + if (row < halfway) CHECKVAL255(y) + else CHECKVAL0(y); } else { - if (row < halfway) checkval(y, 76) - else checkval(y, 226); + if (row < halfway) CHECKVAL(y, 76) + else CHECKVAL(y, 226); } } } @@ -304,12 +304,12 @@ int checkBufYUV(unsigned char *buf, int w, int h, int subsamp, v = buf[ypitch * ph + uvpitch * ch + (uvpitch * row + col)]; if (((row * vsf / blocksize) + (col * hsf / blocksize)) % 2 == 0) { - checkval(u, 128); checkval(v, 128); + CHECKVAL(u, 128); CHECKVAL(v, 128); } else { if (row < halfway) { - checkval(u, 85); checkval255(v); + CHECKVAL(u, 85); CHECKVAL255(v); } else { - checkval0(u); checkval(v, 149); + CHECKVAL0(u); CHECKVAL(v, 149); } } } @@ -348,7 +348,7 @@ void writeJPEG(unsigned char *jpegBuf, unsigned long jpegSize, char *filename) if (!file || fwrite(jpegBuf, jpegSize, 1, file) != 1) { printf("ERROR: Could not write to %s.\n%s\n", filename, strerror(errno)); - bailout() + BAILOUT() } bailout: @@ -368,7 +368,7 @@ void compTest(tjhandle handle, unsigned char **dstBuf, unsigned long *dstSize, const char *buStr = (flags & TJFLAG_BOTTOMUP) ? "BU" : "TD"; if ((srcBuf = (unsigned char *)malloc(w * h * tjPixelSize[pf])) == NULL) - _throw("Memory allocation failure"); + THROW("Memory allocation failure"); initBuf(srcBuf, w, h, pf, flags); if (*dstBuf && *dstSize > 0) memset(*dstBuf, 0, *dstSize); @@ -379,28 +379,28 @@ void compTest(tjhandle handle, unsigned char **dstBuf, unsigned long *dstSize, tjscalingfactor sf = { 1, 1 }; tjhandle handle2 = tjInitCompress(); - if (!handle2) _throwtj(); + if (!handle2) THROW_TJ(); if ((yuvBuf = (unsigned char *)malloc(yuvSize)) == NULL) - _throw("Memory allocation failure"); + THROW("Memory allocation failure"); memset(yuvBuf, 0, yuvSize); printf("%s %s -> YUV %s ... ", pfStr, buStrLong, subNameLong[subsamp]); - _tj(tjEncodeYUV3(handle2, srcBuf, w, 0, h, pf, yuvBuf, pad, subsamp, - flags)); + TRY_TJ(tjEncodeYUV3(handle2, srcBuf, w, 0, h, pf, yuvBuf, pad, subsamp, + flags)); tjDestroy(handle2); if (checkBufYUV(yuvBuf, w, h, subsamp, sf)) printf("Passed.\n"); else printf("FAILED!\n"); printf("YUV %s %s -> JPEG Q%d ... ", subNameLong[subsamp], buStrLong, jpegQual); - _tj(tjCompressFromYUV(handle, yuvBuf, w, pad, h, subsamp, dstBuf, dstSize, - jpegQual, flags)); + TRY_TJ(tjCompressFromYUV(handle, yuvBuf, w, pad, h, subsamp, dstBuf, + dstSize, jpegQual, flags)); } else { printf("%s %s -> %s Q%d ... ", pfStr, buStrLong, subNameLong[subsamp], jpegQual); - _tj(tjCompress2(handle, srcBuf, w, 0, h, pf, dstBuf, dstSize, subsamp, - jpegQual, flags)); + TRY_TJ(tjCompress2(handle, srcBuf, w, 0, h, pf, dstBuf, dstSize, subsamp, + jpegQual, flags)); } snprintf(tempStr, 1024, "%s_enc_%s_%s_%s_Q%d.jpg", basename, pfStr, buStr, @@ -424,14 +424,14 @@ void _decompTest(tjhandle handle, unsigned char *jpegBuf, int scaledHeight = TJSCALED(h, sf); unsigned long dstSize = 0; - _tj(tjDecompressHeader2(handle, jpegBuf, jpegSize, &_hdrw, &_hdrh, - &_hdrsubsamp)); + TRY_TJ(tjDecompressHeader2(handle, jpegBuf, jpegSize, &_hdrw, &_hdrh, + &_hdrsubsamp)); if (_hdrw != w || _hdrh != h || _hdrsubsamp != subsamp) - _throw("Incorrect JPEG header"); + THROW("Incorrect JPEG header"); dstSize = scaledWidth * scaledHeight * tjPixelSize[pf]; if ((dstBuf = (unsigned char *)malloc(dstSize)) == NULL) - _throw("Memory allocation failure"); + THROW("Memory allocation failure"); memset(dstBuf, 0, dstSize); if (doYUV) { @@ -439,26 +439,26 @@ void _decompTest(tjhandle handle, unsigned char *jpegBuf, subsamp); tjhandle handle2 = tjInitDecompress(); - if (!handle2) _throwtj(); + if (!handle2) THROW_TJ(); if ((yuvBuf = (unsigned char *)malloc(yuvSize)) == NULL) - _throw("Memory allocation failure"); + THROW("Memory allocation failure"); memset(yuvBuf, 0, yuvSize); printf("JPEG -> YUV %s ", subNameLong[subsamp]); if (sf.num != 1 || sf.denom != 1) printf("%d/%d ... ", sf.num, sf.denom); else printf("... "); - _tj(tjDecompressToYUV2(handle, jpegBuf, jpegSize, yuvBuf, scaledWidth, pad, - scaledHeight, flags)); + TRY_TJ(tjDecompressToYUV2(handle, jpegBuf, jpegSize, yuvBuf, scaledWidth, + pad, scaledHeight, flags)); if (checkBufYUV(yuvBuf, scaledWidth, scaledHeight, subsamp, sf)) printf("Passed.\n"); else printf("FAILED!\n"); printf("YUV %s -> %s %s ... ", subNameLong[subsamp], pixFormatStr[pf], (flags & TJFLAG_BOTTOMUP) ? "Bottom-Up" : "Top-Down "); - _tj(tjDecodeYUV(handle2, yuvBuf, pad, subsamp, dstBuf, scaledWidth, 0, - scaledHeight, pf, flags)); + TRY_TJ(tjDecodeYUV(handle2, yuvBuf, pad, subsamp, dstBuf, scaledWidth, 0, + scaledHeight, pf, flags)); tjDestroy(handle2); } else { printf("JPEG -> %s %s ", pixFormatStr[pf], @@ -466,8 +466,8 @@ void _decompTest(tjhandle handle, unsigned char *jpegBuf, if (sf.num != 1 || sf.denom != 1) printf("%d/%d ... ", sf.num, sf.denom); else printf("... "); - _tj(tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, scaledWidth, 0, - scaledHeight, pf, flags)); + TRY_TJ(tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, scaledWidth, 0, + scaledHeight, pf, flags)); } if (checkBuf(dstBuf, scaledWidth, scaledHeight, pf, subsamp, sf, flags)) @@ -488,7 +488,7 @@ void decompTest(tjhandle handle, unsigned char *jpegBuf, int i, n = 0; tjscalingfactor *sf = tjGetScalingFactors(&n); - if (!sf || !n) _throwtj(); + if (!sf || !n) THROW_TJ(); for (i = 0; i < n; i++) { if (subsamp == TJSAMP_444 || subsamp == TJSAMP_GRAY || @@ -517,11 +517,11 @@ void doTest(int w, int h, const int *formats, int nformats, int subsamp, size = tjBufSize(w, h, subsamp); if (size != 0) if ((dstBuf = (unsigned char *)tjAlloc(size)) == NULL) - _throw("Memory allocation failure."); + THROW("Memory allocation failure."); if ((chandle = tjInitCompress()) == NULL || (dhandle = tjInitDecompress()) == NULL) - _throwtj(); + THROW_TJ(); for (pfi = 0; pfi < nformats; pfi++) { for (i = 0; i < 2; i++) { @@ -552,14 +552,50 @@ bailout: } -void bufSizeTest(void) +#if SIZEOF_SIZE_T == 8 +#define CHECKSIZE(function) { \ + if ((unsigned long long)size < (unsigned long long)0xFFFFFFFF) \ + THROW(#function " overflow"); \ +} +#else +#define CHECKSIZE(function) { \ + if (size != (unsigned long)(-1) || \ + !strcmp(tjGetErrorStr2(NULL), "No error")) \ + THROW(#function " overflow"); \ +} +#endif + +static void overflowTest(void) +{ + /* Ensure that the various buffer size functions don't overflow */ + unsigned long size; + + size = tjBufSize(26755, 26755, TJSAMP_444); + CHECKSIZE(tjBufSize()); + size = TJBUFSIZE(26755, 26755); + CHECKSIZE(TJBUFSIZE()); + size = tjBufSizeYUV2(37838, 1, 37838, TJSAMP_444); + CHECKSIZE(tjBufSizeYUV2()); + size = TJBUFSIZEYUV(37838, 37838, TJSAMP_444); + CHECKSIZE(TJBUFSIZEYUV()); + size = tjBufSizeYUV(37838, 37838, TJSAMP_444); + CHECKSIZE(tjBufSizeYUV()); + size = tjPlaneSizeYUV(0, 65536, 0, 65536, TJSAMP_444); + CHECKSIZE(tjPlaneSizeYUV()); + +bailout: + return; +} + + +static void bufSizeTest(void) { int w, h, i, subsamp; unsigned char *srcBuf = NULL, *dstBuf = NULL; tjhandle handle = NULL; unsigned long dstSize = 0; - if ((handle = tjInitCompress()) == NULL) _throwtj(); + if ((handle = tjInitCompress()) == NULL) THROW_TJ(); printf("Buffer size regression test\n"); for (subsamp = 0; subsamp < TJ_NUMSAMP; subsamp++) { @@ -569,12 +605,12 @@ void bufSizeTest(void) for (h = 1; h < maxh; h++) { if (h % 100 == 0) printf("%.4d x %.4d\b\b\b\b\b\b\b\b\b\b\b", w, h); if ((srcBuf = (unsigned char *)malloc(w * h * 4)) == NULL) - _throw("Memory allocation failure"); + THROW("Memory allocation failure"); if (!alloc || doYUV) { if (doYUV) dstSize = tjBufSizeYUV2(w, pad, h, subsamp); else dstSize = tjBufSize(w, h, subsamp); if ((dstBuf = (unsigned char *)tjAlloc(dstSize)) == NULL) - _throw("Memory allocation failure"); + THROW("Memory allocation failure"); } for (i = 0; i < w * h * 4; i++) { @@ -583,12 +619,12 @@ void bufSizeTest(void) } if (doYUV) { - _tj(tjEncodeYUV3(handle, srcBuf, w, 0, h, TJPF_BGRX, dstBuf, pad, - subsamp, 0)); + TRY_TJ(tjEncodeYUV3(handle, srcBuf, w, 0, h, TJPF_BGRX, dstBuf, pad, + subsamp, 0)); } else { - _tj(tjCompress2(handle, srcBuf, w, 0, h, TJPF_BGRX, &dstBuf, - &dstSize, subsamp, 100, - alloc ? 0 : TJFLAG_NOREALLOC)); + TRY_TJ(tjCompress2(handle, srcBuf, w, 0, h, TJPF_BGRX, &dstBuf, + &dstSize, subsamp, 100, + alloc ? 0 : TJFLAG_NOREALLOC)); } free(srcBuf); srcBuf = NULL; if (!alloc || doYUV) { @@ -596,12 +632,12 @@ void bufSizeTest(void) } if ((srcBuf = (unsigned char *)malloc(h * w * 4)) == NULL) - _throw("Memory allocation failure"); + THROW("Memory allocation failure"); if (!alloc || doYUV) { if (doYUV) dstSize = tjBufSizeYUV2(h, pad, w, subsamp); else dstSize = tjBufSize(h, w, subsamp); if ((dstBuf = (unsigned char *)tjAlloc(dstSize)) == NULL) - _throw("Memory allocation failure"); + THROW("Memory allocation failure"); } for (i = 0; i < h * w * 4; i++) { @@ -610,12 +646,12 @@ void bufSizeTest(void) } if (doYUV) { - _tj(tjEncodeYUV3(handle, srcBuf, h, 0, w, TJPF_BGRX, dstBuf, pad, - subsamp, 0)); + TRY_TJ(tjEncodeYUV3(handle, srcBuf, h, 0, w, TJPF_BGRX, dstBuf, pad, + subsamp, 0)); } else { - _tj(tjCompress2(handle, srcBuf, h, 0, w, TJPF_BGRX, &dstBuf, - &dstSize, subsamp, 100, - alloc ? 0 : TJFLAG_NOREALLOC)); + TRY_TJ(tjCompress2(handle, srcBuf, h, 0, w, TJPF_BGRX, &dstBuf, + &dstSize, subsamp, 100, + alloc ? 0 : TJFLAG_NOREALLOC)); } free(srcBuf); srcBuf = NULL; if (!alloc || doYUV) { @@ -736,20 +772,20 @@ int doBmpTest(const char *ext, int width, int align, int height, int pf, } if ((buf = (unsigned char *)tjAlloc(pitch * height)) == NULL) - _throw("Could not allocate memory"); + THROW("Could not allocate memory"); initBitmap(buf, width, pitch, height, pf, flags); snprintf(filename, 80, "test_bmp_%s_%d_%s.%s", pixFormatStr[pf], align, (flags & TJFLAG_BOTTOMUP) ? "bu" : "td", ext); - _tj(tjSaveImage(filename, buf, width, pitch, height, pf, flags)); + TRY_TJ(tjSaveImage(filename, buf, width, pitch, height, pf, flags)); md5sum = MD5File(filename, md5buf); if (strcasecmp(md5sum, md5ref)) - _throwmd5(filename, md5sum, md5ref); + THROW_MD5(filename, md5sum, md5ref); tjFree(buf); buf = NULL; if ((buf = tjLoadImage(filename, &loadWidth, align, &loadHeight, &pf, flags)) == NULL) - _throwtj(); + THROW_TJ(); if (width != loadWidth || height != loadHeight) { printf("\n Image dimensions of %s are bogus\n", filename); retval = -1; goto bailout; @@ -763,7 +799,7 @@ int doBmpTest(const char *ext, int width, int align, int height, int pf, pf = TJPF_XBGR; if ((buf = tjLoadImage(filename, &loadWidth, align, &loadHeight, &pf, flags)) == NULL) - _throwtj(); + THROW_TJ(); pitch = PAD(width * tjPixelSize[pf], align); if (!cmpBitmap(buf, width, pitch, height, pf, flags, 1)) { printf("\n Converting %s to RGB failed\n", filename); @@ -774,7 +810,7 @@ int doBmpTest(const char *ext, int width, int align, int height, int pf, pf = TJPF_CMYK; if ((buf = tjLoadImage(filename, &loadWidth, align, &loadHeight, &pf, flags)) == NULL) - _throwtj(); + THROW_TJ(); pitch = PAD(width * tjPixelSize[pf], align); if (!cmpBitmap(buf, width, pitch, height, pf, flags, 1)) { printf("\n Converting %s to CMYK failed\n", filename); @@ -788,7 +824,7 @@ int doBmpTest(const char *ext, int width, int align, int height, int pf, pixelFormat = TJPF_UNKNOWN; if ((buf = tjLoadImage(filename, &loadWidth, align, &loadHeight, &pixelFormat, flags)) == NULL) - _throwtj(); + THROW_TJ(); if ((pf == TJPF_GRAY && pixelFormat != TJPF_GRAY) || (pf != TJPF_GRAY && !strcasecmp(ext, "bmp") && pixelFormat != TJPF_BGR) || @@ -863,6 +899,7 @@ int main(int argc, char *argv[]) } if (alloc) printf("Testing automatic buffer allocation\n"); if (doYUV) num4bf = 4; + overflowTest(); doTest(35, 39, _3byteFormats, 2, TJSAMP_444, "test"); doTest(39, 41, _4byteFormats, num4bf, TJSAMP_444, "test"); doTest(41, 35, _3byteFormats, 2, TJSAMP_422, "test"); diff --git a/turbojpeg-jni.c b/turbojpeg-jni.c index d0a0935b..13f18f78 100644 --- a/turbojpeg-jni.c +++ b/turbojpeg-jni.c @@ -39,55 +39,55 @@ #define PAD(v, p) ((v + (p) - 1) & (~((p) - 1))) -#define bailif0(f) { \ +#define BAILIF0(f) { \ if (!(f) || (*env)->ExceptionCheck(env)) { \ goto bailout; \ } \ } -#define _throw(msg, exceptionClass) { \ +#define THROW(msg, exceptionClass) { \ jclass _exccls = (*env)->FindClass(env, exceptionClass); \ \ - bailif0(_exccls); \ + BAILIF0(_exccls); \ (*env)->ThrowNew(env, _exccls, msg); \ goto bailout; \ } -#define _throwtj() { \ +#define THROW_TJ() { \ jclass _exccls; \ jmethodID _excid; \ jobject _excobj; \ jstring _errstr; \ \ - bailif0(_errstr = (*env)->NewStringUTF(env, tjGetErrorStr2(handle))); \ - bailif0(_exccls = (*env)->FindClass(env, \ + BAILIF0(_errstr = (*env)->NewStringUTF(env, tjGetErrorStr2(handle))); \ + BAILIF0(_exccls = (*env)->FindClass(env, \ "org/libjpegturbo/turbojpeg/TJException")); \ - bailif0(_excid = (*env)->GetMethodID(env, _exccls, "<init>", \ + BAILIF0(_excid = (*env)->GetMethodID(env, _exccls, "<init>", \ "(Ljava/lang/String;I)V")); \ - bailif0(_excobj = (*env)->NewObject(env, _exccls, _excid, _errstr, \ + BAILIF0(_excobj = (*env)->NewObject(env, _exccls, _excid, _errstr, \ tjGetErrorCode(handle))); \ (*env)->Throw(env, _excobj); \ goto bailout; \ } -#define _throwarg(msg) _throw(msg, "java/lang/IllegalArgumentException") +#define THROW_ARG(msg) THROW(msg, "java/lang/IllegalArgumentException") -#define _throwmem() \ - _throw("Memory allocation failure", "java/lang/OutOfMemoryError"); +#define THROW_MEM() \ + THROW("Memory allocation failure", "java/lang/OutOfMemoryError"); -#define gethandle() \ +#define GET_HANDLE() \ jclass _cls = (*env)->GetObjectClass(env, obj); \ jfieldID _fid; \ \ - bailif0(_cls); \ - bailif0(_fid = (*env)->GetFieldID(env, _cls, "handle", "J")); \ + BAILIF0(_cls); \ + BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "handle", "J")); \ handle = (tjhandle)(size_t)(*env)->GetLongField(env, obj, _fid); #ifdef _WIN32 #define setenv(envvar, value, dummy) _putenv_s(envvar, value) #endif -#define prop2env(property, envvar) { \ +#define PROP2ENV(property, envvar) { \ if ((jName = (*env)->NewStringUTF(env, property)) != NULL && \ (jValue = (*env)->CallStaticObjectMethod(env, cls, mid, \ jName)) != NULL) { \ @@ -105,14 +105,14 @@ int ProcessSystemProperties(JNIEnv *env) jstring jName, jValue; const char *value; - bailif0(cls = (*env)->FindClass(env, "java/lang/System")); - bailif0(mid = (*env)->GetStaticMethodID(env, cls, "getProperty", + BAILIF0(cls = (*env)->FindClass(env, "java/lang/System")); + BAILIF0(mid = (*env)->GetStaticMethodID(env, cls, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;")); - prop2env("turbojpeg.optimize", "TJ_OPTIMIZE"); - prop2env("turbojpeg.arithmetic", "TJ_ARITHMETIC"); - prop2env("turbojpeg.restart", "TJ_RESTART"); - prop2env("turbojpeg.progressive", "TJ_PROGRESSIVE"); + PROP2ENV("turbojpeg.optimize", "TJ_OPTIMIZE"); + PROP2ENV("turbojpeg.arithmetic", "TJ_ARITHMETIC"); + PROP2ENV("turbojpeg.restart", "TJ_RESTART"); + PROP2ENV("turbojpeg.progressive", "TJ_PROGRESSIVE"); return 0; bailout: @@ -125,7 +125,7 @@ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSize { jint retval = (jint)tjBufSize(width, height, jpegSubsamp); - if (retval == -1) _throwarg(tjGetErrorStr()); + if (retval == -1) THROW_ARG(tjGetErrorStr()); bailout: return retval; @@ -137,7 +137,7 @@ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__IIII { jint retval = (jint)tjBufSizeYUV2(width, pad, height, subsamp); - if (retval == -1) _throwarg(tjGetErrorStr()); + if (retval == -1) THROW_ARG(tjGetErrorStr()); bailout: return retval; @@ -160,7 +160,7 @@ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_planeSizeYUV__IIIII jint retval = (jint)tjPlaneSizeYUV(componentID, width, stride, height, subsamp); - if (retval == -1) _throwarg(tjGetErrorStr()); + if (retval == -1) THROW_ARG(tjGetErrorStr()); bailout: return retval; @@ -172,7 +172,7 @@ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_planeWidth__III { jint retval = (jint)tjPlaneWidth(componentID, width, subsamp); - if (retval == -1) _throwarg(tjGetErrorStr()); + if (retval == -1) THROW_ARG(tjGetErrorStr()); bailout: return retval; @@ -184,7 +184,7 @@ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_planeHeight__III { jint retval = (jint)tjPlaneHeight(componentID, height, subsamp); - if (retval == -1) _throwarg(tjGetErrorStr()); + if (retval == -1) THROW_ARG(tjGetErrorStr()); bailout: return retval; @@ -199,10 +199,10 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_init tjhandle handle; if ((handle = tjInitCompress()) == NULL) - _throw(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException"); + THROW(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException"); - bailif0(cls = (*env)->GetObjectClass(env, obj)); - bailif0(fid = (*env)->GetFieldID(env, cls, "handle", "J")); + BAILIF0(cls = (*env)->GetObjectClass(env, obj)); + BAILIF0(fid = (*env)->GetFieldID(env, cls, "handle", "J")); (*env)->SetLongField(env, obj, fid, (size_t)handle); bailout: @@ -219,31 +219,31 @@ static jint TJCompressor_compress jsize arraySize = 0, actualPitch; unsigned char *srcBuf = NULL, *jpegBuf = NULL; - gethandle(); + GET_HANDLE(); if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF || width < 1 || height < 1 || pitch < 0) - _throwarg("Invalid argument in compress()"); + THROW_ARG("Invalid argument in compress()"); if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF) - _throwarg("Mismatch between Java and C API"); + THROW_ARG("Mismatch between Java and C API"); actualPitch = (pitch == 0) ? width * tjPixelSize[pf] : pitch; arraySize = (y + height - 1) * actualPitch + (x + width) * tjPixelSize[pf]; if ((*env)->GetArrayLength(env, src) * srcElementSize < arraySize) - _throwarg("Source buffer is not large enough"); + THROW_ARG("Source buffer is not large enough"); jpegSize = tjBufSize(width, height, jpegSubsamp); if ((*env)->GetArrayLength(env, dst) < (jsize)jpegSize) - _throwarg("Destination buffer is not large enough"); + THROW_ARG("Destination buffer is not large enough"); if (ProcessSystemProperties(env) < 0) goto bailout; - bailif0(srcBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); - bailif0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); + BAILIF0(srcBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); + BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); if (tjCompress2(handle, &srcBuf[y * actualPitch + x * tjPixelSize[pf]], width, pitch, height, pf, &jpegBuf, &jpegSize, jpegSubsamp, jpegQual, flags | TJFLAG_NOREALLOC) == -1) - _throwtj(); + THROW_TJ(); bailout: if (jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0); @@ -278,9 +278,9 @@ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3 jint jpegQual, jint flags) { if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) - _throwarg("Invalid argument in compress()"); + THROW_ARG("Invalid argument in compress()"); if (tjPixelSize[pf] != sizeof(jint)) - _throwarg("Pixel format must be 32-bit when compressing from an integer buffer."); + THROW_ARG("Pixel format must be 32-bit when compressing from an integer buffer."); return TJCompressor_compress(env, obj, src, sizeof(jint), x, y, width, stride * sizeof(jint), height, pf, dst, @@ -297,9 +297,9 @@ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3 jint flags) { if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) - _throwarg("Invalid argument in compress()"); + THROW_ARG("Invalid argument in compress()"); if (tjPixelSize[pf] != sizeof(jint)) - _throwarg("Pixel format must be 32-bit when compressing from an integer buffer."); + THROW_ARG("Pixel format must be 32-bit when compressing from an integer buffer."); return TJCompressor_compress(env, obj, src, sizeof(jint), 0, 0, width, stride * sizeof(jint), height, pf, dst, @@ -323,54 +323,54 @@ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compressFrom int *srcOffsets = NULL, *srcStrides = NULL; int nc = (subsamp == org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY ? 1 : 3), i; - gethandle(); + GET_HANDLE(); if (subsamp < 0 || subsamp >= org_libjpegturbo_turbojpeg_TJ_NUMSAMP) - _throwarg("Invalid argument in compressFromYUV()"); + THROW_ARG("Invalid argument in compressFromYUV()"); if (org_libjpegturbo_turbojpeg_TJ_NUMSAMP != TJ_NUMSAMP) - _throwarg("Mismatch between Java and C API"); + THROW_ARG("Mismatch between Java and C API"); if ((*env)->GetArrayLength(env, srcobjs) < nc) - _throwarg("Planes array is too small for the subsampling type"); + THROW_ARG("Planes array is too small for the subsampling type"); if ((*env)->GetArrayLength(env, jSrcOffsets) < nc) - _throwarg("Offsets array is too small for the subsampling type"); + THROW_ARG("Offsets array is too small for the subsampling type"); if ((*env)->GetArrayLength(env, jSrcStrides) < nc) - _throwarg("Strides array is too small for the subsampling type"); + THROW_ARG("Strides array is too small for the subsampling type"); jpegSize = tjBufSize(width, height, subsamp); if ((*env)->GetArrayLength(env, dst) < (jsize)jpegSize) - _throwarg("Destination buffer is not large enough"); + THROW_ARG("Destination buffer is not large enough"); if (ProcessSystemProperties(env) < 0) goto bailout; - bailif0(srcOffsets = (*env)->GetPrimitiveArrayCritical(env, jSrcOffsets, 0)); - bailif0(srcStrides = (*env)->GetPrimitiveArrayCritical(env, jSrcStrides, 0)); + BAILIF0(srcOffsets = (*env)->GetPrimitiveArrayCritical(env, jSrcOffsets, 0)); + BAILIF0(srcStrides = (*env)->GetPrimitiveArrayCritical(env, jSrcStrides, 0)); for (i = 0; i < nc; i++) { int planeSize = tjPlaneSizeYUV(i, width, srcStrides[i], height, subsamp); int pw = tjPlaneWidth(i, width, subsamp); if (planeSize < 0 || pw < 0) - _throwarg(tjGetErrorStr()); + THROW_ARG(tjGetErrorStr()); if (srcOffsets[i] < 0) - _throwarg("Invalid argument in compressFromYUV()"); + THROW_ARG("Invalid argument in compressFromYUV()"); if (srcStrides[i] < 0 && srcOffsets[i] - planeSize + pw < 0) - _throwarg("Negative plane stride would cause memory to be accessed below plane boundary"); + THROW_ARG("Negative plane stride would cause memory to be accessed below plane boundary"); - bailif0(jSrcPlanes[i] = (*env)->GetObjectArrayElement(env, srcobjs, i)); + BAILIF0(jSrcPlanes[i] = (*env)->GetObjectArrayElement(env, srcobjs, i)); if ((*env)->GetArrayLength(env, jSrcPlanes[i]) < srcOffsets[i] + planeSize) - _throwarg("Source plane is not large enough"); + THROW_ARG("Source plane is not large enough"); - bailif0(srcPlanes[i] = + BAILIF0(srcPlanes[i] = (*env)->GetPrimitiveArrayCritical(env, jSrcPlanes[i], 0)); srcPlanes[i] = &srcPlanes[i][srcOffsets[i]]; } - bailif0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); + BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); if (tjCompressFromYUVPlanes(handle, srcPlanes, width, srcStrides, height, subsamp, &jpegBuf, &jpegSize, jpegQual, flags | TJFLAG_NOREALLOC) == -1) - _throwtj(); + THROW_TJ(); bailout: if (jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0); @@ -398,56 +398,56 @@ static void TJCompressor_encodeYUV int *dstOffsets = NULL, *dstStrides = NULL; int nc = (subsamp == org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY ? 1 : 3), i; - gethandle(); + GET_HANDLE(); if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF || width < 1 || height < 1 || pitch < 0 || subsamp < 0 || subsamp >= org_libjpegturbo_turbojpeg_TJ_NUMSAMP) - _throwarg("Invalid argument in encodeYUV()"); + THROW_ARG("Invalid argument in encodeYUV()"); if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF || org_libjpegturbo_turbojpeg_TJ_NUMSAMP != TJ_NUMSAMP) - _throwarg("Mismatch between Java and C API"); + THROW_ARG("Mismatch between Java and C API"); if ((*env)->GetArrayLength(env, dstobjs) < nc) - _throwarg("Planes array is too small for the subsampling type"); + THROW_ARG("Planes array is too small for the subsampling type"); if ((*env)->GetArrayLength(env, jDstOffsets) < nc) - _throwarg("Offsets array is too small for the subsampling type"); + THROW_ARG("Offsets array is too small for the subsampling type"); if ((*env)->GetArrayLength(env, jDstStrides) < nc) - _throwarg("Strides array is too small for the subsampling type"); + THROW_ARG("Strides array is too small for the subsampling type"); actualPitch = (pitch == 0) ? width * tjPixelSize[pf] : pitch; arraySize = (y + height - 1) * actualPitch + (x + width) * tjPixelSize[pf]; if ((*env)->GetArrayLength(env, src) * srcElementSize < arraySize) - _throwarg("Source buffer is not large enough"); + THROW_ARG("Source buffer is not large enough"); - bailif0(dstOffsets = (*env)->GetPrimitiveArrayCritical(env, jDstOffsets, 0)); - bailif0(dstStrides = (*env)->GetPrimitiveArrayCritical(env, jDstStrides, 0)); + BAILIF0(dstOffsets = (*env)->GetPrimitiveArrayCritical(env, jDstOffsets, 0)); + BAILIF0(dstStrides = (*env)->GetPrimitiveArrayCritical(env, jDstStrides, 0)); for (i = 0; i < nc; i++) { int planeSize = tjPlaneSizeYUV(i, width, dstStrides[i], height, subsamp); int pw = tjPlaneWidth(i, width, subsamp); if (planeSize < 0 || pw < 0) - _throwarg(tjGetErrorStr()); + THROW_ARG(tjGetErrorStr()); if (dstOffsets[i] < 0) - _throwarg("Invalid argument in encodeYUV()"); + THROW_ARG("Invalid argument in encodeYUV()"); if (dstStrides[i] < 0 && dstOffsets[i] - planeSize + pw < 0) - _throwarg("Negative plane stride would cause memory to be accessed below plane boundary"); + THROW_ARG("Negative plane stride would cause memory to be accessed below plane boundary"); - bailif0(jDstPlanes[i] = (*env)->GetObjectArrayElement(env, dstobjs, i)); + BAILIF0(jDstPlanes[i] = (*env)->GetObjectArrayElement(env, dstobjs, i)); if ((*env)->GetArrayLength(env, jDstPlanes[i]) < dstOffsets[i] + planeSize) - _throwarg("Destination plane is not large enough"); + THROW_ARG("Destination plane is not large enough"); - bailif0(dstPlanes[i] = + BAILIF0(dstPlanes[i] = (*env)->GetPrimitiveArrayCritical(env, jDstPlanes[i], 0)); dstPlanes[i] = &dstPlanes[i][dstOffsets[i]]; } - bailif0(srcBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); + BAILIF0(srcBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); if (tjEncodeYUVPlanes(handle, &srcBuf[y * actualPitch + x * tjPixelSize[pf]], width, pitch, height, pf, dstPlanes, dstStrides, subsamp, flags) == -1) - _throwtj(); + THROW_TJ(); bailout: if (srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0); @@ -479,9 +479,9 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___ jintArray jDstOffsets, jintArray jDstStrides, jint subsamp, jint flags) { if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) - _throwarg("Invalid argument in encodeYUV()"); + THROW_ARG("Invalid argument in encodeYUV()"); if (tjPixelSize[pf] != sizeof(jint)) - _throwarg("Pixel format must be 32-bit when encoding from an integer buffer."); + THROW_ARG("Pixel format must be 32-bit when encoding from an integer buffer."); TJCompressor_encodeYUV(env, obj, src, sizeof(jint), x, y, width, stride * sizeof(jint), height, pf, dstobjs, @@ -499,27 +499,27 @@ JNIEXPORT void JNICALL TJCompressor_encodeYUV_12 jsize arraySize = 0; unsigned char *srcBuf = NULL, *dstBuf = NULL; - gethandle(); + GET_HANDLE(); if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF || width < 1 || height < 1 || pitch < 0) - _throwarg("Invalid argument in encodeYUV()"); + THROW_ARG("Invalid argument in encodeYUV()"); if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF) - _throwarg("Mismatch between Java and C API"); + THROW_ARG("Mismatch between Java and C API"); arraySize = (pitch == 0) ? width * tjPixelSize[pf] * height : pitch * height; if ((*env)->GetArrayLength(env, src) * srcElementSize < arraySize) - _throwarg("Source buffer is not large enough"); + THROW_ARG("Source buffer is not large enough"); if ((*env)->GetArrayLength(env, dst) < (jsize)tjBufSizeYUV(width, height, subsamp)) - _throwarg("Destination buffer is not large enough"); + THROW_ARG("Destination buffer is not large enough"); - bailif0(srcBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); - bailif0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); + BAILIF0(srcBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); + BAILIF0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); if (tjEncodeYUV2(handle, srcBuf, width, pitch, height, pf, dstBuf, subsamp, flags) == -1) - _throwtj(); + THROW_TJ(); bailout: if (dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0); @@ -541,9 +541,9 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___ jint height, jint pf, jbyteArray dst, jint subsamp, jint flags) { if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) - _throwarg("Invalid argument in encodeYUV()"); + THROW_ARG("Invalid argument in encodeYUV()"); if (tjPixelSize[pf] != sizeof(jint)) - _throwarg("Pixel format must be 32-bit when encoding from an integer buffer."); + THROW_ARG("Pixel format must be 32-bit when encoding from an integer buffer."); TJCompressor_encodeYUV_12(env, obj, src, sizeof(jint), width, stride * sizeof(jint), height, pf, dst, subsamp, @@ -559,9 +559,9 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy { tjhandle handle = 0; - gethandle(); + GET_HANDLE(); - if (tjDestroy(handle) == -1) _throwtj(); + if (tjDestroy(handle) == -1) THROW_TJ(); (*env)->SetLongField(env, obj, _fid, 0); bailout: @@ -577,10 +577,10 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_init tjhandle handle; if ((handle = tjInitDecompress()) == NULL) - _throw(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException"); + THROW(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException"); - bailif0(cls = (*env)->GetObjectClass(env, obj)); - bailif0(fid = (*env)->GetFieldID(env, cls, "handle", "J")); + BAILIF0(cls = (*env)->GetObjectClass(env, obj)); + BAILIF0(fid = (*env)->GetFieldID(env, cls, "handle", "J")); (*env)->SetLongField(env, obj, fid, (size_t)handle); bailout: @@ -599,17 +599,17 @@ JNIEXPORT jobjectArray JNICALL Java_org_libjpegturbo_turbojpeg_TJ_getScalingFact jobjectArray sfjava = NULL; if ((sf = tjGetScalingFactors(&n)) == NULL || n == 0) - _throwarg(tjGetErrorStr()); + THROW_ARG(tjGetErrorStr()); - bailif0(sfcls = (*env)->FindClass(env, + BAILIF0(sfcls = (*env)->FindClass(env, "org/libjpegturbo/turbojpeg/TJScalingFactor")); - bailif0(sfjava = (jobjectArray)(*env)->NewObjectArray(env, n, sfcls, 0)); + BAILIF0(sfjava = (jobjectArray)(*env)->NewObjectArray(env, n, sfcls, 0)); for (i = 0; i < n; i++) { - bailif0(sfobj = (*env)->AllocObject(env, sfcls)); - bailif0(fid = (*env)->GetFieldID(env, sfcls, "num", "I")); + BAILIF0(sfobj = (*env)->AllocObject(env, sfcls)); + BAILIF0(fid = (*env)->GetFieldID(env, sfcls, "num", "I")); (*env)->SetIntField(env, sfobj, fid, sf[i].num); - bailif0(fid = (*env)->GetFieldID(env, sfcls, "denom", "I")); + BAILIF0(fid = (*env)->GetFieldID(env, sfcls, "denom", "I")); (*env)->SetIntField(env, sfobj, fid, sf[i].denom); (*env)->SetObjectArrayElement(env, sfjava, i, sfobj); } @@ -626,29 +626,29 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress unsigned char *jpegBuf = NULL; int width = 0, height = 0, jpegSubsamp = -1, jpegColorspace = -1; - gethandle(); + GET_HANDLE(); if ((*env)->GetArrayLength(env, src) < jpegSize) - _throwarg("Source buffer is not large enough"); + THROW_ARG("Source buffer is not large enough"); - bailif0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); + BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); if (tjDecompressHeader3(handle, jpegBuf, (unsigned long)jpegSize, &width, &height, &jpegSubsamp, &jpegColorspace) == -1) - _throwtj(); + THROW_TJ(); (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0); jpegBuf = NULL; - bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I")); + BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I")); (*env)->SetIntField(env, obj, _fid, jpegSubsamp); if ((_fid = (*env)->GetFieldID(env, _cls, "jpegColorspace", "I")) == 0) (*env)->ExceptionClear(env); else (*env)->SetIntField(env, obj, _fid, jpegColorspace); - bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I")); + BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I")); (*env)->SetIntField(env, obj, _fid, width); - bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I")); + BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I")); (*env)->SetIntField(env, obj, _fid, height); bailout: @@ -664,27 +664,27 @@ static void TJDecompressor_decompress jsize arraySize = 0, actualPitch; unsigned char *jpegBuf = NULL, *dstBuf = NULL; - gethandle(); + GET_HANDLE(); if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) - _throwarg("Invalid argument in decompress()"); + THROW_ARG("Invalid argument in decompress()"); if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF) - _throwarg("Mismatch between Java and C API"); + THROW_ARG("Mismatch between Java and C API"); if ((*env)->GetArrayLength(env, src) < jpegSize) - _throwarg("Source buffer is not large enough"); + THROW_ARG("Source buffer is not large enough"); actualPitch = (pitch == 0) ? width * tjPixelSize[pf] : pitch; arraySize = (y + height - 1) * actualPitch + (x + width) * tjPixelSize[pf]; if ((*env)->GetArrayLength(env, dst) * dstElementSize < arraySize) - _throwarg("Destination buffer is not large enough"); + THROW_ARG("Destination buffer is not large enough"); - bailif0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); - bailif0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); + BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); + BAILIF0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); if (tjDecompress2(handle, jpegBuf, (unsigned long)jpegSize, &dstBuf[y * actualPitch + x * tjPixelSize[pf]], width, pitch, height, pf, flags) == -1) - _throwtj(); + THROW_TJ(); bailout: if (dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0); @@ -715,9 +715,9 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress jint x, jint y, jint width, jint stride, jint height, jint pf, jint flags) { if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) - _throwarg("Invalid argument in decompress()"); + THROW_ARG("Invalid argument in decompress()"); if (tjPixelSize[pf] != sizeof(jint)) - _throwarg("Pixel format must be 32-bit when decompressing to an integer buffer."); + THROW_ARG("Pixel format must be 32-bit when decompressing to an integer buffer."); TJDecompressor_decompress(env, obj, src, jpegSize, dst, sizeof(jint), x, y, width, stride * sizeof(jint), height, pf, flags); @@ -732,9 +732,9 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress jint width, jint stride, jint height, jint pf, jint flags) { if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) - _throwarg("Invalid argument in decompress()"); + THROW_ARG("Invalid argument in decompress()"); if (tjPixelSize[pf] != sizeof(jint)) - _throwarg("Pixel format must be 32-bit when decompressing to an integer buffer."); + THROW_ARG("Pixel format must be 32-bit when decompressing to an integer buffer."); TJDecompressor_decompress(env, obj, src, jpegSize, dst, sizeof(jint), 0, 0, width, stride * sizeof(jint), height, pf, flags); @@ -757,15 +757,15 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress int nc = 0, i, width, height, scaledWidth, scaledHeight, nsf = 0; tjscalingfactor *sf; - gethandle(); + GET_HANDLE(); if ((*env)->GetArrayLength(env, src) < jpegSize) - _throwarg("Source buffer is not large enough"); - bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I")); + THROW_ARG("Source buffer is not large enough"); + BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I")); jpegSubsamp = (int)(*env)->GetIntField(env, obj, _fid); - bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I")); + BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I")); jpegWidth = (int)(*env)->GetIntField(env, obj, _fid); - bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I")); + BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I")); jpegHeight = (int)(*env)->GetIntField(env, obj, _fid); nc = (jpegSubsamp == org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY ? 1 : 3); @@ -776,7 +776,7 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress if (height == 0) height = jpegHeight; sf = tjGetScalingFactors(&nsf); if (!sf || nsf < 1) - _throwarg(tjGetErrorStr()); + THROW_ARG(tjGetErrorStr()); for (i = 0; i < nsf; i++) { scaledWidth = TJSCALED(jpegWidth, sf[i]); scaledHeight = TJSCALED(jpegHeight, sf[i]); @@ -784,37 +784,37 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress break; } if (i >= nsf) - _throwarg("Could not scale down to desired image dimensions"); + THROW_ARG("Could not scale down to desired image dimensions"); - bailif0(dstOffsets = (*env)->GetPrimitiveArrayCritical(env, jDstOffsets, 0)); - bailif0(dstStrides = (*env)->GetPrimitiveArrayCritical(env, jDstStrides, 0)); + BAILIF0(dstOffsets = (*env)->GetPrimitiveArrayCritical(env, jDstOffsets, 0)); + BAILIF0(dstStrides = (*env)->GetPrimitiveArrayCritical(env, jDstStrides, 0)); for (i = 0; i < nc; i++) { int planeSize = tjPlaneSizeYUV(i, scaledWidth, dstStrides[i], scaledHeight, jpegSubsamp); int pw = tjPlaneWidth(i, scaledWidth, jpegSubsamp); if (planeSize < 0 || pw < 0) - _throwarg(tjGetErrorStr()); + THROW_ARG(tjGetErrorStr()); if (dstOffsets[i] < 0) - _throwarg("Invalid argument in decompressToYUV()"); + THROW_ARG("Invalid argument in decompressToYUV()"); if (dstStrides[i] < 0 && dstOffsets[i] - planeSize + pw < 0) - _throwarg("Negative plane stride would cause memory to be accessed below plane boundary"); + THROW_ARG("Negative plane stride would cause memory to be accessed below plane boundary"); - bailif0(jDstPlanes[i] = (*env)->GetObjectArrayElement(env, dstobjs, i)); + BAILIF0(jDstPlanes[i] = (*env)->GetObjectArrayElement(env, dstobjs, i)); if ((*env)->GetArrayLength(env, jDstPlanes[i]) < dstOffsets[i] + planeSize) - _throwarg("Destination plane is not large enough"); + THROW_ARG("Destination plane is not large enough"); - bailif0(dstPlanes[i] = + BAILIF0(dstPlanes[i] = (*env)->GetPrimitiveArrayCritical(env, jDstPlanes[i], 0)); dstPlanes[i] = &dstPlanes[i][dstOffsets[i]]; } - bailif0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); + BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); if (tjDecompressToYUVPlanes(handle, jpegBuf, (unsigned long)jpegSize, dstPlanes, desiredWidth, dstStrides, desiredHeight, flags) == -1) - _throwtj(); + THROW_TJ(); bailout: if (jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0); @@ -838,26 +838,26 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress unsigned char *jpegBuf = NULL, *dstBuf = NULL; int jpegSubsamp = -1, jpegWidth = 0, jpegHeight = 0; - gethandle(); + GET_HANDLE(); if ((*env)->GetArrayLength(env, src) < jpegSize) - _throwarg("Source buffer is not large enough"); - bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I")); + THROW_ARG("Source buffer is not large enough"); + BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I")); jpegSubsamp = (int)(*env)->GetIntField(env, obj, _fid); - bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I")); + BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I")); jpegWidth = (int)(*env)->GetIntField(env, obj, _fid); - bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I")); + BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I")); jpegHeight = (int)(*env)->GetIntField(env, obj, _fid); if ((*env)->GetArrayLength(env, dst) < (jsize)tjBufSizeYUV(jpegWidth, jpegHeight, jpegSubsamp)) - _throwarg("Destination buffer is not large enough"); + THROW_ARG("Destination buffer is not large enough"); - bailif0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); - bailif0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); + BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); + BAILIF0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); if (tjDecompressToYUV(handle, jpegBuf, (unsigned long)jpegSize, dstBuf, flags) == -1) - _throwtj(); + THROW_TJ(); bailout: if (dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0); @@ -877,55 +877,55 @@ static void TJDecompressor_decodeYUV int *srcOffsets = NULL, *srcStrides = NULL; int nc = (subsamp == org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY ? 1 : 3), i; - gethandle(); + GET_HANDLE(); if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF || subsamp < 0 || subsamp >= org_libjpegturbo_turbojpeg_TJ_NUMSAMP) - _throwarg("Invalid argument in decodeYUV()"); + THROW_ARG("Invalid argument in decodeYUV()"); if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF || org_libjpegturbo_turbojpeg_TJ_NUMSAMP != TJ_NUMSAMP) - _throwarg("Mismatch between Java and C API"); + THROW_ARG("Mismatch between Java and C API"); if ((*env)->GetArrayLength(env, srcobjs) < nc) - _throwarg("Planes array is too small for the subsampling type"); + THROW_ARG("Planes array is too small for the subsampling type"); if ((*env)->GetArrayLength(env, jSrcOffsets) < nc) - _throwarg("Offsets array is too small for the subsampling type"); + THROW_ARG("Offsets array is too small for the subsampling type"); if ((*env)->GetArrayLength(env, jSrcStrides) < nc) - _throwarg("Strides array is too small for the subsampling type"); + THROW_ARG("Strides array is too small for the subsampling type"); actualPitch = (pitch == 0) ? width * tjPixelSize[pf] : pitch; arraySize = (y + height - 1) * actualPitch + (x + width) * tjPixelSize[pf]; if ((*env)->GetArrayLength(env, dst) * dstElementSize < arraySize) - _throwarg("Destination buffer is not large enough"); + THROW_ARG("Destination buffer is not large enough"); - bailif0(srcOffsets = (*env)->GetPrimitiveArrayCritical(env, jSrcOffsets, 0)); - bailif0(srcStrides = (*env)->GetPrimitiveArrayCritical(env, jSrcStrides, 0)); + BAILIF0(srcOffsets = (*env)->GetPrimitiveArrayCritical(env, jSrcOffsets, 0)); + BAILIF0(srcStrides = (*env)->GetPrimitiveArrayCritical(env, jSrcStrides, 0)); for (i = 0; i < nc; i++) { int planeSize = tjPlaneSizeYUV(i, width, srcStrides[i], height, subsamp); int pw = tjPlaneWidth(i, width, subsamp); if (planeSize < 0 || pw < 0) - _throwarg(tjGetErrorStr()); + THROW_ARG(tjGetErrorStr()); if (srcOffsets[i] < 0) - _throwarg("Invalid argument in decodeYUV()"); + THROW_ARG("Invalid argument in decodeYUV()"); if (srcStrides[i] < 0 && srcOffsets[i] - planeSize + pw < 0) - _throwarg("Negative plane stride would cause memory to be accessed below plane boundary"); + THROW_ARG("Negative plane stride would cause memory to be accessed below plane boundary"); - bailif0(jSrcPlanes[i] = (*env)->GetObjectArrayElement(env, srcobjs, i)); + BAILIF0(jSrcPlanes[i] = (*env)->GetObjectArrayElement(env, srcobjs, i)); if ((*env)->GetArrayLength(env, jSrcPlanes[i]) < srcOffsets[i] + planeSize) - _throwarg("Source plane is not large enough"); + THROW_ARG("Source plane is not large enough"); - bailif0(srcPlanes[i] = + BAILIF0(srcPlanes[i] = (*env)->GetPrimitiveArrayCritical(env, jSrcPlanes[i], 0)); srcPlanes[i] = &srcPlanes[i][srcOffsets[i]]; } - bailif0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); + BAILIF0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); if (tjDecodeYUVPlanes(handle, srcPlanes, srcStrides, subsamp, &dstBuf[y * actualPitch + x * tjPixelSize[pf]], width, pitch, height, pf, flags) == -1) - _throwtj(); + THROW_TJ(); bailout: if (dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0); @@ -958,9 +958,9 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decodeYUV_ jint width, jint stride, jint height, jint pf, jint flags) { if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) - _throwarg("Invalid argument in decodeYUV()"); + THROW_ARG("Invalid argument in decodeYUV()"); if (tjPixelSize[pf] != sizeof(jint)) - _throwarg("Pixel format must be 32-bit when decoding to an integer buffer."); + THROW_ARG("Pixel format must be 32-bit when decoding to an integer buffer."); TJDecompressor_decodeYUV(env, obj, srcobjs, jSrcOffsets, jSrcStrides, subsamp, dst, sizeof(jint), x, y, width, @@ -979,10 +979,10 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_init tjhandle handle; if ((handle = tjInitTransform()) == NULL) - _throw(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException"); + THROW(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException"); - bailif0(cls = (*env)->GetObjectClass(env, obj)); - bailif0(fid = (*env)->GetFieldID(env, cls, "handle", "J")); + BAILIF0(cls = (*env)->GetObjectClass(env, obj)); + BAILIF0(fid = (*env)->GetFieldID(env, cls, "handle", "J")); (*env)->SetLongField(env, obj, fid, (size_t)handle); bailout: @@ -1007,43 +1007,43 @@ static int JNICustomFilter(short *coeffs, tjregion arrayRegion, jmethodID mid; jfieldID fid; - bailif0(bufobj = (*env)->NewDirectByteBuffer(env, coeffs, + BAILIF0(bufobj = (*env)->NewDirectByteBuffer(env, coeffs, sizeof(short) * arrayRegion.w * arrayRegion.h)); - bailif0(cls = (*env)->FindClass(env, "java/nio/ByteOrder")); - bailif0(mid = (*env)->GetStaticMethodID(env, cls, "nativeOrder", + BAILIF0(cls = (*env)->FindClass(env, "java/nio/ByteOrder")); + BAILIF0(mid = (*env)->GetStaticMethodID(env, cls, "nativeOrder", "()Ljava/nio/ByteOrder;")); - bailif0(borobj = (*env)->CallStaticObjectMethod(env, cls, mid)); - bailif0(cls = (*env)->GetObjectClass(env, bufobj)); - bailif0(mid = (*env)->GetMethodID(env, cls, "order", + BAILIF0(borobj = (*env)->CallStaticObjectMethod(env, cls, mid)); + BAILIF0(cls = (*env)->GetObjectClass(env, bufobj)); + BAILIF0(mid = (*env)->GetMethodID(env, cls, "order", "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;")); (*env)->CallObjectMethod(env, bufobj, mid, borobj); - bailif0(mid = (*env)->GetMethodID(env, cls, "asShortBuffer", + BAILIF0(mid = (*env)->GetMethodID(env, cls, "asShortBuffer", "()Ljava/nio/ShortBuffer;")); - bailif0(bufobj = (*env)->CallObjectMethod(env, bufobj, mid)); + BAILIF0(bufobj = (*env)->CallObjectMethod(env, bufobj, mid)); - bailif0(cls = (*env)->FindClass(env, "java/awt/Rectangle")); - bailif0(arrayRegionObj = (*env)->AllocObject(env, cls)); - bailif0(fid = (*env)->GetFieldID(env, cls, "x", "I")); + BAILIF0(cls = (*env)->FindClass(env, "java/awt/Rectangle")); + BAILIF0(arrayRegionObj = (*env)->AllocObject(env, cls)); + BAILIF0(fid = (*env)->GetFieldID(env, cls, "x", "I")); (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.x); - bailif0(fid = (*env)->GetFieldID(env, cls, "y", "I")); + BAILIF0(fid = (*env)->GetFieldID(env, cls, "y", "I")); (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.y); - bailif0(fid = (*env)->GetFieldID(env, cls, "width", "I")); + BAILIF0(fid = (*env)->GetFieldID(env, cls, "width", "I")); (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.w); - bailif0(fid = (*env)->GetFieldID(env, cls, "height", "I")); + BAILIF0(fid = (*env)->GetFieldID(env, cls, "height", "I")); (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.h); - bailif0(planeRegionObj = (*env)->AllocObject(env, cls)); - bailif0(fid = (*env)->GetFieldID(env, cls, "x", "I")); + BAILIF0(planeRegionObj = (*env)->AllocObject(env, cls)); + BAILIF0(fid = (*env)->GetFieldID(env, cls, "x", "I")); (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.x); - bailif0(fid = (*env)->GetFieldID(env, cls, "y", "I")); + BAILIF0(fid = (*env)->GetFieldID(env, cls, "y", "I")); (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.y); - bailif0(fid = (*env)->GetFieldID(env, cls, "width", "I")); + BAILIF0(fid = (*env)->GetFieldID(env, cls, "width", "I")); (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.w); - bailif0(fid = (*env)->GetFieldID(env, cls, "height", "I")); + BAILIF0(fid = (*env)->GetFieldID(env, cls, "height", "I")); (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.h); - bailif0(cls = (*env)->GetObjectClass(env, cfobj)); - bailif0(mid = (*env)->GetMethodID(env, cls, "customFilter", + BAILIF0(cls = (*env)->GetObjectClass(env, cfobj)); + BAILIF0(mid = (*env)->GetMethodID(env, cls, "customFilter", "(Ljava/nio/ShortBuffer;Ljava/awt/Rectangle;Ljava/awt/Rectangle;IILorg/libjpegturbo/turbojpeg/TJTransform;)V")); (*env)->CallVoidMethod(env, cfobj, mid, bufobj, arrayRegionObj, planeRegionObj, componentIndex, transformIndex, tobj); @@ -1070,33 +1070,33 @@ JNIEXPORT jintArray JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_transf jint *dstSizesi = NULL; JNICustomFilterParams *params = NULL; - gethandle(); + GET_HANDLE(); if ((*env)->GetArrayLength(env, jsrcBuf) < jpegSize) - _throwarg("Source buffer is not large enough"); - bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I")); + THROW_ARG("Source buffer is not large enough"); + BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I")); jpegWidth = (int)(*env)->GetIntField(env, obj, _fid); - bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I")); + BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I")); jpegHeight = (int)(*env)->GetIntField(env, obj, _fid); - bailif0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I")); + BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I")); jpegSubsamp = (int)(*env)->GetIntField(env, obj, _fid); n = (*env)->GetArrayLength(env, dstobjs); if (n != (*env)->GetArrayLength(env, tobjs)) - _throwarg("Mismatch between size of transforms array and destination buffers array"); + THROW_ARG("Mismatch between size of transforms array and destination buffers array"); if ((dstBufs = (unsigned char **)malloc(sizeof(unsigned char *) * n)) == NULL) - _throwmem(); + THROW_MEM(); if ((jdstBufs = (jbyteArray *)malloc(sizeof(jbyteArray) * n)) == NULL) - _throwmem(); + THROW_MEM(); if ((dstSizes = (unsigned long *)malloc(sizeof(unsigned long) * n)) == NULL) - _throwmem(); + THROW_MEM(); if ((t = (tjtransform *)malloc(sizeof(tjtransform) * n)) == NULL) - _throwmem(); + THROW_MEM(); if ((params = (JNICustomFilterParams *)malloc(sizeof(JNICustomFilterParams) * n)) == NULL) - _throwmem(); + THROW_MEM(); for (i = 0; i < n; i++) { dstBufs[i] = NULL; jdstBufs[i] = NULL; dstSizes[i] = 0; memset(&t[i], 0, sizeof(tjtransform)); @@ -1106,22 +1106,22 @@ JNIEXPORT jintArray JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_transf for (i = 0; i < n; i++) { jobject tobj, cfobj; - bailif0(tobj = (*env)->GetObjectArrayElement(env, tobjs, i)); - bailif0(_cls = (*env)->GetObjectClass(env, tobj)); - bailif0(_fid = (*env)->GetFieldID(env, _cls, "op", "I")); + BAILIF0(tobj = (*env)->GetObjectArrayElement(env, tobjs, i)); + BAILIF0(_cls = (*env)->GetObjectClass(env, tobj)); + BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "op", "I")); t[i].op = (*env)->GetIntField(env, tobj, _fid); - bailif0(_fid = (*env)->GetFieldID(env, _cls, "options", "I")); + BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "options", "I")); t[i].options = (*env)->GetIntField(env, tobj, _fid); - bailif0(_fid = (*env)->GetFieldID(env, _cls, "x", "I")); + BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "x", "I")); t[i].r.x = (*env)->GetIntField(env, tobj, _fid); - bailif0(_fid = (*env)->GetFieldID(env, _cls, "y", "I")); + BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "y", "I")); t[i].r.y = (*env)->GetIntField(env, tobj, _fid); - bailif0(_fid = (*env)->GetFieldID(env, _cls, "width", "I")); + BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "width", "I")); t[i].r.w = (*env)->GetIntField(env, tobj, _fid); - bailif0(_fid = (*env)->GetFieldID(env, _cls, "height", "I")); + BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "height", "I")); t[i].r.h = (*env)->GetIntField(env, tobj, _fid); - bailif0(_fid = (*env)->GetFieldID(env, _cls, "cf", + BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "cf", "Lorg/libjpegturbo/turbojpeg/TJCustomFilter;")); cfobj = (*env)->GetObjectField(env, tobj, _fid); if (cfobj) { @@ -1138,19 +1138,19 @@ JNIEXPORT jintArray JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_transf if (t[i].r.w != 0) w = t[i].r.w; if (t[i].r.h != 0) h = t[i].r.h; - bailif0(jdstBufs[i] = (*env)->GetObjectArrayElement(env, dstobjs, i)); + BAILIF0(jdstBufs[i] = (*env)->GetObjectArrayElement(env, dstobjs, i)); if ((unsigned long)(*env)->GetArrayLength(env, jdstBufs[i]) < tjBufSize(w, h, jpegSubsamp)) - _throwarg("Destination buffer is not large enough"); + THROW_ARG("Destination buffer is not large enough"); } - bailif0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, jsrcBuf, 0)); + BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, jsrcBuf, 0)); for (i = 0; i < n; i++) - bailif0(dstBufs[i] = + BAILIF0(dstBufs[i] = (*env)->GetPrimitiveArrayCritical(env, jdstBufs[i], 0)); if (tjTransform(handle, jpegBuf, jpegSize, n, dstBufs, dstSizes, t, flags | TJFLAG_NOREALLOC) == -1) - _throwtj(); + THROW_TJ(); for (i = 0; i < n; i++) { (*env)->ReleasePrimitiveArrayCritical(env, jdstBufs[i], dstBufs[i], 0); @@ -1160,7 +1160,7 @@ JNIEXPORT jintArray JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_transf jpegBuf = NULL; jdstSizes = (*env)->NewIntArray(env, n); - bailif0(dstSizesi = (*env)->GetIntArrayElements(env, jdstSizes, 0)); + BAILIF0(dstSizesi = (*env)->GetIntArrayElements(env, jdstSizes, 0)); for (i = 0; i < n; i++) dstSizesi[i] = (int)dstSizes[i]; bailout: diff --git a/turbojpeg.c b/turbojpeg.c index b3caa0d4..1f99786f 100644 --- a/turbojpeg.c +++ b/turbojpeg.c @@ -50,7 +50,7 @@ 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) */ @@ -164,20 +164,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 +190,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 +202,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; \ \ @@ -413,7 +413,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); @@ -489,11 +489,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 @@ -501,36 +501,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++) { @@ -539,11 +544,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) @@ -562,10 +569,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) @@ -583,10 +590,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) @@ -602,11 +609,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); @@ -615,10 +622,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; } @@ -630,21 +639,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. */ @@ -670,9 +679,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], @@ -723,7 +732,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++) { @@ -732,17 +741,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]; @@ -767,7 +776,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); @@ -778,12 +787,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]; @@ -795,11 +804,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); @@ -812,10 +821,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); @@ -827,7 +836,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; @@ -877,12 +886,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); @@ -939,7 +948,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++) { @@ -947,14 +956,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. */ @@ -993,7 +1002,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; @@ -1002,11 +1011,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]; @@ -1070,12 +1079,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); @@ -1154,13 +1163,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. */ @@ -1185,11 +1194,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; @@ -1238,14 +1247,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"); @@ -1274,7 +1283,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; @@ -1284,16 +1293,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], @@ -1386,7 +1395,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++) { @@ -1394,14 +1403,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. */ @@ -1409,7 +1418,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; @@ -1445,12 +1454,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]; @@ -1461,10 +1470,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); @@ -1476,7 +1485,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; @@ -1525,12 +1534,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); @@ -1569,7 +1578,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++) { @@ -1577,11 +1586,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"); @@ -1601,10 +1610,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; @@ -1616,9 +1625,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; @@ -1642,7 +1651,7 @@ DLLEXPORT int tjDecompressToYUVPlanes(tjhandle handle, 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; @@ -1651,11 +1660,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]; @@ -1736,12 +1745,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. */ @@ -1752,7 +1761,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; @@ -1765,7 +1774,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); @@ -1830,14 +1839,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"); @@ -1847,7 +1856,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)) { @@ -1885,11 +1894,11 @@ 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 || @@ -1952,7 +1961,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; } } @@ -1989,21 +1998,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. */ @@ -2014,14 +2023,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); @@ -2034,7 +2043,7 @@ DLLEXPORT unsigned char *tjLoadImage(const char *filename, int *width, 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"); + THROWG("tjLoadImage(): Memory allocation failure"); if (setjmp(this->jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. */ @@ -2081,7 +2090,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; @@ -2089,7 +2098,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. */ @@ -2104,11 +2113,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; } |