diff --git a/twelvemonkeys-imageio/core/src/main/java/com/twelvemonkeys/imageio/stream/BufferedImageInputStream.java b/twelvemonkeys-imageio/core/src/main/java/com/twelvemonkeys/imageio/stream/BufferedImageInputStream.java old mode 100755 new mode 100644 index fa5cb7a4..a396734c --- a/twelvemonkeys-imageio/core/src/main/java/com/twelvemonkeys/imageio/stream/BufferedImageInputStream.java +++ b/twelvemonkeys-imageio/core/src/main/java/com/twelvemonkeys/imageio/stream/BufferedImageInputStream.java @@ -26,14 +26,15 @@ public final class BufferedImageInputStream extends ImageInputStreamImpl impleme private int mBufferPos = 0; private int mBufferLength = 0; - public BufferedImageInputStream(final ImageInputStream pStream) { + public BufferedImageInputStream(final ImageInputStream pStream) throws IOException { this(pStream, DEFAULT_BUFFER_SIZE); } - private BufferedImageInputStream(final ImageInputStream pStream, final int pBufferSize) { + private BufferedImageInputStream(final ImageInputStream pStream, final int pBufferSize) throws IOException { Validate.notNull(pStream, "stream"); mStream = pStream; + streamPos = pStream.getStreamPosition(); mBuffer = new byte[pBufferSize]; } @@ -66,39 +67,55 @@ public final class BufferedImageInputStream extends ImageInputStreamImpl impleme public int read(final byte[] pBuffer, final int pOffset, final int pLength) throws IOException { bitOffset = 0; - boolean bypassBuffer = false; - + // TODO: Consider fixing the bypass buffer code... if (!isBufferValid()) { // Bypass cache if cache is empty for reads longer than buffer if (pLength >= mBuffer.length) { - bypassBuffer = true; + return readDirect(pBuffer, pOffset, pLength); } else { fillBuffer(); } } - if (!bypassBuffer && mBufferLength <= 0) { + return readBuffered(pBuffer, pOffset, pLength); + } + + private int readDirect(final byte[] pBuffer, final int pOffset, final int pLength) throws IOException { +// System.err.println("BEFORE streamPos: " + streamPos); +// System.err.println("BEFORE mStream.getStreamPosition(): " + mStream.getStreamPosition()); + + int read = mStream.read(pBuffer, pOffset, Math.min(mBuffer.length, pLength)); + + if (read > 0) { + streamPos += read; + } + +// System.err.println("AFTER streamPos: " + streamPos); +// System.err.println("AFTER mStream.getStreamPosition(): " + mStream.getStreamPosition()); +// System.err.println(); + + + mBufferStart = mStream.getStreamPosition(); + mBufferLength = 0; + + return read; + } + + + private int readBuffered(final byte[] pBuffer, final int pOffset, final int pLength) { + if (mBufferLength <= 0) { return -1; } // Read as much as possible from buffer - int length = bypassBuffer ? 0 : Math.min(mBufferLength - mBufferPos, pLength); + int length = Math.min(mBufferLength - mBufferPos, pLength); if (length > 0) { System.arraycopy(mBuffer, mBufferPos, pBuffer, pOffset, length); mBufferPos += length; } - // Read rest directly from stream, if longer than buffer - if (pLength - length >= mBuffer.length) { - int read = mStream.read(pBuffer, pOffset + length, pLength - length); - - if (read > 0) { - length += read; - } - } - streamPos += length; return length; diff --git a/twelvemonkeys-imageio/core/src/test/java/com/twelvemonkeys/imageio/stream/BufferedImageInputStreamTestCase.java b/twelvemonkeys-imageio/core/src/test/java/com/twelvemonkeys/imageio/stream/BufferedImageInputStreamTestCase.java old mode 100755 new mode 100644 index b7b33390..8c04d347 --- a/twelvemonkeys-imageio/core/src/test/java/com/twelvemonkeys/imageio/stream/BufferedImageInputStreamTestCase.java +++ b/twelvemonkeys-imageio/core/src/test/java/com/twelvemonkeys/imageio/stream/BufferedImageInputStreamTestCase.java @@ -17,14 +17,14 @@ import java.util.Random; * @author last modified by $Author: haraldk$ * @version $Id: BufferedImageInputStreamTestCase.java,v 1.0 Jun 30, 2008 3:07:42 PM haraldk Exp$ */ -public class BufferedImageInputStreamTestCase extends TestCase{ +public class BufferedImageInputStreamTestCase extends TestCase { protected final Random mRandom = new Random(); - public void testCreate() { + public void testCreate() throws IOException { new BufferedImageInputStream(new ByteArrayImageInputStream(new byte[0])); } - public void testCreateNull() { + public void testCreateNull() throws IOException { try { new BufferedImageInputStream(null); fail("Expected IllegalArgumentException"); @@ -76,6 +76,35 @@ public class BufferedImageInputStreamTestCase extends TestCase{ assertTrue(rangeEquals(bytes, size, result, 0, size)); } + public void testBufferPositionCorrect() throws IOException { + // Fill bytes + byte[] bytes = new byte[1024]; + mRandom.nextBytes(bytes); + + ByteArrayImageInputStream input = new ByteArrayImageInputStream(bytes); + + input.readByte(); + input.readByte(); + input.skipBytes(124); + input.readByte(); + input.readByte(); + + // Sanity check + assertEquals(128, input.getStreamPosition()); + + BufferedImageInputStream stream = new BufferedImageInputStream(input); + + assertEquals(input.getStreamPosition(), stream.getStreamPosition()); + + stream.skipBytes(128); + + //assertTrue(256 <= input.getStreamPosition()); + assertEquals(256, stream.getStreamPosition()); + + stream.seek(1020); + assertEquals(1020, stream.getStreamPosition()); + } + /** * Test two arrays for range equality. That is, they contain the same elements for some specified range. *