blob: f872cf003b833bb3ad30b1ee0ee55aacc3041dde [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")); \
DRC46a03922014-08-15 14:40:05 +000058 handle=(tjhandle)(size_t)(*env)->GetLongField(env, obj, _fid); \
DRCf8e00552011-02-04 11:06:36 +000059
DRCa4940d12014-08-15 16:07:15 +000060/* TurboJPEG 1.2.x: TJ::bufSize() */
DRC3bad53f2011-02-23 02:20:49 +000061JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSize
DRC9b49f0e2011-07-12 03:17:23 +000062 (JNIEnv *env, jclass cls, jint width, jint height, jint jpegSubsamp)
DRCf8e00552011-02-04 11:06:36 +000063{
DRC9b49f0e2011-07-12 03:17:23 +000064 jint retval=(jint)tjBufSize(width, height, jpegSubsamp);
DRC36336fc2011-02-22 10:27:31 +000065 if(retval==-1) _throw(tjGetErrorStr());
66
67 bailout:
68 return retval;
69}
70
DRCa4940d12014-08-15 16:07:15 +000071/* TurboJPEG 1.4.x: TJ::bufSizeYUV() */
DRCfef98522013-04-28 01:32:52 +000072JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__IIII
73 (JNIEnv *env, jclass cls, jint width, jint pad, jint height, jint subsamp)
DRC36336fc2011-02-22 10:27:31 +000074{
DRCfef98522013-04-28 01:32:52 +000075 jint retval=(jint)tjBufSizeYUV2(width, pad, height, subsamp);
DRC36336fc2011-02-22 10:27:31 +000076 if(retval==-1) _throw(tjGetErrorStr());
77
78 bailout:
79 return retval;
DRCf8e00552011-02-04 11:06:36 +000080}
81
DRCa4940d12014-08-15 16:07:15 +000082/* TurboJPEG 1.2.x: TJ::bufSizeYUV() */
DRCfef98522013-04-28 01:32:52 +000083JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__III
84 (JNIEnv *env, jclass cls, jint width, jint height, jint subsamp)
85{
86 return Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__IIII(env, cls, width,
87 4, height, subsamp);
88}
89
DRCa4940d12014-08-15 16:07:15 +000090/* TurboJPEG 1.2.x: TJCompressor::init() */
DRCc5a41992011-02-08 06:54:36 +000091JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_init
DRCf8e00552011-02-04 11:06:36 +000092 (JNIEnv *env, jobject obj)
93{
94 jclass cls;
95 jfieldID fid;
96 tjhandle handle;
97
DRC1a3dbe62011-02-28 10:51:55 +000098 if((handle=tjInitCompress())==NULL)
DRCf8e00552011-02-04 11:06:36 +000099 _throw(tjGetErrorStr());
100
101 bailif0(cls=(*env)->GetObjectClass(env, obj));
102 bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J"));
DRC46a03922014-08-15 14:40:05 +0000103 (*env)->SetLongField(env, obj, fid, (size_t)handle);
DRCf8e00552011-02-04 11:06:36 +0000104
105 bailout:
106 return;
107}
108
DRC5d87f6d2014-08-15 16:40:56 +0000109static jint TJCompressor_compress
DRC927a10d2014-08-15 13:18:58 +0000110 (JNIEnv *env, jobject obj, jarray src, jint srcElementSize, jint x, jint y,
111 jint width, jint pitch, jint height, jint pf, jbyteArray dst,
112 jint jpegSubsamp, jint jpegQual, jint flags)
DRCf8e00552011-02-04 11:06:36 +0000113{
DRC9b28def2011-05-21 14:37:15 +0000114 tjhandle handle=0;
DRCfac3bea2012-09-24 02:27:55 +0000115 unsigned long jpegSize=0;
116 jsize arraySize=0, actualPitch;
DRC9b28def2011-05-21 14:37:15 +0000117 unsigned char *srcBuf=NULL, *jpegBuf=NULL;
DRCf8e00552011-02-04 11:06:36 +0000118
119 gethandle();
120
DRC92549de2011-03-15 20:52:02 +0000121 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1
DRC6acf52b2011-03-02 01:09:20 +0000122 || pitch<0)
DRC4f1580c2011-02-25 06:11:03 +0000123 _throw("Invalid argument in compress()");
DRC9b28def2011-05-21 14:37:15 +0000124 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
125 _throw("Mismatch between Java and C API");
DRC4f1580c2011-02-25 06:11:03 +0000126
DRCfac3bea2012-09-24 02:27:55 +0000127 actualPitch=(pitch==0)? width*tjPixelSize[pf]:pitch;
DRC927a10d2014-08-15 13:18:58 +0000128 arraySize=(y+height-1)*actualPitch + (x+width)*tjPixelSize[pf];
129 if((*env)->GetArrayLength(env, src)*srcElementSize<arraySize)
DRC6acf52b2011-03-02 01:09:20 +0000130 _throw("Source buffer is not large enough");
DRC9b49f0e2011-07-12 03:17:23 +0000131 jpegSize=tjBufSize(width, height, jpegSubsamp);
DRC9b28def2011-05-21 14:37:15 +0000132 if((*env)->GetArrayLength(env, dst)<(jsize)jpegSize)
DRC6acf52b2011-03-02 01:09:20 +0000133 _throw("Destination buffer is not large enough");
134
DRC9b28def2011-05-21 14:37:15 +0000135 bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
136 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
DRCf8e00552011-02-04 11:06:36 +0000137
DRCfac3bea2012-09-24 02:27:55 +0000138 if(tjCompress2(handle, &srcBuf[y*actualPitch + x*tjPixelSize[pf]], width,
139 pitch, height, pf, &jpegBuf, &jpegSize, jpegSubsamp, jpegQual,
140 flags|TJFLAG_NOREALLOC)==-1)
DRCfac3bea2012-09-24 02:27:55 +0000141 _throw(tjGetErrorStr());
DRCfac3bea2012-09-24 02:27:55 +0000142
143 bailout:
144 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0);
145 if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
146 return (jint)jpegSize;
147}
148
DRCa4940d12014-08-15 16:07:15 +0000149/* TurboJPEG 1.3.x: TJCompressor::compress() byte source */
DRC927a10d2014-08-15 13:18:58 +0000150JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIIIII_3BIII
151 (JNIEnv *env, jobject obj, jbyteArray src, jint x, jint y, jint width,
152 jint pitch, jint height, jint pf, jbyteArray dst, jint jpegSubsamp,
153 jint jpegQual, jint flags)
154{
155 return TJCompressor_compress(env, obj, src, 1, x, y, width, pitch, height,
156 pf, dst, jpegSubsamp, jpegQual, flags);
157}
158
DRCa4940d12014-08-15 16:07:15 +0000159/* TurboJPEG 1.2.x: TJCompressor::compress() byte source */
DRCfac3bea2012-09-24 02:27:55 +0000160JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIII_3BIII
161 (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch,
162 jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpegQual,
163 jint flags)
164{
DRC927a10d2014-08-15 13:18:58 +0000165 return TJCompressor_compress(env, obj, src, 1, 0, 0, width, pitch, height,
166 pf, dst, jpegSubsamp, jpegQual, flags);
DRCfac3bea2012-09-24 02:27:55 +0000167}
168
DRCa4940d12014-08-15 16:07:15 +0000169/* TurboJPEG 1.3.x: TJCompressor::compress() int source */
DRCfac3bea2012-09-24 02:27:55 +0000170JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIIIII_3BIII
171 (JNIEnv *env, jobject obj, jintArray src, jint x, jint y, jint width,
172 jint stride, jint height, jint pf, jbyteArray dst, jint jpegSubsamp,
173 jint jpegQual, jint flags)
174{
DRC927a10d2014-08-15 13:18:58 +0000175 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
DRCfac3bea2012-09-24 02:27:55 +0000176 _throw("Invalid argument in compress()");
DRCfac3bea2012-09-24 02:27:55 +0000177 if(tjPixelSize[pf]!=sizeof(jint))
178 _throw("Pixel format must be 32-bit when compressing from an integer buffer.");
179
DRC927a10d2014-08-15 13:18:58 +0000180 return TJCompressor_compress(env, obj, src, sizeof(jint), x, y, width,
181 stride*sizeof(jint), height, pf, dst, jpegSubsamp, jpegQual, flags);
DRCf8e00552011-02-04 11:06:36 +0000182
183 bailout:
DRC927a10d2014-08-15 13:18:58 +0000184 return 0;
DRCf8e00552011-02-04 11:06:36 +0000185}
186
DRCa4940d12014-08-15 16:07:15 +0000187/* TurboJPEG 1.2.x: TJCompressor::compress() int source */
DRC4f1580c2011-02-25 06:11:03 +0000188JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIII_3BIII
DRC927a10d2014-08-15 13:18:58 +0000189 (JNIEnv *env, jobject obj, jintArray src, jint width, jint stride,
DRC9b28def2011-05-21 14:37:15 +0000190 jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpegQual,
DRC4f1580c2011-02-25 06:11:03 +0000191 jint flags)
DRC84a1bcc2011-02-23 12:09:56 +0000192{
DRC927a10d2014-08-15 13:18:58 +0000193 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
194 _throw("Invalid argument in compress()");
195 if(tjPixelSize[pf]!=sizeof(jint))
196 _throw("Pixel format must be 32-bit when compressing from an integer buffer.");
197
198 return TJCompressor_compress(env, obj, src, sizeof(jint), 0, 0, width,
199 stride*sizeof(jint), height, pf, dst, jpegSubsamp, jpegQual, flags);
200
201 bailout:
202 return 0;
DRC84a1bcc2011-02-23 12:09:56 +0000203}
204
DRCa4940d12014-08-15 16:07:15 +0000205/* TurboJPEG 1.4.x: TJCompressor::compressFromYUV() */
DRC1e672742013-10-31 05:04:51 +0000206JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compressFromYUV___3BIIII_3BII
207 (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pad, jint height,
208 jint subsamp, jbyteArray dst, jint jpegQual, jint flags)
209{
210 tjhandle handle=0;
211 unsigned long jpegSize=0;
212 jsize arraySize=0;
213 unsigned char *srcBuf=NULL, *jpegBuf=NULL;
214
215 gethandle();
216
217 arraySize=tjBufSizeYUV2(width, pad, height, subsamp);
218 if((*env)->GetArrayLength(env, src)<arraySize)
219 _throw("Source buffer is not large enough");
220 jpegSize=tjBufSize(width, height, subsamp);
221 if((*env)->GetArrayLength(env, dst)<(jsize)jpegSize)
222 _throw("Destination buffer is not large enough");
223
224 bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
225 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
226
227 if(tjCompressFromYUV(handle, srcBuf, width, pad, height, subsamp, &jpegBuf,
228 &jpegSize, jpegQual, flags|TJFLAG_NOREALLOC)==-1)
DRC1e672742013-10-31 05:04:51 +0000229 _throw(tjGetErrorStr());
DRC1e672742013-10-31 05:04:51 +0000230
231 bailout:
232 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0);
233 if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
234 return (jint)jpegSize;
235}
236
DRC5d87f6d2014-08-15 16:40:56 +0000237static void TJCompressor_encodeYUV
DRC927a10d2014-08-15 13:18:58 +0000238 (JNIEnv *env, jobject obj, jarray src, jint srcElementSize, jint x, jint y,
239 jint width, jint pitch, jint height, jint pf, jbyteArray dst, jint pad,
240 jint subsamp, jint flags)
DRC4f1580c2011-02-25 06:11:03 +0000241{
DRC9b28def2011-05-21 14:37:15 +0000242 tjhandle handle=0;
DRCfc26b652014-03-16 22:56:26 +0000243 jsize arraySize=0, actualPitch, yuvSize;
DRC9b28def2011-05-21 14:37:15 +0000244 unsigned char *srcBuf=NULL, *dstBuf=NULL;
DRC4f1580c2011-02-25 06:11:03 +0000245
246 gethandle();
247
DRC92549de2011-03-15 20:52:02 +0000248 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1
DRC6acf52b2011-03-02 01:09:20 +0000249 || pitch<0)
DRC4f1580c2011-02-25 06:11:03 +0000250 _throw("Invalid argument in encodeYUV()");
DRC9b28def2011-05-21 14:37:15 +0000251 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
252 _throw("Mismatch between Java and C API");
DRC4f1580c2011-02-25 06:11:03 +0000253
DRCfc26b652014-03-16 22:56:26 +0000254 actualPitch=(pitch==0)? width*tjPixelSize[pf]:pitch;
DRC927a10d2014-08-15 13:18:58 +0000255 arraySize=(y+height-1)*actualPitch + (x+width)*tjPixelSize[pf];
256 if((*env)->GetArrayLength(env, src)*srcElementSize<arraySize)
DRC6acf52b2011-03-02 01:09:20 +0000257 _throw("Source buffer is not large enough");
DRCfef98522013-04-28 01:32:52 +0000258 yuvSize=(jsize)tjBufSizeYUV2(width, pad, height, subsamp);
259 if(yuvSize==(unsigned long)-1)
260 _throw(tjGetErrorStr());
261 if((*env)->GetArrayLength(env, dst)<yuvSize)
DRC6acf52b2011-03-02 01:09:20 +0000262 _throw("Destination buffer is not large enough");
263
DRC9b28def2011-05-21 14:37:15 +0000264 bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
265 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
DRC4f1580c2011-02-25 06:11:03 +0000266
DRCfc26b652014-03-16 22:56:26 +0000267 if(tjEncodeYUV3(handle, &srcBuf[y*actualPitch + x*tjPixelSize[pf]], width,
268 pitch, height, pf, dstBuf, pad, subsamp, flags)==-1)
DRC4f1580c2011-02-25 06:11:03 +0000269 _throw(tjGetErrorStr());
DRC4f1580c2011-02-25 06:11:03 +0000270
271 bailout:
DRC9b28def2011-05-21 14:37:15 +0000272 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
273 if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
DRC4f1580c2011-02-25 06:11:03 +0000274 return;
275}
276
DRCa4940d12014-08-15 16:07:15 +0000277/* TurboJPEG 1.4.x: TJCompressor::encodeYUV() byte source */
DRC927a10d2014-08-15 13:18:58 +0000278JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIIIII_3BIII
279 (JNIEnv *env, jobject obj, jbyteArray src, jint x, jint y, jint width,
280 jint pitch, jint height, jint pf, jbyteArray dst, jint pad, jint subsamp,
281 jint flags)
282{
DRC46a03922014-08-15 14:40:05 +0000283 TJCompressor_encodeYUV(env, obj, src, 1, x, y, width, pitch, height, pf, dst,
284 pad, subsamp, flags);
DRC927a10d2014-08-15 13:18:58 +0000285}
286
DRCa4940d12014-08-15 16:07:15 +0000287/* TurboJPEG 1.2.x: TJCompressor::encodeYUV() byte source */
DRCfef98522013-04-28 01:32:52 +0000288JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIII_3BII
289 (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch,
DRC6acf52b2011-03-02 01:09:20 +0000290 jint height, jint pf, jbyteArray dst, jint subsamp, jint flags)
DRC4f1580c2011-02-25 06:11:03 +0000291{
DRC46a03922014-08-15 14:40:05 +0000292 TJCompressor_encodeYUV(env, obj, src, 1, 0, 0, width, pitch, height, pf, dst,
293 4, subsamp, flags);
DRCfef98522013-04-28 01:32:52 +0000294}
295
DRCa4940d12014-08-15 16:07:15 +0000296/* TurboJPEG 1.4.x: TJCompressor::encodeYUV() int source */
DRCfc26b652014-03-16 22:56:26 +0000297JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIIIII_3BIII
298 (JNIEnv *env, jobject obj, jintArray src, jint x, jint y, jint width,
299 jint stride, jint height, jint pf, jbyteArray dst, jint pad, jint subsamp,
300 jint flags)
DRCfef98522013-04-28 01:32:52 +0000301{
DRC927a10d2014-08-15 13:18:58 +0000302 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
DRC1d29c5f2013-04-27 20:54:44 +0000303 _throw("Invalid argument in encodeYUV()");
DRC9b28def2011-05-21 14:37:15 +0000304 if(tjPixelSize[pf]!=sizeof(jint))
DRC4f1580c2011-02-25 06:11:03 +0000305 _throw("Pixel format must be 32-bit when encoding from an integer buffer.");
DRC4f1580c2011-02-25 06:11:03 +0000306
DRC46a03922014-08-15 14:40:05 +0000307 TJCompressor_encodeYUV(env, obj, src, sizeof(jint), x, y, width,
DRC927a10d2014-08-15 13:18:58 +0000308 stride*sizeof(jint), height, pf, dst, pad, subsamp, flags);
DRC4f1580c2011-02-25 06:11:03 +0000309
310 bailout:
DRC4f1580c2011-02-25 06:11:03 +0000311 return;
312}
313
DRCa4940d12014-08-15 16:07:15 +0000314/* TurboJPEG 1.2.x: TJCompressor::encodeYUV() int source */
DRCfef98522013-04-28 01:32:52 +0000315JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIII_3BII
DRC927a10d2014-08-15 13:18:58 +0000316 (JNIEnv *env, jobject obj, jintArray src, jint width, jint stride,
DRCfef98522013-04-28 01:32:52 +0000317 jint height, jint pf, jbyteArray dst, jint subsamp, jint flags)
318{
DRC927a10d2014-08-15 13:18:58 +0000319 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
320 _throw("Invalid argument in encodeYUV()");
321 if(tjPixelSize[pf]!=sizeof(jint))
322 _throw("Pixel format must be 32-bit when encoding from an integer buffer.");
323
DRC46a03922014-08-15 14:40:05 +0000324 TJCompressor_encodeYUV(env, obj, src, sizeof(jint), 0, 0, width,
DRC927a10d2014-08-15 13:18:58 +0000325 stride*sizeof(jint), height, pf, dst, 4, subsamp, flags);
326
327 bailout:
328 return;
DRCfef98522013-04-28 01:32:52 +0000329}
330
DRCa4940d12014-08-15 16:07:15 +0000331/* TurboJPEG 1.2.x: TJCompressor::destroy() */
DRCc5a41992011-02-08 06:54:36 +0000332JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy
DRCf8e00552011-02-04 11:06:36 +0000333 (JNIEnv *env, jobject obj)
334{
335 tjhandle handle=0;
336
337 gethandle();
338
339 if(tjDestroy(handle)==-1) _throw(tjGetErrorStr());
DRC3bad53f2011-02-23 02:20:49 +0000340 (*env)->SetLongField(env, obj, _fid, 0);
DRCf8e00552011-02-04 11:06:36 +0000341
342 bailout:
343 return;
344}
345
DRCa4940d12014-08-15 16:07:15 +0000346/* TurboJPEG 1.2.x: TJDecompressor::init() */
DRCc5a41992011-02-08 06:54:36 +0000347JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_init
DRCf8e00552011-02-04 11:06:36 +0000348 (JNIEnv *env, jobject obj)
349{
350 jclass cls;
351 jfieldID fid;
352 tjhandle handle;
353
DRC1a3dbe62011-02-28 10:51:55 +0000354 if((handle=tjInitDecompress())==NULL) _throw(tjGetErrorStr());
DRCf8e00552011-02-04 11:06:36 +0000355
356 bailif0(cls=(*env)->GetObjectClass(env, obj));
357 bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J"));
DRC46a03922014-08-15 14:40:05 +0000358 (*env)->SetLongField(env, obj, fid, (size_t)handle);
DRCf8e00552011-02-04 11:06:36 +0000359
360 bailout:
361 return;
362}
363
DRCa4940d12014-08-15 16:07:15 +0000364/* TurboJPEG 1.2.x: TJDecompressor::getScalingFactors() */
DRC109a5782011-03-01 09:53:07 +0000365JNIEXPORT jobjectArray JNICALL Java_org_libjpegturbo_turbojpeg_TJ_getScalingFactors
366 (JNIEnv *env, jclass cls)
DRC36336fc2011-02-22 10:27:31 +0000367{
DRCb7c8c862014-08-15 16:20:59 +0000368 jclass sfcls=NULL; jfieldID fid=0;
DRC109a5782011-03-01 09:53:07 +0000369 tjscalingfactor *sf=NULL; int n=0, i;
370 jobject sfobj=NULL;
371 jobjectArray sfjava=NULL;
372
373 if((sf=tjGetScalingFactors(&n))==NULL || n==0)
DRC36336fc2011-02-22 10:27:31 +0000374 _throw(tjGetErrorStr());
375
DRCb2f94152011-04-02 02:09:03 +0000376 bailif0(sfcls=(*env)->FindClass(env, "org/libjpegturbo/turbojpeg/TJScalingFactor"));
DRC109a5782011-03-01 09:53:07 +0000377 bailif0(sfjava=(jobjectArray)(*env)->NewObjectArray(env, n, sfcls, 0));
DRC36336fc2011-02-22 10:27:31 +0000378
DRC109a5782011-03-01 09:53:07 +0000379 for(i=0; i<n; i++)
380 {
381 bailif0(sfobj=(*env)->AllocObject(env, sfcls));
382 bailif0(fid=(*env)->GetFieldID(env, sfcls, "num", "I"));
383 (*env)->SetIntField(env, sfobj, fid, sf[i].num);
384 bailif0(fid=(*env)->GetFieldID(env, sfcls, "denom", "I"));
385 (*env)->SetIntField(env, sfobj, fid, sf[i].denom);
386 (*env)->SetObjectArrayElement(env, sfjava, i, sfobj);
387 }
DRC36336fc2011-02-22 10:27:31 +0000388
389 bailout:
DRC109a5782011-03-01 09:53:07 +0000390 return sfjava;
DRC36336fc2011-02-22 10:27:31 +0000391}
392
DRCa4940d12014-08-15 16:07:15 +0000393/* TurboJPEG 1.2.x: TJDecompressor::decompressHeader() */
DRC3bad53f2011-02-23 02:20:49 +0000394JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressHeader
DRC9b28def2011-05-21 14:37:15 +0000395 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize)
DRCf8e00552011-02-04 11:06:36 +0000396{
DRCf8e00552011-02-04 11:06:36 +0000397 tjhandle handle=0;
DRC9b28def2011-05-21 14:37:15 +0000398 unsigned char *jpegBuf=NULL;
DRC38cb1ec2013-08-23 04:45:43 +0000399 int width=0, height=0, jpegSubsamp=-1, jpegColorspace=-1;
DRCf8e00552011-02-04 11:06:36 +0000400
401 gethandle();
402
DRC9b28def2011-05-21 14:37:15 +0000403 if((*env)->GetArrayLength(env, src)<jpegSize)
DRC6acf52b2011-03-02 01:09:20 +0000404 _throw("Source buffer is not large enough");
405
DRC9b28def2011-05-21 14:37:15 +0000406 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
DRCf8e00552011-02-04 11:06:36 +0000407
DRC1a45b812014-05-09 18:06:58 +0000408 if(tjDecompressHeader3(handle, jpegBuf, (unsigned long)jpegSize,
DRC38cb1ec2013-08-23 04:45:43 +0000409 &width, &height, &jpegSubsamp, &jpegColorspace)==-1)
DRCf8e00552011-02-04 11:06:36 +0000410 _throw(tjGetErrorStr());
DRC8951cf02014-08-14 16:54:04 +0000411
DRC9b28def2011-05-21 14:37:15 +0000412 (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0); jpegBuf=NULL;
DRCf8e00552011-02-04 11:06:36 +0000413
DRC26dd86b2014-08-15 14:01:21 +0000414 bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
DRC9b28def2011-05-21 14:37:15 +0000415 (*env)->SetIntField(env, obj, _fid, jpegSubsamp);
DRC26dd86b2014-08-15 14:01:21 +0000416 if((_fid=(*env)->GetFieldID(env, _cls, "jpegColorspace", "I"))==0)
417 (*env)->ExceptionClear(env);
418 else
419 (*env)->SetIntField(env, obj, _fid, jpegColorspace);
420 bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
DRC3bad53f2011-02-23 02:20:49 +0000421 (*env)->SetIntField(env, obj, _fid, width);
DRC26dd86b2014-08-15 14:01:21 +0000422 bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
DRC3bad53f2011-02-23 02:20:49 +0000423 (*env)->SetIntField(env, obj, _fid, height);
DRCf8e00552011-02-04 11:06:36 +0000424
425 bailout:
DRC8951cf02014-08-14 16:54:04 +0000426 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
DRC3bad53f2011-02-23 02:20:49 +0000427 return;
DRCf8e00552011-02-04 11:06:36 +0000428}
429
DRC5d87f6d2014-08-15 16:40:56 +0000430static void TJDecompressor_decompress
DRC927a10d2014-08-15 13:18:58 +0000431 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jarray dst,
432 jint dstElementSize, jint x, jint y, jint width, jint pitch, jint height,
433 jint pf, jint flags)
DRCf8e00552011-02-04 11:06:36 +0000434{
DRC9b28def2011-05-21 14:37:15 +0000435 tjhandle handle=0;
DRCf659f432012-06-06 08:41:06 +0000436 jsize arraySize=0, actualPitch;
DRC9b28def2011-05-21 14:37:15 +0000437 unsigned char *jpegBuf=NULL, *dstBuf=NULL;
DRCf8e00552011-02-04 11:06:36 +0000438
439 gethandle();
440
DRC92549de2011-03-15 20:52:02 +0000441 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
DRC4f1580c2011-02-25 06:11:03 +0000442 _throw("Invalid argument in decompress()");
DRC9b28def2011-05-21 14:37:15 +0000443 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
444 _throw("Mismatch between Java and C API");
DRC4f1580c2011-02-25 06:11:03 +0000445
DRC9b28def2011-05-21 14:37:15 +0000446 if((*env)->GetArrayLength(env, src)<jpegSize)
DRC6acf52b2011-03-02 01:09:20 +0000447 _throw("Source buffer is not large enough");
DRCf659f432012-06-06 08:41:06 +0000448 actualPitch=(pitch==0)? width*tjPixelSize[pf]:pitch;
DRCdc31f0b2012-06-07 09:38:57 +0000449 arraySize=(y+height-1)*actualPitch + (x+width)*tjPixelSize[pf];
DRC927a10d2014-08-15 13:18:58 +0000450 if((*env)->GetArrayLength(env, dst)*dstElementSize<arraySize)
DRC6acf52b2011-03-02 01:09:20 +0000451 _throw("Destination buffer is not large enough");
452
DRC9b28def2011-05-21 14:37:15 +0000453 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
454 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
DRCf8e00552011-02-04 11:06:36 +0000455
DRCf659f432012-06-06 08:41:06 +0000456 if(tjDecompress2(handle, jpegBuf, (unsigned long)jpegSize,
457 &dstBuf[y*actualPitch + x*tjPixelSize[pf]], width, pitch, height, pf,
458 flags)==-1)
DRCf659f432012-06-06 08:41:06 +0000459 _throw(tjGetErrorStr());
DRCf659f432012-06-06 08:41:06 +0000460
461 bailout:
462 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
463 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
464 return;
465}
466
DRCa4940d12014-08-15 16:07:15 +0000467/* TurboJPEG 1.3.x: TJDecompressor::decompress() byte destination */
DRC927a10d2014-08-15 13:18:58 +0000468JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIIIII
469 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
470 jint x, jint y, jint width, jint pitch, jint height, jint pf, jint flags)
471{
472 TJDecompressor_decompress(env, obj, src, jpegSize, dst, 1, x, y, width,
473 pitch, height, pf, flags);
474}
475
DRCa4940d12014-08-15 16:07:15 +0000476/* TurboJPEG 1.2.x: TJDecompressor::decompress() byte destination */
DRCf659f432012-06-06 08:41:06 +0000477JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIII
478 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
479 jint width, jint pitch, jint height, jint pf, jint flags)
480{
DRC927a10d2014-08-15 13:18:58 +0000481 TJDecompressor_decompress(env, obj, src, jpegSize, dst, 1, 0, 0, width,
482 pitch, height, pf, flags);
DRCf659f432012-06-06 08:41:06 +0000483}
484
DRCa4940d12014-08-15 16:07:15 +0000485/* TurboJPEG 1.3.x: TJDecompressor::decompress() int destination */
DRCf659f432012-06-06 08:41:06 +0000486JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIIIII
487 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jintArray dst,
488 jint x, jint y, jint width, jint stride, jint height, jint pf, jint flags)
489{
DRCf659f432012-06-06 08:41:06 +0000490 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
491 _throw("Invalid argument in decompress()");
DRCf659f432012-06-06 08:41:06 +0000492 if(tjPixelSize[pf]!=sizeof(jint))
493 _throw("Pixel format must be 32-bit when decompressing to an integer buffer.");
494
DRC927a10d2014-08-15 13:18:58 +0000495 TJDecompressor_decompress(env, obj, src, jpegSize, dst, sizeof(jint), x, y,
496 width, stride*sizeof(jint), height, pf, flags);
DRCf8e00552011-02-04 11:06:36 +0000497
498 bailout:
DRCf8e00552011-02-04 11:06:36 +0000499 return;
500}
501
DRCa4940d12014-08-15 16:07:15 +0000502/* TurboJPEG 1.2.x: TJDecompressor::decompress() int destination */
DRC4f1580c2011-02-25 06:11:03 +0000503JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIII
DRC9b28def2011-05-21 14:37:15 +0000504 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jintArray dst,
DRCf659f432012-06-06 08:41:06 +0000505 jint width, jint stride, jint height, jint pf, jint flags)
DRC84a1bcc2011-02-23 12:09:56 +0000506{
DRC927a10d2014-08-15 13:18:58 +0000507 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
508 _throw("Invalid argument in decompress()");
509 if(tjPixelSize[pf]!=sizeof(jint))
510 _throw("Pixel format must be 32-bit when decompressing to an integer buffer.");
511
512 TJDecompressor_decompress(env, obj, src, jpegSize, dst, sizeof(jint), 0, 0,
513 width, stride*sizeof(jint), height, pf, flags);
514
515 bailout:
516 return;
DRC1a45b812014-05-09 18:06:58 +0000517
DRC4f1580c2011-02-25 06:11:03 +0000518}
DRC84a1bcc2011-02-23 12:09:56 +0000519
DRCa4940d12014-08-15 16:07:15 +0000520/* TurboJPEG 1.4.x: TJDecompressor::decompressToYUV() */
DRCfef98522013-04-28 01:32:52 +0000521JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3BIIII
DRC9b28def2011-05-21 14:37:15 +0000522 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
DRCfef98522013-04-28 01:32:52 +0000523 jint desiredWidth, jint pad, jint desiredHeight, jint flags)
DRC4f1580c2011-02-25 06:11:03 +0000524{
525 tjhandle handle=0;
DRC9b28def2011-05-21 14:37:15 +0000526 unsigned char *jpegBuf=NULL, *dstBuf=NULL;
DRC6acf52b2011-03-02 01:09:20 +0000527 int jpegSubsamp=-1, jpegWidth=0, jpegHeight=0;
DRCfef98522013-04-28 01:32:52 +0000528 jsize yuvSize;
DRC4f1580c2011-02-25 06:11:03 +0000529
530 gethandle();
531
DRC9b28def2011-05-21 14:37:15 +0000532 if((*env)->GetArrayLength(env, src)<jpegSize)
DRC6acf52b2011-03-02 01:09:20 +0000533 _throw("Source buffer is not large enough");
DRC26dd86b2014-08-15 14:01:21 +0000534 bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
DRC6acf52b2011-03-02 01:09:20 +0000535 jpegSubsamp=(int)(*env)->GetIntField(env, obj, _fid);
DRC26dd86b2014-08-15 14:01:21 +0000536 bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
DRC6acf52b2011-03-02 01:09:20 +0000537 jpegWidth=(int)(*env)->GetIntField(env, obj, _fid);
DRC26dd86b2014-08-15 14:01:21 +0000538 bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
DRC6acf52b2011-03-02 01:09:20 +0000539 jpegHeight=(int)(*env)->GetIntField(env, obj, _fid);
DRC6acf52b2011-03-02 01:09:20 +0000540
DRCfef98522013-04-28 01:32:52 +0000541 yuvSize=(jsize)tjBufSizeYUV2(desiredWidth==0? jpegWidth:desiredWidth,
542 pad, desiredHeight==0? jpegHeight:desiredHeight, jpegSubsamp);
543 if(yuvSize==(unsigned long)-1)
544 _throw(tjGetErrorStr());
545 if((*env)->GetArrayLength(env, dst)<yuvSize)
546 _throw("Destination buffer is not large enough");
DRC9b28def2011-05-21 14:37:15 +0000547 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
548 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
DRC4f1580c2011-02-25 06:11:03 +0000549
DRCfef98522013-04-28 01:32:52 +0000550 if(tjDecompressToYUV2(handle, jpegBuf, (unsigned long)jpegSize, dstBuf,
551 desiredWidth, pad, desiredHeight, flags)==-1)
DRC4f1580c2011-02-25 06:11:03 +0000552 _throw(tjGetErrorStr());
DRC4f1580c2011-02-25 06:11:03 +0000553
554 bailout:
DRC9b28def2011-05-21 14:37:15 +0000555 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
556 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
DRC4f1580c2011-02-25 06:11:03 +0000557 return;
DRC84a1bcc2011-02-23 12:09:56 +0000558}
559
DRCa4940d12014-08-15 16:07:15 +0000560/* TurboJPEG 1.2.x: TJDecompressor::decompressToYUV() */
DRCfef98522013-04-28 01:32:52 +0000561JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3BI
562 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
563 jint flags)
564{
565 Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV___3BI_3BIIII(
566 env, obj, src, jpegSize, dst, 0, 4, 0, flags);
567}
568
DRC5d87f6d2014-08-15 16:40:56 +0000569static void TJDecompressor_decodeYUV
DRCfc26b652014-03-16 22:56:26 +0000570 (JNIEnv *env, jobject obj, jbyteArray src, jint pad, jint subsamp,
DRC927a10d2014-08-15 13:18:58 +0000571 jarray dst, jint dstElementSize, jint x, jint y, jint width, jint pitch,
572 jint height, jint pf, jint flags)
DRCfc26b652014-03-16 22:56:26 +0000573{
574 tjhandle handle=0;
575 jsize arraySize=0, actualPitch;
576 unsigned char *srcBuf=NULL, *dstBuf=NULL;
577
578 gethandle();
579
580 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
581 _throw("Invalid argument in decodeYUV()");
582 if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
583 _throw("Mismatch between Java and C API");
584
585 arraySize=tjBufSizeYUV2(width, pad, height, subsamp);
586 if((*env)->GetArrayLength(env, src)<arraySize)
587 _throw("Source buffer is not large enough");
588 actualPitch=(pitch==0)? width*tjPixelSize[pf]:pitch;
589 arraySize=(y+height-1)*actualPitch + (x+width)*tjPixelSize[pf];
DRC927a10d2014-08-15 13:18:58 +0000590 if((*env)->GetArrayLength(env, dst)*dstElementSize<arraySize)
DRCfc26b652014-03-16 22:56:26 +0000591 _throw("Destination buffer is not large enough");
592
593 bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
594 bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
595
596 if(tjDecodeYUV(handle, srcBuf, pad, subsamp,
597 &dstBuf[y*actualPitch + x*tjPixelSize[pf]], width, pitch, height, pf,
598 flags)==-1)
DRCfc26b652014-03-16 22:56:26 +0000599 _throw(tjGetErrorStr());
DRCfc26b652014-03-16 22:56:26 +0000600
601 bailout:
602 if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
603 if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
604 return;
605}
606
DRCa4940d12014-08-15 16:07:15 +0000607/* TurboJPEG 1.4.x: TJDecompressor::decodeYUV() byte destination */
DRC927a10d2014-08-15 13:18:58 +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 TJDecompressor_decodeYUV(env, obj, src, pad, subsamp, dst, 1, x, y, width,
614 pitch, height, pf, flags);
615}
616
DRCa4940d12014-08-15 16:07:15 +0000617/* TurboJPEG 1.4.x: TJDecompressor::decodeYUV() int destination */
DRCfc26b652014-03-16 22:56:26 +0000618JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decodeYUV___3BII_3IIIIIIII
619 (JNIEnv *env, jobject obj, jbyteArray src, jint pad, jint subsamp,
620 jintArray dst, jint x, jint y, jint width, jint stride, jint height,
621 jint pf, jint flags)
622{
DRCfc26b652014-03-16 22:56:26 +0000623 if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
624 _throw("Invalid argument in decodeYUV()");
DRCfc26b652014-03-16 22:56:26 +0000625 if(tjPixelSize[pf]!=sizeof(jint))
626 _throw("Pixel format must be 32-bit when decoding to an integer buffer.");
627
DRC927a10d2014-08-15 13:18:58 +0000628 TJDecompressor_decodeYUV(env, obj, src, pad, subsamp, dst, sizeof(jint), x,
629 y, width, stride*sizeof(jint), height, pf, flags);
DRCfc26b652014-03-16 22:56:26 +0000630
631 bailout:
DRCfc26b652014-03-16 22:56:26 +0000632 return;
633}
634
DRCa4940d12014-08-15 16:07:15 +0000635/* TurboJPEG 1.2.x: TJTransformer::init() */
DRCe8573012011-03-04 10:13:59 +0000636JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_init
637 (JNIEnv *env, jobject obj)
638{
639 jclass cls;
640 jfieldID fid;
641 tjhandle handle;
642
643 if((handle=tjInitTransform())==NULL) _throw(tjGetErrorStr());
644
645 bailif0(cls=(*env)->GetObjectClass(env, obj));
646 bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J"));
DRC46a03922014-08-15 14:40:05 +0000647 (*env)->SetLongField(env, obj, fid, (size_t)handle);
DRCe8573012011-03-04 10:13:59 +0000648
649 bailout:
650 return;
651}
652
DRCf5467112011-09-20 05:02:19 +0000653typedef struct _JNICustomFilterParams
654{
655 JNIEnv *env;
656 jobject tobj;
657 jobject cfobj;
658} JNICustomFilterParams;
659
660static int JNICustomFilter(short *coeffs, tjregion arrayRegion,
661 tjregion planeRegion, int componentIndex, int transformIndex,
662 tjtransform *transform)
663{
664 JNICustomFilterParams *params=(JNICustomFilterParams *)transform->data;
665 JNIEnv *env=params->env;
666 jobject tobj=params->tobj, cfobj=params->cfobj;
DRCb7c8c862014-08-15 16:20:59 +0000667 jobject arrayRegionObj, planeRegionObj, bufobj, borobj;
DRCf5467112011-09-20 05:02:19 +0000668 jclass cls; jmethodID mid; jfieldID fid;
669
670 bailif0(bufobj=(*env)->NewDirectByteBuffer(env, coeffs,
671 sizeof(short)*arrayRegion.w*arrayRegion.h));
672 bailif0(cls=(*env)->FindClass(env, "java/nio/ByteOrder"));
DRCb7c8c862014-08-15 16:20:59 +0000673 bailif0(mid=(*env)->GetStaticMethodID(env, cls, "nativeOrder",
DRCf5467112011-09-20 05:02:19 +0000674 "()Ljava/nio/ByteOrder;"));
675 bailif0(borobj=(*env)->CallStaticObjectMethod(env, cls, mid));
676 bailif0(cls=(*env)->GetObjectClass(env, bufobj));
677 bailif0(mid=(*env)->GetMethodID(env, cls, "order",
678 "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;"));
679 (*env)->CallObjectMethod(env, bufobj, mid, borobj);
DRCb7c8c862014-08-15 16:20:59 +0000680 bailif0(mid=(*env)->GetMethodID(env, cls, "asShortBuffer",
DRCf5467112011-09-20 05:02:19 +0000681 "()Ljava/nio/ShortBuffer;"));
682 bailif0(bufobj=(*env)->CallObjectMethod(env, bufobj, mid));
683
684 bailif0(cls=(*env)->FindClass(env, "java/awt/Rectangle"));
685 bailif0(arrayRegionObj=(*env)->AllocObject(env, cls));
686 bailif0(fid=(*env)->GetFieldID(env, cls, "x", "I"));
687 (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.x);
688 bailif0(fid=(*env)->GetFieldID(env, cls, "y", "I"));
689 (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.y);
690 bailif0(fid=(*env)->GetFieldID(env, cls, "width", "I"));
691 (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.w);
692 bailif0(fid=(*env)->GetFieldID(env, cls, "height", "I"));
693 (*env)->SetIntField(env, arrayRegionObj, fid, arrayRegion.h);
694
695 bailif0(planeRegionObj=(*env)->AllocObject(env, cls));
696 bailif0(fid=(*env)->GetFieldID(env, cls, "x", "I"));
697 (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.x);
698 bailif0(fid=(*env)->GetFieldID(env, cls, "y", "I"));
699 (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.y);
700 bailif0(fid=(*env)->GetFieldID(env, cls, "width", "I"));
701 (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.w);
702 bailif0(fid=(*env)->GetFieldID(env, cls, "height", "I"));
703 (*env)->SetIntField(env, planeRegionObj, fid, planeRegion.h);
704
705 bailif0(cls=(*env)->GetObjectClass(env, cfobj));
706 bailif0(mid=(*env)->GetMethodID(env, cls, "customFilter",
707 "(Ljava/nio/ShortBuffer;Ljava/awt/Rectangle;Ljava/awt/Rectangle;IILorg/libjpegturbo/turbojpeg/TJTransform;)V"));
708 (*env)->CallVoidMethod(env, cfobj, mid, bufobj, arrayRegionObj,
709 planeRegionObj, componentIndex, transformIndex, tobj);
710
711 return 0;
712
713 bailout:
714 return -1;
715}
716
DRCa4940d12014-08-15 16:07:15 +0000717/* TurboJPEG 1.2.x: TJTransformer::transform() */
DRCe8573012011-03-04 10:13:59 +0000718JNIEXPORT jintArray JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_transform
DRC9b28def2011-05-21 14:37:15 +0000719 (JNIEnv *env, jobject obj, jbyteArray jsrcBuf, jint jpegSize,
DRCe8573012011-03-04 10:13:59 +0000720 jobjectArray dstobjs, jobjectArray tobjs, jint flags)
721{
722 tjhandle handle=0; int i;
DRC9b28def2011-05-21 14:37:15 +0000723 unsigned char *jpegBuf=NULL, **dstBufs=NULL; jsize n=0;
724 unsigned long *dstSizes=NULL; tjtransform *t=NULL;
725 jbyteArray *jdstBufs=NULL;
DRC9b49f0e2011-07-12 03:17:23 +0000726 int jpegWidth=0, jpegHeight=0, jpegSubsamp;
DRC9b28def2011-05-21 14:37:15 +0000727 jintArray jdstSizes=0; jint *dstSizesi=NULL;
DRCf5467112011-09-20 05:02:19 +0000728 JNICustomFilterParams *params=NULL;
DRCe8573012011-03-04 10:13:59 +0000729
730 gethandle();
731
DRC9b28def2011-05-21 14:37:15 +0000732 if((*env)->GetArrayLength(env, jsrcBuf)<jpegSize)
DRCe8573012011-03-04 10:13:59 +0000733 _throw("Source buffer is not large enough");
DRC26dd86b2014-08-15 14:01:21 +0000734 bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
DRCe8573012011-03-04 10:13:59 +0000735 jpegWidth=(int)(*env)->GetIntField(env, obj, _fid);
DRC26dd86b2014-08-15 14:01:21 +0000736 bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
DRCe8573012011-03-04 10:13:59 +0000737 jpegHeight=(int)(*env)->GetIntField(env, obj, _fid);
DRC26dd86b2014-08-15 14:01:21 +0000738 bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
DRC9b49f0e2011-07-12 03:17:23 +0000739 jpegSubsamp=(int)(*env)->GetIntField(env, obj, _fid);
DRCe8573012011-03-04 10:13:59 +0000740
741 n=(*env)->GetArrayLength(env, dstobjs);
742 if(n!=(*env)->GetArrayLength(env, tobjs))
743 _throw("Mismatch between size of transforms array and destination buffers array");
744
DRC9b28def2011-05-21 14:37:15 +0000745 if((dstBufs=(unsigned char **)malloc(sizeof(unsigned char *)*n))==NULL)
DRCe8573012011-03-04 10:13:59 +0000746 _throw("Memory allocation failure");
DRC9b28def2011-05-21 14:37:15 +0000747 if((jdstBufs=(jbyteArray *)malloc(sizeof(jbyteArray)*n))==NULL)
DRCe8573012011-03-04 10:13:59 +0000748 _throw("Memory allocation failure");
DRC9b28def2011-05-21 14:37:15 +0000749 if((dstSizes=(unsigned long *)malloc(sizeof(unsigned long)*n))==NULL)
DRCe8573012011-03-04 10:13:59 +0000750 _throw("Memory allocation failure");
751 if((t=(tjtransform *)malloc(sizeof(tjtransform)*n))==NULL)
752 _throw("Memory allocation failure");
DRCf5467112011-09-20 05:02:19 +0000753 if((params=(JNICustomFilterParams *)malloc(sizeof(JNICustomFilterParams)*n))
754 ==NULL)
755 _throw("Memory allocation failure");
DRCe8573012011-03-04 10:13:59 +0000756 for(i=0; i<n; i++)
757 {
DRC9b28def2011-05-21 14:37:15 +0000758 dstBufs[i]=NULL; jdstBufs[i]=NULL; dstSizes[i]=0;
DRCe8573012011-03-04 10:13:59 +0000759 memset(&t[i], 0, sizeof(tjtransform));
DRCf5467112011-09-20 05:02:19 +0000760 memset(&params[i], 0, sizeof(JNICustomFilterParams));
DRCe8573012011-03-04 10:13:59 +0000761 }
762
763 for(i=0; i<n; i++)
764 {
DRCf5467112011-09-20 05:02:19 +0000765 jobject tobj, cfobj;
DRCe8573012011-03-04 10:13:59 +0000766
767 bailif0(tobj=(*env)->GetObjectArrayElement(env, tobjs, i));
768 bailif0(_cls=(*env)->GetObjectClass(env, tobj));
769 bailif0(_fid=(*env)->GetFieldID(env, _cls, "op", "I"));
770 t[i].op=(*env)->GetIntField(env, tobj, _fid);
771 bailif0(_fid=(*env)->GetFieldID(env, _cls, "options", "I"));
772 t[i].options=(*env)->GetIntField(env, tobj, _fid);
773 bailif0(_fid=(*env)->GetFieldID(env, _cls, "x", "I"));
774 t[i].r.x=(*env)->GetIntField(env, tobj, _fid);
775 bailif0(_fid=(*env)->GetFieldID(env, _cls, "y", "I"));
776 t[i].r.y=(*env)->GetIntField(env, tobj, _fid);
777 bailif0(_fid=(*env)->GetFieldID(env, _cls, "width", "I"));
778 t[i].r.w=(*env)->GetIntField(env, tobj, _fid);
779 bailif0(_fid=(*env)->GetFieldID(env, _cls, "height", "I"));
780 t[i].r.h=(*env)->GetIntField(env, tobj, _fid);
DRCf5467112011-09-20 05:02:19 +0000781
DRCf5467112011-09-20 05:02:19 +0000782 bailif0(_fid=(*env)->GetFieldID(env, _cls, "cf",
783 "Lorg/libjpegturbo/turbojpeg/TJCustomFilter;"));
DRC06420c42011-09-26 18:46:09 +0000784 cfobj=(*env)->GetObjectField(env, tobj, _fid);
785 if(cfobj)
786 {
787 params[i].env=env;
788 params[i].tobj=tobj;
789 params[i].cfobj=cfobj;
790 t[i].customFilter=JNICustomFilter;
791 t[i].data=(void *)&params[i];
792 }
DRCe8573012011-03-04 10:13:59 +0000793 }
794
DRCe8573012011-03-04 10:13:59 +0000795 for(i=0; i<n; i++)
796 {
797 int w=jpegWidth, h=jpegHeight;
798 if(t[i].r.w!=0) w=t[i].r.w;
799 if(t[i].r.h!=0) h=t[i].r.h;
DRC9b28def2011-05-21 14:37:15 +0000800 bailif0(jdstBufs[i]=(*env)->GetObjectArrayElement(env, dstobjs, i));
DRCefe28ce2012-01-17 11:48:38 +0000801 if((unsigned long)(*env)->GetArrayLength(env, jdstBufs[i])
802 <tjBufSize(w, h, jpegSubsamp))
DRCe8573012011-03-04 10:13:59 +0000803 _throw("Destination buffer is not large enough");
DRCe8573012011-03-04 10:13:59 +0000804 }
DRC8951cf02014-08-14 16:54:04 +0000805 bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, jsrcBuf, 0));
806 for(i=0; i<n; i++)
807 bailif0(dstBufs[i]=(*env)->GetPrimitiveArrayCritical(env, jdstBufs[i], 0));
DRCe8573012011-03-04 10:13:59 +0000808
DRC9b28def2011-05-21 14:37:15 +0000809 if(tjTransform(handle, jpegBuf, jpegSize, n, dstBufs, dstSizes, t,
DRC4db92ad2011-05-25 04:52:25 +0000810 flags|TJFLAG_NOREALLOC)==-1)
DRCe8573012011-03-04 10:13:59 +0000811 _throw(tjGetErrorStr());
DRC8951cf02014-08-14 16:54:04 +0000812
813 for(i=0; i<n; i++)
814 {
815 (*env)->ReleasePrimitiveArrayCritical(env, jdstBufs[i], dstBufs[i], 0);
816 dstBufs[i]=NULL;
DRCe8573012011-03-04 10:13:59 +0000817 }
DRC8951cf02014-08-14 16:54:04 +0000818 (*env)->ReleasePrimitiveArrayCritical(env, jsrcBuf, jpegBuf, 0);
819 jpegBuf=NULL;
DRCe8573012011-03-04 10:13:59 +0000820
DRC9b28def2011-05-21 14:37:15 +0000821 jdstSizes=(*env)->NewIntArray(env, n);
822 bailif0(dstSizesi=(*env)->GetIntArrayElements(env, jdstSizes, 0));
823 for(i=0; i<n; i++) dstSizesi[i]=(int)dstSizes[i];
DRCe8573012011-03-04 10:13:59 +0000824
825 bailout:
DRC8951cf02014-08-14 16:54:04 +0000826 if(dstSizesi) (*env)->ReleaseIntArrayElements(env, jdstSizes, dstSizesi, 0);
DRC9b28def2011-05-21 14:37:15 +0000827 if(dstBufs)
DRCe8573012011-03-04 10:13:59 +0000828 {
829 for(i=0; i<n; i++)
830 {
DRC9b28def2011-05-21 14:37:15 +0000831 if(dstBufs[i] && jdstBufs && jdstBufs[i])
832 (*env)->ReleasePrimitiveArrayCritical(env, jdstBufs[i], dstBufs[i], 0);
DRCe8573012011-03-04 10:13:59 +0000833 }
DRC9b28def2011-05-21 14:37:15 +0000834 free(dstBufs);
DRCe8573012011-03-04 10:13:59 +0000835 }
DRC8951cf02014-08-14 16:54:04 +0000836 if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, jsrcBuf, jpegBuf, 0);
DRC9b28def2011-05-21 14:37:15 +0000837 if(jdstBufs) free(jdstBufs);
838 if(dstSizes) free(dstSizes);
DRCe8573012011-03-04 10:13:59 +0000839 if(t) free(t);
DRC9b28def2011-05-21 14:37:15 +0000840 return jdstSizes;
DRCe8573012011-03-04 10:13:59 +0000841}
842
DRCa4940d12014-08-15 16:07:15 +0000843/* TurboJPEG 1.2.x: TJDecompressor::destroy() */
DRCc5a41992011-02-08 06:54:36 +0000844JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_destroy
DRCf8e00552011-02-04 11:06:36 +0000845 (JNIEnv *env, jobject obj)
846{
DRCc5a41992011-02-08 06:54:36 +0000847 Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy(env, obj);
DRCf8e00552011-02-04 11:06:36 +0000848}