IMAGING-186: Add sCAL support to PNG reading and writing. Thanks to Ric Emery. This also closes #23 from GitHub.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/imaging/trunk@1754653 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 14f224a..4730adb 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -46,6 +46,9 @@
<body>
<release version="1.0" date="TBA" description="First major release">
+ <action issue="IMAGING-186" dev="britter" type="update" due-to="Ric Emery">
+ Add sCAL support to PNG reading and writing.
+ </action>
<action issue="IMAGING-176" dev="britter" type="fix" due-to="Gabriel Axel">
TiffImageParser.getImageInfo() throws exception when "Compression" field is missing.
</action>
diff --git a/src/main/java/org/apache/commons/imaging/formats/png/ChunkType.java b/src/main/java/org/apache/commons/imaging/formats/png/ChunkType.java
index 3231635..0035bb7 100644
--- a/src/main/java/org/apache/commons/imaging/formats/png/ChunkType.java
+++ b/src/main/java/org/apache/commons/imaging/formats/png/ChunkType.java
@@ -75,6 +75,9 @@
/** Physical pixel dimensions */
pHYs,
+ /** Physical scale */
+ sCAL,
+
/** Suggested palette */
sPLT,
diff --git a/src/main/java/org/apache/commons/imaging/formats/png/PhysicalScale.java b/src/main/java/org/apache/commons/imaging/formats/png/PhysicalScale.java
new file mode 100644
index 0000000..ca1d657
--- /dev/null
+++ b/src/main/java/org/apache/commons/imaging/formats/png/PhysicalScale.java
@@ -0,0 +1,61 @@
+/*
+ * 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.formats.png;
+
+/**
+ * Used to specify physical scale when reading or storing image information.
+ */
+public class PhysicalScale {
+ private static final int METER_UNITS = 1;
+ private static final int RADIAN_UNITS = 2;
+ public static final PhysicalScale UNDEFINED = createFromMeters(-1.0, -1.0);
+
+ private final int units;
+ private final double horizontalUnitsPerPixel;
+ private final double verticalUnitsPerPixel;
+
+ private PhysicalScale(final int units, final double horizontalUnitsPerPixel,
+ final double verticalUnitsPerPixel) {
+ this.units = units;
+ this.horizontalUnitsPerPixel = horizontalUnitsPerPixel;
+ this.verticalUnitsPerPixel = verticalUnitsPerPixel;
+ }
+
+ public static PhysicalScale createFromMeters(final double x, final double y) {
+ return new PhysicalScale(METER_UNITS, x, y);
+ }
+
+ public static PhysicalScale createFromRadians(final double x, final double y) {
+ return new PhysicalScale(RADIAN_UNITS, x, y);
+ }
+
+ public boolean isInMeters() {
+ return METER_UNITS == units;
+ }
+
+ public boolean isInRadians() {
+ return RADIAN_UNITS == units;
+ }
+
+ public double getHorizontalUnitsPerPixel() {
+ return horizontalUnitsPerPixel;
+ }
+
+ public double getVerticalUnitsPerPixel() {
+ return verticalUnitsPerPixel;
+ }
+}
diff --git a/src/main/java/org/apache/commons/imaging/formats/png/PngConstants.java b/src/main/java/org/apache/commons/imaging/formats/png/PngConstants.java
index c712d11..a17e1b3 100644
--- a/src/main/java/org/apache/commons/imaging/formats/png/PngConstants.java
+++ b/src/main/java/org/apache/commons/imaging/formats/png/PngConstants.java
@@ -69,6 +69,16 @@
*/
public static final String PARAM_KEY_PNG_TEXT_CHUNKS = "PNG_TEXT_CHUNKS";
+ /**
+ * Parameter key. Used in write operations to indicate the Physical Scale - sCAL.
+ * <p>
+ * Valid values: PhysicalScale
+ * <p>
+ *
+ * @see org.apache.commons.imaging.formats.png.PhysicalScale
+ */
+ public static final String PARAM_KEY_PHYSICAL_SCALE = "PHYSICAL_SCALE_CHUNK";
+
private PngConstants() {
}
}
diff --git a/src/main/java/org/apache/commons/imaging/formats/png/PngImageInfo.java b/src/main/java/org/apache/commons/imaging/formats/png/PngImageInfo.java
index 74b7657..7e6e254 100644
--- a/src/main/java/org/apache/commons/imaging/formats/png/PngImageInfo.java
+++ b/src/main/java/org/apache/commons/imaging/formats/png/PngImageInfo.java
@@ -24,6 +24,7 @@
public class PngImageInfo extends ImageInfo {
private final List<PngText> textChunks;
+ private final PhysicalScale physicalScale;
PngImageInfo(final String formatDetails, final int bitsPerPixel,
final List<String> comments, final ImageFormat format, final String formatName,
@@ -32,7 +33,7 @@
final int physicalWidthDpi, final float physicalWidthInch, final int width,
final boolean progressive, final boolean transparent, final boolean usesPalette,
final ColorType colorType, final CompressionAlgorithm compressionAlgorithm,
- final List<PngText> textChunks) {
+ final List<PngText> textChunks, final PhysicalScale physicalScale) {
super(formatDetails, bitsPerPixel, comments, format, formatName,
height, mimeType, numberOfImages, physicalHeightDpi,
physicalHeightInch, physicalWidthDpi, physicalWidthInch, width,
@@ -40,10 +41,20 @@
compressionAlgorithm);
this.textChunks = textChunks;
+ this.physicalScale = physicalScale;
}
public List<PngText> getTextChunks() {
return new ArrayList<>(textChunks);
}
+ /**
+ * Physical scale of Image.
+ *
+ * @return {@link PhysicalScale}. If undefined then {@link PhysicalScale#UNDEFINED}
+ * is returned.
+ */
+ public PhysicalScale getPhysicalScale() {
+ return physicalScale;
+ }
}
diff --git a/src/main/java/org/apache/commons/imaging/formats/png/PngImageParser.java b/src/main/java/org/apache/commons/imaging/formats/png/PngImageParser.java
index b22bc3e..b2912f8 100644
--- a/src/main/java/org/apache/commons/imaging/formats/png/PngImageParser.java
+++ b/src/main/java/org/apache/commons/imaging/formats/png/PngImageParser.java
@@ -52,6 +52,7 @@
import org.apache.commons.imaging.formats.png.chunks.PngChunkItxt;
import org.apache.commons.imaging.formats.png.chunks.PngChunkPhys;
import org.apache.commons.imaging.formats.png.chunks.PngChunkPlte;
+import org.apache.commons.imaging.formats.png.chunks.PngChunkScal;
import org.apache.commons.imaging.formats.png.chunks.PngChunkText;
import org.apache.commons.imaging.formats.png.chunks.PngChunkZtxt;
import org.apache.commons.imaging.formats.png.chunks.PngTextChunk;
@@ -191,6 +192,8 @@
result.add(new PngChunkPlte(length, chunkType, crc, bytes));
} else if (chunkType == ChunkType.pHYs.value) {
result.add(new PngChunkPhys(length, chunkType, crc, bytes));
+ } else if (chunkType == ChunkType.sCAL.value) {
+ result.add(new PngChunkScal(length, chunkType, crc, bytes));
} else if (chunkType == ChunkType.IDAT.value) {
result.add(new PngChunkIdat(length, chunkType, crc, bytes));
} else if (chunkType == ChunkType.gAMA.value) {
@@ -338,6 +341,7 @@
final List<PngChunk> chunks = readChunks(byteSource, new ChunkType[] {
ChunkType.IHDR,
ChunkType.pHYs,
+ ChunkType.sCAL,
ChunkType.tEXt,
ChunkType.zTXt,
ChunkType.tRNS,
@@ -380,6 +384,23 @@
pngChunkpHYs = (PngChunkPhys) pHYss.get(0);
}
+ PhysicalScale physicalScale = PhysicalScale.UNDEFINED;
+
+ final List<PngChunk> sCALs = filterChunks(chunks, ChunkType.sCAL);
+ if (sCALs.size() > 1) {
+ throw new ImageReadException("PNG contains more than one sCAL:"
+ + sCALs.size());
+ } else if (sCALs.size() == 1) {
+ PngChunkScal pngChunkScal = (PngChunkScal) sCALs.get(0);
+ if (pngChunkScal.unitSpecifier == 1) {
+ physicalScale = PhysicalScale.createFromMeters(pngChunkScal.unitsPerPixelXAxis,
+ pngChunkScal.unitsPerPixelYAxis);
+ } else {
+ physicalScale = PhysicalScale.createFromRadians(pngChunkScal.unitsPerPixelXAxis,
+ pngChunkScal.unitsPerPixelYAxis);
+ }
+ }
+
final List<PngChunk> tEXts = filterChunks(chunks, ChunkType.tEXt);
final List<PngChunk> zTXts = filterChunks(chunks, ChunkType.zTXt);
final List<PngChunk> iTXts = filterChunks(chunks, ChunkType.iTXt);
@@ -465,7 +486,8 @@
format, formatName, height, mimeType, numberOfImages,
physicalHeightDpi, physicalHeightInch, physicalWidthDpi,
physicalWidthInch, width, progressive, transparent,
- usesPalette, colorType, compressionAlgorithm, textChunks);
+ usesPalette, colorType, compressionAlgorithm, textChunks,
+ physicalScale);
}
@Override
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 b7c7812..73950e8 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
@@ -297,6 +297,22 @@
writeChunk(os, ChunkType.pHYs, bytes);
}
+ private void writeChunkSCAL(final OutputStream os, final double xUPP, final double yUPP, final byte units)
+ throws IOException {
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ // unit specifier
+ baos.write(units);
+
+ // units per pixel, x-axis
+ baos.write(String.valueOf(xUPP).getBytes("ISO-8859-1"));
+ baos.write(0);
+
+ baos.write(String.valueOf(yUPP).getBytes("ISO-8859-1"));
+
+ writeChunk(os, ChunkType.sCAL, baos.toByteArray());
+ }
+
private byte getBitDepth(final PngColorType pngColorType, final Map<String, Object> params) {
byte depth = 8;
@@ -363,6 +379,7 @@
hIST No After PLTE; before IDAT
tRNS No After PLTE; before IDAT
pHYs No Before IDAT
+ sCAL No Before IDAT
sPLT Yes Before IDAT
tIME No None
iTXt Yes None
@@ -400,6 +417,7 @@
params.remove(PngConstants.PARAM_KEY_PNG_TEXT_CHUNKS);
}
params.remove(ImagingConstants.PARAM_KEY_PIXEL_DENSITY);
+ params.remove(PngConstants.PARAM_KEY_PHYSICAL_SCALE);
if (!params.isEmpty()) {
final Object firstKey = params.keySet().iterator().next();
throw new ImageWriteException("Unknown parameter: " + firstKey);
@@ -517,6 +535,13 @@
}
}
+ final Object physcialScaleObj = params.get(PngConstants.PARAM_KEY_PHYSICAL_SCALE);
+ if (physcialScaleObj instanceof PhysicalScale) {
+ final PhysicalScale physicalScale = (PhysicalScale)physcialScaleObj;
+ writeChunkSCAL(os, physicalScale.getHorizontalUnitsPerPixel(), physicalScale.getVerticalUnitsPerPixel(),
+ physicalScale.isInMeters() ? (byte) 1 : (byte) 2);
+ }
+
if (params.containsKey(ImagingConstants.PARAM_KEY_XMP_XML)) {
final String xmpXml = (String) params.get(ImagingConstants.PARAM_KEY_XMP_XML);
writeChunkXmpiTXt(os, xmpXml);
@@ -652,6 +677,7 @@
hIST No After PLTE; before IDAT
tRNS No After PLTE; before IDAT
pHYs No Before IDAT
+ sCAL No Before IDAT
sPLT Yes Before IDAT
tIME No None
iTXt Yes None
diff --git a/src/main/java/org/apache/commons/imaging/formats/png/chunks/PngChunkScal.java b/src/main/java/org/apache/commons/imaging/formats/png/chunks/PngChunkScal.java
new file mode 100644
index 0000000..a22d4ae
--- /dev/null
+++ b/src/main/java/org/apache/commons/imaging/formats/png/chunks/PngChunkScal.java
@@ -0,0 +1,64 @@
+/*
+ * 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.formats.png.chunks;
+
+import org.apache.commons.imaging.ImageReadException;
+
+import java.io.IOException;
+
+import static org.apache.commons.imaging.common.BinaryFunctions.findNull;
+
+public class PngChunkScal extends PngChunk {
+ public final double unitsPerPixelXAxis;
+ public final double unitsPerPixelYAxis;
+ public final int unitSpecifier;
+
+ public PngChunkScal(int length, int chunkType, int crc, byte[] bytes)
+ throws ImageReadException, IOException {
+ super(length, chunkType, crc, bytes);
+
+ unitSpecifier = bytes[0];
+ if (unitSpecifier != 1 && unitSpecifier != 2) {
+ throw new ImageReadException("PNG sCAL invalid unit specifier: " + unitSpecifier);
+ }
+
+ final int separator = findNull(bytes);
+ if (separator < 0) {
+ throw new ImageReadException("PNG sCAL x and y axis value separator not found.");
+ }
+
+ final int xIndex = 1;
+ final String xStr = new String(bytes, xIndex, separator - 1, "ISO-8859-1");
+ unitsPerPixelXAxis = toDouble(xStr);
+
+ final int yIndex = separator + 1;
+ if (yIndex >= length) {
+ throw new ImageReadException("PNG sCAL chunk missing the y axis value.");
+ }
+
+ final String yStr = new String(bytes, yIndex, length - yIndex);
+ unitsPerPixelYAxis = toDouble(yStr);
+ }
+
+ private double toDouble(final String str) throws ImageReadException {
+ try {
+ return Double.valueOf(str);
+ } catch (NumberFormatException e) {
+ throw new ImageReadException("PNG sCAL error reading axis value - " + str);
+ }
+ }
+}
diff --git a/src/test/java/org/apache/commons/imaging/formats/png/PhysicalScaleTest.java b/src/test/java/org/apache/commons/imaging/formats/png/PhysicalScaleTest.java
new file mode 100644
index 0000000..e5cfffe
--- /dev/null
+++ b/src/test/java/org/apache/commons/imaging/formats/png/PhysicalScaleTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.formats.png;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class PhysicalScaleTest {
+ private final double delta = 0.01;
+
+ @Test
+ public void createFromMeters() {
+ final PhysicalScale physicalScale = PhysicalScale.createFromMeters(1.0, 2.0);
+
+ assertTrue("Should be in meteres", physicalScale.isInMeters());
+ assertFalse("Should not be in radians", physicalScale.isInRadians());
+ assertEquals("Invalid horizontal units per pixel", physicalScale.getHorizontalUnitsPerPixel(), 1.0, delta);
+ assertEquals("Invalid vertical units per pixel", physicalScale.getVerticalUnitsPerPixel(), 2.0, delta);
+ }
+
+ @Test
+ public void createFromRadians() {
+ final PhysicalScale physicalScale = PhysicalScale.createFromRadians(2.0, 1.0);
+
+ assertFalse("Should not be in meteres", physicalScale.isInMeters());
+ assertTrue("Should be in radians", physicalScale.isInRadians());
+ assertEquals("Invalid horizontal units per pixel", physicalScale.getHorizontalUnitsPerPixel(), 2.0, delta);
+ assertEquals("Invalid vertical units per pixel", physicalScale.getVerticalUnitsPerPixel(), 1.0, delta);
+ }
+}
diff --git a/src/test/java/org/apache/commons/imaging/formats/png/PngWriteReadTest.java b/src/test/java/org/apache/commons/imaging/formats/png/PngWriteReadTest.java
index 1ceb7e3..b8ad2b6 100644
--- a/src/test/java/org/apache/commons/imaging/formats/png/PngWriteReadTest.java
+++ b/src/test/java/org/apache/commons/imaging/formats/png/PngWriteReadTest.java
@@ -18,6 +18,7 @@
package org.apache.commons.imaging.formats.png;
import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -107,6 +108,38 @@
assertTrue(Imaging.getImageInfo(pngBytes).isTransparent());
}
+ @Test
+ public void testPhysicalScaleMeters() throws Exception {
+ final Map<String, Object> optionalParams = new HashMap<>();
+ optionalParams.put(PngConstants.PARAM_KEY_PHYSICAL_SCALE, PhysicalScale.createFromMeters(0.01, 0.02));
+
+ final int[][] smallAscendingPixels = getAscendingRawData(256, 256);
+ final byte[] pngBytes = Imaging.writeImageToBytes(
+ imageDataToBufferedImage(smallAscendingPixels),
+ ImageFormats.PNG, optionalParams);
+ final PngImageInfo imageInfo = (PngImageInfo) Imaging.getImageInfo(pngBytes);
+ final PhysicalScale physicalScale = imageInfo.getPhysicalScale();
+ assertTrue("Invalid units", physicalScale.isInMeters());
+ assertEquals("Invalid horizontal units", 0.01, physicalScale.getHorizontalUnitsPerPixel(), 0.001);
+ assertEquals("Invalid vertical units", 0.02, physicalScale.getVerticalUnitsPerPixel(), 0.001);
+ }
+
+ @Test
+ public void testPhysicalScaleRadians() throws Exception {
+ final Map<String, Object> optionalParams = new HashMap<>();
+ optionalParams.put(PngConstants.PARAM_KEY_PHYSICAL_SCALE, PhysicalScale.createFromRadians(0.01, 0.02));
+
+ final int[][] smallAscendingPixels = getAscendingRawData(256, 256);
+ final byte[] pngBytes = Imaging.writeImageToBytes(
+ imageDataToBufferedImage(smallAscendingPixels),
+ ImageFormats.PNG, optionalParams);
+ final PngImageInfo imageInfo = (PngImageInfo) Imaging.getImageInfo(pngBytes);
+ final PhysicalScale physicalScale = imageInfo.getPhysicalScale();
+ assertTrue("Invalid units", physicalScale.isInRadians());
+ assertEquals("Invalid horizontal units", 0.01, physicalScale.getHorizontalUnitsPerPixel(), 0.001);
+ assertEquals("Invalid vertical units", 0.02, physicalScale.getVerticalUnitsPerPixel(), 0.001);
+ }
+
private BufferedImage imageDataToBufferedImage(final int[][] rawData) {
final int width = rawData[0].length;
final int height = rawData.length;
diff --git a/src/test/java/org/apache/commons/imaging/formats/png/chunks/PngChunkScalTest.java b/src/test/java/org/apache/commons/imaging/formats/png/chunks/PngChunkScalTest.java
new file mode 100644
index 0000000..5e735d5
--- /dev/null
+++ b/src/test/java/org/apache/commons/imaging/formats/png/chunks/PngChunkScalTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.formats.png.chunks;
+
+import org.apache.commons.imaging.ImageReadException;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+
+public class PngChunkScalTest {
+ private final double delta = 0.001;
+ private final int chunkType = 1933787468;
+
+ @Test
+ public void testConstructMeters() throws IOException, ImageReadException {
+ final PngChunkScal pngChunkScal = new PngChunkScal(10, chunkType, 0,
+ new byte[]{1, 48, 46, 48, 49, 0, 48, 46, 48, 50});
+
+ assertEquals("Invalid unit specifier", pngChunkScal.unitSpecifier, 1);
+ assertEquals("Invalid units per pixel x axis", pngChunkScal.unitsPerPixelXAxis, 0.01, delta);
+ assertEquals("Invalid units per pixel y axis", pngChunkScal.unitsPerPixelYAxis, 0.02, delta);
+ }
+
+ @Test
+ public void testConstructRadians() throws IOException, ImageReadException {
+ final PngChunkScal pngChunkScal = new PngChunkScal(10, chunkType, 0,
+ new byte[]{2, 48, 46, 48, 49, 0, 48, 46, 48, 50});
+
+ assertEquals("Invalid unit specifier", pngChunkScal.unitSpecifier, 2);
+ assertEquals("Invalid units per pixel x axis", pngChunkScal.unitsPerPixelXAxis, 0.01, delta);
+ assertEquals("Invalid units per pixel y axis", pngChunkScal.unitsPerPixelYAxis, 0.02, delta);
+ }
+
+ @Test(expected = ImageReadException.class)
+ public void testConstruct_InvalidUnitSpecifier() throws IOException, ImageReadException {
+ new PngChunkScal(10, chunkType, 0, new byte[]{3, 48, 46, 48, 49, 0, 48, 46, 48, 50});
+ }
+
+ @Test(expected = ImageReadException.class)
+ public void testConstruct_MissingSeparator() throws IOException, ImageReadException {
+ new PngChunkScal(9, chunkType, 0, new byte[]{1, 48, 46, 48, 49, 48, 46, 48, 50});
+ }
+
+ @Test(expected = ImageReadException.class)
+ public void testConstruct_InvalidDblValue() throws IOException, ImageReadException {
+ new PngChunkScal(10, chunkType, 0, new byte[]{2, 65, 46, 48, 49, 0, 48, 46, 48, 50});
+ }
+
+ @Test(expected = ImageReadException.class)
+ public void testConstruct_MissingXValue() throws IOException, ImageReadException {
+ new PngChunkScal(2, chunkType, 0, new byte[]{2, 0});
+ }
+
+ @Test(expected = ImageReadException.class)
+ public void testConstruct_MissingYValue() throws IOException, ImageReadException {
+ new PngChunkScal(6, chunkType, 0, new byte[]{2, 48, 46, 48, 49, 0});
+ }
+}