From ba5c667b6c40616bd3091471f55ce0526c057d8e Mon Sep 17 00:00:00 2001 From: Oliver Schmidtmer Date: Thu, 27 May 2021 22:11:13 +0200 Subject: [PATCH 1/2] #579 Deeper EOL search in the CCITT stream --- .../plugins/tiff/CCITTFaxDecoderStream.java | 53 +++++++++++-------- 1 file changed, 32 insertions(+), 21 deletions(-) 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 df2a871f..a7fd75de 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 @@ -152,39 +152,50 @@ final class CCITTFaxDecoderStream extends FilterInputStream { static int findCompressionType(final int type, final InputStream in) throws IOException { // Discover possible incorrect type, revert to RLE if (type == TIFFExtension.COMPRESSION_CCITT_T4 && in.markSupported()) { - byte[] streamData = new byte[32]; + int limit = 500; try { - in.mark(streamData.length); + in.mark(limit); - int offset = 0; - while (offset < streamData.length) { - int read = in.read(streamData, offset, streamData.length - offset); - if (read <= 0) { - break; + int first = in.read(); + int second = in.read(); + if (first == -1 || second == -1) { + // stream to short + return type; + } + else if (first == 0 && (((byte) second) >> 4 == 1 || ((byte) second) == 1)) { + // correct, starts with EOL or byte aligned EOL + return type; + } + short b = (short) (((((byte) first) << 8) + ((byte) second)) >> 4); + int limitBits = limit * 8; + int read = second; + byte streamByte = (byte) read; + for (int i = 12; i < limitBits; i++) { + if (i % 8 == 0) { + read = in.read(); + if (read > -1) { + streamByte = (byte) read; + } + else { + // no EOL before stream end + return TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE; + } } - offset += read; - } - } - finally { - in.reset(); - } - - if (streamData[0] != 0 || (streamData[1] >> 4 != 1 && streamData[1] != 1)) { - // Leading EOL (0b000000000001) not found, search further and try RLE if not found - int numBits = streamData.length * 8; - short b = (short) (((streamData[0] << 8) + streamData[1]) >> 4); - for (int i = 12; i < numBits; i++) { - b = (short) ((b << 1) + ((streamData[(i / 8)] >> (7 - (i % 8))) & 0x01)); + b = (short) ((b << 1) + ((streamByte >> (7 - (i % 8))) & 0x01)); if ((b & 0xFFF) == 1) { + // found EOL return TIFFExtension.COMPRESSION_CCITT_T4; } } - + // no EOL till limit return TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE; } + finally { + in.reset(); + } } return type; From cd42d81817cdeb1d59c1d0efd8eba2cbf3bb5ff6 Mon Sep 17 00:00:00 2001 From: Oliver Schmidtmer Date: Fri, 28 May 2021 14:38:44 +0200 Subject: [PATCH 2/2] Invert EOF check --- .../imageio/plugins/tiff/CCITTFaxDecoderStream.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) 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 a7fd75de..2d0be3ba 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 @@ -174,13 +174,11 @@ final class CCITTFaxDecoderStream extends FilterInputStream { for (int i = 12; i < limitBits; i++) { if (i % 8 == 0) { read = in.read(); - if (read > -1) { - streamByte = (byte) read; - } - else { + if (read == -1) { // no EOL before stream end return TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE; } + streamByte = (byte) read; } b = (short) ((b << 1) + ((streamByte >> (7 - (i % 8))) & 0x01));