📄 pngimagereader.java
字号:
private void parse_cHRM_chunk() throws IOException { metadata.cHRM_whitePointX = stream.readInt(); metadata.cHRM_whitePointY = stream.readInt(); metadata.cHRM_redX = stream.readInt(); metadata.cHRM_redY = stream.readInt(); metadata.cHRM_greenX = stream.readInt(); metadata.cHRM_greenY = stream.readInt(); metadata.cHRM_blueX = stream.readInt(); metadata.cHRM_blueY = stream.readInt(); metadata.cHRM_present = true; } private void parse_gAMA_chunk() throws IOException { int gamma = stream.readInt(); metadata.gAMA_gamma = gamma; metadata.gAMA_present = true; } private void parse_hIST_chunk() throws IOException, IIOException { if (!metadata.PLTE_present) { throw new IIOException("hIST chunk without prior PLTE chunk!"); } metadata.hIST_histogram = new char[metadata.PLTE_red.length]; stream.readFully(metadata.hIST_histogram, 0, metadata.hIST_histogram.length); metadata.hIST_present = true; } private void parse_iCCP_chunk(int chunkLength) throws IOException { String keyword = readNullTerminatedString(); metadata.iCCP_profileName = keyword; metadata.iCCP_compressionMethod = stream.readUnsignedByte(); byte[] compressedProfile = new byte[chunkLength - keyword.length() - 2]; stream.readFully(compressedProfile); metadata.iCCP_compressedProfile = compressedProfile; metadata.iCCP_present = true; } private void parse_iTXt_chunk(int chunkLength) throws IOException { long chunkStart = stream.getStreamPosition(); String keyword = readNullTerminatedString(); metadata.iTXt_keyword.add(keyword); int compressionFlag = stream.readUnsignedByte(); metadata.iTXt_compressionFlag.add(new Integer(compressionFlag)); int compressionMethod = stream.readUnsignedByte(); metadata.iTXt_compressionMethod.add(new Integer(compressionMethod)); String languageTag = readNullTerminatedString(); metadata.iTXt_languageTag.add(languageTag); String translatedKeyword = stream.readUTF(); metadata.iTXt_translatedKeyword.add(translatedKeyword); stream.skipBytes(1); // Null separator String text; if (compressionFlag == 1) { // Decompress the text long pos = stream.getStreamPosition(); byte[] b = new byte[(int)(chunkStart + chunkLength - pos)]; stream.readFully(b); text = inflate(b); } else { text = stream.readUTF(); } metadata.iTXt_text.add(text); } private void parse_pHYs_chunk() throws IOException { metadata.pHYs_pixelsPerUnitXAxis = stream.readInt(); metadata.pHYs_pixelsPerUnitYAxis = stream.readInt(); metadata.pHYs_unitSpecifier = stream.readUnsignedByte(); metadata.pHYs_present = true; } private void parse_sBIT_chunk() throws IOException { int colorType = metadata.IHDR_colorType; if (colorType == PNG_COLOR_GRAY || colorType == PNG_COLOR_GRAY_ALPHA) { metadata.sBIT_grayBits = stream.readUnsignedByte(); } else if (colorType == PNG_COLOR_RGB || colorType == PNG_COLOR_PALETTE || colorType == PNG_COLOR_RGB_ALPHA) { metadata.sBIT_redBits = stream.readUnsignedByte(); metadata.sBIT_greenBits = stream.readUnsignedByte(); metadata.sBIT_blueBits = stream.readUnsignedByte(); } if (colorType == PNG_COLOR_GRAY_ALPHA || colorType == PNG_COLOR_RGB_ALPHA) { metadata.sBIT_alphaBits = stream.readUnsignedByte(); } metadata.sBIT_colorType = colorType; metadata.sBIT_present = true; } private void parse_sPLT_chunk(int chunkLength) throws IOException, IIOException { metadata.sPLT_paletteName = readNullTerminatedString(); chunkLength -= metadata.sPLT_paletteName.length() + 1; int sampleDepth = stream.readUnsignedByte(); metadata.sPLT_sampleDepth = sampleDepth; int numEntries = chunkLength/(4*(sampleDepth/8) + 2); metadata.sPLT_red = new int[numEntries]; metadata.sPLT_green = new int[numEntries]; metadata.sPLT_blue = new int[numEntries]; metadata.sPLT_alpha = new int[numEntries]; metadata.sPLT_frequency = new int[numEntries]; if (sampleDepth == 8) { for (int i = 0; i < numEntries; i++) { metadata.sPLT_red[i] = stream.readUnsignedByte(); metadata.sPLT_green[i] = stream.readUnsignedByte(); metadata.sPLT_blue[i] = stream.readUnsignedByte(); metadata.sPLT_alpha[i] = stream.readUnsignedByte(); metadata.sPLT_frequency[i] = stream.readUnsignedShort(); } } else if (sampleDepth == 16) { for (int i = 0; i < numEntries; i++) { metadata.sPLT_red[i] = stream.readUnsignedShort(); metadata.sPLT_green[i] = stream.readUnsignedShort(); metadata.sPLT_blue[i] = stream.readUnsignedShort(); metadata.sPLT_alpha[i] = stream.readUnsignedShort(); metadata.sPLT_frequency[i] = stream.readUnsignedShort(); } } else { throw new IIOException("sPLT sample depth not 8 or 16!"); } metadata.sPLT_present = true; } private void parse_sRGB_chunk() throws IOException { metadata.sRGB_renderingIntent = stream.readUnsignedByte(); metadata.sRGB_present = true; } private void parse_tEXt_chunk(int chunkLength) throws IOException { String keyword = readNullTerminatedString(); metadata.tEXt_keyword.add(keyword); byte[] b = new byte[chunkLength - keyword.length() - 1]; stream.readFully(b); metadata.tEXt_text.add(new String(b)); } private void parse_tIME_chunk() throws IOException { metadata.tIME_year = stream.readUnsignedShort(); metadata.tIME_month = stream.readUnsignedByte(); metadata.tIME_day = stream.readUnsignedByte(); metadata.tIME_hour = stream.readUnsignedByte(); metadata.tIME_minute = stream.readUnsignedByte(); metadata.tIME_second = stream.readUnsignedByte(); metadata.tIME_present = true; } private void parse_tRNS_chunk(int chunkLength) throws IOException { int colorType = metadata.IHDR_colorType; if (colorType == PNG_COLOR_PALETTE) { if (!metadata.PLTE_present) { processWarningOccurred("tRNS chunk without prior PLTE chunk, ignoring it."); return; } // Alpha table may have fewer entries than RGB palette int maxEntries = metadata.PLTE_red.length; int numEntries = chunkLength; if (numEntries > maxEntries) { processWarningOccurred("tRNS chunk has more entries than prior PLTE chunk, ignoring extras."); numEntries = maxEntries; } metadata.tRNS_alpha = new byte[numEntries]; metadata.tRNS_colorType = PNG_COLOR_PALETTE; stream.read(metadata.tRNS_alpha, 0, numEntries); stream.skipBytes(chunkLength - numEntries); } else if (colorType == PNG_COLOR_GRAY) { if (chunkLength != 2) { processWarningOccurred("tRNS chunk for gray image must have length 2, ignoring chunk."); stream.skipBytes(chunkLength); return; } metadata.tRNS_gray = stream.readUnsignedShort(); metadata.tRNS_colorType = PNG_COLOR_GRAY; } else if (colorType == PNG_COLOR_RGB) { if (chunkLength != 6) { processWarningOccurred("tRNS chunk for RGB image must have length 6, ignoring chunk."); stream.skipBytes(chunkLength); return; } metadata.tRNS_red = stream.readUnsignedShort(); metadata.tRNS_green = stream.readUnsignedShort(); metadata.tRNS_blue = stream.readUnsignedShort(); metadata.tRNS_colorType = PNG_COLOR_RGB; } else { processWarningOccurred("Gray+Alpha and RGBS images may not have a tRNS chunk, ignoring it."); return; } metadata.tRNS_present = true; } private static String inflate(byte[] b) throws IOException { InputStream bais = new ByteArrayInputStream(b); InputStream iis = new InflaterInputStream(bais); StringBuilder sb = new StringBuilder(80); int c; while ((c = iis.read()) != -1) { sb.append((char)c); } return sb.toString(); } private void parse_zTXt_chunk(int chunkLength) throws IOException { String keyword = readNullTerminatedString(); metadata.zTXt_keyword.add(keyword); int method = stream.readUnsignedByte(); metadata.zTXt_compressionMethod.add(new Integer(method)); byte[] b = new byte[chunkLength - keyword.length() - 2]; stream.readFully(b); metadata.zTXt_text.add(inflate(b)); } private void readMetadata() throws IIOException { if (gotMetadata) { return; } readHeader(); /* * Optimization: We can skip the remaining metadata if the * ignoreMetadata flag is set, and only if this is not a palette * image (in that case, we need to read the metadata to get the * tRNS chunk, which is needed for the getImageTypes() method). */ int colorType = metadata.IHDR_colorType; if (ignoreMetadata && colorType != PNG_COLOR_PALETTE) { try { while (true) { int chunkLength = stream.readInt(); int chunkType = stream.readInt(); if (chunkType == IDAT_TYPE) { // We've reached the image data stream.skipBytes(-8); imageStartPosition = stream.getStreamPosition(); break; } else { // Skip the chunk plus the 4 CRC bytes that follow stream.skipBytes(chunkLength + 4); } } } catch (IOException e) { throw new IIOException("Error skipping PNG metadata", e); } gotMetadata = true; return; } try { loop: while (true) { int chunkLength = stream.readInt(); int chunkType = stream.readInt(); switch (chunkType) { case IDAT_TYPE: // If chunk type is 'IDAT', we've reached the image data. stream.skipBytes(-8); imageStartPosition = stream.getStreamPosition(); break loop; case PLTE_TYPE: parse_PLTE_chunk(chunkLength); break; case bKGD_TYPE: parse_bKGD_chunk(); break; case cHRM_TYPE: parse_cHRM_chunk(); break; case gAMA_TYPE: parse_gAMA_chunk(); break; case hIST_TYPE: parse_hIST_chunk(); break; case iCCP_TYPE: parse_iCCP_chunk(chunkLength); break; case iTXt_TYPE: parse_iTXt_chunk(chunkLength); break; case pHYs_TYPE: parse_pHYs_chunk(); break; case sBIT_TYPE: parse_sBIT_chunk(); break; case sPLT_TYPE: parse_sPLT_chunk(chunkLength); break; case sRGB_TYPE: parse_sRGB_chunk(); break; case tEXt_TYPE: parse_tEXt_chunk(chunkLength); break; case tIME_TYPE: parse_tIME_chunk(); break; case tRNS_TYPE: parse_tRNS_chunk(chunkLength); break; case zTXt_TYPE: parse_zTXt_chunk(chunkLength); break; default: // Read an unknown chunk byte[] b = new byte[chunkLength]; stream.readFully(b); StringBuilder chunkName = new StringBuilder(4); chunkName.append((char)(chunkType >>> 24)); chunkName.append((char)((chunkType >> 16) & 0xff)); chunkName.append((char)((chunkType >> 8) & 0xff)); chunkName.append((char)(chunkType & 0xff)); int ancillaryBit = chunkType >>> 28; if (ancillaryBit == 0) { processWarningOccurred("Encountered unknown chunk with critical bit set!"); } metadata.unknownChunkType.add(chunkName.toString()); metadata.unknownChunkData.add(b); break; } int chunkCRC = stream.readInt(); stream.flushBefore(stream.getStreamPosition()); } } catch (IOException e) { throw new IIOException("Error reading PNG metadata", e); } gotMetadata = true; } // Data filtering methods
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -