diff --git a/BUILDING.txt b/BUILDING.txt index 9da5f200..3cae8dfc 100644 --- a/BUILDING.txt +++ b/BUILDING.txt @@ -30,6 +30,10 @@ Build Requirements -- GCC v4.1 or later recommended for best performance +-- If building the TurboJPEG/OSS JNI wrapper, the Java Development Kit (JDK) + must be installed. On OS X 10.5 and later, instead install the Java + Developer Package, which can be obtained from http://connect.apple.com. + ================== Out-of-Tree Builds @@ -117,6 +121,14 @@ add --without-arith-enc or --without-arith-dec to the configure command line to disable encoding or decoding (respectively.) +TurboJPEG/OSS JNI Wrapper +------------------------- +Add --with-jni to the configure command line to incorporate an optional Java +Native Interface wrapper into the TurboJPEG/OSS dynamic library. This allows +the dynamic library to be used directly from Java applications. See +java/README for more details. + + ======================== Installing libjpeg-turbo ======================== diff --git a/ChangeLog.txt b/ChangeLog.txt index 87025ece..5c5a05d3 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,9 @@ +1.1.90 (1.2 beta1) +================== + +[1] Added a JNI wrapper for TurboJPEG/OSS. See java/README for more details. + + 1.1.0 ===== diff --git a/Makefile.am b/Makefile.am index 2f7e773e..aedec6d5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -34,12 +34,24 @@ libjpeg_la_SOURCES += jdarith.c endif -libturbojpeg_la_SOURCES = $(libjpeg_la_SOURCES) turbojpegl.c turbojpeg.h \ - turbojpeg-mapfile +libturbojpeg_la_SOURCES = $(libjpeg_la_SOURCES) turbojpegl.c turbojpeg.h + +if WITH_JNI + +libturbojpeg_la_SOURCES += turbojpeg-jni.c +TJMAPFILE = turbojpeg-mapfile.jni + +else + +TJMAPFILE = turbojpeg-mapfile + +endif + +libturbojpeg_la_SOURCES += $(TJMAPFILE) if ANON_VERSION_SCRIPT -libturbojpeg_la_LDFLAGS += $(ANON_VERSION_SCRIPT_FLAG)$(srcdir)/turbojpeg-mapfile +libturbojpeg_la_LDFLAGS += $(ANON_VERSION_SCRIPT_FLAG)$(srcdir)/$(TJMAPFILE) endif diff --git a/configure.ac b/configure.ac index aa16d837..0e1886f7 100644 --- a/configure.ac +++ b/configure.ac @@ -231,6 +231,16 @@ AM_CONDITIONAL([WITH_ARITH_DEC], [test "x$with_arith_dec" != "xno"]) AM_CONDITIONAL([WITH_ARITH], [test "x$with_arith_dec" != "xno" -o "x$with_arith_enc" != "xno"]) +AC_MSG_CHECKING([whether to include JNI wrapper in TurboJPEG/OSS]) +AC_ARG_WITH([jni], + AC_HELP_STRING([--with-jni],[Include JNI wrapper in the TurboJPEG/OSS library])) +if test "x$with_jni" = "xyes"; then + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi +AM_CONDITIONAL([WITH_JNI], [test "x$with_jni" = "xyes"]) + # SIMD is optional AC_ARG_WITH([simd], AC_HELP_STRING([--without-simd],[Omit accelerated SIMD routines.])) diff --git a/java/README b/java/README new file mode 100644 index 00000000..cc141e9e --- /dev/null +++ b/java/README @@ -0,0 +1,27 @@ +TurboJPEG/OSS JNI Wrapper +========================= + +TurboJPEG/OSS can optionally be built with a Java Native Interface wrapper, +which allows the TurboJPEG/OSS dynamic library to be loaded and used directly +from Java applications. The Java front end for this is defined in +turbojpeg.java, which should be located in the same directory as this README +file. turbojpeg.java is licensed under a BSD-style license, so it can be +incorporated directly into both open source and proprietary projects without +restriction. + +tjexample.java, which should also be located in the same directory as this +README file, demonstrates how to use the TurboJPEG/OSS Java front end to +compress and decompress JPEG images in memory. + + javac *.java + +builds .class files for both the front end and example code. + + +Note for OS X users +------------------- + +/usr/lib, the directory under which libturbojpeg.dylib is installed on Mac +systems, is not part of the normal Java library path. Thus, when running a +Java application that uses TurboJPEG/OSS on Mac systems, you will need to pass +an argument of -Djava.library.path=/usr/lib to java. diff --git a/java/TJ.h b/java/TJ.h new file mode 100644 index 00000000..ab8b3fba --- /dev/null +++ b/java/TJ.h @@ -0,0 +1,47 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class TJ */ + +#ifndef _Included_TJ +#define _Included_TJ +#ifdef __cplusplus +extern "C" { +#endif +#undef TJ_SAMP444 +#define TJ_SAMP444 0L +#undef TJ_SAMP422 +#define TJ_SAMP422 1L +#undef TJ_SAMP420 +#define TJ_SAMP420 2L +#undef TJ_GRAYSCALE +#define TJ_GRAYSCALE 3L +#undef TJ_BGR +#define TJ_BGR 1L +#undef TJ_BOTTOMUP +#define TJ_BOTTOMUP 2L +#undef TJ_FORCEMMX +#define TJ_FORCEMMX 8L +#undef TJ_FORCESSE +#define TJ_FORCESSE 16L +#undef TJ_FORCESSE2 +#define TJ_FORCESSE2 32L +#undef TJ_ALPHAFIRST +#define TJ_ALPHAFIRST 64L +#undef TJ_FORCESSE3 +#define TJ_FORCESSE3 128L +#undef TJ_FASTUPSAMPLE +#define TJ_FASTUPSAMPLE 256L +#undef TJ_YUV +#define TJ_YUV 512L +/* + * Class: TJ + * Method: BUFSIZE + * Signature: (II)J + */ +JNIEXPORT jlong JNICALL Java_TJ_BUFSIZE + (JNIEnv *, jobject, jint, jint); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/java/tjCompressor.h b/java/tjCompressor.h new file mode 100644 index 00000000..fa2c5ff3 --- /dev/null +++ b/java/tjCompressor.h @@ -0,0 +1,37 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class tjCompressor */ + +#ifndef _Included_tjCompressor +#define _Included_tjCompressor +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: tjCompressor + * Method: Init + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_tjCompressor_Init + (JNIEnv *, jobject); + +/* + * Class: tjCompressor + * Method: Destroy + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_tjCompressor_Destroy + (JNIEnv *, jobject); + +/* + * Class: tjCompressor + * Method: Compress + * Signature: ([BIIII[BIII)J + */ +JNIEXPORT jlong JNICALL Java_tjCompressor_Compress + (JNIEnv *, jobject, jbyteArray, jint, jint, jint, jint, jbyteArray, jint, jint, jint); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/java/tjDecompressor.h b/java/tjDecompressor.h new file mode 100644 index 00000000..498112b0 --- /dev/null +++ b/java/tjDecompressor.h @@ -0,0 +1,45 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class tjDecompressor */ + +#ifndef _Included_tjDecompressor +#define _Included_tjDecompressor +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: tjDecompressor + * Method: Init + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_tjDecompressor_Init + (JNIEnv *, jobject); + +/* + * Class: tjDecompressor + * Method: Destroy + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_tjDecompressor_Destroy + (JNIEnv *, jobject); + +/* + * Class: tjDecompressor + * Method: DecompressHeader + * Signature: ([BJ)LtjHeaderInfo; + */ +JNIEXPORT jobject JNICALL Java_tjDecompressor_DecompressHeader + (JNIEnv *, jobject, jbyteArray, jlong); + +/* + * Class: tjDecompressor + * Method: Decompress + * Signature: ([BJ[BIIIII)V + */ +JNIEXPORT void JNICALL Java_tjDecompressor_Decompress + (JNIEnv *, jobject, jbyteArray, jlong, jbyteArray, jint, jint, jint, jint, jint); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/java/tjexample.java b/java/tjexample.java new file mode 100644 index 00000000..5f923335 --- /dev/null +++ b/java/tjexample.java @@ -0,0 +1,91 @@ +/* + * Copyright (C)2011 D. R. Commander. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of the libjpeg-turbo Project nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This program demonstrates how to compress and decompress JPEG files using + * the TurboJPEG JNI wrapper + */ + +import java.io.*; + +public class tjexample { + + public static final String classname=new tjexample().getClass().getName(); + + public static void main(String argv[]) { + + try { + + if(argv.length<2) { + System.out.println("USAGE: java "+classname+" "); + System.exit(1); + } + + File file=new File(argv[0]); + FileInputStream fis=new FileInputStream(file); + int inputsize=fis.available(); + if(inputsize<1) { + System.out.println("Input file contains no data"); + System.exit(1); + } + byte [] inputbuf=new byte[inputsize]; + fis.read(inputbuf); + fis.close(); + + tjDecompressor tjd=new tjDecompressor(); + tjHeaderInfo tji=tjd.DecompressHeader(inputbuf, inputsize); + System.out.print("Source Image: "+tji.width+" x "+tji.height+ " pixels, "); + switch(tji.subsamp) { + case TJ.SAMP444: System.out.println("4:4:4 subsampling"); break; + case TJ.SAMP422: System.out.println("4:2:2 subsampling"); break; + case TJ.SAMP420: System.out.println("4:2:0 subsampling"); break; + case TJ.GRAYSCALE: System.out.println("Grayscale"); break; + default: System.out.println("Unknown subsampling"); break; + } + byte [] tmpbuf=new byte[tji.width*tji.height*3]; + tjd.Decompress(inputbuf, inputsize, tmpbuf, tji.width, tji.width*3, + tji.height, 3, TJ.BOTTOMUP); + tjd.close(); + + tjCompressor tjc=new tjCompressor(); + byte [] outputbuf=new byte[(int)TJ.BUFSIZE(tji.width, tji.height)]; + long outputsize=tjc.Compress(tmpbuf, tji.width, tji.width*3, tji.height, + 3, outputbuf, tji.subsamp, 95, TJ.BOTTOMUP); + tjc.close(); + + file=new File(argv[1]); + FileOutputStream fos=new FileOutputStream(file); + fos.write(outputbuf, 0, (int)outputsize); + fos.close(); + + } catch(Exception e) { + System.out.println(e); + } + } + +}; diff --git a/java/turbojpeg.java b/java/turbojpeg.java new file mode 100644 index 00000000..e5ecca79 --- /dev/null +++ b/java/turbojpeg.java @@ -0,0 +1,123 @@ +/* + * Copyright (C)2011 D. R. Commander. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of the libjpeg-turbo Project nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +final class TJ { + + // Subsampling options + final static int + SAMP444 = 0, + SAMP422 = 1, + SAMP420 = 2, + GRAYSCALE = 3; + + // Flags + final static int + BGR = 1, + BOTTOMUP = 2, + FORCEMMX = 8, + FORCESSE = 16, + FORCESSE2 = 32, + ALPHAFIRST = 64, + FORCESSE3 = 128, + FASTUPSAMPLE = 256, + YUV = 512; + + public native final static long BUFSIZE(int width, int height); +}; + +class tjCompressor { + + tjCompressor() throws Exception {Init();} + + public void close() throws Exception {Destroy();} + + protected void finalize() throws Throwable { + try { + close(); + } catch(Exception e) { + } + finally { + super.finalize(); + } + }; + + private native void Init() throws Exception; + + private native void Destroy() throws Exception; + + // JPEG size in bytes is returned + public native long Compress(byte [] srcbuf, int width, int pitch, + int height, int pixelsize, byte [] dstbuf, int jpegsubsamp, int jpegqual, + int flags) throws Exception; + + static { + System.loadLibrary("turbojpeg"); + } + + private long handle=0; +}; + +class tjHeaderInfo { + int subsamp=-1; + int width=-1; + int height=-1; +}; + +class tjDecompressor { + + tjDecompressor() throws Exception {Init();} + + public void close() throws Exception {Destroy();} + + protected void finalize() throws Throwable { + try { + close(); + } catch(Exception e) { + } + finally { + super.finalize(); + } + }; + + private native void Init() throws Exception; + + private native void Destroy() throws Exception; + + public native tjHeaderInfo DecompressHeader(byte [] srcbuf, long size) + throws Exception; + + public native void Decompress(byte [] srcbuf, long size, byte [] dstbuf, + int width, int pitch, int height, int pixelsize, int flags) + throws Exception; + + static { + System.loadLibrary("turbojpeg"); + } + + private long handle=0; +}; diff --git a/turbojpeg-jni.c b/turbojpeg-jni.c new file mode 100644 index 00000000..436a6dde --- /dev/null +++ b/turbojpeg-jni.c @@ -0,0 +1,200 @@ +/* + * Copyright (C)2011 D. R. Commander. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of the libjpeg-turbo Project nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "turbojpeg.h" +#include +#include "java/tjCompressor.h" +#include "java/tjDecompressor.h" +#include "java/TJ.h" + +#define _throw(msg) { \ + jclass _exccls=(*env)->FindClass(env, "java/lang/Exception"); \ + if(!_exccls) goto bailout; \ + (*env)->ThrowNew(env, _exccls, msg); \ + goto bailout; \ +} + +#define bailif0(f) {if(!(f)) goto bailout;} + +#define gethandle() { \ + jclass _cls=(*env)->GetObjectClass(env, obj); \ + jfieldID _fid; \ + if(!_cls) goto bailout; \ + bailif0(_fid=(*env)->GetFieldID(env, _cls, "handle", "J")); \ + handle=(tjhandle)(long)(*env)->GetLongField(env, obj, _fid); \ +} + +JNIEXPORT jlong JNICALL Java_TJ_BUFSIZE + (JNIEnv *env, jobject obj, jint width, jint height) +{ + return TJBUFSIZE(width, height); +} + +JNIEXPORT void JNICALL Java_tjCompressor_Init + (JNIEnv *env, jobject obj) +{ + jclass cls; + jfieldID fid; + tjhandle handle; + + if((handle=tjInitCompress())==NULL) + _throw(tjGetErrorStr()); + + bailif0(cls=(*env)->GetObjectClass(env, obj)); + bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J")); + (*env)->SetLongField(env, obj, fid, (long)handle); + + bailout: + return; +} + +JNIEXPORT jlong JNICALL Java_tjCompressor_Compress + (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch, + jint height, jint pixelsize, jbyteArray dst, jint jpegsubsamp, + jint jpegqual, jint flags) +{ + tjhandle handle=0; + unsigned long size=0; + jbyte *srcbuf=NULL, *dstbuf=NULL; + + gethandle(); + + bailif0(srcbuf=(*env)->GetPrimitiveArrayCritical(env, src, 0)); + bailif0(dstbuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0)); + + if(tjCompress(handle, srcbuf, width, pitch, height, pixelsize, dstbuf, + &size, jpegsubsamp, jpegqual, flags)==-1) + { + (*env)->ReleasePrimitiveArrayCritical(env, dst, dstbuf, 0); + (*env)->ReleasePrimitiveArrayCritical(env, src, srcbuf, 0); + _throw(tjGetErrorStr()); + } + + bailout: + if(dstbuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstbuf, 0); + if(srcbuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcbuf, 0); + return size; +} + +JNIEXPORT void JNICALL Java_tjCompressor_Destroy + (JNIEnv *env, jobject obj) +{ + tjhandle handle=0; + + gethandle(); + + if(tjDestroy(handle)==-1) _throw(tjGetErrorStr()); + + bailout: + return; +} + +JNIEXPORT void JNICALL Java_tjDecompressor_Init + (JNIEnv *env, jobject obj) +{ + jclass cls; + jfieldID fid; + tjhandle handle; + + if((handle=tjInitDecompress())==NULL) _throw(tjGetErrorStr()); + + bailif0(cls=(*env)->GetObjectClass(env, obj)); + bailif0(fid=(*env)->GetFieldID(env, cls, "handle", "J")); + (*env)->SetLongField(env, obj, fid, (long)handle); + + bailout: + return; +} + +JNIEXPORT jobject JNICALL Java_tjDecompressor_DecompressHeader + (JNIEnv *env, jobject obj, jbyteArray src, jlong size) +{ + jclass jhicls=NULL; + jfieldID fid; + tjhandle handle=0; + jbyte *srcbuf=NULL; + int width=0, height=0, jpegsubsamp=-1; + jobject jhiobj=NULL; + + gethandle(); + + bailif0(srcbuf=(*env)->GetPrimitiveArrayCritical(env, src, 0)); + + if(tjDecompressHeader2(handle, srcbuf, (unsigned long)size, + &width, &height, &jpegsubsamp)==-1) + { + (*env)->ReleasePrimitiveArrayCritical(env, src, srcbuf, 0); + _throw(tjGetErrorStr()); + } + (*env)->ReleasePrimitiveArrayCritical(env, src, srcbuf, 0); srcbuf=NULL; + + bailif0(jhicls=(*env)->FindClass(env, "tjHeaderInfo")); + bailif0(jhiobj=(*env)->AllocObject(env, jhicls)); + + bailif0(fid=(*env)->GetFieldID(env, jhicls, "subsamp", "I")); + (*env)->SetIntField(env, jhiobj, fid, jpegsubsamp); + bailif0(fid=(*env)->GetFieldID(env, jhicls, "width", "I")); + (*env)->SetIntField(env, jhiobj, fid, width); + bailif0(fid=(*env)->GetFieldID(env, jhicls, "height", "I")); + (*env)->SetIntField(env, jhiobj, fid, height); + + bailout: + return jhiobj; +} + +JNIEXPORT void JNICALL Java_tjDecompressor_Decompress + (JNIEnv *env, jobject obj, jbyteArray src, jlong size, jbyteArray dst, + jint width, jint pitch, jint height, jint pixelsize, jint flags) +{ + tjhandle handle=0; + jbyte *srcbuf=NULL, *dstbuf=NULL; + + gethandle(); + + bailif0(srcbuf=(*env)->GetPrimitiveArrayCritical(env, src, 0)); + bailif0(dstbuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0)); + + if(tjDecompress(handle, srcbuf, (unsigned long)size, dstbuf, width, pitch, + height, pixelsize, flags)==-1) + { + (*env)->ReleasePrimitiveArrayCritical(env, dst, dstbuf, 0); + (*env)->ReleasePrimitiveArrayCritical(env, src, srcbuf, 0); + _throw(tjGetErrorStr()); + } + + bailout: + if(dstbuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstbuf, 0); + if(srcbuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcbuf, 0); + return; +} + +JNIEXPORT void JNICALL Java_tjDecompressor_Destroy + (JNIEnv *env, jobject obj) +{ + Java_tjCompressor_Destroy(env, obj); +} diff --git a/turbojpeg-mapfile.jni b/turbojpeg-mapfile.jni new file mode 100755 index 00000000..47199f2d --- /dev/null +++ b/turbojpeg-mapfile.jni @@ -0,0 +1,22 @@ +{ + global: + tjInitCompress; + tjCompress; + TJBUFSIZE; + tjInitDecompress; + tjDecompressHeader; + tjDecompressHeader2; + tjDecompress; + tjDestroy; + tjGetErrorStr; + Java_TJ_BUFSIZE; + Java_tjCompressor_Init; + Java_tjCompressor_Compress; + Java_tjCompressor_Destroy; + Java_tjDecompressor_Init; + Java_tjDecompressor_DecompressHeader; + Java_tjDecompressor_Decompress; + Java_tjDecompressor_Destroy; + local: + *; +};