Merge pull request #608 from Schmidor/ccitt_eol_search

#579 Deeper EOL search in the CCITT stream
This commit is contained in:
Harald Kuhr 2021-05-31 10:40:20 +02:00 committed by GitHub
commit eab24890ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -152,39 +152,48 @@ final class CCITTFaxDecoderStream extends FilterInputStream {
static int findCompressionType(final int type, final InputStream in) throws IOException { static int findCompressionType(final int type, final InputStream in) throws IOException {
// Discover possible incorrect type, revert to RLE // Discover possible incorrect type, revert to RLE
if (type == TIFFExtension.COMPRESSION_CCITT_T4 && in.markSupported()) { if (type == TIFFExtension.COMPRESSION_CCITT_T4 && in.markSupported()) {
byte[] streamData = new byte[32]; int limit = 500;
try { try {
in.mark(streamData.length); in.mark(limit);
int offset = 0; int first = in.read();
while (offset < streamData.length) { int second = in.read();
int read = in.read(streamData, offset, streamData.length - offset); if (first == -1 || second == -1) {
if (read <= 0) { // stream to short
break; 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) {
// no EOL before stream end
return TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE;
}
streamByte = (byte) read;
} }
offset += read; b = (short) ((b << 1) + ((streamByte >> (7 - (i % 8))) & 0x01));
}
}
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));
if ((b & 0xFFF) == 1) { if ((b & 0xFFF) == 1) {
// found EOL
return TIFFExtension.COMPRESSION_CCITT_T4; return TIFFExtension.COMPRESSION_CCITT_T4;
} }
} }
// no EOL till limit
return TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE; return TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE;
} }
finally {
in.reset();
}
} }
return type; return type;