#404, #406: Better detection of source color space for JPEG-in-TIFF.

This commit is contained in:
Harald Kuhr
2018-03-06 22:48:07 +01:00
parent 633e5cc6a2
commit 127e6c0acb
3 changed files with 195 additions and 41 deletions
@@ -327,7 +327,7 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest<TIFFImageReader
@Test
public void testReadYCbCrJPEGAssumedRGB() throws IOException {
// Problematic test data, which is YCbCr encoded (as correctly specified by the PhotometricInterpretation tag,
// but the JPEGImageReader will detect the data as RGB due to non-subsampled data and SOF ids.
// but the JPEGImageReader will detect the data as RGB due to non-subsampled data and SOF ids).
TestData testData = new TestData(getClassLoaderResource("/tiff/xerox-jpeg-ycbcr-weird-coefficients.tif"), new Dimension(2482, 3520));
try (ImageInputStream stream = testData.getInputStream()) {
@@ -335,32 +335,65 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest<TIFFImageReader
reader.setInput(stream);
ImageReadParam param = reader.getDefaultReadParam();
// TODO: There's a bug in reading with source region for the raster case...
// param.setSourceRegion(new Rectangle(8, 8));
param.setSourceRegion(new Rectangle(8, 8));
BufferedImage image = reader.read(0, param);
assertNotNull(image);
// assertEquals(new Dimension(8, 8), new Dimension(image.getWidth(), image.getHeight()));
assertEquals(testData.getDimension(0), new Dimension(image.getWidth(), image.getHeight()));
assertEquals(new Dimension(8, 8), new Dimension(image.getWidth(), image.getHeight()));
// The pixel at 0, 0 should be white(-ish), not red!
// The pixel at x, y should be white(-ish), not red!
// NOTE: The image contains some weird custom YCbCr coefficients, which are roughly
// 0.299, 0.587, 0.144, instead of the standard 0.299, 0.587, 0.114 (the last/blue coefficient differs)
// this will make the background bright purple, rather than pure white as it would have been
// 0.299, 0.587, 0.144, instead of the standard 0.299, 0.587, 0.114 (the last/blue coefficient differs).
// This will make the background bright purple, rather than pure white as it would have been
// with standard coefficients. Could be a typo/bug in the encoder or intentional.
// Some/most software ignores the custom coefficients, and decodes the image as white background...
int argb = image.getRGB(0, 0);
assertEquals("Alpha", 0xff, (argb >>> 24) & 0xff);
assertEquals("Red", 0xff, (argb >> 16) & 0xff);
assertEquals("Green", 0xf2, (argb >> 8) & 0xff);
assertEquals("Blue", 0xff, argb & 0xff);
for (int y = 0; y < 8; y++) {
for (int x = 0; x < 8; x++) {
int argb = image.getRGB(x, y);
assertEquals("Alpha", 0xff, (argb >>> 24) & 0xff);
assertEquals("Red", 0xff, (argb >> 16) & 0xff);
assertEquals("Green", 0xff, (argb >> 8) & 0xff, 13); // Depending on coeffs
assertEquals("Blue", 0xff, argb & 0xff);
}
}
}
}
@Test
public void testReadRGBJPEGAssumedYCbCr() throws IOException {
// Problematic test data, which is RGB encoded (as correctly specified by the PhotometricInterpretation tag,
// but the JPEGImageReader will detect the data as YCbCr).
// There is also bogus YCbCrSubSampling fields in the TIFF structure.
TestData testData = new TestData(getClassLoaderResource("/tiff/twain-rgb-jpeg-with-bogus-ycbcr-subsampling.tif"), new Dimension(850, 1100));
try (ImageInputStream stream = testData.getInputStream()) {
TIFFImageReader reader = createReader();
reader.setInput(stream);
ImageReadParam param = reader.getDefaultReadParam();
param.setSourceRegion(new Rectangle(8, 8));
BufferedImage image = reader.read(0, param);
assertNotNull(image);
assertEquals(new Dimension(8, 8), new Dimension(image.getWidth(), image.getHeight()));
// The pixel at x, y should be white, not pink!
for (int y = 0; y < 8; y++) {
for (int x = 0; x < 8; x++) {
int argb = image.getRGB(x, y);
assertEquals("Alpha", 0xff, (argb >>> 24) & 0xff);
assertEquals("Red", 0xff, (argb >> 16) & 0xff);
assertEquals("Green", 0xff, (argb >> 8) & 0xff);
assertEquals("Blue", 0xff, argb & 0xff);
}
}
}
}
@Test
public void testReadJPEGRasterCaseWithSrcRegion() throws IOException {
// Problematic test data, which is YCbCr encoded (as correctly specified by the PhotometricInterpretation tag,
// but the JPEGImageReader will detect the data as RGB due to non-subsampled data and SOF ids.
// but the JPEGImageReader will detect the data as RGB due to non-subsampled data and SOF ids).
TestData testData = new TestData(getClassLoaderResource("/tiff/xerox-jpeg-ycbcr-weird-coefficients.tif"), new Dimension(2482, 3520));
try (ImageInputStream stream = testData.getInputStream()) {