TJCompressor.java revision fac3bea8dae8664110951427434d94bcd139d17b
1c5a419970eb91c85844002901210484b29e25fb1DRC/* 2fac3bea8dae8664110951427434d94bcd139d17bDRC * Copyright (C)2011-2012 D. R. Commander. All Rights Reserved. 3c5a419970eb91c85844002901210484b29e25fb1DRC * 4c5a419970eb91c85844002901210484b29e25fb1DRC * Redistribution and use in source and binary forms, with or without 5c5a419970eb91c85844002901210484b29e25fb1DRC * modification, are permitted provided that the following conditions are met: 6c5a419970eb91c85844002901210484b29e25fb1DRC * 7c5a419970eb91c85844002901210484b29e25fb1DRC * - Redistributions of source code must retain the above copyright notice, 8c5a419970eb91c85844002901210484b29e25fb1DRC * this list of conditions and the following disclaimer. 9c5a419970eb91c85844002901210484b29e25fb1DRC * - Redistributions in binary form must reproduce the above copyright notice, 10c5a419970eb91c85844002901210484b29e25fb1DRC * this list of conditions and the following disclaimer in the documentation 11c5a419970eb91c85844002901210484b29e25fb1DRC * and/or other materials provided with the distribution. 12c5a419970eb91c85844002901210484b29e25fb1DRC * - Neither the name of the libjpeg-turbo Project nor the names of its 13c5a419970eb91c85844002901210484b29e25fb1DRC * contributors may be used to endorse or promote products derived from this 14c5a419970eb91c85844002901210484b29e25fb1DRC * software without specific prior written permission. 15c5a419970eb91c85844002901210484b29e25fb1DRC * 16c5a419970eb91c85844002901210484b29e25fb1DRC * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", 17c5a419970eb91c85844002901210484b29e25fb1DRC * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18c5a419970eb91c85844002901210484b29e25fb1DRC * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19c5a419970eb91c85844002901210484b29e25fb1DRC * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE 20c5a419970eb91c85844002901210484b29e25fb1DRC * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21c5a419970eb91c85844002901210484b29e25fb1DRC * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22c5a419970eb91c85844002901210484b29e25fb1DRC * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23c5a419970eb91c85844002901210484b29e25fb1DRC * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24c5a419970eb91c85844002901210484b29e25fb1DRC * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25c5a419970eb91c85844002901210484b29e25fb1DRC * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26c5a419970eb91c85844002901210484b29e25fb1DRC * POSSIBILITY OF SUCH DAMAGE. 27c5a419970eb91c85844002901210484b29e25fb1DRC */ 28c5a419970eb91c85844002901210484b29e25fb1DRC 29c5a419970eb91c85844002901210484b29e25fb1DRCpackage org.libjpegturbo.turbojpeg; 30c5a419970eb91c85844002901210484b29e25fb1DRC 3184a1bcca6fd0f21091a84f04b820b29012c60857DRCimport java.awt.image.*; 321f014c32e66e00f4e6934f31beefae57ab51a477DRCimport java.nio.*; 3384a1bcca6fd0f21091a84f04b820b29012c60857DRC 3492549de2c2b139070294aec12ec39b7c86a56b52DRC/** 3592549de2c2b139070294aec12ec39b7c86a56b52DRC * TurboJPEG compressor 3692549de2c2b139070294aec12ec39b7c86a56b52DRC */ 37c5a419970eb91c85844002901210484b29e25fb1DRCpublic class TJCompressor { 38c5a419970eb91c85844002901210484b29e25fb1DRC 392c74e5124d25112809bdc26cbc36aa764e8870c3DRC private final static String NO_ASSOC_ERROR = 402c74e5124d25112809bdc26cbc36aa764e8870c3DRC "No source image is associated with this instance"; 412c74e5124d25112809bdc26cbc36aa764e8870c3DRC 4292549de2c2b139070294aec12ec39b7c86a56b52DRC /** 4392549de2c2b139070294aec12ec39b7c86a56b52DRC * Create a TurboJPEG compressor instance. 4492549de2c2b139070294aec12ec39b7c86a56b52DRC */ 45c5a419970eb91c85844002901210484b29e25fb1DRC public TJCompressor() throws Exception { 46c5a419970eb91c85844002901210484b29e25fb1DRC init(); 47c5a419970eb91c85844002901210484b29e25fb1DRC } 48c5a419970eb91c85844002901210484b29e25fb1DRC 4992549de2c2b139070294aec12ec39b7c86a56b52DRC /** 5092549de2c2b139070294aec12ec39b7c86a56b52DRC * Create a TurboJPEG compressor instance and associate the uncompressed 512c74e5124d25112809bdc26cbc36aa764e8870c3DRC * source image stored in <code>srcImage</code> with the newly-created 522c74e5124d25112809bdc26cbc36aa764e8870c3DRC * instance. 5392549de2c2b139070294aec12ec39b7c86a56b52DRC * 542c74e5124d25112809bdc26cbc36aa764e8870c3DRC * @param srcImage see {@link #setSourceImage} for description 5592549de2c2b139070294aec12ec39b7c86a56b52DRC * 562c74e5124d25112809bdc26cbc36aa764e8870c3DRC * @param width see {@link #setSourceImage} for description 5792549de2c2b139070294aec12ec39b7c86a56b52DRC * 582c74e5124d25112809bdc26cbc36aa764e8870c3DRC * @param pitch see {@link #setSourceImage} for description 5992549de2c2b139070294aec12ec39b7c86a56b52DRC * 602c74e5124d25112809bdc26cbc36aa764e8870c3DRC * @param height see {@link #setSourceImage} for description 6192549de2c2b139070294aec12ec39b7c86a56b52DRC * 622c74e5124d25112809bdc26cbc36aa764e8870c3DRC * @param pixelFormat see {@link #setSourceImage} for description 6392549de2c2b139070294aec12ec39b7c86a56b52DRC */ 642c74e5124d25112809bdc26cbc36aa764e8870c3DRC public TJCompressor(byte[] srcImage, int width, int pitch, int height, 6536336fcddc4cc9f74988e3f03c4683c88c8fce45DRC int pixelFormat) throws Exception { 662c74e5124d25112809bdc26cbc36aa764e8870c3DRC setSourceImage(srcImage, width, pitch, height, pixelFormat); 6736336fcddc4cc9f74988e3f03c4683c88c8fce45DRC } 6836336fcddc4cc9f74988e3f03c4683c88c8fce45DRC 6992549de2c2b139070294aec12ec39b7c86a56b52DRC /** 70fac3bea8dae8664110951427434d94bcd139d17bDRC * Create a TurboJPEG compressor instance and associate the uncompressed 71fac3bea8dae8664110951427434d94bcd139d17bDRC * source image stored in <code>srcImage</code> with the newly-created 72fac3bea8dae8664110951427434d94bcd139d17bDRC * instance. 73fac3bea8dae8664110951427434d94bcd139d17bDRC * 74fac3bea8dae8664110951427434d94bcd139d17bDRC * @param srcImage see {@link #setSourceImage} for description 75fac3bea8dae8664110951427434d94bcd139d17bDRC * 76fac3bea8dae8664110951427434d94bcd139d17bDRC * @param x see {@link #setSourceImage} for description 77fac3bea8dae8664110951427434d94bcd139d17bDRC * 78fac3bea8dae8664110951427434d94bcd139d17bDRC * @param y see {@link #setSourceImage} for description 79fac3bea8dae8664110951427434d94bcd139d17bDRC * 80fac3bea8dae8664110951427434d94bcd139d17bDRC * @param width see {@link #setSourceImage} for description 81fac3bea8dae8664110951427434d94bcd139d17bDRC * 82fac3bea8dae8664110951427434d94bcd139d17bDRC * @param pitch see {@link #setSourceImage} for description 83fac3bea8dae8664110951427434d94bcd139d17bDRC * 84fac3bea8dae8664110951427434d94bcd139d17bDRC * @param height see {@link #setSourceImage} for description 85fac3bea8dae8664110951427434d94bcd139d17bDRC * 86fac3bea8dae8664110951427434d94bcd139d17bDRC * @param pixelFormat see {@link #setSourceImage} for description 87fac3bea8dae8664110951427434d94bcd139d17bDRC */ 88fac3bea8dae8664110951427434d94bcd139d17bDRC public TJCompressor(byte[] srcImage, int x, int y, int width, int pitch, 89fac3bea8dae8664110951427434d94bcd139d17bDRC int height, int pixelFormat) throws Exception { 90fac3bea8dae8664110951427434d94bcd139d17bDRC setSourceImage(srcImage, x, y, width, pitch, height, pixelFormat); 91fac3bea8dae8664110951427434d94bcd139d17bDRC } 92fac3bea8dae8664110951427434d94bcd139d17bDRC 93fac3bea8dae8664110951427434d94bcd139d17bDRC /** 9492549de2c2b139070294aec12ec39b7c86a56b52DRC * Associate an uncompressed source image with this compressor instance. 9592549de2c2b139070294aec12ec39b7c86a56b52DRC * 962c74e5124d25112809bdc26cbc36aa764e8870c3DRC * @param srcImage image buffer containing RGB or grayscale pixels to be 9792549de2c2b139070294aec12ec39b7c86a56b52DRC * compressed 9892549de2c2b139070294aec12ec39b7c86a56b52DRC * 99fac3bea8dae8664110951427434d94bcd139d17bDRC * @param x x offset (in pixels) of the region from which the JPEG image 100fac3bea8dae8664110951427434d94bcd139d17bDRC * should be compressed, relative to the start of <code>srcImage</code>. 101fac3bea8dae8664110951427434d94bcd139d17bDRC * 102fac3bea8dae8664110951427434d94bcd139d17bDRC * @param y y offset (in pixels) of the region from which the JPEG image 103fac3bea8dae8664110951427434d94bcd139d17bDRC * should be compressed, relative to the start of <code>srcImage</code>. 104fac3bea8dae8664110951427434d94bcd139d17bDRC * 105fac3bea8dae8664110951427434d94bcd139d17bDRC * @param width width (in pixels) of the region in the source image from 106fac3bea8dae8664110951427434d94bcd139d17bDRC * which the JPEG image should be compressed. 10792549de2c2b139070294aec12ec39b7c86a56b52DRC * 10892549de2c2b139070294aec12ec39b7c86a56b52DRC * @param pitch bytes per line of the source image. Normally, this should be 10992549de2c2b139070294aec12ec39b7c86a56b52DRC * <code>width * TJ.pixelSize(pixelFormat)</code> if the source image is 11092549de2c2b139070294aec12ec39b7c86a56b52DRC * unpadded, but you can use this parameter to, for instance, specify that 111fac3bea8dae8664110951427434d94bcd139d17bDRC * the scanlines in the source image are padded to a 4-byte boundary or to 112fac3bea8dae8664110951427434d94bcd139d17bDRC * compress a JPEG image from a region of a larger source image. You can 113fac3bea8dae8664110951427434d94bcd139d17bDRC * also be clever and use this parameter to skip lines, etc. Setting this 114fac3bea8dae8664110951427434d94bcd139d17bDRC * parameter to 0 is the equivalent of setting it to <code>width * 11592549de2c2b139070294aec12ec39b7c86a56b52DRC * TJ.pixelSize(pixelFormat)</code>. 11692549de2c2b139070294aec12ec39b7c86a56b52DRC * 117fac3bea8dae8664110951427434d94bcd139d17bDRC * @param height height (in pixels) of the region in the source image from 118fac3bea8dae8664110951427434d94bcd139d17bDRC * which the JPEG image should be compressed. 11992549de2c2b139070294aec12ec39b7c86a56b52DRC * 1202c74e5124d25112809bdc26cbc36aa764e8870c3DRC * @param pixelFormat pixel format of the source image (one of 1212c74e5124d25112809bdc26cbc36aa764e8870c3DRC * {@link TJ TJ.PF_*}) 12292549de2c2b139070294aec12ec39b7c86a56b52DRC */ 123fac3bea8dae8664110951427434d94bcd139d17bDRC public void setSourceImage(byte[] srcImage, int x, int y, int width, 124fac3bea8dae8664110951427434d94bcd139d17bDRC int pitch, int height, int pixelFormat) throws Exception { 12536336fcddc4cc9f74988e3f03c4683c88c8fce45DRC if(handle == 0) init(); 126fac3bea8dae8664110951427434d94bcd139d17bDRC if(srcImage == null || x < 0 || y < 0 || width < 1 || height < 1 127fac3bea8dae8664110951427434d94bcd139d17bDRC || pitch < 0 || pixelFormat < 0 || pixelFormat >= TJ.NUMPF) 1282c74e5124d25112809bdc26cbc36aa764e8870c3DRC throw new Exception("Invalid argument in setSourceImage()"); 1292c74e5124d25112809bdc26cbc36aa764e8870c3DRC srcBuf = srcImage; 1302c74e5124d25112809bdc26cbc36aa764e8870c3DRC srcWidth = width; 1312c74e5124d25112809bdc26cbc36aa764e8870c3DRC if(pitch == 0) srcPitch = width * TJ.getPixelSize(pixelFormat); 1322c74e5124d25112809bdc26cbc36aa764e8870c3DRC else srcPitch = pitch; 1332c74e5124d25112809bdc26cbc36aa764e8870c3DRC srcHeight = height; 1342c74e5124d25112809bdc26cbc36aa764e8870c3DRC srcPixelFormat = pixelFormat; 135fac3bea8dae8664110951427434d94bcd139d17bDRC srcX = x; 136fac3bea8dae8664110951427434d94bcd139d17bDRC srcY = y; 13736336fcddc4cc9f74988e3f03c4683c88c8fce45DRC } 13836336fcddc4cc9f74988e3f03c4683c88c8fce45DRC 13992549de2c2b139070294aec12ec39b7c86a56b52DRC /** 140fac3bea8dae8664110951427434d94bcd139d17bDRC * Associate an uncompressed source image with this compressor instance. 141fac3bea8dae8664110951427434d94bcd139d17bDRC * 142fac3bea8dae8664110951427434d94bcd139d17bDRC * @param srcImage see 143fac3bea8dae8664110951427434d94bcd139d17bDRC * {@link #setSourceImage(byte[], int, int, int, int, int, int)} for 144fac3bea8dae8664110951427434d94bcd139d17bDRC * description 145fac3bea8dae8664110951427434d94bcd139d17bDRC * 146fac3bea8dae8664110951427434d94bcd139d17bDRC * @param width see 147fac3bea8dae8664110951427434d94bcd139d17bDRC * {@link #setSourceImage(byte[], int, int, int, int, int, int)} for 148fac3bea8dae8664110951427434d94bcd139d17bDRC * description 149fac3bea8dae8664110951427434d94bcd139d17bDRC * 150fac3bea8dae8664110951427434d94bcd139d17bDRC * @param pitch see 151fac3bea8dae8664110951427434d94bcd139d17bDRC * {@link #setSourceImage(byte[], int, int, int, int, int, int)} for 152fac3bea8dae8664110951427434d94bcd139d17bDRC * description 153fac3bea8dae8664110951427434d94bcd139d17bDRC * 154fac3bea8dae8664110951427434d94bcd139d17bDRC * @param height see 155fac3bea8dae8664110951427434d94bcd139d17bDRC * {@link #setSourceImage(byte[], int, int, int, int, int, int)} for 156fac3bea8dae8664110951427434d94bcd139d17bDRC * description 157fac3bea8dae8664110951427434d94bcd139d17bDRC * 158fac3bea8dae8664110951427434d94bcd139d17bDRC * @param pixelFormat pixel format of the source image (one of 159fac3bea8dae8664110951427434d94bcd139d17bDRC * {@link TJ TJ.PF_*}) 160fac3bea8dae8664110951427434d94bcd139d17bDRC */ 161fac3bea8dae8664110951427434d94bcd139d17bDRC 162fac3bea8dae8664110951427434d94bcd139d17bDRC public void setSourceImage(byte[] srcImage, int width, int pitch, 163fac3bea8dae8664110951427434d94bcd139d17bDRC int height, int pixelFormat) throws Exception { 164fac3bea8dae8664110951427434d94bcd139d17bDRC setSourceImage(srcImage, 0, 0, width, pitch, height, pixelFormat); 165fac3bea8dae8664110951427434d94bcd139d17bDRC srcX = srcY = -1; 166fac3bea8dae8664110951427434d94bcd139d17bDRC } 167fac3bea8dae8664110951427434d94bcd139d17bDRC 168fac3bea8dae8664110951427434d94bcd139d17bDRC 169fac3bea8dae8664110951427434d94bcd139d17bDRC /** 17092549de2c2b139070294aec12ec39b7c86a56b52DRC * Set the level of chrominance subsampling for subsequent compress/encode 17192549de2c2b139070294aec12ec39b7c86a56b52DRC * operations. 17292549de2c2b139070294aec12ec39b7c86a56b52DRC * 1732c74e5124d25112809bdc26cbc36aa764e8870c3DRC * @param newSubsamp the new level of chrominance subsampling (one of 1742c74e5124d25112809bdc26cbc36aa764e8870c3DRC * {@link TJ TJ.SAMP_*}) 17592549de2c2b139070294aec12ec39b7c86a56b52DRC */ 1764f1580cc0e7c33385e88bca7fe08602b87d29aebDRC public void setSubsamp(int newSubsamp) throws Exception { 1772c74e5124d25112809bdc26cbc36aa764e8870c3DRC if(newSubsamp < 0 || newSubsamp >= TJ.NUMSAMP) 178f7f3ea404cc8618305efc059c34d881566206ed9DRC throw new Exception("Invalid argument in setSubsamp()"); 1794f1580cc0e7c33385e88bca7fe08602b87d29aebDRC subsamp = newSubsamp; 1804f1580cc0e7c33385e88bca7fe08602b87d29aebDRC } 1814f1580cc0e7c33385e88bca7fe08602b87d29aebDRC 18292549de2c2b139070294aec12ec39b7c86a56b52DRC /** 18392549de2c2b139070294aec12ec39b7c86a56b52DRC * Set the JPEG image quality level for subsequent compress operations. 18492549de2c2b139070294aec12ec39b7c86a56b52DRC * 18592549de2c2b139070294aec12ec39b7c86a56b52DRC * @param quality the new JPEG image quality level (1 to 100, 1 = worst, 18692549de2c2b139070294aec12ec39b7c86a56b52DRC * 100 = best) 18792549de2c2b139070294aec12ec39b7c86a56b52DRC */ 1884f1580cc0e7c33385e88bca7fe08602b87d29aebDRC public void setJPEGQuality(int quality) throws Exception { 1894f1580cc0e7c33385e88bca7fe08602b87d29aebDRC if(quality < 1 || quality > 100) 190f7f3ea404cc8618305efc059c34d881566206ed9DRC throw new Exception("Invalid argument in setJPEGQuality()"); 1914f1580cc0e7c33385e88bca7fe08602b87d29aebDRC jpegQuality = quality; 1924f1580cc0e7c33385e88bca7fe08602b87d29aebDRC } 1934f1580cc0e7c33385e88bca7fe08602b87d29aebDRC 19492549de2c2b139070294aec12ec39b7c86a56b52DRC /** 19592549de2c2b139070294aec12ec39b7c86a56b52DRC * Compress the uncompressed source image associated with this compressor 19692549de2c2b139070294aec12ec39b7c86a56b52DRC * instance and output a JPEG image to the given destination buffer. 19792549de2c2b139070294aec12ec39b7c86a56b52DRC * 19880803ae5fe6ca228d0783b1921e7e800c9a28964DRC * @param dstBuf buffer that will receive the JPEG image. Use 19992549de2c2b139070294aec12ec39b7c86a56b52DRC * {@link TJ#bufSize} to determine the maximum size for this buffer based on 20092549de2c2b139070294aec12ec39b7c86a56b52DRC * the image width and height. 20192549de2c2b139070294aec12ec39b7c86a56b52DRC * 2022c74e5124d25112809bdc26cbc36aa764e8870c3DRC * @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*} 20392549de2c2b139070294aec12ec39b7c86a56b52DRC */ 204f7f3ea404cc8618305efc059c34d881566206ed9DRC public void compress(byte[] dstBuf, int flags) throws Exception { 2054f1580cc0e7c33385e88bca7fe08602b87d29aebDRC if(dstBuf == null || flags < 0) 2064f1580cc0e7c33385e88bca7fe08602b87d29aebDRC throw new Exception("Invalid argument in compress()"); 2072c74e5124d25112809bdc26cbc36aa764e8870c3DRC if(srcBuf == null) throw new Exception(NO_ASSOC_ERROR); 2084f1580cc0e7c33385e88bca7fe08602b87d29aebDRC if(jpegQuality < 0) throw new Exception("JPEG Quality not set"); 2094f1580cc0e7c33385e88bca7fe08602b87d29aebDRC if(subsamp < 0) throw new Exception("Subsampling level not set"); 210fac3bea8dae8664110951427434d94bcd139d17bDRC if (srcX >= 0 && srcY >= 0) 211fac3bea8dae8664110951427434d94bcd139d17bDRC compressedSize = compress(srcBuf, srcX, srcY, srcWidth, srcPitch, 212fac3bea8dae8664110951427434d94bcd139d17bDRC srcHeight, srcPixelFormat, dstBuf, subsamp, jpegQuality, flags); 213fac3bea8dae8664110951427434d94bcd139d17bDRC else 214fac3bea8dae8664110951427434d94bcd139d17bDRC compressedSize = compress(srcBuf, srcWidth, srcPitch, 215fac3bea8dae8664110951427434d94bcd139d17bDRC srcHeight, srcPixelFormat, dstBuf, subsamp, jpegQuality, flags); 2164f1580cc0e7c33385e88bca7fe08602b87d29aebDRC } 2174f1580cc0e7c33385e88bca7fe08602b87d29aebDRC 21892549de2c2b139070294aec12ec39b7c86a56b52DRC /** 21992549de2c2b139070294aec12ec39b7c86a56b52DRC * Compress the uncompressed source image associated with this compressor 22092549de2c2b139070294aec12ec39b7c86a56b52DRC * instance and return a buffer containing a JPEG image. 22192549de2c2b139070294aec12ec39b7c86a56b52DRC * 2222c74e5124d25112809bdc26cbc36aa764e8870c3DRC * @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*} 22392549de2c2b139070294aec12ec39b7c86a56b52DRC * 22492549de2c2b139070294aec12ec39b7c86a56b52DRC * @return a buffer containing a JPEG image. The length of this buffer will 22592549de2c2b139070294aec12ec39b7c86a56b52DRC * not be equal to the size of the JPEG image. Use {@link 22692549de2c2b139070294aec12ec39b7c86a56b52DRC * #getCompressedSize} to obtain the size of the JPEG image. 22792549de2c2b139070294aec12ec39b7c86a56b52DRC */ 228f7f3ea404cc8618305efc059c34d881566206ed9DRC public byte[] compress(int flags) throws Exception { 2292c74e5124d25112809bdc26cbc36aa764e8870c3DRC if(srcWidth < 1 || srcHeight < 1) 2302c74e5124d25112809bdc26cbc36aa764e8870c3DRC throw new Exception(NO_ASSOC_ERROR); 2319b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC byte[] buf = new byte[TJ.bufSize(srcWidth, srcHeight, subsamp)]; 2324f1580cc0e7c33385e88bca7fe08602b87d29aebDRC compress(buf, flags); 2334f1580cc0e7c33385e88bca7fe08602b87d29aebDRC return buf; 2344f1580cc0e7c33385e88bca7fe08602b87d29aebDRC } 2354f1580cc0e7c33385e88bca7fe08602b87d29aebDRC 23692549de2c2b139070294aec12ec39b7c86a56b52DRC /** 23792549de2c2b139070294aec12ec39b7c86a56b52DRC * Compress the uncompressed source image stored in <code>srcImage</code> 23892549de2c2b139070294aec12ec39b7c86a56b52DRC * and output a JPEG image to the given destination buffer. 23992549de2c2b139070294aec12ec39b7c86a56b52DRC * 24092549de2c2b139070294aec12ec39b7c86a56b52DRC * @param srcImage a <code>BufferedImage</code> instance containing RGB or 24192549de2c2b139070294aec12ec39b7c86a56b52DRC * grayscale pixels to be compressed 24292549de2c2b139070294aec12ec39b7c86a56b52DRC * 24380803ae5fe6ca228d0783b1921e7e800c9a28964DRC * @param dstBuf buffer that will receive the JPEG image. Use 24492549de2c2b139070294aec12ec39b7c86a56b52DRC * {@link TJ#bufSize} to determine the maximum size for this buffer based on 24592549de2c2b139070294aec12ec39b7c86a56b52DRC * the image width and height. 24692549de2c2b139070294aec12ec39b7c86a56b52DRC * 2472c74e5124d25112809bdc26cbc36aa764e8870c3DRC * @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*} 24892549de2c2b139070294aec12ec39b7c86a56b52DRC */ 249f7f3ea404cc8618305efc059c34d881566206ed9DRC public void compress(BufferedImage srcImage, byte[] dstBuf, int flags) 2504f1580cc0e7c33385e88bca7fe08602b87d29aebDRC throws Exception { 2514f1580cc0e7c33385e88bca7fe08602b87d29aebDRC if(srcImage == null || dstBuf == null || flags < 0) 2524f1580cc0e7c33385e88bca7fe08602b87d29aebDRC throw new Exception("Invalid argument in compress()"); 2534f1580cc0e7c33385e88bca7fe08602b87d29aebDRC int width = srcImage.getWidth(); 2544f1580cc0e7c33385e88bca7fe08602b87d29aebDRC int height = srcImage.getHeight(); 255f7f3ea404cc8618305efc059c34d881566206ed9DRC int pixelFormat; boolean intPixels = false; 2561f014c32e66e00f4e6934f31beefae57ab51a477DRC if(byteOrder == null) 2571f014c32e66e00f4e6934f31beefae57ab51a477DRC byteOrder = ByteOrder.nativeOrder(); 2584f1580cc0e7c33385e88bca7fe08602b87d29aebDRC switch(srcImage.getType()) { 2594f1580cc0e7c33385e88bca7fe08602b87d29aebDRC case BufferedImage.TYPE_3BYTE_BGR: 260f7f3ea404cc8618305efc059c34d881566206ed9DRC pixelFormat = TJ.PF_BGR; break; 261c08e8c15bc73e7931ac5b87b992b17bbbda7f332DRC case BufferedImage.TYPE_4BYTE_ABGR: 262c08e8c15bc73e7931ac5b87b992b17bbbda7f332DRC case BufferedImage.TYPE_4BYTE_ABGR_PRE: 263c08e8c15bc73e7931ac5b87b992b17bbbda7f332DRC pixelFormat = TJ.PF_XBGR; break; 2644f1580cc0e7c33385e88bca7fe08602b87d29aebDRC case BufferedImage.TYPE_BYTE_GRAY: 265f7f3ea404cc8618305efc059c34d881566206ed9DRC pixelFormat = TJ.PF_GRAY; break; 2664f1580cc0e7c33385e88bca7fe08602b87d29aebDRC case BufferedImage.TYPE_INT_BGR: 2671f014c32e66e00f4e6934f31beefae57ab51a477DRC if(byteOrder == ByteOrder.BIG_ENDIAN) 2681f014c32e66e00f4e6934f31beefae57ab51a477DRC pixelFormat = TJ.PF_XBGR; 2691f014c32e66e00f4e6934f31beefae57ab51a477DRC else 2701f014c32e66e00f4e6934f31beefae57ab51a477DRC pixelFormat = TJ.PF_RGBX; 2711f014c32e66e00f4e6934f31beefae57ab51a477DRC intPixels = true; break; 2724f1580cc0e7c33385e88bca7fe08602b87d29aebDRC case BufferedImage.TYPE_INT_RGB: 273c08e8c15bc73e7931ac5b87b992b17bbbda7f332DRC case BufferedImage.TYPE_INT_ARGB: 274c08e8c15bc73e7931ac5b87b992b17bbbda7f332DRC case BufferedImage.TYPE_INT_ARGB_PRE: 2751f014c32e66e00f4e6934f31beefae57ab51a477DRC if(byteOrder == ByteOrder.BIG_ENDIAN) 2761f014c32e66e00f4e6934f31beefae57ab51a477DRC pixelFormat = TJ.PF_XRGB; 2771f014c32e66e00f4e6934f31beefae57ab51a477DRC else 2781f014c32e66e00f4e6934f31beefae57ab51a477DRC pixelFormat = TJ.PF_BGRX; 2791f014c32e66e00f4e6934f31beefae57ab51a477DRC intPixels = true; break; 2804f1580cc0e7c33385e88bca7fe08602b87d29aebDRC default: 2814f1580cc0e7c33385e88bca7fe08602b87d29aebDRC throw new Exception("Unsupported BufferedImage format"); 2824f1580cc0e7c33385e88bca7fe08602b87d29aebDRC } 2834f1580cc0e7c33385e88bca7fe08602b87d29aebDRC WritableRaster wr = srcImage.getRaster(); 2844f1580cc0e7c33385e88bca7fe08602b87d29aebDRC if(jpegQuality < 0) throw new Exception("JPEG Quality not set"); 2854f1580cc0e7c33385e88bca7fe08602b87d29aebDRC if(subsamp < 0) throw new Exception("Subsampling level not set"); 2864f1580cc0e7c33385e88bca7fe08602b87d29aebDRC if(intPixels) { 2874f1580cc0e7c33385e88bca7fe08602b87d29aebDRC SinglePixelPackedSampleModel sm = 2884f1580cc0e7c33385e88bca7fe08602b87d29aebDRC (SinglePixelPackedSampleModel)srcImage.getSampleModel(); 2894f1580cc0e7c33385e88bca7fe08602b87d29aebDRC int pitch = sm.getScanlineStride(); 2904f1580cc0e7c33385e88bca7fe08602b87d29aebDRC DataBufferInt db = (DataBufferInt)wr.getDataBuffer(); 291f7f3ea404cc8618305efc059c34d881566206ed9DRC int[] buf = db.getData(); 292fac3bea8dae8664110951427434d94bcd139d17bDRC if (srcX >= 0 && srcY >= 0) 293fac3bea8dae8664110951427434d94bcd139d17bDRC compressedSize = compress(buf, srcX, srcY, width, pitch, height, 294fac3bea8dae8664110951427434d94bcd139d17bDRC pixelFormat, dstBuf, subsamp, jpegQuality, flags); 295fac3bea8dae8664110951427434d94bcd139d17bDRC else 296fac3bea8dae8664110951427434d94bcd139d17bDRC compressedSize = compress(buf, width, pitch, height, pixelFormat, 297fac3bea8dae8664110951427434d94bcd139d17bDRC dstBuf, subsamp, jpegQuality, flags); 2984f1580cc0e7c33385e88bca7fe08602b87d29aebDRC } 2994f1580cc0e7c33385e88bca7fe08602b87d29aebDRC else { 3004f1580cc0e7c33385e88bca7fe08602b87d29aebDRC ComponentSampleModel sm = 3014f1580cc0e7c33385e88bca7fe08602b87d29aebDRC (ComponentSampleModel)srcImage.getSampleModel(); 3024f1580cc0e7c33385e88bca7fe08602b87d29aebDRC int pixelSize = sm.getPixelStride(); 3034f1580cc0e7c33385e88bca7fe08602b87d29aebDRC if(pixelSize != TJ.getPixelSize(pixelFormat)) 3044f1580cc0e7c33385e88bca7fe08602b87d29aebDRC throw new Exception("Inconsistency between pixel format and pixel size in BufferedImage"); 3054f1580cc0e7c33385e88bca7fe08602b87d29aebDRC int pitch = sm.getScanlineStride(); 3064f1580cc0e7c33385e88bca7fe08602b87d29aebDRC DataBufferByte db = (DataBufferByte)wr.getDataBuffer(); 307f7f3ea404cc8618305efc059c34d881566206ed9DRC byte[] buf = db.getData(); 308fac3bea8dae8664110951427434d94bcd139d17bDRC if (srcX >= 0 && srcY >= 0) 309fac3bea8dae8664110951427434d94bcd139d17bDRC compressedSize = compress(buf, srcX, srcY, width, pitch, height, 310fac3bea8dae8664110951427434d94bcd139d17bDRC pixelFormat, dstBuf, subsamp, jpegQuality, flags); 311fac3bea8dae8664110951427434d94bcd139d17bDRC else 312fac3bea8dae8664110951427434d94bcd139d17bDRC compressedSize = compress(buf, width, pitch, height, pixelFormat, 313fac3bea8dae8664110951427434d94bcd139d17bDRC dstBuf, subsamp, jpegQuality, flags); 3144f1580cc0e7c33385e88bca7fe08602b87d29aebDRC } 3154f1580cc0e7c33385e88bca7fe08602b87d29aebDRC } 3164f1580cc0e7c33385e88bca7fe08602b87d29aebDRC 31792549de2c2b139070294aec12ec39b7c86a56b52DRC /** 31892549de2c2b139070294aec12ec39b7c86a56b52DRC * Compress the uncompressed source image stored in <code>srcImage</code> 31992549de2c2b139070294aec12ec39b7c86a56b52DRC * and return a buffer containing a JPEG image. 32092549de2c2b139070294aec12ec39b7c86a56b52DRC * 32192549de2c2b139070294aec12ec39b7c86a56b52DRC * @param srcImage a <code>BufferedImage</code> instance containing RGB or 32292549de2c2b139070294aec12ec39b7c86a56b52DRC * grayscale pixels to be compressed 32392549de2c2b139070294aec12ec39b7c86a56b52DRC * 3242c74e5124d25112809bdc26cbc36aa764e8870c3DRC * @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*} 32592549de2c2b139070294aec12ec39b7c86a56b52DRC * 32692549de2c2b139070294aec12ec39b7c86a56b52DRC * @return a buffer containing a JPEG image. The length of this buffer will 32792549de2c2b139070294aec12ec39b7c86a56b52DRC * not be equal to the size of the JPEG image. Use {@link 32892549de2c2b139070294aec12ec39b7c86a56b52DRC * #getCompressedSize} to obtain the size of the JPEG image. 32992549de2c2b139070294aec12ec39b7c86a56b52DRC */ 330f7f3ea404cc8618305efc059c34d881566206ed9DRC public byte[] compress(BufferedImage srcImage, int flags) throws Exception { 3314f1580cc0e7c33385e88bca7fe08602b87d29aebDRC int width = srcImage.getWidth(); 3324f1580cc0e7c33385e88bca7fe08602b87d29aebDRC int height = srcImage.getHeight(); 3339b49f0e4c77c727648c6d3a4915eefdf5436de4aDRC byte[] buf = new byte[TJ.bufSize(width, height, subsamp)]; 3344f1580cc0e7c33385e88bca7fe08602b87d29aebDRC compress(srcImage, buf, flags); 3354f1580cc0e7c33385e88bca7fe08602b87d29aebDRC return buf; 3364f1580cc0e7c33385e88bca7fe08602b87d29aebDRC } 3374f1580cc0e7c33385e88bca7fe08602b87d29aebDRC 33892549de2c2b139070294aec12ec39b7c86a56b52DRC /** 33992549de2c2b139070294aec12ec39b7c86a56b52DRC * Encode the uncompressed source image associated with this compressor 34092549de2c2b139070294aec12ec39b7c86a56b52DRC * instance and output a YUV planar image to the given destination buffer. 3412c74e5124d25112809bdc26cbc36aa764e8870c3DRC * This method uses the accelerated color conversion routines in 34292549de2c2b139070294aec12ec39b7c86a56b52DRC * TurboJPEG's underlying codec to produce a planar YUV image that is 34392549de2c2b139070294aec12ec39b7c86a56b52DRC * suitable for direct video display. Specifically, if the chrominance 34492549de2c2b139070294aec12ec39b7c86a56b52DRC * components are subsampled along the horizontal dimension, then the width 34592549de2c2b139070294aec12ec39b7c86a56b52DRC * of the luminance plane is padded to 2 in the output image (same goes for 34692549de2c2b139070294aec12ec39b7c86a56b52DRC * the height of the luminance plane, if the chrominance components are 34792549de2c2b139070294aec12ec39b7c86a56b52DRC * subsampled along the vertical dimension.) Also, each line of each plane 34892549de2c2b139070294aec12ec39b7c86a56b52DRC * in the output image is padded to 4 bytes. Although this will work with 34992549de2c2b139070294aec12ec39b7c86a56b52DRC * any subsampling option, it is really only useful in combination with 35092549de2c2b139070294aec12ec39b7c86a56b52DRC * {@link TJ#SAMP_420}, which produces an image compatible with the I420 (AKA 35192549de2c2b139070294aec12ec39b7c86a56b52DRC * "YUV420P") format. 35292549de2c2b139070294aec12ec39b7c86a56b52DRC * 35380803ae5fe6ca228d0783b1921e7e800c9a28964DRC * @param dstBuf buffer that will receive the YUV planar image. Use 35492549de2c2b139070294aec12ec39b7c86a56b52DRC * {@link TJ#bufSizeYUV} to determine the appropriate size for this buffer 35592549de2c2b139070294aec12ec39b7c86a56b52DRC * based on the image width, height, and level of chrominance subsampling. 35692549de2c2b139070294aec12ec39b7c86a56b52DRC * 3572c74e5124d25112809bdc26cbc36aa764e8870c3DRC * @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*} 35892549de2c2b139070294aec12ec39b7c86a56b52DRC */ 359f7f3ea404cc8618305efc059c34d881566206ed9DRC public void encodeYUV(byte[] dstBuf, int flags) throws Exception { 3604f1580cc0e7c33385e88bca7fe08602b87d29aebDRC if(dstBuf == null || flags < 0) 3614f1580cc0e7c33385e88bca7fe08602b87d29aebDRC throw new Exception("Invalid argument in compress()"); 3622c74e5124d25112809bdc26cbc36aa764e8870c3DRC if(srcBuf == null) throw new Exception(NO_ASSOC_ERROR); 3634f1580cc0e7c33385e88bca7fe08602b87d29aebDRC if(subsamp < 0) throw new Exception("Subsampling level not set"); 3642c74e5124d25112809bdc26cbc36aa764e8870c3DRC encodeYUV(srcBuf, srcWidth, srcPitch, srcHeight, 3652c74e5124d25112809bdc26cbc36aa764e8870c3DRC srcPixelFormat, dstBuf, subsamp, flags); 3662c74e5124d25112809bdc26cbc36aa764e8870c3DRC compressedSize = TJ.bufSizeYUV(srcWidth, srcHeight, subsamp); 3674f1580cc0e7c33385e88bca7fe08602b87d29aebDRC } 3684f1580cc0e7c33385e88bca7fe08602b87d29aebDRC 36992549de2c2b139070294aec12ec39b7c86a56b52DRC /** 37092549de2c2b139070294aec12ec39b7c86a56b52DRC * Encode the uncompressed source image associated with this compressor 37192549de2c2b139070294aec12ec39b7c86a56b52DRC * instance and return a buffer containing a YUV planar image. See 37292549de2c2b139070294aec12ec39b7c86a56b52DRC * {@link #encodeYUV(byte[], int)} for more detail. 37392549de2c2b139070294aec12ec39b7c86a56b52DRC * 3742c74e5124d25112809bdc26cbc36aa764e8870c3DRC * @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*} 37592549de2c2b139070294aec12ec39b7c86a56b52DRC * 37692549de2c2b139070294aec12ec39b7c86a56b52DRC * @return a buffer containing a YUV planar image 37792549de2c2b139070294aec12ec39b7c86a56b52DRC */ 378f7f3ea404cc8618305efc059c34d881566206ed9DRC public byte[] encodeYUV(int flags) throws Exception { 3792c74e5124d25112809bdc26cbc36aa764e8870c3DRC if(srcWidth < 1 || srcHeight < 1) 3802c74e5124d25112809bdc26cbc36aa764e8870c3DRC throw new Exception(NO_ASSOC_ERROR); 3814f1580cc0e7c33385e88bca7fe08602b87d29aebDRC if(subsamp < 0) throw new Exception("Subsampling level not set"); 3822c74e5124d25112809bdc26cbc36aa764e8870c3DRC byte[] buf = new byte[TJ.bufSizeYUV(srcWidth, srcHeight, subsamp)]; 3834f1580cc0e7c33385e88bca7fe08602b87d29aebDRC encodeYUV(buf, flags); 3844f1580cc0e7c33385e88bca7fe08602b87d29aebDRC return buf; 3854f1580cc0e7c33385e88bca7fe08602b87d29aebDRC } 3864f1580cc0e7c33385e88bca7fe08602b87d29aebDRC 38792549de2c2b139070294aec12ec39b7c86a56b52DRC /** 38892549de2c2b139070294aec12ec39b7c86a56b52DRC * Encode the uncompressed source image stored in <code>srcImage</code> 38992549de2c2b139070294aec12ec39b7c86a56b52DRC * and output a YUV planar image to the given destination buffer. See 39092549de2c2b139070294aec12ec39b7c86a56b52DRC * {@link #encodeYUV(byte[], int)} for more detail. 39192549de2c2b139070294aec12ec39b7c86a56b52DRC * 39292549de2c2b139070294aec12ec39b7c86a56b52DRC * @param srcImage a <code>BufferedImage</code> instance containing RGB or 39392549de2c2b139070294aec12ec39b7c86a56b52DRC * grayscale pixels to be encoded 39492549de2c2b139070294aec12ec39b7c86a56b52DRC * 39580803ae5fe6ca228d0783b1921e7e800c9a28964DRC * @param dstBuf buffer that will receive the YUV planar image. Use 39692549de2c2b139070294aec12ec39b7c86a56b52DRC * {@link TJ#bufSizeYUV} to determine the appropriate size for this buffer 39792549de2c2b139070294aec12ec39b7c86a56b52DRC * based on the image width, height, and level of chrominance subsampling. 39892549de2c2b139070294aec12ec39b7c86a56b52DRC * 3992c74e5124d25112809bdc26cbc36aa764e8870c3DRC * @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*} 40092549de2c2b139070294aec12ec39b7c86a56b52DRC */ 401f7f3ea404cc8618305efc059c34d881566206ed9DRC public void encodeYUV(BufferedImage srcImage, byte[] dstBuf, int flags) 4024f1580cc0e7c33385e88bca7fe08602b87d29aebDRC throws Exception { 4034f1580cc0e7c33385e88bca7fe08602b87d29aebDRC if(srcImage == null || dstBuf == null || flags < 0) 4044f1580cc0e7c33385e88bca7fe08602b87d29aebDRC throw new Exception("Invalid argument in encodeYUV()"); 40584a1bcca6fd0f21091a84f04b820b29012c60857DRC int width = srcImage.getWidth(); 40684a1bcca6fd0f21091a84f04b820b29012c60857DRC int height = srcImage.getHeight(); 407f7f3ea404cc8618305efc059c34d881566206ed9DRC int pixelFormat; boolean intPixels = false; 4081f014c32e66e00f4e6934f31beefae57ab51a477DRC if(byteOrder == null) 4091f014c32e66e00f4e6934f31beefae57ab51a477DRC byteOrder = ByteOrder.nativeOrder(); 41084a1bcca6fd0f21091a84f04b820b29012c60857DRC switch(srcImage.getType()) { 41184a1bcca6fd0f21091a84f04b820b29012c60857DRC case BufferedImage.TYPE_3BYTE_BGR: 412f7f3ea404cc8618305efc059c34d881566206ed9DRC pixelFormat = TJ.PF_BGR; break; 413c08e8c15bc73e7931ac5b87b992b17bbbda7f332DRC case BufferedImage.TYPE_4BYTE_ABGR: 414c08e8c15bc73e7931ac5b87b992b17bbbda7f332DRC case BufferedImage.TYPE_4BYTE_ABGR_PRE: 415c08e8c15bc73e7931ac5b87b992b17bbbda7f332DRC pixelFormat = TJ.PF_XBGR; break; 41684a1bcca6fd0f21091a84f04b820b29012c60857DRC case BufferedImage.TYPE_BYTE_GRAY: 417f7f3ea404cc8618305efc059c34d881566206ed9DRC pixelFormat = TJ.PF_GRAY; break; 41884a1bcca6fd0f21091a84f04b820b29012c60857DRC case BufferedImage.TYPE_INT_BGR: 4191f014c32e66e00f4e6934f31beefae57ab51a477DRC if(byteOrder == ByteOrder.BIG_ENDIAN) 4201f014c32e66e00f4e6934f31beefae57ab51a477DRC pixelFormat = TJ.PF_XBGR; 4211f014c32e66e00f4e6934f31beefae57ab51a477DRC else 4221f014c32e66e00f4e6934f31beefae57ab51a477DRC pixelFormat = TJ.PF_RGBX; 4231f014c32e66e00f4e6934f31beefae57ab51a477DRC intPixels = true; break; 42484a1bcca6fd0f21091a84f04b820b29012c60857DRC case BufferedImage.TYPE_INT_RGB: 425c08e8c15bc73e7931ac5b87b992b17bbbda7f332DRC case BufferedImage.TYPE_INT_ARGB: 426c08e8c15bc73e7931ac5b87b992b17bbbda7f332DRC case BufferedImage.TYPE_INT_ARGB_PRE: 4271f014c32e66e00f4e6934f31beefae57ab51a477DRC if(byteOrder == ByteOrder.BIG_ENDIAN) 4281f014c32e66e00f4e6934f31beefae57ab51a477DRC pixelFormat = TJ.PF_XRGB; 4291f014c32e66e00f4e6934f31beefae57ab51a477DRC else 4301f014c32e66e00f4e6934f31beefae57ab51a477DRC pixelFormat = TJ.PF_BGRX; 4311f014c32e66e00f4e6934f31beefae57ab51a477DRC intPixels = true; break; 43284a1bcca6fd0f21091a84f04b820b29012c60857DRC default: 43384a1bcca6fd0f21091a84f04b820b29012c60857DRC throw new Exception("Unsupported BufferedImage format"); 43484a1bcca6fd0f21091a84f04b820b29012c60857DRC } 43584a1bcca6fd0f21091a84f04b820b29012c60857DRC WritableRaster wr = srcImage.getRaster(); 4364f1580cc0e7c33385e88bca7fe08602b87d29aebDRC if(subsamp < 0) throw new Exception("Subsampling level not set"); 43784a1bcca6fd0f21091a84f04b820b29012c60857DRC if(intPixels) { 43884a1bcca6fd0f21091a84f04b820b29012c60857DRC SinglePixelPackedSampleModel sm = 43984a1bcca6fd0f21091a84f04b820b29012c60857DRC (SinglePixelPackedSampleModel)srcImage.getSampleModel(); 44084a1bcca6fd0f21091a84f04b820b29012c60857DRC int pitch = sm.getScanlineStride(); 44184a1bcca6fd0f21091a84f04b820b29012c60857DRC DataBufferInt db = (DataBufferInt)wr.getDataBuffer(); 442f7f3ea404cc8618305efc059c34d881566206ed9DRC int[] buf = db.getData(); 4434f1580cc0e7c33385e88bca7fe08602b87d29aebDRC encodeYUV(buf, width, pitch, height, pixelFormat, dstBuf, subsamp, 4444f1580cc0e7c33385e88bca7fe08602b87d29aebDRC flags); 44584a1bcca6fd0f21091a84f04b820b29012c60857DRC } 44684a1bcca6fd0f21091a84f04b820b29012c60857DRC else { 44784a1bcca6fd0f21091a84f04b820b29012c60857DRC ComponentSampleModel sm = 44884a1bcca6fd0f21091a84f04b820b29012c60857DRC (ComponentSampleModel)srcImage.getSampleModel(); 44984a1bcca6fd0f21091a84f04b820b29012c60857DRC int pixelSize = sm.getPixelStride(); 4504f1580cc0e7c33385e88bca7fe08602b87d29aebDRC if(pixelSize != TJ.getPixelSize(pixelFormat)) 45184a1bcca6fd0f21091a84f04b820b29012c60857DRC throw new Exception("Inconsistency between pixel format and pixel size in BufferedImage"); 45284a1bcca6fd0f21091a84f04b820b29012c60857DRC int pitch = sm.getScanlineStride(); 45384a1bcca6fd0f21091a84f04b820b29012c60857DRC DataBufferByte db = (DataBufferByte)wr.getDataBuffer(); 454f7f3ea404cc8618305efc059c34d881566206ed9DRC byte[] buf = db.getData(); 4554f1580cc0e7c33385e88bca7fe08602b87d29aebDRC encodeYUV(buf, width, pitch, height, pixelFormat, dstBuf, subsamp, 4564f1580cc0e7c33385e88bca7fe08602b87d29aebDRC flags); 45784a1bcca6fd0f21091a84f04b820b29012c60857DRC } 4584f1580cc0e7c33385e88bca7fe08602b87d29aebDRC compressedSize = TJ.bufSizeYUV(width, height, subsamp); 4594f1580cc0e7c33385e88bca7fe08602b87d29aebDRC } 4604f1580cc0e7c33385e88bca7fe08602b87d29aebDRC 46192549de2c2b139070294aec12ec39b7c86a56b52DRC /** 46292549de2c2b139070294aec12ec39b7c86a56b52DRC * Encode the uncompressed source image stored in <code>srcImage</code> 46392549de2c2b139070294aec12ec39b7c86a56b52DRC * and return a buffer containing a YUV planar image. See 46492549de2c2b139070294aec12ec39b7c86a56b52DRC * {@link #encodeYUV(byte[], int)} for more detail. 46592549de2c2b139070294aec12ec39b7c86a56b52DRC * 46692549de2c2b139070294aec12ec39b7c86a56b52DRC * @param srcImage a <code>BufferedImage</code> instance containing RGB or 46792549de2c2b139070294aec12ec39b7c86a56b52DRC * grayscale pixels to be encoded 46892549de2c2b139070294aec12ec39b7c86a56b52DRC * 4692c74e5124d25112809bdc26cbc36aa764e8870c3DRC * @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*} 47092549de2c2b139070294aec12ec39b7c86a56b52DRC * 47192549de2c2b139070294aec12ec39b7c86a56b52DRC * @return a buffer containing a YUV planar image 47292549de2c2b139070294aec12ec39b7c86a56b52DRC */ 473f7f3ea404cc8618305efc059c34d881566206ed9DRC public byte[] encodeYUV(BufferedImage srcImage, int flags) 4744f1580cc0e7c33385e88bca7fe08602b87d29aebDRC throws Exception { 4754f1580cc0e7c33385e88bca7fe08602b87d29aebDRC if(subsamp < 0) throw new Exception("Subsampling level not set"); 4764f1580cc0e7c33385e88bca7fe08602b87d29aebDRC int width = srcImage.getWidth(); 4774f1580cc0e7c33385e88bca7fe08602b87d29aebDRC int height = srcImage.getHeight(); 478f7f3ea404cc8618305efc059c34d881566206ed9DRC byte[] buf = new byte[TJ.bufSizeYUV(width, height, subsamp)]; 4794f1580cc0e7c33385e88bca7fe08602b87d29aebDRC encodeYUV(srcImage, buf, flags); 4804f1580cc0e7c33385e88bca7fe08602b87d29aebDRC return buf; 4814f1580cc0e7c33385e88bca7fe08602b87d29aebDRC } 4824f1580cc0e7c33385e88bca7fe08602b87d29aebDRC 48392549de2c2b139070294aec12ec39b7c86a56b52DRC /** 48492549de2c2b139070294aec12ec39b7c86a56b52DRC * Returns the size of the image (in bytes) generated by the most recent 48592549de2c2b139070294aec12ec39b7c86a56b52DRC * compress/encode operation. 48692549de2c2b139070294aec12ec39b7c86a56b52DRC * 48792549de2c2b139070294aec12ec39b7c86a56b52DRC * @return the size of the image (in bytes) generated by the most recent 48892549de2c2b139070294aec12ec39b7c86a56b52DRC * compress/encode operation 48992549de2c2b139070294aec12ec39b7c86a56b52DRC */ 4904f1580cc0e7c33385e88bca7fe08602b87d29aebDRC public int getCompressedSize() { 4914f1580cc0e7c33385e88bca7fe08602b87d29aebDRC return compressedSize; 49284a1bcca6fd0f21091a84f04b820b29012c60857DRC } 49384a1bcca6fd0f21091a84f04b820b29012c60857DRC 49492549de2c2b139070294aec12ec39b7c86a56b52DRC /** 49592549de2c2b139070294aec12ec39b7c86a56b52DRC * Free the native structures associated with this compressor instance. 49692549de2c2b139070294aec12ec39b7c86a56b52DRC */ 497c5a419970eb91c85844002901210484b29e25fb1DRC public void close() throws Exception { 498c5a419970eb91c85844002901210484b29e25fb1DRC destroy(); 499c5a419970eb91c85844002901210484b29e25fb1DRC } 500c5a419970eb91c85844002901210484b29e25fb1DRC 501c5a419970eb91c85844002901210484b29e25fb1DRC protected void finalize() throws Throwable { 502c5a419970eb91c85844002901210484b29e25fb1DRC try { 503c5a419970eb91c85844002901210484b29e25fb1DRC close(); 504c5a419970eb91c85844002901210484b29e25fb1DRC } 505f7f3ea404cc8618305efc059c34d881566206ed9DRC catch(Exception e) {} 506c5a419970eb91c85844002901210484b29e25fb1DRC finally { 507c5a419970eb91c85844002901210484b29e25fb1DRC super.finalize(); 508c5a419970eb91c85844002901210484b29e25fb1DRC } 509c5a419970eb91c85844002901210484b29e25fb1DRC }; 510c5a419970eb91c85844002901210484b29e25fb1DRC 511c5a419970eb91c85844002901210484b29e25fb1DRC private native void init() throws Exception; 512c5a419970eb91c85844002901210484b29e25fb1DRC 513c5a419970eb91c85844002901210484b29e25fb1DRC private native void destroy() throws Exception; 514c5a419970eb91c85844002901210484b29e25fb1DRC 515c5a419970eb91c85844002901210484b29e25fb1DRC // JPEG size in bytes is returned 516f7f3ea404cc8618305efc059c34d881566206ed9DRC private native int compress(byte[] srcBuf, int width, int pitch, 517fac3bea8dae8664110951427434d94bcd139d17bDRC int height, int pixelFormat, byte[] dstBuf, int jpegSubsamp, int jpegQual, 518c5a419970eb91c85844002901210484b29e25fb1DRC int flags) throws Exception; 519c5a419970eb91c85844002901210484b29e25fb1DRC 520fac3bea8dae8664110951427434d94bcd139d17bDRC private native int compress(byte[] srcBuf, int x, int y, int width, 521fac3bea8dae8664110951427434d94bcd139d17bDRC int pitch, int height, int pixelFormat, byte[] dstBuf, int jpegSubsamp, 522fac3bea8dae8664110951427434d94bcd139d17bDRC int jpegQual, int flags) throws Exception; 523fac3bea8dae8664110951427434d94bcd139d17bDRC 524fac3bea8dae8664110951427434d94bcd139d17bDRC private native int compress(int[] srcBuf, int width, int stride, 525fac3bea8dae8664110951427434d94bcd139d17bDRC int height, int pixelFormat, byte[] dstBuf, int jpegSubsamp, int jpegQual, 5264f1580cc0e7c33385e88bca7fe08602b87d29aebDRC int flags) throws Exception; 5274f1580cc0e7c33385e88bca7fe08602b87d29aebDRC 528fac3bea8dae8664110951427434d94bcd139d17bDRC private native int compress(int[] srcBuf, int x, int y, int width, 529fac3bea8dae8664110951427434d94bcd139d17bDRC int stride, int height, int pixelFormat, byte[] dstBuf, int jpegSubsamp, 530fac3bea8dae8664110951427434d94bcd139d17bDRC int jpegQual, int flags) throws Exception; 531fac3bea8dae8664110951427434d94bcd139d17bDRC 532f7f3ea404cc8618305efc059c34d881566206ed9DRC private native void encodeYUV(byte[] srcBuf, int width, int pitch, 533fac3bea8dae8664110951427434d94bcd139d17bDRC int height, int pixelFormat, byte[] dstBuf, int subsamp, int flags) 5344f1580cc0e7c33385e88bca7fe08602b87d29aebDRC throws Exception; 5354f1580cc0e7c33385e88bca7fe08602b87d29aebDRC 536f7f3ea404cc8618305efc059c34d881566206ed9DRC private native void encodeYUV(int[] srcBuf, int width, int pitch, 537fac3bea8dae8664110951427434d94bcd139d17bDRC int height, int pixelFormat, byte[] dstBuf, int subsamp, int flags) 53884a1bcca6fd0f21091a84f04b820b29012c60857DRC throws Exception; 53984a1bcca6fd0f21091a84f04b820b29012c60857DRC 540c5a419970eb91c85844002901210484b29e25fb1DRC static { 541b2f9415a6365b8eb412a5b6159be3cc0f875325fDRC TJLoader.load(); 542c5a419970eb91c85844002901210484b29e25fb1DRC } 543c5a419970eb91c85844002901210484b29e25fb1DRC 544c5a419970eb91c85844002901210484b29e25fb1DRC private long handle = 0; 5452c74e5124d25112809bdc26cbc36aa764e8870c3DRC private byte[] srcBuf = null; 5462c74e5124d25112809bdc26cbc36aa764e8870c3DRC private int srcWidth = 0; 5472c74e5124d25112809bdc26cbc36aa764e8870c3DRC private int srcHeight = 0; 548fac3bea8dae8664110951427434d94bcd139d17bDRC private int srcX = -1; 549fac3bea8dae8664110951427434d94bcd139d17bDRC private int srcY = -1; 5502c74e5124d25112809bdc26cbc36aa764e8870c3DRC private int srcPitch = 0; 5512c74e5124d25112809bdc26cbc36aa764e8870c3DRC private int srcPixelFormat = -1; 5524f1580cc0e7c33385e88bca7fe08602b87d29aebDRC private int subsamp = -1; 5534f1580cc0e7c33385e88bca7fe08602b87d29aebDRC private int jpegQuality = -1; 5544f1580cc0e7c33385e88bca7fe08602b87d29aebDRC private int compressedSize = 0; 5551f014c32e66e00f4e6934f31beefae57ab51a477DRC private ByteOrder byteOrder = null; 556c5a419970eb91c85844002901210484b29e25fb1DRC}; 557