001    /*
002     * TIFFTag
003     * 
004     * Copyright (c) 2001, 2002, 2003 Marco Schmidt.
005     * All rights reserved.
006     */
007    
008    package net.sourceforge.jiu.codecs.tiff;
009    
010    import java.util.Vector;
011    import net.sourceforge.jiu.codecs.tiff.TIFFConstants;
012    
013    /**
014     * This encapsulates the data stored in a TIFF tag (a single image file directory entry).
015     * That includes the following items:
016     * <ul>
017     * <li>identification number, 254 or higher; see the many TAG_xyz constants in
018     *  {@link TIFFConstants} for a list of allowed values</li>
019     * <li>type; the allowed types include integer and floating point numbers, Strings etc.;
020     *  see the TAG_TYPE_xyz constants in {@link TIFFConstants}</li>
021     * <li>count; the number of values of the given type that are stored in this tag;
022     *  1 or higher</li>
023     * <li>offset; if count is 1 and the type fits into four bytes, this is the complete
024     *   value of this tag; otherwise, it is an offset into the file to the position
025     *   that will hold the value(s)</li>
026     * </ul>
027     * See the TIFF specification manual linked in the description of {@link TIFFCodec}
028     * for more details.
029     *
030     * @author Marco Schmidt
031     * @see TIFFImageFileDirectory
032     */
033    public class TIFFTag implements TIFFConstants
034    {
035            private int id;
036            private int type;
037            private int count;
038            private int offset;
039            private Vector objects;
040    
041            /**
042             * Creates a new tag with the given ID, type, number of objects / primitives stored in it
043             * and offset value.
044             */
045            public TIFFTag(int id, int type, int count, int offset)
046            {
047                    this.id = id;
048                    this.type = type;
049                    this.count = count;
050                    if (count < 1)
051                    {
052                            throw new IllegalArgumentException("Tiff tag count value must " +
053                                    "not be smaller than 1: " + count);
054                    }
055                    this.offset = offset;
056                    objects = null;
057            }
058    
059            public TIFFTag(int id, int type, int count, int offset, Vector vector)
060            {
061                    this(id, type, count, offset);
062                    objects = vector;
063            }
064    
065            /**
066             * Returns the number of items stored in this tag.
067             */
068            public int getCount()
069            {
070                    return count;
071            }
072    
073            /**
074             * Returns an item stored in this tag an <code>int</code> value.
075             * @param index zero-based index of the integer item to be returned
076             */
077            public int getElementAsInt(int index)
078            {
079                    Object element = getObject(index);
080                    if (element == null)
081                    {
082                            throw new IllegalArgumentException("Tag does not contain a list of values.");
083                    }
084                    if (element instanceof Short)
085                    {
086                            return ((Short)element).shortValue() & 0xffff;
087                    }
088                    if (element instanceof Integer)
089                    {
090                            return ((Integer)element).intValue();
091                    }
092                    if (element instanceof Byte)
093                    {
094                            return ((Byte)element).byteValue() & 0xff;
095                    }
096                    throw new IllegalArgumentException("Element #" + index + " is not an integer value.");
097            }
098    
099            /**
100             * Returns the ID of this tag, which may be one of the TAG_xyz constants.
101             */
102            public int getId()
103            {
104                    return id;
105            }
106    
107            /**
108             * Returns an object from this tag's Vector of items,
109             * or <code>null</code> if no such Vector exists.
110             */
111            public Object getObject(int index)
112            {
113                    if (objects == null)
114                    {
115                            return null;
116                    }
117                    else
118                    {
119                            return objects.elementAt(index);
120                    }
121            }
122    
123            /**
124             * Returns the offset value stored in this tag.
125             */
126            public int getOffset()
127            {
128                    return offset;
129            }
130    
131            /**
132             * If this tag has a Vector of items and if the first item
133             * is a String, that String is returned, <code>null</code>
134             * otherwise.
135             */
136            public String getString()
137            {
138                    if (objects != null && objects.size() > 0)
139                    {
140                            Object o = objects.elementAt(0);
141                            if (o != null && o instanceof String)
142                            {
143                                    return (String)o;
144                            }
145                    }
146                    return null;
147            }
148    
149            /**
150             * Returns the type of this tag's content as a TAG_TYPE_xyz constant.
151             */
152            public int getType()
153            {
154                    return type;
155            }
156    
157            /**
158             * Returns the Vector encapsulating the items stored in this tag.
159             * @see #setVector
160             */
161            public Vector getVector()
162            {
163                    return objects;
164            }
165    
166            /**
167             * Returns if the value(s) stored in this tag are of type BYTE, SHORT or
168             * LONG.
169             * Note that BYTE and SHORT have the same meaning as in Java (one and two bytes 
170             * large) while LONG is a 32-bit-value, just like <code>int</code> in Java.
171             * @return if this tag's contains integer values <= 32 bits
172             */
173            public boolean isInt()
174            {
175                    return (type == TAG_TYPE_BYTE || type == TAG_TYPE_SHORT || type == TAG_TYPE_LONG);
176            }
177    
178            /**
179             * If this tag encapsulates more than one item or a single
180             * item that does not fit into four bytes, this Vector
181             * will store all elements in it.
182             * The size() method called on that Vector object returns 
183             * the same value as getCount().
184             * @param vector the Vector with the items to be encapsulated by this tag
185             * @see #getVector
186             */
187            public void setVector(Vector vector)
188            {
189                    objects = vector;
190            }
191    }