1 /*
2  * $RCSfile: TIFFField.java,v $
3  *
4  * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
5  *
6  * Use is subject to license terms.
7  *
8  * $Revision: 1.1 $
9  * $Date: 2005/02/11 04:55:34 $
10  * $State: Exp $
11  */
12 package com.lightcrafts.media.jai.codec;
13 
14 import java.io.Serializable;
15 
16 /**
17  * A class representing a field in a TIFF 6.0 Image File Directory.
18  *
19  * <p> The TIFF file format is described in more detail in the
20  * comments for the TIFFDescriptor class.
21  *
22  * <p> A field in a TIFF Image File Directory (IFD).  A field is defined
23  * as a sequence of values of identical data type.  TIFF 6.0 defines
24  * 12 data types, which are mapped internally onto the Java datatypes
25  * byte, int, long, float, and double.
26  *
27  * <p><b> This class is not a committed part of the JAI API.  It may
28  * be removed or changed in future releases of JAI.</b>
29  *
30  * @see com.lightcrafts.mediax.jai.operator.TIFFDescriptor
31  * @see TIFFDirectory
32  */
33 public class TIFFField extends Object implements Comparable, Serializable {
34 
35     /** Flag for 8 bit unsigned integers. */
36     public static final int TIFF_BYTE      =  1;
37 
38     /** Flag for null-terminated ASCII strings. */
39     public static final int TIFF_ASCII     =  2;
40 
41     /** Flag for 16 bit unsigned integers. */
42     public static final int TIFF_SHORT     =  3;
43 
44     /** Flag for 32 bit unsigned integers. */
45     public static final int TIFF_LONG      =  4;
46 
47     /** Flag for pairs of 32 bit unsigned integers. */
48     public static final int TIFF_RATIONAL  =  5;
49 
50     /** Flag for 8 bit signed integers. */
51     public static final int TIFF_SBYTE     =  6;
52 
53     /** Flag for 8 bit uninterpreted bytes. */
54     public static final int TIFF_UNDEFINED =  7;
55 
56     /** Flag for 16 bit signed integers. */
57     public static final int TIFF_SSHORT    =  8;
58 
59     /** Flag for 32 bit signed integers. */
60     public static final int TIFF_SLONG     =  9;
61 
62     /** Flag for pairs of 32 bit signed integers. */
63     public static final int TIFF_SRATIONAL = 10;
64 
65     /** Flag for 32 bit IEEE floats. */
66     public static final int TIFF_FLOAT     = 11;
67 
68     /** Flag for 64 bit IEEE doubles. */
69     public static final int TIFF_DOUBLE    = 12;
70 
71     /** The tag number. */
72     int tag;
73 
74     /** The tag type. */
75     int type;
76 
77     /** The number of data items present in the field. */
78     int count;
79 
80     /** The field data. */
81     Object data;
82 
83     /** The default constructor. */
TIFFField()84     TIFFField() {}
85 
86     /**
87      * Constructs a TIFFField with arbitrary data.  The data
88      * parameter must be an array of a Java type appropriate for the
89      * type of the TIFF field.  Since there is no available 32-bit
90      * unsigned datatype, long is used. The mapping between types is
91      * as follows:
92      *
93      * <table border=1>
94      * <tr>
95      * <th> TIFF type </th> <th> Java type </th>
96      * <tr>
97      * <td><tt>TIFF_BYTE</tt></td>      <td><tt>byte</tt></td>
98      * <tr>
99      * <td><tt>TIFF_ASCII</tt></td>     <td><tt>String</tt></td>
100      * <tr>
101      * <td><tt>TIFF_SHORT</tt></td>     <td><tt>char</tt></td>
102      * <tr>
103      * <td><tt>TIFF_LONG</tt></td>      <td><tt>long</tt></td>
104      * <tr>
105      * <td><tt>TIFF_RATIONAL</tt></td>  <td><tt>long[2]</tt></td>
106      * <tr>
107      * <td><tt>TIFF_SBYTE</tt></td>     <td><tt>byte</tt></td>
108      * <tr>
109      * <td><tt>TIFF_UNDEFINED</tt></td> <td><tt>byte</tt></td>
110      * <tr>
111      * <td><tt>TIFF_SSHORT</tt></td>    <td><tt>short</tt></td>
112      * <tr>
113      * <td><tt>TIFF_SLONG</tt></td>     <td><tt>int</tt></td>
114      * <tr>
115      * <td><tt>TIFF_SRATIONAL</tt></td> <td><tt>int[2]</tt></td>
116      * <tr>
117      * <td><tt>TIFF_FLOAT</tt></td>     <td><tt>float</tt></td>
118      * <tr>
119      * <td><tt>TIFF_DOUBLE</tt></td>    <td><tt>double</tt></td>
120      * </table>
121      *
122      * <p>Note that the <code>data</code> parameter should always
123      * be the actual field value regardless of the number of bytes
124      * required for that value.  This is the case despite the fact
125      * that the TIFF <i>IFD Entry</i> corresponding to the field may
126      * actually contain the offset to the field's value rather than
127      * the value itself (the latter occurring if and only if the
128      * value fits into 4 bytes).</p>
129      */
TIFFField(int tag, int type, int count, Object data)130     public TIFFField(int tag, int type, int count, Object data) {
131         this.tag = tag;
132         this.type = type;
133         this.count = count;
134         this.data = data;
135     }
136 
137     /**
138      * Returns the tag number, between 0 and 65535.
139      */
getTag()140     public int getTag() {
141         return tag;
142     }
143 
144     /**
145      * Returns the type of the data stored in the field.
146      * For a TIFF6.0 file, the value will equal one of the
147      * TIFF_ constants defined in this class.  For future
148      * revisions of TIFF, higher values are possible.
149      *
150      */
getType()151     public int getType() {
152         return type;
153     }
154 
155     /**
156      * Returns the number of data items present in the field.
157      */
getCount()158     public int getCount() {
159         return count;
160     }
161 
162     /**
163      * Returns the data as an uninterpreted array of bytes.
164      * The type of the field must be one of TIFF_BYTE, TIFF_SBYTE,
165      * or TIFF_UNDEFINED;
166      *
167      * <p> For data in TIFF_BYTE format, the application must take
168      * care when promoting the data to longer integral types
169      * to avoid sign extension.
170      *
171      * <p> A ClassCastException will be thrown if the field is not
172      * of type TIFF_BYTE, TIFF_SBYTE, or TIFF_UNDEFINED.
173      */
getAsBytes()174     public byte[] getAsBytes() {
175         return (byte[])data;
176     }
177 
178     /**
179      * Returns TIFF_SHORT data as an array of chars (unsigned 16-bit
180      * integers).
181      *
182      * <p> A ClassCastException will be thrown if the field is not
183      * of type TIFF_SHORT.
184      */
getAsChars()185     public char[] getAsChars() {
186         return (char[])data;
187     }
188 
189     /**
190      * Returns TIFF_SSHORT data as an array of shorts (signed 16-bit
191      * integers).
192      *
193      * <p> A ClassCastException will be thrown if the field is not
194      * of type TIFF_SSHORT.
195      */
getAsShorts()196     public short[] getAsShorts() {
197         return (short[])data;
198     }
199 
200     /**
201      * Returns TIFF_SLONG data as an array of ints (signed 32-bit
202      * integers).
203      *
204      * <p> A ClassCastException will be thrown if the field is not
205      * of type TIFF_SLONG.
206      */
getAsInts()207     public int[] getAsInts() {
208         return (int[])data;
209     }
210 
211     /**
212      * Returns TIFF_LONG data as an array of longs (signed 64-bit
213      * integers).
214      *
215      * <p> A ClassCastException will be thrown if the field is not
216      * of type TIFF_LONG.
217      */
getAsLongs()218     public long[] getAsLongs() {
219         return (long[])data;
220     }
221 
222     /**
223      * Returns TIFF_FLOAT data as an array of floats.
224      *
225      * <p> A ClassCastException will be thrown if the field is not
226      * of type TIFF_FLOAT.
227      */
getAsFloats()228     public float[] getAsFloats() {
229         return (float[])data;
230     }
231 
232     /**
233      * Returns TIFF_DOUBLE data as an array of doubles.
234      *
235      * <p> A ClassCastException will be thrown if the field is not
236      * of type TIFF_DOUBLE.
237      */
getAsDoubles()238     public double[] getAsDoubles() {
239         return (double[])data;
240     }
241 
242     /**
243      * Returns TIFF_SRATIONAL data as an array of 2-element arrays of ints.
244      *
245      * <p> A ClassCastException will be thrown if the field is not
246      * of type TIFF_SRATIONAL.
247      */
getAsSRationals()248     public int[][] getAsSRationals() {
249         return (int[][])data;
250     }
251 
252     /**
253      * Returns TIFF_RATIONAL data as an array of 2-element arrays of longs.
254      *
255      * <p> A ClassCastException will be thrown if the field is not
256      * of type TIFF_RATTIONAL.
257      */
getAsRationals()258     public long[][] getAsRationals() {
259         return (long[][])data;
260     }
261 
262     /**
263      * Returns data in TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT,
264      * TIFF_SSHORT, or TIFF_SLONG format as an int.
265      *
266      * <p> TIFF_BYTE and TIFF_UNDEFINED data are treated as unsigned;
267      * that is, no sign extension will take place and the returned
268      * value will be in the range [0, 255].  TIFF_SBYTE data will
269      * be returned in the range [-128, 127].
270      *
271      * <p> A ClassCastException will be thrown if the field is not of
272      * type TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT,
273      * TIFF_SSHORT, or TIFF_SLONG.
274      */
getAsInt(int index)275     public int getAsInt(int index) {
276         switch (type) {
277         case TIFF_BYTE: case TIFF_UNDEFINED:
278             return ((byte[])data)[index] & 0xff;
279         case TIFF_SBYTE:
280             return ((byte[])data)[index];
281         case TIFF_SHORT:
282             return ((char[])data)[index] & 0xffff;
283         case TIFF_SSHORT:
284             return ((short[])data)[index];
285         case TIFF_SLONG:
286             return ((int[])data)[index];
287         default:
288             throw new ClassCastException();
289         }
290     }
291 
292     /**
293      * Returns data in TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT,
294      * TIFF_SSHORT, TIFF_SLONG, or TIFF_LONG format as a long.
295      *
296      * <p> TIFF_BYTE and TIFF_UNDEFINED data are treated as unsigned;
297      * that is, no sign extension will take place and the returned
298      * value will be in the range [0, 255].  TIFF_SBYTE data will
299      * be returned in the range [-128, 127].
300      *
301      * <p> A ClassCastException will be thrown if the field is not of
302      * type TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT,
303      * TIFF_SSHORT, TIFF_SLONG, or TIFF_LONG.
304      */
getAsLong(int index)305     public long getAsLong(int index) {
306         switch (type) {
307         case TIFF_BYTE: case TIFF_UNDEFINED:
308             return ((byte[])data)[index] & 0xff;
309         case TIFF_SBYTE:
310             return ((byte[])data)[index];
311         case TIFF_SHORT:
312             return ((char[])data)[index] & 0xffff;
313         case TIFF_SSHORT:
314             return ((short[])data)[index];
315         case TIFF_SLONG:
316             return ((int[])data)[index];
317         case TIFF_LONG:
318             return ((long[])data)[index];
319         default:
320             throw new ClassCastException();
321         }
322     }
323 
324     /**
325      * Returns data in any numerical format as a float.  Data in
326      * TIFF_SRATIONAL or TIFF_RATIONAL format are evaluated by
327      * dividing the numerator into the denominator using
328      * double-precision arithmetic and then truncating to single
329      * precision.  Data in TIFF_SLONG, TIFF_LONG, or TIFF_DOUBLE
330      * format may suffer from truncation.
331      *
332      * <p> A ClassCastException will be thrown if the field is
333      * of type TIFF_UNDEFINED or TIFF_ASCII.
334      */
getAsFloat(int index)335     public float getAsFloat(int index) {
336         switch (type) {
337         case TIFF_BYTE:
338             return ((byte[])data)[index] & 0xff;
339         case TIFF_SBYTE:
340             return ((byte[])data)[index];
341         case TIFF_SHORT:
342             return ((char[])data)[index] & 0xffff;
343         case TIFF_SSHORT:
344             return ((short[])data)[index];
345         case TIFF_SLONG:
346             return ((int[])data)[index];
347         case TIFF_LONG:
348             return ((long[])data)[index];
349         case TIFF_FLOAT:
350             return ((float[])data)[index];
351         case TIFF_DOUBLE:
352             return (float)((double[])data)[index];
353         case TIFF_SRATIONAL:
354             int[] ivalue = getAsSRational(index);
355             return (float)((double)ivalue[0]/ivalue[1]);
356         case TIFF_RATIONAL:
357             long[] lvalue = getAsRational(index);
358             return (float)((double)lvalue[0]/lvalue[1]);
359         default:
360             throw new ClassCastException();
361         }
362     }
363 
364     /**
365      * Returns data in any numerical format as a float.  Data in
366      * TIFF_SRATIONAL or TIFF_RATIONAL format are evaluated by
367      * dividing the numerator into the denominator using
368      * double-precision arithmetic.
369      *
370      * <p> A ClassCastException will be thrown if the field is of
371      * type TIFF_UNDEFINED or TIFF_ASCII.
372      */
getAsDouble(int index)373     public double getAsDouble(int index) {
374         switch (type) {
375         case TIFF_BYTE:
376             return ((byte[])data)[index] & 0xff;
377         case TIFF_SBYTE:
378             return ((byte[])data)[index];
379         case TIFF_SHORT:
380             return ((char[])data)[index] & 0xffff;
381         case TIFF_SSHORT:
382             return ((short[])data)[index];
383         case TIFF_SLONG:
384             return ((int[])data)[index];
385         case TIFF_LONG:
386             return ((long[])data)[index];
387         case TIFF_FLOAT:
388             return ((float[])data)[index];
389         case TIFF_DOUBLE:
390             return ((double[])data)[index];
391         case TIFF_SRATIONAL:
392             int[] ivalue = getAsSRational(index);
393             return (double)ivalue[0]/ivalue[1];
394         case TIFF_RATIONAL:
395             long[] lvalue = getAsRational(index);
396             return (double)lvalue[0]/lvalue[1];
397         default:
398             throw new ClassCastException();
399         }
400     }
401 
402     /**
403      * Returns a TIFF_ASCII data item as a String.
404      *
405      * <p> A ClassCastException will be thrown if the field is not
406      * of type TIFF_ASCII.
407      */
getAsString(int index)408     public String getAsString(int index) {
409         return ((String[])data)[index];
410     }
411 
412     /**
413      * Returns a TIFF_SRATIONAL data item as a two-element array
414      * of ints.
415      *
416      * <p> A ClassCastException will be thrown if the field is not
417      * of type TIFF_SRATIONAL.
418      */
getAsSRational(int index)419     public int[] getAsSRational(int index) {
420         return ((int[][])data)[index];
421     }
422 
423     /**
424      * Returns a TIFF_RATIONAL data item as a two-element array
425      * of ints.
426      *
427      * <p> A ClassCastException will be thrown if the field is not
428      * of type TIFF_RATIONAL.
429      */
getAsRational(int index)430     public long[] getAsRational(int index) {
431         return ((long[][])data)[index];
432     }
433 
434     /**
435      * Compares this <code>TIFFField</code> with another
436      * <code>TIFFField</code> by comparing the tags.
437      *
438      * <p><b>Note: this class has a natural ordering that is inconsistent
439      * with <code>equals()</code>.</b>
440      *
441      * @throws IllegalArgumentException if the parameter is <code>null</code>.
442      * @throws ClassCastException if the parameter is not a
443      *         <code>TIFFField</code>.
444      */
compareTo(Object o)445     public int compareTo(Object o) {
446         if(o == null) {
447             throw new IllegalArgumentException();
448         }
449 
450         int oTag = ((TIFFField)o).getTag();
451 
452         if(tag < oTag) {
453             return -1;
454         } else if(tag > oTag) {
455             return 1;
456         } else {
457             return 0;
458         }
459     }
460 }
461