~tom-gall/libjpeg-turbo/upstream-1.2

« back to all changes in this revision

Viewing changes to turbojpeg-jni.c

  • Committer: Tom Gall
  • Date: 2011-08-15 23:41:58 UTC
  • Revision ID: tom.gall@linaro.org-20110815234158-yqcft1w9j8w3nnf6
merge in 1.1.90 from upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C)2011 D. R. Commander.  All Rights Reserved.
 
3
 *
 
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
 
 
29
#include <stdlib.h>
 
30
#include <string.h>
 
31
#include "turbojpeg.h"
 
32
#include <jni.h>
 
33
#include "java/org_libjpegturbo_turbojpeg_TJCompressor.h"
 
34
#include "java/org_libjpegturbo_turbojpeg_TJDecompressor.h"
 
35
#include "java/org_libjpegturbo_turbojpeg_TJ.h"
 
36
 
 
37
#define _throw(msg) {  \
 
38
        jclass _exccls=(*env)->FindClass(env, "java/lang/Exception");  \
 
39
        if(!_exccls) goto bailout;  \
 
40
        (*env)->ThrowNew(env, _exccls, msg);  \
 
41
        goto bailout;  \
 
42
}
 
43
 
 
44
#define bailif0(f) {if(!(f)) goto bailout;}
 
45
 
 
46
#define gethandle()  \
 
47
        jclass _cls=(*env)->GetObjectClass(env, obj);  \
 
48
        jfieldID _fid;  \
 
49
        if(!_cls) goto bailout;  \
 
50
        bailif0(_fid=(*env)->GetFieldID(env, _cls, "handle", "J"));  \
 
51
        handle=(tjhandle)(jlong)(*env)->GetLongField(env, obj, _fid);  \
 
52
 
 
53
JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSize
 
54
        (JNIEnv *env, jclass cls, jint width, jint height, jint jpegSubsamp)
 
55
{
 
56
        jint retval=(jint)tjBufSize(width, height, jpegSubsamp);
 
57
        if(retval==-1) _throw(tjGetErrorStr());
 
58
 
 
59
        bailout:
 
60
        return retval;
 
61
}
 
62
 
 
63
JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV
 
64
        (JNIEnv *env, jclass cls, jint width, jint height, jint subsamp)
 
65
{
 
66
        jint retval=(jint)tjBufSizeYUV(width, height, subsamp);
 
67
        if(retval==-1) _throw(tjGetErrorStr());
 
68
 
 
69
        bailout:
 
70
        return retval;
 
71
}
 
72
 
 
73
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_init
 
74
        (JNIEnv *env, jobject obj)
 
75
{
 
76
        jclass cls;
 
77
        jfieldID fid;
 
78
        tjhandle handle;
 
79
 
 
80
        if((handle=tjInitCompress())==NULL)
 
81
                _throw(tjGetErrorStr());
 
82
 
 
83
        bailif0(cls=(*env)->GetObjectClass(env, obj));
 
84
        bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J"));
 
85
        (*env)->SetLongField(env, obj, fid, (jlong)handle);
 
86
 
 
87
        bailout:
 
88
        return;
 
89
}
 
90
 
 
91
JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIII_3BIII
 
92
        (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch,
 
93
                jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpegQual,
 
94
                jint flags)
 
95
{
 
96
        tjhandle handle=0;
 
97
        unsigned long jpegSize=0;  jsize arraySize=0;
 
98
        unsigned char *srcBuf=NULL, *jpegBuf=NULL;
 
99
 
 
100
        gethandle();
 
101
 
 
102
        if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1
 
103
                || pitch<0)
 
104
                _throw("Invalid argument in compress()");
 
105
        if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
 
106
                _throw("Mismatch between Java and C API");
 
107
 
 
108
        arraySize=(pitch==0)? width*tjPixelSize[pf]*height:pitch*height;
 
109
        if((*env)->GetArrayLength(env, src)<arraySize)
 
110
                _throw("Source buffer is not large enough");
 
111
        jpegSize=tjBufSize(width, height, jpegSubsamp);
 
112
        if((*env)->GetArrayLength(env, dst)<(jsize)jpegSize)
 
113
                _throw("Destination buffer is not large enough");
 
114
 
 
115
        bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
 
116
        bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
 
117
 
 
118
        if(tjCompress2(handle, srcBuf, width, pitch, height, pf, &jpegBuf,
 
119
                &jpegSize, jpegSubsamp, jpegQual, flags|TJFLAG_NOREALLOC)==-1)
 
