When decompressing to a 4-byte RGB buffer, set the unused byte to 0xFF so it can be interpreted as an opaque alpha channel.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@699 632fc199-4ca6-4c93-a231-07263d6284db
This commit is contained in:
@@ -60,6 +60,11 @@ worst-case JPEG size based on the level of chrominance subsampling.
|
|||||||
[16] Fixed 32-bit supplementary package for amd64 Debian systems which was
|
[16] Fixed 32-bit supplementary package for amd64 Debian systems which was
|
||||||
broken by enhancements to the packaging system in 1.1.
|
broken by enhancements to the packaging system in 1.1.
|
||||||
|
|
||||||
|
[17] When decompressing a JPEG image using an output colorspace of
|
||||||
|
JCS_EXT_RGBX, JCS_EXT_BGRX, JCS_EXT_XBGR, or JCS_EXT_XRGB, libjpeg-turbo will
|
||||||
|
now set the unused byte to 0xFF, which allows applications to interpret that
|
||||||
|
byte as an alpha channel (0xFF = opaque).
|
||||||
|
|
||||||
|
|
||||||
1.1.1
|
1.1.1
|
||||||
=====
|
=====
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import java.io.*;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.awt.image.*;
|
import java.awt.image.*;
|
||||||
import javax.imageio.*;
|
import javax.imageio.*;
|
||||||
|
import java.nio.*;
|
||||||
import org.libjpegturbo.turbojpeg.*;
|
import org.libjpegturbo.turbojpeg.*;
|
||||||
|
|
||||||
public class TJUnitTest {
|
public class TJUnitTest {
|
||||||
@@ -59,26 +60,31 @@ public class TJUnitTest {
|
|||||||
private final static String pixFormatStr[] = {
|
private final static String pixFormatStr[] = {
|
||||||
"RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "Grayscale"
|
"RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "Grayscale"
|
||||||
};
|
};
|
||||||
private final static int biType[] = {
|
|
||||||
0, BufferedImage.TYPE_3BYTE_BGR, BufferedImage.TYPE_INT_BGR,
|
private final static int alphaOffset[] = {
|
||||||
BufferedImage.TYPE_INT_RGB, 0, 0, BufferedImage.TYPE_BYTE_GRAY
|
-1, -1, 3, 3, 0, 0, -1
|
||||||
};
|
};
|
||||||
|
|
||||||
private final static int _3byteFormats[] = {
|
private final static int _3byteFormats[] = {
|
||||||
TJ.PF_RGB, TJ.PF_BGR
|
TJ.PF_RGB, TJ.PF_BGR
|
||||||
};
|
};
|
||||||
private final static int _3byteFormatsBI[] = {
|
private final static int _3byteFormatsBI[] = {
|
||||||
TJ.PF_BGR
|
BufferedImage.TYPE_3BYTE_BGR
|
||||||
};
|
};
|
||||||
private final static int _4byteFormats[] = {
|
private final static 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 final static int _4byteFormatsBI[] = {
|
||||||
TJ.PF_RGBX, TJ.PF_BGRX
|
BufferedImage.TYPE_INT_BGR, BufferedImage.TYPE_INT_RGB,
|
||||||
|
BufferedImage.TYPE_4BYTE_ABGR, BufferedImage.TYPE_4BYTE_ABGR_PRE,
|
||||||
|
BufferedImage.TYPE_INT_ARGB, BufferedImage.TYPE_INT_ARGB_PRE
|
||||||
};
|
};
|
||||||
private final static int onlyGray[] = {
|
private final static int onlyGray[] = {
|
||||||
TJ.PF_GRAY
|
TJ.PF_GRAY
|
||||||
};
|
};
|
||||||
|
private final static int onlyGrayBI[] = {
|
||||||
|
BufferedImage.TYPE_BYTE_GRAY
|
||||||
|
};
|
||||||
private final static int onlyRGB[] = {
|
private final static int onlyRGB[] = {
|
||||||
TJ.PF_RGB
|
TJ.PF_RGB
|
||||||
};
|
};
|
||||||
@@ -90,6 +96,55 @@ public class TJUnitTest {
|
|||||||
|
|
||||||
private static int exitStatus = 0;
|
private static int exitStatus = 0;
|
||||||
|
|
||||||
|
private static int biTypePF(int biType) {
|
||||||
|
ByteOrder byteOrder = ByteOrder.nativeOrder();
|
||||||
|
switch(biType) {
|
||||||
|
case BufferedImage.TYPE_3BYTE_BGR:
|
||||||
|
return TJ.PF_BGR;
|
||||||
|
case BufferedImage.TYPE_4BYTE_ABGR:
|
||||||
|
case BufferedImage.TYPE_4BYTE_ABGR_PRE:
|
||||||
|
return TJ.PF_XBGR;
|
||||||
|
case BufferedImage.TYPE_BYTE_GRAY:
|
||||||
|
return TJ.PF_GRAY;
|
||||||
|
case BufferedImage.TYPE_INT_BGR:
|
||||||
|
if(byteOrder == ByteOrder.BIG_ENDIAN)
|
||||||
|
return TJ.PF_XBGR;
|
||||||
|
else
|
||||||
|
return TJ.PF_RGBX;
|
||||||
|
case BufferedImage.TYPE_INT_RGB:
|
||||||
|
case BufferedImage.TYPE_INT_ARGB:
|
||||||
|
case BufferedImage.TYPE_INT_ARGB_PRE:
|
||||||
|
if(byteOrder == ByteOrder.BIG_ENDIAN)
|
||||||
|
return TJ.PF_XRGB;
|
||||||
|
else
|
||||||
|
return TJ.PF_BGRX;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String biTypeStr(int biType) {
|
||||||
|
switch(biType) {
|
||||||
|
case BufferedImage.TYPE_3BYTE_BGR:
|
||||||
|
return "3BYTE_BGR";
|
||||||
|
case BufferedImage.TYPE_4BYTE_ABGR:
|
||||||
|
return "4BYTE_ABGR";
|
||||||
|
case BufferedImage.TYPE_4BYTE_ABGR_PRE:
|
||||||
|
return "4BYTE_ABGR_PRE";
|
||||||
|
case BufferedImage.TYPE_BYTE_GRAY:
|
||||||
|
return "BYTE_GRAY";
|
||||||
|
case BufferedImage.TYPE_INT_BGR:
|
||||||
|
return "INT_BGR";
|
||||||
|
case BufferedImage.TYPE_INT_RGB:
|
||||||
|
return "INT_RGB";
|
||||||
|
case BufferedImage.TYPE_INT_ARGB:
|
||||||
|
return "INT_ARGB";
|
||||||
|
case BufferedImage.TYPE_INT_ARGB_PRE:
|
||||||
|
return "INT_ARGB_PRE";
|
||||||
|
}
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static double getTime() {
|
private static double getTime() {
|
||||||
return (double)System.nanoTime() / 1.0e9;
|
return (double)System.nanoTime() / 1.0e9;
|
||||||
}
|
}
|
||||||
@@ -99,6 +154,7 @@ public class TJUnitTest {
|
|||||||
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);
|
||||||
|
int aoffset = alphaOffset[pf];
|
||||||
int ps = TJ.getPixelSize(pf);
|
int ps = TJ.getPixelSize(pf);
|
||||||
int index, row, col, halfway = 16;
|
int index, row, col, halfway = 16;
|
||||||
|
|
||||||
@@ -132,6 +188,7 @@ public class TJUnitTest {
|
|||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -141,6 +198,7 @@ public class TJUnitTest {
|
|||||||
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;
|
||||||
|
int ashift = alphaOffset[pf] * 8;
|
||||||
int index, row, col, halfway = 16;
|
int index, row, col, halfway = 16;
|
||||||
|
|
||||||
Arrays.fill(buf, 0);
|
Arrays.fill(buf, 0);
|
||||||
@@ -160,6 +218,7 @@ public class TJUnitTest {
|
|||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -167,9 +226,11 @@ public class TJUnitTest {
|
|||||||
private static void initImg(BufferedImage img, int pf, int flags)
|
private static void initImg(BufferedImage img, int pf, int flags)
|
||||||
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_PRE) {
|
||||||
SinglePixelPackedSampleModel sm =
|
SinglePixelPackedSampleModel sm =
|
||||||
(SinglePixelPackedSampleModel)img.getSampleModel();
|
(SinglePixelPackedSampleModel)img.getSampleModel();
|
||||||
int pitch = sm.getScanlineStride();
|
int pitch = sm.getScanlineStride();
|
||||||
@@ -218,6 +279,7 @@ public class TJUnitTest {
|
|||||||
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);
|
||||||
|
int aoffset = alphaOffset[pf];
|
||||||
int ps = TJ.getPixelSize(pf);
|
int ps = TJ.getPixelSize(pf);
|
||||||
int index, row, col, retval = 1;
|
int index, row, col, retval = 1;
|
||||||
int halfway = 16 * sf.getNum() / sf.getDenom();
|
int halfway = 16 * sf.getNum() / sf.getDenom();
|
||||||
@@ -232,6 +294,7 @@ public class TJUnitTest {
|
|||||||
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;
|
||||||
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");
|
||||||
@@ -268,6 +331,7 @@ public class TJUnitTest {
|
|||||||
checkVal0(row, col, b, "B");
|
checkVal0(row, col, b, "B");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
checkVal255(row, col, a, "A");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -297,6 +361,7 @@ public class TJUnitTest {
|
|||||||
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;
|
||||||
|
int ashift = alphaOffset[pf] * 8;
|
||||||
int index, row, col, retval = 1;
|
int index, row, col, retval = 1;
|
||||||
int halfway = 16 * sf.getNum() / sf.getDenom();
|
int halfway = 16 * sf.getNum() / sf.getDenom();
|
||||||
int blockSize = 8 * sf.getNum() / sf.getDenom();
|
int blockSize = 8 * sf.getNum() / sf.getDenom();
|
||||||
@@ -310,6 +375,7 @@ public class TJUnitTest {
|
|||||||
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;
|
||||||
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");
|
||||||
@@ -346,6 +412,7 @@ public class TJUnitTest {
|
|||||||
checkVal0(row, col, b, "B");
|
checkVal0(row, col, b, "B");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
checkVal255(row, col, a, "A");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -373,9 +440,11 @@ public class TJUnitTest {
|
|||||||
private static int checkImg(BufferedImage img, int pf,
|
private static int checkImg(BufferedImage img, int pf,
|
||||||
int subsamp, TJScalingFactor sf, int flags) throws Exception {
|
int subsamp, 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_PRE) {
|
||||||
SinglePixelPackedSampleModel sm =
|
SinglePixelPackedSampleModel sm =
|
||||||
(SinglePixelPackedSampleModel)img.getSampleModel();
|
(SinglePixelPackedSampleModel)img.getSampleModel();
|
||||||
int pitch = sm.getScanlineStride();
|
int pitch = sm.getScanlineStride();
|
||||||
@@ -506,11 +575,17 @@ public class TJUnitTest {
|
|||||||
BufferedImage img = null;
|
BufferedImage img = null;
|
||||||
String pfStr;
|
String pfStr;
|
||||||
double t;
|
double t;
|
||||||
int size = 0, ps = TJ.getPixelSize(pf);
|
int size = 0, ps, imgType = pf;
|
||||||
|
|
||||||
pfStr = pixFormatStr[pf];
|
if (bi) {
|
||||||
|
pf = biTypePF(imgType);
|
||||||
|
pfStr = biTypeStr(imgType);
|
||||||
|
}
|
||||||
|
else pfStr = pixFormatStr[pf];
|
||||||
|
ps = TJ.getPixelSize(pf);
|
||||||
|
|
||||||
System.out.print(pfStr + " ");
|
System.out.print(pfStr + " ");
|
||||||
|
if(bi) System.out.print("(" + pixFormatStr[pf] + ") ");
|
||||||
if((flags & TJ.FLAG_BOTTOMUP) != 0) System.out.print("Bottom-Up");
|
if((flags & TJ.FLAG_BOTTOMUP) != 0) System.out.print("Bottom-Up");
|
||||||
else System.out.print("Top-Down ");
|
else System.out.print("Top-Down ");
|
||||||
System.out.print(" -> " + subNameLong[subsamp] + " ");
|
System.out.print(" -> " + subNameLong[subsamp] + " ");
|
||||||
@@ -518,7 +593,7 @@ public class TJUnitTest {
|
|||||||
else System.out.print("Q" + jpegQual + " ... ");
|
else System.out.print("Q" + jpegQual + " ... ");
|
||||||
|
|
||||||
if(bi) {
|
if(bi) {
|
||||||
img = new BufferedImage(w, h, biType[pf]);
|
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") + "_"
|
||||||
@@ -578,18 +653,24 @@ public class TJUnitTest {
|
|||||||
double t;
|
double t;
|
||||||
int scaledWidth = sf.getScaled(w);
|
int scaledWidth = sf.getScaled(w);
|
||||||
int scaledHeight = sf.getScaled(h);
|
int scaledHeight = sf.getScaled(h);
|
||||||
int temp1, temp2;
|
int temp1, temp2, imgType = pf;
|
||||||
BufferedImage img = null;
|
BufferedImage img = null;
|
||||||
byte[] dstBuf = null;
|
byte[] dstBuf = null;
|
||||||
|
|
||||||
if(yuv == YUVENCODE) return;
|
if(yuv == YUVENCODE) return;
|
||||||
|
|
||||||
pfStr = pixFormatStr[pf];
|
if (bi) {
|
||||||
|
pf = biTypePF(imgType);
|
||||||
|
pfStr = biTypeStr(imgType);
|
||||||
|
}
|
||||||
|
else 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((flags & TJ.FLAG_BOTTOMUP) != 0) System.out.print("Bottom-Up ");
|
if((flags & TJ.FLAG_BOTTOMUP) != 0) System.out.print("Bottom-Up ");
|
||||||
else System.out.print("Top-Down ");
|
else System.out.print("Top-Down ");
|
||||||
if(!sf.isOne())
|
if(!sf.isOne())
|
||||||
@@ -613,7 +694,7 @@ public class TJUnitTest {
|
|||||||
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, biType[pf], 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;
|
||||||
@@ -775,7 +856,7 @@ public class TJUnitTest {
|
|||||||
doTest(39, 41, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_440,
|
doTest(39, 41, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_440,
|
||||||
testName);
|
testName);
|
||||||
}
|
}
|
||||||
doTest(35, 39, onlyGray, TJ.SAMP_GRAY, testName);
|
doTest(35, 39, bi ? onlyGrayBI : onlyGray, TJ.SAMP_GRAY, testName);
|
||||||
doTest(39, 41, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_GRAY,
|
doTest(39, 41, bi ? _3byteFormatsBI : _3byteFormats, TJ.SAMP_GRAY,
|
||||||
testName);
|
testName);
|
||||||
doTest(41, 35, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_GRAY,
|
doTest(41, 35, bi ? _4byteFormatsBI : _4byteFormats, TJ.SAMP_GRAY,
|
||||||
|
|||||||
@@ -190,6 +190,9 @@ public class TJCompressor {
|
|||||||
switch(srcImage.getType()) {
|
switch(srcImage.getType()) {
|
||||||
case BufferedImage.TYPE_3BYTE_BGR:
|
case BufferedImage.TYPE_3BYTE_BGR:
|
||||||
pixelFormat = TJ.PF_BGR; break;
|
pixelFormat = TJ.PF_BGR; break;
|
||||||
|
case BufferedImage.TYPE_4BYTE_ABGR:
|
||||||
|
case BufferedImage.TYPE_4BYTE_ABGR_PRE:
|
||||||
|
pixelFormat = TJ.PF_XBGR; break;
|
||||||
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:
|
||||||
@@ -199,6 +202,8 @@ public class TJCompressor {
|
|||||||
pixelFormat = TJ.PF_RGBX;
|
pixelFormat = TJ.PF_RGBX;
|
||||||
intPixels = true; break;
|
intPixels = true; break;
|
||||||
case BufferedImage.TYPE_INT_RGB:
|
case BufferedImage.TYPE_INT_RGB:
|
||||||
|
case BufferedImage.TYPE_INT_ARGB:
|
||||||
|
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
|
||||||
@@ -329,6 +334,9 @@ public class TJCompressor {
|
|||||||
switch(srcImage.getType()) {
|
switch(srcImage.getType()) {
|
||||||
case BufferedImage.TYPE_3BYTE_BGR:
|
case BufferedImage.TYPE_3BYTE_BGR:
|
||||||
pixelFormat = TJ.PF_BGR; break;
|
pixelFormat = TJ.PF_BGR; break;
|
||||||
|
case BufferedImage.TYPE_4BYTE_ABGR:
|
||||||
|
case BufferedImage.TYPE_4BYTE_ABGR_PRE:
|
||||||
|
pixelFormat = TJ.PF_XBGR; break;
|
||||||
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:
|
||||||
@@ -338,6 +346,8 @@ public class TJCompressor {
|
|||||||
pixelFormat = TJ.PF_RGBX;
|
pixelFormat = TJ.PF_RGBX;
|
||||||
intPixels = true; break;
|
intPixels = true; break;
|
||||||
case BufferedImage.TYPE_INT_RGB:
|
case BufferedImage.TYPE_INT_RGB:
|
||||||
|
case BufferedImage.TYPE_INT_ARGB:
|
||||||
|
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
|
||||||
|
|||||||
@@ -387,6 +387,9 @@ public class TJDecompressor {
|
|||||||
switch(dstImage.getType()) {
|
switch(dstImage.getType()) {
|
||||||
case BufferedImage.TYPE_3BYTE_BGR:
|
case BufferedImage.TYPE_3BYTE_BGR:
|
||||||
pixelFormat = TJ.PF_BGR; break;
|
pixelFormat = TJ.PF_BGR; break;
|
||||||
|
case BufferedImage.TYPE_4BYTE_ABGR:
|
||||||
|
case BufferedImage.TYPE_4BYTE_ABGR_PRE:
|
||||||
|
pixelFormat = TJ.PF_XBGR; break;
|
||||||
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:
|
||||||
@@ -396,6 +399,8 @@ public class TJDecompressor {
|
|||||||
pixelFormat = TJ.PF_RGBX;
|
pixelFormat = TJ.PF_RGBX;
|
||||||
intPixels = true; break;
|
intPixels = true; break;
|
||||||
case BufferedImage.TYPE_INT_RGB:
|
case BufferedImage.TYPE_INT_RGB:
|
||||||
|
case BufferedImage.TYPE_INT_ARGB:
|
||||||
|
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
|
||||||
|
|||||||
@@ -54,6 +54,10 @@ ycc_rgb_convert_internal (j_decompress_ptr cinfo,
|
|||||||
y = GETJSAMPLE(inptr0[col]);
|
y = GETJSAMPLE(inptr0[col]);
|
||||||
cb = GETJSAMPLE(inptr1[col]);
|
cb = GETJSAMPLE(inptr1[col]);
|
||||||
cr = GETJSAMPLE(inptr2[col]);
|
cr = GETJSAMPLE(inptr2[col]);
|
||||||
|
/* Initialize 4-byte pixels so the alpha channel will be opaque */
|
||||||
|
#if RGB_PIXELSIZE == 4
|
||||||
|
*(unsigned int *)outptr = 0xFFFFFFFF;
|
||||||
|
#endif
|
||||||
/* Range-limiting is essential due to noise introduced by DCT losses. */
|
/* Range-limiting is essential due to noise introduced by DCT losses. */
|
||||||
outptr[RGB_RED] = range_limit[y + Crrtab[cr]];
|
outptr[RGB_RED] = range_limit[y + Crrtab[cr]];
|
||||||
outptr[RGB_GREEN] = range_limit[y +
|
outptr[RGB_GREEN] = range_limit[y +
|
||||||
@@ -86,6 +90,10 @@ gray_rgb_convert_internal (j_decompress_ptr cinfo,
|
|||||||
inptr = input_buf[0][input_row++];
|
inptr = input_buf[0][input_row++];
|
||||||
outptr = *output_buf++;
|
outptr = *output_buf++;
|
||||||
for (col = 0; col < num_cols; col++) {
|
for (col = 0; col < num_cols; col++) {
|
||||||
|
/* Initialize 4-byte pixels so the alpha channel will be opaque */
|
||||||
|
#if RGB_PIXELSIZE == 4
|
||||||
|
*(unsigned int *)outptr = 0xFFFFFFFF;
|
||||||
|
#endif
|
||||||
/* We can dispense with GETJSAMPLE() here */
|
/* We can dispense with GETJSAMPLE() here */
|
||||||
outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
|
outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
|
||||||
outptr += RGB_PIXELSIZE;
|
outptr += RGB_PIXELSIZE;
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ definev(EXT_XRGB_GREEN)
|
|||||||
definev(EXT_XRGB_BLUE)
|
definev(EXT_XRGB_BLUE)
|
||||||
definev(EXT_XRGB_PIXELSIZE)
|
definev(EXT_XRGB_PIXELSIZE)
|
||||||
|
|
||||||
|
%define RGBX_FILLER_0XFF 1
|
||||||
|
|
||||||
; Representation of a single sample (pixel element value).
|
; Representation of a single sample (pixel element value).
|
||||||
; On this SIMD implementation, this must be 'unsigned char'.
|
; On this SIMD implementation, this must be 'unsigned char'.
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ const char *pixFormatStr[TJ_NUMPF]=
|
|||||||
"RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "Grayscale"
|
"RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "Grayscale"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const int alphaOffset[TJ_NUMPF] = {-1, -1, 3, 3, 0, 0, -1};
|
||||||
|
|
||||||
const int _3byteFormats[]={TJPF_RGB, TJPF_BGR};
|
const int _3byteFormats[]={TJPF_RGB, TJPF_BGR};
|
||||||
const int _4byteFormats[]={TJPF_RGBX, TJPF_BGRX, TJPF_XBGR, TJPF_XRGB};
|
const int _4byteFormats[]={TJPF_RGBX, TJPF_BGRX, TJPF_XBGR, TJPF_XRGB};
|
||||||
const int _onlyGray[]={TJPF_GRAY};
|
const int _onlyGray[]={TJPF_GRAY};
|
||||||
@@ -156,6 +158,7 @@ int checkBuf(unsigned char *buf, int w, int h, int pf, int subsamp,
|
|||||||
int roffset=tjRedOffset[pf];
|
int roffset=tjRedOffset[pf];
|
||||||
int goffset=tjGreenOffset[pf];
|
int goffset=tjGreenOffset[pf];
|
||||||
int boffset=tjBlueOffset[pf];
|
int boffset=tjBlueOffset[pf];
|
||||||
|
int aoffset=alphaOffset[pf];
|
||||||
int ps=tjPixelSize[pf];
|
int ps=tjPixelSize[pf];
|
||||||
int index, row, col, retval=1;
|
int index, row, col, retval=1;
|
||||||
int halfway=16*sf.num/sf.denom;
|
int halfway=16*sf.num/sf.denom;
|
||||||
@@ -165,12 +168,13 @@ int checkBuf(unsigned char *buf, int w, int h, int pf, int subsamp,
|
|||||||
{
|
{
|
||||||
for(col=0; col<w; col++)
|
for(col=0; col<w; col++)
|
||||||
{
|
{
|
||||||
unsigned char r, g, b;
|
unsigned char r, g, b, a;
|
||||||
if(flags&TJFLAG_BOTTOMUP) index=(h-row-1)*w+col;
|
if(flags&TJFLAG_BOTTOMUP) index=(h-row-1)*w+col;
|
||||||
else index=row*w+col;
|
else index=row*w+col;
|
||||||
r=buf[index*ps+roffset];
|
r=buf[index*ps+roffset];
|
||||||
g=buf[index*ps+goffset];
|
g=buf[index*ps+goffset];
|
||||||
b=buf[index*ps+boffset];
|
b=buf[index*ps+boffset];
|
||||||
|
a=aoffset>=0? buf[index*ps+aoffset]:0xFF;
|
||||||
if(((row/blocksize)+(col/blocksize))%2==0)
|
if(((row/blocksize)+(col/blocksize))%2==0)
|
||||||
{
|
{
|
||||||
if(row<halfway)
|
if(row<halfway)
|
||||||
@@ -207,6 +211,7 @@ int checkBuf(unsigned char *buf, int w, int h, int pf, int subsamp,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
checkval255(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user