mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-04 03:55:28 -04:00
TMI-38: Fixed a bug in the getSourceCS method, that incorrectly identified non-subsampled JFIF files, as RGB instead of YCbCr.
This commit is contained in:
parent
5c735674f0
commit
037a47ca2a
@ -212,7 +212,7 @@ public class JPEGImageReader extends ImageReaderBase {
|
|||||||
@Override
|
@Override
|
||||||
public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) throws IOException {
|
public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) throws IOException {
|
||||||
Iterator<ImageTypeSpecifier> types = delegate.getImageTypes(imageIndex);
|
Iterator<ImageTypeSpecifier> types = delegate.getImageTypes(imageIndex);
|
||||||
JPEGColorSpace csType = getSourceCSType(getAdobeDCT(), getSOF());
|
JPEGColorSpace csType = getSourceCSType(getJFIF(), getAdobeDCT(), getSOF());
|
||||||
|
|
||||||
if (types == null || !types.hasNext() || csType == JPEGColorSpace.CMYK || csType == JPEGColorSpace.YCCK) {
|
if (types == null || !types.hasNext() || csType == JPEGColorSpace.CMYK || csType == JPEGColorSpace.YCCK) {
|
||||||
ArrayList<ImageTypeSpecifier> typeList = new ArrayList<ImageTypeSpecifier>();
|
ArrayList<ImageTypeSpecifier> typeList = new ArrayList<ImageTypeSpecifier>();
|
||||||
@ -266,7 +266,7 @@ public class JPEGImageReader extends ImageReaderBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, consult the image metadata
|
// Otherwise, consult the image metadata
|
||||||
JPEGColorSpace csType = getSourceCSType(getAdobeDCT(), getSOF());
|
JPEGColorSpace csType = getSourceCSType(getJFIF(), getAdobeDCT(), getSOF());
|
||||||
|
|
||||||
switch (csType) {
|
switch (csType) {
|
||||||
case CMYK:
|
case CMYK:
|
||||||
@ -318,7 +318,7 @@ public class JPEGImageReader extends ImageReaderBase {
|
|||||||
ICC_Profile profile = getEmbeddedICCProfile(false);
|
ICC_Profile profile = getEmbeddedICCProfile(false);
|
||||||
AdobeDCTSegment adobeDCT = getAdobeDCT();
|
AdobeDCTSegment adobeDCT = getAdobeDCT();
|
||||||
SOFSegment sof = getSOF();
|
SOFSegment sof = getSOF();
|
||||||
JPEGColorSpace sourceCSType = getSourceCSType(adobeDCT, sof);
|
JPEGColorSpace sourceCSType = getSourceCSType(getJFIF(), adobeDCT, sof);
|
||||||
|
|
||||||
// We need to apply ICC profile unless the profile is sRGB/default gray (whatever that is)
|
// We need to apply ICC profile unless the profile is sRGB/default gray (whatever that is)
|
||||||
// - or only filter out the bad ICC profiles in the JPEGSegmentImageInputStream.
|
// - or only filter out the bad ICC profiles in the JPEGSegmentImageInputStream.
|
||||||
@ -499,7 +499,7 @@ public class JPEGImageReader extends ImageReaderBase {
|
|||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JPEGColorSpace getSourceCSType(AdobeDCTSegment adobeDCT, final SOFSegment startOfFrame) throws IIOException {
|
static JPEGColorSpace getSourceCSType(JFIFSegment jfif, AdobeDCTSegment adobeDCT, final SOFSegment startOfFrame) throws IIOException {
|
||||||
/*
|
/*
|
||||||
ADAPTED from http://download.oracle.com/javase/6/docs/api/javax/imageio/metadata/doc-files/jpeg_metadata.html:
|
ADAPTED from http://download.oracle.com/javase/6/docs/api/javax/imageio/metadata/doc-files/jpeg_metadata.html:
|
||||||
|
|
||||||
@ -586,7 +586,7 @@ public class JPEGImageReader extends ImageReaderBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return JPEGColorSpace.RGB;
|
return jfif != null ? JPEGColorSpace.YCbCr : JPEGColorSpace.RGB;
|
||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
if (startOfFrame.components[0].id == 1 && startOfFrame.components[1].id == 2 && startOfFrame.components[2].id == 3 && startOfFrame.components[3].id == 4) {
|
if (startOfFrame.components[0].id == 1 && startOfFrame.components[1].id == 2 && startOfFrame.components[2].id == 3 && startOfFrame.components[3].id == 4) {
|
||||||
@ -629,10 +629,10 @@ public class JPEGImageReader extends ImageReaderBase {
|
|||||||
// See ColorConvertOp#filter(Raster, WritableRaster)
|
// See ColorConvertOp#filter(Raster, WritableRaster)
|
||||||
|
|
||||||
if (profile != null && profile.getProfileClass() != ICC_Profile.CLASS_DISPLAY) {
|
if (profile != null && profile.getProfileClass() != ICC_Profile.CLASS_DISPLAY) {
|
||||||
byte[] profileData = profile.getData(); // Need to clone entire profile, due to a JDK 7 bug
|
byte[] profileData = profile.getData(); // Need to clone entire profile, due to a OpenJDK bug
|
||||||
|
|
||||||
if (profileData[ICC_Profile.icHdrRenderingIntent] == ICC_Profile.icPerceptual) {
|
if (profileData[ICC_Profile.icHdrRenderingIntent] == ICC_Profile.icPerceptual) {
|
||||||
processWarningOccurred("ICC profile is Perceptual but Display class, treating as Display class");
|
processWarningOccurred("ICC profile is Perceptual, ignoring, treating as Display class");
|
||||||
|
|
||||||
intToBigEndian(ICC_Profile.icSigDisplayClass, profileData, ICC_Profile.icHdrDeviceClass); // Header is first
|
intToBigEndian(ICC_Profile.icSigDisplayClass, profileData, ICC_Profile.icHdrDeviceClass); // Header is first
|
||||||
|
|
||||||
|
@ -329,6 +329,32 @@ public class JPEGImageReaderTest extends ImageReaderAbstractTestCase<JPEGImageRe
|
|||||||
verify(warningListener).warningOccurred(eq(reader), anyString());
|
verify(warningListener).warningOccurred(eq(reader), anyString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testYCbCrNotSubsampledNonstandardChannelIndexes() throws IOException {
|
||||||
|
// Regression: Make sure 3 channel, non-subsampled JFIF, defaults to YCbCr, even if unstandard channel indexes
|
||||||
|
JPEGImageReader reader = createReader();
|
||||||
|
reader.setInput(ImageIO.createImageInputStream(getClassLoaderResource("/jpeg/jfif-ycbcr-no-subsampling-intel.jpg")));
|
||||||
|
|
||||||
|
assertEquals(600, reader.getWidth(0));
|
||||||
|
assertEquals(600, reader.getHeight(0));
|
||||||
|
|
||||||
|
ImageReadParam param = reader.getDefaultReadParam();
|
||||||
|
param.setSourceRegion(new Rectangle(8, 8));
|
||||||
|
|
||||||
|
BufferedImage image = reader.read(0, param);
|
||||||
|
|
||||||
|
assertNotNull(image);
|
||||||
|
assertEquals(8, image.getWidth());
|
||||||
|
assertEquals(8, image.getHeight());
|
||||||
|
|
||||||
|
// QnD test: Make sure all pixels are white (if treated as RGB, they will be pink-ish)
|
||||||
|
for (int y = 0; y < image.getHeight(); y++) {
|
||||||
|
for (int x = 0; x < image.getWidth(); x++) {
|
||||||
|
assertEquals(0xffffff, image.getRGB(x, y) & 0xffffff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCorbisRGB() throws IOException {
|
public void testCorbisRGB() throws IOException {
|
||||||
// Special case, throws exception below without special treatment
|
// Special case, throws exception below without special treatment
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
Loading…
x
Reference in New Issue
Block a user