Add JNI wrapper for TurboJPEG/OSS


git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@337 632fc199-4ca6-4c93-a231-07263d6284db
diff --git a/java/README b/java/README
new file mode 100644
index 0000000..cc141e9
--- /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 0000000..ab8b3fb
--- /dev/null
+++ b/java/TJ.h
@@ -0,0 +1,47 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* 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 0000000..fa2c5ff
--- /dev/null
+++ b/java/tjCompressor.h
@@ -0,0 +1,37 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* 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 0000000..498112b
--- /dev/null
+++ b/java/tjDecompressor.h
@@ -0,0 +1,45 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* 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 0000000..5f92333
--- /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+" <Input file> <Output file>");
+        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 0000000..e5ecca7
--- /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;
+};