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