Code formatting tweaks

git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.3.x@968 632fc199-4ca6-4c93-a231-07263d6284db
This commit is contained in:
DRC
2013-04-27 12:36:07 +00:00
parent aba6c404c3
commit 08fcac01e6
10 changed files with 940 additions and 880 deletions

View File

@@ -32,40 +32,37 @@ import javax.imageio.*;
import java.util.*; import java.util.*;
import org.libjpegturbo.turbojpeg.*; import org.libjpegturbo.turbojpeg.*;
class TJBench class TJBench {
{
static final int YUVENCODE = 1; static final int YUVENCODE = 1;
static final int YUVDECODE = 2; static final int YUVDECODE = 2;
static int flags = 0, yuv = 0, quiet = 0, pf = TJ.PF_BGR; static int flags = 0, yuv = 0, quiet = 0, pf = TJ.PF_BGR;
static boolean decompOnly, doTile; static boolean decompOnly, doTile;
static final String pixFormatStr[] = { static final String[] pixFormatStr = {
"RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "GRAY" "RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "GRAY"
}; };
static final String subNameLong[] = { static final String[] subNameLong = {
"4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0" "4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0"
}; };
static final String subName[] = { static final String[] subName = {
"444", "422", "420", "GRAY", "440" "444", "422", "420", "GRAY", "440"
}; };
static TJScalingFactor sf; static TJScalingFactor sf;
static int nsf = 0;
static int xformOp = TJTransform.OP_NONE, xformOpt = 0; static int xformOp = TJTransform.OP_NONE, xformOpt = 0;
static double benchTime = 5.0; static double benchTime = 5.0;
static final double getTime() static final double getTime() {
{
return (double)System.nanoTime() / 1.0e9; return (double)System.nanoTime() / 1.0e9;
} }
static String sigFig(double val, int figs) static String sigFig(double val, int figs) {
{
String format; String format;
int digitsAfterDecimal = figs - (int)Math.ceil(Math.log10(Math.abs(val))); int digitsAfterDecimal = figs - (int)Math.ceil(Math.log10(Math.abs(val)));
if (digitsAfterDecimal < 1) if (digitsAfterDecimal < 1)
@@ -76,19 +73,18 @@ class TJBench
} }
static byte[] loadImage(String fileName, int[] w, int[] h, int pf) static byte[] loadImage(String fileName, int[] w, int[] h, int pixelFormat)
throws Exception throws Exception {
{
BufferedImage img = ImageIO.read(new File(fileName)); BufferedImage img = ImageIO.read(new File(fileName));
if (img == null) if (img == null)
throw new Exception("Could not read " + fileName); throw new Exception("Could not read " + fileName);
w[0] = img.getWidth(); w[0] = img.getWidth();
h[0] = img.getHeight(); h[0] = img.getHeight();
int rgb[] = img.getRGB(0, 0, w[0], h[0], null, 0, w[0]); int[] rgb = img.getRGB(0, 0, w[0], h[0], null, 0, w[0]);
int ps = TJ.getPixelSize(pf); int ps = TJ.getPixelSize(pixelFormat);
int rindex = TJ.getRedOffset(pf); int rindex = TJ.getRedOffset(pixelFormat);
int gindex = TJ.getGreenOffset(pf); int gindex = TJ.getGreenOffset(pixelFormat);
int bindex = TJ.getBlueOffset(pf); int bindex = TJ.getBlueOffset(pixelFormat);
byte[] dstBuf = new byte[w[0] * h[0] * ps]; byte[] dstBuf = new byte[w[0] * h[0] * ps];
int pixels = w[0] * h[0], dstPtr = 0, rgbPtr = 0; int pixels = w[0] * h[0], dstPtr = 0, rgbPtr = 0;
while (pixels-- > 0) { while (pixels-- > 0) {
@@ -102,15 +98,14 @@ class TJBench
} }
static void saveImage(String fileName, byte[] srcBuf, int w, int h, int pf) static void saveImage(String fileName, byte[] srcBuf, int w, int h,
throws Exception int pixelFormat) throws Exception {
{
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
int pixels = w * h, srcPtr = 0; int pixels = w * h, srcPtr = 0;
int ps = TJ.getPixelSize(pf); int ps = TJ.getPixelSize(pixelFormat);
int rindex = TJ.getRedOffset(pf); int rindex = TJ.getRedOffset(pixelFormat);
int gindex = TJ.getGreenOffset(pf); int gindex = TJ.getGreenOffset(pixelFormat);
int bindex = TJ.getBlueOffset(pf); int bindex = TJ.getBlueOffset(pixelFormat);
for (int y = 0; y < h; y++) { for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++, srcPtr += ps) { for (int x = 0; x < w; x++, srcPtr += ps) {
int pixel = (srcBuf[srcPtr + rindex] & 0xff) << 16 | int pixel = (srcBuf[srcPtr + rindex] & 0xff) << 16 |
@@ -127,8 +122,7 @@ class TJBench
static void decompTest(byte[] srcBuf, byte[][] jpegBuf, int[] jpegSize, static void decompTest(byte[] srcBuf, byte[][] jpegBuf, int[] jpegSize,
byte[] dstBuf, int w, int h, int subsamp, byte[] dstBuf, int w, int h, int subsamp,
int jpegQual, String fileName, int tilew, int tileh) int jpegQual, String fileName, int tilew, int tileh)
throws Exception throws Exception {
{
String qualStr = new String(""), sizeStr, tempStr; String qualStr = new String(""), sizeStr, tempStr;
TJDecompressor tjd; TJDecompressor tjd;
double start, elapsed; double start, elapsed;
@@ -161,7 +155,7 @@ class TJBench
/* Benchmark */ /* Benchmark */
for (i = 0, start = getTime(); (elapsed = getTime() - start) < benchTime; for (i = 0, start = getTime(); (elapsed = getTime() - start) < benchTime;
i++) { i++) {
int tile=0; int tile = 0;
if (yuv == YUVDECODE) if (yuv == YUVDECODE)
tjd.decompressToYUV(dstBuf, flags); tjd.decompressToYUV(dstBuf, flags);
else { else {
@@ -221,7 +215,8 @@ class TJBench
int lum = (int)((double)(srcBuf[rindex] & 0xff) * 0.299 + int lum = (int)((double)(srcBuf[rindex] & 0xff) * 0.299 +
(double)(srcBuf[gindex] & 0xff) * 0.587 + (double)(srcBuf[gindex] & 0xff) * 0.587 +
(double)(srcBuf[bindex] & 0xff) * 0.114 + 0.5); (double)(srcBuf[bindex] & 0xff) * 0.114 + 0.5);
if (lum > 255) lum = 255; if (lum < 0) lum = 0; if (lum > 255) lum = 255;
if (lum < 0) lum = 0;
dstBuf[rindex] = (byte)Math.abs((dstBuf[rindex] & 0xff) - lum); dstBuf[rindex] = (byte)Math.abs((dstBuf[rindex] & 0xff) - lum);
dstBuf[gindex] = (byte)Math.abs((dstBuf[gindex] & 0xff) - lum); dstBuf[gindex] = (byte)Math.abs((dstBuf[gindex] & 0xff) - lum);
dstBuf[bindex] = (byte)Math.abs((dstBuf[bindex] & 0xff) - lum); dstBuf[bindex] = (byte)Math.abs((dstBuf[bindex] & 0xff) - lum);
@@ -241,8 +236,7 @@ class TJBench
static void doTestYUV(byte[] srcBuf, int w, int h, int subsamp, static void doTestYUV(byte[] srcBuf, int w, int h, int subsamp,
String fileName) throws Exception String fileName) throws Exception {
{
TJCompressor tjc; TJCompressor tjc;
byte[] dstBuf; byte[] dstBuf;
double start, elapsed; double start, elapsed;
@@ -304,8 +298,7 @@ class TJBench
static void doTest(byte[] srcBuf, int w, int h, int subsamp, int jpegQual, static void doTest(byte[] srcBuf, int w, int h, int subsamp, int jpegQual,
String fileName) throws Exception String fileName) throws Exception {
{
TJCompressor tjc; TJCompressor tjc;
byte[] tmpBuf; byte[] tmpBuf;
byte[][] jpegBuf; byte[][] jpegBuf;
@@ -418,8 +411,7 @@ class TJBench
} }
static void doDecompTest(String fileName) throws Exception static void doDecompTest(String fileName) throws Exception {
{
TJTransformer tjt; TJTransformer tjt;
byte[][] jpegBuf; byte[][] jpegBuf;
byte[] srcBuf; byte[] srcBuf;
@@ -477,7 +469,7 @@ class TJBench
System.out.format(" --> %d x %d", sf.getScaled(_w), System.out.format(" --> %d x %d", sf.getScaled(_w),
sf.getScaled(_h)); sf.getScaled(_h));
System.out.println(""); System.out.println("");
} else if (quiet==1) { } else if (quiet == 1) {
System.out.format("%s\t%s\t%s\t", pixFormatStr[pf], System.out.format("%s\t%s\t%s\t", pixFormatStr[pf],
(flags & TJ.FLAG_BOTTOMUP) != 0 ? "BU" : "TD", (flags & TJ.FLAG_BOTTOMUP) != 0 ? "BU" : "TD",
subNameLong[subsamp]); subNameLong[subsamp]);
@@ -510,7 +502,7 @@ class TJBench
_ntilesw = (_w + _tilew - 1) / _tilew; _ntilesw = (_w + _tilew - 1) / _tilew;
_ntilesh = (_h + _tileh - 1) / _tileh; _ntilesh = (_h + _tileh - 1) / _tileh;
TJTransform t[] = new TJTransform[_ntilesw * _ntilesh]; TJTransform[] t = new TJTransform[_ntilesw * _ntilesh];
jpegBuf = new byte[_ntilesw * _ntilesh][TJ.bufSize(_tilew, _tileh, subsamp)]; jpegBuf = new byte[_ntilesw * _ntilesh][TJ.bufSize(_tilew, _tileh, subsamp)];
for (y = 0, tile = 0; y < _h; y += _tileh) { for (y = 0, tile = 0; y < _h; y += _tileh) {
@@ -583,10 +575,9 @@ class TJBench
} }
static void usage() throws Exception static void usage() throws Exception {
{
int i; int i;
TJScalingFactor scalingFactors[] = TJ.getScalingFactors(); TJScalingFactor[] scalingFactors = TJ.getScalingFactors();
int nsf = scalingFactors.length; int nsf = scalingFactors.length;
String className = new TJBench().getClass().getName(); String className = new TJBench().getClass().getName();
@@ -641,8 +632,7 @@ class TJBench
} }
public static void main(String argv[]) public static void main(String[] argv) {
{
byte[] srcBuf = null; int w = 0, h = 0; byte[] srcBuf = null; int w = 0, h = 0;
int minQual = -1, maxQual = -1; int minQual = -1, maxQual = -1;
int minArg = 1; int retval = 0; int minArg = 1; int retval = 0;
@@ -751,7 +741,7 @@ class TJBench
} catch(Exception e) {} } catch(Exception e) {}
if (temp2 <= 0) temp2 = 1; if (temp2 <= 0) temp2 = 1;
if (temp1 > 0) { if (temp1 > 0) {
TJScalingFactor scalingFactors[] = TJ.getScalingFactors(); TJScalingFactor[] scalingFactors = TJ.getScalingFactors();
for (int j = 0; j < scalingFactors.length; j++) { for (int j = 0; j < scalingFactors.length; j++) {
if ((double)temp1 / (double)temp2 == if ((double)temp1 / (double)temp2 ==
(double)scalingFactors[j].getNum() / (double)scalingFactors[j].getNum() /

View File

@@ -51,12 +51,15 @@ public class TJExample implements TJCustomFilter {
System.out.println("Options:\n"); System.out.println("Options:\n");
System.out.println("-scale M/N = if the input image is a JPEG file, scale the width/height of the"); System.out.println("-scale M/N = if the input image is a JPEG file, scale the width/height of the");
System.out.print(" output image by a factor of M/N (M/N = "); System.out.print(" output image by a factor of M/N (M/N = ");
for(int i = 0; i < sf.length; i++) { for (int i = 0; i < sf.length; i++) {
System.out.print(sf[i].getNum() + "/" + sf[i].getDenom()); System.out.print(sf[i].getNum() + "/" + sf[i].getDenom());
if(sf.length == 2 && i != sf.length - 1) System.out.print(" or "); if (sf.length == 2 && i != sf.length - 1)
else if(sf.length > 2) { System.out.print(" or ");
if(i != sf.length - 1) System.out.print(", "); else if (sf.length > 2) {
if(i == sf.length - 2) System.out.print("or "); if (i != sf.length - 1)
System.out.print(", ");
if (i == sf.length - 2)
System.out.print("or ");
} }
} }
System.out.println(")\n"); System.out.println(")\n");
@@ -90,13 +93,14 @@ public class TJExample implements TJCustomFilter {
System.exit(1); System.exit(1);
} }
private final static String sampName[] = { private static final String[] sampName = {
"4:4:4", "4:2:2", "4:2:0", "Grayscale", "4:4:0" "4:4:4", "4:2:2", "4:2:0", "Grayscale", "4:4:0"
}; };
public static void main(String argv[]) { public static void main(String[] argv) {
BufferedImage img = null; byte[] bmpBuf = null; BufferedImage img = null;
byte[] bmpBuf = null;
TJTransform xform = new TJTransform(); TJTransform xform = new TJTransform();
int flags = 0; int flags = 0;
@@ -104,7 +108,7 @@ public class TJExample implements TJCustomFilter {
sf = TJ.getScalingFactors(); sf = TJ.getScalingFactors();
if(argv.length < 2) { if (argv.length < 2) {
usage(); usage();
} }
@@ -113,119 +117,134 @@ public class TJExample implements TJCustomFilter {
int outSubsamp = -1, outQual = 95; int outSubsamp = -1, outQual = 95;
boolean display = false; boolean display = false;
if(argv.length > 1) { if (argv.length > 1) {
for(int i = 1; i < argv.length; i++) { for (int i = 1; i < argv.length; i++) {
if(argv[i].length() < 2) continue; if (argv[i].length() < 2)
if(argv[i].length() > 2 continue;
&& argv[i].substring(0, 3).equalsIgnoreCase("-sc")) { if (argv[i].length() > 2 &&
argv[i].substring(0, 3).equalsIgnoreCase("-sc")) {
int match = 0; int match = 0;
if(i < argv.length - 1) { if (i < argv.length - 1) {
String[] scaleArg = argv[++i].split("/"); String[] scaleArg = argv[++i].split("/");
if(scaleArg.length == 2) { if (scaleArg.length == 2) {
TJScalingFactor tempsf = TJScalingFactor tempsf =
new TJScalingFactor(Integer.parseInt(scaleArg[0]), new TJScalingFactor(Integer.parseInt(scaleArg[0]),
Integer.parseInt(scaleArg[1])); Integer.parseInt(scaleArg[1]));
for(int j = 0; j < sf.length; j++) { for (int j = 0; j < sf.length; j++) {
if(tempsf.equals(sf[j])) { if (tempsf.equals(sf[j])) {
scaleFactor = sf[j]; scaleFactor = sf[j];
match = 1; break; match = 1;
break;
} }
} }
} }
} }
if(match != 1) usage(); if (match != 1) usage();
} }
if(argv[i].equalsIgnoreCase("-h") || argv[i].equalsIgnoreCase("-?")) if (argv[i].equalsIgnoreCase("-h") || argv[i].equalsIgnoreCase("-?"))
usage(); usage();
if(argv[i].length() > 2 if (argv[i].length() > 2 &&
&& argv[i].substring(0, 3).equalsIgnoreCase("-sa")) { argv[i].substring(0, 3).equalsIgnoreCase("-sa")) {
if(i < argv.length - 1) { if (i < argv.length - 1) {
i++; i++;
if(argv[i].substring(0, 1).equalsIgnoreCase("g")) if (argv[i].substring(0, 1).equalsIgnoreCase("g"))
outSubsamp = TJ.SAMP_GRAY; outSubsamp = TJ.SAMP_GRAY;
else if(argv[i].equals("444")) outSubsamp = TJ.SAMP_444; else if (argv[i].equals("444"))
else if(argv[i].equals("422")) outSubsamp = TJ.SAMP_422; outSubsamp = TJ.SAMP_444;
else if(argv[i].equals("420")) outSubsamp = TJ.SAMP_420; else if (argv[i].equals("422"))
else usage(); outSubsamp = TJ.SAMP_422;
else if (argv[i].equals("420"))
outSubsamp = TJ.SAMP_420;
else
usage();
} else
usage();
} }
else usage(); if (argv[i].substring(0, 2).equalsIgnoreCase("-q")) {
} if (i < argv.length - 1) {
if(argv[i].substring(0, 2).equalsIgnoreCase("-q")) {
if(i < argv.length - 1) {
int qual = Integer.parseInt(argv[++i]); int qual = Integer.parseInt(argv[++i]);
if(qual >= 1 && qual <= 100) outQual = qual; if (qual >= 1 && qual <= 100)
else usage(); outQual = qual;
else
usage();
} else
usage();
} }
else usage(); if (argv[i].substring(0, 2).equalsIgnoreCase("-g"))
}
if(argv[i].substring(0, 2).equalsIgnoreCase("-g"))
xform.options |= TJTransform.OPT_GRAY; xform.options |= TJTransform.OPT_GRAY;
if(argv[i].equalsIgnoreCase("-hflip")) if (argv[i].equalsIgnoreCase("-hflip"))
xform.op = TJTransform.OP_HFLIP; xform.op = TJTransform.OP_HFLIP;
if(argv[i].equalsIgnoreCase("-vflip")) if (argv[i].equalsIgnoreCase("-vflip"))
xform.op = TJTransform.OP_VFLIP; xform.op = TJTransform.OP_VFLIP;
if(argv[i].equalsIgnoreCase("-transpose")) if (argv[i].equalsIgnoreCase("-transpose"))
xform.op = TJTransform.OP_TRANSPOSE; xform.op = TJTransform.OP_TRANSPOSE;
if(argv[i].equalsIgnoreCase("-transverse")) if (argv[i].equalsIgnoreCase("-transverse"))
xform.op = TJTransform.OP_TRANSVERSE; xform.op = TJTransform.OP_TRANSVERSE;
if(argv[i].equalsIgnoreCase("-rot90")) if (argv[i].equalsIgnoreCase("-rot90"))
xform.op = TJTransform.OP_ROT90; xform.op = TJTransform.OP_ROT90;
if(argv[i].equalsIgnoreCase("-rot180")) if (argv[i].equalsIgnoreCase("-rot180"))
xform.op = TJTransform.OP_ROT180; xform.op = TJTransform.OP_ROT180;
if(argv[i].equalsIgnoreCase("-rot270")) if (argv[i].equalsIgnoreCase("-rot270"))
xform.op = TJTransform.OP_ROT270; xform.op = TJTransform.OP_ROT270;
if(argv[i].equalsIgnoreCase("-custom")) if (argv[i].equalsIgnoreCase("-custom"))
xform.cf = new TJExample(); xform.cf = new TJExample();
else if(argv[i].length() > 2 else if (argv[i].length() > 2 &&
&& argv[i].substring(0, 2).equalsIgnoreCase("-c")) { argv[i].substring(0, 2).equalsIgnoreCase("-c")) {
if(i >= argv.length - 1) usage(); if (i >= argv.length - 1)
usage();
String[] cropArg = argv[++i].split(","); String[] cropArg = argv[++i].split(",");
if(cropArg.length != 3) usage(); if (cropArg.length != 3)
usage();
String[] dimArg = cropArg[2].split("[xX]"); String[] dimArg = cropArg[2].split("[xX]");
if(dimArg.length != 2) usage(); if (dimArg.length != 2)
usage();
int tempx = Integer.parseInt(cropArg[0]); int tempx = Integer.parseInt(cropArg[0]);
int tempy = Integer.parseInt(cropArg[1]); int tempy = Integer.parseInt(cropArg[1]);
int tempw = Integer.parseInt(dimArg[0]); int tempw = Integer.parseInt(dimArg[0]);
int temph = Integer.parseInt(dimArg[1]); int temph = Integer.parseInt(dimArg[1]);
if(tempx < 0 || tempy < 0 || tempw < 0 || temph < 0) usage(); if (tempx < 0 || tempy < 0 || tempw < 0 || temph < 0)
xform.x = tempx; xform.y = tempy; usage();
xform.width = tempw; xform.height = temph; xform.x = tempx;
xform.y = tempy;
xform.width = tempw;
xform.height = temph;
xform.options |= TJTransform.OPT_CROP; xform.options |= TJTransform.OPT_CROP;
} }
if(argv[i].substring(0, 2).equalsIgnoreCase("-d")) if (argv[i].substring(0, 2).equalsIgnoreCase("-d"))
display = true; display = true;
if(argv[i].equalsIgnoreCase("-fastupsample")) { if (argv[i].equalsIgnoreCase("-fastupsample")) {
System.out.println("Using fast upsampling code"); System.out.println("Using fast upsampling code");
flags |= TJ.FLAG_FASTUPSAMPLE; flags |= TJ.FLAG_FASTUPSAMPLE;
} }
if(argv[i].equalsIgnoreCase("-fastdct")) { if (argv[i].equalsIgnoreCase("-fastdct")) {
System.out.println("Using fastest DCT/IDCT algorithm"); System.out.println("Using fastest DCT/IDCT algorithm");
flags |= TJ.FLAG_FASTDCT; flags |= TJ.FLAG_FASTDCT;
} }
if(argv[i].equalsIgnoreCase("-accuratedct")) { if (argv[i].equalsIgnoreCase("-accuratedct")) {
System.out.println("Using most accurate DCT/IDCT algorithm"); System.out.println("Using most accurate DCT/IDCT algorithm");
flags |= TJ.FLAG_ACCURATEDCT; flags |= TJ.FLAG_ACCURATEDCT;
} }
} }
} }
String[] inFileTokens = argv[0].split("\\."); String[] inFileTokens = argv[0].split("\\.");
if(inFileTokens.length > 1) if (inFileTokens.length > 1)
inFormat = inFileTokens[inFileTokens.length - 1]; inFormat = inFileTokens[inFileTokens.length - 1];
String[] outFileTokens; String[] outFileTokens;
if(display) outFormat = "bmp"; if (display)
outFormat = "bmp";
else { else {
outFileTokens = argv[1].split("\\."); outFileTokens = argv[1].split("\\.");
if(outFileTokens.length > 1) if (outFileTokens.length > 1)
outFormat = outFileTokens[outFileTokens.length - 1]; outFormat = outFileTokens[outFileTokens.length - 1];
} }
File file = new File(argv[0]); File file = new File(argv[0]);
int width, height; int width, height;
if(inFormat.equalsIgnoreCase("jpg")) { if (inFormat.equalsIgnoreCase("jpg")) {
FileInputStream fis = new FileInputStream(file); FileInputStream fis = new FileInputStream(file);
int inputSize = fis.available(); int inputSize = fis.available();
if(inputSize < 1) { if (inputSize < 1) {
System.out.println("Input file contains no data"); System.out.println("Input file contains no data");
System.exit(1); System.exit(1);
} }
@@ -234,27 +253,28 @@ public class TJExample implements TJCustomFilter {
fis.close(); fis.close();
TJDecompressor tjd; TJDecompressor tjd;
if(xform.op != TJTransform.OP_NONE || xform.options != 0 if (xform.op != TJTransform.OP_NONE || xform.options != 0 ||
|| xform.cf != null) { xform.cf != null) {
TJTransformer tjt = new TJTransformer(inputBuf); TJTransformer tjt = new TJTransformer(inputBuf);
TJTransform t[] = new TJTransform[1]; TJTransform[] t = new TJTransform[1];
t[0] = xform; t[0] = xform;
t[0].options |= TJTransform.OPT_TRIM; t[0].options |= TJTransform.OPT_TRIM;
TJDecompressor[] tjdx = tjt.transform(t, 0); TJDecompressor[] tjdx = tjt.transform(t, 0);
tjd = tjdx[0]; tjd = tjdx[0];
} } else
else tjd = new TJDecompressor(inputBuf); tjd = new TJDecompressor(inputBuf);
width = tjd.getWidth(); width = tjd.getWidth();
height = tjd.getHeight(); height = tjd.getHeight();
int inSubsamp = tjd.getSubsamp(); int inSubsamp = tjd.getSubsamp();
System.out.println("Source Image: " + width + " x " + height System.out.println("Source Image: " + width + " x " + height +
+ " pixels, " + sampName[inSubsamp] + " subsampling"); " pixels, " + sampName[inSubsamp] + " subsampling");
if(outSubsamp < 0) outSubsamp = inSubsamp; if (outSubsamp < 0)
outSubsamp = inSubsamp;
if(outFormat.equalsIgnoreCase("jpg") if (outFormat.equalsIgnoreCase("jpg") &&
&& (xform.op != TJTransform.OP_NONE || xform.options != 0) (xform.op != TJTransform.OP_NONE || xform.options != 0) &&
&& scaleFactor.isOne()) { scaleFactor.isOne()) {
file = new File(argv[1]); file = new File(argv[1]);
FileOutputStream fos = new FileOutputStream(file); FileOutputStream fos = new FileOutputStream(file);
fos.write(tjd.getJPEGBuf(), 0, tjd.getJPEGSize()); fos.write(tjd.getJPEGBuf(), 0, tjd.getJPEGSize());
@@ -265,45 +285,45 @@ public class TJExample implements TJCustomFilter {
width = scaleFactor.getScaled(width); width = scaleFactor.getScaled(width);
height = scaleFactor.getScaled(height); height = scaleFactor.getScaled(height);
if(!outFormat.equalsIgnoreCase("jpg")) if (!outFormat.equalsIgnoreCase("jpg"))
img = tjd.decompress(width, height, BufferedImage.TYPE_INT_RGB, img = tjd.decompress(width, height, BufferedImage.TYPE_INT_RGB,
flags); flags);
else bmpBuf = tjd.decompress(width, 0, height, TJ.PF_BGRX, flags); else
bmpBuf = tjd.decompress(width, 0, height, TJ.PF_BGRX, flags);
tjd.close(); tjd.close();
} } else {
else {
img = ImageIO.read(file); img = ImageIO.read(file);
if (img == null) if (img == null)
throw new Exception("Input image type not supported."); throw new Exception("Input image type not supported.");
width = img.getWidth(); width = img.getWidth();
height = img.getHeight(); height = img.getHeight();
if(outSubsamp < 0) { if (outSubsamp < 0) {
if(img.getType() == BufferedImage.TYPE_BYTE_GRAY) if (img.getType() == BufferedImage.TYPE_BYTE_GRAY)
outSubsamp = TJ.SAMP_GRAY; outSubsamp = TJ.SAMP_GRAY;
else outSubsamp = TJ.SAMP_444; else
outSubsamp = TJ.SAMP_444;
} }
} }
System.gc(); System.gc();
if(!display) if (!display)
System.out.print("Dest. Image (" + outFormat + "): " + width + " x " System.out.print("Dest. Image (" + outFormat + "): " + width + " x " +
+ height + " pixels"); height + " pixels");
if(display) { if (display) {
ImageIcon icon = new ImageIcon(img); ImageIcon icon = new ImageIcon(img);
JLabel label = new JLabel(icon, JLabel.CENTER); JLabel label = new JLabel(icon, JLabel.CENTER);
JOptionPane.showMessageDialog(null, label, "Output Image", JOptionPane.showMessageDialog(null, label, "Output Image",
JOptionPane.PLAIN_MESSAGE); JOptionPane.PLAIN_MESSAGE);
} } else if (outFormat.equalsIgnoreCase("jpg")) {
else if(outFormat.equalsIgnoreCase("jpg")) { System.out.println(", " + sampName[outSubsamp] +
System.out.println(", " + sampName[outSubsamp] " subsampling, quality = " + outQual);
+ " subsampling, quality = " + outQual);
TJCompressor tjc = new TJCompressor(); TJCompressor tjc = new TJCompressor();
int jpegSize; int jpegSize;
byte[] jpegBuf; byte[] jpegBuf;
tjc.setSubsamp(outSubsamp); tjc.setSubsamp(outSubsamp);
tjc.setJPEGQuality(outQual); tjc.setJPEGQuality(outQual);
if(img != null) if (img != null)
jpegBuf = tjc.compress(img, flags); jpegBuf = tjc.compress(img, flags);
else { else {
tjc.setSourceImage(bmpBuf, width, 0, height, TJ.PF_BGRX); tjc.setSourceImage(bmpBuf, width, 0, height, TJ.PF_BGRX);
@@ -316,27 +336,26 @@ public class TJExample implements TJCustomFilter {
FileOutputStream fos = new FileOutputStream(file); FileOutputStream fos = new FileOutputStream(file);
fos.write(jpegBuf, 0, jpegSize); fos.write(jpegBuf, 0, jpegSize);
fos.close(); fos.close();
} } else {
else {
System.out.print("\n"); System.out.print("\n");
file = new File(argv[1]); file = new File(argv[1]);
ImageIO.write(img, outFormat, file); ImageIO.write(img, outFormat, file);
} }
} } catch(Exception e) {
catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
System.exit(-1); System.exit(-1);
} }
} }
public void customFilter(ShortBuffer coeffBuffer, Rectangle bufferRegion, public void customFilter(ShortBuffer coeffBuffer, Rectangle bufferRegion,
Rectangle planeRegion, int componentIndex, int transformIndex, Rectangle planeRegion, int componentIndex,
TJTransform transform) throws Exception { int transformIndex, TJTransform transform)
for(int i=0; i<bufferRegion.width*bufferRegion.height; i++) { throws Exception {
for (int i = 0; i < bufferRegion.width * bufferRegion.height; i++) {
coeffBuffer.put(i, (short)(-coeffBuffer.get(i))); coeffBuffer.put(i, (short)(-coeffBuffer.get(i)));
} }
} }
static TJScalingFactor sf [] = null; static TJScalingFactor[] sf = null;
}; };

View File

@@ -50,48 +50,48 @@ public class TJUnitTest {
System.exit(1); System.exit(1);
} }
private final static String subNameLong[] = { private static final String[] subNameLong = {
"4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0" "4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0"
}; };
private final static String subName[] = { private static final String[] subName = {
"444", "422", "420", "GRAY", "440" "444", "422", "420", "GRAY", "440"
}; };
private final static String pixFormatStr[] = { private static final String[] pixFormatStr = {
"RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "Grayscale", "RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "Grayscale",
"RGBA", "BGRA", "ABGR", "ARGB" "RGBA", "BGRA", "ABGR", "ARGB"
}; };
private final static int alphaOffset[] = { private static final int[] alphaOffset = {
-1, -1, -1, -1, -1, -1, -1, 3, 3, 0, 0 -1, -1, -1, -1, -1, -1, -1, 3, 3, 0, 0
}; };
private final static int _3byteFormats[] = { private static final int[] _3byteFormats = {
TJ.PF_RGB, TJ.PF_BGR TJ.PF_RGB, TJ.PF_BGR
}; };
private final static int _3byteFormatsBI[] = { private static final int[] _3byteFormatsBI = {
BufferedImage.TYPE_3BYTE_BGR BufferedImage.TYPE_3BYTE_BGR
}; };
private final static int _4byteFormats[] = { private static final int[] _4byteFormats = {
TJ.PF_RGBX, TJ.PF_BGRX, TJ.PF_XBGR, TJ.PF_XRGB TJ.PF_RGBX, TJ.PF_BGRX, TJ.PF_XBGR, TJ.PF_XRGB
}; };
private final static int _4byteFormatsBI[] = { private static final int[] _4byteFormatsBI = {
BufferedImage.TYPE_INT_BGR, BufferedImage.TYPE_INT_RGB, BufferedImage.TYPE_INT_BGR, BufferedImage.TYPE_INT_RGB,
BufferedImage.TYPE_4BYTE_ABGR, BufferedImage.TYPE_4BYTE_ABGR_PRE, BufferedImage.TYPE_4BYTE_ABGR, BufferedImage.TYPE_4BYTE_ABGR_PRE,
BufferedImage.TYPE_INT_ARGB, BufferedImage.TYPE_INT_ARGB_PRE BufferedImage.TYPE_INT_ARGB, BufferedImage.TYPE_INT_ARGB_PRE
}; };
private final static int onlyGray[] = { private static final int[] onlyGray = {
TJ.PF_GRAY TJ.PF_GRAY
}; };
private final static int onlyGrayBI[] = { private static final int[] onlyGrayBI = {
BufferedImage.TYPE_BYTE_GRAY BufferedImage.TYPE_BYTE_GRAY
}; };
private final static int onlyRGB[] = { private static final int[] onlyRGB = {
TJ.PF_RGB TJ.PF_RGB
}; };
private final static int YUVENCODE = 1; private static final int YUVENCODE = 1;
private final static int YUVDECODE = 2; private static final int YUVDECODE = 2;
private static int yuv = 0; private static int yuv = 0;
private static boolean bi = false; private static boolean bi = false;
@@ -108,18 +108,18 @@ public class TJUnitTest {
case BufferedImage.TYPE_BYTE_GRAY: case BufferedImage.TYPE_BYTE_GRAY:
return TJ.PF_GRAY; return TJ.PF_GRAY;
case BufferedImage.TYPE_INT_BGR: case BufferedImage.TYPE_INT_BGR:
if(byteOrder == ByteOrder.BIG_ENDIAN) if (byteOrder == ByteOrder.BIG_ENDIAN)
return TJ.PF_XBGR; return TJ.PF_XBGR;
else else
return TJ.PF_RGBX; return TJ.PF_RGBX;
case BufferedImage.TYPE_INT_RGB: case BufferedImage.TYPE_INT_RGB:
if(byteOrder == ByteOrder.BIG_ENDIAN) if (byteOrder == ByteOrder.BIG_ENDIAN)
return TJ.PF_XRGB; return TJ.PF_XRGB;
else else
return TJ.PF_BGRX; return TJ.PF_BGRX;
case BufferedImage.TYPE_INT_ARGB: case BufferedImage.TYPE_INT_ARGB:
case BufferedImage.TYPE_INT_ARGB_PRE: case BufferedImage.TYPE_INT_ARGB_PRE:
if(byteOrder == ByteOrder.BIG_ENDIAN) if (byteOrder == ByteOrder.BIG_ENDIAN)
return TJ.PF_ARGB; return TJ.PF_ARGB;
else else
return TJ.PF_BGRA; return TJ.PF_BGRA;
@@ -149,7 +149,6 @@ public class TJUnitTest {
return "Unknown"; return "Unknown";
} }
private static double getTime() { private static double getTime() {
return (double)System.nanoTime() / 1.0e9; return (double)System.nanoTime() / 1.0e9;
} }
@@ -164,36 +163,40 @@ public class TJUnitTest {
int index, row, col, halfway = 16; int index, row, col, halfway = 16;
Arrays.fill(buf, (byte)0); Arrays.fill(buf, (byte)0);
if(pf == TJ.PF_GRAY) { if (pf == TJ.PF_GRAY) {
for(row = 0; row < h; row++) { for (row = 0; row < h; row++) {
for(col = 0; col < w; col++) { for (col = 0; col < w; col++) {
if((flags & TJ.FLAG_BOTTOMUP) != 0) if ((flags & TJ.FLAG_BOTTOMUP) != 0)
index = pitch * (h - row - 1) + col; index = pitch * (h - row - 1) + col;
else index = pitch * row + col; else
if(((row / 8) + (col / 8)) % 2 == 0) index = pitch * row + col;
if (((row / 8) + (col / 8)) % 2 == 0)
buf[index] = (row < halfway) ? (byte)255 : 0; buf[index] = (row < halfway) ? (byte)255 : 0;
else buf[index] = (row < halfway) ? 76 : (byte)226; else
buf[index] = (row < halfway) ? 76 : (byte)226;
} }
} }
return; return;
} }
for(row = 0; row < h; row++) { for (row = 0; row < h; row++) {
for(col = 0; col < w; col++) { for (col = 0; col < w; col++) {
if((flags & TJ.FLAG_BOTTOMUP) != 0) if ((flags & TJ.FLAG_BOTTOMUP) != 0)
index = pitch * (h - row - 1) + col * ps; index = pitch * (h - row - 1) + col * ps;
else index = pitch * row + col * ps; else
if(((row / 8) + (col / 8)) % 2 == 0) { index = pitch * row + col * ps;
if(row < halfway) { if (((row / 8) + (col / 8)) % 2 == 0) {
if (row < halfway) {
buf[index + roffset] = (byte)255; buf[index + roffset] = (byte)255;
buf[index + goffset] = (byte)255; buf[index + goffset] = (byte)255;
buf[index + boffset] = (byte)255; buf[index + boffset] = (byte)255;
} }
} } else {
else {
buf[index + roffset] = (byte)255; buf[index + roffset] = (byte)255;
if(row >= halfway) buf[index + goffset] = (byte)255; if (row >= halfway)
buf[index + goffset] = (byte)255;
} }
if (aoffset >= 0) buf[index + aoffset] = (byte)255; if (aoffset >= 0)
buf[index + aoffset] = (byte)255;
} }
} }
} }
@@ -207,23 +210,25 @@ public class TJUnitTest {
int index, row, col, halfway = 16; int index, row, col, halfway = 16;
Arrays.fill(buf, 0); Arrays.fill(buf, 0);
for(row = 0; row < h; row++) { for (row = 0; row < h; row++) {
for(col = 0; col < w; col++) { for (col = 0; col < w; col++) {
if((flags & TJ.FLAG_BOTTOMUP) != 0) if ((flags & TJ.FLAG_BOTTOMUP) != 0)
index = pitch * (h - row - 1) + col; index = pitch * (h - row - 1) + col;
else index = pitch * row + col; else
if(((row / 8) + (col / 8)) % 2 == 0) { index = pitch * row + col;
if(row < halfway) { if (((row / 8) + (col / 8)) % 2 == 0) {
if (row < halfway) {
buf[index] |= (255 << rshift); buf[index] |= (255 << rshift);
buf[index] |= (255 << gshift); buf[index] |= (255 << gshift);
buf[index] |= (255 << bshift); buf[index] |= (255 << bshift);
} }
} } else {
else {
buf[index] |= (255 << rshift); buf[index] |= (255 << rshift);
if(row >= halfway) buf[index] |= (255 << gshift); if (row >= halfway)
buf[index] |= (255 << gshift);
} }
if (ashift >= 0) buf[index] |= (255 << ashift); if (ashift >= 0)
buf[index] |= (255 << ashift);
} }
} }
} }
@@ -232,18 +237,17 @@ public class TJUnitTest {
throws Exception { throws Exception {
WritableRaster wr = img.getRaster(); WritableRaster wr = img.getRaster();
int imgType = img.getType(); int imgType = img.getType();
if(imgType == BufferedImage.TYPE_INT_RGB if (imgType == BufferedImage.TYPE_INT_RGB ||
|| imgType == BufferedImage.TYPE_INT_BGR imgType == BufferedImage.TYPE_INT_BGR ||
|| imgType == BufferedImage.TYPE_INT_ARGB imgType == BufferedImage.TYPE_INT_ARGB ||
|| imgType == BufferedImage.TYPE_INT_ARGB_PRE) { imgType == BufferedImage.TYPE_INT_ARGB_PRE) {
SinglePixelPackedSampleModel sm = SinglePixelPackedSampleModel sm =
(SinglePixelPackedSampleModel)img.getSampleModel(); (SinglePixelPackedSampleModel)img.getSampleModel();
int pitch = sm.getScanlineStride(); int pitch = sm.getScanlineStride();
DataBufferInt db = (DataBufferInt)wr.getDataBuffer(); DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
int[] buf = db.getData(); int[] buf = db.getData();
initIntBuf(buf, img.getWidth(), pitch, img.getHeight(), pf, flags); initIntBuf(buf, img.getWidth(), pitch, img.getHeight(), pf, flags);
} } else {
else {
ComponentSampleModel sm = (ComponentSampleModel)img.getSampleModel(); ComponentSampleModel sm = (ComponentSampleModel)img.getSampleModel();
int pitch = sm.getScanlineStride(); int pitch = sm.getScanlineStride();
DataBufferByte db = (DataBufferByte)wr.getDataBuffer(); DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
@@ -255,32 +259,33 @@ public class TJUnitTest {
private static void checkVal(int row, int col, int v, String vname, int cv) private static void checkVal(int row, int col, int v, String vname, int cv)
throws Exception { throws Exception {
v = (v < 0) ? v + 256 : v; v = (v < 0) ? v + 256 : v;
if(v < cv - 1 || v > cv + 1) { if (v < cv - 1 || v > cv + 1) {
throw new Exception("\nComp. " + vname + " at " + row + "," + col throw new Exception("\nComp. " + vname + " at " + row + "," + col +
+ " should be " + cv + ", not " + v + "\n"); " should be " + cv + ", not " + v + "\n");
} }
} }
private static void checkVal0(int row, int col, int v, String vname) private static void checkVal0(int row, int col, int v, String vname)
throws Exception { throws Exception {
v = (v < 0) ? v + 256 : v; v = (v < 0) ? v + 256 : v;
if(v > 1) { if (v > 1) {
throw new Exception("\nComp. " + vname + " at " + row + "," + col throw new Exception("\nComp. " + vname + " at " + row + "," + col +
+ " should be 0, not " + v + "\n"); " should be 0, not " + v + "\n");
} }
} }
private static void checkVal255(int row, int col, int v, String vname) private static void checkVal255(int row, int col, int v, String vname)
throws Exception { throws Exception {
v = (v < 0) ? v + 256 : v; v = (v < 0) ? v + 256 : v;
if(v < 254) { if (v < 254) {
throw new Exception("\nComp. " + vname + " at " + row + "," + col throw new Exception("\nComp. " + vname + " at " + row + "," + col +
+ " should be 255, not " + v + "\n"); " should be 255, not " + v + "\n");
} }
} }
private static int checkBuf(byte[] buf, int w, int pitch, int h, int pf, private static int checkBuf(byte[] buf, int w, int pitch, int h, int pf,
int subsamp, TJScalingFactor sf, int flags) throws Exception { int subsamp, TJScalingFactor sf, int flags)
throws Exception {
int roffset = TJ.getRedOffset(pf); int roffset = TJ.getRedOffset(pf);
int goffset = TJ.getGreenOffset(pf); int goffset = TJ.getGreenOffset(pf);
int boffset = TJ.getBlueOffset(pf); int boffset = TJ.getBlueOffset(pf);
@@ -291,46 +296,42 @@ public class TJUnitTest {
int blockSize = 8 * sf.getNum() / sf.getDenom(); int blockSize = 8 * sf.getNum() / sf.getDenom();
try { try {
for(row = 0; row < halfway; row++) { for (row = 0; row < halfway; row++) {
for(col = 0; col < w; col++) { for (col = 0; col < w; col++) {
if((flags & TJ.FLAG_BOTTOMUP) != 0) if ((flags & TJ.FLAG_BOTTOMUP) != 0)
index = pitch * (h - row - 1) + col * ps; index = pitch * (h - row - 1) + col * ps;
else index = pitch * row + col * ps; else
index = pitch * row + col * ps;
byte r = buf[index + roffset]; byte r = buf[index + roffset];
byte g = buf[index + goffset]; byte g = buf[index + goffset];
byte b = buf[index + boffset]; byte b = buf[index + boffset];
byte a = aoffset >= 0 ? buf[index + aoffset] : (byte)255; byte a = aoffset >= 0 ? buf[index + aoffset] : (byte)255;
if(((row / blockSize) + (col / blockSize)) % 2 == 0) { if (((row / blockSize) + (col / blockSize)) % 2 == 0) {
if(row < halfway) { if (row < halfway) {
checkVal255(row, col, r, "R"); checkVal255(row, col, r, "R");
checkVal255(row, col, g, "G"); checkVal255(row, col, g, "G");
checkVal255(row, col, b, "B"); checkVal255(row, col, b, "B");
} } else {
else {
checkVal0(row, col, r, "R"); checkVal0(row, col, r, "R");
checkVal0(row, col, g, "G"); checkVal0(row, col, g, "G");
checkVal0(row, col, b, "B"); checkVal0(row, col, b, "B");
} }
} } else {
else { if (subsamp == TJ.SAMP_GRAY) {
if(subsamp == TJ.SAMP_GRAY) { if (row < halfway) {
if(row < halfway) {
checkVal(row, col, r, "R", 76); checkVal(row, col, r, "R", 76);
checkVal(row, col, g, "G", 76); checkVal(row, col, g, "G", 76);
checkVal(row, col, b, "B", 76); checkVal(row, col, b, "B", 76);
} } else {
else {
checkVal(row, col, r, "R", 226); checkVal(row, col, r, "R", 226);
checkVal(row, col, g, "G", 226); checkVal(row, col, g, "G", 226);
checkVal(row, col, b, "B", 226); checkVal(row, col, b, "B", 226);
} }
} } else {
else {
checkVal255(row, col, r, "R"); checkVal255(row, col, r, "R");
if(row < halfway) { if (row < halfway) {
checkVal0(row, col, g, "G"); checkVal0(row, col, g, "G");
} } else {
else {
checkVal255(row, col, g, "G"); checkVal255(row, col, g, "G");
} }
checkVal0(row, col, b, "B"); checkVal0(row, col, b, "B");
@@ -339,20 +340,21 @@ public class TJUnitTest {
checkVal255(row, col, a, "A"); checkVal255(row, col, a, "A");
} }
} }
} } catch(Exception e) {
catch(Exception e) {
System.out.println(e); System.out.println(e);
retval = 0; retval = 0;
} }
if(retval == 0) { if (retval == 0) {
System.out.print("\n"); System.out.print("\n");
for(row = 0; row < h; row++) { for (row = 0; row < h; row++) {
for(col = 0; col < w; col++) { for (col = 0; col < w; col++) {
int r = buf[pitch * row + col * ps + roffset]; int r = buf[pitch * row + col * ps + roffset];
int g = buf[pitch * row + col * ps + goffset]; int g = buf[pitch * row + col * ps + goffset];
int b = buf[pitch * row + col * ps + boffset]; int b = buf[pitch * row + col * ps + boffset];
if(r < 0) r += 256; if(g < 0) g += 256; if(b < 0) b += 256; 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.format("%3d/%3d/%3d ", r, g, b);
} }
System.out.print("\n"); System.out.print("\n");
@@ -362,7 +364,8 @@ public class TJUnitTest {
} }
private static int checkIntBuf(int[] buf, int w, int pitch, int h, int pf, private static int checkIntBuf(int[] buf, int w, int pitch, int h, int pf,
int subsamp, TJScalingFactor sf, int flags) throws Exception { int subsamp, TJScalingFactor sf, int flags)
throws Exception {
int rshift = TJ.getRedOffset(pf) * 8; int rshift = TJ.getRedOffset(pf) * 8;
int gshift = TJ.getGreenOffset(pf) * 8; int gshift = TJ.getGreenOffset(pf) * 8;
int bshift = TJ.getBlueOffset(pf) * 8; int bshift = TJ.getBlueOffset(pf) * 8;
@@ -372,46 +375,42 @@ public class TJUnitTest {
int blockSize = 8 * sf.getNum() / sf.getDenom(); int blockSize = 8 * sf.getNum() / sf.getDenom();
try { try {
for(row = 0; row < halfway; row++) { for (row = 0; row < halfway; row++) {
for(col = 0; col < w; col++) { for (col = 0; col < w; col++) {
if((flags & TJ.FLAG_BOTTOMUP) != 0) if ((flags & TJ.FLAG_BOTTOMUP) != 0)
index = pitch * (h - row - 1) + col; index = pitch * (h - row - 1) + col;
else index = pitch * row + col; else
index = pitch * row + col;
int r = (buf[index] >> rshift) & 0xFF; int r = (buf[index] >> rshift) & 0xFF;
int g = (buf[index] >> gshift) & 0xFF; int g = (buf[index] >> gshift) & 0xFF;
int b = (buf[index] >> bshift) & 0xFF; int b = (buf[index] >> bshift) & 0xFF;
int a = ashift >= 0 ? (buf[index] >> ashift) & 0xFF : 255; int a = ashift >= 0 ? (buf[index] >> ashift) & 0xFF : 255;
if(((row / blockSize) + (col / blockSize)) % 2 == 0) { if (((row / blockSize) + (col / blockSize)) % 2 == 0) {
if(row < halfway) { if (row < halfway) {
checkVal255(row, col, r, "R"); checkVal255(row, col, r, "R");
checkVal255(row, col, g, "G"); checkVal255(row, col, g, "G");
checkVal255(row, col, b, "B"); checkVal255(row, col, b, "B");
} } else {
else {
checkVal0(row, col, r, "R"); checkVal0(row, col, r, "R");
checkVal0(row, col, g, "G"); checkVal0(row, col, g, "G");
checkVal0(row, col, b, "B"); checkVal0(row, col, b, "B");
} }
} } else {
else { if (subsamp == TJ.SAMP_GRAY) {
if(subsamp == TJ.SAMP_GRAY) { if (row < halfway) {
if(row < halfway) {
checkVal(row, col, r, "R", 76); checkVal(row, col, r, "R", 76);
checkVal(row, col, g, "G", 76); checkVal(row, col, g, "G", 76);
checkVal(row, col, b, "B", 76); checkVal(row, col, b, "B", 76);
} } else {
else {
checkVal(row, col, r, "R", 226); checkVal(row, col, r, "R", 226);
checkVal(row, col, g, "G", 226); checkVal(row, col, g, "G", 226);
checkVal(row, col, b, "B", 226); checkVal(row, col, b, "B", 226);
} }
} } else {
else {
checkVal255(row, col, r, "R"); checkVal255(row, col, r, "R");
if(row < halfway) { if (row < halfway) {
checkVal0(row, col, g, "G"); checkVal0(row, col, g, "G");
} } else {
else {
checkVal255(row, col, g, "G"); checkVal255(row, col, g, "G");
} }
checkVal0(row, col, b, "B"); checkVal0(row, col, b, "B");
@@ -420,20 +419,21 @@ public class TJUnitTest {
checkVal255(row, col, a, "A"); checkVal255(row, col, a, "A");
} }
} }
} } catch(Exception e) {
catch(Exception e) {
System.out.println(e); System.out.println(e);
retval = 0; retval = 0;
} }
if(retval == 0) { if (retval == 0) {
System.out.print("\n"); System.out.print("\n");
for(row = 0; row < h; row++) { for (row = 0; row < h; row++) {
for(col = 0; col < w; col++) { for (col = 0; col < w; col++) {
int r = (buf[pitch * row + col] >> rshift) & 0xFF; int r = (buf[pitch * row + col] >> rshift) & 0xFF;
int g = (buf[pitch * row + col] >> gshift) & 0xFF; int g = (buf[pitch * row + col] >> gshift) & 0xFF;
int b = (buf[pitch * row + col] >> bshift) & 0xFF; int b = (buf[pitch * row + col] >> bshift) & 0xFF;
if(r < 0) r += 256; if(g < 0) g += 256; if(b < 0) b += 256; 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.format("%3d/%3d/%3d ", r, g, b);
} }
System.out.print("\n"); System.out.print("\n");
@@ -442,14 +442,14 @@ public class TJUnitTest {
return retval; return retval;
} }
private static int checkImg(BufferedImage img, int pf, private static int checkImg(BufferedImage img, int pf, int subsamp,
int subsamp, TJScalingFactor sf, int flags) throws Exception { TJScalingFactor sf, int flags) throws Exception {
WritableRaster wr = img.getRaster(); WritableRaster wr = img.getRaster();
int imgType = img.getType(); int imgType = img.getType();
if(imgType == BufferedImage.TYPE_INT_RGB if (imgType == BufferedImage.TYPE_INT_RGB ||
|| imgType == BufferedImage.TYPE_INT_BGR imgType == BufferedImage.TYPE_INT_BGR ||
|| imgType == BufferedImage.TYPE_INT_ARGB imgType == BufferedImage.TYPE_INT_ARGB ||
|| imgType == BufferedImage.TYPE_INT_ARGB_PRE) { imgType == BufferedImage.TYPE_INT_ARGB_PRE) {
SinglePixelPackedSampleModel sm = SinglePixelPackedSampleModel sm =
(SinglePixelPackedSampleModel)img.getSampleModel(); (SinglePixelPackedSampleModel)img.getSampleModel();
int pitch = sm.getScanlineStride(); int pitch = sm.getScanlineStride();
@@ -457,8 +457,7 @@ public class TJUnitTest {
int[] buf = db.getData(); int[] buf = db.getData();
return checkIntBuf(buf, img.getWidth(), pitch, img.getHeight(), pf, return checkIntBuf(buf, img.getWidth(), pitch, img.getHeight(), pf,
subsamp, sf, flags); subsamp, sf, flags);
} } else {
else {
ComponentSampleModel sm = (ComponentSampleModel)img.getSampleModel(); ComponentSampleModel sm = (ComponentSampleModel)img.getSampleModel();
int pitch = sm.getScanlineStride(); int pitch = sm.getScanlineStride();
DataBufferByte db = (DataBufferByte)wr.getDataBuffer(); DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
@@ -475,49 +474,50 @@ public class TJUnitTest {
private static int checkBufYUV(byte[] buf, int size, int w, int h, private static int checkBufYUV(byte[] buf, int size, int w, int h,
int subsamp) throws Exception { int subsamp) throws Exception {
int row, col; int row, col;
int hsf = TJ.getMCUWidth(subsamp)/8, vsf = TJ.getMCUHeight(subsamp)/8; int hsf = TJ.getMCUWidth(subsamp) / 8, vsf = TJ.getMCUHeight(subsamp) / 8;
int pw = PAD(w, hsf), ph = PAD(h, vsf); int pw = PAD(w, hsf), ph = PAD(h, vsf);
int cw = pw / hsf, ch = ph / vsf; int cw = pw / hsf, ch = ph / vsf;
int ypitch = PAD(pw, 4), uvpitch = PAD(cw, 4); int ypitch = PAD(pw, 4), uvpitch = PAD(cw, 4);
int retval = 1; int retval = 1;
int correctsize = ypitch * ph int correctsize = ypitch * ph +
+ (subsamp == TJ.SAMP_GRAY ? 0 : uvpitch * ch * 2); (subsamp == TJ.SAMP_GRAY ? 0 : uvpitch * ch * 2);
int halfway = 16; int halfway = 16;
try { try {
if(size != correctsize) if (size != correctsize)
throw new Exception("\nIncorrect size " + size + ". Should be " throw new Exception("\nIncorrect size " + size + ". Should be " +
+ correctsize); correctsize);
for(row = 0; row < ph; row++) { for (row = 0; row < ph; row++) {
for(col = 0; col < pw; col++) { for (col = 0; col < pw; col++) {
byte y = buf[ypitch * row + col]; byte y = buf[ypitch * row + col];
if(((row / 8) + (col / 8)) % 2 == 0) { if (((row / 8) + (col / 8)) % 2 == 0) {
if(row < halfway) checkVal255(row, col, y, "Y"); if (row < halfway)
else checkVal0(row, col, y, "Y"); checkVal255(row, col, y, "Y");
} else
else { checkVal0(row, col, y, "Y");
if(row < halfway) checkVal(row, col, y, "Y", 76); } else {
else checkVal(row, col, y, "Y", 226); if (row < halfway)
checkVal(row, col, y, "Y", 76);
else
checkVal(row, col, y, "Y", 226);
} }
} }
} }
if(subsamp != TJ.SAMP_GRAY) { if (subsamp != TJ.SAMP_GRAY) {
halfway = 16 / vsf; halfway = 16 / vsf;
for(row = 0; row < ch; row++) { for (row = 0; row < ch; row++) {
for(col = 0; col < cw; col++) { for (col = 0; col < cw; col++) {
byte u = buf[ypitch * ph + (uvpitch * row + col)], byte u = buf[ypitch * ph + (uvpitch * row + col)],
v = buf[ypitch * ph + uvpitch * ch + (uvpitch * row + col)]; v = buf[ypitch * ph + uvpitch * ch + (uvpitch * row + col)];
if(((row * vsf / 8) + (col * hsf / 8)) % 2 == 0) { if (((row * vsf / 8) + (col * hsf / 8)) % 2 == 0) {
checkVal(row, col, u, "U", 128); checkVal(row, col, u, "U", 128);
checkVal(row, col, v, "V", 128); checkVal(row, col, v, "V", 128);
} } else {
else { if (row < halfway) {
if(row < halfway) {
checkVal(row, col, u, "U", 85); checkVal(row, col, u, "U", 85);
checkVal255(row, col, v, "V"); checkVal255(row, col, v, "V");
} } else {
else {
checkVal0(row, col, u, "U"); checkVal0(row, col, u, "U");
checkVal(row, col, v, "V", 149); checkVal(row, col, v, "V", 149);
} }
@@ -525,35 +525,34 @@ public class TJUnitTest {
} }
} }
} }
} } catch(Exception e) {
catch(Exception e) {
System.out.println(e); System.out.println(e);
retval = 0; retval = 0;
} }
if(retval == 0) { if (retval == 0) {
for(row = 0; row < ph; row++) { for (row = 0; row < ph; row++) {
for(col = 0; col < pw; col++) { for (col = 0; col < pw; col++) {
int y = buf[ypitch * row + col]; int y = buf[ypitch * row + col];
if(y < 0) y += 256; if (y < 0) y += 256;
System.out.format("%3d ", y); System.out.format("%3d ", y);
} }
System.out.print("\n"); System.out.print("\n");
} }
System.out.print("\n"); System.out.print("\n");
for(row = 0; row < ch; row++) { for (row = 0; row < ch; row++) {
for(col = 0; col < cw; col++) { for (col = 0; col < cw; col++) {
int u = buf[ypitch * ph + (uvpitch * row + col)]; int u = buf[ypitch * ph + (uvpitch * row + col)];
if(u < 0) u += 256; if (u < 0) u += 256;
System.out.format("%3d ", u); System.out.format("%3d ", u);
} }
System.out.print("\n"); System.out.print("\n");
} }
System.out.print("\n"); System.out.print("\n");
for(row = 0; row < ch; row++) { for (row = 0; row < ch; row++) {
for(col = 0; col < cw; col++) { for (col = 0; col < cw; col++) {
int v = buf[ypitch * ph + uvpitch * ch + (uvpitch * row + col)]; int v = buf[ypitch * ph + uvpitch * ch + (uvpitch * row + col)];
if(v < 0) v += 256; if (v < 0) v += 256;
System.out.format("%3d ", v); System.out.format("%3d ", v);
} }
System.out.print("\n"); System.out.print("\n");
@@ -573,8 +572,8 @@ public class TJUnitTest {
} }
private static int compTest(TJCompressor tjc, byte[] dstBuf, int w, private static int compTest(TJCompressor tjc, byte[] dstBuf, int w,
int h, int pf, String baseName, int subsamp, int jpegQual, int h, int pf, String baseName, int subsamp,
int flags) throws Exception { int jpegQual, int flags) throws Exception {
String tempstr; String tempstr;
byte[] srcBuf = null; byte[] srcBuf = null;
BufferedImage img = null; BufferedImage img = null;
@@ -585,28 +584,32 @@ public class TJUnitTest {
if (bi) { if (bi) {
pf = biTypePF(imgType); pf = biTypePF(imgType);
pfStr = biTypeStr(imgType); pfStr = biTypeStr(imgType);
} } else
else pfStr = pixFormatStr[pf]; pfStr = pixFormatStr[pf];
ps = TJ.getPixelSize(pf); ps = TJ.getPixelSize(pf);
System.out.print(pfStr + " "); System.out.print(pfStr + " ");
if(bi) System.out.print("(" + pixFormatStr[pf] + ") "); if (bi)
if((flags & TJ.FLAG_BOTTOMUP) != 0) System.out.print("Bottom-Up"); System.out.print("(" + pixFormatStr[pf] + ") ");
else System.out.print("Top-Down "); if ((flags & TJ.FLAG_BOTTOMUP) != 0)
System.out.print("Bottom-Up");
else
System.out.print("Top-Down ");
System.out.print(" -> " + subNameLong[subsamp] + " "); System.out.print(" -> " + subNameLong[subsamp] + " ");
if(yuv == YUVENCODE) System.out.print("YUV ... "); if (yuv == YUVENCODE)
else System.out.print("Q" + jpegQual + " ... "); System.out.print("YUV ... ");
else
System.out.print("Q" + jpegQual + " ... ");
if(bi) { if (bi) {
img = new BufferedImage(w, h, imgType); img = new BufferedImage(w, h, imgType);
initImg(img, pf, flags); initImg(img, pf, flags);
tempstr = baseName + "_enc_" + pfStr + "_" tempstr = baseName + "_enc_" + pfStr + "_" +
+ (((flags & TJ.FLAG_BOTTOMUP) != 0) ? "BU" : "TD") + "_" (((flags & TJ.FLAG_BOTTOMUP) != 0) ? "BU" : "TD") + "_" +
+ subName[subsamp] + "_Q" + jpegQual + ".png"; subName[subsamp] + "_Q" + jpegQual + ".png";
File file = new File(tempstr); File file = new File(tempstr);
ImageIO.write(img, "png", file); ImageIO.write(img, "png", file);
} } else {
else {
srcBuf = new byte[w * h * ps + 1]; srcBuf = new byte[w * h * ps + 1];
initBuf(srcBuf, w, w * ps, h, pf, flags); initBuf(srcBuf, w, w * ps, h, pf, flags);
} }
@@ -615,36 +618,40 @@ public class TJUnitTest {
t = getTime(); t = getTime();
tjc.setSubsamp(subsamp); tjc.setSubsamp(subsamp);
tjc.setJPEGQuality(jpegQual); tjc.setJPEGQuality(jpegQual);
if(bi) { if (bi) {
if(yuv == YUVENCODE) tjc.encodeYUV(img, dstBuf, flags); if (yuv == YUVENCODE)
else tjc.compress(img, dstBuf, flags); tjc.encodeYUV(img, dstBuf, flags);
} else
else { tjc.compress(img, dstBuf, flags);
} else {
tjc.setSourceImage(srcBuf, w, 0, h, pf); tjc.setSourceImage(srcBuf, w, 0, h, pf);
if(yuv == YUVENCODE) tjc.encodeYUV(dstBuf, flags); if (yuv == YUVENCODE)
else tjc.compress(dstBuf, flags); tjc.encodeYUV(dstBuf, flags);
else
tjc.compress(dstBuf, flags);
} }
size = tjc.getCompressedSize(); size = tjc.getCompressedSize();
t = getTime() - t; t = getTime() - t;
if(yuv == YUVENCODE) if (yuv == YUVENCODE)
tempstr = baseName + "_enc_" + pfStr + "_" tempstr = baseName + "_enc_" + pfStr + "_" +
+ (((flags & TJ.FLAG_BOTTOMUP) != 0) ? "BU" : "TD") + "_" (((flags & TJ.FLAG_BOTTOMUP) != 0) ? "BU" : "TD") + "_" +
+ subName[subsamp] + ".yuv"; subName[subsamp] + ".yuv";
else else
tempstr = baseName + "_enc_" + pfStr + "_" tempstr = baseName + "_enc_" + pfStr + "_" +
+ (((flags & TJ.FLAG_BOTTOMUP) != 0) ? "BU" : "TD") + "_" (((flags & TJ.FLAG_BOTTOMUP) != 0) ? "BU" : "TD") + "_" +
+ subName[subsamp] + "_Q" + jpegQual + ".jpg"; subName[subsamp] + "_Q" + jpegQual + ".jpg";
writeJPEG(dstBuf, size, tempstr); writeJPEG(dstBuf, size, tempstr);
if(yuv == YUVENCODE) { if (yuv == YUVENCODE) {
if(checkBufYUV(dstBuf, size, w, h, subsamp) == 1) if (checkBufYUV(dstBuf, size, w, h, subsamp) == 1)
System.out.print("Passed."); System.out.print("Passed.");
else { else {
System.out.print("FAILED!"); exitStatus = -1; System.out.print("FAILED!");
exitStatus = -1;
} }
} } else
else System.out.print("Done."); System.out.print("Done.");
System.out.format(" %.6f ms\n", t * 1000.); System.out.format(" %.6f ms\n", t * 1000.);
System.out.println(" Result in " + tempstr); System.out.println(" Result in " + tempstr);
@@ -652,8 +659,9 @@ public class TJUnitTest {
} }
private static void decompTest(TJDecompressor tjd, byte[] jpegBuf, private static void decompTest(TJDecompressor tjd, byte[] jpegBuf,
int jpegSize, int w, int h, int pf, String baseName, int subsamp, int jpegSize, int w, int h, int pf,
int flags, TJScalingFactor sf) throws Exception { String baseName, int subsamp, int flags,
TJScalingFactor sf) throws Exception {
String pfStr, tempstr; String pfStr, tempstr;
double t; double t;
int scaledWidth = sf.getScaled(w); int scaledWidth = sf.getScaled(w);
@@ -662,87 +670,94 @@ public class TJUnitTest {
BufferedImage img = null; BufferedImage img = null;
byte[] dstBuf = null; byte[] dstBuf = null;
if(yuv == YUVENCODE) return; if (yuv == YUVENCODE) return;
if (bi) { if (bi) {
pf = biTypePF(imgType); pf = biTypePF(imgType);
pfStr = biTypeStr(imgType); pfStr = biTypeStr(imgType);
} } else
else pfStr = pixFormatStr[pf]; pfStr = pixFormatStr[pf];
System.out.print("JPEG -> "); System.out.print("JPEG -> ");
if(yuv == YUVDECODE) if (yuv == YUVDECODE)
System.out.print("YUV " + subName[subsamp] + " ... "); System.out.print("YUV " + subName[subsamp] + " ... ");
else { else {
System.out.print(pfStr + " "); System.out.print(pfStr + " ");
if(bi) System.out.print("(" + pixFormatStr[pf] + ") "); if (bi)
if((flags & TJ.FLAG_BOTTOMUP) != 0) System.out.print("Bottom-Up "); System.out.print("(" + pixFormatStr[pf] + ") ");
else System.out.print("Top-Down "); if ((flags & TJ.FLAG_BOTTOMUP) != 0)
if(!sf.isOne()) System.out.print("Bottom-Up ");
else
System.out.print("Top-Down ");
if (!sf.isOne())
System.out.print(sf.getNum() + "/" + sf.getDenom() + " ... "); System.out.print(sf.getNum() + "/" + sf.getDenom() + " ... ");
else System.out.print("... "); else
System.out.print("... ");
} }
t = getTime(); t = getTime();
tjd.setJPEGImage(jpegBuf, jpegSize); tjd.setJPEGImage(jpegBuf, jpegSize);
if(tjd.getWidth() != w || tjd.getHeight() != h if (tjd.getWidth() != w || tjd.getHeight() != h ||
|| tjd.getSubsamp() != subsamp) tjd.getSubsamp() != subsamp)
throw new Exception("Incorrect JPEG header"); throw new Exception("Incorrect JPEG header");
temp1 = scaledWidth; temp1 = scaledWidth;
temp2 = scaledHeight; temp2 = scaledHeight;
temp1 = tjd.getScaledWidth(temp1, temp2); temp1 = tjd.getScaledWidth(temp1, temp2);
temp2 = tjd.getScaledHeight(temp1, temp2); temp2 = tjd.getScaledHeight(temp1, temp2);
if(temp1 != scaledWidth || temp2 != scaledHeight) if (temp1 != scaledWidth || temp2 != scaledHeight)
throw new Exception("Scaled size mismatch"); throw new Exception("Scaled size mismatch");
if(yuv == YUVDECODE) dstBuf = tjd.decompressToYUV(flags); if (yuv == YUVDECODE)
dstBuf = tjd.decompressToYUV(flags);
else { else {
if(bi) if (bi)
img = tjd.decompress(scaledWidth, scaledHeight, imgType, flags); img = tjd.decompress(scaledWidth, scaledHeight, imgType, flags);
else dstBuf = tjd.decompress(scaledWidth, 0, scaledHeight, pf, flags); else
dstBuf = tjd.decompress(scaledWidth, 0, scaledHeight, pf, flags);
} }
t = getTime() - t; t = getTime() - t;
if(bi) { if (bi) {
tempstr = baseName + "_dec_" + pfStr + "_" tempstr = baseName + "_dec_" + pfStr + "_" +
+ (((flags & TJ.FLAG_BOTTOMUP) != 0) ? "BU" : "TD") + "_" (((flags & TJ.FLAG_BOTTOMUP) != 0) ? "BU" : "TD") + "_" +
+ subName[subsamp] + "_" + (double)sf.getNum() / (double)sf.getDenom() subName[subsamp] + "_" +
+ "x" + ".png"; (double)sf.getNum() / (double)sf.getDenom() + "x" + ".png";
File file = new File(tempstr); File file = new File(tempstr);
ImageIO.write(img, "png", file); ImageIO.write(img, "png", file);
} }
if(yuv == YUVDECODE) { if (yuv == YUVDECODE) {
if(checkBufYUV(dstBuf, dstBuf.length, w, h, subsamp) == 1) if (checkBufYUV(dstBuf, dstBuf.length, w, h, subsamp) == 1)
System.out.print("Passed."); System.out.print("Passed.");
else { else {
System.out.print("FAILED!"); exitStatus = -1; System.out.print("FAILED!"); exitStatus = -1;
} }
} } else {
else { if ((bi && checkImg(img, pf, subsamp, sf, flags) == 1) ||
if((bi && checkImg(img, pf, subsamp, sf, flags) == 1) (!bi && checkBuf(dstBuf, scaledWidth,
|| (!bi && checkBuf(dstBuf, scaledWidth, scaledWidth scaledWidth * TJ.getPixelSize(pf), scaledHeight, pf,
* TJ.getPixelSize(pf), scaledHeight, pf, subsamp, sf, flags) == 1)) subsamp, sf, flags) == 1))
System.out.print("Passed."); System.out.print("Passed.");
else { else {
System.out.print("FAILED!"); exitStatus = -1; System.out.print("FAILED!");
exitStatus = -1;
} }
} }
System.out.format(" %.6f ms\n", t * 1000.); System.out.format(" %.6f ms\n", t * 1000.);
} }
private static void decompTest(TJDecompressor tjd, byte[] jpegBuf, private static void decompTest(TJDecompressor tjd, byte[] jpegBuf,
int jpegSize, int w, int h, int pf, String baseName, int subsamp, int jpegSize, int w, int h, int pf,
String baseName, int subsamp,
int flags) throws Exception { int flags) throws Exception {
int i; int i;
if((subsamp == TJ.SAMP_444 || subsamp == TJ.SAMP_GRAY) && yuv == 0) { if ((subsamp == TJ.SAMP_444 || subsamp == TJ.SAMP_GRAY) && yuv == 0) {
TJScalingFactor sf[] = TJ.getScalingFactors(); TJScalingFactor[] sf = TJ.getScalingFactors();
for(i = 0; i < sf.length; i++) for (i = 0; i < sf.length; i++)
decompTest(tjd, jpegBuf, jpegSize, w, h, pf, baseName, subsamp, decompTest(tjd, jpegBuf, jpegSize, w, h, pf, baseName, subsamp,
flags, sf[i]); flags, sf[i]);
} } else
else
decompTest(tjd, jpegBuf, jpegSize, w, h, pf, baseName, subsamp, decompTest(tjd, jpegBuf, jpegSize, w, h, pf, baseName, subsamp,
flags, new TJScalingFactor(1, 1)); flags, new TJScalingFactor(1, 1));
System.out.print("\n"); System.out.print("\n");
@@ -755,41 +770,44 @@ public class TJUnitTest {
int size; int size;
byte[] dstBuf; byte[] dstBuf;
if(yuv == YUVENCODE) dstBuf = new byte[TJ.bufSizeYUV(w, h, subsamp)]; if (yuv == YUVENCODE)
else dstBuf = new byte[TJ.bufSize(w, h, subsamp)]; dstBuf = new byte[TJ.bufSizeYUV(w, h, subsamp)];
else
dstBuf = new byte[TJ.bufSize(w, h, subsamp)];
try { try {
tjc = new TJCompressor(); tjc = new TJCompressor();
tjd = new TJDecompressor(); tjd = new TJDecompressor();
for(int pf : formats) { for (int pf : formats) {
for(int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
int flags = 0; int flags = 0;
if (subsamp == TJ.SAMP_422 || subsamp == TJ.SAMP_420 if (subsamp == TJ.SAMP_422 || subsamp == TJ.SAMP_420 ||
|| subsamp == TJ.SAMP_440) subsamp == TJ.SAMP_440)
flags |= TJ.FLAG_FASTUPSAMPLE; flags |= TJ.FLAG_FASTUPSAMPLE;
if(i == 1) { if (i == 1) {
if(yuv == YUVDECODE) { if (yuv == YUVDECODE) {
tjc.close(); tjd.close(); return; tjc.close();
} tjd.close();
else flags |= TJ.FLAG_BOTTOMUP; return;
} else
flags |= TJ.FLAG_BOTTOMUP;
} }
size = compTest(tjc, dstBuf, w, h, pf, baseName, subsamp, 100, size = compTest(tjc, dstBuf, w, h, pf, baseName, subsamp, 100,
flags); flags);
decompTest(tjd, dstBuf, size, w, h, pf, baseName, subsamp, flags); decompTest(tjd, dstBuf, size, w, h, pf, baseName, subsamp, flags);
if(pf >= TJ.PF_RGBX && pf <= TJ.PF_XRGB && !bi) if (pf >= TJ.PF_RGBX && pf <= TJ.PF_XRGB && !bi)
decompTest(tjd, dstBuf, size, w, h, pf + (TJ.PF_RGBA - TJ.PF_RGBX), decompTest(tjd, dstBuf, size, w, h, pf + (TJ.PF_RGBA - TJ.PF_RGBX),
baseName, subsamp, flags); baseName, subsamp, flags);
} }
} }
} } catch(Exception e) {
catch(Exception e) { if (tjc != null) tjc.close();
if(tjc != null) tjc.close(); if (tjd != null) tjd.close();
if(tjd != null) tjd.close();
throw e; throw e;
} }
if(tjc != null) tjc.close(); if (tjc != null) tjc.close();
if(tjd != null) tjd.close(); if (tjd != null) tjd.close();
} }
private static void bufSizeTest() throws Exception { private static void bufSizeTest() throws Exception {
@@ -801,15 +819,15 @@ public class TJUnitTest {
try { try {
tjc = new TJCompressor(); tjc = new TJCompressor();
System.out.println("Buffer size regression test"); System.out.println("Buffer size regression test");
for(subsamp = 0; subsamp < TJ.NUMSAMP; subsamp++) { for (subsamp = 0; subsamp < TJ.NUMSAMP; subsamp++) {
for(w = 1; w < 48; w++) { for (w = 1; w < 48; w++) {
int maxh = (w == 1) ? 2048 : 48; int maxh = (w == 1) ? 2048 : 48;
for(h = 1; h < maxh; h++) { for (h = 1; h < maxh; h++) {
if(h % 100 == 0) if (h % 100 == 0)
System.out.format("%04d x %04d\b\b\b\b\b\b\b\b\b\b\b", w, h); System.out.format("%04d x %04d\b\b\b\b\b\b\b\b\b\b\b", w, h);
srcBuf = new byte[w * h * 4]; srcBuf = new byte[w * h * 4];
jpegBuf = new byte[TJ.bufSize(w, h, subsamp)]; jpegBuf = new byte[TJ.bufSize(w, h, subsamp)];
for(i = 0; i < w * h * 4; i++) { for (i = 0; i < w * h * 4; i++) {
srcBuf[i] = (byte)(r.nextInt(2) * 255); srcBuf[i] = (byte)(r.nextInt(2) * 255);
} }
tjc.setSourceImage(srcBuf, w, 0, h, TJ.PF_BGRX); tjc.setSourceImage(srcBuf, w, 0, h, TJ.PF_BGRX);
@@ -819,7 +837,7 @@ public class TJUnitTest {
srcBuf = new byte[h * w * 4]; srcBuf = new byte[h * w * 4];
jpegBuf = new byte[TJ.bufSize(h, w, subsamp)]; jpegBuf = new byte[TJ.bufSize(h, w, subsamp)];
for(i = 0; i < h * w * 4; i++) { for (i = 0; i < h * w * 4; i++) {
srcBuf[i] = (byte)(r.nextInt(2) * 255); srcBuf[i] = (byte)(r.nextInt(2) * 255);
} }
tjc.setSourceImage(srcBuf, h, 0, w, TJ.PF_BGRX); tjc.setSourceImage(srcBuf, h, 0, w, TJ.PF_BGRX);
@@ -828,31 +846,33 @@ public class TJUnitTest {
} }
} }
System.out.println("Done. "); System.out.println("Done. ");
} } catch(Exception e) {
catch(Exception e) { if (tjc != null) tjc.close();
if(tjc != null) tjc.close();
throw e; throw e;
} }
if(tjc != null) tjc.close(); if (tjc != null) tjc.close();
} }
public static void main(String argv[]) { public static void main(String[] argv) {
try { try {
String testName = "javatest"; String testName = "javatest";
boolean doyuv = false; boolean doyuv = false;
for(int i = 0; i < argv.length; i++) { for (int i = 0; i < argv.length; i++) {
if(argv[i].equalsIgnoreCase("-yuv")) doyuv = true; if (argv[i].equalsIgnoreCase("-yuv"))
if(argv[i].substring(0, 1).equalsIgnoreCase("-h") doyuv = true;
|| argv[i].equalsIgnoreCase("-?")) if (argv[i].substring(0, 1).equalsIgnoreCase("-h") ||
argv[i].equalsIgnoreCase("-?"))
usage(); usage();
if(argv[i].equalsIgnoreCase("-bi")) { if (argv[i].equalsIgnoreCase("-bi")) {
bi = true; bi = true;
testName = "javabitest"; testName = "javabitest";
} }
} }
if(doyuv) yuv = YUVENCODE; if (doyuv) yuv = YUVENCODE;
doTest(35, 39, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_444, testName); doTest(35, 39, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_444,
doTest(39, 41, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_444, testName); testName);
doTest(39, 41, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_444,
testName);
doTest(41, 35, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_422, doTest(41, 35, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_422,
testName); testName);
doTest(35, 39, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_422, doTest(35, 39, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_422,
@@ -870,8 +890,9 @@ public class TJUnitTest {
testName); testName);
doTest(41, 35, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_GRAY, doTest(41, 35, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_GRAY,
testName); testName);
if(!doyuv && !bi) bufSizeTest(); if (!doyuv && !bi)
if(doyuv && !bi) { bufSizeTest();
if (doyuv && !bi) {
yuv = YUVDECODE; yuv = YUVDECODE;
doTest(48, 48, onlyRGB, TJ.SAMP_444, "javatest_yuv0"); doTest(48, 48, onlyRGB, TJ.SAMP_444, "javatest_yuv0");
doTest(35, 39, onlyRGB, TJ.SAMP_444, "javatest_yuv1"); doTest(35, 39, onlyRGB, TJ.SAMP_444, "javatest_yuv1");
@@ -886,8 +907,7 @@ public class TJUnitTest {
doTest(48, 48, onlyGray, TJ.SAMP_GRAY, "javatest_yuv0"); doTest(48, 48, onlyGray, TJ.SAMP_GRAY, "javatest_yuv0");
doTest(39, 41, onlyGray, TJ.SAMP_GRAY, "javatest_yuv1"); doTest(39, 41, onlyGray, TJ.SAMP_GRAY, "javatest_yuv1");
} }
} } catch(Exception e) {
catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
exitStatus = -1; exitStatus = -1;
} }

View File

@@ -31,38 +31,38 @@ package org.libjpegturbo.turbojpeg;
/** /**
* TurboJPEG utility class (cannot be instantiated) * TurboJPEG utility class (cannot be instantiated)
*/ */
final public class TJ { public final class TJ {
/** /**
* The number of chrominance subsampling options * The number of chrominance subsampling options
*/ */
final public static int NUMSAMP = 5; public static final int NUMSAMP = 5;
/** /**
* 4:4:4 chrominance subsampling (no chrominance subsampling). The JPEG * 4:4:4 chrominance subsampling (no chrominance subsampling). The JPEG
* or YUV image will contain one chrominance component for every pixel in the * or YUV image will contain one chrominance component for every pixel in the
* source image. * source image.
*/ */
final public static int SAMP_444 = 0; public static final int SAMP_444 = 0;
/** /**
* 4:2:2 chrominance subsampling. The JPEG or YUV image will contain one * 4:2:2 chrominance subsampling. The JPEG or YUV image will contain one
* chrominance component for every 2x1 block of pixels in the source image. * chrominance component for every 2x1 block of pixels in the source image.
*/ */
final public static int SAMP_422 = 1; public static final int SAMP_422 = 1;
/** /**
* 4:2:0 chrominance subsampling. The JPEG or YUV image will contain one * 4:2:0 chrominance subsampling. The JPEG or YUV image will contain one
* chrominance component for every 2x2 block of pixels in the source image. * chrominance component for every 2x2 block of pixels in the source image.
*/ */
final public static int SAMP_420 = 2; public static final int SAMP_420 = 2;
/** /**
* Grayscale. The JPEG or YUV image will contain no chrominance components. * Grayscale. The JPEG or YUV image will contain no chrominance components.
*/ */
final public static int SAMP_GRAY = 3; public static final int SAMP_GRAY = 3;
/** /**
* 4:4:0 chrominance subsampling. The JPEG or YUV image will contain one * 4:4:0 chrominance subsampling. The JPEG or YUV image will contain one
* chrominance component for every 1x2 block of pixels in the source image. * chrominance component for every 1x2 block of pixels in the source image.
*/ */
final public static int SAMP_440 = 4; public static final int SAMP_440 = 4;
/** /**
@@ -75,12 +75,12 @@ final public class TJ {
* @return the MCU block width for the given level of chrominance subsampling * @return the MCU block width for the given level of chrominance subsampling
*/ */
public static int getMCUWidth(int subsamp) throws Exception { public static int getMCUWidth(int subsamp) throws Exception {
if(subsamp < 0 || subsamp >= NUMSAMP) if (subsamp < 0 || subsamp >= NUMSAMP)
throw new Exception("Invalid subsampling type"); throw new Exception("Invalid subsampling type");
return mcuWidth[subsamp]; return mcuWidth[subsamp];
} }
final private static int mcuWidth[] = { private static final int[] mcuWidth = {
8, 16, 16, 8, 8 8, 16, 16, 8, 8
}; };
@@ -96,12 +96,12 @@ final public class TJ {
* subsampling * subsampling
*/ */
public static int getMCUHeight(int subsamp) throws Exception { public static int getMCUHeight(int subsamp) throws Exception {
if(subsamp < 0 || subsamp >= NUMSAMP) if (subsamp < 0 || subsamp >= NUMSAMP)
throw new Exception("Invalid subsampling type"); throw new Exception("Invalid subsampling type");
return mcuHeight[subsamp]; return mcuHeight[subsamp];
} }
final private static int mcuHeight[] = { private static final int[] mcuHeight = {
8, 8, 16, 8, 16 8, 8, 16, 8, 16
}; };
@@ -109,76 +109,76 @@ final public class TJ {
/** /**
* The number of pixel formats * The number of pixel formats
*/ */
final public static int NUMPF = 11; public static final int NUMPF = 11;
/** /**
* RGB pixel format. The red, green, and blue components in the image are * RGB pixel format. The red, green, and blue components in the image are
* stored in 3-byte pixels in the order R, G, B from lowest to highest byte * stored in 3-byte pixels in the order R, G, B from lowest to highest byte
* address within each pixel. * address within each pixel.
*/ */
final public static int PF_RGB = 0; public static final int PF_RGB = 0;
/** /**
* BGR pixel format. The red, green, and blue components in the image are * BGR pixel format. The red, green, and blue components in the image are
* stored in 3-byte pixels in the order B, G, R from lowest to highest byte * stored in 3-byte pixels in the order B, G, R from lowest to highest byte
* address within each pixel. * address within each pixel.
*/ */
final public static int PF_BGR = 1; public static final int PF_BGR = 1;
/** /**
* RGBX pixel format. The red, green, and blue components in the image are * RGBX pixel format. The red, green, and blue components in the image are
* stored in 4-byte pixels in the order R, G, B from lowest to highest byte * stored in 4-byte pixels in the order R, G, B from lowest to highest byte
* address within each pixel. The X component is ignored when compressing * address within each pixel. The X component is ignored when compressing
* and undefined when decompressing. * and undefined when decompressing.
*/ */
final public static int PF_RGBX = 2; public static final int PF_RGBX = 2;
/** /**
* BGRX pixel format. The red, green, and blue components in the image are * BGRX pixel format. The red, green, and blue components in the image are
* stored in 4-byte pixels in the order B, G, R from lowest to highest byte * stored in 4-byte pixels in the order B, G, R from lowest to highest byte
* address within each pixel. The X component is ignored when compressing * address within each pixel. The X component is ignored when compressing
* and undefined when decompressing. * and undefined when decompressing.
*/ */
final public static int PF_BGRX = 3; public static final int PF_BGRX = 3;
/** /**
* XBGR pixel format. The red, green, and blue components in the image are * XBGR pixel format. The red, green, and blue components in the image are
* stored in 4-byte pixels in the order R, G, B from highest to lowest byte * stored in 4-byte pixels in the order R, G, B from highest to lowest byte
* address within each pixel. The X component is ignored when compressing * address within each pixel. The X component is ignored when compressing
* and undefined when decompressing. * and undefined when decompressing.
*/ */
final public static int PF_XBGR = 4; public static final int PF_XBGR = 4;
/** /**
* XRGB pixel format. The red, green, and blue components in the image are * XRGB pixel format. The red, green, and blue components in the image are
* stored in 4-byte pixels in the order B, G, R from highest to lowest byte * stored in 4-byte pixels in the order B, G, R from highest to lowest byte
* address within each pixel. The X component is ignored when compressing * address within each pixel. The X component is ignored when compressing
* and undefined when decompressing. * and undefined when decompressing.
*/ */
final public static int PF_XRGB = 5; public static final int PF_XRGB = 5;
/** /**
* Grayscale pixel format. Each 1-byte pixel represents a luminance * Grayscale pixel format. Each 1-byte pixel represents a luminance
* (brightness) level from 0 to 255. * (brightness) level from 0 to 255.
*/ */
final public static int PF_GRAY = 6; public static final int PF_GRAY = 6;
/** /**
* RGBA pixel format. This is the same as {@link #PF_RGBX}, except that when * RGBA pixel format. This is the same as {@link #PF_RGBX}, except that when
* decompressing, the X byte is guaranteed to be 0xFF, which can be * decompressing, the X byte is guaranteed to be 0xFF, which can be
* interpreted as an opaque alpha channel. * interpreted as an opaque alpha channel.
*/ */
final public static int PF_RGBA = 7; public static final int PF_RGBA = 7;
/** /**
* BGRA pixel format. This is the same as {@link #PF_BGRX}, except that when * BGRA pixel format. This is the same as {@link #PF_BGRX}, except that when
* decompressing, the X byte is guaranteed to be 0xFF, which can be * decompressing, the X byte is guaranteed to be 0xFF, which can be
* interpreted as an opaque alpha channel. * interpreted as an opaque alpha channel.
*/ */
final public static int PF_BGRA = 8; public static final int PF_BGRA = 8;
/** /**
* ABGR pixel format. This is the same as {@link #PF_XBGR}, except that when * ABGR pixel format. This is the same as {@link #PF_XBGR}, except that when
* decompressing, the X byte is guaranteed to be 0xFF, which can be * decompressing, the X byte is guaranteed to be 0xFF, which can be
* interpreted as an opaque alpha channel. * interpreted as an opaque alpha channel.
*/ */
final public static int PF_ABGR = 9; public static final int PF_ABGR = 9;
/** /**
* ARGB pixel format. This is the same as {@link #PF_XRGB}, except that when * ARGB pixel format. This is the same as {@link #PF_XRGB}, except that when
* decompressing, the X byte is guaranteed to be 0xFF, which can be * decompressing, the X byte is guaranteed to be 0xFF, which can be
* interpreted as an opaque alpha channel. * interpreted as an opaque alpha channel.
*/ */
final public static int PF_ARGB = 10; public static final int PF_ARGB = 10;
/** /**
@@ -189,12 +189,12 @@ final public class TJ {
* @return the pixel size (in bytes) for the given pixel format * @return the pixel size (in bytes) for the given pixel format
*/ */
public static int getPixelSize(int pixelFormat) throws Exception { public static int getPixelSize(int pixelFormat) throws Exception {
if(pixelFormat < 0 || pixelFormat >= NUMPF) if (pixelFormat < 0 || pixelFormat >= NUMPF)
throw new Exception("Invalid pixel format"); throw new Exception("Invalid pixel format");
return pixelSize[pixelFormat]; return pixelSize[pixelFormat];
} }
final private static int pixelSize[] = { private static final int[] pixelSize = {
3, 3, 4, 4, 4, 4, 1, 4, 4, 4, 4 3, 3, 4, 4, 4, 4, 1, 4, 4, 4, 4
}; };
@@ -211,12 +211,12 @@ final public class TJ {
* @return the red offset for the given pixel format * @return the red offset for the given pixel format
*/ */
public static int getRedOffset(int pixelFormat) throws Exception { public static int getRedOffset(int pixelFormat) throws Exception {
if(pixelFormat < 0 || pixelFormat >= NUMPF) if (pixelFormat < 0 || pixelFormat >= NUMPF)
throw new Exception("Invalid pixel format"); throw new Exception("Invalid pixel format");
return redOffset[pixelFormat]; return redOffset[pixelFormat];
} }
final private static int redOffset[] = { private static final int[] redOffset = {
0, 2, 0, 2, 3, 1, 0, 0, 2, 3, 1 0, 2, 0, 2, 3, 1, 0, 0, 2, 3, 1
}; };
@@ -233,12 +233,12 @@ final public class TJ {
* @return the green offset for the given pixel format * @return the green offset for the given pixel format
*/ */
public static int getGreenOffset(int pixelFormat) throws Exception { public static int getGreenOffset(int pixelFormat) throws Exception {
if(pixelFormat < 0 || pixelFormat >= NUMPF) if (pixelFormat < 0 || pixelFormat >= NUMPF)
throw new Exception("Invalid pixel format"); throw new Exception("Invalid pixel format");
return greenOffset[pixelFormat]; return greenOffset[pixelFormat];
} }
final private static int greenOffset[] = { private static final int[] greenOffset = {
1, 1, 1, 1, 2, 2, 0, 1, 1, 2, 2 1, 1, 1, 1, 2, 2, 0, 1, 1, 2, 2
}; };
@@ -255,12 +255,12 @@ final public class TJ {
* @return the blue offset for the given pixel format * @return the blue offset for the given pixel format
*/ */
public static int getBlueOffset(int pixelFormat) throws Exception { public static int getBlueOffset(int pixelFormat) throws Exception {
if(pixelFormat < 0 || pixelFormat >= NUMPF) if (pixelFormat < 0 || pixelFormat >= NUMPF)
throw new Exception("Invalid pixel format"); throw new Exception("Invalid pixel format");
return blueOffset[pixelFormat]; return blueOffset[pixelFormat];
} }
final private static int blueOffset[] = { private static final int[] blueOffset = {
2, 0, 2, 0, 1, 3, 0, 2, 0, 1, 3 2, 0, 2, 0, 1, 3, 0, 2, 0, 1, 3
}; };
@@ -269,27 +269,27 @@ final public class TJ {
* The uncompressed source/destination image is stored in bottom-up (Windows, * The uncompressed source/destination image is stored in bottom-up (Windows,
* OpenGL) order, not top-down (X11) order. * OpenGL) order, not top-down (X11) order.
*/ */
final public static int FLAG_BOTTOMUP = 2; public static final int FLAG_BOTTOMUP = 2;
/** /**
* Turn off CPU auto-detection and force TurboJPEG to use MMX code * Turn off CPU auto-detection and force TurboJPEG to use MMX code
* (if the underlying codec supports it.) * (if the underlying codec supports it.)
*/ */
final public static int FLAG_FORCEMMX = 8; public static final int FLAG_FORCEMMX = 8;
/** /**
* Turn off CPU auto-detection and force TurboJPEG to use SSE code * Turn off CPU auto-detection and force TurboJPEG to use SSE code
* (if the underlying codec supports it.) * (if the underlying codec supports it.)
*/ */
final public static int FLAG_FORCESSE = 16; public static final int FLAG_FORCESSE = 16;
/** /**
* Turn off CPU auto-detection and force TurboJPEG to use SSE2 code * Turn off CPU auto-detection and force TurboJPEG to use SSE2 code
* (if the underlying codec supports it.) * (if the underlying codec supports it.)
*/ */
final public static int FLAG_FORCESSE2 = 32; public static final int FLAG_FORCESSE2 = 32;
/** /**
* Turn off CPU auto-detection and force TurboJPEG to use SSE3 code * Turn off CPU auto-detection and force TurboJPEG to use SSE3 code
* (if the underlying codec supports it.) * (if the underlying codec supports it.)
*/ */
final public static int FLAG_FORCESSE3 = 128; public static final int FLAG_FORCESSE3 = 128;
/** /**
* When decompressing an image that was compressed using chrominance * When decompressing an image that was compressed using chrominance
* subsampling, use the fastest chrominance upsampling algorithm available in * subsampling, use the fastest chrominance upsampling algorithm available in
@@ -297,7 +297,7 @@ final public class TJ {
* creates a smooth transition between neighboring chrominance components in * creates a smooth transition between neighboring chrominance components in
* order to reduce upsampling artifacts in the decompressed image. * order to reduce upsampling artifacts in the decompressed image.
*/ */
final public static int FLAG_FASTUPSAMPLE = 256; public static final int FLAG_FASTUPSAMPLE = 256;
/** /**
* Use the fastest DCT/IDCT algorithm available in the underlying codec. The * Use the fastest DCT/IDCT algorithm available in the underlying codec. The
* default if this flag is not specified is implementation-specific. The * default if this flag is not specified is implementation-specific. The
@@ -306,7 +306,7 @@ final public class TJ {
* effect on accuracy, but it uses the accurate algorithm when decompressing, * effect on accuracy, but it uses the accurate algorithm when decompressing,
* because this has been shown to have a larger effect. * because this has been shown to have a larger effect.
*/ */
final public static int FLAG_FASTDCT = 2048; public static final int FLAG_FASTDCT = 2048;
/** /**
* Use the most accurate DCT/IDCT algorithm available in the underlying * Use the most accurate DCT/IDCT algorithm available in the underlying
* codec. The default if this flag is not specified is * codec. The default if this flag is not specified is
@@ -316,7 +316,7 @@ final public class TJ {
* accurate algorithm when decompressing, because this has been shown to have * accurate algorithm when decompressing, because this has been shown to have
* a larger effect. * a larger effect.
*/ */
final public static int FLAG_ACCURATEDCT = 4096; public static final int FLAG_ACCURATEDCT = 4096;
/** /**
@@ -333,7 +333,7 @@ final public class TJ {
* @return the maximum size of the buffer (in bytes) required to hold a JPEG * @return the maximum size of the buffer (in bytes) required to hold a JPEG
* image with the given width, height, and level of chrominance subsampling * image with the given width, height, and level of chrominance subsampling
*/ */
public native static int bufSize(int width, int height, int jpegSubsamp) public static native int bufSize(int width, int height, int jpegSubsamp)
throws Exception; throws Exception;
/** /**
@@ -350,7 +350,7 @@ final public class TJ {
* @return the size of the buffer (in bytes) required to hold a YUV planar * @return the size of the buffer (in bytes) required to hold a YUV planar
* image with the given width, height, and level of chrominance subsampling * image with the given width, height, and level of chrominance subsampling
*/ */
public native static int bufSizeYUV(int width, int height, public static native int bufSizeYUV(int width, int height,
int subsamp) int subsamp)
throws Exception; throws Exception;
@@ -361,7 +361,7 @@ final public class TJ {
* @return a list of fractional scaling factors that the JPEG decompressor in * @return a list of fractional scaling factors that the JPEG decompressor in
* this implementation of TurboJPEG supports * this implementation of TurboJPEG supports
*/ */
public native static TJScalingFactor[] getScalingFactors() public static native TJScalingFactor[] getScalingFactors()
throws Exception; throws Exception;
static { static {

View File

@@ -36,7 +36,7 @@ import java.nio.*;
*/ */
public class TJCompressor { public class TJCompressor {
private final static String NO_ASSOC_ERROR = private static final String NO_ASSOC_ERROR =
"No source image is associated with this instance"; "No source image is associated with this instance";
/** /**
@@ -123,15 +123,18 @@ public class TJCompressor {
* {@link TJ TJ.PF_*}) * {@link TJ TJ.PF_*})
*/ */
public void setSourceImage(byte[] srcImage, int x, int y, int width, public void setSourceImage(byte[] srcImage, int x, int y, int width,
int pitch, int height, int pixelFormat) throws Exception { int pitch, int height, int pixelFormat)
if(handle == 0) init(); throws Exception {
if(srcImage == null || x < 0 || y < 0 || width < 1 || height < 1 if (handle == 0) init();
|| pitch < 0 || pixelFormat < 0 || pixelFormat >= TJ.NUMPF) if (srcImage == null || x < 0 || y < 0 || width < 1 || height < 1 ||
pitch < 0 || pixelFormat < 0 || pixelFormat >= TJ.NUMPF)
throw new Exception("Invalid argument in setSourceImage()"); throw new Exception("Invalid argument in setSourceImage()");
srcBuf = srcImage; srcBuf = srcImage;
srcWidth = width; srcWidth = width;
if(pitch == 0) srcPitch = width * TJ.getPixelSize(pixelFormat); if (pitch == 0)
else srcPitch = pitch; srcPitch = width * TJ.getPixelSize(pixelFormat);
else
srcPitch = pitch;
srcHeight = height; srcHeight = height;
srcPixelFormat = pixelFormat; srcPixelFormat = pixelFormat;
srcX = x; srcX = x;
@@ -157,7 +160,7 @@ public class TJCompressor {
* {@link TJ TJ.SAMP_*}) * {@link TJ TJ.SAMP_*})
*/ */
public void setSubsamp(int newSubsamp) throws Exception { public void setSubsamp(int newSubsamp) throws Exception {
if(newSubsamp < 0 || newSubsamp >= TJ.NUMSAMP) if (newSubsamp < 0 || newSubsamp >= TJ.NUMSAMP)
throw new Exception("Invalid argument in setSubsamp()"); throw new Exception("Invalid argument in setSubsamp()");
subsamp = newSubsamp; subsamp = newSubsamp;
} }
@@ -169,7 +172,7 @@ public class TJCompressor {
* 100 = best) * 100 = best)
*/ */
public void setJPEGQuality(int quality) throws Exception { public void setJPEGQuality(int quality) throws Exception {
if(quality < 1 || quality > 100) if (quality < 1 || quality > 100)
throw new Exception("Invalid argument in setJPEGQuality()"); throw new Exception("Invalid argument in setJPEGQuality()");
jpegQuality = quality; jpegQuality = quality;
} }
@@ -185,17 +188,22 @@ public class TJCompressor {
* @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*} * @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*}
*/ */
public void compress(byte[] dstBuf, int flags) throws Exception { public void compress(byte[] dstBuf, int flags) throws Exception {
if(dstBuf == null || flags < 0) if (dstBuf == null || flags < 0)
throw new Exception("Invalid argument in compress()"); throw new Exception("Invalid argument in compress()");
if(srcBuf == null) throw new Exception(NO_ASSOC_ERROR); if (srcBuf == null)
if(jpegQuality < 0) throw new Exception("JPEG Quality not set"); throw new Exception(NO_ASSOC_ERROR);
if(subsamp < 0) throw new Exception("Subsampling level not set"); if (jpegQuality < 0)
throw new Exception("JPEG Quality not set");
if (subsamp < 0)
throw new Exception("Subsampling level not set");
if (srcX >= 0 && srcY >= 0) if (srcX >= 0 && srcY >= 0)
compressedSize = compress(srcBuf, srcX, srcY, srcWidth, srcPitch, compressedSize = compress(srcBuf, srcX, srcY, srcWidth, srcPitch,
srcHeight, srcPixelFormat, dstBuf, subsamp, jpegQuality, flags); srcHeight, srcPixelFormat, dstBuf, subsamp,
jpegQuality, flags);
else else
compressedSize = compress(srcBuf, srcWidth, srcPitch, compressedSize = compress(srcBuf, srcWidth, srcPitch, srcHeight,
srcHeight, srcPixelFormat, dstBuf, subsamp, jpegQuality, flags); srcPixelFormat, dstBuf, subsamp, jpegQuality,
flags);
} }
/** /**
@@ -209,7 +217,7 @@ public class TJCompressor {
* #getCompressedSize} to obtain the size of the JPEG image. * #getCompressedSize} to obtain the size of the JPEG image.
*/ */
public byte[] compress(int flags) throws Exception { public byte[] compress(int flags) throws Exception {
if(srcWidth < 1 || srcHeight < 1) if (srcWidth < 1 || srcHeight < 1)
throw new Exception(NO_ASSOC_ERROR); throw new Exception(NO_ASSOC_ERROR);
byte[] buf = new byte[TJ.bufSize(srcWidth, srcHeight, subsamp)]; byte[] buf = new byte[TJ.bufSize(srcWidth, srcHeight, subsamp)];
compress(buf, flags); compress(buf, flags);
@@ -231,12 +239,13 @@ public class TJCompressor {
*/ */
public void compress(BufferedImage srcImage, byte[] dstBuf, int flags) public void compress(BufferedImage srcImage, byte[] dstBuf, int flags)
throws Exception { throws Exception {
if(srcImage == null || dstBuf == null || flags < 0) if (srcImage == null || dstBuf == null || flags < 0)
throw new Exception("Invalid argument in compress()"); throw new Exception("Invalid argument in compress()");
int width = srcImage.getWidth(); int width = srcImage.getWidth();
int height = srcImage.getHeight(); int height = srcImage.getHeight();
int pixelFormat; boolean intPixels = false; int pixelFormat;
if(byteOrder == null) boolean intPixels = false;
if (byteOrder == null)
byteOrder = ByteOrder.nativeOrder(); byteOrder = ByteOrder.nativeOrder();
switch(srcImage.getType()) { switch(srcImage.getType()) {
case BufferedImage.TYPE_3BYTE_BGR: case BufferedImage.TYPE_3BYTE_BGR:
@@ -247,7 +256,7 @@ public class TJCompressor {
case BufferedImage.TYPE_BYTE_GRAY: case BufferedImage.TYPE_BYTE_GRAY:
pixelFormat = TJ.PF_GRAY; break; pixelFormat = TJ.PF_GRAY; break;
case BufferedImage.TYPE_INT_BGR: case BufferedImage.TYPE_INT_BGR:
if(byteOrder == ByteOrder.BIG_ENDIAN) if (byteOrder == ByteOrder.BIG_ENDIAN)
pixelFormat = TJ.PF_XBGR; pixelFormat = TJ.PF_XBGR;
else else
pixelFormat = TJ.PF_RGBX; pixelFormat = TJ.PF_RGBX;
@@ -255,7 +264,7 @@ public class TJCompressor {
case BufferedImage.TYPE_INT_RGB: case BufferedImage.TYPE_INT_RGB:
case BufferedImage.TYPE_INT_ARGB: case BufferedImage.TYPE_INT_ARGB:
case BufferedImage.TYPE_INT_ARGB_PRE: case BufferedImage.TYPE_INT_ARGB_PRE:
if(byteOrder == ByteOrder.BIG_ENDIAN) if (byteOrder == ByteOrder.BIG_ENDIAN)
pixelFormat = TJ.PF_XRGB; pixelFormat = TJ.PF_XRGB;
else else
pixelFormat = TJ.PF_BGRX; pixelFormat = TJ.PF_BGRX;
@@ -264,9 +273,11 @@ public class TJCompressor {
throw new Exception("Unsupported BufferedImage format"); throw new Exception("Unsupported BufferedImage format");
} }
WritableRaster wr = srcImage.getRaster(); WritableRaster wr = srcImage.getRaster();
if(jpegQuality < 0) throw new Exception("JPEG Quality not set"); if (jpegQuality < 0)
if(subsamp < 0) throw new Exception("Subsampling level not set"); throw new Exception("JPEG Quality not set");
if(intPixels) { if (subsamp < 0)
throw new Exception("Subsampling level not set");
if (intPixels) {
SinglePixelPackedSampleModel sm = SinglePixelPackedSampleModel sm =
(SinglePixelPackedSampleModel)srcImage.getSampleModel(); (SinglePixelPackedSampleModel)srcImage.getSampleModel();
int pitch = sm.getScanlineStride(); int pitch = sm.getScanlineStride();
@@ -274,23 +285,24 @@ public class TJCompressor {
int[] buf = db.getData(); int[] buf = db.getData();
if (srcX >= 0 && srcY >= 0) if (srcX >= 0 && srcY >= 0)
compressedSize = compress(buf, srcX, srcY, width, pitch, height, compressedSize = compress(buf, srcX, srcY, width, pitch, height,
pixelFormat, dstBuf, subsamp, jpegQuality, flags); pixelFormat, dstBuf, subsamp, jpegQuality,
flags);
else else
compressedSize = compress(buf, width, pitch, height, pixelFormat, compressedSize = compress(buf, width, pitch, height, pixelFormat,
dstBuf, subsamp, jpegQuality, flags); dstBuf, subsamp, jpegQuality, flags);
} } else {
else {
ComponentSampleModel sm = ComponentSampleModel sm =
(ComponentSampleModel)srcImage.getSampleModel(); (ComponentSampleModel)srcImage.getSampleModel();
int pixelSize = sm.getPixelStride(); int pixelSize = sm.getPixelStride();
if(pixelSize != TJ.getPixelSize(pixelFormat)) if (pixelSize != TJ.getPixelSize(pixelFormat))
throw new Exception("Inconsistency between pixel format and pixel size in BufferedImage"); throw new Exception("Inconsistency between pixel format and pixel size in BufferedImage");
int pitch = sm.getScanlineStride(); int pitch = sm.getScanlineStride();
DataBufferByte db = (DataBufferByte)wr.getDataBuffer(); DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
byte[] buf = db.getData(); byte[] buf = db.getData();
if (srcX >= 0 && srcY >= 0) if (srcX >= 0 && srcY >= 0)
compressedSize = compress(buf, srcX, srcY, width, pitch, height, compressedSize = compress(buf, srcX, srcY, width, pitch, height,
pixelFormat, dstBuf, subsamp, jpegQuality, flags); pixelFormat, dstBuf, subsamp, jpegQuality,
flags);
else else
compressedSize = compress(buf, width, pitch, height, pixelFormat, compressedSize = compress(buf, width, pitch, height, pixelFormat,
dstBuf, subsamp, jpegQuality, flags); dstBuf, subsamp, jpegQuality, flags);
@@ -340,10 +352,12 @@ public class TJCompressor {
* @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*} * @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*}
*/ */
public void encodeYUV(byte[] dstBuf, int flags) throws Exception { public void encodeYUV(byte[] dstBuf, int flags) throws Exception {
if(dstBuf == null || flags < 0) if (dstBuf == null || flags < 0)
throw new Exception("Invalid argument in compress()"); throw new Exception("Invalid argument in compress()");
if(srcBuf == null) throw new Exception(NO_ASSOC_ERROR); if (srcBuf == null)
if(subsamp < 0) throw new Exception("Subsampling level not set"); throw new Exception(NO_ASSOC_ERROR);
if (subsamp < 0)
throw new Exception("Subsampling level not set");
encodeYUV(srcBuf, srcWidth, srcPitch, srcHeight, encodeYUV(srcBuf, srcWidth, srcPitch, srcHeight,
srcPixelFormat, dstBuf, subsamp, flags); srcPixelFormat, dstBuf, subsamp, flags);
compressedSize = TJ.bufSizeYUV(srcWidth, srcHeight, subsamp); compressedSize = TJ.bufSizeYUV(srcWidth, srcHeight, subsamp);
@@ -359,9 +373,10 @@ public class TJCompressor {
* @return a buffer containing a YUV planar image * @return a buffer containing a YUV planar image
*/ */
public byte[] encodeYUV(int flags) throws Exception { public byte[] encodeYUV(int flags) throws Exception {
if(srcWidth < 1 || srcHeight < 1) if (srcWidth < 1 || srcHeight < 1)
throw new Exception(NO_ASSOC_ERROR); throw new Exception(NO_ASSOC_ERROR);
if(subsamp < 0) throw new Exception("Subsampling level not set"); if (subsamp < 0)
throw new Exception("Subsampling level not set");
byte[] buf = new byte[TJ.bufSizeYUV(srcWidth, srcHeight, subsamp)]; byte[] buf = new byte[TJ.bufSizeYUV(srcWidth, srcHeight, subsamp)];
encodeYUV(buf, flags); encodeYUV(buf, flags);
return buf; return buf;
@@ -383,12 +398,12 @@ public class TJCompressor {
*/ */
public void encodeYUV(BufferedImage srcImage, byte[] dstBuf, int flags) public void encodeYUV(BufferedImage srcImage, byte[] dstBuf, int flags)
throws Exception { throws Exception {
if(srcImage == null || dstBuf == null || flags < 0) if (srcImage == null || dstBuf == null || flags < 0)
throw new Exception("Invalid argument in encodeYUV()"); throw new Exception("Invalid argument in encodeYUV()");
int width = srcImage.getWidth(); int width = srcImage.getWidth();
int height = srcImage.getHeight(); int height = srcImage.getHeight();
int pixelFormat; boolean intPixels = false; int pixelFormat; boolean intPixels = false;
if(byteOrder == null) if (byteOrder == null)
byteOrder = ByteOrder.nativeOrder(); byteOrder = ByteOrder.nativeOrder();
switch(srcImage.getType()) { switch(srcImage.getType()) {
case BufferedImage.TYPE_3BYTE_BGR: case BufferedImage.TYPE_3BYTE_BGR:
@@ -399,7 +414,7 @@ public class TJCompressor {
case BufferedImage.TYPE_BYTE_GRAY: case BufferedImage.TYPE_BYTE_GRAY:
pixelFormat = TJ.PF_GRAY; break; pixelFormat = TJ.PF_GRAY; break;
case BufferedImage.TYPE_INT_BGR: case BufferedImage.TYPE_INT_BGR:
if(byteOrder == ByteOrder.BIG_ENDIAN) if (byteOrder == ByteOrder.BIG_ENDIAN)
pixelFormat = TJ.PF_XBGR; pixelFormat = TJ.PF_XBGR;
else else
pixelFormat = TJ.PF_RGBX; pixelFormat = TJ.PF_RGBX;
@@ -407,7 +422,7 @@ public class TJCompressor {
case BufferedImage.TYPE_INT_RGB: case BufferedImage.TYPE_INT_RGB:
case BufferedImage.TYPE_INT_ARGB: case BufferedImage.TYPE_INT_ARGB:
case BufferedImage.TYPE_INT_ARGB_PRE: case BufferedImage.TYPE_INT_ARGB_PRE:
if(byteOrder == ByteOrder.BIG_ENDIAN) if (byteOrder == ByteOrder.BIG_ENDIAN)
pixelFormat = TJ.PF_XRGB; pixelFormat = TJ.PF_XRGB;
else else
pixelFormat = TJ.PF_BGRX; pixelFormat = TJ.PF_BGRX;
@@ -416,8 +431,8 @@ public class TJCompressor {
throw new Exception("Unsupported BufferedImage format"); throw new Exception("Unsupported BufferedImage format");
} }
WritableRaster wr = srcImage.getRaster(); WritableRaster wr = srcImage.getRaster();
if(subsamp < 0) throw new Exception("Subsampling level not set"); if (subsamp < 0) throw new Exception("Subsampling level not set");
if(intPixels) { if (intPixels) {
SinglePixelPackedSampleModel sm = SinglePixelPackedSampleModel sm =
(SinglePixelPackedSampleModel)srcImage.getSampleModel(); (SinglePixelPackedSampleModel)srcImage.getSampleModel();
int pitch = sm.getScanlineStride(); int pitch = sm.getScanlineStride();
@@ -425,12 +440,11 @@ public class TJCompressor {
int[] buf = db.getData(); int[] buf = db.getData();
encodeYUV(buf, width, pitch, height, pixelFormat, dstBuf, subsamp, encodeYUV(buf, width, pitch, height, pixelFormat, dstBuf, subsamp,
flags); flags);
} } else {
else {
ComponentSampleModel sm = ComponentSampleModel sm =
(ComponentSampleModel)srcImage.getSampleModel(); (ComponentSampleModel)srcImage.getSampleModel();
int pixelSize = sm.getPixelStride(); int pixelSize = sm.getPixelStride();
if(pixelSize != TJ.getPixelSize(pixelFormat)) if (pixelSize != TJ.getPixelSize(pixelFormat))
throw new Exception("Inconsistency between pixel format and pixel size in BufferedImage"); throw new Exception("Inconsistency between pixel format and pixel size in BufferedImage");
int pitch = sm.getScanlineStride(); int pitch = sm.getScanlineStride();
DataBufferByte db = (DataBufferByte)wr.getDataBuffer(); DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
@@ -453,9 +467,9 @@ public class TJCompressor {
* *
* @return a buffer containing a YUV planar image * @return a buffer containing a YUV planar image
*/ */
public byte[] encodeYUV(BufferedImage srcImage, int flags) public byte[] encodeYUV(BufferedImage srcImage, int flags) throws Exception {
throws Exception { if (subsamp < 0)
if(subsamp < 0) throw new Exception("Subsampling level not set"); throw new Exception("Subsampling level not set");
int width = srcImage.getWidth(); int width = srcImage.getWidth();
int height = srcImage.getHeight(); int height = srcImage.getHeight();
byte[] buf = new byte[TJ.bufSizeYUV(width, height, subsamp)]; byte[] buf = new byte[TJ.bufSizeYUV(width, height, subsamp)];
@@ -484,9 +498,8 @@ public class TJCompressor {
protected void finalize() throws Throwable { protected void finalize() throws Throwable {
try { try {
close(); close();
} } catch(Exception e) {
catch(Exception e) {} } finally {
finally {
super.finalize(); super.finalize();
} }
}; };

View File

@@ -69,7 +69,7 @@ public interface TJCustomFilter {
* @param transform a {@link TJTransform} instance that specifies the * @param transform a {@link TJTransform} instance that specifies the
* parameters and/or cropping region for this transform * parameters and/or cropping region for this transform
*/ */
public void customFilter(ShortBuffer coeffBuffer, Rectangle bufferRegion, void customFilter(ShortBuffer coeffBuffer, Rectangle bufferRegion,
Rectangle planeRegion, int componentID, int transformID, Rectangle planeRegion, int componentID, int transformID,
TJTransform transform) TJTransform transform)
throws Exception; throws Exception;

View File

@@ -36,7 +36,7 @@ import java.nio.*;
*/ */
public class TJDecompressor { public class TJDecompressor {
private final static String NO_ASSOC_ERROR = private static final String NO_ASSOC_ERROR =
"No JPEG image is associated with this instance"; "No JPEG image is associated with this instance";
/** /**
@@ -82,7 +82,7 @@ public class TJDecompressor {
* @param imageSize size of the JPEG image (in bytes) * @param imageSize size of the JPEG image (in bytes)
*/ */
public void setJPEGImage(byte[] jpegImage, int imageSize) throws Exception { public void setJPEGImage(byte[] jpegImage, int imageSize) throws Exception {
if(jpegImage == null || imageSize < 1) if (jpegImage == null || imageSize < 1)
throw new Exception("Invalid argument in setJPEGImage()"); throw new Exception("Invalid argument in setJPEGImage()");
jpegBuf = jpegImage; jpegBuf = jpegImage;
jpegBufSize = imageSize; jpegBufSize = imageSize;
@@ -97,7 +97,8 @@ public class TJDecompressor {
* instance * instance
*/ */
public int getWidth() throws Exception { public int getWidth() throws Exception {
if(jpegWidth < 1) throw new Exception(NO_ASSOC_ERROR); if (jpegWidth < 1)
throw new Exception(NO_ASSOC_ERROR);
return jpegWidth; return jpegWidth;
} }
@@ -109,7 +110,8 @@ public class TJDecompressor {
* instance * instance
*/ */
public int getHeight() throws Exception { public int getHeight() throws Exception {
if(jpegHeight < 1) throw new Exception(NO_ASSOC_ERROR); if (jpegHeight < 1)
throw new Exception(NO_ASSOC_ERROR);
return jpegHeight; return jpegHeight;
} }
@@ -121,8 +123,9 @@ public class TJDecompressor {
* associated with this decompressor instance * associated with this decompressor instance
*/ */
public int getSubsamp() throws Exception { public int getSubsamp() throws Exception {
if(jpegSubsamp < 0) throw new Exception(NO_ASSOC_ERROR); if (jpegSubsamp < 0)
if(jpegSubsamp >= TJ.NUMSAMP) throw new Exception(NO_ASSOC_ERROR);
if (jpegSubsamp >= TJ.NUMSAMP)
throw new Exception("JPEG header information is invalid"); throw new Exception("JPEG header information is invalid");
return jpegSubsamp; return jpegSubsamp;
} }
@@ -133,7 +136,8 @@ public class TJDecompressor {
* @return the JPEG image buffer associated with this decompressor instance * @return the JPEG image buffer associated with this decompressor instance
*/ */
public byte[] getJPEGBuf() throws Exception { public byte[] getJPEGBuf() throws Exception {
if(jpegBuf == null) throw new Exception(NO_ASSOC_ERROR); if (jpegBuf == null)
throw new Exception(NO_ASSOC_ERROR);
return jpegBuf; return jpegBuf;
} }
@@ -145,7 +149,8 @@ public class TJDecompressor {
* decompressor instance * decompressor instance
*/ */
public int getJPEGSize() throws Exception { public int getJPEGSize() throws Exception {
if(jpegBufSize < 1) throw new Exception(NO_ASSOC_ERROR); if (jpegBufSize < 1)
throw new Exception(NO_ASSOC_ERROR);
return jpegBufSize; return jpegBufSize;
} }
@@ -171,21 +176,23 @@ public class TJDecompressor {
*/ */
public int getScaledWidth(int desiredWidth, int desiredHeight) public int getScaledWidth(int desiredWidth, int desiredHeight)
throws Exception { throws Exception {
if(jpegWidth < 1 || jpegHeight < 1) if (jpegWidth < 1 || jpegHeight < 1)
throw new Exception(NO_ASSOC_ERROR); throw new Exception(NO_ASSOC_ERROR);
if(desiredWidth < 0 || desiredHeight < 0) if (desiredWidth < 0 || desiredHeight < 0)
throw new Exception("Invalid argument in getScaledWidth()"); throw new Exception("Invalid argument in getScaledWidth()");
TJScalingFactor sf[] = TJ.getScalingFactors(); TJScalingFactor[] sf = TJ.getScalingFactors();
if(desiredWidth == 0) desiredWidth = jpegWidth; if (desiredWidth == 0)
if(desiredHeight == 0) desiredHeight = jpegHeight; desiredWidth = jpegWidth;
if (desiredHeight == 0)
desiredHeight = jpegHeight;
int scaledWidth = jpegWidth, scaledHeight = jpegHeight; int scaledWidth = jpegWidth, scaledHeight = jpegHeight;
for(int i = 0; i < sf.length; i++) { for (int i = 0; i < sf.length; i++) {
scaledWidth = sf[i].getScaled(jpegWidth); scaledWidth = sf[i].getScaled(jpegWidth);
scaledHeight = sf[i].getScaled(jpegHeight); scaledHeight = sf[i].getScaled(jpegHeight);
if(scaledWidth <= desiredWidth && scaledHeight <= desiredHeight) if (scaledWidth <= desiredWidth && scaledHeight <= desiredHeight)
break; break;
} }
if(scaledWidth > desiredWidth || scaledHeight > desiredHeight) if (scaledWidth > desiredWidth || scaledHeight > desiredHeight)
throw new Exception("Could not scale down to desired image dimensions"); throw new Exception("Could not scale down to desired image dimensions");
return scaledWidth; return scaledWidth;
} }
@@ -211,21 +218,23 @@ public class TJDecompressor {
*/ */
public int getScaledHeight(int desiredWidth, int desiredHeight) public int getScaledHeight(int desiredWidth, int desiredHeight)
throws Exception { throws Exception {
if(jpegWidth < 1 || jpegHeight < 1) if (jpegWidth < 1 || jpegHeight < 1)
throw new Exception(NO_ASSOC_ERROR); throw new Exception(NO_ASSOC_ERROR);
if(desiredWidth < 0 || desiredHeight < 0) if (desiredWidth < 0 || desiredHeight < 0)
throw new Exception("Invalid argument in getScaledHeight()"); throw new Exception("Invalid argument in getScaledHeight()");
TJScalingFactor sf[] = TJ.getScalingFactors(); TJScalingFactor[] sf = TJ.getScalingFactors();
if(desiredWidth == 0) desiredWidth = jpegWidth; if (desiredWidth == 0)
if(desiredHeight == 0) desiredHeight = jpegHeight; desiredWidth = jpegWidth;
if (desiredHeight == 0)
desiredHeight = jpegHeight;
int scaledWidth = jpegWidth, scaledHeight = jpegHeight; int scaledWidth = jpegWidth, scaledHeight = jpegHeight;
for(int i = 0; i < sf.length; i++) { for (int i = 0; i < sf.length; i++) {
scaledWidth = sf[i].getScaled(jpegWidth); scaledWidth = sf[i].getScaled(jpegWidth);
scaledHeight = sf[i].getScaled(jpegHeight); scaledHeight = sf[i].getScaled(jpegHeight);
if(scaledWidth <= desiredWidth && scaledHeight <= desiredHeight) if (scaledWidth <= desiredWidth && scaledHeight <= desiredHeight)
break; break;
} }
if(scaledWidth > desiredWidth || scaledHeight > desiredHeight) if (scaledWidth > desiredWidth || scaledHeight > desiredHeight)
throw new Exception("Could not scale down to desired image dimensions"); throw new Exception("Could not scale down to desired image dimensions");
return scaledHeight; return scaledHeight;
} }
@@ -284,12 +293,13 @@ public class TJDecompressor {
* @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*} * @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*}
*/ */
public void decompress(byte[] dstBuf, int x, int y, int desiredWidth, public void decompress(byte[] dstBuf, int x, int y, int desiredWidth,
int pitch, int desiredHeight, int pixelFormat, int flags) int pitch, int desiredHeight, int pixelFormat,
throws Exception { int flags) throws Exception {
if(jpegBuf == null) throw new Exception(NO_ASSOC_ERROR); if (jpegBuf == null)
if(dstBuf == null || x < 0 || y < 0 || desiredWidth < 0 || pitch < 0 throw new Exception(NO_ASSOC_ERROR);
|| desiredHeight < 0 || pixelFormat < 0 || pixelFormat >= TJ.NUMPF if (dstBuf == null || x < 0 || y < 0 || desiredWidth < 0 || pitch < 0 ||
|| flags < 0) desiredHeight < 0 || pixelFormat < 0 || pixelFormat >= TJ.NUMPF ||
flags < 0)
throw new Exception("Invalid argument in decompress()"); throw new Exception("Invalid argument in decompress()");
decompress(jpegBuf, jpegBufSize, dstBuf, x, y, desiredWidth, pitch, decompress(jpegBuf, jpegBufSize, dstBuf, x, y, desiredWidth, pitch,
desiredHeight, pixelFormat, flags); desiredHeight, pixelFormat, flags);
@@ -331,13 +341,14 @@ public class TJDecompressor {
*/ */
public byte[] decompress(int desiredWidth, int pitch, int desiredHeight, public byte[] decompress(int desiredWidth, int pitch, int desiredHeight,
int pixelFormat, int flags) throws Exception { int pixelFormat, int flags) throws Exception {
if(desiredWidth < 0 || pitch < 0 || desiredHeight < 0 if (desiredWidth < 0 || pitch < 0 || desiredHeight < 0 ||
|| pixelFormat < 0 || pixelFormat >= TJ.NUMPF || flags < 0) pixelFormat < 0 || pixelFormat >= TJ.NUMPF || flags < 0)
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(desiredWidth, desiredHeight); int scaledWidth = getScaledWidth(desiredWidth, desiredHeight);
int scaledHeight = getScaledHeight(desiredWidth, desiredHeight); int scaledHeight = getScaledHeight(desiredWidth, desiredHeight);
if(pitch == 0) pitch = scaledWidth * pixelSize; if (pitch == 0)
pitch = scaledWidth * pixelSize;
byte[] buf = new byte[pitch * scaledHeight]; byte[] buf = new byte[pitch * scaledHeight];
decompress(buf, desiredWidth, pitch, desiredHeight, pixelFormat, flags); decompress(buf, desiredWidth, pitch, desiredHeight, pixelFormat, flags);
return buf; return buf;
@@ -361,8 +372,9 @@ public class TJDecompressor {
* @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*} * @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*}
*/ */
public void decompressToYUV(byte[] dstBuf, int flags) throws Exception { public void decompressToYUV(byte[] dstBuf, int flags) throws Exception {
if(jpegBuf == null) throw new Exception(NO_ASSOC_ERROR); if (jpegBuf == null)
if(dstBuf == null || flags < 0) throw new Exception(NO_ASSOC_ERROR);
if (dstBuf == null || flags < 0)
throw new Exception("Invalid argument in decompressToYUV()"); throw new Exception("Invalid argument in decompressToYUV()");
decompressToYUV(jpegBuf, jpegBufSize, dstBuf, flags); decompressToYUV(jpegBuf, jpegBufSize, dstBuf, flags);
} }
@@ -378,11 +390,11 @@ public class TJDecompressor {
* @return a buffer containing a YUV planar image * @return a buffer containing a YUV planar image
*/ */
public byte[] decompressToYUV(int flags) throws Exception { public byte[] decompressToYUV(int flags) throws Exception {
if(flags < 0) if (flags < 0)
throw new Exception("Invalid argument in decompressToYUV()"); throw new Exception("Invalid argument in decompressToYUV()");
if(jpegWidth < 1 || jpegHeight < 1 || jpegSubsamp < 0) if (jpegWidth < 1 || jpegHeight < 1 || jpegSubsamp < 0)
throw new Exception(NO_ASSOC_ERROR); throw new Exception(NO_ASSOC_ERROR);
if(jpegSubsamp >= TJ.NUMSAMP) if (jpegSubsamp >= TJ.NUMSAMP)
throw new Exception("JPEG header information is invalid"); throw new Exception("JPEG header information is invalid");
byte[] buf = new byte[TJ.bufSizeYUV(jpegWidth, jpegHeight, jpegSubsamp)]; byte[] buf = new byte[TJ.bufSizeYUV(jpegWidth, jpegHeight, jpegSubsamp)];
decompressToYUV(buf, flags); decompressToYUV(buf, flags);
@@ -440,12 +452,13 @@ public class TJDecompressor {
* @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*} * @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*}
*/ */
public void decompress(int[] dstBuf, int x, int y, int desiredWidth, public void decompress(int[] dstBuf, int x, int y, int desiredWidth,
int stride, int desiredHeight, int pixelFormat, int flags) int stride, int desiredHeight, int pixelFormat,
throws Exception { int flags) throws Exception {
if(jpegBuf == null) throw new Exception(NO_ASSOC_ERROR); if (jpegBuf == null)
if(dstBuf == null || x < 0 || y < 0 || desiredWidth < 0 || stride < 0 throw new Exception(NO_ASSOC_ERROR);
|| desiredHeight < 0 || pixelFormat < 0 || pixelFormat >= TJ.NUMPF if (dstBuf == null || x < 0 || y < 0 || desiredWidth < 0 || stride < 0 ||
|| flags < 0) desiredHeight < 0 || pixelFormat < 0 || pixelFormat >= TJ.NUMPF ||
flags < 0)
throw new Exception("Invalid argument in decompress()"); throw new Exception("Invalid argument in decompress()");
decompress(jpegBuf, jpegBufSize, dstBuf, x, y, desiredWidth, stride, decompress(jpegBuf, jpegBufSize, dstBuf, x, y, desiredWidth, stride,
desiredHeight, pixelFormat, flags); desiredHeight, pixelFormat, flags);
@@ -462,16 +475,16 @@ public class TJDecompressor {
* @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*} * @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*}
*/ */
public void decompress(BufferedImage dstImage, int flags) throws Exception { public void decompress(BufferedImage dstImage, int flags) throws Exception {
if(dstImage == null || flags < 0) if (dstImage == null || flags < 0)
throw new Exception("Invalid argument in decompress()"); throw new Exception("Invalid argument in decompress()");
int desiredWidth = dstImage.getWidth(); int desiredWidth = dstImage.getWidth();
int desiredHeight = dstImage.getHeight(); int desiredHeight = dstImage.getHeight();
int scaledWidth = getScaledWidth(desiredWidth, desiredHeight); int scaledWidth = getScaledWidth(desiredWidth, desiredHeight);
int scaledHeight = getScaledHeight(desiredWidth, desiredHeight); int scaledHeight = getScaledHeight(desiredWidth, desiredHeight);
if(scaledWidth != desiredWidth || scaledHeight != desiredHeight) if (scaledWidth != desiredWidth || scaledHeight != desiredHeight)
throw new Exception("BufferedImage dimensions do not match a scaled image size that TurboJPEG is capable of generating."); throw new Exception("BufferedImage dimensions do not match a scaled image size that TurboJPEG is capable of generating.");
int pixelFormat; boolean intPixels = false; int pixelFormat; boolean intPixels = false;
if(byteOrder == null) if (byteOrder == null)
byteOrder = ByteOrder.nativeOrder(); byteOrder = ByteOrder.nativeOrder();
switch(dstImage.getType()) { switch(dstImage.getType()) {
case BufferedImage.TYPE_3BYTE_BGR: case BufferedImage.TYPE_3BYTE_BGR:
@@ -482,20 +495,20 @@ public class TJDecompressor {
case BufferedImage.TYPE_BYTE_GRAY: case BufferedImage.TYPE_BYTE_GRAY:
pixelFormat = TJ.PF_GRAY; break; pixelFormat = TJ.PF_GRAY; break;
case BufferedImage.TYPE_INT_BGR: case BufferedImage.TYPE_INT_BGR:
if(byteOrder == ByteOrder.BIG_ENDIAN) if (byteOrder == ByteOrder.BIG_ENDIAN)
pixelFormat = TJ.PF_XBGR; pixelFormat = TJ.PF_XBGR;
else else
pixelFormat = TJ.PF_RGBX; pixelFormat = TJ.PF_RGBX;
intPixels = true; break; intPixels = true; break;
case BufferedImage.TYPE_INT_RGB: case BufferedImage.TYPE_INT_RGB:
if(byteOrder == ByteOrder.BIG_ENDIAN) if (byteOrder == ByteOrder.BIG_ENDIAN)
pixelFormat = TJ.PF_XRGB; pixelFormat = TJ.PF_XRGB;
else else
pixelFormat = TJ.PF_BGRX; pixelFormat = TJ.PF_BGRX;
intPixels = true; break; intPixels = true; break;
case BufferedImage.TYPE_INT_ARGB: case BufferedImage.TYPE_INT_ARGB:
case BufferedImage.TYPE_INT_ARGB_PRE: case BufferedImage.TYPE_INT_ARGB_PRE:
if(byteOrder == ByteOrder.BIG_ENDIAN) if (byteOrder == ByteOrder.BIG_ENDIAN)
pixelFormat = TJ.PF_ARGB; pixelFormat = TJ.PF_ARGB;
else else
pixelFormat = TJ.PF_BGRA; pixelFormat = TJ.PF_BGRA;
@@ -504,21 +517,21 @@ public class TJDecompressor {
throw new Exception("Unsupported BufferedImage format"); throw new Exception("Unsupported BufferedImage format");
} }
WritableRaster wr = dstImage.getRaster(); WritableRaster wr = dstImage.getRaster();
if(intPixels) { if (intPixels) {
SinglePixelPackedSampleModel sm = SinglePixelPackedSampleModel sm =
(SinglePixelPackedSampleModel)dstImage.getSampleModel(); (SinglePixelPackedSampleModel)dstImage.getSampleModel();
int pitch = sm.getScanlineStride(); int pitch = sm.getScanlineStride();
DataBufferInt db = (DataBufferInt)wr.getDataBuffer(); DataBufferInt db = (DataBufferInt)wr.getDataBuffer();
int[] buf = db.getData(); int[] buf = db.getData();
if(jpegBuf == null) throw new Exception(NO_ASSOC_ERROR); if (jpegBuf == null)
throw new Exception(NO_ASSOC_ERROR);
decompress(jpegBuf, jpegBufSize, buf, scaledWidth, pitch, scaledHeight, decompress(jpegBuf, jpegBufSize, buf, scaledWidth, pitch, scaledHeight,
pixelFormat, flags); pixelFormat, flags);
} } else {
else {
ComponentSampleModel sm = ComponentSampleModel sm =
(ComponentSampleModel)dstImage.getSampleModel(); (ComponentSampleModel)dstImage.getSampleModel();
int pixelSize = sm.getPixelStride(); int pixelSize = sm.getPixelStride();
if(pixelSize != TJ.getPixelSize(pixelFormat)) if (pixelSize != TJ.getPixelSize(pixelFormat))
throw new Exception("Inconsistency between pixel format and pixel size in BufferedImage"); throw new Exception("Inconsistency between pixel format and pixel size in BufferedImage");
int pitch = sm.getScanlineStride(); int pitch = sm.getScanlineStride();
DataBufferByte db = (DataBufferByte)wr.getDataBuffer(); DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
@@ -550,8 +563,9 @@ public class TJDecompressor {
* decompressed image * decompressed image
*/ */
public BufferedImage decompress(int desiredWidth, int desiredHeight, public BufferedImage decompress(int desiredWidth, int desiredHeight,
int bufferedImageType, int flags) throws Exception { int bufferedImageType, int flags)
if(desiredWidth < 0 || desiredHeight < 0 || flags < 0) throws Exception {
if (desiredWidth < 0 || desiredHeight < 0 || flags < 0)
throw new Exception("Invalid argument in decompress()"); throw new Exception("Invalid argument in decompress()");
int scaledWidth = getScaledWidth(desiredWidth, desiredHeight); int scaledWidth = getScaledWidth(desiredWidth, desiredHeight);
int scaledHeight = getScaledHeight(desiredWidth, desiredHeight); int scaledHeight = getScaledHeight(desiredWidth, desiredHeight);
@@ -571,9 +585,8 @@ public class TJDecompressor {
protected void finalize() throws Throwable { protected void finalize() throws Throwable {
try { try {
close(); close();
} } catch(Exception e) {
catch(Exception e) {} } finally {
finally {
super.finalize(); super.finalize();
} }
}; };

View File

@@ -34,7 +34,7 @@ package org.libjpegturbo.turbojpeg;
public class TJScalingFactor { public class TJScalingFactor {
public TJScalingFactor(int num, int denom) throws Exception { public TJScalingFactor(int num, int denom) throws Exception {
if(num < 1 || denom < 1) if (num < 1 || denom < 1)
throw new Exception("Numerator and denominator must be >= 1"); throw new Exception("Numerator and denominator must be >= 1");
this.num = num; this.num = num;
this.denom = denom; this.denom = denom;

View File

@@ -40,54 +40,54 @@ public class TJTransform extends Rectangle {
/** /**
* The number of lossless transform operations * The number of lossless transform operations
*/ */
final public static int NUMOP = 8; public static final int NUMOP = 8;
/** /**
* Do not transform the position of the image pixels. * Do not transform the position of the image pixels.
*/ */
final public static int OP_NONE = 0; public static final int OP_NONE = 0;
/** /**
* Flip (mirror) image horizontally. This transform is imperfect if there * Flip (mirror) image horizontally. This transform is imperfect if there
* are any partial MCU blocks on the right edge. * are any partial MCU blocks on the right edge.
* @see #OPT_PERFECT * @see #OPT_PERFECT
*/ */
final public static int OP_HFLIP = 1; public static final int OP_HFLIP = 1;
/** /**
* Flip (mirror) image vertically. This transform is imperfect if there are * Flip (mirror) image vertically. This transform is imperfect if there are
* any partial MCU blocks on the bottom edge. * any partial MCU blocks on the bottom edge.
* @see #OPT_PERFECT * @see #OPT_PERFECT
*/ */
final public static int OP_VFLIP = 2; public static final int OP_VFLIP = 2;
/** /**
* Transpose image (flip/mirror along upper left to lower right axis). This * Transpose image (flip/mirror along upper left to lower right axis). This
* transform is always perfect. * transform is always perfect.
* @see #OPT_PERFECT * @see #OPT_PERFECT
*/ */
final public static int OP_TRANSPOSE = 3; public static final int OP_TRANSPOSE = 3;
/** /**
* Transverse transpose image (flip/mirror along upper right to lower left * Transverse transpose image (flip/mirror along upper right to lower left
* axis). This transform is imperfect if there are any partial MCU blocks in * axis). This transform is imperfect if there are any partial MCU blocks in
* the image. * the image.
* @see #OPT_PERFECT * @see #OPT_PERFECT
*/ */
final public static int OP_TRANSVERSE = 4; public static final int OP_TRANSVERSE = 4;
/** /**
* Rotate image clockwise by 90 degrees. This transform is imperfect if * Rotate image clockwise by 90 degrees. This transform is imperfect if
* there are any partial MCU blocks on the bottom edge. * there are any partial MCU blocks on the bottom edge.
* @see #OPT_PERFECT * @see #OPT_PERFECT
*/ */
final public static int OP_ROT90 = 5; public static final int OP_ROT90 = 5;
/** /**
* Rotate image 180 degrees. This transform is imperfect if there are any * Rotate image 180 degrees. This transform is imperfect if there are any
* partial MCU blocks in the image. * partial MCU blocks in the image.
* @see #OPT_PERFECT * @see #OPT_PERFECT
*/ */
final public static int OP_ROT180 = 6; public static final int OP_ROT180 = 6;
/** /**
* Rotate image counter-clockwise by 90 degrees. This transform is imperfect * Rotate image counter-clockwise by 90 degrees. This transform is imperfect
* if there are any partial MCU blocks on the right edge. * if there are any partial MCU blocks on the right edge.
* @see #OPT_PERFECT * @see #OPT_PERFECT
*/ */
final public static int OP_ROT270 = 7; public static final int OP_ROT270 = 7;
/** /**
@@ -103,21 +103,21 @@ public class TJTransform extends Rectangle {
* partial MCU blocks that cannot be transformed will be left in place, which * partial MCU blocks that cannot be transformed will be left in place, which
* will create odd-looking strips on the right or bottom edge of the image. * will create odd-looking strips on the right or bottom edge of the image.
*/ */
final public static int OPT_PERFECT = 1; public static final int OPT_PERFECT = 1;
/** /**
* This option will discard any partial MCU blocks that cannot be * This option will discard any partial MCU blocks that cannot be
* transformed. * transformed.
*/ */
final public static int OPT_TRIM = 2; public static final int OPT_TRIM = 2;
/** /**
* This option will enable lossless cropping. * This option will enable lossless cropping.
*/ */
final public static int OPT_CROP = 4; public static final int OPT_CROP = 4;
/** /**
* This option will discard the color data in the input image and produce * This option will discard the color data in the input image and produce
* a grayscale output image. * a grayscale output image.
*/ */
final public static int OPT_GRAY = 8; public static final int OPT_GRAY = 8;
/** /**
* This option will prevent {@link TJTransformer#transform * This option will prevent {@link TJTransformer#transform
* TJTransformer.transform()} from outputting a JPEG image for this * TJTransformer.transform()} from outputting a JPEG image for this
@@ -125,7 +125,7 @@ public class TJTransform extends Rectangle {
* filter to capture the transformed DCT coefficients without transcoding * filter to capture the transformed DCT coefficients without transcoding
* them. * them.
*/ */
final public static int OPT_NOOUTPUT = 16; public static final int OPT_NOOUTPUT = 16;
/** /**
@@ -162,7 +162,9 @@ public class TJTransform extends Rectangle {
public TJTransform(int x, int y, int w, int h, int op, int options, public TJTransform(int x, int y, int w, int h, int op, int options,
TJCustomFilter cf) throws Exception { TJCustomFilter cf) throws Exception {
super(x, y, w, h); super(x, y, w, h);
this.op = op; this.options = options; this.cf = cf; this.op = op;
this.options = options;
this.cf = cf;
} }
/** /**
@@ -184,7 +186,9 @@ public class TJTransform extends Rectangle {
public TJTransform(Rectangle r, int op, int options, public TJTransform(Rectangle r, int op, int options,
TJCustomFilter cf) throws Exception { TJCustomFilter cf) throws Exception {
super(r); super(r);
this.op = op; this.options = options; this.cf = cf; this.op = op;
this.options = options;
this.cf = cf;
} }
/** /**

View File

@@ -94,7 +94,8 @@ public class TJTransformer extends TJDecompressor {
*/ */
public void transform(byte[][] dstBufs, TJTransform[] transforms, public void transform(byte[][] dstBufs, TJTransform[] transforms,
int flags) throws Exception { int flags) throws Exception {
if(jpegBuf == null) throw new Exception("JPEG buffer not initialized"); if (jpegBuf == null)
throw new Exception("JPEG buffer not initialized");
transformedSizes = transform(jpegBuf, jpegBufSize, dstBufs, transforms, transformedSizes = transform(jpegBuf, jpegBufSize, dstBufs, transforms,
flags); flags);
} }
@@ -116,19 +117,19 @@ public class TJTransformer extends TJDecompressor {
public TJDecompressor[] transform(TJTransform[] transforms, int flags) public TJDecompressor[] transform(TJTransform[] transforms, int flags)
throws Exception { throws Exception {
byte[][] dstBufs = new byte[transforms.length][]; byte[][] dstBufs = new byte[transforms.length][];
if(jpegWidth < 1 || jpegHeight < 1) if (jpegWidth < 1 || jpegHeight < 1)
throw new Exception("JPEG buffer not initialized"); throw new Exception("JPEG buffer not initialized");
for(int i = 0; i < transforms.length; i++) { for (int i = 0; i < transforms.length; i++) {
int w = jpegWidth, h = jpegHeight; int w = jpegWidth, h = jpegHeight;
if((transforms[i].options & TJTransform.OPT_CROP) != 0) { if ((transforms[i].options & TJTransform.OPT_CROP) != 0) {
if(transforms[i].width != 0) w = transforms[i].width; if (transforms[i].width != 0) w = transforms[i].width;
if(transforms[i].height != 0) h = transforms[i].height; if (transforms[i].height != 0) h = transforms[i].height;
} }
dstBufs[i] = new byte[TJ.bufSize(w, h, jpegSubsamp)]; dstBufs[i] = new byte[TJ.bufSize(w, h, jpegSubsamp)];
} }
TJDecompressor[] tjd = new TJDecompressor[transforms.length]; TJDecompressor[] tjd = new TJDecompressor[transforms.length];
transform(dstBufs, transforms, flags); transform(dstBufs, transforms, flags);
for(int i = 0; i < transforms.length; i++) for (int i = 0; i < transforms.length; i++)
tjd[i] = new TJDecompressor(dstBufs[i], transformedSizes[i]); tjd[i] = new TJDecompressor(dstBufs[i], transformedSizes[i]);
return tjd; return tjd;
} }
@@ -141,7 +142,7 @@ public class TJTransformer extends TJDecompressor {
* the most recent call to {@link #transform transform()} * the most recent call to {@link #transform transform()}
*/ */
public int[] getTransformedSizes() throws Exception { public int[] getTransformedSizes() throws Exception {
if(transformedSizes == null) if (transformedSizes == null)
throw new Exception("No image has been transformed yet"); throw new Exception("No image has been transformed yet");
return transformedSizes; return transformedSizes;
} }