diff options
author | Jonathan Wright <jonathan.wright@arm.com> | 2020-11-25 13:36:43 +0000 |
---|---|---|
committer | Jonathan Wright <jonathan.wright@arm.com> | 2020-11-30 12:08:32 +0000 |
commit | bbb828223e9c8f83f0e84db1e98b116029e62765 (patch) | |
tree | d2467975e2bf1442216d2c779054102ee37f599c /turbojpeg-jni.c | |
parent | d5148db386ceb4a608058320071cbed890bd6ad2 (diff) |
Update libjpeg-turbo to v2.0.90 (2.1 beta1)
Update Chromium's copy of libjpeg-turbo to the latest upstream
release (v2.0.90) and re-apply our local changes documented in
README.chromium.
Cherry-pick two additional changes from upstream to fix bugs found
by fuzzers:
1) https://github.com/libjpeg-turbo/libjpeg-turbo/commit/ccaba5d7894ecfb5a8f11e48d3f86e1f14d5a469
2) https://github.com/libjpeg-turbo/libjpeg-turbo/commit/c7ca521bc85b57d41d3ad4963c13fc0100481084
Significant changes provided by this update:
1) A large performance boost to JPEG encoding due to an improved
Huffman encoding implementation.
2) The complete removal of Arm Neon assembly code. This allows Arm's
control-flow integrity security features (Armv8.3-A Pointer
Authentication and Armv8.5-A Branch Target Identification) to be
switched on with the appropriate compiler flags.
Bug: 922430
Bug: b/135180511
Bug: 919548, 1145581
Change-Id: I319fcdc55b3fd5b219425c07a4e4a03587f4e06d
Diffstat (limited to 'turbojpeg-jni.c')
-rw-r--r-- | turbojpeg-jni.c | 200 |
1 files changed, 91 insertions, 109 deletions
diff --git a/turbojpeg-jni.c b/turbojpeg-jni.c index 9363450..1b728e3 100644 --- a/turbojpeg-jni.c +++ b/turbojpeg-jni.c @@ -1,5 +1,5 @@ /* - * Copyright (C)2011-2019 D. R. Commander. All Rights Reserved. + * Copyright (C)2011-2020 D. R. Commander. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -326,9 +326,11 @@ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compressFrom tjhandle handle = 0; unsigned long jpegSize = 0; jbyteArray jSrcPlanes[3] = { NULL, NULL, NULL }; - const unsigned char *srcPlanes[3]; + const unsigned char *srcPlanesTmp[3] = { NULL, NULL, NULL }; + const unsigned char *srcPlanes[3] = { NULL, NULL, NULL }; + int *srcOffsetsTmp = NULL, srcOffsets[3] = { 0, 0, 0 }; + int *srcStridesTmp = NULL, srcStrides[3] = { 0, 0, 0 }; unsigned char *jpegBuf = NULL; - int *srcOffsets = NULL, *srcStrides = NULL; int nc = (subsamp == org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY ? 1 : 3), i; GET_HANDLE(); @@ -351,56 +353,49 @@ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compressFrom if (ProcessSystemProperties(env) < 0) goto bailout; -#define RELEASE_ARRAYS_COMPRESSFROMYUV() { \ - SAFE_RELEASE(dst, jpegBuf); \ - for (i = 0; i < nc; i++) \ - SAFE_RELEASE(jSrcPlanes[i], srcPlanes[i]); \ - SAFE_RELEASE(jSrcStrides, srcStrides); \ - SAFE_RELEASE(jSrcOffsets, srcOffsets); \ -} + BAILIF0(srcOffsetsTmp = + (*env)->GetPrimitiveArrayCritical(env, jSrcOffsets, 0)); + for (i = 0; i < nc; i++) srcOffsets[i] = srcOffsetsTmp[i]; + SAFE_RELEASE(jSrcOffsets, srcOffsetsTmp); + + BAILIF0(srcStridesTmp = + (*env)->GetPrimitiveArrayCritical(env, jSrcStrides, 0)); + for (i = 0; i < nc; i++) srcStrides[i] = srcStridesTmp[i]; + SAFE_RELEASE(jSrcStrides, srcStridesTmp); - 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) { - RELEASE_ARRAYS_COMPRESSFROMYUV(); + if (planeSize < 0 || pw < 0) THROW_ARG(tjGetErrorStr()); - } - if (srcOffsets[i] < 0) { - RELEASE_ARRAYS_COMPRESSFROMYUV(); + if (srcOffsets[i] < 0) THROW_ARG("Invalid argument in compressFromYUV()"); - } - if (srcStrides[i] < 0 && srcOffsets[i] - planeSize + pw < 0) { - RELEASE_ARRAYS_COMPRESSFROMYUV(); + if (srcStrides[i] < 0 && srcOffsets[i] - planeSize + pw < 0) THROW_ARG("Negative plane stride would cause memory to be accessed below plane boundary"); - } BAILIF0(jSrcPlanes[i] = (*env)->GetObjectArrayElement(env, srcobjs, i)); if ((*env)->GetArrayLength(env, jSrcPlanes[i]) < - srcOffsets[i] + planeSize) { - RELEASE_ARRAYS_COMPRESSFROMYUV(); + srcOffsets[i] + planeSize) THROW_ARG("Source plane is not large enough"); - } - BAILIF0(srcPlanes[i] = + BAILIF0(srcPlanesTmp[i] = (*env)->GetPrimitiveArrayCritical(env, jSrcPlanes[i], 0)); - srcPlanes[i] = &srcPlanes[i][srcOffsets[i]]; + srcPlanes[i] = &srcPlanesTmp[i][srcOffsets[i]]; + SAFE_RELEASE(jSrcPlanes[i], srcPlanesTmp[i]); } BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); if (tjCompressFromYUVPlanes(handle, srcPlanes, width, srcStrides, height, subsamp, &jpegBuf, &jpegSize, jpegQual, flags | TJFLAG_NOREALLOC) == -1) { - RELEASE_ARRAYS_COMPRESSFROMYUV(); + SAFE_RELEASE(dst, jpegBuf); THROW_TJ(); } bailout: - RELEASE_ARRAYS_COMPRESSFROMYUV(); + SAFE_RELEASE(dst, jpegBuf); return (jint)jpegSize; } @@ -411,9 +406,12 @@ static void TJCompressor_encodeYUV { tjhandle handle = 0; jsize arraySize = 0, actualPitch; + unsigned char *srcBuf = NULL; jbyteArray jDstPlanes[3] = { NULL, NULL, NULL }; - unsigned char *srcBuf = NULL, *dstPlanes[3]; - int *dstOffsets = NULL, *dstStrides = NULL; + unsigned char *dstPlanesTmp[3] = { NULL, NULL, NULL }; + unsigned char *dstPlanes[3] = { NULL, NULL, NULL }; + int *dstOffsetsTmp = NULL, dstOffsets[3] = { 0, 0, 0 }; + int *dstStridesTmp = NULL, dstStrides[3] = { 0, 0, 0 }; int nc = (subsamp == org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY ? 1 : 3), i; GET_HANDLE(); @@ -438,56 +436,49 @@ static void TJCompressor_encodeYUV if ((*env)->GetArrayLength(env, src) * srcElementSize < arraySize) THROW_ARG("Source buffer is not large enough"); -#define RELEASE_ARRAYS_ENCODEYUV() { \ - SAFE_RELEASE(src, srcBuf); \ - for (i = 0; i < nc; i++) \ - SAFE_RELEASE(jDstPlanes[i], dstPlanes[i]); \ - SAFE_RELEASE(jDstStrides, dstStrides); \ - SAFE_RELEASE(jDstOffsets, dstOffsets); \ -} + BAILIF0(dstOffsetsTmp = + (*env)->GetPrimitiveArrayCritical(env, jDstOffsets, 0)); + for (i = 0; i < nc; i++) dstOffsets[i] = dstOffsetsTmp[i]; + SAFE_RELEASE(jDstOffsets, dstOffsetsTmp); + + BAILIF0(dstStridesTmp = + (*env)->GetPrimitiveArrayCritical(env, jDstStrides, 0)); + for (i = 0; i < nc; i++) dstStrides[i] = dstStridesTmp[i]; + SAFE_RELEASE(jDstStrides, dstStridesTmp); - 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) { - RELEASE_ARRAYS_ENCODEYUV(); + if (planeSize < 0 || pw < 0) THROW_ARG(tjGetErrorStr()); - } - if (dstOffsets[i] < 0) { - RELEASE_ARRAYS_ENCODEYUV(); + if (dstOffsets[i] < 0) THROW_ARG("Invalid argument in encodeYUV()"); - } - if (dstStrides[i] < 0 && dstOffsets[i] - planeSize + pw < 0) { - RELEASE_ARRAYS_ENCODEYUV(); + if (dstStrides[i] < 0 && dstOffsets[i] - planeSize + pw < 0) THROW_ARG("Negative plane stride would cause memory to be accessed below plane boundary"); - } BAILIF0(jDstPlanes[i] = (*env)->GetObjectArrayElement(env, dstobjs, i)); if ((*env)->GetArrayLength(env, jDstPlanes[i]) < - dstOffsets[i] + planeSize) { - RELEASE_ARRAYS_ENCODEYUV(); + dstOffsets[i] + planeSize) THROW_ARG("Destination plane is not large enough"); - } - BAILIF0(dstPlanes[i] = + BAILIF0(dstPlanesTmp[i] = (*env)->GetPrimitiveArrayCritical(env, jDstPlanes[i], 0)); - dstPlanes[i] = &dstPlanes[i][dstOffsets[i]]; + dstPlanes[i] = &dstPlanesTmp[i][dstOffsets[i]]; + SAFE_RELEASE(jDstPlanes[i], dstPlanesTmp[i]); } 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) { - RELEASE_ARRAYS_ENCODEYUV(); + SAFE_RELEASE(src, srcBuf); THROW_TJ(); } bailout: - RELEASE_ARRAYS_ENCODEYUV(); + SAFE_RELEASE(src, srcBuf); } /* TurboJPEG 1.4.x: TJCompressor::encodeYUV() byte source */ @@ -785,9 +776,12 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress jintArray jDstStrides, jint desiredHeight, jint flags) { tjhandle handle = 0; + unsigned char *jpegBuf = NULL; jbyteArray jDstPlanes[3] = { NULL, NULL, NULL }; - unsigned char *jpegBuf = NULL, *dstPlanes[3]; - int *dstOffsets = NULL, *dstStrides = NULL; + unsigned char *dstPlanesTmp[3] = { NULL, NULL, NULL }; + unsigned char *dstPlanes[3] = { NULL, NULL, NULL }; + int *dstOffsetsTmp = NULL, dstOffsets[3] = { 0, 0, 0 }; + int *dstStridesTmp = NULL, dstStrides[3] = { 0, 0, 0 }; int jpegSubsamp = -1, jpegWidth = 0, jpegHeight = 0; int nc = 0, i, width, height, scaledWidth, scaledHeight, nsf = 0; tjscalingfactor *sf; @@ -821,57 +815,50 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress if (i >= nsf) THROW_ARG("Could not scale down to desired image dimensions"); -#define RELEASE_ARRAYS_DECOMPRESSTOYUV() { \ - SAFE_RELEASE(src, jpegBuf); \ - for (i = 0; i < nc; i++) \ - SAFE_RELEASE(jDstPlanes[i], dstPlanes[i]); \ - SAFE_RELEASE(jDstStrides, dstStrides); \ - SAFE_RELEASE(jDstOffsets, dstOffsets); \ -} + BAILIF0(dstOffsetsTmp = + (*env)->GetPrimitiveArrayCritical(env, jDstOffsets, 0)); + for (i = 0; i < nc; i++) dstOffsets[i] = dstOffsetsTmp[i]; + SAFE_RELEASE(jDstOffsets, dstOffsetsTmp); + + BAILIF0(dstStridesTmp = + (*env)->GetPrimitiveArrayCritical(env, jDstStrides, 0)); + for (i = 0; i < nc; i++) dstStrides[i] = dstStridesTmp[i]; + SAFE_RELEASE(jDstStrides, dstStridesTmp); - 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) { - RELEASE_ARRAYS_DECOMPRESSTOYUV(); + if (planeSize < 0 || pw < 0) THROW_ARG(tjGetErrorStr()); - } - if (dstOffsets[i] < 0) { - RELEASE_ARRAYS_DECOMPRESSTOYUV(); + if (dstOffsets[i] < 0) THROW_ARG("Invalid argument in decompressToYUV()"); - } - if (dstStrides[i] < 0 && dstOffsets[i] - planeSize + pw < 0) { - RELEASE_ARRAYS_DECOMPRESSTOYUV(); + if (dstStrides[i] < 0 && dstOffsets[i] - planeSize + pw < 0) THROW_ARG("Negative plane stride would cause memory to be accessed below plane boundary"); - } BAILIF0(jDstPlanes[i] = (*env)->GetObjectArrayElement(env, dstobjs, i)); if ((*env)->GetArrayLength(env, jDstPlanes[i]) < - dstOffsets[i] + planeSize) { - RELEASE_ARRAYS_DECOMPRESSTOYUV(); + dstOffsets[i] + planeSize) THROW_ARG("Destination plane is not large enough"); - } - BAILIF0(dstPlanes[i] = + BAILIF0(dstPlanesTmp[i] = (*env)->GetPrimitiveArrayCritical(env, jDstPlanes[i], 0)); - dstPlanes[i] = &dstPlanes[i][dstOffsets[i]]; + dstPlanes[i] = &dstPlanesTmp[i][dstOffsets[i]]; + SAFE_RELEASE(jDstPlanes[i], dstPlanesTmp[i]); } BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); if (tjDecompressToYUVPlanes(handle, jpegBuf, (unsigned long)jpegSize, dstPlanes, desiredWidth, dstStrides, desiredHeight, flags) == -1) { - RELEASE_ARRAYS_DECOMPRESSTOYUV(); + SAFE_RELEASE(src, jpegBuf); THROW_TJ(); } bailout: - RELEASE_ARRAYS_DECOMPRESSTOYUV(); + SAFE_RELEASE(src, jpegBuf); } /* TurboJPEG 1.2.x: TJDecompressor::decompressToYUV() */ @@ -920,9 +907,11 @@ static void TJDecompressor_decodeYUV tjhandle handle = 0; jsize arraySize = 0, actualPitch; jbyteArray jSrcPlanes[3] = { NULL, NULL, NULL }; - const unsigned char *srcPlanes[3]; + const unsigned char *srcPlanesTmp[3] = { NULL, NULL, NULL }; + const unsigned char *srcPlanes[3] = { NULL, NULL, NULL }; + int *srcOffsetsTmp = NULL, srcOffsets[3] = { 0, 0, 0 }; + int *srcStridesTmp = NULL, srcStrides[3] = { 0, 0, 0 }; unsigned char *dstBuf = NULL; - int *srcOffsets = NULL, *srcStrides = NULL; int nc = (subsamp == org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY ? 1 : 3), i; GET_HANDLE(); @@ -946,56 +935,49 @@ static void TJDecompressor_decodeYUV if ((*env)->GetArrayLength(env, dst) * dstElementSize < arraySize) THROW_ARG("Destination buffer is not large enough"); -#define RELEASE_ARRAYS_DECODEYUV() { \ - SAFE_RELEASE(dst, dstBuf); \ - for (i = 0; i < nc; i++) \ - SAFE_RELEASE(jSrcPlanes[i], srcPlanes[i]); \ - SAFE_RELEASE(jSrcStrides, srcStrides); \ - SAFE_RELEASE(jSrcOffsets, srcOffsets); \ -} + BAILIF0(srcOffsetsTmp = + (*env)->GetPrimitiveArrayCritical(env, jSrcOffsets, 0)); + for (i = 0; i < nc; i++) srcOffsets[i] = srcOffsetsTmp[i]; + SAFE_RELEASE(jSrcOffsets, srcOffsetsTmp); + + BAILIF0(srcStridesTmp = + (*env)->GetPrimitiveArrayCritical(env, jSrcStrides, 0)); + for (i = 0; i < nc; i++) srcStrides[i] = srcStridesTmp[i]; + SAFE_RELEASE(jSrcStrides, srcStridesTmp); - 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) { - RELEASE_ARRAYS_DECODEYUV(); + if (planeSize < 0 || pw < 0) THROW_ARG(tjGetErrorStr()); - } - if (srcOffsets[i] < 0) { - RELEASE_ARRAYS_DECODEYUV(); + if (srcOffsets[i] < 0) THROW_ARG("Invalid argument in decodeYUV()"); - } - if (srcStrides[i] < 0 && srcOffsets[i] - planeSize + pw < 0) { - RELEASE_ARRAYS_DECODEYUV(); + if (srcStrides[i] < 0 && srcOffsets[i] - planeSize + pw < 0) THROW_ARG("Negative plane stride would cause memory to be accessed below plane boundary"); - } BAILIF0(jSrcPlanes[i] = (*env)->GetObjectArrayElement(env, srcobjs, i)); if ((*env)->GetArrayLength(env, jSrcPlanes[i]) < - srcOffsets[i] + planeSize) { - RELEASE_ARRAYS_DECODEYUV(); + srcOffsets[i] + planeSize) THROW_ARG("Source plane is not large enough"); - } - BAILIF0(srcPlanes[i] = + BAILIF0(srcPlanesTmp[i] = (*env)->GetPrimitiveArrayCritical(env, jSrcPlanes[i], 0)); - srcPlanes[i] = &srcPlanes[i][srcOffsets[i]]; + srcPlanes[i] = &srcPlanesTmp[i][srcOffsets[i]]; + SAFE_RELEASE(jSrcPlanes[i], srcPlanesTmp[i]); } 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) { - RELEASE_ARRAYS_DECODEYUV(); + SAFE_RELEASE(dst, dstBuf); THROW_TJ(); } bailout: - RELEASE_ARRAYS_DECODEYUV(); + SAFE_RELEASE(dst, dstBuf); } /* TurboJPEG 1.4.x: TJDecompressor::decodeYUV() byte destination */ |