1 /*
   2  * Copyright (c) 2005, 2015, 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 javax.imageio.plugins.tiff;
  26 
  27 import java.util.Iterator;
  28 import java.util.Set;
  29 import java.util.SortedMap;
  30 import java.util.TreeMap;
  31 
  32 /**
  33  * A class defining the notion of a TIFF tag.  A TIFF tag is a key
  34  * that may appear in an Image File Directory (IFD).  In the IFD
  35  * each tag has some data associated with it, which may consist of zero
  36  * or more values of a given data type. The combination of a tag and a
  37  * value is known as an IFD Entry or TIFF Field.
  38  *
  39  * <p> The actual tag values used in the root IFD of a standard ("baseline")
  40  * tiff stream are defined in the {@link BaselineTIFFTagSet
  41  * BaselineTIFFTagSet} class.
  42  *
  43  * @since 1.9
  44  * @see   BaselineTIFFTagSet
  45  * @see   TIFFField
  46  * @see   TIFFTagSet
  47  */
  48 public class TIFFTag {
  49 
  50     // TIFF 6.0 + Adobe PageMaker(R) 6.0 TIFF Technical Notes 1 IFD data type
  51 
  52     /** Flag for 8 bit unsigned integers. */
  53     public static final int TIFF_BYTE        =  1;
  54 
  55     /** Flag for null-terminated ASCII strings. */
  56     public static final int TIFF_ASCII       =  2;
  57 
  58     /** Flag for 16 bit unsigned integers. */
  59     public static final int TIFF_SHORT       =  3;
  60 
  61     /** Flag for 32 bit unsigned integers. */
  62     public static final int TIFF_LONG        =  4;
  63 
  64     /** Flag for pairs of 32 bit unsigned integers. */
  65     public static final int TIFF_RATIONAL    =  5;
  66 
  67     /** Flag for 8 bit signed integers. */
  68     public static final int TIFF_SBYTE       =  6;
  69 
  70     /** Flag for 8 bit uninterpreted bytes. */
  71     public static final int TIFF_UNDEFINED   =  7;
  72 
  73     /** Flag for 16 bit signed integers. */
  74     public static final int TIFF_SSHORT      =  8;
  75 
  76     /** Flag for 32 bit signed integers. */
  77     public static final int TIFF_SLONG       =  9;
  78 
  79     /** Flag for pairs of 32 bit signed integers. */
  80     public static final int TIFF_SRATIONAL   = 10;
  81 
  82     /** Flag for 32 bit IEEE floats. */
  83     public static final int TIFF_FLOAT       = 11;
  84 
  85     /** Flag for 64 bit IEEE doubles. */
  86     public static final int TIFF_DOUBLE      = 12;
  87 
  88     /**
  89      * Flag for IFD pointer defined in TIFF Tech Note 1 in
  90      * TIFF Specification Supplement 1.
  91      */
  92     public static final int TIFF_IFD_POINTER = 13;
  93 
  94     /**
  95      * The numerically smallest constant representing a TIFF data type.
  96      */
  97     public static final int MIN_DATATYPE = TIFF_BYTE;
  98 
  99     /**
 100      * The numerically largest constant representing a TIFF data type.
 101      */
 102     public static final int MAX_DATATYPE = TIFF_IFD_POINTER;
 103 
 104     /**
 105      * The name assigned to a tag with an unknown tag number. Such
 106      * a tag may be created for example when reading an IFD and a
 107      * tag number is encountered which is not in any of the
 108      * <code>TIFFTagSet</code>s known to the reader.
 109      */
 110     public static final String UNKNOWN_TAG_NAME = "UnknownTag";
 111 
 112     /**
 113      * Disallowed data type mask.
 114      */
 115     private static final int DISALLOWED_DATATYPES_MASK = ~0x3fff;
 116 
 117     private static final int[] SIZE_OF_TYPE = {
 118         0, //  0 = n/a
 119         1, //  1 = byte
 120         1, //  2 = ascii
 121         2, //  3 = short
 122         4, //  4 = long
 123         8, //  5 = rational
 124         1, //  6 = sbyte
 125         1, //  7 = undefined
 126         2, //  8 = sshort
 127         4, //  9 = slong
 128         8, // 10 = srational
 129         4, // 11 = float
 130         8, // 12 = double
 131         4, // 13 = IFD_POINTER
 132     };
 133 
 134     private int number;
 135     private String name;
 136     private int dataTypes;
 137     private int count;
 138     private TIFFTagSet tagSet = null;
 139 
 140     // Mnemonic names for integral enumerated constants
 141     private SortedMap<Integer,String> valueNames = null;
 142 
 143     /**
 144      * Constructs a <code>TIFFTag</code> with a given name, tag number, set
 145      * of legal data types, and value count. A negative value count signifies
 146      * that either an arbitrary number of values is legal or the required count
 147      * is determined by the values of other fields in the IFD. A non-negative
 148      * count specifies the number of values which an associated field must
 149      * contain. The tag will have no associated <code>TIFFTagSet</code>.
 150      *
 151      * <p> If there are mnemonic names to be associated with the legal
 152      * data values for the tag, {@link #addValueName(int, String)
 153      * addValueName()} should be called on the new instance for each name.
 154      * Mnemonic names apply only to tags which have integral data type.</p>
 155      *
 156      * <p> See the documentation for {@link #getDataTypes()
 157      * getDataTypes()} for an explanation of how the set
 158      * of data types is to be converted into a bit mask.</p>
 159      *
 160      * @param name the name of the tag.
 161      * @param number the number used to represent the tag.
 162      * @param dataTypes a bit mask indicating the set of legal data
 163      * types for this tag.
 164      * @param count the value count for this tag.
 165      * @throws NullPointerException if name is null.
 166      * @throws IllegalArgumentException if number is negative or dataTypes
 167      * is negative or specifies an out of range type.
 168      */
 169     public TIFFTag(String name, int number, int dataTypes, int count) {
 170         if (name == null) {
 171             throw new NullPointerException("name == null");
 172         } else if (number < 0) {
 173             throw new IllegalArgumentException("number (" + number + ") < 0");
 174         } else if (dataTypes < 0
 175             || (dataTypes & DISALLOWED_DATATYPES_MASK) != 0) {
 176             throw new IllegalArgumentException("dataTypes out of range");
 177         }
 178 
 179         this.name = name;
 180         this.number = number;
 181         this.dataTypes = dataTypes;
 182         this.count = count;
 183     }
 184 
 185     /**
 186      * Constructs a <code>TIFFTag</code> with a given name, tag number and
 187      * <code>TIFFTagSet</code> to which it refers. The legal data types are
 188      * set to include {@link #TIFF_LONG} and {@link #TIFF_IFD_POINTER} and the
 189      * value count is unity. The <code>TIFFTagSet</code> will
 190      * represent the set of <code>TIFFTag</code>s which appear in the IFD
 191      * pointed to. A <code>TIFFTag</code> represents an IFD pointer if and
 192      * only if <code>tagSet</code> is non-<code>null</code> or the data
 193      * type <code>TIFF_IFD_POINTER</code> is legal.
 194      *
 195      * @param name the name of the tag.
 196      * @param number the number used to represent the tag.
 197      * @param tagSet the <code>TIFFTagSet</code> to which this tag belongs.
 198      * @throws NullPointerException if name or tagSet is null.
 199      * @throws IllegalArgumentException if number is negative.
 200      *
 201      * @see #TIFFTag(String, int, int, int)
 202      */
 203     public TIFFTag(String name, int number, TIFFTagSet tagSet) {
 204         this(name, number,
 205             1 << TIFFTag.TIFF_LONG | 1 << TIFFTag.TIFF_IFD_POINTER, 1);
 206         if (tagSet == null) {
 207             throw new NullPointerException("tagSet == null");
 208         }
 209         this.tagSet = tagSet;
 210     }
 211 
 212     /**
 213      * Constructs  a  <code>TIFFTag</code>  with  a  given  name,  tag number,
 214      * and set  of  legal  data  types.  The value count of the tag will be
 215      * undefined and it will  have  no associated <code>TIFFTagSet</code>.
 216      *
 217      * @param name the name of the tag.
 218      * @param number the number used to represent the tag.
 219      * @param dataTypes a bit mask indicating the set of legal data
 220      * types for this tag.
 221      * @throws NullPointerException if name is null.
 222      * @throws IllegalArgumentException if number is negative or dataTypes
 223      * is negative or specifies an out of range type.
 224      *
 225      * @see #TIFFTag(String, int, int, int)
 226      */
 227     public TIFFTag(String name, int number, int dataTypes) {
 228         this(name, number, dataTypes, -1);
 229     }
 230 
 231     /**
 232      * Returns the number of bytes used to store a value of the given
 233      * data type.
 234      *
 235      * @param dataType the data type to be queried.
 236      *
 237      * @return the number of bytes used to store the given data type.
 238      *
 239      * @throws IllegalArgumentException if <code>datatype</code> is
 240      * less than <code>MIN_DATATYPE</code> or greater than
 241      * <code>MAX_DATATYPE</code>.
 242      */
 243     public static int getSizeOfType(int dataType) {
 244         if (dataType < MIN_DATATYPE ||dataType > MAX_DATATYPE) {
 245             throw new IllegalArgumentException("dataType out of range!");
 246         }
 247 
 248         return SIZE_OF_TYPE[dataType];
 249     }
 250 
 251     /**
 252      * Returns the name of the tag, as it will appear in image metadata.
 253      *
 254      * @return the tag name, as a <code>String</code>.
 255      */
 256     public String getName() {
 257         return name;
 258     }
 259 
 260     /**
 261      * Returns the integer used to represent the tag.
 262      *
 263      * @return the tag number, as an <code>int</code>.
 264      */
 265     public int getNumber() {
 266         return number;
 267     }
 268 
 269     /**
 270      * Returns a bit mask indicating the set of data types that may
 271      * be used to store the data associated with the tag.
 272      * For example, a tag that can store both SHORT and LONG values
 273      * would return a value of:
 274      *
 275      * <pre>
 276      * (1 &lt;&lt; TIFFTag.TIFF_SHORT) | (1 &lt;&lt; TIFFTag.TIFF_LONG)
 277      * </pre>
 278      *
 279      * @return an <code>int</code> containing a bitmask encoding the
 280      * set of valid data types.
 281      */
 282     public int getDataTypes() {
 283         return dataTypes;
 284     }
 285 
 286     /**
 287      * Returns the value count of this tag. If this value is positive, it
 288      * represents the required number of values for a <code>TIFFField</code>
 289      * which has this tag. If the value is negative, the count is undefined.
 290      * In the latter case the count may be derived, e.g., the number of values
 291      * of the <code>BitsPerSample</code> field is <code>SamplesPerPixel</code>,
 292      * or it may be variable as in the case of most <code>US-ASCII</code>
 293      * fields.
 294      *
 295      * @return the value count of this tag.
 296      */
 297     public int getCount() {
 298         return count;
 299     }
 300 
 301     /**
 302      * Returns <code>true</code> if the given data type
 303      * may be used for the data associated with this tag.
 304      *
 305      * @param dataType the data type to be queried, one of
 306      * <code>TIFF_BYTE</code>, <code>TIFF_SHORT</code>, etc.
 307      *
 308      * @return a <code>boolean</code> indicating whether the given
 309      * data type may be used with this tag.
 310      *
 311      * @throws IllegalArgumentException if <code>datatype</code> is
 312      * less than <code>MIN_DATATYPE</code> or greater than
 313      * <code>MAX_DATATYPE</code>.
 314      */
 315     public boolean isDataTypeOK(int dataType) {
 316         if (dataType < MIN_DATATYPE || dataType > MAX_DATATYPE) {
 317             throw new IllegalArgumentException("datatype not in range!");
 318         }
 319         return (dataTypes & (1 << dataType)) != 0;
 320     }
 321 
 322     /**
 323      * Returns the <code>TIFFTagSet</code> of which this tag is a part.
 324      *
 325      * @return the containing <code>TIFFTagSet</code>.
 326      */
 327     public TIFFTagSet getTagSet() {
 328         return tagSet;
 329     }
 330 
 331     /**
 332      * Returns <code>true</code> if this tag is used to point to an IFD
 333      * structure containing additional tags. A <code>TIFFTag</code> represents
 334      * an IFD pointer if and only if its <code>TIFFTagSet</code> is
 335      * non-<code>null</code> or the data type <code>TIFF_IFD_POINTER</code> is
 336      * legal. This condition will be satisfied if and only if either
 337      * <code>getTagSet()&nbsp;!=&nbsp;null</code> or
 338      * <code>isDataTypeOK(TIFF_IFD_POINTER)&nbsp;==&nbsp;true</code>.
 339      *
 340      * <p>Many TIFF extensions use the IFD mechanism in order to limit the
 341      * number of new tags that may appear in the root IFD.</p>
 342      *
 343      * @return <code>true</code> if this tag points to an IFD.
 344      */
 345     public boolean isIFDPointer() {
 346         return tagSet != null || isDataTypeOK(TIFF_IFD_POINTER);
 347     }
 348 
 349     /**
 350      * Returns <code>true</code> if there are mnemonic names associated with
 351      * the set of legal values for the data associated with this tag.  Mnemonic
 352      * names apply only to tags which have integral data type.
 353      *
 354      * @return <code>true</code> if mnemonic value names are available.
 355      */
 356     public boolean hasValueNames() {
 357         return valueNames != null;
 358     }
 359 
 360     /**
 361      * Adds a mnemonic name for a particular value that this tag's data may take
 362      * on.  Mnemonic names apply only to tags which have integral data type.
 363      *
 364      * @param value the data value.
 365      * @param name the name to associate with the value.
 366      */
 367     protected void addValueName(int value, String name) {
 368         if (valueNames == null) {
 369             valueNames = new TreeMap<Integer,String>();
 370         }
 371         valueNames.put(Integer.valueOf(value), name);
 372     }
 373 
 374     /**
 375      * Returns the mnemonic name associated with a particular value
 376      * that this tag's data may take on, or <code>null</code> if
 377      * no name is present.  Mnemonic names apply only to tags which have
 378      * integral data type.
 379      *
 380      * @param value the data value.
 381      *
 382      * @return the mnemonic name associated with the value, as a
 383      * <code>String</code>.
 384      */
 385     public String getValueName(int value) {
 386         if (valueNames == null) {
 387             return null;
 388         }
 389         return valueNames.get(Integer.valueOf(value));
 390     }
 391 
 392     /**
 393      * Returns an array of values for which mnemonic names are defined.  The
 394      * method {@link #getValueName(int) getValueName()} will return
 395      * non-{@code null} only for values contained in the returned array.
 396      * Mnemonic names apply only to tags which have integral data type.
 397      *
 398      * @return the values for which there is a mnemonic name.
 399      */
 400     public int[] getNamedValues() {
 401         int[] intValues = null;
 402         if (valueNames != null) {
 403             Set<Integer> values = valueNames.keySet();
 404             Iterator<Integer> iter = values.iterator();
 405             intValues = new int[values.size()];
 406             int i = 0;
 407             while (iter.hasNext()) {
 408                 intValues[i++] = iter.next();
 409             }
 410         }
 411         return intValues;
 412     }
 413 }