120
        {
 
121
                (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0);
 
122
                (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
 
123
                jpegBuf=srcBuf=NULL;
 
124
                _throw(tjGetErrorStr());
 
125
        }
 
126
 
 
127
        bailout:
 
128
        if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0);
 
129
        if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
 
130
        return (jint)jpegSize;
 
131
}
 
132
 
 
133
JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIII_3BIII
 
134
        (JNIEnv *env, jobject obj, jintArray src, jint width, jint pitch,
 
135
                jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpegQual,
 
136
                jint flags)
 
137
{
 
138
        tjhandle handle=0;
 
139
        unsigned long jpegSize=0;  jsize arraySize=0;
 
140
        unsigned char *srcBuf=NULL, *jpegBuf=NULL;
 
141
 
 
142
        gethandle();
 
143
 
 
144
        if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1
 
145
                || pitch<0)
 
146
                _throw("Invalid argument in compress()");
 
147
        if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
 
148
                _throw("Mismatch between Java and C API");
 
149
        if(tjPixelSize[pf]!=sizeof(jint))
 
150
                _throw("Pixel format must be 32-bit when compressing from an integer buffer.");
 
151
 
 
152
        arraySize=(pitch==0)? width*height:pitch*height;
 
153
        if((*env)->GetArrayLength(env, src)<arraySize)
 
154
                _throw("Source buffer is not large enough");
 
155
        jpegSize=tjBufSize(width, height, jpegSubsamp);
 
156
        if((*env)->GetArrayLength(env, dst)<(jsize)jpegSize)
 
157
                _throw("Destination buffer is not large enough");
 
158
 
 
159
        bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
 
160
        bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
 
161
 
 
162
        if(tjCompress2(handle, srcBuf, width, pitch*sizeof(jint), height, pf,
 
163
                &jpegBuf, &jpegSize, jpegSubsamp, jpegQual, flags|TJFLAG_NOREALLOC)==-1)
 
164
        {
 
165
                (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0);
 
166
                (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
 
167
                jpegBuf=srcBuf=NULL;
 
168
                _throw(tjGetErrorStr());
 
169
        }
 
170
 
 
171
        bailout:
 
172
        if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, jpegBuf, 0);
 
173
        if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
 
174
        return (jint)jpegSize;
 
175
}
 
176
 
 
177
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIII_3BII
 
178
        (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch,
 
179
                jint height, jint pf, jbyteArray dst, jint subsamp, jint flags)
 
180
{
 
181
        tjhandle handle=0;
 
182
        jsize arraySize=0;
 
183
        unsigned char *srcBuf=NULL, *dstBuf=NULL;
 
184
 
 
185
        gethandle();
 
186
 
 
187
        if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1
 
188
                || pitch<0)
 
189
                _throw("Invalid argument in encodeYUV()");
 
190
        if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
 
191
                _throw("Mismatch between Java and C API");
 
192
 
 
193
        arraySize=(pitch==0)? width*tjPixelSize[pf]*height:pitch*height;
 
194
        if((*env)->GetArrayLength(env, src)<arraySize)
 
195
                _throw("Source buffer is not large enough");
 
196
        if((*env)->GetArrayLength(env, dst)
 
197
                <(jsize)tjBufSizeYUV(width, height, subsamp))
 
198
                _throw("Destination buffer is not large enough");
 
199
 
 
200
        bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
 
201
        bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
 
202
 
 
203
        if(tjEncodeYUV2(handle, srcBuf, width, pitch, height, pf, dstBuf, subsamp,
 
204
                flags)==-1)
 
