diff --git a/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/CCITTFaxDecoderStream.java b/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/CCITTFaxDecoderStream.java index 21c27e04..ea25bd26 100644 --- a/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/CCITTFaxDecoderStream.java +++ b/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/CCITTFaxDecoderStream.java @@ -58,8 +58,6 @@ final class CCITTFaxDecoderStream extends FilterInputStream { private final boolean optionUncompressed; private final boolean optionByteAligned; - // Need to take fill order into account (?) (use flip table?) - private final int fillOrder; private final int type; private int decodedLength; @@ -81,12 +79,10 @@ final class CCITTFaxDecoderStream extends FilterInputStream { * @param columns the number of columns in the stream. * @param type the type of stream, must be one of {@code COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE}, * {@code COMPRESSION_CCITT_T4} or {@code COMPRESSION_CCITT_T6}. - * @param fillOrder fillOrder, must be {@code FILL_LEFT_TO_RIGHT} or - * {@code FILL_RIGHT_TO_LEFT}. * @param options CCITT T.4 or T.6 options. * @param byteAligned enable byte alignment used in PDF files (EncodedByteAlign). */ - public CCITTFaxDecoderStream(final InputStream stream, final int columns, final int type, final int fillOrder, + public CCITTFaxDecoderStream(final InputStream stream, final int columns, final int type, final long options, final boolean byteAligned) { super(Validate.notNull(stream, "stream")); @@ -95,10 +91,6 @@ final class CCITTFaxDecoderStream extends FilterInputStream { type == TIFFExtension.COMPRESSION_CCITT_T4 || type == TIFFExtension.COMPRESSION_CCITT_T6, type, "Only CCITT Modified Huffman RLE compression (2), CCITT T4 (3) or CCITT T6 (4) supported: %s"); - this.fillOrder = Validate.isTrue( - fillOrder == TIFFBaseline.FILL_LEFT_TO_RIGHT || fillOrder == TIFFExtension.FILL_RIGHT_TO_LEFT, - fillOrder, "Expected fill order 1 or 2: %s" - ); // We know this is only used for b/w (1 bit) decodedRow = new byte[(columns + 7) / 8]; @@ -140,25 +132,22 @@ final class CCITTFaxDecoderStream extends FilterInputStream { * @param columns the number of columns in the stream. * @param type the type of stream, must be one of {@code COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE}, * {@code COMPRESSION_CCITT_T4} or {@code COMPRESSION_CCITT_T6}. - * @param fillOrder fillOrder, must be {@code FILL_LEFT_TO_RIGHT} or - * {@code FILL_RIGHT_TO_LEFT}. * @param options CCITT T.4 or T.6 options. */ - public CCITTFaxDecoderStream(final InputStream stream, final int columns, final int type, final int fillOrder, + public CCITTFaxDecoderStream(final InputStream stream, final int columns, final int type, final long options) { - this(stream, columns, type, fillOrder, options, type == TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE); + this(stream, columns, type, options, type == TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE); } static int findCompressionType(final int encodedType, final InputStream stream) throws IOException { // Discover possible incorrect compression type, revert to RLE if no EOLs found if (encodedType == TIFFExtension.COMPRESSION_CCITT_T4 && stream.markSupported()) { int limit = 512; - try { stream.mark(limit); - int first = stream.read(); int second = stream.read(); + if (first == -1 || second == -1) { // stream to short return encodedType; @@ -178,7 +167,6 @@ final class CCITTFaxDecoderStream extends FilterInputStream { // no EOL before stream end return TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE; } - streamByte = (byte) read; } b = (short) ((b << 1) + ((streamByte >> (7 - (i % 8))) & 0x01)); @@ -487,14 +475,7 @@ final class CCITTFaxDecoderStream extends FilterInputStream { bufferPos = 0; } - boolean isSet; - - if (fillOrder == TIFFBaseline.FILL_LEFT_TO_RIGHT) { - isSet = ((buffer >> (7 - bufferPos)) & 1) == 1; - } - else { - isSet = ((buffer >> (bufferPos)) & 1) == 1; - } + boolean isSet = ((buffer >> (7 - bufferPos)) & 1) == 1; bufferPos++; diff --git a/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReader.java b/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReader.java index 2bca8d13..acb12811 100644 --- a/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReader.java +++ b/imageio/imageio-tiff/src/main/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReader.java @@ -2354,9 +2354,9 @@ public final class TIFFImageReader extends ImageReaderBase { case TIFFExtension.COMPRESSION_CCITT_T6: // TODO: Find a better way to test for incorrect CCITT type ONCE per IFD if (overrideCCITTCompression == -1) { - overrideCCITTCompression = findCCITTType(compression, stream); + overrideCCITTCompression = findCCITTType(compression, createFillOrderStream(fillOrder, stream)); } - return new CCITTFaxDecoderStream(stream, width, overrideCCITTCompression, fillOrder, getCCITTOptions(compression), compression == TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE); + return new CCITTFaxDecoderStream(createFillOrderStream(fillOrder, stream), width, overrideCCITTCompression, getCCITTOptions(compression), compression == TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE); default: throw new IllegalArgumentException("Unsupported TIFF compression: " + compression); } diff --git a/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/CCITTFaxDecoderStreamTest.java b/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/CCITTFaxDecoderStreamTest.java index dbe4d3c0..9fa9413f 100644 --- a/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/CCITTFaxDecoderStreamTest.java +++ b/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/CCITTFaxDecoderStreamTest.java @@ -153,7 +153,7 @@ public class CCITTFaxDecoderStreamTest { @Test public void testDecodeType2() throws IOException { InputStream stream = new CCITTFaxDecoderStream(new ByteArrayInputStream(DATA_TYPE_2), 6, - TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE, 1, 0L); + TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE, 0L); byte[] imageData = ((DataBufferByte) image.getData().getDataBuffer()).getData(); byte[] bytes = new byte[imageData.length]; @@ -164,7 +164,7 @@ public class CCITTFaxDecoderStreamTest { @Test public void testDecodeType3_1D() throws IOException { InputStream stream = new CCITTFaxDecoderStream(new ByteArrayInputStream(DATA_G3_1D), 6, - TIFFExtension.COMPRESSION_CCITT_T4, 1, 0L); + TIFFExtension.COMPRESSION_CCITT_T4, 0L); byte[] imageData = ((DataBufferByte) image.getData().getDataBuffer()).getData(); byte[] bytes = new byte[imageData.length]; @@ -175,7 +175,7 @@ public class CCITTFaxDecoderStreamTest { @Test public void testDecodeType3_1D_FILL() throws IOException { InputStream stream = new CCITTFaxDecoderStream(new ByteArrayInputStream(DATA_G3_1D_FILL), 6, - TIFFExtension.COMPRESSION_CCITT_T4, 1, TIFFExtension.GROUP3OPT_FILLBITS); + TIFFExtension.COMPRESSION_CCITT_T4, TIFFExtension.GROUP3OPT_FILLBITS); byte[] imageData = ((DataBufferByte) image.getData().getDataBuffer()).getData(); byte[] bytes = new byte[imageData.length]; @@ -184,7 +184,7 @@ public class CCITTFaxDecoderStreamTest { } @Test - public void testFidCompressionType() throws IOException { + public void testFindCompressionType() throws IOException { // RLE assertEquals(TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE, CCITTFaxDecoderStream.findCompressionType(TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE, new ByteArrayInputStream(DATA_RLE_UNALIGNED))); @@ -193,8 +193,8 @@ public class CCITTFaxDecoderStreamTest { assertEquals(TIFFExtension.COMPRESSION_CCITT_T4, CCITTFaxDecoderStream.findCompressionType(TIFFExtension.COMPRESSION_CCITT_T4, new ByteArrayInputStream(DATA_G3_1D_FILL))); assertEquals(TIFFExtension.COMPRESSION_CCITT_T4, CCITTFaxDecoderStream.findCompressionType(TIFFExtension.COMPRESSION_CCITT_T4, new ByteArrayInputStream(DATA_G3_2D))); assertEquals(TIFFExtension.COMPRESSION_CCITT_T4, CCITTFaxDecoderStream.findCompressionType(TIFFExtension.COMPRESSION_CCITT_T4, new ByteArrayInputStream(DATA_G3_2D_FILL))); - assertEquals(TIFFExtension.COMPRESSION_CCITT_T4, CCITTFaxDecoderStream.findCompressionType(TIFFExtension.COMPRESSION_CCITT_T4, new ByteArrayInputStream(DATA_G3_2D_lsb2msb))); - assertEquals(TIFFExtension.COMPRESSION_CCITT_T4, CCITTFaxDecoderStream.findCompressionType(TIFFExtension.COMPRESSION_CCITT_T4, new ByteArrayInputStream(DATA_G3_LONG))); + assertEquals(TIFFExtension.COMPRESSION_CCITT_T4, CCITTFaxDecoderStream.findCompressionType(TIFFExtension.COMPRESSION_CCITT_T4, new ReverseInputStream(new ByteArrayInputStream(DATA_G3_2D_lsb2msb)))); + assertEquals(TIFFExtension.COMPRESSION_CCITT_T4, CCITTFaxDecoderStream.findCompressionType(TIFFExtension.COMPRESSION_CCITT_T4, new ReverseInputStream(new ByteArrayInputStream(DATA_G3_LONG)))); // Group 4/CCITT_T6 assertEquals(TIFFExtension.COMPRESSION_CCITT_T6, CCITTFaxDecoderStream.findCompressionType(TIFFExtension.COMPRESSION_CCITT_T6, new ByteArrayInputStream(DATA_G4))); @@ -208,7 +208,7 @@ public class CCITTFaxDecoderStreamTest { @Test public void testDecodeType3_2D() throws IOException { InputStream stream = new CCITTFaxDecoderStream(new ByteArrayInputStream(DATA_G3_2D), 6, - TIFFExtension.COMPRESSION_CCITT_T4, 1, TIFFExtension.GROUP3OPT_2DENCODING); + TIFFExtension.COMPRESSION_CCITT_T4, TIFFExtension.GROUP3OPT_2DENCODING); byte[] imageData = ((DataBufferByte) image.getData().getDataBuffer()).getData(); byte[] bytes = new byte[imageData.length]; @@ -219,7 +219,7 @@ public class CCITTFaxDecoderStreamTest { @Test public void testDecodeType3_2D_FILL() throws IOException { InputStream stream = new CCITTFaxDecoderStream(new ByteArrayInputStream(DATA_G3_2D_FILL), 6, - TIFFExtension.COMPRESSION_CCITT_T4, 1, + TIFFExtension.COMPRESSION_CCITT_T4, TIFFExtension.GROUP3OPT_2DENCODING | TIFFExtension.GROUP3OPT_FILLBITS); byte[] imageData = ((DataBufferByte) image.getData().getDataBuffer()).getData(); @@ -230,8 +230,8 @@ public class CCITTFaxDecoderStreamTest { @Test public void testDecodeType3_2D_REVERSED() throws IOException { - InputStream stream = new CCITTFaxDecoderStream(new ByteArrayInputStream(DATA_G3_2D_lsb2msb), 6, - TIFFExtension.COMPRESSION_CCITT_T4, 2, TIFFExtension.GROUP3OPT_2DENCODING); + InputStream stream = new CCITTFaxDecoderStream(new ReverseInputStream(new ByteArrayInputStream(DATA_G3_2D_lsb2msb)), 6, + TIFFExtension.COMPRESSION_CCITT_T4, TIFFExtension.GROUP3OPT_2DENCODING); byte[] imageData = ((DataBufferByte) image.getData().getDataBuffer()).getData(); byte[] bytes = new byte[imageData.length]; @@ -242,7 +242,7 @@ public class CCITTFaxDecoderStreamTest { @Test public void testDecodeType4() throws IOException { InputStream stream = new CCITTFaxDecoderStream(new ByteArrayInputStream(DATA_G4), 6, - TIFFExtension.COMPRESSION_CCITT_T6, 1, 0L); + TIFFExtension.COMPRESSION_CCITT_T6, 0L); byte[] imageData = ((DataBufferByte) image.getData().getDataBuffer()).getData(); byte[] bytes = new byte[imageData.length]; @@ -265,7 +265,7 @@ public class CCITTFaxDecoderStreamTest { new DataInputStream(inputStream).readFully(data); InputStream stream = new CCITTFaxDecoderStream(new ByteArrayInputStream(data), - 6, TIFFExtension.COMPRESSION_CCITT_T6, 1, 0L); + 6, TIFFExtension.COMPRESSION_CCITT_T6, 0L); byte[] bytes = new byte[6]; // 6 x 6 pixel, 1 bpp => 6 bytes new DataInputStream(stream).readFully(bytes); @@ -290,7 +290,7 @@ public class CCITTFaxDecoderStreamTest { byte[] encoded = imageOutput.toByteArray(); InputStream inputStream = new CCITTFaxDecoderStream(new ByteArrayInputStream(encoded), 8, - TIFFExtension.COMPRESSION_CCITT_T6, 1, 0L); + TIFFExtension.COMPRESSION_CCITT_T6, 0L); byte decoded = (byte) inputStream.read(); assertEquals(data[0], decoded); } @@ -307,7 +307,7 @@ public class CCITTFaxDecoderStreamTest { } InputStream inputStream = new CCITTFaxDecoderStream(stream, - 24, TIFFExtension.COMPRESSION_CCITT_T6, 1, 0L); + 24, TIFFExtension.COMPRESSION_CCITT_T6, 0L); byte decoded = (byte) inputStream.read(); assertEquals((byte) 0b10101010, decoded); } @@ -315,7 +315,7 @@ public class CCITTFaxDecoderStreamTest { @Test public void testDecodeType4ByteAligned() throws IOException { CCITTFaxDecoderStream stream = new CCITTFaxDecoderStream(new ByteArrayInputStream(DATA_G4_ALIGNED), 6, - TIFFExtension.COMPRESSION_CCITT_T6, 1, 0L, true); + TIFFExtension.COMPRESSION_CCITT_T6, 0L, true); byte[] imageData = ((DataBufferByte) image.getData().getDataBuffer()).getData(); byte[] bytes = new byte[imageData.length]; @@ -326,7 +326,7 @@ public class CCITTFaxDecoderStreamTest { @Test public void testDecodeType2NotByteAligned() throws IOException { CCITTFaxDecoderStream stream = new CCITTFaxDecoderStream(new ByteArrayInputStream(DATA_RLE_UNALIGNED), 6, - TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE, 1, 0L, false); + TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE, 0L, false); byte[] imageData = ((DataBufferByte) image.getData().getDataBuffer()).getData(); byte[] bytes = new byte[imageData.length]; @@ -348,7 +348,7 @@ public class CCITTFaxDecoderStreamTest { new DataInputStream(inputStream).readFully(data); InputStream stream = new CCITTFaxDecoderStream(new ByteArrayInputStream(data), - 1728, TIFFExtension.COMPRESSION_CCITT_T4, 1, TIFFExtension.GROUP3OPT_FILLBITS); + 1728, TIFFExtension.COMPRESSION_CCITT_T4, TIFFExtension.GROUP3OPT_FILLBITS); byte[] bytes = new byte[216 * 1168]; // 1728 x 1168 pixel, 1 bpp => 216 bytes * 1168 new DataInputStream(stream).readFully(bytes); diff --git a/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/CCITTFaxEncoderStreamTest.java b/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/CCITTFaxEncoderStreamTest.java index de302c20..cb835fe0 100644 --- a/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/CCITTFaxEncoderStreamTest.java +++ b/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/CCITTFaxEncoderStreamTest.java @@ -163,7 +163,7 @@ public class CCITTFaxEncoderStreamTest { byte[] encodedData = imageOutput.toByteArray(); byte[] decodedData = new byte[data.length]; - CCITTFaxDecoderStream inputStream = new CCITTFaxDecoderStream(new ByteArrayInputStream(encodedData), 3200, TIFFExtension.COMPRESSION_CCITT_T6, 1, 0L); + CCITTFaxDecoderStream inputStream = new CCITTFaxDecoderStream(new ByteArrayInputStream(encodedData), 3200, TIFFExtension.COMPRESSION_CCITT_T6, 0L); new DataInputStream(inputStream).readFully(decodedData); inputStream.close(); @@ -184,8 +184,12 @@ public class CCITTFaxEncoderStreamTest { outputSteam.close(); byte[] encodedData = imageOutput.toByteArray(); + InputStream inStream = new ByteArrayInputStream(encodedData); + if(fillOrder == TIFFExtension.FILL_RIGHT_TO_LEFT){ + inStream = new ReverseInputStream(inStream); + } try (CCITTFaxDecoderStream inputStream = - new CCITTFaxDecoderStream(new ByteArrayInputStream(encodedData), 6, type, fillOrder, options)) { + new CCITTFaxDecoderStream(inStream, 6, type, options)) { new DataInputStream(inputStream).readFully(redecodedData); } diff --git a/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReaderTest.java b/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReaderTest.java index fad5e6c4..41ba555e 100644 --- a/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReaderTest.java +++ b/imageio/imageio-tiff/src/test/java/com/twelvemonkeys/imageio/plugins/tiff/TIFFImageReaderTest.java @@ -124,6 +124,7 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest