/* * TiffMetadataStruct.java * * Created on February 17, 2006, 1:02 PM * * To change this template, choose Tools | Template Manager * and open the template in the editor. */ package edu.mbl.jif.imaging.meta; /* * TiffMetadataStruct.java * * Created on February 16, 2006, 10:24 AM * * To change this template, choose Tools | Template Manager * and open the template in the editor. */ import javax.imageio.metadata.IIOMetadata; import javax.imageio.metadata.IIOMetadataNode; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * * @author GBH */ public class TiffMetadata { //TIFFTagSet //TIFFTag. //BaselineTIFFTagSet.TAG_IMAGE_DESCRIPTION /** * The DOM element ID (tag) for a TIFF Image File Directory */ public static final String TIFF_IFD_TAG = "TIFFIFD"; /** * The DOM element ID (tag) for a TIFF Field */ public static final String TIFF_FIELD_TAG = "TIFFField"; /** * The DOM element ID (tag) for a set of TIFF Double values */ public static final String TIFF_DOUBLES_TAG = "TIFFDoubles"; /** * The DOM element ID (tag) for a single TIFF double. The * value is stored in an attribute named "value" */ public static final String TIFF_DOUBLE_TAG = "TIFFDouble"; /** * The DOM element ID (tag) for a set of TIFF Short values */ public static final String TIFF_SHORTS_TAG = "TIFFShorts"; /** * The DOM element ID (tag) for a single TIFF Short value. The * value is stored in an attribute named "value" */ public static final String TIFF_SHORT_TAG = "TIFFShort"; /** * The DOM element ID (tag) for a set of TIFF Ascii values */ public static final String TIFF_ASCIIS_TAG = "TIFFAsciis"; /** * The DOM element ID (tag) for a single TIFF Ascii value */ public static final String TIFF_ASCII_TAG = "TIFFAscii"; /** * The DOM attribute name for a TIFF Field Tag (number) */ public static final String NUMBER_ATTR = "number"; /** * The DOM attribute name for a TIFF Entry value (whether Short, * Double, or Ascii) */ public static final String VALUE_ATTR = "value"; /** * The root of the metadata DOM tree */ private IIOMetadataNode myRootNode; private IIOMetadata imageMetadata; /** * The constructor builds a metadata adapter for the image metadata * root IIOMetadataNode. * * @param imageNode The image metadata */ public TiffMetadata(IIOMetadata imageMetadata) { this.imageMetadata = imageMetadata; String formatName = imageMetadata.getNativeMetadataFormatName(); myRootNode = (IIOMetadataNode)imageMetadata.getAsTree(formatName); } public String getImageDescription() { //BaselineTIFFTagSet.TAG_IMAGE_DESCRIPTION return ""; } public int getNumericTag(int tag) { IIOMetadataNode keyDir = getTiffField(tag); if(keyDir == null) { throw new UnsupportedOperationException("directory does not exist");} IIOMetadataNode tiffShortsNode = (IIOMetadataNode)keyDir.getFirstChild(); NodeList keys = tiffShortsNode.getElementsByTagName(TIFF_SHORT_TAG); Node n = keys.item(0); int value = getIntValueAttribute(n); return value; } /** * Gets the value attribute of the given Node. * * @param node A Node containing a value attribute, for example the * node <TIFFShort value="123"> * @return A String containing the text from the value attribute. * In the above example, the string would be 123 */ protected String getValueAttribute(Node node) { return node.getAttributes().getNamedItem(VALUE_ATTR).getNodeValue(); } // public String getValueAttribute(Node node) { // NamedNodeMap attributes = node.getAttributes(); // int numAttributes = attributes.getLength(); // for(int i = 0; i < numAttributes; i++) { // Node attribute = attributes.item(i); // if(i > 0) { // System.out.println(""); // indent(0, node.getNodeName().length()+1); // } // System.out.print(" "+attribute.getNodeName()+"="); // System.out.print("\""+attribute.getNodeValue()+"\""); // /** * Gets the value attribute's contents and parses it as an int */ public int getIntValueAttribute(Node node) { return Integer.parseInt(getValueAttribute(node)); } /** * Gets a TIFFField node with the given tag number. This is done by * searching for a TIFFField with attribute number whose value is * the specified tag value. */ public IIOMetadataNode getTiffField(int tag) { IIOMetadataNode result = null; IIOMetadataNode tiffDirectory = getTiffDirectory(); NodeList children = tiffDirectory.getElementsByTagName(TIFF_FIELD_TAG); // embed the exit condition in the for loop for (int i = 0; i < children.getLength() && result == null; i++) { // search through all the TIFF fields to find the one with the // given tag value Node child = children.item(i); Node number = child.getAttributes().getNamedItem(NUMBER_ATTR); if (number != null) { int num = Integer.parseInt(number.getNodeValue()); if (num == tag) { result = (IIOMetadataNode) child; } } } return result; } /** * Gets the TIFFIFD (image file directory) node. */ public IIOMetadataNode getTiffDirectory() { // there should only be one, and it should be the only node // in the metadata, so just get it. return (IIOMetadataNode) myRootNode.getFirstChild(); } /** * Gets an array of int values stored in a TIFFShorts element that * contains a sequence of TIFFShort values. * * @param tiffField An IIOMetadataNode pointing to a TIFFField * element that contains a TIFFShorts element. */ public int[] getTiffShorts(IIOMetadataNode tiffField) { IIOMetadataNode shortsElement = (IIOMetadataNode) tiffField.getFirstChild(); NodeList shorts = shortsElement.getElementsByTagName(TIFF_SHORT_TAG); int[] result = new int[shorts.getLength()]; for (int i = 0; i < shorts.getLength(); i++) { Node node = shorts.item(i); result[i] = getIntValueAttribute(node); } return result; } /** * Gets a single TIFFShort value at the given index. * * @param tiffField An IIOMetadataNode pointing to a TIFFField * element that contains a TIFFShorts element. * @param index The 0-based index of the desired short value */ public int getTiffShort(IIOMetadataNode tiffField, int index) { IIOMetadataNode shortsElement = (IIOMetadataNode) tiffField.getFirstChild(); NodeList shorts = shortsElement.getElementsByTagName(TIFF_SHORT_TAG); Node node = shorts.item(index); int result = getIntValueAttribute(node); return result; } /** * Gets an array of double values from a TIFFDoubles TIFFField. * * @param tiffField An IIOMetadataNode pointing to a TIFFField * element that contains a TIFFDoubles element. */ public double[] getTiffDoubles(IIOMetadataNode tiffField) { IIOMetadataNode doublesElement = (IIOMetadataNode) tiffField.getFirstChild(); NodeList doubles = doublesElement.getElementsByTagName(TIFF_DOUBLE_TAG); double[] result = new double[doubles.getLength()]; for (int i = 0; i < doubles.getLength(); i++) { Node node = doubles.item(i); result[i] = Double.parseDouble(getValueAttribute(node)); } return result; } /** * Gets a single double value at the specified index from a sequence * of TIFFDoubles * * @param tiffField An IIOMetadataNode pointing to a TIFFField * element that contains a TIFFDoubles element. */ public double getTiffDouble(IIOMetadataNode tiffField, int index) { IIOMetadataNode doublesElement = (IIOMetadataNode) tiffField.getFirstChild(); NodeList doubles = doublesElement.getElementsByTagName(TIFF_DOUBLE_TAG); Node node = doubles.item(index); double result = Double.parseDouble(getValueAttribute(node)); return result; } /** * Gets a portion of a TIFFAscii string with the specified start * character and length; * * @param tiffField An IIOMetadataNode pointing to a TIFFField * element that contains a TIFFAsciis element. This element should * contain a single TiffAscii element. * @return A substring of the value contained in the TIFFAscii node, * with the final '|' character removed. */ public String getTiffAscii(IIOMetadataNode tiffField, int start, int length) { IIOMetadataNode asciisElement = (IIOMetadataNode) tiffField.getFirstChild(); NodeList asciis = asciisElement.getElementsByTagName(TIFF_ASCII_TAG); // there should be only one, so get the first Node node = asciis.item(0); // GeoTIFF specification places a vertical bar '|' in place of \0 // null delimiters so drop off the vertical bar for Java Strings String result = getValueAttribute(node).substring(start, length - 1); return result; } public String getTIFF_FIELD_TAG() { return TIFF_FIELD_TAG; } //======================================================================= // Display public static void displayIIOMetadata(IIOMetadata meta) { displayMetadata(meta.getAsTree("javax_imageio_1.0"), 0); } public static void displayIIOMetadataNative(IIOMetadata meta) { displayMetadata(meta.getAsTree(meta.getNativeMetadataFormatName()), 0); } static void indent(int level) { for (int i = 0; i < level; i++) { System.out.print(" "); } } static void displayMetadata(Node node, int level) { indent(level); // emit open tag System.out.print("<" + node.getNodeName()); NamedNodeMap map = node.getAttributes(); if (map != null) { // print attribute values int length = map.getLength(); for (int i = 0; i < length; i++) { Node attr = map.item(i); System.out.print(" " + attr.getNodeName() + "=\"" + attr.getNodeValue() + "\""); } } Node child = node.getFirstChild(); if (child != null) { System.out.println(">"); // close current tag while (child != null) { // emit child tags recursively displayMetadata(child, level + 1); child = child.getNextSibling(); } indent(level); // emit close tag System.out.println("</" + node.getNodeName() + ">"); } else { System.out.println("/>"); } } }