blob: 53bdceba36d44aa7778a653fc61c6e84490c6479 [file] [log] [blame]
DRCf8e00552011-02-04 11:06:36 +00001/*
DRCfc26b652014-03-16 22:56:26 +00002 * Copyright (C)2011-2014 D. R. Commander. All Rights Reserved.
DRCf8e00552011-02-04 11:06:36 +00003 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * - Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 * - Redistributions in binary form must reproduce the above copyright notice,
10 * this list of conditions and the following disclaimer in the documentation
11 * and/or other materials provided with the distribution.
12 * - Neither the name of the libjpeg-turbo Project nor the names of its
13 * contributors may be used to endorse or promote products derived from this
14 * software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
DRCe8573012011-03-04 10:13:59 +000029#include <stdlib.h>
30#include <string.h>
DRCf8e00552011-02-04 11:06:36 +000031#include "turbojpeg.h"
DRCbc2e66c2012-10-02 06:47:37 +000032#ifdef WIN32
33#include "tjutil.h"
34#endif
DRCf8e00552011-02-04 11:06:36 +000035#include <jni.h>
DRCc5a41992011-02-08 06:54:36 +000036#include "java/org_libjpegturbo_turbojpeg_TJCompressor.h"
37#include "java/org_libjpegturbo_turbojpeg_TJDecompressor.h"
38#include "java/org_libjpegturbo_turbojpeg_TJ.h"
DRCf8e00552011-02-04 11:06:36 +000039
40#define _throw(msg) { \
41 jclass _exccls=(*env)->FindClass(env, "java/lang/Exception"); \
42 if(!_exccls) goto bailout; \
43 (*env)->ThrowNew(env, _exccls, msg); \
44 goto bailout; \
45}
46
DRCfac3bea2012-09-24 02:27:55 +000047#define bailif0(f) {if(!(f)) { \
48 char temps[80]; \
49 snprintf(temps, 80, "Unexpected NULL condition in line %d", __LINE__); \
50 _throw(temps); \
51}}
DRCf8e00552011-02-04 11:06:36 +000052
DRC3bad53f2011-02-23 02:20:49 +000053#define gethandle() \
DRCf8e00552011-02-04 11:06:36 +000054 jclass _cls=(*env)->GetObjectClass(env, obj); \
55 jfieldID _fid; \
56 if(!_cls) goto bailout; \
57 bailif0(_fid=(*env)->GetFieldID(env, _cls, "handle", "J")); \
DRC23da0c02011-03-04 15:28:16 +000058 handle=(tjhandle)(jlong)(*env)->GetLongField(env, obj, _fid); \
DRCf8e00552011-02-04 11:06:36 +000059
DRC3bad53f2011-02-23 02:20:49 +000060JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSize
DRC9b49f0e2011-07-12 03:17:23 +000061 (JNIEnv *env, jclass cls, jint width, jint height, jint jpegSubsamp)
DRCf8e00552011-02-04 11:06:36 +000062{
DRC9b49f0e2011-07-12 03:17:23 +000063 jint retval=(jint)tjBufSize(width, height, jpegSubsamp);
DRC36336fc2011-02-22 10:27:31 +000064 if(retval==-1) _throw(tjGetErrorStr());
65
66 bailout:
67 return retval;
68}
69
DRCfef98522013-04-28 01:32:52 +000070JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__IIII
71 (JNIEnv *env, jclass cls, jint width, jint pad, jint height, jint subsamp)
DRC36336fc2011-02-22 10:27:31 +000072{
DRCfef98522013-04-28 01:32:52 +000073 jint retval=(jint)tjBufSizeYUV2(width, pad, height, subsamp);
DRC36336fc2011-02-22 10:27:31 +000074 if(retval==-1) _throw(tjGetErrorStr());
75
76 bailout:
77 return retval;
DRCf8e00552011-02-04 11:06:36 +000078}
79
DRCfef98522013-04-28 01:32:52 +000080JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__III
81 (JNIEnv *env, jclass cls, jint width, jint height, jint subsamp)
82{
83 return Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__IIII(env, cls, width,
84 4, height, subsamp);
85}
86
DRCc5a41992011-02-08 06:54:36 +000087JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_init
DRCf8e00552011-02-04 11:06:36 +000088 (JNIEnv *env, jobject obj)
89{
90 jclass cls;
91 jfieldID fid;
92 tjhandle handle;
93
DRC1a3dbe62011-02-28 10:51:55 +000094 if((handle=tjInitCompress())==NULL)
DRCf8e00552011-02-04 11:06:36 +000095 _throw(tjGetErrorStr());
96
97 bailif0(cls=(*env)->GetObjectClass(env, obj));
98 bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J"));
DRC23da0c02011-03-04 15:28:16 +000099 (*env)->SetLongField(env, obj, fid, (jlong)handle);
DRCf8e00552011-02-04 11:06:36 +0000100
101 bailout:
102 return;
103}
104
DRCfac3bea2012-09-24 02:27:55 +0000105JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIIIII_3BIII
106 (JNIEnv *env, jobject obj, jbyteArray src, jint x, jint y, jint width,
107 jint pitch, jint height, jint pf, jbyteArray dst, jint jpegSubsamp,
108 jint jpegQual, jint flags)
DRCf8e00552011-02-04 11:06:36 +0000109{
DRC9b28def2011-05-21 14:37:15 +0000110 tjhandle handle=0;
DRCfac3bea2012-09-24 02:27:55 +0000111 unsigned long jpegSize=0;
112 jsize arraySize=0, actualPitch;
DRC9b28def2011-05-21 14:37:15 +0000113 unsigned char *srcBuf=NULL, *jpegBuf=NULL;
DRCf8e00552011-02-04 11:06:36 +0000114
115 gethandle();
116
DRC92549de2011-03-15 20:52:02 +0000117 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1
DRC6acf52b2011-03-02 01:09:20 +0000118 || pitch<0)
DRC4f1580c2011-02-25 06:11:03 +0000119 _throw("Invalid argument in compress()");
DRC9b28def2011-05-21 14:37:15 +0000120 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
121 _throw("Mismatch between Java and C API");
DRC4f1580c2011-02-25 06:11:03 +0000122
DRCfac3bea2012-09-24 02:27:55 +0000123 actualPitch=(pitch==0)? width*tjPixelSize[pf]:pitch;
124 arraySize=(y+height-1)*actualPitch + x+width;
DRC9b28def2011-05-21 14:37:15 +0000125 if((*env)->GetArrayLength(env, src)<arraySize)
DRC6acf52b2011-03-02 01:09:20 +0000126 _throw("Source buffer is not large enough");
DRC9b49f0e2011-07-12 03:17:23 +0000127 jpegSize=tjBufSize(width, height, jpegSubsamp);
DRC9b28def2011-05-21 14:37:15 +0000128 if((*env)->GetArrayLength(env, dst)<(jsize)jpegSize)
DRC6acf52b2011-03-02 01:09:20 +0000129 _throw("Destination buffer is not large enough");
130
DRC9b28def2011-05-21 14:37:15 +0000131 bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
132 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
DRCf8e00552011-02-04 11:06:36 +0000133
DRCfac3bea2012-09-24 02:27:55 +0000134 if(tjCompress2(handle, &srcBuf[y*actualPitch + x*tjPixelSize[pf]], width,
135 pitch, height, pf, &jpegBuf, &jpegSize, jpegSubsamp, jpegQual,
136 flags|TJFLAG_NOREALLOC)==-1)
DRCfac3bea2012-09-24 02:27:55 +0000137 _throw(tjGetErrorStr());
DRCfac3bea2012-09-24 02:27:55 +0000138
139 bailout:
140 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0);
141 if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
142 return (jint)jpegSize;
143}
144
145JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIII_3BIII
146 (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch,
147 jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpegQual,
148 jint flags)
149{
150 return Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIIIII_3BIII(
151 env, obj, src, 0, 0, width, pitch, height, pf, dst, jpegSubsamp, jpegQual,
152 flags);
153}
154
155JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIIIII_3BIII
156 (JNIEnv *env, jobject obj, jintArray src, jint x, jint y, jint width,
157 jint stride, jint height, jint pf, jbyteArray dst, jint jpegSubsamp,
158 jint jpegQual, jint flags)
159{
160 tjhandle handle=0;
161 unsigned long jpegSize=0;
162 jsize arraySize=0, actualStride;
163 unsigned char *srcBuf=NULL, *jpegBuf=NULL;
164
165 gethandle();
166
167 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1
168 || stride<0)
169 _throw("Invalid argument in compress()");
170 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
171 _throw("Mismatch between Java and C API");
172 if(tjPixelSize[pf]!=sizeof(jint))
173 _throw("Pixel format must be 32-bit when compressing from an integer buffer.");
174
175 actualStride=(stride==0)? width:stride;
176 arraySize=(y+height-1)*actualStride + x+width;
177 if((*env)->GetArrayLength(env, src)<arraySize)
178 _throw("Source buffer is not large enough");
179 jpegSize=tjBufSize(width, height, jpegSubsamp);
180 if((*env)->GetArrayLength(env, dst)<(jsize)jpegSize)
181 _throw("Destination buffer is not large enough");
182
183 bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
184 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
185
186 if(tjCompress2(handle, &srcBuf[(y*actualStride + x)*sizeof(int)], width,
187 stride*sizeof(jint), height, pf, &jpegBuf, &jpegSize, jpegSubsamp,
188 jpegQual, flags|TJFLAG_NOREALLOC)==-1)
DRCf8e00552011-02-04 11:06:36 +0000189 _throw(tjGetErrorStr());
DRCf8e00552011-02-04 11:06:36 +0000190
191 bailout:
DRC9b28def2011-05-21 14:37:15 +0000192 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0);
193 if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
194 return (jint)jpegSize;
DRCf8e00552011-02-04 11:06:36 +0000195}
196
DRC4f1580c2011-02-25 06:11:03 +0000197JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIII_3BIII
DRC84a1bcc2011-02-23 12:09:56 +0000198 (JNIEnv *env, jobject obj, jintArray src, jint width, jint pitch,
DRC9b28def2011-05-21 14:37:15 +0000199 jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpegQual,
DRC4f1580c2011-02-25 06:11:03 +0000200 jint flags)
DRC84a1bcc2011-02-23 12:09:56 +0000201{
DRCfac3bea2012-09-24 02:27:55 +0000202 return Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIIIII_3BIII(
203 env, obj, src, 0, 0, width, pitch, height, pf, dst, jpegSubsamp, jpegQual,
204 flags);
DRC84a1bcc2011-02-23 12:09:56 +0000205}
206
DRC1e672742013-10-31 05:04:51 +0000207JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compressFromYUV___3BIIII_3BII
208 (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pad, jint height,
209 jint subsamp, jbyteArray dst, jint jpegQual, jint flags)
210{
211 tjhandle handle=0;
212 unsigned long jpegSize=0;
213 jsize arraySize=0;
214 unsigned char *srcBuf=NULL, *jpegBuf=NULL;
215
216 gethandle();
217
218 arraySize=tjBufSizeYUV2(width, pad, height, subsamp);
219 if((*env)->GetArrayLength(env, src)<arraySize)
220 _throw("Source buffer is not large enough");
221 jpegSize=tjBufSize(width, height, subsamp);
222 if((*env)->GetArrayLength(env, dst)<(jsize)jpegSize)
223 _throw("Destination buffer is not large enough");
224
225 bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
226 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
227
228 if(tjCompressFromYUV(handle, srcBuf, width, pad, height, subsamp, &jpegBuf,
229 &jpegSize, jpegQual, flags|TJFLAG_NOREALLOC)==-1)
DRC1e672742013-10-31 05:04:51 +0000230 _throw(tjGetErrorStr());
DRC1e672742013-10-31 05:04:51 +0000231
232 bailout:
233 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0);
234 if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
235 return (jint)jpegSize;
236}
237
DRCfc26b652014-03-16 22:56:26 +0000238JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIIIII_3BIII
239 (JNIEnv *env, jobject obj, jbyteArray src, jint x, jint y, jint width,
240 jint pitch, jint height, jint pf, jbyteArray dst, jint pad, jint subsamp,
241 jint flags)
DRC4f1580c2011-02-25 06:11:03 +0000242{
DRC9b28def2011-05-21 14:37:15 +0000243 tjhandle handle=0;
DRCfc26b652014-03-16 22:56:26 +0000244 jsize arraySize=0, actualPitch, yuvSize;
DRC9b28def2011-05-21 14:37:15 +0000245 unsigned char *srcBuf=NULL, *dstBuf=NULL;
DRC4f1580c2011-02-25 06:11:03 +0000246
247 gethandle();
248
DRC92549de2011-03-15 20:52:02 +0000249 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1
DRC6acf52b2011-03-02 01:09:20 +0000250 || pitch<0)
DRC4f1580c2011-02-25 06:11:03 +0000251 _throw("Invalid argument in encodeYUV()");
DRC9b28def2011-05-21 14:37:15 +0000252 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
253 _throw("Mismatch between Java and C API");
DRC4f1580c2011-02-25 06:11:03 +0000254
DRCfc26b652014-03-16 22:56:26 +0000255 actualPitch=(pitch==0)? width*tjPixelSize[pf]:pitch;
256 arraySize=(y+height-1)*actualPitch + x+width;
DRC9b28def2011-05-21 14:37:15 +0000257 if((*env)->GetArrayLength(env, src)<arraySize)
DRC6acf52b2011-03-02 01:09:20 +0000258 _throw("Source buffer is not large enough");
DRCfef98522013-04-28 01:32:52 +0000259 yuvSize=(jsize)tjBufSizeYUV2(width, pad, height, subsamp);
260 if(yuvSize==(unsigned long)-1)
261 _throw(tjGetErrorStr());
262 if((*env)->GetArrayLength(env, dst)<yuvSize)
DRC6acf52b2011-03-02 01:09:20 +0000263 _throw("Destination buffer is not large enough");
264
DRC9b28def2011-05-21 14:37:15 +0000265 bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
266 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
DRC4f1580c2011-02-25 06:11:03 +0000267
DRCfc26b652014-03-16 22:56:26 +0000268 if(tjEncodeYUV3(handle, &srcBuf[y*actualPitch + x*tjPixelSize[pf]], width,
269 pitch, height, pf, dstBuf, pad, subsamp, flags)==-1)
DRC4f1580c2011-02-25 06:11:03 +0000270 _throw(tjGetErrorStr());
DRC4f1580c2011-02-25 06:11:03 +0000271
272 bailout:
DRC9b28def2011-05-21 14:37:15 +0000273 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
274 if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
DRC4f1580c2011-02-25 06:11:03 +0000275 return;
276}
277
DRCfef98522013-04-28 01:32:52 +0000278JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIII_3BII
279 (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch,
DRC6acf52b2011-03-02 01:09:20 +0000280 jint height, jint pf, jbyteArray dst, jint subsamp, jint flags)
DRC4f1580c2011-02-25 06:11:03 +0000281{
DRCfc26b652014-03-16 22:56:26 +0000282 Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIIIII_3BIII(
283 env, obj, src, 0, 0, width, pitch, height, pf, dst, 4, subsamp, flags);
DRCfef98522013-04-28 01:32:52 +0000284}
285
DRCfc26b652014-03-16 22:56:26 +0000286JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIIIII_3BIII
287 (JNIEnv *env, jobject obj, jintArray src, jint x, jint y, jint width,
288 jint stride, jint height, jint pf, jbyteArray dst, jint pad, jint subsamp,
289 jint flags)
DRCfef98522013-04-28 01:32:52 +0000290{
DRC4f1580c2011-02-25 06:11:03 +0000291 tjhandle handle=0;
DRCfc26b652014-03-16 22:56:26 +0000292 jsize arraySize=0, actualStride, yuvSize;
DRC9b28def2011-05-21 14:37:15 +0000293 unsigned char *srcBuf=NULL, *dstBuf=NULL;
DRC4f1580c2011-02-25 06:11:03 +0000294
295 gethandle();
296
DRC92549de2011-03-15 20:52:02 +0000297 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1
DRC1d29c5f2013-04-27 20:54:44 +0000298 || stride<0)
299 _throw("Invalid argument in encodeYUV()");
DRC9b28def2011-05-21 14:37:15 +0000300 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
301 _throw("Mismatch between Java and C API");
302 if(tjPixelSize[pf]!=sizeof(jint))
DRC4f1580c2011-02-25 06:11:03 +0000303 _throw("Pixel format must be 32-bit when encoding from an integer buffer.");
DRC4f1580c2011-02-25 06:11:03 +0000304
DRCfc26b652014-03-16 22:56:26 +0000305 actualStride=(stride==0)? width:stride;
306 arraySize=(y+height-1)*actualStride + x+width;
DRC9b28def2011-05-21 14:37:15 +0000307 if((*env)->GetArrayLength(env, src)<arraySize)
DRC6acf52b2011-03-02 01:09:20 +0000308 _throw("Source buffer is not large enough");
DRCfef98522013-04-28 01:32:52 +0000309 yuvSize=(jsize)tjBufSizeYUV2(width, pad, height, subsamp);
310 if(yuvSize==(unsigned long)-1)
311 _throw(tjGetErrorStr());
312 if((*env)->GetArrayLength(env, dst)<yuvSize)
DRC6acf52b2011-03-02 01:09:20 +0000313 _throw("Destination buffer is not large enough");
314
DRC9b28def2011-05-21 14:37:15 +0000315 bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
316 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
DRC4f1580c2011-02-25 06:11:03 +0000317
DRCfc26b652014-03-16 22:56:26 +0000318 if(tjEncodeYUV3(handle, &srcBuf[(y*actualStride + x)*sizeof(int)], width,
319 stride*sizeof(jint), height, pf, dstBuf, pad, subsamp, flags)==-1)
DRC4f1580c2011-02-25 06:11:03 +0000320 _throw(tjGetErrorStr());
DRC4f1580c2011-02-25 06:11:03 +0000321
322 bailout:
DRC9b28def2011-05-21 14:37:15 +0000323 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
324 if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
DRC4f1580c2011-02-25 06:11:03 +0000325 return;
326}
327
DRCfef98522013-04-28 01:32:52 +0000328JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIII_3BII
329 (JNIEnv *env, jobject obj, jintArray src, jint width, jint pitch,
330 jint height, jint pf, jbyteArray dst, jint subsamp, jint flags)
331{
DRCfc26b652014-03-16 22:56:26 +0000332 Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIIIII_3BIII(
333 env, obj, src, 0, 0, width, pitch, height, pf, dst, 4, subsamp, flags);
DRCfef98522013-04-28 01:32:52 +0000334}
335
DRCc5a41992011-02-08 06:54:36 +0000336JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy
DRCf8e00552011-02-04 11:06:36 +0000337 (JNIEnv *env, jobject obj)
338{
339 tjhandle handle=0;
340
341 gethandle();
342
343 if(tjDestroy(handle)==-1) _throw(tjGetErrorStr());
DRC3bad53f2011-02-23 02:20:49 +0000344 (*env)->SetLongField(env, obj, _fid, 0);
DRCf8e00552011-02-04 11:06:36 +0000345
346 bailout:
347 return;
348}
349
DRCc5a41992011-02-08 06:54:36 +0000350JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_init
DRCf8e00552011-02-04 11:06:36 +0000351 (JNIEnv *env, jobject obj)
352{
353 jclass cls;
354 jfieldID fid;
355 tjhandle handle;
356
DRC1a3dbe62011-02-28 10:51:55 +0000357 if((handle=tjInitDecompress())==NULL) _throw(tjGetErrorStr());
DRCf8e00552011-02-04 11:06:36 +0000358
359 bailif0(cls=(*env)->GetObjectClass(env, obj));
360 bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J"));
DRC23da0c02011-03-04 15:28:16 +0000361 (*env)->SetLongField(env, obj, fid, (jlong)handle);
DRCf8e00552011-02-04 11:06:36 +0000362
363 bailout:
364 return;
365}
366
DRC109a5782011-03-01 09:53:07 +0000367JNIEXPORT jobjectArray JNICALL Java_org_libjpegturbo_turbojpeg_TJ_getScalingFactors
368 (JNIEnv *env, jclass cls)
DRC36336fc2011-02-22 10:27:31 +0000369{
DRC109a5782011-03-01 09:53:07 +0000370 jclass sfcls=NULL; jfieldID fid=0;
371 tjscalingfactor *sf=NULL; int n=0, i;
372 jobject sfobj=NULL;
373 jobjectArray sfjava=NULL;
374
375 if((sf=tjGetScalingFactors(&n))==NULL || n==0)
DRC36336fc2011-02-22 10:27:31 +0000376 _throw(tjGetErrorStr());
377
DRCb2f94152011-04-02 02:09:03 +0000378 bailif0(sfcls=(*env)->FindClass(env, "org/libjpegturbo/turbojpeg/TJScalingFactor"));
DRC109a5782011-03-01 09:53:07 +0000379 bailif0(sfjava=(jobjectArray)(*env)->NewObjectArray(env, n, sfcls, 0));
DRC36336fc2011-02-22 10:27:31 +0000380
DRC109a5782011-03-01 09:53:07 +0000381 for(i=0; i<n; i++)
382 {
383 bailif0(sfobj=(*env)->AllocObject(env, sfcls));
384 bailif0(fid=(*env)->GetFieldID(env, sfcls, "num", "I"));
385 (*env)->SetIntField(env, sfobj, fid, sf[i].num);
386 bailif0(fid=(*env)->GetFieldID(env, sfcls, "denom", "I"));
387 (*env)->SetIntField(env, sfobj, fid, sf[i].denom);
388 (*env)->SetObjectArrayElement(env, sfjava, i, sfobj);
389 }
DRC36336fc2011-02-22 10:27:31 +0000390
391 bailout:
DRC109a5782011-03-01 09:53:07 +0000392 return sfjava;
DRC36336fc2011-02-22 10:27:31 +0000393}
394
DRC3bad53f2011-02-23 02:20:49 +0000395JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressHeader
DRC9b28def2011-05-21 14:37:15 +0000396 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize)
DRCf8e00552011-02-04 11:06:36 +0000397{
DRCf8e00552011-02-04 11:06:36 +0000398 tjhandle handle=0;
DRC9b28def2011-05-21 14:37:15 +0000399 unsigned char *jpegBuf=NULL;
DRC38cb1ec2013-08-23 04:45:43 +0000400 int width=0, height=0, jpegSubsamp=-1, jpegColorspace=-1;
DRCf8e00552011-02-04 11:06:36 +0000401
402 gethandle();
403
DRC9b28def2011-05-21 14:37:15 +0000404 if((*env)->GetArrayLength(env, src)<jpegSize)
DRC6acf52b2011-03-02 01:09:20 +0000405 _throw("Source buffer is not large enough");
406
DRC9b28def2011-05-21 14:37:15 +0000407 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
DRCf8e00552011-02-04 11:06:36 +0000408
DRC1a45b812014-05-09 18:06:58 +0000409 if(tjDecompressHeader3(handle, jpegBuf, (unsigned long)jpegSize,
DRC38cb1ec2013-08-23 04:45:43 +0000410 &width, &height, &jpegSubsamp, &jpegColorspace)==-1)
DRCf8e00552011-02-04 11:06:36 +0000411 _throw(tjGetErrorStr());
DRC8951cf02014-08-14 16:54:04 +0000412
DRC9b28def2011-05-21 14:37:15 +0000413 (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0); jpegBuf=NULL;
DRCf8e00552011-02-04 11:06:36 +0000414
DRCfc26b652014-03-16 22:56:26 +0000415 bailif0(_fid=(*env)->GetFieldID(env, _cls, "srcSubsamp", "I"));
DRC9b28def2011-05-21 14:37:15 +0000416 (*env)->SetIntField(env, obj, _fid, jpegSubsamp);
DRCfc26b652014-03-16 22:56:26 +0000417 bailif0(_fid=(*env)->GetFieldID(env, _cls, "srcColorspace", "I"));
DRC38cb1ec2013-08-23 04:45:43 +0000418 (*env)->SetIntField(env, obj, _fid, jpegColorspace);
DRCfc26b652014-03-16 22:56:26 +0000419 bailif0(_fid=(*env)->GetFieldID(env, _cls, "srcWidth", "I"));
DRC3bad53f2011-02-23 02:20:49 +0000420 (*env)->SetIntField(env, obj, _fid, width);
DRCfc26b652014-03-16 22:56:26 +0000421 bailif0(_fid=(*env)->GetFieldID(env, _cls, "srcHeight", "I"));
DRC3bad53f2011-02-23 02:20:49 +0000422 (*env)->SetIntField(env, obj, _fid, height);
DRCf8e00552011-02-04 11:06:36 +0000423
424 bailout:
DRC8951cf02014-08-14 16:54:04 +0000425 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
DRC3bad53f2011-02-23 02:20:49 +0000426 return;
DRCf8e00552011-02-04 11:06:36 +0000427}
428
DRCf659f432012-06-06 08:41:06 +0000429JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIIIII
DRC9b28def2011-05-21 14:37:15 +0000430 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
DRCf659f432012-06-06 08:41:06 +0000431 jint x, jint y, jint width, jint pitch, jint height, jint pf, jint flags)
DRCf8e00552011-02-04 11:06:36 +0000432{
DRC9b28def2011-05-21 14:37:15 +0000433 tjhandle handle=0;
DRCf659f432012-06-06 08:41:06 +0000434 jsize arraySize=0, actualPitch;
DRC9b28def2011-05-21 14:37:15 +0000435 unsigned char *jpegBuf=NULL, *dstBuf=NULL;
DRCf8e00552011-02-04 11:06:36 +0000436
437 gethandle();
438
DRC92549de2011-03-15 20:52:02 +0000439 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
DRC4f1580c2011-02-25 06:11:03 +0000440 _throw("Invalid argument in decompress()");
DRC9b28def2011-05-21 14:37:15 +0000441 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
442 _throw("Mismatch between Java and C API");
DRC4f1580c2011-02-25 06:11:03 +0000443
DRC9b28def2011-05-21 14:37:15 +0000444 if((*env)->GetArrayLength(env, src)<jpegSize)
DRC6acf52b2011-03-02 01:09:20 +0000445 _throw("Source buffer is not large enough");
DRCf659f432012-06-06 08:41:06 +0000446 actualPitch=(pitch==0)? width*tjPixelSize[pf]:pitch;
DRCdc31f0b2012-06-07 09:38:57 +0000447 arraySize=(y+height-1)*actualPitch + (x+width)*tjPixelSize[pf];
DRC9b28def2011-05-21 14:37:15 +0000448 if((*env)->GetArrayLength(env, dst)<arraySize)
DRC6acf52b2011-03-02 01:09:20 +0000449 _throw("Destination buffer is not large enough");
450
DRC9b28def2011-05-21 14:37:15 +0000451 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
452 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
DRCf8e00552011-02-04 11:06:36 +0000453
DRCf659f432012-06-06 08:41:06 +0000454 if(tjDecompress2(handle, jpegBuf, (unsigned long)jpegSize,
455 &dstBuf[y*actualPitch + x*tjPixelSize[pf]], width, pitch, height, pf,
456 flags)==-1)
DRCf659f432012-06-06 08:41:06 +0000457 _throw(tjGetErrorStr());
DRCf659f432012-06-06 08:41:06 +0000458
459 bailout:
460 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
461 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
462 return;
463}
464
465JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIII
466 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
467 jint width, jint pitch, jint height, jint pf, jint flags)
468{
469 Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIIIII
470 (env, obj, src, jpegSize, dst, 0, 0, width, pitch, height, pf, flags);
471}
472
473JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIIIII
474 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jintArray dst,
475 jint x, jint y, jint width, jint stride, jint height, jint pf, jint flags)
476{
477 tjhandle handle=0;
478 jsize arraySize=0, actualStride;
479 unsigned char *jpegBuf=NULL, *dstBuf=NULL;
480
481 gethandle();
482
483 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
484 _throw("Invalid argument in decompress()");
485 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
486 _throw("Mismatch between Java and C API");
487 if(tjPixelSize[pf]!=sizeof(jint))
488 _throw("Pixel format must be 32-bit when decompressing to an integer buffer.");
489
490 if((*env)->GetArrayLength(env, src)<jpegSize)
491 _throw("Source buffer is not large enough");
492 actualStride=(stride==0)? width:stride;
DRCdc31f0b2012-06-07 09:38:57 +0000493 arraySize=(y+height-1)*actualStride + x+width;
DRCf659f432012-06-06 08:41:06 +0000494 if((*env)->GetArrayLength(env, dst)<arraySize)
495 _throw("Destination buffer is not large enough");
496
497 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
498 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
499
500 if(tjDecompress2(handle, jpegBuf, (unsigned long)jpegSize,
501 &dstBuf[(y*actualStride + x)*sizeof(int)], width, stride*sizeof(jint),
502 height, pf, flags)==-1)
DRCf8e00552011-02-04 11:06:36 +0000503 _throw(tjGetErrorStr());
DRCf8e00552011-02-04 11:06:36 +0000504
505 bailout:
DRC9b28def2011-05-21 14:37:15 +0000506 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
507 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
DRCf8e00552011-02-04 11:06:36 +0000508 return;
509}
510
DRC4f1580c2011-02-25 06:11:03 +0000511JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIII
DRC9b28def2011-05-21 14:37:15 +0000512 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jintArray dst,
DRCf659f432012-06-06 08:41:06 +0000513 jint width, jint stride, jint height, jint pf, jint flags)
DRC84a1bcc2011-02-23 12:09:56 +0000514{
DRCf659f432012-06-06 08:41:06 +0000515 Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIIIII
516 (env, obj, src, jpegSize, dst, 0, 0, width, stride, height, pf, flags);
DRC1a45b812014-05-09 18:06:58 +0000517
DRC4f1580c2011-02-25 06:11:03 +0000518}
DRC84a1bcc2011-02-23 12:09:56 +0000519
DRCfef98522013-04-28 01:32:52 +0000520JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3BIIII
DRC9b28def2011-05-21 14:37:15 +0000521 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
DRCfef98522013-04-28 01:32:52 +0000522 jint desiredWidth, jint pad, jint desiredHeight, jint flags)
DRC4f1580c2011-02-25 06:11:03 +0000523{
524 tjhandle handle=0;
DRC9b28def2011-05-21 14:37:15 +0000525 unsigned char *jpegBuf=NULL, *dstBuf=NULL;
DRC6acf52b2011-03-02 01:09:20 +0000526 int jpegSubsamp=-1, jpegWidth=0, jpegHeight=0;
DRCfef98522013-04-28 01:32:52 +0000527 jsize yuvSize;
DRC4f1580c2011-02-25 06:11:03 +0000528
529 gethandle();
530
DRC9b28def2011-05-21 14:37:15 +0000531 if((*env)->GetArrayLength(env, src)<jpegSize)
DRC6acf52b2011-03-02 01:09:20 +0000532 _throw("Source buffer is not large enough");
DRCfc26b652014-03-16 22:56:26 +0000533 bailif0(_fid=(*env)->GetFieldID(env, _cls, "srcSubsamp", "I"));
DRC6acf52b2011-03-02 01:09:20 +0000534 jpegSubsamp=(int)(*env)->GetIntField(env, obj, _fid);
DRCfc26b652014-03-16 22:56:26 +0000535 bailif0(_fid=(*env)->GetFieldID(env, _cls, "srcWidth", "I"));
DRC6acf52b2011-03-02 01:09:20 +0000536 jpegWidth=(int)(*env)->GetIntField(env, obj, _fid);
DRCfc26b652014-03-16 22:56:26 +0000537 bailif0(_fid=(*env)->GetFieldID(env, _cls, "srcHeight", "I"));
DRC6acf52b2011-03-02 01:09:20 +0000538 jpegHeight=(int)(*env)->GetIntField(env, obj, _fid);
DRC6acf52b2011-03-02 01:09:20 +0000539
DRCfef98522013-04-28 01:32:52 +0000540 yuvSize=(jsize)tjBufSizeYUV2(desiredWidth==0? jpegWidth:desiredWidth,
541 pad, desiredHeight==0? jpegHeight:desiredHeight, jpegSubsamp);
542 if(yuvSize==(unsigned long)-1)
543 _throw(tjGetErrorStr());
544 if((*env)->GetArrayLength(env, dst)<yuvSize)
545 _throw("Destination buffer is not large enough");
DRC9b28def2011-05-21 14:37:15 +0000546 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
547 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
DRC4f1580c2011-02-25 06:11:03 +0000548
DRCfef98522013-04-28 01:32:52 +0000549 if(tjDecompressToYUV2(handle, jpegBuf, (unsigned long)jpegSize, dstBuf,
550 desiredWidth, pad, desiredHeight, flags)==-1)
DRC4f1580c2011-02-25 06:11:03 +0000551 _throw(tjGetErrorStr());
DRC4f1580c2011-02-25 06:11:03 +0000552
553 bailout:
DRC9b28def2011-05-21 14:37:15 +0000554 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
555 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
DRC4f1580c2011-02-25 06:11:03 +0000556 return;
DRC84a1bcc2011-02-23 12:09:56 +0000557}
558
DRCfef98522013-04-28 01:32:52 +0000559JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3BI
560 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
561 jint flags)
562{
563 Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3BIIII(
564 env, obj, src, jpegSize, dst, 0, 4, 0, flags);
565}
566
DRCfc26b652014-03-16 22:56:26 +0000567JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decodeYUV___3BII_3BIIIIIII
568 (JNIEnv *env, jobject obj, jbyteArray src, jint pad, jint subsamp,
569 jbyteArray dst, jint x, jint y, jint width, jint pitch, jint height,
570 jint pf, jint flags)
571{
572 tjhandle handle=0;
573 jsize arraySize=0, actualPitch;
574 unsigned char *srcBuf=NULL, *dstBuf=NULL;
575
576 gethandle();
577
578 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
579 _throw("Invalid argument in decodeYUV()");
580 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
581 _throw("Mismatch between Java and C API");
582
583 arraySize=tjBufSizeYUV2(width, pad, height, subsamp);
584 if((*env)->GetArrayLength(env, src)<arraySize)
585 _throw("Source buffer is not large enough");
586 actualPitch=(pitch==0)? width*tjPixelSize[pf]:pitch;
587 arraySize=(y+height-1)*actualPitch + (x+width)*tjPixelSize[pf];
588 if((*env)->GetArrayLength(env, dst)<arraySize)
589 _throw("Destination buffer is not large enough");
590
591 bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
592 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
593
594 if(tjDecodeYUV(handle, srcBuf, pad, subsamp,
595 &dstBuf[y*actualPitch + x*tjPixelSize[pf]], width, pitch, height, pf,
596 flags)==-1)
DRCfc26b652014-03-16 22:56:26 +0000597 _throw(tjGetErrorStr());
DRCfc26b652014-03-16 22:56:26 +0000598
599 bailout:
600 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
601 if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
602 return;
603}
604
605JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decodeYUV___3BII_3IIIIIIII
606 (JNIEnv *env, jobject obj, jbyteArray src, jint pad, jint subsamp,
607 jintArray dst, jint x, jint y, jint width, jint stride, jint height,
608 jint pf, jint flags)
609{
610 tjhandle handle=0;
611 jsize arraySize=0, actualStride;
612 unsigned char *srcBuf=NULL, *dstBuf=NULL;
613
614 gethandle();
615
616 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
617 _throw("Invalid argument in decodeYUV()");
618 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
619 _throw("Mismatch between Java and C API");
620 if(tjPixelSize[pf]!=sizeof(jint))
621 _throw("Pixel format must be 32-bit when decoding to an integer buffer.");
622
623 arraySize=tjBufSizeYUV2(width, pad, height, subsamp);
624 if((*env)->GetArrayLength(env, src)<arraySize)
625 _throw("Source buffer is not large enough");
626 actualStride=(stride==0)? width:stride;
627 arraySize=(y+height-1)*actualStride + x+width;
628 if((*env)->GetArrayLength(env, dst)<arraySize)
629 _throw("Destination buffer is not large enough");
630
631 bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
632 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
633
634 if(tjDecodeYUV(handle, srcBuf, pad, subsamp,
635 &dstBuf[(y*actualStride + x)*sizeof(int)], width, stride*sizeof(jint),
636 height, pf, flags)==-1)
DRCfc26b652014-03-16 22:56:26 +0000637 _throw(tjGetErrorStr());
DRCfc26b652014-03-16 22:56:26 +0000638
639 bailout:
640 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
641 if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
642 return;
643}
644
DRCe8573012011-03-04 10:13:59 +0000645JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_init
646 (JNIEnv *env, jobject obj)
647{
648 jclass cls;
649 jfieldID fid;
650 tjhandle handle;
651
652 if((handle=tjInitTransform())==NULL) _throw(tjGetErrorStr());
653
654 bailif0(cls=(*env)->GetObjectClass(env, obj));
655 bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J"));
DRC23da0c02011-03-04 15:28:16 +0000656 (*env)->SetLongField(env, obj, fid, (jlong)handle);
DRCe8573012011-03-04 10:13:59 +0000657
658 bailout:
659 return;
660}
661
DRCf5467112011-09-20 05:02:19 +0000662typedef struct _JNICustomFilterParams
663{
664 JNIEnv *env;
665 jobject tobj;
666 jobject cfobj;
667} JNICustomFilterParams;
668
669static int JNICustomFilter(short *coeffs, tjregion arrayRegion,
670 tjregion planeRegion, int componentIndex, int transformIndex,
671 tjtransform *transform)
672{
673 JNICustomFilterParams *params=(JNICustomFilterParams *)transform->data;
674 JNIEnv *env=params->env;
675 jobject tobj=params->tobj, cfobj=params->cfobj;
676 jobject arrayRegionObj, planeRegionObj, bufobj, borobj;
677 jclass cls; jmethodID mid; jfieldID fid;
678
679 bailif0(bufobj=(*env)->NewDirectByteBuffer(env, coeffs,
680 sizeof(short)*arrayRegion.w*arrayRegion.h));
681 bailif0(cls=(*env)->FindClass(env, "java/nio/ByteOrder"));
682 bailif0(mid=(*env)->GetStaticMethodID(env, cls, "nativeOrder",
683 "()Ljava/nio/ByteOrder;"));
684 bailif0(borobj=(*env)->CallStaticObjectMethod(env, cls, mid));
685 bailif0(cls=(*env)->GetObjectClass(env, bufobj));
686 bailif0(mid=(*env)->GetMethodID(env, cls, "order",
687 "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;"));
688 (*env)->CallObjectMethod(env, bufobj, mid, borobj);
689 bailif0(mid=(*env)->GetMethodID(env, cls, "asShortBuffer",
690 "()Ljava/nio/ShortBuffer;"));
691 bailif0(bufobj=(*env)->CallObjectMethod(env, bufobj, mid));
692
693 bailif0(cls=(*env)->FindClass(env, "java/awt/Rectangle"));
694 bailif0(arrayRegionObj=(*env)->AllocObject(env, cls));
695 bailif0(fid=(*env)->GetFieldID(env, cls, "x", "I"));
696 (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.x);
697 bailif0(fid=(*env)->GetFieldID(env, cls, "y", "I"));
698 (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.y);
699 bailif0(fid=(*env)->GetFieldID(env, cls, "width", "I"));
700 (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.w);
701 bailif0(fid=(*env)->GetFieldID(env, cls, "height", "I"));
702 (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.h);
703
704 bailif0(planeRegionObj=(*env)->AllocObject(env, cls));
705 bailif0(fid=(*env)->GetFieldID(env, cls, "x", "I"));
706 (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.x);
707 bailif0(fid=(*env)->GetFieldID(env, cls, "y", "I"));
708 (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.y);
709 bailif0(fid=(*env)->GetFieldID(env, cls, "width", "I"));
710 (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.w);
711 bailif0(fid=(*env)->GetFieldID(env, cls, "height", "I"));
712 (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.h);
713
714 bailif0(cls=(*env)->GetObjectClass(env, cfobj));
715 bailif0(mid=(*env)->GetMethodID(env, cls, "customFilter",
716 "(Ljava/nio/ShortBuffer;Ljava/awt/Rectangle;Ljava/awt/Rectangle;IILorg/libjpegturbo/turbojpeg/TJTransform;)V"));
717 (*env)->CallVoidMethod(env, cfobj, mid, bufobj, arrayRegionObj,
718 planeRegionObj, componentIndex, transformIndex, tobj);
719
720 return 0;
721
722 bailout:
723 return -1;
724}
725
DRCe8573012011-03-04 10:13:59 +0000726JNIEXPORT jintArray JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_transform
DRC9b28def2011-05-21 14:37:15 +0000727 (JNIEnv *env, jobject obj, jbyteArray jsrcBuf, jint jpegSize,
DRCe8573012011-03-04 10:13:59 +0000728 jobjectArray dstobjs, jobjectArray tobjs, jint flags)
729{
730 tjhandle handle=0; int i;
DRC9b28def2011-05-21 14:37:15 +0000731 unsigned char *jpegBuf=NULL, **dstBufs=NULL; jsize n=0;
732 unsigned long *dstSizes=NULL; tjtransform *t=NULL;
733 jbyteArray *jdstBufs=NULL;
DRC9b49f0e2011-07-12 03:17:23 +0000734 int jpegWidth=0, jpegHeight=0, jpegSubsamp;
DRC9b28def2011-05-21 14:37:15 +0000735 jintArray jdstSizes=0; jint *dstSizesi=NULL;
DRCf5467112011-09-20 05:02:19 +0000736 JNICustomFilterParams *params=NULL;
DRCe8573012011-03-04 10:13:59 +0000737
738 gethandle();
739
DRC9b28def2011-05-21 14:37:15 +0000740 if((*env)->GetArrayLength(env, jsrcBuf)<jpegSize)
DRCe8573012011-03-04 10:13:59 +0000741 _throw("Source buffer is not large enough");
DRCfc26b652014-03-16 22:56:26 +0000742 bailif0(_fid=(*env)->GetFieldID(env, _cls, "srcWidth", "I"));
DRCe8573012011-03-04 10:13:59 +0000743 jpegWidth=(int)(*env)->GetIntField(env, obj, _fid);
DRCfc26b652014-03-16 22:56:26 +0000744 bailif0(_fid=(*env)->GetFieldID(env, _cls, "srcHeight", "I"));
DRCe8573012011-03-04 10:13:59 +0000745 jpegHeight=(int)(*env)->GetIntField(env, obj, _fid);
DRCfc26b652014-03-16 22:56:26 +0000746 bailif0(_fid=(*env)->GetFieldID(env, _cls, "srcSubsamp", "I"));
DRC9b49f0e2011-07-12 03:17:23 +0000747 jpegSubsamp=(int)(*env)->GetIntField(env, obj, _fid);
DRCe8573012011-03-04 10:13:59 +0000748
749 n=(*env)->GetArrayLength(env, dstobjs);
750 if(n!=(*env)->GetArrayLength(env, tobjs))
751 _throw("Mismatch between size of transforms array and destination buffers array");
752
DRC9b28def2011-05-21 14:37:15 +0000753 if((dstBufs=(unsigned char **)malloc(sizeof(unsigned char *)*n))==NULL)
DRCe8573012011-03-04 10:13:59 +0000754 _throw("Memory allocation failure");
DRC9b28def2011-05-21 14:37:15 +0000755 if((jdstBufs=(jbyteArray *)malloc(sizeof(jbyteArray)*n))==NULL)
DRCe8573012011-03-04 10:13:59 +0000756 _throw("Memory allocation failure");
DRC9b28def2011-05-21 14:37:15 +0000757 if((dstSizes=(unsigned long *)malloc(sizeof(unsigned long)*n))==NULL)
DRCe8573012011-03-04 10:13:59 +0000758 _throw("Memory allocation failure");
759 if((t=(tjtransform *)malloc(sizeof(tjtransform)*n))==NULL)
760 _throw("Memory allocation failure");
DRCf5467112011-09-20 05:02:19 +0000761 if((params=(JNICustomFilterParams *)malloc(sizeof(JNICustomFilterParams)*n))
762 ==NULL)
763 _throw("Memory allocation failure");
DRCe8573012011-03-04 10:13:59 +0000764 for(i=0; i<n; i++)
765 {
DRC9b28def2011-05-21 14:37:15 +0000766 dstBufs[i]=NULL; jdstBufs[i]=NULL; dstSizes[i]=0;
DRCe8573012011-03-04 10:13:59 +0000767 memset(&t[i], 0, sizeof(tjtransform));
DRCf5467112011-09-20 05:02:19 +0000768 memset(&params[i], 0, sizeof(JNICustomFilterParams));
DRCe8573012011-03-04 10:13:59 +0000769 }
770
771 for(i=0; i<n; i++)
772 {
DRCf5467112011-09-20 05:02:19 +0000773 jobject tobj, cfobj;
DRCe8573012011-03-04 10:13:59 +0000774
775 bailif0(tobj=(*env)->GetObjectArrayElement(env, tobjs, i));
776 bailif0(_cls=(*env)->GetObjectClass(env, tobj));
777 bailif0(_fid=(*env)->GetFieldID(env, _cls, "op", "I"));
778 t[i].op=(*env)->GetIntField(env, tobj, _fid);
779 bailif0(_fid=(*env)->GetFieldID(env, _cls, "options", "I"));
780 t[i].options=(*env)->GetIntField(env, tobj, _fid);
781 bailif0(_fid=(*env)->GetFieldID(env, _cls, "x", "I"));
782 t[i].r.x=(*env)->GetIntField(env, tobj, _fid);
783 bailif0(_fid=(*env)->GetFieldID(env, _cls, "y", "I"));
784 t[i].r.y=(*env)->GetIntField(env, tobj, _fid);
785 bailif0(_fid=(*env)->GetFieldID(env, _cls, "width", "I"));
786 t[i].r.w=(*env)->GetIntField(env, tobj, _fid);
787 bailif0(_fid=(*env)->GetFieldID(env, _cls, "height", "I"));
788 t[i].r.h=(*env)->GetIntField(env, tobj, _fid);
DRCf5467112011-09-20 05:02:19 +0000789
DRCf5467112011-09-20 05:02:19 +0000790 bailif0(_fid=(*env)->GetFieldID(env, _cls, "cf",
791 "Lorg/libjpegturbo/turbojpeg/TJCustomFilter;"));
DRC06420c42011-09-26 18:46:09 +0000792 cfobj=(*env)->GetObjectField(env, tobj, _fid);
793 if(cfobj)
794 {
795 params[i].env=env;
796 params[i].tobj=tobj;
797 params[i].cfobj=cfobj;
798 t[i].customFilter=JNICustomFilter;
799 t[i].data=(void *)&params[i];
800 }
DRCe8573012011-03-04 10:13:59 +0000801 }
802
DRCe8573012011-03-04 10:13:59 +0000803 for(i=0; i<n; i++)
804 {
805 int w=jpegWidth, h=jpegHeight;
806 if(t[i].r.w!=0) w=t[i].r.w;
807 if(t[i].r.h!=0) h=t[i].r.h;
DRC9b28def2011-05-21 14:37:15 +0000808 bailif0(jdstBufs[i]=(*env)->GetObjectArrayElement(env, dstobjs, i));
DRCefe28ce2012-01-17 11:48:38 +0000809 if((unsigned long)(*env)->GetArrayLength(env, jdstBufs[i])
810 <tjBufSize(w, h, jpegSubsamp))
DRCe8573012011-03-04 10:13:59 +0000811 _throw("Destination buffer is not large enough");
DRCe8573012011-03-04 10:13:59 +0000812 }
DRC8951cf02014-08-14 16:54:04 +0000813 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, jsrcBuf, 0));
814 for(i=0; i<n; i++)
815 bailif0(dstBufs[i]=(*env)->GetPrimitiveArrayCritical(env, jdstBufs[i], 0));
DRCe8573012011-03-04 10:13:59 +0000816
DRC9b28def2011-05-21 14:37:15 +0000817 if(tjTransform(handle, jpegBuf, jpegSize, n, dstBufs, dstSizes, t,
DRC4db92ad2011-05-25 04:52:25 +0000818 flags|TJFLAG_NOREALLOC)==-1)
DRCe8573012011-03-04 10:13:59 +0000819 _throw(tjGetErrorStr());
DRC8951cf02014-08-14 16:54:04 +0000820
821 for(i=0; i<n; i++)
822 {
823 (*env)->ReleasePrimitiveArrayCritical(env, jdstBufs[i], dstBufs[i], 0);
824 dstBufs[i]=NULL;
DRCe8573012011-03-04 10:13:59 +0000825 }
DRC8951cf02014-08-14 16:54:04 +0000826 (*env)->ReleasePrimitiveArrayCritical(env, jsrcBuf, jpegBuf, 0);
827 jpegBuf=NULL;
DRCe8573012011-03-04 10:13:59 +0000828
DRC9b28def2011-05-21 14:37:15 +0000829 jdstSizes=(*env)->NewIntArray(env, n);
830 bailif0(dstSizesi=(*env)->GetIntArrayElements(env, jdstSizes, 0));
831 for(i=0; i<n; i++) dstSizesi[i]=(int)dstSizes[i];
DRCe8573012011-03-04 10:13:59 +0000832
833 bailout:
DRC8951cf02014-08-14 16:54:04 +0000834 if(dstSizesi) (*env)->ReleaseIntArrayElements(env, jdstSizes, dstSizesi, 0);
DRC9b28def2011-05-21 14:37:15 +0000835 if(dstBufs)
DRCe8573012011-03-04 10:13:59 +0000836 {
837 for(i=0; i<n; i++)
838 {
DRC9b28def2011-05-21 14:37:15 +0000839 if(dstBufs[i] && jdstBufs && jdstBufs[i])
840 (*env)->ReleasePrimitiveArrayCritical(env, jdstBufs[i], dstBufs[i], 0);
DRCe8573012011-03-04 10:13:59 +0000841 }
DRC9b28def2011-05-21 14:37:15 +0000842 free(dstBufs);
DRCe8573012011-03-04 10:13:59 +0000843 }
DRC8951cf02014-08-14 16:54:04 +0000844 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, jsrcBuf, jpegBuf, 0);
DRC9b28def2011-05-21 14:37:15 +0000845 if(jdstBufs) free(jdstBufs);
846 if(dstSizes) free(dstSizes);
DRCe8573012011-03-04 10:13:59 +0000847 if(t) free(t);
DRC9b28def2011-05-21 14:37:15 +0000848 return jdstSizes;
DRCe8573012011-03-04 10:13:59 +0000849}
850
DRCc5a41992011-02-08 06:54:36 +0000851JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_destroy
DRCf8e00552011-02-04 11:06:36 +0000852 (JNIEnv *env, jobject obj)
853{
DRCc5a41992011-02-08 06:54:36 +0000854 Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy(env, obj);
DRCf8e00552011-02-04 11:06:36 +0000855}