/* * @(#)TIFFTag.java 1.0 2010-07-24 * * Copyright (c) 2010 Werner Randelshofer, Goldau, Switzerland. * All rights reserved. * * You may not use, copy or modify this file, except in compliance with the * license agreement you entered into with Werner Randelshofer. * For details see accompanying license terms. */ package org.monte.media.tiff; import org.monte.media.math.Rational; /** * A class defining the notion of a TIFF tag. A TIFF tag is a key that may * appear in an Image File Directory (IFD). In the IFD each tag has some data * associated with it, which may consist of zero or more values of a given data * type. The combination of a tag and a value is known as an IFD Entry or TIFF * Field. * <p> * The actual tag values used in the root IFD of a standard ("baseline") tiff * stream are defined in the {@link BaselineTagSet} class. * <p> * * @author Werner Randelshofer * @version 1.0 2010-07-24 Created. */ public class TIFFTag { public final static int ASCII_MASK = 1 << IFDDataType.ASCII.getTypeNumber(); public final static int BYTE_MASK = 1 << IFDDataType.BYTE.getTypeNumber(); public final static int DOUBLE_MASK = 1 << IFDDataType.DOUBLE.getTypeNumber(); public final static int FLOAT_MASK = 1 << IFDDataType.FLOAT.getTypeNumber(); public final static int IFD_MASK = 1 << IFDDataType.IFD.getTypeNumber(); public final static int LONG_MASK = 1 << IFDDataType.LONG.getTypeNumber(); public final static int SHORT_MASK = 1 << IFDDataType.SHORT.getTypeNumber(); public final static int RATIONAL_MASK = 1 << IFDDataType.RATIONAL.getTypeNumber(); public final static int SBYTE_MASK = 1 << IFDDataType.BYTE.getTypeNumber(); public final static int SLONG_MASK = 1 << IFDDataType.SLONG.getTypeNumber(); public final static int SSHORT_MASK = 1 << IFDDataType.SSHORT.getTypeNumber(); public final static int SRATIONAL_MASK = 1 << IFDDataType.SRATIONAL.getTypeNumber(); public final static int UNDEFINED_MASK = 1 << IFDDataType.UNDEFINED.getTypeNumber(); public final static int ALL_MASK = -1; private String name; private int number; private int dataTypes; private TagSet tagSet; private ValueFormatter formatter; /** * Constructs a TIFFTag with a given name, tag number, set of legal data types, * and TagSet to which it refers. The tagSet parameter will generally be * non-null only if this TIFFTag corresponds to a pointer to a TIFF IFD. In this * case tagSet will represent the set of TIFFTags which appear in the IFD * pointed to. A TIFFTag represents an IFD pointer if and only if tagSet is * non-null or the data type TIFF_IFD_POINTER is legal. * <p> * If there are mnemonic names to be associated with the legal data values for the * tag, addValueName() should be called on the new instance for each name. * <p> * See the documentation for getDataTypes() for an explanation of how the set of data types is to be converted into a bit mask. * @param name the name of the tag; may be null. * @param number the number used to represent the tag. * @param dataTypes a bit mask indicating the set of legal data types for this tag. * @param formatter a ValueFormatter for formatting data values. */ public TIFFTag(String name, int number, int dataTypes, ValueFormatter formatter) { this.name = name; this.number = number; this.dataTypes = dataTypes; this.formatter = formatter; } /** * Constructs a TIFFTag with a given name, tag number, set of legal data types, * and TagSet to which it refers. The tagSet parameter will generally be * non-null only if this TIFFTag corresponds to a pointer to a TIFF IFD. In this * case tagSet will represent the set of TIFFTags which appear in the IFD * pointed to. A TIFFTag represents an IFD pointer if and only if tagSet is * non-null or the data type TIFF_IFD_POINTER is legal. * <p> * If there are mnemonic names to be associated with the legal data values for the * tag, addValueName() should be called on the new instance for each name. * <p> * See the documentation for getDataTypes() for an explanation of how the set of data types is to be converted into a bit mask. * @param name the name of the tag; may be null. * @param number the number used to represent the tag. * @param dataTypes a bit mask indicating the set of legal data types for this tag. */ public TIFFTag(String name, int number, int dataTypes) { this(name, number, dataTypes, null); } /** * @param tagSet the TagSet to which this tag belongs; may be null. */ /* package */ void setTagSet(TagSet tagSet) { this.tagSet = tagSet; } /** Returns the integer used to represent the tag. */ public int getNumber() { return number; } /** Returns the name of the tag, or null if the name is not known. */ public String getName() { return name; } public boolean isSynthetic() { return number < 0; } public IFDDataType getType(Object data) { int m = dataTypes; if (data != null && data.getClass().isArray()) { data = ((Object[]) data)[0]; } for (int i = 0; i < 32; i++) { if ((m & 1) == 1) { switch (IFDDataType.valueOf(i)) { case ASCII: if (data == null || (data instanceof String)) { return IFDDataType.ASCII; } break; case BYTE: if (data == null || (data instanceof Short)) { return IFDDataType.BYTE; } break; case DOUBLE: if (data == null || (data instanceof Double)) { return IFDDataType.DOUBLE; } break; case FLOAT: if (data == null || (data instanceof Float)) { return IFDDataType.FLOAT; } break; case IFD: if (data == null || (data instanceof Long)) { return IFDDataType.IFD; } break; case LONG: if (data == null || (data instanceof Long)) { return IFDDataType.LONG; } break; case RATIONAL: if (data == null || (data instanceof Rational)) { return IFDDataType.RATIONAL; } break; case SBYTE: if (data == null || (data instanceof Byte)) { return IFDDataType.SBYTE; } break; case SHORT: if (data == null || (data instanceof Integer)) { return IFDDataType.SHORT; } break; case SLONG: if (data == null || (data instanceof Integer)) { return IFDDataType.SLONG; } break; case SRATIONAL: if (data == null || (data instanceof Rational)) { return IFDDataType.SRATIONAL; } break; case SSHORT: if (data == null || (data instanceof Short)) { return IFDDataType.SSHORT; } break; case UNDEFINED: if (data == null || (data instanceof Byte)) { return IFDDataType.UNDEFINED; } break; } return IFDDataType.valueOf(i); } m >>= 1; } return IFDDataType.UNDEFINED; } public Object prettyFormat(Object data) { return (formatter == null) ? data : formatter.prettyFormat(data); } public Object format(Object data) { return (formatter == null) ? data : formatter.format(data); } @Override public String toString() { return name; } public String getDescription(Object data) { return (formatter == null) ? null : formatter.descriptionFormat(data); } }