722 723 // verify the chunk length 724 if (chunkLength < 0) { 725 throw new IIOException("Invalid chunk length " + chunkLength); 726 }; 727 728 try { 729 stream.mark(); 730 stream.seek(stream.getStreamPosition() + chunkLength); 731 chunkCRC = stream.readInt(); 732 stream.reset(); 733 } catch (IOException e) { 734 throw new IIOException("Invalid chunk length " + chunkLength); 735 } 736 737 switch (chunkType) { 738 case IDAT_TYPE: 739 // If chunk type is 'IDAT', we've reached the image data. 740 if (imageStartPosition == -1L) { 741 /* 742 * PNGs may contain multiple IDAT chunks containing 743 * a portion of image data. We store the position of 744 * the first IDAT chunk and continue with iteration 745 * of other chunks that follow image data. 746 */ 747 imageStartPosition = stream.getStreamPosition() - 8; 748 } 749 // Move to the CRC byte location. 750 stream.skipBytes(chunkLength); 751 break; 752 case IEND_TYPE: 753 /* 754 * If the chunk type is 'IEND', we've reached end of image. 755 * Seek to the first IDAT chunk for subsequent decoding. 756 */ 757 stream.seek(imageStartPosition); 758 759 /* 760 * flushBefore discards the portion of the stream before 761 * the indicated position. Hence this should be used after | 722 723 // verify the chunk length 724 if (chunkLength < 0) { 725 throw new IIOException("Invalid chunk length " + chunkLength); 726 }; 727 728 try { 729 stream.mark(); 730 stream.seek(stream.getStreamPosition() + chunkLength); 731 chunkCRC = stream.readInt(); 732 stream.reset(); 733 } catch (IOException e) { 734 throw new IIOException("Invalid chunk length " + chunkLength); 735 } 736 737 switch (chunkType) { 738 case IDAT_TYPE: 739 // If chunk type is 'IDAT', we've reached the image data. 740 if (imageStartPosition == -1L) { 741 /* 742 * PNG specification mandates that if colorType is 743 * PNG_COLOR_PALETTE then PLTE chunk should appear 744 * before the first IDAT chunk. 745 */ 746 if (colorType == PNG_COLOR_PALETTE && 747 metadata.PLTE_present == false) 748 { 749 throw new IIOException("PNG image doesn't contain" 750 + " required PLTE chunk"); 751 } 752 /* 753 * PNGs may contain multiple IDAT chunks containing 754 * a portion of image data. We store the position of 755 * the first IDAT chunk and continue with iteration 756 * of other chunks that follow image data. 757 */ 758 imageStartPosition = stream.getStreamPosition() - 8; 759 } 760 // Move to the CRC byte location. 761 stream.skipBytes(chunkLength); 762 break; 763 case IEND_TYPE: 764 /* 765 * If the chunk type is 'IEND', we've reached end of image. 766 * Seek to the first IDAT chunk for subsequent decoding. 767 */ 768 stream.seek(imageStartPosition); 769 770 /* 771 * flushBefore discards the portion of the stream before 772 * the indicated position. Hence this should be used after |