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