blob: 4b5578ff9a35886d33a447a8dfaeebf23072c2de [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)
137 {
138 (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0);
139 (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
140 jpegBuf=srcBuf=NULL;
141 _throw(tjGetErrorStr());
142 }
143
144 bailout:
145 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0);
146 if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
147 return (jint)jpegSize;
148}
149
150JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIII_3BIII
151 (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch,
152 jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpegQual,
153 jint flags)
154{
155 return Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIIIII_3BIII(
156 env, obj, src, 0, 0, width, pitch, height, pf, dst, jpegSubsamp, jpegQual,
157 flags);
158}
159
160JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIIIII_3BIII
161 (JNIEnv *env, jobject obj, jintArray src, jint x, jint y, jint width,
162 jint stride, jint height, jint pf, jbyteArray dst, jint jpegSubsamp,
163 jint jpegQual, jint flags)
164{
165 tjhandle handle=0;
166 unsigned long jpegSize=0;
167 jsize arraySize=0, actualStride;
168 unsigned char *srcBuf=NULL, *jpegBuf=NULL;
169
170 gethandle();
171
172 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1
173 || stride<0)
174 _throw("Invalid argument in compress()");
175 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
176 _throw("Mismatch between Java and C API");
177 if(tjPixelSize[pf]!=sizeof(jint))
178 _throw("Pixel format must be 32-bit when compressing from an integer buffer.");
179
180 actualStride=(stride==0)? width:stride;
181 arraySize=(y+height-1)*actualStride + x+width;
182 if((*env)->GetArrayLength(env, src)<arraySize)
183 _throw("Source buffer is not large enough");
184 jpegSize=tjBufSize(width, height, jpegSubsamp);
185 if((*env)->GetArrayLength(env, dst)<(jsize)jpegSize)
186 _throw("Destination buffer is not large enough");
187
188 bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
189 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
190
191 if(tjCompress2(handle, &srcBuf[(y*actualStride + x)*sizeof(int)], width,
192 stride*sizeof(jint), height, pf, &jpegBuf, &jpegSize, jpegSubsamp,
193 jpegQual, flags|TJFLAG_NOREALLOC)==-1)
DRCf8e00552011-02-04 11:06:36 +0000194 {
DRC9b28def2011-05-21 14:37:15 +0000195 (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0);
196 (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
197 jpegBuf=srcBuf=NULL;
DRCf8e00552011-02-04 11:06:36 +0000198 _throw(tjGetErrorStr());
199 }
200
201 bailout:
DRC9b28def2011-05-21 14:37:15 +0000202 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0);
203 if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
204 return (jint)jpegSize;
DRCf8e00552011-02-04 11:06:36 +0000205}
206
DRC4f1580c2011-02-25 06:11:03 +0000207JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIII_3BIII
DRC84a1bcc2011-02-23 12:09:56 +0000208 (JNIEnv *env, jobject obj, jintArray src, jint width, jint pitch,
DRC9b28def2011-05-21 14:37:15 +0000209 jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpegQual,
DRC4f1580c2011-02-25 06:11:03 +0000210 jint flags)
DRC84a1bcc2011-02-23 12:09:56 +0000211{
DRCfac3bea2012-09-24 02:27:55 +0000212 return Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIIIII_3BIII(
213 env, obj, src, 0, 0, width, pitch, height, pf, dst, jpegSubsamp, jpegQual,
214 flags);
DRC84a1bcc2011-02-23 12:09:56 +0000215}
216
DRC1e672742013-10-31 05:04:51 +0000217JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compressFromYUV___3BIIII_3BII
218 (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pad, jint height,
219 jint subsamp, jbyteArray dst, jint jpegQual, jint flags)
220{
221 tjhandle handle=0;
222 unsigned long jpegSize=0;
223 jsize arraySize=0;
224 unsigned char *srcBuf=NULL, *jpegBuf=NULL;
225
226 gethandle();
227
228 arraySize=tjBufSizeYUV2(width, pad, height, subsamp);
229 if((*env)->GetArrayLength(env, src)<arraySize)
230 _throw("Source buffer is not large enough");
231 jpegSize=tjBufSize(width, height, subsamp);
232 if((*env)->GetArrayLength(env, dst)<(jsize)jpegSize)
233 _throw("Destination buffer is not large enough");
234
235 bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
236 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
237
238 if(tjCompressFromYUV(handle, srcBuf, width, pad, height, subsamp, &jpegBuf,
239 &jpegSize, jpegQual, flags|TJFLAG_NOREALLOC)==-1)
240 {
241 (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0);
242 (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
243 jpegBuf=srcBuf=NULL;
244 _throw(tjGetErrorStr());
245 }
246
247 bailout:
248 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0);
249 if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
250 return (jint)jpegSize;
251}
252
DRCfc26b652014-03-16 22:56:26 +0000253JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIIIII_3BIII
254 (JNIEnv *env, jobject obj, jbyteArray src, jint x, jint y, jint width,
255 jint pitch, jint height, jint pf, jbyteArray dst, jint pad, jint subsamp,
256 jint flags)
DRC4f1580c2011-02-25 06:11:03 +0000257{
DRC9b28def2011-05-21 14:37:15 +0000258 tjhandle handle=0;
DRCfc26b652014-03-16 22:56:26 +0000259 jsize arraySize=0, actualPitch, yuvSize;
DRC9b28def2011-05-21 14:37:15 +0000260 unsigned char *srcBuf=NULL, *dstBuf=NULL;
DRC4f1580c2011-02-25 06:11:03 +0000261
262 gethandle();
263
DRC92549de2011-03-15 20:52:02 +0000264 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1
DRC6acf52b2011-03-02 01:09:20 +0000265 || pitch<0)
DRC4f1580c2011-02-25 06:11:03 +0000266 _throw("Invalid argument in encodeYUV()");
DRC9b28def2011-05-21 14:37:15 +0000267 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
268 _throw("Mismatch between Java and C API");
DRC4f1580c2011-02-25 06:11:03 +0000269
DRCfc26b652014-03-16 22:56:26 +0000270 actualPitch=(pitch==0)? width*tjPixelSize[pf]:pitch;
271 arraySize=(y+height-1)*actualPitch + x+width;
DRC9b28def2011-05-21 14:37:15 +0000272 if((*env)->GetArrayLength(env, src)<arraySize)
DRC6acf52b2011-03-02 01:09:20 +0000273 _throw("Source buffer is not large enough");
DRCfef98522013-04-28 01:32:52 +0000274 yuvSize=(jsize)tjBufSizeYUV2(width, pad, height, subsamp);
275 if(yuvSize==(unsigned long)-1)
276 _throw(tjGetErrorStr());
277 if((*env)->GetArrayLength(env, dst)<yuvSize)
DRC6acf52b2011-03-02 01:09:20 +0000278 _throw("Destination buffer is not large enough");
279
DRC9b28def2011-05-21 14:37:15 +0000280 bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
281 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
DRC4f1580c2011-02-25 06:11:03 +0000282
DRCfc26b652014-03-16 22:56:26 +0000283 if(tjEncodeYUV3(handle, &srcBuf[y*actualPitch + x*tjPixelSize[pf]], width,
284 pitch, height, pf, dstBuf, pad, subsamp, flags)==-1)
DRC4f1580c2011-02-25 06:11:03 +0000285 {
DRC9b28def2011-05-21 14:37:15 +0000286 (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
287 (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
288 dstBuf=srcBuf=NULL;
DRC4f1580c2011-02-25 06:11:03 +0000289 _throw(tjGetErrorStr());
290 }
291
292 bailout:
DRC9b28def2011-05-21 14:37:15 +0000293 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
294 if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
DRC4f1580c2011-02-25 06:11:03 +0000295 return;
296}
297
DRCfef98522013-04-28 01:32:52 +0000298JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIII_3BII
299 (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch,
DRC6acf52b2011-03-02 01:09:20 +0000300 jint height, jint pf, jbyteArray dst, jint subsamp, jint flags)
DRC4f1580c2011-02-25 06:11:03 +0000301{
DRCfc26b652014-03-16 22:56:26 +0000302 Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIIIII_3BIII(
303 env, obj, src, 0, 0, width, pitch, height, pf, dst, 4, subsamp, flags);
DRCfef98522013-04-28 01:32:52 +0000304}
305
DRCfc26b652014-03-16 22:56:26 +0000306JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIIIII_3BIII
307 (JNIEnv *env, jobject obj, jintArray src, jint x, jint y, jint width,
308 jint stride, jint height, jint pf, jbyteArray dst, jint pad, jint subsamp,
309 jint flags)
DRCfef98522013-04-28 01:32:52 +0000310{
DRC4f1580c2011-02-25 06:11:03 +0000311 tjhandle handle=0;
DRCfc26b652014-03-16 22:56:26 +0000312 jsize arraySize=0, actualStride, yuvSize;
DRC9b28def2011-05-21 14:37:15 +0000313 unsigned char *srcBuf=NULL, *dstBuf=NULL;
DRC4f1580c2011-02-25 06:11:03 +0000314
315 gethandle();
316
DRC92549de2011-03-15 20:52:02 +0000317 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1
DRC1d29c5f2013-04-27 20:54:44 +0000318 || stride<0)
319 _throw("Invalid argument in encodeYUV()");
DRC9b28def2011-05-21 14:37:15 +0000320 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
321 _throw("Mismatch between Java and C API");
322 if(tjPixelSize[pf]!=sizeof(jint))
DRC4f1580c2011-02-25 06:11:03 +0000323 _throw("Pixel format must be 32-bit when encoding from an integer buffer.");
DRC4f1580c2011-02-25 06:11:03 +0000324
DRCfc26b652014-03-16 22:56:26 +0000325 actualStride=(stride==0)? width:stride;
326 arraySize=(y+height-1)*actualStride + x+width;
DRC9b28def2011-05-21 14:37:15 +0000327 if((*env)->GetArrayLength(env, src)<arraySize)
DRC6acf52b2011-03-02 01:09:20 +0000328 _throw("Source buffer is not large enough");
DRCfef98522013-04-28 01:32:52 +0000329 yuvSize=(jsize)tjBufSizeYUV2(width, pad, height, subsamp);
330 if(yuvSize==(unsigned long)-1)
331 _throw(tjGetErrorStr());
332 if((*env)->GetArrayLength(env, dst)<yuvSize)
DRC6acf52b2011-03-02 01:09:20 +0000333 _throw("Destination buffer is not large enough");
334
DRC9b28def2011-05-21 14:37:15 +0000335 bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
336 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
DRC4f1580c2011-02-25 06:11:03 +0000337
DRCfc26b652014-03-16 22:56:26 +0000338 if(tjEncodeYUV3(handle, &srcBuf[(y*actualStride + x)*sizeof(int)], width,
339 stride*sizeof(jint), height, pf, dstBuf, pad, subsamp, flags)==-1)
DRC4f1580c2011-02-25 06:11:03 +0000340 {
DRC9b28def2011-05-21 14:37:15 +0000341 (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
342 (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
343 dstBuf=srcBuf=NULL;
DRC4f1580c2011-02-25 06:11:03 +0000344 _throw(tjGetErrorStr());
345 }
346
347 bailout:
DRC9b28def2011-05-21 14:37:15 +0000348 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
349 if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
DRC4f1580c2011-02-25 06:11:03 +0000350 return;
351}
352
DRCfef98522013-04-28 01:32:52 +0000353JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIII_3BII
354 (JNIEnv *env, jobject obj, jintArray src, jint width, jint pitch,
355 jint height, jint pf, jbyteArray dst, jint subsamp, jint flags)
356{
DRCfc26b652014-03-16 22:56:26 +0000357 Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIIIII_3BIII(
358 env, obj, src, 0, 0, width, pitch, height, pf, dst, 4, subsamp, flags);
DRCfef98522013-04-28 01:32:52 +0000359}
360
DRCc5a41992011-02-08 06:54:36 +0000361JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy
DRCf8e00552011-02-04 11:06:36 +0000362 (JNIEnv *env, jobject obj)
363{
364 tjhandle handle=0;
365
366 gethandle();
367
368 if(tjDestroy(handle)==-1) _throw(tjGetErrorStr());
DRC3bad53f2011-02-23 02:20:49 +0000369 (*env)->SetLongField(env, obj, _fid, 0);
DRCf8e00552011-02-04 11:06:36 +0000370
371 bailout:
372 return;
373}
374
DRCc5a41992011-02-08 06:54:36 +0000375JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_init
DRCf8e00552011-02-04 11:06:36 +0000376 (JNIEnv *env, jobject obj)
377{
378 jclass cls;
379 jfieldID fid;
380 tjhandle handle;
381
DRC1a3dbe62011-02-28 10:51:55 +0000382 if((handle=tjInitDecompress())==NULL) _throw(tjGetErrorStr());
DRCf8e00552011-02-04 11:06:36 +0000383
384 bailif0(cls=(*env)->GetObjectClass(env, obj));
385 bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J"));
DRC23da0c02011-03-04 15:28:16 +0000386 (*env)->SetLongField(env, obj, fid, (jlong)handle);
DRCf8e00552011-02-04 11:06:36 +0000387
388 bailout:
389 return;
390}
391
DRC109a5782011-03-01 09:53:07 +0000392JNIEXPORT jobjectArray JNICALL Java_org_libjpegturbo_turbojpeg_TJ_getScalingFactors
393 (JNIEnv *env, jclass cls)
DRC36336fc2011-02-22 10:27:31 +0000394{
DRC109a5782011-03-01 09:53:07 +0000395 jclass sfcls=NULL; jfieldID fid=0;
396 tjscalingfactor *sf=NULL; int n=0, i;
397 jobject sfobj=NULL;
398 jobjectArray sfjava=NULL;
399
400 if((sf=tjGetScalingFactors(&n))==NULL || n==0)
DRC36336fc2011-02-22 10:27:31 +0000401 _throw(tjGetErrorStr());
402
DRCb2f94152011-04-02 02:09:03 +0000403 bailif0(sfcls=(*env)->FindClass(env, "org/libjpegturbo/turbojpeg/TJScalingFactor"));
DRC109a5782011-03-01 09:53:07 +0000404 bailif0(sfjava=(jobjectArray)(*env)->NewObjectArray(env, n, sfcls, 0));
DRC36336fc2011-02-22 10:27:31 +0000405
DRC109a5782011-03-01 09:53:07 +0000406 for(i=0; i<n; i++)
407 {
408 bailif0(sfobj=(*env)->AllocObject(env, sfcls));
409 bailif0(fid=(*env)->GetFieldID(env, sfcls, "num", "I"));
410 (*env)->SetIntField(env, sfobj, fid, sf[i].num);
411 bailif0(fid=(*env)->GetFieldID(env, sfcls, "denom", "I"));
412 (*env)->SetIntField(env, sfobj, fid, sf[i].denom);
413 (*env)->SetObjectArrayElement(env, sfjava, i, sfobj);
414 }
DRC36336fc2011-02-22 10:27:31 +0000415
416 bailout:
DRC109a5782011-03-01 09:53:07 +0000417 return sfjava;
DRC36336fc2011-02-22 10:27:31 +0000418}
419
DRC3bad53f2011-02-23 02:20:49 +0000420JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressHeader
DRC9b28def2011-05-21 14:37:15 +0000421 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize)
DRCf8e00552011-02-04 11:06:36 +0000422{
DRCf8e00552011-02-04 11:06:36 +0000423 tjhandle handle=0;
DRC9b28def2011-05-21 14:37:15 +0000424 unsigned char *jpegBuf=NULL;
DRC38cb1ec2013-08-23 04:45:43 +0000425 int width=0, height=0, jpegSubsamp=-1, jpegColorspace=-1;
DRCf8e00552011-02-04 11:06:36 +0000426
427 gethandle();
428
DRC9b28def2011-05-21 14:37:15 +0000429 if((*env)->GetArrayLength(env, src)<jpegSize)
DRC6acf52b2011-03-02 01:09:20 +0000430 _throw("Source buffer is not large enough");
431
DRC9b28def2011-05-21 14:37:15 +0000432 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
DRCf8e00552011-02-04 11:06:36 +0000433
DRC1a45b812014-05-09 18:06:58 +0000434 if(tjDecompressHeader3(handle, jpegBuf, (unsigned long)jpegSize,
DRC38cb1ec2013-08-23 04:45:43 +0000435 &width, &height, &jpegSubsamp, &jpegColorspace)==-1)
DRCf8e00552011-02-04 11:06:36 +0000436 {
DRC9b28def2011-05-21 14:37:15 +0000437 (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
DRCf8e00552011-02-04 11:06:36 +0000438 _throw(tjGetErrorStr());
439 }
DRC9b28def2011-05-21 14:37:15 +0000440 (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0); jpegBuf=NULL;
DRCf8e00552011-02-04 11:06:36 +0000441
DRCfc26b652014-03-16 22:56:26 +0000442 bailif0(_fid=(*env)->GetFieldID(env, _cls, "srcSubsamp", "I"));
DRC9b28def2011-05-21 14:37:15 +0000443 (*env)->SetIntField(env, obj, _fid, jpegSubsamp);
DRCfc26b652014-03-16 22:56:26 +0000444 bailif0(_fid=(*env)->GetFieldID(env, _cls, "srcColorspace", "I"));
DRC38cb1ec2013-08-23 04:45:43 +0000445 (*env)->SetIntField(env, obj, _fid, jpegColorspace);
DRCfc26b652014-03-16 22:56:26 +0000446 bailif0(_fid=(*env)->GetFieldID(env, _cls, "srcWidth", "I"));
DRC3bad53f2011-02-23 02:20:49 +0000447 (*env)->SetIntField(env, obj, _fid, width);
DRCfc26b652014-03-16 22:56:26 +0000448 bailif0(_fid=(*env)->GetFieldID(env, _cls, "srcHeight", "I"));
DRC3bad53f2011-02-23 02:20:49 +0000449 (*env)->SetIntField(env, obj, _fid, height);
DRCf8e00552011-02-04 11:06:36 +0000450
451 bailout:
DRC3bad53f2011-02-23 02:20:49 +0000452 return;
DRCf8e00552011-02-04 11:06:36 +0000453}
454
DRCf659f432012-06-06 08:41:06 +0000455JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIIIII
DRC9b28def2011-05-21 14:37:15 +0000456 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
DRCf659f432012-06-06 08:41:06 +0000457 jint x, jint y, jint width, jint pitch, jint height, jint pf, jint flags)
DRCf8e00552011-02-04 11:06:36 +0000458{
DRC9b28def2011-05-21 14:37:15 +0000459 tjhandle handle=0;
DRCf659f432012-06-06 08:41:06 +0000460 jsize arraySize=0, actualPitch;
DRC9b28def2011-05-21 14:37:15 +0000461 unsigned char *jpegBuf=NULL, *dstBuf=NULL;
DRCf8e00552011-02-04 11:06:36 +0000462
463 gethandle();
464
DRC92549de2011-03-15 20:52:02 +0000465 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
DRC4f1580c2011-02-25 06:11:03 +0000466 _throw("Invalid argument in decompress()");
DRC9b28def2011-05-21 14:37:15 +0000467 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
468 _throw("Mismatch between Java and C API");
DRC4f1580c2011-02-25 06:11:03 +0000469
DRC9b28def2011-05-21 14:37:15 +0000470 if((*env)->GetArrayLength(env, src)<jpegSize)
DRC6acf52b2011-03-02 01:09:20 +0000471 _throw("Source buffer is not large enough");
DRCf659f432012-06-06 08:41:06 +0000472 actualPitch=(pitch==0)? width*tjPixelSize[pf]:pitch;
DRCdc31f0b2012-06-07 09:38:57 +0000473 arraySize=(y+height-1)*actualPitch + (x+width)*tjPixelSize[pf];
DRC9b28def2011-05-21 14:37:15 +0000474 if((*env)->GetArrayLength(env, dst)<arraySize)
DRC6acf52b2011-03-02 01:09:20 +0000475 _throw("Destination buffer is not large enough");
476
DRC9b28def2011-05-21 14:37:15 +0000477 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
478 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
DRCf8e00552011-02-04 11:06:36 +0000479
DRCf659f432012-06-06 08:41:06 +0000480 if(tjDecompress2(handle, jpegBuf, (unsigned long)jpegSize,
481 &dstBuf[y*actualPitch + x*tjPixelSize[pf]], width, pitch, height, pf,
482 flags)==-1)
483 {
484 (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
485 (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
486 dstBuf=jpegBuf=NULL;
487 _throw(tjGetErrorStr());
488 }
489
490 bailout:
491 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
492 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
493 return;
494}
495
496JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIII
497 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
498 jint width, jint pitch, jint height, jint pf, jint flags)
499{
500 Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIIIII
501 (env, obj, src, jpegSize, dst, 0, 0, width, pitch, height, pf, flags);
502}
503
504JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIIIII
505 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jintArray dst,
506 jint x, jint y, jint width, jint stride, jint height, jint pf, jint flags)
507{
508 tjhandle handle=0;
509 jsize arraySize=0, actualStride;
510 unsigned char *jpegBuf=NULL, *dstBuf=NULL;
511
512 gethandle();
513
514 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
515 _throw("Invalid argument in decompress()");
516 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
517 _throw("Mismatch between Java and C API");
518 if(tjPixelSize[pf]!=sizeof(jint))
519 _throw("Pixel format must be 32-bit when decompressing to an integer buffer.");
520
521 if((*env)->GetArrayLength(env, src)<jpegSize)
522 _throw("Source buffer is not large enough");
523 actualStride=(stride==0)? width:stride;
DRCdc31f0b2012-06-07 09:38:57 +0000524 arraySize=(y+height-1)*actualStride + x+width;
DRCf659f432012-06-06 08:41:06 +0000525 if((*env)->GetArrayLength(env, dst)<arraySize)
526 _throw("Destination buffer is not large enough");
527
528 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
529 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
530
531 if(tjDecompress2(handle, jpegBuf, (unsigned long)jpegSize,
532 &dstBuf[(y*actualStride + x)*sizeof(int)], width, stride*sizeof(jint),
533 height, pf, flags)==-1)
DRCf8e00552011-02-04 11:06:36 +0000534 {
DRC9b28def2011-05-21 14:37:15 +0000535 (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
536 (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
537 dstBuf=jpegBuf=NULL;
DRCf8e00552011-02-04 11:06:36 +0000538 _throw(tjGetErrorStr());
539 }
540
541 bailout:
DRC9b28def2011-05-21 14:37:15 +0000542 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
543 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
DRCf8e00552011-02-04 11:06:36 +0000544 return;
545}
546
DRC4f1580c2011-02-25 06:11:03 +0000547JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIII
DRC9b28def2011-05-21 14:37:15 +0000548 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jintArray dst,
DRCf659f432012-06-06 08:41:06 +0000549 jint width, jint stride, jint height, jint pf, jint flags)
DRC84a1bcc2011-02-23 12:09:56 +0000550{
DRCf659f432012-06-06 08:41:06 +0000551 Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIIIII
552 (env, obj, src, jpegSize, dst, 0, 0, width, stride, height, pf, flags);
DRC1a45b812014-05-09 18:06:58 +0000553
DRC4f1580c2011-02-25 06:11:03 +0000554}
DRC84a1bcc2011-02-23 12:09:56 +0000555
DRCfef98522013-04-28 01:32:52 +0000556JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3BIIII
DRC9b28def2011-05-21 14:37:15 +0000557 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
DRCfef98522013-04-28 01:32:52 +0000558 jint desiredWidth, jint pad, jint desiredHeight, jint flags)
DRC4f1580c2011-02-25 06:11:03 +0000559{
560 tjhandle handle=0;
DRC9b28def2011-05-21 14:37:15 +0000561 unsigned char *jpegBuf=NULL, *dstBuf=NULL;
DRC6acf52b2011-03-02 01:09:20 +0000562 int jpegSubsamp=-1, jpegWidth=0, jpegHeight=0;
DRCfef98522013-04-28 01:32:52 +0000563 jsize yuvSize;
DRC4f1580c2011-02-25 06:11:03 +0000564
565 gethandle();
566
DRC9b28def2011-05-21 14:37:15 +0000567 if((*env)->GetArrayLength(env, src)<jpegSize)
DRC6acf52b2011-03-02 01:09:20 +0000568 _throw("Source buffer is not large enough");
DRCfc26b652014-03-16 22:56:26 +0000569 bailif0(_fid=(*env)->GetFieldID(env, _cls, "srcSubsamp", "I"));
DRC6acf52b2011-03-02 01:09:20 +0000570 jpegSubsamp=(int)(*env)->GetIntField(env, obj, _fid);
DRCfc26b652014-03-16 22:56:26 +0000571 bailif0(_fid=(*env)->GetFieldID(env, _cls, "srcWidth", "I"));
DRC6acf52b2011-03-02 01:09:20 +0000572 jpegWidth=(int)(*env)->GetIntField(env, obj, _fid);
DRCfc26b652014-03-16 22:56:26 +0000573 bailif0(_fid=(*env)->GetFieldID(env, _cls, "srcHeight", "I"));
DRC6acf52b2011-03-02 01:09:20 +0000574 jpegHeight=(int)(*env)->GetIntField(env, obj, _fid);
DRC6acf52b2011-03-02 01:09:20 +0000575
DRCfef98522013-04-28 01:32:52 +0000576 yuvSize=(jsize)tjBufSizeYUV2(desiredWidth==0? jpegWidth:desiredWidth,
577 pad, desiredHeight==0? jpegHeight:desiredHeight, jpegSubsamp);
578 if(yuvSize==(unsigned long)-1)
579 _throw(tjGetErrorStr());
580 if((*env)->GetArrayLength(env, dst)<yuvSize)
581 _throw("Destination buffer is not large enough");
DRC9b28def2011-05-21 14:37:15 +0000582 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
583 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
DRC4f1580c2011-02-25 06:11:03 +0000584
DRCfef98522013-04-28 01:32:52 +0000585 if(tjDecompressToYUV2(handle, jpegBuf, (unsigned long)jpegSize, dstBuf,
586 desiredWidth, pad, desiredHeight, flags)==-1)
DRC4f1580c2011-02-25 06:11:03 +0000587 {
DRC9b28def2011-05-21 14:37:15 +0000588 (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
589 (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
590 dstBuf=jpegBuf=NULL;
DRC4f1580c2011-02-25 06:11:03 +0000591 _throw(tjGetErrorStr());
592 }
593
594 bailout:
DRC9b28def2011-05-21 14:37:15 +0000595 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
596 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
DRC4f1580c2011-02-25 06:11:03 +0000597 return;
DRC84a1bcc2011-02-23 12:09:56 +0000598}
599
DRCfef98522013-04-28 01:32:52 +0000600JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3BI
601 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
602 jint flags)
603{
604 Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3BIIII(
605 env, obj, src, jpegSize, dst, 0, 4, 0, flags);
606}
607
DRCfc26b652014-03-16 22:56:26 +0000608JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decodeYUV___3BII_3BIIIIIII
609 (JNIEnv *env, jobject obj, jbyteArray src, jint pad, jint subsamp,
610 jbyteArray dst, jint x, jint y, jint width, jint pitch, jint height,
611 jint pf, jint flags)
612{
613 tjhandle handle=0;
614 jsize arraySize=0, actualPitch;
615 unsigned char *srcBuf=NULL, *dstBuf=NULL;
616
617 gethandle();
618
619 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
620 _throw("Invalid argument in decodeYUV()");
621 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
622 _throw("Mismatch between Java and C API");
623
624 arraySize=tjBufSizeYUV2(width, pad, height, subsamp);
625 if((*env)->GetArrayLength(env, src)<arraySize)
626 _throw("Source buffer is not large enough");
627 actualPitch=(pitch==0)? width*tjPixelSize[pf]:pitch;
628 arraySize=(y+height-1)*actualPitch + (x+width)*tjPixelSize[pf];
629 if((*env)->GetArrayLength(env, dst)<arraySize)
630 _throw("Destination buffer is not large enough");
631
632 bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
633 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
634
635 if(tjDecodeYUV(handle, srcBuf, pad, subsamp,
636 &dstBuf[y*actualPitch + x*tjPixelSize[pf]], width, pitch, height, pf,
637 flags)==-1)
638 {
639 (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
640 (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
641 dstBuf=srcBuf=NULL;
642 _throw(tjGetErrorStr());
643 }
644
645 bailout:
646 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
647 if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
648 return;
649}
650
651JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decodeYUV___3BII_3IIIIIIII
652 (JNIEnv *env, jobject obj, jbyteArray src, jint pad, jint subsamp,
653 jintArray dst, jint x, jint y, jint width, jint stride, jint height,
654 jint pf, jint flags)
655{
656 tjhandle handle=0;
657 jsize arraySize=0, actualStride;
658 unsigned char *srcBuf=NULL, *dstBuf=NULL;
659
660 gethandle();
661
662 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
663 _throw("Invalid argument in decodeYUV()");
664 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
665 _throw("Mismatch between Java and C API");
666 if(tjPixelSize[pf]!=sizeof(jint))
667 _throw("Pixel format must be 32-bit when decoding to an integer buffer.");
668
669 arraySize=tjBufSizeYUV2(width, pad, height, subsamp);
670 if((*env)->GetArrayLength(env, src)<arraySize)
671 _throw("Source buffer is not large enough");
672 actualStride=(stride==0)? width:stride;
673 arraySize=(y+height-1)*actualStride + x+width;
674 if((*env)->GetArrayLength(env, dst)<arraySize)
675 _throw("Destination buffer is not large enough");
676
677 bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
678 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
679
680 if(tjDecodeYUV(handle, srcBuf, pad, subsamp,
681 &dstBuf[(y*actualStride + x)*sizeof(int)], width, stride*sizeof(jint),
682 height, pf, flags)==-1)
683 {
684 (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
685 (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
686 dstBuf=srcBuf=NULL;
687 _throw(tjGetErrorStr());
688 }
689
690 bailout:
691 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
692 if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
693 return;
694}
695
DRCe8573012011-03-04 10:13:59 +0000696JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_init
697 (JNIEnv *env, jobject obj)
698{
699 jclass cls;
700 jfieldID fid;
701 tjhandle handle;
702
703 if((handle=tjInitTransform())==NULL) _throw(tjGetErrorStr());
704
705 bailif0(cls=(*env)->GetObjectClass(env, obj));
706 bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J"));
DRC23da0c02011-03-04 15:28:16 +0000707 (*env)->SetLongField(env, obj, fid, (jlong)handle);
DRCe8573012011-03-04 10:13:59 +0000708
709 bailout:
710 return;
711}
712
DRCf5467112011-09-20 05:02:19 +0000713typedef struct _JNICustomFilterParams
714{
715 JNIEnv *env;
716 jobject tobj;
717 jobject cfobj;
718} JNICustomFilterParams;
719
720static int JNICustomFilter(short *coeffs, tjregion arrayRegion,
721 tjregion planeRegion, int componentIndex, int transformIndex,
722 tjtransform *transform)
723{
724 JNICustomFilterParams *params=(JNICustomFilterParams *)transform->data;
725 JNIEnv *env=params->env;
726 jobject tobj=params->tobj, cfobj=params->cfobj;
727 jobject arrayRegionObj, planeRegionObj, bufobj, borobj;
728 jclass cls; jmethodID mid; jfieldID fid;
729
730 bailif0(bufobj=(*env)->NewDirectByteBuffer(env, coeffs,
731 sizeof(short)*arrayRegion.w*arrayRegion.h));
732 bailif0(cls=(*env)->FindClass(env, "java/nio/ByteOrder"));
733 bailif0(mid=(*env)->GetStaticMethodID(env, cls, "nativeOrder",
734 "()Ljava/nio/ByteOrder;"));
735 bailif0(borobj=(*env)->CallStaticObjectMethod(env, cls, mid));
736 bailif0(cls=(*env)->GetObjectClass(env, bufobj));
737 bailif0(mid=(*env)->GetMethodID(env, cls, "order",
738 "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;"));
739 (*env)->CallObjectMethod(env, bufobj, mid, borobj);
740 bailif0(mid=(*env)->GetMethodID(env, cls, "asShortBuffer",
741 "()Ljava/nio/ShortBuffer;"));
742 bailif0(bufobj=(*env)->CallObjectMethod(env, bufobj, mid));
743
744 bailif0(cls=(*env)->FindClass(env, "java/awt/Rectangle"));
745 bailif0(arrayRegionObj=(*env)->AllocObject(env, cls));
746 bailif0(fid=(*env)->GetFieldID(env, cls, "x", "I"));
747 (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.x);
748 bailif0(fid=(*env)->GetFieldID(env, cls, "y", "I"));
749 (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.y);
750 bailif0(fid=(*env)->GetFieldID(env, cls, "width", "I"));
751 (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.w);
752 bailif0(fid=(*env)->GetFieldID(env, cls, "height", "I"));
753 (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.h);
754
755 bailif0(planeRegionObj=(*env)->AllocObject(env, cls));
756 bailif0(fid=(*env)->GetFieldID(env, cls, "x", "I"));
757 (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.x);
758 bailif0(fid=(*env)->GetFieldID(env, cls, "y", "I"));
759 (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.y);
760 bailif0(fid=(*env)->GetFieldID(env, cls, "width", "I"));
761 (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.w);
762 bailif0(fid=(*env)->GetFieldID(env, cls, "height", "I"));
763 (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.h);
764
765 bailif0(cls=(*env)->GetObjectClass(env, cfobj));
766 bailif0(mid=(*env)->GetMethodID(env, cls, "customFilter",
767 "(Ljava/nio/ShortBuffer;Ljava/awt/Rectangle;Ljava/awt/Rectangle;IILorg/libjpegturbo/turbojpeg/TJTransform;)V"));
768 (*env)->CallVoidMethod(env, cfobj, mid, bufobj, arrayRegionObj,
769 planeRegionObj, componentIndex, transformIndex, tobj);
770
771 return 0;
772
773 bailout:
774 return -1;
775}
776
DRCe8573012011-03-04 10:13:59 +0000777JNIEXPORT jintArray JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_transform
DRC9b28def2011-05-21 14:37:15 +0000778 (JNIEnv *env, jobject obj, jbyteArray jsrcBuf, jint jpegSize,
DRCe8573012011-03-04 10:13:59 +0000779 jobjectArray dstobjs, jobjectArray tobjs, jint flags)
780{
781 tjhandle handle=0; int i;
DRC9b28def2011-05-21 14:37:15 +0000782 unsigned char *jpegBuf=NULL, **dstBufs=NULL; jsize n=0;
783 unsigned long *dstSizes=NULL; tjtransform *t=NULL;
784 jbyteArray *jdstBufs=NULL;
DRC9b49f0e2011-07-12 03:17:23 +0000785 int jpegWidth=0, jpegHeight=0, jpegSubsamp;
DRC9b28def2011-05-21 14:37:15 +0000786 jintArray jdstSizes=0; jint *dstSizesi=NULL;
DRCf5467112011-09-20 05:02:19 +0000787 JNICustomFilterParams *params=NULL;
DRCe8573012011-03-04 10:13:59 +0000788
789 gethandle();
790
DRC9b28def2011-05-21 14:37:15 +0000791 if((*env)->GetArrayLength(env, jsrcBuf)<jpegSize)
DRCe8573012011-03-04 10:13:59 +0000792 _throw("Source buffer is not large enough");
DRCfc26b652014-03-16 22:56:26 +0000793 bailif0(_fid=(*env)->GetFieldID(env, _cls, "srcWidth", "I"));
DRCe8573012011-03-04 10:13:59 +0000794 jpegWidth=(int)(*env)->GetIntField(env, obj, _fid);
DRCfc26b652014-03-16 22:56:26 +0000795 bailif0(_fid=(*env)->GetFieldID(env, _cls, "srcHeight", "I"));
DRCe8573012011-03-04 10:13:59 +0000796 jpegHeight=(int)(*env)->GetIntField(env, obj, _fid);
DRCfc26b652014-03-16 22:56:26 +0000797 bailif0(_fid=(*env)->GetFieldID(env, _cls, "srcSubsamp", "I"));
DRC9b49f0e2011-07-12 03:17:23 +0000798 jpegSubsamp=(int)(*env)->GetIntField(env, obj, _fid);
DRCe8573012011-03-04 10:13:59 +0000799
800 n=(*env)->GetArrayLength(env, dstobjs);
801 if(n!=(*env)->GetArrayLength(env, tobjs))
802 _throw("Mismatch between size of transforms array and destination buffers array");
803
DRC9b28def2011-05-21 14:37:15 +0000804 if((dstBufs=(unsigned char **)malloc(sizeof(unsigned char *)*n))==NULL)
DRCe8573012011-03-04 10:13:59 +0000805 _throw("Memory allocation failure");
DRC9b28def2011-05-21 14:37:15 +0000806 if((jdstBufs=(jbyteArray *)malloc(sizeof(jbyteArray)*n))==NULL)
DRCe8573012011-03-04 10:13:59 +0000807 _throw("Memory allocation failure");
DRC9b28def2011-05-21 14:37:15 +0000808 if((dstSizes=(unsigned long *)malloc(sizeof(unsigned long)*n))==NULL)
DRCe8573012011-03-04 10:13:59 +0000809 _throw("Memory allocation failure");
810 if((t=(tjtransform *)malloc(sizeof(tjtransform)*n))==NULL)
811 _throw("Memory allocation failure");
DRCf5467112011-09-20 05:02:19 +0000812 if((params=(JNICustomFilterParams *)malloc(sizeof(JNICustomFilterParams)*n))
813 ==NULL)
814 _throw("Memory allocation failure");
DRCe8573012011-03-04 10:13:59 +0000815 for(i=0; i<n; i++)
816 {
DRC9b28def2011-05-21 14:37:15 +0000817 dstBufs[i]=NULL; jdstBufs[i]=NULL; dstSizes[i]=0;
DRCe8573012011-03-04 10:13:59 +0000818 memset(&t[i], 0, sizeof(tjtransform));
DRCf5467112011-09-20 05:02:19 +0000819 memset(&params[i], 0, sizeof(JNICustomFilterParams));
DRCe8573012011-03-04 10:13:59 +0000820 }
821
822 for(i=0; i<n; i++)
823 {
DRCf5467112011-09-20 05:02:19 +0000824 jobject tobj, cfobj;
DRCe8573012011-03-04 10:13:59 +0000825
826 bailif0(tobj=(*env)->GetObjectArrayElement(env, tobjs, i));
827 bailif0(_cls=(*env)->GetObjectClass(env, tobj));
828 bailif0(_fid=(*env)->GetFieldID(env, _cls, "op", "I"));
829 t[i].op=(*env)->GetIntField(env, tobj, _fid);
830 bailif0(_fid=(*env)->GetFieldID(env, _cls, "options", "I"));
831 t[i].options=(*env)->GetIntField(env, tobj, _fid);
832 bailif0(_fid=(*env)->GetFieldID(env, _cls, "x", "I"));
833 t[i].r.x=(*env)->GetIntField(env, tobj, _fid);
834 bailif0(_fid=(*env)->GetFieldID(env, _cls, "y", "I"));
835 t[i].r.y=(*env)->GetIntField(env, tobj, _fid);
836 bailif0(_fid=(*env)->GetFieldID(env, _cls, "width", "I"));
837 t[i].r.w=(*env)->GetIntField(env, tobj, _fid);
838 bailif0(_fid=(*env)->GetFieldID(env, _cls, "height", "I"));
839 t[i].r.h=(*env)->GetIntField(env, tobj, _fid);
DRCf5467112011-09-20 05:02:19 +0000840
DRCf5467112011-09-20 05:02:19 +0000841 bailif0(_fid=(*env)->GetFieldID(env, _cls, "cf",
842 "Lorg/libjpegturbo/turbojpeg/TJCustomFilter;"));
DRC06420c42011-09-26 18:46:09 +0000843 cfobj=(*env)->GetObjectField(env, tobj, _fid);
844 if(cfobj)
845 {
846 params[i].env=env;
847 params[i].tobj=tobj;
848 params[i].cfobj=cfobj;
849 t[i].customFilter=JNICustomFilter;
850 t[i].data=(void *)&params[i];
851 }
DRCe8573012011-03-04 10:13:59 +0000852 }
853
DRC9b28def2011-05-21 14:37:15 +0000854 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, jsrcBuf, 0));
DRCe8573012011-03-04 10:13:59 +0000855 for(i=0; i<n; i++)
856 {
857 int w=jpegWidth, h=jpegHeight;
858 if(t[i].r.w!=0) w=t[i].r.w;
859 if(t[i].r.h!=0) h=t[i].r.h;
DRC9b28def2011-05-21 14:37:15 +0000860 bailif0(jdstBufs[i]=(*env)->GetObjectArrayElement(env, dstobjs, i));
DRCefe28ce2012-01-17 11:48:38 +0000861 if((unsigned long)(*env)->GetArrayLength(env, jdstBufs[i])
862 <tjBufSize(w, h, jpegSubsamp))
DRCe8573012011-03-04 10:13:59 +0000863 _throw("Destination buffer is not large enough");
DRC9b28def2011-05-21 14:37:15 +0000864 bailif0(dstBufs[i]=(*env)->GetPrimitiveArrayCritical(env, jdstBufs[i], 0));
DRCe8573012011-03-04 10:13:59 +0000865 }
866
DRC9b28def2011-05-21 14:37:15 +0000867 if(tjTransform(handle, jpegBuf, jpegSize, n, dstBufs, dstSizes, t,
DRC4db92ad2011-05-25 04:52:25 +0000868 flags|TJFLAG_NOREALLOC)==-1)
DRCe8573012011-03-04 10:13:59 +0000869 {
DRC9b28def2011-05-21 14:37:15 +0000870 (*env)->ReleasePrimitiveArrayCritical(env, jsrcBuf, jpegBuf, 0);
871 jpegBuf=NULL;
DRCe8573012011-03-04 10:13:59 +0000872 for(i=0; i<n; i++)
873 {
DRC9b28def2011-05-21 14:37:15 +0000874 (*env)->ReleasePrimitiveArrayCritical(env, jdstBufs[i], dstBufs[i], 0);
875 dstBufs[i]=NULL;
DRCe8573012011-03-04 10:13:59 +0000876 }
877 _throw(tjGetErrorStr());
878 }
879
DRC9b28def2011-05-21 14:37:15 +0000880 jdstSizes=(*env)->NewIntArray(env, n);
881 bailif0(dstSizesi=(*env)->GetIntArrayElements(env, jdstSizes, 0));
882 for(i=0; i<n; i++) dstSizesi[i]=(int)dstSizes[i];
DRCe8573012011-03-04 10:13:59 +0000883
884 bailout:
DRC9b28def2011-05-21 14:37:15 +0000885 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, jsrcBuf, jpegBuf, 0);
886 if(dstBufs)
DRCe8573012011-03-04 10:13:59 +0000887 {
888 for(i=0; i<n; i++)
889 {
DRC9b28def2011-05-21 14:37:15 +0000890 if(dstBufs[i] && jdstBufs && jdstBufs[i])
891 (*env)->ReleasePrimitiveArrayCritical(env, jdstBufs[i], dstBufs[i], 0);
DRCe8573012011-03-04 10:13:59 +0000892 }
DRC9b28def2011-05-21 14:37:15 +0000893 free(dstBufs);
DRCe8573012011-03-04 10:13:59 +0000894 }
DRC9b28def2011-05-21 14:37:15 +0000895 if(jdstBufs) free(jdstBufs);
896 if(dstSizes) free(dstSizes);
897 if(dstSizesi) (*env)->ReleaseIntArrayElements(env, jdstSizes, dstSizesi, 0);
DRCe8573012011-03-04 10:13:59 +0000898 if(t) free(t);
DRC9b28def2011-05-21 14:37:15 +0000899 return jdstSizes;
DRCe8573012011-03-04 10:13:59 +0000900}
901
DRCc5a41992011-02-08 06:54:36 +0000902JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_destroy
DRCf8e00552011-02-04 11:06:36 +0000903 (JNIEnv *env, jobject obj)
904{
DRCc5a41992011-02-08 06:54:36 +0000905 Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy(env, obj);
DRCf8e00552011-02-04 11:06:36 +0000906}