mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-05 20:45:29 -04:00
Merge pull request #371 from Schmidor/ccittbytealigned
Support PDF ByteAligned Flag on CCITT Decoder
This commit is contained in:
commit
2d564ad98e
@ -71,6 +71,8 @@ final class CCITTFaxDecoderStream extends FilterInputStream {
|
|||||||
|
|
||||||
private boolean optionUncompressed = false;
|
private boolean optionUncompressed = false;
|
||||||
|
|
||||||
|
private boolean optionByteAligned = false;
|
||||||
|
|
||||||
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 int fillOrder,
|
||||||
final long options) {
|
final long options) {
|
||||||
super(Validate.notNull(stream, "stream"));
|
super(Validate.notNull(stream, "stream"));
|
||||||
@ -92,6 +94,9 @@ final class CCITTFaxDecoderStream extends FilterInputStream {
|
|||||||
this.changesCurrentRow = new int[columns + 2];
|
this.changesCurrentRow = new int[columns + 2];
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case TIFFBaseline.COMPRESSION_CCITT_MODIFIED_HUFFMAN_RLE:
|
||||||
|
optionByteAligned = true;
|
||||||
|
break;
|
||||||
case TIFFExtension.COMPRESSION_CCITT_T4:
|
case TIFFExtension.COMPRESSION_CCITT_T4:
|
||||||
optionG32D = (options & TIFFExtension.GROUP3OPT_2DENCODING) != 0;
|
optionG32D = (options & TIFFExtension.GROUP3OPT_2DENCODING) != 0;
|
||||||
optionG3Fill = (options & TIFFExtension.GROUP3OPT_FILLBITS) != 0;
|
optionG3Fill = (options & TIFFExtension.GROUP3OPT_FILLBITS) != 0;
|
||||||
@ -106,6 +111,15 @@ final class CCITTFaxDecoderStream extends FilterInputStream {
|
|||||||
"CCITT GROUP 3/4 OPTION UNCOMPRESSED is not supported");
|
"CCITT GROUP 3/4 OPTION UNCOMPRESSED is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is used for CCITT streams from PDF files, which use EncodedByteAlign
|
||||||
|
*
|
||||||
|
* @param enable enable byte alignment
|
||||||
|
*/
|
||||||
|
public void setOptionByteAligned(boolean enable) {
|
||||||
|
optionByteAligned = enable;
|
||||||
|
}
|
||||||
|
|
||||||
private void fetch() throws IOException {
|
private void fetch() throws IOException {
|
||||||
if (decodedPos >= decodedLength) {
|
if (decodedPos >= decodedLength) {
|
||||||
decodedLength = 0;
|
decodedLength = 0;
|
||||||
@ -241,11 +255,16 @@ final class CCITTFaxDecoderStream extends FilterInputStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void decodeRowType2() throws IOException {
|
private void decodeRowType2() throws IOException {
|
||||||
resetBuffer();
|
if (optionByteAligned) {
|
||||||
|
resetBuffer();
|
||||||
|
}
|
||||||
decode1D();
|
decode1D();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void decodeRowType4() throws IOException {
|
private void decodeRowType4() throws IOException {
|
||||||
|
if (optionByteAligned) {
|
||||||
|
resetBuffer();
|
||||||
|
}
|
||||||
eof: while (true) {
|
eof: while (true) {
|
||||||
// read till next EOL code
|
// read till next EOL code
|
||||||
Node n = eolOnlyTree.root;
|
Node n = eolOnlyTree.root;
|
||||||
@ -272,6 +291,9 @@ final class CCITTFaxDecoderStream extends FilterInputStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void decodeRowType6() throws IOException {
|
private void decodeRowType6() throws IOException {
|
||||||
|
if (optionByteAligned) {
|
||||||
|
resetBuffer();
|
||||||
|
}
|
||||||
decode2D();
|
decode2D();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,17 +391,7 @@ final class CCITTFaxDecoderStream extends FilterInputStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void resetBuffer() throws IOException {
|
private void resetBuffer() throws IOException {
|
||||||
for (int i = 0; i < decodedRow.length; i++) {
|
bufferPos = -1;
|
||||||
decodedRow[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
if (bufferPos == -1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
readBit();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int buffer = -1;
|
int buffer = -1;
|
||||||
|
@ -74,6 +74,13 @@ public class CCITTFaxDecoderStreamTest {
|
|||||||
// Line 4: V-1, V0, V0 EOL EOL
|
// Line 4: V-1, V0, V0 EOL EOL
|
||||||
static final byte[] DATA_G4 = { 0x04, 0x17, (byte) 0xF5, (byte) 0x80, 0x08, 0x00, (byte) 0x80 };
|
static final byte[] DATA_G4 = { 0x04, 0x17, (byte) 0xF5, (byte) 0x80, 0x08, 0x00, (byte) 0x80 };
|
||||||
|
|
||||||
|
static final byte[] DATA_G4_ALIGNED = {
|
||||||
|
0x04, 0x14, // 00000100 000101(00)
|
||||||
|
(byte) 0xE0, // 111 (00000)
|
||||||
|
(byte) 0xE0, // 111 (00000)
|
||||||
|
0x58 // 01011 (000)
|
||||||
|
};
|
||||||
|
|
||||||
// TODO: Better tests (full A4 width scan lines?)
|
// TODO: Better tests (full A4 width scan lines?)
|
||||||
|
|
||||||
// From http://www.mikekohn.net/file_formats/tiff.php
|
// From http://www.mikekohn.net/file_formats/tiff.php
|
||||||
@ -262,6 +269,18 @@ public class CCITTFaxDecoderStreamTest {
|
|||||||
assertEquals((byte) 0b10101010, decoded);
|
assertEquals((byte) 0b10101010, decoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDecodeType4ByteAligned() throws IOException {
|
||||||
|
CCITTFaxDecoderStream stream = new CCITTFaxDecoderStream(new ByteArrayInputStream(DATA_G4_ALIGNED), 6,
|
||||||
|
TIFFExtension.COMPRESSION_CCITT_T6, 1, 0L);
|
||||||
|
stream.setOptionByteAligned(true);
|
||||||
|
|
||||||
|
byte[] imageData = ((DataBufferByte) image.getData().getDataBuffer()).getData();
|
||||||
|
byte[] bytes = new byte[imageData.length];
|
||||||
|
new DataInputStream(stream).readFully(bytes);
|
||||||
|
assertArrayEquals(imageData, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testG3AOE() throws IOException {
|
public void testG3AOE() throws IOException {
|
||||||
InputStream inputStream = getClass().getResourceAsStream("/tiff/ccitt/g3aoe.tif");
|
InputStream inputStream = getClass().getResourceAsStream("/tiff/ccitt/g3aoe.tif");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user