/* * 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); }}
/*
* 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);
}
}