mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-04 20:15:28 -04:00
#738 PSD: No longer decompress PackBits across boundaries
This commit is contained in:
parent
614a07e040
commit
606fd53823
@ -41,21 +41,20 @@ import java.io.InputStream;
|
|||||||
* underlying stream.
|
* underlying stream.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/SubStream.java#2 $
|
|
||||||
*/
|
*/
|
||||||
public final class SubStream extends FilterInputStream {
|
public final class SubStream extends FilterInputStream {
|
||||||
private long bytesLeft;
|
private long bytesLeft;
|
||||||
private int markLimit;
|
private int markLimit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@code SubStream} of the given {@code pStream}.
|
* Creates a {@code SubStream} of the given {@code stream}.
|
||||||
*
|
*
|
||||||
* @param pStream the underlying input stream
|
* @param stream the underlying input stream
|
||||||
* @param pLength maximum number of bytes to read drom this stream
|
* @param length maximum number of bytes to read from this stream
|
||||||
*/
|
*/
|
||||||
public SubStream(final InputStream pStream, final long pLength) {
|
public SubStream(final InputStream stream, final long length) {
|
||||||
super(Validate.notNull(pStream, "stream"));
|
super(Validate.notNull(stream, "stream"));
|
||||||
bytesLeft = pLength;
|
bytesLeft = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -73,13 +72,13 @@ public final class SubStream extends FilterInputStream {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int available() throws IOException {
|
public int available() throws IOException {
|
||||||
return (int) Math.min(super.available(), bytesLeft);
|
return (int) findMaxLen(super.available());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mark(int pReadLimit) {
|
public void mark(int readLimit) {
|
||||||
super.mark(pReadLimit);// This either succeeds or does nothing...
|
super.mark(readLimit);// This either succeeds or does nothing...
|
||||||
markLimit = pReadLimit;
|
markLimit = readLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -93,44 +92,42 @@ public final class SubStream extends FilterInputStream {
|
|||||||
if (bytesLeft-- <= 0) {
|
if (bytesLeft-- <= 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.read();
|
return super.read();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final int read(byte[] pBytes) throws IOException {
|
public int read(byte[] bytes) throws IOException {
|
||||||
return read(pBytes, 0, pBytes.length);
|
return read(bytes, 0, bytes.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read(final byte[] pBytes, final int pOffset, final int pLength) throws IOException {
|
public int read(final byte[] bytes, final int off, final int len) throws IOException {
|
||||||
if (bytesLeft <= 0) {
|
if (bytesLeft <= 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int read = super.read(pBytes, pOffset, (int) findMaxLen(pLength));
|
int read = super.read(bytes, off, (int) findMaxLen(len));
|
||||||
bytesLeft = read < 0 ? 0 : bytesLeft - read;
|
bytesLeft = read < 0 ? 0 : bytesLeft - read;
|
||||||
|
|
||||||
return read;
|
return read;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long skip(long length) throws IOException {
|
||||||
|
long skipped = super.skip(findMaxLen(length));// Skips 0 or more, never -1
|
||||||
|
bytesLeft -= skipped;
|
||||||
|
|
||||||
|
return skipped;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the maximum number of bytes we can read or skip, from this stream.
|
* Finds the maximum number of bytes we can read or skip, from this stream.
|
||||||
*
|
*
|
||||||
* @param pLength the requested length
|
* @param length the requested length
|
||||||
* @return the maximum number of bytes to read
|
* @return the maximum number of bytes to read
|
||||||
*/
|
*/
|
||||||
private long findMaxLen(long pLength) {
|
private long findMaxLen(long length) {
|
||||||
if (bytesLeft < pLength) {
|
return bytesLeft < length ? Math.max(bytesLeft, 0) : length;
|
||||||
return (int) Math.max(bytesLeft, 0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return pLength;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long skip(long pLength) throws IOException {
|
|
||||||
long skipped = super.skip(findMaxLen(pLength));// Skips 0 or more, never -1
|
|
||||||
bytesLeft -= skipped;
|
|
||||||
return skipped;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ package com.twelvemonkeys.imageio.plugins.psd;
|
|||||||
|
|
||||||
import com.twelvemonkeys.imageio.stream.DirectImageInputStream;
|
import com.twelvemonkeys.imageio.stream.DirectImageInputStream;
|
||||||
import com.twelvemonkeys.imageio.stream.SubImageInputStream;
|
import com.twelvemonkeys.imageio.stream.SubImageInputStream;
|
||||||
|
import com.twelvemonkeys.io.SubStream;
|
||||||
import com.twelvemonkeys.io.enc.DecoderStream;
|
import com.twelvemonkeys.io.enc.DecoderStream;
|
||||||
import com.twelvemonkeys.io.enc.PackBitsDecoder;
|
import com.twelvemonkeys.io.enc.PackBitsDecoder;
|
||||||
import com.twelvemonkeys.lang.StringUtil;
|
import com.twelvemonkeys.lang.StringUtil;
|
||||||
@ -107,7 +108,8 @@ final class PSDUtil {
|
|||||||
return new SubImageInputStream(stream, streamLength < 0 ? Long.MAX_VALUE : streamLength);
|
return new SubImageInputStream(stream, streamLength < 0 ? Long.MAX_VALUE : streamLength);
|
||||||
|
|
||||||
case PSD.COMPRESSION_RLE:
|
case PSD.COMPRESSION_RLE:
|
||||||
return new DirectImageInputStream(new SequenceInputStream(new LazyPackBitsStreamEnumeration(byteCounts, stream)));
|
int rowLength = (columns * bitsPerSample + 7) / 8;
|
||||||
|
return new DirectImageInputStream(new SequenceInputStream(new LazyPackBitsStreamEnumeration(stream, byteCounts, rowLength)));
|
||||||
|
|
||||||
case PSD.COMPRESSION_ZIP:
|
case PSD.COMPRESSION_ZIP:
|
||||||
return new DirectImageInputStream(new InflaterInputStream(createStreamAdapter(stream, compressedLength)));
|
return new DirectImageInputStream(new InflaterInputStream(createStreamAdapter(stream, compressedLength)));
|
||||||
@ -124,11 +126,13 @@ final class PSDUtil {
|
|||||||
private static class LazyPackBitsStreamEnumeration implements Enumeration<InputStream> {
|
private static class LazyPackBitsStreamEnumeration implements Enumeration<InputStream> {
|
||||||
private final ImageInputStream stream;
|
private final ImageInputStream stream;
|
||||||
private final int[] byteCounts;
|
private final int[] byteCounts;
|
||||||
|
private final int rowLength;
|
||||||
private int index;
|
private int index;
|
||||||
|
|
||||||
public LazyPackBitsStreamEnumeration(int[] byteCounts, ImageInputStream stream) {
|
public LazyPackBitsStreamEnumeration(ImageInputStream stream, int[] byteCounts, int rowLength) {
|
||||||
this.byteCounts = byteCounts;
|
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
|
this.byteCounts = byteCounts;
|
||||||
|
this.rowLength = rowLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -138,7 +142,7 @@ final class PSDUtil {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream nextElement() {
|
public InputStream nextElement() {
|
||||||
return new DecoderStream(createStreamAdapter(stream, byteCounts[index++]), new PackBitsDecoder());
|
return new SubStream(new DecoderStream(createStreamAdapter(stream, byteCounts[index++]), new PackBitsDecoder(), rowLength), rowLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user