001/* 002 * $RCSfile: TIFFFieldNode.java,v $ 003 * 004 * 005 * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. 006 * 007 * Redistribution and use in source and binary forms, with or without 008 * modification, are permitted provided that the following conditions 009 * are met: 010 * 011 * - Redistribution of source code must retain the above copyright 012 * notice, this list of conditions and the following disclaimer. 013 * 014 * - Redistribution in binary form must reproduce the above copyright 015 * notice, this list of conditions and the following disclaimer in 016 * the documentation and/or other materials provided with the 017 * distribution. 018 * 019 * Neither the name of Sun Microsystems, Inc. or the names of 020 * contributors may be used to endorse or promote products derived 021 * from this software without specific prior written permission. 022 * 023 * This software is provided "AS IS," without a warranty of any 024 * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND 025 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, 026 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY 027 * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL 028 * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF 029 * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS 030 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR 031 * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, 032 * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND 033 * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR 034 * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE 035 * POSSIBILITY OF SUCH DAMAGES. 036 * 037 * You acknowledge that this software is not designed or intended for 038 * use in the design, construction, operation or maintenance of any 039 * nuclear facility. 040 * 041 * $Revision: 1.2 $ 042 * $Date: 2006/04/18 20:47:02 $ 043 * $State: Exp $ 044 */ 045package com.github.jaiimageio.impl.plugins.tiff; 046 047import java.io.IOException; 048import java.io.Serializable; 049import java.util.Arrays; 050import java.util.List; 051 052import javax.imageio.metadata.IIOMetadata; 053import javax.imageio.metadata.IIOMetadataNode; 054import javax.imageio.stream.ImageOutputStream; 055 056import org.w3c.dom.Node; 057import org.w3c.dom.NodeList; 058 059import com.github.jaiimageio.impl.plugins.tiff.TIFFIFD; 060import com.github.jaiimageio.impl.plugins.tiff.TIFFImageMetadata; 061import com.github.jaiimageio.plugins.tiff.TIFFDirectory; 062import com.github.jaiimageio.plugins.tiff.TIFFField; 063import com.github.jaiimageio.plugins.tiff.TIFFTag; 064import com.github.jaiimageio.plugins.tiff.TIFFTagSet; 065 066/** 067 * The <code>Node</code> representation of a <code>TIFFField</code> 068 * wherein the child node is procedural rather than buffered. 069 * 070 * @since 1.1-beta 071 */ 072public class TIFFFieldNode extends IIOMetadataNode { 073 private static String getNodeName(TIFFField f) { 074 return f.getData() instanceof TIFFDirectory ? 075 "TIFFIFD" : "TIFFField"; 076 } 077 078 private boolean isIFD; 079 080 /** Initialization flag. */ 081 private Boolean isInitialized = Boolean.FALSE; 082 083 private TIFFField field; 084 085 // XXX Set the user object to "field"? 086 public TIFFFieldNode(TIFFField field) { 087 super(getNodeName(field)); 088 089 isIFD = field.getData() instanceof TIFFDirectory; 090 091 this.field = field; 092 093 TIFFTag tag = field.getTag(); 094 int tagNumber = tag.getNumber(); 095 String tagName = tag.getName(); 096 097 if(isIFD) { 098 if(tagNumber != 0) { 099 setAttribute("parentTagNumber", Integer.toString(tagNumber)); 100 } 101 if(tagName != null) { 102 setAttribute("parentTagName", tagName); 103 } 104 105 TIFFDirectory dir = (TIFFDirectory)field.getData(); 106 TIFFTagSet[] tagSets = dir.getTagSets(); 107 if(tagSets != null) { 108 String tagSetNames = ""; 109 for(int i = 0; i < tagSets.length; i++) { 110 tagSetNames += tagSets[i].getClass().getName(); 111 if(i != tagSets.length - 1) { 112 tagSetNames += ","; 113 } 114 } 115 setAttribute("tagSets", tagSetNames); 116 } 117 } else { 118 setAttribute("number", Integer.toString(tagNumber)); 119 setAttribute("name", tagName); 120 } 121 } 122 123 private synchronized void initialize() { 124 if(isInitialized == Boolean.TRUE) return; 125 126 if(isIFD) { 127 TIFFDirectory dir = (TIFFDirectory)field.getData(); 128 TIFFField[] fields = dir.getTIFFFields(); 129 if(fields != null) { 130 TIFFTagSet[] tagSets = dir.getTagSets(); 131 List tagSetList = Arrays.asList(tagSets); 132 int numFields = fields.length; 133 for(int i = 0; i < numFields; i++) { 134 TIFFField f = fields[i]; 135 int tagNumber = f.getTagNumber(); 136 TIFFTag tag = TIFFIFD.getTag(tagNumber, tagSetList); 137 138 Node node = f.getAsNativeNode(); 139 140 if (node != null) { 141 appendChild(node); 142 } 143 } 144 } 145 } else { 146 IIOMetadataNode child; 147 int count = field.getCount(); 148 if (field.getType() == TIFFTag.TIFF_UNDEFINED) { 149 child = new IIOMetadataNode("TIFFUndefined"); 150 151 byte[] data = field.getAsBytes(); 152 StringBuffer sb = new StringBuffer(); 153 for (int i = 0; i < count; i++) { 154 sb.append(Integer.toString(data[i] & 0xff)); 155 if (i < count - 1) { 156 sb.append(","); 157 } 158 } 159 child.setAttribute("value", sb.toString()); 160 } else { 161 child = new IIOMetadataNode("TIFF" + 162 field.getTypeName(field.getType()) + 163 "s"); 164 165 TIFFTag tag = field.getTag(); 166 167 for (int i = 0; i < count; i++) { 168 IIOMetadataNode cchild = 169 new IIOMetadataNode("TIFF" + 170 field.getTypeName(field.getType())); 171 172 cchild.setAttribute("value", field.getValueAsString(i)); 173 if (tag.hasValueNames() && field.isIntegral()) { 174 int value = field.getAsInt(i); 175 String name = tag.getValueName(value); 176 if (name != null) { 177 cchild.setAttribute("description", name); 178 } 179 } 180 181 child.appendChild(cchild); 182 } 183 } 184 appendChild(child); 185 } 186 187 isInitialized = Boolean.TRUE; 188 } 189 190 // Need to override this method to avoid a stack overflow exception 191 // which will occur if super.appendChild is called from initialize(). 192 public Node appendChild(Node newChild) { 193 if (newChild == null) { 194 throw new IllegalArgumentException("newChild == null!"); 195 } 196 197 return super.insertBefore(newChild, null); 198 } 199 200 // Override all methods which refer to child nodes. 201 202 public boolean hasChildNodes() { 203 initialize(); 204 return super.hasChildNodes(); 205 } 206 207 public int getLength() { 208 initialize(); 209 return super.getLength(); 210 } 211 212 public Node getFirstChild() { 213 initialize(); 214 return super.getFirstChild(); 215 } 216 217 public Node getLastChild() { 218 initialize(); 219 return super.getLastChild(); 220 } 221 222 public Node getPreviousSibling() { 223 initialize(); 224 return super.getPreviousSibling(); 225 } 226 227 public Node getNextSibling() { 228 initialize(); 229 return super.getNextSibling(); 230 } 231 232 public Node insertBefore(Node newChild, 233 Node refChild) { 234 initialize(); 235 return super.insertBefore(newChild, refChild); 236 } 237 238 public Node replaceChild(Node newChild, 239 Node oldChild) { 240 initialize(); 241 return super.replaceChild(newChild, oldChild); 242 } 243 244 public Node removeChild(Node oldChild) { 245 initialize(); 246 return super.removeChild(oldChild); 247 } 248 249 public Node cloneNode(boolean deep) { 250 initialize(); 251 return super.cloneNode(deep); 252 } 253}