001: /*
002: * $RCSfile: TIFFField.java,v $
003: *
004: * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Use is subject to license terms.
007: *
008: * $Revision: 1.1 $
009: * $Date: 2005/02/11 04:55:34 $
010: * $State: Exp $
011: */
012: package com.sun.media.jai.codec;
013:
014: import java.io.Serializable;
015:
016: /**
017: * A class representing a field in a TIFF 6.0 Image File Directory.
018: *
019: * <p> The TIFF file format is described in more detail in the
020: * comments for the TIFFDescriptor class.
021: *
022: * <p> A field in a TIFF Image File Directory (IFD). A field is defined
023: * as a sequence of values of identical data type. TIFF 6.0 defines
024: * 12 data types, which are mapped internally onto the Java datatypes
025: * byte, int, long, float, and double.
026: *
027: * <p><b> This class is not a committed part of the JAI API. It may
028: * be removed or changed in future releases of JAI.</b>
029: *
030: * @see javax.media.jai.operator.TIFFDescriptor
031: * @see TIFFDirectory
032: */
033: public class TIFFField extends Object implements Comparable,
034: Serializable {
035:
036: /** Flag for 8 bit unsigned integers. */
037: public static final int TIFF_BYTE = 1;
038:
039: /** Flag for null-terminated ASCII strings. */
040: public static final int TIFF_ASCII = 2;
041:
042: /** Flag for 16 bit unsigned integers. */
043: public static final int TIFF_SHORT = 3;
044:
045: /** Flag for 32 bit unsigned integers. */
046: public static final int TIFF_LONG = 4;
047:
048: /** Flag for pairs of 32 bit unsigned integers. */
049: public static final int TIFF_RATIONAL = 5;
050:
051: /** Flag for 8 bit signed integers. */
052: public static final int TIFF_SBYTE = 6;
053:
054: /** Flag for 8 bit uninterpreted bytes. */
055: public static final int TIFF_UNDEFINED = 7;
056:
057: /** Flag for 16 bit signed integers. */
058: public static final int TIFF_SSHORT = 8;
059:
060: /** Flag for 32 bit signed integers. */
061: public static final int TIFF_SLONG = 9;
062:
063: /** Flag for pairs of 32 bit signed integers. */
064: public static final int TIFF_SRATIONAL = 10;
065:
066: /** Flag for 32 bit IEEE floats. */
067: public static final int TIFF_FLOAT = 11;
068:
069: /** Flag for 64 bit IEEE doubles. */
070: public static final int TIFF_DOUBLE = 12;
071:
072: /** The tag number. */
073: int tag;
074:
075: /** The tag type. */
076: int type;
077:
078: /** The number of data items present in the field. */
079: int count;
080:
081: /** The field data. */
082: Object data;
083:
084: /** The default constructor. */
085: TIFFField() {
086: }
087:
088: /**
089: * Constructs a TIFFField with arbitrary data. The data
090: * parameter must be an array of a Java type appropriate for the
091: * type of the TIFF field. Since there is no available 32-bit
092: * unsigned datatype, long is used. The mapping between types is
093: * as follows:
094: *
095: * <table border=1>
096: * <tr>
097: * <th> TIFF type </th> <th> Java type </th>
098: * <tr>
099: * <td><tt>TIFF_BYTE</tt></td> <td><tt>byte</tt></td>
100: * <tr>
101: * <td><tt>TIFF_ASCII</tt></td> <td><tt>String</tt></td>
102: * <tr>
103: * <td><tt>TIFF_SHORT</tt></td> <td><tt>char</tt></td>
104: * <tr>
105: * <td><tt>TIFF_LONG</tt></td> <td><tt>long</tt></td>
106: * <tr>
107: * <td><tt>TIFF_RATIONAL</tt></td> <td><tt>long[2]</tt></td>
108: * <tr>
109: * <td><tt>TIFF_SBYTE</tt></td> <td><tt>byte</tt></td>
110: * <tr>
111: * <td><tt>TIFF_UNDEFINED</tt></td> <td><tt>byte</tt></td>
112: * <tr>
113: * <td><tt>TIFF_SSHORT</tt></td> <td><tt>short</tt></td>
114: * <tr>
115: * <td><tt>TIFF_SLONG</tt></td> <td><tt>int</tt></td>
116: * <tr>
117: * <td><tt>TIFF_SRATIONAL</tt></td> <td><tt>int[2]</tt></td>
118: * <tr>
119: * <td><tt>TIFF_FLOAT</tt></td> <td><tt>float</tt></td>
120: * <tr>
121: * <td><tt>TIFF_DOUBLE</tt></td> <td><tt>double</tt></td>
122: * </table>
123: *
124: * <p>Note that the <code>data</code> parameter should always
125: * be the actual field value regardless of the number of bytes
126: * required for that value. This is the case despite the fact
127: * that the TIFF <i>IFD Entry</i> corresponding to the field may
128: * actually contain the offset to the field's value rather than
129: * the value itself (the latter occurring if and only if the
130: * value fits into 4 bytes).</p>
131: */
132: public TIFFField(int tag, int type, int count, Object data) {
133: this .tag = tag;
134: this .type = type;
135: this .count = count;
136: this .data = data;
137: }
138:
139: /**
140: * Returns the tag number, between 0 and 65535.
141: */
142: public int getTag() {
143: return tag;
144: }
145:
146: /**
147: * Returns the type of the data stored in the field.
148: * For a TIFF6.0 file, the value will equal one of the
149: * TIFF_ constants defined in this class. For future
150: * revisions of TIFF, higher values are possible.
151: *
152: */
153: public int getType() {
154: return type;
155: }
156:
157: /**
158: * Returns the number of data items present in the field.
159: */
160: public int getCount() {
161: return count;
162: }
163:
164: /**
165: * Returns the data as an uninterpreted array of bytes.
166: * The type of the field must be one of TIFF_BYTE, TIFF_SBYTE,
167: * or TIFF_UNDEFINED;
168: *
169: * <p> For data in TIFF_BYTE format, the application must take
170: * care when promoting the data to longer integral types
171: * to avoid sign extension.
172: *
173: * <p> A ClassCastException will be thrown if the field is not
174: * of type TIFF_BYTE, TIFF_SBYTE, or TIFF_UNDEFINED.
175: */
176: public byte[] getAsBytes() {
177: return (byte[]) data;
178: }
179:
180: /**
181: * Returns TIFF_SHORT data as an array of chars (unsigned 16-bit
182: * integers).
183: *
184: * <p> A ClassCastException will be thrown if the field is not
185: * of type TIFF_SHORT.
186: */
187: public char[] getAsChars() {
188: return (char[]) data;
189: }
190:
191: /**
192: * Returns TIFF_SSHORT data as an array of shorts (signed 16-bit
193: * integers).
194: *
195: * <p> A ClassCastException will be thrown if the field is not
196: * of type TIFF_SSHORT.
197: */
198: public short[] getAsShorts() {
199: return (short[]) data;
200: }
201:
202: /**
203: * Returns TIFF_SLONG data as an array of ints (signed 32-bit
204: * integers).
205: *
206: * <p> A ClassCastException will be thrown if the field is not
207: * of type TIFF_SLONG.
208: */
209: public int[] getAsInts() {
210: return (int[]) data;
211: }
212:
213: /**
214: * Returns TIFF_LONG data as an array of longs (signed 64-bit
215: * integers).
216: *
217: * <p> A ClassCastException will be thrown if the field is not
218: * of type TIFF_LONG.
219: */
220: public long[] getAsLongs() {
221: return (long[]) data;
222: }
223:
224: /**
225: * Returns TIFF_FLOAT data as an array of floats.
226: *
227: * <p> A ClassCastException will be thrown if the field is not
228: * of type TIFF_FLOAT.
229: */
230: public float[] getAsFloats() {
231: return (float[]) data;
232: }
233:
234: /**
235: * Returns TIFF_DOUBLE data as an array of doubles.
236: *
237: * <p> A ClassCastException will be thrown if the field is not
238: * of type TIFF_DOUBLE.
239: */
240: public double[] getAsDoubles() {
241: return (double[]) data;
242: }
243:
244: /**
245: * Returns TIFF_SRATIONAL data as an array of 2-element arrays of ints.
246: *
247: * <p> A ClassCastException will be thrown if the field is not
248: * of type TIFF_SRATIONAL.
249: */
250: public int[][] getAsSRationals() {
251: return (int[][]) data;
252: }
253:
254: /**
255: * Returns TIFF_RATIONAL data as an array of 2-element arrays of longs.
256: *
257: * <p> A ClassCastException will be thrown if the field is not
258: * of type TIFF_RATTIONAL.
259: */
260: public long[][] getAsRationals() {
261: return (long[][]) data;
262: }
263:
264: /**
265: * Returns data in TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT,
266: * TIFF_SSHORT, or TIFF_SLONG format as an int.
267: *
268: * <p> TIFF_BYTE and TIFF_UNDEFINED data are treated as unsigned;
269: * that is, no sign extension will take place and the returned
270: * value will be in the range [0, 255]. TIFF_SBYTE data will
271: * be returned in the range [-128, 127].
272: *
273: * <p> A ClassCastException will be thrown if the field is not of
274: * type TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT,
275: * TIFF_SSHORT, or TIFF_SLONG.
276: */
277: public int getAsInt(int index) {
278: switch (type) {
279: case TIFF_BYTE:
280: case TIFF_UNDEFINED:
281: return ((byte[]) data)[index] & 0xff;
282: case TIFF_SBYTE:
283: return ((byte[]) data)[index];
284: case TIFF_SHORT:
285: return ((char[]) data)[index] & 0xffff;
286: case TIFF_SSHORT:
287: return ((short[]) data)[index];
288: case TIFF_SLONG:
289: return ((int[]) data)[index];
290: default:
291: throw new ClassCastException();
292: }
293: }
294:
295: /**
296: * Returns data in TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT,
297: * TIFF_SSHORT, TIFF_SLONG, or TIFF_LONG format as a long.
298: *
299: * <p> TIFF_BYTE and TIFF_UNDEFINED data are treated as unsigned;
300: * that is, no sign extension will take place and the returned
301: * value will be in the range [0, 255]. TIFF_SBYTE data will
302: * be returned in the range [-128, 127].
303: *
304: * <p> A ClassCastException will be thrown if the field is not of
305: * type TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT,
306: * TIFF_SSHORT, TIFF_SLONG, or TIFF_LONG.
307: */
308: public long getAsLong(int index) {
309: switch (type) {
310: case TIFF_BYTE:
311: case TIFF_UNDEFINED:
312: return ((byte[]) data)[index] & 0xff;
313: case TIFF_SBYTE:
314: return ((byte[]) data)[index];
315: case TIFF_SHORT:
316: return ((char[]) data)[index] & 0xffff;
317: case TIFF_SSHORT:
318: return ((short[]) data)[index];
319: case TIFF_SLONG:
320: return ((int[]) data)[index];
321: case TIFF_LONG:
322: return ((long[]) data)[index];
323: default:
324: throw new ClassCastException();
325: }
326: }
327:
328: /**
329: * Returns data in any numerical format as a float. Data in
330: * TIFF_SRATIONAL or TIFF_RATIONAL format are evaluated by
331: * dividing the numerator into the denominator using
332: * double-precision arithmetic and then truncating to single
333: * precision. Data in TIFF_SLONG, TIFF_LONG, or TIFF_DOUBLE
334: * format may suffer from truncation.
335: *
336: * <p> A ClassCastException will be thrown if the field is
337: * of type TIFF_UNDEFINED or TIFF_ASCII.
338: */
339: public float getAsFloat(int index) {
340: switch (type) {
341: case TIFF_BYTE:
342: return ((byte[]) data)[index] & 0xff;
343: case TIFF_SBYTE:
344: return ((byte[]) data)[index];
345: case TIFF_SHORT:
346: return ((char[]) data)[index] & 0xffff;
347: case TIFF_SSHORT:
348: return ((short[]) data)[index];
349: case TIFF_SLONG:
350: return ((int[]) data)[index];
351: case TIFF_LONG:
352: return ((long[]) data)[index];
353: case TIFF_FLOAT:
354: return ((float[]) data)[index];
355: case TIFF_DOUBLE:
356: return (float) ((double[]) data)[index];
357: case TIFF_SRATIONAL:
358: int[] ivalue = getAsSRational(index);
359: return (float) ((double) ivalue[0] / ivalue[1]);
360: case TIFF_RATIONAL:
361: long[] lvalue = getAsRational(index);
362: return (float) ((double) lvalue[0] / lvalue[1]);
363: default:
364: throw new ClassCastException();
365: }
366: }
367:
368: /**
369: * Returns data in any numerical format as a float. Data in
370: * TIFF_SRATIONAL or TIFF_RATIONAL format are evaluated by
371: * dividing the numerator into the denominator using
372: * double-precision arithmetic.
373: *
374: * <p> A ClassCastException will be thrown if the field is of
375: * type TIFF_UNDEFINED or TIFF_ASCII.
376: */
377: public double getAsDouble(int index) {
378: switch (type) {
379: case TIFF_BYTE:
380: return ((byte[]) data)[index] & 0xff;
381: case TIFF_SBYTE:
382: return ((byte[]) data)[index];
383: case TIFF_SHORT:
384: return ((char[]) data)[index] & 0xffff;
385: case TIFF_SSHORT:
386: return ((short[]) data)[index];
387: case TIFF_SLONG:
388: return ((int[]) data)[index];
389: case TIFF_LONG:
390: return ((long[]) data)[index];
391: case TIFF_FLOAT:
392: return ((float[]) data)[index];
393: case TIFF_DOUBLE:
394: return ((double[]) data)[index];
395: case TIFF_SRATIONAL:
396: int[] ivalue = getAsSRational(index);
397: return (double) ivalue[0] / ivalue[1];
398: case TIFF_RATIONAL:
399: long[] lvalue = getAsRational(index);
400: return (double) lvalue[0] / lvalue[1];
401: default:
402: throw new ClassCastException();
403: }
404: }
405:
406: /**
407: * Returns a TIFF_ASCII data item as a String.
408: *
409: * <p> A ClassCastException will be thrown if the field is not
410: * of type TIFF_ASCII.
411: */
412: public String getAsString(int index) {
413: return ((String[]) data)[index];
414: }
415:
416: /**
417: * Returns a TIFF_SRATIONAL data item as a two-element array
418: * of ints.
419: *
420: * <p> A ClassCastException will be thrown if the field is not
421: * of type TIFF_SRATIONAL.
422: */
423: public int[] getAsSRational(int index) {
424: return ((int[][]) data)[index];
425: }
426:
427: /**
428: * Returns a TIFF_RATIONAL data item as a two-element array
429: * of ints.
430: *
431: * <p> A ClassCastException will be thrown if the field is not
432: * of type TIFF_RATIONAL.
433: */
434: public long[] getAsRational(int index) {
435: return ((long[][]) data)[index];
436: }
437:
438: /**
439: * Compares this <code>TIFFField</code> with another
440: * <code>TIFFField</code> by comparing the tags.
441: *
442: * <p><b>Note: this class has a natural ordering that is inconsistent
443: * with <code>equals()</code>.</b>
444: *
445: * @throws IllegalArgumentException if the parameter is <code>null</code>.
446: * @throws ClassCastException if the parameter is not a
447: * <code>TIFFField</code>.
448: */
449: public int compareTo(Object o) {
450: if (o == null) {
451: throw new IllegalArgumentException();
452: }
453:
454: int oTag = ((TIFFField) o).getTag();
455:
456: if (tag < oTag) {
457: return -1;
458: } else if (tag > oTag) {
459: return 1;
460: } else {
461: return 0;
462: }
463: }
464: }
|