#280 Support for bitsPerSample == 6, 10, 12, 14 & 24

This commit is contained in:
Harald Kuhr
2016-11-16 18:52:39 +01:00
parent ab13084f44
commit e0b9bdef7e
10 changed files with 573 additions and 76 deletions
@@ -0,0 +1,186 @@
package com.twelvemonkeys.imageio.plugins.tiff;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.nio.ByteOrder;
import static org.junit.Assert.*;
/**
* BitPaddingStreamTest.
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: harald.kuhr$
* @version $Id: BitPaddingStreamTest.java,v 1.0 16/11/2016 harald.kuhr Exp$
*/
public class BitPaddingStreamTest {
@Test(expected = IllegalArgumentException.class)
public void testCreateNullStream() {
new BitPaddingStream(null, 1, 12, 4, ByteOrder.BIG_ENDIAN);
}
@Test(expected = IllegalArgumentException.class)
public void testCreateBadBits() {
new BitPaddingStream(new ByteArrayInputStream(new byte[6]), 1, 7, 4, ByteOrder.BIG_ENDIAN);
}
@Test(expected = IllegalArgumentException.class)
public void testCreateBadBitsLarge() {
new BitPaddingStream(new ByteArrayInputStream(new byte[6]), 1, 37, 4, ByteOrder.BIG_ENDIAN);
}
@Test(expected = IllegalArgumentException.class)
public void testCreateNullByteOrder() {
new BitPaddingStream(new ByteArrayInputStream(new byte[6]), 1, 12, 4, null);
}
@Test
public void testRead() throws IOException {
byte[] bytes = {(byte) 0xff, (byte) 0xf0, 0x00, 0x66, 0x67, (byte) 0x89};
BitPaddingStream stream = new BitPaddingStream(new ByteArrayInputStream(bytes), 1, 12, 4, ByteOrder.BIG_ENDIAN);
assertEquals(0x0f, stream.read());
assertEquals(0xff, stream.read());
assertEquals(0x00, stream.read());
assertEquals(0x00, stream.read());
assertEquals(0x06, stream.read());
assertEquals(0x66, stream.read());
assertEquals(0x07, stream.read());
assertEquals(0x89, stream.read());
assertEquals(-1, stream.read());
}
// TODO: Test read 10, 14, etc bits....
@Test
public void testReadLittleEndian() throws IOException {
byte[] bytes = {(byte) 0xff, (byte) 0xf0, 0x00, 0x66, 0x67, (byte) 0x89};
BitPaddingStream stream = new BitPaddingStream(new ByteArrayInputStream(bytes), 1, 12, 4, ByteOrder.LITTLE_ENDIAN);
assertEquals(0xff, stream.read());
assertEquals(0x0f, stream.read());
assertEquals(0x00, stream.read());
assertEquals(0x00, stream.read());
assertEquals(0x66, stream.read());
assertEquals(0x06, stream.read());
assertEquals(0x89, stream.read());
assertEquals(0x07, stream.read());
assertEquals(-1, stream.read());
}
@Test
public void testRead3Components() throws IOException {
byte[] bytes = {(byte) 0xff, (byte) 0xf0, 0x00, 0x66, 0x60};
BitPaddingStream stream = new BitPaddingStream(new ByteArrayInputStream(bytes), 3, 12, 1, ByteOrder.BIG_ENDIAN);
assertEquals(0x0f, stream.read());
assertEquals(0xff, stream.read());
assertEquals(0x00, stream.read());
assertEquals(0x00, stream.read());
assertEquals(0x06, stream.read());
assertEquals(0x66, stream.read());
assertEquals(-1, stream.read());
}
@Test
public void testReadArray() throws IOException {
byte[] bytes = {(byte) 0xff, (byte) 0xf0, 0x00, 0x66, 0x67, (byte) 0x89};
BitPaddingStream stream = new BitPaddingStream(new ByteArrayInputStream(bytes), 1, 12, 4, ByteOrder.BIG_ENDIAN);
byte[] result = new byte[8];
new DataInputStream(stream).readFully(result);
assertArrayEquals(new byte[] {0x0f, (byte) 0xff, 0x00, 0x00, 0x06, 0x66, 0x07, (byte) 0x89}, result);
assertEquals(-1, stream.read());
assertEquals(-1, stream.read(new byte[4]));
}
@Test
public void testReadArrayLittleEndian() throws IOException {
byte[] bytes = {(byte) 0xff, (byte) 0xf0, 0x00, 0x66, 0x67, (byte) 0x89};
BitPaddingStream stream = new BitPaddingStream(new ByteArrayInputStream(bytes), 1, 12, 4, ByteOrder.LITTLE_ENDIAN);
byte[] result = new byte[8];
new DataInputStream(stream).readFully(result);
assertArrayEquals(new byte[] {(byte) 0xff, 0x0f, 0x00, 0x00, 0x66, 0x06, (byte) 0x89, 0x07}, result);
assertEquals(-1, stream.read());
assertEquals(-1, stream.read(new byte[4]));
}
@Test
public void testReadArray2Components() throws IOException {
byte[] bytes = {(byte) 0xff, (byte) 0xf0, 0x00, 0x66, 0x67, (byte) 0x89};
BitPaddingStream stream = new BitPaddingStream(new ByteArrayInputStream(bytes), 2, 12, 2, ByteOrder.BIG_ENDIAN);
byte[] result = new byte[8];
new DataInputStream(stream).readFully(result);
assertArrayEquals(new byte[] {0x0f, (byte) 0xff, 0x00, 0x00, 0x06, 0x66, 0x07, (byte) 0x89}, result);
assertEquals(-1, stream.read());
assertEquals(-1, stream.read(new byte[4]));
}
@Test
public void testReadArray3Components() throws IOException {
byte[] bytes = {(byte) 0xff, (byte) 0xf0, 0x00, 0x66, 0x6f};
BitPaddingStream stream = new BitPaddingStream(new ByteArrayInputStream(bytes), 3, 12, 1, ByteOrder.BIG_ENDIAN);
byte[] result = new byte[6];
new DataInputStream(stream).readFully(result);
assertArrayEquals(new byte[] {0x0f, (byte) 0xff, 0x00, 0x00, 0x06, 0x66}, result);
assertEquals(-1, stream.read());
assertEquals(-1, stream.read(new byte[4]));
}
@Test
public void testReadArray4Components() throws IOException {
byte[] bytes = {(byte) 0xff, (byte) 0xf0, 0x00, 0x66, 0x67, (byte) 0x89};
BitPaddingStream stream = new BitPaddingStream(new ByteArrayInputStream(bytes), 4, 12, 1, ByteOrder.BIG_ENDIAN);
byte[] result = new byte[8];
new DataInputStream(stream).readFully(result);
assertArrayEquals(new byte[] {0x0f, (byte) 0xff, 0x00, 0x00, 0x06, 0x66, 0x07, (byte) 0x89}, result);
assertEquals(-1, stream.read());
assertEquals(-1, stream.read(new byte[4]));
}
@Test
public void testSkip() throws IOException {
byte[] bytes = {(byte) 0xff, (byte) 0xf0, 0x00, 0x66, 0x67, (byte) 0x89};
BitPaddingStream stream = new BitPaddingStream(new ByteArrayInputStream(bytes), 1, 12, 4, ByteOrder.BIG_ENDIAN);
assertEquals(4, stream.skip(4)); // Normal skip
assertEquals(0x06, stream.read()); // Verify position after skip
assertEquals(3, stream.skip(4)); // Partial skip
assertEquals(-1, stream.read()); // Verify position (EOF)
}
}
@@ -29,6 +29,7 @@ package com.twelvemonkeys.imageio.plugins.tiff;/*
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
import org.junit.Test;
import javax.imageio.IIOException;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
@@ -44,6 +45,7 @@ import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.junit.Assert.*;
import static org.junit.internal.matchers.StringContains.containsString;
import static org.mockito.Matchers.contains;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.*;
@@ -109,8 +111,13 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest<TIFFImageReader
// Gray
new TestData(getClassLoaderResource("/tiff/depth/flower-minisblack-02.tif"), new Dimension(73, 43)), // Gray 2 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-minisblack-04.tif"), new Dimension(73, 43)), // Gray 4 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-minisblack-06.tif"), new Dimension(73, 43)), // Gray 6 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-minisblack-08.tif"), new Dimension(73, 43)), // Gray 8 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-minisblack-10.tif"), new Dimension(73, 43)), // Gray 10 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-minisblack-12.tif"), new Dimension(73, 43)), // Gray 12 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-minisblack-14.tif"), new Dimension(73, 43)), // Gray 14 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-minisblack-16.tif"), new Dimension(73, 43)), // Gray 16 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-minisblack-24.tif"), new Dimension(73, 43)), // Gray 24 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-minisblack-32.tif"), new Dimension(73, 43)), // Gray 32 bit/sample
// Palette
new TestData(getClassLoaderResource("/tiff/depth/flower-palette-02.tif"), new Dimension(73, 43)), // Palette 2 bit/sample
@@ -119,12 +126,21 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest<TIFFImageReader
new TestData(getClassLoaderResource("/tiff/depth/flower-palette-16.tif"), new Dimension(73, 43)), // Palette 16 bit/sample
// RGB Interleaved (PlanarConfiguration: 1)
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-contig-08.tif"), new Dimension(73, 43)), // RGB 8 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-contig-10.tif"), new Dimension(73, 43)), // RGB 10 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-contig-12.tif"), new Dimension(73, 43)), // RGB 12 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-contig-14.tif"), new Dimension(73, 43)), // RGB 14 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-contig-16.tif"), new Dimension(73, 43)), // RGB 16 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-contig-24.tif"), new Dimension(73, 43)), // RGB 24 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-contig-32.tif"), new Dimension(73, 43)), // RGB 32 bit/sample
// RGB Planar (PlanarConfiguration: 2)
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-planar-08.tif"), new Dimension(73, 43)), // RGB 8 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-planar-10.tif"), new Dimension(73, 43)), // RGB 10 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-planar-12.tif"), new Dimension(73, 43)), // RGB 12 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-planar-14.tif"), new Dimension(73, 43)), // RGB 14 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-planar-16.tif"), new Dimension(73, 43)), // RGB 16 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-planar-32.tif"), new Dimension(73, 43)), // RGB 32 bit FP samples!
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-planar-24.tif"), new Dimension(73, 43)), // RGB 24 bit/sample
// RGB Interleaved Floating point..!? We can read this one, but the samples are not normalized, so colors are way too bright...
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-planar-32.tif"), new Dimension(73, 43)), // RGB 32 bit FP samples (!)
// Separated (CMYK) Interleaved (PlanarConfiguration: 1)
new TestData(getClassLoaderResource("/tiff/depth/flower-separated-contig-08.tif"), new Dimension(73, 43)), // CMYK 8 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-separated-contig-16.tif"), new Dimension(73, 43)), // CMYK 16 bit/sample
@@ -134,6 +150,16 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest<TIFFImageReader
);
}
protected List<TestData> getUnsupportedTestData() {
return Arrays.asList(
// RGB Interleaved (PlanarConfiguration: 1)
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-contig-02.tif"), new Dimension(73, 43)), // RGB 2 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-contig-04.tif"), new Dimension(73, 43)), // RGB 4 bit/sample
// RGB Planar (PlanarConfiguration: 2)
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-planar-02.tif"), new Dimension(73, 43)), // RGB 2 bit/sample
new TestData(getClassLoaderResource("/tiff/depth/flower-rgb-planar-04.tif"), new Dimension(73, 43)) // RGB 4 bit/sample
);
}
@Override
protected ImageReaderSpi createProvider() {
return SPI;
@@ -512,4 +538,26 @@ public class TIFFImageReaderTest extends ImageReaderAbstractTest<TIFFImageReader
assertSubsampledImageDataEquals("Subsampled image data does not match expected", image, subsampled, param);
}
@Test
public void testReadUnsupported() {
ImageReader reader = createReader();
for (TestData data : getUnsupportedTestData()) {
reader.setInput(data.getInputStream());
for (int i = 0; i < data.getImageCount(); i++) {
try {
reader.read(i);
fail("Sample should be moved from unsupported to normal test case");
}
catch (IIOException e) {
assertThat(e.getMessage().toLowerCase(), containsString("unsupported"));
}
catch (Exception e) {
failBecause(String.format("Image %s index %s could not be read: %s", data.getInput(), i, e), e);
}
}
}
}
}