diff options
author | dcommander <dcommander@632fc199-4ca6-4c93-a231-07263d6284db> | 2011-02-23 02:20:49 +0000 |
---|---|---|
committer | dcommander <dcommander@632fc199-4ca6-4c93-a231-07263d6284db> | 2011-02-23 02:20:49 +0000 |
commit | 71a2597162730c99e56bae45dd92f7b2c368fd64 (patch) | |
tree | cb4ad70486ebd93711f686b2fb44406da92fc516 /java | |
parent | 008b115d517aa471173cb3f8ae130c2d3f5fb57a (diff) |
More JNI cleanup + added unit test and fixed bugs uncovered by it
git-svn-id: svn://svn.code.sf.net/p/libjpeg-turbo/code/trunk@431 632fc199-4ca6-4c93-a231-07263d6284db
Diffstat (limited to 'java')
-rw-r--r-- | java/TJExample.java | 18 | ||||
-rw-r--r-- | java/TJUnitTest.java | 706 | ||||
-rw-r--r-- | java/org/libjpegturbo/turbojpeg/TJ.java | 56 | ||||
-rw-r--r-- | java/org/libjpegturbo/turbojpeg/TJCompressor.java | 6 | ||||
-rw-r--r-- | java/org/libjpegturbo/turbojpeg/TJDecompressor.java | 61 | ||||
-rw-r--r-- | java/org/libjpegturbo/turbojpeg/TJHeaderInfo.java | 35 | ||||
-rw-r--r-- | java/org_libjpegturbo_turbojpeg_TJ.h | 64 | ||||
-rw-r--r-- | java/org_libjpegturbo_turbojpeg_TJCompressor.h | 4 | ||||
-rw-r--r-- | java/org_libjpegturbo_turbojpeg_TJDecompressor.h | 10 |
9 files changed, 820 insertions, 140 deletions
diff --git a/java/TJExample.java b/java/TJExample.java index 3362e81..4db7a63 100644 --- a/java/TJExample.java +++ b/java/TJExample.java @@ -84,10 +84,10 @@ public class TJExample { int subsamp=tjd.getSubsamp(); System.out.print("Source Image: "+width+" x "+height+" pixels, "); switch(subsamp) { - case TJ.SAMP444: System.out.println("4:4:4 subsampling"); break; - case TJ.SAMP422: System.out.println("4:2:2 subsampling"); break; - case TJ.SAMP420: System.out.println("4:2:0 subsampling"); break; - case TJ.GRAYSCALE: System.out.println("Grayscale"); break; + case TJ.SAMP_444: System.out.println("4:4:4 subsampling"); break; + case TJ.SAMP_422: System.out.println("4:2:2 subsampling"); break; + case TJ.SAMP_420: System.out.println("4:2:0 subsampling"); break; + case TJ.SAMP_GRAY: System.out.println("Grayscale"); break; default: System.out.println("Unknown subsampling"); break; } @@ -98,17 +98,17 @@ public class TJExample { +" pixels"); } - byte [] tmpbuf=tjd.decompress(width, 0, height, TJ.BGR, TJ.BOTTOMUP); + byte [] tmpbuf=tjd.decompress(width, 0, height, TJ.PF_BGR, TJ.BOTTOMUP); tjd.close(); - TJCompressor tjc=new TJCompressor(tmpbuf, width, 0, height, TJ.BGR); - byte [] outputbuf=new byte[(int)TJ.bufSize(width, height)]; - long outputsize=tjc.compress(outputbuf, subsamp, 95, TJ.BOTTOMUP); + TJCompressor tjc=new TJCompressor(tmpbuf, width, 0, height, TJ.PF_BGR); + byte [] outputbuf=new byte[TJ.bufSize(width, height)]; + int outputsize=tjc.compress(outputbuf, subsamp, 95, TJ.BOTTOMUP); tjc.close(); file=new File(argv[1]); FileOutputStream fos=new FileOutputStream(file); - fos.write(outputbuf, 0, (int)outputsize); + fos.write(outputbuf, 0, outputsize); fos.close(); } catch(Exception e) { diff --git a/java/TJUnitTest.java b/java/TJUnitTest.java new file mode 100644 index 0000000..e52b1f8 --- /dev/null +++ b/java/TJUnitTest.java @@ -0,0 +1,706 @@ +/* + * Copyright (C)2011 D. R. Commander. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of the libjpeg-turbo Project nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This program tests the various code paths in the TurboJPEG JNI Wrapper + */ + +import java.io.*; +import java.util.*; +import org.libjpegturbo.turbojpeg.*; + +public class TJUnitTest { + + private static final String classname=new TJUnitTest().getClass().getName(); + + private static void usage() { + System.out.println("\nUSAGE: java "+classname+" [options]\n"); + System.out.println("Options:\n"); + System.out.println("-yuv = test YUV encoding/decoding support\n"); + System.exit(1); + } + + private final static String _subnamel[]= + {"4:4:4", "4:2:2", "4:2:0", "GRAY"}; + private final static String _subnames[]= + {"444", "422", "420", "GRAY"}; + private final static int _hsf[]={1, 2, 2, 1}; + private final static int _vsf[]={1, 1, 2, 1}; + + 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 _3byteFormats[]= + {TJ.PF_RGB, TJ.PF_BGR}; + private final static int _4byteFormats[]= + {TJ.PF_RGBX, TJ.PF_BGRX, TJ.PF_XBGR, TJ.PF_XRGB}; + private final static int _onlyGray[]= + {TJ.PF_GRAY}; + private final static int _onlyRGB[]= + {TJ.PF_RGB}; + + private final static int YUVENCODE=1, YUVDECODE=2; + private static int yuv=0; + + private static int exitstatus=0; + + private static double gettime() + { + return (double)System.nanoTime()/1.0e9; + } + + private final static byte pixels[][]= + { + {0, (byte)255, 0}, + {(byte)255, 0, (byte)255}, + {(byte)255, (byte)255, 0}, + {0, 0, (byte)255}, + {0, (byte)255, (byte)255}, + {(byte)255, 0, 0}, + {(byte)255, (byte)255, (byte)255}, + {0, 0, 0}, + {(byte)255, 0, 0} + }; + + private static void initbuf(byte [] buf, int w, int h, int pf, int flags) + { + int roffset=_roffset[pf], goffset=_goffset[pf], boffset=_boffset[pf]; + int ps=TJ.pixelSize[pf]; + int i, _i, j; + + Arrays.fill(buf, (byte)0); + 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) buf[w*i+j]=(byte)255; + else buf[w*i+j]=76; + } + } + 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) buf[w*i+j]=0; + else buf[w*i+j]=(byte)226; + } + } + 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++) + { + buf[(w*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; + } + } + } + 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) + { + buf[(w*i+j)*ps+roffset]=(byte)255; + buf[(w*i+j)*ps+goffset]=(byte)255; + } + } + } + } + + private static void dumpbuf(byte [] buf, int w, int h, int pf, + int scalefactor, int flags) + { + 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++) + { + 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"); + } + } + + private static void checkval(int i, int j, byte v, String vname, int cvi) + throws Exception + { + int vi=(v<0)? v+256:v; + if(vi<cvi-1 || vi>cvi+1) + { + throw new Exception("\nComp. "+vname+" at "+i+","+j+" should be "+cvi + +", not "+v+"\n"); + } + } + + private static void checkval0(int i, int j, byte v, String vname) + throws Exception + { + int vi=(v<0)? v+256:v; + if(vi>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) + throws Exception + { + int vi=(v<0)? v+256:v; + if(vi<254 && !(vi==217 && i==0 && j==21)) + { + throw new Exception("\nComp. "+vname+" at "+i+","+j+" should be 255, not " + +v+"\n"); + } + } + + private static int checkbuf(byte [] buf, int w, 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 i, _i, j, retval=1; + 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++) + { + 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 + { + 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) + { + 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++) + { + 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"); + } + } + } + for(_i=halfway; _i<h; _i++) + { + if((flags&TJ.BOTTOMUP)!=0) i=h-_i-1; else i=_i; + for(j=0; j<w; j++) + { + checkval0(_i, j, buf[(w*i+j)*ps+boffset], "B"); + if(((_i/blocksize)+(j/blocksize))%2==0) + { + checkval0(_i, j, buf[(w*i+j)*ps+roffset], "R"); + checkval0(_i, j, buf[(w*i+j)*ps+goffset], "G"); + } + else + { + checkval255(_i, j, buf[(w*i+j)*ps+roffset], "R"); + checkval255(_i, j, buf[(w*i+j)*ps+goffset], "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))); + } + + private static int checkbufyuv(byte [] buf, int size, int w, int h, + int subsamp) + { + int i, j; + int hsf=_hsf[subsamp], vsf=_vsf[subsamp]; + int pw=PAD(w, hsf), ph=PAD(h, vsf); + int cw=pw/hsf, ch=ph/vsf; + int ypitch=PAD(pw, 4), uvpitch=PAD(cw, 4); + int retval=1; + int correctsize=ypitch*ph + (subsamp==TJ.SAMP_GRAY? 0:uvpitch*ch*2); + + try + { + if(size!=correctsize) + throw new Exception("\nIncorrect size "+size+". Should be " + +correctsize); + + for(i=0; i<16; i++) + { + for(j=0; j<pw; j++) + { + byte y=buf[ypitch*i+j]; + if(((i/8)+(j/8))%2==0) checkval255(i, j, y, "Y"); + else checkval(i, j, y, "Y", 76); + } + } + for(i=16; i<ph; i++) + { + for(j=0; j<pw; j++) + { + byte y=buf[ypitch*i+j]; + if(((i/8)+(j/8))%2==0) checkval0(i, j, y, "Y"); + else checkval(i, j, y, "Y", 226); + } + } + if(subsamp!=TJ.SAMP_GRAY) + { + for(i=0; i<16/vsf; i++) + { + for(j=0; j<cw; j++) + { + byte u=buf[ypitch*ph + (uvpitch*i+j)], + v=buf[ypitch*ph + uvpitch*ch + (uvpitch*i+j)]; + if(((i*vsf/8)+(j*hsf/8))%2==0) + { + checkval(i, j, u, "U", 128); checkval(i, j, v, "V", 128); + } + else + { + checkval(i, j, u, "U", 85); checkval255(i, j, v, "V"); + } + } + } + for(i=16/vsf; i<ch; i++) + { + for(j=0; j<cw; j++) + { + byte u=buf[ypitch*ph + (uvpitch*i+j)], + v=buf[ypitch*ph + uvpitch*ch + (uvpitch*i+j)]; + if(((i*vsf/8)+(j*hsf/8))%2==0) + { + checkval(i, j, u, "U", 128); checkval(i, j, v, "V", 128); + } + else + { + checkval0(i, j, u, "U"); checkval(i, j, v, "V", 149); + } + } + } + } + } + catch(Exception e) + { + System.out.println(e); + retval=0; + } + + if(retval==0) + { + for(i=0; i<ph; i++) + { + for(j=0; j<pw; j++) + { + int y=buf[ypitch*i+j]; + if(y<0) y+=256; + System.out.format("%3d ", y); + } + System.out.print("\n"); + } + System.out.print("\n"); + for(i=0; i<ch; i++) + { + for(j=0; j<cw; j++) + { + int u=buf[ypitch*ph + (uvpitch*i+j)]; + if(u<0) u+=256; + System.out.format("%3d ", u); + } + System.out.print("\n"); + } + System.out.print("\n"); + for(i=0; i<ch; i++) + { + for(j=0; j<cw; j++) + { + int v=buf[ypitch*ph + uvpitch*ch + (uvpitch*i+j)]; + if(v<0) v+=256; + System.out.format("%3d ", v); + } + System.out.print("\n"); + } + System.out.print("\n"); + } + + return retval; + } + + private static void writejpeg(byte [] jpegbuf, int jpgbufsize, + String filename) throws Exception + { + File file=new File(filename); + FileOutputStream fos=new FileOutputStream(file); + fos.write(jpegbuf, 0, jpgbufsize); + fos.close(); + } + + private static int gentestjpeg(TJCompressor tjc, byte [] jpegbuf, int w, + int h, int pf, String basefilename, int subsamp, int qual, + int flags) throws Exception + { + String tempstr; byte [] bmpbuf; + String pixformat; double t; + int size=0; + + if(yuv==YUVENCODE) flags|=TJ.YUV; + + pixformat=_pixformatstr[pf]; + + System.out.print(pixformat+" "); + if((flags&TJ.BOTTOMUP)!=0) System.out.print("Bottom-Up"); + else System.out.print("Top-Down "); + System.out.print(" -> "+_subnamel[subsamp]+" "); + 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); + Arrays.fill(jpegbuf, (byte)0); + + t=gettime(); + tjc.setBitmapBuffer(bmpbuf, w, 0, h, pf); + size=tjc.compress(jpegbuf, subsamp, qual, flags); + t=gettime()-t; + + if(yuv==YUVENCODE) + tempstr=basefilename+"_enc_"+pixformat+"_" + +(((flags&TJ.BOTTOMUP)!=0)? "BU":"TD")+"_"+_subnames[subsamp]+".yuv"; + else + tempstr=basefilename+"_enc_"+pixformat+"_" + +(((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) + System.out.print("Passed."); + else {System.out.print("FAILED!"); exitstatus=-1;} + } + else System.out.print("Done."); + System.out.format(" %.6f ms\n", t*1000.); + System.out.println(" Result in "+tempstr); + + return size; + } + + private static void _gentestbmp(TJDecompressor tjd, byte [] jpegbuf, + 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; + int scaledw=(w+scalefactor-1)/scalefactor; + int scaledh=(h+scalefactor-1)/scalefactor; + int temp1, temp2; + + if(yuv==YUVDECODE) flags|=TJ.YUV; + else if(yuv==YUVENCODE) return; + + pixformat=_pixformatstr[pf]; + System.out.print("JPEG -> "); + if(yuv==YUVDECODE) + System.out.print("YUV "+_subnames[subsamp]+" ... "); + else + { + System.out.print(pixformat+" "); + if((flags&TJ.BOTTOMUP)!=0) System.out.print("Bottom-Up "); + else System.out.print("Top-Down "); + if(scalefactor!=1) System.out.print("1/"+scalefactor+" ... "); + else System.out.print("... "); + } + + t=gettime(); + tjd.setJPEGBuffer(jpegbuf, jpegsize); + if(tjd.getWidth()!=w || tjd.getHeight()!=h || tjd.getSubsamp()!=subsamp) + throw new Exception("Incorrect JPEG header"); + + temp1=scaledw; temp2=scaledh; + temp1=tjd.getScaledWidth(temp1, temp2); + temp2=tjd.getScaledHeight(temp1, temp2); + if(temp1!=scaledw || temp2!=scaledh) + throw new Exception("Scaled size mismatch"); + + byte [] bmpbuf=tjd.decompress(scaledw, 0, scaledh, pf, flags); + t=gettime()-t; + + if(yuv==YUVDECODE) + { + if(checkbufyuv(bmpbuf, bmpbuf.length, w, h, subsamp)==1) + System.out.print("Passed."); + else {System.out.print("FAILED!"); exitstatus=-1;} + } + else + { + if(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); + } + } + System.out.format(" %.6f ms\n", t*1000.); + } + + private static void gentestbmp(TJDecompressor tjd, byte [] jpegbuf, + int jpegsize, int w, int h, int pf, String basefilename, int subsamp, + int flags) throws Exception + { + int i; + if((subsamp==TJ.SAMP_444 || subsamp==TJ.SAMP_GRAY) && yuv==0) + { + for(i=1; i<=8; i*=2) + _gentestbmp(tjd, jpegbuf, jpegsize, w, h, pf, basefilename, subsamp, + flags, i); + } + else + _gentestbmp(tjd, jpegbuf, jpegsize, w, h, pf, basefilename, subsamp, + flags, 1); + System.out.print("\n"); + } + + private static void dotest(int w, int h, int [] formats, int subsamp, + String basefilename) throws Exception + { + TJCompressor tjc=null; TJDecompressor tjd=null; + int size; int pfstart, pfend; + + byte [] jpegbuf=new byte[TJ.bufSize(w, h)]; + + try + { + tjc=new TJCompressor(); + tjd=new TJDecompressor(); + + for(int pf : formats) + { + for(int i=0; i<2; i++) + { + int flags=0; + if(i==1) + { + if(yuv==YUVDECODE) + { + tjc.close(); tjd.close(); return; + } + else flags|=TJ.BOTTOMUP; + } + size=gentestjpeg(tjc, jpegbuf, w, h, pf, basefilename, subsamp, 100, + flags); + gentestbmp(tjd, jpegbuf, size, w, h, pf, basefilename, subsamp, + flags); + } + } + } + catch(Exception e) + { + if(tjc!=null) tjc.close(); + if(tjd!=null) tjd.close(); + throw e; + } + if(tjc!=null) tjc.close(); + if(tjd!=null) tjd.close(); + } + + private final static int MAXLENGTH=2048; + + private static void dotest1() throws Exception + { + int i, j, i2; byte [] bmpbuf, jpgbuf; + TJCompressor tjc=null; int size; + + try + { + tjc=new TJCompressor(); + System.out.println("Buffer size regression test"); + for(j=1; j<48; j++) + { + for(i=1; i<(j==1?MAXLENGTH:48); i++) + { + if(i%100==0) System.out.format("%04d x %04d\b\b\b\b\b\b\b\b\b\b\b", + i, j); + bmpbuf=new byte[i*j*4]; + jpgbuf=new byte[TJ.bufSize(i, j)]; + Arrays.fill(bmpbuf, (byte)0); + for(i2=0; i2<i*j; i2++) + { + bmpbuf[i2*4]=pixels[i2%9][2]; + bmpbuf[i2*4+1]=pixels[i2%9][1]; + 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); + + bmpbuf=new byte[j*i*4]; + jpgbuf=new byte[TJ.bufSize(j, i)]; + for(i2=0; i2<j*i; i2++) + { + if(i2%2==0) bmpbuf[i2*4]=bmpbuf[i2*4+1]=bmpbuf[i2*4+2]=(byte)0xFF; + 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); + } + } + System.out.println("Done. "); + } + catch(Exception e) + { + if(tjc!=null) tjc.close(); + throw e; + } + if(tjc!=null) tjc.close(); + } + + public static void main(String argv[]) + { + try + { + boolean doyuv=false; + for(int i=0; i<argv.length; i++) + { + if(argv[i].equalsIgnoreCase("-yuv")) doyuv=true; + if(argv[i].substring(0, 1).equalsIgnoreCase("-h") + || argv[i].equalsIgnoreCase("-?")) + usage(); + } + if(doyuv) yuv=YUVENCODE; + dotest(35, 39, _3byteFormats, TJ.SAMP_444, "test"); + dotest(39, 41, _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(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(); + if(doyuv) + { + yuv=YUVDECODE; + dotest(48, 48, _onlyRGB, TJ.SAMP_444, "test"); + dotest(35, 39, _onlyRGB, TJ.SAMP_444, "test"); + dotest(48, 48, _onlyRGB, TJ.SAMP_422, "test"); + 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, _onlyGray, TJ.SAMP_GRAY, "test"); + dotest(35, 39, _onlyGray, TJ.SAMP_GRAY, "test"); + } + } + catch(Exception e) + { + System.out.println(e); + } + System.exit(exitstatus); + } +} diff --git a/java/org/libjpegturbo/turbojpeg/TJ.java b/java/org/libjpegturbo/turbojpeg/TJ.java index 6bbbd72..9951fa2 100644 --- a/java/org/libjpegturbo/turbojpeg/TJ.java +++ b/java/org/libjpegturbo/turbojpeg/TJ.java @@ -30,31 +30,31 @@ package org.libjpegturbo.turbojpeg; final public class TJ { - // Subsampling options + // Chrominance subsampling options final public static int - NUMSUBOPT = 4, - SAMP444 = 0, - SAMP422 = 1, - SAMP420 = 2, - GRAYSCALE = 3; + NUMSAMPOPT = 4, + SAMP_444 = 0, + SAMP_422 = 1, + SAMP_420 = 2, + SAMP_GRAY = 3; - // Pixel formats + // Bitmap pixel formats final public static int - NUMPIXFORMATS = 7, - RGB = 0, - BGR = 1, - RGBX = 2, - BGRX = 3, - XBGR = 4, - XRGB = 5, - YUV = 6; + NUMPFOPT = 7, + PF_RGB = 0, + PF_BGR = 1, + PF_RGBX = 2, + PF_BGRX = 3, + PF_XBGR = 4, + PF_XRGB = 5, + PF_GRAY = 6; final public static int pixelSize[] = { - 3, 3, 4, 4, 4, 4, 3 + 3, 3, 4, 4, 4, 4, 1 }; - public static int getPixelSize(int pixelFormat) throws Exception { - if(pixelFormat < 0 || pixelFormat >= NUMPIXFORMATS) + final public static int getPixelSize(int pixelFormat) throws Exception { + if(pixelFormat < 0 || pixelFormat >= NUMPFOPT) throw new Exception("Invalid pixel format"); return pixelSize[pixelFormat]; } @@ -66,27 +66,31 @@ final public class TJ { FORCESSE = 16, FORCESSE2 = 32, FORCESSE3 = 128, - FASTUPSAMPLE = 256; + FASTUPSAMPLE = 256, + YUV = 512; final private static int TJ_BGR = 1, - TJ_ALPHAFIRST = 64, - TJ_YUV = 512; + TJ_ALPHAFIRST = 64; final private static int flags[] = { - 0, TJ_BGR, 0, TJ_BGR, TJ_BGR|TJ_ALPHAFIRST, TJ_ALPHAFIRST, TJ_YUV + 0, TJ_BGR, 0, TJ_BGR, TJ_BGR|TJ_ALPHAFIRST, TJ_ALPHAFIRST, 0 }; - public static int getFlags(int pixelFormat) throws Exception { - if(pixelFormat < 0 || pixelFormat >= NUMPIXFORMATS) + final public static int getFlags(int pixelFormat) throws Exception { + if(pixelFormat < 0 || pixelFormat >= NUMPFOPT) throw new Exception("Invalid pixel format"); return flags[pixelFormat]; } - public native final static long bufSize(int width, int height) + public native final static int bufSize(int width, int height) throws Exception; - public native final static long bufSizeYUV(int width, int height, + public native final static int bufSizeYUV(int width, int height, int subsamp) throws Exception; + + static { + System.loadLibrary("turbojpeg"); + } }; diff --git a/java/org/libjpegturbo/turbojpeg/TJCompressor.java b/java/org/libjpegturbo/turbojpeg/TJCompressor.java index 38de21f..8833570 100644 --- a/java/org/libjpegturbo/turbojpeg/TJCompressor.java +++ b/java/org/libjpegturbo/turbojpeg/TJCompressor.java @@ -43,7 +43,7 @@ public class TJCompressor { int pixelFormat) throws Exception { if(handle == 0) init(); if(buf == null || width < 1 || height < 1 || pitch < 0 || pixelFormat < 0 - || pixelFormat >= TJ.NUMPIXFORMATS) + || pixelFormat >= TJ.NUMPFOPT) throw new Exception("Invalid argument in setBitmapBuffer()"); bitmapBuf = buf; bitmapWidth = width; @@ -53,7 +53,7 @@ public class TJCompressor { bitmapPixelFormat = pixelFormat; } - public long compress(byte [] dstBuf, int jpegSubsamp, int jpegQual, + 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, @@ -79,7 +79,7 @@ public class TJCompressor { private native void destroy() throws Exception; // JPEG size in bytes is returned - private native long compress(byte [] srcBuf, int width, int pitch, + private native int compress(byte [] srcBuf, int width, int pitch, int height, int pixelSize, byte [] dstbuf, int jpegSubsamp, int jpegQual, int flags) throws Exception; diff --git a/java/org/libjpegturbo/turbojpeg/TJDecompressor.java b/java/org/libjpegturbo/turbojpeg/TJDecompressor.java index 446eb3c..01d5e9c 100644 --- a/java/org/libjpegturbo/turbojpeg/TJDecompressor.java +++ b/java/org/libjpegturbo/turbojpeg/TJDecompressor.java @@ -35,70 +35,76 @@ public class TJDecompressor { } public TJDecompressor(byte [] buf) throws Exception { - setJPEGBuffer(buf); + setJPEGBuffer(buf, buf.length); } - public void setJPEGBuffer(byte [] buf) throws Exception { + public TJDecompressor(byte [] buf, int bufSize) throws Exception { + setJPEGBuffer(buf, bufSize); + } + + public void setJPEGBuffer(byte [] buf, int bufSize) throws Exception { if(handle == 0) init(); - if(buf == null) throw new Exception("Invalid argument in setJPEGBuffer()"); + if(buf == null || bufSize < 1) + throw new Exception("Invalid argument in setJPEGBuffer()"); jpegBuf = buf; - decompressHeader(); + jpegBufSize = bufSize; + decompressHeader(jpegBuf, jpegBufSize); } public int getWidth() throws Exception { - if(header.width < 1) throw new Exception("JPEG buffer not initialized"); - return header.width; + if(jpegWidth < 1) throw new Exception("JPEG buffer not initialized"); + return jpegWidth; } public int getHeight() throws Exception { - if(header.height < 1) throw new Exception("JPEG buffer not initialized"); - return header.height; + if(jpegHeight < 1) throw new Exception("JPEG buffer not initialized"); + return jpegHeight; } public int getSubsamp() throws Exception { - if(header.subsamp < 0) throw new Exception("JPEG buffer not initialized"); - return header.subsamp; + if(jpegSubsamp < 0) throw new Exception("JPEG buffer not initialized"); + return jpegSubsamp; } public int getScaledWidth(int desired_width, int desired_height) throws Exception { - if(header.width < 1 || header.height < 1) + if(jpegWidth < 1 || jpegHeight < 1) throw new Exception("JPEG buffer not initialized"); - return getScaledWidth(header.width, header.height, desired_width, + return getScaledWidth(jpegWidth, jpegHeight, desired_width, desired_height); } public int getScaledHeight(int output_width, int output_height) throws Exception { - if(header.width < 1 || header.height < 1) + if(jpegWidth < 1 || jpegHeight < 1) throw new Exception("JPEG buffer not initialized"); - return getScaledHeight(header.width, header.height, output_width, + return getScaledHeight(jpegWidth, jpegHeight, output_width, output_height); } public void decompress(byte [] dstBuf, int width, int pitch, int height, int pixelFormat, int flags) throws Exception { if(jpegBuf == null) throw new Exception("JPEG buffer not initialized"); - decompress(jpegBuf, jpegBuf.length, dstBuf, width, pitch, height, + decompress(jpegBuf, jpegBufSize, dstBuf, width, pitch, height, TJ.getPixelSize(pixelFormat), flags | TJ.getFlags(pixelFormat)); } public byte [] decompress(int width, int pitch, int height, int pixelFormat, int flags) throws Exception { if(width < 0 || height < 0 || pitch < 0 || pixelFormat < 0 - || pixelFormat >= TJ.NUMPIXFORMATS) + || pixelFormat >= TJ.NUMPFOPT) throw new Exception("Invalid argument in decompress()"); int pixelSize = TJ.getPixelSize(pixelFormat); int scaledWidth = getScaledWidth(width, height); int scaledHeight = getScaledHeight(width, height); if(pitch == 0) pitch = scaledWidth * pixelSize; - long bufSize; - if(pixelFormat == TJ.YUV) - bufSize = TJ.bufSizeYUV(width, height, header.subsamp); + int bufSize; + if((flags&TJ.YUV)!=0) + bufSize = TJ.bufSizeYUV(width, height, jpegSubsamp); else bufSize = pitch * scaledHeight; - byte [] buf = new byte[(int)bufSize]; + byte [] buf = new byte[bufSize]; if(jpegBuf == null) throw new Exception("JPEG buffer not initialized"); - decompress(jpegBuf, jpegBuf.length, buf, width, pitch, height, + decompress(jpegBuf, jpegBufSize, buf, width, pitch, height, TJ.getPixelSize(pixelFormat), flags | TJ.getFlags(pixelFormat)); return buf; } @@ -121,14 +127,10 @@ public class TJDecompressor { private native void destroy() throws Exception; - private native TJHeaderInfo decompressHeader(byte [] srcBuf, long size) + private native void decompressHeader(byte [] srcBuf, int size) throws Exception; - private void decompressHeader() throws Exception { - header = decompressHeader(jpegBuf, jpegBuf.length); - } - - private native void decompress(byte [] srcBuf, long size, byte [] dstBuf, + private native void decompress(byte [] srcBuf, int size, byte [] dstBuf, int width, int pitch, int height, int pixelSize, int flags) throws Exception; @@ -144,5 +146,8 @@ public class TJDecompressor { private long handle = 0; private byte [] jpegBuf = null; - TJHeaderInfo header = null; + private int jpegBufSize = 0; + private int jpegWidth = 0; + private int jpegHeight = 0; + private int jpegSubsamp = -1; }; diff --git a/java/org/libjpegturbo/turbojpeg/TJHeaderInfo.java b/java/org/libjpegturbo/turbojpeg/TJHeaderInfo.java deleted file mode 100644 index e4ee59f..0000000 --- a/java/org/libjpegturbo/turbojpeg/TJHeaderInfo.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C)2011 D. R. Commander. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - Neither the name of the libjpeg-turbo Project nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -package org.libjpegturbo.turbojpeg; - -public class TJHeaderInfo { - public int subsamp = -1; - public int width = -1; - public int height = -1; -}; diff --git a/java/org_libjpegturbo_turbojpeg_TJ.h b/java/org_libjpegturbo_turbojpeg_TJ.h index 7009251..a1fe82d 100644 --- a/java/org_libjpegturbo_turbojpeg_TJ.h +++ b/java/org_libjpegturbo_turbojpeg_TJ.h @@ -7,32 +7,32 @@ #ifdef __cplusplus extern "C" { #endif -#undef org_libjpegturbo_turbojpeg_TJ_NUMSUBOPT -#define org_libjpegturbo_turbojpeg_TJ_NUMSUBOPT 4L -#undef org_libjpegturbo_turbojpeg_TJ_SAMP444 -#define org_libjpegturbo_turbojpeg_TJ_SAMP444 0L -#undef org_libjpegturbo_turbojpeg_TJ_SAMP422 -#define org_libjpegturbo_turbojpeg_TJ_SAMP422 1L -#undef org_libjpegturbo_turbojpeg_TJ_SAMP420 -#define org_libjpegturbo_turbojpeg_TJ_SAMP420 2L -#undef org_libjpegturbo_turbojpeg_TJ_GRAYSCALE -#define org_libjpegturbo_turbojpeg_TJ_GRAYSCALE 3L -#undef org_libjpegturbo_turbojpeg_TJ_NUMPIXFORMATS -#define org_libjpegturbo_turbojpeg_TJ_NUMPIXFORMATS 7L -#undef org_libjpegturbo_turbojpeg_TJ_RGB -#define org_libjpegturbo_turbojpeg_TJ_RGB 0L -#undef org_libjpegturbo_turbojpeg_TJ_BGR -#define org_libjpegturbo_turbojpeg_TJ_BGR 1L -#undef org_libjpegturbo_turbojpeg_TJ_RGBX -#define org_libjpegturbo_turbojpeg_TJ_RGBX 2L -#undef org_libjpegturbo_turbojpeg_TJ_BGRX -#define org_libjpegturbo_turbojpeg_TJ_BGRX 3L -#undef org_libjpegturbo_turbojpeg_TJ_XBGR -#define org_libjpegturbo_turbojpeg_TJ_XBGR 4L -#undef org_libjpegturbo_turbojpeg_TJ_XRGB -#define org_libjpegturbo_turbojpeg_TJ_XRGB 5L -#undef org_libjpegturbo_turbojpeg_TJ_YUV -#define org_libjpegturbo_turbojpeg_TJ_YUV 6L +#undef org_libjpegturbo_turbojpeg_TJ_NUMSAMPOPT +#define org_libjpegturbo_turbojpeg_TJ_NUMSAMPOPT 4L +#undef org_libjpegturbo_turbojpeg_TJ_SAMP_444 +#define org_libjpegturbo_turbojpeg_TJ_SAMP_444 0L +#undef org_libjpegturbo_turbojpeg_TJ_SAMP_422 +#define org_libjpegturbo_turbojpeg_TJ_SAMP_422 1L +#undef org_libjpegturbo_turbojpeg_TJ_SAMP_420 +#define org_libjpegturbo_turbojpeg_TJ_SAMP_420 2L +#undef org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY +#define org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY 3L +#undef org_libjpegturbo_turbojpeg_TJ_NUMPFOPT +#define org_libjpegturbo_turbojpeg_TJ_NUMPFOPT 7L +#undef org_libjpegturbo_turbojpeg_TJ_PF_RGB +#define org_libjpegturbo_turbojpeg_TJ_PF_RGB 0L +#undef org_libjpegturbo_turbojpeg_TJ_PF_BGR +#define org_libjpegturbo_turbojpeg_TJ_PF_BGR 1L +#undef org_libjpegturbo_turbojpeg_TJ_PF_RGBX +#define org_libjpegturbo_turbojpeg_TJ_PF_RGBX 2L +#undef org_libjpegturbo_turbojpeg_TJ_PF_BGRX +#define org_libjpegturbo_turbojpeg_TJ_PF_BGRX 3L +#undef org_libjpegturbo_turbojpeg_TJ_PF_XBGR +#define org_libjpegturbo_turbojpeg_TJ_PF_XBGR 4L +#undef org_libjpegturbo_turbojpeg_TJ_PF_XRGB +#define org_libjpegturbo_turbojpeg_TJ_PF_XRGB 5L +#undef org_libjpegturbo_turbojpeg_TJ_PF_GRAY +#define org_libjpegturbo_turbojpeg_TJ_PF_GRAY 6L #undef org_libjpegturbo_turbojpeg_TJ_BOTTOMUP #define org_libjpegturbo_turbojpeg_TJ_BOTTOMUP 2L #undef org_libjpegturbo_turbojpeg_TJ_FORCEMMX @@ -45,26 +45,26 @@ 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 -#undef org_libjpegturbo_turbojpeg_TJ_TJ_YUV -#define org_libjpegturbo_turbojpeg_TJ_TJ_YUV 512L /* * Class: org_libjpegturbo_turbojpeg_TJ * Method: bufSize - * Signature: (II)J + * Signature: (II)I */ -JNIEXPORT jlong JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSize +JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSize (JNIEnv *, jclass, jint, jint); /* * Class: org_libjpegturbo_turbojpeg_TJ * Method: bufSizeYUV - * Signature: (III)J + * Signature: (III)I */ -JNIEXPORT jlong JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV +JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV (JNIEnv *, jclass, jint, jint, jint); #ifdef __cplusplus diff --git a/java/org_libjpegturbo_turbojpeg_TJCompressor.h b/java/org_libjpegturbo_turbojpeg_TJCompressor.h index 090929c..3148fb6 100644 --- a/java/org_libjpegturbo_turbojpeg_TJCompressor.h +++ b/java/org_libjpegturbo_turbojpeg_TJCompressor.h @@ -26,9 +26,9 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy /* * Class: org_libjpegturbo_turbojpeg_TJCompressor * Method: compress - * Signature: ([BIIII[BIII)J + * Signature: ([BIIII[BIII)I */ -JNIEXPORT jlong JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress +JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress (JNIEnv *, jobject, jbyteArray, jint, jint, jint, jint, jbyteArray, jint, jint, jint); #ifdef __cplusplus diff --git a/java/org_libjpegturbo_turbojpeg_TJDecompressor.h b/java/org_libjpegturbo_turbojpeg_TJDecompressor.h index 3277bcf..16c3923 100644 --- a/java/org_libjpegturbo_turbojpeg_TJDecompressor.h +++ b/java/org_libjpegturbo_turbojpeg_TJDecompressor.h @@ -26,18 +26,18 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_destroy /* * Class: org_libjpegturbo_turbojpeg_TJDecompressor * Method: decompressHeader - * Signature: ([BJ)Lorg/libjpegturbo/turbojpeg/TJHeaderInfo; + * Signature: ([BI)V */ -JNIEXPORT jobject JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressHeader - (JNIEnv *, jobject, jbyteArray, jlong); +JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressHeader + (JNIEnv *, jobject, jbyteArray, jint); /* * Class: org_libjpegturbo_turbojpeg_TJDecompressor * Method: decompress - * Signature: ([BJ[BIIIII)V + * Signature: ([BI[BIIIII)V */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress - (JNIEnv *, jobject, jbyteArray, jlong, jbyteArray, jint, jint, jint, jint, jint); + (JNIEnv *, jobject, jbyteArray, jint, jbyteArray, jint, jint, jint, jint, jint); /* * Class: org_libjpegturbo_turbojpeg_TJDecompressor |