OLD | NEW |
(Empty) | |
| 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___3
BIIII_3BIII |
| 92 (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch, |
| 93 jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpe
gQual, |
| 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___3
IIIII_3BIII |
| 134 (JNIEnv *env, jobject obj, jintArray src, jint width, jint pitch, |
| 135 jint height, jint pf, jbyteArray dst, jint jpegSubsamp, jint jpe
gQual, |
| 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 int
eger 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_NOREALL
OC)==-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, subsam
p, |
| 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 intege
r 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_getScalingFact
ors |
| 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/TJScali
ngFactor")); |
| 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_decompress
Header |
| 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=NU
LL; |
| 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 int
eger 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_decompress
ToYUV |
| 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_transf
orm |
| 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 destinatio
n 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, jpeg
Subsamp)) |
| 558 _throw("Destination buffer is not large enough"); |
| 559 bailif0(dstBufs[i]=(*env)->GetPrimitiveArrayCritical(env, jdstBu
fs[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, jdstB
ufs[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 } |
OLD | NEW |