205
        {
 
206
                (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
 
207
                (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
 
208
                dstBuf=srcBuf=NULL;
 
209
                _throw(tjGetErrorStr());
 
210
        }
 
211
 
 
212
        bailout:
 
213
        if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
 
214
        if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
 
215
        return;
 
216
}
 
217
 
 
218
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIII_3BII
 
219
        (JNIEnv *env, jobject obj, jintArray src, jint width, jint pitch,
 
220
                jint height, jint pf, jbyteArray dst, jint subsamp, jint flags)
 
221
{
 
222
        tjhandle handle=0;
 
223
        jsize arraySize=0;
 
224
        unsigned char *srcBuf=NULL, *dstBuf=NULL;
 
225
 
 
226
        gethandle();
 
227
 
 
228
        if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF || width<1 || height<1
 
229
                || pitch<0)
 
230
                _throw("Invalid argument in compress()");
 
231
        if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
 
232
                _throw("Mismatch between Java and C API");
 
233
        if(tjPixelSize[pf]!=sizeof(jint))
 
234
                _throw("Pixel format must be 32-bit when encoding from an integer buffer.");
 
235
 
 
236
        arraySize=(pitch==0)? width*height:pitch*height;
 
237
        if((*env)->GetArrayLength(env, src)<arraySize)
 
238
                _throw("Source buffer is not large enough");
 
239
        if((*env)->GetArrayLength(env, dst)
 
240
                <(jsize)tjBufSizeYUV(width, height, subsamp))
 
241
                _throw("Destination buffer is not large enough");
 
242
 
 
243
        bailif0(srcBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
 
244
        bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
 
245
 
 
246
        if(tjEncodeYUV2(handle, srcBuf, width, pitch*sizeof(jint), height, pf,
 
247
                dstBuf, subsamp, flags)==-1)
 
248
        {
 
249
                (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
 
250
                (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
 
251
                dstBuf=srcBuf=NULL;
 
252
                _throw(tjGetErrorStr());
 
253
        }
 
254
 
 
255
        bailout:
 
256
        if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
 
257
        if(srcBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcBuf, 0);
 
258
        return;
 
259
}
 
260
 
 
261
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy
 
262
        (JNIEnv *env, jobject obj)
 
263
{
 
264
        tjhandle handle=0;
 
265
 
 
266
        gethandle();
 
267
 
 
268
        if(tjDestroy(handle)==-1) _throw(tjGetErrorStr());
 
269
        (*env)->SetLongField(env, obj, _fid, 0);
 
270
 
 
271
        bailout:
 
272
        return;
 
273
}
 
274
 
 
275
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_init
 
276
        (JNIEnv *env, jobject obj)
 
277
{
 
278
        jclass cls;
 
279
        jfieldID fid;
 
280
        tjhandle handle;
 
281
 
 
282
        if((handle=tjInitDecompress())==NULL) _throw(tjGetErrorStr());
 
283
 
 
284
        bailif0(cls=(*env)->GetObjectClass(env, obj));
 
285
        bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J"));
 
286
        (*env)->SetLongField(env, obj, fid, (jlong)handle);
 
287
 
 
288
        bailout:
 
289
        return;
 
290
}
 
291
 
 
292
JNIEXPORT jobjectArray JNICALL Java_org_libjpegturbo_turbojpeg_TJ_getScalingFactors
 
293
        (JNIEnv *env, jclass cls)
 
294
{
 
295
  jclass sfcls=NULL;  jfieldID fid=0;
 
296
        tjscalingfactor *sf=NULL;  int n=0, i;
 
297
        jobject sfobj=NULL;
 
298
        jobjectArray sfjava=NULL;
 
299
 
 
300
        if((sf=tjGetScalingFactors(&n))==NULL || n==0)
 
301
                _throw(tjGetErrorStr());
 
302
 
 
303
        bailif0(sfcls=(*env)->FindClass(env, "org/libjpegturbo/turbojpeg/TJScalingFactor"));
 
304
        bailif0(sfjava=(jobjectArray)(*env)->NewObjectArray(env, n, sfcls, 0));
 
305
 
 
306
        for(i=0; i<n; i++)
 
307
        {
 
308
                bailif0(sfobj=(*env)->AllocObject(env, sfcls));
 
309
                bailif0(fid=(*env)->GetFieldID(env, sfcls, "num", "I"));
 
310
                (*env)->SetIntField(env, sfobj, fid, sf[i].num);
 
311
                bailif0(fid=(*env)->GetFieldID(env, sfcls, "denom", "I"));
 
312
                (*env)->SetIntField(env, sfobj, fid, sf[i].denom);
 
313
                (*env)->SetObjectArrayElement(env, sfjava, i, sfobj);
 
314
        }
 
315
 
 
316
        bailout:
 
317
        return sfjava;
 
318
}
 
319
 
 
320
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressHeader
 
321
        (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize)
 
322
{
 
323
        tjhandle handle=0;
 
324
        unsigned char *jpegBuf=NULL;
 
325
        int width=0, height=0, jpegSubsamp=-1;
 
326
 
 
327
        gethandle();
 
328
 
 
329
        if((*env)->GetArrayLength(env, src)<jpegSize)
 
330
                _throw("Source buffer is not large enough");
 
331
 
 
332
        bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
 
333
 
 
334
        if(tjDecompressHeader2(handle, jpegBuf, (unsigned long)jpegSize, 
 
335
                &width, &height, &jpegSubsamp)==-1)
 
336
        {
 
337
                (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
 
338
                _throw(tjGetErrorStr());
 
339
        }
 
340
        (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);  jpegBuf=NULL;
 
341
 
 
342
        bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
 
343
        (*env)->SetIntField(env, obj, _fid, jpegSubsamp);
 
344
        bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
 
345
        (*env)->SetIntField(env, obj, _fid, width);
 
346
        bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
 
347
        (*env)->SetIntField(env, obj, _fid, height);
 
348
 
 
349
        bailout:
 
350
        return;
 
351
}
 
352
 
 
353
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIII
 
354
        (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
 
355
                jint width, jint pitch, jint height, jint pf, jint flags)
 
356
{
 
357
        tjhandle handle=0;
 
358
        jsize arraySize=0;
 
359
        unsigned char *jpegBuf=NULL, *dstBuf=NULL;
 
360
 
 
361
        gethandle();
 
362
 
 
363
        if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
 
364
                _throw("Invalid argument in decompress()");
 
365
        if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
 
366
                _throw("Mismatch between Java and C API");
 
367
 
 
368
        if((*env)->GetArrayLength(env, src)<jpegSize)
 
369
                _throw("Source buffer is not large enough");
 
370
        arraySize=(pitch==0)? width*tjPixelSize[pf]*height:pitch*height;
 
371
        if((*env)->GetArrayLength(env, dst)<arraySize)
 
372
                _throw("Destination buffer is not large enough");
 
373
 
 
374
        bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
 
375
        bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
 
376
 
 
377
        if(tjDecompress2(handle, jpegBuf, (unsigned long)jpegSize, dstBuf, width,
 
378
                pitch, height, pf, flags)==-1)
 
379
        {
 
380
                (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
 
381
                (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
 
382
                dstBuf=jpegBuf=NULL;
 
383
                _throw(tjGetErrorStr());
 
384
        }
 
385
 
 
386
        bailout:
 
387
        if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
 
388
        if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
 
389
        return;
 
390
}
 
391
 
 
392
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIII
 
393
        (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jintArray dst,
 
394
                jint width, jint pitch, jint height, jint pf, jint flags)
 
395
{
 
396
        tjhandle handle=0;
 
397
        jsize arraySize=0;
 
398
        unsigned char *jpegBuf=NULL, *dstBuf=NULL;
 
399
 
 
400
        gethandle();
 
401
 
 
402
        if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPF)
 
403
                _throw("Invalid argument in decompress()");
 
404
        if(org_libjpegturbo_turbojpeg_TJ_NUMPF!=TJ_NUMPF)
 
405
                _throw("Mismatch between Java and C API");
 
406
        if(tjPixelSize[pf]!=sizeof(jint))
 
407
                _throw("Pixel format must be 32-bit when decompressing to an integer buffer.");
 
408
 
 
409
        if((*env)->GetArrayLength(env, src)<jpegSize)
 
410
                _throw("Source buffer is not large enough");
 
411
        arraySize=(pitch==0)? width*height:pitch*height;
 
412
        if((*env)->GetArrayLength(env, dst)<arraySize)
 
413
                _throw("Destination buffer is not large enough");
 
414
 
 
415
        bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
 
416
        bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
 
417
 
 
418
        if(tjDecompress2(handle, jpegBuf, (unsigned long)jpegSize, dstBuf, width,
 
419
                pitch*sizeof(jint), height, pf, flags)==-1)
 
420
        {
 
421
                (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
 
422
                (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
 
423
                dstBuf=jpegBuf=NULL;
 
424
                _throw(tjGetErrorStr());
 
425
        }
 
426
 
 
427
        bailout:
 
428
        if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
 
429
        if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
 
430
        return;
 
431
}
 
432
 
 
433
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV
 
434
        (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst,
 
435
                jint flags)
 
436
{
 
437
        tjhandle handle=0;
 
438
        unsigned char *jpegBuf=NULL, *dstBuf=NULL;
 
439
        int jpegSubsamp=-1, jpegWidth=0, jpegHeight=0;
 
440
 
 
441
        gethandle();
 
442
 
 
443
        if((*env)->GetArrayLength(env, src)<jpegSize)
 
444
                _throw("Source buffer is not large enough");
 
445
        bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
 
446
        jpegSubsamp=(int)(*env)->GetIntField(env, obj, _fid);
 
447
        bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
 
448
        jpegWidth=(int)(*env)->GetIntField(env, obj, _fid);
 
449
        bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
 
450
        jpegHeight=(int)(*env)->GetIntField(env, obj, _fid);
 
451
        if((*env)->GetArrayLength(env, dst)
 
452
                <(jsize)tjBufSizeYUV(jpegWidth, jpegHeight, jpegSubsamp))
 
453
                _throw("Destination buffer is not large enough");
 
454
 
 
455
        bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
 
456
        bailif0(dstBuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
 
457
 
 
458
        if(tjDecompressToYUV(handle, jpegBuf, (unsigned long)jpegSize, dstBuf,
 
459
                flags)==-1)
 
460
        {
 
461
                (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
 
462
                (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
 
463
                dstBuf=jpegBuf=NULL;
 
464
                _throw(tjGetErrorStr());
 
465
        }
 
466
 
 
467
        bailout:
 
468
        if(dstBuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstBuf, 0);
 
469
        if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, src, jpegBuf, 0);
 
470
        return;
 
471
}
 
472
 
 
473
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_init
 
474
        (JNIEnv *env, jobject obj)
 
475
{
 
476
        jclass cls;
 
477
        jfieldID fid;
 
478
        tjhandle handle;
 
479
 
 
480
        if((handle=tjInitTransform())==NULL) _throw(tjGetErrorStr());
 
481
 
 
482
        bailif0(cls=(*env)->GetObjectClass(env, obj));
 
483
        bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J"));
 
484
        (*env)->SetLongField(env, obj, fid, (jlong)handle);
 
485
 
 
486
        bailout:
 
487
        return;
 
488
}
 
489
 
 
490
JNIEXPORT jintArray JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_transform
 
491
        (JNIEnv *env, jobject obj, jbyteArray jsrcBuf, jint jpegSize,
 
492
                jobjectArray dstobjs, jobjectArray tobjs, jint flags)
 
493
{
 
494
        tjhandle handle=0;  int i;
 
495
        unsigned char *jpegBuf=NULL, **dstBufs=NULL;  jsize n=0;
 
496
        unsigned long *dstSizes=NULL;  tjtransform *t=NULL;
 
497
        jbyteArray *jdstBufs=NULL;
 
498
        int jpegWidth=0, jpegHeight=0, jpegSubsamp;
 
499
        jintArray jdstSizes=0;  jint *dstSizesi=NULL;
 
500
 
 
501
        gethandle();
 
502
 
 
503
        if((*env)->GetArrayLength(env, jsrcBuf)<jpegSize)
 
504
                _throw("Source buffer is not large enough");
 
505
        bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
 
506
        jpegWidth=(int)(*env)->GetIntField(env, obj, _fid);
 
507
        bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
 
508
        jpegHeight=(int)(*env)->GetIntField(env, obj, _fid);
 
509
        bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
 
510
        jpegSubsamp=(int)(*env)->GetIntField(env, obj, _fid);
 
511
 
 
512
        n=(*env)->GetArrayLength(env, dstobjs);
 
513
        if(n!=(*env)->GetArrayLength(env, tobjs))
 
514
                _throw("Mismatch between size of transforms array and destination buffers array");
 
515
 
 
516
        if((dstBufs=(unsigned char **)malloc(sizeof(unsigned char *)*n))==NULL)
 
517
                _throw("Memory allocation failure");
 
518
        if((jdstBufs=(jbyteArray *)malloc(sizeof(jbyteArray)*n))==NULL)
 
519
                _throw("Memory allocation failure");
 
520
        if((dstSizes=(unsigned long *)malloc(sizeof(unsigned long)*n))==NULL)
 
521
                _throw("Memory allocation failure");
 
522
        if((t=(tjtransform *)malloc(sizeof(tjtransform)*n))==NULL)
 
523
                _throw("Memory allocation failure");
 
524
        for(i=0; i<n; i++)
 
525
        {
 
526
                dstBufs[i]=NULL;  jdstBufs[i]=NULL;  dstSizes[i]=0;
 
527
                memset(&t[i], 0, sizeof(tjtransform));
 
528
        }
 
529
 
 
530
        for(i=0; i<n; i++)
 
531
        {
 
532
                jobject tobj;
 
533
 
 
534
                bailif0(tobj=(*env)->GetObjectArrayElement(env, tobjs, i));
 
535
                bailif0(_cls=(*env)->GetObjectClass(env, tobj));
 
536
                bailif0(_fid=(*env)->GetFieldID(env, _cls, "op", "I"));
 
537
                t[i].op=(*env)->GetIntField(env, tobj, _fid);
 
538
                bailif0(_fid=(*env)->GetFieldID(env, _cls, "options", "I"));
 
539
                t[i].options=(*env)->GetIntField(env, tobj, _fid);
 
540
                bailif0(_fid=(*env)->GetFieldID(env, _cls, "x", "I"));
 
541
                t[i].r.x=(*env)->GetIntField(env, tobj, _fid);
 
542
                bailif0(_fid=(*env)->GetFieldID(env, _cls, "y", "I"));
 
543
                t[i].r.y=(*env)->GetIntField(env, tobj, _fid);
 
544
                bailif0(_fid=(*env)->GetFieldID(env, _cls, "width", "I"));
 
545
                t[i].r.w=(*env)->GetIntField(env, tobj, _fid);
 
546
                bailif0(_fid=(*env)->GetFieldID(env, _cls, "height", "I"));
 
547
                t[i].r.h=(*env)->GetIntField(env, tobj, _fid);
 
548
        }
 
549
 
 
550
        bailif0(jpegBuf=(*env)->GetPrimitiveArrayCritical(env, jsrcBuf, 0));
 
551
        for(i=0; i<n; i++)
 
552
        {
 
553
                int w=jpegWidth, h=jpegHeight;
 
554
                if(t[i].r.w!=0) w=t[i].r.w;
 
555
                if(t[i].r.h!=0) h=t[i].r.h;
 
556
                bailif0(jdstBufs[i]=(*env)->GetObjectArrayElement(env, dstobjs, i));
 
557
                if((*env)->GetArrayLength(env, jdstBufs[i])<tjBufSize(w, h, jpegSubsamp))
 
558
                        _throw("Destination buffer is not large enough");
 
559
                bailif0(dstBufs[i]=(*env)->GetPrimitiveArrayCritical(env, jdstBufs[i], 0));
 
560
        }
 
561
 
 
562
        if(tjTransform(handle, jpegBuf, jpegSize, n, dstBufs, dstSizes, t,
 
563
                flags|TJFLAG_NOREALLOC)==-1)
 
564
        {
 
565
                (*env)->ReleasePrimitiveArrayCritical(env, jsrcBuf, jpegBuf, 0);
 
566
                jpegBuf=NULL;
 
567
                for(i=0; i<n; i++)
 
568
                {
 
569
                        (*env)->ReleasePrimitiveArrayCritical(env, jdstBufs[i], dstBufs[i], 0);
 
570
                        dstBufs[i]=NULL;
 
571
                }
 
572
                _throw(tjGetErrorStr());
 
573
        }
 
574
 
 
575
        jdstSizes=(*env)->NewIntArray(env, n);
 
576
        bailif0(dstSizesi=(*env)->GetIntArrayElements(env, jdstSizes, 0));
 
577
        for(i=0; i<n; i++) dstSizesi[i]=(int)dstSizes[i];
 
578
 
 
579
        bailout:
 
580
        if(jpegBuf) (*env)->ReleasePrimitiveArrayCritical(env, jsrcBuf, jpegBuf, 0);
 
581
        if(dstBufs)
 
582
        {
 
583
                for(i=0; i<n; i++)
 
584
                {
 
585
                        if(dstBufs[i] && jdstBufs && jdstBufs[i])
 
586
                                (*env)->ReleasePrimitiveArrayCritical(env, jdstBufs[i], dstBufs[i], 0);
 
587
                }
 
588
                free(dstBufs);
 
589
        }
 
590
        if(jdstBufs) free(jdstBufs);
 
591
        if(dstSizes) free(dstSizes);
 
592
        if(dstSizesi) (*env)->ReleaseIntArrayElements(env, jdstSizes, dstSizesi, 0);
 
593
        if(t) free(t);
 
594
        return jdstSizes;
 
595
}
 
596
 
 
597
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_destroy
 
598
        (JNIEnv *env, jobject obj)
 
599
{
 
600
        Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy(env, obj);
 
601
}