ImageReaderBaseTest.java
/*
* Copyright (c) 2012, Harald Kuhr
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.twelvemonkeys.imageio;
import static java.util.Collections.singleton;
import static org.junit.jupiter.api.Assertions.*;
import java.awt.*;
import java.awt.color.ColorSpace;
import java.awt.image.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.imageio.IIOException;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageTypeSpecifier;
import com.twelvemonkeys.imageio.color.ColorSpaces;
import com.twelvemonkeys.imageio.util.ImageTypeSpecifiers;
import org.junit.jupiter.api.Test;
/**
* ImageReaderBaseTest
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: haraldk$
* @version $Id: ImageReaderBaseTest.java,v 1.0 23.05.12 09:50 haraldk Exp$
*/
class ImageReaderBaseTest {
private static final List<ImageTypeSpecifier> TYPES = Arrays.asList(
ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB),
ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_ARGB)
);
@Test
void testGetDestinationZeroWidth() {
assertThrows(IllegalArgumentException.class, () -> ImageReaderBase.getDestination(null, TYPES.iterator(), 0, 42));
}
@Test
void testGetDestinationNegativeWidth() {
assertThrows(IllegalArgumentException.class, () -> ImageReaderBase.getDestination(null, TYPES.iterator(), -1, 42));
}
@Test
void testGetDestinationZeroHeight() {
assertThrows(IllegalArgumentException.class, () -> ImageReaderBase.getDestination(null, TYPES.iterator(), 42, 0));
}
@Test
void testGetDestinationNegativeHeight() {
assertThrows(IllegalArgumentException.class, () -> ImageReaderBase.getDestination(null, TYPES.iterator(), 42, -1));
}
@Test
void testGetDestinationNullTypes() {
assertThrows(IllegalArgumentException.class, () -> ImageReaderBase.getDestination(null, null, 42, 42));
}
@Test
void testGetDestinationNoTypes() {
assertThrows(IllegalArgumentException.class, () -> ImageReaderBase.getDestination(null, Collections.emptyIterator(), 42, 42));
}
@Test
void testGetDestinationParamSourceRegionWider() throws IIOException {
ImageReadParam param = new ImageReadParam();
param.setSourceRegion(new Rectangle(42, 1));
BufferedImage destination = ImageReaderBase.getDestination(param, TYPES.iterator(), 3, 3);
assertEquals(3, destination.getWidth());
assertEquals(1, destination.getHeight());
assertEquals(TYPES.get(0).getBufferedImageType(), destination.getType());
}
@Test
void testGetDestinationParamSourceRegionTaller() throws IIOException {
ImageReadParam param = new ImageReadParam();
param.setSourceRegion(new Rectangle(1, 42));
BufferedImage destination = ImageReaderBase.getDestination(param, TYPES.iterator(), 3, 3);
assertEquals(1, destination.getWidth());
assertEquals(3, destination.getHeight());
assertEquals(TYPES.get(0).getBufferedImageType(), destination.getType());
}
@Test
void testGetDestinationParamDestinationWider() throws IIOException {
ImageReadParam param = new ImageReadParam();
param.setDestination(new BufferedImage(42, 1, BufferedImage.TYPE_INT_RGB));
BufferedImage destination = ImageReaderBase.getDestination(param, TYPES.iterator(), 3, 3);
assertEquals(42, destination.getWidth());
assertEquals(1, destination.getHeight());
assertEquals(BufferedImage.TYPE_INT_RGB, destination.getType());
}
@Test
void testGetDestinationParamDestinationTaller() throws IIOException {
ImageReadParam param = new ImageReadParam();
param.setDestination(new BufferedImage(1, 42, BufferedImage.TYPE_INT_ARGB));
BufferedImage destination = ImageReaderBase.getDestination(param, TYPES.iterator(), 3, 3);
assertEquals(1, destination.getWidth());
assertEquals(42, destination.getHeight());
assertEquals(BufferedImage.TYPE_INT_ARGB, destination.getType());
}
@Test
void testGetDestinationNoParam() throws IIOException {
BufferedImage destination = ImageReaderBase.getDestination(null, TYPES.iterator(), 42, 1);
assertEquals(BufferedImage.TYPE_INT_RGB, destination.getType());
assertEquals(42, destination.getWidth());
assertEquals(1, destination.getHeight());
}
@Test
void testGetDestinationParamNoDestination() throws IIOException {
BufferedImage destination = ImageReaderBase.getDestination(new ImageReadParam(), TYPES.iterator(), 42, 1);
assertEquals(BufferedImage.TYPE_INT_RGB, destination.getType());
assertEquals(42, destination.getWidth());
assertEquals(1, destination.getHeight());
}
@Test
void testGetDestinationParamGoodDestination() throws IIOException {
ImageReadParam param = new ImageReadParam();
param.setDestination(new BufferedImage(21, 1, BufferedImage.TYPE_INT_ARGB));
BufferedImage destination = ImageReaderBase.getDestination(param, TYPES.iterator(), 42, 1);
assertEquals(BufferedImage.TYPE_INT_ARGB, destination.getType());
assertEquals(21, destination.getWidth());
assertEquals(1, destination.getHeight());
}
@Test
void testGetDestinationParamIllegalDestination() {
ImageReadParam param = new ImageReadParam();
param.setDestination(new BufferedImage(21, 1, BufferedImage.TYPE_USHORT_565_RGB));
assertThrows(IIOException.class, () -> ImageReaderBase.getDestination(param, TYPES.iterator(), 42, 1));
}
@Test
void testGetDestinationParamGoodDestinationType() throws IIOException {
ImageReadParam param = new ImageReadParam();
param.setDestinationType(ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_ARGB));
BufferedImage destination = ImageReaderBase.getDestination(param, TYPES.iterator(), 6, 7);
assertEquals(BufferedImage.TYPE_INT_ARGB, destination.getType());
assertEquals(6, destination.getWidth());
assertEquals(7, destination.getHeight());
}
@Test
void testGetDestinationParamGoodDestinationTypeAlt() throws IIOException {
ImageReadParam param = new ImageReadParam();
// In essence, this is the same as TYPE_INT_ARGB
ImageTypeSpecifier type = ImageTypeSpecifier.createPacked(ColorSpace.getInstance(ColorSpace.CS_sRGB), 0xff0000, 0xff00, 0xff, 0xff000000, DataBuffer.TYPE_INT, false);
param.setDestinationType(type);
BufferedImage destination = ImageReaderBase.getDestination(param, TYPES.iterator(), 6, 7);
assertEquals(BufferedImage.TYPE_INT_ARGB, destination.getType());
assertEquals(6, destination.getWidth());
assertEquals(7, destination.getHeight());
}
@Test
void testGetDestinationParamIllegalDestinationType() {
ImageReadParam param = new ImageReadParam();
param.setDestinationType(ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_BYTE_GRAY));
assertThrows(IIOException.class, () -> ImageReaderBase.getDestination(param, TYPES.iterator(), 6, 7));
}
@Test
void testGetDestinationParamIllegalDestinationTypeAlt() {
ImageReadParam param = new ImageReadParam();
param.setDestinationType(ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_BGR));
assertThrows(IIOException.class, () -> ImageReaderBase.getDestination(param, TYPES.iterator(), 6, 7));
}
@Test
void testGetDestinationSourceExceedsIntegerMax() throws IIOException {
ImageReadParam param = new ImageReadParam();
param.setSourceRegion(new Rectangle(42, 7));
BufferedImage destination = ImageReaderBase.getDestination(param, TYPES.iterator(), Integer.MAX_VALUE, 42);// 90 194 313 174 pixels
assertEquals(42, destination.getWidth());
assertEquals(7, destination.getHeight());
assertEquals(TYPES.get(0).getBufferedImageType(), destination.getType());
}
@Test
void testGetDestinationParamDestinationExceedsIntegerMax() {
ImageReadParam param = new ImageReadParam();
param.setSourceRegion(new Rectangle(3 * Short.MAX_VALUE, 2 * Short.MAX_VALUE)); // 6 442 057 734 pixels
assertThrows(IIOException.class, () -> ImageReaderBase.getDestination(param, TYPES.iterator(), 6 * Short.MAX_VALUE, 4 * Short.MAX_VALUE)); // 25 768 230 936 pixels
}
@Test
void testGetDestinationDimensionExceedsIntegerMax() {
assertThrows(IIOException.class, () -> ImageReaderBase.getDestination(null, TYPES.iterator(), 3 * Short.MAX_VALUE, 2 * Short.MAX_VALUE)); // 6 442 057 734 pixels
}
@Test
void testGetDestinationStorageExceedsIntegerMax() {
Set<ImageTypeSpecifier> byteTypes = singleton(ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_3BYTE_BGR));
assertThrows(IIOException.class, () -> ImageReaderBase.getDestination(null, byteTypes.iterator(), Short.MAX_VALUE, Short.MAX_VALUE)); // 1 073 676 289 pixels
// => 3 221 028 867 bytes needed in continuous array, not possible
}
@Test
void testHasExplicitDestinationNull() {
assertFalse(ImageReaderBase.hasExplicitDestination(null));
}
@Test
void testHasExplicitDestinationDefaultParam() {
assertFalse(ImageReaderBase.hasExplicitDestination(new ImageReadParam()));
}
@Test
void testHasExplicitDestinationParamWithDestination() {
ImageReadParam param = new ImageReadParam();
param.setDestination(new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_GRAY));
assertTrue(ImageReaderBase.hasExplicitDestination(param));
}
@Test
void testHasExplicitDestinationParamWithDestinationType() {
ImageReadParam param = new ImageReadParam();
param.setDestinationType(ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_ARGB));
assertTrue(ImageReaderBase.hasExplicitDestination(param));
}
@Test
void testHasExplicitDestinationParamWithDestinationOffset() {
ImageReadParam param = new ImageReadParam();
param.setDestinationOffset(new Point(42, 42));
assertTrue(ImageReaderBase.hasExplicitDestination(param));
}
@Test
void testHasExplicitDestinationParamWithDestinationOffsetUnspecified() {
ImageReadParam param = new ImageReadParam();
// getDestinationOffset should now return new Point(0, 0)
assertFalse(ImageReaderBase.hasExplicitDestination(param));
}
@Test
void testHasExplicitDestinationParamWithDestinationOffsetOrigin() {
ImageReadParam param = new ImageReadParam();
param.setDestinationOffset(new Point(0, 0));
assertFalse(ImageReaderBase.hasExplicitDestination(param));
}
// Destination allocation size guard (GHSA-7c3w-m9qh-j2vj). TYPES is INT_RGB/INT_ARGB, i.e. 4 bytes/pixel.
@Test
void testValidateSourceSizeWithinExpansionRatioIsAllowed() {
// 100 x 100 x 4 = 40000 bytes; with 40000 bytes of input the limit is 40000 * 16, so it must not be rejected.
assertDoesNotThrow(() -> ImageReaderBase.validateSourceSize(TYPES.iterator().next(), 100, 100, 40000L, 16));
}
@Test
void testValidateSourceSizeExceedingExpansionRatioIsRejected() {
// A 100-byte input must not be able to force a ~1.6 GB raster (20000 x 20000 x 4).
IIOException exception = assertThrows(IIOException.class,
() -> ImageReaderBase.validateSourceSize(TYPES.iterator().next(), 20000, 20000, 100L, 16));
assertTrue(exception.getMessage().contains("exceeding"), exception.getMessage());
}
@Test
void testValidateSourceSizeUnknownLengthRejectedByMaxImageBytes() {
// Unknown length (-1) uses the injected ceiling; 4 MB declared against a 1 MB ceiling must be rejected.
IIOException exception = assertThrows(IIOException.class,
() -> ImageReaderBase.validateSourceSize(4L * 1024 * 1024, -1L, 16, 1024 * 1024));
assertTrue(exception.getMessage().contains("unknown length"), exception.getMessage());
}
@Test
void testValidateSourceSizeUnknownLengthWithinMaxImageBytesIsAllowed() {
// 4 MB declared against a 64 MB ceiling must be allowed (no exception).
assertDoesNotThrow(() -> ImageReaderBase.validateSourceSize(4L * 1024 * 1024, -1L, 16, 64L * 1024 * 1024));
}
@Test
void testDefaultMaxImageBytesIsCappedAndFloored() {
// No property set: default is half the heap, capped at 512 MB, floored at 64 MB.
long cap = 512L * 1024 * 1024;
long floor = 64L * 1024 * 1024;
long maxHeap = Runtime.getRuntime().maxMemory();
if (maxHeap < floor) {
assertEquals(floor, ImageReaderBase.defaultMaxImageBytes());
}
else if (maxHeap > cap) {
assertEquals(cap, ImageReaderBase.defaultMaxImageBytes());
}
else {
assertEquals(maxHeap / 2, ImageReaderBase.defaultMaxImageBytes());
}
}
@Test
void testComputeSizeBinary() {
ImageTypeSpecifier binarySpec = ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_BYTE_BINARY);
assertEquals(((DataBufferByte) binarySpec.getSampleModel(8, 10).createDataBuffer()).getData().length, ImageReaderBase.computeByteSize(binarySpec, 8, 10));
assertEquals(((DataBufferByte) binarySpec.getSampleModel(10, 10).createDataBuffer()).getData().length, ImageReaderBase.computeByteSize(binarySpec, 10, 10));
assertEquals(10, ImageReaderBase.computeByteSize(binarySpec, 8, 10)); // 8 bits / 1 byte per row
assertEquals(20, ImageReaderBase.computeByteSize(binarySpec, 10, 10)); // 10 bits / 2 bytes per row
// Special case, SampleModel overflow
assertEquals(10L * ((Integer.MAX_VALUE + 7L) / 8), ImageReaderBase.computeByteSize(binarySpec, Integer.MAX_VALUE, 10));
assertEquals(2L * Integer.MAX_VALUE, ImageReaderBase.computeByteSize(binarySpec, 9, Integer.MAX_VALUE));
}
@Test
void testComputeSizeIndexed() {
// indexed2 is basically same as binary
ImageTypeSpecifier indexed2Spec = ImageTypeSpecifiers.createIndexed(new int[2], false, -1, 1, DataBuffer.TYPE_BYTE);
assertEquals(10, ImageReaderBase.computeByteSize(indexed2Spec, 8, 10));
assertEquals(20, ImageReaderBase.computeByteSize(indexed2Spec, 10, 10));
ImageTypeSpecifier indexed4Spec = ImageTypeSpecifiers.createIndexed(new int[4], false, -1, 2, DataBuffer.TYPE_BYTE);
assertEquals(10, ImageReaderBase.computeByteSize(indexed4Spec, 4, 10));
assertEquals(30, ImageReaderBase.computeByteSize(indexed4Spec, 10, 10));
// 3 bits/pixel could be packed but it's impractical, so reverts to 1 byte/sample
ImageTypeSpecifier indexed8Spec = ImageTypeSpecifiers.createIndexed(new int[8], false, -1, 3, DataBuffer.TYPE_BYTE);
assertEquals(((DataBufferByte) indexed8Spec.getSampleModel(10, 10).createDataBuffer()).getData().length, ImageReaderBase.computeByteSize(indexed8Spec, 10, 10));
assertEquals(100, ImageReaderBase.computeByteSize(indexed8Spec, 10, 10));
ImageTypeSpecifier indexed16Spec = ImageTypeSpecifiers.createIndexed(new int[16], false, -1, 4, DataBuffer.TYPE_BYTE);
assertEquals(10, ImageReaderBase.computeByteSize(indexed16Spec, 2, 10));
assertEquals(50, ImageReaderBase.computeByteSize(indexed16Spec, 10, 10));
// Anything above 4 bits is impractical to pack, so we have 1 byte/sample
ImageTypeSpecifier indexed32Spec = ImageTypeSpecifiers.createIndexed(new int[32], false, -1, 5, DataBuffer.TYPE_BYTE);
assertEquals(100, ImageReaderBase.computeByteSize(indexed32Spec, 10, 10));
ImageTypeSpecifier indexed64Spec = ImageTypeSpecifiers.createIndexed(new int[64], false, -1, 6, DataBuffer.TYPE_BYTE);
assertEquals(100, ImageReaderBase.computeByteSize(indexed64Spec, 10, 10));
ImageTypeSpecifier indexed128Spec = ImageTypeSpecifiers.createIndexed(new int[128], false, -1, 7, DataBuffer.TYPE_BYTE);
assertEquals(100, ImageReaderBase.computeByteSize(indexed128Spec, 10, 10));
ImageTypeSpecifier indexed256Spec = ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_BYTE_INDEXED);
assertEquals(100, ImageReaderBase.computeByteSize(indexed256Spec, 10, 10));
// Trying to pack two 8 bit samples into a 16 bit sample won't work...
// IndexColorModel 8 bits/TYPE_USHORT will create a sample model with TYPE_USHORT but a raster with TYPE_BYTE,
// which is incompatible.
//ImageTypeSpecifier indexed256UshortSpec = ImageTypeSpecifiers.createIndexed(new int[256], false, -1, 8, DataBuffer.TYPE_USHORT);
//assertEquals(100, ImageReaderBase.computeByteSize(indexed256UshortSpec, 10, 10)); // Will fail, actual 200
// Custom setup that creates the model we intended to create above...
int[] colors = new int[256];
IndexColorModel indexColorModel = new IndexColorModel(8, colors.length, colors, 0, false, -1, DataBuffer.TYPE_BYTE);
SampleModel sampleModel = new MultiPixelPackedSampleModel(DataBuffer.TYPE_USHORT, 1, 1, 8);
ImageTypeSpecifier indexed256UshortCustomSpec = new ImageTypeSpecifier(indexColorModel, sampleModel);
assertEquals(100, ImageReaderBase.computeByteSize(indexed256UshortCustomSpec, 10, 10));
// Extra verification that it actually would work
BufferedImage bufferedImage = indexed256UshortCustomSpec.createBufferedImage(10, 10);
assertEquals(2L * ((DataBufferUShort) bufferedImage.getRaster().getDataBuffer()).getData().length, ImageReaderBase.computeByteSize(indexed256UshortCustomSpec, 10, 10));
// Not sure why creating a 10 bit IndexColorModel with TYPE_BYTE is allowed?
//ImageTypeSpecifier indexed1024BadByteSpec = ImageTypeSpecifiers.createIndexed(new int[1024], false, -1, 10, DataBuffer.TYPE_BYTE);
//assertEquals(2 * 100, ImageReaderBase.computeByteSize(indexed1024BadByteSpec, 10, 10)); // Will fail, actual 100
ImageTypeSpecifier indexed1024Spec = ImageTypeSpecifiers.createIndexed(new int[1024], false, -1, 10, DataBuffer.TYPE_USHORT);
assertEquals(2 * 100, ImageReaderBase.computeByteSize(indexed1024Spec, 10, 10));
// Special case, SampleModel overflow
assertEquals(10L * ((Integer.MAX_VALUE + 7L) / 8), ImageReaderBase.computeByteSize(indexed2Spec, Integer.MAX_VALUE, 10));
assertEquals(2L * Integer.MAX_VALUE, ImageReaderBase.computeByteSize(indexed2Spec, 10, Integer.MAX_VALUE));
assertEquals(10L * ((Integer.MAX_VALUE + 3L) / 4), ImageReaderBase.computeByteSize(indexed4Spec, Integer.MAX_VALUE, 10));
assertEquals(3L * Integer.MAX_VALUE, ImageReaderBase.computeByteSize(indexed4Spec, 10, Integer.MAX_VALUE));
assertEquals(10L * ((Integer.MAX_VALUE + 1L) / 2), ImageReaderBase.computeByteSize(indexed16Spec, Integer.MAX_VALUE, 10));
assertEquals(5L * Integer.MAX_VALUE, ImageReaderBase.computeByteSize(indexed16Spec, 10, Integer.MAX_VALUE));
assertEquals(10L * Integer.MAX_VALUE, ImageReaderBase.computeByteSize(indexed256Spec, 10, Integer.MAX_VALUE));
}
@Test
void testComputeSizeGray() {
ColorSpace gray = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ImageTypeSpecifier byteGraySpec = ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_BYTE_GRAY);
assertEquals(100, ImageReaderBase.computeByteSize(byteGraySpec, 10, 10));
ImageTypeSpecifier byteGrayASpec = ImageTypeSpecifiers.createInterleaved(gray, new int[]{0, 1}, DataBuffer.TYPE_BYTE, true, false);
assertEquals(((DataBufferByte) byteGrayASpec.getSampleModel(10, 10).createDataBuffer()).getData().length, ImageReaderBase.computeByteSize(byteGrayASpec, 10, 10));
assertEquals(2 * 100, ImageReaderBase.computeByteSize(byteGrayASpec, 10, 10));
ImageTypeSpecifier ushortGraySpec = ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_USHORT_GRAY);
assertEquals(((DataBufferUShort) ushortGraySpec.getSampleModel(10, 10).createDataBuffer()).getData().length * 2L, ImageReaderBase.computeByteSize(ushortGraySpec, 10, 10));
assertEquals(2 * 100, ImageReaderBase.computeByteSize(ushortGraySpec, 10, 10));
ImageTypeSpecifier ushortGrayASpec = ImageTypeSpecifiers.createInterleaved(gray, new int[]{0, 1}, DataBuffer.TYPE_USHORT, true, false);
assertEquals(2 * 2 * 100, ImageReaderBase.computeByteSize(ushortGrayASpec, 10, 10));
ImageTypeSpecifier intGraySpec = ImageTypeSpecifiers.createInterleaved(gray, new int[]{0}, DataBuffer.TYPE_INT, false, false);
assertEquals(4 * 100, ImageReaderBase.computeByteSize(intGraySpec, 10, 10));
ImageTypeSpecifier intGrayASpec = ImageTypeSpecifiers.createInterleaved(gray, new int[]{0, 1}, DataBuffer.TYPE_INT, true, false);
assertEquals(4 * 2 * 100, ImageReaderBase.computeByteSize(intGrayASpec, 10, 10));
ImageTypeSpecifier packedGray1 = ImageTypeSpecifiers.createPackedGrayscale(gray, 1, DataBuffer.TYPE_BYTE);
assertEquals(20, ImageReaderBase.computeByteSize(packedGray1, 10, 10)); // 10 bits / 2 bytes per row
ImageTypeSpecifier packedGray2 = ImageTypeSpecifiers.createPackedGrayscale(gray, 2, DataBuffer.TYPE_BYTE);
assertEquals(30, ImageReaderBase.computeByteSize(packedGray2, 10, 10)); // 20 bits / 3 bytes per row
ImageTypeSpecifier packedGray4 = ImageTypeSpecifiers.createPackedGrayscale(gray, 4, DataBuffer.TYPE_BYTE);
assertEquals(50, ImageReaderBase.computeByteSize(packedGray4, 10, 10)); // 40 bits / 5 bytes per row
// Special case, SampleModel overflow
assertEquals(2L * 10L * Integer.MAX_VALUE, ImageReaderBase.computeByteSize(byteGrayASpec, Integer.MAX_VALUE, 10));
assertEquals(2L * 10L * Integer.MAX_VALUE, ImageReaderBase.computeByteSize(ushortGraySpec, 10, Integer.MAX_VALUE));
}
@Test
void testComputeSizeRGB() {
ColorSpace sRGB = ColorSpace.getInstance(ColorSpace.CS_sRGB);
ImageTypeSpecifier ushortRGBPacked555Spec = ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_USHORT_555_RGB);
assertEquals(((DataBufferUShort) ushortRGBPacked555Spec.getSampleModel(10, 10).createDataBuffer()).getData().length * 2L, ImageReaderBase.computeByteSize(ushortRGBPacked555Spec, 10, 10));
assertEquals(2 * 100, ImageReaderBase.computeByteSize(ushortRGBPacked555Spec, 10, 10));
ImageTypeSpecifier ushortRGBPacked565Spec = ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_USHORT_565_RGB);
assertEquals(2 * 100, ImageReaderBase.computeByteSize(ushortRGBPacked565Spec, 10, 10));
ImageTypeSpecifier ushortARGBPacked4444Spec = ImageTypeSpecifiers.createPacked(sRGB, 0xF00, 0xF0, 0xF, 0xF000, DataBuffer.TYPE_USHORT, false);
assertEquals(2 * 100, ImageReaderBase.computeByteSize(ushortARGBPacked4444Spec, 10, 10));
ImageTypeSpecifier intRGBPackedSpec = ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
assertEquals(4 * 100, ImageReaderBase.computeByteSize(intRGBPackedSpec, 10, 10));
ImageTypeSpecifier intARGBPackedSpec = ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_INT_ARGB);
assertEquals(4 * 100, ImageReaderBase.computeByteSize(intARGBPackedSpec, 10, 10));
ImageTypeSpecifier intBGRPackedSpec = ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_INT_BGR);
assertEquals(4 * 100, ImageReaderBase.computeByteSize(intBGRPackedSpec, 10, 10));
ImageTypeSpecifier intARGBPrePackedSpec = ImageTypeSpecifiers.createFromBufferedImageType(BufferedImage.TYPE_INT_ARGB_PRE);
assertEquals(4 * 100, ImageReaderBase.computeByteSize(intARGBPrePackedSpec, 10, 10));
ImageTypeSpecifier byteRGBInterleavedSpec = ImageTypeSpecifiers.createInterleaved(sRGB, new int[] {0, 1, 2}, DataBuffer.TYPE_BYTE, false, false);
assertEquals(3 * 100, ImageReaderBase.computeByteSize(byteRGBInterleavedSpec, 10, 10));
ImageTypeSpecifier byteRGBAInterleavedSpec = ImageTypeSpecifiers.createInterleaved(sRGB, new int[] {0, 1, 2, 3}, DataBuffer.TYPE_BYTE, true, false);
assertEquals(4 * 100, ImageReaderBase.computeByteSize(byteRGBAInterleavedSpec, 10, 10));
ImageTypeSpecifier byteRGBBandedSpec = ImageTypeSpecifiers.createBanded(sRGB, new int[] {0, 1, 2}, new int[3], DataBuffer.TYPE_BYTE, false, false);
assertEquals(3 * 100, ImageReaderBase.computeByteSize(byteRGBBandedSpec, 10, 10));
ImageTypeSpecifier byteRGBABandedSpec = ImageTypeSpecifiers.createBanded(sRGB, new int[] {0, 1, 2, 3}, new int[4], DataBuffer.TYPE_BYTE, true, false);
assertEquals(4 * 100, ImageReaderBase.computeByteSize(byteRGBABandedSpec, 10, 10));
ImageTypeSpecifier ushortRGBInterleavedSpec = ImageTypeSpecifiers.createInterleaved(sRGB, new int[] {0, 1, 2}, DataBuffer.TYPE_USHORT, false, false);
assertEquals(3 * 2 * 100, ImageReaderBase.computeByteSize(ushortRGBInterleavedSpec, 10, 10));
ImageTypeSpecifier ushortRGBAInterleavedSpec = ImageTypeSpecifiers.createInterleaved(sRGB, new int[] {0, 1, 2, 3}, DataBuffer.TYPE_USHORT, true, false);
assertEquals(4 * 2 * 100, ImageReaderBase.computeByteSize(ushortRGBAInterleavedSpec, 10, 10));
ImageTypeSpecifier ushortRGBBandedSpec = ImageTypeSpecifiers.createBanded(sRGB, new int[] {0, 1, 2}, new int[3], DataBuffer.TYPE_USHORT, false, false);
assertEquals(3 * 2 * 100, ImageReaderBase.computeByteSize(ushortRGBBandedSpec, 10, 10));
ImageTypeSpecifier ushortRGBABandedSpec = ImageTypeSpecifiers.createBanded(sRGB, new int[] {0, 1, 2, 3}, new int[4], DataBuffer.TYPE_USHORT, true, false);
assertEquals(4 * 2 * 100, ImageReaderBase.computeByteSize(ushortRGBABandedSpec, 10, 10));
ImageTypeSpecifier intRGBInterleavedSpec = ImageTypeSpecifiers.createInterleaved(sRGB, new int[] {0, 1, 2}, DataBuffer.TYPE_INT, false, false);
assertEquals(3 * 4 * 100, ImageReaderBase.computeByteSize(intRGBInterleavedSpec, 10, 10));
ImageTypeSpecifier intRGBAInterleavedSpec = ImageTypeSpecifiers.createInterleaved(sRGB, new int[] {0, 1, 2, 4}, DataBuffer.TYPE_INT, true, false);
assertEquals(4 * 4 * 100, ImageReaderBase.computeByteSize(intRGBAInterleavedSpec, 10, 10));
ImageTypeSpecifier intRGBBandedSpec = ImageTypeSpecifiers.createBanded(sRGB, new int[] {0, 1, 2}, new int[3], DataBuffer.TYPE_INT, false, false);
assertEquals(3 * 4 * 100, ImageReaderBase.computeByteSize(intRGBBandedSpec, 10, 10));
ImageTypeSpecifier intRGBABandedSpec = ImageTypeSpecifiers.createBanded(sRGB, new int[] {0, 1, 2, 4}, new int[4], DataBuffer.TYPE_INT, true, false);
assertEquals(4 * 4 * 100, ImageReaderBase.computeByteSize(intRGBABandedSpec, 10, 10));
// Special case, SampleModel overflow
assertEquals(3L * 10L * Integer.MAX_VALUE, ImageReaderBase.computeByteSize(byteRGBInterleavedSpec, Integer.MAX_VALUE, 10));
assertEquals(4L * 10L * Integer.MAX_VALUE, ImageReaderBase.computeByteSize(byteRGBABandedSpec, 10, Integer.MAX_VALUE));
assertEquals(3L * 2L * 10L * Integer.MAX_VALUE, ImageReaderBase.computeByteSize(ushortRGBBandedSpec, Integer.MAX_VALUE, 10));
assertEquals(4L * 2L * 10L * Integer.MAX_VALUE, ImageReaderBase.computeByteSize(ushortRGBAInterleavedSpec, 10, Integer.MAX_VALUE));
assertEquals(3L * 4L * 10L * Integer.MAX_VALUE, ImageReaderBase.computeByteSize(intRGBInterleavedSpec, Integer.MAX_VALUE, 10));
assertEquals(4L * 4L * 10L * Integer.MAX_VALUE, ImageReaderBase.computeByteSize(intRGBABandedSpec, 10, Integer.MAX_VALUE));
assertEquals(2L * 10L * Integer.MAX_VALUE, ImageReaderBase.computeByteSize(ushortARGBPacked4444Spec, Integer.MAX_VALUE, 10));
assertEquals(4L * 10L * Integer.MAX_VALUE, ImageReaderBase.computeByteSize(intRGBPackedSpec, 10, Integer.MAX_VALUE));
assertEquals(4L * 10L * Integer.MAX_VALUE, ImageReaderBase.computeByteSize(intARGBPackedSpec, Integer.MAX_VALUE, 10));
}
@Test
void testComputeSizeCMYK() {
ColorSpace cmyk = ColorSpaces.getColorSpace(ColorSpaces.CS_GENERIC_CMYK);
ImageTypeSpecifier byteCMYKInterleavedSpec = ImageTypeSpecifiers.createInterleaved(cmyk, new int[] {0, 1, 2, 3}, DataBuffer.TYPE_BYTE, false, false);
assertEquals(4 * 100, ImageReaderBase.computeByteSize(byteCMYKInterleavedSpec, 10, 10));
ImageTypeSpecifier byteCMYKAInterleavedSpec = ImageTypeSpecifiers.createInterleaved(cmyk, new int[] {0, 1, 2, 3, 4}, DataBuffer.TYPE_BYTE, true, false);
assertEquals(5 * 100, ImageReaderBase.computeByteSize(byteCMYKAInterleavedSpec, 10, 10));
ImageTypeSpecifier byteCMYKBandedSpec = ImageTypeSpecifiers.createBanded(cmyk, new int[] {0, 1, 2, 3}, new int[4], DataBuffer.TYPE_BYTE, false, false);
assertEquals(4 * 100, ImageReaderBase.computeByteSize(byteCMYKBandedSpec, 10, 10));
ImageTypeSpecifier byteCMYKABandedSpec = ImageTypeSpecifiers.createBanded(cmyk, new int[] {0, 1, 2, 3, 4}, new int[5], DataBuffer.TYPE_BYTE, true, false);
assertEquals(5 * 100, ImageReaderBase.computeByteSize(byteCMYKABandedSpec, 10, 10));
ImageTypeSpecifier ushortCMYKInterleavedSpec = ImageTypeSpecifiers.createInterleaved(cmyk, new int[] {0, 1, 2, 3}, DataBuffer.TYPE_USHORT, false, false);
assertEquals(4 * 2 * 100, ImageReaderBase.computeByteSize(ushortCMYKInterleavedSpec, 10, 10));
ImageTypeSpecifier ushortCMYKAInterleavedSpec = ImageTypeSpecifiers.createInterleaved(cmyk, new int[] {0, 1, 2, 3, 5}, DataBuffer.TYPE_USHORT, true, false);
assertEquals(5 * 2 * 100, ImageReaderBase.computeByteSize(ushortCMYKAInterleavedSpec, 10, 10));
ImageTypeSpecifier ushortCMYKBandedSpec = ImageTypeSpecifiers.createBanded(cmyk, new int[] {0, 1, 2, 3}, new int[4], DataBuffer.TYPE_USHORT, false, false);
assertEquals(4 * 2 * 100, ImageReaderBase.computeByteSize(ushortCMYKBandedSpec, 10, 10));
ImageTypeSpecifier ushortCMYKABandedSpec = ImageTypeSpecifiers.createBanded(cmyk, new int[] {0, 1, 2, 3, 5}, new int[5], DataBuffer.TYPE_USHORT, true, false);
assertEquals(5 * 2 * 100, ImageReaderBase.computeByteSize(ushortCMYKABandedSpec, 10, 10));
ImageTypeSpecifier intCMYKInterleavedSpec = ImageTypeSpecifiers.createInterleaved(cmyk, new int[] {0, 1, 2, 3}, DataBuffer.TYPE_INT, false, false);
assertEquals(4 * 4 * 100, ImageReaderBase.computeByteSize(intCMYKInterleavedSpec, 10, 10));
ImageTypeSpecifier intCMYKAInterleavedSpec = ImageTypeSpecifiers.createInterleaved(cmyk, new int[] {0, 1, 2, 3, 4}, DataBuffer.TYPE_INT, true, false);
assertEquals(5 * 4 * 100, ImageReaderBase.computeByteSize(intCMYKAInterleavedSpec, 10, 10));
ImageTypeSpecifier intCMYKBandedSpec = ImageTypeSpecifiers.createBanded(cmyk, new int[] {0, 1, 2, 3}, new int[4], DataBuffer.TYPE_INT, false, false);
assertEquals(4 * 4 * 100, ImageReaderBase.computeByteSize(intCMYKBandedSpec, 10, 10));
ImageTypeSpecifier intCMYKABandedSpec = ImageTypeSpecifiers.createBanded(cmyk, new int[] {0, 1, 2, 3, 4}, new int[5], DataBuffer.TYPE_INT, true, false);
assertEquals(5 * 4 * 100, ImageReaderBase.computeByteSize(intCMYKABandedSpec, 10, 10));
// No need to test the overflow cases here, should be equivalent to the RGB specs
}
}