]> granicus.if.org Git - libjpeg-turbo/commitdiff
Implement YUV encode/decode methods at the Java level; Remove some of the arguments...
authorDRC <dcommander@users.sourceforge.net>
Fri, 25 Feb 2011 06:11:03 +0000 (06:11 +0000)
committerDRC <dcommander@users.sourceforge.net>
Fri, 25 Feb 2011 06:11:03 +0000 (06:11 +0000)
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@451 632fc199-4ca6-4c93-a231-07263d6284db

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

index 238bc2fc352a12e844d49a977a9c33762f569040..fc4cb6b94b486a0957880377333bb141f672d15e 100644 (file)
@@ -150,10 +150,8 @@ public class TJExample {
           height = (height + scaleFactor - 1)/scaleFactor;
         }
 
-        if(!outFormat.equalsIgnoreCase("jpg")) {
-          img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
-          tjd.decompress(img, 0);
-        }
+        if(!outFormat.equalsIgnoreCase("jpg"))
+          img = tjd.decompress(width, height, BufferedImage.TYPE_INT_RGB, 0);
         else bmpBuf = tjd.decompress(width, 0, height, TJ.PF_BGRX, 0);
         tjd.close();
       }
@@ -175,14 +173,17 @@ public class TJExample {
           + " subsampling, quality = " + outQual);
         TJCompressor tjc = new TJCompressor();
         int jpegSize;
-        byte [] jpegBuf = new byte[TJ.bufSize(width, height)];
+        byte [] jpegBuf;
 
+        tjc.setSubsamp(outSubsamp);
+        tjc.setJPEGQuality(outQual);
         if(img != null)
-          jpegSize = tjc.compress(img, jpegBuf, outSubsamp, outQual, 0);
+          jpegBuf = tjc.compress(img, 0);
         else {
           tjc.setBitmapBuffer(bmpBuf, width, 0, height, TJ.PF_BGRX);
-          jpegSize = tjc.compress(jpegBuf, outSubsamp, outQual, 0);
+          jpegBuf = tjc.compress(0);
         }
+        jpegSize = tjc.getCompressedSize();
         tjc.close();
 
         file = new File(argv[1]);
index 227729ad76e1b2fb6a258e622a6c3f90fc25c6b8..b9b792cd55b38a3be0a20ecdafbb8e20df087c95 100644 (file)
@@ -57,12 +57,6 @@ public class TJUnitTest {
 
        private final static String _pixformatstr[]=
                {"RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "Grayscale"};
-       private final static int _roffset[]=
-               {0, 2, 0, 2, 3, 1, 0};
-       private final static int _goffset[]=
-               {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};
@@ -104,10 +98,13 @@ public class TJUnitTest {
                {(byte)255, 0, 0}
        };
 
-       private static void initbuf(byte [] buf, int w, int h, int pf, int flags)
+       private static void initbuf(byte [] buf, int w, int pitch, int h, int pf,
+               int flags) throws Exception
        {
-               int roffset=_roffset[pf], goffset=_goffset[pf], boffset=_boffset[pf];
-               int ps=TJ.pixelSize[pf];
+               int roffset=TJ.getRedShift(pf)/8;
+               int goffset=TJ.getGreenShift(pf)/8;
+               int boffset=TJ.getBlueShift(pf)/8;
+               int ps=TJ.getPixelSize(pf);
                int i, _i, j;
 
                Arrays.fill(buf, (byte)0);
@@ -118,8 +115,8 @@ public class TJUnitTest {
                                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) buf[w*i+j]=(byte)255;
-                                       else buf[w*i+j]=76;
+                                       if(((_i/8)+(j/8))%2==0) buf[pitch*i+j]=(byte)255;
+                                       else buf[pitch*i+j]=76;
                                }
                        }
                        for(_i=16; _i<h; _i++)
@@ -127,8 +124,8 @@ public class TJUnitTest {
                                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) buf[w*i+j]=0;
-                                       else buf[w*i+j]=(byte)226;
+                                       if(((_i/8)+(j/8))%2==0) buf[pitch*i+j]=0;
+                                       else buf[pitch*i+j]=(byte)226;
                                }
                        }
                        return;
@@ -138,11 +135,11 @@ public class TJUnitTest {
                        if((flags&TJ.BOTTOMUP)!=0) i=h-_i-1;  else i=_i;
                        for(j=0; j<w; j++)
                        {
-                               buf[(w*i+j)*ps+roffset]=(byte)255;
+                               buf[pitch*i+j*ps+roffset]=(byte)255;
                                if(((_i/8)+(j/8))%2==0)
                                {
-                                       buf[(w*i+j)*ps+goffset]=(byte)255;
-                                       buf[(w*i+j)*ps+boffset]=(byte)255;
+                                       buf[pitch*i+j*ps+goffset]=(byte)255;
+                                       buf[pitch*i+j*ps+boffset]=(byte)255;
                                }
                        }
                }
@@ -153,49 +150,33 @@ public class TJUnitTest {
                        {
                                if(((_i/8)+(j/8))%2!=0)
                                {
-                                       buf[(w*i+j)*ps+roffset]=(byte)255;
-                                       buf[(w*i+j)*ps+goffset]=(byte)255;
+                                       buf[pitch*i+j*ps+roffset]=(byte)255;
+                                       buf[pitch*i+j*ps+goffset]=(byte)255;
                                }
                        }
                }
        }
 
-       private static void initimg(BufferedImage img, int pf, int flags)
+       private static void initintbuf(int [] buf, int w, int pitch, int h, int pf,
+               int flags) throws Exception
        {
-               int i, _i, j, w=img.getWidth(), h=img.getHeight(), pixel;
+               int rshift=TJ.getRedShift(pf);
+               int gshift=TJ.getGreenShift(pf);
+               int bshift=TJ.getBlueShift(pf);
+               int i, _i, j;
 
-               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;
-               }
+               Arrays.fill(buf, 0);
                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);
+                               buf[pitch*i+j]=(255 << rshift);
+                               if(((_i/8)+(j/8))%2==0)
+                               {
+                                       buf[pitch*i+j]|=(255 << gshift);
+                                       buf[pitch*i+j]|=(255 << bshift);
+                               }
                        }
                }
                for(_i=16; _i<h; _i++)
@@ -203,32 +184,38 @@ public class TJUnitTest {
                        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);
+                               if(((_i/8)+(j/8))%2!=0)
+                               {
+                                       buf[pitch*i+j]=(255 << rshift);
+                                       buf[pitch*i+j]|=(255 << gshift);
+                               }
                        }
                }
        }
 
