Compare commits

...

10 Commits

Author SHA1 Message Date
Harald Kuhr 5da934e11b [maven-release-plugin] prepare release twelvemonkeys-3.6.2 2021-01-23 17:08:59 +01:00
Harald Kuhr 51297ad496 #582: Fix for missing Exif thumbnail, now only issues warning.
(cherry picked from commit de02e3d7e0)
2021-01-23 17:01:14 +01:00
Harald Kuhr 80a534cd62 Fix some corner cases in BufferedImageInputStream.
(cherry picked from commit 8a1a90dafd)
2021-01-23 17:01:08 +01:00
Harald Kuhr 24130d466d #579 More reliable CCITT compression type detection
(cherry picked from commit 253f04066b)
2021-01-23 17:01:05 +01:00
Harald Kuhr 7559686782 StandardCharsets.US_ASCII instead of Charset.forName("ascii")
(cherry picked from commit 74902b3fb4)
2021-01-23 17:00:58 +01:00
Harald Kuhr b6988c37a7 #577 Fix TGA subsampling + bonus metadata fix and palette conversion.
(cherry picked from commit af1a6492d4)
2021-01-23 17:00:48 +01:00
Harald Kuhr bbffb1d416 BufferedImageInputStream performance optimizations.
(cherry picked from commit c7d2f422b8)
2021-01-23 17:00:31 +01:00
Harald Kuhr c68de3bc92 Updated links to latest version.
(cherry picked from commit 25150b421c)
2021-01-23 16:59:58 +01:00
Harald Kuhr a12b6044c6 Add XWD to BOM.
(cherry picked from commit 94031a2913)
2021-01-23 16:59:48 +01:00
Harald Kuhr 9a0e2d9659 [maven-release-plugin] prepare for next development iteration 2020-11-19 22:40:02 +01:00
39 changed files with 418 additions and 101 deletions
+32 -32
View File
@@ -280,12 +280,12 @@ To depend on the JPEG and TIFF plugin using Maven, add the following to your POM
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-jpeg</artifactId>
<version>3.6</version>
<version>3.6.1</version>
</dependency>
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-tiff</artifactId>
<version>3.6</version>
<version>3.6.1</version>
</dependency>
<!--
@@ -295,7 +295,7 @@ To depend on the JPEG and TIFF plugin using Maven, add the following to your POM
<dependency>
<groupId>com.twelvemonkeys.servlet</groupId>
<artifactId>servlet</artifactId>
<version>3.6</version>
<version>3.6.1</version>
</dependency>
</dependencies>
```
@@ -304,13 +304,13 @@ To depend on the JPEG and TIFF plugin using Maven, add the following to your POM
To depend on the JPEG and TIFF plugin in your IDE or program, add all of the following JARs to your class path:
twelvemonkeys-common-lang-3.6.jar
twelvemonkeys-common-io-3.6.jar
twelvemonkeys-common-image-3.6.jar
twelvemonkeys-imageio-core-3.6.jar
twelvemonkeys-imageio-metadata-3.6.jar
twelvemonkeys-imageio-jpeg-3.6.jar
twelvemonkeys-imageio-tiff-3.6.jar
twelvemonkeys-common-lang-3.6.1.jar
twelvemonkeys-common-io-3.6.1.jar
twelvemonkeys-common-image-3.6.1.jar
twelvemonkeys-imageio-core-3.6.1.jar
twelvemonkeys-imageio-metadata-3.6.1.jar
twelvemonkeys-imageio-jpeg-3.6.1.jar
twelvemonkeys-imageio-tiff-3.6.1.jar
#### Deploying the plugins in a web app
@@ -376,42 +376,42 @@ Other "fat" JAR bundlers will probably have similar mechanisms to merge entries
### Links to prebuilt binaries
##### Latest version (3.6)
##### Latest version (3.6.1)
Requires Java 7 or later.
Common dependencies
* [common-lang-3.6.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-lang/3.6/common-lang-3.6.jar)
* [common-io-3.6.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-io/3.6/common-io-3.6.jar)
* [common-image-3.6.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-image/3.6/common-image-3.6.jar)
* [common-lang-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-lang/3.6.1/common-lang-3.6.1.jar)
* [common-io-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-io/3.6.1/common-io-3.6.1.jar)
* [common-image-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-image/3.6.1/common-image-3.6.1.jar)
ImageIO dependencies
* [imageio-core-3.6.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-core/3.6/imageio-core-3.6.jar)
* [imageio-metadata-3.6.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-metadata/3.6/imageio-metadata-3.6.jar)
* [imageio-core-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-core/3.6.1/imageio-core-3.6.1.jar)
* [imageio-metadata-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-metadata/3.6.1/imageio-metadata-3.6.1.jar)
ImageIO plugins
* [imageio-bmp-3.6.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-bmp/3.6/imageio-bmp-3.6.jar)
* [imageio-jpeg-3.6.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-jpeg/3.6/imageio-jpeg-3.6.jar)
* [imageio-tiff-3.6.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-tiff/3.6/imageio-tiff-3.6.jar)
* [imageio-pnm-3.6.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-pnm/3.6/imageio-pnm-3.6.jar)
* [imageio-psd-3.6.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-psd/3.6/imageio-psd-3.6.jar)
* [imageio-hdr-3.6.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-hdr/3.6/imageio-hdr-3.6.jar)
* [imageio-iff-3.6.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-iff/3.6/imageio-iff-3.6.jar)
* [imageio-pcx-3.6.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-pcx/3.6/imageio-pcx-3.6.jar)
* [imageio-pict-3.6.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-pict/3.6/imageio-pict-3.6.jar)
* [imageio-sgi-3.6.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-sgi/3.6/imageio-sgi-3.6.jar)
* [imageio-tga-3.6.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-tga/3.6/imageio-tga-3.6.jar)
* [imageio-icns-3.6.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-icns/3.6/imageio-icns-3.6.jar)
* [imageio-thumbsdb-3.6.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-thumbsdb/3.6/imageio-thumbsdb-3.6.jar)
* [imageio-bmp-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-bmp/3.6.1/imageio-bmp-3.6.1.jar)
* [imageio-jpeg-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-jpeg/3.6.1/imageio-jpeg-3.6.1.jar)
* [imageio-tiff-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-tiff/3.6.1/imageio-tiff-3.6.1.jar)
* [imageio-pnm-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-pnm/3.6.1/imageio-pnm-3.6.1.jar)
* [imageio-psd-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-psd/3.6.1/imageio-psd-3.6.1.jar)
* [imageio-hdr-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-hdr/3.6.1/imageio-hdr-3.6.1.jar)
* [imageio-iff-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-iff/3.6.1/imageio-iff-3.6.1.jar)
* [imageio-pcx-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-pcx/3.6.1/imageio-pcx-3.6.1.jar)
* [imageio-pict-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-pict/3.6.1/imageio-pict-3.6.1.jar)
* [imageio-sgi-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-sgi/3.6.1/imageio-sgi-3.6.1.jar)
* [imageio-tga-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-tga/3.6.1/imageio-tga-3.6.1.jar)
* [imageio-icns-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-icns/3.6.1/imageio-icns-3.6.1.jar)
* [imageio-thumbsdb-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-thumbsdb/3.6.1/imageio-thumbsdb-3.6.1.jar)
ImageIO plugins requiring 3rd party libs
* [imageio-batik-3.6.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-batik/3.6/imageio-batik-3.6.jar)
* [imageio-batik-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-batik/3.6.1/imageio-batik-3.6.1.jar)
Photoshop Path support for ImageIO
* [imageio-clippath-3.6.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-clippath/3.6/imageio-clippath-3.6.jar)
* [imageio-clippath-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-clippath/3.6.1/imageio-clippath-3.6.1.jar)
Servlet support
* [servlet-3.6.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/servlet/servlet/3.6/servlet-3.6.jar)
* [servlet-3.6.1.jar](http://search.maven.org/remotecontent?filepath=com/twelvemonkeys/servlet/servlet/3.6.1/servlet-3.6.1.jar)
##### Old version (3.0.x)
+6 -1
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>com.twelvemonkeys</groupId>
<artifactId>twelvemonkeys</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<groupId>com.twelvemonkeys.bom</groupId>
@@ -123,6 +123,11 @@
<artifactId>imageio-tiff</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-xwd</artifactId>
<version>${project.version}</version>
</dependency>
<!-- ImageIO 3rd party dependent plugins -->
<dependency>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.common</groupId>
<artifactId>common</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<artifactId>common-image</artifactId>
<packaging>jar</packaging>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.common</groupId>
<artifactId>common</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<artifactId>common-io</artifactId>
<packaging>jar</packaging>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.common</groupId>
<artifactId>common</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<artifactId>common-lang</artifactId>
<packaging>jar</packaging>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys</groupId>
<artifactId>twelvemonkeys</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<groupId>com.twelvemonkeys.common</groupId>
<artifactId>common</artifactId>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys</groupId>
<artifactId>twelvemonkeys</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<groupId>com.twelvemonkeys.contrib</groupId>
<artifactId>contrib</artifactId>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<artifactId>imageio-batik</artifactId>
<name>TwelveMonkeys :: ImageIO :: Batik Plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<artifactId>imageio-bmp</artifactId>
<name>TwelveMonkeys :: ImageIO :: BMP plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<artifactId>imageio-clippath</artifactId>
<name>TwelveMonkeys :: ImageIO :: Photoshop Path Support</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<artifactId>imageio-core</artifactId>
<name>TwelveMonkeys :: ImageIO :: Core</name>
@@ -57,8 +57,10 @@ public final class BufferedImageInputStream extends ImageInputStreamImpl impleme
private ImageInputStream stream;
private ByteBuffer buffer;
private ByteBuffer integralCache = ByteBuffer.allocate(8);
private ByteBuffer buffer;
private final ByteBuffer integralCache = ByteBuffer.allocate(8);
private final byte[] integralCacheArray = integralCache.array();
public BufferedImageInputStream(final ImageInputStream pStream) throws IOException {
this(pStream, DEFAULT_BUFFER_SIZE);
@@ -97,10 +99,10 @@ public final class BufferedImageInputStream extends ImageInputStreamImpl impleme
if (!buffer.hasRemaining()) {
fillBuffer();
}
if (!buffer.hasRemaining()) {
return -1;
if (!buffer.hasRemaining()) {
return -1;
}
}
bitOffset = 0;
@@ -172,21 +174,21 @@ public final class BufferedImageInputStream extends ImageInputStreamImpl impleme
@Override
public short readShort() throws IOException {
readFully(integralCache.array(), 0, 2);
readFully(integralCacheArray, 0, 2);
return integralCache.getShort(0);
}
@Override
public int readInt() throws IOException {
readFully(integralCache.array(), 0, 4);
readFully(integralCacheArray, 0, 4);
return integralCache.getInt(0);
}
@Override
public long readLong() throws IOException {
readFully(integralCache.array(), 0, 8);
readFully(integralCacheArray, 0, 8);
return integralCache.getLong(0);
}
@@ -253,6 +255,7 @@ public final class BufferedImageInputStream extends ImageInputStreamImpl impleme
}
int val = buffer.get() & 0xff;
streamPos++;
accum <<= 8;
accum |= val;
@@ -262,9 +265,7 @@ public final class BufferedImageInputStream extends ImageInputStreamImpl impleme
// Move byte position back if in the middle of a byte
if (newBitOffset != 0) {
buffer.position(buffer.position() - 1);
}
else {
streamPos++;
streamPos--;
}
this.bitOffset = newBitOffset;
@@ -279,26 +280,26 @@ public final class BufferedImageInputStream extends ImageInputStreamImpl impleme
}
@Override
public void seek(long pPosition) throws IOException {
public void seek(long position) throws IOException {
checkClosed();
bitOffset = 0;
if (streamPos == pPosition) {
if (streamPos == position) {
return;
}
// Optimized to not invalidate buffer if new position is within current buffer
long newBufferPos = buffer.position() + pPosition - streamPos;
long newBufferPos = buffer.position() + position - streamPos;
if (newBufferPos >= 0 && newBufferPos <= buffer.limit()) {
buffer.position((int) newBufferPos);
}
else {
// Will invalidate buffer
buffer.limit(0);
stream.seek(pPosition);
stream.seek(position);
}
streamPos = pPosition;
streamPos = position;
}
@Override
@@ -330,7 +331,9 @@ public final class BufferedImageInputStream extends ImageInputStreamImpl impleme
@Override
public void close() throws IOException {
if (stream != null) {
//stream.close();
// TODO: FixMe: Need to close underlying stream here!
// For call sites that relies on not closing, we should instead not close the buffered stream.
// stream.close();
stream = null;
buffer = null;
}
@@ -32,16 +32,19 @@ package com.twelvemonkeys.imageio.stream;
import com.twelvemonkeys.io.ole2.CompoundDocument;
import com.twelvemonkeys.io.ole2.Entry;
import org.junit.Test;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.MemoryCacheImageInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Random;
import static java.util.Arrays.fill;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
/**
* BufferedImageInputStreamTest
@@ -72,6 +75,257 @@ public class BufferedImageInputStreamTest {
}
}
@Test
public void testReadBit() throws IOException {
byte[] bytes = new byte[] {(byte) 0xF0, (byte) 0x0F};
// Create wrapper stream
BufferedImageInputStream stream = new BufferedImageInputStream(new ByteArrayImageInputStream(bytes));
// Read all bits
assertEquals(1, stream.readBit());
assertEquals(1, stream.getBitOffset());
assertEquals(0, stream.getStreamPosition());
assertEquals(1, stream.readBit());
assertEquals(2, stream.getBitOffset());
assertEquals(0, stream.getStreamPosition());
assertEquals(1, stream.readBit());
assertEquals(3, stream.getBitOffset());
assertEquals(0, stream.getStreamPosition());
assertEquals(1, stream.readBit());
assertEquals(4, stream.getBitOffset());
assertEquals(0, stream.getStreamPosition());
assertEquals(0, stream.readBit());
assertEquals(5, stream.getBitOffset());
assertEquals(0, stream.getStreamPosition());
assertEquals(0, stream.readBit());
assertEquals(6, stream.getBitOffset());
assertEquals(0, stream.getStreamPosition());
assertEquals(0, stream.readBit());
assertEquals(7, stream.getBitOffset());
assertEquals(0, stream.getStreamPosition());
assertEquals(0, stream.readBit()); // last bit
assertEquals(0, stream.getBitOffset());
assertEquals(1, stream.getStreamPosition());
// Full reset, read same sequence again
stream.seek(0);
assertEquals(0, stream.getBitOffset());
assertEquals(0, stream.getStreamPosition());
assertEquals(1, stream.readBit());
assertEquals(1, stream.readBit());
assertEquals(1, stream.readBit());
assertEquals(1, stream.readBit());
assertEquals(0, stream.readBit());
assertEquals(0, stream.readBit());
assertEquals(0, stream.readBit());
assertEquals(0, stream.readBit());
assertEquals(0, stream.getBitOffset());
assertEquals(1, stream.getStreamPosition());
// Full reset, read partial
stream.seek(0);
assertEquals(1, stream.readBit());
assertEquals(1, stream.readBit());
// Byte reset, read same sequence again
stream.setBitOffset(0);
assertEquals(1, stream.readBit());
assertEquals(1, stream.readBit());
assertEquals(1, stream.readBit());
assertEquals(1, stream.readBit());
assertEquals(0, stream.readBit());
// Byte reset, read partial sequence again
stream.setBitOffset(3);
assertEquals(1, stream.readBit());
assertEquals(0, stream.readBit());
assertEquals(0, stream.getStreamPosition());
// Byte reset, read partial sequence again
stream.setBitOffset(6);
assertEquals(0, stream.readBit());
assertEquals(0, stream.readBit());
assertEquals(1, stream.getStreamPosition());
// Read all bits, second byte
assertEquals(0, stream.readBit());
assertEquals(1, stream.getBitOffset());
assertEquals(1, stream.getStreamPosition());
assertEquals(0, stream.readBit());
assertEquals(2, stream.getBitOffset());
assertEquals(1, stream.getStreamPosition());
assertEquals(0, stream.readBit());
assertEquals(3, stream.getBitOffset());
assertEquals(1, stream.getStreamPosition());
assertEquals(0, stream.readBit());
assertEquals(4, stream.getBitOffset());
assertEquals(1, stream.getStreamPosition());
assertEquals(1, stream.readBit());
assertEquals(5, stream.getBitOffset());
assertEquals(1, stream.getStreamPosition());
assertEquals(1, stream.readBit());
assertEquals(6, stream.getBitOffset());
assertEquals(1, stream.getStreamPosition());
assertEquals(1, stream.readBit());
assertEquals(7, stream.getBitOffset());
assertEquals(1, stream.getStreamPosition());
assertEquals(1, stream.readBit()); // last bit
assertEquals(0, stream.getBitOffset());
assertEquals(2, stream.getStreamPosition());
}
@Test
public void testReadBits() throws IOException {
byte[] bytes = new byte[] {(byte) 0xF0, (byte) 0xCC, (byte) 0xAA};
// Create wrapper stream
BufferedImageInputStream stream = new BufferedImageInputStream(new ByteArrayImageInputStream(bytes));
// Read all bits, first byte
assertEquals(3, stream.readBits(2));
assertEquals(2, stream.getBitOffset());
assertEquals(0, stream.getStreamPosition());
assertEquals(3, stream.readBits(2));
assertEquals(4, stream.getBitOffset());
assertEquals(0, stream.getStreamPosition());
assertEquals(0, stream.readBits(2));
assertEquals(6, stream.getBitOffset());
assertEquals(0, stream.getStreamPosition());
assertEquals(0, stream.readBits(2));
assertEquals(0, stream.getBitOffset());
assertEquals(1, stream.getStreamPosition());
// Read all bits, second byte
assertEquals(3, stream.readBits(2));
assertEquals(2, stream.getBitOffset());
assertEquals(1, stream.getStreamPosition());
assertEquals(0, stream.readBits(2));
assertEquals(4, stream.getBitOffset());
assertEquals(1, stream.getStreamPosition());
assertEquals(3, stream.readBits(2));
assertEquals(6, stream.getBitOffset());
assertEquals(1, stream.getStreamPosition());
assertEquals(0, stream.readBits(2));
assertEquals(0, stream.getBitOffset());
assertEquals(2, stream.getStreamPosition());
// Read all bits, third byte
assertEquals(2, stream.readBits(2));
assertEquals(2, stream.getBitOffset());
assertEquals(2, stream.getStreamPosition());
assertEquals(2, stream.readBits(2));
assertEquals(4, stream.getBitOffset());
assertEquals(2, stream.getStreamPosition());
assertEquals(2, stream.readBits(2));
assertEquals(6, stream.getBitOffset());
assertEquals(2, stream.getStreamPosition());
assertEquals(2, stream.readBits(2));
assertEquals(0, stream.getBitOffset());
assertEquals(3, stream.getStreamPosition());
// Full reset, read same sequence again
stream.seek(0);
assertEquals(0, stream.getBitOffset());
assertEquals(0, stream.getStreamPosition());
// Read all bits, increasing size
assertEquals(7, stream.readBits(3)); // 111
assertEquals(3, stream.getBitOffset());
assertEquals(0, stream.getStreamPosition());
assertEquals(8, stream.readBits(4)); // 1000
assertEquals(7, stream.getBitOffset());
assertEquals(0, stream.getStreamPosition());
assertEquals(12, stream.readBits(5)); // 01100
assertEquals(4, stream.getBitOffset());
assertEquals(1, stream.getStreamPosition());
assertEquals(50, stream.readBits(6)); // 110010
assertEquals(2, stream.getBitOffset());
assertEquals(2, stream.getStreamPosition());
assertEquals(42, stream.readBits(6)); // 101010
assertEquals(0, stream.getBitOffset());
assertEquals(3, stream.getStreamPosition());
// Full reset, read same sequence again
stream.seek(0);
assertEquals(0, stream.getBitOffset());
assertEquals(0, stream.getStreamPosition());
// Read all bits multi-byte
assertEquals(0xF0C, stream.readBits(12)); // 111100001100
assertEquals(4, stream.getBitOffset());
assertEquals(1, stream.getStreamPosition());
assertEquals(0xCAA, stream.readBits(12)); // 110010101010
assertEquals(0, stream.getBitOffset());
assertEquals(3, stream.getStreamPosition());
// Full reset, read same sequence again, all bits in one go
stream.seek(0);
assertEquals(0, stream.getBitOffset());
assertEquals(0, stream.getStreamPosition());
assertEquals(0xF0CCAA, stream.readBits(24));
}
@Test
public void testReadBitsRandom() throws IOException {
long value = random.nextLong();
byte[] bytes = new byte[8];
ByteBuffer.wrap(bytes).putLong(value);
// Create wrapper stream
BufferedImageInputStream stream = new BufferedImageInputStream(new ByteArrayImageInputStream(bytes));
for (int i = 1; i < 64; i++) {
stream.seek(0);
assertEquals(i + " bits differ", value >>> (64L - i), stream.readBits(i));
}
}
@Test
public void testClose() throws IOException {
// Create wrapper stream
ImageInputStream mock = mock(ImageInputStream.class);
BufferedImageInputStream stream = new BufferedImageInputStream(mock);
stream.close();
verify(mock, never()).close();
}
// TODO: Write other tests
// TODO: Create test that exposes read += -1 (eof) bug
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<artifactId>imageio-hdr</artifactId>
<name>TwelveMonkeys :: ImageIO :: HDR plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<artifactId>imageio-icns</artifactId>
<name>TwelveMonkeys :: ImageIO :: ICNS plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<artifactId>imageio-iff</artifactId>
<name>TwelveMonkeys :: ImageIO :: IFF plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<artifactId>imageio-jpeg</artifactId>
<name>TwelveMonkeys :: ImageIO :: JPEG plugin</name>
@@ -1129,13 +1129,13 @@ public final class JPEGImageReader extends ImageReaderBase {
Application exif = exifSegments.get(0);
// Identifier is "Exif\0" + 1 byte pad
int offset = exif.identifier.length() + 2;
int dataOffset = exif.identifier.length() + 2;
if (exif.data.length <= offset) {
if (exif.data.length <= dataOffset) {
processWarningOccurred("Exif chunk has no data.");
}
else {
ImageInputStream stream = new ByteArrayImageInputStream(exif.data, offset, exif.data.length - offset);
ImageInputStream stream = new ByteArrayImageInputStream(exif.data, dataOffset, exif.data.length - dataOffset);
CompoundDirectory exifMetadata = (CompoundDirectory) new TIFFReader().read(stream);
if (exifMetadata.directoryCount() == 2) {
@@ -1146,14 +1146,18 @@ public final class JPEGImageReader extends ImageReaderBase {
int compression = compressionEntry == null ? 6 : ((Number) compressionEntry.getValue()).intValue();
if (compression == 6) {
if (ifd1.getEntryById(TIFF.TAG_JPEG_INTERCHANGE_FORMAT) != null) {
Entry jpegLength = ifd1.getEntryById(TIFF.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH);
Entry jpegOffEntry = ifd1.getEntryById(TIFF.TAG_JPEG_INTERCHANGE_FORMAT);
if (jpegOffEntry != null) {
Entry jpegLenEntry = ifd1.getEntryById(TIFF.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH);
if ((jpegLength == null || ((Number) jpegLength.getValue()).longValue() > 0)) {
// Test if Exif thumbnail is contained within the Exif segment (offset + length <= segment.length)
long jpegOffset = ((Number) jpegOffEntry.getValue()).longValue();
long jpegLength = jpegLenEntry != null ? ((Number) jpegLenEntry.getValue()).longValue() : -1;
if (jpegLength > 0 && jpegOffset + jpegLength <= stream.length()) {
thumbnails.add(new EXIFThumbnailReader(thumbnailProgressDelegator, getThumbnailReader(), 0, thumbnails.size(), ifd1, stream));
}
else {
processWarningOccurred("EXIF IFD with empty (zero-length) thumbnail");
processWarningOccurred("EXIF IFD with empty or incomplete JPEG thumbnail");
}
}
else {
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>imageio-metadata</artifactId>
@@ -48,7 +48,7 @@ import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.*;
import static com.twelvemonkeys.lang.Validate.notNull;
@@ -154,7 +154,7 @@ public final class JPEGSegmentUtil {
}
static String asAsciiString(final byte[] data, final int offset, final int length) {
return new String(data, offset, length, Charset.forName("ascii"));
return new String(data, offset, length, StandardCharsets.US_ASCII);
}
static void readSOI(final ImageInputStream stream) throws IOException {
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<artifactId>imageio-pcx</artifactId>
<name>TwelveMonkeys :: ImageIO :: PCX plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<artifactId>imageio-pdf</artifactId>
<name>TwelveMonkeys :: ImageIO :: PDF plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<artifactId>imageio-pict</artifactId>
<name>TwelveMonkeys :: ImageIO :: PICT plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<artifactId>imageio-pnm</artifactId>
<name>TwelveMonkeys :: ImageIO :: PNM plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<artifactId>imageio-psd</artifactId>
<name>TwelveMonkeys :: ImageIO :: PSD plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<artifactId>imageio-reference</artifactId>
<name>TwelveMonkeys :: ImageIO :: reference test cases</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<artifactId>imageio-sgi</artifactId>
<name>TwelveMonkeys :: ImageIO :: SGI plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<artifactId>imageio-tga</artifactId>
<name>TwelveMonkeys :: ImageIO :: TGA plugin</name>
@@ -200,12 +200,12 @@ final class TGAHeader {
int components = colorMap.hasAlpha() ? 4 : 3;
byte[] cmap = new byte[rgb.length * components];
for (int i = 0; i < rgb.length; i++) {
cmap[i * components ] = (byte) ((rgb[i] >> 16) & 0xff);
cmap[i * components + 1] = (byte) ((rgb[i] >> 8) & 0xff);
cmap[i * components + 2] = (byte) ((rgb[i] ) & 0xff);
cmap[i * components ] = (byte) ((rgb[i] ) & 0xff); // B
cmap[i * components + 1] = (byte) ((rgb[i] >> 8) & 0xff); // G
cmap[i * components + 2] = (byte) ((rgb[i] >> 16) & 0xff); // R
if (components == 4) {
cmap[i * components + 3] = (byte) ((rgb[i] >>> 24) & 0xff);
cmap[i * components + 3] = (byte) ((rgb[i] >>> 24) & 0xff); // A
}
}
@@ -298,9 +298,23 @@ final class TGAHeader {
hasAlpha = false;
break;
case 24:
// BGR -> RGB
for (int i = 0; i < cmap.length; i += 3) {
byte b = cmap[i];
cmap[i ] = cmap[i + 2];
cmap[i + 2] = b;
}
hasAlpha = false;
break;
case 32:
// BGRA -> RGBA
for (int i = 0; i < cmap.length; i += 4) {
byte b = cmap[i];
cmap[i ] = cmap[i + 2];
cmap[i + 2] = b;
}
hasAlpha = true;
break;
default:
@@ -224,7 +224,7 @@ final class TGAImageReader extends ImageReaderBase {
byte[] rowDataByte, WritableRaster destChannel, Raster srcChannel, int y) throws IOException {
// If subsampled or outside source region, skip entire row
if (y % ySub != 0 || height - 1 - y < srcRegion.y || height - 1 - y >= srcRegion.y + srcRegion.height) {
imageInput.skipBytes(rowDataByte.length);
input.skipBytes(rowDataByte.length);
return;
}
@@ -251,7 +251,8 @@ final class TGAImageReader extends ImageReaderBase {
destChannel.setDataElements(0, dstY, srcChannel);
break;
case TGA.ORIGIN_UPPER_LEFT:
destChannel.setDataElements(0, y, srcChannel);
dstY = y / ySub;
destChannel.setDataElements(0, dstY, srcChannel);
break;
default:
throw new IIOException("Unsupported origin: " + origin);
@@ -289,7 +290,8 @@ final class TGAImageReader extends ImageReaderBase {
destChannel.setDataElements(0, dstY, srcChannel);
break;
case TGA.ORIGIN_UPPER_LEFT:
destChannel.setDataElements(0, y, srcChannel);
dstY = y / ySub;
destChannel.setDataElements(0, dstY, srcChannel);
break;
default:
throw new IIOException("Unsupported origin: " + origin);
@@ -189,6 +189,7 @@ final class TGAMetadata extends AbstractMetadata {
switch (header.getPixelDepth()) {
case 8:
bitsPerSample.setAttribute("value", createListValue(1, Integer.toString(header.getPixelDepth())));
break;
case 16:
if (header.getAttributeBits() > 0 && extensions != null && extensions.hasAlpha()) {
bitsPerSample.setAttribute("value", "5, 5, 5, 1");
@@ -32,11 +32,19 @@ package com.twelvemonkeys.imageio.plugins.tga;
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
import org.junit.Test;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertNotNull;
/**
* TGAImageReaderTest
*
@@ -104,4 +112,23 @@ public class TGAImageReaderTest extends ImageReaderAbstractTest<TGAImageReader>
"image/targa", "image/x-targa"
);
}
@Test
public void testSubsampling() throws IOException {
ImageReader reader = createReader();
ImageReadParam param = reader.getDefaultReadParam();
param.setSourceSubsampling(3, 5, 0, 0);
for (TestData testData : getTestData()) {
try (ImageInputStream input = testData.getInputStream()) {
reader.setInput(input);
assertNotNull(reader.read(0, param));
}
finally {
reader.reset();
}
}
reader.dispose();
}
}
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<artifactId>imageio-thumbsdb</artifactId>
<name>TwelveMonkeys :: ImageIO :: Thumbs.db plugin</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<artifactId>imageio-tiff</artifactId>
<name>TwelveMonkeys :: ImageIO :: TIFF plugin</name>
@@ -152,7 +152,7 @@ final class CCITTFaxDecoderStream extends FilterInputStream {
static int findCompressionType(final int type, final InputStream in) throws IOException {
// Discover possible incorrect type, revert to RLE
if (type == TIFFExtension.COMPRESSION_CCITT_T4 && in.markSupported()) {
byte[] streamData = new byte[20];
byte[] streamData = new byte[32];
try {
in.mark(streamData.length);
@@ -173,8 +173,9 @@ final class CCITTFaxDecoderStream extends FilterInputStream {
if (streamData[0] != 0 || (streamData[1] >> 4 != 1 && streamData[1] != 1)) {
// Leading EOL (0b000000000001) not found, search further and try RLE if not found
int numBits = streamData.length * 8;
short b = (short) (((streamData[0] << 8) + streamData[1]) >> 4);
for (int i = 12; i < 160; i++) {
for (int i = 12; i < numBits; i++) {
b = (short) ((b << 1) + ((streamData[(i / 8)] >> (7 - (i % 8))) & 0x01));
if ((b & 0xFFF) == 1) {
@@ -68,14 +68,19 @@ public class CCITTFaxDecoderStreamTest {
};
// group3_2d.tif: EOL|k=1|3W|1B|2W|EOL|k=0|V|V|V|EOL|k=1|3W|1B|2W|EOL|k=0|V-1|V|V|6*F
static final byte[] DATA_G3_2D = { 0x00, 0x1C, 0x27, 0x00, 0x17, 0x00, 0x1C, 0x27, 0x00, 0x12, (byte) 0xC0 };
static final byte[] DATA_G3_2D = {0x00, 0x1C, 0x27, 0x00, 0x17, 0x00, 0x1C, 0x27, 0x00, 0x12, (byte) 0xC0};
// group3_2d_fill.tif
static final byte[] DATA_G3_2D_FILL = { 0x00, 0x01, (byte) 0xC2, 0x70, 0x01, 0x70, 0x01, (byte) 0xC2, 0x70, 0x01,
0x2C };
static final byte[] DATA_G3_2D_FILL = {0x00, 0x01, (byte) 0xC2, 0x70, 0x01, 0x70, 0x01, (byte) 0xC2,
0x70, 0x01, 0x2C};
static final byte[] DATA_G3_2D_lsb2msb = { 0x00, 0x38, (byte) 0xE4, 0x00, (byte) 0xE8, 0x00, 0x38, (byte) 0xE4,
0x00, 0x48, 0x03 };
static final byte[] DATA_G3_2D_lsb2msb = {0x00, 0x38, (byte) 0xE4, 0x00, (byte) 0xE8, 0x00, 0x38, (byte) 0xE4,
0x00, 0x48, 0x03};
static final byte[] DATA_G3_LONG = {0x00, 0x68, 0x0A, (byte) 0xC9, 0x3A, 0x3A, 0x00, 0x68,
(byte) 0x8A, (byte) 0xD8, 0x3A, 0x35, 0x00, 0x68, 0x0A, 0x06,
(byte) 0xDD, 0x3A, 0x19, 0x00, 0x68, (byte) 0x8A, (byte) 0x9E, 0x75,
0x08, 0x00, 0x68};
// group4.tif:
// Line 1: V-3, V-2, V0
@@ -189,6 +194,7 @@ public class CCITTFaxDecoderStreamTest {
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)));
// Group 4/CCITT_T6
assertEquals(TIFFExtension.COMPRESSION_CCITT_T6, CCITTFaxDecoderStream.findCompressionType(TIFFExtension.COMPRESSION_CCITT_T6, new ByteArrayInputStream(DATA_G4)));
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>com.twelvemonkeys</groupId>
<artifactId>twelvemonkeys</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.twelvemonkeys.imageio</groupId>
+2 -2
View File
@@ -9,7 +9,7 @@
<groupId>com.twelvemonkeys</groupId>
<artifactId>twelvemonkeys</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
<packaging>pom</packaging>
<name>Twelvemonkeys</name>
@@ -86,7 +86,7 @@
<connection>scm:git:https://github.com/haraldk/TwelveMonkeys</connection>
<developerConnection>scm:git:ssh://git@github.com/haraldk/TwelveMonkeys</developerConnection>
<url>https://github.com/haraldk/TwelveMonkeys</url>
<tag>twelvemonkeys-3.6.1</tag>
<tag>twelvemonkeys-3.6.2</tag>
</scm>
<properties>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>com.twelvemonkeys</groupId>
<artifactId>twelvemonkeys</artifactId>
<version>3.6.1</version>
<version>3.6.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>