]> granicus.if.org Git - libjpeg-turbo/commitdiff
Support for compressing from/decompressing to a BufferedImage in the Java wrapper
authorDRC <dcommander@users.sourceforge.net>
Wed, 23 Feb 2011 12:09:56 +0000 (12:09 +0000)
committerDRC <dcommander@users.sourceforge.net>
Wed, 23 Feb 2011 12:09:56 +0000 (12:09 +0000)
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@432 632fc199-4ca6-4c93-a231-07263d6284db

java/TJUnitTest.java
java/org/libjpegturbo/turbojpeg/TJCompressor.java
java/org/libjpegturbo/turbojpeg/TJDecompressor.java
java/org_libjpegturbo_turbojpeg_TJCompressor.h
java/org_libjpegturbo_turbojpeg_TJDecompressor.h
turbojpeg-jni.c
turbojpeg-mapfile.jni

index e52b1f8fb70c9928a6cf7042fcc94a22f1ca4372..227729ad76e1b2fb6a258e622a6c3f90fc25c6b8 100644 (file)
@@ -32,6 +32,8 @@
 
 import java.io.*;
 import java.util.*;
+import java.awt.image.*;
+import javax.imageio.*;
 import org.libjpegturbo.turbojpeg.*;
 
 public class TJUnitTest {
@@ -42,6 +44,7 @@ public class TJUnitTest {
                System.out.println("\nUSAGE: java "+classname+" [options]\n");
                System.out.println("Options:\n");
                System.out.println("-yuv = test YUV encoding/decoding support\n");
+               System.out.println("-bi = test BufferedImage support\n");
                System.exit(1);
        }
 
@@ -60,11 +63,18 @@ public class TJUnitTest {
                {1, 1, 1, 1, 2, 2, 0};
        private final static int _boffset[]=
                {2, 0, 2, 0, 1, 3, 0};
+       private final static int biType[]=
+               {0, BufferedImage.TYPE_3BYTE_BGR, BufferedImage.TYPE_INT_BGR,
+                       BufferedImage.TYPE_INT_RGB, 0, 0, BufferedImage.TYPE_BYTE_GRAY};
 
        private final static int _3byteFormats[]=
                {TJ.PF_RGB, TJ.PF_BGR};
+       private final static int _3byteFormatsBI[]=
+               {TJ.PF_BGR};
        private final static int _4byteFormats[]=
                {TJ.PF_RGBX, TJ.PF_BGRX, TJ.PF_XBGR, TJ.PF_XRGB};
+       private final static int _4byteFormatsBI[]=
+               {TJ.PF_RGBX, TJ.PF_BGRX};
        private final static int _onlyGray[]=
                {TJ.PF_GRAY};
        private final static int _onlyRGB[]=
@@ -72,6 +82,7 @@ public class TJUnitTest {
 
        private final static int YUVENCODE=1, YUVDECODE=2;
        private static int yuv=0;
+       private static boolean bi=false;
 
        private static int exitstatus=0;
 
@@ -149,6 +160,56 @@ public class TJUnitTest {
                }
        }
 
+       private static void initimg(BufferedImage img, int pf, int flags)
+       {
+               int i, _i, j, w=img.getWidth(), h=img.getHeight(), pixel;
+
+               if(pf==TJ.PF_GRAY)
+               {
+                       for(_i=0; _i<16; _i++)
+                       {
+                               if((flags&TJ.BOTTOMUP)!=0) i=h-_i-1;  else i=_i;
+                               for(j=0; j<w; j++)
+                               {
+                                       if(((_i/8)+(j/8))%2==0) pixel=0xFFFFFFFF;
+                                       else pixel=0xFF4C4C4C;
+                                       img.setRGB(j, i, pixel);
+                               }
+                       }
+                       for(_i=16; _i<h; _i++)
+                       {
+                               if((flags&TJ.BOTTOMUP)!=0) i=h-_i-1;  else i=_i;
+                               for(j=0; j<w; j++)
+                               {
+                                       if(((_i/8)+(j/8))%2==0) pixel=0xFF000000;
+                                       else pixel=0xFFE2E2E2;
+                                       img.setRGB(j, i, pixel);
+                               }
+                       }
+                       return;
+               }
+               for(_i=0; _i<16; _i++)
+               {
+                       if((flags&TJ.BOTTOMUP)!=0) i=h-_i-1;  else i=_i;
+                       for(j=0; j<w; j++)
+                       {
+                               pixel=0xFFFF0000;
+                               if(((_i/8)+(j/8))%2==0) pixel|=0x0000FFFF;
+                               img.setRGB(j, i, pixel);
+                       }
+               }
+               for(_i=16; _i<h; _i++)
+               {
+                       if((flags&TJ.BOTTOMUP)!=0) i=h-_i-1;  else i=_i;
+                       for(j=0; j<w; j++)
+                       {
+                               pixel=0;
+                               if(((_i/8)+(j/8))%2!=0) pixel=0xFFFFFF00;
+                               img.setRGB(j, i, pixel);
+                       }
+               }
+       }
+
        private static void dumpbuf(byte [] buf, int w, int h, int pf,
                int scalefactor, int flags)
        {
@@ -171,33 +232,33 @@ public class TJUnitTest {
                }
        }
 
-       private static void checkval(int i, int j, byte v, String vname, int cvi)
+       private static void checkval(int i, int j, int v, String vname, int cv)
                throws Exception
        {
-               int vi=(v<0)? v+256:v;
-               if(vi<cvi-1 || vi>cvi+1)
+               v=(v<0)? v+256:v;
+               if(v<cv-1 || v>cv+1)
                {
-                       throw new Exception("\nComp. "+vname+" at "+i+","+j+" should be "+cvi
+                       throw new Exception("\nComp. "+vname+" at "+i+","+j+" should be "+cv
                                +", not "+v+"\n");
                }
        }
 
-       private static void checkval0(int i, int j, byte v, String vname)
+       private static void checkval0(int i, int j, int v, String vname)
                throws Exception
        {
-               int vi=(v<0)? v+256:v;
-               if(vi>1)
+               v=(v<0)? v+256:v;
+               if(v>1)
                {
                        throw new Exception("\nComp. "+vname+" at "+i+","+j+" should be 0, not "
                                +v+"\n");
                }
        }
 
-       private static void checkval255(int i, int j, byte v, String vname)
+       private static void checkval255(int i, int j, int v, String vname)
                throws Exception
        {
-               int vi=(v<0)? v+256:v;
-               if(vi<254 && !(vi==217 && i==0 && j==21))
+               v=(v<0)? v+256:v;
+               if(v<254 && !(v==217 && i==0 && j==21))
                {
                        throw new Exception("\nComp. "+vname+" at "+i+","+j+" should be 255, not "
                                +v+"\n");
@@ -309,6 +370,115 @@ public class TJUnitTest {
                return retval;
        }
 
+       private static int checkimg(BufferedImage img, int pf,
+               int subsamp, int scalefactor, int flags) throws Exception
+       {
+               int i, _i, j, retval=1, w=img.getWidth(), h=img.getHeight();
+               int halfway=16/scalefactor, blocksize=8/scalefactor;
+
+               try
+               {
+                       if(subsamp==TJ.SAMP_GRAY)
+                       {
+                               for(_i=0; _i<halfway; _i++)
+                               {
+                                       if((flags&TJ.BOTTOMUP)!=0) i=h-_i-1;  else i=_i;
+                                       for(j=0; j<w; j++)
+                                       {
+                                               int r=(img.getRGB(j, i)>>16) & 0xFF;
+                                               int g=(img.getRGB(j, i)>>8) & 0xFF;
+                                               int b=img.getRGB(j, i) & 0xFF;
+                                               if(((_i/blocksize)+(j/blocksize))%2==0)
+                                               {
+                                                       checkval255(_i, j, r, "R");
+                                                       checkval255(_i, j, g, "G");
+                                                       checkval255(_i, j, b, "B");
+                                               }
+                                               else
+                                               {
+                                                       checkval(_i, j, r, "R", 76);
+                                                       checkval(_i, j, g, "G", 76);
+                                                       checkval(_i, j, b, "B", 76);
+                                               }
+                                       }
+                               }
+                               for(_i=halfway; _i<h; _i++)
+                               {
+                                       if((flags&TJ.BOTTOMUP)!=0) i=h-_i-1;  else i=_i;
+                                       for(j=0; j<w; j++)
+                                       {
+                                               int r=(img.getRGB(j, i)>>16) & 0xFF;
+                                               int g=(img.getRGB(j, i)>>8) & 0xFF;
+                                               int b=img.getRGB(j, i) & 0xFF;
+                                               if(((_i/blocksize)+(j/blocksize))%2==0)
+                                               {
+                                                       checkval0(_i, j, r, "R");
+                                                       checkval0(_i, j, g, "G");
+                                                       checkval0(_i, j, b, "B");
+                                               }
+                                               else
+                                               {
+                                                       checkval(_i, j, r, "R", 226);
+                                                       checkval(_i, j, g, "G", 226);
+                                                       checkval(_i, j, b, "B", 226);
+                                               }
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               for(_i=0; _i<halfway; _i++)
+                               {
+                                       if((flags&TJ.BOTTOMUP)!=0) i=h-_i-1;  else i=_i;
+                                       for(j=0; j<w; j++)
+                                       {
+                                               int r=(img.getRGB(j, i)>>16) & 0xFF;
+                                               int g=(img.getRGB(j, i)>>8) & 0xFF;
+                                               int b=img.getRGB(j, i) & 0xFF;
+                                               checkval255(_i, j, r, "R");
+                                               if(((_i/blocksize)+(j/blocksize))%2==0)
+                                               {
+                                                       checkval255(_i, j, g, "G");
+                                                       checkval255(_i, j, b, "B");
+                                               }
+                                               else
+                                               {
+                                                       checkval0(_i, j, g, "G");
+                                                       checkval0(_i, j, b, "B");
+                                               }
+                                       }
+                               }
+                               for(_i=halfway; _i<h; _i++)
+                               {
+                                       if((flags&TJ.BOTTOMUP)!=0) i=h-_i-1;  else i=_i;
+                                       for(j=0; j<w; j++)
+                                       {
+                                               int r=(img.getRGB(j, i)>>16) & 0xFF;
+                                               int g=(img.getRGB(j, i)>>8) & 0xFF;
+                                               int b=img.getRGB(j, i) & 0xFF;
+                                               checkval0(_i, j, b, "B");
+                                               if(((_i/blocksize)+(j/blocksize))%2==0)
+                                               {
+                                                       checkval0(_i, j, r, "R");
+                                                       checkval0(_i, j, g, "G");
+                                               }
+                                               else
+                                               {
+                                                       checkval255(_i, j, r, "R");
+                                                       checkval255(_i, j, g, "G");
+                                               }
+                                       }
+                               }
+                       }
+               }
+               catch(Exception e)
+               {
+                       System.out.println(e);
+                       retval=0;
+               }
+               return retval;
+       }
+
        private static int PAD(int v, int p)
        {
                return ((v+(p)-1)&(~((p)-1)));
@@ -444,9 +614,9 @@ public class TJUnitTest {
                int h, int pf, String basefilename, int subsamp, int qual,
                int flags) throws Exception
        {
-               String tempstr;  byte [] bmpbuf;
+               String tempstr;  byte [] bmpbuf=null;  BufferedImage img=null;
                String pixformat;  double t;
-               int size=0;
+               int size=0, ps=TJ.pixelSize[pf];
 
                if(yuv==YUVENCODE) flags|=TJ.YUV;
 
@@ -459,13 +629,31 @@ public class TJUnitTest {
                if(yuv==YUVENCODE) System.out.print("YUV ... ");
                else System.out.print("Q"+qual+" ... ");
 
-               bmpbuf=new byte[w*h*TJ.pixelSize[pf]+1];
-               initbuf(bmpbuf, w, h, pf, flags);
+               if(bi)
+               {
+                       img=new BufferedImage(w, h, biType[pf]);
+                       initimg(img, pf, flags);
+                       tempstr=basefilename+"_enc_"+pixformat+"_"
+                               +(((flags&TJ.BOTTOMUP)!=0)? "BU":"TD")+"_"+_subnames[subsamp]
+                               +"_Q"+qual+".png";
+                       File file=new File(tempstr);
+                       ImageIO.write(img, "png", file);
+               }
+               else
+               {
+                       bmpbuf=new byte[w*h*ps+1];
+                       initbuf(bmpbuf, w, h, pf, flags);
+               }
                Arrays.fill(jpegbuf, (byte)0);
 
                t=gettime();
-               tjc.setBitmapBuffer(bmpbuf, w, 0, h, pf);
-               size=tjc.compress(jpegbuf, subsamp, qual, flags);
+               if(bi)
+                       size=tjc.compress(img, jpegbuf, subsamp, qual, flags);
+               else
+               {
+                       tjc.setBitmapBuffer(bmpbuf, w, 0, h, pf);
+                       size=tjc.compress(jpegbuf, subsamp, qual, flags);
+               }
                t=gettime()-t;
 
                if(yuv==YUVENCODE)
@@ -476,6 +664,7 @@ public class TJUnitTest {
                                +(((flags&TJ.BOTTOMUP)!=0)? "BU":"TD")+"_"+_subnames[subsamp]
                                +"_Q"+qual+".jpg";
                writejpeg(jpegbuf, size, tempstr);
+
                if(yuv==YUVENCODE)
                {
                        if(checkbufyuv(jpegbuf, size, w, h, subsamp)==1)
@@ -493,10 +682,12 @@ public class TJUnitTest {
                int jpegsize, int w, int h, int pf, String basefilename, int subsamp,
                int flags, int scalefactor) throws Exception
        {
-               String pixformat;  int _hdrw=0, _hdrh=0, _hdrsubsamp=-1;  double t;
+               String pixformat, tempstr;  int _hdrw=0, _hdrh=0, _hdrsubsamp=-1;
+               double t;
                int scaledw=(w+scalefactor-1)/scalefactor;
                int scaledh=(h+scalefactor-1)/scalefactor;
                int temp1, temp2;
+               BufferedImage img=null;  byte [] bmpbuf=null;
 
                if(yuv==YUVDECODE) flags|=TJ.YUV;
                else if(yuv==YUVENCODE) return;
@@ -525,9 +716,24 @@ public class TJUnitTest {
                if(temp1!=scaledw || temp2!=scaledh)
                        throw new Exception("Scaled size mismatch");
 
-               byte [] bmpbuf=tjd.decompress(scaledw, 0, scaledh, pf, flags);
+               if(bi)
+               {
+                       img=new BufferedImage(scaledw, scaledh, biType[pf]);
+                       tjd.decompress(img, flags);
+               }
+               else
+                       bmpbuf=tjd.decompress(scaledw, 0, scaledh, pf, flags);
                t=gettime()-t;
 
+               if(bi)
+               {
+                       tempstr=basefilename+"_dec_"+pixformat+"_"
+                               +(((flags&TJ.BOTTOMUP)!=0)? "BU":"TD")+"_"+_subnames[subsamp]
+                               +"_"+scalefactor+"x"+".png";
+                       File file=new File(tempstr);
+                       ImageIO.write(img, "png", file);
+               }
+
                if(yuv==YUVDECODE)
                {
                        if(checkbufyuv(bmpbuf, bmpbuf.length, w, h, subsamp)==1)
@@ -536,13 +742,15 @@ public class TJUnitTest {
                }
                else
                {
-                       if(checkbuf(bmpbuf, scaledw, scaledh, pf, subsamp, scalefactor, flags)
-                               ==1)
+                       if((bi && checkimg(img, pf, subsamp, scalefactor, flags)==1)
+                               || (!bi && checkbuf(bmpbuf, scaledw, scaledh, pf, subsamp, scalefactor,
+                               flags)==1))
                                System.out.print("Passed.");
                        else
                        {
                                System.out.print("FAILED!");  exitstatus=-1;
-                               dumpbuf(bmpbuf, scaledw, scaledh, pf, scalefactor, flags);
+                               if(bmpbuf!=null)
+                                       dumpbuf(bmpbuf, scaledw, scaledh, pf, scalefactor, flags);
                        }
                }
                System.out.format("  %.6f ms\n", t*1000.);
@@ -669,10 +877,13 @@ public class TJUnitTest {
                                if(argv[i].substring(0, 1).equalsIgnoreCase("-h")
                                        || argv[i].equalsIgnoreCase("-?"))
                                        usage();
+                               if(argv[i].equalsIgnoreCase("-bi")) bi=true;
                        }
+                       if(bi && doyuv)
+                               throw new Exception("-bi and -yuv cannot be used together.");
                        if(doyuv) yuv=YUVENCODE;
-                       dotest(35, 39, _3byteFormats, TJ.SAMP_444, "test");
-                       dotest(39, 41, _4byteFormats, TJ.SAMP_444, "test");
+                       dotest(35, 39, bi? _3byteFormatsBI:_3byteFormats, TJ.SAMP_444, "test");
+                       dotest(39, 41, bi? _4byteFormatsBI:_4byteFormats, TJ.SAMP_444, "test");
                        if(doyuv)
                        {
                                dotest(41, 35, _3byteFormats, TJ.SAMP_422, "test");
@@ -681,9 +892,9 @@ public class TJUnitTest {
                                dotest(41, 35, _4byteFormats, TJ.SAMP_420, "test");
                        }
                        dotest(35, 39, _onlyGray, TJ.SAMP_GRAY, "test");
-                       dotest(39, 41, _3byteFormats, TJ.SAMP_GRAY, "test");
-                       dotest(41, 35, _4byteFormats, TJ.SAMP_GRAY, "test");
-                       if(!doyuv) dotest1();
+                       dotest(39, 41, bi? _3byteFormatsBI:_3byteFormats, TJ.SAMP_GRAY, "test");
+                       dotest(41, 35, bi? _4byteFormatsBI:_4byteFormats, TJ.SAMP_GRAY, "test");
+                       if(!doyuv && !bi) dotest1();
                        if(doyuv)
                        {
                                yuv=YUVDECODE;
@@ -700,6 +911,7 @@ public class TJUnitTest {
                catch(Exception e)
                {
                        System.out.println(e);
+                       exitstatus=-1;
                }
                System.exit(exitstatus);
        }
index 8833570c5e7af5b6c41de695bdc4e5cb477b2330..0fcffacafca7fde049748f9504cddcacd6d6315d 100644 (file)
@@ -28,6 +28,8 @@
 
 package org.libjpegturbo.turbojpeg;
 
+import java.awt.image.*;
+
 public class TJCompressor {
 
   public TJCompressor() throws Exception {
@@ -60,6 +62,50 @@ public class TJCompressor {
         flags | TJ.getFlags(bitmapPixelFormat));
   }
 
+  public int compress(BufferedImage srcImage, byte [] dstBuf, int jpegSubsamp,
+    int jpegQual, int flags) throws Exception {
+    if(srcImage == null || flags < 0)
+      throw new Exception("Invalid argument in decompress()");
+    flags &= ~(TJ.YUV);
+    int width = srcImage.getWidth();
+    int height = srcImage.getHeight();
+    int pixelFormat;  boolean intPixels=false;
+    switch(srcImage.getType()) {
+      case BufferedImage.TYPE_3BYTE_BGR:
+        pixelFormat=TJ.PF_BGR;  break;
+      case BufferedImage.TYPE_BYTE_GRAY:
+        pixelFormat=TJ.PF_GRAY;  break;
+      case BufferedImage.TYPE_INT_BGR:
+        pixelFormat=TJ.PF_RGBX;  intPixels=true;  break;
+      case BufferedImage.TYPE_INT_RGB:
+        pixelFormat=TJ.PF_BGRX;  intPixels=true;  break;
+      default:
+        throw new Exception("Unsupported BufferedImage format");
+    }
+    WritableRaster wr = srcImage.getRaster();
+    if(intPixels) {
+      SinglePixelPackedSampleModel sm =
+        (SinglePixelPackedSampleModel)srcImage.getSampleModel();
+      int pitch = sm.getScanlineStride();
+      DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
+      int [] buf = db.getData();
+      return compress(buf, width, pitch, height, dstBuf, jpegSubsamp, jpegQual,
+        flags | TJ.getFlags(pixelFormat));
+    }
+    else {
+      ComponentSampleModel sm =
+        (ComponentSampleModel)srcImage.getSampleModel();
+      int pixelSize = sm.getPixelStride();
+      if(pixelSize != TJ.pixelSize[pixelFormat])
+        throw new Exception("Inconsistency between pixel format and pixel size in BufferedImage");
+      int pitch = sm.getScanlineStride();
+      DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
+      byte [] buf = db.getData();
+      return compress(buf, width, pitch, height, TJ.getPixelSize(pixelFormat),
+        dstBuf, jpegSubsamp, jpegQual, flags | TJ.getFlags(pixelFormat));
+    }
+  }
+
   public void close() throws Exception {
     destroy();
   }
@@ -83,6 +129,10 @@ public class TJCompressor {
     int height, int pixelSize, byte [] dstbuf, int jpegSubsamp, int jpegQual,
     int flags) throws Exception;
 
+  private native int compress(int [] srcBuf, int width, int pitch,
+    int height, byte [] dstbuf, int jpegSubsamp, int jpegQual, int flags)
+    throws Exception;
+
   static {
     System.loadLibrary("turbojpeg");
   }
index 01d5e9ce591725859e7ebc3bff6e8d6e4f2377f5..08d0bbd8df23c83827fd8a16c63573f09ae556e5 100644 (file)
@@ -28,6 +28,8 @@
 
 package org.libjpegturbo.turbojpeg;
 
+import java.awt.image.*;
+
 public class TJDecompressor {
 
   public TJDecompressor() throws Exception {
@@ -66,49 +68,96 @@ public class TJDecompressor {
     return jpegSubsamp;
   }
 
-  public int getScaledWidth(int desired_width, int desired_height)
+  public int getScaledWidth(int desiredWidth, int desiredHeight)
     throws Exception {
     if(jpegWidth < 1 || jpegHeight < 1)
       throw new Exception("JPEG buffer not initialized");
-    return getScaledWidth(jpegWidth, jpegHeight, desired_width,
-      desired_height);
+    return getScaledWidth(jpegWidth, jpegHeight, desiredWidth,
+      desiredHeight);
   }
 
-  public int getScaledHeight(int output_width, int output_height)
+  public int getScaledHeight(int desiredWidth, int desiredHeight)
     throws Exception {
     if(jpegWidth < 1 || jpegHeight < 1)
       throw new Exception("JPEG buffer not initialized");
-    return getScaledHeight(jpegWidth, jpegHeight, output_width,
-      output_height);
+    return getScaledHeight(jpegWidth, jpegHeight, desiredWidth,
+      desiredHeight);
   }
 
-  public void decompress(byte [] dstBuf, int width, int pitch,
-    int height, int pixelFormat, int flags) throws Exception {
+  public void decompress(byte [] dstBuf, int desiredWidth, int pitch,
+    int desiredHeight, int pixelFormat, int flags) throws Exception {
     if(jpegBuf == null) throw new Exception("JPEG buffer not initialized");
-    decompress(jpegBuf, jpegBufSize, dstBuf, width, pitch, height,
-      TJ.getPixelSize(pixelFormat), flags | TJ.getFlags(pixelFormat));
+    decompress(jpegBuf, jpegBufSize, dstBuf, desiredWidth, pitch,
+      desiredHeight, TJ.getPixelSize(pixelFormat),
+      flags | TJ.getFlags(pixelFormat));
   }
 
-  public byte [] decompress(int width, int pitch, int height,
+  public byte [] decompress(int desiredWidth, int pitch, int desiredHeight,
     int pixelFormat, int flags) throws Exception {
-    if(width < 0 || height < 0 || pitch < 0 || pixelFormat < 0
-      || pixelFormat >= TJ.NUMPFOPT)
+    if(desiredWidth < 0 || desiredHeight < 0 || pitch < 0 || pixelFormat < 0
+      || pixelFormat >= TJ.NUMPFOPT || flags < 0)
       throw new Exception("Invalid argument in decompress()");
     int pixelSize = TJ.getPixelSize(pixelFormat);
-    int scaledWidth = getScaledWidth(width, height);
-    int scaledHeight = getScaledHeight(width, height);
+    int scaledWidth = getScaledWidth(desiredWidth, desiredHeight);
+    int scaledHeight = getScaledHeight(desiredWidth, desiredHeight);
     if(pitch == 0) pitch = scaledWidth * pixelSize;
     int bufSize;
     if((flags&TJ.YUV)!=0)
-      bufSize = TJ.bufSizeYUV(width, height, jpegSubsamp);
+      bufSize = TJ.bufSizeYUV(jpegWidth, jpegHeight, jpegSubsamp);
     else bufSize = pitch * scaledHeight;
     byte [] buf = new byte[bufSize];
     if(jpegBuf == null) throw new Exception("JPEG buffer not initialized");
-    decompress(jpegBuf, jpegBufSize, buf, width, pitch, height,
+    decompress(jpegBuf, jpegBufSize, buf, desiredWidth, pitch, desiredHeight,
       TJ.getPixelSize(pixelFormat), flags | TJ.getFlags(pixelFormat));
     return buf;
   }
 
+  public void decompress(BufferedImage dstImage, int flags) throws Exception {
+    if(dstImage == null || flags < 0)
+      throw new Exception("Invalid argument in decompress()");
+    flags &= ~(TJ.YUV);
+    int desiredWidth = dstImage.getWidth();
+    int desiredHeight = dstImage.getHeight();
+    int scaledWidth = getScaledWidth(desiredWidth, desiredHeight);
+    int scaledHeight = getScaledHeight(desiredWidth, desiredHeight);
+    if(scaledWidth != desiredWidth || scaledHeight != desiredHeight)
+      throw new Exception("BufferedImage dimensions do not match a scaled image size that TurboJPEG is capable of generating.");
+    int pixelFormat;  boolean intPixels=false;
+    switch(dstImage.getType()) {
+      case BufferedImage.TYPE_3BYTE_BGR:
+        pixelFormat=TJ.PF_BGR;  break;
+      case BufferedImage.TYPE_BYTE_GRAY:
+        pixelFormat=TJ.PF_GRAY;  break;
+      case BufferedImage.TYPE_INT_BGR:
+        pixelFormat=TJ.PF_RGBX;  intPixels=true;  break;
+      case BufferedImage.TYPE_INT_RGB:
+        pixelFormat=TJ.PF_BGRX;  intPixels=true;  break;
+      default:
+        throw new Exception("Unsupported BufferedImage format");
+    }
+    WritableRaster wr = dstImage.getRaster();
+    if(intPixels) {
+      SinglePixelPackedSampleModel sm =
+        (SinglePixelPackedSampleModel)dstImage.getSampleModel();
+      int pitch = sm.getScanlineStride();
+      DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
+      int [] buf = db.getData();
+      decompress(jpegBuf, jpegBufSize, buf, scaledWidth, pitch, scaledHeight,
+        flags | TJ.getFlags(pixelFormat));
+    }
+    else {
+      ComponentSampleModel sm =
+        (ComponentSampleModel)dstImage.getSampleModel();
+      int pixelSize = sm.getPixelStride();
+      if(pixelSize != TJ.pixelSize[pixelFormat])
+        throw new Exception("Inconsistency between pixel format and pixel size in BufferedImage");
+      int pitch = sm.getScanlineStride();
+      DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
+      byte [] buf = db.getData();
+      decompress(buf, scaledWidth, pitch, scaledHeight, pixelFormat, flags);
+    }
+  }
+
   public void close() throws Exception {
     destroy();
   }
@@ -131,14 +180,18 @@ public class TJDecompressor {
     throws Exception;
 
   private native void decompress(byte [] srcBuf, int size, byte [] dstBuf,
-    int width, int pitch, int height, int pixelSize, int flags)
+    int desiredWidth, int pitch, int desiredHeight, int pixelSize, int flags)
+    throws Exception;
+
+  private native void decompress(byte [] srcBuf, int size, int [] dstBuf,
+    int desiredWidth, int pitch, int desiredHeight, int flags)
     throws Exception;
 
-  private native int getScaledWidth(int input_width, int input_height,
-    int output_width, int output_height) throws Exception;
+  private native int getScaledWidth(int jpegWidth, int jpegHeight,
+    int desiredWidth, int desiredHeight) throws Exception;
 
-  private native int getScaledHeight(int input_width, int input_height,
-    int output_width, int output_height) throws Exception;
+  private native int getScaledHeight(int jpegWidth, int jpegHeight,
+    int desiredWidth, int desiredHeight) throws Exception;
 
   static {
     System.loadLibrary("turbojpeg");
index 3148fb6fe62dcf09d476e7f25e7e6a4857b7f2e9..e7129af0899ace81478a3c7008853d0bc5fe278a 100644 (file)
@@ -28,9 +28,17 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy
  * Method:    compress
  * Signature: ([BIIII[BIII)I
  */
-JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress
+JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIII_3BIII
   (JNIEnv *, jobject, jbyteArray, jint, jint, jint, jint, jbyteArray, jint, jint, jint);
 
+/*
+ * Class:     org_libjpegturbo_turbojpeg_TJCompressor
+ * Method:    compress
+ * Signature: ([IIII[BIII)I
+ */
+JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIII_3BIII
+  (JNIEnv *, jobject, jintArray, jint, jint, jint, jbyteArray, jint, jint, jint);
+
 #ifdef __cplusplus
 }
 #endif
index 16c39237ec495620e31bb26d119aecf8eaf0db3a..8f65388423f9ca61b314c39c3a5eae015538b4af 100644 (file)
@@ -36,9 +36,17 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress
  * Method:    decompress
  * Signature: ([BI[BIIIII)V
  */
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress
+JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIII
   (JNIEnv *, jobject, jbyteArray, jint, jbyteArray, jint, jint, jint, jint, jint);
 
+/*
+ * Class:     org_libjpegturbo_turbojpeg_TJDecompressor
+ * Method:    decompress
+ * Signature: ([BI[IIIII)V
+ */
+JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIII
+  (JNIEnv *, jobject, jbyteArray, jint, jintArray, jint, jint, jint, jint);
+
 /*
  * Class:     org_libjpegturbo_turbojpeg_TJDecompressor
  * Method:    getScaledWidth
index f2f34eed2e30b453f3f34c9d26446b25e37341e5..b9bd4293ed89d02c797fc84fc5d4999ff250c02f 100644 (file)
@@ -86,7 +86,7 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_init
        return;
 }
 
-JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress
+JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIII_3BIII
        (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch,
                jint height, jint pixelsize, jbyteArray dst, jint jpegsubsamp,
                jint jpegqual, jint flags)
@@ -114,6 +114,33 @@ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress
        return (jint)size;
 }
 
+JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIII_3BIII
+       (JNIEnv *env, jobject obj, jintArray src, jint width, jint pitch,
+               jint height, jbyteArray dst, jint jpegsubsamp, jint jpegqual, jint flags)
+{
+       tjhandle handle=0;
+       unsigned long size=0;
+       unsigned char *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*sizeof(jint), height,
+               sizeof(jint),   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 (jint)size;
+}
+
 JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy
        (JNIEnv *env, jobject obj)
 {
@@ -199,7 +226,7 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress
        return;
 }
 
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress
+JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIII
        (JNIEnv *env, jobject obj, jbyteArray src, jint size, jbyteArray dst,
                jint width, jint pitch, jint height, jint pixelsize, jint flags)
 {
@@ -225,6 +252,33 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress
        return;
 }
 
+JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIII
+       (JNIEnv *env, jobject obj, jbyteArray src, jint size, jintArray dst,
+               jint width, jint pitch, jint height, jint flags)
+{
+       tjhandle handle=0;
+       unsigned char *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*sizeof(jint), height, sizeof(jint), 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_org_libjpegturbo_turbojpeg_TJDecompressor_destroy
        (JNIEnv *env, jobject obj)
 {
index bf2ce4b45c0503338271a8dfa2fa39aeff21cc3f..7c930b820c9d8c02c3a5ef45c3e90448d512d029 100755 (executable)
                Java_org_libjpegturbo_turbojpeg_TJ_bufSize;
                Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV;
                Java_org_libjpegturbo_turbojpeg_TJCompressor_init;
-               Java_org_libjpegturbo_turbojpeg_TJCompressor_compress;
+               Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIII_3BIII;
+               Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIII_3BIII;
                Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy;
                Java_org_libjpegturbo_turbojpeg_TJDecompressor_init;
                Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressHeader;
-               Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress;
+               Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIII;
+               Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIII;
                Java_org_libjpegturbo_turbojpeg_TJDecompressor_destroy;         
                Java_org_libjpegturbo_turbojpeg_TJDecompressor_getScaledHeight;
                Java_org_libjpegturbo_turbojpeg_TJDecompressor_getScaledWidth;