-       private static void dumpbuf(byte [] buf, int w, int h, int pf,
-               int scalefactor, int flags)
+       private static void initimg(BufferedImage img, int pf, int flags)
+               throws Exception
        {
-               int ps=TJ.pixelSize[pf];
-               int roffset=_roffset[pf], goffset=_goffset[pf], boffset=_boffset[pf];
-               int i, j;
-
-               System.out.print("\n");
-               for(i=0; i<h; i++)
+               WritableRaster wr=img.getRaster();
+               int imgtype=img.getType();
+               if(imgtype==BufferedImage.TYPE_INT_RGB
+                       || imgtype==BufferedImage.TYPE_INT_BGR)
+               {
+      SinglePixelPackedSampleModel sm=
+                               (SinglePixelPackedSampleModel)img.getSampleModel();
+                       int pitch=sm.getScanlineStride();
+                       DataBufferInt db=(DataBufferInt)wr.getDataBuffer();
+                       int [] buf = db.getData();
+                       initintbuf(buf, img.getWidth(), pitch, img.getHeight(), pf, flags);
+               }
+               else
                {
-                       for(j=0; j<w; j++)
-                       {
-                               int r=buf[(w*i+j)*ps+roffset];
-                               int g=buf[(w*i+j)*ps+goffset];
-                               int b=buf[(w*i+j)*ps+boffset];
-                               if(r<0) r+=256;  if(g<0) g+=256;  if(b<0) b+=256;
-                               System.out.format("%3d/%3d/%3d ", r, g, b);
-                       }
-                       System.out.print("\n");
+                       ComponentSampleModel sm=
+                               (ComponentSampleModel)img.getSampleModel();
+                       int pitch=sm.getScanlineStride();
+                       DataBufferByte db=(DataBufferByte)wr.getDataBuffer();
+                       byte [] buf = db.getData();
+                       initbuf(buf, img.getWidth(), pitch, img.getHeight(), pf, flags);
                }
        }
 
@@ -265,98 +252,73 @@ public class TJUnitTest {
                }
        }
 
