1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright (C)2011-2020 D. R. Commander. All Rights Reserved. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 5cb93a386Sopenharmony_ci * modification, are permitted provided that the following conditions are met: 6cb93a386Sopenharmony_ci * 7cb93a386Sopenharmony_ci * - Redistributions of source code must retain the above copyright notice, 8cb93a386Sopenharmony_ci * this list of conditions and the following disclaimer. 9cb93a386Sopenharmony_ci * - Redistributions in binary form must reproduce the above copyright notice, 10cb93a386Sopenharmony_ci * this list of conditions and the following disclaimer in the documentation 11cb93a386Sopenharmony_ci * and/or other materials provided with the distribution. 12cb93a386Sopenharmony_ci * - Neither the name of the libjpeg-turbo Project nor the names of its 13cb93a386Sopenharmony_ci * contributors may be used to endorse or promote products derived from this 14cb93a386Sopenharmony_ci * software without specific prior written permission. 15cb93a386Sopenharmony_ci * 16cb93a386Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", 17cb93a386Sopenharmony_ci * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18cb93a386Sopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19cb93a386Sopenharmony_ci * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE 20cb93a386Sopenharmony_ci * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21cb93a386Sopenharmony_ci * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22cb93a386Sopenharmony_ci * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23cb93a386Sopenharmony_ci * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24cb93a386Sopenharmony_ci * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25cb93a386Sopenharmony_ci * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26cb93a386Sopenharmony_ci * POSSIBILITY OF SUCH DAMAGE. 27cb93a386Sopenharmony_ci */ 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_ci#include <stdlib.h> 30cb93a386Sopenharmony_ci#include <string.h> 31cb93a386Sopenharmony_ci#include "turbojpeg.h" 32cb93a386Sopenharmony_ci#ifdef WIN32 33cb93a386Sopenharmony_ci#include "tjutil.h" 34cb93a386Sopenharmony_ci#endif 35cb93a386Sopenharmony_ci#include <jni.h> 36cb93a386Sopenharmony_ci#include "java/org_libjpegturbo_turbojpeg_TJCompressor.h" 37cb93a386Sopenharmony_ci#include "java/org_libjpegturbo_turbojpeg_TJDecompressor.h" 38cb93a386Sopenharmony_ci#include "java/org_libjpegturbo_turbojpeg_TJTransformer.h" 39cb93a386Sopenharmony_ci#include "java/org_libjpegturbo_turbojpeg_TJ.h" 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_ci#define BAILIF0(f) { \ 42cb93a386Sopenharmony_ci if (!(f) || (*env)->ExceptionCheck(env)) { \ 43cb93a386Sopenharmony_ci goto bailout; \ 44cb93a386Sopenharmony_ci } \ 45cb93a386Sopenharmony_ci} 46cb93a386Sopenharmony_ci 47cb93a386Sopenharmony_ci#define THROW(msg, exceptionClass) { \ 48cb93a386Sopenharmony_ci jclass _exccls = (*env)->FindClass(env, exceptionClass); \ 49cb93a386Sopenharmony_ci \ 50cb93a386Sopenharmony_ci BAILIF0(_exccls); \ 51cb93a386Sopenharmony_ci (*env)->ThrowNew(env, _exccls, msg); \ 52cb93a386Sopenharmony_ci goto bailout; \ 53cb93a386Sopenharmony_ci} 54cb93a386Sopenharmony_ci 55cb93a386Sopenharmony_ci#define THROW_TJ() { \ 56cb93a386Sopenharmony_ci jclass _exccls; \ 57cb93a386Sopenharmony_ci jmethodID _excid; \ 58cb93a386Sopenharmony_ci jobject _excobj; \ 59cb93a386Sopenharmony_ci jstring _errstr; \ 60cb93a386Sopenharmony_ci \ 61cb93a386Sopenharmony_ci BAILIF0(_errstr = (*env)->NewStringUTF(env, tjGetErrorStr2(handle))); \ 62cb93a386Sopenharmony_ci BAILIF0(_exccls = (*env)->FindClass(env, \ 63cb93a386Sopenharmony_ci "org/libjpegturbo/turbojpeg/TJException")); \ 64cb93a386Sopenharmony_ci BAILIF0(_excid = (*env)->GetMethodID(env, _exccls, "<init>", \ 65cb93a386Sopenharmony_ci "(Ljava/lang/String;I)V")); \ 66cb93a386Sopenharmony_ci BAILIF0(_excobj = (*env)->NewObject(env, _exccls, _excid, _errstr, \ 67cb93a386Sopenharmony_ci tjGetErrorCode(handle))); \ 68cb93a386Sopenharmony_ci (*env)->Throw(env, _excobj); \ 69cb93a386Sopenharmony_ci goto bailout; \ 70cb93a386Sopenharmony_ci} 71cb93a386Sopenharmony_ci 72cb93a386Sopenharmony_ci#define THROW_ARG(msg) THROW(msg, "java/lang/IllegalArgumentException") 73cb93a386Sopenharmony_ci 74cb93a386Sopenharmony_ci#define THROW_MEM() \ 75cb93a386Sopenharmony_ci THROW("Memory allocation failure", "java/lang/OutOfMemoryError"); 76cb93a386Sopenharmony_ci 77cb93a386Sopenharmony_ci#define GET_HANDLE() \ 78cb93a386Sopenharmony_ci jclass _cls = (*env)->GetObjectClass(env, obj); \ 79cb93a386Sopenharmony_ci jfieldID _fid; \ 80cb93a386Sopenharmony_ci \ 81cb93a386Sopenharmony_ci BAILIF0(_cls); \ 82cb93a386Sopenharmony_ci BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "handle", "J")); \ 83cb93a386Sopenharmony_ci handle = (tjhandle)(size_t)(*env)->GetLongField(env, obj, _fid); 84cb93a386Sopenharmony_ci 85cb93a386Sopenharmony_ci#ifdef _WIN32 86cb93a386Sopenharmony_ci#define setenv(envvar, value, dummy) _putenv_s(envvar, value) 87cb93a386Sopenharmony_ci#endif 88cb93a386Sopenharmony_ci 89cb93a386Sopenharmony_ci#define PROP2ENV(property, envvar) { \ 90cb93a386Sopenharmony_ci if ((jName = (*env)->NewStringUTF(env, property)) != NULL && \ 91cb93a386Sopenharmony_ci (jValue = (*env)->CallStaticObjectMethod(env, cls, mid, \ 92cb93a386Sopenharmony_ci jName)) != NULL) { \ 93cb93a386Sopenharmony_ci if ((value = (*env)->GetStringUTFChars(env, jValue, 0)) != NULL) { \ 94cb93a386Sopenharmony_ci setenv(envvar, value, 1); \ 95cb93a386Sopenharmony_ci (*env)->ReleaseStringUTFChars(env, jValue, value); \ 96cb93a386Sopenharmony_ci } \ 97cb93a386Sopenharmony_ci } \ 98cb93a386Sopenharmony_ci} 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_ci#define SAFE_RELEASE(javaArray, cArray) { \ 101cb93a386Sopenharmony_ci if (javaArray && cArray) \ 102cb93a386Sopenharmony_ci (*env)->ReleasePrimitiveArrayCritical(env, javaArray, (void *)cArray, 0); \ 103cb93a386Sopenharmony_ci cArray = NULL; \ 104cb93a386Sopenharmony_ci} 105cb93a386Sopenharmony_ci 106cb93a386Sopenharmony_cistatic int ProcessSystemProperties(JNIEnv *env) 107cb93a386Sopenharmony_ci{ 108cb93a386Sopenharmony_ci jclass cls; 109cb93a386Sopenharmony_ci jmethodID mid; 110cb93a386Sopenharmony_ci jstring jName, jValue; 111cb93a386Sopenharmony_ci const char *value; 112cb93a386Sopenharmony_ci 113cb93a386Sopenharmony_ci BAILIF0(cls = (*env)->FindClass(env, "java/lang/System")); 114cb93a386Sopenharmony_ci BAILIF0(mid = (*env)->GetStaticMethodID(env, cls, "getProperty", 115cb93a386Sopenharmony_ci "(Ljava/lang/String;)Ljava/lang/String;")); 116cb93a386Sopenharmony_ci 117cb93a386Sopenharmony_ci PROP2ENV("turbojpeg.optimize", "TJ_OPTIMIZE"); 118cb93a386Sopenharmony_ci PROP2ENV("turbojpeg.arithmetic", "TJ_ARITHMETIC"); 119cb93a386Sopenharmony_ci PROP2ENV("turbojpeg.restart", "TJ_RESTART"); 120cb93a386Sopenharmony_ci PROP2ENV("turbojpeg.progressive", "TJ_PROGRESSIVE"); 121cb93a386Sopenharmony_ci return 0; 122cb93a386Sopenharmony_ci 123cb93a386Sopenharmony_cibailout: 124cb93a386Sopenharmony_ci return -1; 125cb93a386Sopenharmony_ci} 126cb93a386Sopenharmony_ci 127cb93a386Sopenharmony_ci/* TurboJPEG 1.2.x: TJ::bufSize() */ 128cb93a386Sopenharmony_ciJNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSize 129cb93a386Sopenharmony_ci (JNIEnv *env, jclass cls, jint width, jint height, jint jpegSubsamp) 130cb93a386Sopenharmony_ci{ 131cb93a386Sopenharmony_ci jint retval = (jint)tjBufSize(width, height, jpegSubsamp); 132cb93a386Sopenharmony_ci 133cb93a386Sopenharmony_ci if (retval == -1) THROW_ARG(tjGetErrorStr()); 134cb93a386Sopenharmony_ci 135cb93a386Sopenharmony_cibailout: 136cb93a386Sopenharmony_ci return retval; 137cb93a386Sopenharmony_ci} 138cb93a386Sopenharmony_ci 139cb93a386Sopenharmony_ci/* TurboJPEG 1.4.x: TJ::bufSizeYUV() */ 140cb93a386Sopenharmony_ciJNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__IIII 141cb93a386Sopenharmony_ci (JNIEnv *env, jclass cls, jint width, jint pad, jint height, jint subsamp) 142cb93a386Sopenharmony_ci{ 143cb93a386Sopenharmony_ci jint retval = (jint)tjBufSizeYUV2(width, pad, height, subsamp); 144cb93a386Sopenharmony_ci 145cb93a386Sopenharmony_ci if (retval == -1) THROW_ARG(tjGetErrorStr()); 146cb93a386Sopenharmony_ci 147cb93a386Sopenharmony_cibailout: 148cb93a386Sopenharmony_ci return retval; 149cb93a386Sopenharmony_ci} 150cb93a386Sopenharmony_ci 151cb93a386Sopenharmony_ci/* TurboJPEG 1.2.x: TJ::bufSizeYUV() */ 152cb93a386Sopenharmony_ciJNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__III 153cb93a386Sopenharmony_ci (JNIEnv *env, jclass cls, jint width, jint height, jint subsamp) 154cb93a386Sopenharmony_ci{ 155cb93a386Sopenharmony_ci return Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__IIII(env, cls, width, 156cb93a386Sopenharmony_ci 4, height, 157cb93a386Sopenharmony_ci subsamp); 158cb93a386Sopenharmony_ci} 159cb93a386Sopenharmony_ci 160cb93a386Sopenharmony_ci/* TurboJPEG 1.4.x: TJ::planeSizeYUV() */ 161cb93a386Sopenharmony_ciJNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_planeSizeYUV__IIIII 162cb93a386Sopenharmony_ci (JNIEnv *env, jclass cls, jint componentID, jint width, jint stride, 163cb93a386Sopenharmony_ci jint height, jint subsamp) 164cb93a386Sopenharmony_ci{ 165cb93a386Sopenharmony_ci jint retval = (jint)tjPlaneSizeYUV(componentID, width, stride, height, 166cb93a386Sopenharmony_ci subsamp); 167cb93a386Sopenharmony_ci 168cb93a386Sopenharmony_ci if (retval == -1) THROW_ARG(tjGetErrorStr()); 169cb93a386Sopenharmony_ci 170cb93a386Sopenharmony_cibailout: 171cb93a386Sopenharmony_ci return retval; 172cb93a386Sopenharmony_ci} 173cb93a386Sopenharmony_ci 174cb93a386Sopenharmony_ci/* TurboJPEG 1.4.x: TJ::planeWidth() */ 175cb93a386Sopenharmony_ciJNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_planeWidth__III 176cb93a386Sopenharmony_ci (JNIEnv *env, jclass cls, jint componentID, jint width, jint subsamp) 177cb93a386Sopenharmony_ci{ 178cb93a386Sopenharmony_ci jint retval = (jint)tjPlaneWidth(componentID, width, subsamp); 179cb93a386Sopenharmony_ci 180cb93a386Sopenharmony_ci if (retval == -1) THROW_ARG(tjGetErrorStr()); 181cb93a386Sopenharmony_ci 182cb93a386Sopenharmony_cibailout: 183cb93a386Sopenharmony_ci return retval; 184cb93a386Sopenharmony_ci} 185cb93a386Sopenharmony_ci 186cb93a386Sopenharmony_ci/* TurboJPEG 1.4.x: TJ::planeHeight() */ 187cb93a386Sopenharmony_ciJNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_planeHeight__III 188cb93a386Sopenharmony_ci (JNIEnv *env, jclass cls, jint componentID, jint height, jint subsamp) 189cb93a386Sopenharmony_ci{ 190cb93a386Sopenharmony_ci jint retval = (jint)tjPlaneHeight(componentID, height, subsamp); 191cb93a386Sopenharmony_ci 192cb93a386Sopenharmony_ci if (retval == -1) THROW_ARG(tjGetErrorStr()); 193cb93a386Sopenharmony_ci 194cb93a386Sopenharmony_cibailout: 195cb93a386Sopenharmony_ci return retval; 196cb93a386Sopenharmony_ci} 197cb93a386Sopenharmony_ci 198cb93a386Sopenharmony_ci/* TurboJPEG 1.2.x: TJCompressor::init() */ 199cb93a386Sopenharmony_ciJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_init 200cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj) 201cb93a386Sopenharmony_ci{ 202cb93a386Sopenharmony_ci jclass cls; 203cb93a386Sopenharmony_ci jfieldID fid; 204cb93a386Sopenharmony_ci tjhandle handle; 205cb93a386Sopenharmony_ci 206cb93a386Sopenharmony_ci if ((handle = tjInitCompress()) == NULL) 207cb93a386Sopenharmony_ci THROW(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException"); 208cb93a386Sopenharmony_ci 209cb93a386Sopenharmony_ci BAILIF0(cls = (*env)->GetObjectClass(env, obj)); 210cb93a386Sopenharmony_ci BAILIF0(fid = (*env)->GetFieldID(env, cls, "handle", "J")); 211cb93a386Sopenharmony_ci (*env)->SetLongField(env, obj, fid, (size_t)handle); 212cb93a386Sopenharmony_ci 213cb93a386Sopenharmony_cibailout: 214cb93a386Sopenharmony_ci return; 215cb93a386Sopenharmony_ci} 216cb93a386Sopenharmony_ci 217cb93a386Sopenharmony_cistatic jint TJCompressor_compress 218cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jarray src, jint srcElementSize, jint x, jint y, 219cb93a386Sopenharmony_ci jint width, jint pitch, jint height, jint pf, jbyteArray dst, 220cb93a386Sopenharmony_ci jint jpegSubsamp, jint jpegQual, jint flags) 221cb93a386Sopenharmony_ci{ 222cb93a386Sopenharmony_ci tjhandle handle = 0; 223cb93a386Sopenharmony_ci unsigned long jpegSize = 0; 224cb93a386Sopenharmony_ci jsize arraySize = 0, actualPitch; 225cb93a386Sopenharmony_ci unsigned char *srcBuf = NULL, *jpegBuf = NULL; 226cb93a386Sopenharmony_ci 227cb93a386Sopenharmony_ci GET_HANDLE(); 228cb93a386Sopenharmony_ci 229cb93a386Sopenharmony_ci if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF || width < 1 || 230cb93a386Sopenharmony_ci height < 1 || pitch < 0) 231cb93a386Sopenharmony_ci THROW_ARG("Invalid argument in compress()"); 232cb93a386Sopenharmony_ci if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF) 233cb93a386Sopenharmony_ci THROW_ARG("Mismatch between Java and C API"); 234cb93a386Sopenharmony_ci 235cb93a386Sopenharmony_ci actualPitch = (pitch == 0) ? width * tjPixelSize[pf] : pitch; 236cb93a386Sopenharmony_ci arraySize = (y + height - 1) * actualPitch + (x + width) * tjPixelSize[pf]; 237cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, src) * srcElementSize < arraySize) 238cb93a386Sopenharmony_ci THROW_ARG("Source buffer is not large enough"); 239cb93a386Sopenharmony_ci jpegSize = tjBufSize(width, height, jpegSubsamp); 240cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, dst) < (jsize)jpegSize) 241cb93a386Sopenharmony_ci THROW_ARG("Destination buffer is not large enough"); 242cb93a386Sopenharmony_ci 243cb93a386Sopenharmony_ci if (ProcessSystemProperties(env) < 0) goto bailout; 244cb93a386Sopenharmony_ci 245cb93a386Sopenharmony_ci BAILIF0(srcBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); 246cb93a386Sopenharmony_ci BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); 247cb93a386Sopenharmony_ci 248cb93a386Sopenharmony_ci if (tjCompress2(handle, &srcBuf[y * actualPitch + x * tjPixelSize[pf]], 249cb93a386Sopenharmony_ci width, pitch, height, pf, &jpegBuf, &jpegSize, jpegSubsamp, 250cb93a386Sopenharmony_ci jpegQual, flags | TJFLAG_NOREALLOC) == -1) { 251cb93a386Sopenharmony_ci SAFE_RELEASE(dst, jpegBuf); 252cb93a386Sopenharmony_ci SAFE_RELEASE(src, srcBuf); 253cb93a386Sopenharmony_ci THROW_TJ(); 254cb93a386Sopenharmony_ci } 255cb93a386Sopenharmony_ci 256cb93a386Sopenharmony_cibailout: 257cb93a386Sopenharmony_ci SAFE_RELEASE(dst, jpegBuf); 258cb93a386Sopenharmony_ci SAFE_RELEASE(src, srcBuf); 259cb93a386Sopenharmony_ci return (jint)jpegSize; 260cb93a386Sopenharmony_ci} 261cb93a386Sopenharmony_ci 262cb93a386Sopenharmony_ci/* TurboJPEG 1.3.x: TJCompressor::compress() byte source */ 263cb93a386Sopenharmony_ciJNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIIIII_3BIII 264cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jbyteArray src, jint x, jint y, jint width, 265cb93a386Sopenharmony_ci jint pitch, jint height, jint pf, jbyteArray dst, jint jpegSubsamp, 266cb93a386Sopenharmony_ci jint jpegQual, jint flags) 267cb93a386Sopenharmony_ci{ 268cb93a386Sopenharmony_ci return TJCompressor_compress(env, obj, src, 1, x, y, width, pitch, height, 269cb93a386Sopenharmony_ci pf, dst, jpegSubsamp, jpegQual, flags); 270cb93a386Sopenharmony_ci} 271cb93a386Sopenharmony_ci 272cb93a386Sopenharmony_ci/* TurboJPEG 1.2.x: TJCompressor::compress() byte source */ 273cb93a386Sopenharmony_ciJNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIII_3BIII 274cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch, 275cb93a386Sopenharmony_ci jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpegQual, 276cb93a386Sopenharmony_ci jint flags) 277cb93a386Sopenharmony_ci{ 278cb93a386Sopenharmony_ci return TJCompressor_compress(env, obj, src, 1, 0, 0, width, pitch, height, 279cb93a386Sopenharmony_ci pf, dst, jpegSubsamp, jpegQual, flags); 280cb93a386Sopenharmony_ci} 281cb93a386Sopenharmony_ci 282cb93a386Sopenharmony_ci/* TurboJPEG 1.3.x: TJCompressor::compress() int source */ 283cb93a386Sopenharmony_ciJNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIIIII_3BIII 284cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jintArray src, jint x, jint y, jint width, 285cb93a386Sopenharmony_ci jint stride, jint height, jint pf, jbyteArray dst, jint jpegSubsamp, 286cb93a386Sopenharmony_ci jint jpegQual, jint flags) 287cb93a386Sopenharmony_ci{ 288cb93a386Sopenharmony_ci if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) 289cb93a386Sopenharmony_ci THROW_ARG("Invalid argument in compress()"); 290cb93a386Sopenharmony_ci if (tjPixelSize[pf] != sizeof(jint)) 291cb93a386Sopenharmony_ci THROW_ARG("Pixel format must be 32-bit when compressing from an integer buffer."); 292cb93a386Sopenharmony_ci 293cb93a386Sopenharmony_ci return TJCompressor_compress(env, obj, src, sizeof(jint), x, y, width, 294cb93a386Sopenharmony_ci stride * sizeof(jint), height, pf, dst, 295cb93a386Sopenharmony_ci jpegSubsamp, jpegQual, flags); 296cb93a386Sopenharmony_ci 297cb93a386Sopenharmony_cibailout: 298cb93a386Sopenharmony_ci return 0; 299cb93a386Sopenharmony_ci} 300cb93a386Sopenharmony_ci 301cb93a386Sopenharmony_ci/* TurboJPEG 1.2.x: TJCompressor::compress() int source */ 302cb93a386Sopenharmony_ciJNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIII_3BIII 303cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jintArray src, jint width, jint stride, 304cb93a386Sopenharmony_ci jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpegQual, 305cb93a386Sopenharmony_ci jint flags) 306cb93a386Sopenharmony_ci{ 307cb93a386Sopenharmony_ci if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) 308cb93a386Sopenharmony_ci THROW_ARG("Invalid argument in compress()"); 309cb93a386Sopenharmony_ci if (tjPixelSize[pf] != sizeof(jint)) 310cb93a386Sopenharmony_ci THROW_ARG("Pixel format must be 32-bit when compressing from an integer buffer."); 311cb93a386Sopenharmony_ci 312cb93a386Sopenharmony_ci return TJCompressor_compress(env, obj, src, sizeof(jint), 0, 0, width, 313cb93a386Sopenharmony_ci stride * sizeof(jint), height, pf, dst, 314cb93a386Sopenharmony_ci jpegSubsamp, jpegQual, flags); 315cb93a386Sopenharmony_ci 316cb93a386Sopenharmony_cibailout: 317cb93a386Sopenharmony_ci return 0; 318cb93a386Sopenharmony_ci} 319cb93a386Sopenharmony_ci 320cb93a386Sopenharmony_ci/* TurboJPEG 1.4.x: TJCompressor::compressFromYUV() */ 321cb93a386Sopenharmony_ciJNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compressFromYUV___3_3B_3II_3III_3BII 322cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets, 323cb93a386Sopenharmony_ci jint width, jintArray jSrcStrides, jint height, jint subsamp, 324cb93a386Sopenharmony_ci jbyteArray dst, jint jpegQual, jint flags) 325cb93a386Sopenharmony_ci{ 326cb93a386Sopenharmony_ci tjhandle handle = 0; 327cb93a386Sopenharmony_ci unsigned long jpegSize = 0; 328cb93a386Sopenharmony_ci jbyteArray jSrcPlanes[3] = { NULL, NULL, NULL }; 329cb93a386Sopenharmony_ci const unsigned char *srcPlanesTmp[3] = { NULL, NULL, NULL }; 330cb93a386Sopenharmony_ci const unsigned char *srcPlanes[3] = { NULL, NULL, NULL }; 331cb93a386Sopenharmony_ci int *srcOffsetsTmp = NULL, srcOffsets[3] = { 0, 0, 0 }; 332cb93a386Sopenharmony_ci int *srcStridesTmp = NULL, srcStrides[3] = { 0, 0, 0 }; 333cb93a386Sopenharmony_ci unsigned char *jpegBuf = NULL; 334cb93a386Sopenharmony_ci int nc = (subsamp == org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY ? 1 : 3), i; 335cb93a386Sopenharmony_ci 336cb93a386Sopenharmony_ci GET_HANDLE(); 337cb93a386Sopenharmony_ci 338cb93a386Sopenharmony_ci if (subsamp < 0 || subsamp >= org_libjpegturbo_turbojpeg_TJ_NUMSAMP) 339cb93a386Sopenharmony_ci THROW_ARG("Invalid argument in compressFromYUV()"); 340cb93a386Sopenharmony_ci if (org_libjpegturbo_turbojpeg_TJ_NUMSAMP != TJ_NUMSAMP) 341cb93a386Sopenharmony_ci THROW_ARG("Mismatch between Java and C API"); 342cb93a386Sopenharmony_ci 343cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, srcobjs) < nc) 344cb93a386Sopenharmony_ci THROW_ARG("Planes array is too small for the subsampling type"); 345cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, jSrcOffsets) < nc) 346cb93a386Sopenharmony_ci THROW_ARG("Offsets array is too small for the subsampling type"); 347cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, jSrcStrides) < nc) 348cb93a386Sopenharmony_ci THROW_ARG("Strides array is too small for the subsampling type"); 349cb93a386Sopenharmony_ci 350cb93a386Sopenharmony_ci jpegSize = tjBufSize(width, height, subsamp); 351cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, dst) < (jsize)jpegSize) 352cb93a386Sopenharmony_ci THROW_ARG("Destination buffer is not large enough"); 353cb93a386Sopenharmony_ci 354cb93a386Sopenharmony_ci if (ProcessSystemProperties(env) < 0) goto bailout; 355cb93a386Sopenharmony_ci 356cb93a386Sopenharmony_ci BAILIF0(srcOffsetsTmp = 357cb93a386Sopenharmony_ci (*env)->GetPrimitiveArrayCritical(env, jSrcOffsets, 0)); 358cb93a386Sopenharmony_ci for (i = 0; i < nc; i++) srcOffsets[i] = srcOffsetsTmp[i]; 359cb93a386Sopenharmony_ci SAFE_RELEASE(jSrcOffsets, srcOffsetsTmp); 360cb93a386Sopenharmony_ci 361cb93a386Sopenharmony_ci BAILIF0(srcStridesTmp = 362cb93a386Sopenharmony_ci (*env)->GetPrimitiveArrayCritical(env, jSrcStrides, 0)); 363cb93a386Sopenharmony_ci for (i = 0; i < nc; i++) srcStrides[i] = srcStridesTmp[i]; 364cb93a386Sopenharmony_ci SAFE_RELEASE(jSrcStrides, srcStridesTmp); 365cb93a386Sopenharmony_ci 366cb93a386Sopenharmony_ci for (i = 0; i < nc; i++) { 367cb93a386Sopenharmony_ci int planeSize = tjPlaneSizeYUV(i, width, srcStrides[i], height, subsamp); 368cb93a386Sopenharmony_ci int pw = tjPlaneWidth(i, width, subsamp); 369cb93a386Sopenharmony_ci 370cb93a386Sopenharmony_ci if (planeSize < 0 || pw < 0) 371cb93a386Sopenharmony_ci THROW_ARG(tjGetErrorStr()); 372cb93a386Sopenharmony_ci 373cb93a386Sopenharmony_ci if (srcOffsets[i] < 0) 374cb93a386Sopenharmony_ci THROW_ARG("Invalid argument in compressFromYUV()"); 375cb93a386Sopenharmony_ci if (srcStrides[i] < 0 && srcOffsets[i] - planeSize + pw < 0) 376cb93a386Sopenharmony_ci THROW_ARG("Negative plane stride would cause memory to be accessed below plane boundary"); 377cb93a386Sopenharmony_ci 378cb93a386Sopenharmony_ci BAILIF0(jSrcPlanes[i] = (*env)->GetObjectArrayElement(env, srcobjs, i)); 379cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, jSrcPlanes[i]) < 380cb93a386Sopenharmony_ci srcOffsets[i] + planeSize) 381cb93a386Sopenharmony_ci THROW_ARG("Source plane is not large enough"); 382cb93a386Sopenharmony_ci 383cb93a386Sopenharmony_ci BAILIF0(srcPlanesTmp[i] = 384cb93a386Sopenharmony_ci (*env)->GetPrimitiveArrayCritical(env, jSrcPlanes[i], 0)); 385cb93a386Sopenharmony_ci srcPlanes[i] = &srcPlanesTmp[i][srcOffsets[i]]; 386cb93a386Sopenharmony_ci SAFE_RELEASE(jSrcPlanes[i], srcPlanesTmp[i]); 387cb93a386Sopenharmony_ci } 388cb93a386Sopenharmony_ci BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); 389cb93a386Sopenharmony_ci 390cb93a386Sopenharmony_ci if (tjCompressFromYUVPlanes(handle, srcPlanes, width, srcStrides, height, 391cb93a386Sopenharmony_ci subsamp, &jpegBuf, &jpegSize, jpegQual, 392cb93a386Sopenharmony_ci flags | TJFLAG_NOREALLOC) == -1) { 393cb93a386Sopenharmony_ci SAFE_RELEASE(dst, jpegBuf); 394cb93a386Sopenharmony_ci THROW_TJ(); 395cb93a386Sopenharmony_ci } 396cb93a386Sopenharmony_ci 397cb93a386Sopenharmony_cibailout: 398cb93a386Sopenharmony_ci SAFE_RELEASE(dst, jpegBuf); 399cb93a386Sopenharmony_ci return (jint)jpegSize; 400cb93a386Sopenharmony_ci} 401cb93a386Sopenharmony_ci 402cb93a386Sopenharmony_cistatic void TJCompressor_encodeYUV 403cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jarray src, jint srcElementSize, jint x, jint y, 404cb93a386Sopenharmony_ci jint width, jint pitch, jint height, jint pf, jobjectArray dstobjs, 405cb93a386Sopenharmony_ci jintArray jDstOffsets, jintArray jDstStrides, jint subsamp, jint flags) 406cb93a386Sopenharmony_ci{ 407cb93a386Sopenharmony_ci tjhandle handle = 0; 408cb93a386Sopenharmony_ci jsize arraySize = 0, actualPitch; 409cb93a386Sopenharmony_ci unsigned char *srcBuf = NULL; 410cb93a386Sopenharmony_ci jbyteArray jDstPlanes[3] = { NULL, NULL, NULL }; 411cb93a386Sopenharmony_ci unsigned char *dstPlanesTmp[3] = { NULL, NULL, NULL }; 412cb93a386Sopenharmony_ci unsigned char *dstPlanes[3] = { NULL, NULL, NULL }; 413cb93a386Sopenharmony_ci int *dstOffsetsTmp = NULL, dstOffsets[3] = { 0, 0, 0 }; 414cb93a386Sopenharmony_ci int *dstStridesTmp = NULL, dstStrides[3] = { 0, 0, 0 }; 415cb93a386Sopenharmony_ci int nc = (subsamp == org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY ? 1 : 3), i; 416cb93a386Sopenharmony_ci 417cb93a386Sopenharmony_ci GET_HANDLE(); 418cb93a386Sopenharmony_ci 419cb93a386Sopenharmony_ci if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF || width < 1 || 420cb93a386Sopenharmony_ci height < 1 || pitch < 0 || subsamp < 0 || 421cb93a386Sopenharmony_ci subsamp >= org_libjpegturbo_turbojpeg_TJ_NUMSAMP) 422cb93a386Sopenharmony_ci THROW_ARG("Invalid argument in encodeYUV()"); 423cb93a386Sopenharmony_ci if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF || 424cb93a386Sopenharmony_ci org_libjpegturbo_turbojpeg_TJ_NUMSAMP != TJ_NUMSAMP) 425cb93a386Sopenharmony_ci THROW_ARG("Mismatch between Java and C API"); 426cb93a386Sopenharmony_ci 427cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, dstobjs) < nc) 428cb93a386Sopenharmony_ci THROW_ARG("Planes array is too small for the subsampling type"); 429cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, jDstOffsets) < nc) 430cb93a386Sopenharmony_ci THROW_ARG("Offsets array is too small for the subsampling type"); 431cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, jDstStrides) < nc) 432cb93a386Sopenharmony_ci THROW_ARG("Strides array is too small for the subsampling type"); 433cb93a386Sopenharmony_ci 434cb93a386Sopenharmony_ci actualPitch = (pitch == 0) ? width * tjPixelSize[pf] : pitch; 435cb93a386Sopenharmony_ci arraySize = (y + height - 1) * actualPitch + (x + width) * tjPixelSize[pf]; 436cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, src) * srcElementSize < arraySize) 437cb93a386Sopenharmony_ci THROW_ARG("Source buffer is not large enough"); 438cb93a386Sopenharmony_ci 439cb93a386Sopenharmony_ci BAILIF0(dstOffsetsTmp = 440cb93a386Sopenharmony_ci (*env)->GetPrimitiveArrayCritical(env, jDstOffsets, 0)); 441cb93a386Sopenharmony_ci for (i = 0; i < nc; i++) dstOffsets[i] = dstOffsetsTmp[i]; 442cb93a386Sopenharmony_ci SAFE_RELEASE(jDstOffsets, dstOffsetsTmp); 443cb93a386Sopenharmony_ci 444cb93a386Sopenharmony_ci BAILIF0(dstStridesTmp = 445cb93a386Sopenharmony_ci (*env)->GetPrimitiveArrayCritical(env, jDstStrides, 0)); 446cb93a386Sopenharmony_ci for (i = 0; i < nc; i++) dstStrides[i] = dstStridesTmp[i]; 447cb93a386Sopenharmony_ci SAFE_RELEASE(jDstStrides, dstStridesTmp); 448cb93a386Sopenharmony_ci 449cb93a386Sopenharmony_ci for (i = 0; i < nc; i++) { 450cb93a386Sopenharmony_ci int planeSize = tjPlaneSizeYUV(i, width, dstStrides[i], height, subsamp); 451cb93a386Sopenharmony_ci int pw = tjPlaneWidth(i, width, subsamp); 452cb93a386Sopenharmony_ci 453cb93a386Sopenharmony_ci if (planeSize < 0 || pw < 0) 454cb93a386Sopenharmony_ci THROW_ARG(tjGetErrorStr()); 455cb93a386Sopenharmony_ci 456cb93a386Sopenharmony_ci if (dstOffsets[i] < 0) 457cb93a386Sopenharmony_ci THROW_ARG("Invalid argument in encodeYUV()"); 458cb93a386Sopenharmony_ci if (dstStrides[i] < 0 && dstOffsets[i] - planeSize + pw < 0) 459cb93a386Sopenharmony_ci THROW_ARG("Negative plane stride would cause memory to be accessed below plane boundary"); 460cb93a386Sopenharmony_ci 461cb93a386Sopenharmony_ci BAILIF0(jDstPlanes[i] = (*env)->GetObjectArrayElement(env, dstobjs, i)); 462cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, jDstPlanes[i]) < 463cb93a386Sopenharmony_ci dstOffsets[i] + planeSize) 464cb93a386Sopenharmony_ci THROW_ARG("Destination plane is not large enough"); 465cb93a386Sopenharmony_ci 466cb93a386Sopenharmony_ci BAILIF0(dstPlanesTmp[i] = 467cb93a386Sopenharmony_ci (*env)->GetPrimitiveArrayCritical(env, jDstPlanes[i], 0)); 468cb93a386Sopenharmony_ci dstPlanes[i] = &dstPlanesTmp[i][dstOffsets[i]]; 469cb93a386Sopenharmony_ci SAFE_RELEASE(jDstPlanes[i], dstPlanesTmp[i]); 470cb93a386Sopenharmony_ci } 471cb93a386Sopenharmony_ci BAILIF0(srcBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); 472cb93a386Sopenharmony_ci 473cb93a386Sopenharmony_ci if (tjEncodeYUVPlanes(handle, &srcBuf[y * actualPitch + x * tjPixelSize[pf]], 474cb93a386Sopenharmony_ci width, pitch, height, pf, dstPlanes, dstStrides, 475cb93a386Sopenharmony_ci subsamp, flags) == -1) { 476cb93a386Sopenharmony_ci SAFE_RELEASE(src, srcBuf); 477cb93a386Sopenharmony_ci THROW_TJ(); 478cb93a386Sopenharmony_ci } 479cb93a386Sopenharmony_ci 480cb93a386Sopenharmony_cibailout: 481cb93a386Sopenharmony_ci SAFE_RELEASE(src, srcBuf); 482cb93a386Sopenharmony_ci} 483cb93a386Sopenharmony_ci 484cb93a386Sopenharmony_ci/* TurboJPEG 1.4.x: TJCompressor::encodeYUV() byte source */ 485cb93a386Sopenharmony_ciJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIIIII_3_3B_3I_3III 486cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jbyteArray src, jint x, jint y, jint width, 487cb93a386Sopenharmony_ci jint pitch, jint height, jint pf, jobjectArray dstobjs, 488cb93a386Sopenharmony_ci jintArray jDstOffsets, jintArray jDstStrides, jint subsamp, jint flags) 489cb93a386Sopenharmony_ci{ 490cb93a386Sopenharmony_ci TJCompressor_encodeYUV(env, obj, src, 1, x, y, width, pitch, height, pf, 491cb93a386Sopenharmony_ci dstobjs, jDstOffsets, jDstStrides, subsamp, flags); 492cb93a386Sopenharmony_ci} 493cb93a386Sopenharmony_ci 494cb93a386Sopenharmony_ci/* TurboJPEG 1.4.x: TJCompressor::encodeYUV() int source */ 495cb93a386Sopenharmony_ciJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIIIII_3_3B_3I_3III 496cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jintArray src, jint x, jint y, jint width, 497cb93a386Sopenharmony_ci jint stride, jint height, jint pf, jobjectArray dstobjs, 498cb93a386Sopenharmony_ci jintArray jDstOffsets, jintArray jDstStrides, jint subsamp, jint flags) 499cb93a386Sopenharmony_ci{ 500cb93a386Sopenharmony_ci if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) 501cb93a386Sopenharmony_ci THROW_ARG("Invalid argument in encodeYUV()"); 502cb93a386Sopenharmony_ci if (tjPixelSize[pf] != sizeof(jint)) 503cb93a386Sopenharmony_ci THROW_ARG("Pixel format must be 32-bit when encoding from an integer buffer."); 504cb93a386Sopenharmony_ci 505cb93a386Sopenharmony_ci TJCompressor_encodeYUV(env, obj, src, sizeof(jint), x, y, width, 506cb93a386Sopenharmony_ci stride * sizeof(jint), height, pf, dstobjs, 507cb93a386Sopenharmony_ci jDstOffsets, jDstStrides, subsamp, flags); 508cb93a386Sopenharmony_ci 509cb93a386Sopenharmony_cibailout: 510cb93a386Sopenharmony_ci return; 511cb93a386Sopenharmony_ci} 512cb93a386Sopenharmony_ci 513cb93a386Sopenharmony_cistatic void JNICALL TJCompressor_encodeYUV_12 514cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jarray src, jint srcElementSize, jint width, 515cb93a386Sopenharmony_ci jint pitch, jint height, jint pf, jbyteArray dst, jint subsamp, jint flags) 516cb93a386Sopenharmony_ci{ 517cb93a386Sopenharmony_ci tjhandle handle = 0; 518cb93a386Sopenharmony_ci jsize arraySize = 0; 519cb93a386Sopenharmony_ci unsigned char *srcBuf = NULL, *dstBuf = NULL; 520cb93a386Sopenharmony_ci 521cb93a386Sopenharmony_ci GET_HANDLE(); 522cb93a386Sopenharmony_ci 523cb93a386Sopenharmony_ci if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF || width < 1 || 524cb93a386Sopenharmony_ci height < 1 || pitch < 0) 525cb93a386Sopenharmony_ci THROW_ARG("Invalid argument in encodeYUV()"); 526cb93a386Sopenharmony_ci if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF) 527cb93a386Sopenharmony_ci THROW_ARG("Mismatch between Java and C API"); 528cb93a386Sopenharmony_ci 529cb93a386Sopenharmony_ci arraySize = (pitch == 0) ? width * tjPixelSize[pf] * height : pitch * height; 530cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, src) * srcElementSize < arraySize) 531cb93a386Sopenharmony_ci THROW_ARG("Source buffer is not large enough"); 532cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, dst) < 533cb93a386Sopenharmony_ci (jsize)tjBufSizeYUV(width, height, subsamp)) 534cb93a386Sopenharmony_ci THROW_ARG("Destination buffer is not large enough"); 535cb93a386Sopenharmony_ci 536cb93a386Sopenharmony_ci BAILIF0(srcBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); 537cb93a386Sopenharmony_ci BAILIF0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); 538cb93a386Sopenharmony_ci 539cb93a386Sopenharmony_ci if (tjEncodeYUV2(handle, srcBuf, width, pitch, height, pf, dstBuf, subsamp, 540cb93a386Sopenharmony_ci flags) == -1) { 541cb93a386Sopenharmony_ci SAFE_RELEASE(dst, dstBuf); 542cb93a386Sopenharmony_ci SAFE_RELEASE(src, srcBuf); 543cb93a386Sopenharmony_ci THROW_TJ(); 544cb93a386Sopenharmony_ci } 545cb93a386Sopenharmony_ci 546cb93a386Sopenharmony_cibailout: 547cb93a386Sopenharmony_ci SAFE_RELEASE(dst, dstBuf); 548cb93a386Sopenharmony_ci SAFE_RELEASE(src, srcBuf); 549cb93a386Sopenharmony_ci} 550cb93a386Sopenharmony_ci 551cb93a386Sopenharmony_ci/* TurboJPEG 1.2.x: TJCompressor::encodeYUV() byte source */ 552cb93a386Sopenharmony_ciJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIII_3BII 553cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch, 554cb93a386Sopenharmony_ci jint height, jint pf, jbyteArray dst, jint subsamp, jint flags) 555cb93a386Sopenharmony_ci{ 556cb93a386Sopenharmony_ci TJCompressor_encodeYUV_12(env, obj, src, 1, width, pitch, height, pf, dst, 557cb93a386Sopenharmony_ci subsamp, flags); 558cb93a386Sopenharmony_ci} 559cb93a386Sopenharmony_ci 560cb93a386Sopenharmony_ci/* TurboJPEG 1.2.x: TJCompressor::encodeYUV() int source */ 561cb93a386Sopenharmony_ciJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIII_3BII 562cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jintArray src, jint width, jint stride, 563cb93a386Sopenharmony_ci jint height, jint pf, jbyteArray dst, jint subsamp, jint flags) 564cb93a386Sopenharmony_ci{ 565cb93a386Sopenharmony_ci if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) 566cb93a386Sopenharmony_ci THROW_ARG("Invalid argument in encodeYUV()"); 567cb93a386Sopenharmony_ci if (tjPixelSize[pf] != sizeof(jint)) 568cb93a386Sopenharmony_ci THROW_ARG("Pixel format must be 32-bit when encoding from an integer buffer."); 569cb93a386Sopenharmony_ci 570cb93a386Sopenharmony_ci TJCompressor_encodeYUV_12(env, obj, src, sizeof(jint), width, 571cb93a386Sopenharmony_ci stride * sizeof(jint), height, pf, dst, subsamp, 572cb93a386Sopenharmony_ci flags); 573cb93a386Sopenharmony_ci 574cb93a386Sopenharmony_cibailout: 575cb93a386Sopenharmony_ci return; 576cb93a386Sopenharmony_ci} 577cb93a386Sopenharmony_ci 578cb93a386Sopenharmony_ci/* TurboJPEG 1.2.x: TJCompressor::destroy() */ 579cb93a386Sopenharmony_ciJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy 580cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj) 581cb93a386Sopenharmony_ci{ 582cb93a386Sopenharmony_ci tjhandle handle = 0; 583cb93a386Sopenharmony_ci 584cb93a386Sopenharmony_ci GET_HANDLE(); 585cb93a386Sopenharmony_ci 586cb93a386Sopenharmony_ci if (tjDestroy(handle) == -1) THROW_TJ(); 587cb93a386Sopenharmony_ci (*env)->SetLongField(env, obj, _fid, 0); 588cb93a386Sopenharmony_ci 589cb93a386Sopenharmony_cibailout: 590cb93a386Sopenharmony_ci return; 591cb93a386Sopenharmony_ci} 592cb93a386Sopenharmony_ci 593cb93a386Sopenharmony_ci/* TurboJPEG 1.2.x: TJDecompressor::init() */ 594cb93a386Sopenharmony_ciJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_init 595cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj) 596cb93a386Sopenharmony_ci{ 597cb93a386Sopenharmony_ci jclass cls; 598cb93a386Sopenharmony_ci jfieldID fid; 599cb93a386Sopenharmony_ci tjhandle handle; 600cb93a386Sopenharmony_ci 601cb93a386Sopenharmony_ci if ((handle = tjInitDecompress()) == NULL) 602cb93a386Sopenharmony_ci THROW(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException"); 603cb93a386Sopenharmony_ci 604cb93a386Sopenharmony_ci BAILIF0(cls = (*env)->GetObjectClass(env, obj)); 605cb93a386Sopenharmony_ci BAILIF0(fid = (*env)->GetFieldID(env, cls, "handle", "J")); 606cb93a386Sopenharmony_ci (*env)->SetLongField(env, obj, fid, (size_t)handle); 607cb93a386Sopenharmony_ci 608cb93a386Sopenharmony_cibailout: 609cb93a386Sopenharmony_ci return; 610cb93a386Sopenharmony_ci} 611cb93a386Sopenharmony_ci 612cb93a386Sopenharmony_ci/* TurboJPEG 1.2.x: TJDecompressor::getScalingFactors() */ 613cb93a386Sopenharmony_ciJNIEXPORT jobjectArray JNICALL Java_org_libjpegturbo_turbojpeg_TJ_getScalingFactors 614cb93a386Sopenharmony_ci (JNIEnv *env, jclass cls) 615cb93a386Sopenharmony_ci{ 616cb93a386Sopenharmony_ci jclass sfcls = NULL; 617cb93a386Sopenharmony_ci jfieldID fid = 0; 618cb93a386Sopenharmony_ci tjscalingfactor *sf = NULL; 619cb93a386Sopenharmony_ci int n = 0, i; 620cb93a386Sopenharmony_ci jobject sfobj = NULL; 621cb93a386Sopenharmony_ci jobjectArray sfjava = NULL; 622cb93a386Sopenharmony_ci 623cb93a386Sopenharmony_ci if ((sf = tjGetScalingFactors(&n)) == NULL || n == 0) 624cb93a386Sopenharmony_ci THROW_ARG(tjGetErrorStr()); 625cb93a386Sopenharmony_ci 626cb93a386Sopenharmony_ci BAILIF0(sfcls = (*env)->FindClass(env, 627cb93a386Sopenharmony_ci "org/libjpegturbo/turbojpeg/TJScalingFactor")); 628cb93a386Sopenharmony_ci BAILIF0(sfjava = (jobjectArray)(*env)->NewObjectArray(env, n, sfcls, 0)); 629cb93a386Sopenharmony_ci 630cb93a386Sopenharmony_ci for (i = 0; i < n; i++) { 631cb93a386Sopenharmony_ci BAILIF0(sfobj = (*env)->AllocObject(env, sfcls)); 632cb93a386Sopenharmony_ci BAILIF0(fid = (*env)->GetFieldID(env, sfcls, "num", "I")); 633cb93a386Sopenharmony_ci (*env)->SetIntField(env, sfobj, fid, sf[i].num); 634cb93a386Sopenharmony_ci BAILIF0(fid = (*env)->GetFieldID(env, sfcls, "denom", "I")); 635cb93a386Sopenharmony_ci (*env)->SetIntField(env, sfobj, fid, sf[i].denom); 636cb93a386Sopenharmony_ci (*env)->SetObjectArrayElement(env, sfjava, i, sfobj); 637cb93a386Sopenharmony_ci } 638cb93a386Sopenharmony_ci 639cb93a386Sopenharmony_cibailout: 640cb93a386Sopenharmony_ci return sfjava; 641cb93a386Sopenharmony_ci} 642cb93a386Sopenharmony_ci 643cb93a386Sopenharmony_ci/* TurboJPEG 1.2.x: TJDecompressor::decompressHeader() */ 644cb93a386Sopenharmony_ciJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressHeader 645cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize) 646cb93a386Sopenharmony_ci{ 647cb93a386Sopenharmony_ci tjhandle handle = 0; 648cb93a386Sopenharmony_ci unsigned char *jpegBuf = NULL; 649cb93a386Sopenharmony_ci int width = 0, height = 0, jpegSubsamp = -1, jpegColorspace = -1; 650cb93a386Sopenharmony_ci 651cb93a386Sopenharmony_ci GET_HANDLE(); 652cb93a386Sopenharmony_ci 653cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, src) < jpegSize) 654cb93a386Sopenharmony_ci THROW_ARG("Source buffer is not large enough"); 655cb93a386Sopenharmony_ci 656cb93a386Sopenharmony_ci BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); 657cb93a386Sopenharmony_ci 658cb93a386Sopenharmony_ci if (tjDecompressHeader3(handle, jpegBuf, (unsigned long)jpegSize, &width, 659cb93a386Sopenharmony_ci &height, &jpegSubsamp, &jpegColorspace) == -1) { 660cb93a386Sopenharmony_ci SAFE_RELEASE(src, jpegBuf); 661cb93a386Sopenharmony_ci THROW_TJ(); 662cb93a386Sopenharmony_ci } 663cb93a386Sopenharmony_ci 664cb93a386Sopenharmony_ci SAFE_RELEASE(src, jpegBuf); 665cb93a386Sopenharmony_ci 666cb93a386Sopenharmony_ci BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I")); 667cb93a386Sopenharmony_ci (*env)->SetIntField(env, obj, _fid, jpegSubsamp); 668cb93a386Sopenharmony_ci if ((_fid = (*env)->GetFieldID(env, _cls, "jpegColorspace", "I")) == 0) 669cb93a386Sopenharmony_ci (*env)->ExceptionClear(env); 670cb93a386Sopenharmony_ci else 671cb93a386Sopenharmony_ci (*env)->SetIntField(env, obj, _fid, jpegColorspace); 672cb93a386Sopenharmony_ci BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I")); 673cb93a386Sopenharmony_ci (*env)->SetIntField(env, obj, _fid, width); 674cb93a386Sopenharmony_ci BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I")); 675cb93a386Sopenharmony_ci (*env)->SetIntField(env, obj, _fid, height); 676cb93a386Sopenharmony_ci 677cb93a386Sopenharmony_cibailout: 678cb93a386Sopenharmony_ci SAFE_RELEASE(src, jpegBuf); 679cb93a386Sopenharmony_ci} 680cb93a386Sopenharmony_ci 681cb93a386Sopenharmony_cistatic void TJDecompressor_decompress 682cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jarray dst, 683cb93a386Sopenharmony_ci jint dstElementSize, jint x, jint y, jint width, jint pitch, jint height, 684cb93a386Sopenharmony_ci jint pf, jint flags) 685cb93a386Sopenharmony_ci{ 686cb93a386Sopenharmony_ci tjhandle handle = 0; 687cb93a386Sopenharmony_ci jsize arraySize = 0, actualPitch; 688cb93a386Sopenharmony_ci unsigned char *jpegBuf = NULL, *dstBuf = NULL; 689cb93a386Sopenharmony_ci 690cb93a386Sopenharmony_ci GET_HANDLE(); 691cb93a386Sopenharmony_ci 692cb93a386Sopenharmony_ci if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) 693cb93a386Sopenharmony_ci THROW_ARG("Invalid argument in decompress()"); 694cb93a386Sopenharmony_ci if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF) 695cb93a386Sopenharmony_ci THROW_ARG("Mismatch between Java and C API"); 696cb93a386Sopenharmony_ci 697cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, src) < jpegSize) 698cb93a386Sopenharmony_ci THROW_ARG("Source buffer is not large enough"); 699cb93a386Sopenharmony_ci actualPitch = (pitch == 0) ? width * tjPixelSize[pf] : pitch; 700cb93a386Sopenharmony_ci arraySize = (y + height - 1) * actualPitch + (x + width) * tjPixelSize[pf]; 701cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, dst) * dstElementSize < arraySize) 702cb93a386Sopenharmony_ci THROW_ARG("Destination buffer is not large enough"); 703cb93a386Sopenharmony_ci 704cb93a386Sopenharmony_ci BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); 705cb93a386Sopenharmony_ci BAILIF0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); 706cb93a386Sopenharmony_ci 707cb93a386Sopenharmony_ci if (tjDecompress2(handle, jpegBuf, (unsigned long)jpegSize, 708cb93a386Sopenharmony_ci &dstBuf[y * actualPitch + x * tjPixelSize[pf]], width, 709cb93a386Sopenharmony_ci pitch, height, pf, flags) == -1) { 710cb93a386Sopenharmony_ci SAFE_RELEASE(dst, dstBuf); 711cb93a386Sopenharmony_ci SAFE_RELEASE(src, jpegBuf); 712cb93a386Sopenharmony_ci THROW_TJ(); 713cb93a386Sopenharmony_ci } 714cb93a386Sopenharmony_ci 715cb93a386Sopenharmony_cibailout: 716cb93a386Sopenharmony_ci SAFE_RELEASE(dst, dstBuf); 717cb93a386Sopenharmony_ci SAFE_RELEASE(src, jpegBuf); 718cb93a386Sopenharmony_ci} 719cb93a386Sopenharmony_ci 720cb93a386Sopenharmony_ci/* TurboJPEG 1.3.x: TJDecompressor::decompress() byte destination */ 721cb93a386Sopenharmony_ciJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIIIII 722cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst, 723cb93a386Sopenharmony_ci jint x, jint y, jint width, jint pitch, jint height, jint pf, jint flags) 724cb93a386Sopenharmony_ci{ 725cb93a386Sopenharmony_ci TJDecompressor_decompress(env, obj, src, jpegSize, dst, 1, x, y, width, 726cb93a386Sopenharmony_ci pitch, height, pf, flags); 727cb93a386Sopenharmony_ci} 728cb93a386Sopenharmony_ci 729cb93a386Sopenharmony_ci/* TurboJPEG 1.2.x: TJDecompressor::decompress() byte destination */ 730cb93a386Sopenharmony_ciJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIII 731cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst, 732cb93a386Sopenharmony_ci jint width, jint pitch, jint height, jint pf, jint flags) 733cb93a386Sopenharmony_ci{ 734cb93a386Sopenharmony_ci TJDecompressor_decompress(env, obj, src, jpegSize, dst, 1, 0, 0, width, 735cb93a386Sopenharmony_ci pitch, height, pf, flags); 736cb93a386Sopenharmony_ci} 737cb93a386Sopenharmony_ci 738cb93a386Sopenharmony_ci/* TurboJPEG 1.3.x: TJDecompressor::decompress() int destination */ 739cb93a386Sopenharmony_ciJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIIIII 740cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jintArray dst, 741cb93a386Sopenharmony_ci jint x, jint y, jint width, jint stride, jint height, jint pf, jint flags) 742cb93a386Sopenharmony_ci{ 743cb93a386Sopenharmony_ci if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) 744cb93a386Sopenharmony_ci THROW_ARG("Invalid argument in decompress()"); 745cb93a386Sopenharmony_ci if (tjPixelSize[pf] != sizeof(jint)) 746cb93a386Sopenharmony_ci THROW_ARG("Pixel format must be 32-bit when decompressing to an integer buffer."); 747cb93a386Sopenharmony_ci 748cb93a386Sopenharmony_ci TJDecompressor_decompress(env, obj, src, jpegSize, dst, sizeof(jint), x, y, 749cb93a386Sopenharmony_ci width, stride * sizeof(jint), height, pf, flags); 750cb93a386Sopenharmony_ci 751cb93a386Sopenharmony_cibailout: 752cb93a386Sopenharmony_ci return; 753cb93a386Sopenharmony_ci} 754cb93a386Sopenharmony_ci 755cb93a386Sopenharmony_ci/* TurboJPEG 1.2.x: TJDecompressor::decompress() int destination */ 756cb93a386Sopenharmony_ciJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIII 757cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jintArray dst, 758cb93a386Sopenharmony_ci jint width, jint stride, jint height, jint pf, jint flags) 759cb93a386Sopenharmony_ci{ 760cb93a386Sopenharmony_ci if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) 761cb93a386Sopenharmony_ci THROW_ARG("Invalid argument in decompress()"); 762cb93a386Sopenharmony_ci if (tjPixelSize[pf] != sizeof(jint)) 763cb93a386Sopenharmony_ci THROW_ARG("Pixel format must be 32-bit when decompressing to an integer buffer."); 764cb93a386Sopenharmony_ci 765cb93a386Sopenharmony_ci TJDecompressor_decompress(env, obj, src, jpegSize, dst, sizeof(jint), 0, 0, 766cb93a386Sopenharmony_ci width, stride * sizeof(jint), height, pf, flags); 767cb93a386Sopenharmony_ci 768cb93a386Sopenharmony_cibailout: 769cb93a386Sopenharmony_ci return; 770cb93a386Sopenharmony_ci} 771cb93a386Sopenharmony_ci 772cb93a386Sopenharmony_ci/* TurboJPEG 1.4.x: TJDecompressor::decompressToYUV() */ 773cb93a386Sopenharmony_ciJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3_3B_3II_3III 774cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, 775cb93a386Sopenharmony_ci jobjectArray dstobjs, jintArray jDstOffsets, jint desiredWidth, 776cb93a386Sopenharmony_ci jintArray jDstStrides, jint desiredHeight, jint flags) 777cb93a386Sopenharmony_ci{ 778cb93a386Sopenharmony_ci tjhandle handle = 0; 779cb93a386Sopenharmony_ci unsigned char *jpegBuf = NULL; 780cb93a386Sopenharmony_ci jbyteArray jDstPlanes[3] = { NULL, NULL, NULL }; 781cb93a386Sopenharmony_ci unsigned char *dstPlanesTmp[3] = { NULL, NULL, NULL }; 782cb93a386Sopenharmony_ci unsigned char *dstPlanes[3] = { NULL, NULL, NULL }; 783cb93a386Sopenharmony_ci int *dstOffsetsTmp = NULL, dstOffsets[3] = { 0, 0, 0 }; 784cb93a386Sopenharmony_ci int *dstStridesTmp = NULL, dstStrides[3] = { 0, 0, 0 }; 785cb93a386Sopenharmony_ci int jpegSubsamp = -1, jpegWidth = 0, jpegHeight = 0; 786cb93a386Sopenharmony_ci int nc = 0, i, width, height, scaledWidth, scaledHeight, nsf = 0; 787cb93a386Sopenharmony_ci tjscalingfactor *sf; 788cb93a386Sopenharmony_ci 789cb93a386Sopenharmony_ci GET_HANDLE(); 790cb93a386Sopenharmony_ci 791cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, src) < jpegSize) 792cb93a386Sopenharmony_ci THROW_ARG("Source buffer is not large enough"); 793cb93a386Sopenharmony_ci BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I")); 794cb93a386Sopenharmony_ci jpegSubsamp = (int)(*env)->GetIntField(env, obj, _fid); 795cb93a386Sopenharmony_ci BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I")); 796cb93a386Sopenharmony_ci jpegWidth = (int)(*env)->GetIntField(env, obj, _fid); 797cb93a386Sopenharmony_ci BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I")); 798cb93a386Sopenharmony_ci jpegHeight = (int)(*env)->GetIntField(env, obj, _fid); 799cb93a386Sopenharmony_ci 800cb93a386Sopenharmony_ci nc = (jpegSubsamp == org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY ? 1 : 3); 801cb93a386Sopenharmony_ci 802cb93a386Sopenharmony_ci width = desiredWidth; 803cb93a386Sopenharmony_ci height = desiredHeight; 804cb93a386Sopenharmony_ci if (width == 0) width = jpegWidth; 805cb93a386Sopenharmony_ci if (height == 0) height = jpegHeight; 806cb93a386Sopenharmony_ci sf = tjGetScalingFactors(&nsf); 807cb93a386Sopenharmony_ci if (!sf || nsf < 1) 808cb93a386Sopenharmony_ci THROW_ARG(tjGetErrorStr()); 809cb93a386Sopenharmony_ci for (i = 0; i < nsf; i++) { 810cb93a386Sopenharmony_ci scaledWidth = TJSCALED(jpegWidth, sf[i]); 811cb93a386Sopenharmony_ci scaledHeight = TJSCALED(jpegHeight, sf[i]); 812cb93a386Sopenharmony_ci if (scaledWidth <= width && scaledHeight <= height) 813cb93a386Sopenharmony_ci break; 814cb93a386Sopenharmony_ci } 815cb93a386Sopenharmony_ci if (i >= nsf) 816cb93a386Sopenharmony_ci THROW_ARG("Could not scale down to desired image dimensions"); 817cb93a386Sopenharmony_ci 818cb93a386Sopenharmony_ci BAILIF0(dstOffsetsTmp = 819cb93a386Sopenharmony_ci (*env)->GetPrimitiveArrayCritical(env, jDstOffsets, 0)); 820cb93a386Sopenharmony_ci for (i = 0; i < nc; i++) dstOffsets[i] = dstOffsetsTmp[i]; 821cb93a386Sopenharmony_ci SAFE_RELEASE(jDstOffsets, dstOffsetsTmp); 822cb93a386Sopenharmony_ci 823cb93a386Sopenharmony_ci BAILIF0(dstStridesTmp = 824cb93a386Sopenharmony_ci (*env)->GetPrimitiveArrayCritical(env, jDstStrides, 0)); 825cb93a386Sopenharmony_ci for (i = 0; i < nc; i++) dstStrides[i] = dstStridesTmp[i]; 826cb93a386Sopenharmony_ci SAFE_RELEASE(jDstStrides, dstStridesTmp); 827cb93a386Sopenharmony_ci 828cb93a386Sopenharmony_ci for (i = 0; i < nc; i++) { 829cb93a386Sopenharmony_ci int planeSize = tjPlaneSizeYUV(i, scaledWidth, dstStrides[i], scaledHeight, 830cb93a386Sopenharmony_ci jpegSubsamp); 831cb93a386Sopenharmony_ci int pw = tjPlaneWidth(i, scaledWidth, jpegSubsamp); 832cb93a386Sopenharmony_ci 833cb93a386Sopenharmony_ci if (planeSize < 0 || pw < 0) 834cb93a386Sopenharmony_ci THROW_ARG(tjGetErrorStr()); 835cb93a386Sopenharmony_ci 836cb93a386Sopenharmony_ci if (dstOffsets[i] < 0) 837cb93a386Sopenharmony_ci THROW_ARG("Invalid argument in decompressToYUV()"); 838cb93a386Sopenharmony_ci if (dstStrides[i] < 0 && dstOffsets[i] - planeSize + pw < 0) 839cb93a386Sopenharmony_ci THROW_ARG("Negative plane stride would cause memory to be accessed below plane boundary"); 840cb93a386Sopenharmony_ci 841cb93a386Sopenharmony_ci BAILIF0(jDstPlanes[i] = (*env)->GetObjectArrayElement(env, dstobjs, i)); 842cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, jDstPlanes[i]) < 843cb93a386Sopenharmony_ci dstOffsets[i] + planeSize) 844cb93a386Sopenharmony_ci THROW_ARG("Destination plane is not large enough"); 845cb93a386Sopenharmony_ci 846cb93a386Sopenharmony_ci BAILIF0(dstPlanesTmp[i] = 847cb93a386Sopenharmony_ci (*env)->GetPrimitiveArrayCritical(env, jDstPlanes[i], 0)); 848cb93a386Sopenharmony_ci dstPlanes[i] = &dstPlanesTmp[i][dstOffsets[i]]; 849cb93a386Sopenharmony_ci SAFE_RELEASE(jDstPlanes[i], dstPlanesTmp[i]); 850cb93a386Sopenharmony_ci } 851cb93a386Sopenharmony_ci BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); 852cb93a386Sopenharmony_ci 853cb93a386Sopenharmony_ci if (tjDecompressToYUVPlanes(handle, jpegBuf, (unsigned long)jpegSize, 854cb93a386Sopenharmony_ci dstPlanes, desiredWidth, dstStrides, 855cb93a386Sopenharmony_ci desiredHeight, flags) == -1) { 856cb93a386Sopenharmony_ci SAFE_RELEASE(src, jpegBuf); 857cb93a386Sopenharmony_ci THROW_TJ(); 858cb93a386Sopenharmony_ci } 859cb93a386Sopenharmony_ci 860cb93a386Sopenharmony_cibailout: 861cb93a386Sopenharmony_ci SAFE_RELEASE(src, jpegBuf); 862cb93a386Sopenharmony_ci} 863cb93a386Sopenharmony_ci 864cb93a386Sopenharmony_ci/* TurboJPEG 1.2.x: TJDecompressor::decompressToYUV() */ 865cb93a386Sopenharmony_ciJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3BI 866cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst, 867cb93a386Sopenharmony_ci jint flags) 868cb93a386Sopenharmony_ci{ 869cb93a386Sopenharmony_ci tjhandle handle = 0; 870cb93a386Sopenharmony_ci unsigned char *jpegBuf = NULL, *dstBuf = NULL; 871cb93a386Sopenharmony_ci int jpegSubsamp = -1, jpegWidth = 0, jpegHeight = 0; 872cb93a386Sopenharmony_ci 873cb93a386Sopenharmony_ci GET_HANDLE(); 874cb93a386Sopenharmony_ci 875cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, src) < jpegSize) 876cb93a386Sopenharmony_ci THROW_ARG("Source buffer is not large enough"); 877cb93a386Sopenharmony_ci BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I")); 878cb93a386Sopenharmony_ci jpegSubsamp = (int)(*env)->GetIntField(env, obj, _fid); 879cb93a386Sopenharmony_ci BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I")); 880cb93a386Sopenharmony_ci jpegWidth = (int)(*env)->GetIntField(env, obj, _fid); 881cb93a386Sopenharmony_ci BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I")); 882cb93a386Sopenharmony_ci jpegHeight = (int)(*env)->GetIntField(env, obj, _fid); 883cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, dst) < 884cb93a386Sopenharmony_ci (jsize)tjBufSizeYUV(jpegWidth, jpegHeight, jpegSubsamp)) 885cb93a386Sopenharmony_ci THROW_ARG("Destination buffer is not large enough"); 886cb93a386Sopenharmony_ci 887cb93a386Sopenharmony_ci BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, src, 0)); 888cb93a386Sopenharmony_ci BAILIF0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); 889cb93a386Sopenharmony_ci 890cb93a386Sopenharmony_ci if (tjDecompressToYUV(handle, jpegBuf, (unsigned long)jpegSize, dstBuf, 891cb93a386Sopenharmony_ci flags) == -1) { 892cb93a386Sopenharmony_ci SAFE_RELEASE(dst, dstBuf); 893cb93a386Sopenharmony_ci SAFE_RELEASE(src, jpegBuf); 894cb93a386Sopenharmony_ci THROW_TJ(); 895cb93a386Sopenharmony_ci } 896cb93a386Sopenharmony_ci 897cb93a386Sopenharmony_cibailout: 898cb93a386Sopenharmony_ci SAFE_RELEASE(dst, dstBuf); 899cb93a386Sopenharmony_ci SAFE_RELEASE(src, jpegBuf); 900cb93a386Sopenharmony_ci} 901cb93a386Sopenharmony_ci 902cb93a386Sopenharmony_cistatic void TJDecompressor_decodeYUV 903cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets, 904cb93a386Sopenharmony_ci jintArray jSrcStrides, jint subsamp, jarray dst, jint dstElementSize, 905cb93a386Sopenharmony_ci jint x, jint y, jint width, jint pitch, jint height, jint pf, jint flags) 906cb93a386Sopenharmony_ci{ 907cb93a386Sopenharmony_ci tjhandle handle = 0; 908cb93a386Sopenharmony_ci jsize arraySize = 0, actualPitch; 909cb93a386Sopenharmony_ci jbyteArray jSrcPlanes[3] = { NULL, NULL, NULL }; 910cb93a386Sopenharmony_ci const unsigned char *srcPlanesTmp[3] = { NULL, NULL, NULL }; 911cb93a386Sopenharmony_ci const unsigned char *srcPlanes[3] = { NULL, NULL, NULL }; 912cb93a386Sopenharmony_ci int *srcOffsetsTmp = NULL, srcOffsets[3] = { 0, 0, 0 }; 913cb93a386Sopenharmony_ci int *srcStridesTmp = NULL, srcStrides[3] = { 0, 0, 0 }; 914cb93a386Sopenharmony_ci unsigned char *dstBuf = NULL; 915cb93a386Sopenharmony_ci int nc = (subsamp == org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY ? 1 : 3), i; 916cb93a386Sopenharmony_ci 917cb93a386Sopenharmony_ci GET_HANDLE(); 918cb93a386Sopenharmony_ci 919cb93a386Sopenharmony_ci if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF || subsamp < 0 || 920cb93a386Sopenharmony_ci subsamp >= org_libjpegturbo_turbojpeg_TJ_NUMSAMP) 921cb93a386Sopenharmony_ci THROW_ARG("Invalid argument in decodeYUV()"); 922cb93a386Sopenharmony_ci if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF || 923cb93a386Sopenharmony_ci org_libjpegturbo_turbojpeg_TJ_NUMSAMP != TJ_NUMSAMP) 924cb93a386Sopenharmony_ci THROW_ARG("Mismatch between Java and C API"); 925cb93a386Sopenharmony_ci 926cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, srcobjs) < nc) 927cb93a386Sopenharmony_ci THROW_ARG("Planes array is too small for the subsampling type"); 928cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, jSrcOffsets) < nc) 929cb93a386Sopenharmony_ci THROW_ARG("Offsets array is too small for the subsampling type"); 930cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, jSrcStrides) < nc) 931cb93a386Sopenharmony_ci THROW_ARG("Strides array is too small for the subsampling type"); 932cb93a386Sopenharmony_ci 933cb93a386Sopenharmony_ci actualPitch = (pitch == 0) ? width * tjPixelSize[pf] : pitch; 934cb93a386Sopenharmony_ci arraySize = (y + height - 1) * actualPitch + (x + width) * tjPixelSize[pf]; 935cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, dst) * dstElementSize < arraySize) 936cb93a386Sopenharmony_ci THROW_ARG("Destination buffer is not large enough"); 937cb93a386Sopenharmony_ci 938cb93a386Sopenharmony_ci BAILIF0(srcOffsetsTmp = 939cb93a386Sopenharmony_ci (*env)->GetPrimitiveArrayCritical(env, jSrcOffsets, 0)); 940cb93a386Sopenharmony_ci for (i = 0; i < nc; i++) srcOffsets[i] = srcOffsetsTmp[i]; 941cb93a386Sopenharmony_ci SAFE_RELEASE(jSrcOffsets, srcOffsetsTmp); 942cb93a386Sopenharmony_ci 943cb93a386Sopenharmony_ci BAILIF0(srcStridesTmp = 944cb93a386Sopenharmony_ci (*env)->GetPrimitiveArrayCritical(env, jSrcStrides, 0)); 945cb93a386Sopenharmony_ci for (i = 0; i < nc; i++) srcStrides[i] = srcStridesTmp[i]; 946cb93a386Sopenharmony_ci SAFE_RELEASE(jSrcStrides, srcStridesTmp); 947cb93a386Sopenharmony_ci 948cb93a386Sopenharmony_ci for (i = 0; i < nc; i++) { 949cb93a386Sopenharmony_ci int planeSize = tjPlaneSizeYUV(i, width, srcStrides[i], height, subsamp); 950cb93a386Sopenharmony_ci int pw = tjPlaneWidth(i, width, subsamp); 951cb93a386Sopenharmony_ci 952cb93a386Sopenharmony_ci if (planeSize < 0 || pw < 0) 953cb93a386Sopenharmony_ci THROW_ARG(tjGetErrorStr()); 954cb93a386Sopenharmony_ci 955cb93a386Sopenharmony_ci if (srcOffsets[i] < 0) 956cb93a386Sopenharmony_ci THROW_ARG("Invalid argument in decodeYUV()"); 957cb93a386Sopenharmony_ci if (srcStrides[i] < 0 && srcOffsets[i] - planeSize + pw < 0) 958cb93a386Sopenharmony_ci THROW_ARG("Negative plane stride would cause memory to be accessed below plane boundary"); 959cb93a386Sopenharmony_ci 960cb93a386Sopenharmony_ci BAILIF0(jSrcPlanes[i] = (*env)->GetObjectArrayElement(env, srcobjs, i)); 961cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, jSrcPlanes[i]) < 962cb93a386Sopenharmony_ci srcOffsets[i] + planeSize) 963cb93a386Sopenharmony_ci THROW_ARG("Source plane is not large enough"); 964cb93a386Sopenharmony_ci 965cb93a386Sopenharmony_ci BAILIF0(srcPlanesTmp[i] = 966cb93a386Sopenharmony_ci (*env)->GetPrimitiveArrayCritical(env, jSrcPlanes[i], 0)); 967cb93a386Sopenharmony_ci srcPlanes[i] = &srcPlanesTmp[i][srcOffsets[i]]; 968cb93a386Sopenharmony_ci SAFE_RELEASE(jSrcPlanes[i], srcPlanesTmp[i]); 969cb93a386Sopenharmony_ci } 970cb93a386Sopenharmony_ci BAILIF0(dstBuf = (*env)->GetPrimitiveArrayCritical(env, dst, 0)); 971cb93a386Sopenharmony_ci 972cb93a386Sopenharmony_ci if (tjDecodeYUVPlanes(handle, srcPlanes, srcStrides, subsamp, 973cb93a386Sopenharmony_ci &dstBuf[y * actualPitch + x * tjPixelSize[pf]], width, 974cb93a386Sopenharmony_ci pitch, height, pf, flags) == -1) { 975cb93a386Sopenharmony_ci SAFE_RELEASE(dst, dstBuf); 976cb93a386Sopenharmony_ci THROW_TJ(); 977cb93a386Sopenharmony_ci } 978cb93a386Sopenharmony_ci 979cb93a386Sopenharmony_cibailout: 980cb93a386Sopenharmony_ci SAFE_RELEASE(dst, dstBuf); 981cb93a386Sopenharmony_ci} 982cb93a386Sopenharmony_ci 983cb93a386Sopenharmony_ci/* TurboJPEG 1.4.x: TJDecompressor::decodeYUV() byte destination */ 984cb93a386Sopenharmony_ciJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decodeYUV___3_3B_3I_3II_3BIIIIIII 985cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets, 986cb93a386Sopenharmony_ci jintArray jSrcStrides, jint subsamp, jbyteArray dst, jint x, jint y, 987cb93a386Sopenharmony_ci jint width, jint pitch, jint height, jint pf, jint flags) 988cb93a386Sopenharmony_ci{ 989cb93a386Sopenharmony_ci TJDecompressor_decodeYUV(env, obj, srcobjs, jSrcOffsets, jSrcStrides, 990cb93a386Sopenharmony_ci subsamp, dst, 1, x, y, width, pitch, height, pf, 991cb93a386Sopenharmony_ci flags); 992cb93a386Sopenharmony_ci} 993cb93a386Sopenharmony_ci 994cb93a386Sopenharmony_ci/* TurboJPEG 1.4.x: TJDecompressor::decodeYUV() int destination */ 995cb93a386Sopenharmony_ciJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decodeYUV___3_3B_3I_3II_3IIIIIIII 996cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets, 997cb93a386Sopenharmony_ci jintArray jSrcStrides, jint subsamp, jintArray dst, jint x, jint y, 998cb93a386Sopenharmony_ci jint width, jint stride, jint height, jint pf, jint flags) 999cb93a386Sopenharmony_ci{ 1000cb93a386Sopenharmony_ci if (pf < 0 || pf >= org_libjpegturbo_turbojpeg_TJ_NUMPF) 1001cb93a386Sopenharmony_ci THROW_ARG("Invalid argument in decodeYUV()"); 1002cb93a386Sopenharmony_ci if (tjPixelSize[pf] != sizeof(jint)) 1003cb93a386Sopenharmony_ci THROW_ARG("Pixel format must be 32-bit when decoding to an integer buffer."); 1004cb93a386Sopenharmony_ci 1005cb93a386Sopenharmony_ci TJDecompressor_decodeYUV(env, obj, srcobjs, jSrcOffsets, jSrcStrides, 1006cb93a386Sopenharmony_ci subsamp, dst, sizeof(jint), x, y, width, 1007cb93a386Sopenharmony_ci stride * sizeof(jint), height, pf, flags); 1008cb93a386Sopenharmony_ci 1009cb93a386Sopenharmony_cibailout: 1010cb93a386Sopenharmony_ci return; 1011cb93a386Sopenharmony_ci} 1012cb93a386Sopenharmony_ci 1013cb93a386Sopenharmony_ci/* TurboJPEG 1.2.x: TJTransformer::init() */ 1014cb93a386Sopenharmony_ciJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_init 1015cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj) 1016cb93a386Sopenharmony_ci{ 1017cb93a386Sopenharmony_ci jclass cls; 1018cb93a386Sopenharmony_ci jfieldID fid; 1019cb93a386Sopenharmony_ci tjhandle handle; 1020cb93a386Sopenharmony_ci 1021cb93a386Sopenharmony_ci if ((handle = tjInitTransform()) == NULL) 1022cb93a386Sopenharmony_ci THROW(tjGetErrorStr(), "org/libjpegturbo/turbojpeg/TJException"); 1023cb93a386Sopenharmony_ci 1024cb93a386Sopenharmony_ci BAILIF0(cls = (*env)->GetObjectClass(env, obj)); 1025cb93a386Sopenharmony_ci BAILIF0(fid = (*env)->GetFieldID(env, cls, "handle", "J")); 1026cb93a386Sopenharmony_ci (*env)->SetLongField(env, obj, fid, (size_t)handle); 1027cb93a386Sopenharmony_ci 1028cb93a386Sopenharmony_cibailout: 1029cb93a386Sopenharmony_ci return; 1030cb93a386Sopenharmony_ci} 1031cb93a386Sopenharmony_ci 1032cb93a386Sopenharmony_citypedef struct _JNICustomFilterParams { 1033cb93a386Sopenharmony_ci JNIEnv *env; 1034cb93a386Sopenharmony_ci jobject tobj; 1035cb93a386Sopenharmony_ci jobject cfobj; 1036cb93a386Sopenharmony_ci} JNICustomFilterParams; 1037cb93a386Sopenharmony_ci 1038cb93a386Sopenharmony_cistatic int JNICustomFilter(short *coeffs, tjregion arrayRegion, 1039cb93a386Sopenharmony_ci tjregion planeRegion, int componentIndex, 1040cb93a386Sopenharmony_ci int transformIndex, tjtransform *transform) 1041cb93a386Sopenharmony_ci{ 1042cb93a386Sopenharmony_ci JNICustomFilterParams *params = (JNICustomFilterParams *)transform->data; 1043cb93a386Sopenharmony_ci JNIEnv *env = params->env; 1044cb93a386Sopenharmony_ci jobject tobj = params->tobj, cfobj = params->cfobj; 1045cb93a386Sopenharmony_ci jobject arrayRegionObj, planeRegionObj, bufobj, borobj; 1046cb93a386Sopenharmony_ci jclass cls; 1047cb93a386Sopenharmony_ci jmethodID mid; 1048cb93a386Sopenharmony_ci jfieldID fid; 1049cb93a386Sopenharmony_ci 1050cb93a386Sopenharmony_ci BAILIF0(bufobj = (*env)->NewDirectByteBuffer(env, coeffs, 1051cb93a386Sopenharmony_ci sizeof(short) * arrayRegion.w * arrayRegion.h)); 1052cb93a386Sopenharmony_ci BAILIF0(cls = (*env)->FindClass(env, "java/nio/ByteOrder")); 1053cb93a386Sopenharmony_ci BAILIF0(mid = (*env)->GetStaticMethodID(env, cls, "nativeOrder", 1054cb93a386Sopenharmony_ci "()Ljava/nio/ByteOrder;")); 1055cb93a386Sopenharmony_ci BAILIF0(borobj = (*env)->CallStaticObjectMethod(env, cls, mid)); 1056cb93a386Sopenharmony_ci BAILIF0(cls = (*env)->GetObjectClass(env, bufobj)); 1057cb93a386Sopenharmony_ci BAILIF0(mid = (*env)->GetMethodID(env, cls, "order", 1058cb93a386Sopenharmony_ci "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;")); 1059cb93a386Sopenharmony_ci (*env)->CallObjectMethod(env, bufobj, mid, borobj); 1060cb93a386Sopenharmony_ci BAILIF0(mid = (*env)->GetMethodID(env, cls, "asShortBuffer", 1061cb93a386Sopenharmony_ci "()Ljava/nio/ShortBuffer;")); 1062cb93a386Sopenharmony_ci BAILIF0(bufobj = (*env)->CallObjectMethod(env, bufobj, mid)); 1063cb93a386Sopenharmony_ci 1064cb93a386Sopenharmony_ci BAILIF0(cls = (*env)->FindClass(env, "java/awt/Rectangle")); 1065cb93a386Sopenharmony_ci BAILIF0(arrayRegionObj = (*env)->AllocObject(env, cls)); 1066cb93a386Sopenharmony_ci BAILIF0(fid = (*env)->GetFieldID(env, cls, "x", "I")); 1067cb93a386Sopenharmony_ci (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.x); 1068cb93a386Sopenharmony_ci BAILIF0(fid = (*env)->GetFieldID(env, cls, "y", "I")); 1069cb93a386Sopenharmony_ci (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.y); 1070cb93a386Sopenharmony_ci BAILIF0(fid = (*env)->GetFieldID(env, cls, "width", "I")); 1071cb93a386Sopenharmony_ci (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.w); 1072cb93a386Sopenharmony_ci BAILIF0(fid = (*env)->GetFieldID(env, cls, "height", "I")); 1073cb93a386Sopenharmony_ci (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.h); 1074cb93a386Sopenharmony_ci 1075cb93a386Sopenharmony_ci BAILIF0(planeRegionObj = (*env)->AllocObject(env, cls)); 1076cb93a386Sopenharmony_ci BAILIF0(fid = (*env)->GetFieldID(env, cls, "x", "I")); 1077cb93a386Sopenharmony_ci (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.x); 1078cb93a386Sopenharmony_ci BAILIF0(fid = (*env)->GetFieldID(env, cls, "y", "I")); 1079cb93a386Sopenharmony_ci (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.y); 1080cb93a386Sopenharmony_ci BAILIF0(fid = (*env)->GetFieldID(env, cls, "width", "I")); 1081cb93a386Sopenharmony_ci (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.w); 1082cb93a386Sopenharmony_ci BAILIF0(fid = (*env)->GetFieldID(env, cls, "height", "I")); 1083cb93a386Sopenharmony_ci (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.h); 1084cb93a386Sopenharmony_ci 1085cb93a386Sopenharmony_ci BAILIF0(cls = (*env)->GetObjectClass(env, cfobj)); 1086cb93a386Sopenharmony_ci BAILIF0(mid = (*env)->GetMethodID(env, cls, "customFilter", 1087cb93a386Sopenharmony_ci "(Ljava/nio/ShortBuffer;Ljava/awt/Rectangle;Ljava/awt/Rectangle;IILorg/libjpegturbo/turbojpeg/TJTransform;)V")); 1088cb93a386Sopenharmony_ci (*env)->CallVoidMethod(env, cfobj, mid, bufobj, arrayRegionObj, 1089cb93a386Sopenharmony_ci planeRegionObj, componentIndex, transformIndex, tobj); 1090cb93a386Sopenharmony_ci 1091cb93a386Sopenharmony_ci return 0; 1092cb93a386Sopenharmony_ci 1093cb93a386Sopenharmony_cibailout: 1094cb93a386Sopenharmony_ci return -1; 1095cb93a386Sopenharmony_ci} 1096cb93a386Sopenharmony_ci 1097cb93a386Sopenharmony_ci/* TurboJPEG 1.2.x: TJTransformer::transform() */ 1098cb93a386Sopenharmony_ciJNIEXPORT jintArray JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_transform 1099cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj, jbyteArray jsrcBuf, jint jpegSize, 1100cb93a386Sopenharmony_ci jobjectArray dstobjs, jobjectArray tobjs, jint flags) 1101cb93a386Sopenharmony_ci{ 1102cb93a386Sopenharmony_ci tjhandle handle = 0; 1103cb93a386Sopenharmony_ci unsigned char *jpegBuf = NULL, **dstBufs = NULL; 1104cb93a386Sopenharmony_ci jsize n = 0; 1105cb93a386Sopenharmony_ci unsigned long *dstSizes = NULL; 1106cb93a386Sopenharmony_ci tjtransform *t = NULL; 1107cb93a386Sopenharmony_ci jbyteArray *jdstBufs = NULL; 1108cb93a386Sopenharmony_ci int i, jpegWidth = 0, jpegHeight = 0, jpegSubsamp; 1109cb93a386Sopenharmony_ci jintArray jdstSizes = 0; 1110cb93a386Sopenharmony_ci jint *dstSizesi = NULL; 1111cb93a386Sopenharmony_ci JNICustomFilterParams *params = NULL; 1112cb93a386Sopenharmony_ci 1113cb93a386Sopenharmony_ci GET_HANDLE(); 1114cb93a386Sopenharmony_ci 1115cb93a386Sopenharmony_ci if ((*env)->GetArrayLength(env, jsrcBuf) < jpegSize) 1116cb93a386Sopenharmony_ci THROW_ARG("Source buffer is not large enough"); 1117cb93a386Sopenharmony_ci BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegWidth", "I")); 1118cb93a386Sopenharmony_ci jpegWidth = (int)(*env)->GetIntField(env, obj, _fid); 1119cb93a386Sopenharmony_ci BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegHeight", "I")); 1120cb93a386Sopenharmony_ci jpegHeight = (int)(*env)->GetIntField(env, obj, _fid); 1121cb93a386Sopenharmony_ci BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "jpegSubsamp", "I")); 1122cb93a386Sopenharmony_ci jpegSubsamp = (int)(*env)->GetIntField(env, obj, _fid); 1123cb93a386Sopenharmony_ci 1124cb93a386Sopenharmony_ci n = (*env)->GetArrayLength(env, dstobjs); 1125cb93a386Sopenharmony_ci if (n != (*env)->GetArrayLength(env, tobjs)) 1126cb93a386Sopenharmony_ci THROW_ARG("Mismatch between size of transforms array and destination buffers array"); 1127cb93a386Sopenharmony_ci 1128cb93a386Sopenharmony_ci if ((dstBufs = 1129cb93a386Sopenharmony_ci (unsigned char **)malloc(sizeof(unsigned char *) * n)) == NULL) 1130cb93a386Sopenharmony_ci THROW_MEM(); 1131cb93a386Sopenharmony_ci if ((jdstBufs = (jbyteArray *)malloc(sizeof(jbyteArray) * n)) == NULL) 1132cb93a386Sopenharmony_ci THROW_MEM(); 1133cb93a386Sopenharmony_ci if ((dstSizes = (unsigned long *)malloc(sizeof(unsigned long) * n)) == NULL) 1134cb93a386Sopenharmony_ci THROW_MEM(); 1135cb93a386Sopenharmony_ci if ((t = (tjtransform *)malloc(sizeof(tjtransform) * n)) == NULL) 1136cb93a386Sopenharmony_ci THROW_MEM(); 1137cb93a386Sopenharmony_ci if ((params = (JNICustomFilterParams *)malloc(sizeof(JNICustomFilterParams) * 1138cb93a386Sopenharmony_ci n)) == NULL) 1139cb93a386Sopenharmony_ci THROW_MEM(); 1140cb93a386Sopenharmony_ci for (i = 0; i < n; i++) { 1141cb93a386Sopenharmony_ci dstBufs[i] = NULL; jdstBufs[i] = NULL; dstSizes[i] = 0; 1142cb93a386Sopenharmony_ci memset(&t[i], 0, sizeof(tjtransform)); 1143cb93a386Sopenharmony_ci memset(¶ms[i], 0, sizeof(JNICustomFilterParams)); 1144cb93a386Sopenharmony_ci } 1145cb93a386Sopenharmony_ci 1146cb93a386Sopenharmony_ci for (i = 0; i < n; i++) { 1147cb93a386Sopenharmony_ci jobject tobj, cfobj; 1148cb93a386Sopenharmony_ci 1149cb93a386Sopenharmony_ci BAILIF0(tobj = (*env)->GetObjectArrayElement(env, tobjs, i)); 1150cb93a386Sopenharmony_ci BAILIF0(_cls = (*env)->GetObjectClass(env, tobj)); 1151cb93a386Sopenharmony_ci BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "op", "I")); 1152cb93a386Sopenharmony_ci t[i].op = (*env)->GetIntField(env, tobj, _fid); 1153cb93a386Sopenharmony_ci BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "options", "I")); 1154cb93a386Sopenharmony_ci t[i].options = (*env)->GetIntField(env, tobj, _fid); 1155cb93a386Sopenharmony_ci BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "x", "I")); 1156cb93a386Sopenharmony_ci t[i].r.x = (*env)->GetIntField(env, tobj, _fid); 1157cb93a386Sopenharmony_ci BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "y", "I")); 1158cb93a386Sopenharmony_ci t[i].r.y = (*env)->GetIntField(env, tobj, _fid); 1159cb93a386Sopenharmony_ci BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "width", "I")); 1160cb93a386Sopenharmony_ci t[i].r.w = (*env)->GetIntField(env, tobj, _fid); 1161cb93a386Sopenharmony_ci BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "height", "I")); 1162cb93a386Sopenharmony_ci t[i].r.h = (*env)->GetIntField(env, tobj, _fid); 1163cb93a386Sopenharmony_ci 1164cb93a386Sopenharmony_ci BAILIF0(_fid = (*env)->GetFieldID(env, _cls, "cf", 1165cb93a386Sopenharmony_ci "Lorg/libjpegturbo/turbojpeg/TJCustomFilter;")); 1166cb93a386Sopenharmony_ci cfobj = (*env)->GetObjectField(env, tobj, _fid); 1167cb93a386Sopenharmony_ci if (cfobj) { 1168cb93a386Sopenharmony_ci params[i].env = env; 1169cb93a386Sopenharmony_ci params[i].tobj = tobj; 1170cb93a386Sopenharmony_ci params[i].cfobj = cfobj; 1171cb93a386Sopenharmony_ci t[i].customFilter = JNICustomFilter; 1172cb93a386Sopenharmony_ci t[i].data = (void *)¶ms[i]; 1173cb93a386Sopenharmony_ci } 1174cb93a386Sopenharmony_ci } 1175cb93a386Sopenharmony_ci 1176cb93a386Sopenharmony_ci for (i = 0; i < n; i++) { 1177cb93a386Sopenharmony_ci int w = jpegWidth, h = jpegHeight; 1178cb93a386Sopenharmony_ci 1179cb93a386Sopenharmony_ci if (t[i].r.w != 0) w = t[i].r.w; 1180cb93a386Sopenharmony_ci if (t[i].r.h != 0) h = t[i].r.h; 1181cb93a386Sopenharmony_ci BAILIF0(jdstBufs[i] = (*env)->GetObjectArrayElement(env, dstobjs, i)); 1182cb93a386Sopenharmony_ci if ((unsigned long)(*env)->GetArrayLength(env, jdstBufs[i]) < 1183cb93a386Sopenharmony_ci tjBufSize(w, h, jpegSubsamp)) 1184cb93a386Sopenharmony_ci THROW_ARG("Destination buffer is not large enough"); 1185cb93a386Sopenharmony_ci } 1186cb93a386Sopenharmony_ci BAILIF0(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, jsrcBuf, 0)); 1187cb93a386Sopenharmony_ci for (i = 0; i < n; i++) 1188cb93a386Sopenharmony_ci BAILIF0(dstBufs[i] = 1189cb93a386Sopenharmony_ci (*env)->GetPrimitiveArrayCritical(env, jdstBufs[i], 0)); 1190cb93a386Sopenharmony_ci 1191cb93a386Sopenharmony_ci if (tjTransform(handle, jpegBuf, jpegSize, n, dstBufs, dstSizes, t, 1192cb93a386Sopenharmony_ci flags | TJFLAG_NOREALLOC) == -1) { 1193cb93a386Sopenharmony_ci for (i = 0; i < n; i++) 1194cb93a386Sopenharmony_ci SAFE_RELEASE(jdstBufs[i], dstBufs[i]); 1195cb93a386Sopenharmony_ci SAFE_RELEASE(jsrcBuf, jpegBuf); 1196cb93a386Sopenharmony_ci THROW_TJ(); 1197cb93a386Sopenharmony_ci } 1198cb93a386Sopenharmony_ci 1199cb93a386Sopenharmony_ci for (i = 0; i < n; i++) 1200cb93a386Sopenharmony_ci SAFE_RELEASE(jdstBufs[i], dstBufs[i]); 1201cb93a386Sopenharmony_ci SAFE_RELEASE(jsrcBuf, jpegBuf); 1202cb93a386Sopenharmony_ci 1203cb93a386Sopenharmony_ci jdstSizes = (*env)->NewIntArray(env, n); 1204cb93a386Sopenharmony_ci BAILIF0(dstSizesi = (*env)->GetIntArrayElements(env, jdstSizes, 0)); 1205cb93a386Sopenharmony_ci for (i = 0; i < n; i++) dstSizesi[i] = (int)dstSizes[i]; 1206cb93a386Sopenharmony_ci 1207cb93a386Sopenharmony_cibailout: 1208cb93a386Sopenharmony_ci if (dstSizesi) (*env)->ReleaseIntArrayElements(env, jdstSizes, dstSizesi, 0); 1209cb93a386Sopenharmony_ci if (dstBufs) { 1210cb93a386Sopenharmony_ci for (i = 0; i < n; i++) { 1211cb93a386Sopenharmony_ci if (dstBufs[i] && jdstBufs && jdstBufs[i]) 1212cb93a386Sopenharmony_ci (*env)->ReleasePrimitiveArrayCritical(env, jdstBufs[i], dstBufs[i], 0); 1213cb93a386Sopenharmony_ci } 1214cb93a386Sopenharmony_ci free(dstBufs); 1215cb93a386Sopenharmony_ci } 1216cb93a386Sopenharmony_ci SAFE_RELEASE(jsrcBuf, jpegBuf); 1217cb93a386Sopenharmony_ci free(jdstBufs); 1218cb93a386Sopenharmony_ci free(dstSizes); 1219cb93a386Sopenharmony_ci free(t); 1220cb93a386Sopenharmony_ci return jdstSizes; 1221cb93a386Sopenharmony_ci} 1222cb93a386Sopenharmony_ci 1223cb93a386Sopenharmony_ci/* TurboJPEG 1.2.x: TJDecompressor::destroy() */ 1224cb93a386Sopenharmony_ciJNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_destroy 1225cb93a386Sopenharmony_ci (JNIEnv *env, jobject obj) 1226cb93a386Sopenharmony_ci{ 1227cb93a386Sopenharmony_ci Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy(env, obj); 1228cb93a386Sopenharmony_ci} 1229