From: DRC Date: Fri, 25 Feb 2011 06:11:03 +0000 (+0000) Subject: Implement YUV encode/decode methods at the Java level; Remove some of the arguments... X-Git-Tag: 1.1.90~205 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4f1580cc0e7c33385e88bca7fe08602b87d29aeb;p=libjpeg-turbo Implement YUV encode/decode methods at the Java level; Remove some of the arguments from the Java API and replace with get/set methods; General API cleanup; Fix BufferedImage grayscale tests in TJUnitTest git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@451 632fc199-4ca6-4c93-a231-07263d6284db --- diff --git a/java/TJExample.java b/java/TJExample.java index 238bc2f..fc4cb6b 100644 --- a/java/TJExample.java +++ b/java/TJExample.java @@ -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]); diff --git a/java/TJUnitTest.java b/java/TJUnitTest.java index 227729a..b9b792c 100644 --- a/java/TJUnitTest.java +++ b/java/TJUnitTest.java @@ -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> 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>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> 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>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> 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) diff --git a/java/org/libjpegturbo/turbojpeg/TJ.java b/java/org/libjpegturbo/turbojpeg/TJ.java index 9951fa2..332426a 100644 --- a/java/org/libjpegturbo/turbojpeg/TJ.java +++ b/java/org/libjpegturbo/turbojpeg/TJ.java @@ -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; diff --git a/java/org/libjpegturbo/turbojpeg/TJCompressor.java b/java/org/libjpegturbo/turbojpeg/TJCompressor.java index 0fcffac..d0c1910 100644 --- a/java/org/libjpegturbo/turbojpeg/TJCompressor.java +++ b/java/org/libjpegturbo/turbojpeg/TJCompressor.java @@ -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; }; diff --git a/java/org/libjpegturbo/turbojpeg/TJDecompressor.java b/java/org/libjpegturbo/turbojpeg/TJDecompressor.java index 9cd2fe6..fdc1e4e 100644 --- a/java/org/libjpegturbo/turbojpeg/TJDecompressor.java +++ b/java/org/libjpegturbo/turbojpeg/TJDecompressor.java @@ -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, diff --git a/java/org_libjpegturbo_turbojpeg_TJ.h b/java/org_libjpegturbo_turbojpeg_TJ.h index a1fe82d..b2be5d8 100644 --- a/java/org_libjpegturbo_turbojpeg_TJ.h +++ b/java/org_libjpegturbo_turbojpeg_TJ.h @@ -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 diff --git a/java/org_libjpegturbo_turbojpeg_TJCompressor.h b/java/org_libjpegturbo_turbojpeg_TJCompressor.h index e7129af..59f81e3 100644 --- a/java/org_libjpegturbo_turbojpeg_TJCompressor.h +++ b/java/org_libjpegturbo_turbojpeg_TJCompressor.h @@ -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 } diff --git a/java/org_libjpegturbo_turbojpeg_TJDecompressor.h b/java/org_libjpegturbo_turbojpeg_TJDecompressor.h index 8f65388..6951906 100644 --- a/java/org_libjpegturbo_turbojpeg_TJDecompressor.h +++ b/java/org_libjpegturbo_turbojpeg_TJDecompressor.h @@ -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 diff --git a/turbojpeg-jni.c b/turbojpeg-jni.c index b9bd429..6e04a5c 100644 --- a/turbojpeg-jni.c +++ b/turbojpeg-jni.c @@ -32,6 +32,12 @@ #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 diff --git a/turbojpeg-mapfile.jni b/turbojpeg-mapfile.jni index eead41b..f5277a5 100755 --- a/turbojpeg-mapfile.jni +++ b/turbojpeg-mapfile.jni @@ -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;