#232: Cleanup after merge of #225

This commit is contained in:
Harald Kuhr 2016-04-21 14:05:45 +02:00
parent 2cec177c6d
commit 047884e3d9
4 changed files with 107 additions and 80 deletions

View File

@ -281,7 +281,6 @@ final class CCITTFaxDecoderStream extends FilterInputStream {
int index = 0; int index = 0;
boolean white = true; boolean white = true;
for (int i = 0; i <= changesCurrentRowCount; i++) { for (int i = 0; i <= changesCurrentRowCount; i++) {
int nextChange = columns; int nextChange = columns;
@ -404,14 +403,14 @@ final class CCITTFaxDecoderStream extends FilterInputStream {
@Override @Override
public int read() throws IOException { public int read() throws IOException {
if (decodedLength < 0) { if (decodedLength < 0) {
return 0xFF; return 0x0;
} }
if (decodedPos >= decodedLength) { if (decodedPos >= decodedLength) {
fetch(); fetch();
if (decodedLength < 0) { if (decodedLength < 0) {
return 0xFF; return 0x0;
} }
} }
@ -421,7 +420,7 @@ final class CCITTFaxDecoderStream extends FilterInputStream {
@Override @Override
public int read(byte[] b, int off, int len) throws IOException { public int read(byte[] b, int off, int len) throws IOException {
if (decodedLength < 0) { if (decodedLength < 0) {
Arrays.fill(b, off, len, (byte)0xFF); Arrays.fill(b, off, off + len, (byte) 0x0);
return len; return len;
} }
@ -429,7 +428,7 @@ final class CCITTFaxDecoderStream extends FilterInputStream {
fetch(); fetch();
if (decodedLength < 0) { if (decodedLength < 0) {
Arrays.fill(b, off, len, (byte)0xFF); Arrays.fill(b, off, off + len, (byte) 0x0);
return len; return len;
} }
} }

View File

@ -40,7 +40,7 @@ import java.io.OutputStream;
* @author last modified by $Author$ * @author last modified by $Author$
* @version $Id$ * @version $Id$
*/ */
public class CCITTFaxEncoderStream extends OutputStream { final class CCITTFaxEncoderStream extends OutputStream {
private int currentBufferLength = 0; private int currentBufferLength = 0;
private final byte[] inputBuffer; private final byte[] inputBuffer;

View File

@ -37,8 +37,9 @@ import java.io.ByteArrayInputStream;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Arrays;
import static org.junit.Assert.*; import static org.junit.Assert.assertArrayEquals;
/** /**
* CCITTFaxDecoderStreamTest * CCITTFaxDecoderStreamTest
@ -109,11 +110,11 @@ public class CCITTFaxDecoderStreamTest {
// 1 1 1 0 1 1 x x // 1 1 1 0 1 1 x x
// 1 1 1 0 1 1 x x // 1 1 1 0 1 1 x x
// 1 1 0 0 1 1 x x // 1 1 0 0 1 1 x x
BufferedImage image; final BufferedImage image = new BufferedImage(6, 4, BufferedImage.TYPE_BYTE_BINARY);;
@Before @Before
public void init() { public void init() {
image = new BufferedImage(6, 4, BufferedImage.TYPE_BYTE_BINARY);
for (int y = 0; y < 4; y++) { for (int y = 0; y < 4; y++) {
for (int x = 0; x < 6; x++) { for (int x = 0; x < 6; x++) {
image.setRGB(x, y, x != 3 ? 0xff000000 : 0xffffffff); image.setRGB(x, y, x != 3 ? 0xff000000 : 0xffffffff);
@ -200,4 +201,32 @@ public class CCITTFaxDecoderStreamTest {
new DataInputStream(stream).readFully(bytes); new DataInputStream(stream).readFully(bytes);
assertArrayEquals(imageData, bytes); assertArrayEquals(imageData, bytes);
} }
@Test
public void testDecodeMissingRows() throws IOException {
// See https://github.com/haraldk/TwelveMonkeys/pull/225 and https://github.com/haraldk/TwelveMonkeys/issues/232
InputStream inputStream = getClass().getResourceAsStream("/tiff/ccitt_tolessrows.tif");
// Skip until StripOffsets: 8
for (int i = 0; i < 8; i++) {
inputStream.read();
}
// Read until StripByteCounts: 7
byte[] data = new byte[7];
new DataInputStream(inputStream).readFully(data);
InputStream stream = new CCITTFaxDecoderStream(new ByteArrayInputStream(data),
6, TIFFExtension.COMPRESSION_CCITT_T6, 1, 0L);
byte[] bytes = new byte[6]; // 6 x 6 pixel, 1 bpp => 6 bytes
new DataInputStream(stream).readFully(bytes);
// Pad image data with 0s
byte[] imageData = Arrays.copyOf(((DataBufferByte) image.getData().getDataBuffer()).getData(), 6);
assertArrayEquals(imageData, bytes);
// Ideally, we should have no more data now, but the stream don't know that...
// assertEquals("Should contain no more data", -1, stream.read());
}
} }

View File

@ -29,7 +29,6 @@
package com.twelvemonkeys.imageio.plugins.tiff; package com.twelvemonkeys.imageio.plugins.tiff;
import com.twelvemonkeys.imageio.plugins.tiff.CCITTFaxEncoderStream.Code; import com.twelvemonkeys.imageio.plugins.tiff.CCITTFaxEncoderStream.Code;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -122,16 +121,34 @@ public class CCITTFaxEncoderStreamTest {
@Test @Test
public void testReencodeImages() throws IOException { public void testReencodeImages() throws IOException {
testImage(getClassLoaderResource("/tiff/fivepages-scan-causingerrors.tif")); try (ImageInputStream iis = ImageIO.createImageInputStream(getClassLoaderResource("/tiff/fivepages-scan-causingerrors.tif").openStream())) {
ImageReader reader = ImageIO.getImageReaders(iis).next();
reader.setInput(iis, true);
ByteArrayOutputStream outputBuffer = new ByteArrayOutputStream();
ImageWriter writer = ImageIO.getImageWritersByFormatName("TIFF").next();
BufferedImage originalImage;
try (ImageOutputStream output = ImageIO.createImageOutputStream(outputBuffer)) {
writer.setOutput(output);
originalImage = reader.read(0);
IIOImage outputImage = new IIOImage(originalImage, null, reader.getImageMetadata(0));
writer.write(outputImage);
}
byte[] originalData = ((DataBufferByte) originalImage.getData().getDataBuffer()).getData();
BufferedImage reencodedImage = ImageIO.read(new ByteArrayInputStream(outputBuffer.toByteArray()));
byte[] reencodedData = ((DataBufferByte) reencodedImage.getData().getDataBuffer()).getData();
assertArrayEquals(originalData, reencodedData);
}
} }
/**
* Test for "Fixed an issue with long runlengths in CCITTFax writing #188"
*
* @throws IOException
*/
@Test @Test
public void testRunlengthIssue() throws IOException { public void testRunlengthIssue() throws IOException {
// Test for "Fixed an issue with long runlengths in CCITTFax writing #188"
byte[] data = new byte[400]; byte[] data = new byte[400];
Arrays.fill(data, (byte) 0xFF); Arrays.fill(data, (byte) 0xFF);
data[0] = 0; data[0] = 0;
@ -158,37 +175,19 @@ public class CCITTFaxEncoderStreamTest {
private void testStreamEncodeDecode(int type, int fillOrder, long options) throws IOException { private void testStreamEncodeDecode(int type, int fillOrder, long options) throws IOException {
byte[] imageData = ((DataBufferByte) image.getData().getDataBuffer()).getData(); byte[] imageData = ((DataBufferByte) image.getData().getDataBuffer()).getData();
byte[] redecodedData = new byte[imageData.length]; byte[] redecodedData = new byte[imageData.length];
ByteArrayOutputStream imageOutput = new ByteArrayOutputStream(); ByteArrayOutputStream imageOutput = new ByteArrayOutputStream();
OutputStream outputSteam = new CCITTFaxEncoderStream(imageOutput, 6, 4, type, fillOrder, options); OutputStream outputSteam = new CCITTFaxEncoderStream(imageOutput, 6, 4, type, fillOrder, options);
outputSteam.write(imageData); outputSteam.write(imageData);
outputSteam.close(); outputSteam.close();
byte[] encodedData = imageOutput.toByteArray(); byte[] encodedData = imageOutput.toByteArray();
CCITTFaxDecoderStream inputStream = new CCITTFaxDecoderStream(new ByteArrayInputStream(encodedData), 6, type, try (CCITTFaxDecoderStream inputStream =
fillOrder, options); new CCITTFaxDecoderStream(new ByteArrayInputStream(encodedData), 6, type, fillOrder, options)) {
new DataInputStream(inputStream).readFully(redecodedData); new DataInputStream(inputStream).readFully(redecodedData);
inputStream.close(); }
assertArrayEquals(imageData, redecodedData); assertArrayEquals(imageData, redecodedData);
} }
private void testImage(URL imageUrl) throws IOException {
ImageInputStream iis = ImageIO.createImageInputStream(imageUrl.openStream());
ImageReader reader = ImageIO.getImageReadersByFormatName("TIFF").next();
reader.setInput(iis, true);
ByteArrayOutputStream outputBuffer = new ByteArrayOutputStream();
ImageWriter writer = ImageIO.getImageWritersByFormatName("TIFF").next();
ImageOutputStream output = ImageIO.createImageOutputStream(outputBuffer);
writer.setOutput(output);
BufferedImage originalImage = reader.read(0);
IIOImage outputImage = new IIOImage(originalImage, null, reader.getImageMetadata(0));
writer.write(outputImage);
BufferedImage reencodedImage = ImageIO.read(new ByteArrayInputStream(outputBuffer.toByteArray()));
byte[] reencodedData = ((DataBufferByte) reencodedImage.getData().getDataBuffer()).getData();
Assert.assertArrayEquals(((DataBufferByte) originalImage.getData().getDataBuffer()).getData(), reencodedData);
}
} }