--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFMetadata.java Sun Aug 17 15:54:13 2014 +0100
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 com.sun.imageio.plugins.gif;
+
+import javax.imageio.metadata.IIOInvalidTreeException;
+import javax.imageio.metadata.IIOMetadata;
+import javax.imageio.metadata.IIOMetadataFormatImpl;
+import org.w3c.dom.Node;
+
+/**
+ * Class which adds utility DOM element attribute access methods to
+ * <code>IIOMetadata</code> for subclass use.
+ */
+abstract class GIFMetadata extends IIOMetadata {
+
+ /**
+ * Represents an undefined value of integer attributes.
+ */
+ static final int UNDEFINED_INTEGER_VALUE = -1;
+
+ //
+ // Note: These attribute methods were shamelessly lifted from
+ // com.sun.imageio.plugins.png.PNGMetadata and modified.
+ //
+
+ // Shorthand for throwing an IIOInvalidTreeException
+ protected static void fatal(Node node, String reason)
+ throws IIOInvalidTreeException {
+ throw new IIOInvalidTreeException(reason, node);
+ }
+
+ // Get an integer-valued attribute
+ protected static String getStringAttribute(Node node, String name,
+ String defaultValue,
+ boolean required,
+ String[] range)
+ throws IIOInvalidTreeException {
+ Node attr = node.getAttributes().getNamedItem(name);
+ if (attr == null) {
+ if (!required) {
+ return defaultValue;
+ } else {
+ fatal(node, "Required attribute " + name + " not present!");
+ }
+ }
+ String value = attr.getNodeValue();
+
+ if (range != null) {
+ if (value == null) {
+ fatal(node,
+ "Null value for "+node.getNodeName()+
+ " attribute "+name+"!");
+ }
+ boolean validValue = false;
+ int len = range.length;
+ for (int i = 0; i < len; i++) {
+ if (value.equals(range[i])) {
+ validValue = true;
+ break;
+ }
+ }
+ if (!validValue) {
+ fatal(node,
+ "Bad value for "+node.getNodeName()+
+ " attribute "+name+"!");
+ }
+ }
+
+ return value;
+ }
+
+
+ // Get an integer-valued attribute
+ protected static int getIntAttribute(Node node, String name,
+ int defaultValue, boolean required,
+ boolean bounded, int min, int max)
+ throws IIOInvalidTreeException {
+ String value = getStringAttribute(node, name, null, required, null);
+ if (value == null || "".equals(value)) {
+ return defaultValue;
+ }
+
+ int intValue = defaultValue;
+ try {
+ intValue = Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ fatal(node,
+ "Bad value for "+node.getNodeName()+
+ " attribute "+name+"!");
+ }
+ if (bounded && (intValue < min || intValue > max)) {
+ fatal(node,
+ "Bad value for "+node.getNodeName()+
+ " attribute "+name+"!");
+ }
+ return intValue;
+ }
+
+ // Get a float-valued attribute
+ protected static float getFloatAttribute(Node node, String name,
+ float defaultValue,
+ boolean required)
+ throws IIOInvalidTreeException {
+ String value = getStringAttribute(node, name, null, required, null);
+ if (value == null) {
+ return defaultValue;
+ }
+ return Float.parseFloat(value);
+ }
+
+ // Get a required integer-valued attribute
+ protected static int getIntAttribute(Node node, String name,
+ boolean bounded, int min, int max)
+ throws IIOInvalidTreeException {
+ return getIntAttribute(node, name, -1, true, bounded, min, max);
+ }
+
+ // Get a required float-valued attribute
+ protected static float getFloatAttribute(Node node, String name)
+ throws IIOInvalidTreeException {
+ return getFloatAttribute(node, name, -1.0F, true);
+ }
+
+ // Get a boolean-valued attribute
+ protected static boolean getBooleanAttribute(Node node, String name,
+ boolean defaultValue,
+ boolean required)
+ throws IIOInvalidTreeException {
+ Node attr = node.getAttributes().getNamedItem(name);
+ if (attr == null) {
+ if (!required) {
+ return defaultValue;
+ } else {
+ fatal(node, "Required attribute " + name + " not present!");
+ }
+ }
+ String value = attr.getNodeValue();
+ // Allow lower case booleans for backward compatibility, #5082756
+ if (value.equals("TRUE") || value.equals("true")) {
+ return true;
+ } else if (value.equals("FALSE") || value.equals("false")) {
+ return false;
+ } else {
+ fatal(node, "Attribute " + name + " must be 'TRUE' or 'FALSE'!");
+ return false;
+ }
+ }
+
+ // Get a required boolean-valued attribute
+ protected static boolean getBooleanAttribute(Node node, String name)
+ throws IIOInvalidTreeException {
+ return getBooleanAttribute(node, name, false, true);
+ }
+
+ // Get an enumerated attribute as an index into a String array
+ protected static int getEnumeratedAttribute(Node node,
+ String name,
+ String[] legalNames,
+ int defaultValue,
+ boolean required)
+ throws IIOInvalidTreeException {
+ Node attr = node.getAttributes().getNamedItem(name);
+ if (attr == null) {
+ if (!required) {
+ return defaultValue;
+ } else {
+ fatal(node, "Required attribute " + name + " not present!");
+ }
+ }
+ String value = attr.getNodeValue();
+ for (int i = 0; i < legalNames.length; i++) {
+ if(value.equals(legalNames[i])) {
+ return i;
+ }
+ }
+
+ fatal(node, "Illegal value for attribute " + name + "!");
+ return -1;
+ }
+
+ // Get a required enumerated attribute as an index into a String array
+ protected static int getEnumeratedAttribute(Node node,
+ String name,
+ String[] legalNames)
+ throws IIOInvalidTreeException {
+ return getEnumeratedAttribute(node, name, legalNames, -1, true);
+ }
+
+ // Get a String-valued attribute
+ protected static String getAttribute(Node node, String name,
+ String defaultValue, boolean required)
+ throws IIOInvalidTreeException {
+ Node attr = node.getAttributes().getNamedItem(name);
+ if (attr == null) {
+ if (!required) {
+ return defaultValue;
+ } else {
+ fatal(node, "Required attribute " + name + " not present!");
+ }
+ }
+ return attr.getNodeValue();
+ }
+
+ // Get a required String-valued attribute
+ protected static String getAttribute(Node node, String name)
+ throws IIOInvalidTreeException {
+ return getAttribute(node, name, null, true);
+ }
+
+ protected GIFMetadata(boolean standardMetadataFormatSupported,
+ String nativeMetadataFormatName,
+ String nativeMetadataFormatClassName,
+ String[] extraMetadataFormatNames,
+ String[] extraMetadataFormatClassNames) {
+ super(standardMetadataFormatSupported,
+ nativeMetadataFormatName,
+ nativeMetadataFormatClassName,
+ extraMetadataFormatNames,
+ extraMetadataFormatClassNames);
+ }
+
+ public void mergeTree(String formatName, Node root)
+ throws IIOInvalidTreeException {
+ if (formatName.equals(nativeMetadataFormatName)) {
+ if (root == null) {
+ throw new IllegalArgumentException("root == null!");
+ }
+ mergeNativeTree(root);
+ } else if (formatName.equals
+ (IIOMetadataFormatImpl.standardMetadataFormatName)) {
+ if (root == null) {
+ throw new IllegalArgumentException("root == null!");
+ }
+ mergeStandardTree(root);
+ } else {
+ throw new IllegalArgumentException("Not a recognized format!");
+ }
+ }
+
+ protected byte[] getColorTable(Node colorTableNode,
+ String entryNodeName,
+ boolean lengthExpected,
+ int expectedLength)
+ throws IIOInvalidTreeException {
+ byte[] red = new byte[256];
+ byte[] green = new byte[256];
+ byte[] blue = new byte[256];
+ int maxIndex = -1;
+
+ Node entry = colorTableNode.getFirstChild();
+ if (entry == null) {
+ fatal(colorTableNode, "Palette has no entries!");
+ }
+
+ while (entry != null) {
+ if (!entry.getNodeName().equals(entryNodeName)) {
+ fatal(colorTableNode,
+ "Only a "+entryNodeName+" may be a child of a "+
+ entry.getNodeName()+"!");
+ }
+
+ int index = getIntAttribute(entry, "index", true, 0, 255);
+ if (index > maxIndex) {
+ maxIndex = index;
+ }
+ red[index] = (byte)getIntAttribute(entry, "red", true, 0, 255);
+ green[index] = (byte)getIntAttribute(entry, "green", true, 0, 255);
+ blue[index] = (byte)getIntAttribute(entry, "blue", true, 0, 255);
+
+ entry = entry.getNextSibling();
+ }
+
+ int numEntries = maxIndex + 1;
+
+ if (lengthExpected && numEntries != expectedLength) {
+ fatal(colorTableNode, "Unexpected length for palette!");
+ }
+
+ byte[] colorTable = new byte[3*numEntries];
+ for (int i = 0, j = 0; i < numEntries; i++) {
+ colorTable[j++] = red[i];
+ colorTable[j++] = green[i];
+ colorTable[j++] = blue[i];
+ }
+
+ return colorTable;
+ }
+
+ protected abstract void mergeNativeTree(Node root)
+ throws IIOInvalidTreeException;
+
+ protected abstract void mergeStandardTree(Node root)
+ throws IIOInvalidTreeException;
+}