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