TMI-67: Handle broken old-style-jpeg from Snowbound software.

This commit is contained in:
Harald Kuhr 2014-10-09 18:26:40 +02:00
parent 35f63ab972
commit 00e68d6035
3 changed files with 51 additions and 2 deletions

View File

@ -764,7 +764,7 @@ public class TIFFImageReader extends ImageReaderBase {
int jpegLenght = getValueAsIntWithDefault(TIFF.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH, -1);
// TODO: 515/JPEGRestartInterval (may be absent)
// Currently ignored
// Currently ignored (for lossless only)
// 517/JPEGLosslessPredictors
// 518/JPEGPointTransforms
@ -782,6 +782,33 @@ public class TIFFImageReader extends ImageReaderBase {
}
imageInput.seek(jpegOffset);
// NOTE: Some known TIFF encoder encodes bad JPEGInterchangeFormat tags,
// but has the correct offset to the JPEG stream in the StripOffset tag.
long realJPEGOffset = jpegOffset;
short expectedSOI = (short) (imageInput.readByte() << 8 | imageInput.readByte());
if (expectedSOI != (short) JPEG.SOI) {
if (stripTileOffsets != null && stripTileOffsets.length == 1) {
imageInput.seek(stripTileOffsets[0]);
expectedSOI = (short) (imageInput.readByte() << 8 | imageInput.readByte());
if (expectedSOI == (short) JPEG.SOI) {
realJPEGOffset = stripTileOffsets[0];
}
}
if (realJPEGOffset != jpegOffset) {
processWarningOccurred("Incorrect JPEGInterchangeFormat tag, using StripOffset/TileOffset instead.");
}
else {
processWarningOccurred("Incorrect JPEGInterchangeFormat tag encountered (not a valid SOI marker).");
// We'll fail below, but we don't need to handle this especially
}
}
imageInput.seek(realJPEGOffset);
stream = new SubImageInputStream(imageInput, jpegLenght != -1 ? jpegLenght : Short.MAX_VALUE);
jpegReader.setInput(stream);
@ -807,7 +834,6 @@ public class TIFFImageReader extends ImageReaderBase {
}
else {
// The hard way: Read tables and re-create a full JFIF stream
processWarningOccurred("Old-style JPEG compressed TIFF without JFIF stream encountered. Attempting to re-create JFIF stream.");
// 519/JPEGQTables

View File

@ -30,11 +30,16 @@ import com.twelvemonkeys.imageio.util.ImageReaderAbstractTestCase;
import org.junit.Test;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* TIFFImageReaderTest
*
@ -120,4 +125,22 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTestCase<TIFFImageRe
}
// TODO: Test YCbCr colors
@Test
public void testReadOldStyleJPEGGrayscale() throws IOException {
TestData testData = new TestData(getClassLoaderResource("/tiff/grayscale-old-style-jpeg.tiff"), new Dimension(600, 600));
ImageInputStream stream = testData.getInputStream();
try {
TIFFImageReader reader = createReader();
reader.setInput(stream);
BufferedImage image = reader.read(0);
assertNotNull(image);
assertEquals(testData.getDimension(0), new Dimension(image.getWidth(), image.getHeight()));
}
finally {
stream.close();
}
}
}