mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2026-05-01 00:00:02 -04:00
Merge branch 'master' of https://github.com/haraldk/TwelveMonkeys
Conflicts: imageio/imageio-reference/pom.xml imageio/imageio-thumbsdb/pom.xml
This commit is contained in:
+13
-8
@@ -212,7 +212,7 @@ public class JPEGImageReader extends ImageReaderBase {
|
||||
@Override
|
||||
public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) throws IOException {
|
||||
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) {
|
||||
ArrayList<ImageTypeSpecifier> typeList = new ArrayList<ImageTypeSpecifier>();
|
||||
@@ -266,7 +266,7 @@ public class JPEGImageReader extends ImageReaderBase {
|
||||
}
|
||||
|
||||
// Otherwise, consult the image metadata
|
||||
JPEGColorSpace csType = getSourceCSType(getAdobeDCT(), getSOF());
|
||||
JPEGColorSpace csType = getSourceCSType(getJFIF(), getAdobeDCT(), getSOF());
|
||||
|
||||
switch (csType) {
|
||||
case CMYK:
|
||||
@@ -318,7 +318,7 @@ public class JPEGImageReader extends ImageReaderBase {
|
||||
ICC_Profile profile = getEmbeddedICCProfile(false);
|
||||
AdobeDCTSegment adobeDCT = getAdobeDCT();
|
||||
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)
|
||||
// - or only filter out the bad ICC profiles in the JPEGSegmentImageInputStream.
|
||||
@@ -438,7 +438,7 @@ public class JPEGImageReader extends ImageReaderBase {
|
||||
// Unfortunately looping is slower than reading all at once, but
|
||||
// that requires 2 x memory or more, so a few steps is an ok compromise I guess
|
||||
try {
|
||||
final int step = Math.max(1024, srcRegion.height / 10); // * param.getSourceYSubsampling(); // TODO: Using a multiple of 8 is probably a good idea for JPEG
|
||||
final int step = Math.max(1024, srcRegion.height / 10); // TODO: Using a multiple of 8 is probably a good idea for JPEG
|
||||
final int srcMaxY = srcRegion.y + srcRegion.height;
|
||||
int destY = dstRegion.y;
|
||||
|
||||
@@ -452,6 +452,11 @@ public class JPEGImageReader extends ImageReaderBase {
|
||||
// Let the progress delegator handle progress, using corrected range
|
||||
progressDelegator.updateProgressRange(100f * (y + scan) / srcRegion.height);
|
||||
|
||||
// Make sure subsampling is within bounds
|
||||
if (scan <= param.getSubsamplingYOffset()) {
|
||||
param.setSourceSubsampling(param.getSourceXSubsampling(), param.getSourceYSubsampling(), param.getSubsamplingXOffset(), scan - 1);
|
||||
}
|
||||
|
||||
Rectangle subRegion = new Rectangle(srcRegion.x, y, srcRegion.width, scan);
|
||||
param.setSourceRegion(subRegion);
|
||||
Raster raster = delegate.readRaster(imageIndex, param); // non-converted
|
||||
@@ -503,7 +508,7 @@ public class JPEGImageReader extends ImageReaderBase {
|
||||
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:
|
||||
|
||||
@@ -590,7 +595,7 @@ public class JPEGImageReader extends ImageReaderBase {
|
||||
}
|
||||
}
|
||||
|
||||
return JPEGColorSpace.RGB;
|
||||
return jfif != null ? JPEGColorSpace.YCbCr : JPEGColorSpace.RGB;
|
||||
}
|
||||
case 4:
|
||||
if (startOfFrame.components[0].id == 1 && startOfFrame.components[1].id == 2 && startOfFrame.components[2].id == 3 && startOfFrame.components[3].id == 4) {
|
||||
@@ -633,10 +638,10 @@ public class JPEGImageReader extends ImageReaderBase {
|
||||
// See ColorConvertOp#filter(Raster, WritableRaster)
|
||||
|
||||
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) {
|
||||
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
|
||||
|
||||
|
||||
+143
@@ -30,6 +30,7 @@ package com.twelvemonkeys.imageio.plugins.jpeg;
|
||||
|
||||
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTestCase;
|
||||
import org.hamcrest.core.IsInstanceOf;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mockito.internal.matchers.GreaterThan;
|
||||
import org.w3c.dom.Element;
|
||||
@@ -329,6 +330,32 @@ public class JPEGImageReaderTest extends ImageReaderAbstractTestCase<JPEGImageRe
|
||||
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
|
||||
public void testCorbisRGB() throws IOException {
|
||||
// Special case, throws exception below without special treatment
|
||||
@@ -659,6 +686,122 @@ public class JPEGImageReaderTest extends ImageReaderAbstractTestCase<JPEGImageRe
|
||||
}
|
||||
}
|
||||
|
||||
// Regression: Test subsampling offset within of bounds
|
||||
// NOTE: These tests assumes the reader will read at least 1024 scanlines (if available) each iteration,
|
||||
// this might change in the future. If so, the tests will no longer test what tey are supposed to....
|
||||
@Test
|
||||
public void testReadSubsamplingBounds1028() throws IOException {
|
||||
JPEGImageReader reader = createReader();
|
||||
reader.setInput(ImageIO.createImageInputStream(getClassLoaderResource("/jpeg/read-error1028.jpg")));
|
||||
|
||||
ImageReadParam param = reader.getDefaultReadParam();
|
||||
param.setSourceSubsampling(3, 3, 1, 1);
|
||||
|
||||
BufferedImage image = reader.read(0, param);
|
||||
|
||||
assertNotNull(image);
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void testReadSubsamplingNotSkippingLines1028() throws IOException {
|
||||
JPEGImageReader reader = createReader();
|
||||
reader.setInput(ImageIO.createImageInputStream(getClassLoaderResource("/jpeg/read-error1028.jpg")));
|
||||
|
||||
ImageReadParam param = reader.getDefaultReadParam();
|
||||
param.setSourceSubsampling(3, 3, 1, 1);
|
||||
|
||||
BufferedImage image = reader.read(0, param);
|
||||
|
||||
assertNotNull(image);
|
||||
|
||||
// Make sure correct color is actually read, not just left empty
|
||||
assertEquals(0xfefefd, image.getRGB(0, image.getHeight() - 2) & 0xffffff);
|
||||
assertEquals(0xfefefd, image.getRGB(0, image.getHeight() - 1) & 0xffffff);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadSubsamplingBounds1027() throws IOException {
|
||||
JPEGImageReader reader = createReader();
|
||||
reader.setInput(ImageIO.createImageInputStream(getClassLoaderResource("/jpeg/read-error1027.jpg")));
|
||||
|
||||
ImageReadParam param = reader.getDefaultReadParam();
|
||||
param.setSourceSubsampling(3, 3, 2, 2);
|
||||
|
||||
BufferedImage image = reader.read(0, param);
|
||||
|
||||
assertNotNull(image);
|
||||
|
||||
// Make sure correct color is actually read, not just left empty
|
||||
assertEquals(0xfefefd, image.getRGB(0, image.getHeight() - 2) & 0xffffff);
|
||||
assertEquals(0xfefefd, image.getRGB(0, image.getHeight() - 1) & 0xffffff);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadSubsamplingBounds1026() throws IOException {
|
||||
JPEGImageReader reader = createReader();
|
||||
reader.setInput(ImageIO.createImageInputStream(getClassLoaderResource("/jpeg/read-error1026.jpg")));
|
||||
|
||||
ImageReadParam param = reader.getDefaultReadParam();
|
||||
param.setSourceSubsampling(3, 3, 1, 1);
|
||||
|
||||
BufferedImage image = reader.read(0, param);
|
||||
|
||||
assertNotNull(image);
|
||||
|
||||
// Make sure correct color is actually read, not just left empty
|
||||
assertEquals(0xfefefd, image.getRGB(0, image.getHeight() - 2) & 0xffffff);
|
||||
assertEquals(0xfefefd, image.getRGB(0, image.getHeight() - 1) & 0xffffff);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadSubsamplingBounds1025() throws IOException {
|
||||
JPEGImageReader reader = createReader();
|
||||
reader.setInput(ImageIO.createImageInputStream(getClassLoaderResource("/jpeg/read-error1025.jpg")));
|
||||
|
||||
ImageReadParam param = reader.getDefaultReadParam();
|
||||
param.setSourceSubsampling(3, 3, 1, 1);
|
||||
|
||||
BufferedImage image = reader.read(0, param);
|
||||
|
||||
assertNotNull(image);
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void testReadSubsamplingNotSkippingLines1025() throws IOException {
|
||||
JPEGImageReader reader = createReader();
|
||||
reader.setInput(ImageIO.createImageInputStream(getClassLoaderResource("/jpeg/read-error1025.jpg")));
|
||||
|
||||
ImageReadParam param = reader.getDefaultReadParam();
|
||||
param.setSourceSubsampling(3, 3, 1, 1);
|
||||
|
||||
BufferedImage image = reader.read(0, param);
|
||||
|
||||
assertNotNull(image);
|
||||
|
||||
// Make sure correct color is actually read, not just left empty
|
||||
assertEquals(0xfefefd, image.getRGB(0, image.getHeight() - 2) & 0xffffff);
|
||||
assertEquals(0xfefefd, image.getRGB(0, image.getHeight() - 1) & 0xffffff);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadSubsamplingBounds1024() throws IOException {
|
||||
JPEGImageReader reader = createReader();
|
||||
reader.setInput(ImageIO.createImageInputStream(getClassLoaderResource("/jpeg/read-error1024.jpg")));
|
||||
|
||||
ImageReadParam param = reader.getDefaultReadParam();
|
||||
param.setSourceSubsampling(3, 3, 1, 1);
|
||||
|
||||
BufferedImage image = reader.read(0, param);
|
||||
|
||||
assertNotNull(image);
|
||||
|
||||
// Make sure correct color is actually read, not just left empty
|
||||
assertEquals(0xfefefd, image.getRGB(0, image.getHeight() - 2) & 0xffffff);
|
||||
assertEquals(0xfefefd, image.getRGB(0, image.getHeight() - 1) & 0xffffff);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testXDensityOutOfRangeIssue() throws IOException {
|
||||
// Image has JFIF with x/y density 0
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
Reference in New Issue
Block a user