402 lines · 17.0 KB · Java
RawDownload
/* * Copyright (c) 2005, 2008, 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 java.io.UnsupportedEncodingException;import java.nio.charset.Charset;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import javax.imageio.ImageTypeSpecifier;import javax.imageio.metadata.IIOInvalidTreeException;import javax.imageio.metadata.IIOMetadata;import javax.imageio.metadata.IIOMetadataNode;import javax.imageio.metadata.IIOMetadataFormat;import javax.imageio.metadata.IIOMetadataFormatImpl;import org.w3c.dom.Node; class GIFWritableImageMetadata extends GIFImageMetadata {     // package scope    static final String    NATIVE_FORMAT_NAME = "javax_imageio_gif_image_1.0";     GIFWritableImageMetadata() {        super(true,              NATIVE_FORMAT_NAME,              "com.sun.imageio.plugins.gif.GIFImageMetadataFormat",              null, null);    }     public boolean isReadOnly() {        return false;    }     public void reset() {        // Fields from Image Descriptor        imageLeftPosition = 0;        imageTopPosition = 0;        imageWidth = 0;        imageHeight = 0;        interlaceFlag = false;        sortFlag = false;        localColorTable = null;         // Fields from Graphic Control Extension        disposalMethod = 0;        userInputFlag = false;        transparentColorFlag = false;        delayTime = 0;        transparentColorIndex = 0;         // Fields from Plain Text Extension        hasPlainTextExtension = false;        textGridLeft = 0;        textGridTop = 0;        textGridWidth = 0;        textGridHeight = 0;        characterCellWidth = 0;        characterCellHeight = 0;        textForegroundColor = 0;        textBackgroundColor = 0;        text = null;         // Fields from ApplicationExtension        applicationIDs = null;        authenticationCodes = null;        applicationData = null;         // Fields from CommentExtension        // List of byte[]        comments = null;    }     private byte[] fromISO8859(String data) {        try {            return data.getBytes("ISO-8859-1");        } catch (UnsupportedEncodingException e) {            return "".getBytes();        }    }     protected void mergeNativeTree(Node root) throws IIOInvalidTreeException {        Node node = root;        if (!node.getNodeName().equals(nativeMetadataFormatName)) {            fatal(node, "Root must be " + nativeMetadataFormatName);        }         node = node.getFirstChild();        while (node != null) {            String name = node.getNodeName();             if (name.equals("ImageDescriptor")) {                imageLeftPosition = getIntAttribute(node,                                                    "imageLeftPosition",                                                    -1, true,                                                    true, 0, 65535);                 imageTopPosition = getIntAttribute(node,                                                   "imageTopPosition",                                                   -1, true,                                                   true, 0, 65535);                 imageWidth = getIntAttribute(node,                                             "imageWidth",                                             -1, true,                                             true, 1, 65535);                 imageHeight = getIntAttribute(node,                                              "imageHeight",                                              -1, true,                                              true, 1, 65535);                 interlaceFlag = getBooleanAttribute(node, "interlaceFlag",                                                    false, true);            } else if (name.equals("LocalColorTable")) {                int sizeOfLocalColorTable =                    getIntAttribute(node, "sizeOfLocalColorTable",                                    true, 2, 256);                if (sizeOfLocalColorTable != 2 &&                    sizeOfLocalColorTable != 4 &&                    sizeOfLocalColorTable != 8 &&                    sizeOfLocalColorTable != 16 &&                    sizeOfLocalColorTable != 32 &&                    sizeOfLocalColorTable != 64 &&                    sizeOfLocalColorTable != 128 &&                    sizeOfLocalColorTable != 256) {                    fatal(node,                          "Bad value for LocalColorTable attribute sizeOfLocalColorTable!");                }                 sortFlag = getBooleanAttribute(node, "sortFlag", false, true);                 localColorTable = getColorTable(node, "ColorTableEntry",                                                true, sizeOfLocalColorTable);            } else if (name.equals("GraphicControlExtension")) {                String disposalMethodName =                    getStringAttribute(node, "disposalMethod", null,                                       true, disposalMethodNames);                disposalMethod = 0;                while(!disposalMethodName.equals(disposalMethodNames[disposalMethod])) {                    disposalMethod++;                }                 userInputFlag = getBooleanAttribute(node, "userInputFlag",                                                    false, true);                 transparentColorFlag =                    getBooleanAttribute(node, "transparentColorFlag",                                        false, true);                 delayTime = getIntAttribute(node,                                            "delayTime",                                            -1, true,                                            true, 0, 65535);                 transparentColorIndex =                    getIntAttribute(node, "transparentColorIndex",                                    -1, true,                                    true, 0, 65535);            } else if (name.equals("PlainTextExtension")) {                hasPlainTextExtension = true;                 textGridLeft = getIntAttribute(node,                                               "textGridLeft",                                               -1, true,                                               true, 0, 65535);                 textGridTop = getIntAttribute(node,                                              "textGridTop",                                              -1, true,                                              true, 0, 65535);                 textGridWidth = getIntAttribute(node,                                                "textGridWidth",                                                -1, true,                                                true, 1, 65535);                 textGridHeight = getIntAttribute(node,                                                 "textGridHeight",                                                 -1, true,                                                 true, 1, 65535);                 characterCellWidth = getIntAttribute(node,                                                     "characterCellWidth",                                                     -1, true,                                                     true, 1, 65535);                 characterCellHeight = getIntAttribute(node,                                                      "characterCellHeight",                                                      -1, true,                                                      true, 1, 65535);                 textForegroundColor = getIntAttribute(node,                                                      "textForegroundColor",                                                      -1, true,                                                      true, 0, 255);                 textBackgroundColor = getIntAttribute(node,                                                      "textBackgroundColor",                                                      -1, true,                                                      true, 0, 255);                 // XXX The "text" attribute of the PlainTextExtension element                // is not defined in the GIF image metadata format but it is                // present in the GIFImageMetadata class. Consequently it is                // used here but not required and with a default of "". See                // bug 5082763.                 String textString =                    getStringAttribute(node, "text", "", false, null);                text = fromISO8859(textString);            } else if (name.equals("ApplicationExtensions")) {                IIOMetadataNode applicationExtension =                    (IIOMetadataNode)node.getFirstChild();                 if (!applicationExtension.getNodeName().equals("ApplicationExtension")) {                    fatal(node,                          "Only a ApplicationExtension may be a child of a ApplicationExtensions!");                }                 String applicationIDString =                    getStringAttribute(applicationExtension, "applicationID",                                       null, true, null);                 String authenticationCodeString =                    getStringAttribute(applicationExtension, "authenticationCode",                                       null, true, null);                 Object applicationExtensionData =                    applicationExtension.getUserObject();                if (applicationExtensionData == null ||                    !(applicationExtensionData instanceof byte[])) {                    fatal(applicationExtension,                          "Bad user object in ApplicationExtension!");                }                 if (applicationIDs == null) {                    applicationIDs = new ArrayList();                    authenticationCodes = new ArrayList();                    applicationData = new ArrayList();                }                 applicationIDs.add(fromISO8859(applicationIDString));                authenticationCodes.add(fromISO8859(authenticationCodeString));                applicationData.add(applicationExtensionData);            } else if (name.equals("CommentExtensions")) {                Node commentExtension = node.getFirstChild();                if (commentExtension != null) {                    while(commentExtension != null) {                        if (!commentExtension.getNodeName().equals("CommentExtension")) {                            fatal(node,                                  "Only a CommentExtension may be a child of a CommentExtensions!");                        }                         if (comments == null) {                            comments = new ArrayList();                        }                         String comment =                            getStringAttribute(commentExtension, "value", null,                                               true, null);                         comments.add(fromISO8859(comment));                         commentExtension = commentExtension.getNextSibling();                    }                }            } else {                fatal(node, "Unknown child of root node!");            }             node = node.getNextSibling();        }    }     protected void mergeStandardTree(Node root)      throws IIOInvalidTreeException {        Node node = root;        if (!node.getNodeName()            .equals(IIOMetadataFormatImpl.standardMetadataFormatName)) {            fatal(node, "Root must be " +                  IIOMetadataFormatImpl.standardMetadataFormatName);        }         node = node.getFirstChild();        while (node != null) {            String name = node.getNodeName();             if (name.equals("Chroma")) {                Node childNode = node.getFirstChild();                while(childNode != null) {                    String childName = childNode.getNodeName();                    if (childName.equals("Palette")) {                        localColorTable = getColorTable(childNode,                                                        "PaletteEntry",                                                        false, -1);                        break;                    }                    childNode = childNode.getNextSibling();                }            } else if (name.equals("Compression")) {                Node childNode = node.getFirstChild();                while(childNode != null) {                    String childName = childNode.getNodeName();                    if (childName.equals("NumProgressiveScans")) {                        int numProgressiveScans =                            getIntAttribute(childNode, "value", 4, false,                                            true, 1, Integer.MAX_VALUE);                        if (numProgressiveScans > 1) {                            interlaceFlag = true;                        }                        break;                    }                    childNode = childNode.getNextSibling();                }            } else if (name.equals("Dimension")) {                Node childNode = node.getFirstChild();                while(childNode != null) {                    String childName = childNode.getNodeName();                    if (childName.equals("HorizontalPixelOffset")) {                        imageLeftPosition = getIntAttribute(childNode,                                                            "value",                                                            -1, true,                                                            true, 0, 65535);                    } else if (childName.equals("VerticalPixelOffset")) {                        imageTopPosition = getIntAttribute(childNode,                                                           "value",                                                           -1, true,                                                           true, 0, 65535);                    }                    childNode = childNode.getNextSibling();                }            } else if (name.equals("Text")) {                Node childNode = node.getFirstChild();                while(childNode != null) {                    String childName = childNode.getNodeName();                    if (childName.equals("TextEntry") &&                        getAttribute(childNode, "compression",                                     "none", false).equals("none") &&                        Charset.isSupported(getAttribute(childNode,                                                         "encoding",                                                         "ISO-8859-1",                                                         false))) {                        String value = getAttribute(childNode, "value");                        byte[] comment = fromISO8859(value);                        if (comments == null) {                            comments = new ArrayList();                        }                        comments.add(comment);                    }                    childNode = childNode.getNextSibling();                }            } else if (name.equals("Transparency")) {                Node childNode = node.getFirstChild();                while(childNode != null) {                    String childName = childNode.getNodeName();                    if (childName.equals("TransparentIndex")) {                        transparentColorIndex = getIntAttribute(childNode,                                                                "value",                                                                -1, true,                                                                true, 0, 255);                        transparentColorFlag = true;                        break;                    }                    childNode = childNode.getNextSibling();                }            }             node = node.getNextSibling();        }    }     public void setFromTree(String formatName, Node root)        throws IIOInvalidTreeException    {        reset();        mergeTree(formatName, root);    }}