More JNI cleanup + added unit test and fixed bugs uncovered by it

git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@431 632fc199-4ca6-4c93-a231-07263d6284db
This commit is contained in:
DRC
2011-02-23 02:20:49 +00:00
parent 7ffa0c85de
commit 3bad53fa04
11 changed files with 842 additions and 168 deletions

View File

@@ -84,10 +84,10 @@ public class TJExample {
int subsamp=tjd.getSubsamp(); int subsamp=tjd.getSubsamp();
System.out.print("Source Image: "+width+" x "+height+" pixels, "); System.out.print("Source Image: "+width+" x "+height+" pixels, ");
switch(subsamp) { switch(subsamp) {
case TJ.SAMP444: System.out.println("4:4:4 subsampling"); break; case TJ.SAMP_444: System.out.println("4:4:4 subsampling"); break;
case TJ.SAMP422: System.out.println("4:2:2 subsampling"); break; case TJ.SAMP_422: System.out.println("4:2:2 subsampling"); break;
case TJ.SAMP420: System.out.println("4:2:0 subsampling"); break; case TJ.SAMP_420: System.out.println("4:2:0 subsampling"); break;
case TJ.GRAYSCALE: System.out.println("Grayscale"); break; case TJ.SAMP_GRAY: System.out.println("Grayscale"); break;
default: System.out.println("Unknown subsampling"); break; default: System.out.println("Unknown subsampling"); break;
} }
@@ -98,17 +98,17 @@ public class TJExample {
+" pixels"); +" 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(); tjd.close();
TJCompressor tjc=new TJCompressor(tmpbuf, width, 0, height, TJ.BGR); TJCompressor tjc=new TJCompressor(tmpbuf, width, 0, height, TJ.PF_BGR);
byte [] outputbuf=new byte[(int)TJ.bufSize(width, height)]; byte [] outputbuf=new byte[TJ.bufSize(width, height)];
long outputsize=tjc.compress(outputbuf, subsamp, 95, TJ.BOTTOMUP); int outputsize=tjc.compress(outputbuf, subsamp, 95, TJ.BOTTOMUP);
tjc.close(); tjc.close();
file=new File(argv[1]); file=new File(argv[1]);
FileOutputStream fos=new FileOutputStream(file); FileOutputStream fos=new FileOutputStream(file);
fos.write(outputbuf, 0, (int)outputsize); fos.write(outputbuf, 0, outputsize);
fos.close(); fos.close();
} catch(Exception e) { } catch(Exception e) {

706
java/TJUnitTest.java Normal file
View File

@@ -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);
}
}

View File

