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.util.Arrays; 048import java.util.List; 049 050import javax.imageio.metadata.IIOMetadataNode; 051 052import org.w3c.dom.Node; 053 054import com.github.jaiimageio.plugins.tiff.TIFFDirectory; 055import com.github.jaiimageio.plugins.tiff.TIFFField; 056import com.github.jaiimageio.plugins.tiff.TIFFTag; 057import com.github.jaiimageio.plugins.tiff.TIFFTagSet; 058 059/** 060 * The <code>Node</code> representation of a <code>TIFFField</code> 061 * wherein the child node is procedural rather than buffered. 062 * 063 * @since 1.1-beta 064 */ 065public class TIFFFieldNode extends IIOMetadataNode { 066 private static String getNodeName(TIFFField f) { 067 return f.getData() instanceof TIFFDirectory ? 068 "TIFFIFD" : "TIFFField"; 069 } 070 071 private boolean isIFD; 072 073 /** Initialization flag. */ 074 private Boolean isInitialized = Boolean.FALSE; 075 076 private TIFFField field; 077 078 // XXX Set the user object to "field"? 079 public TIFFFieldNode(TIFFField field) { 080 super(getNodeName(field)); 081 082 isIFD = field.getData() instanceof TIFFDirectory; 083 084 this.field = field; 085 086 TIFFTag tag = field.getTag(); 087 int tagNumber = tag.getNumber(); 088 String tagName = tag.getName(); 089 090 if(isIFD) { 091 if(tagNumber != 0) { 092 setAttribute("parentTagNumber", Integer.toString(tagNumber)); 093 } 094 if(tagName != null) { 095 setAttribute("parentTagName", tagName); 096 } 097 098 TIFFDirectory dir = (TIFFDirectory)field.getData(); 099 TIFFTagSet[] tagSets = dir.getTagSets(); 100 if(tagSets != null) { 101 String tagSetNames = ""; 102 for(int i = 0; i < tagSets.length; i++) { 103 tagSetNames += tagSets[i].getClass().getName(); 104 if(i != tagSets.length - 1) { 105 tagSetNames += ","; 106 } 107 } 108 setAttribute("tagSets", tagSetNames); 109 } 110 } else { 111 setAttribute("number", Integer.toString(tagNumber)); 112 setAttribute("name", tagName); 113 } 114 } 115 116 private synchronized void initialize() { 117 if(isInitialized == Boolean.TRUE) return; 118 119 if(isIFD) { 120 TIFFDirectory dir = (TIFFDirectory)field.getData(); 121 TIFFField[] fields = dir.getTIFFFields(); 122 if(fields != null) { 123 TIFFTagSet[] tagSets = dir.getTagSets(); 124 List tagSetList = Arrays.asList(tagSets); 125 int numFields = fields.length; 126 for(int i = 0; i < numFields; i++) { 127 TIFFField f = fields[i]; 128 int tagNumber = f.getTagNumber(); 129 TIFFTag tag = TIFFIFD.getTag(tagNumber, tagSetList); 130 131 Node node = f.getAsNativeNode(); 132 133 if (node != null) { 134 appendChild(node); 135 } 136 } 137 } 138 } else { 139 IIOMetadataNode child; 140 int count = field.getCount(); 141 if (field.getType() == TIFFTag.TIFF_UNDEFINED) { 142 child = new IIOMetadataNode("TIFFUndefined"); 143 144 byte[] data = field.getAsBytes(); 145 StringBuffer sb = new StringBuffer(); 146 for (int i = 0; i < count; i++) { 147 sb.append(Integer.toString(data[i] & 0xff)); 148 if (i < count - 1) { 149 sb.append(","); 150 } 151 } 152 child.setAttribute("value", sb.toString()); 153 } else { 154 child = new IIOMetadataNode("TIFF" + 155 field.getTypeName(field.getType()) + 156 "s"); 157 158 TIFFTag tag = field.getTag(); 159 160 for (int i = 0; i < count; i++) { 161 IIOMetadataNode cchild = 162 new IIOMetadataNode("TIFF" + 163 field.getTypeName(field.getType())); 164 165 cchild.setAttribute("value", field.getValueAsString(i)); 166 if (tag.hasValueNames() && field.isIntegral()) { 167 int value = field.getAsInt(i); 168 String name = tag.getValueName(value); 169 if (name != null) { 170 cchild.setAttribute("description", name); 171 } 172 } 173 174 child.appendChild(cchild); 175 } 176 } 177 appendChild(child); 178 } 179 180 isInitialized = Boolean.TRUE; 181 } 182 183 // Need to override this method to avoid a stack overflow exception 184 // which will occur if super.appendChild is called from initialize(). 185 public Node appendChild(Node newChild) { 186 if (newChild == null) { 187 throw new IllegalArgumentException("newChild == null!"); 188 } 189 190 return super.insertBefore(newChild, null); 191 } 192 193 // Override all methods which refer to child nodes. 194 195 public boolean hasChildNodes() { 196 initialize(); 197 return super.hasChildNodes(); 198 } 199 200 public int getLength() { 201 initialize(); 202 return super.getLength(); 203 } 204 205 public Node getFirstChild() { 206 initialize(); 207 return super.getFirstChild(); 208 } 209 210 public Node getLastChild() { 211 initialize(); 212 return super.getLastChild(); 213 } 214 215 public Node getPreviousSibling() { 216 initialize(); 217 return super.getPreviousSibling(); 218 } 219 220 public Node getNextSibling() { 221 initialize(); 222 return super.getNextSibling(); 223 } 224 225 public Node insertBefore(Node newChild, 226 Node refChild) { 227 initialize(); 228 return super.insertBefore(newChild, refChild); 229 } 230 231 public Node replaceChild(Node newChild, 232 Node oldChild) { 233 initialize(); 234 return super.replaceChild(newChild, oldChild); 235 } 236 237 public Node removeChild(Node oldChild) { 238 initialize(); 239 return super.removeChild(oldChild); 240 } 241 242 public Node cloneNode(boolean deep) { 243 initialize(); 244 return super.cloneNode(deep); 245 } 246}