001/*
002 * $RCSfile: TIFFTag.java,v $
003 *
004 * 
005 * Copyright (c) 2005 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.4 $
042 * $Date: 2006/04/11 22:10:35 $
043 * $State: Exp $
044 */
045package com.github.jaiimageio.plugins.tiff;
046
047import java.util.Map;
048import java.util.HashMap;
049import javax.imageio.metadata.IIOMetadataNode;
050import org.w3c.dom.Node;
051
052/**
053 * A class defining the notion of a TIFF tag.  A TIFF tag is a key
054 * that may appear in an Image File Directory (IFD).  In the IFD
055 * each tag has some data associated with it, which may consist of zero
056 * or more values of a given data type. The combination of a tag and a
057 * value is known as an IFD Entry or TIFF Field.
058 *
059 * <p> The actual tag values used in the root IFD of a standard ("baseline")
060 * tiff stream are defined in the {@link BaselineTIFFTagSet
061 * <code>BaselineTIFFTagSet</code>} class.
062 *
063 * @see BaselineTIFFTagSet
064 * @see TIFFField
065 * @see TIFFTagSet
066 */
067public class TIFFTag {
068
069    // TIFF 6.0 + Adobe PageMaker(R) 6.0 TIFF Technical Notes 1 IFD data type
070
071    /** Flag for 8 bit unsigned integers. */
072    public static final int TIFF_BYTE        =  1;
073
074    /** Flag for null-terminated ASCII strings. */
075    public static final int TIFF_ASCII       =  2;
076
077    /** Flag for 16 bit unsigned integers. */
078    public static final int TIFF_SHORT       =  3;
079
080    /** Flag for 32 bit unsigned integers. */
081    public static final int TIFF_LONG        =  4;
082
083    /** Flag for pairs of 32 bit unsigned integers. */
084    public static final int TIFF_RATIONAL    =  5;
085
086    /** Flag for 8 bit signed integers. */
087    public static final int TIFF_SBYTE       =  6;
088
089    /** Flag for 8 bit uninterpreted bytes. */
090    public static final int TIFF_UNDEFINED   =  7;
091
092    /** Flag for 16 bit signed integers. */
093    public static final int TIFF_SSHORT      =  8;
094
095    /** Flag for 32 bit signed integers. */
096    public static final int TIFF_SLONG       =  9;
097
098    /** Flag for pairs of 32 bit signed integers. */
099    public static final int TIFF_SRATIONAL   = 10;
100
101    /** Flag for 32 bit IEEE floats. */
102    public static final int TIFF_FLOAT       = 11;
103
104    /** Flag for 64 bit IEEE doubles. */
105    public static final int TIFF_DOUBLE      = 12;
106
107    /**
108     * Flag for IFD pointer defined in TIFF Tech Note 1 in
109     * TIFF Specification Supplement 1.
110     */
111    public static final int TIFF_IFD_POINTER = 13;
112
113    /**
114     * The numerically smallest constant representing a TIFF data type.
115     */
116    public static final int MIN_DATATYPE = TIFF_BYTE;
117
118    /**
119     * The numerically largest constant representing a TIFF data type.
120     */
121    public static final int MAX_DATATYPE = TIFF_IFD_POINTER;
122
123    private static final int[] sizeOfType = {
124        0, //  0 = n/a
125        1, //  1 = byte
126        1, //  2 = ascii
127        2, //  3 = short
128        4, //  4 = long
129        8, //  5 = rational
130        1, //  6 = sbyte
131        1, //  7 = undefined
132        2, //  8 = sshort
133        4, //  9 = slong
134        8, // 10 = srational
135        4, // 11 = float
136        8, // 12 = double 
137        4, // 13 = IFD_POINTER
138    };
139
140    // Other tags
141
142    // Tech notes: http://partners.adobe.com/asn/developer/pdfs/tn/TIFFPM6.pdf
143
144//     // Tech note 1: TIFF Trees
145//     // Adds additional data type 13 = "IFD" (like LONG)
146//     public static final int TAG_SUB_IFDS = 330; // IFD or LONG)
147
148//     // Tech note 2: Clipping Path
149//     public static final int TAG_CLIP_PATH = 343; // BYTE
150//     public static final int TAG_X_CLIP_PATH_UNITS = 344; // DWORD
151//     public static final int TAG_Y_CLIP_PATH_UNITS = 345; // DWORD
152        
153//     // Tech note 3: Indexed Images
154//     public static final int TAG_INDEXED = 346; // SHORT
155    
156//     // Tech note 4: ICC L*a*b*
157//     // New PhotometricInterpretation = 9
158
159//     // Adobe
160
161//     // PageMaker stuff
162//     public static final int TAG_IMAGE_ID = 32781; // ASCII
163//     public static final int TAG_OPI_PROXY = 351; // SHORT
164
165//     // Photoshop stuff
166//     public static final int TAG_IMAGE_SOURCE_DATA = 37724; // UNDEFINED
167//     // 34377 - Image Resource Blocks
168    
169//     // GeoTIFF
170//     public static final int TAG_MODEL_PIXEL_SCALE = 33550;
171//     public static final int TAG_MODEL_TRANSFORMATION = 34264;
172//     public static final int TAG_MODEL_TIEPOINT = 33922;
173//     public static final int TAG_GEO_KEY_DIRECTORY = 34735;
174//     public static final int TAG_GEO_DOUBLE_PARAMS = 34736;
175//     public static final int TAG_GEO_ASCII_PARAMS = 34737;
176//     public static final int TAG_INTERGRAPH_MATRIX = 33920;
177
178//     // 33918 - Intergraph
179//     // See http://remotesensing.org/lists/libtiff_archive/msg00557.html    
180
181//     // Helios ICC profile tagging
182    
183//     // 34841 - HELIOS ICC profile reference       (ASCII)
184
185//     // eiSTream Annotation Specification , Version 1.00.06
186//     // Formerly Wang?
187
188//     // 32932 - eiStream Annotation Data           (BYTE/any)
189//     // 32934 - ???
190
191    int number;
192
193    String name;
194
195    int dataTypes;
196
197    TIFFTagSet tagSet = null;
198
199    // Mnemonic names for integral enumerated constants
200    Map valueNames = null;
201
202    /**
203     * Constructs a <code>TIFFTag</code> with a given name, tag number, set
204     * of legal data types, and <code>TIFFTagSet</code> to which it refers.
205     * The <code>tagSet</code> parameter will generally be
206     * non-<code>null</code> only if this <code>TIFFTag</code> corresponds
207     * to a pointer to a TIFF IFD. In this case <code>tagSet</code> will
208     * represent the set of <code>TIFFTag</code>s which appear in the IFD
209     * pointed to. A <code>TIFFTag</code> represents an IFD pointer if and
210     * only if <code>tagSet</code> is non-<code>null</code> or the data
211     * type <code>TIFF_IFD_POINTER</code> is legal.
212     *
213     * <p> If there are mnemonic names to be associated with the legal
214     * data values for the tag, {@link #addValueName(int, String)
215     * <code>addValueName()</code>} should be called on the new instance
216     * for each name.</p>
217     *
218     * <p> See the documentation for {@link #getDataTypes()
219     * <code>getDataTypes()</code>} for an explanation of how the set
220     * of data types is to be converted into a bit mask.</p>
221     *
222     * @param name the name of the tag; may be <code>null</code>.
223     * @param number the number used to represent the tag.
224     * @param dataTypes a bit mask indicating the set of legal data
225     * types for this tag.
226     * @param tagSet the <code>TIFFTagSet</code> to which this tag
227     * belongs; may be <code>null</code>.
228     */
229    public TIFFTag(String name, int number, int dataTypes, TIFFTagSet tagSet) {
230        this.name = name;
231        this.number = number;
232        this.dataTypes = dataTypes;
233        this.tagSet = tagSet;
234    }
235
236    /**
237     * Constructs  a  <code>TIFFTag</code>  with  a  given  name,  tag
238     * number,  and set  of  legal  data  types.  The  tag  will  have  no
239     * associated <code>TIFFTagSet</code>.
240     *
241     * @param name the name of the tag; may be <code>null</code>.
242     * @param number the number used to represent the tag.
243     * @param dataTypes a bit mask indicating the set of legal data
244     * types for this tag.
245     *
246     * @see #TIFFTag(String, int, int, TIFFTagSet)
247     */
248    public TIFFTag(String name, int number, int dataTypes) {
249        this(name, number, dataTypes, null);
250    }
251
252    /**
253     * Returns the number of bytes used to store a value of the given
254     * data type.
255     *
256     * @param dataType the data type to be queried.
257     *
258     * @return the number of bytes used to store the given data type.
259     *
260     * @throws IllegalArgumentException if <code>datatype</code> is
261     * less than <code>MIN_DATATYPE</code> or greater than
262     * <code>MAX_DATATYPE</code>.
263     */
264    public static int getSizeOfType(int dataType) {
265        if (dataType < MIN_DATATYPE ||dataType > MAX_DATATYPE) {
266            throw new IllegalArgumentException("dataType out of range!");
267        }
268            
269        return sizeOfType[dataType];
270    }
271
272    /**
273     * Returns the name of the tag, as it will appear in image metadata.
274     *
275     * @return the tag name, as a <code>String</code>.
276     */
277    public String getName() {
278        return name;
279    }
280
281    /**
282     * Returns the integer used to represent the tag.
283     *
284     * @return the tag number, as an <code>int</code>.
285     */
286    public int getNumber() {
287        return number;
288    }
289
290    /**
291     * Returns a bit mask indicating the set of data types that may
292     * be used to store the data associated with the tag.
293     * For example, a tag that can store both SHORT and LONG values
294     * would return a value of:
295     *
296     * <pre>
297     * (1 << TIFFTag.TIFF_SHORT) | (1 << TIFFTag.TIFF_LONG)
298     * </pre>
299     *
300     * @return an <code>int</code> containing a bitmask encoding the
301     * set of valid data types.
302     */
303    public int getDataTypes() {
304        return dataTypes;
305    }
306
307    /**
308     * Returns <code>true</code> if the given data type
309     * may be used for the data associated with this tag.
310     *
311     * @param dataType the data type to be queried, one of
312     * <code>TIFF_BYTE</code>, <code>TIFF_SHORT</code>, etc.
313     *
314     * @return a <code>boolean</code> indicating whether the given
315     * data type may be used with this tag.
316     *
317     * @throws IllegalArgumentException if <code>datatype</code> is
318     * less than <code>MIN_DATATYPE</code> or greater than
319     * <code>MAX_DATATYPE</code>.
320     */
321    public boolean isDataTypeOK(int dataType) {
322        if (dataType < MIN_DATATYPE || dataType > MAX_DATATYPE) {
323            throw new IllegalArgumentException("datatype not in range!");
324        }
325        return (dataTypes & (1 << dataType)) != 0;
326    }
327
328    /**
329     * Returns the <code>TIFFTagSet</code> of which this tag is a part.
330     *
331     * @return the containing <code>TIFFTagSet</code>.
332     */
333    public TIFFTagSet getTagSet() {
334        return tagSet;
335    }
336
337    /**
338     * Returns <code>true</code> if this tag is used to point to an IFD
339     * structure containing additional tags.  This condition will be
340     * satisfied if and only if either
341     * <code>getTagSet()&nbsp;!=&nbsp;null</code> or
342     * <code>isDataTypeOK(TIFF_IFD_POINTER)&nbsp;==&nbsp;true</code>.
343     *
344     * <p>Many TIFF extensions use this mechanism in order to limit the
345     * number of new tags that may appear in the root IFD.</p>
346     *
347     * @return <code>true</code> if this tag points to an IFD.
348     */
349    public boolean isIFDPointer() {
350        return tagSet != null || ((dataTypes & (1 << TIFF_IFD_POINTER)) != 0);
351    }
352
353    /**
354     * Returns <code>true</code> if there are mnemonic names associated with
355     * the set of legal values for the data associated with this tag.
356     *
357     * @return <code>true</code> if mnemonic value names are available.
358     */
359    public boolean hasValueNames() {
360        return valueNames != null;
361    }
362
363    /**
364     * Adds a mnemonic name for a particular value that this tag's
365     * data may take on.
366     *
367     * @param value the data value.
368     * @param name the name to associate with the value.
369     */
370    protected void addValueName(int value, String name) {
371        if (valueNames == null) {
372            valueNames = new HashMap();
373        }
374        valueNames.put(new Integer(value), name);
375    }
376    
377    /**
378     * Returns the mnemonic name associated with a particular value
379     * that this tag's data may take on, or <code>null</code> if
380     * no name is present.
381     *
382     * @param value the data value.
383     *
384     * @return the mnemonic name associated with the value, as a
385     * <code>String</code>.
386     */
387    public String getValueName(int value) {
388        if (valueNames == null) {
389            return null;
390        }
391        return (String)valueNames.get(new Integer(value));
392    }
393    
394}