/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
// package scope
public static final String
= "com.sun.imageio.plugins.png.PNGMetadataFormat";
// Color types for IHDR chunk
};
public static final int[] IHDR_numChannels = {
1, 0, 3, 3, 2, 0, 4
};
// Bit depths for IHDR chunk
"1", "2", "4", "8", "16"
};
// Compression methods for IHDR chunk
"deflate"
};
// Filter methods for IHDR chunk
"adaptive"
};
// Interlace methods for IHDR chunk
"none", "adam7"
};
// Compression methods for iCCP chunk
"deflate"
};
// Compression methods for zTXt chunk
"deflate"
};
// "Unknown" unit for pHYs chunk
// "Meter" unit for pHYs chunk
// Unit specifiers for pHYs chunk
"unknown", "meter"
};
// Rendering intents for sRGB chunk
"Perceptual", // 0
"Relative colorimetric", // 1
"Saturation", // 2
"Absolute colorimetric" // 3
};
// Color space types for Chroma->ColorSpaceType node
};
// 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;
// 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.
// 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_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 int iCCP_compressionMethod;
public byte[] iCCP_compressedProfile;
// iTXt chunk
// pHYs chunk
public boolean pHYs_present;
public int pHYs_pixelsPerUnitXAxis;
public int pHYs_pixelsPerUnitYAxis;
// sBIT chunk
public boolean sBIT_present;
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 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
// 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_gray;
public int tRNS_red;
public int tRNS_green;
public int tRNS_blue;
// zTXt chunk
// Unknown chunks
public PNGMetadata() {
super(true,
}
// 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.
*/
// Initialize IHDR_bitDepth
// Choose max bit depth over all channels
// Fixes bug 4413109
if (sampleSize[i] > bitDepth) {
bitDepth = sampleSize[i];
}
}
// Multi-channel images must have a bit depth of 8 or 16
bitDepth = 8;
}
// Round bit depth up to a power of 2
bitDepth = 4;
bitDepth = 8;
bitDepth = 16;
} else if (bitDepth > 16) {
throw new RuntimeException("bitDepth > 16!");
}
// Initialize IHDR_colorType
if (colorModel instanceof IndexColorModel) {
// 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 ||
isGray = true;
for (int i = 0; i < size; i++) {
isGray = false;
break;
}
}
}
// Determine whether transparency exists
if (hasAlpha) {
}
/*
* NB: PNG_COLOR_GRAY_ALPHA color type may be not optimal for images
* contained more than 1024 pixels (or even 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
* use PNG_COLOR_PALETTE color type for large images.
*/
} else {
PLTE_present = true;
PLTE_order = null;
if (hasAlpha) {
tRNS_present = true;
// Reorder the palette so that non-opaque entries
// come first. Since the tRNS chunk does not have
// to store trailing 255's, this can save a
// considerable amount of space when encoding
// images with only one transparent pixel value,
// e.g., images from GIF sources.
// Scan for non-opaque entries and assign them
// positions starting at 0.
int newIndex = 0;
if (alpha[i] != (byte)255) {
PLTE_order[i] = newIndex;
++newIndex;
}
}
int numTransparent = newIndex;
// Scan for opaque entries and assign them
// positions following the non-opaque entries.
if (alpha[i] == (byte)255) {
PLTE_order[i] = newIndex++;
}
}
// Reorder the palettes
byte[] oldGreen = PLTE_green;
PLTE_green = new byte[len];
for (int i = 0; i < len; i++) {
}
// Copy only the transparent entries into tRNS_alpha
tRNS_alpha = new byte[numTransparent];
}
}
} else {
if (numBands == 1) {
} else if (numBands == 2) {
} else if (numBands == 3) {
} else if (numBands == 4) {
} else {
throw new RuntimeException("Number of bands not 1-4!");
}
}
IHDR_present = true;
}
public boolean isReadOnly() {
return false;
}
return null;
} else {
for (byte[] b: in) {
}
return list;
}
}
// Deep clone
try {
} catch (CloneNotSupportedException e) {
return null;
}
// unknownChunkData needs deep clone
return metadata;
}
return getNativeTree();
} else if (formatName.equals
return getStandardTree();
} else {
throw new IllegalArgumentException("Not a recognized format!");
}
}
// IHDR
if (IHDR_present) {
// IHDR_compressionMethod must be 0 in PNG 1.1
// IHDR_filterMethod must be 0 in PNG 1.1
}
// PLTE
if (PLTE_present) {
for (int i = 0; i < numEntries; i++) {
}
}
// bKGD
if (bKGD_present) {
}
}
// cHRM
if (cHRM_present) {
}
// gAMA
if (gAMA_present) {
}
// hIST
if (hIST_present) {
new IIOMetadataNode("hISTEntry");
}
}
// iCCP
if (iCCP_present) {
}
}
// iTXt
iTXt_languageTag.get(i));
}
}
// pHYs
if (pHYs_present) {
}
// sBIT
if (sBIT_present) {
}
}
// sPLT
if (sPLT_present) {
for (int i = 0; i < numEntries; i++) {
}
}
// sRGB
if (sRGB_present) {
}
// tEXt
}
}
// tIME
if (tIME_present) {
}
// tRNS
if (tRNS_present) {
new IIOMetadataNode("tRNS_PaletteEntry");
}
}
}
// zTXt
}
}
// Unknown chunks
new IIOMetadataNode("UnknownChunks");
new IIOMetadataNode("UnknownChunk");
}
}
return root;
}
private int getNumChannels() {
// Determine number of channels
// Be careful about palette color with transparency
numChannels = 4;
}
return numChannels;
}
if (gAMA_present) {
}
if (PLTE_present) {
boolean hasAlpha = tRNS_present &&
new IIOMetadataNode("PaletteEntry");
if (hasAlpha) {
}
}
}
if (bKGD_present) {
} else {
int r, g, b;
r = g = b = bKGD_gray;
} else {
r = bKGD_red;
g = bKGD_green;
b = bKGD_blue;
}
}
}
return chroma_node;
}
return compression_node;
}
if (times == 1) {
return s;
}
for (int i = 1; i < times; i++) {
}
}
"Index" : "UnsignedIntegral");
if (sBIT_present) {
} else { // sBIT_colorType == PNGImageReader.PNG_COLOR_RGB ||
// sBIT_colorType == PNGImageReader.PNG_COLOR_RGB_ALPHA
}
}
}
// SampleMSB
return data_node;
}
float ratio = pHYs_present ?
}
return dimension_node;
}
if (!tIME_present) {
return null;
}
return document_node;
}
if (numEntries == 0) {
return null;
}
}
iTXt_languageTag.get(i));
if (iTXt_compressionFlag.get(i)) {
} else {
}
}
}
return text_node;
}
new IIOMetadataNode("Transparency");
boolean hasAlpha =
tRNS_present &&
(tRNS_colorType == IHDR_colorType) &&
(tRNS_alpha != null));
if (tRNS_present) {
}
}
return transparency_node;
}
// Shorthand for throwing an IIOInvalidTreeException
throws IIOInvalidTreeException {
}
// Get an integer-valued attribute
throws IIOInvalidTreeException {
if (!required) {
return defaultValue;
} else {
}
}
return attr.getNodeValue();
}
// Get an integer-valued attribute
int defaultValue, boolean required)
throws IIOInvalidTreeException {
return defaultValue;
}
}
// Get a float-valued attribute
float defaultValue, boolean required)
throws IIOInvalidTreeException {
return defaultValue;
}
}
// Get a required integer-valued attribute
throws IIOInvalidTreeException {
}
// Get a required float-valued attribute
throws IIOInvalidTreeException {
}
// Get a boolean-valued attribute
boolean defaultValue,
boolean required)
throws IIOInvalidTreeException {
if (!required) {
return defaultValue;
} else {
}
}
// Allow lower case booleans for backward compatibility, #5082756
return true;
return false;
} else {
return false;
}
}
// Get a required boolean-valued attribute
throws IIOInvalidTreeException {
}
// Get an enumerated attribute as an index into a String array
int defaultValue, boolean required)
throws IIOInvalidTreeException {
if (!required) {
return defaultValue;
} else {
}
}
return i;
}
}
return -1;
}
// Get a required enumerated attribute as an index into a String array
throws IIOInvalidTreeException {
}
// Get a String-valued attribute
throws IIOInvalidTreeException {
if (!required) {
return defaultValue;
} else {
}
}
return attr.getNodeValue();
}
// Get a required String-valued attribute
throws IIOInvalidTreeException {
}
throws IIOInvalidTreeException {
throw new IllegalArgumentException("root == null!");
}
} else if (formatName.equals
throw new IllegalArgumentException("root == null!");
}
} else {
throw new IllegalArgumentException("Not a recognized format!");
}
}
throws IIOInvalidTreeException {
}
"filterMethod",
IHDR_present = true;
byte[] red = new byte[256];
byte[] green = new byte[256];
byte[] blue = new byte[256];
int maxindex = -1;
if (PLTE_entry == null) {
}
while (PLTE_entry != null) {
"Only a PLTEEntry may be a child of a PLTE!");
}
"Bad value for PLTEEntry attribute index!");
}
}
}
PLTE_red = new byte[numEntries];
PLTE_green = new byte[numEntries];
PLTE_blue = new byte[numEntries];
PLTE_present = true;
bKGD_present = false; // Guard against partial overwrite
}
} else {
}
}
bKGD_present = true;
cHRM_present = true;
gAMA_present = true;
char[] hist = new char[256];
int maxindex = -1;
if (hIST_entry == null) {
}
while (hIST_entry != null) {
"Only a hISTEntry may be a child of a hIST!");
}
"Bad value for histEntry attribute index!");
}
}
}
hIST_histogram = new char[numEntries];
hIST_present = true;
if (compressedProfile == null) {
}
if (!(compressedProfile instanceof byte[])) {
}
(byte[])((byte[])compressedProfile).clone();
iCCP_present = true;
"Only an iTXtEntry may be a child of an iTXt!");
}
if (isValidKeyword(keyword)) {
boolean compressionFlag =
}
// silently skip invalid text entry
}
pHYs_present = true;
sBIT_present = false; // Guard against partial overwrite
}
} else {
}
}
sBIT_present = true;
int[] red = new int[256];
int[] green = new int[256];
int[] blue = new int[256];
int[] alpha = new int[256];
int[] frequency = new int[256];
int maxindex = -1;
if (sPLT_entry == null) {
}
while (sPLT_entry != null) {
"Only an sPLTEntry may be a child of an sPLT!");
}
"Bad value for PLTEEntry attribute index!");
}
}
}
sPLT_red = new int[numEntries];
sPLT_green = new int[numEntries];
sPLT_blue = new int[numEntries];
sPLT_alpha = new int[numEntries];
sPLT_frequency = new int[numEntries];
sPLT_present = true;
sRGB_present = true;
"Only an tEXtEntry may be a child of an tEXt!");
}
}
tIME_present = true;
tRNS_present = false; // Guard against partial overwrite
}
byte[] alpha = new byte[256];
int maxindex = -1;
if (tRNS_paletteEntry == null) {
}
while (tRNS_paletteEntry != null) {
"tRNS_PaletteEntry")) {
"Only a tRNS_PaletteEntry may be a child of a tRNS_Palette!");
}
int index =
"Bad value for tRNS_PaletteEntry attribute index!");
}
}
(byte)getIntAttribute(tRNS_paletteEntry,
"alpha");
}
tRNS_alpha = new byte[numEntries];
} else {
}
}
tRNS_present = true;
"Only an zTXtEntry may be a child of an zTXt!");
}
int compressionMethod =
}
while (unknown_node != null) {
"Only an UnknownChunk may be a child of an UnknownChunks!");
}
"Chunk type must be 4 characters!");
}
"No chunk data present in user object!");
}
if (!(chunkData instanceof byte[])) {
"User object not a byte array!");
}
}
} else {
}
}
}
/*
* Accrding to PNG spec, keywords are restricted to 1 to 79 bytes
* in length. Keywords shall contain only printable Latin-1 characters
* and spaces; To reduce the chances for human misreading of a keyword,
* leading spaces, trailing spaces, and consecutive spaces are not
* permitted in keywords.
*
* See: http://www.w3.org/TR/PNG/#11keywords
*/
return false;
}
return false;
}
return isISOLatin(s, false);
}
/*
* According to PNG spec, keyword shall contain only printable
* Latin-1 [ISO-8859-1] characters and spaces; that is, only
* character codes 32-126 and 161-255 decimal are allowed.
* For Latin-1 value fields the 0x10 (linefeed) control
* character is aloowed too.
*
* See: http://www.w3.org/TR/PNG/#11keywords
*/
for (int i = 0; i < len; i++) {
char c = s.charAt(i);
if (c < 32 || c > 255 || (c > 126 && c < 161)) {
// not printable. Check whether this is an allowed
// control char
if (!isLineFeedAllowed || c != 0x10) {
return false;
}
}
}
return true;
}
throws IIOInvalidTreeException {
if (!node.getNodeName()
}
gAMA_present = true;
byte[] red = new byte[256];
byte[] green = new byte[256];
byte[] blue = new byte[256];
int maxindex = -1;
}
}
}
PLTE_red = new byte[numEntries];
PLTE_green = new byte[numEntries];
PLTE_blue = new byte[numEntries];
PLTE_present = true;
bKGD_present = true;
} else {
bKGD_green = green;
}
bKGD_present = true;
}
// } else if (childName.equals("ColorSpaceType")) {
// } else if (childName.equals("NumChannels")) {
}
// Use Adam7 if NumProgressiveScans > 1
// } else if (childName.equals("CompressionTypeName")) {
// } else if (childName.equals("Lossless")) {
// } else if (childName.equals("BitRate")) {
}
}
StringTokenizer t = new StringTokenizer(s);
int maxBits = -1;
while (t.hasMoreTokens()) {
}
}
if (maxBits < 1) {
maxBits = 1;
}
maxBits = 8;
}
if (maxBits > 8) {
maxBits = 16;
}
StringTokenizer t = new StringTokenizer(s);
int numTokens = t.countTokens();
if (numTokens == 1) {
} else if (numTokens == 2) {
} else if (numTokens == 3) {
} else if (numTokens == 4) {
}
sBIT_present = true;
}
// } else if (childName.equals("PlanarConfiguration")) {
// } else if (childName.equals("SampleFormat")) {
// } else if (childName.equals("SampleMSB")) {
}
}
boolean gotWidth = false;
boolean gotHeight = false;
boolean gotAspectRatio = false;
float width = -1.0F;
float height = -1.0F;
float aspectRatio = -1.0F;
gotAspectRatio = true;
gotWidth = true;
gotHeight = true;
// } else if (childName.equals("ImageOrientation")) {
// } else if
// (childName.equals("HorizontalPhysicalPixelSpacing")) {
// } else if
// (childName.equals("VerticalPhysicalPixelSpacing")) {
// } else if (childName.equals("HorizontalPosition")) {
// } else if (childName.equals("VerticalPosition")) {
// } else if (childName.equals("HorizontalPixelOffset")) {
// } else if (childName.equals("VerticalPixelOffset")) {
}
}
pHYs_present = true;
pHYs_unitSpecifier = 1;
} else if (gotAspectRatio) {
pHYs_present = true;
pHYs_unitSpecifier = 0;
// Find a reasonable rational approximation
int denom = 1;
break;
}
}
}
tIME_present = true;
// } else if (childName.equals("SubimageInterpretation")) {
// } else if (childName.equals("ImageCreationTime")) {
}
}
if (!isValidKeyword(keyword)) {
// Just ignore this node, PNG requires keywords
} else if (isISOLatin(value, true)) {
// Use a zTXt node
} else {
// Use a tEXt node
}
} else {
// Use an iTXt node
}
}
}
// } else if (name.equals("Transparency")) {
// Node child = node.getFirstChild();
// while (child != null) {
// String childName = child.getNodeName();
// if (childName.equals("Alpha")) {
// } else if (childName.equals("TransparentIndex")) {
// } else if (childName.equals("TransparentColor")) {
// } else if (childName.equals("TileTransparencies")) {
// } else if (childName.equals("TileOpacities")) {
// }
// child = child.getNextSibling();
// }
// } else {
// // fatal(node, "Unknown child of root node!");
}
}
}
// Reset all instance variables to their initial state
public void reset() {
IHDR_present = false;
PLTE_present = false;
bKGD_present = false;
cHRM_present = false;
gAMA_present = false;
hIST_present = false;
iCCP_present = false;
pHYs_present = false;
sBIT_present = false;
sPLT_present = false;
sRGB_present = false;
tIME_present = false;
tRNS_present = false;
unknownChunkData = new ArrayList<byte[]>();
}
}