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 77c8c38c60..98fb0e8907 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 @@ -29,6 +29,7 @@ import java.io.OutputStream; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -71,7 +72,8 @@ /** * Parses PNG images. */ -public class PngImageParser extends AbstractImageParser implements XmpEmbeddable { +public class PngImageParser extends AbstractImageParser + implements XmpEmbeddable { private static final Logger LOGGER = Logger.getLogger(PngImageParser.class.getName()); @@ -101,7 +103,8 @@ public PngImageParser() { } @Override - public boolean dumpImageFile(final PrintWriter pw, final ByteSource byteSource) throws ImagingException, IOException { + public boolean dumpImageFile(final PrintWriter pw, final ByteSource byteSource) + throws ImagingException, IOException { final ImageInfo imageInfo = getImageInfo(byteSource); if (imageInfo == null) { return false; @@ -163,18 +166,29 @@ protected ImageFormat[] getAcceptedTypes() { // private static final int tRNS = CharsToQuad('t', 'R', 'N', 's'); + final Boolean[] reach = new Boolean[50]; + { + Arrays.fill(reach, false); + } + + @Override - public BufferedImage getBufferedImage(final ByteSource byteSource, final PngImagingParameters params) throws ImagingException, IOException { + public BufferedImage getBufferedImage(final ByteSource byteSource, final PngImagingParameters params) + throws ImagingException, IOException { final List chunks = readChunks(byteSource, - new ChunkType[] { ChunkType.IHDR, ChunkType.PLTE, ChunkType.IDAT, ChunkType.tRNS, ChunkType.iCCP, ChunkType.gAMA, ChunkType.sRGB, }, false); + new ChunkType[] { ChunkType.IHDR, ChunkType.PLTE, ChunkType.IDAT, ChunkType.tRNS, ChunkType.iCCP, + ChunkType.gAMA, ChunkType.sRGB, }, + false); if (chunks.isEmpty()) { + reach[1] = true; throw new ImagingException("PNG: no chunks"); } final List IHDRs = filterChunks(chunks, ChunkType.IHDR); if (IHDRs.size() != 1) { + reach[2] = true; throw new ImagingException("PNG contains more than one Header"); } @@ -182,21 +196,25 @@ public BufferedImage getBufferedImage(final ByteSource byteSource, final PngImag final List PLTEs = filterChunks(chunks, ChunkType.PLTE); if (PLTEs.size() > 1) { + reach[3] = true; throw new ImagingException("PNG contains more than one Palette"); } PngChunkPlte pngChunkPLTE = null; if (PLTEs.size() == 1) { + reach[4] = true; pngChunkPLTE = (PngChunkPlte) PLTEs.get(0); } final List IDATs = filterChunks(chunks, ChunkType.IDAT); if (IDATs.isEmpty()) { + reach[5] = true; throw new ImagingException("PNG missing image data"); } ByteArrayOutputStream baos = new ByteArrayOutputStream(); for (final PngChunk IDAT : IDATs) { + reach[6] = true; final PngChunkIdat pngChunkIDAT = (PngChunkIdat) IDAT; final byte[] bytes = pngChunkIDAT.getBytes(); // System.out.println(i + ": bytes: " + bytes.length); @@ -211,6 +229,7 @@ public BufferedImage getBufferedImage(final ByteSource byteSource, final PngImag final List tRNSs = filterChunks(chunks, ChunkType.tRNS); if (!tRNSs.isEmpty()) { + reach[7] = true; final PngChunk pngChunktRNS = tRNSs.get(0); abstractTransparencyFilter = getTransparencyFilter(pngChunkIHDR.getPngColorType(), pngChunktRNS); } @@ -222,22 +241,29 @@ public BufferedImage getBufferedImage(final ByteSource byteSource, final PngImag final List gAMAs = filterChunks(chunks, ChunkType.gAMA); final List iCCPs = filterChunks(chunks, ChunkType.iCCP); if (sRGBs.size() > 1) { + reach[8] = true; throw new ImagingException("PNG: unexpected sRGB chunk"); } if (gAMAs.size() > 1) { + reach[9] = true; throw new ImagingException("PNG: unexpected gAMA chunk"); } if (iCCPs.size() > 1) { + reach[10] = true; throw new ImagingException("PNG: unexpected iCCP chunk"); } if (sRGBs.size() == 1) { + reach[11] = true; // no color management necessary. if (LOGGER.isLoggable(Level.FINEST)) { + reach[12] = true; LOGGER.finest("sRGB, no color management necessary."); } } else if (iCCPs.size() == 1) { + reach[13] = true; if (LOGGER.isLoggable(Level.FINEST)) { + reach[14] = true; LOGGER.finest("iCCP."); } @@ -245,11 +271,14 @@ public BufferedImage getBufferedImage(final ByteSource byteSource, final PngImag final byte[] bytes = pngChunkiCCP.getUncompressedProfile(); try { + reach[15] = true; iccProfile = ICC_Profile.getInstance(bytes); } catch (final IllegalArgumentException iae) { + reach[16] = true; throw new ImagingException("The image data does not correspond to a valid ICC Profile", iae); } } else if (gAMAs.size() == 1) { + reach[17] = true; final PngChunkGama pngChunkgAMA = (PngChunkGama) gAMAs.get(0); final double gamma = pngChunkgAMA.getGamma(); @@ -258,10 +287,12 @@ public BufferedImage getBufferedImage(final ByteSource byteSource, final PngImag final double targetGamma = 1.0; final double diff = Math.abs(targetGamma - gamma); if (diff >= 0.5) { + reach[18] = true; gammaCorrection = new GammaCorrection(gamma, targetGamma); } if (gammaCorrection != null && pngChunkPLTE != null) { + reach[19] = true; pngChunkPLTE.correct(gammaCorrection); } @@ -275,6 +306,7 @@ public BufferedImage getBufferedImage(final ByteSource byteSource, final PngImag final int bitDepth = pngChunkIHDR.getBitDepth(); if (pngChunkIHDR.getFilterMethod() != 0) { + reach[20] = true; throw new ImagingException("PNG: unknown FilterMethod: " + pngChunkIHDR.getFilterMethod()); } @@ -284,8 +316,10 @@ public BufferedImage getBufferedImage(final ByteSource byteSource, final PngImag BufferedImage result; if (pngColorType.isGreyscale()) { + reach[21] = true; result = getBufferedImageFactory(params).getGrayscaleBufferedImage(width, height, hasAlpha); } else { + reach[22] = true; result = getBufferedImageFactory(params).getColorBufferedImage(width, height, hasAlpha); } @@ -295,23 +329,30 @@ public BufferedImage getBufferedImage(final ByteSource byteSource, final PngImag final AbstractScanExpediter abstractScanExpediter; switch (pngChunkIHDR.getInterlaceMethod()) { - case NONE: - abstractScanExpediter = new ScanExpediterSimple(width, height, iis, result, pngColorType, bitDepth, bitsPerPixel, pngChunkPLTE, gammaCorrection, - abstractTransparencyFilter); - break; - case ADAM7: - abstractScanExpediter = new ScanExpediterInterlaced(width, height, iis, result, pngColorType, bitDepth, bitsPerPixel, pngChunkPLTE, - gammaCorrection, abstractTransparencyFilter); - break; - default: - throw new ImagingException("Unknown InterlaceMethod: " + pngChunkIHDR.getInterlaceMethod()); + case NONE: + reach[23] = true; + abstractScanExpediter = new ScanExpediterSimple(width, height, iis, result, pngColorType, bitDepth, + bitsPerPixel, pngChunkPLTE, gammaCorrection, + abstractTransparencyFilter); + break; + case ADAM7: + reach[24] = true; + abstractScanExpediter = new ScanExpediterInterlaced(width, height, iis, result, pngColorType, + bitDepth, bitsPerPixel, pngChunkPLTE, + gammaCorrection, abstractTransparencyFilter); + break; + default: + reach[25] = true; + throw new ImagingException("Unknown InterlaceMethod: " + pngChunkIHDR.getInterlaceMethod()); } abstractScanExpediter.drive(); if (iccProfile != null) { + reach[26] = true; final boolean isSrgb = new IccProfileParser().isSrgb(iccProfile); if (!isSrgb) { + reach[27] = true; final ICC_ColorSpace cs = new ICC_ColorSpace(iccProfile); final ColorModel srgbCM = ColorModel.getRGBdefault(); @@ -358,10 +399,14 @@ public PngImagingParameters getDefaultParameters() { * Gets TIFF image metadata for a byte source and TIFF parameters. * * @param byteSource The source of the image. - * @param params Optional instructions for special-handling or interpretation of the input data (null objects are permitted and must be supported by + * @param params Optional instructions for special-handling or + * interpretation of the input data (null objects are + * permitted and must be supported by * implementations). * @return TIFF image metadata. - * @throws ImagingException In the event that the specified content does not conform to the format of the specific parser implementation. + * @throws ImagingException In the event that the specified content does not + * conform to the format of the specific parser + * implementation. * @throws IOException In the event of unsuccessful data read operation. * @since 1.0-alpha6 */ @@ -384,7 +429,9 @@ public TiffImageMetadata getExifMetadata(final ByteSource byteSource, TiffImagin * * @param byteSource The source of the image. * @return TIFF image metadata. - * @throws ImagingException In the event that the specified content does not conform to the format of the specific parser implementation. + * @throws ImagingException In the event that the specified content does not + * conform to the format of the specific parser + * implementation. * @throws IOException In the event of unsuccessful data read operation. * @since 1.0-alpha6 */ @@ -399,7 +446,8 @@ public byte[] getExifRawData(final ByteSource byteSource) throws ImagingExceptio } @Override - public byte[] getIccProfileBytes(final ByteSource byteSource, final PngImagingParameters params) throws ImagingException, IOException { + public byte[] getIccProfileBytes(final ByteSource byteSource, final PngImagingParameters params) + throws ImagingException, IOException { final List chunks = readChunks(byteSource, new ChunkType[] { ChunkType.iCCP }, true); if (chunks.isEmpty()) { @@ -416,9 +464,12 @@ public byte[] getIccProfileBytes(final ByteSource byteSource, final PngImagingPa } @Override - public ImageInfo getImageInfo(final ByteSource byteSource, final PngImagingParameters params) throws ImagingException, IOException { - final List chunks = readChunks(byteSource, new ChunkType[] { ChunkType.IHDR, ChunkType.pHYs, ChunkType.sCAL, ChunkType.tEXt, ChunkType.zTXt, - ChunkType.tRNS, ChunkType.PLTE, ChunkType.iTXt, }, false); + public ImageInfo getImageInfo(final ByteSource byteSource, final PngImagingParameters params) + throws ImagingException, IOException { + final List chunks = readChunks(byteSource, + new ChunkType[] { ChunkType.IHDR, ChunkType.pHYs, ChunkType.sCAL, ChunkType.tEXt, ChunkType.zTXt, + ChunkType.tRNS, ChunkType.PLTE, ChunkType.iTXt, }, + false); if (chunks.isEmpty()) { throw new ImagingException("PNG: no chunks"); @@ -461,9 +512,11 @@ public ImageInfo getImageInfo(final ByteSource byteSource, final PngImagingParam if (sCALs.size() == 1) { final PngChunkScal pngChunkScal = (PngChunkScal) sCALs.get(0); if (pngChunkScal.getUnitSpecifier() == 1) { - physicalScale = PhysicalScale.createFromMeters(pngChunkScal.getUnitsPerPixelXAxis(), pngChunkScal.getUnitsPerPixelYAxis()); + physicalScale = PhysicalScale.createFromMeters(pngChunkScal.getUnitsPerPixelXAxis(), + pngChunkScal.getUnitsPerPixelYAxis()); } else { - physicalScale = PhysicalScale.createFromRadians(pngChunkScal.getUnitsPerPixelXAxis(), pngChunkScal.getUnitsPerPixelYAxis()); + physicalScale = PhysicalScale.createFromRadians(pngChunkScal.getUnitsPerPixelXAxis(), + pngChunkScal.getUnitsPerPixelYAxis()); } } @@ -532,29 +585,32 @@ public ImageInfo getImageInfo(final ByteSource byteSource, final PngImagingParam final ImageInfo.ColorType colorType; switch (pngChunkIHDR.getPngColorType()) { - case GREYSCALE: - case GREYSCALE_WITH_ALPHA: - colorType = ImageInfo.ColorType.GRAYSCALE; - break; - case TRUE_COLOR: - case INDEXED_COLOR: - case TRUE_COLOR_WITH_ALPHA: - colorType = ImageInfo.ColorType.RGB; - break; - default: - throw new ImagingException("Png: Unknown ColorType: " + pngChunkIHDR.getPngColorType()); + case GREYSCALE: + case GREYSCALE_WITH_ALPHA: + colorType = ImageInfo.ColorType.GRAYSCALE; + break; + case TRUE_COLOR: + case INDEXED_COLOR: + case TRUE_COLOR_WITH_ALPHA: + colorType = ImageInfo.ColorType.RGB; + break; + default: + throw new ImagingException("Png: Unknown ColorType: " + pngChunkIHDR.getPngColorType()); } final String formatDetails = "Png"; final ImageInfo.CompressionAlgorithm compressionAlgorithm = ImageInfo.CompressionAlgorithm.PNG_FILTER; - return new PngImageInfo(formatDetails, bitsPerPixel, comments, format, formatName, height, mimeType, numberOfImages, physicalHeightDpi, - physicalHeightInch, physicalWidthDpi, physicalWidthInch, width, progressive, transparent, usesPalette, colorType, compressionAlgorithm, + return new PngImageInfo(formatDetails, bitsPerPixel, comments, format, formatName, height, mimeType, + numberOfImages, physicalHeightDpi, + physicalHeightInch, physicalWidthDpi, physicalWidthInch, width, progressive, transparent, usesPalette, + colorType, compressionAlgorithm, textChunks, physicalScale); } @Override - public Dimension getImageSize(final ByteSource byteSource, final PngImagingParameters params) throws ImagingException, IOException { + public Dimension getImageSize(final ByteSource byteSource, final PngImagingParameters params) + throws ImagingException, IOException { final List chunks = readChunks(byteSource, new ChunkType[] { ChunkType.IHDR, }, true); if (chunks.isEmpty()) { @@ -571,7 +627,8 @@ public Dimension getImageSize(final ByteSource byteSource, final PngImagingParam } @Override - public ImageMetadata getMetadata(final ByteSource byteSource, final PngImagingParameters params) throws ImagingException, IOException { + public ImageMetadata getMetadata(final ByteSource byteSource, final PngImagingParameters params) + throws ImagingException, IOException { final ChunkType[] chunkTypes = { ChunkType.tEXt, ChunkType.zTXt, ChunkType.iTXt, ChunkType.eXIf }; final List chunks = readChunks(byteSource, chunkTypes, false); @@ -604,24 +661,26 @@ public String getName() { return "Png-Custom"; } - private AbstractTransparencyFilter getTransparencyFilter(final PngColorType pngColorType, final PngChunk pngChunktRNS) + private AbstractTransparencyFilter getTransparencyFilter(final PngColorType pngColorType, + final PngChunk pngChunktRNS) throws ImagingException, IOException { switch (pngColorType) { - case GREYSCALE: // 1,2,4,8,16 Each pixel is a grayscale sample. - return new TransparencyFilterGrayscale(pngChunktRNS.getBytes()); - case TRUE_COLOR: // 8,16 Each pixel is an R,G,B triple. - return new TransparencyFilterTrueColor(pngChunktRNS.getBytes()); - case INDEXED_COLOR: // 1,2,4,8 Each pixel is a palette index; - return new TransparencyFilterIndexedColor(pngChunktRNS.getBytes()); - case GREYSCALE_WITH_ALPHA: // 8,16 Each pixel is a grayscale sample, - case TRUE_COLOR_WITH_ALPHA: // 8,16 Each pixel is an R,G,B triple, - default: - throw new ImagingException("Simple Transparency not compatible with ColorType: " + pngColorType); + case GREYSCALE: // 1,2,4,8,16 Each pixel is a grayscale sample. + return new TransparencyFilterGrayscale(pngChunktRNS.getBytes()); + case TRUE_COLOR: // 8,16 Each pixel is an R,G,B triple. + return new TransparencyFilterTrueColor(pngChunktRNS.getBytes()); + case INDEXED_COLOR: // 1,2,4,8 Each pixel is a palette index; + return new TransparencyFilterIndexedColor(pngChunktRNS.getBytes()); + case GREYSCALE_WITH_ALPHA: // 8,16 Each pixel is a grayscale sample, + case TRUE_COLOR_WITH_ALPHA: // 8,16 Each pixel is an R,G,B triple, + default: + throw new ImagingException("Simple Transparency not compatible with ColorType: " + pngColorType); } } @Override - public String getXmpXml(final ByteSource byteSource, final XmpImagingParameters params) throws ImagingException, IOException { + public String getXmpXml(final ByteSource byteSource, final XmpImagingParameters params) + throws ImagingException, IOException { final List chunks = readChunks(byteSource, new ChunkType[] { ChunkType.iTXt }, false); @@ -657,12 +716,13 @@ public String getXmpXml(final ByteSource byteSource, final XmpImagingParameters< * Checks if the PNG image has the specified chunk type. * * @param byteSource the byte source. - * @param chunkType the chunk type to check. + * @param chunkType the chunk type to check. * @return true if chunk type exists, false otherwise. * @throws ImagingException if an imaging error occurs. - * @throws IOException if an I/O error occurs. + * @throws IOException if an I/O error occurs. */ - public boolean hasChunkType(final ByteSource byteSource, final ChunkType chunkType) throws ImagingException, IOException { + public boolean hasChunkType(final ByteSource byteSource, final ChunkType chunkType) + throws ImagingException, IOException { try (InputStream is = byteSource.getInputStream()) { readSignature(is); final List chunks = readChunks(is, new ChunkType[] { chunkType }, true); @@ -684,7 +744,8 @@ private boolean keepChunk(final int chunkType, final ChunkType[] chunkTypes) { return false; } - private List readChunks(final ByteSource byteSource, final ChunkType[] chunkTypes, final boolean returnAfterFirst) + private List readChunks(final ByteSource byteSource, final ChunkType[] chunkTypes, + final boolean returnAfterFirst) throws ImagingException, IOException { try (InputStream is = byteSource.getInputStream()) { readSignature(is); @@ -692,7 +753,8 @@ private List readChunks(final ByteSource byteSource, final ChunkType[] } } - private List readChunks(final InputStream is, final ChunkType[] chunkTypes, final boolean returnAfterFirst) throws ImagingException, IOException { + private List readChunks(final InputStream is, final ChunkType[] chunkTypes, + final boolean returnAfterFirst) throws ImagingException, IOException { final List result = new ArrayList<>(); while (true) { @@ -710,7 +772,8 @@ private List readChunks(final InputStream is, final ChunkType[] chunkT byte[] bytes = null; if (keep) { - bytes = BinaryFunctions.readBytes("Chunk Data", is, length, "Not a Valid PNG File: Couldn't read Chunk Data."); + bytes = BinaryFunctions.readBytes("Chunk Data", is, length, + "Not a Valid PNG File: Couldn't read Chunk Data."); } else { BinaryFunctions.skipBytes(is, length, "Not a Valid PNG File"); } @@ -743,16 +806,20 @@ private List readChunks(final InputStream is, final ChunkType[] chunkT * Reads reads the signature. * * @param in an input stream. - * @throws ImagingException In the event that the specified content does not conform to the format of the specific parser implementation. + * @throws ImagingException In the event that the specified content does not + * conform to the format of the specific parser + * implementation. * @throws IOException In the event of unsuccessful data read operation. */ public void readSignature(final InputStream in) throws ImagingException, IOException { - BinaryFunctions.readAndVerifyBytes(in, PngConstants.PNG_SIGNATURE, "Not a Valid PNG Segment: Incorrect Signature"); + BinaryFunctions.readAndVerifyBytes(in, PngConstants.PNG_SIGNATURE, + "Not a Valid PNG Segment: Incorrect Signature"); } @Override - public void writeImage(final BufferedImage src, final OutputStream os, final PngImagingParameters params) throws ImagingException, IOException { + public void writeImage(final BufferedImage src, final OutputStream os, final PngImagingParameters params) + throws ImagingException, IOException { new PngWriter().writeImage(src, os, params, null); } diff --git a/src/test/java/org/apache/commons/imaging/formats/png/PngReadTest.java b/src/test/java/org/apache/commons/imaging/formats/png/PngReadTest.java index fc36f8afe0..411b2103a3 100644 --- a/src/test/java/org/apache/commons/imaging/formats/png/PngReadTest.java +++ b/src/test/java/org/apache/commons/imaging/formats/png/PngReadTest.java @@ -26,6 +26,7 @@ import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; +import java.util.Arrays; import java.util.List; import org.apache.commons.imaging.ImageInfo; @@ -56,7 +57,8 @@ void test() throws Exception { assertThrows(Exception.class, () -> Imaging.getImageInfo(imageFile), "Image read should have failed."); - assertThrows(Exception.class, () -> Imaging.getBufferedImage(imageFile), "Image read should have failed."); + assertThrows(Exception.class, () -> Imaging.getBufferedImage(imageFile), + "Image read should have failed."); } else { final ImageMetadata metadata = Imaging.getMetadata(imageFile); assertFalse(metadata instanceof File); // Dummy check to avoid unused warning (it may be null) @@ -75,7 +77,7 @@ void test() throws Exception { /** * Test reading EXIF from the 'eXIf' chunk in PNG file. * - * @throws IOException if it fails to read the test image + * @throws IOException if it fails to read the test image * @throws ImagingException if it fails to read the test image */ @Test @@ -102,7 +104,8 @@ void testReadExif() throws IOException, ImagingException { /** * Test reading metadata from PNG file with UTF-8 characters in the text chunks. * - * @see IMAGING-342 + * @see IMAGING-342 * @throws IOException if it fails to read the test image * @throws ImagingException if it fails to read the test image */ @@ -115,13 +118,15 @@ void testReadMetadataFromItxtChunk() throws IOException, ImagingException { final List items = metadata.getItems(); assertEquals(1, items.size()); - final GenericImageMetadata.GenericImageMetadataItem item = (GenericImageMetadata.GenericImageMetadataItem) items.get(0); + final GenericImageMetadata.GenericImageMetadataItem item = (GenericImageMetadata.GenericImageMetadataItem) items + .get(0); assertEquals("Comment", item.getKeyword()); assertEquals("\u2192 UTF-8 Test", item.getText()); } /** - * If the PNG image data contains an invalid ICC Profile, previous versions would simply rethrow the IAE. This test verifies we are instead raising the + * If the PNG image data contains an invalid ICC Profile, previous versions + * would simply rethrow the IAE. This test verifies we are instead raising the * documented {@literal ImageReadException}. * *

@@ -132,13 +137,18 @@ void testReadMetadataFromItxtChunk() throws IOException, ImagingException { */ @Test void testUncaughtExceptionOssFuzz33691() throws IOException { - final File file = TestResources.resourceToFile("/images/png/oss-fuzz-33691/clusterfuzz-testcase-minimized-ImagingPngFuzzer-6177282101215232"); + final File file = TestResources.resourceToFile( + "/images/png/oss-fuzz-33691/clusterfuzz-testcase-minimized-ImagingPngFuzzer-6177282101215232"); final PngImageParser parser = new PngImageParser(); - assertThrows(ImagingException.class, () -> parser.getBufferedImage(ByteSource.file(file), new PngImagingParameters())); + assertThrows(ImagingException.class, + () -> parser.getBufferedImage(ByteSource.file(file), new PngImagingParameters())); + System.out.println(Arrays.toString(parser.reach)); + } /** - * Test that a PNG image using indexed color type but no PLTE chunks does not throw a {@code NullPointerException}. + * Test that a PNG image using indexed color type but no PLTE chunks does not + * throw a {@code NullPointerException}. * *

* See Google OSS Fuzz issue 37607 @@ -148,8 +158,11 @@ void testUncaughtExceptionOssFuzz33691() throws IOException { */ @Test void testUncaughtExceptionOssFuzz37607() throws IOException { - final File file = TestResources.resourceToFile("/images/png/IMAGING-317/clusterfuzz-testcase-minimized-ImagingPngFuzzer-6242400830357504"); + final File file = TestResources.resourceToFile( + "/images/png/IMAGING-317/clusterfuzz-testcase-minimized-ImagingPngFuzzer-6242400830357504"); final PngImageParser parser = new PngImageParser(); - assertThrows(ImagingException.class, () -> parser.getBufferedImage(ByteSource.file(file), new PngImagingParameters())); + assertThrows(ImagingException.class, + () -> parser.getBufferedImage(ByteSource.file(file), new PngImagingParameters())); + System.out.println(Arrays.toString(parser.reach)); } }