1342 Enumeration<InputStream> e = new PNGImageDataEnumeration(stream); 1343 InputStream is = new SequenceInputStream(e); 1344 1345 /* InflaterInputStream uses an Inflater instance which consumes 1346 * native (non-GC visible) resources. This is normally implicitly 1347 * freed when the stream is closed. However since the 1348 * InflaterInputStream wraps a client-supplied input stream, 1349 * we cannot close it. 1350 * But the app may depend on GC finalization to close the stream. 1351 * Therefore to ensure timely freeing of native resources we 1352 * explicitly create the Inflater instance and free its resources 1353 * when we are done with the InflaterInputStream by calling 1354 * inf.end(); 1355 */ 1356 inf = new Inflater(); 1357 is = new InflaterInputStream(is, inf); 1358 is = new BufferedInputStream(is); 1359 this.pixelStream = new DataInputStream(is); 1360 1361 /* 1362 * NB: the PNG spec declares that valid range for width 1363 * and height is [1, 2^31-1], so here we may fail to allocate 1364 * a buffer for destination image due to memory limitation. 1365 * 1366 * However, the recovery strategy for this case should be 1367 * defined on the level of application, so we will not 1368 * try to estimate the required amount of the memory and/or 1369 * handle OOM in any way. 1370 */ 1371 theImage = getDestination(param, 1372 getImageTypes(0), 1373 width, 1374 height); 1375 1376 Rectangle destRegion = new Rectangle(0, 0, 0, 0); 1377 sourceRegion = new Rectangle(0, 0, 0, 0); 1378 computeRegions(param, width, height, 1379 theImage, 1380 sourceRegion, destRegion); 1381 destinationOffset.setLocation(destRegion.getLocation()); 1382 1383 // At this point the header has been read and we know 1384 // how many bands are in the image, so perform checking 1385 // of the read param. 1386 int colorType = metadata.IHDR_colorType; 1387 checkReadParamBandSettings(param, 1388 inputBandsForColorType[colorType], 1389 theImage.getSampleModel().getNumBands()); 1654 1655 public IIOMetadata getStreamMetadata() 1656 throws IIOException { 1657 return null; 1658 } 1659 1660 public IIOMetadata getImageMetadata(int imageIndex) throws IIOException { 1661 if (imageIndex != 0) { 1662 throw new IndexOutOfBoundsException("imageIndex != 0!"); 1663 } 1664 readMetadata(); 1665 return metadata; 1666 } 1667 1668 public BufferedImage read(int imageIndex, ImageReadParam param) 1669 throws IIOException { 1670 if (imageIndex != 0) { 1671 throw new IndexOutOfBoundsException("imageIndex != 0!"); 1672 } 1673 1674 readImage(param); 1675 return theImage; 1676 } 1677 1678 public void reset() { 1679 super.reset(); 1680 resetStreamSettings(); 1681 } 1682 1683 private void resetStreamSettings() { 1684 gotHeader = false; 1685 gotMetadata = false; 1686 metadata = null; 1687 pixelStream = null; 1688 } 1689 } | 1342 Enumeration<InputStream> e = new PNGImageDataEnumeration(stream); 1343 InputStream is = new SequenceInputStream(e); 1344 1345 /* InflaterInputStream uses an Inflater instance which consumes 1346 * native (non-GC visible) resources. This is normally implicitly 1347 * freed when the stream is closed. However since the 1348 * InflaterInputStream wraps a client-supplied input stream, 1349 * we cannot close it. 1350 * But the app may depend on GC finalization to close the stream. 1351 * Therefore to ensure timely freeing of native resources we 1352 * explicitly create the Inflater instance and free its resources 1353 * when we are done with the InflaterInputStream by calling 1354 * inf.end(); 1355 */ 1356 inf = new Inflater(); 1357 is = new InflaterInputStream(is, inf); 1358 is = new BufferedInputStream(is); 1359 this.pixelStream = new DataInputStream(is); 1360 1361 /* 1362 * PNG spec declares that valid range for width 1363 * and height is [1, 2^31-1], so here we may fail to allocate 1364 * a buffer for destination image due to memory limitation. 1365 * 1366 * If the read operation triggers OutOfMemoryError, the same 1367 * will be wrapped in an IIOException at PNGImageReader.read 1368 * method. 1369 * 1370 * The recovery strategy for this case should be defined at 1371 * the level of application, so we will not try to estimate 1372 * the required amount of the memory and/or handle OOM in 1373 * any way. 1374 */ 1375 theImage = getDestination(param, 1376 getImageTypes(0), 1377 width, 1378 height); 1379 1380 Rectangle destRegion = new Rectangle(0, 0, 0, 0); 1381 sourceRegion = new Rectangle(0, 0, 0, 0); 1382 computeRegions(param, width, height, 1383 theImage, 1384 sourceRegion, destRegion); 1385 destinationOffset.setLocation(destRegion.getLocation()); 1386 1387 // At this point the header has been read and we know 1388 // how many bands are in the image, so perform checking 1389 // of the read param. 1390 int colorType = metadata.IHDR_colorType; 1391 checkReadParamBandSettings(param, 1392 inputBandsForColorType[colorType], 1393 theImage.getSampleModel().getNumBands()); 1658 1659 public IIOMetadata getStreamMetadata() 1660 throws IIOException { 1661 return null; 1662 } 1663 1664 public IIOMetadata getImageMetadata(int imageIndex) throws IIOException { 1665 if (imageIndex != 0) { 1666 throw new IndexOutOfBoundsException("imageIndex != 0!"); 1667 } 1668 readMetadata(); 1669 return metadata; 1670 } 1671 1672 public BufferedImage read(int imageIndex, ImageReadParam param) 1673 throws IIOException { 1674 if (imageIndex != 0) { 1675 throw new IndexOutOfBoundsException("imageIndex != 0!"); 1676 } 1677 1678 try { 1679 readImage(param); 1680 } catch (IOException | 1681 IllegalStateException | 1682 IllegalArgumentException e) 1683 { 1684 throw e; 1685 } catch (Throwable e) { 1686 throw new IIOException("Caught exception during read: ", e); 1687 } 1688 return theImage; 1689 } 1690 1691 public void reset() { 1692 super.reset(); 1693 resetStreamSettings(); 1694 } 1695 1696 private void resetStreamSettings() { 1697 gotHeader = false; 1698 gotMetadata = false; 1699 metadata = null; 1700 pixelStream = null; 1701 } 1702 } |