📄 pngmetadata.java
字号:
/* * @(#)PNGMetadata.java 1.43 07/09/12 * * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.imageio.plugins.png;import java.awt.image.ColorModel;import java.awt.image.IndexColorModel;import java.awt.image.SampleModel;import java.util.ArrayList;import java.util.Iterator;import java.util.StringTokenizer;import javax.imageio.ImageTypeSpecifier;import javax.imageio.metadata.IIOInvalidTreeException;import javax.imageio.metadata.IIOMetadata;import javax.imageio.metadata.IIOMetadataFormat;import javax.imageio.metadata.IIOMetadataFormatImpl;import javax.imageio.metadata.IIOMetadataNode;import org.w3c.dom.Node;/** * @version 0.5 */public class PNGMetadata extends IIOMetadata implements Cloneable { // package scope public static final String nativeMetadataFormatName = "javax_imageio_png_1.0"; protected static final String nativeMetadataFormatClassName = "com.sun.imageio.plugins.png.PNGMetadataFormat"; // Color types for IHDR chunk public static final String[] IHDR_colorTypeNames = { "Grayscale", null, "RGB", "Palette", "GrayAlpha", null, "RGBAlpha" }; public static final int[] IHDR_numChannels = { 1, 0, 3, 3, 2, 0, 4 }; // Bit depths for IHDR chunk public static final String[] IHDR_bitDepths = { "1", "2", "4", "8", "16" }; // Compression methods for IHDR chunk public static final String[] IHDR_compressionMethodNames = { "deflate" }; // Filter methods for IHDR chunk public static final String[] IHDR_filterMethodNames = { "adaptive" }; // Interlace methods for IHDR chunk public static final String[] IHDR_interlaceMethodNames = { "none", "adam7" }; // Compression methods for iCCP chunk public static final String[] iCCP_compressionMethodNames = { "deflate" }; // Compression methods for zTXt chunk public static final String[] zTXt_compressionMethodNames = { "deflate" }; // "Unknown" unit for pHYs chunk public static final int PHYS_UNIT_UNKNOWN = 0; // "Meter" unit for pHYs chunk public static final int PHYS_UNIT_METER = 1; // Unit specifiers for pHYs chunk public static final String[] unitSpecifierNames = { "unknown", "meter" }; // Rendering intents for sRGB chunk public static final String[] renderingIntentNames = { "Perceptual", // 0 "Relative colorimetric", // 1 "Saturation", // 2 "Absolute colorimetric" // 3 }; // Color space types for Chroma->ColorSpaceType node public static final String[] colorSpaceTypeNames = { "GRAY", null, "RGB", "RGB", "GRAY", null, "RGB" }; // IHDR chunk public boolean IHDR_present; public int IHDR_width; public int IHDR_height; public int IHDR_bitDepth; public int IHDR_colorType; public int IHDR_compressionMethod; public int IHDR_filterMethod; public int IHDR_interlaceMethod; // 0 == none, 1 == adam7 // PLTE chunk public boolean PLTE_present; public byte[] PLTE_red; public byte[] PLTE_green; public byte[] PLTE_blue; // If non-null, used to reorder palette entries during encoding in // order to minimize the size of the tRNS chunk. Thus an index of // 'i' in the source should be encoded as index 'PLTE_order[i]'. // PLTE_order will be null unless 'initialize' is called with an // IndexColorModel image type. public int[] PLTE_order = null; // bKGD chunk // If external (non-PNG sourced) data has red = green = blue, // always store it as gray and promote when writing public boolean bKGD_present; public int bKGD_colorType; // PNG_COLOR_GRAY, _RGB, or _PALETTE public int bKGD_index; public int bKGD_gray; public int bKGD_red; public int bKGD_green; public int bKGD_blue; // cHRM chunk public boolean cHRM_present; public int cHRM_whitePointX; public int cHRM_whitePointY; public int cHRM_redX; public int cHRM_redY; public int cHRM_greenX; public int cHRM_greenY; public int cHRM_blueX; public int cHRM_blueY; // gAMA chunk public boolean gAMA_present; public int gAMA_gamma; // hIST chunk public boolean hIST_present; public char[] hIST_histogram; // iCCP chunk public boolean iCCP_present; public String iCCP_profileName; public int iCCP_compressionMethod; public byte[] iCCP_compressedProfile; // iTXt chunk public ArrayList iTXt_keyword = new ArrayList(); // Strings public ArrayList iTXt_compressionFlag = new ArrayList(); // Integers public ArrayList iTXt_compressionMethod = new ArrayList(); // Integers public ArrayList iTXt_languageTag = new ArrayList(); // Strings public ArrayList iTXt_translatedKeyword = new ArrayList(); // Strings public ArrayList iTXt_text = new ArrayList(); // Strings // pHYs chunk public boolean pHYs_present; public int pHYs_pixelsPerUnitXAxis; public int pHYs_pixelsPerUnitYAxis; public int pHYs_unitSpecifier; // 0 == unknown, 1 == meter // sBIT chunk public boolean sBIT_present; public int sBIT_colorType; // PNG_COLOR_GRAY, _GRAY_ALPHA, _RGB, _RGB_ALPHA public int sBIT_grayBits; public int sBIT_redBits; public int sBIT_greenBits; public int sBIT_blueBits; public int sBIT_alphaBits; // sPLT chunk public boolean sPLT_present; public String sPLT_paletteName; // 1-79 characters public int sPLT_sampleDepth; // 8 or 16 public int[] sPLT_red; public int[] sPLT_green; public int[] sPLT_blue; public int[] sPLT_alpha; public int[] sPLT_frequency; // sRGB chunk public boolean sRGB_present; public int sRGB_renderingIntent; // tEXt chunk public ArrayList tEXt_keyword = new ArrayList(); // 1-79 char Strings public ArrayList tEXt_text = new ArrayList(); // Strings // tIME chunk public boolean tIME_present; public int tIME_year; public int tIME_month; public int tIME_day; public int tIME_hour; public int tIME_minute; public int tIME_second; // tRNS chunk // If external (non-PNG sourced) data has red = green = blue, // always store it as gray and promote when writing public boolean tRNS_present; public int tRNS_colorType; // PNG_COLOR_GRAY, _RGB, or _PALETTE public byte[] tRNS_alpha; // May have fewer entries than PLTE_red, etc. public int tRNS_gray; public int tRNS_red; public int tRNS_green; public int tRNS_blue; // zTXt chunk public ArrayList zTXt_keyword = new ArrayList(); // Strings public ArrayList zTXt_compressionMethod = new ArrayList(); // Integers public ArrayList zTXt_text = new ArrayList(); // Strings // Unknown chunks public ArrayList unknownChunkType = new ArrayList(); // Strings public ArrayList unknownChunkData = new ArrayList(); // byte arrays public PNGMetadata() { super(true, nativeMetadataFormatName, nativeMetadataFormatClassName, null, null); } public PNGMetadata(IIOMetadata metadata) { // TODO -- implement } /** * Sets the IHDR_bitDepth and IHDR_colorType variables. * The <code>numBands</code> parameter is necessary since * we may only be writing a subset of the image bands. */ public void initialize(ImageTypeSpecifier imageType, int numBands) { ColorModel colorModel = imageType.getColorModel(); SampleModel sampleModel = imageType.getSampleModel(); // Initialize IHDR_bitDepth int[] sampleSize = sampleModel.getSampleSize(); int bitDepth = sampleSize[0]; // Choose max bit depth over all channels // Fixes bug 4413109 for (int i = 1; i < sampleSize.length; i++) { if (sampleSize[i] > bitDepth) { bitDepth = sampleSize[i]; } } // Multi-channel images must have a bit depth of 8 or 16 if (sampleSize.length > 1 && bitDepth < 8) { bitDepth = 8; } // Round bit depth up to a power of 2 if (bitDepth > 2 && bitDepth < 4) { bitDepth = 4; } else if (bitDepth > 4 && bitDepth < 8) { bitDepth = 8; } else if (bitDepth > 8 && bitDepth < 16) { bitDepth = 16; } else if (bitDepth > 16) { throw new RuntimeException("bitDepth > 16!"); } IHDR_bitDepth = bitDepth; // Initialize IHDR_colorType if (colorModel instanceof IndexColorModel) { IndexColorModel icm = (IndexColorModel)colorModel; int size = icm.getMapSize(); byte[] reds = new byte[size]; icm.getReds(reds); byte[] greens = new byte[size]; icm.getGreens(greens); byte[] blues = new byte[size]; icm.getBlues(blues); // Determine whether the color tables are actually a gray ramp // if the color type has not been set previously boolean isGray = false; if (!IHDR_present || (IHDR_colorType != PNGImageReader.PNG_COLOR_PALETTE)) { isGray = true; int scale = 255/((1 << IHDR_bitDepth) - 1); for (int i = 0; i < size; i++) { byte red = reds[i]; if ((red != (byte)(i*scale)) || (red != greens[i]) || (red != blues[i])) { isGray = false; break; } } } // Determine whether transparency exists boolean hasAlpha = colorModel.hasAlpha(); byte[] alpha = null; if (hasAlpha) { alpha = new byte[size]; icm.getAlphas(alpha); } /* * NB: PNG_COLOR_GRAY_ALPHA color type may be not optimal for images * containing more than 1024 pixels (or even more than 768 pixels in * case of single transparent pixel in palette). * For such images alpha samples in raster will occupy more space than * it is required to store palette so it could be reasonable to
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -