From 4a51850e9b38b061d0a8668db189a4a0d2d893de Mon Sep 17 00:00:00 2001 From: Harald Kuhr Date: Sat, 18 Mar 2023 10:33:34 +0100 Subject: [PATCH] #738 PSD: No longer decompress PackBits across boundaries (cherry picked from commit 606fd53823623ba866fc4e31ce7fa751278fd51d) --- .../java/com/twelvemonkeys/io/SubStream.java | 57 +++++++++---------- .../imageio/plugins/psd/PSDUtil.java | 12 ++-- 2 files changed, 35 insertions(+), 34 deletions(-) diff --git a/common/common-io/src/main/java/com/twelvemonkeys/io/SubStream.java b/common/common-io/src/main/java/com/twelvemonkeys/io/SubStream.java index 76a3c01f..2b4cc2b0 100755 --- a/common/common-io/src/main/java/com/twelvemonkeys/io/SubStream.java +++ b/common/common-io/src/main/java/com/twelvemonkeys/io/SubStream.java @@ -41,21 +41,20 @@ import java.io.InputStream; * underlying stream. * * @author Harald Kuhr - * @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 { private long bytesLeft; 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 pLength maximum number of bytes to read drom this stream + * @param stream the underlying input stream + * @param length maximum number of bytes to read from this stream */ - public SubStream(final InputStream pStream, final long pLength) { - super(Validate.notNull(pStream, "stream")); - bytesLeft = pLength; + public SubStream(final InputStream stream, final long length) { + super(Validate.notNull(stream, "stream")); + bytesLeft = length; } /** @@ -73,13 +72,13 @@ public final class SubStream extends FilterInputStream { @Override public int available() throws IOException { - return (int) Math.min(super.available(), bytesLeft); + return (int) findMaxLen(super.available()); } @Override - public void mark(int pReadLimit) { - super.mark(pReadLimit);// This either succeeds or does nothing... - markLimit = pReadLimit; + public void mark(int readLimit) { + super.mark(readLimit);// This either succeeds or does nothing... + markLimit = readLimit; } @Override @@ -93,44 +92,42 @@ public final class SubStream extends FilterInputStream { if (bytesLeft-- <= 0) { return -1; } + return super.read(); } @Override - public final int read(byte[] pBytes) throws IOException { - return read(pBytes, 0, pBytes.length); + public int read(byte[] bytes) throws IOException { + return read(bytes, 0, bytes.length); } @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) { 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; + 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. * - * @param pLength the requested length + * @param length the requested length * @return the maximum number of bytes to read */ - private long findMaxLen(long pLength) { - if (bytesLeft < pLength) { - 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; + private long findMaxLen(long length) { + return bytesLeft < length ? Math.max(bytesLeft, 0) : length; } } diff --git a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDUtil.java b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDUtil.java index 8bba61ce..18aae338 100644 --- a/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDUtil.java +++ b/imageio/imageio-psd/src/main/java/com/twelvemonkeys/imageio/plugins/psd/PSDUtil.java @@ -32,6 +32,7 @@ package com.twelvemonkeys.imageio.plugins.psd; import com.twelvemonkeys.imageio.stream.DirectImageInputStream; import com.twelvemonkeys.imageio.stream.SubImageInputStream; +import com.twelvemonkeys.io.SubStream; import com.twelvemonkeys.io.enc.DecoderStream; import com.twelvemonkeys.io.enc.PackBitsDecoder; import com.twelvemonkeys.lang.StringUtil; @@ -107,7 +108,8 @@ final class PSDUtil { return new SubImageInputStream(stream, streamLength < 0 ? Long.MAX_VALUE : streamLength); 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: return new DirectImageInputStream(new InflaterInputStream(createStreamAdapter(stream, compressedLength))); @@ -124,11 +126,13 @@ final class PSDUtil { private static class LazyPackBitsStreamEnumeration implements Enumeration { private final ImageInputStream stream; private final int[] byteCounts; + private final int rowLength; private int index; - public LazyPackBitsStreamEnumeration(int[] byteCounts, ImageInputStream stream) { - this.byteCounts = byteCounts; + public LazyPackBitsStreamEnumeration(ImageInputStream stream, int[] byteCounts, int rowLength) { this.stream = stream; + this.byteCounts = byteCounts; + this.rowLength = rowLength; } @Override @@ -138,7 +142,7 @@ final class PSDUtil { @Override 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); } } }