CCITT Fax writer: adjust formatting and write finishing bytes on last row instead of on stream closing

This commit is contained in:
Schmidor
2015-10-09 23:18:56 +02:00
parent 585b5faa62
commit c8621439c0
2 changed files with 81 additions and 73 deletions

View File

@@ -28,11 +28,11 @@
package com.twelvemonkeys.imageio.plugins.tiff;
import com.twelvemonkeys.lang.Validate;
import java.io.IOException;
import java.io.OutputStream;
import com.twelvemonkeys.lang.Validate;
/**
* CCITT Modified Huffman RLE, Group 3 (T4) and Group 4 (T6) fax compression.
*
@@ -46,9 +46,11 @@ public class CCITTFaxEncoderStream extends OutputStream {
private final byte[] inputBuffer;
private final int inputBufferLength;
private int columns;
private int rows;
private int[] changesCurrentRow;
private int[] changesReferenceRow;
private int currentRow = 0;
private int changesCurrentRowLength = 0;
private int changesReferenceRowLength = 0;
private byte outputBuffer = 0;
@@ -60,12 +62,13 @@ public class CCITTFaxEncoderStream extends OutputStream {
private boolean optionUncompressed;
private OutputStream stream;
public CCITTFaxEncoderStream(final OutputStream stream, final int columns, final int type, final int fillOrder,
public CCITTFaxEncoderStream(final OutputStream stream, final int columns, final int rows, final int type, final int fillOrder,
final long options) {
this.stream = stream;
this.type = type;
this.columns = columns;
this.rows = rows;
this.fillOrder = fillOrder;
this.changesReferenceRow = new int[columns];
@@ -107,15 +110,11 @@ public class CCITTFaxEncoderStream extends OutputStream {
@Override
public void close() throws IOException {
if (type == TIFFExtension.COMPRESSION_CCITT_T6) {
writeEOL();
writeEOL();
}
fill();
stream.close();
}
private void encodeRow() throws IOException {
currentRow++;
int[] tmp = changesReferenceRow;
changesReferenceRow = changesCurrentRow;
changesCurrentRow = tmp;
@@ -127,7 +126,7 @@ public class CCITTFaxEncoderStream extends OutputStream {
while (index < columns) {
int byteIndex = index / 8;
int bit = index % 8;
if ((((inputBuffer[byteIndex] >> (7 - bit)) & 1) == 1) != (!white)) {
if ((((inputBuffer[byteIndex] >> (7 - bit)) & 1) == 1) == (white)) {
changesCurrentRow[changesCurrentRowLength] = index;
changesCurrentRowLength++;
white = !white;
@@ -146,6 +145,14 @@ public class CCITTFaxEncoderStream extends OutputStream {
encodeRowType6();
break;
}
if (currentRow == rows) {
if (type == TIFFExtension.COMPRESSION_CCITT_T6) {
writeEOL();
writeEOL();
}
fill();
}
}
private void encodeRowType2() throws IOException {
@@ -161,11 +168,13 @@ public class CCITTFaxEncoderStream extends OutputStream {
if (changesReferenceRowLength == 0) {
write(1, 1);
encode1D();
} else {
}
else {
write(0, 1);
encode2D();
}
} else {
}
else {
encode1D();
}
if (optionG3Fill) {
@@ -211,7 +220,8 @@ public class CCITTFaxEncoderStream extends OutputStream {
if (nonterm >= codes.length) {
write(codes[codes.length - 1].code, codes[codes.length - 1].length);
nonterm -= codes.length - 1;
} else {
}
else {
write(codes[nonterm - 1].code, codes[nonterm - 1].length);
nonterm = 0;
}
@@ -234,14 +244,16 @@ public class CCITTFaxEncoderStream extends OutputStream {
// PMODE
write(1, 4);
index = nextRefs[1];
} else if (difference > 3 || difference < -3) {
}
else if (difference > 3 || difference < -3) {
// HMODE
write(1, 3);
writeRun(nextChanges[0] - index, white);
writeRun(nextChanges[1] - nextChanges[0], !white);
index = nextChanges[1];
} else {
}
else {
// VMODE
switch (difference) {
case 0:
@@ -292,7 +304,8 @@ public class CCITTFaxEncoderStream extends OutputStream {
boolean codeBit = ((code >> (codeLength - i - 1)) & 1) == 1;
if (fillOrder == TIFFBaseline.FILL_LEFT_TO_RIGHT) {
outputBuffer |= (codeBit ? 1 << (7 - ((outputBufferBitLength) % 8)) : 0);
} else {
}
else {
outputBuffer |= (codeBit ? 1 << (((outputBufferBitLength) % 8)) : 0);
}
outputBufferBitLength++;
@@ -355,7 +368,8 @@ public class CCITTFaxEncoderStream extends OutputStream {
if (value < 64) {
WHITE_TERMINATING_CODES[value] = new Code(code, bitLength);
} else {
}
else {
WHITE_NONTERMINATING_CODES[(value / 64) - 1] = new Code(code, bitLength);
}
}
@@ -371,7 +385,8 @@ public class CCITTFaxEncoderStream extends OutputStream {
if (value < 64) {
BLACK_TERMINATING_CODES[value] = new Code(code, bitLength);
} else {
}
else {
BLACK_NONTERMINATING_CODES[(value / 64) - 1] = new Code(code, bitLength);
}
}

View File

@@ -28,22 +28,15 @@
package com.twelvemonkeys.imageio.plugins.tiff;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.OutputStream;
import com.twelvemonkeys.imageio.plugins.tiff.CCITTFaxEncoderStream.Code;
import org.junit.Before;
import org.junit.Test;
import com.twelvemonkeys.imageio.plugins.tiff.CCITTFaxEncoderStream.Code;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.*;
import static org.junit.Assert.*;
/**
* CCITTFaxEncoderStreamTest
@@ -122,7 +115,7 @@ public class CCITTFaxEncoderStreamTest {
byte[] imageData = ((DataBufferByte) image.getData().getDataBuffer()).getData();
byte[] redecodedData = new byte[imageData.length];
ByteArrayOutputStream imageOutput = new ByteArrayOutputStream();
OutputStream outputSteam = new CCITTFaxEncoderStream(imageOutput, 6, type, fillOrder, options);
OutputStream outputSteam = new CCITTFaxEncoderStream(imageOutput, 6, 4, type, fillOrder, options);
outputSteam.write(imageData);
outputSteam.close();
byte[] encodedData = imageOutput.toByteArray();