mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-03 03:25:28 -04:00
(cherry picked from commit 62ba73a30e653372e832db2bfeacfc685ac0c3ea)
This commit is contained in:
parent
182b2fdfa9
commit
c249a21c8c
@ -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++;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -124,6 +124,7 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest<TIFFImageReader
|
||||
new TestData(getClassLoaderResource("/tiff/fivepages-scan-causingerrors.tif"), new Dimension(2480, 3518)), // B/W, CCITT T4
|
||||
new TestData(getClassLoaderResource("/tiff/CCITTgetNextChangingElement.tif"), new Dimension(2402,195)),
|
||||
new TestData(getClassLoaderResource("/tiff/ccitt-too-many-changes.tif"), new Dimension(24,153)),
|
||||
new TestData(getClassLoaderResource("/tiff/ccitt/G32DS.tif"), new Dimension(2464,3248)), // B/W, FillOrder Right to Left
|
||||
// CIELab
|
||||
new TestData(getClassLoaderResource("/tiff/ColorCheckerCalculator.tif"), new Dimension(798, 546)), // CIELab 8 bit/sample
|
||||
// Gray
|
||||
|
BIN
imageio/imageio-tiff/src/test/resources/tiff/ccitt/G32DS.tif
Normal file
BIN
imageio/imageio-tiff/src/test/resources/tiff/ccitt/G32DS.tif
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user