This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-imaging.git
The following commit(s) were added to refs/heads/master by this push: new d0fa70d1 More allocation checking d0fa70d1 is described below commit d0fa70d1df83dbf571feed3e95dd4067d82029c0 Author: Gary Gregory <garydgreg...@gmail.com> AuthorDate: Sat May 13 14:47:02 2023 -0400 More allocation checking Also, don't reinvent the wheel, reuse UnsynchronizedByteArrayOutputStream --- pom.xml | 1 - .../commons/imaging/common/AllocationChecker.java | 17 +++++++ .../imaging/common/AllocationRequestException.java | 16 ++++++- .../commons/imaging/common/BasicCParser.java | 2 +- .../commons/imaging/common/BinaryFunctions.java | 6 +-- .../commons/imaging/common/ByteConversions.java | 20 ++++---- .../imaging/common/FastByteArrayOutputStream.java | 55 ---------------------- .../commons/imaging/common/ImageBuilder.java | 6 +-- .../apache/commons/imaging/common/PackBits.java | 3 +- .../apache/commons/imaging/common/ZlibDeflate.java | 2 +- .../common/bytesource/ByteSourceInputStream.java | 3 +- .../common/itu_t4/BitArrayOutputStream.java | 6 ++- .../imaging/common/itu_t4/T4AndT6Compression.java | 17 +++---- .../common/mylzw/BitsToByteInputStream.java | 6 +-- .../imaging/formats/bmp/BmpImageParser.java | 3 +- .../imaging/formats/gif/GifImageParser.java | 7 +-- .../imaging/formats/icns/Rle24Compression.java | 4 +- .../imaging/formats/ico/IcoImageParser.java | 5 +- .../imaging/formats/jpeg/JpegImageParser.java | 3 +- .../imaging/formats/jpeg/decoder/Block.java | 4 +- .../imaging/formats/jpeg/decoder/JpegDecoder.java | 15 +++--- .../imaging/formats/jpeg/iptc/IptcParser.java | 3 +- .../imaging/formats/jpeg/segments/DhtSegment.java | 6 ++- .../imaging/formats/jpeg/segments/SofnSegment.java | 3 +- .../imaging/formats/jpeg/segments/SosSegment.java | 4 +- .../imaging/formats/pcx/PcxImageParser.java | 16 ++++--- .../commons/imaging/formats/pcx/PcxWriter.java | 13 ++--- .../commons/imaging/formats/png/PngWriter.java | 9 ++-- .../commons/imaging/formats/png/ScanExpediter.java | 3 +- .../imaging/formats/png/chunks/PngChunkIccp.java | 3 +- .../imaging/formats/png/chunks/PngChunkItxt.java | 3 +- .../imaging/formats/png/chunks/PngChunkPlte.java | 3 +- .../imaging/formats/png/chunks/PngChunkZtxt.java | 3 +- .../psd/datareaders/CompressedDataReader.java | 5 +- .../psd/datareaders/UncompressedDataReader.java | 4 +- .../commons/imaging/formats/rgbe/RgbeInfo.java | 5 +- .../commons/imaging/formats/tiff/TiffField.java | 13 ++--- .../imaging/formats/tiff/TiffRasterDataFloat.java | 6 ++- .../imaging/formats/tiff/TiffRasterDataInt.java | 8 ++-- .../formats/tiff/datareaders/DataReaderStrips.java | 9 ++-- .../formats/tiff/datareaders/DataReaderTiled.java | 7 +-- .../formats/tiff/datareaders/ImageDataReader.java | 7 +-- .../formats/tiff/fieldtypes/FieldTypeAscii.java | 5 +- .../formats/tiff/fieldtypes/FieldTypeByte.java | 2 +- .../formats/tiff/fieldtypes/FieldTypeDouble.java | 3 +- .../formats/tiff/fieldtypes/FieldTypeFloat.java | 3 +- .../formats/tiff/fieldtypes/FieldTypeLong.java | 3 +- .../formats/tiff/fieldtypes/FieldTypeRational.java | 5 +- .../formats/tiff/fieldtypes/FieldTypeShort.java | 3 +- .../PhotometricInterpreterPalette.java | 3 +- .../formats/tiff/taginfos/TagInfoAscii.java | 3 +- .../formats/tiff/taginfos/TagInfoGpsText.java | 12 ++--- .../formats/tiff/write/ImageDataOffsets.java | 3 +- .../formats/tiff/write/TiffImageWriterBase.java | 29 ++++++------ .../tiff/write/TiffImageWriterLossless.java | 3 +- .../formats/tiff/write/TiffOutputDirectory.java | 5 +- .../imaging/formats/xbm/XbmImageParser.java | 3 +- .../imaging/formats/xpm/XpmImageParser.java | 7 +-- .../commons/imaging/icc/IccProfileParser.java | 3 +- .../imaging/palette/MedianCutQuantizer.java | 7 +-- .../commons/imaging/palette/PaletteFactory.java | 9 ++-- .../commons/imaging/palette/QuantizedPalette.java | 4 +- 62 files changed, 239 insertions(+), 210 deletions(-) diff --git a/pom.xml b/pom.xml index 19ad0264..f724a2e5 100644 --- a/pom.xml +++ b/pom.xml @@ -228,7 +228,6 @@ <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.11.0</version> - <scope>test</scope> </dependency> </dependencies> diff --git a/src/main/java/org/apache/commons/imaging/common/AllocationChecker.java b/src/main/java/org/apache/commons/imaging/common/AllocationChecker.java index 9cd222f5..511a0d75 100644 --- a/src/main/java/org/apache/commons/imaging/common/AllocationChecker.java +++ b/src/main/java/org/apache/commons/imaging/common/AllocationChecker.java @@ -46,4 +46,21 @@ public class AllocationChecker { return request; } + /** + * Checks a request for meeting allocation limits. + * <p> + * The default limit is {@value #DEFAULT}, override with the system property + * "org.apache.commons.imaging.common.mylzw.AllocationChecker". + * </p> + * + * @param request an allocation request. + * @return the request. + */ + public static int check(final long request) { + if (request > Integer.MAX_VALUE) { + throw new AllocationRequestException(DEFAULT, request); + } + return check((int) request); + } + } diff --git a/src/main/java/org/apache/commons/imaging/common/AllocationRequestException.java b/src/main/java/org/apache/commons/imaging/common/AllocationRequestException.java index a0d4b4c1..f05193aa 100644 --- a/src/main/java/org/apache/commons/imaging/common/AllocationRequestException.java +++ b/src/main/java/org/apache/commons/imaging/common/AllocationRequestException.java @@ -25,7 +25,7 @@ public class AllocationRequestException extends ImagingRuntimeException { private static final long serialVersionUID = 1L; private final int limit; - private final int request; + private final long request; /** * Constructs a new instance. @@ -39,6 +39,18 @@ public class AllocationRequestException extends ImagingRuntimeException { this.request = request; } + /** + * Constructs a new instance. + * + * @param limit The allocation limit. + * @param request The allocation request. + */ + public AllocationRequestException(final int limit, final long request) { + super(String.format("Allocation limit %,d exceeded: %,d", limit, request)); + this.limit = limit; + this.request = request; + } + /** * Gets the allocation limit. * @@ -53,7 +65,7 @@ public class AllocationRequestException extends ImagingRuntimeException { * * @return the allocation request. */ - public int getRequest() { + public long getRequest() { return request; } } diff --git a/src/main/java/org/apache/commons/imaging/common/BasicCParser.java b/src/main/java/org/apache/commons/imaging/common/BasicCParser.java index 9e1ce784..91837c05 100644 --- a/src/main/java/org/apache/commons/imaging/common/BasicCParser.java +++ b/src/main/java/org/apache/commons/imaging/common/BasicCParser.java @@ -353,7 +353,7 @@ public class BasicCParser { ++numLiveTokens; } } - final String[] liveTokens = new String[numLiveTokens]; + final String[] liveTokens = new String[AllocationChecker.check(numLiveTokens)]; int next = 0; for (final String token : tokens) { if (token != null && !token.isEmpty()) { diff --git a/src/main/java/org/apache/commons/imaging/common/BinaryFunctions.java b/src/main/java/org/apache/commons/imaging/common/BinaryFunctions.java index abdaaa7d..6609d6ac 100644 --- a/src/main/java/org/apache/commons/imaging/common/BinaryFunctions.java +++ b/src/main/java/org/apache/commons/imaging/common/BinaryFunctions.java @@ -83,7 +83,7 @@ public final class BinaryFunctions { if (length < 0) { throw new IOException(String.format("%s, invalid length: %d", exception, length)); } - final byte[] result = new byte[length]; + final byte[] result = new byte[AllocationChecker.check(length)]; raf.seek(pos); @@ -265,7 +265,7 @@ public final class BinaryFunctions { throw new IOException(String.format("%s, invalid length: %d", exception, length)); } AllocationChecker.check(length); - final byte[] result = new byte[length]; + final byte[] result = new byte[AllocationChecker.check(length)]; int read = 0; while (read < length) { final int count = is.read(result, read, length - read); @@ -329,7 +329,7 @@ public final class BinaryFunctions { } public static byte[] slice(final byte[] bytes, final int start, final int count) { - final byte[] result = new byte[count]; + final byte[] result = new byte[AllocationChecker.check(count)]; System.arraycopy(bytes, start, result, 0, count); return result; } diff --git a/src/main/java/org/apache/commons/imaging/common/ByteConversions.java b/src/main/java/org/apache/commons/imaging/common/ByteConversions.java index 612fb01f..029b2fa0 100644 --- a/src/main/java/org/apache/commons/imaging/common/ByteConversions.java +++ b/src/main/java/org/apache/commons/imaging/common/ByteConversions.java @@ -59,7 +59,7 @@ public final class ByteConversions { private static byte[] toBytes(final double[] values, final int offset, final int length, final ByteOrder byteOrder) { - final byte[] result = new byte[length * 8]; + final byte[] result = new byte[AllocationChecker.check(length * 8)]; for (int i = 0; i < length; i++) { toBytes(values[offset + i], byteOrder, result, i * 8); } @@ -92,7 +92,7 @@ public final class ByteConversions { } private static byte[] toBytes(final float[] values, final int offset, final int length, final ByteOrder byteOrder) { - final byte[] result = new byte[length * 4]; + final byte[] result = new byte[AllocationChecker.check(length * 4)]; for (int i = 0; i < length; i++) { toBytes(values[offset + i], byteOrder, result, i * 4); } @@ -124,7 +124,7 @@ public final class ByteConversions { } private static byte[] toBytes(final int[] values, final int offset, final int length, final ByteOrder byteOrder) { - final byte[] result = new byte[length * 4]; + final byte[] result = new byte[AllocationChecker.check(length * 4)]; for (int i = 0; i < length; i++) { toBytes(values[offset + i], byteOrder, result, i * 4); } @@ -166,7 +166,7 @@ public final class ByteConversions { private static byte[] toBytes(final RationalNumber[] values, final int offset, final int length, final ByteOrder byteOrder) { - final byte[] result = new byte[length * 8]; + final byte[] result = new byte[AllocationChecker.check(length * 8)]; for (int i = 0; i < length; i++) { toBytes(values[offset + i], byteOrder, result, i * 8); } @@ -194,7 +194,7 @@ public final class ByteConversions { } private static byte[] toBytes(final short[] values, final int offset, final int length, final ByteOrder byteOrder) { - final byte[] result = new byte[length * 2]; + final byte[] result = new byte[AllocationChecker.check(length * 2)]; for (int i = 0; i < length; i++) { toBytes(values[offset + i], byteOrder, result, i * 2); } @@ -233,7 +233,7 @@ public final class ByteConversions { private static double[] toDoubles(final byte[] bytes, final int offset, final int length, final ByteOrder byteOrder) { - final double[] result = new double[length / 8]; + final double[] result = new double[AllocationChecker.check(length / 8)]; Arrays.setAll(result, i -> toDouble(bytes, offset + 8 * i, byteOrder)); return result; } @@ -262,7 +262,7 @@ public final class ByteConversions { private static float[] toFloats(final byte[] bytes, final int offset, final int length, final ByteOrder byteOrder) { - final float[] result = new float[length / 4]; + final float[] result = new float[AllocationChecker.check(length / 4)]; for (int i = 0; i < result.length; i++) { result[i] = toFloat(bytes, offset + 4 * i, byteOrder); } @@ -290,7 +290,7 @@ public final class ByteConversions { private static int[] toInts(final byte[] bytes, final int offset, final int length, final ByteOrder byteOrder) { - final int[] result = new int[length / 4]; + final int[] result = new int[AllocationChecker.check(length / 4)]; Arrays.setAll(result, i -> toInt(bytes, offset + 4 * i, byteOrder)); return result; } @@ -368,7 +368,7 @@ public final class ByteConversions { private static short[] toShorts(final byte[] bytes, final int offset, final int length, final ByteOrder byteOrder) { - final short[] result = new short[length / 2]; + final short[] result = new short[AllocationChecker.check(length / 2)]; for (int i = 0; i < result.length; i++) { result[i] = toShort(bytes, offset + 2 * i, byteOrder); } @@ -394,7 +394,7 @@ public final class ByteConversions { private static int[] toUInt16s(final byte[] bytes, final int offset, final int length, final ByteOrder byteOrder) { - final int[] result = new int[length / 2]; + final int[] result = new int[AllocationChecker.check(length / 2)]; Arrays.setAll(result, i -> toUInt16(bytes, offset + 2 * i, byteOrder)); return result; } diff --git a/src/main/java/org/apache/commons/imaging/common/FastByteArrayOutputStream.java b/src/main/java/org/apache/commons/imaging/common/FastByteArrayOutputStream.java deleted file mode 100644 index b068eb6f..00000000 --- a/src/main/java/org/apache/commons/imaging/common/FastByteArrayOutputStream.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.imaging.common; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.Arrays; - -/** - * Like ByteArrayOutputStream, but has some performance benefit, - * because it's not thread safe. - */ -class FastByteArrayOutputStream extends OutputStream { - private final byte[] bytes; - private int count; - - FastByteArrayOutputStream(final int length) { - bytes = new byte[length]; - } - - public int getBytesWritten() { - return count; - } - - public byte[] toByteArray() { - if (count < bytes.length) { - return Arrays.copyOf(bytes, count); - } - return bytes; - } - - @Override - public void write(final int value) throws IOException { - if (count >= bytes.length) { - throw new IOException("Write exceeded expected length (" + count + ", " + bytes.length + ")"); - } - - bytes[count] = (byte) value; - count++; - } -} diff --git a/src/main/java/org/apache/commons/imaging/common/ImageBuilder.java b/src/main/java/org/apache/commons/imaging/common/ImageBuilder.java index f695c3ba..bf31bc58 100644 --- a/src/main/java/org/apache/commons/imaging/common/ImageBuilder.java +++ b/src/main/java/org/apache/commons/imaging/common/ImageBuilder.java @@ -73,7 +73,7 @@ public class ImageBuilder { public ImageBuilder(final int width, final int height, final boolean hasAlpha) { checkDimensions(width, height); - data = new int[width * height]; + data = new int[AllocationChecker.check(width * height)]; this.width = width; this.height = height; this.hasAlpha = hasAlpha; @@ -95,7 +95,7 @@ public class ImageBuilder { public ImageBuilder(final int width, final int height, final boolean hasAlpha, final boolean isAlphaPremultiplied) { checkDimensions(width, height); - data = new int[width * height]; + data = new int[AllocationChecker.check(width * height)]; this.width = width; this.height = height; this.hasAlpha = hasAlpha; @@ -203,7 +203,7 @@ public class ImageBuilder { checkBounds(x, y, w, h); // Transcribe the data to an output image array - final int[] argb = new int[w * h]; + final int[] argb = new int[AllocationChecker.check(w * h)]; int k = 0; for (int iRow = 0; iRow < h; iRow++) { final int dIndex = (iRow + y) * width + x; diff --git a/src/main/java/org/apache/commons/imaging/common/PackBits.java b/src/main/java/org/apache/commons/imaging/common/PackBits.java index 19efec6a..755909e8 100644 --- a/src/main/java/org/apache/commons/imaging/common/PackBits.java +++ b/src/main/java/org/apache/commons/imaging/common/PackBits.java @@ -20,12 +20,13 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import org.apache.commons.imaging.ImageReadException; +import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream; public class PackBits { public byte[] compress(final byte[] bytes) throws IOException { // max length 1 extra byte for every 128 - try (FastByteArrayOutputStream baos = new FastByteArrayOutputStream(bytes.length * 2)) { + try (UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream(AllocationChecker.check(bytes.length * 2))) { int ptr = 0; while (ptr < bytes.length) { int dup = findNextDuplicate(bytes, ptr); diff --git a/src/main/java/org/apache/commons/imaging/common/ZlibDeflate.java b/src/main/java/org/apache/commons/imaging/common/ZlibDeflate.java index 4efddfd3..9b8990be 100644 --- a/src/main/java/org/apache/commons/imaging/common/ZlibDeflate.java +++ b/src/main/java/org/apache/commons/imaging/common/ZlibDeflate.java @@ -71,7 +71,7 @@ public class ZlibDeflate { try { final Inflater inflater = new Inflater(); inflater.setInput(bytes); - final byte[] result = new byte[expectedSize]; + final byte[] result = new byte[AllocationChecker.check(expectedSize)]; inflater.inflate(result); return result; } catch (final DataFormatException e) { diff --git a/src/main/java/org/apache/commons/imaging/common/bytesource/ByteSourceInputStream.java b/src/main/java/org/apache/commons/imaging/common/bytesource/ByteSourceInputStream.java index d03f97ad..351cbfd0 100644 --- a/src/main/java/org/apache/commons/imaging/common/bytesource/ByteSourceInputStream.java +++ b/src/main/java/org/apache/commons/imaging/common/bytesource/ByteSourceInputStream.java @@ -23,6 +23,7 @@ import java.io.InputStream; import java.util.Arrays; import java.util.Objects; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.BinaryFunctions; public class ByteSourceInputStream extends ByteSource { @@ -203,7 +204,7 @@ public class ByteSourceInputStream extends ByteSource { final InputStream cis = getInputStream(); BinaryFunctions.skipBytes(cis, blockStart); - final byte[] bytes = new byte[blockLength]; + final byte[] bytes = new byte[AllocationChecker.check(blockLength)]; int total = 0; while (true) { final int read = cis.read(bytes, total, bytes.length - total); diff --git a/src/main/java/org/apache/commons/imaging/common/itu_t4/BitArrayOutputStream.java b/src/main/java/org/apache/commons/imaging/common/itu_t4/BitArrayOutputStream.java index 3eba5939..1f830019 100644 --- a/src/main/java/org/apache/commons/imaging/common/itu_t4/BitArrayOutputStream.java +++ b/src/main/java/org/apache/commons/imaging/common/itu_t4/BitArrayOutputStream.java @@ -19,6 +19,8 @@ package org.apache.commons.imaging.common.itu_t4; import java.io.OutputStream; import java.util.Arrays; +import org.apache.commons.imaging.common.AllocationChecker; + /** * Output stream writing to a byte array, and capable * of writing 1 bit at a time, starting from the most significant bit. @@ -34,7 +36,7 @@ class BitArrayOutputStream extends OutputStream { } BitArrayOutputStream(final int size) { - buffer = new byte[size]; + buffer = new byte[AllocationChecker.check(size)]; } @Override @@ -89,7 +91,7 @@ class BitArrayOutputStream extends OutputStream { private void writeByte(final int b) { if (bytesWritten >= buffer.length) { - final byte[] bigger = new byte[buffer.length * 2]; + final byte[] bigger = new byte[AllocationChecker.check(buffer.length * 2)]; System.arraycopy(buffer, 0, bigger, 0, bytesWritten); buffer = bigger; } diff --git a/src/main/java/org/apache/commons/imaging/common/itu_t4/T4AndT6Compression.java b/src/main/java/org/apache/commons/imaging/common/itu_t4/T4AndT6Compression.java index 34f23800..3531d893 100644 --- a/src/main/java/org/apache/commons/imaging/common/itu_t4/T4AndT6Compression.java +++ b/src/main/java/org/apache/commons/imaging/common/itu_t4/T4AndT6Compression.java @@ -21,6 +21,7 @@ import java.io.IOException; import org.apache.commons.imaging.ImageReadException; import org.apache.commons.imaging.ImageWriteException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.itu_t4.T4_T6_Tables.Entry; public final class T4AndT6Compression { @@ -204,8 +205,8 @@ public final class T4AndT6Compression { throws ImageWriteException { final BitInputStreamFlexible inputStream = new BitInputStreamFlexible(new ByteArrayInputStream(uncompressed)); final BitArrayOutputStream outputStream = new BitArrayOutputStream(); - int[] referenceLine = new int[width]; - int[] codingLine = new int[width]; + int[] referenceLine = new int[AllocationChecker.check(width)]; + int[] codingLine = new int[AllocationChecker.check(width)]; int kCounter = 0; if (hasFill) { T4_T6_Tables.EOL16.writeBits(outputStream); @@ -283,14 +284,14 @@ public final class T4AndT6Compression { try (ByteArrayInputStream bais = new ByteArrayInputStream(uncompressed); BitInputStreamFlexible inputStream = new BitInputStreamFlexible(bais)) { final BitArrayOutputStream outputStream = new BitArrayOutputStream(); - int[] referenceLine = new int[width]; - int[] codingLine = new int[width]; + int[] referenceLine = new int[AllocationChecker.check(width)]; + int[] codingLine = new int[AllocationChecker.check(width)]; for (int y = 0; y < height; y++) { for (int i = 0; i < width; i++) { try { codingLine[i] = inputStream.readBits(1); - } catch (final IOException ioException) { - throw new ImageWriteException("Error reading image to compress", ioException); + } catch (final IOException e) { + throw new ImageWriteException("Error reading image to compress", e); } } int codingA0Color = WHITE; @@ -434,7 +435,7 @@ public final class T4AndT6Compression { final int height, final boolean hasFill) throws ImageReadException { final BitInputStreamFlexible inputStream = new BitInputStreamFlexible(new ByteArrayInputStream(compressed)); try (BitArrayOutputStream outputStream = new BitArrayOutputStream()) { - final int[] referenceLine = new int[width]; + final int[] referenceLine = new int[AllocationChecker.check(width)]; for (int y = 0; y < height; y++) { int rowLength = 0; try { @@ -541,7 +542,7 @@ public final class T4AndT6Compression { throws ImageReadException { final BitInputStreamFlexible inputStream = new BitInputStreamFlexible(new ByteArrayInputStream(compressed)); final BitArrayOutputStream outputStream = new BitArrayOutputStream(); - final int[] referenceLine = new int[width]; + final int[] referenceLine = new int[AllocationChecker.check(width)]; for (int y = 0; y < height; y++) { int rowLength = 0; try { diff --git a/src/main/java/org/apache/commons/imaging/common/mylzw/BitsToByteInputStream.java b/src/main/java/org/apache/commons/imaging/common/mylzw/BitsToByteInputStream.java index ba011627..cbcc2f09 100644 --- a/src/main/java/org/apache/commons/imaging/common/mylzw/BitsToByteInputStream.java +++ b/src/main/java/org/apache/commons/imaging/common/mylzw/BitsToByteInputStream.java @@ -19,6 +19,8 @@ package org.apache.commons.imaging.common.mylzw; import java.io.IOException; import java.io.InputStream; +import org.apache.commons.imaging.common.AllocationChecker; + public class BitsToByteInputStream extends InputStream { private final MyBitInputStream is; private final int desiredDepth; @@ -45,12 +47,10 @@ public class BitsToByteInputStream extends InputStream { } public int[] readBitsArray(final int sampleBits, final int length) throws IOException { - final int[] result = new int[length]; - + final int[] result = new int[AllocationChecker.check(length)]; for (int i = 0; i < length; i++) { result[i] = readBits(sampleBits); } - return result; } } diff --git a/src/main/java/org/apache/commons/imaging/formats/bmp/BmpImageParser.java b/src/main/java/org/apache/commons/imaging/formats/bmp/BmpImageParser.java index b2df9253..82df3632 100644 --- a/src/main/java/org/apache/commons/imaging/formats/bmp/BmpImageParser.java +++ b/src/main/java/org/apache/commons/imaging/formats/bmp/BmpImageParser.java @@ -325,8 +325,7 @@ public class BmpImageParser extends ImageParser<BmpImagingParameters> { final byte identifier2 = readByte("Identifier2", is, "Not a Valid BMP File"); if (formatCompliance != null) { - formatCompliance.compareBytes("Signature", BMP_HEADER_SIGNATURE, - new byte[]{identifier1, identifier2,}); + formatCompliance.compareBytes("Signature", BMP_HEADER_SIGNATURE, new byte[] { identifier1, identifier2 }); } final int fileSize = read4Bytes("File Size", is, "Not a Valid BMP File", getByteOrder()); diff --git a/src/main/java/org/apache/commons/imaging/formats/gif/GifImageParser.java b/src/main/java/org/apache/commons/imaging/formats/gif/GifImageParser.java index ba86a721..5551ca32 100644 --- a/src/main/java/org/apache/commons/imaging/formats/gif/GifImageParser.java +++ b/src/main/java/org/apache/commons/imaging/formats/gif/GifImageParser.java @@ -44,6 +44,7 @@ import org.apache.commons.imaging.ImageInfo; import org.apache.commons.imaging.ImageParser; import org.apache.commons.imaging.ImageReadException; import org.apache.commons.imaging.ImageWriteException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.BinaryOutputStream; import org.apache.commons.imaging.common.ImageBuilder; import org.apache.commons.imaging.common.ImageMetadata; @@ -348,7 +349,7 @@ public class GifImageParser extends ImageParser<GifImagingParameters> implements } final int length = bytes.length / 3; - final int[] result = new int[length]; + final int[] result = new int[AllocationChecker.check(length)]; for (int i = 0; i < length; i++) { final int red = 0xff & bytes[(i * 3) + 0]; @@ -757,7 +758,7 @@ public class GifImageParser extends ImageParser<GifImagingParameters> implements if (formatCompliance != null) { formatCompliance.compareBytes("Signature", GIF_HEADER_SIGNATURE, - new byte[]{identifier1, identifier2, identifier3,}); + new byte[] { identifier1, identifier2, identifier3 }); formatCompliance.compare("version", 56, version1); formatCompliance.compare("version", new int[] { 55, 57, }, version2); formatCompliance.compare("version", 97, version3); @@ -1106,7 +1107,7 @@ public class GifImageParser extends ImageParser<GifImagingParameters> implements lzwMinimumCodeSize, ByteOrder.LITTLE_ENDIAN, false); // GIF // Mode); - final byte[] imageData = new byte[width * height]; + final byte[] imageData = new byte[AllocationChecker.check(width * height)]; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { final int argb = src.getRGB(x, y); diff --git a/src/main/java/org/apache/commons/imaging/formats/icns/Rle24Compression.java b/src/main/java/org/apache/commons/imaging/formats/icns/Rle24Compression.java index d3e1a50a..949f75c3 100644 --- a/src/main/java/org/apache/commons/imaging/formats/icns/Rle24Compression.java +++ b/src/main/java/org/apache/commons/imaging/formats/icns/Rle24Compression.java @@ -16,10 +16,12 @@ */ package org.apache.commons.imaging.formats.icns; +import org.apache.commons.imaging.common.AllocationChecker; + final class Rle24Compression { public static byte[] decompress(final int width, final int height, final byte[] data) { final int pixelCount = width * height; - final byte[] result = new byte[4 * pixelCount]; + final byte[] result = new byte[AllocationChecker.check(4 * pixelCount)]; // Several ICNS parsers advance by 4 bytes here: // http://code.google.com/p/icns2png/ - when the width is >= 128 diff --git a/src/main/java/org/apache/commons/imaging/formats/ico/IcoImageParser.java b/src/main/java/org/apache/commons/imaging/formats/ico/IcoImageParser.java index dfe8dca9..71147e03 100644 --- a/src/main/java/org/apache/commons/imaging/formats/ico/IcoImageParser.java +++ b/src/main/java/org/apache/commons/imaging/formats/ico/IcoImageParser.java @@ -41,6 +41,7 @@ import org.apache.commons.imaging.ImageReadException; import org.apache.commons.imaging.ImageWriteException; import org.apache.commons.imaging.Imaging; import org.apache.commons.imaging.PixelDensity; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.BinaryOutputStream; import org.apache.commons.imaging.common.ImageMetadata; import org.apache.commons.imaging.common.bytesource.ByteSource; @@ -580,12 +581,12 @@ public class IcoImageParser extends ImageParser<IcoImagingParameters> { try (InputStream is = byteSource.getInputStream()) { final FileHeader fileHeader = readFileHeader(is); - final IconInfo[] fIconInfos = new IconInfo[fileHeader.iconCount]; + final IconInfo[] fIconInfos = new IconInfo[AllocationChecker.check(fileHeader.iconCount)]; for (int i = 0; i < fileHeader.iconCount; i++) { fIconInfos[i] = readIconInfo(is); } - final IconData[] fIconDatas = new IconData[fileHeader.iconCount]; + final IconData[] fIconDatas = new IconData[AllocationChecker.check(fileHeader.iconCount)]; for (int i = 0; i < fileHeader.iconCount; i++) { final byte[] iconData = byteSource.getBlock( fIconInfos[i].imageOffset, fIconInfos[i].imageSize); diff --git a/src/main/java/org/apache/commons/imaging/formats/jpeg/JpegImageParser.java b/src/main/java/org/apache/commons/imaging/formats/jpeg/JpegImageParser.java index ba16d914..f10d747c 100644 --- a/src/main/java/org/apache/commons/imaging/formats/jpeg/JpegImageParser.java +++ b/src/main/java/org/apache/commons/imaging/formats/jpeg/JpegImageParser.java @@ -37,6 +37,7 @@ import org.apache.commons.imaging.ImageFormats; import org.apache.commons.imaging.ImageInfo; import org.apache.commons.imaging.ImageParser; import org.apache.commons.imaging.ImageReadException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.ImageMetadata; import org.apache.commons.imaging.common.XmpEmbeddable; import org.apache.commons.imaging.common.XmpImagingParameters; @@ -127,7 +128,7 @@ public class JpegImageParser extends ImageParser<JpegImagingParameters> implemen } } - final byte[] result = new byte[total]; + final byte[] result = new byte[AllocationChecker.check(total)]; int progress = 0; for (final App2Segment segment : segments) { diff --git a/src/main/java/org/apache/commons/imaging/formats/jpeg/decoder/Block.java b/src/main/java/org/apache/commons/imaging/formats/jpeg/decoder/Block.java index 17162616..10d127de 100644 --- a/src/main/java/org/apache/commons/imaging/formats/jpeg/decoder/Block.java +++ b/src/main/java/org/apache/commons/imaging/formats/jpeg/decoder/Block.java @@ -15,13 +15,15 @@ package org.apache.commons.imaging.formats.jpeg.decoder; +import org.apache.commons.imaging.common.AllocationChecker; + final class Block { final int[] samples; final int width; final int height; Block(final int width, final int height) { - samples = new int[width * height]; + this.samples = new int[AllocationChecker.check(width * height)]; this.width = width; this.height = height; } diff --git a/src/main/java/org/apache/commons/imaging/formats/jpeg/decoder/JpegDecoder.java b/src/main/java/org/apache/commons/imaging/formats/jpeg/decoder/JpegDecoder.java index 80a7094c..41826c9b 100644 --- a/src/main/java/org/apache/commons/imaging/formats/jpeg/decoder/JpegDecoder.java +++ b/src/main/java/org/apache/commons/imaging/formats/jpeg/decoder/JpegDecoder.java @@ -33,6 +33,7 @@ import java.util.Properties; import org.apache.commons.imaging.ImageReadException; import org.apache.commons.imaging.color.ColorConversions; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.BinaryFileParser; import org.apache.commons.imaging.common.bytesource.ByteSource; import org.apache.commons.imaging.formats.jpeg.JpegConstants; @@ -108,7 +109,7 @@ public class JpegDecoder extends BinaryFileParser implements JpegUtils.Visitor { final List<Integer> intervalStarts = getIntervalStartPositions(scanPayload); // get number of intervals in payload to init an array of appropriate length final int intervalCount = intervalStarts.size(); - final JpegInputStream[] streams = new JpegInputStream[intervalCount]; + final JpegInputStream[] streams = new JpegInputStream[AllocationChecker.check(intervalCount)]; for (int i = 0; i < intervalCount; i++) { final int from = intervalStarts.get(i); int to; @@ -141,7 +142,7 @@ public class JpegDecoder extends BinaryFileParser implements JpegUtils.Visitor { private final float[] block = new float[64]; private Block[] allocateMCUMemory() throws ImageReadException { - final Block[] mcu = new Block[sosSegment.numberOfComponents]; + final Block[] mcu = new Block[AllocationChecker.check(sosSegment.numberOfComponents)]; for (int i = 0; i < sosSegment.numberOfComponents; i++) { final SosSegment.Component scanComponent = sosSegment.getComponents(i); SofnSegment.Component frameComponent = null; @@ -378,9 +379,9 @@ public class JpegDecoder extends BinaryFileParser implements JpegUtils.Visitor { } quantizationTables[table.destinationIdentifier] = table; final int mSize = 64; - final int[] quantizationMatrixInt = new int[mSize]; + final int[] quantizationMatrixInt = new int[AllocationChecker.check(mSize)]; ZigZag.zigZagToBlock(table.getElements(), quantizationMatrixInt); - final float[] quantizationMatrixFloat = new float[mSize]; + final float[] quantizationMatrixFloat = new float[AllocationChecker.check(mSize)]; for (int j = 0; j < mSize; j++) { quantizationMatrixFloat[j] = quantizationMatrixInt[j]; } @@ -423,7 +424,7 @@ public class JpegDecoder extends BinaryFileParser implements JpegUtils.Visitor { // the payload contains the entropy-encoded segments (or ECS) divided by RST markers // or only one ECS if the entropy-encoded data is not divided by RST markers // length of payload = length of image data - length of data already read - final int[] scanPayload = new int[imageData.length - segmentLength]; + final int[] scanPayload = new int[AllocationChecker.check(imageData.length - segmentLength)]; int payloadReadCount = 0; while (payloadReadCount < scanPayload.length) { scanPayload[payloadReadCount] = is.read(); @@ -444,9 +445,9 @@ public class JpegDecoder extends BinaryFileParser implements JpegUtils.Visitor { final int xMCUs = (sofnSegment.width + hSize - 1) / hSize; final int yMCUs = (sofnSegment.height + vSize - 1) / vSize; final Block[] mcu = allocateMCUMemory(); - final Block[] scaledMCU = new Block[mcu.length]; + final Block[] scaledMCU = new Block[AllocationChecker.check(mcu.length)]; Arrays.setAll(scaledMCU, i -> new Block(hSize, vSize)); - final int[] preds = new int[sofnSegment.numberOfComponents]; + final int[] preds = new int[AllocationChecker.check(sofnSegment.numberOfComponents)]; ColorModel colorModel; WritableRaster raster; switch (sofnSegment.numberOfComponents) { diff --git a/src/main/java/org/apache/commons/imaging/formats/jpeg/iptc/IptcParser.java b/src/main/java/org/apache/commons/imaging/formats/jpeg/iptc/IptcParser.java index 0b8d887c..2df375e1 100644 --- a/src/main/java/org/apache/commons/imaging/formats/jpeg/iptc/IptcParser.java +++ b/src/main/java/org/apache/commons/imaging/formats/jpeg/iptc/IptcParser.java @@ -43,6 +43,7 @@ import org.apache.commons.imaging.ImageReadException; import org.apache.commons.imaging.ImageWriteException; import org.apache.commons.imaging.ImagingConstants; import org.apache.commons.imaging.ImagingParameters; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.BinaryFileParser; import org.apache.commons.imaging.common.BinaryFunctions; import org.apache.commons.imaging.common.BinaryOutputStream; @@ -83,7 +84,7 @@ public class IptcParser extends BinaryFileParser { } catch (final IllegalArgumentException e) { } // check if encoding is a escape sequence // normalize encoding byte sequence - final byte[] codedCharsetNormalized = new byte[codedCharset.length]; + final byte[] codedCharsetNormalized = new byte[AllocationChecker.check(codedCharset.length)]; int j = 0; for (final byte element : codedCharset) { if (element != ' ') { diff --git a/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/DhtSegment.java b/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/DhtSegment.java index 06e03a95..e93ead44 100644 --- a/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/DhtSegment.java +++ b/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/DhtSegment.java @@ -24,6 +24,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import org.apache.commons.imaging.common.AllocationChecker; + public class DhtSegment extends Segment { public static class HuffmanTable { // some arrays are better off one-based @@ -73,7 +75,7 @@ public class DhtSegment extends Segment { k = 0; int code = 0; int si = huffSize[0]; - huffCode = new int[lastK]; + huffCode = new int[AllocationChecker.check(lastK)]; while (true) { if (k >= lastK) { break; @@ -156,7 +158,7 @@ public class DhtSegment extends Segment { length--; bitsSum += bits[i]; } - final int[] huffVal = new int[bitsSum]; + final int[] huffVal = new int[AllocationChecker.check(bitsSum)]; for (int i = 0; i < bitsSum; i++) { huffVal[i] = 0xff & readByte("Vij", is, "Not a Valid JPEG File"); length--; diff --git a/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/SofnSegment.java b/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/SofnSegment.java index 4a37dfab..0b8012c4 100644 --- a/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/SofnSegment.java +++ b/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/SofnSegment.java @@ -26,6 +26,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.imaging.ImageReadException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.formats.jpeg.JpegConstants; public class SofnSegment extends Segment { @@ -73,7 +74,7 @@ public class SofnSegment extends Segment { if (numberOfComponents < 0) { throw new ImageReadException("The number of components in a SOF0Segment cannot be less than 0!"); } - components = new Component[numberOfComponents]; + components = new Component[AllocationChecker.check(numberOfComponents)]; for (int i = 0; i < numberOfComponents; i++) { final int componentIdentifier = readByte("ComponentIdentifier", is, "Not a Valid JPEG File"); diff --git a/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/SosSegment.java b/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/SosSegment.java index 55af52ba..f41834e5 100644 --- a/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/SosSegment.java +++ b/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/SosSegment.java @@ -24,6 +24,8 @@ import java.io.InputStream; import java.util.logging.Level; import java.util.logging.Logger; +import org.apache.commons.imaging.common.AllocationChecker; + public class SosSegment extends Segment { public static class Component { @@ -66,7 +68,7 @@ public class SosSegment extends Segment { // Debug.debug("number_of_components_in_scan", // numberOfComponents); - components = new Component[numberOfComponents]; + components = new Component[AllocationChecker.check(numberOfComponents)]; for (int i = 0; i < numberOfComponents; i++) { final int scanComponentSelector = readByte("scanComponentSelector", is, "Not a Valid JPEG File"); // Debug.debug("scanComponentSelector", scanComponentSelector); diff --git a/src/main/java/org/apache/commons/imaging/formats/pcx/PcxImageParser.java b/src/main/java/org/apache/commons/imaging/formats/pcx/PcxImageParser.java index ce4caa54..a175d14b 100644 --- a/src/main/java/org/apache/commons/imaging/formats/pcx/PcxImageParser.java +++ b/src/main/java/org/apache/commons/imaging/formats/pcx/PcxImageParser.java @@ -46,6 +46,7 @@ import org.apache.commons.imaging.ImageInfo; import org.apache.commons.imaging.ImageParser; import org.apache.commons.imaging.ImageReadException; import org.apache.commons.imaging.ImageWriteException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.ImageMetadata; import org.apache.commons.imaging.common.bytesource.ByteSource; @@ -304,12 +305,12 @@ public class PcxImageParser extends ImageParser<PcxImagingParameters> { throw new ImageReadException("Unsupported/invalid image encoding " + pcxHeader.encoding); } final int scanlineLength = pcxHeader.bytesPerLine * pcxHeader.nPlanes; - final byte[] scanline = new byte[scanlineLength]; + final byte[] scanline = new byte[AllocationChecker.check(scanlineLength)]; if ((pcxHeader.bitsPerPixel == 1 || pcxHeader.bitsPerPixel == 2 || pcxHeader.bitsPerPixel == 4 || pcxHeader.bitsPerPixel == 8) && pcxHeader.nPlanes == 1) { final int bytesPerImageRow = (xSize * pcxHeader.bitsPerPixel + 7) / 8; - final byte[] image = new byte[ySize * bytesPerImageRow]; + final byte[] image = new byte[AllocationChecker.check(ySize * bytesPerImageRow)]; for (int y = 0; y < ySize; y++) { rleReader.read(is, scanline); System.arraycopy(scanline, 0, image, y * bytesPerImageRow, @@ -359,7 +360,7 @@ public class PcxImageParser extends ImageParser<PcxImagingParameters> { DataBuffer.TYPE_BYTE); final BufferedImage image = new BufferedImage(xSize, ySize, BufferedImage.TYPE_BYTE_BINARY, colorModel); - final byte[] unpacked = new byte[xSize]; + final byte[] unpacked = new byte[AllocationChecker.check(xSize)]; for (int y = 0; y < ySize; y++) { rleReader.read(is, scanline); int nextByte = 0; @@ -378,9 +379,10 @@ public class PcxImageParser extends ImageParser<PcxImagingParameters> { } if (pcxHeader.bitsPerPixel == 8 && pcxHeader.nPlanes == 3) { final byte[][] image = new byte[3][]; - image[0] = new byte[xSize * ySize]; - image[1] = new byte[xSize * ySize]; - image[2] = new byte[xSize * ySize]; + final int xySize = xSize * ySize; + image[0] = new byte[AllocationChecker.check(xySize)]; + image[1] = new byte[AllocationChecker.check(xySize)]; + image[2] = new byte[AllocationChecker.check(xySize)]; for (int y = 0; y < ySize; y++) { rleReader.read(is, scanline); System.arraycopy(scanline, 0, image[0], y * xSize, xSize); @@ -407,7 +409,7 @@ public class PcxImageParser extends ImageParser<PcxImagingParameters> { + pcxHeader.nPlanes); } final int rowLength = 3 * xSize; - final byte[] image = new byte[rowLength * ySize]; + final byte[] image = new byte[AllocationChecker.check(rowLength * ySize)]; for (int y = 0; y < ySize; y++) { rleReader.read(is, scanline); if (pcxHeader.bitsPerPixel == 24) { diff --git a/src/main/java/org/apache/commons/imaging/formats/pcx/PcxWriter.java b/src/main/java/org/apache/commons/imaging/formats/pcx/PcxWriter.java index ed53d86d..415548f0 100644 --- a/src/main/java/org/apache/commons/imaging/formats/pcx/PcxWriter.java +++ b/src/main/java/org/apache/commons/imaging/formats/pcx/PcxWriter.java @@ -21,6 +21,7 @@ import java.io.OutputStream; import java.util.Arrays; import org.apache.commons.imaging.PixelDensity; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.BinaryOutputStream; import org.apache.commons.imaging.palette.PaletteFactory; import org.apache.commons.imaging.palette.SimplePalette; @@ -182,10 +183,10 @@ class PcxWriter { private void writePixels(final BufferedImage src, final int bitDepth, final int planes, final int bytesPerLine, final SimplePalette palette, final BinaryOutputStream bos) throws IOException { - final byte[] plane0 = new byte[bytesPerLine]; - final byte[] plane1 = new byte[bytesPerLine]; - final byte[] plane2 = new byte[bytesPerLine]; - final byte[] plane3 = new byte[bytesPerLine]; + final byte[] plane0 = new byte[AllocationChecker.check(bytesPerLine)]; + final byte[] plane1 = new byte[AllocationChecker.check(bytesPerLine)]; + final byte[] plane2 = new byte[AllocationChecker.check(bytesPerLine)]; + final byte[] plane3 = new byte[AllocationChecker.check(bytesPerLine)]; final byte[][] allPlanes = { plane0, plane1, plane2, plane3 }; for (int y = 0; y < src.getHeight(); y++) { @@ -265,8 +266,8 @@ class PcxWriter { private void writePixels32(final BufferedImage src, final int bytesPerLine, final BinaryOutputStream bos) throws IOException { - final int[] rgbs = new int[src.getWidth()]; - final byte[] plane = new byte[4 * bytesPerLine]; + final int[] rgbs = new int[AllocationChecker.check(src.getWidth())]; + final byte[] plane = new byte[AllocationChecker.check(4 * bytesPerLine)]; for (int y = 0; y < src.getHeight(); y++) { src.getRGB(0, y, src.getWidth(), 1, rgbs, 0, src.getWidth()); for (int x = 0; x < rgbs.length; x++) { diff --git a/src/main/java/org/apache/commons/imaging/formats/png/PngWriter.java b/src/main/java/org/apache/commons/imaging/formats/png/PngWriter.java index fd3eeaa0..55f923a7 100644 --- a/src/main/java/org/apache/commons/imaging/formats/png/PngWriter.java +++ b/src/main/java/org/apache/commons/imaging/formats/png/PngWriter.java @@ -27,6 +27,7 @@ import java.util.zip.DeflaterOutputStream; import org.apache.commons.imaging.ImageWriteException; import org.apache.commons.imaging.PixelDensity; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.internal.Debug; import org.apache.commons.imaging.palette.Palette; import org.apache.commons.imaging.palette.PaletteFactory; @@ -182,7 +183,7 @@ class PngWriter { private void writeChunkPLTE(final OutputStream os, final Palette palette) throws IOException { final int length = palette.length(); - final byte[] bytes = new byte[length * 3]; + final byte[] bytes = new byte[AllocationChecker.check(length * 3)]; // Debug.debug("length", length); for (int i = 0; i < length; i++) { @@ -235,7 +236,7 @@ class PngWriter { } private void writeChunkTRNS(final OutputStream os, final Palette palette) throws IOException { - final byte[] bytes = new byte[palette.length()]; + final byte[] bytes = new byte[AllocationChecker.check(palette.length())]; for (int i = 0; i < bytes.length; i++) { bytes[i] = (byte) (0xff & (palette.getEntry(i) >> 24)); @@ -470,7 +471,7 @@ class PngWriter { final boolean useAlpha = pngColorType == PngColorType.GREYSCALE_WITH_ALPHA || pngColorType == PngColorType.TRUE_COLOR_WITH_ALPHA; - final int[] row = new int[width]; + final int[] row = new int[AllocationChecker.check(width)]; for (int y = 0; y < height; y++) { // Debug.debug("y", y + "/" + height); src.getRGB(0, y, width, 1, row, 0, width); @@ -521,7 +522,7 @@ class PngWriter { final boolean useAlpha = pngColorType == PngColorType.GREYSCALE_WITH_ALPHA || pngColorType == PngColorType.TRUE_COLOR_WITH_ALPHA; - final int[] row = new int[width]; + final int[] row = new int[AllocationChecker.check(width)]; for (int y = 0; y < height; y++) { // Debug.debug("y", y + "/" + height); src.getRGB(0, y, width, 1, row, 0, width); diff --git a/src/main/java/org/apache/commons/imaging/formats/png/ScanExpediter.java b/src/main/java/org/apache/commons/imaging/formats/png/ScanExpediter.java index 7de3de32..fb1a9fe9 100644 --- a/src/main/java/org/apache/commons/imaging/formats/png/ScanExpediter.java +++ b/src/main/java/org/apache/commons/imaging/formats/png/ScanExpediter.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.io.InputStream; import org.apache.commons.imaging.ImageReadException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.formats.png.chunks.PngChunkPlte; import org.apache.commons.imaging.formats.png.scanlinefilters.ScanlineFilter; import org.apache.commons.imaging.formats.png.scanlinefilters.ScanlineFilterAverage; @@ -208,7 +209,7 @@ abstract class ScanExpediter { final int bytesPerPixel) throws ImageReadException, IOException { final ScanlineFilter filter = getScanlineFilter(filterType, bytesPerPixel); - final byte[] dst = new byte[src.length]; + final byte[] dst = new byte[AllocationChecker.check(src.length)]; filter.unfilter(src, dst, prev); return dst; } diff --git a/src/main/java/org/apache/commons/imaging/formats/png/chunks/PngChunkIccp.java b/src/main/java/org/apache/commons/imaging/formats/png/chunks/PngChunkIccp.java index af4a0ecd..c4d8696b 100644 --- a/src/main/java/org/apache/commons/imaging/formats/png/chunks/PngChunkIccp.java +++ b/src/main/java/org/apache/commons/imaging/formats/png/chunks/PngChunkIccp.java @@ -28,6 +28,7 @@ import java.util.logging.Logger; import java.util.zip.InflaterInputStream; import org.apache.commons.imaging.ImageReadException; +import org.apache.commons.imaging.common.AllocationChecker; /** * The PNG iCCP chunk. If "present, the image samples conform to the color space represented by the embedded ICC @@ -83,7 +84,7 @@ public class PngChunkIccp extends PngChunk { compressionMethod = bytes[index + 1]; final int compressedProfileLength = bytes.length - (index + 1 + 1); - compressedProfile = new byte[compressedProfileLength]; + compressedProfile = new byte[AllocationChecker.check(compressedProfileLength)]; System.arraycopy(bytes, index + 1 + 1, compressedProfile, 0, compressedProfileLength); if (LOGGER.isLoggable(Level.FINEST)) { diff --git a/src/main/java/org/apache/commons/imaging/formats/png/chunks/PngChunkItxt.java b/src/main/java/org/apache/commons/imaging/formats/png/chunks/PngChunkItxt.java index a18e6268..40373476 100644 --- a/src/main/java/org/apache/commons/imaging/formats/png/chunks/PngChunkItxt.java +++ b/src/main/java/org/apache/commons/imaging/formats/png/chunks/PngChunkItxt.java @@ -25,6 +25,7 @@ import java.nio.charset.StandardCharsets; import java.util.zip.InflaterInputStream; import org.apache.commons.imaging.ImageReadException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.formats.png.PngConstants; import org.apache.commons.imaging.formats.png.PngText; @@ -90,7 +91,7 @@ public class PngChunkItxt extends PngTextChunk { if (compressed) { final int compressedTextLength = bytes.length - index; - final byte[] compressedText = new byte[compressedTextLength]; + final byte[] compressedText = new byte[AllocationChecker.check(compressedTextLength)]; System.arraycopy(bytes, index, compressedText, 0, compressedTextLength); text = new String(getStreamBytes( diff --git a/src/main/java/org/apache/commons/imaging/formats/png/chunks/PngChunkPlte.java b/src/main/java/org/apache/commons/imaging/formats/png/chunks/PngChunkPlte.java index a741a37b..4c786222 100644 --- a/src/main/java/org/apache/commons/imaging/formats/png/chunks/PngChunkPlte.java +++ b/src/main/java/org/apache/commons/imaging/formats/png/chunks/PngChunkPlte.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.util.Arrays; import org.apache.commons.imaging.ImageReadException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.formats.png.GammaCorrection; public class PngChunkPlte extends PngChunk { @@ -40,7 +41,7 @@ public class PngChunkPlte extends PngChunk { final int count = length / 3; - rgb = new int[count]; + rgb = new int[AllocationChecker.check(count)]; for (int i = 0; i < count; i++) { final int red = readByte("red[" + i + "]", is, diff --git a/src/main/java/org/apache/commons/imaging/formats/png/chunks/PngChunkZtxt.java b/src/main/java/org/apache/commons/imaging/formats/png/chunks/PngChunkZtxt.java index ee2c404e..f08467ee 100644 --- a/src/main/java/org/apache/commons/imaging/formats/png/chunks/PngChunkZtxt.java +++ b/src/main/java/org/apache/commons/imaging/formats/png/chunks/PngChunkZtxt.java @@ -25,6 +25,7 @@ import java.nio.charset.StandardCharsets; import java.util.zip.InflaterInputStream; import org.apache.commons.imaging.ImageReadException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.formats.png.PngConstants; import org.apache.commons.imaging.formats.png.PngText; @@ -54,7 +55,7 @@ public class PngChunkZtxt extends PngTextChunk { } final int compressedTextLength = bytes.length - index; - final byte[] compressedText = new byte[compressedTextLength]; + final byte[] compressedText = new byte[AllocationChecker.check(compressedTextLength)]; System.arraycopy(bytes, index, compressedText, 0, compressedTextLength); text = new String(getStreamBytes(new InflaterInputStream(new ByteArrayInputStream(compressedText))), StandardCharsets.ISO_8859_1); diff --git a/src/main/java/org/apache/commons/imaging/formats/psd/datareaders/CompressedDataReader.java b/src/main/java/org/apache/commons/imaging/formats/psd/datareaders/CompressedDataReader.java index 1a2515df..811c069f 100644 --- a/src/main/java/org/apache/commons/imaging/formats/psd/datareaders/CompressedDataReader.java +++ b/src/main/java/org/apache/commons/imaging/formats/psd/datareaders/CompressedDataReader.java @@ -23,6 +23,7 @@ import java.io.InputStream; import java.nio.ByteOrder; import org.apache.commons.imaging.ImageReadException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.BinaryFileParser; import org.apache.commons.imaging.common.BinaryFunctions; import org.apache.commons.imaging.common.PackBits; @@ -50,7 +51,7 @@ public class CompressedDataReader implements DataReader { // this.setDebug(true); final int scanlineCount = height * header.channels; - final int[] scanlineByteCounts = new int[scanlineCount]; + final int[] scanlineByteCounts = new int[AllocationChecker.check(scanlineCount)]; for (int i = 0; i < scanlineCount; i++) { scanlineByteCounts[i] = BinaryFunctions.read2Bytes("scanline_bytecount[" + i + "]", is, "PSD: bad Image Data", bfp.getByteOrder()); @@ -61,7 +62,7 @@ public class CompressedDataReader implements DataReader { final int depth = header.depth; final int channelCount = dataParser.getBasicChannelsCount(); - final int[][][] data = new int[channelCount][height][]; + final int[][][] data = new int[AllocationChecker.check(channelCount)][AllocationChecker.check(height)][]; // channels[0] = for (int channel = 0; channel < channelCount; channel++) { for (int y = 0; y < height; y++) { diff --git a/src/main/java/org/apache/commons/imaging/formats/psd/datareaders/UncompressedDataReader.java b/src/main/java/org/apache/commons/imaging/formats/psd/datareaders/UncompressedDataReader.java index 6683d684..4aa4ee30 100644 --- a/src/main/java/org/apache/commons/imaging/formats/psd/datareaders/UncompressedDataReader.java +++ b/src/main/java/org/apache/commons/imaging/formats/psd/datareaders/UncompressedDataReader.java @@ -22,6 +22,7 @@ import java.io.InputStream; import java.nio.ByteOrder; import org.apache.commons.imaging.ImageReadException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.BinaryFileParser; import org.apache.commons.imaging.common.mylzw.BitsToByteInputStream; import org.apache.commons.imaging.common.mylzw.MyBitInputStream; @@ -50,7 +51,8 @@ public class UncompressedDataReader implements DataReader { final MyBitInputStream mbis = new MyBitInputStream(is, ByteOrder.BIG_ENDIAN); // we want all samples to be bytes try (BitsToByteInputStream bbis = new BitsToByteInputStream(mbis, 8)) { - final int[][][] data = new int[channelCount][height][width]; + final int[][][] data = new int[AllocationChecker.check(channelCount)][AllocationChecker + .check(height)][AllocationChecker.check(width)]; for (int channel = 0; channel < channelCount; channel++) { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { diff --git a/src/main/java/org/apache/commons/imaging/formats/rgbe/RgbeInfo.java b/src/main/java/org/apache/commons/imaging/formats/rgbe/RgbeInfo.java index eea790ef..eb81183d 100644 --- a/src/main/java/org/apache/commons/imaging/formats/rgbe/RgbeInfo.java +++ b/src/main/java/org/apache/commons/imaging/formats/rgbe/RgbeInfo.java @@ -24,6 +24,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.imaging.ImageReadException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.BinaryFunctions; import org.apache.commons.imaging.common.ByteConversions; import org.apache.commons.imaging.common.GenericImageMetadata; @@ -106,8 +107,8 @@ class RgbeInfo implements Closeable { final byte[] scanLineBytes = ByteConversions.toBytes((short) wd, ByteOrder.BIG_ENDIAN); - final byte[] rgbe = new byte[wd * 4]; - final float[][] out = new float[3][wd * ht]; + final byte[] rgbe = new byte[AllocationChecker.check(wd * 4)]; + final float[][] out = new float[3][AllocationChecker.check(wd * ht)]; for (int i = 0; i < ht; i++) { BinaryFunctions.readAndVerifyBytes(in, TWO_TWO, "Scan line " + i + " expected to start with 0x2 0x2"); diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/TiffField.java b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffField.java index 281be3f2..f1994d48 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/TiffField.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffField.java @@ -29,6 +29,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.imaging.ImageReadException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.BinaryFunctions; import org.apache.commons.imaging.formats.tiff.constants.TiffConstants; import org.apache.commons.imaging.formats.tiff.constants.TiffTagConstants; @@ -155,25 +156,25 @@ public class TiffField { } if (o instanceof Number[]) { final Number[] numbers = (Number[]) o; - final double[] result = new double[numbers.length]; + final double[] result = new double[AllocationChecker.check(numbers.length)]; Arrays.setAll(result, i -> numbers[i].doubleValue()); return result; } if (o instanceof short[]) { final short[] numbers = (short[]) o; - final double[] result = new double[numbers.length]; + final double[] result = new double[AllocationChecker.check(numbers.length)]; Arrays.setAll(result, i -> numbers[i]); return result; } if (o instanceof int[]) { final int[] numbers = (int[]) o; - final double[] result = new double[numbers.length]; + final double[] result = new double[AllocationChecker.check(numbers.length)]; Arrays.setAll(result, i -> numbers[i]); return result; } if (o instanceof float[]) { final float[] numbers = (float[]) o; - final double[] result = new double[numbers.length]; + final double[] result = new double[AllocationChecker.check(numbers.length)]; Arrays.setAll(result, i -> numbers[i]); return result; } @@ -219,13 +220,13 @@ public class TiffField { } if (o instanceof Number[]) { final Number[] numbers = (Number[]) o; - final int[] result = new int[numbers.length]; + final int[] result = new int[AllocationChecker.check(numbers.length)]; Arrays.setAll(result, i -> numbers[i].intValue()); return result; } if (o instanceof short[]) { final short[] numbers = (short[]) o; - final int[] result = new int[numbers.length]; + final int[] result = new int[AllocationChecker.check(numbers.length)]; Arrays.setAll(result, i -> 0xffff & numbers[i]); return result; } diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/TiffRasterDataFloat.java b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffRasterDataFloat.java index 723f8f2f..9b236a19 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/TiffRasterDataFloat.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffRasterDataFloat.java @@ -18,6 +18,8 @@ package org.apache.commons.imaging.formats.tiff; import java.util.stream.IntStream; +import org.apache.commons.imaging.common.AllocationChecker; + /** * Provides a simple container for floating-point data. Some TIFF files are used * to store floating-point data rather than images. This class is intended to @@ -53,7 +55,7 @@ public class TiffRasterDataFloat extends TiffRasterData { */ public TiffRasterDataFloat(final int width, final int height) { super(width, height, 1); - data = new float[nCells]; + data = new float[AllocationChecker.check(nCells)]; } /** @@ -82,7 +84,7 @@ public class TiffRasterDataFloat extends TiffRasterData { */ public TiffRasterDataFloat(final int width, final int height, final int samplesPerPixel) { super(width, height, samplesPerPixel); - data = new float[nCells]; + data = new float[AllocationChecker.check(nCells)]; } /** diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/TiffRasterDataInt.java b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffRasterDataInt.java index 728209fb..08a91704 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/TiffRasterDataInt.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffRasterDataInt.java @@ -16,6 +16,8 @@ */ package org.apache.commons.imaging.formats.tiff; +import org.apache.commons.imaging.common.AllocationChecker; + /** * Provides a simple container for floating-point data. Some TIFF files are used * to store floating-point data rather than images. This class is intended to @@ -51,7 +53,7 @@ public class TiffRasterDataInt extends TiffRasterData { */ public TiffRasterDataInt(final int width, final int height) { super(width, height, 1); - data = new int[nCells]; + data = new int[AllocationChecker.check(nCells)]; } /** @@ -63,7 +65,7 @@ public class TiffRasterDataInt extends TiffRasterData { */ public TiffRasterDataInt(final int width, final int height, final int samplesPerPixel) { super(width, height, samplesPerPixel); - data = new int[nCells]; + data = new int[AllocationChecker.check(nCells)]; } /** @@ -111,7 +113,7 @@ public class TiffRasterDataInt extends TiffRasterData { */ @Override public float[] getData() { - final float[] result = new float[nCells]; + final float[] result = new float[AllocationChecker.check(nCells)]; for (int i = 0; i < nCells; i++) { result[i] = data[i]; } diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/DataReaderStrips.java b/src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/DataReaderStrips.java index c9347870..e3f5a94d 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/DataReaderStrips.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/DataReaderStrips.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.nio.ByteOrder; import org.apache.commons.imaging.ImageReadException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.ImageBuilder; import org.apache.commons.imaging.formats.tiff.TiffDirectory; import org.apache.commons.imaging.formats.tiff.TiffImageData; @@ -218,7 +219,7 @@ public final class DataReaderStrips extends ImageDataReader { // special case handled above try (BitInputStream bis = new BitInputStream(new ByteArrayInputStream(bytes), byteOrder)) { - int[] samples = new int[bitsPerSampleLength]; + int[] samples = new int[AllocationChecker.check(bitsPerSampleLength)]; resetPredictor(); for (int i = 0; i < pixelsPerStrip; i++) { getSamplesAsBytes(bis, samples); @@ -309,7 +310,7 @@ public final class DataReaderStrips extends ImageDataReader { final long bytesPerStrip = rowsInThisStrip * bytesPerRow; final long pixelsPerStrip = rowsInThisStrip * width; - final byte[] b = new byte[(int) bytesPerStrip]; + final byte[] b = new byte[AllocationChecker.check((int) bytesPerStrip)]; for (int iPlane = 0; iPlane < 3; iPlane++) { final int planeStrip = iPlane * nStripsInPlane + strip; final byte[] compressed = imageData.getImageData(planeStrip).getData(); @@ -372,7 +373,7 @@ public final class DataReaderStrips extends ImageDataReader { rasterHeight = height; } - final float[] rasterDataFloat = new float[rasterWidth * rasterHeight * samplesPerPixel]; + final float[] rasterDataFloat = new float[AllocationChecker.check(rasterWidth * rasterHeight * samplesPerPixel)]; // the legacy code is optimized to the reading of whole // strips (except for the last strip in the image, which can @@ -425,7 +426,7 @@ public final class DataReaderStrips extends ImageDataReader { rasterHeight = height; } - final int[] rasterDataInt = new int[rasterWidth * rasterHeight]; + final int[] rasterDataInt = new int[AllocationChecker.check(rasterWidth * rasterHeight)]; // the legacy code is optimized to the reading of whole // strips (except for the last strip in the image, which can diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/DataReaderTiled.java b/src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/DataReaderTiled.java index 2cebc9da..1bf65009 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/DataReaderTiled.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/DataReaderTiled.java @@ -28,6 +28,7 @@ import java.io.IOException; import java.nio.ByteOrder; import org.apache.commons.imaging.ImageReadException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.ImageBuilder; import org.apache.commons.imaging.formats.tiff.TiffDirectory; import org.apache.commons.imaging.formats.tiff.TiffImageData; @@ -184,7 +185,7 @@ public final class DataReaderTiled extends ImageDataReader { int tileX = 0; int tileY = 0; - int[] samples = new int[bitsPerSampleLength]; + int[] samples = new int[AllocationChecker.check(bitsPerSampleLength)]; resetPredictor(); for (int i = 0; i < pixelsPerTile; i++) { @@ -313,7 +314,7 @@ public final class DataReaderTiled extends ImageDataReader { rasterWidth = width; rasterHeight = height; } - final float[] rasterDataFloat = new float[rasterWidth * rasterHeight * samplesPerPixel]; + final float[] rasterDataFloat = new float[AllocationChecker.check(rasterWidth * rasterHeight * samplesPerPixel)]; // tileWidth is the width of the tile // tileLength is the height of the tile @@ -365,7 +366,7 @@ public final class DataReaderTiled extends ImageDataReader { rasterWidth = width; rasterHeight = height; } - final int[] rasterDataInt = new int[rasterWidth * rasterHeight]; + final int[] rasterDataInt = new int[AllocationChecker.check(rasterWidth * rasterHeight)]; // tileWidth is the width of the tile // tileLength is the height of the tile diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/ImageDataReader.java b/src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/ImageDataReader.java index 39953654..d0899056 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/ImageDataReader.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/ImageDataReader.java @@ -37,6 +37,7 @@ import java.nio.ByteOrder; import java.util.Arrays; import org.apache.commons.imaging.ImageReadException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.ImageBuilder; import org.apache.commons.imaging.common.PackBits; import org.apache.commons.imaging.common.ZlibDeflate; @@ -199,7 +200,7 @@ public abstract class ImageDataReader { this.width = width; this.height = height; this.planarConfiguration = planarConfiguration; - last = new int[samplesPerPixel]; + last = new int[AllocationChecker.check(samplesPerPixel)]; } @@ -640,7 +641,7 @@ public abstract class ImageDataReader { final int bytesPerScan = scanSize * samplesPerPixel * bytesPerSample; final int nBytes = bytesPerScan * height; final int length = bytes.length < nBytes ? nBytes / bytesPerScan : height; - final int[] samples = new int[scanSize * samplesPerPixel * height]; + final int[] samples = new int[AllocationChecker.check(scanSize * samplesPerPixel * height)]; // floating-point differencing is indicated by a predictor value of 3. if (predictor == TiffTagConstants.PREDICTOR_VALUE_FLOATING_POINT_DIFFERENCING) { // at this time, this class supports the 32-bit format. The @@ -842,7 +843,7 @@ public abstract class ImageDataReader { final int nBytes = bytesPerSample * scanSize * height; final int length = bytes.length < nBytes ? nBytes / scanSize : height; - final int[] samples = new int[scanSize * height]; + final int[] samples = new int[AllocationChecker.check(scanSize * height)]; // At this time, Commons Imaging only supports two-byte // two's complement short integers. It is assumed that // the calling module already checked the arguments for diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeAscii.java b/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeAscii.java index 6ff55d0b..1dde1f10 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeAscii.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeAscii.java @@ -21,6 +21,7 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; import org.apache.commons.imaging.ImageWriteException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.formats.tiff.TiffField; public class FieldTypeAscii extends FieldType { @@ -39,7 +40,7 @@ public class FieldTypeAscii extends FieldType { nullCount++; } } - final String[] strings = new String[nullCount]; + final String[] strings = new String[AllocationChecker.check(nullCount)]; int stringsAdded = 0; strings[0] = ""; // if we have a 0 length string int nextStringPos = 0; @@ -89,7 +90,7 @@ public class FieldTypeAscii extends FieldType { final byte[] bytes = string.getBytes(StandardCharsets.UTF_8); totalLength += (bytes.length + 1); } - final byte[] result = new byte[totalLength]; + final byte[] result = new byte[AllocationChecker.check(totalLength)]; int position = 0; for (final String string : strings) { final byte[] bytes = string.getBytes(StandardCharsets.UTF_8); diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeByte.java b/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeByte.java index e5c913a9..88e7e76f 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeByte.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeByte.java @@ -38,7 +38,7 @@ public class FieldTypeByte extends FieldType { @Override public byte[] writeData(final Object o, final ByteOrder byteOrder) throws ImageWriteException { if (o instanceof Byte) { - return new byte[] { ((Byte) o).byteValue(), }; + return new byte[] { ((Byte) o).byteValue() }; } if (o instanceof byte[]) { return (byte[]) o; diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeDouble.java b/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeDouble.java index 61eac42d..e6b3de18 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeDouble.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeDouble.java @@ -20,6 +20,7 @@ import java.nio.ByteOrder; import java.util.Arrays; import org.apache.commons.imaging.ImageWriteException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.ByteConversions; import org.apache.commons.imaging.formats.tiff.TiffField; @@ -48,7 +49,7 @@ public class FieldTypeDouble extends FieldType { if (!(o instanceof Double[])) { throw new ImageWriteException("Invalid data", o); } - final double[] values = new double[((Double[]) o).length]; + final double[] values = new double[AllocationChecker.check(((Double[]) o).length)]; Arrays.setAll(values, i -> ((Double[]) o)[i].doubleValue()); return ByteConversions.toBytes(values, byteOrder); } diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeFloat.java b/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeFloat.java index d90d4a34..f88e1707 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeFloat.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeFloat.java @@ -19,6 +19,7 @@ package org.apache.commons.imaging.formats.tiff.fieldtypes; import java.nio.ByteOrder; import org.apache.commons.imaging.ImageWriteException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.ByteConversions; import org.apache.commons.imaging.formats.tiff.TiffField; @@ -49,7 +50,7 @@ public class FieldTypeFloat extends FieldType { throw new ImageWriteException("Invalid data", o); } final Float[] numbers = (Float[]) o; - final float[] values = new float[numbers.length]; + final float[] values = new float[AllocationChecker.check(numbers.length)]; for (int i = 0; i < values.length; i++) { values[i] = numbers[i].floatValue(); } diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeLong.java b/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeLong.java index 7b0d82f4..90bab592 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeLong.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeLong.java @@ -19,6 +19,7 @@ package org.apache.commons.imaging.formats.tiff.fieldtypes; import java.nio.ByteOrder; import org.apache.commons.imaging.ImageWriteException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.ByteConversions; import org.apache.commons.imaging.formats.tiff.TiffField; @@ -50,7 +51,7 @@ public class FieldTypeLong extends FieldType { throw new ImageWriteException("Invalid data", o); } final Integer[] numbers = (Integer[]) o; - final int[] values = new int[numbers.length]; + final int[] values = new int[AllocationChecker.check(numbers.length)]; for (int i = 0; i < values.length; i++) { values[i] = numbers[i]; } diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeRational.java b/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeRational.java index ab603994..7f3abad4 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeRational.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeRational.java @@ -20,6 +20,7 @@ import java.nio.ByteOrder; import java.util.Arrays; import org.apache.commons.imaging.ImageWriteException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.ByteConversions; import org.apache.commons.imaging.common.RationalNumber; import org.apache.commons.imaging.formats.tiff.TiffField; @@ -56,7 +57,7 @@ public class FieldTypeRational extends FieldType { } if (o instanceof Number[]) { final Number[] numbers = (Number[]) o; - final RationalNumber[] rationalNumbers = new RationalNumber[numbers.length]; + final RationalNumber[] rationalNumbers = new RationalNumber[AllocationChecker.check(numbers.length)]; Arrays.setAll(rationalNumbers, RationalNumber::valueOf); return ByteConversions.toBytes(rationalNumbers, byteOrder); } @@ -64,7 +65,7 @@ public class FieldTypeRational extends FieldType { throw new ImageWriteException("Invalid data", o); } final double[] numbers = (double[]) o; - final RationalNumber[] rationalNumbers = new RationalNumber[numbers.length]; + final RationalNumber[] rationalNumbers = new RationalNumber[AllocationChecker.check(numbers.length)]; Arrays.setAll(rationalNumbers, RationalNumber::valueOf); return ByteConversions.toBytes(rationalNumbers, byteOrder); } diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeShort.java b/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeShort.java index d1e7c79a..4fee9326 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeShort.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/fieldtypes/FieldTypeShort.java @@ -19,6 +19,7 @@ package org.apache.commons.imaging.formats.tiff.fieldtypes; import java.nio.ByteOrder; import org.apache.commons.imaging.ImageWriteException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.ByteConversions; import org.apache.commons.imaging.formats.tiff.TiffField; @@ -49,7 +50,7 @@ public class FieldTypeShort extends FieldType { throw new ImageWriteException("Invalid data", o); } final Short[] numbers = (Short[]) o; - final short[] values = new short[numbers.length]; + final short[] values = new short[AllocationChecker.check(numbers.length)]; for (int i = 0; i < values.length; i++) { values[i] = numbers[i].shortValue(); } diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/photometricinterpreters/PhotometricInterpreterPalette.java b/src/main/java/org/apache/commons/imaging/formats/tiff/photometricinterpreters/PhotometricInterpreterPalette.java index 60fe73cb..1a7940b0 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/photometricinterpreters/PhotometricInterpreterPalette.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/photometricinterpreters/PhotometricInterpreterPalette.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.util.Arrays; import org.apache.commons.imaging.ImageReadException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.ImageBuilder; public class PhotometricInterpreterPalette extends PhotometricInterpreter { @@ -38,7 +39,7 @@ public class PhotometricInterpreterPalette extends PhotometricInterpreter { final int bitsPerPixel = getBitsPerSample(0); final int colormapScale = (1 << bitsPerPixel); - indexColorMap = new int[colormapScale]; + indexColorMap = new int[AllocationChecker.check(colormapScale)]; Arrays.setAll(indexColorMap, i -> { final int red = (colorMap[i] >> 8) & 0xff; final int green = (colorMap[i + (colormapScale)] >> 8) & 0xff; diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/taginfos/TagInfoAscii.java b/src/main/java/org/apache/commons/imaging/formats/tiff/taginfos/TagInfoAscii.java index 538a3efe..57b823e4 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/taginfos/TagInfoAscii.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/taginfos/TagInfoAscii.java @@ -20,6 +20,7 @@ import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import org.apache.commons.imaging.ImageWriteException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.formats.tiff.constants.TiffDirectoryType; import org.apache.commons.imaging.formats.tiff.fieldtypes.FieldType; @@ -41,7 +42,7 @@ public class TagInfoAscii extends TagInfo { nullCount++; } } - final String[] strings = new String[nullCount + 1]; + final String[] strings = new String[AllocationChecker.check(nullCount + 1)]; int stringsAdded = 0; strings[0] = ""; // if we have a 0 length string int nextStringPos = 0; diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/taginfos/TagInfoGpsText.java b/src/main/java/org/apache/commons/imaging/formats/tiff/taginfos/TagInfoGpsText.java index 30806424..df0041a2 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/taginfos/TagInfoGpsText.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/taginfos/TagInfoGpsText.java @@ -22,6 +22,7 @@ import java.nio.charset.StandardCharsets; import org.apache.commons.imaging.ImageReadException; import org.apache.commons.imaging.ImageWriteException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.BinaryFunctions; import org.apache.commons.imaging.formats.tiff.TiffField; import org.apache.commons.imaging.formats.tiff.constants.TiffDirectoryType; @@ -88,12 +89,9 @@ public final class TagInfoGpsText extends TagInfo { final String decodedAscii = new String(asciiBytes, TEXT_ENCODING_ASCII.encodingName); if (decodedAscii.equals(s)) { // no unicode/non-ascii values. - final byte[] result = new byte[asciiBytes.length - + TEXT_ENCODING_ASCII.prefix.length]; - System.arraycopy(TEXT_ENCODING_ASCII.prefix, 0, result, 0, - TEXT_ENCODING_ASCII.prefix.length); - System.arraycopy(asciiBytes, 0, result, - TEXT_ENCODING_ASCII.prefix.length, asciiBytes.length); + final byte[] result = new byte[AllocationChecker.check(asciiBytes.length + TEXT_ENCODING_ASCII.prefix.length)]; + System.arraycopy(TEXT_ENCODING_ASCII.prefix, 0, result, 0, TEXT_ENCODING_ASCII.prefix.length); + System.arraycopy(asciiBytes, 0, result, TEXT_ENCODING_ASCII.prefix.length, asciiBytes.length); return result; } // use Unicode @@ -104,7 +102,7 @@ public final class TagInfoGpsText extends TagInfo { encoding = TEXT_ENCODING_UNICODE_LE; } final byte[] unicodeBytes = s.getBytes(encoding.encodingName); - final byte[] result = new byte[unicodeBytes.length + encoding.prefix.length]; + final byte[] result = new byte[AllocationChecker.check(unicodeBytes.length + encoding.prefix.length)]; System.arraycopy(encoding.prefix, 0, result, 0, encoding.prefix.length); System.arraycopy(unicodeBytes, 0, result, encoding.prefix.length, unicodeBytes.length); return result; diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/write/ImageDataOffsets.java b/src/main/java/org/apache/commons/imaging/formats/tiff/write/ImageDataOffsets.java index efd26c4c..7c2a0adc 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/write/ImageDataOffsets.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/write/ImageDataOffsets.java @@ -18,6 +18,7 @@ package org.apache.commons.imaging.formats.tiff.write; import java.util.Arrays; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.formats.tiff.TiffElement; class ImageDataOffsets { @@ -29,7 +30,7 @@ class ImageDataOffsets { this.imageDataOffsets = imageDataOffsets; this.imageDataOffsetsField = imageDataOffsetsField; - outputItems = new TiffOutputItem[imageData.length]; + outputItems = new TiffOutputItem[AllocationChecker.check(imageData.length)]; Arrays.setAll(outputItems, i -> new TiffOutputItem.Value("TIFF image data", imageData[i].getData())); } diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/write/TiffImageWriterBase.java b/src/main/java/org/apache/commons/imaging/formats/tiff/write/TiffImageWriterBase.java index 6a5da9a2..1b708337 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/write/TiffImageWriterBase.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/write/TiffImageWriterBase.java @@ -43,6 +43,7 @@ import java.util.Map; import org.apache.commons.imaging.ImageWriteException; import org.apache.commons.imaging.PixelDensity; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.BinaryOutputStream; import org.apache.commons.imaging.common.PackBits; import org.apache.commons.imaging.common.RationalNumber; @@ -90,24 +91,24 @@ public abstract class TiffImageWriterBase { * @param src a valid image * @return true if at least one non-opaque pixel is found. */ - private boolean checkForActualAlpha(final BufferedImage src){ + private boolean checkForActualAlpha(final BufferedImage src) { // to conserve memory, very large images may be read // in pieces. final int width = src.getWidth(); final int height = src.getHeight(); - int nRowsPerRead = MAX_PIXELS_FOR_RGB/width; - if(nRowsPerRead<1){ + int nRowsPerRead = MAX_PIXELS_FOR_RGB / width; + if (nRowsPerRead < 1) { nRowsPerRead = 1; } - final int nReads = (height+nRowsPerRead-1)/nRowsPerRead; - final int []argb = new int[nRowsPerRead*width]; - for(int iRead=0; iRead<nReads; iRead++){ - final int i0 = iRead*nRowsPerRead; - final int i1 = i0+nRowsPerRead>height? height: i0+nRowsPerRead; - src.getRGB(0, i0, width, i1-i0, argb, 0, width); - final int n = (i1-i0)*width; - for(int i=0; i<n; i++){ - if((argb[i]&0xff000000)!=0xff000000){ + final int nReads = (height + nRowsPerRead - 1) / nRowsPerRead; + final int[] argb = new int[AllocationChecker.check(nRowsPerRead * width)]; + for (int iRead = 0; iRead < nReads; iRead++) { + final int i0 = iRead * nRowsPerRead; + final int i1 = i0 + nRowsPerRead > height ? height : i0 + nRowsPerRead; + src.getRGB(0, i0, width, i1 - i0, argb, 0, width); + final int n = (i1 - i0) * width; + for (int i = 0; i < n; i++) { + if ((argb[i] & 0xff000000) != 0xff000000) { return true; } } @@ -143,7 +144,7 @@ public abstract class TiffImageWriterBase { byte[][] result; { // Write Strips - result = new byte[stripCount][]; + result = new byte[AllocationChecker.check(stripCount)][]; int remainingRows = height; @@ -155,7 +156,7 @@ public abstract class TiffImageWriterBase { final int bytesPerRow = (bitsInRow + 7) / 8; final int bytesInStrip = rowsInStrip * bytesPerRow; - final byte[] uncompressed = new byte[bytesInStrip]; + final byte[] uncompressed = new byte[AllocationChecker.check(bytesInStrip)]; int counter = 0; int y = i * rowsPerStrip; diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/write/TiffImageWriterLossless.java b/src/main/java/org/apache/commons/imaging/formats/tiff/write/TiffImageWriterLossless.java index 14a1c775..7c6f22e4 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/write/TiffImageWriterLossless.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/write/TiffImageWriterLossless.java @@ -32,6 +32,7 @@ import java.util.Map; import org.apache.commons.imaging.FormatCompliance; import org.apache.commons.imaging.ImageReadException; import org.apache.commons.imaging.ImageWriteException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.BinaryOutputStream; import org.apache.commons.imaging.common.bytesource.ByteSource; import org.apache.commons.imaging.common.bytesource.ByteSourceArray; @@ -289,7 +290,7 @@ public class TiffImageWriterLossless extends TiffImageWriterBase { final long outputLength) throws IOException, ImageWriteException { final TiffOutputDirectory rootDirectory = outputSet.getRootDirectory(); - final byte[] output = new byte[(int) outputLength]; + final byte[] output = new byte[AllocationChecker.check(outputLength)]; // copy old data (including maker notes, etc.) System.arraycopy(exifBytes, 0, output, 0, Math.min(exifBytes.length, output.length)); diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/write/TiffOutputDirectory.java b/src/main/java/org/apache/commons/imaging/formats/tiff/write/TiffOutputDirectory.java index 581584cc..40d51008 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/write/TiffOutputDirectory.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/write/TiffOutputDirectory.java @@ -30,6 +30,7 @@ import java.util.Comparator; import java.util.List; import org.apache.commons.imaging.ImageWriteException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.BinaryOutputStream; import org.apache.commons.imaging.common.RationalNumber; import org.apache.commons.imaging.formats.tiff.JpegImageData; @@ -633,8 +634,8 @@ public final class TiffOutputDirectory extends TiffOutputItem { // TiffOutputField imageDataOffsetsField = null; - final int[] imageDataOffsets = new int[imageData.length]; - final int[] imageDataByteCounts = new int[imageData.length]; + final int[] imageDataOffsets = new int[AllocationChecker.check(imageData.length)]; + final int[] imageDataByteCounts = new int[AllocationChecker.check(imageData.length)]; Arrays.setAll(imageDataByteCounts, i -> imageData[i].length); // Append imageData-related fields to first directory diff --git a/src/main/java/org/apache/commons/imaging/formats/xbm/XbmImageParser.java b/src/main/java/org/apache/commons/imaging/formats/xbm/XbmImageParser.java index f90351ba..01d05a51 100644 --- a/src/main/java/org/apache/commons/imaging/formats/xbm/XbmImageParser.java +++ b/src/main/java/org/apache/commons/imaging/formats/xbm/XbmImageParser.java @@ -42,6 +42,7 @@ import org.apache.commons.imaging.ImageInfo; import org.apache.commons.imaging.ImageParser; import org.apache.commons.imaging.ImageReadException; import org.apache.commons.imaging.ImageWriteException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.BasicCParser; import org.apache.commons.imaging.common.ImageMetadata; import org.apache.commons.imaging.common.bytesource.ByteSource; @@ -296,7 +297,7 @@ public class XbmImageParser extends ImageParser<XbmImagingParameters> { } final int rowLength = (xbmHeader.width + 7) / 8; - final byte[] imageData = new byte[rowLength * xbmHeader.height]; + final byte[] imageData = new byte[AllocationChecker.check(rowLength * xbmHeader.height)]; int i = 0; for (int y = 0; y < xbmHeader.height; y++) { for (int x = 0; x < xbmHeader.width; x += inputWidth) { diff --git a/src/main/java/org/apache/commons/imaging/formats/xpm/XpmImageParser.java b/src/main/java/org/apache/commons/imaging/formats/xpm/XpmImageParser.java index bc98b6e6..299c70f8 100644 --- a/src/main/java/org/apache/commons/imaging/formats/xpm/XpmImageParser.java +++ b/src/main/java/org/apache/commons/imaging/formats/xpm/XpmImageParser.java @@ -45,6 +45,7 @@ import org.apache.commons.imaging.ImageInfo; import org.apache.commons.imaging.ImageParser; import org.apache.commons.imaging.ImageReadException; import org.apache.commons.imaging.ImageWriteException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.BasicCParser; import org.apache.commons.imaging.common.ImageMetadata; import org.apache.commons.imaging.common.bytesource.ByteSource; @@ -559,7 +560,7 @@ public class XpmImageParser extends ImageParser<XpmImagingParameters> { WritableRaster raster; int bpp; if (xpmHeader.palette.size() <= (1 << 8)) { - final int[] palette = new int[xpmHeader.palette.size()]; + final int[] palette = new int[AllocationChecker.check(xpmHeader.palette.size())]; for (final Entry<Object, PaletteEntry> entry : xpmHeader.palette.entrySet()) { final PaletteEntry paletteEntry = entry.getValue(); palette[paletteEntry.index] = paletteEntry.getBestARGB(); @@ -571,7 +572,7 @@ public class XpmImageParser extends ImageParser<XpmImagingParameters> { null); bpp = 8; } else if (xpmHeader.palette.size() <= (1 << 16)) { - final int[] palette = new int[xpmHeader.palette.size()]; + final int[] palette = new int[AllocationChecker.check(xpmHeader.palette.size())]; for (final Entry<Object, PaletteEntry> entry : xpmHeader.palette.entrySet()) { final PaletteEntry paletteEntry = entry.getValue(); palette[paletteEntry.index] = paletteEntry.getBestARGB(); @@ -637,7 +638,7 @@ public class XpmImageParser extends ImageParser<XpmImagingParameters> { private String toColor(final int color) { final String hex = Integer.toHexString(color); if (hex.length() < 6) { - final char[] zeroes = new char[6 - hex.length()]; + final char[] zeroes = new char[AllocationChecker.check(6 - hex.length())]; Arrays.fill(zeroes, '0'); return "#" + new String(zeroes) + hex; } diff --git a/src/main/java/org/apache/commons/imaging/icc/IccProfileParser.java b/src/main/java/org/apache/commons/imaging/icc/IccProfileParser.java index a78bffc0..91401ac1 100644 --- a/src/main/java/org/apache/commons/imaging/icc/IccProfileParser.java +++ b/src/main/java/org/apache/commons/imaging/icc/IccProfileParser.java @@ -28,6 +28,7 @@ import java.nio.ByteOrder; import java.util.logging.Level; import java.util.logging.Logger; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.common.BinaryFileParser; import org.apache.commons.imaging.common.bytesource.ByteSource; import org.apache.commons.imaging.common.bytesource.ByteSourceArray; @@ -248,7 +249,7 @@ public class IccProfileParser extends BinaryFileParser { final int tagCount = read4Bytes("TagCount", is, "Not a Valid ICC Profile", getByteOrder()); // List tags = new ArrayList(); - final IccTag[] tags = new IccTag[tagCount]; + final IccTag[] tags = new IccTag[AllocationChecker.check(tagCount)]; for (int i = 0; i < tagCount; i++) { final int tagSignature = read4Bytes("TagSignature[" + i + "]", is, "Not a Valid ICC Profile", getByteOrder()); diff --git a/src/main/java/org/apache/commons/imaging/palette/MedianCutQuantizer.java b/src/main/java/org/apache/commons/imaging/palette/MedianCutQuantizer.java index 4f2fc2ec..2ad9539f 100644 --- a/src/main/java/org/apache/commons/imaging/palette/MedianCutQuantizer.java +++ b/src/main/java/org/apache/commons/imaging/palette/MedianCutQuantizer.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Map; import org.apache.commons.imaging.ImageWriteException; +import org.apache.commons.imaging.common.AllocationChecker; import org.apache.commons.imaging.internal.Debug; public class MedianCutQuantizer { @@ -56,7 +57,7 @@ public class MedianCutQuantizer { final int width = image.getWidth(); final int height = image.getHeight(); - final int[] row = new int[width]; + final int[] row = new int[AllocationChecker.check(width)]; for (int y = 0; y < height; y++) { image.getRGB(0, y, width, 1, row, 0, width); for (int x = 0; x < width; x++) { @@ -91,7 +92,7 @@ public class MedianCutQuantizer { if (discreteColors <= maxColors) { Debug.debug("lossless palette: " + discreteColors); - final int[] palette = new int[discreteColors]; + final int[] palette = new int[AllocationChecker.check(discreteColors)]; final List<ColorCount> colorCounts = new ArrayList<>( colorMap.values()); @@ -121,7 +122,7 @@ public class MedianCutQuantizer { final int paletteSize = colorGroups.size(); Debug.debug("palette size: " + paletteSize); - final int[] palette = new int[paletteSize]; + final int[] palette = new int[AllocationChecker.check(paletteSize)]; for (int i = 0; i < colorGroups.size(); i++) { final ColorGroup colorGroup = colorGroups.get(i); diff --git a/src/main/java/org/apache/commons/imaging/palette/PaletteFactory.java b/src/main/java/org/apache/commons/imaging/palette/PaletteFactory.java index 65844aae..74fa9a0f 100644 --- a/src/main/java/org/apache/commons/imaging/palette/PaletteFactory.java +++ b/src/main/java/org/apache/commons/imaging/palette/PaletteFactory.java @@ -28,6 +28,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.imaging.ImageWriteException; +import org.apache.commons.imaging.common.AllocationChecker; /** * Factory for creating palettes. @@ -336,7 +337,7 @@ public class PaletteFactory { public Palette makeExactRgbPaletteFancy(final BufferedImage src) { // map what rgb values have been used - final byte[] rgbmap = new byte[256 * 256 * 32]; + final byte[] rgbmap = new byte[AllocationChecker.check(256 * 256 * 32)]; final int width = src.getWidth(); final int height = src.getHeight(); @@ -361,7 +362,7 @@ public class PaletteFactory { LOGGER.finest("Used colors: " + count); } - final int[] colormap = new int[count]; + final int[] colormap = new int[AllocationChecker.check(count)]; int mapsize = 0; for (int i = 0; i < rgbmap.length; i++) { final int eight = 0xff & rgbmap[i]; @@ -407,7 +408,7 @@ public class PaletteFactory { } } - final int[] result = new int[rgbs.size()]; + final int[] result = new int[AllocationChecker.check(rgbs.size())]; int next = 0; for (final int rgb : rgbs) { result[next++] = rgb; @@ -447,7 +448,7 @@ public class PaletteFactory { final int tableScale = precision * COMPONENTS; final int tableSize = 1 << tableScale; - final int[] table = new int[tableSize]; + final int[] table = new int[AllocationChecker.check(tableSize)]; final int width = src.getWidth(); final int height = src.getHeight(); diff --git a/src/main/java/org/apache/commons/imaging/palette/QuantizedPalette.java b/src/main/java/org/apache/commons/imaging/palette/QuantizedPalette.java index fb80b285..bcab31a3 100644 --- a/src/main/java/org/apache/commons/imaging/palette/QuantizedPalette.java +++ b/src/main/java/org/apache/commons/imaging/palette/QuantizedPalette.java @@ -20,8 +20,10 @@ import java.util.Collections; import java.util.List; import org.apache.commons.imaging.ImageWriteException; +import org.apache.commons.imaging.common.AllocationChecker; public class QuantizedPalette implements Palette { + private final int precision; private final List<ColorSpaceSubset> subsets; private final ColorSpaceSubset[] straight; @@ -30,7 +32,7 @@ public class QuantizedPalette implements Palette { this.subsets = subsets == null ? Collections.emptyList() : Collections.unmodifiableList(subsets); this.precision = precision; - straight = new ColorSpaceSubset[1 << (precision * 3)]; + straight = new ColorSpaceSubset[AllocationChecker.check(1 << (precision * 3))]; for (int i = 0; i < this.subsets.size(); i++) { final ColorSpaceSubset subset = subsets.get(i);