blob: efe55902058eed2a3e1baca1f3da63742e0e797e [file] [log] [blame]
DRCf8e00552011-02-04 11:06:36 +00001/*
DRC1d29c5f2013-04-27 20:54:44 +00002 * Copyright (C)2011-2013 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
DRCfef98522013-04-28 01:32:52 +0000253JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIII_3BIII
DRC4f1580c2011-02-25 06:11:03 +0000254 (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch,
DRCfef98522013-04-28 01:32:52 +0000255 jint height, jint pf, jbyteArray dst, jint pad, jint subsamp, jint flags)
DRC4f1580c2011-02-25 06:11:03 +0000256{
DRC9b28def2011-05-21 14:37:15 +0000257 tjhandle handle=0;
DRCfef98522013-04-28 01:32:52 +0000258 jsize arraySize=0, yuvSize;
DRC9b28def2011-05-21 14:37:15 +0000259 unsigned char *srcBuf=NULL, *dstBuf=NULL;
DRC4f1580c2011-02-25 06:11:03 +0000260
261 gethandle();
262
DRC92549de2011-03-15 20:52:02 +0000263 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1
DRC6acf52b2011-03-02 01:09:20 +0000264 || pitch<0)
DRC4f1580c2011-02-25 06:11:03 +0000265 _throw("Invalid argument in encodeYUV()");
DRC9b28def2011-05-21 14:37:15 +0000266 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
267 _throw("Mismatch between Java and C API");
DRC4f1580c2011-02-25 06:11:03 +0000268
DRC9b28def2011-05-21 14:37:15 +0000269 arraySize=(pitch==0)? width*tjPixelSize[pf]*height:pitch*height;
270 if((*env)->GetArrayLength(env, src)<arraySize)
DRC6acf52b2011-03-02 01:09:20 +0000271 _throw("Source buffer is not large enough");
DRCfef98522013-04-28 01:32:52 +0000272 yuvSize=(jsize)tjBufSizeYUV2(width, pad, height, subsamp);
273 if(yuvSize==(unsigned long)-1)
274 _throw(tjGetErrorStr());
275 if((*env)->GetArrayLength(env, dst)<yuvSize)
DRC6acf52b2011-03-02 01:09:20 +0000276 _throw("Destination buffer is not large enough");
277
DRC9b28def2011-05-21 14:37:15 +0000278 bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
279 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
DRC4f1580c2011-02-25 06:11:03 +0000280
DRCfef98522013-04-28 01:32:52 +0000281 if(tjEncodeYUV3(handle, srcBuf, width, pitch, height, pf, dstBuf, pad,
282 subsamp, flags)==-1)
DRC4f1580c2011-02-25 06:11:03 +0000283 {
DRC9b28def2011-05-21 14:37:15 +0000284 (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
285 (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
286 dstBuf=srcBuf=NULL;
DRC4f1580c2011-02-25 06:11:03 +0000287 _throw(tjGetErrorStr());
288 }
289
290 bailout:
DRC9b28def2011-05-21 14:37:15 +0000291 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
292 if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
DRC4f1580c2011-02-25 06:11:03 +0000293 return;
294}
295
DRCfef98522013-04-28 01:32:52 +0000296JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIII_3BII
297 (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch,
DRC6acf52b2011-03-02 01:09:20 +0000298 jint height, jint pf, jbyteArray dst, jint subsamp, jint flags)
DRC4f1580c2011-02-25 06:11:03 +0000299{
DRCfef98522013-04-28 01:32:52 +0000300 Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIII_3BIII(
301 env, obj, src, width, pitch, height, pf, dst, 4, subsamp, flags);
302}
303
304JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIII_3BIII
305 (JNIEnv *env, jobject obj, jintArray src, jint width, jint stride,
306 jint height, jint pf, jbyteArray dst, jint pad, jint subsamp, jint flags)
307{
DRC4f1580c2011-02-25 06:11:03 +0000308 tjhandle handle=0;
DRCfef98522013-04-28 01:32:52 +0000309 jsize arraySize=0, yuvSize;
DRC9b28def2011-05-21 14:37:15 +0000310 unsigned char *srcBuf=NULL, *dstBuf=NULL;
DRC4f1580c2011-02-25 06:11:03 +0000311
312 gethandle();
313
DRC92549de2011-03-15 20:52:02 +0000314 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1
DRC1d29c5f2013-04-27 20:54:44 +0000315 || stride<0)
316 _throw("Invalid argument in encodeYUV()");
DRC9b28def2011-05-21 14:37:15 +0000317 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
318 _throw("Mismatch between Java and C API");
319 if(tjPixelSize[pf]!=sizeof(jint))
DRC4f1580c2011-02-25 06:11:03 +0000320 _throw("Pixel format must be 32-bit when encoding from an integer buffer.");
DRC4f1580c2011-02-25 06:11:03 +0000321
DRC1d29c5f2013-04-27 20:54:44 +0000322 arraySize=(stride==0)? width*height:stride*height;
DRC9b28def2011-05-21 14:37:15 +0000323 if((*env)->GetArrayLength(env, src)<arraySize)
DRC6acf52b2011-03-02 01:09:20 +0000324 _throw("Source buffer is not large enough");
DRCfef98522013-04-28 01:32:52 +0000325 yuvSize=(jsize)tjBufSizeYUV2(width, pad, height, subsamp);
326 if(yuvSize==(unsigned long)-1)
327 _throw(tjGetErrorStr());
328 if((*env)->GetArrayLength(env, dst)<yuvSize)
DRC6acf52b2011-03-02 01:09:20 +0000329 _throw("Destination buffer is not large enough");
330
DRC9b28def2011-05-21 14:37:15 +0000331 bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
332 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
DRC4f1580c2011-02-25 06:11:03 +0000333
DRCfef98522013-04-28 01:32:52 +0000334 if(tjEncodeYUV3(handle, srcBuf, width, stride*sizeof(jint), height, pf,
335 dstBuf, pad, subsamp, flags)==-1)
DRC4f1580c2011-02-25 06:11:03 +0000336 {
DRC9b28def2011-05-21 14:37:15 +0000337 (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
338 (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
339 dstBuf=srcBuf=NULL;
DRC4f1580c2011-02-25 06:11:03 +0000340 _throw(tjGetErrorStr());
341 }
342
343 bailout:
DRC9b28def2011-05-21 14:37:15 +0000344 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
345 if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
DRC4f1580c2011-02-25 06:11:03 +0000346 return;
347}
348
DRCfef98522013-04-28 01:32:52 +0000349JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIII_3BII
350 (JNIEnv *env, jobject obj, jintArray src, jint width, jint pitch,
351 jint height, jint pf, jbyteArray dst, jint subsamp, jint flags)
352{
353 Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIII_3BIII(
354 env, obj, src, width, pitch, height, pf, dst, 4, subsamp, flags);
355}
356
DRCc5a41992011-02-08 06:54:36 +0000357JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy
DRCf8e00552011-02-04 11:06:36 +0000358 (JNIEnv *env, jobject obj)
359{
360 tjhandle handle=0;
361
362 gethandle();
363
364 if(tjDestroy(handle)==-1) _throw(tjGetErrorStr());
DRC3bad53f2011-02-23 02:20:49 +0000365 (*env)->SetLongField(env, obj, _fid, 0);
DRCf8e00552011-02-04 11:06:36 +0000366
367 bailout:
368 return;
369}
370
DRCc5a41992011-02-08 06:54:36 +0000371JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_init
DRCf8e00552011-02-04 11:06:36 +0000372 (JNIEnv *env, jobject obj)
373{
374 jclass cls;
375 jfieldID fid;
376 tjhandle handle;
377
DRC1a3dbe62011-02-28 10:51:55 +0000378 if((handle=tjInitDecompress())==NULL) _throw(tjGetErrorStr());
DRCf8e00552011-02-04 11:06:36 +0000379
380 bailif0(cls=(*env)->GetObjectClass(env, obj));
381 bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J"));
DRC23da0c02011-03-04 15:28:16 +0000382 (*env)->SetLongField(env, obj, fid, (jlong)handle);
DRCf8e00552011-02-04 11:06:36 +0000383
384 bailout:
385 return;
386}
387
DRC109a5782011-03-01 09:53:07 +0000388JNIEXPORT jobjectArray JNICALL Java_org_libjpegturbo_turbojpeg_TJ_getScalingFactors
389 (JNIEnv *env, jclass cls)
DRC36336fc2011-02-22 10:27:31 +0000390{
DRC109a5782011-03-01 09:53:07 +0000391 jclass sfcls=NULL; jfieldID fid=0;
392 tjscalingfactor *sf=NULL; int n=0, i;
393 jobject sfobj=NULL;
394 jobjectArray sfjava=NULL;
395
396 if((sf=tjGetScalingFactors(&n))==NULL || n==0)
DRC36336fc2011-02-22 10:27:31 +0000397 _throw(tjGetErrorStr());
398
DRCb2f94152011-04-02 02:09:03 +0000399 bailif0(sfcls=(*env)->FindClass(env, "org/libjpegturbo/turbojpeg/TJScalingFactor"));
DRC109a5782011-03-01 09:53:07 +0000400 bailif0(sfjava=(jobjectArray)(*env)->NewObjectArray(env, n, sfcls, 0));
DRC36336fc2011-02-22 10:27:31 +0000401
DRC109a5782011-03-01 09:53:07 +0000402 for(i=0; i<n; i++)
403 {
404 bailif0(sfobj=(*env)->AllocObject(env, sfcls));
405 bailif0(fid=(*env)->GetFieldID(env, sfcls, "num", "I"));
406 (*env)->SetIntField(env, sfobj, fid, sf[i].num);
407 bailif0(fid=(*env)->GetFieldID(env, sfcls, "denom", "I"));
408 (*env)->SetIntField(env, sfobj, fid, sf[i].denom);
409 (*env)->SetObjectArrayElement(env, sfjava, i, sfobj);
410 }
DRC36336fc2011-02-22 10:27:31 +0000411
412 bailout:
DRC109a5782011-03-01 09:53:07 +0000413 return sfjava;
DRC36336fc2011-02-22 10:27:31 +0000414}
415
DRC3bad53f2011-02-23 02:20:49 +0000416JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressHeader
DRC9b28def2011-05-21 14:37:15 +0000417 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize)
DRCf8e00552011-02-04 11:06:36 +0000418{
DRCf8e00552011-02-04 11:06:36 +0000419 tjhandle handle=0;
DRC9b28def2011-05-21 14:37:15 +0000420 unsigned char *jpegBuf=NULL;
DRC38cb1ec2013-08-23 04:45:43 +0000421 int width=0, height=0, jpegSubsamp=-1, jpegColorspace=-1;
DRCf8e00552011-02-04 11:06:36 +0000422
423 gethandle();
424
DRC9b28def2011-05-21 14:37:15 +0000425 if((*env)->GetArrayLength(env, src)<jpegSize)
DRC6acf52b2011-03-02 01:09:20 +0000426 _throw("Source buffer is not large enough");
427
DRC9b28def2011-05-21 14:37:15 +0000428 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
DRCf8e00552011-02-04 11:06:36 +0000429
DRC38cb1ec2013-08-23 04:45:43 +0000430 if(tjDecompressHeader3(handle, jpegBuf, (unsigned long)jpegSize,
431 &width, &height, &jpegSubsamp, &jpegColorspace)==-1)
DRCf8e00552011-02-04 11:06:36 +0000432 {
DRC9b28def2011-05-21 14:37:15 +0000433 (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
DRCf8e00552011-02-04 11:06:36 +0000434 _throw(tjGetErrorStr());
435 }
DRC9b28def2011-05-21 14:37:15 +0000436 (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0); jpegBuf=NULL;
DRCf8e00552011-02-04 11:06:36 +0000437
DRC3bad53f2011-02-23 02:20:49 +0000438 bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
DRC9b28def2011-05-21 14:37:15 +0000439 (*env)->SetIntField(env, obj, _fid, jpegSubsamp);
DRC38cb1ec2013-08-23 04:45:43 +0000440 bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegColorspace", "I"));
441 (*env)->SetIntField(env, obj, _fid, jpegColorspace);
DRC3bad53f2011-02-23 02:20:49 +0000442 bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
443 (*env)->SetIntField(env, obj, _fid, width);
444 bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
445 (*env)->SetIntField(env, obj, _fid, height);
DRCf8e00552011-02-04 11:06:36 +0000446
447 bailout:
DRC3bad53f2011-02-23 02:20:49 +0000448 return;
DRCf8e00552011-02-04 11:06:36 +0000449}
450
DRCf659f432012-06-06 08:41:06 +0000451JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIIIII
DRC9b28def2011-05-21 14:37:15 +0000452 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
DRCf659f432012-06-06 08:41:06 +0000453 jint x, jint y, jint width, jint pitch, jint height, jint pf, jint flags)
DRCf8e00552011-02-04 11:06:36 +0000454{
DRC9b28def2011-05-21 14:37:15 +0000455 tjhandle handle=0;
DRCf659f432012-06-06 08:41:06 +0000456 jsize arraySize=0, actualPitch;
DRC9b28def2011-05-21 14:37:15 +0000457 unsigned char *jpegBuf=NULL, *dstBuf=NULL;
DRCf8e00552011-02-04 11:06:36 +0000458
459 gethandle();
460
DRC92549de2011-03-15 20:52:02 +0000461 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
DRC4f1580c2011-02-25 06:11:03 +0000462 _throw("Invalid argument in decompress()");
DRC9b28def2011-05-21 14:37:15 +0000463 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
464 _throw("Mismatch between Java and C API");
DRC4f1580c2011-02-25 06:11:03 +0000465
DRC9b28def2011-05-21 14:37:15 +0000466 if((*env)->GetArrayLength(env, src)<jpegSize)
DRC6acf52b2011-03-02 01:09:20 +0000467 _throw("Source buffer is not large enough");
DRCf659f432012-06-06 08:41:06 +0000468 actualPitch=(pitch==0)? width*tjPixelSize[pf]:pitch;
DRCdc31f0b2012-06-07 09:38:57 +0000469 arraySize=(y+height-1)*actualPitch + (x+width)*tjPixelSize[pf];
DRC9b28def2011-05-21 14:37:15 +0000470 if((*env)->GetArrayLength(env, dst)<arraySize)
DRC6acf52b2011-03-02 01:09:20 +0000471 _throw("Destination buffer is not large enough");
472
DRC9b28def2011-05-21 14:37:15 +0000473 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
474 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
DRCf8e00552011-02-04 11:06:36 +0000475
DRCf659f432012-06-06 08:41:06 +0000476 if(tjDecompress2(handle, jpegBuf, (unsigned long)jpegSize,
477 &dstBuf[y*actualPitch + x*tjPixelSize[pf]], width, pitch, height, pf,
478 flags)==-1)
479 {
480 (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
481 (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
482 dstBuf=jpegBuf=NULL;
483 _throw(tjGetErrorStr());
484 }
485
486 bailout:
487 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
488 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
489 return;
490}
491
492JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIII
493 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
494 jint width, jint pitch, jint height, jint pf, jint flags)
495{
496 Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIIIII
497 (env, obj, src, jpegSize, dst, 0, 0, width, pitch, height, pf, flags);
498}
499
500JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIIIII
501 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jintArray dst,
502 jint x, jint y, jint width, jint stride, jint height, jint pf, jint flags)
503{
504 tjhandle handle=0;
505 jsize arraySize=0, actualStride;
506 unsigned char *jpegBuf=NULL, *dstBuf=NULL;
507
508 gethandle();
509
510 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
511 _throw("Invalid argument in decompress()");
512 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
513 _throw("Mismatch between Java and C API");
514 if(tjPixelSize[pf]!=sizeof(jint))
515 _throw("Pixel format must be 32-bit when decompressing to an integer buffer.");
516
517 if((*env)->GetArrayLength(env, src)<jpegSize)
518 _throw("Source buffer is not large enough");
519 actualStride=(stride==0)? width:stride;
DRCdc31f0b2012-06-07 09:38:57 +0000520 arraySize=(y+height-1)*actualStride + x+width;
DRCf659f432012-06-06 08:41:06 +0000521 if((*env)->GetArrayLength(env, dst)<arraySize)
522 _throw("Destination buffer is not large enough");
523
524 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
525 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
526
527 if(tjDecompress2(handle, jpegBuf, (unsigned long)jpegSize,
528 &dstBuf[(y*actualStride + x)*sizeof(int)], width, stride*sizeof(jint),
529 height, pf, flags)==-1)
DRCf8e00552011-02-04 11:06:36 +0000530 {
DRC9b28def2011-05-21 14:37:15 +0000531 (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
532 (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
533 dstBuf=jpegBuf=NULL;
DRCf8e00552011-02-04 11:06:36 +0000534 _throw(tjGetErrorStr());
535 }
536
537 bailout:
DRC9b28def2011-05-21 14:37:15 +0000538 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
539 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
DRCf8e00552011-02-04 11:06:36 +0000540 return;
541}
542
DRC4f1580c2011-02-25 06:11:03 +0000543JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIII
DRC9b28def2011-05-21 14:37:15 +0000544 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jintArray dst,
DRCf659f432012-06-06 08:41:06 +0000545 jint width, jint stride, jint height, jint pf, jint flags)
DRC84a1bcc2011-02-23 12:09:56 +0000546{
DRCf659f432012-06-06 08:41:06 +0000547 Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIIIII
548 (env, obj, src, jpegSize, dst, 0, 0, width, stride, height, pf, flags);
549
DRC4f1580c2011-02-25 06:11:03 +0000550}
DRC84a1bcc2011-02-23 12:09:56 +0000551
DRCfef98522013-04-28 01:32:52 +0000552JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3BIIII
DRC9b28def2011-05-21 14:37:15 +0000553 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
DRCfef98522013-04-28 01:32:52 +0000554 jint desiredWidth, jint pad, jint desiredHeight, jint flags)
DRC4f1580c2011-02-25 06:11:03 +0000555{
556 tjhandle handle=0;
DRC9b28def2011-05-21 14:37:15 +0000557 unsigned char *jpegBuf=NULL, *dstBuf=NULL;
DRC6acf52b2011-03-02 01:09:20 +0000558 int jpegSubsamp=-1, jpegWidth=0, jpegHeight=0;
DRCfef98522013-04-28 01:32:52 +0000559 jsize yuvSize;
DRC4f1580c2011-02-25 06:11:03 +0000560
561 gethandle();
562
DRC9b28def2011-05-21 14:37:15 +0000563 if((*env)->GetArrayLength(env, src)<jpegSize)
DRC6acf52b2011-03-02 01:09:20 +0000564 _throw("Source buffer is not large enough");
565 bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
566 jpegSubsamp=(int)(*env)->GetIntField(env, obj, _fid);
567 bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
568 jpegWidth=(int)(*env)->GetIntField(env, obj, _fid);
569 bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
570 jpegHeight=(int)(*env)->GetIntField(env, obj, _fid);
DRC6acf52b2011-03-02 01:09:20 +0000571
DRCfef98522013-04-28 01:32:52 +0000572 yuvSize=(jsize)tjBufSizeYUV2(desiredWidth==0? jpegWidth:desiredWidth,
573 pad, desiredHeight==0? jpegHeight:desiredHeight, jpegSubsamp);
574 if(yuvSize==(unsigned long)-1)
575 _throw(tjGetErrorStr());
576 if((*env)->GetArrayLength(env, dst)<yuvSize)
577 _throw("Destination buffer is not large enough");
DRC9b28def2011-05-21 14:37:15 +0000578 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
579 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
DRC4f1580c2011-02-25 06:11:03 +0000580
DRCfef98522013-04-28 01:32:52 +0000581 if(tjDecompressToYUV2(handle, jpegBuf, (unsigned long)jpegSize, dstBuf,
582 desiredWidth, pad, desiredHeight, flags)==-1)
DRC4f1580c2011-02-25 06:11:03 +0000583 {
DRC9b28def2011-05-21 14:37:15 +0000584 (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
585 (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
586 dstBuf=jpegBuf=NULL;
DRC4f1580c2011-02-25 06:11:03 +0000587 _throw(tjGetErrorStr());
588 }
589
590 bailout:
DRC9b28def2011-05-21 14:37:15 +0000591 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
592 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
DRC4f1580c2011-02-25 06:11:03 +0000593 return;
DRC84a1bcc2011-02-23 12:09:56 +0000594}
595
DRCfef98522013-04-28 01:32:52 +0000596JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3BI
597 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
598 jint flags)
599{
600 Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3BIIII(
601 env, obj, src, jpegSize, dst, 0, 4, 0, flags);
602}
603
DRCe8573012011-03-04 10:13:59 +0000604JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_init
605 (JNIEnv *env, jobject obj)
606{
607 jclass cls;
608 jfieldID fid;
609 tjhandle handle;
610
611 if((handle=tjInitTransform())==NULL) _throw(tjGetErrorStr());
612
613 bailif0(cls=(*env)->GetObjectClass(env, obj));
614 bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J"));
DRC23da0c02011-03-04 15:28:16 +0000615 (*env)->SetLongField(env, obj, fid, (jlong)handle);
DRCe8573012011-03-04 10:13:59 +0000616
617 bailout:
618 return;
619}
620
DRCf5467112011-09-20 05:02:19 +0000621typedef struct _JNICustomFilterParams
622{
623 JNIEnv *env;
624 jobject tobj;
625 jobject cfobj;
626} JNICustomFilterParams;
627
628static int JNICustomFilter(short *coeffs, tjregion arrayRegion,
629 tjregion planeRegion, int componentIndex, int transformIndex,
630 tjtransform *transform)
631{
632 JNICustomFilterParams *params=(JNICustomFilterParams *)transform->data;
633 JNIEnv *env=params->env;
634 jobject tobj=params->tobj, cfobj=params->cfobj;
635 jobject arrayRegionObj, planeRegionObj, bufobj, borobj;
636 jclass cls; jmethodID mid; jfieldID fid;
637
638 bailif0(bufobj=(*env)->NewDirectByteBuffer(env, coeffs,
639 sizeof(short)*arrayRegion.w*arrayRegion.h));
640 bailif0(cls=(*env)->FindClass(env, "java/nio/ByteOrder"));
641 bailif0(mid=(*env)->GetStaticMethodID(env, cls, "nativeOrder",
642 "()Ljava/nio/ByteOrder;"));
643 bailif0(borobj=(*env)->CallStaticObjectMethod(env, cls, mid));
644 bailif0(cls=(*env)->GetObjectClass(env, bufobj));
645 bailif0(mid=(*env)->GetMethodID(env, cls, "order",
646 "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;"));
647 (*env)->CallObjectMethod(env, bufobj, mid, borobj);
648 bailif0(mid=(*env)->GetMethodID(env, cls, "asShortBuffer",
649 "()Ljava/nio/ShortBuffer;"));
650 bailif0(bufobj=(*env)->CallObjectMethod(env, bufobj, mid));
651
652 bailif0(cls=(*env)->FindClass(env, "java/awt/Rectangle"));
653 bailif0(arrayRegionObj=(*env)->AllocObject(env, cls));
654 bailif0(fid=(*env)->GetFieldID(env, cls, "x", "I"));
655 (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.x);
656 bailif0(fid=(*env)->GetFieldID(env, cls, "y", "I"));
657 (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.y);
658 bailif0(fid=(*env)->GetFieldID(env, cls, "width", "I"));
659 (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.w);
660 bailif0(fid=(*env)->GetFieldID(env, cls, "height", "I"));
661 (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.h);
662
663 bailif0(planeRegionObj=(*env)->AllocObject(env, cls));
664 bailif0(fid=(*env)->GetFieldID(env, cls, "x", "I"));
665 (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.x);
666 bailif0(fid=(*env)->GetFieldID(env, cls, "y", "I"));
667 (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.y);
668 bailif0(fid=(*env)->GetFieldID(env, cls, "width", "I"));
669 (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.w);
670 bailif0(fid=(*env)->GetFieldID(env, cls, "height", "I"));
671 (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.h);
672
673 bailif0(cls=(*env)->GetObjectClass(env, cfobj));
674 bailif0(mid=(*env)->GetMethodID(env, cls, "customFilter",
675 "(Ljava/nio/ShortBuffer;Ljava/awt/Rectangle;Ljava/awt/Rectangle;IILorg/libjpegturbo/turbojpeg/TJTransform;)V"));
676 (*env)->CallVoidMethod(env, cfobj, mid, bufobj, arrayRegionObj,
677 planeRegionObj, componentIndex, transformIndex, tobj);
678
679 return 0;
680
681 bailout:
682 return -1;
683}
684
DRCe8573012011-03-04 10:13:59 +0000685JNIEXPORT jintArray JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_transform
DRC9b28def2011-05-21 14:37:15 +0000686 (JNIEnv *env, jobject obj, jbyteArray jsrcBuf, jint jpegSize,
DRCe8573012011-03-04 10:13:59 +0000687 jobjectArray dstobjs, jobjectArray tobjs, jint flags)
688{
689 tjhandle handle=0; int i;
DRC9b28def2011-05-21 14:37:15 +0000690 unsigned char *jpegBuf=NULL, **dstBufs=NULL; jsize n=0;
691 unsigned long *dstSizes=NULL; tjtransform *t=NULL;
692 jbyteArray *jdstBufs=NULL;
DRC9b49f0e2011-07-12 03:17:23 +0000693 int jpegWidth=0, jpegHeight=0, jpegSubsamp;
DRC9b28def2011-05-21 14:37:15 +0000694 jintArray jdstSizes=0; jint *dstSizesi=NULL;
DRCf5467112011-09-20 05:02:19 +0000695 JNICustomFilterParams *params=NULL;
DRCe8573012011-03-04 10:13:59 +0000696
697 gethandle();
698
DRC9b28def2011-05-21 14:37:15 +0000699 if((*env)->GetArrayLength(env, jsrcBuf)<jpegSize)
DRCe8573012011-03-04 10:13:59 +0000700 _throw("Source buffer is not large enough");
701 bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
702 jpegWidth=(int)(*env)->GetIntField(env, obj, _fid);
703 bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
704 jpegHeight=(int)(*env)->GetIntField(env, obj, _fid);
DRC9b49f0e2011-07-12 03:17:23 +0000705 bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
706 jpegSubsamp=(int)(*env)->GetIntField(env, obj, _fid);
DRCe8573012011-03-04 10:13:59 +0000707
708 n=(*env)->GetArrayLength(env, dstobjs);
709 if(n!=(*env)->GetArrayLength(env, tobjs))
710 _throw("Mismatch between size of transforms array and destination buffers array");
711
DRC9b28def2011-05-21 14:37:15 +0000712 if((dstBufs=(unsigned char **)malloc(sizeof(unsigned char *)*n))==NULL)
DRCe8573012011-03-04 10:13:59 +0000713 _throw("Memory allocation failure");
DRC9b28def2011-05-21 14:37:15 +0000714 if((jdstBufs=(jbyteArray *)malloc(sizeof(jbyteArray)*n))==NULL)
DRCe8573012011-03-04 10:13:59 +0000715 _throw("Memory allocation failure");
DRC9b28def2011-05-21 14:37:15 +0000716 if((dstSizes=(unsigned long *)malloc(sizeof(unsigned long)*n))==NULL)
DRCe8573012011-03-04 10:13:59 +0000717 _throw("Memory allocation failure");
718 if((t=(tjtransform *)malloc(sizeof(tjtransform)*n))==NULL)
719 _throw("Memory allocation failure");
DRCf5467112011-09-20 05:02:19 +0000720 if((params=(JNICustomFilterParams *)malloc(sizeof(JNICustomFilterParams)*n))
721 ==NULL)
722 _throw("Memory allocation failure");
DRCe8573012011-03-04 10:13:59 +0000723 for(i=0; i<n; i++)
724 {
DRC9b28def2011-05-21 14:37:15 +0000725 dstBufs[i]=NULL; jdstBufs[i]=NULL; dstSizes[i]=0;
DRCe8573012011-03-04 10:13:59 +0000726 memset(&t[i], 0, sizeof(tjtransform));
DRCf5467112011-09-20 05:02:19 +0000727 memset(&params[i], 0, sizeof(JNICustomFilterParams));
DRCe8573012011-03-04 10:13:59 +0000728 }
729
730 for(i=0; i<n; i++)
731 {
DRCf5467112011-09-20 05:02:19 +0000732 jobject tobj, cfobj;
DRCe8573012011-03-04 10:13:59 +0000733
734 bailif0(tobj=(*env)->GetObjectArrayElement(env, tobjs, i));
735 bailif0(_cls=(*env)->GetObjectClass(env, tobj));
736 bailif0(_fid=(*env)->GetFieldID(env, _cls, "op", "I"));
737 t[i].op=(*env)->GetIntField(env, tobj, _fid);
738 bailif0(_fid=(*env)->GetFieldID(env, _cls, "options", "I"));
739 t[i].options=(*env)->GetIntField(env, tobj, _fid);
740 bailif0(_fid=(*env)->GetFieldID(env, _cls, "x", "I"));
741 t[i].r.x=(*env)->GetIntField(env, tobj, _fid);
742 bailif0(_fid=(*env)->GetFieldID(env, _cls, "y", "I"));
743 t[i].r.y=(*env)->GetIntField(env, tobj, _fid);
744 bailif0(_fid=(*env)->GetFieldID(env, _cls, "width", "I"));
745 t[i].r.w=(*env)->GetIntField(env, tobj, _fid);
746 bailif0(_fid=(*env)->GetFieldID(env, _cls, "height", "I"));
747 t[i].r.h=(*env)->GetIntField(env, tobj, _fid);
DRCf5467112011-09-20 05:02:19 +0000748
DRCf5467112011-09-20 05:02:19 +0000749 bailif0(_fid=(*env)->GetFieldID(env, _cls, "cf",
750 "Lorg/libjpegturbo/turbojpeg/TJCustomFilter;"));
DRC06420c42011-09-26 18:46:09 +0000751 cfobj=(*env)->GetObjectField(env, tobj, _fid);
752 if(cfobj)
753 {
754 params[i].env=env;
755 params[i].tobj=tobj;
756 params[i].cfobj=cfobj;
757 t[i].customFilter=JNICustomFilter;
758 t[i].data=(void *)&params[i];
759 }
DRCe8573012011-03-04 10:13:59 +0000760 }
761
DRC9b28def2011-05-21 14:37:15 +0000762 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, jsrcBuf, 0));
DRCe8573012011-03-04 10:13:59 +0000763 for(i=0; i<n; i++)
764 {
765 int w=jpegWidth, h=jpegHeight;
766 if(t[i].r.w!=0) w=t[i].r.w;
767 if(t[i].r.h!=0) h=t[i].r.h;
DRC9b28def2011-05-21 14:37:15 +0000768 bailif0(jdstBufs[i]=(*env)->GetObjectArrayElement(env, dstobjs, i));
DRCefe28ce2012-01-17 11:48:38 +0000769 if((unsigned long)(*env)->GetArrayLength(env, jdstBufs[i])
770 <tjBufSize(w, h, jpegSubsamp))
DRCe8573012011-03-04 10:13:59 +0000771 _throw("Destination buffer is not large enough");
DRC9b28def2011-05-21 14:37:15 +0000772 bailif0(dstBufs[i]=(*env)->GetPrimitiveArrayCritical(env, jdstBufs[i], 0));
DRCe8573012011-03-04 10:13:59 +0000773 }
774
DRC9b28def2011-05-21 14:37:15 +0000775 if(tjTransform(handle, jpegBuf, jpegSize, n, dstBufs, dstSizes, t,
DRC4db92ad2011-05-25 04:52:25 +0000776 flags|TJFLAG_NOREALLOC)==-1)
DRCe8573012011-03-04 10:13:59 +0000777 {
DRC9b28def2011-05-21 14:37:15 +0000778 (*env)->ReleasePrimitiveArrayCritical(env, jsrcBuf, jpegBuf, 0);
779 jpegBuf=NULL;
DRCe8573012011-03-04 10:13:59 +0000780 for(i=0; i<n; i++)
781 {
DRC9b28def2011-05-21 14:37:15 +0000782 (*env)->ReleasePrimitiveArrayCritical(env, jdstBufs[i], dstBufs[i], 0);
783 dstBufs[i]=NULL;
DRCe8573012011-03-04 10:13:59 +0000784 }
785 _throw(tjGetErrorStr());
786 }
787
DRC9b28def2011-05-21 14:37:15 +0000788 jdstSizes=(*env)->NewIntArray(env, n);
789 bailif0(dstSizesi=(*env)->GetIntArrayElements(env, jdstSizes, 0));
790 for(i=0; i<n; i++) dstSizesi[i]=(int)dstSizes[i];
DRCe8573012011-03-04 10:13:59 +0000791
792 bailout:
DRC9b28def2011-05-21 14:37:15 +0000793 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, jsrcBuf, jpegBuf, 0);
794 if(dstBufs)
DRCe8573012011-03-04 10:13:59 +0000795 {
796 for(i=0; i<n; i++)
797 {
DRC9b28def2011-05-21 14:37:15 +0000798 if(dstBufs[i] && jdstBufs && jdstBufs[i])
799 (*env)->ReleasePrimitiveArrayCritical(env, jdstBufs[i], dstBufs[i], 0);
DRCe8573012011-03-04 10:13:59 +0000800 }
DRC9b28def2011-05-21 14:37:15 +0000801 free(dstBufs);
DRCe8573012011-03-04 10:13:59 +0000802 }
DRC9b28def2011-05-21 14:37:15 +0000803 if(jdstBufs) free(jdstBufs);
804 if(dstSizes) free(dstSizes);
805 if(dstSizesi) (*env)->ReleaseIntArrayElements(env, jdstSizes, dstSizesi, 0);
DRCe8573012011-03-04 10:13:59 +0000806 if(t) free(t);
DRC9b28def2011-05-21 14:37:15 +0000807 return jdstSizes;
DRCe8573012011-03-04 10:13:59 +0000808}
809
DRCc5a41992011-02-08 06:54:36 +0000810JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_destroy
DRCf8e00552011-02-04 11:06:36 +0000811 (JNIEnv *env, jobject obj)
812{
DRCc5a41992011-02-08 06:54:36 +0000813 Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy(env, obj);
DRCf8e00552011-02-04 11:06:36 +0000814}