mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-03 11:35:29 -04:00
#626 Clean up + fill order support for all compression types
(cherry picked from commit 3e1f85c4dc0650d2283525587ecac8f7a4f76dbd)
This commit is contained in:
parent
e8e3e0f1d6
commit
b19df1640b
@ -143,12 +143,13 @@ final class CCITTFaxDecoderStream extends FilterInputStream {
|
|||||||
// Discover possible incorrect compression type, revert to RLE if no EOLs found
|
// Discover possible incorrect compression type, revert to RLE if no EOLs found
|
||||||
if (encodedType == TIFFExtension.COMPRESSION_CCITT_T4 && stream.markSupported()) {
|
if (encodedType == TIFFExtension.COMPRESSION_CCITT_T4 && stream.markSupported()) {
|
||||||
int limit = 512;
|
int limit = 512;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
stream.mark(limit);
|
stream.mark(limit);
|
||||||
int first = stream.read();
|
int first = stream.read();
|
||||||
int second = stream.read();
|
int second = stream.read();
|
||||||
|
|
||||||
if (first == -1 || second == -1) {
|
if (second == -1) {
|
||||||
// stream to short
|
// stream to short
|
||||||
return encodedType;
|
return encodedType;
|
||||||
}
|
}
|
||||||
@ -156,10 +157,12 @@ final class CCITTFaxDecoderStream extends FilterInputStream {
|
|||||||
// correct, starts with EOL or byte aligned EOL
|
// correct, starts with EOL or byte aligned EOL
|
||||||
return encodedType;
|
return encodedType;
|
||||||
}
|
}
|
||||||
|
|
||||||
short b = (short) (((((byte) first) << 8) + ((byte) second)) >> 4);
|
short b = (short) (((((byte) first) << 8) + ((byte) second)) >> 4);
|
||||||
int limitBits = limit * 8;
|
int limitBits = limit * 8;
|
||||||
int read = second;
|
int read = second;
|
||||||
byte streamByte = (byte) read;
|
byte streamByte = (byte) read;
|
||||||
|
|
||||||
for (int i = 12; i < limitBits; i++) {
|
for (int i = 12; i < limitBits; i++) {
|
||||||
if (i % 8 == 0) {
|
if (i % 8 == 0) {
|
||||||
read = stream.read();
|
read = stream.read();
|
||||||
@ -176,6 +179,7 @@ final class CCITTFaxDecoderStream extends FilterInputStream {
|
|||||||
return TIFFExtension.COMPRESSION_CCITT_T4;
|
return TIFFExtension.COMPRESSION_CCITT_T4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// no EOL till limit
|
// no EOL till limit
|
||||||
return TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE;
|
return TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE;
|
||||||
}
|
}
|
||||||
@ -465,7 +469,7 @@ final class CCITTFaxDecoderStream extends FilterInputStream {
|
|||||||
int bufferPos = -1;
|
int bufferPos = -1;
|
||||||
|
|
||||||
private boolean readBit() throws IOException {
|
private boolean readBit() throws IOException {
|
||||||
if (bufferPos < 0 || bufferPos > 7) {
|
if (bufferPos > 7 || bufferPos < 0) {
|
||||||
buffer = in.read();
|
buffer = in.read();
|
||||||
|
|
||||||
if (buffer == -1) {
|
if (buffer == -1) {
|
||||||
@ -475,14 +479,10 @@ final class CCITTFaxDecoderStream extends FilterInputStream {
|
|||||||
bufferPos = 0;
|
bufferPos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isSet = ((buffer >> (7 - bufferPos)) & 1) == 1;
|
boolean isSet = (buffer & 0x80) != 0;
|
||||||
|
buffer <<= 1;
|
||||||
bufferPos++;
|
bufferPos++;
|
||||||
|
|
||||||
if (bufferPos > 7) {
|
|
||||||
bufferPos = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return isSet;
|
return isSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1062,9 +1062,10 @@ public final class TIFFImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
// General uncompressed/compressed reading
|
// General uncompressed/compressed reading
|
||||||
int bands = planarConfiguration == TIFFExtension.PLANARCONFIG_PLANAR ? rawType.getNumBands() : 1;
|
int bands = planarConfiguration == TIFFExtension.PLANARCONFIG_PLANAR ? rawType.getNumBands() : 1;
|
||||||
|
int fillOrder = getValueAsIntWithDefault(TIFF.TAG_FILL_ORDER, TIFFBaseline.FILL_LEFT_TO_RIGHT);
|
||||||
int bitsPerSample = getBitsPerSample();
|
int bitsPerSample = getBitsPerSample();
|
||||||
boolean needsBitPadding = bitsPerSample > 16 && bitsPerSample % 16 != 0 || bitsPerSample > 8 && bitsPerSample % 8 != 0 || bitsPerSample == 6;
|
boolean needsBitPadding = bitsPerSample > 16 && bitsPerSample % 16 != 0 || bitsPerSample > 8 && bitsPerSample % 8 != 0 || bitsPerSample == 6;
|
||||||
boolean needsAdapter = compression != TIFFBaseline.COMPRESSION_NONE
|
boolean needsAdapter = compression != TIFFBaseline.COMPRESSION_NONE || fillOrder != TIFFBaseline.FILL_LEFT_TO_RIGHT
|
||||||
|| interpretation == TIFFExtension.PHOTOMETRIC_YCBCR || needsBitPadding;
|
|| interpretation == TIFFExtension.PHOTOMETRIC_YCBCR || needsBitPadding;
|
||||||
|
|
||||||
for (int y = 0; y < tilesDown; y++) {
|
for (int y = 0; y < tilesDown; y++) {
|
||||||
@ -1081,7 +1082,7 @@ public final class TIFFImageReader extends ImageReaderBase {
|
|||||||
|
|
||||||
DataInput input;
|
DataInput input;
|
||||||
if (!needsAdapter) {
|
if (!needsAdapter) {
|
||||||
// No need for transformation, fast forward
|
// No need for transformation, fast-forward
|
||||||
input = imageInput;
|
input = imageInput;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1089,6 +1090,7 @@ public final class TIFFImageReader extends ImageReaderBase {
|
|||||||
? createStreamAdapter(imageInput, stripTileByteCounts[i])
|
? createStreamAdapter(imageInput, stripTileByteCounts[i])
|
||||||
: createStreamAdapter(imageInput);
|
: createStreamAdapter(imageInput);
|
||||||
|
|
||||||
|
adapter = createFillOrderStream(fillOrder, adapter);
|
||||||
adapter = createDecompressorStream(compression, stripTileWidth, numBands, adapter);
|
adapter = createDecompressorStream(compression, stripTileWidth, numBands, adapter);
|
||||||
adapter = createUnpredictorStream(predictor, stripTileWidth, numBands, bitsPerSample, adapter, imageInput.getByteOrder());
|
adapter = createUnpredictorStream(predictor, stripTileWidth, numBands, bitsPerSample, adapter, imageInput.getByteOrder());
|
||||||
|
|
||||||
@ -2333,30 +2335,28 @@ public final class TIFFImageReader extends ImageReaderBase {
|
|||||||
return (short) Math.max(0, Math.min(0xffff, val));
|
return (short) Math.max(0, Math.min(0xffff, val));
|
||||||
}
|
}
|
||||||
|
|
||||||
private InputStream createDecompressorStream(final int compression, final int width, final int bands, final InputStream stream) throws IOException {
|
private InputStream createDecompressorStream(final int compression, final int width, final int bands, InputStream stream) throws IOException {
|
||||||
int fillOrder = getValueAsIntWithDefault(TIFF.TAG_FILL_ORDER, 1);
|
|
||||||
|
|
||||||
switch (compression) {
|
switch (compression) {
|
||||||
case TIFFBaseline.COMPRESSION_NONE:
|
case TIFFBaseline.COMPRESSION_NONE:
|
||||||
return stream;
|
return stream;
|
||||||
case TIFFBaseline.COMPRESSION_PACKBITS:
|
case TIFFBaseline.COMPRESSION_PACKBITS:
|
||||||
return new DecoderStream(createFillOrderStream(fillOrder, stream), new PackBitsDecoder(), 256);
|
return new DecoderStream(stream, new PackBitsDecoder(), 256);
|
||||||
case TIFFExtension.COMPRESSION_LZW:
|
case TIFFExtension.COMPRESSION_LZW:
|
||||||
// NOTE: Needs large buffer for compatibility with certain encoders
|
// NOTE: Needs large buffer for compatibility with certain encoders
|
||||||
return new DecoderStream(createFillOrderStream(fillOrder, stream), LZWDecoder.create(LZWDecoder.isOldBitReversedStream(stream)), Math.max(width * bands, 4096));
|
return new DecoderStream(stream, LZWDecoder.create(LZWDecoder.isOldBitReversedStream(stream)), Math.max(width * bands, 4096));
|
||||||
case TIFFExtension.COMPRESSION_ZLIB:
|
case TIFFExtension.COMPRESSION_ZLIB:
|
||||||
case TIFFExtension.COMPRESSION_DEFLATE:
|
case TIFFExtension.COMPRESSION_DEFLATE:
|
||||||
// TIFF specification, supplement 2 says ZLIB (8) and DEFLATE (32946) algorithms are identical
|
// TIFF specification, supplement 2 says ZLIB (8) and DEFLATE (32946) algorithms are identical
|
||||||
case TIFFCustom.COMPRESSION_PIXTIFF_ZIP:
|
case TIFFCustom.COMPRESSION_PIXTIFF_ZIP:
|
||||||
return new InflaterInputStream(createFillOrderStream(fillOrder, stream), new Inflater(), 1024);
|
return new InflaterInputStream(stream, new Inflater(), 1024);
|
||||||
case TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE:
|
case TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE:
|
||||||
case TIFFExtension.COMPRESSION_CCITT_T4:
|
case TIFFExtension.COMPRESSION_CCITT_T4:
|
||||||
case TIFFExtension.COMPRESSION_CCITT_T6:
|
case TIFFExtension.COMPRESSION_CCITT_T6:
|
||||||
// TODO: Find a better way to test for incorrect CCITT type ONCE per IFD
|
// TODO: Find a better way to test for incorrect CCITT type ONCE per IFD
|
||||||
if (overrideCCITTCompression == -1) {
|
if (overrideCCITTCompression == -1) {
|
||||||
overrideCCITTCompression = findCCITTType(compression, createFillOrderStream(fillOrder, stream));
|
overrideCCITTCompression = findCCITTType(compression, stream);
|
||||||
}
|
}
|
||||||
return new CCITTFaxDecoderStream(createFillOrderStream(fillOrder, stream), width, overrideCCITTCompression, getCCITTOptions(compression), compression == TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE);
|
return new CCITTFaxDecoderStream(stream, width, overrideCCITTCompression, getCCITTOptions(compression), compression == TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE);
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unsupported TIFF compression: " + compression);
|
throw new IllegalArgumentException("Unsupported TIFF compression: " + compression);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user