@@ -30,31 +30,31 @@ package org.libjpegturbo.turbojpeg;
final public class TJ { final public class TJ {
// Subsampling options // Chrominance subsampling options
final public static int final public static int
NUMSUBOPT = 4, NUMSAMPOPT = 4,
SAMP444 = 0, SAMP_444 = 0,
SAMP422 = 1, SAMP_422 = 1,
SAMP420 = 2, SAMP_420 = 2,
GRAYSCALE = 3; SAMP_GRAY = 3;
// Pixel formats // Bitmap pixel formats
final public static int final public static int
NUMPIXFORMATS = 7, NUMPFOPT = 7,
RGB = 0, PF_RGB = 0,
BGR = 1, PF_BGR = 1,
RGBX = 2, PF_RGBX = 2,
BGRX = 3, PF_BGRX = 3,
XBGR = 4, PF_XBGR = 4,
XRGB = 5, PF_XRGB = 5,
YUV = 6; PF_GRAY = 6;
final public static int pixelSize[] = { 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 { final public static int getPixelSize(int pixelFormat) throws Exception {
if(pixelFormat < 0 || pixelFormat >= NUMPIXFORMATS) if(pixelFormat < 0 || pixelFormat >= NUMPFOPT)
throw new Exception("Invalid pixel format"); throw new Exception("Invalid pixel format");
return pixelSize[pixelFormat]; return pixelSize[pixelFormat];
} }
@@ -66,27 +66,31 @@ final public class TJ {
FORCESSE = 16, FORCESSE = 16,
FORCESSE2 = 32, FORCESSE2 = 32,
FORCESSE3 = 128, FORCESSE3 = 128,
FASTUPSAMPLE = 256; FASTUPSAMPLE = 256,
YUV = 512;
final private static int final private static int
TJ_BGR = 1, TJ_BGR = 1,
TJ_ALPHAFIRST = 64, TJ_ALPHAFIRST = 64;
TJ_YUV = 512;
final private static int flags[] = { 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 { final public static int getFlags(int pixelFormat) throws Exception {
if(pixelFormat < 0 || pixelFormat >= NUMPIXFORMATS) if(pixelFormat < 0 || pixelFormat >= NUMPFOPT)
throw new Exception("Invalid pixel format"); throw new Exception("Invalid pixel format");
return flags[pixelFormat]; 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; throws Exception;
public native final static long bufSizeYUV(int width, int height, public native final static int bufSizeYUV(int width, int height,
int subsamp) int subsamp)
throws Exception; throws Exception;
static {
System.loadLibrary("turbojpeg");
}
}; };

View File

@@ -43,7 +43,7 @@ public class TJCompressor {
int pixelFormat) throws Exception { int pixelFormat) throws Exception {
if(handle == 0) init(); if(handle == 0) init();
if(buf == null || width < 1 || height < 1 || pitch < 0 || pixelFormat < 0 if(buf == null || width < 1 || height < 1 || pitch < 0 || pixelFormat < 0
|| pixelFormat >= TJ.NUMPIXFORMATS) || pixelFormat >= TJ.NUMPFOPT)
throw new Exception("Invalid argument in setBitmapBuffer()"); throw new Exception("Invalid argument in setBitmapBuffer()");
bitmapBuf = buf; bitmapBuf = buf;
bitmapWidth = width; bitmapWidth = width;
@@ -53,7 +53,7 @@ public class TJCompressor {
bitmapPixelFormat = pixelFormat; bitmapPixelFormat = pixelFormat;
} }
public long compress(byte [] dstBuf, int jpegSubsamp, int jpegQual, public int compress(byte [] dstBuf, int jpegSubsamp, int jpegQual,
int flags) throws Exception { int flags) throws Exception {
return compress(bitmapBuf, bitmapWidth, bitmapPitch, bitmapHeight, return compress(bitmapBuf, bitmapWidth, bitmapPitch, bitmapHeight,
TJ.getPixelSize(bitmapPixelFormat), dstBuf, jpegSubsamp, jpegQual, TJ.getPixelSize(bitmapPixelFormat), dstBuf, jpegSubsamp, jpegQual,
@@ -79,7 +79,7 @@ public class TJCompressor {
private native void destroy() throws Exception; private native void destroy() throws Exception;
// JPEG size in bytes is returned // 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 height, int pixelSize, byte [] dstbuf, int jpegSubsamp, int jpegQual,
int flags) throws Exception; int flags) throws Exception;

View File

@@ -35,70 +35,76 @@ public class TJDecompressor {
} }
public TJDecompressor(byte [] buf) throws Exception { 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(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; jpegBuf = buf;
decompressHeader(); jpegBufSize = bufSize;
decompressHeader(jpegBuf, jpegBufSize);
} }
public int getWidth() throws Exception { public int getWidth() throws Exception {
if(header.width < 1) throw new Exception("JPEG buffer not initialized"); if(jpegWidth < 1) throw new Exception("JPEG buffer not initialized");
return header.width; return jpegWidth;
} }
public int getHeight() throws Exception { public int getHeight() throws Exception {
if(header.height < 1) throw new Exception("JPEG buffer not initialized"); if(jpegHeight < 1) throw new Exception("JPEG buffer not initialized");
return header.height; return jpegHeight;
} }
public int getSubsamp() throws Exception { public int getSubsamp() throws Exception {
if(header.subsamp < 0) throw new Exception("JPEG buffer not initialized"); if(jpegSubsamp < 0) throw new Exception("JPEG buffer not initialized");
return header.subsamp; return jpegSubsamp;
} }
public int getScaledWidth(int desired_width, int desired_height) public int getScaledWidth(int desired_width, int desired_height)
throws Exception { throws Exception {
if(header.width < 1 || header.height < 1) if(jpegWidth < 1 || jpegHeight < 1)
throw new Exception("JPEG buffer not initialized"); throw new Exception("JPEG buffer not initialized");
return getScaledWidth(header.width, header.height, desired_width, return getScaledWidth(jpegWidth, jpegHeight, desired_width,
desired_height); desired_height);
} }
public int getScaledHeight(int output_width, int output_height) public int getScaledHeight(int output_width, int output_height)
throws Exception { throws Exception {
if(header.width < 1 || header.height < 1) if(jpegWidth < 1 || jpegHeight < 1)
throw new Exception("JPEG buffer not initialized"); throw new Exception("JPEG buffer not initialized");
return getScaledHeight(header.width, header.height, output_width, return getScaledHeight(jpegWidth, jpegHeight, output_width,
output_height); output_height);
} }
public void decompress(byte [] dstBuf, int width, int pitch, public void decompress(byte [] dstBuf, int width, int pitch,
int height, int pixelFormat, int flags) throws Exception { int height, int pixelFormat, int flags) throws Exception {
if(jpegBuf == null) throw new Exception("JPEG buffer not initialized"); 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)); TJ.getPixelSize(pixelFormat), flags | TJ.getFlags(pixelFormat));
} }
public byte [] decompress(int width, int pitch, int height, public byte [] decompress(int width, int pitch, int height,
int pixelFormat, int flags) throws Exception { int pixelFormat, int flags) throws Exception {
if(width < 0 || height < 0 || pitch < 0 || pixelFormat < 0 if(width < 0 || height < 0 || pitch < 0 || pixelFormat < 0
|| pixelFormat >= TJ.NUMPIXFORMATS) || pixelFormat >= TJ.NUMPFOPT)
throw new Exception("Invalid argument in decompress()"); throw new Exception("Invalid argument in decompress()");
int pixelSize = TJ.getPixelSize(pixelFormat); int pixelSize = TJ.getPixelSize(pixelFormat);
int scaledWidth = getScaledWidth(width, height); int scaledWidth = getScaledWidth(width, height);
int scaledHeight = getScaledHeight(width, height); int scaledHeight = getScaledHeight(width, height);
if(pitch == 0) pitch = scaledWidth * pixelSize; if(pitch == 0) pitch = scaledWidth * pixelSize;
long bufSize; int bufSize;
if(pixelFormat == TJ.YUV) if((flags&TJ.YUV)!=0)
bufSize = TJ.bufSizeYUV(width, height, header.subsamp); bufSize = TJ.bufSizeYUV(width, height, jpegSubsamp);
else bufSize = pitch * scaledHeight; 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"); 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)); TJ.getPixelSize(pixelFormat), flags | TJ.getFlags(pixelFormat));
return buf; return buf;
} }
@@ -121,14 +127,10 @@ public class TJDecompressor {
private native void destroy() throws Exception; private native void destroy() throws Exception;
private native TJHeaderInfo decompressHeader(byte [] srcBuf, long size) private native void decompressHeader(byte [] srcBuf, int size)
throws Exception; throws Exception;
private void decompressHeader() throws Exception { private native void decompress(byte [] srcBuf, int size, byte [] dstBuf,
header = decompressHeader(jpegBuf, jpegBuf.length);
}
private native void decompress(byte [] srcBuf, long size, byte [] dstBuf,
int width, int pitch, int height, int pixelSize, int flags) int width, int pitch, int height, int pixelSize, int flags)
throws Exception; throws Exception;
@@ -144,5 +146,8 @@ public class TJDecompressor {
private long handle = 0; private long handle = 0;
private byte [] jpegBuf = null; private byte [] jpegBuf = null;
TJHeaderInfo header = null; private int jpegBufSize = 0;
private int jpegWidth = 0;
private int jpegHeight = 0;
private int jpegSubsamp = -1;
}; };

View File

@@ -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;
};

View File

@@ -7,32 +7,32 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#undef org_libjpegturbo_turbojpeg_TJ_NUMSUBOPT #undef org_libjpegturbo_turbojpeg_TJ_NUMSAMPOPT
#define org_libjpegturbo_turbojpeg_TJ_NUMSUBOPT 4L #define org_libjpegturbo_turbojpeg_TJ_NUMSAMPOPT 4L
#undef org_libjpegturbo_turbojpeg_TJ_SAMP444 #undef org_libjpegturbo_turbojpeg_TJ_SAMP_444
#define org_libjpegturbo_turbojpeg_TJ_SAMP444 0L #define org_libjpegturbo_turbojpeg_TJ_SAMP_444 0L
#undef org_libjpegturbo_turbojpeg_TJ_SAMP422 #undef org_libjpegturbo_turbojpeg_TJ_SAMP_422
#define org_libjpegturbo_turbojpeg_TJ_SAMP422 1L #define org_libjpegturbo_turbojpeg_TJ_SAMP_422 1L
#undef org_libjpegturbo_turbojpeg_TJ_SAMP420 #undef org_libjpegturbo_turbojpeg_TJ_SAMP_420
#define org_libjpegturbo_turbojpeg_TJ_SAMP420 2L #define org_libjpegturbo_turbojpeg_TJ_SAMP_420 2L
#undef org_libjpegturbo_turbojpeg_TJ_GRAYSCALE #undef org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY
#define org_libjpegturbo_turbojpeg_TJ_GRAYSCALE 3L #define org_libjpegturbo_turbojpeg_TJ_SAMP_GRAY 3L
#undef org_libjpegturbo_turbojpeg_TJ_NUMPIXFORMATS #undef org_libjpegturbo_turbojpeg_TJ_NUMPFOPT
#define org_libjpegturbo_turbojpeg_TJ_NUMPIXFORMATS 7L #define org_libjpegturbo_turbojpeg_TJ_NUMPFOPT 7L
#undef org_libjpegturbo_turbojpeg_TJ_RGB #undef org_libjpegturbo_turbojpeg_TJ_PF_RGB
#define org_libjpegturbo_turbojpeg_TJ_RGB 0L #define org_libjpegturbo_turbojpeg_TJ_PF_RGB 0L
#undef org_libjpegturbo_turbojpeg_TJ_BGR #undef org_libjpegturbo_turbojpeg_TJ_PF_BGR
#define org_libjpegturbo_turbojpeg_TJ_BGR 1L #define org_libjpegturbo_turbojpeg_TJ_PF_BGR 1L
#undef org_libjpegturbo_turbojpeg_TJ_RGBX #undef org_libjpegturbo_turbojpeg_TJ_PF_RGBX
#define org_libjpegturbo_turbojpeg_TJ_RGBX 2L #define org_libjpegturbo_turbojpeg_TJ_PF_RGBX 2L
#undef org_libjpegturbo_turbojpeg_TJ_BGRX #undef org_libjpegturbo_turbojpeg_TJ_PF_BGRX
#define org_libjpegturbo_turbojpeg_TJ_BGRX 3L #define org_libjpegturbo_turbojpeg_TJ_PF_BGRX 3L
#undef org_libjpegturbo_turbojpeg_TJ_XBGR #undef org_libjpegturbo_turbojpeg_TJ_PF_XBGR
#define org_libjpegturbo_turbojpeg_TJ_XBGR 4L #define org_libjpegturbo_turbojpeg_TJ_PF_XBGR 4L
#undef org_libjpegturbo_turbojpeg_TJ_XRGB #undef org_libjpegturbo_turbojpeg_TJ_PF_XRGB
#define org_libjpegturbo_turbojpeg_TJ_XRGB 5L #define org_libjpegturbo_turbojpeg_TJ_PF_XRGB 5L
#undef org_libjpegturbo_turbojpeg_TJ_YUV #undef org_libjpegturbo_turbojpeg_TJ_PF_GRAY
#define org_libjpegturbo_turbojpeg_TJ_YUV 6L #define org_libjpegturbo_turbojpeg_TJ_PF_GRAY 6L
#undef org_libjpegturbo_turbojpeg_TJ_BOTTOMUP #undef org_libjpegturbo_turbojpeg_TJ_BOTTOMUP
#define org_libjpegturbo_turbojpeg_TJ_BOTTOMUP 2L #define org_libjpegturbo_turbojpeg_TJ_BOTTOMUP 2L
#undef org_libjpegturbo_turbojpeg_TJ_FORCEMMX #undef org_libjpegturbo_turbojpeg_TJ_FORCEMMX
@@ -45,26 +45,26 @@ extern "C" {
#define org_libjpegturbo_turbojpeg_TJ_FORCESSE3 128L #define org_libjpegturbo_turbojpeg_TJ_FORCESSE3 128L
#undef org_libjpegturbo_turbojpeg_TJ_FASTUPSAMPLE #undef org_libjpegturbo_turbojpeg_TJ_FASTUPSAMPLE
#define org_libjpegturbo_turbojpeg_TJ_FASTUPSAMPLE 256L #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 #undef org_libjpegturbo_turbojpeg_TJ_TJ_BGR
#define org_libjpegturbo_turbojpeg_TJ_TJ_BGR 1L #define org_libjpegturbo_turbojpeg_TJ_TJ_BGR 1L
#undef org_libjpegturbo_turbojpeg_TJ_TJ_ALPHAFIRST #undef org_libjpegturbo_turbojpeg_TJ_TJ_ALPHAFIRST
#define org_libjpegturbo_turbojpeg_TJ_TJ_ALPHAFIRST 64L #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 * Class: org_libjpegturbo_turbojpeg_TJ
* Method: bufSize * 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); (JNIEnv *, jclass, jint, jint);
/* /*
* Class: org_libjpegturbo_turbojpeg_TJ * Class: org_libjpegturbo_turbojpeg_TJ
* Method: bufSizeYUV * 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); (JNIEnv *, jclass, jint, jint, jint);
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -26,9 +26,9 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy
/* /*
* Class: org_libjpegturbo_turbojpeg_TJCompressor * Class: org_libjpegturbo_turbojpeg_TJCompressor
* Method: compress * 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); (JNIEnv *, jobject, jbyteArray, jint, jint, jint, jint, jbyteArray, jint, jint, jint);
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -26,18 +26,18 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_destroy
/* /*
* Class: org_libjpegturbo_turbojpeg_TJDecompressor * Class: org_libjpegturbo_turbojpeg_TJDecompressor
* Method: decompressHeader * Method: decompressHeader
* Signature: ([BJ)Lorg/libjpegturbo/turbojpeg/TJHeaderInfo; * Signature: ([BI)V
*/ */
JNIEXPORT jobject JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressHeader JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressHeader
(JNIEnv *, jobject, jbyteArray, jlong); (JNIEnv *, jobject, jbyteArray, jint);
/* /*
* Class: org_libjpegturbo_turbojpeg_TJDecompressor * Class: org_libjpegturbo_turbojpeg_TJDecompressor
* Method: decompress * Method: decompress
* Signature: ([BJ[BIIIII)V * Signature: ([BI[BIIIII)V
*/ */
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress 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 * Class: org_libjpegturbo_turbojpeg_TJDecompressor

View File

@@ -580,7 +580,7 @@ void dotest1(void)
{ {
bmpbuf[i2*4]=pixels[i2%9][2]; bmpbuf[i2*4]=pixels[i2%9][2];
bmpbuf[i2*4+1]=pixels[i2%9][1]; bmpbuf[i2*4+1]=pixels[i2%9][1];
bmpbuf[i2*2+2]=pixels[i2%9][0]; bmpbuf[i2*4+2]=pixels[i2%9][0];
} }
_catch(tjCompress(hnd, bmpbuf, i, 0, j, 4, _catch(tjCompress(hnd, bmpbuf, i, 0, j, 4,
jpgbuf, &size, TJ_444, 100, TJ_BGR)); jpgbuf, &size, TJ_444, 100, TJ_BGR));
@@ -591,10 +591,10 @@ void dotest1(void)
{ {
printf("Memory allocation failure\n"); bailout(); printf("Memory allocation failure\n"); bailout();
} }
for(i2=0; i2<j*i*4; i2++) for(i2=0; i2<j*i; i2++)
{ {
if(i2%2==0) bmpbuf[i2]=0xFF; if(i2%2==0) bmpbuf[i2*4]=bmpbuf[i2*4+1]=bmpbuf[i2*4+2]=0xFF;
else bmpbuf[i2]=0; else bmpbuf[i2*4]=bmpbuf[i2*4+1]=bmpbuf[i2*4+2]=0;
} }
_catch(tjCompress(hnd, bmpbuf, j, 0, i, 4, _catch(tjCompress(hnd, bmpbuf, j, 0, i, 4,
jpgbuf, &size, TJ_444, 100, TJ_BGR)); jpgbuf, &size, TJ_444, 100, TJ_BGR));

View File

@@ -41,28 +41,27 @@
#define bailif0(f) {if(!(f)) goto bailout;} #define bailif0(f) {if(!(f)) goto bailout;}
#define gethandle() { \ #define gethandle() \
jclass _cls=(*env)->GetObjectClass(env, obj); \ jclass _cls=(*env)->GetObjectClass(env, obj); \
jfieldID _fid; \ jfieldID _fid; \
if(!_cls) goto bailout; \ if(!_cls) goto bailout; \
bailif0(_fid=(*env)->GetFieldID(env, _cls, "handle", "J")); \ bailif0(_fid=(*env)->GetFieldID(env, _cls, "handle", "J")); \
handle=(tjhandle)(long)(*env)->GetLongField(env, obj, _fid); \ handle=(tjhandle)(long)(*env)->GetLongField(env, obj, _fid); \
}
JNIEXPORT jlong JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSize JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSize
(JNIEnv *env, jclass cls, jint width, jint height) (JNIEnv *env, jclass cls, jint width, jint height)
{ {
jlong retval=TJBUFSIZE(width, height); jint retval=(jint)TJBUFSIZE(width, height);
if(retval==-1) _throw(tjGetErrorStr()); if(retval==-1) _throw(tjGetErrorStr());
bailout: bailout:
return retval; return retval;
} }
JNIEXPORT jlong JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV
(JNIEnv *env, jclass cls, jint width, jint height, jint subsamp) (JNIEnv *env, jclass cls, jint width, jint height, jint subsamp)
{ {
jlong retval=TJBUFSIZEYUV(width, height, subsamp); jint retval=(jint)TJBUFSIZEYUV(width, height, subsamp);
if(retval==-1) _throw(tjGetErrorStr()); if(retval==-1) _throw(tjGetErrorStr());
bailout: bailout:
@@ -87,7 +86,7 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_init
return; return;
} }
JNIEXPORT jlong JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress
(JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch, (JNIEnv *env, jobject obj, jbyteArray src, jint width, jint pitch,
jint height, jint pixelsize, jbyteArray dst, jint jpegsubsamp, jint height, jint pixelsize, jbyteArray dst, jint jpegsubsamp,
jint jpegqual, jint flags) jint jpegqual, jint flags)
@@ -112,7 +111,7 @@ JNIEXPORT jlong JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress
bailout: bailout:
if(dstbuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstbuf, 0); if(dstbuf) (*env)->ReleasePrimitiveArrayCritical(env, dst, dstbuf, 0);
if(srcbuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcbuf, 0); if(srcbuf) (*env)->ReleasePrimitiveArrayCritical(env, src, srcbuf, 0);
return size; return (jint)size;
} }
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy
@@ -123,6 +122,7 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy
gethandle(); gethandle();
if(tjDestroy(handle)==-1) _throw(tjGetErrorStr()); if(tjDestroy(handle)==-1) _throw(tjGetErrorStr());
(*env)->SetLongField(env, obj, _fid, 0);
bailout: bailout:
return; return;
@@ -169,15 +169,12 @@ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_getScaledH
return output_height; return output_height;
} }
JNIEXPORT jobject JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressHeader JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressHeader
(JNIEnv *env, jobject obj, jbyteArray src, jlong size) (JNIEnv *env, jobject obj, jbyteArray src, jint size)
{ {
jclass jhicls=NULL;
jfieldID fid;
tjhandle handle=0; tjhandle handle=0;
unsigned char *srcbuf=NULL; unsigned char *srcbuf=NULL;
int width=0, height=0, jpegsubsamp=-1; int width=0, height=0, jpegsubsamp=-1;
jobject jhiobj=NULL;
gethandle(); gethandle();
@@ -191,22 +188,19 @@ JNIEXPORT jobject JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompr
} }
(*env)->ReleasePrimitiveArrayCritical(env, src, srcbuf, 0); srcbuf=NULL; (*env)->ReleasePrimitiveArrayCritical(env, src, srcbuf, 0); srcbuf=NULL;
bailif0(jhicls=(*env)->FindClass(env, "org/libjpegturbo/turbojpeg/TJHeaderInfo")); bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegSubsamp", "I"));
bailif0(jhiobj=(*env)->AllocObject(env, jhicls)); (*env)->SetIntField(env, obj, _fid, jpegsubsamp);
bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegWidth", "I"));
bailif0(fid=(*env)->GetFieldID(env, jhicls, "subsamp", "I")); (*env)->SetIntField(env, obj, _fid, width);
(*env)->SetIntField(env, jhiobj, fid, jpegsubsamp); bailif0(_fid=(*env)->GetFieldID(env, _cls, "jpegHeight", "I"));
bailif0(fid=(*env)->GetFieldID(env, jhicls, "width", "I")); (*env)->SetIntField(env, obj, _fid, height);
(*env)->SetIntField(env, jhiobj, fid, width);
bailif0(fid=(*env)->GetFieldID(env, jhicls, "height", "I"));
(*env)->SetIntField(env, jhiobj, fid, height);
bailout: bailout:
return jhiobj; return;
} }
JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress
(JNIEnv *env, jobject obj, jbyteArray src, jlong size, jbyteArray dst, (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 pixelsize, jint flags)
{ {
tjhandle handle=0; tjhandle handle=0;