-       private static int checkbuf(byte [] buf, int w, int h, int pf, int subsamp,
-               int scalefactor, int flags) throws Exception
+       private static int checkbuf(byte [] buf, int w, int pitch, int h, int pf,
+               int subsamp, int scalefactor, int flags) throws Exception
        {
-               int roffset=_roffset[pf], goffset=_goffset[pf], boffset=_boffset[pf];
-               int ps=TJ.pixelSize[pf];
+               int roffset=TJ.getRedShift(pf)/8;
+               int goffset=TJ.getGreenShift(pf)/8;
+               int boffset=TJ.getBlueShift(pf)/8;
+               int ps=TJ.getPixelSize(pf);
                int i, _i, j, retval=1;
                int halfway=16/scalefactor, blocksize=8/scalefactor;
 
                try
                {
-                       if(subsamp==TJ.SAMP_GRAY)
+                       for(_i=0; _i<halfway; _i++)
                        {
-                               for(_i=0; _i<halfway; _i++)
+                               if((flags&TJ.BOTTOMUP)!=0) i=h-_i-1;  else i=_i;
+                               for(j=0; j<w; j++)
                                {
-                                       if((flags&TJ.BOTTOMUP)!=0) i=h-_i-1;  else i=_i;
-                                       for(j=0; j<w; j++)
+                                       byte r=buf[pitch*i+j*ps+roffset], g=buf[pitch*i+j*ps+goffset],
+                                               b=buf[pitch*i+j*ps+boffset];
+                                       if(((_i/blocksize)+(j/blocksize))%2==0)
                                        {
-                                               byte r=buf[(w*i+j)*ps+roffset],
-                                                       g=buf[(w*i+j)*ps+goffset],
-                                                       b=buf[(w*i+j)*ps+boffset];
-                                               if(((_i/blocksize)+(j/blocksize))%2==0)
-                                               {
-                                                       checkval255(_i, j, r, "R");
-                                                       checkval255(_i, j, g, "G");
-                                                       checkval255(_i, j, b, "B");
-                                               }
-                                               else
+                                               checkval255(_i, j, r, "R");
+                                               checkval255(_i, j, g, "G");
+                                               checkval255(_i, j, b, "B");
+                                       }
+                                       else
+                                       {
+                                               if(subsamp==TJ.SAMP_GRAY)
                                                {
                                                        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++)
-                                       {
-                                               byte r=buf[(w*i+j)*ps+roffset],
-                                                       g=buf[(w*i+j)*ps+goffset],
-                                                       b=buf[(w*i+j)*ps+boffset];
-                                               if(((_i/blocksize)+(j/blocksize))%2==0)
+                                               else
                                                {
-                                                       checkval0(_i, j, r, "R");
+                                                       checkval255(_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=halfway; _i<h; _i++)
                        {
-                               for(_i=0; _i<halfway; _i++)
+                               if((flags&TJ.BOTTOMUP)!=0) i=h-_i-1;  else i=_i;
+                               for(j=0; j<w; j++)
                                {
-                                       if((flags&TJ.BOTTOMUP)!=0) i=h-_i-1;  else i=_i;
-                                       for(j=0; j<w; j++)
+                                       byte r=buf[pitch*i+j*ps+roffset], g=buf[pitch*i+j*ps+goffset],
+                                               b=buf[pitch*i+j*ps+boffset];
+                                       if(((_i/blocksize)+(j/blocksize))%2==0)
                                        {
-                                               checkval255(_i, j, buf[(w*i+j)*ps+roffset], "R");
-                                               if(((_i/blocksize)+(j/blocksize))%2==0)
-                                               {
-                                                       checkval255(_i, j, buf[(w*i+j)*ps+goffset], "G");
-                                                       checkval255(_i, j, buf[(w*i+j)*ps+boffset], "B");
-                                               }
-                                               else
-                                               {
-                                                       checkval0(_i, j, buf[(w*i+j)*ps+goffset], "G");
-                                                       checkval0(_i, j, buf[(w*i+j)*ps+boffset], "B");
-                                               }
+                                               checkval0(_i, j, r, "R");
+                                               checkval0(_i, j, g, "G");
                                        }
-                               }
-                               for(_i=halfway; _i<h; _i++)
-                               {
-                                       if((flags&TJ.BOTTOMUP)!=0) i=h-_i-1;  else i=_i;
-                                       for(j=0; j<w; j++)
+                                       else
                                        {
-                                               checkval0(_i, j, buf[(w*i+j)*ps+boffset], "B");
-                                               if(((_i/blocksize)+(j/blocksize))%2==0)
+                                               if(subsamp==TJ.SAMP_GRAY)
                                                {
-                                                       checkval0(_i, j, buf[(w*i+j)*ps+roffset], "R");
-                                                       checkval0(_i, j, buf[(w*i+j)*ps+goffset], "G");
+                                                       checkval(_i, j, r, "R", 226);
+                                                       checkval(_i, j, g, "G", 226);
+                                                       checkval(_i, j, b, "B", 226);
                                                }
                                                else
                                                {
-                                                       checkval255(_i, j, buf[(w*i+j)*ps+roffset], "R");
-                                                       checkval255(_i, j, buf[(w*i+j)*ps+goffset], "G");
+                                                       checkval255(_i, j, r, "R");
+                                                       checkval255(_i, j, g, "G");
+                                                       checkval0(_i, j, b, "B");                                                       
                                                }
                                        }
                                }
@@ -367,105 +329,94 @@ public class TJUnitTest {
                        System.out.println(e);
                        retval=0;
                }
+
+               if(retval==0)
+               {
+                       System.out.print("\n");
+                       for(i=0; i<h; i++)
+                       {
+                               for(j=0; j<w; j++)
+                               {
+                                       int r=buf[pitch*i+j*ps+roffset];
+                                       int g=buf[pitch*i+j*ps+goffset];
+                                       int b=buf[pitch*i+j*ps+boffset];
+                                       if(r<0) r+=256;  if(g<0) g+=256;  if(b<0) b+=256;
+                                       System.out.format("%3d/%3d/%3d ", r, g, b);
+                               }
+                               System.out.print("\n");
+                       }
+               }
                return retval;
        }
 
-       private static int checkimg(BufferedImage img, int pf,
+       private static int checkintbuf(int [] buf, int w, int pitch, int h, int pf,
                int subsamp, int scalefactor, int flags) throws Exception
        {
-               int i, _i, j, retval=1, w=img.getWidth(), h=img.getHeight();
+               int rshift=TJ.getRedShift(pf);
+               int gshift=TJ.getGreenShift(pf);
+               int bshift=TJ.getBlueShift(pf);
+               int i, _i, j, retval=1;
                int halfway=16/scalefactor, blocksize=8/scalefactor;
 
                try
                {
-                       if(subsamp==TJ.SAMP_GRAY)
+                       for(_i=0; _i<halfway; _i++)
                        {
-                               for(_i=0; _i<halfway; _i++)
+                               if((flags&TJ.BOTTOMUP)!=0) i=h-_i-1;  else i=_i;
+                               for(j=0; j<w; j++)
                                {
-                                       if((flags&TJ.BOTTOMUP)!=0) i=h-_i-1;  else i=_i;
-                                       for(j=0; j<w; j++)
+                                       int r=(buf[pitch*i+j] >> rshift) & 0xFF;
+                                       int g=(buf[pitch*i+j] >> gshift) & 0xFF;
+                                       int b=(buf[pitch*i+j] >> bshift) & 0xFF;
+                                       if(((_i/blocksize)+(j/blocksize))%2==0)
                                        {
-                                               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
+                                               checkval255(_i, j, r, "R");
+                                               checkval255(_i, j, g, "G");
+                                               checkval255(_i, j, b, "B");
+                                       }
+                                       else
+                                       {
+                                               if(subsamp==TJ.SAMP_GRAY)
                                                {
                                                        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)
+                                               else
                                                {
-                                                       checkval0(_i, j, r, "R");
+                                                       checkval255(_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=halfway; _i<h; _i++)
                        {
-                               for(_i=0; _i<halfway; _i++)
+                               if((flags&TJ.BOTTOMUP)!=0) i=h-_i-1;  else i=_i;
+                               for(j=0; j<w; j++)
                                {
-                                       if((flags&TJ.BOTTOMUP)!=0) i=h-_i-1;  else i=_i;
-                                       for(j=0; j<w; j++)
+                                       int r=(buf[pitch*i+j] >> rshift) & 0xFF;
+                                       int g=(buf[pitch*i+j] >> gshift) & 0xFF;
+                                       int b=(buf[pitch*i+j] >> bshift) & 0xFF;
+                                       if(((_i/blocksize)+(j/blocksize))%2==0)
                                        {
-                                               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");
-                                               }
+                                               checkval0(_i, j, r, "R");
+                                               checkval0(_i, j, g, "G");
                                        }
-                               }
-                               for(_i=halfway; _i<h; _i++)
-                               {
-                                       if((flags&TJ.BOTTOMUP)!=0) i=h-_i-1;  else i=_i;
-                                       for(j=0; j<w; j++)
+                                       else
                                        {
-                                               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)
+                                               if(subsamp==TJ.SAMP_GRAY)
                                                {
-                                                       checkval0(_i, j, r, "R");
-                                                       checkval0(_i, j, g, "G");
+                                                       checkval(_i, j, r, "R", 226);
+                                                       checkval(_i, j, g, "G", 226);
+                                                       checkval(_i, j, b, "B", 226);
                                                }
                                                else
                                                {
                                                        checkval255(_i, j, r, "R");
                                                        checkval255(_i, j, g, "G");
+                                                       checkval0(_i, j, b, "B");
                                                }
                                        }
                                }
@@ -476,9 +427,54 @@ public class TJUnitTest {
                        System.out.println(e);
                        retval=0;
                }
+
+               if(retval==0)
+               {
+                       System.out.print("\n");
+                       for(i=0; i<h; i++)
+                       {
+                               for(j=0; j<w; j++)
+                               {
+                                       int r=(buf[pitch*i+j] >> rshift) & 0xFF;
+                                       int g=(buf[pitch*i+j] >> gshift) & 0xFF;
+                                       int b=(buf[pitch*i+j] >> bshift) & 0xFF;
+                                       if(r<0) r+=256;  if(g<0) g+=256;  if(b<0) b+=256;
+                                       System.out.format("%3d/%3d/%3d ", r, g, b);
+                               }
+                               System.out.print("\n");
+                       }
+               }
                return retval;
        }
 
+       private static int checkimg(BufferedImage img, int pf,
+               int subsamp, int scalefactor, int flags) throws Exception
+       {
+               WritableRaster wr=img.getRaster();
+               int imgtype=img.getType();
+               if(imgtype==BufferedImage.TYPE_INT_RGB
+                       || imgtype==BufferedImage.TYPE_INT_BGR)
+               {
+      SinglePixelPackedSampleModel sm=
+                               (SinglePixelPackedSampleModel)img.getSampleModel();
+                       int pitch=sm.getScanlineStride();
+                       DataBufferInt db=(DataBufferInt)wr.getDataBuffer();
+                       int [] buf = db.getData();
+                       return checkintbuf(buf, img.getWidth(), pitch, img.getHeight(), pf,
+                               subsamp, scalefactor, flags);
+               }
+               else
+               {
+                       ComponentSampleModel sm=
+                               (ComponentSampleModel)img.getSampleModel();
+                       int pitch=sm.getScanlineStride();
+                       DataBufferByte db=(DataBufferByte)wr.getDataBuffer();
+                       byte [] buf = db.getData();
+                       return checkbuf(buf, img.getWidth(), pitch, img.getHeight(), pf, subsamp,
+                               scalefactor, flags);
+               }
+       }
+
        private static int PAD(int v, int p)
        {
                return ((v+(p)-1)&(~((p)-1)));
@@ -616,9 +612,7 @@ public class TJUnitTest {
        {
                String tempstr;  byte [] bmpbuf=null;  BufferedImage img=null;
                String pixformat;  double t;
-               int size=0, ps=TJ.pixelSize[pf];
-
-               if(yuv==YUVENCODE) flags|=TJ.YUV;
+               int size=0, ps=TJ.getPixelSize(pf);
 
                pixformat=_pixformatstr[pf];
 
@@ -642,18 +636,25 @@ public class TJUnitTest {
                else
                {
                        bmpbuf=new byte[w*h*ps+1];
-                       initbuf(bmpbuf, w, h, pf, flags);
+                       initbuf(bmpbuf, w, w*ps, h, pf, flags);
                }
                Arrays.fill(jpegbuf, (byte)0);
 
                t=gettime();
+               tjc.setSubsamp(subsamp);
+               tjc.setJPEGQuality(qual);
                if(bi)
-                       size=tjc.compress(img, jpegbuf, subsamp, qual, flags);
+               {
+                       if(yuv==YUVENCODE) tjc.encodeYUV(img, jpegbuf, flags);
+                       else tjc.compress(img, jpegbuf, flags);
+               }
                else
                {
                        tjc.setBitmapBuffer(bmpbuf, w, 0, h, pf);
-                       size=tjc.compress(jpegbuf, subsamp, qual, flags);
+                       if(yuv==YUVENCODE) tjc.encodeYUV(jpegbuf, flags);
+                       else tjc.compress(jpegbuf, flags);
                }
+               size=tjc.getCompressedSize();
                t=gettime()-t;
 
                if(yuv==YUVENCODE)
@@ -689,8 +690,7 @@ public class TJUnitTest {
                int temp1, temp2;
                BufferedImage img=null;  byte [] bmpbuf=null;
 
-               if(yuv==YUVDECODE) flags|=TJ.YUV;
-               else if(yuv==YUVENCODE) return;
+               if(yuv==YUVENCODE) return;
 
                pixformat=_pixformatstr[pf];
                System.out.print("JPEG -> ");
@@ -716,13 +716,12 @@ public class TJUnitTest {
                if(temp1!=scaledw || temp2!=scaledh)
                        throw new Exception("Scaled size mismatch");
 
-               if(bi)
+               if(yuv==YUVDECODE) bmpbuf=tjd.decompressToYUV(flags);
+               else
                {
-                       img=new BufferedImage(scaledw, scaledh, biType[pf]);
-                       tjd.decompress(img, flags);
+                       if(bi) img=tjd.decompress(scaledw, scaledh, biType[pf], flags);
+                       else bmpbuf=tjd.decompress(scaledw, 0, scaledh, pf, flags);
                }
-               else
-                       bmpbuf=tjd.decompress(scaledw, 0, scaledh, pf, flags);
                t=gettime()-t;
 
                if(bi)
@@ -743,14 +742,12 @@ public class TJUnitTest {
                else
                {
                        if((bi && checkimg(img, pf, subsamp, scalefactor, flags)==1)
-                               || (!bi && checkbuf(bmpbuf, scaledw, scaledh, pf, subsamp, scalefactor,
-                               flags)==1))
+                               || (!bi && checkbuf(bmpbuf, scaledw, scaledw*TJ.getPixelSize(pf),
+                                       scaledh, pf, subsamp, scalefactor, flags)==1))
                                System.out.print("Passed.");
                        else
                        {
                                System.out.print("FAILED!");  exitstatus=-1;
-                               if(bmpbuf!=null)
-                                       dumpbuf(bmpbuf, scaledw, scaledh, pf, scalefactor, flags);
                        }
                }
                System.out.format("  %.6f ms\n", t*1000.);
@@ -778,8 +775,10 @@ public class TJUnitTest {
        {
                TJCompressor tjc=null;  TJDecompressor tjd=null;
                int size;  int pfstart, pfend;
+               byte [] jpegbuf;
 
-               byte [] jpegbuf=new byte[TJ.bufSize(w, h)];
+               if(yuv==YUVENCODE) jpegbuf=new byte[TJ.bufSizeYUV(w, h, subsamp)];
+               else jpegbuf=new byte[TJ.bufSize(w, h)];
 
                try
                {
@@ -821,7 +820,7 @@ public class TJUnitTest {
        private static void dotest1() throws Exception
        {
                int i, j, i2;  byte [] bmpbuf, jpgbuf;
-               TJCompressor tjc=null;  int size;
+               TJCompressor tjc=null;
 
                try
                {
@@ -843,7 +842,9 @@ public class TJUnitTest {
                                                bmpbuf[i2*4+2]=pixels[i2%9][0];
                                        }
                                        tjc.setBitmapBuffer(bmpbuf, i, 0, j, TJ.PF_BGRX);
-                                       size=tjc.compress(jpgbuf, TJ.SAMP_444, 100, 0);
+                                       tjc.setSubsamp(TJ.SAMP_444);
+                                       tjc.setJPEGQuality(100);
+                                       tjc.compress(jpgbuf, 0);
 
                                        bmpbuf=new byte[j*i*4];
                                        jpgbuf=new byte[TJ.bufSize(j, i)];
@@ -853,7 +854,7 @@ public class TJUnitTest {
                                                else bmpbuf[i2*4]=bmpbuf[i2*4+1]=bmpbuf[i2*4+2]=0;
                                        }
                                        tjc.setBitmapBuffer(bmpbuf, j, 0, i, TJ.PF_BGRX);
-                                       size=tjc.compress(jpgbuf, TJ.SAMP_444, 100, 0);
+                                       tjc.compress(jpgbuf, 0);
                                }
                        }
                        System.out.println("Done.      ");
@@ -879,23 +880,21 @@ public class TJUnitTest {
                                        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, 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");
-                               dotest(35, 39, _4byteFormats, TJ.SAMP_422, "test");
-                               dotest(39, 41, _3byteFormats, TJ.SAMP_420, "test");
-                               dotest(41, 35, _4byteFormats, TJ.SAMP_420, "test");
+                               dotest(41, 35, bi? _3byteFormatsBI:_3byteFormats, TJ.SAMP_422, "test");
+                               dotest(35, 39, bi? _4byteFormatsBI:_4byteFormats, TJ.SAMP_422, "test");
+                               dotest(39, 41, bi? _3byteFormatsBI:_3byteFormats, TJ.SAMP_420, "test");
+                               dotest(41, 35, bi? _4byteFormatsBI:_4byteFormats, TJ.SAMP_420, "test");
                        }
                        dotest(35, 39, _onlyGray, TJ.SAMP_GRAY, "test");
                        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)
+                       if(doyuv && !bi)
                        {
                                yuv=YUVDECODE;
                                dotest(48, 48, _onlyRGB, TJ.SAMP_444, "test");
@@ -904,8 +903,10 @@ public class TJUnitTest {
                                dotest(39, 41, _onlyRGB, TJ.SAMP_422, "test");
                                dotest(48, 48, _onlyRGB, TJ.SAMP_420, "test");
                                dotest(41, 35, _onlyRGB, TJ.SAMP_420, "test");
+                               dotest(48, 48, _onlyRGB, TJ.SAMP_GRAY, "test");
+                               dotest(35, 39, _onlyRGB, TJ.SAMP_GRAY, "test");
                                dotest(48, 48, _onlyGray, TJ.SAMP_GRAY, "test");
-                               dotest(35, 39, _onlyGray, TJ.SAMP_GRAY, "test");
+                               dotest(39, 41, _onlyGray, TJ.SAMP_GRAY, "test");
                        }
                }
                catch(Exception e)
index 9951fa2c03a51c8960ec238fc8770d3c8db5a90d..332426a919f71dde8720514fda4dea06988cd33d 100644 (file)
@@ -49,7 +49,7 @@ final public class TJ {
     PF_XRGB  = 5,
     PF_GRAY  = 6;
 
-  final public static int pixelSize[] = {
+  final private static int pixelSize[] = {
     3, 3, 4, 4, 4, 4, 1
   };
 
@@ -59,30 +59,45 @@ final public class TJ {
     return pixelSize[pixelFormat];
   }
 
-  // Flags
-  final public static int
-    BOTTOMUP     = 2,
-    FORCEMMX     = 8,
-    FORCESSE     = 16,
-    FORCESSE2    = 32,
-    FORCESSE3    = 128,
-    FASTUPSAMPLE = 256,
-    YUV          = 512;
+  final private static int redShift[] = {
+    0, 16, 0, 16, 24, 8, 0
+  };
 
-  final private static int
-    TJ_BGR        = 1,
-    TJ_ALPHAFIRST = 64;
+  final public static int getRedShift(int pixelFormat) throws Exception {
+    if(pixelFormat < 0 || pixelFormat >= NUMPFOPT)
+      throw new Exception("Invalid pixel format");
+    return redShift[pixelFormat];
+  }
 
-  final private static int flags[] = {
-    0, TJ_BGR, 0, TJ_BGR, TJ_BGR|TJ_ALPHAFIRST, TJ_ALPHAFIRST, 0
+  final private static int greenShift[] = {
+    8, 8, 8, 8, 16, 16, 0
   };
 
-  final public static int getFlags(int pixelFormat) throws Exception {
+  final public static int getGreenShift(int pixelFormat) throws Exception {
     if(pixelFormat < 0 || pixelFormat >= NUMPFOPT)
       throw new Exception("Invalid pixel format");
-    return flags[pixelFormat];
+    return greenShift[pixelFormat];
   }
 
+  final private static int blueShift[] = {
+    16, 0, 16, 0, 8, 24, 0
+  };
+
+  final public static int getBlueShift(int pixelFormat) throws Exception {
+    if(pixelFormat < 0 || pixelFormat >= NUMPFOPT)
+      throw new Exception("Invalid pixel format");
+    return blueShift[pixelFormat];
+  }
+
+  // Flags
+  final public static int
+    BOTTOMUP     = 2,
+    FORCEMMX     = 8,
+    FORCESSE     = 16,
+    FORCESSE2    = 32,
+    FORCESSE3    = 128,
+    FASTUPSAMPLE = 256;
+
   public native final static int bufSize(int width, int height)
     throws Exception;
 
index 0fcffacafca7fde049748f9504cddcacd6d6315d..d0c1910b6c10c549e444acfde7dfa566134b8fca 100644 (file)
@@ -55,18 +55,112 @@ public class TJCompressor {
     bitmapPixelFormat = pixelFormat;
   }
 
-  public int compress(byte [] dstBuf, int jpegSubsamp, int jpegQual,
-    int flags) throws Exception {
-    return compress(bitmapBuf, bitmapWidth, bitmapPitch, bitmapHeight,
-      TJ.getPixelSize(bitmapPixelFormat), dstBuf, jpegSubsamp, jpegQual,
-        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);
+  public void setSubsamp(int newSubsamp) throws Exception {
+    if(newSubsamp < 0 || newSubsamp >= TJ.NUMSAMPOPT)
+      throw new Exception ("Invalid argument in setSubsamp()");
+    subsamp = newSubsamp;
+  }
+
+  public void setJPEGQuality(int quality) throws Exception {
+    if(quality < 1 || quality > 100)
+      throw new Exception ("Invalid argument in setJPEGQuality()");
+    jpegQuality = quality;
+  }
+
+  public void compress(byte [] dstBuf, int flags) throws Exception {
+    if(dstBuf == null || flags < 0)
+      throw new Exception("Invalid argument in compress()");
+    if(bitmapBuf == null) throw new Exception("Bitmap buffer not initialized");
+    if(jpegQuality < 0) throw new Exception("JPEG Quality not set");
+    if(subsamp < 0) throw new Exception("Subsampling level not set");
+    compressedSize = compress(bitmapBuf, bitmapWidth, bitmapPitch,
+      bitmapHeight, bitmapPixelFormat, dstBuf, subsamp, jpegQuality, flags);
+  }
+
+  public byte [] compress(int flags) throws Exception {
+    if(bitmapWidth < 1 || bitmapHeight < 1)
+      throw new Exception("Bitmap buffer not initialized");
+    byte [] buf = new byte[TJ.bufSize(bitmapWidth, bitmapHeight)];
+    compress(buf, flags);
+    return buf;
+  }
+
+  public void compress(BufferedImage srcImage, byte [] dstBuf, int flags)
+    throws Exception {
+    if(srcImage == null || dstBuf == null || flags < 0)
+      throw new Exception("Invalid argument in compress()");
+    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(jpegQuality < 0) throw new Exception("JPEG Quality not set");
+    if(subsamp < 0) throw new Exception("Subsampling level not set");
+    if(intPixels) {
+      SinglePixelPackedSampleModel sm =
+        (SinglePixelPackedSampleModel)srcImage.getSampleModel();
+      int pitch = sm.getScanlineStride();
+      DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
+      int [] buf = db.getData();
+      compressedSize = compress(buf, width, pitch, height, pixelFormat, dstBuf,
+        subsamp, jpegQuality, flags);
+    }
+    else {
+      ComponentSampleModel sm =
+        (ComponentSampleModel)srcImage.getSampleModel();
+      int pixelSize = sm.getPixelStride();
+      if(pixelSize != TJ.getPixelSize(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();
+      compressedSize = compress(buf, width, pitch, height, pixelFormat, dstBuf,
+        subsamp, jpegQuality, flags);
+    }
+  }
+
+  public byte [] compress(BufferedImage srcImage, int flags) throws Exception {
+    int width = srcImage.getWidth();
+    int height = srcImage.getHeight();
+    byte [] buf = new byte[TJ.bufSize(width, height)];
+    compress(srcImage, buf, flags);
+    return buf;
+  }
+
+  public void encodeYUV(byte [] dstBuf, int flags) throws Exception {
+    if(dstBuf == null || flags < 0)
+      throw new Exception("Invalid argument in compress()");
+    if(bitmapBuf == null) throw new Exception("Bitmap buffer not initialized");
+    if(subsamp < 0) throw new Exception("Subsampling level not set");
+    encodeYUV(bitmapBuf, bitmapWidth, bitmapPitch, bitmapHeight,
+      bitmapPixelFormat, dstBuf, subsamp, flags);
+    compressedSize = TJ.bufSizeYUV(bitmapWidth, bitmapHeight, subsamp);
+  }
+
+  public byte [] encodeYUV(int flags) throws Exception {
+    if(bitmapWidth < 1 || bitmapHeight < 1)
+      throw new Exception("Bitmap buffer not initialized");
+    if(subsamp < 0) throw new Exception("Subsampling level not set");
+    byte [] buf = new byte[TJ.bufSizeYUV(bitmapWidth, bitmapHeight, subsamp)];
+    encodeYUV(buf, flags);
+    return buf;
+  }
+
+  public void encodeYUV(BufferedImage srcImage, byte [] dstBuf, int flags)
+    throws Exception {
+    if(srcImage == null || dstBuf == null || flags < 0)
+      throw new Exception("Invalid argument in encodeYUV()");
     int width = srcImage.getWidth();
     int height = srcImage.getHeight();
     int pixelFormat;  boolean intPixels=false;
@@ -83,27 +177,43 @@ public class TJCompressor {
         throw new Exception("Unsupported BufferedImage format");
     }
     WritableRaster wr = srcImage.getRaster();
+    if(subsamp < 0) throw new Exception("Subsampling level not set");
     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));
+      encodeYUV(buf, width, pitch, height, pixelFormat, dstBuf, subsamp,
+        flags);
     }
     else {
       ComponentSampleModel sm =
         (ComponentSampleModel)srcImage.getSampleModel();
       int pixelSize = sm.getPixelStride();
-      if(pixelSize != TJ.pixelSize[pixelFormat])
+      if(pixelSize != TJ.getPixelSize(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));
+      encodeYUV(buf, width, pitch, height, pixelFormat, dstBuf, subsamp,
+        flags);
     }
+    compressedSize = TJ.bufSizeYUV(width, height, subsamp);
+  }
+
+  public byte [] encodeYUV(BufferedImage srcImage, int flags)
+    throws Exception {
+    if(subsamp < 0) throw new Exception("Subsampling level not set");
+    int width = srcImage.getWidth();
+    int height = srcImage.getHeight();
+    byte [] buf = new byte[TJ.bufSizeYUV(width, height, subsamp)];
+    encodeYUV(srcImage, buf, flags);
+    return buf;
+  }
+
+  public int getCompressedSize() {
+    return compressedSize;
   }
 
   public void close() throws Exception {
@@ -126,11 +236,19 @@ public class TJCompressor {
 
   // JPEG size in bytes is returned
   private native int compress(byte [] srcBuf, int width, int pitch,
-    int height, int pixelSize, byte [] dstbuf, int jpegSubsamp, int jpegQual,
+    int height, int pixelFormat, 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)
+    int height, int pixelFormat, byte [] dstbuf, int jpegSubsamp, int jpegQual,
+    int flags) throws Exception;
+
+  private native void encodeYUV(byte [] srcBuf, int width, int pitch,
+    int height, int pixelFormat, byte [] dstbuf, int subsamp, int flags)
+    throws Exception;
+
+  private native void encodeYUV(int [] srcBuf, int width, int pitch,
+    int height, int pixelFormat, byte [] dstbuf, int subsamp, int flags)
     throws Exception;
 
   static {
@@ -143,4 +261,7 @@ public class TJCompressor {
   private int bitmapHeight = 0;
   private int bitmapPitch = 0;
   private int bitmapPixelFormat = -1;
+  private int subsamp = -1;
+  private int jpegQuality = -1;
+  private int compressedSize = 0;
 };
index 9cd2fe69a47732f91be1ee6948211e3883ab4996..fdc1e4eb93ae458667627af665f63244d57b4c14 100644 (file)
@@ -74,6 +74,8 @@ public class TJDecompressor {
     throws Exception {
     if(jpegWidth < 1 || jpegHeight < 1)
       throw new Exception("JPEG buffer not initialized");
+    if(desiredWidth < 0 || desiredHeight < 0)
+      throw new Exception("Invalid argument in getScaledWidth()");
     return getScaledWidth(jpegWidth, jpegHeight, desiredWidth,
       desiredHeight);
   }
@@ -82,6 +84,8 @@ public class TJDecompressor {
     throws Exception {
     if(jpegWidth < 1 || jpegHeight < 1)
       throw new Exception("JPEG buffer not initialized");
+    if(desiredWidth < 0 || desiredHeight < 0)
+      throw new Exception("Invalid argument in getScaledHeight()");
     return getScaledHeight(jpegWidth, jpegHeight, desiredWidth,
       desiredHeight);
   }
@@ -89,35 +93,49 @@ public class TJDecompressor {
   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");
+    if(dstBuf == null || desiredWidth < 0 || pitch < 0 || desiredHeight < 0
+      || pixelFormat < 0 || pixelFormat >= TJ.NUMPFOPT || flags < 0)
+      throw new Exception("Invalid argument in decompress()");
     decompress(jpegBuf, jpegBufSize, dstBuf, desiredWidth, pitch,
-      desiredHeight, TJ.getPixelSize(pixelFormat),
-      flags | TJ.getFlags(pixelFormat));
+      desiredHeight, pixelFormat, flags);
   }
 
   public byte [] decompress(int desiredWidth, int pitch, int desiredHeight,
     int pixelFormat, int flags) throws Exception {
-    if(desiredWidth < 0 || desiredHeight < 0 || pitch < 0 || pixelFormat < 0
-      || pixelFormat >= TJ.NUMPFOPT || flags < 0)
+    if(desiredWidth < 0 || pitch < 0 || desiredHeight < 0
+      || pixelFormat < 0 || pixelFormat >= TJ.NUMPFOPT || flags < 0)
       throw new Exception("Invalid argument in decompress()");
     int pixelSize = TJ.getPixelSize(pixelFormat);
     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(jpegWidth, jpegHeight, jpegSubsamp);
-    else bufSize = pitch * scaledHeight;
-    byte [] buf = new byte[bufSize];
+    byte [] buf = new byte[pitch * scaledHeight];
+    decompress(buf, desiredWidth, pitch, desiredHeight, pixelFormat, flags);
+    return buf;
+  }
+
+  public void decompressToYUV(byte [] dstBuf, int flags) throws Exception {
     if(jpegBuf == null) throw new Exception("JPEG buffer not initialized");
-    decompress(jpegBuf, jpegBufSize, buf, desiredWidth, pitch, desiredHeight,
-      TJ.getPixelSize(pixelFormat), flags | TJ.getFlags(pixelFormat));
+    if(dstBuf == null || flags < 0)
+      throw new Exception("Invalid argument in decompressToYUV()");
+    decompressToYUV(jpegBuf, jpegBufSize, dstBuf, flags);
+  }
+
+  public byte [] decompressToYUV(int flags) throws Exception {
+    if(flags < 0)
+      throw new Exception("Invalid argument in decompressToYUV()");
+    if(jpegWidth < 1 || jpegHeight < 1 || jpegSubsamp < 0)
+      throw new Exception("JPEG buffer not initialized");
+    if(jpegSubsamp >= TJ.NUMSAMPOPT)
+      throw new Exception("JPEG header information is invalid");
+    byte [] buf = new byte[TJ.bufSizeYUV(jpegWidth, jpegHeight, jpegSubsamp)];
+    decompressToYUV(buf, flags);
     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);
@@ -144,14 +162,15 @@ public class TJDecompressor {
       int pitch = sm.getScanlineStride();
       DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
       int [] buf = db.getData();
+      if(jpegBuf == null) throw new Exception("JPEG buffer not initialized");
       decompress(jpegBuf, jpegBufSize, buf, scaledWidth, pitch, scaledHeight,
-        flags | TJ.getFlags(pixelFormat));
+        pixelFormat, flags);
     }
     else {
       ComponentSampleModel sm =
         (ComponentSampleModel)dstImage.getSampleModel();
       int pixelSize = sm.getPixelStride();
-      if(pixelSize != TJ.pixelSize[pixelFormat])
+      if(pixelSize != TJ.getPixelSize(pixelFormat))
         throw new Exception("Inconsistency between pixel format and pixel size in BufferedImage");
       int pitch = sm.getScanlineStride();
       DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
@@ -160,6 +179,18 @@ public class TJDecompressor {
     }
   }
 
+  public BufferedImage decompress(int desiredWidth, int desiredHeight,
+    int bufferedImageType, int flags) throws Exception {
+    if(desiredWidth < 0 || desiredHeight < 0 || flags < 0)
+      throw new Exception("Invalid argument in decompress()");
+    int scaledWidth = getScaledWidth(desiredWidth, desiredHeight);
+    int scaledHeight = getScaledHeight(desiredWidth, desiredHeight);
+    BufferedImage img = new BufferedImage(scaledWidth, scaledHeight,
+      bufferedImageType);
+    decompress(img, flags);
+    return img;
+  }
+
   public void close() throws Exception {
     destroy();
   }
@@ -182,11 +213,15 @@ public class TJDecompressor {
     throws Exception;
 
   private native void decompress(byte [] srcBuf, int size, byte [] dstBuf,
-    int desiredWidth, int pitch, int desiredHeight, int pixelSize, int flags)
+    int desiredWidth, int pitch, int desiredHeight, int pixelFormat, int flags)
     throws Exception;
 
   private native void decompress(byte [] srcBuf, int size, int [] dstBuf,
-    int desiredWidth, int pitch, int desiredHeight, int flags)
+    int desiredWidth, int pitch, int desiredHeight, int pixelFormat, int flags)
+    throws Exception;
+
+  private native void decompressToYUV(byte [] srcBuf, int size, byte [] dstBuf,
+    int flags)
     throws Exception;
 
   private native int getScaledWidth(int jpegWidth, int jpegHeight,
index a1fe82db5615db052bea9c5f4b1875d703778f5c..b2be5d83d914277464452ccce26c6fd71c2b5a02 100644 (file)
@@ -45,12 +45,6 @@ extern "C" {
 #define org_libjpegturbo_turbojpeg_TJ_FORCESSE3 128L
 #undef org_libjpegturbo_turbojpeg_TJ_FASTUPSAMPLE
 #define org_libjpegturbo_turbojpeg_TJ_FASTUPSAMPLE 256L
-#undef org_libjpegturbo_turbojpeg_TJ_YUV
-#define org_libjpegturbo_turbojpeg_TJ_YUV 512L
-#undef org_libjpegturbo_turbojpeg_TJ_TJ_BGR
-#define org_libjpegturbo_turbojpeg_TJ_TJ_BGR 1L
-#undef org_libjpegturbo_turbojpeg_TJ_TJ_ALPHAFIRST
-#define org_libjpegturbo_turbojpeg_TJ_TJ_ALPHAFIRST 64L
 /*
  * Class:     org_libjpegturbo_turbojpeg_TJ
  * Method:    bufSize
index e7129af0899ace81478a3c7008853d0bc5fe278a..59f81e3685f72cfab6e55deb7d286540d3090a91 100644 (file)
@@ -34,10 +34,26 @@ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3
 /*
  * Class:     org_libjpegturbo_turbojpeg_TJCompressor
  * Method:    compress
- * Signature: ([IIII[BIII)I
+ * Signature: ([IIIII[BIII)I
  */
-JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIII_3BIII
-  (JNIEnv *, jobject, jintArray, jint, jint, jint, jbyteArray, jint, jint, jint);
+JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIII_3BIII
+  (JNIEnv *, jobject, jintArray, jint, jint, jint, jint, jbyteArray, jint, jint, jint);
+
+/*
+ * Class:     org_libjpegturbo_turbojpeg_TJCompressor
+ * Method:    encodeYUV
+ * Signature: ([BIIII[BII)V
+ */
+JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIII_3BII
+  (JNIEnv *, jobject, jbyteArray, jint, jint, jint, jint, jbyteArray, jint, jint);
+
+/*
+ * Class:     org_libjpegturbo_turbojpeg_TJCompressor
+ * Method:    encodeYUV
+ * Signature: ([IIIII[BII)V
+ */
+JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIII_3BII
+  (JNIEnv *, jobject, jintArray, jint, jint, jint, jint, jbyteArray, jint, jint);
 
 #ifdef __cplusplus
 }
index 8f65388423f9ca61b314c39c3a5eae015538b4af..695190645a80a51971bc5e0dea8109376ff60f26 100644 (file)
@@ -42,10 +42,18 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress
 /*
  * Class:     org_libjpegturbo_turbojpeg_TJDecompressor
  * Method:    decompress
- * Signature: ([BI[IIIII)V
+ * Signature: ([BI[IIIIII)V
  */
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIII
-  (JNIEnv *, jobject, jbyteArray, jint, jintArray, jint, jint, jint, jint);
+JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIII
+  (JNIEnv *, jobject, jbyteArray, jint, jintArray, jint, jint, jint, jint, jint);
+
+/*
+ * Class:     org_libjpegturbo_turbojpeg_TJDecompressor
+ * Method:    decompressToYUV
+ * Signature: ([BI[BI)V
+ */
+JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV
+  (JNIEnv *, jobject, jbyteArray, jint, jbyteArray, jint);
 
 /*
  * Class:     org_libjpegturbo_turbojpeg_TJDecompressor
index b9bd4293ed89d02c797fc84fc5d4999ff250c02f..6e04a5c0cbd7400faef816fe8003db5646b295f3 100644 (file)
 #include "java/org_libjpegturbo_turbojpeg_TJDecompressor.h"
 #include "java/org_libjpegturbo_turbojpeg_TJ.h"
 
+static const int _pixelsize[org_libjpegturbo_turbojpeg_TJ_NUMPFOPT]=
+       {3, 3, 4, 4, 4, 4, 1};
+
+static const int _flags[org_libjpegturbo_turbojpeg_TJ_NUMPFOPT]=
+       {0, TJ_BGR, 0, TJ_BGR, TJ_BGR|TJ_ALPHAFIRST, TJ_ALPHAFIRST, 0};
+
 #define _throw(msg) {  \
        jclass _exccls=(*env)->FindClass(env, "java/lang/Exception");  \
        if(!_exccls) goto bailout;  \
@@ -88,15 +94,20 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_init
 
 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)
+               jint height, jint pf, jbyteArray dst, jint jpegsubsamp, jint jpegqual,
+               jint flags)
 {
-       tjhandle handle=0;
+       tjhandle handle=0;  int pixelsize;
        unsigned long size=0;
        unsigned char *srcbuf=NULL, *dstbuf=NULL;
 
        gethandle();
 
+       if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPFOPT)
+               _throw("Invalid argument in compress()");
+       flags|=_flags[pf];
+       pixelsize=_pixelsize[pf];
+
        bailif0(srcbuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
        bailif0(dstbuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
 
@@ -114,9 +125,10 @@ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3
        return (jint)size;
 }
 
-JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIII_3BIII
+JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIII_3BIII
        (JNIEnv *env, jobject obj, jintArray src, jint width, jint pitch,
-               jint height, jbyteArray dst, jint jpegsubsamp, jint jpegqual, jint flags)
+               jint height, jint pf, jbyteArray dst, jint jpegsubsamp, jint jpegqual,
+               jint flags)
 {
        tjhandle handle=0;
        unsigned long size=0;
@@ -124,6 +136,12 @@ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3
 
        gethandle();
 
+       if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPFOPT)
+               _throw("Invalid argument in compress()");
+       if(_pixelsize[pf]!=sizeof(jint))
+               _throw("Pixel format must be 32-bit when compressing from an integer buffer.");
+       flags|=_flags[pf];
+
        bailif0(srcbuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
        bailif0(dstbuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
 
@@ -141,6 +159,71 @@ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3
        return (jint)size;
 }
 
+JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIII_3BII
+       (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch,
+               jint height, jint pf, jbyteArray dst, jint jpegsubsamp, jint flags)
+{
+       tjhandle handle=0;  int pixelsize;
+       unsigned long size=0;
+       unsigned char *srcbuf=NULL, *dstbuf=NULL;
+
+       gethandle();
+
+       if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPFOPT)
+               _throw("Invalid argument in encodeYUV()");
+       flags|=_flags[pf];
+       pixelsize=_pixelsize[pf];
+
+       bailif0(srcbuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
+       bailif0(dstbuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
+
+       if(tjEncodeYUV(handle, srcbuf, width, pitch, height, pixelsize, dstbuf,
+               jpegsubsamp, 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_TJCompressor_encodeYUV___3IIIII_3BII
+       (JNIEnv *env, jobject obj, jintArray src, jint width, jint pitch,
+               jint height, jint pf, jbyteArray dst, jint jpegsubsamp, jint flags)
+{
+       tjhandle handle=0;
+       unsigned long size=0;
+       unsigned char *srcbuf=NULL, *dstbuf=NULL;
+
+       gethandle();
+
+       if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPFOPT)
+               _throw("Invalid argument in compress()");
+       if(_pixelsize[pf]!=sizeof(jint))
+               _throw("Pixel format must be 32-bit when encoding from an integer buffer.");
+       flags|=_flags[pf];
+
+       bailif0(srcbuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
+       bailif0(dstbuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
+
+       if(tjEncodeYUV(handle, srcbuf, width, pitch*sizeof(jint), height,
+               sizeof(jint),   dstbuf, jpegsubsamp, 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_TJCompressor_destroy
        (JNIEnv *env, jobject obj)
 {
@@ -228,13 +311,18 @@ 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)
+               jint width, jint pitch, jint height, jint pf, jint flags)
 {
-       tjhandle handle=0;
+       tjhandle handle=0;  int pixelsize;
        unsigned char *srcbuf=NULL, *dstbuf=NULL;
 
        gethandle();
 
+       if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPFOPT)
+               _throw("Invalid argument in decompress()");
+       flags|=_flags[pf];
+       pixelsize=_pixelsize[pf];
+
        bailif0(srcbuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
        bailif0(dstbuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
 
@@ -252,15 +340,21 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress
        return;
 }
 
-JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIII
+JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIII
        (JNIEnv *env, jobject obj, jbyteArray src, jint size, jintArray dst,
-               jint width, jint pitch, jint height, jint flags)
+               jint width, jint pitch, jint height, jint pf, jint flags)
 {
-       tjhandle handle=0;
+       tjhandle handle=0;  int ps;
        unsigned char *srcbuf=NULL, *dstbuf=NULL;
 
        gethandle();
 
+       if(pf<0 || pf>=org_libjpegturbo_turbojpeg_TJ_NUMPFOPT)
+               _throw("Invalid argument in decompress()");
+       if(_pixelsize[pf]!=sizeof(jint))
+               _throw("Pixel format must be 32-bit when decompressing to an integer buffer.");
+       flags|=_flags[pf];
+
        bailif0(srcbuf=(*env)->GetPrimitiveArrayCritical(env, src, 0));
        bailif0(dstbuf=(*env)->GetPrimitiveArrayCritical(env, dst, 0));
 
@@ -276,7 +370,31 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress
        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_decompressToYUV
+       (JNIEnv *env, jobject obj, jbyteArray src, jint size, jbyteArray dst,
+               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(tjDecompressToYUV(handle, srcbuf, (unsigned long)size, dstbuf, 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
index eead41bbb0be7888d3315400716d9208cb0dc057..f5277a5a95d35f8e9f1fefc7204ee21aaee32756 100755 (executable)
@@ -30,12 +30,15 @@ TURBOJPEG_1.2
                Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV;
                Java_org_libjpegturbo_turbojpeg_TJCompressor_init;
                Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3BIIII_3BIII;
-               Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIII_3BIII;
+               Java_org_libjpegturbo_turbojpeg_TJCompressor_compress___3IIIII_3BIII;
                Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy;
+               Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3BIIII_3BII;
+               Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV___3IIIII_3BII;
                Java_org_libjpegturbo_turbojpeg_TJDecompressor_init;
                Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressHeader;
                Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3BIIIII;
-               Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIII;
+               Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress___3BI_3IIIIII;
+               Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV;
                Java_org_libjpegturbo_turbojpeg_TJDecompressor_destroy;         
                Java_org_libjpegturbo_turbojpeg_TJDecompressor_getScaledHeight;
                Java_org_libjpegturbo_turbojpeg_TJDecompressor_getScaledWidth;