1 /* 2 * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package com.sun.imageio.plugins.tiff; 26 27 import java.util.Arrays; 28 import java.util.List; 29 import javax.imageio.metadata.IIOMetadataNode; 30 import org.w3c.dom.Node; 31 import javax.imageio.plugins.tiff.TIFFDirectory; 32 import javax.imageio.plugins.tiff.TIFFField; 33 import javax.imageio.plugins.tiff.TIFFTag; 34 import javax.imageio.plugins.tiff.TIFFTagSet; 35 36 /** 37 * The {@code Node} representation of a {@code TIFFField} 38 * wherein the child node is procedural rather than buffered. 39 */ 40 public class TIFFFieldNode extends IIOMetadataNode { 41 private static String getNodeName(TIFFField f) { 42 return (f.hasDirectory() || f.getData() instanceof TIFFDirectory) ? 43 "TIFFIFD" : "TIFFField"; 44 } 45 46 private boolean isIFD; 47 48 private Boolean isInitialized = Boolean.FALSE; 49 50 private TIFFField field; 51 52 public TIFFFieldNode(TIFFField field) { 53 super(getNodeName(field)); 54 55 isIFD = field.hasDirectory() || 56 field.getData() instanceof TIFFDirectory; 57 58 this.field = field; 59 60 TIFFTag tag = field.getTag(); 61 int tagNumber = tag.getNumber(); 62 String tagName = tag.getName(); 63 64 if(isIFD) { 65 if(tagNumber != 0) { 66 setAttribute("parentTagNumber", Integer.toString(tagNumber)); 67 } 68 if(tagName != null) { 69 setAttribute("parentTagName", tagName); 70 } 71 72 TIFFDirectory dir = field.hasDirectory() ? 73 field.getDirectory() : (TIFFDirectory)field.getData(); 74 TIFFTagSet[] tagSets = dir.getTagSets(); 75 if(tagSets != null) { 76 StringBuilder tagSetNames = new StringBuilder(); 77 for(int i = 0; i < tagSets.length; i++) { 78 tagSetNames.append(tagSets[i].getClass().getName()); 79 if(i != tagSets.length - 1) { 80 tagSetNames.append(","); 81 } 82 } 83 setAttribute("tagSets", tagSetNames.toString()); 84 } 85 } else { 86 setAttribute("number", Integer.toString(tagNumber)); 87 setAttribute("name", tagName); 88 } 89 } 90 91 private synchronized void initialize() { 92 if(isInitialized) return; 93 94 if(isIFD) { 95 TIFFDirectory dir = field.hasDirectory() ? 96 field.getDirectory() : (TIFFDirectory)field.getData(); 97 TIFFField[] fields = dir.getTIFFFields(); 98 if(fields != null) { 99 TIFFTagSet[] tagSets = dir.getTagSets(); 100 List<TIFFTagSet> tagSetList = Arrays.asList(tagSets); 101 int numFields = fields.length; 102 for(int i = 0; i < numFields; i++) { 103 TIFFField f = fields[i]; 104 int tagNumber = f.getTagNumber(); 105 TIFFTag tag = TIFFIFD.getTag(tagNumber, tagSetList); 106 107 Node node = f.getAsNativeNode(); 108 109 if (node != null) { 110 appendChild(node); 111 } 112 } 113 } 114 } else { 115 IIOMetadataNode child; 116 int count = field.getCount(); 117 if (field.getType() == TIFFTag.TIFF_UNDEFINED) { 118 child = new IIOMetadataNode("TIFFUndefined"); 119 120 byte[] data = field.getAsBytes(); 121 StringBuffer sb = new StringBuffer(); 122 for (int i = 0; i < count; i++) { 123 sb.append(Integer.toString(data[i] & 0xff)); 124 if (i < count - 1) { 125 sb.append(","); 126 } 127 } 128 child.setAttribute("value", sb.toString()); 129 } else { 130 child = new IIOMetadataNode("TIFF" + 131 TIFFField.getTypeName(field.getType()) + 132 "s"); 133 134 TIFFTag tag = field.getTag(); 135 136 for (int i = 0; i < count; i++) { 137 IIOMetadataNode cchild = 138 new IIOMetadataNode("TIFF" + 139 TIFFField.getTypeName(field.getType())); 140 141 cchild.setAttribute("value", field.getValueAsString(i)); 142 if (tag.hasValueNames() && field.isIntegral()) { 143 int value = field.getAsInt(i); 144 String name = tag.getValueName(value); 145 if (name != null) { 146 cchild.setAttribute("description", name); 147 } 148 } 149 150 child.appendChild(cchild); 151 } 152 } 153 appendChild(child); 154 } 155 156 isInitialized = Boolean.TRUE; 157 } 158 159 // Need to override this method to avoid a stack overflow exception 160 // which will occur if super.appendChild is called from initialize(). 161 public Node appendChild(Node newChild) { 162 if (newChild == null) { 163 throw new NullPointerException("newChild == null!"); 164 } 165 166 return super.insertBefore(newChild, null); 167 } 168 169 // Override all methods which refer to child nodes. 170 171 public boolean hasChildNodes() { 172 initialize(); 173 return super.hasChildNodes(); 174 } 175 176 public int getLength() { 177 initialize(); 178 return super.getLength(); 179 } 180 181 public Node getFirstChild() { 182 initialize(); 183 return super.getFirstChild(); 184 } 185 186 public Node getLastChild() { 187 initialize(); 188 return super.getLastChild(); 189 } 190 191 public Node getPreviousSibling() { 192 initialize(); 193 return super.getPreviousSibling(); 194 } 195 196 public Node getNextSibling() { 197 initialize(); 198 return super.getNextSibling(); 199 } 200 201 public Node insertBefore(Node newChild, 202 Node refChild) { 203 initialize(); 204 return super.insertBefore(newChild, refChild); 205 } 206 207 public Node replaceChild(Node newChild, 208 Node oldChild) { 209 initialize(); 210 return super.replaceChild(newChild, oldChild); 211 } 212 213 public Node removeChild(Node oldChild) { 214 initialize(); 215 return super.removeChild(oldChild); 216 } 217 218 public Node cloneNode(boolean deep) { 219 initialize(); 220 return super.cloneNode(deep); 221 } 222 } --- EOF ---