/*
- * Copyright (C)2011-2014 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:
#include <jni.h>
#include "java/org_libjpegturbo_turbojpeg_TJCompressor.h"
#include "java/org_libjpegturbo_turbojpeg_TJDecompressor.h"
+#include "java/org_libjpegturbo_turbojpeg_TJTransformer.h"
#include "java/org_libjpegturbo_turbojpeg_TJ.h"
-#define PAD(v, p) ((v+(p)-1)&(~((p)-1)))
+#define BAILIF0(f) { \
+ if (!(f) || (*env)->ExceptionCheck(env)) { \
+ goto bailout; \
+ } \
+}
+
+#define THROW(msg, exceptionClass) { \
+ jclass _exccls = (*env)->FindClass(env, exceptionClass); \
+ \
+ BAILIF0(_exccls); \
+ (*env)->ThrowNew(env, _exccls, msg); \
+ goto bailout; \
+}
-#define _throw(msg) { \
- jclass _exccls=(*env)->FindClass(env, "java/lang/Exception"); \
- if(!_exccls) goto bailout; \
- (*env)->ThrowNew(env, _exccls, msg); \
- goto bailout; \
+#define THROW_TJ() { \
+ jclass _exccls; \
+ jmethodID _excid; \
+ jobject _excobj; \
+ jstring _errstr; \
+ \
+ BAILIF0(_errstr = (*env)->NewStringUTF(env, tjGetErrorStr2(handle))); \
+ BAILIF0(_exccls = (*env)->FindClass(env, \
+ "org/libjpegturbo/turbojpeg/TJException")); \
+ BAILIF0(_excid = (*env)->GetMethodID(env, _exccls, "<init>", \
+ "(Ljava/lang/String;I)V")); \
+ BAILIF0(_excobj = (*env)->NewObject(env, _exccls, _excid, _errstr, \
+ tjGetErrorCode(handle))); \
+ (*env)->Throw(env, _excobj); \
+ goto bailout; \
}
-#define bailif0(f) {if(!(f)) { \
- char temps[80]; \
- snprintf(temps, 80, "Unexpected NULL condition in line %d", __LINE__); \
- _throw(temps); \
-}}
+#define THROW_ARG(msg) THROW(msg, "java/lang/IllegalArgumentException")
-#define gethandle() \
- jclass _cls=(*env)->GetObjectClass(env, obj); \
- jfieldID _fid; \
- if(!_cls) goto bailout; \
- bailif0(_fid=(*env)->GetFieldID(env, _cls, "handle", "J")); \
- handle=(tjhandle)(size_t)(*env)->GetLongField(env, obj, _fid); \
+#define THROW_MEM() \
+ THROW("Memory allocation failure", "java/lang/OutOfMemoryError");
+
+#define GET_HANDLE() \
+ jclass _cls = (*env)->GetObjectClass(env, obj); \
+ jfieldID _fid; \
+ \
+ 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)
+#define setenv(envvar, value, dummy) _putenv_s(envvar, value)
#endif
-#define prop2env(property, envvar) \
-{ \
- if((jName=(*env)->NewStringUTF(env, property))!=NULL \
- && (jValue=(*env)->CallStaticObjectMethod(env, cls, mid, jName))!=NULL) \
- { \
- if((value=(*env)->GetStringUTFChars(env, jValue, 0))!=NULL) \
- { \
- setenv(envvar, value, 1); \
- (*env)->ReleaseStringUTFChars(env, jValue, value); \
- } \
- } \
+#define PROP2ENV(property, envvar) { \
+ if ((jName = (*env)->NewStringUTF(env, property)) != NULL && \
+ (jValue = (*env)->CallStaticObjectMethod(env, cls, mid, \
+ jName)) != NULL) { \
+ if ((value = (*env)->GetStringUTFChars(env, jValue, 0)) != NULL) { \
+ setenv(envvar, value, 1); \
+ (*env)->ReleaseStringUTFChars(env, jValue, value); \
+ } \
+ } \
+}
+
+#define SAFE_RELEASE(javaArray, cArray) { \
+ if (javaArray && cArray) \
+ (*env)->ReleasePrimitiveArrayCritical(env, javaArray, (void *)cArray, 0); \
+ cArray = NULL; \
}
-int ProcessSystemProperties(JNIEnv *env)
+static int ProcessSystemProperties(JNIEnv *env)
{
- jclass cls; jmethodID mid;
- jstring jName, jValue;
- const char *value;
-
- 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");
- return 0;
-
- bailout:
- return -1;
+ jclass cls;
+ jmethodID mid;
+ jstring jName, jValue;
+ const char *value;
+
+ 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");
+ return 0;
+
+bailout:
+ return -1;
}
/* TurboJPEG 1.2.x: TJ::bufSize() */
JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSize
- (JNIEnv *env, jclass cls, jint width, jint height, jint jpegSubsamp)
+ (JNIEnv *env, jclass cls, jint width, jint height, jint jpegSubsamp)
{
- jint retval=(jint)tjBufSize(width, height, jpegSubsamp);
- if(retval==-1) _throw(tjGetErrorStr());
+ jint retval = (jint)tjBufSize(width, height, jpegSubsamp);
+
+ if (retval == -1) THROW_ARG(tjGetErrorStr());
- bailout:
- return retval;
+bailout:
+ return retval;
}
/* TurboJPEG 1.4.x: TJ::bufSizeYUV() */
JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__IIII
- (JNIEnv *env, jclass cls, jint width, jint pad, jint height, jint subsamp)
+ (JNIEnv *env, jclass cls, jint width, jint pad, jint height, jint subsamp)
{
- jint retval=(jint)tjBufSizeYUV2(width, pad, height, subsamp);
- if(retval==-1) _throw(tjGetErrorStr());
+ jint retval = (jint)tjBufSizeYUV2(width, pad, height, subsamp);
+
+ if (retval == -1) THROW_ARG(tjGetErrorStr());
- bailout:
- return retval;
+bailout:
+ return retval;
}
/* TurboJPEG 1.2.x: TJ::bufSizeYUV() */
JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__III
- (JNIEnv *env, jclass cls, jint width, jint height, jint subsamp)
+ (JNIEnv *env, jclass cls, jint width, jint height, jint subsamp)
{
- return Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__IIII(env, cls, width,
- 4, height, subsamp);
+ return Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__IIII(env, cls, width,
+ 4, height,
+ subsamp);
}
/* TurboJPEG 1.4.x: TJ::planeSizeYUV() */
JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_planeSizeYUV__IIIII
- (JNIEnv *env, jclass cls, jint componentID, jint width, jint stride,
- jint height, jint subsamp)
+ (JNIEnv *env, jclass cls, jint componentID, jint width, jint stride,
+ jint height, jint subsamp)
{
- jint retval=(jint)tjPlaneSizeYUV(componentID, width, stride, height,
- subsamp);
- if(retval==-1) _throw(tjGetErrorStr());
+ jint retval = (jint)tjPlaneSizeYUV(componentID, width, stride, height,
+ subsamp);
- bailout:
- return retval;
+ if (retval == -1) THROW_ARG(tjGetErrorStr());
+
+bailout:
+ return retval;
}
/* TurboJPEG 1.4.x: TJ::planeWidth() */
JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_planeWidth__III
- (JNIEnv *env, jclass cls, jint componentID, jint width, jint subsamp)
+ (JNIEnv *env, jclass cls, jint componentID, jint width, jint subsamp)
{
- jint retval=(jint)tjPlaneWidth(componentID, width, subsamp);
- if(retval==-1) _throw(tjGetErrorStr());
+ jint retval = (jint)tjPlaneWidth(componentID, width, subsamp);
+
+ if (retval == -1) THROW_ARG(tjGetErrorStr());
- bailout:
- return retval;
+bailout:
+ return retval;
}
/* TurboJPEG 1.4.x: TJ::planeHeight() */
JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_planeHeight__III
- (JNIEnv *env, jclass cls, jint componentID, jint height, jint subsamp)
+ (JNIEnv *env, jclass cls, jint componentID, jint height, jint subsamp)
{
- jint retval=(jint)tjPlaneHeight(componentID, height, subsamp);
- if(retval==-1) _throw(tjGetErrorStr());
+ jint retval = (jint)tjPlaneHeight(componentID, height, subsamp);
- bailout:
- return retval;
+ if (retval == -1) THROW_ARG(tjGetErrorStr());
+
+bailout:
+ return retval;
}
/* TurboJPEG 1.2.x: TJCompressor::init() */
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_init
- (JNIEnv *env, jobject obj)
+ (JNIEnv *env, jobject obj)
{
- jclass cls;
- jfieldID fid;
- tjhandle handle;
+ jclass cls;
+ jfieldID fid;
+ tjhandle handle;
- if((handle=tjInitCompress())==NULL)
- _throw(tjGetErrorStr());
+ if ((handle = tjInitCompress()) == NULL)
+ THROW(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException");
- bailif0(cls=(*env)->GetObjectClass(env, obj));
- bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J"));
- (*env)->SetLongField(env, obj, fid, (size_t)handle);
+ BAILIF0(cls = (*env)->GetObjectClass(env, obj));
+ BAILIF0(fid = (*env)->GetFieldID(env, cls, "handle", "J"));
+ (*env)->SetLongField(env, obj, fid, (size_t)handle);
- bailout:
- return;
+bailout:
+ return;
}
static jint TJCompressor_compress
- (JNIEnv *env, jobject obj, jarray src, jint srcElementSize, jint x, jint y,
- jint width, jint pitch, jint height, jint pf, jbyteArray dst,
- jint jpegSubsamp, jint jpegQual, jint flags)
+ (JNIEnv *env, jobject obj, jarray src, jint srcElementSize, jint x, jint y,
+ jint width, jint pitch, jint height, jint pf, jbyteArray dst,
+ jint jpegSubsamp, jint jpegQual, jint flags)
{
- tjhandle handle=0;
- unsigned long jpegSize=0;
- jsize arraySize=0, actualPitch;
- unsigned char *srcBuf=NULL, *jpegBuf=NULL;
-
- gethandle();
-
- if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1
- || pitch<0)
- _throw("Invalid argument in compress()");
- if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
- _throw("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)
- _throw("Source buffer is not large enough");
- jpegSize=tjBufSize(width, height, jpegSubsamp);
- if((*env)->GetArrayLength(env, dst)<(jsize)jpegSize)
- _throw("Destination buffer is not large enough");
-
- bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
- bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
-
- if(ProcessSystemProperties(env)<0) goto bailout;
-
- if(tjCompress2(handle, &srcBuf[y*actualPitch + x*tjPixelSize[pf]], width,
- pitch, height, pf, &jpegBuf, &jpegSize, jpegSubsamp, jpegQual,
- flags|TJFLAG_NOREALLOC)==-1)
- _throw(tjGetErrorStr());
-
- bailout:
- if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0);
- if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
- return (jint)jpegSize;
+ tjhandle handle = 0;
+ unsigned long jpegSize = 0;
+ jsize arraySize = 0, actualPitch;
+ unsigned char *srcBuf = NULL, *jpegBuf = NULL;
+
+ GET_HANDLE();
+
+ if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF || width < 1 ||
+ height < 1 || pitch < 0)
+ THROW_ARG("Invalid argument in compress()");
+ if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF)
+ 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)
+ THROW_ARG("Source buffer is not large enough");
+ jpegSize = tjBufSize(width, height, jpegSubsamp);
+ if ((*env)->GetArrayLength(env, dst) < (jsize)jpegSize)
+ 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));
+
+ if (tjCompress2(handle, &srcBuf[y * actualPitch + x * tjPixelSize[pf]],
+ width, pitch, height, pf, &jpegBuf, &jpegSize, jpegSubsamp,
+ jpegQual, flags | TJFLAG_NOREALLOC) == -1) {
+ SAFE_RELEASE(dst, jpegBuf);
+ SAFE_RELEASE(src, srcBuf);
+ THROW_TJ();
+ }
+
+bailout:
+ SAFE_RELEASE(dst, jpegBuf);
+ SAFE_RELEASE(src, srcBuf);
+ return (jint)jpegSize;
}
/* TurboJPEG 1.3.x: TJCompressor::compress() byte source */
JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIIIII_3BIII
- (JNIEnv *env, jobject obj, jbyteArray src, jint x, jint y, jint width,
- jint pitch, jint height, jint pf, jbyteArray dst, jint jpegSubsamp,
- jint jpegQual, jint flags)
+ (JNIEnv *env, jobject obj, jbyteArray src, jint x, jint y, jint width,
+ jint pitch, jint height, jint pf, jbyteArray dst, jint jpegSubsamp,
+ jint jpegQual, jint flags)
{
- return TJCompressor_compress(env, obj, src, 1, x, y, width, pitch, height,
- pf, dst, jpegSubsamp, jpegQual, flags);
+ return TJCompressor_compress(env, obj, src, 1, x, y, width, pitch, height,
+ pf, dst, jpegSubsamp, jpegQual, flags);
}
/* TurboJPEG 1.2.x: TJCompressor::compress() byte source */
JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIII_3BIII
- (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch,
- jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpegQual,
- jint flags)
+ (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch,
+ jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpegQual,
+ jint flags)
{
- return TJCompressor_compress(env, obj, src, 1, 0, 0, width, pitch, height,
- pf, dst, jpegSubsamp, jpegQual, flags);
+ return TJCompressor_compress(env, obj, src, 1, 0, 0, width, pitch, height,
+ pf, dst, jpegSubsamp, jpegQual, flags);
}
/* TurboJPEG 1.3.x: TJCompressor::compress() int source */
JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIIIII_3BIII
- (JNIEnv *env, jobject obj, jintArray src, jint x, jint y, jint width,
- jint stride, jint height, jint pf, jbyteArray dst, jint jpegSubsamp,
- jint jpegQual, jint flags)
+ (JNIEnv *env, jobject obj, jintArray src, jint x, jint y, jint width,
+ jint stride, jint height, jint pf, jbyteArray dst, jint jpegSubsamp,
+ jint jpegQual, jint flags)
{
- if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
- _throw("Invalid argument in compress()");
- if(tjPixelSize[pf]!=sizeof(jint))
- _throw("Pixel format must be 32-bit when compressing from an integer buffer.");
+ if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF)
+ THROW_ARG("Invalid argument in compress()");
+ if (tjPixelSize[pf] != sizeof(jint))
+ 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, jpegSubsamp, jpegQual, flags);
+ return TJCompressor_compress(env, obj, src, sizeof(jint), x, y, width,
+ stride * sizeof(jint), height, pf, dst,
+ jpegSubsamp, jpegQual, flags);
- bailout:
- return 0;
+bailout:
+ return 0;
}
/* TurboJPEG 1.2.x: TJCompressor::compress() int source */
JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIII_3BIII
- (JNIEnv *env, jobject obj, jintArray src, jint width, jint stride,
- jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpegQual,
- jint flags)
+ (JNIEnv *env, jobject obj, jintArray src, jint width, jint stride,
+ jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpegQual,
+ jint flags)
{
- if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
- _throw("Invalid argument in compress()");
- if(tjPixelSize[pf]!=sizeof(jint))
- _throw("Pixel format must be 32-bit when compressing from an integer buffer.");
+ if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF)
+ THROW_ARG("Invalid argument in compress()");
+ if (tjPixelSize[pf] != sizeof(jint))
+ 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, jpegSubsamp, jpegQual, flags);
+ return TJCompressor_compress(env, obj, src, sizeof(jint), 0, 0, width,
+ stride * sizeof(jint), height, pf, dst,
+ jpegSubsamp, jpegQual, flags);
- bailout:
- return 0;
+bailout:
+ return 0;
}
/* TurboJPEG 1.4.x: TJCompressor::compressFromYUV() */
JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compressFromYUV___3_3B_3II_3III_3BII
- (JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets,
- jint width, jintArray jSrcStrides, jint height, jint subsamp,
- jbyteArray dst, jint jpegQual, jint flags)
+ (JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets,
+ jint width, jintArray jSrcStrides, jint height, jint subsamp,
+ jbyteArray dst, jint jpegQual, jint flags)
{
- tjhandle handle=0;
- unsigned long jpegSize=0;
- jbyteArray jSrcPlanes[3]={NULL, NULL, NULL};
- unsigned char *srcPlanes[3], *jpegBuf=NULL;
- int *srcOffsets=NULL, *srcStrides=NULL;
- int nc=(subsamp==org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY? 1:3), i;
-
- gethandle();
-
- if(subsamp<0 || subsamp>=org_libjpegturbo_turbojpeg_TJ_NUMSAMP)
- _throw("Invalid argument in compressFromYUV()");
- if(org_libjpegturbo_turbojpeg_TJ_NUMSAMP!=TJ_NUMSAMP)
- _throw("Mismatch between Java and C API");
-
- if((*env)->GetArrayLength(env, srcobjs)<nc)
- _throw("Planes array is too small for the subsampling type");
- if((*env)->GetArrayLength(env, jSrcOffsets)<nc)
- _throw("Offsets array is too small for the subsampling type");
- if((*env)->GetArrayLength(env, jSrcStrides)<nc)
- _throw("Strides array is too small for the subsampling type");
-
- jpegSize=tjBufSize(width, height, subsamp);
- if((*env)->GetArrayLength(env, dst)<(jsize)jpegSize)
- _throw("Destination buffer is not large enough");
-
- 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)
- _throw(tjGetErrorStr());
-
- if(srcOffsets[i]<0)
- _throw("Invalid argument in compressFromYUV()");
- if(srcStrides[i]<0 && srcOffsets[i]-planeSize+pw<0)
- _throw("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)
- _throw("Source plane is not large enough");
-
- bailif0(srcPlanes[i]=(*env)->GetPrimitiveArrayCritical(env, jSrcPlanes[i],
- 0));
- srcPlanes[i]=&srcPlanes[i][srcOffsets[i]];
- }
- bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
-
- if(ProcessSystemProperties(env)<0) goto bailout;
-
- if(tjCompressFromYUVPlanes(handle, srcPlanes, width, srcStrides, height,
- subsamp, &jpegBuf, &jpegSize, jpegQual, flags|TJFLAG_NOREALLOC)==-1)
- _throw(tjGetErrorStr());
-
- bailout:
- if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0);
- for(i=0; i<nc; i++)
- {
- if(srcPlanes[i] && jSrcPlanes[i])
- (*env)->ReleasePrimitiveArrayCritical(env, jSrcPlanes[i], srcPlanes[i],
- 0);
- }
- if(srcStrides)
- (*env)->ReleasePrimitiveArrayCritical(env, jSrcStrides, srcStrides, 0);
- if(srcOffsets)
- (*env)->ReleasePrimitiveArrayCritical(env, jSrcOffsets, srcOffsets, 0);
- return (jint)jpegSize;
+ tjhandle handle = 0;
+ unsigned long jpegSize = 0;
+ jbyteArray jSrcPlanes[3] = { NULL, NULL, NULL };
+ 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 nc = (subsamp == org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY ? 1 : 3), i;
+
+ GET_HANDLE();
+
+ if (subsamp < 0 || subsamp >= org_libjpegturbo_turbojpeg_TJ_NUMSAMP)
+ THROW_ARG("Invalid argument in compressFromYUV()");
+ if (org_libjpegturbo_turbojpeg_TJ_NUMSAMP != TJ_NUMSAMP)
+ THROW_ARG("Mismatch between Java and C API");
+
+ if ((*env)->GetArrayLength(env, srcobjs) < nc)
+ THROW_ARG("Planes array is too small for the subsampling type");
+ if ((*env)->GetArrayLength(env, jSrcOffsets) < nc)
+ THROW_ARG("Offsets array is too small for the subsampling type");
+ if ((*env)->GetArrayLength(env, jSrcStrides) < nc)
+ THROW_ARG("Strides array is too small for the subsampling type");
+
+ jpegSize = tjBufSize(width, height, subsamp);
+ if ((*env)->GetArrayLength(env, dst) < (jsize)jpegSize)
+ THROW_ARG("Destination buffer is not large enough");
+
+ if (ProcessSystemProperties(env) < 0) goto bailout;
+
+ 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);
+
+ 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)
+ THROW_ARG(tjGetErrorStr());
+
+ if (srcOffsets[i] < 0)
+ THROW_ARG("Invalid argument in 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)
+ THROW_ARG("Source plane is not large enough");
+
+ BAILIF0(srcPlanesTmp[i] =
+ (*env)->GetPrimitiveArrayCritical(env, jSrcPlanes[i], 0));
+ 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) {
+ SAFE_RELEASE(dst, jpegBuf);
+ THROW_TJ();
+ }
+
+bailout:
+ SAFE_RELEASE(dst, jpegBuf);
+ return (jint)jpegSize;
}
static void TJCompressor_encodeYUV
- (JNIEnv *env, jobject obj, jarray src, jint srcElementSize, jint x, jint y,
- jint width, jint pitch, jint height, jint pf, jobjectArray dstobjs,
- jintArray jDstOffsets, jintArray jDstStrides, jint subsamp, jint flags)
+ (JNIEnv *env, jobject obj, jarray src, jint srcElementSize, jint x, jint y,
+ jint width, jint pitch, jint height, jint pf, jobjectArray dstobjs,
+ jintArray jDstOffsets, jintArray jDstStrides, jint subsamp, jint flags)
{
- tjhandle handle=0;
- jsize arraySize=0, actualPitch;
- jbyteArray jDstPlanes[3]={NULL, NULL, NULL};
- unsigned char *srcBuf=NULL, *dstPlanes[3];
- int *dstOffsets=NULL, *dstStrides=NULL;
- int nc=(subsamp==org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY? 1:3), i;
-
- gethandle();
-
- if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1
- || pitch<0 || subsamp<0 || subsamp>=org_libjpegturbo_turbojpeg_TJ_NUMSAMP)
- _throw("Invalid argument in encodeYUV()");
- if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF
- || org_libjpegturbo_turbojpeg_TJ_NUMSAMP!=TJ_NUMSAMP)
- _throw("Mismatch between Java and C API");
-
- if((*env)->GetArrayLength(env, dstobjs)<nc)
- _throw("Planes array is too small for the subsampling type");
- if((*env)->GetArrayLength(env, jDstOffsets)<nc)
- _throw("Offsets array is too small for the subsampling type");
- if((*env)->GetArrayLength(env, jDstStrides)<nc)
- _throw("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)
- _throw("Source buffer is not large enough");
-
- 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)
- _throw(tjGetErrorStr());
-
- if(dstOffsets[i]<0)
- _throw("Invalid argument in encodeYUV()");
- if(dstStrides[i]<0 && dstOffsets[i]-planeSize+pw<0)
- _throw("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)
- _throw("Destination plane is not large enough");
-
- bailif0(dstPlanes[i]=(*env)->GetPrimitiveArrayCritical(env, jDstPlanes[i],
- 0));
- dstPlanes[i]=&dstPlanes[i][dstOffsets[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)
- _throw(tjGetErrorStr());
-
- bailout:
- if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
- for(i=0; i<nc; i++)
- {
- if(dstPlanes[i] && jDstPlanes[i])
- (*env)->ReleasePrimitiveArrayCritical(env, jDstPlanes[i], dstPlanes[i],
- 0);
- }
- if(dstStrides)
- (*env)->ReleasePrimitiveArrayCritical(env, jDstStrides, dstStrides, 0);
- if(dstOffsets)
- (*env)->ReleasePrimitiveArrayCritical(env, jDstOffsets, dstOffsets, 0);
- return;
+ tjhandle handle = 0;
+ jsize arraySize = 0, actualPitch;
+ unsigned char *srcBuf = NULL;
+ jbyteArray jDstPlanes[3] = { NULL, NULL, 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();
+
+ if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF || width < 1 ||
+ height < 1 || pitch < 0 || subsamp < 0 ||
+ subsamp >= org_libjpegturbo_turbojpeg_TJ_NUMSAMP)
+ THROW_ARG("Invalid argument in encodeYUV()");
+ if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF ||
+ org_libjpegturbo_turbojpeg_TJ_NUMSAMP != TJ_NUMSAMP)
+ THROW_ARG("Mismatch between Java and C API");
+
+ if ((*env)->GetArrayLength(env, dstobjs) < nc)
+ THROW_ARG("Planes array is too small for the subsampling type");
+ if ((*env)->GetArrayLength(env, jDstOffsets) < nc)
+ THROW_ARG("Offsets array is too small for the subsampling type");
+ if ((*env)->GetArrayLength(env, jDstStrides) < nc)
+ 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)
+ THROW_ARG("Source buffer is not large enough");
+
+ 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);
+
+ 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)
+ THROW_ARG(tjGetErrorStr());
+
+ if (dstOffsets[i] < 0)
+ THROW_ARG("Invalid argument in 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)
+ THROW_ARG("Destination plane is not large enough");
+
+ BAILIF0(dstPlanesTmp[i] =
+ (*env)->GetPrimitiveArrayCritical(env, jDstPlanes[i], 0));
+ 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) {
+ SAFE_RELEASE(src, srcBuf);
+ THROW_TJ();
+ }
+
+bailout:
+ SAFE_RELEASE(src, srcBuf);
}
/* TurboJPEG 1.4.x: TJCompressor::encodeYUV() byte source */
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIIIII_3_3B_3I_3III
- (JNIEnv *env, jobject obj, jbyteArray src, jint x, jint y, jint width,
- jint pitch, jint height, jint pf, jobjectArray dstobjs,
- jintArray jDstOffsets, jintArray jDstStrides, jint subsamp, jint flags)
+ (JNIEnv *env, jobject obj, jbyteArray src, jint x, jint y, jint width,
+ jint pitch, jint height, jint pf, jobjectArray dstobjs,
+ jintArray jDstOffsets, jintArray jDstStrides, jint subsamp, jint flags)
{
- TJCompressor_encodeYUV(env, obj, src, 1, x, y, width, pitch, height, pf,
- dstobjs, jDstOffsets, jDstStrides, subsamp, flags);
+ TJCompressor_encodeYUV(env, obj, src, 1, x, y, width, pitch, height, pf,
+ dstobjs, jDstOffsets, jDstStrides, subsamp, flags);
}
/* TurboJPEG 1.4.x: TJCompressor::encodeYUV() int source */
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIIIII_3_3B_3I_3III
- (JNIEnv *env, jobject obj, jintArray src, jint x, jint y, jint width,
- jint stride, jint height, jint pf, jobjectArray dstobjs,
- jintArray jDstOffsets, jintArray jDstStrides, jint subsamp, jint flags)
+ (JNIEnv *env, jobject obj, jintArray src, jint x, jint y, jint width,
+ jint stride, jint height, jint pf, jobjectArray dstobjs,
+ jintArray jDstOffsets, jintArray jDstStrides, jint subsamp, jint flags)
{
- if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
- _throw("Invalid argument in encodeYUV()");
- if(tjPixelSize[pf]!=sizeof(jint))
- _throw("Pixel format must be 32-bit when encoding from an integer buffer.");
+ if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF)
+ THROW_ARG("Invalid argument in encodeYUV()");
+ if (tjPixelSize[pf] != sizeof(jint))
+ 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, jDstOffsets, jDstStrides,
- subsamp, flags);
+ TJCompressor_encodeYUV(env, obj, src, sizeof(jint), x, y, width,
+ stride * sizeof(jint), height, pf, dstobjs,
+ jDstOffsets, jDstStrides, subsamp, flags);
- bailout:
- return;
+bailout:
+ return;
}
-JNIEXPORT void JNICALL TJCompressor_encodeYUV_12
- (JNIEnv *env, jobject obj, jarray src, jint srcElementSize, jint width,
- jint pitch, jint height, jint pf, jbyteArray dst, jint subsamp, jint flags)
+static void JNICALL TJCompressor_encodeYUV_12
+ (JNIEnv *env, jobject obj, jarray src, jint srcElementSize, jint width,
+ jint pitch, jint height, jint pf, jbyteArray dst, jint subsamp, jint flags)
{
- tjhandle handle=0;
- jsize arraySize=0;
- unsigned char *srcBuf=NULL, *dstBuf=NULL;
-
- gethandle();
-
- if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1
- || pitch<0)
- _throw("Invalid argument in encodeYUV()");
- if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
- _throw("Mismatch between Java and C API");
-
- arraySize=(pitch==0)? width*tjPixelSize[pf]*height:pitch*height;
- if((*env)->GetArrayLength(env, src)*srcElementSize<arraySize)
- _throw("Source buffer is not large enough");
- if((*env)->GetArrayLength(env, dst)
- <(jsize)tjBufSizeYUV(width, height, subsamp))
- _throw("Destination buffer is not large enough");
-
- 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)
- _throw(tjGetErrorStr());
-
- bailout:
- if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
- if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
- return;
+ tjhandle handle = 0;
+ jsize arraySize = 0;
+ unsigned char *srcBuf = NULL, *dstBuf = NULL;
+
+ GET_HANDLE();
+
+ if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF || width < 1 ||
+ height < 1 || pitch < 0)
+ THROW_ARG("Invalid argument in encodeYUV()");
+ if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF)
+ THROW_ARG("Mismatch between Java and C API");
+
+ arraySize = (pitch == 0) ? width * tjPixelSize[pf] * height : pitch * height;
+ if ((*env)->GetArrayLength(env, src) * srcElementSize < arraySize)
+ THROW_ARG("Source buffer is not large enough");
+ if ((*env)->GetArrayLength(env, dst) <
+ (jsize)tjBufSizeYUV(width, height, subsamp))
+ THROW_ARG("Destination buffer is not large enough");
+
+ 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) {
+ SAFE_RELEASE(dst, dstBuf);
+ SAFE_RELEASE(src, srcBuf);
+ THROW_TJ();
+ }
+
+bailout:
+ SAFE_RELEASE(dst, dstBuf);
+ SAFE_RELEASE(src, srcBuf);
}
/* TurboJPEG 1.2.x: TJCompressor::encodeYUV() byte source */
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIII_3BII
- (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch,
- jint height, jint pf, jbyteArray dst, jint subsamp, jint flags)
+ (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch,
+ jint height, jint pf, jbyteArray dst, jint subsamp, jint flags)
{
- TJCompressor_encodeYUV_12(env, obj, src, 1, width, pitch, height, pf, dst,
- subsamp, flags);
+ TJCompressor_encodeYUV_12(env, obj, src, 1, width, pitch, height, pf, dst,
+ subsamp, flags);
}
/* TurboJPEG 1.2.x: TJCompressor::encodeYUV() int source */
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIII_3BII
- (JNIEnv *env, jobject obj, jintArray src, jint width, jint stride,
- jint height, jint pf, jbyteArray dst, jint subsamp, jint flags)
+ (JNIEnv *env, jobject obj, jintArray src, jint width, jint stride,
+ jint height, jint pf, jbyteArray dst, jint subsamp, jint flags)
{
- if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
- _throw("Invalid argument in encodeYUV()");
- if(tjPixelSize[pf]!=sizeof(jint))
- _throw("Pixel format must be 32-bit when encoding from an integer buffer.");
+ if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF)
+ THROW_ARG("Invalid argument in encodeYUV()");
+ if (tjPixelSize[pf] != sizeof(jint))
+ 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, flags);
+ TJCompressor_encodeYUV_12(env, obj, src, sizeof(jint), width,
+ stride * sizeof(jint), height, pf, dst, subsamp,
+ flags);
- bailout:
- return;
+bailout:
+ return;
}
/* TurboJPEG 1.2.x: TJCompressor::destroy() */
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy
- (JNIEnv *env, jobject obj)
+ (JNIEnv *env, jobject obj)
{
- tjhandle handle=0;
+ tjhandle handle = 0;
- gethandle();
+ GET_HANDLE();
- if(tjDestroy(handle)==-1) _throw(tjGetErrorStr());
- (*env)->SetLongField(env, obj, _fid, 0);
+ if (tjDestroy(handle) == -1) THROW_TJ();
+ (*env)->SetLongField(env, obj, _fid, 0);
- bailout:
- return;
+bailout:
+ return;
}
/* TurboJPEG 1.2.x: TJDecompressor::init() */
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_init
- (JNIEnv *env, jobject obj)
+ (JNIEnv *env, jobject obj)
{
- jclass cls;
- jfieldID fid;
- tjhandle handle;
+ jclass cls;
+ jfieldID fid;
+ tjhandle handle;
- if((handle=tjInitDecompress())==NULL) _throw(tjGetErrorStr());
+ if ((handle = tjInitDecompress()) == NULL)
+ THROW(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException");
- bailif0(cls=(*env)->GetObjectClass(env, obj));
- bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J"));
- (*env)->SetLongField(env, obj, fid, (size_t)handle);
+ BAILIF0(cls = (*env)->GetObjectClass(env, obj));
+ BAILIF0(fid = (*env)->GetFieldID(env, cls, "handle", "J"));
+ (*env)->SetLongField(env, obj, fid, (size_t)handle);
- bailout:
- return;
+bailout:
+ return;
}
/* TurboJPEG 1.2.x: TJDecompressor::getScalingFactors() */
JNIEXPORT jobjectArray JNICALL Java_org_libjpegturbo_turbojpeg_TJ_getScalingFactors
- (JNIEnv *env, jclass cls)
+ (JNIEnv *env, jclass cls)
{
- jclass sfcls=NULL; jfieldID fid=0;
- tjscalingfactor *sf=NULL; int n=0, i;
- jobject sfobj=NULL;
- jobjectArray sfjava=NULL;
-
- if((sf=tjGetScalingFactors(&n))==NULL || n==0)
- _throw(tjGetErrorStr());
-
- bailif0(sfcls=(*env)->FindClass(env, "org/libjpegturbo/turbojpeg/TJScalingFactor"));
- 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"));
- (*env)->SetIntField(env, sfobj, fid, sf[i].num);
- bailif0(fid=(*env)->GetFieldID(env, sfcls, "denom", "I"));
- (*env)->SetIntField(env, sfobj, fid, sf[i].denom);
- (*env)->SetObjectArrayElement(env, sfjava, i, sfobj);
- }
-
- bailout:
- return sfjava;
+ jclass sfcls = NULL;
+ jfieldID fid = 0;
+ tjscalingfactor *sf = NULL;
+ int n = 0, i;
+ jobject sfobj = NULL;
+ jobjectArray sfjava = NULL;
+
+ if ((sf = tjGetScalingFactors(&n)) == NULL || n == 0)
+ THROW_ARG(tjGetErrorStr());
+
+ BAILIF0(sfcls = (*env)->FindClass(env,
+ "org/libjpegturbo/turbojpeg/TJScalingFactor"));
+ 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"));
+ (*env)->SetIntField(env, sfobj, fid, sf[i].num);
+ BAILIF0(fid = (*env)->GetFieldID(env, sfcls, "denom", "I"));
+ (*env)->SetIntField(env, sfobj, fid, sf[i].denom);
+ (*env)->SetObjectArrayElement(env, sfjava, i, sfobj);
+ }
+
+bailout:
+ return sfjava;
}
/* TurboJPEG 1.2.x: TJDecompressor::decompressHeader() */
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressHeader
- (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize)
+ (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize)
{
- tjhandle handle=0;
- unsigned char *jpegBuf=NULL;
- int width=0, height=0, jpegSubsamp=-1, jpegColorspace=-1;
-
- gethandle();
-
- if((*env)->GetArrayLength(env, src)<jpegSize)
- _throw("Source buffer is not large enough");
-
- bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
-
- if(tjDecompressHeader3(handle, jpegBuf, (unsigned long)jpegSize,
- &width, &height, &jpegSubsamp, &jpegColorspace)==-1)
- _throw(tjGetErrorStr());
-
- (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0); jpegBuf=NULL;
-
- 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"));
- (*env)->SetIntField(env, obj, _fid, width);
- bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
- (*env)->SetIntField(env, obj, _fid, height);
-
- bailout:
- if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
- return;
+ tjhandle handle = 0;
+ unsigned char *jpegBuf = NULL;
+ int width = 0, height = 0, jpegSubsamp = -1, jpegColorspace = -1;
+
+ GET_HANDLE();
+
+ if ((*env)->GetArrayLength(env, src) < jpegSize)
+ THROW_ARG("Source buffer is not large enough");
+
+ BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0));
+
+ if (tjDecompressHeader3(handle, jpegBuf, (unsigned long)jpegSize, &width,
+ &height, &jpegSubsamp, &jpegColorspace) == -1) {
+ SAFE_RELEASE(src, jpegBuf);
+ THROW_TJ();
+ }
+
+ SAFE_RELEASE(src, jpegBuf);
+
+ 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"));
+ (*env)->SetIntField(env, obj, _fid, width);
+ BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
+ (*env)->SetIntField(env, obj, _fid, height);
+
+bailout:
+ SAFE_RELEASE(src, jpegBuf);
}
static void TJDecompressor_decompress
- (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jarray dst,
- jint dstElementSize, jint x, jint y, jint width, jint pitch, jint height,
- jint pf, jint flags)
+ (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jarray dst,
+ jint dstElementSize, jint x, jint y, jint width, jint pitch, jint height,
+ jint pf, jint flags)
{
- tjhandle handle=0;
- jsize arraySize=0, actualPitch;
- unsigned char *jpegBuf=NULL, *dstBuf=NULL;
-
- gethandle();
-
- if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
- _throw("Invalid argument in decompress()");
- if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
- _throw("Mismatch between Java and C API");
-
- if((*env)->GetArrayLength(env, src)<jpegSize)
- _throw("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)
- _throw("Destination buffer is not large enough");
-
- 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)
- _throw(tjGetErrorStr());
-
- bailout:
- if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
- if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
- return;
+ tjhandle handle = 0;
+ jsize arraySize = 0, actualPitch;
+ unsigned char *jpegBuf = NULL, *dstBuf = NULL;
+
+ GET_HANDLE();
+
+ if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF)
+ THROW_ARG("Invalid argument in decompress()");
+ if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF)
+ THROW_ARG("Mismatch between Java and C API");
+
+ if ((*env)->GetArrayLength(env, src) < jpegSize)
+ 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)
+ THROW_ARG("Destination buffer is not large enough");
+
+ 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) {
+ SAFE_RELEASE(dst, dstBuf);
+ SAFE_RELEASE(src, jpegBuf);
+ THROW_TJ();
+ }
+
+bailout:
+ SAFE_RELEASE(dst, dstBuf);
+ SAFE_RELEASE(src, jpegBuf);
}
/* TurboJPEG 1.3.x: TJDecompressor::decompress() byte destination */
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIIIII
- (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
- jint x, jint y, jint width, jint pitch, jint height, jint pf, jint flags)
+ (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
+ jint x, jint y, jint width, jint pitch, jint height, jint pf, jint flags)
{
- TJDecompressor_decompress(env, obj, src, jpegSize, dst, 1, x, y, width,
- pitch, height, pf, flags);
+ TJDecompressor_decompress(env, obj, src, jpegSize, dst, 1, x, y, width,
+ pitch, height, pf, flags);
}
/* TurboJPEG 1.2.x: TJDecompressor::decompress() byte destination */
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIII
- (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
- jint width, jint pitch, jint height, jint pf, jint flags)
+ (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
+ jint width, jint pitch, jint height, jint pf, jint flags)
{
- TJDecompressor_decompress(env, obj, src, jpegSize, dst, 1, 0, 0, width,
- pitch, height, pf, flags);
+ TJDecompressor_decompress(env, obj, src, jpegSize, dst, 1, 0, 0, width,
+ pitch, height, pf, flags);
}
/* TurboJPEG 1.3.x: TJDecompressor::decompress() int destination */
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIIIII
- (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jintArray dst,
- jint x, jint y, jint width, jint stride, jint height, jint pf, jint flags)
+ (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jintArray dst,
+ jint x, jint y, jint width, jint stride, jint height, jint pf, jint flags)
{
- if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
- _throw("Invalid argument in decompress()");
- if(tjPixelSize[pf]!=sizeof(jint))
- _throw("Pixel format must be 32-bit when decompressing to an integer buffer.");
+ if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF)
+ THROW_ARG("Invalid argument in decompress()");
+ if (tjPixelSize[pf] != sizeof(jint))
+ 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);
+ TJDecompressor_decompress(env, obj, src, jpegSize, dst, sizeof(jint), x, y,
+ width, stride * sizeof(jint), height, pf, flags);
- bailout:
- return;
+bailout:
+ return;
}
/* TurboJPEG 1.2.x: TJDecompressor::decompress() int destination */
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIII
- (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jintArray dst,
- jint width, jint stride, jint height, jint pf, jint flags)
+ (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jintArray dst,
+ jint width, jint stride, jint height, jint pf, jint flags)
{
- if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
- _throw("Invalid argument in decompress()");
- if(tjPixelSize[pf]!=sizeof(jint))
- _throw("Pixel format must be 32-bit when decompressing to an integer buffer.");
+ if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF)
+ THROW_ARG("Invalid argument in decompress()");
+ if (tjPixelSize[pf] != sizeof(jint))
+ 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);
-
- bailout:
- return;
+ TJDecompressor_decompress(env, obj, src, jpegSize, dst, sizeof(jint), 0, 0,
+ width, stride * sizeof(jint), height, pf, flags);
+bailout:
+ return;
}
/* TurboJPEG 1.4.x: TJDecompressor::decompressToYUV() */
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3_3B_3II_3III
- (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize,
- jobjectArray dstobjs, jintArray jDstOffsets, jint desiredWidth,
- jintArray jDstStrides, jint desiredHeight, jint flags)
+ (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize,
+ jobjectArray dstobjs, jintArray jDstOffsets, jint desiredWidth,
+ jintArray jDstStrides, jint desiredHeight, jint flags)
{
- tjhandle handle=0;
- jbyteArray jDstPlanes[3]={NULL, NULL, NULL};
- unsigned char *jpegBuf=NULL, *dstPlanes[3];
- int *dstOffsets=NULL, *dstStrides=NULL;
- int jpegSubsamp=-1, jpegWidth=0, jpegHeight=0;
- int nc=0, i, width, height, scaledWidth, scaledHeight, nsf=0;
- tjscalingfactor *sf;
-
-
- gethandle();
-
- if((*env)->GetArrayLength(env, src)<jpegSize)
- _throw("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"));
- jpegWidth=(int)(*env)->GetIntField(env, obj, _fid);
- 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);
-
- width=desiredWidth; height=desiredHeight;
- if(width==0) width=jpegWidth;
- if(height==0) height=jpegHeight;
- sf=tjGetScalingFactors(&nsf);
- if(!sf || nsf<1)
- _throw(tjGetErrorStr());
- for(i=0; i<nsf; i++)
- {
- scaledWidth=TJSCALED(jpegWidth, sf[i]);
- scaledHeight=TJSCALED(jpegHeight, sf[i]);
- if(scaledWidth<=width && scaledHeight<=height)
- break;
- }
-
- 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)
- _throw(tjGetErrorStr());
-
- if(dstOffsets[i]<0)
- _throw("Invalid argument in decompressToYUV()");
- if(dstStrides[i]<0 && dstOffsets[i]-planeSize+pw<0)
- _throw("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)
- _throw("Destination plane is not large enough");
-
- bailif0(dstPlanes[i]=(*env)->GetPrimitiveArrayCritical(env, jDstPlanes[i],
- 0));
- dstPlanes[i]=&dstPlanes[i][dstOffsets[i]];
- }
- bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
-
- if(tjDecompressToYUVPlanes(handle, jpegBuf, (unsigned long)jpegSize,
- dstPlanes, desiredWidth, dstStrides, desiredHeight, flags)==-1)
- _throw(tjGetErrorStr());
-
- bailout:
- if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
- for(i=0; i<nc; i++)
- {
- if(dstPlanes[i] && jDstPlanes[i])
- (*env)->ReleasePrimitiveArrayCritical(env, jDstPlanes[i], dstPlanes[i],
- 0);
- }
- if(dstStrides)
- (*env)->ReleasePrimitiveArrayCritical(env, jDstStrides, dstStrides, 0);
- if(dstOffsets)
- (*env)->ReleasePrimitiveArrayCritical(env, jDstOffsets, dstOffsets, 0);
- return;
+ tjhandle handle = 0;
+ unsigned char *jpegBuf = NULL;
+ jbyteArray jDstPlanes[3] = { NULL, NULL, 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;
+
+ GET_HANDLE();
+
+ if ((*env)->GetArrayLength(env, src) < jpegSize)
+ 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"));
+ jpegWidth = (int)(*env)->GetIntField(env, obj, _fid);
+ 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);
+
+ width = desiredWidth;
+ height = desiredHeight;
+ if (width == 0) width = jpegWidth;
+ if (height == 0) height = jpegHeight;
+ sf = tjGetScalingFactors(&nsf);
+ if (!sf || nsf < 1)
+ THROW_ARG(tjGetErrorStr());
+ for (i = 0; i < nsf; i++) {
+ scaledWidth = TJSCALED(jpegWidth, sf[i]);
+ scaledHeight = TJSCALED(jpegHeight, sf[i]);
+ if (scaledWidth <= width && scaledHeight <= height)
+ break;
+ }
+ if (i >= nsf)
+ THROW_ARG("Could not scale down to desired image dimensions");
+
+ 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);
+
+ 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)
+ THROW_ARG(tjGetErrorStr());
+
+ if (dstOffsets[i] < 0)
+ THROW_ARG("Invalid argument in 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)
+ THROW_ARG("Destination plane is not large enough");
+
+ BAILIF0(dstPlanesTmp[i] =
+ (*env)->GetPrimitiveArrayCritical(env, jDstPlanes[i], 0));
+ 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) {
+ SAFE_RELEASE(src, jpegBuf);
+ THROW_TJ();
+ }
+
+bailout:
+ SAFE_RELEASE(src, jpegBuf);
}
/* TurboJPEG 1.2.x: TJDecompressor::decompressToYUV() */
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3BI
- (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
- jint flags)
+ (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
+ jint flags)
{
- tjhandle handle=0;
- unsigned char *jpegBuf=NULL, *dstBuf=NULL;
- int jpegSubsamp=-1, jpegWidth=0, jpegHeight=0;
-
- gethandle();
-
- if((*env)->GetArrayLength(env, src)<jpegSize)
- _throw("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"));
- jpegWidth=(int)(*env)->GetIntField(env, obj, _fid);
- 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))
- _throw("Destination buffer is not large enough");
-
- bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
- bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
-
- if(tjDecompressToYUV(handle, jpegBuf, (unsigned long)jpegSize, dstBuf,
- flags)==-1)
- _throw(tjGetErrorStr());
-
- bailout:
- if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
- if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
- return;
+ tjhandle handle = 0;
+ unsigned char *jpegBuf = NULL, *dstBuf = NULL;
+ int jpegSubsamp = -1, jpegWidth = 0, jpegHeight = 0;
+
+ GET_HANDLE();
+
+ if ((*env)->GetArrayLength(env, src) < jpegSize)
+ 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"));
+ jpegWidth = (int)(*env)->GetIntField(env, obj, _fid);
+ 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))
+ THROW_ARG("Destination buffer is not large enough");
+
+ BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0));
+ BAILIF0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0));
+
+ if (tjDecompressToYUV(handle, jpegBuf, (unsigned long)jpegSize, dstBuf,
+ flags) == -1) {
+ SAFE_RELEASE(dst, dstBuf);
+ SAFE_RELEASE(src, jpegBuf);
+ THROW_TJ();
+ }
+
+bailout:
+ SAFE_RELEASE(dst, dstBuf);
+ SAFE_RELEASE(src, jpegBuf);
}
static void TJDecompressor_decodeYUV
- (JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets,
- jintArray jSrcStrides, jint subsamp, jarray dst, jint dstElementSize,
- jint x, jint y, jint width, jint pitch, jint height, jint pf, jint flags)
+ (JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets,
+ jintArray jSrcStrides, jint subsamp, jarray dst, jint dstElementSize,
+ jint x, jint y, jint width, jint pitch, jint height, jint pf, jint flags)
{
- tjhandle handle=0;
- jsize arraySize=0, actualPitch;
- jbyteArray jSrcPlanes[3]={NULL, NULL, NULL};
- unsigned char *srcPlanes[3], *dstBuf=NULL;
- int *srcOffsets=NULL, *srcStrides=NULL;
- int nc=(subsamp==org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY? 1:3), i;
-
- gethandle();
-
- if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || subsamp<0
- || subsamp>=org_libjpegturbo_turbojpeg_TJ_NUMSAMP)
- _throw("Invalid argument in decodeYUV()");
- if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF
- || org_libjpegturbo_turbojpeg_TJ_NUMSAMP!=TJ_NUMSAMP)
- _throw("Mismatch between Java and C API");
-
- if((*env)->GetArrayLength(env, srcobjs)<nc)
- _throw("Planes array is too small for the subsampling type");
- if((*env)->GetArrayLength(env, jSrcOffsets)<nc)
- _throw("Offsets array is too small for the subsampling type");
- if((*env)->GetArrayLength(env, jSrcStrides)<nc)
- _throw("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)
- _throw("Destination buffer is not large enough");
-
- 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)
- _throw(tjGetErrorStr());
-
- if(srcOffsets[i]<0)
- _throw("Invalid argument in decodeYUV()");
- if(srcStrides[i]<0 && srcOffsets[i]-planeSize+pw<0)
- _throw("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)
- _throw("Source plane is not large enough");
-
- bailif0(srcPlanes[i]=(*env)->GetPrimitiveArrayCritical(env, jSrcPlanes[i],
- 0));
- srcPlanes[i]=&srcPlanes[i][srcOffsets[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)
- _throw(tjGetErrorStr());
-
- bailout:
- if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
- for(i=0; i<nc; i++)
- {
- if(srcPlanes[i] && jSrcPlanes[i])
- (*env)->ReleasePrimitiveArrayCritical(env, jSrcPlanes[i], srcPlanes[i],
- 0);
- }
- if(srcStrides)
- (*env)->ReleasePrimitiveArrayCritical(env, jSrcStrides, srcStrides, 0);
- if(srcOffsets)
- (*env)->ReleasePrimitiveArrayCritical(env, jSrcOffsets, srcOffsets, 0);
- return;
+ tjhandle handle = 0;
+ jsize arraySize = 0, actualPitch;
+ jbyteArray jSrcPlanes[3] = { NULL, NULL, NULL };
+ 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 nc = (subsamp == org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY ? 1 : 3), i;
+
+ GET_HANDLE();
+
+ if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF || subsamp < 0 ||
+ subsamp >= org_libjpegturbo_turbojpeg_TJ_NUMSAMP)
+ THROW_ARG("Invalid argument in decodeYUV()");
+ if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF ||
+ org_libjpegturbo_turbojpeg_TJ_NUMSAMP != TJ_NUMSAMP)
+ THROW_ARG("Mismatch between Java and C API");
+
+ if ((*env)->GetArrayLength(env, srcobjs) < nc)
+ THROW_ARG("Planes array is too small for the subsampling type");
+ if ((*env)->GetArrayLength(env, jSrcOffsets) < nc)
+ THROW_ARG("Offsets array is too small for the subsampling type");
+ if ((*env)->GetArrayLength(env, jSrcStrides) < nc)
+ 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)
+ THROW_ARG("Destination buffer is not large enough");
+
+ 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);
+
+ 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)
+ THROW_ARG(tjGetErrorStr());
+
+ if (srcOffsets[i] < 0)
+ THROW_ARG("Invalid argument in 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)
+ THROW_ARG("Source plane is not large enough");
+
+ BAILIF0(srcPlanesTmp[i] =
+ (*env)->GetPrimitiveArrayCritical(env, jSrcPlanes[i], 0));
+ 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) {
+ SAFE_RELEASE(dst, dstBuf);
+ THROW_TJ();
+ }
+
+bailout:
+ SAFE_RELEASE(dst, dstBuf);
}
/* TurboJPEG 1.4.x: TJDecompressor::decodeYUV() byte destination */
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decodeYUV___3_3B_3I_3II_3BIIIIIII
- (JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets,
- jintArray jSrcStrides, jint subsamp, jbyteArray dst, jint x, jint y,
- jint width, jint pitch, jint height, jint pf, jint flags)
+ (JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets,
+ jintArray jSrcStrides, jint subsamp, jbyteArray dst, jint x, jint y,
+ jint width, jint pitch, jint height, jint pf, jint flags)
{
- TJDecompressor_decodeYUV(env, obj, srcobjs, jSrcOffsets, jSrcStrides,
- subsamp, dst, 1, x, y, width, pitch, height, pf, flags);
+ TJDecompressor_decodeYUV(env, obj, srcobjs, jSrcOffsets, jSrcStrides,
+ subsamp, dst, 1, x, y, width, pitch, height, pf,
+ flags);
}
/* TurboJPEG 1.4.x: TJDecompressor::decodeYUV() int destination */
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decodeYUV___3_3B_3I_3II_3IIIIIIII
- (JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets,
- jintArray jSrcStrides, jint subsamp, jintArray dst, jint x, jint y,
- jint width, jint stride, jint height, jint pf, jint flags)
+ (JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets,
+ jintArray jSrcStrides, jint subsamp, jintArray dst, jint x, jint y,
+ jint width, jint stride, jint height, jint pf, jint flags)
{
- if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
- _throw("Invalid argument in decodeYUV()");
- if(tjPixelSize[pf]!=sizeof(jint))
- _throw("Pixel format must be 32-bit when decoding to an integer buffer.");
+ if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF)
+ THROW_ARG("Invalid argument in decodeYUV()");
+ if (tjPixelSize[pf] != sizeof(jint))
+ 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, stride*sizeof(jint), height, pf,
- flags);
+ TJDecompressor_decodeYUV(env, obj, srcobjs, jSrcOffsets, jSrcStrides,
+ subsamp, dst, sizeof(jint), x, y, width,
+ stride * sizeof(jint), height, pf, flags);
- bailout:
- return;
+bailout:
+ return;
}
/* TurboJPEG 1.2.x: TJTransformer::init() */
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_init
- (JNIEnv *env, jobject obj)
+ (JNIEnv *env, jobject obj)
{
- jclass cls;
- jfieldID fid;
- tjhandle handle;
+ jclass cls;
+ jfieldID fid;
+ tjhandle handle;
- if((handle=tjInitTransform())==NULL) _throw(tjGetErrorStr());
+ if ((handle = tjInitTransform()) == NULL)
+ THROW(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException");
- bailif0(cls=(*env)->GetObjectClass(env, obj));
- bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J"));
- (*env)->SetLongField(env, obj, fid, (size_t)handle);
+ BAILIF0(cls = (*env)->GetObjectClass(env, obj));
+ BAILIF0(fid = (*env)->GetFieldID(env, cls, "handle", "J"));
+ (*env)->SetLongField(env, obj, fid, (size_t)handle);
- bailout:
- return;
+bailout:
+ return;
}
-typedef struct _JNICustomFilterParams
-{
- JNIEnv *env;
- jobject tobj;
- jobject cfobj;
+typedef struct _JNICustomFilterParams {
+ JNIEnv *env;
+ jobject tobj;
+ jobject cfobj;
} JNICustomFilterParams;
static int JNICustomFilter(short *coeffs, tjregion arrayRegion,
- tjregion planeRegion, int componentIndex, int transformIndex,
- tjtransform *transform)
+ tjregion planeRegion, int componentIndex,
+ int transformIndex, tjtransform *transform)
{
- JNICustomFilterParams *params=(JNICustomFilterParams *)transform->data;
- JNIEnv *env=params->env;
- jobject tobj=params->tobj, cfobj=params->cfobj;
- jobject arrayRegionObj, planeRegionObj, bufobj, borobj;
- jclass cls; jmethodID mid; jfieldID fid;
-
- 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",
- "()Ljava/nio/ByteOrder;"));
- 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",
- "()Ljava/nio/ShortBuffer;"));
- 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"));
- (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.x);
- bailif0(fid=(*env)->GetFieldID(env, cls, "y", "I"));
- (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.y);
- bailif0(fid=(*env)->GetFieldID(env, cls, "width", "I"));
- (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.w);
- 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"));
- (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.x);
- bailif0(fid=(*env)->GetFieldID(env, cls, "y", "I"));
- (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.y);
- bailif0(fid=(*env)->GetFieldID(env, cls, "width", "I"));
- (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.w);
- 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",
- "(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);
-
- return 0;
-
- bailout:
- return -1;
+ JNICustomFilterParams *params = (JNICustomFilterParams *)transform->data;
+ JNIEnv *env = params->env;
+ jobject tobj = params->tobj, cfobj = params->cfobj;
+ jobject arrayRegionObj, planeRegionObj, bufobj, borobj;
+ jclass cls;
+ jmethodID mid;
+ jfieldID fid;
+
+ 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",
+ "()Ljava/nio/ByteOrder;"));
+ 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",
+ "()Ljava/nio/ShortBuffer;"));
+ 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"));
+ (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.x);
+ BAILIF0(fid = (*env)->GetFieldID(env, cls, "y", "I"));
+ (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.y);
+ BAILIF0(fid = (*env)->GetFieldID(env, cls, "width", "I"));
+ (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.w);
+ 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"));
+ (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.x);
+ BAILIF0(fid = (*env)->GetFieldID(env, cls, "y", "I"));
+ (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.y);
+ BAILIF0(fid = (*env)->GetFieldID(env, cls, "width", "I"));
+ (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.w);
+ 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",
+ "(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);
+
+ return 0;
+
+bailout:
+ return -1;
}
/* TurboJPEG 1.2.x: TJTransformer::transform() */
JNIEXPORT jintArray JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_transform
- (JNIEnv *env, jobject obj, jbyteArray jsrcBuf, jint jpegSize,
- jobjectArray dstobjs, jobjectArray tobjs, jint flags)
+ (JNIEnv *env, jobject obj, jbyteArray jsrcBuf, jint jpegSize,
+ jobjectArray dstobjs, jobjectArray tobjs, jint flags)
{
- tjhandle handle=0; int i;
- unsigned char *jpegBuf=NULL, **dstBufs=NULL; jsize n=0;
- unsigned long *dstSizes=NULL; tjtransform *t=NULL;
- jbyteArray *jdstBufs=NULL;
- int jpegWidth=0, jpegHeight=0, jpegSubsamp;
- jintArray jdstSizes=0; jint *dstSizesi=NULL;
- JNICustomFilterParams *params=NULL;
-
- gethandle();
-
- if((*env)->GetArrayLength(env, jsrcBuf)<jpegSize)
- _throw("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"));
- jpegHeight=(int)(*env)->GetIntField(env, obj, _fid);
- 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))
- _throw("Mismatch between size of transforms array and destination buffers array");
-
- if((dstBufs=(unsigned char **)malloc(sizeof(unsigned char *)*n))==NULL)
- _throw("Memory allocation failure");
- if((jdstBufs=(jbyteArray *)malloc(sizeof(jbyteArray)*n))==NULL)
- _throw("Memory allocation failure");
- if((dstSizes=(unsigned long *)malloc(sizeof(unsigned long)*n))==NULL)
- _throw("Memory allocation failure");
- if((t=(tjtransform *)malloc(sizeof(tjtransform)*n))==NULL)
- _throw("Memory allocation failure");
- if((params=(JNICustomFilterParams *)malloc(sizeof(JNICustomFilterParams)*n))
- ==NULL)
- _throw("Memory allocation failure");
- for(i=0; i<n; i++)
- {
- dstBufs[i]=NULL; jdstBufs[i]=NULL; dstSizes[i]=0;
- memset(&t[i], 0, sizeof(tjtransform));
- memset(¶ms[i], 0, sizeof(JNICustomFilterParams));
- }
-
- 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"));
- t[i].op=(*env)->GetIntField(env, tobj, _fid);
- bailif0(_fid=(*env)->GetFieldID(env, _cls, "options", "I"));
- t[i].options=(*env)->GetIntField(env, tobj, _fid);
- 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"));
- t[i].r.y=(*env)->GetIntField(env, tobj, _fid);
- 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"));
- t[i].r.h=(*env)->GetIntField(env, tobj, _fid);
-
- bailif0(_fid=(*env)->GetFieldID(env, _cls, "cf",
- "Lorg/libjpegturbo/turbojpeg/TJCustomFilter;"));
- cfobj=(*env)->GetObjectField(env, tobj, _fid);
- if(cfobj)
- {
- params[i].env=env;
- params[i].tobj=tobj;
- params[i].cfobj=cfobj;
- t[i].customFilter=JNICustomFilter;
- t[i].data=(void *)¶ms[i];
- }
- }
-
- for(i=0; i<n; i++)
- {
- int w=jpegWidth, h=jpegHeight;
- 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));
- if((unsigned long)(*env)->GetArrayLength(env, jdstBufs[i])
- <tjBufSize(w, h, jpegSubsamp))
- _throw("Destination buffer is not large enough");
- }
- bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, jsrcBuf, 0));
- for(i=0; i<n; i++)
- bailif0(dstBufs[i]=(*env)->GetPrimitiveArrayCritical(env, jdstBufs[i], 0));
-
- if(tjTransform(handle, jpegBuf, jpegSize, n, dstBufs, dstSizes, t,
- flags|TJFLAG_NOREALLOC)==-1)
- _throw(tjGetErrorStr());
-
- for(i=0; i<n; i++)
- {
- (*env)->ReleasePrimitiveArrayCritical(env, jdstBufs[i], dstBufs[i], 0);
- dstBufs[i]=NULL;
- }
- (*env)->ReleasePrimitiveArrayCritical(env, jsrcBuf, jpegBuf, 0);
- jpegBuf=NULL;
-
- jdstSizes=(*env)->NewIntArray(env, n);
- bailif0(dstSizesi=(*env)->GetIntArrayElements(env, jdstSizes, 0));
- for(i=0; i<n; i++) dstSizesi[i]=(int)dstSizes[i];
-
- bailout:
- if(dstSizesi) (*env)->ReleaseIntArrayElements(env, jdstSizes, dstSizesi, 0);
- if(dstBufs)
- {
- for(i=0; i<n; i++)
- {
- if(dstBufs[i] && jdstBufs && jdstBufs[i])
- (*env)->ReleasePrimitiveArrayCritical(env, jdstBufs[i], dstBufs[i], 0);
- }
- free(dstBufs);
- }
- if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, jsrcBuf, jpegBuf, 0);
- if(jdstBufs) free(jdstBufs);
- if(dstSizes) free(dstSizes);
- if(t) free(t);
- return jdstSizes;
+ tjhandle handle = 0;
+ unsigned char *jpegBuf = NULL, **dstBufs = NULL;
+ jsize n = 0;
+ unsigned long *dstSizes = NULL;
+ tjtransform *t = NULL;
+ jbyteArray *jdstBufs = NULL;
+ int i, jpegWidth = 0, jpegHeight = 0, jpegSubsamp;
+ jintArray jdstSizes = 0;
+ jint *dstSizesi = NULL;
+ JNICustomFilterParams *params = NULL;
+
+ GET_HANDLE();
+
+ if ((*env)->GetArrayLength(env, jsrcBuf) < jpegSize)
+ 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"));
+ jpegHeight = (int)(*env)->GetIntField(env, obj, _fid);
+ 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))
+ THROW_ARG("Mismatch between size of transforms array and destination buffers array");
+
+ if ((dstBufs =
+ (unsigned char **)malloc(sizeof(unsigned char *) * n)) == NULL)
+ THROW_MEM();
+ if ((jdstBufs = (jbyteArray *)malloc(sizeof(jbyteArray) * n)) == NULL)
+ THROW_MEM();
+ if ((dstSizes = (unsigned long *)malloc(sizeof(unsigned long) * n)) == NULL)
+ THROW_MEM();
+ if ((t = (tjtransform *)malloc(sizeof(tjtransform) * n)) == NULL)
+ THROW_MEM();
+ if ((params = (JNICustomFilterParams *)malloc(sizeof(JNICustomFilterParams) *
+ n)) == NULL)
+ THROW_MEM();
+ for (i = 0; i < n; i++) {
+ dstBufs[i] = NULL; jdstBufs[i] = NULL; dstSizes[i] = 0;
+ memset(&t[i], 0, sizeof(tjtransform));
+ memset(¶ms[i], 0, sizeof(JNICustomFilterParams));
+ }
+
+ 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"));
+ t[i].op = (*env)->GetIntField(env, tobj, _fid);
+ BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "options", "I"));
+ t[i].options = (*env)->GetIntField(env, tobj, _fid);
+ 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"));
+ t[i].r.y = (*env)->GetIntField(env, tobj, _fid);
+ 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"));
+ t[i].r.h = (*env)->GetIntField(env, tobj, _fid);
+
+ BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "cf",
+ "Lorg/libjpegturbo/turbojpeg/TJCustomFilter;"));
+ cfobj = (*env)->GetObjectField(env, tobj, _fid);
+ if (cfobj) {
+ params[i].env = env;
+ params[i].tobj = tobj;
+ params[i].cfobj = cfobj;
+ t[i].customFilter = JNICustomFilter;
+ t[i].data = (void *)¶ms[i];
+ }
+ }
+
+ for (i = 0; i < n; i++) {
+ int w = jpegWidth, h = jpegHeight;
+
+ 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));
+ if ((unsigned long)(*env)->GetArrayLength(env, jdstBufs[i]) <
+ tjBufSize(w, h, jpegSubsamp))
+ THROW_ARG("Destination buffer is not large enough");
+ }
+ BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, jsrcBuf, 0));
+ for (i = 0; i < n; i++)
+ BAILIF0(dstBufs[i] =
+ (*env)->GetPrimitiveArrayCritical(env, jdstBufs[i], 0));
+
+ if (tjTransform(handle, jpegBuf, jpegSize, n, dstBufs, dstSizes, t,
+ flags | TJFLAG_NOREALLOC) == -1) {
+ for (i = 0; i < n; i++)
+ SAFE_RELEASE(jdstBufs[i], dstBufs[i]);
+ SAFE_RELEASE(jsrcBuf, jpegBuf);
+ THROW_TJ();
+ }
+
+ for (i = 0; i < n; i++)
+ SAFE_RELEASE(jdstBufs[i], dstBufs[i]);
+ SAFE_RELEASE(jsrcBuf, jpegBuf);
+
+ jdstSizes = (*env)->NewIntArray(env, n);
+ BAILIF0(dstSizesi = (*env)->GetIntArrayElements(env, jdstSizes, 0));
+ for (i = 0; i < n; i++) dstSizesi[i] = (int)dstSizes[i];
+
+bailout:
+ if (dstSizesi) (*env)->ReleaseIntArrayElements(env, jdstSizes, dstSizesi, 0);
+ if (dstBufs) {
+ for (i = 0; i < n; i++) {
+ if (dstBufs[i] && jdstBufs && jdstBufs[i])
+ (*env)->ReleasePrimitiveArrayCritical(env, jdstBufs[i], dstBufs[i], 0);
+ }
+ free(dstBufs);
+ }
+ SAFE_RELEASE(jsrcBuf, jpegBuf);
+ free(jdstBufs);
+ free(dstSizes);
+ free(t);
+ return jdstSizes;
}
/* TurboJPEG 1.2.x: TJDecompressor::destroy() */
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_destroy
- (JNIEnv *env, jobject obj)
+ (JNIEnv *env, jobject obj)
{
- Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy(env, obj);
+ Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy(env, obj);
}