jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFMetadata.java
changeset 25859 3317bb8137f4
parent 5506 202f599c92aa
child 35667 ed476aba94de
--- /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;
+}