1 /*
   2  * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package javax.imageio.plugins.tiff;
  26 
  27 import java.util.StringTokenizer;
  28 import org.w3c.dom.NamedNodeMap;
  29 import org.w3c.dom.Node;
  30 import com.sun.imageio.plugins.tiff.TIFFFieldNode;
  31 import com.sun.imageio.plugins.tiff.TIFFIFD;
  32 
  33 /**
  34  * A class representing a field in a TIFF 6.0 Image File Directory.
  35  *
  36  * <p> A field in a TIFF Image File Directory (IFD) is defined as a
  37  * tag number accompanied by a sequence of values of identical data type.
  38  * TIFF 6.0 defines 12 data types; a 13th type {@code IFD} is
  39  * defined in TIFF Tech Note 1 of TIFF Specification Supplement 1. These
  40  * TIFF data types are referred to by Java constants and mapped internally
  41  * onto Java language data types and type names as follows:
  42  *
  43  * <br>
  44  * <br>
  45  * <table border="1">
  46  * <caption>TIFF Data Type to Java Data Type Mapping</caption>
  47  *
  48  * <tr>
  49  * <th>
  50  * <b>TIFF Data Type</b>
  51  * </th>
  52  * <th>
  53  * <b>Java Constant</b>
  54  * </th>
  55  * <th>
  56  * <b>Java Data Type</b>
  57  * </th>
  58  * <th>
  59  * <b>Java Type Name</b>
  60  * </th>
  61  * </tr>
  62  *
  63  * <tr>
  64  * <td>
  65  * <tt>BYTE</tt>
  66  * </td>
  67  * <td>
  68  * {@link TIFFTag#TIFF_BYTE}
  69  * </td>
  70  * <td>
  71  * {@code byte}
  72  * </td>
  73  * <td>
  74  * {@code "Byte"}
  75  * </td>
  76  * </tr>
  77  *
  78  * <tr>
  79  * <td>
  80  * <tt>ASCII</tt>
  81  * </td>
  82  * <td>
  83  * {@link TIFFTag#TIFF_ASCII}
  84  * </td>
  85  * <td>
  86  * {@code String}
  87  * </td>
  88  * <td>
  89  * {@code "Ascii"}
  90  * </td>
  91  * </tr>
  92  *
  93  * <tr>
  94  * <td>
  95  * <tt>SHORT</tt>
  96  * </td>
  97  * <td>
  98  * {@link TIFFTag#TIFF_SHORT}
  99  * </td>
 100  * <td>
 101  * {@code char}
 102  * </td>
 103  * <td>
 104  * {@code "Short"}
 105  * </td>
 106  * </tr>
 107  *
 108  * <tr>
 109  * <td>
 110  * <tt>LONG</tt>
 111  * </td>
 112  * <td>
 113  * {@link TIFFTag#TIFF_LONG}
 114  * </td>
 115  * <td>
 116  * {@code long}
 117  * </td>
 118  * <td>
 119  * {@code "Long"}
 120  * </td>
 121  * </tr>
 122  *
 123  * <tr>
 124  * <td>
 125  * <tt>RATIONAL</tt>
 126  * </td>
 127  * <td>
 128  * {@link TIFFTag#TIFF_RATIONAL}
 129  * </td>
 130  * <td>
 131  * {@code long[2]} {numerator, denominator}
 132  * </td>
 133  * <td>
 134  * {@code "Rational"}
 135  * </td>
 136  * </tr>
 137  *
 138  * <tr>
 139  * <td>
 140  * <tt>SBYTE</tt>
 141  * </td>
 142  * <td>
 143  * {@link TIFFTag#TIFF_SBYTE}
 144  * </td>
 145  * <td>
 146  * {@code byte}
 147  * </td>
 148  * <td>
 149  * {@code "SByte"}
 150  * </td>
 151  * </tr>
 152  *
 153  * <tr>
 154  * <td>
 155  * <tt>UNDEFINED</tt>
 156  * </td>
 157  * <td>
 158  * {@link TIFFTag#TIFF_UNDEFINED}
 159  * </td>
 160  * <td>
 161  * {@code byte}
 162  * </td>
 163  * <td>
 164  * {@code "Undefined"}
 165  * </td>
 166  * </tr>
 167  *
 168  * <tr>
 169  * <td>
 170  * <tt>SSHORT</tt>
 171  * </td>
 172  * <td>
 173  * {@link TIFFTag#TIFF_SSHORT}
 174  * </td>
 175  * <td>
 176  * {@code short}
 177  * </td>
 178  * <td>
 179  * {@code "SShort"}
 180  * </td>
 181  * </tr>
 182  *
 183  * <tr>
 184  * <td>
 185  * <tt>SLONG</tt>
 186  * </td>
 187  * <td>
 188  * {@link TIFFTag#TIFF_SLONG}
 189  * </td>
 190  * <td>
 191  * {@code int}
 192  * </td>
 193  * <td>
 194  * {@code "SLong"}
 195  * </td>
 196  * </tr>
 197  *
 198  * <tr>
 199  * <td>
 200  * <tt>SRATIONAL</tt>
 201  * </td>
 202  * <td>
 203  * {@link TIFFTag#TIFF_SRATIONAL}
 204  * </td>
 205  * <td>
 206  * {@code int[2]} {numerator, denominator}
 207  * </td>
 208  * <td>
 209  * {@code "SRational"}
 210  * </td>
 211  * </tr>
 212  *
 213  * <tr>
 214  * <td>
 215  * <tt>FLOAT</tt>
 216  * </td>
 217  * <td>
 218  * {@link TIFFTag#TIFF_FLOAT}
 219  * </td>
 220  * <td>
 221  * {@code float}
 222  * </td>
 223  * <td>
 224  * {@code "Float"}
 225  * </td>
 226  * </tr>
 227  *
 228  * <tr>
 229  * <td>
 230  * <tt>DOUBLE</tt>
 231  * </td>
 232  * <td>
 233  * {@link TIFFTag#TIFF_DOUBLE}
 234  * </td>
 235  * <td>
 236  * {@code double}
 237  * </td>
 238  * <td>
 239  * {@code "Double"}
 240  * </td>
 241  * </tr>
 242  *
 243  * <tr>
 244  * <td>
 245  * <tt>IFD</tt>
 246  * </td>
 247  * <td>
 248  * {@link TIFFTag#TIFF_IFD_POINTER}
 249  * </td>
 250  * <td>
 251  * {@code long}
 252  * </td>
 253  * <td>
 254  * {@code "IFDPointer"}
 255  * </td>
 256  * </tr>
 257  *
 258  * </table>
 259  *
 260  * @since 9
 261  * @see   TIFFDirectory
 262  * @see   TIFFTag
 263  */
 264 public final class TIFFField implements Cloneable {
 265 
 266     private static final String[] typeNames = {
 267         null,
 268         "Byte", "Ascii", "Short", "Long", "Rational",
 269         "SByte", "Undefined", "SShort", "SLong", "SRational",
 270         "Float", "Double", "IFDPointer"
 271     };
 272 
 273     private static final boolean[] isIntegral = {
 274         false,
 275         true, false, true, true, false,
 276         true, true, true, true, false,
 277         false, false, false
 278     };
 279 
 280     /** The tag. */
 281     private TIFFTag tag;
 282 
 283     /** The tag number. */
 284     private int tagNumber;
 285 
 286     /** The tag type. */
 287     private int type;
 288 
 289     /** The number of data items present in the field. */
 290     private int count;
 291 
 292     /** The field data. */
 293     private Object data;
 294 
 295     /** The IFD contents if available. This will usually be a TIFFIFD. */
 296     private TIFFDirectory dir;
 297 
 298     /** The default constructor. */
 299     private TIFFField() {}
 300 
 301     private static String getAttribute(Node node, String attrName) {
 302         NamedNodeMap attrs = node.getAttributes();
 303         return attrs.getNamedItem(attrName).getNodeValue();
 304     }
 305 
 306     private static void initData(Node node,
 307                                  int[] otype, int[] ocount, Object[] odata) {
 308         int type;
 309         int count;
 310         Object data = null;
 311 
 312         String typeName = node.getNodeName();
 313         typeName = typeName.substring(4);
 314         typeName = typeName.substring(0, typeName.length() - 1);
 315         type = TIFFField.getTypeByName(typeName);
 316         if (type == -1) {
 317             throw new IllegalArgumentException("typeName = " + typeName);
 318         }
 319 
 320         Node child = node.getFirstChild();
 321 
 322         count = 0;
 323         while (child != null) {
 324             String childTypeName = child.getNodeName().substring(4);
 325             if (!typeName.equals(childTypeName)) {
 326                 // warning
 327             }
 328 
 329             ++count;
 330             child = child.getNextSibling();
 331         }
 332 
 333         if (count > 0) {
 334             data = createArrayForType(type, count);
 335             child = node.getFirstChild();
 336             int idx = 0;
 337             while (child != null) {
 338                 String value = getAttribute(child, "value");
 339 
 340                 String numerator, denominator;
 341                 int slashPos;
 342 
 343                 switch (type) {
 344                 case TIFFTag.TIFF_ASCII:
 345                     ((String[])data)[idx] = value;
 346                     break;
 347                 case TIFFTag.TIFF_BYTE:
 348                 case TIFFTag.TIFF_SBYTE:
 349                     ((byte[])data)[idx] =
 350                         (byte)Integer.parseInt(value);
 351                     break;
 352                 case TIFFTag.TIFF_SHORT:
 353                     ((char[])data)[idx] =
 354                         (char)Integer.parseInt(value);
 355                     break;
 356                 case TIFFTag.TIFF_SSHORT:
 357                     ((short[])data)[idx] =
 358                         (short)Integer.parseInt(value);
 359                     break;
 360                 case TIFFTag.TIFF_SLONG:
 361                     ((int[])data)[idx] =
 362                         Integer.parseInt(value);
 363                     break;
 364                 case TIFFTag.TIFF_LONG:
 365                 case TIFFTag.TIFF_IFD_POINTER:
 366                     ((long[])data)[idx] =
 367                         Long.parseLong(value);
 368                     break;
 369                 case TIFFTag.TIFF_FLOAT:
 370                     ((float[])data)[idx] =
 371                         Float.parseFloat(value);
 372                     break;
 373                 case TIFFTag.TIFF_DOUBLE:
 374                     ((double[])data)[idx] =
 375                         Double.parseDouble(value);
 376                     break;
 377                 case TIFFTag.TIFF_SRATIONAL:
 378                     slashPos = value.indexOf("/");
 379                     numerator = value.substring(0, slashPos);
 380                     denominator = value.substring(slashPos + 1);
 381 
 382                     ((int[][])data)[idx] = new int[2];
 383                     ((int[][])data)[idx][0] =
 384                         Integer.parseInt(numerator);
 385                     ((int[][])data)[idx][1] =
 386                         Integer.parseInt(denominator);
 387                     break;
 388                 case TIFFTag.TIFF_RATIONAL:
 389                     slashPos = value.indexOf("/");
 390                     numerator = value.substring(0, slashPos);
 391                     denominator = value.substring(slashPos + 1);
 392 
 393                     ((long[][])data)[idx] = new long[2];
 394                     ((long[][])data)[idx][0] =
 395                         Long.parseLong(numerator);
 396                     ((long[][])data)[idx][1] =
 397                         Long.parseLong(denominator);
 398                     break;
 399                 default:
 400                     // error
 401                 }
 402 
 403                 idx++;
 404                 child = child.getNextSibling();
 405             }
 406         }
 407 
 408         otype[0] = type;
 409         ocount[0] = count;
 410         odata[0] = data;
 411     }
 412 
 413     /**
 414      * Creates a {@code TIFFField} from a TIFF native image
 415      * metadata node. If the value of the {@code "number"} attribute
 416      * of the node is not found in {@code tagSet} then a new
 417      * {@code TIFFTag} with name {@code TIFFTag.UNKNOWN_TAG_NAME}
 418      * will be created and assigned to the field.
 419      *
 420      * @param tagSet The {@code TIFFTagSet} to which the
 421      * {@code TIFFTag} of the field belongs.
 422      * @param node A native TIFF image metadata {@code TIFFField} node.
 423      * @throws IllegalArgumentException If the {@code Node} parameter content
 424      * does not adhere to the {@code TIFFField} element structure defined by
 425      * the <a href="../../metadata/doc-files/tiff_metadata.html#ImageMetadata">
 426      * TIFF native image metadata format specification</a>, or if the
 427      * combination of node attributes and data is not legal per the
 428      * {@link #TIFFField(TIFFTag,int,int,Object)} constructor specification.
 429      * Note that a cause might be set on such an exception.
 430      * @return A new {@code TIFFField}.
 431      */
 432     public static TIFFField createFromMetadataNode(TIFFTagSet tagSet,
 433                                                    Node node) {
 434         if (node == null) {
 435             // This method is specified to throw only IllegalArgumentExceptions
 436             // so we create an IAE with a NullPointerException as its cause.
 437             throw new IllegalArgumentException(new NullPointerException
 438                 ("node == null!"));
 439         }
 440         String name = node.getNodeName();
 441         if (!name.equals("TIFFField")) {
 442             throw new IllegalArgumentException("!name.equals(\"TIFFField\")");
 443         }
 444 
 445         int tagNumber = Integer.parseInt(getAttribute(node, "number"));
 446         TIFFTag tag = null;
 447         if (tagSet != null) {
 448             tag = tagSet.getTag(tagNumber);
 449         }
 450 
 451         int type = TIFFTag.TIFF_UNDEFINED;
 452         int count = 0;
 453         Object data = null;
 454 
 455         Node child = node.getFirstChild();
 456         if (child != null) {
 457             String typeName = child.getNodeName();
 458             if (typeName.equals("TIFFUndefined")) {
 459                 String values = getAttribute(child, "value");
 460                 StringTokenizer st = new StringTokenizer(values, ",");
 461                 count = st.countTokens();
 462 
 463                 byte[] bdata = new byte[count];
 464                 for (int i = 0; i < count; i++) {
 465                     bdata[i] = (byte)Integer.parseInt(st.nextToken());
 466                 }
 467 
 468                 type = TIFFTag.TIFF_UNDEFINED;
 469                 data = bdata;
 470             } else {
 471                 int[] otype = new int[1];
 472                 int[] ocount = new int[1];
 473                 Object[] odata = new Object[1];
 474 
 475                 initData(node.getFirstChild(), otype, ocount, odata);
 476                 type = otype[0];
 477                 count = ocount[0];
 478                 data = odata[0];
 479             }
 480         } else if (tag != null) {
 481             int t = TIFFTag.MAX_DATATYPE;
 482             while(t >= TIFFTag.MIN_DATATYPE && !tag.isDataTypeOK(t)) {
 483                 t--;
 484             }
 485             type = t;
 486         }
 487 
 488         if (tag == null) {
 489             tag = new TIFFTag(TIFFTag.UNKNOWN_TAG_NAME, tagNumber, 1 << type);
 490         }
 491 
 492         TIFFField field;
 493         try {
 494             field = new TIFFField(tag, type, count, data);
 495         } catch (NullPointerException npe) {
 496             // This method is specified to throw only IllegalArgumentExceptions
 497             // so we catch the NullPointerException and set it as the cause of
 498             // the IAE which is thrown.
 499             throw new IllegalArgumentException(npe);
 500         }
 501 
 502         return field;
 503     }
 504 
 505     /**
 506      * Constructs a {@code TIFFField} with arbitrary data. The
 507      * {@code type} parameter must be a value for which
 508      * {@link TIFFTag#isDataTypeOK tag.isDataTypeOK()}
 509      * returns {@code true}. The {@code data} parameter must
 510      * be an array of a Java type appropriate for the type of the TIFF
 511      * field.
 512      *
 513      * <p>Note that the value (data) of the {@code TIFFField}
 514      * will always be the actual field value regardless of the number of
 515      * bytes required for that value. This is the case despite the fact
 516      * that the TIFF <i>IFD Entry</i> corresponding to the field may
 517      * actually contain the offset to the value of the field rather than
 518      * the value itself (the latter occurring if and only if the
 519      * value fits into 4 bytes). In other words, the value of the
 520      * field will already have been read from the TIFF stream. (An exception
 521      * to this case may occur when the field represents the contents of a
 522      * non-baseline IFD. In that case the data will be a {@code long[]}
 523      * containing the offset to the IFD and the {@code TIFFDirectory}
 524      * returned by {@link #getDirectory()} will be its contents.)
 525      *
 526      * @param tag The tag to associated with this field.
 527      * @param type One of the {@code TIFFTag.TIFF_*} constants
 528      * indicating the data type of the field as written to the TIFF stream.
 529      * @param count The number of data values.
 530      * @param data The actual data content of the field.
 531      *
 532      * @throws NullPointerException if {@code tag == null}.
 533      * @throws IllegalArgumentException if {@code type} is not
 534      * one of the {@code TIFFTag.TIFF_*} data type constants.
 535      * @throws IllegalArgumentException if {@code type} is an unacceptable
 536      * data type for the supplied {@code TIFFTag}.
 537      * @throws IllegalArgumentException if {@code count < 0}.
 538      * @throws IllegalArgumentException if {@code count < 1}
 539      * and {@code type} is {@code TIFF_RATIONAL} or
 540      * {@code TIFF_SRATIONAL}.
 541      * @throws IllegalArgumentException if {@code count != 1}
 542      * and {@code type} is {@code TIFF_IFD_POINTER}.
 543      * @throws NullPointerException if {@code data == null}.
 544      * @throws IllegalArgumentException if {@code data} is an instance of
 545      * a class incompatible with the specified type.
 546      * @throws IllegalArgumentException if the size of the data array is wrong.
 547      */
 548     public TIFFField(TIFFTag tag, int type, int count, Object data) {
 549         if(tag == null) {
 550             throw new NullPointerException("tag == null!");
 551         } else if(type < TIFFTag.MIN_DATATYPE || type > TIFFTag.MAX_DATATYPE) {
 552             throw new IllegalArgumentException("Unknown data type "+type);
 553         } else if(!tag.isDataTypeOK(type)) {
 554             throw new IllegalArgumentException("Illegal data type " + type
 555                 + " for " + tag.getName() + " tag");
 556         } else if(count < 0) {
 557             throw new IllegalArgumentException("count < 0!");
 558         } else if((type == TIFFTag.TIFF_RATIONAL
 559                    || type == TIFFTag.TIFF_SRATIONAL)
 560                   && count < 1) {
 561             throw new IllegalArgumentException
 562                 ("Type is TIFF_RATIONAL or TIFF_SRATIONAL and count < 1");
 563         } else if (type == TIFFTag.TIFF_IFD_POINTER && count != 1) {
 564             throw new IllegalArgumentException
 565                 ("Type is TIFF_IFD_POINTER count != 1");
 566         } else if(data == null) {
 567             throw new NullPointerException("data == null!");
 568         }
 569 
 570         boolean isDataArrayCorrect = false;
 571 
 572         switch (type) {
 573         case TIFFTag.TIFF_BYTE:
 574         case TIFFTag.TIFF_SBYTE:
 575         case TIFFTag.TIFF_UNDEFINED:
 576             isDataArrayCorrect = data instanceof byte[]
 577                 && ((byte[])data).length == count;
 578             break;
 579         case TIFFTag.TIFF_ASCII:
 580             isDataArrayCorrect = data instanceof String[]
 581                 && ((String[])data).length == count;
 582             break;
 583         case TIFFTag.TIFF_SHORT:
 584             isDataArrayCorrect = data instanceof char[]
 585                 && ((char[])data).length == count;
 586             break;
 587         case TIFFTag.TIFF_LONG:
 588             isDataArrayCorrect = data instanceof long[]
 589                 && ((long[])data).length == count;
 590             break;
 591         case TIFFTag.TIFF_IFD_POINTER:
 592             isDataArrayCorrect = data instanceof long[]
 593                 && ((long[])data).length == 1;
 594             break;
 595         case TIFFTag.TIFF_RATIONAL:
 596             isDataArrayCorrect = data instanceof long[][]
 597                 && ((long[][])data).length == count
 598                 && ((long[][])data)[0].length == 2;
 599             break;
 600         case TIFFTag.TIFF_SSHORT:
 601             isDataArrayCorrect = data instanceof short[]
 602                 && ((short[])data).length == count;
 603             break;
 604         case TIFFTag.TIFF_SLONG:
 605             isDataArrayCorrect = data instanceof int[]
 606                 && ((int[])data).length == count;
 607             break;
 608         case TIFFTag.TIFF_SRATIONAL:
 609             isDataArrayCorrect = data instanceof int[][]
 610                 && ((int[][])data).length == count
 611                 && ((int[][])data)[0].length == 2;
 612             break;
 613         case TIFFTag.TIFF_FLOAT:
 614             isDataArrayCorrect = data instanceof float[]
 615                 && ((float[])data).length == count;
 616             break;
 617         case TIFFTag.TIFF_DOUBLE:
 618             isDataArrayCorrect = data instanceof double[]
 619                 && ((double[])data).length == count;
 620             break;
 621         default:
 622             throw new IllegalArgumentException("Unknown data type "+type);
 623         }
 624 
 625         if (!isDataArrayCorrect) {
 626             throw new IllegalArgumentException
 627                 ("Illegal class or length for data array");
 628         }
 629 
 630         this.tag = tag;
 631         this.tagNumber = tag.getNumber();
 632         this.type = type;
 633         this.count = count;
 634         this.data = data;
 635     }
 636 
 637     /**
 638      * Constructs a data array using {@link #createArrayForType
 639      * createArrayForType()} and invokes
 640      * {@link #TIFFField(TIFFTag,int,int,Object)} with the supplied
 641      * parameters and the created array.
 642      *
 643      * @param tag The tag to associated with this field.
 644      * @param type One of the {@code TIFFTag.TIFF_*} constants
 645      * indicating the data type of the field as written to the TIFF stream.
 646      * @param count The number of data values.
 647      * @throws NullPointerException if {@code tag == null}.
 648      * @throws IllegalArgumentException if {@code type} is not
 649      * one of the {@code TIFFTag.TIFF_*} data type constants.
 650      * @throws IllegalArgumentException if {@code type} is an unacceptable
 651      * data type for the supplied {@code TIFFTag}.
 652      * @throws IllegalArgumentException if {@code count < 0}.
 653      * @see #TIFFField(TIFFTag,int,int,Object)
 654      */
 655     public TIFFField(TIFFTag tag, int type, int count) {
 656         this(tag, type, count, createArrayForType(type, count));
 657     }
 658 
 659     /**
 660      * Constructs a {@code TIFFField} with a single non-negative integral
 661      * value.
 662      * The field will have type
 663      * {@link TIFFTag#TIFF_SHORT  TIFF_SHORT} if
 664      * {@code val < 65536} and type
 665      * {@link TIFFTag#TIFF_LONG TIFF_LONG} otherwise.  The count
 666      * of the field will be unity.
 667      *
 668      * @param tag The tag to associate with this field.
 669      * @param value The value to associate with this field.
 670      * @throws NullPointerException if {@code tag == null}.
 671      * @throws IllegalArgumentException if the derived type is unacceptable
 672      * for the supplied {@code TIFFTag}.
 673      * @throws IllegalArgumentException if {@code value < 0}.
 674      */
 675     public TIFFField(TIFFTag tag, int value) {
 676         if(tag == null) {
 677             throw new NullPointerException("tag == null!");
 678         }
 679         if (value < 0) {
 680             throw new IllegalArgumentException("value < 0!");
 681         }
 682 
 683         this.tag = tag;
 684         this.tagNumber = tag.getNumber();
 685         this.count = 1;
 686 
 687         if (value < 65536) {
 688             if (!tag.isDataTypeOK(TIFFTag.TIFF_SHORT)) {
 689                 throw new IllegalArgumentException("Illegal data type "
 690                     + TIFFTag.TIFF_SHORT + " for " + tag.getName() + " tag");
 691             }
 692             this.type = TIFFTag.TIFF_SHORT;
 693             char[] cdata = new char[1];
 694             cdata[0] = (char)value;
 695             this.data = cdata;
 696         } else {
 697             if (!tag.isDataTypeOK(TIFFTag.TIFF_LONG)) {
 698                 throw new IllegalArgumentException("Illegal data type "
 699                     + TIFFTag.TIFF_LONG + " for " + tag.getName() + " tag");
 700             }
 701             this.type = TIFFTag.TIFF_LONG;
 702             long[] ldata = new long[1];
 703             ldata[0] = value;
 704             this.data = ldata;
 705         }
 706     }
 707 
 708     /**
 709      * Constructs a {@code TIFFField} with an IFD offset and contents.
 710      * The offset will be stored as the data of this field as
 711      * {@code long[] {offset}}. The directory will not be cloned. The count
 712      * of the field will be unity.
 713      *
 714      * @param tag The tag to associated with this field.
 715      * @param type One of the constants {@code TIFFTag.TIFF_LONG} or
 716      * {@code TIFFTag.TIFF_IFD_POINTER}.
 717      * @param offset The IFD offset.
 718      * @param dir The directory.
 719      *
 720      * @throws NullPointerException if {@code tag == null}.
 721      * @throws IllegalArgumentException if {@code type} is an unacceptable
 722      * data type for the supplied {@code TIFFTag}.
 723      * @throws IllegalArgumentException if {@code type} is neither
 724      * {@code TIFFTag.TIFF_LONG} nor {@code TIFFTag.TIFF_IFD_POINTER}.
 725      * @throws IllegalArgumentException if {@code offset <= 0}.
 726      * @throws NullPointerException if {@code dir == null}.
 727      *
 728      * @see #TIFFField(TIFFTag,int,int,Object)
 729      */
 730     public TIFFField(TIFFTag tag, int type, long offset, TIFFDirectory dir) {
 731         if (tag == null) {
 732             throw new NullPointerException("tag == null!");
 733         } else if (type < TIFFTag.MIN_DATATYPE || type > TIFFTag.MAX_DATATYPE) {
 734             throw new IllegalArgumentException("Unknown data type "+type);
 735         } else if (!tag.isDataTypeOK(type)) {
 736             throw new IllegalArgumentException("Illegal data type " + type
 737                 + " for " + tag.getName() + " tag");
 738         } else if (type != TIFFTag.TIFF_LONG
 739                    && type != TIFFTag.TIFF_IFD_POINTER) {
 740             throw new IllegalArgumentException("type " + type
 741                 + " is neither TIFFTag.TIFF_LONG nor TIFFTag.TIFF_IFD_POINTER");
 742         } else if (offset <= 0) {
 743             throw new IllegalArgumentException("offset " + offset
 744                 + " is non-positive");
 745         } else if (dir == null) {
 746             throw new NullPointerException("dir == null");
 747         }
 748 
 749         this.tag = tag;
 750         this.tagNumber = tag.getNumber();
 751         this.type = type;
 752         this.count = 1;
 753         this.data = new long[] {offset};
 754 
 755         this.dir = dir;
 756     }
 757 
 758     /**
 759      * Retrieves the tag associated with this field.
 760      *
 761      * @return The associated {@code TIFFTag}.
 762      */
 763     public TIFFTag getTag() {
 764         return tag;
 765     }
 766 
 767     /**
 768      * Retrieves the tag number in the range {@code [0,65535]}.
 769      *
 770      * @return The tag number.
 771      */
 772     public int getTagNumber() {
 773         return tagNumber;
 774     }
 775 
 776     /**
 777      * Returns the type of the data stored in the field.  For a TIFF 6.0
 778      * stream, the value will equal one of the {@code TIFFTag.TIFF_*}
 779      * constants. For future revisions of TIFF, higher values are possible.
 780      *
 781      * @return The data type of the field value.
 782      */
 783     public int getType() {
 784         return type;
 785     }
 786 
 787     /**
 788      * Returns the name of the supplied data type constant.
 789      *
 790      * @param dataType One of the {@code TIFFTag.TIFF_*} constants
 791      * indicating the data type of the field as written to the TIFF stream.
 792      * @return The type name corresponding to the supplied type constant.
 793      * @throws IllegalArgumentException if {@code dataType} is not
 794      * one of the {@code TIFFTag.TIFF_*} data type constants.
 795      */
 796     public static String getTypeName(int dataType) {
 797         if (dataType < TIFFTag.MIN_DATATYPE ||
 798             dataType > TIFFTag.MAX_DATATYPE) {
 799             throw new IllegalArgumentException("Unknown data type "+dataType);
 800         }
 801 
 802         return typeNames[dataType];
 803     }
 804 
 805     /**
 806      * Returns the data type constant corresponding to the supplied data
 807      * type name. If the name is unknown {@code -1} will be returned.
 808      *
 809      * @param typeName The type name.
 810      * @return One of the {@code TIFFTag.TIFF_*} constants or
 811      * {@code -1} if the name is not recognized.
 812      */
 813     public static int getTypeByName(String typeName) {
 814         for (int i = TIFFTag.MIN_DATATYPE; i <= TIFFTag.MAX_DATATYPE; i++) {
 815             if (typeName.equals(typeNames[i])) {
 816                 return i;
 817             }
 818         }
 819 
 820         return -1;
 821     }
 822 
 823     /**
 824      * Creates an array appropriate for the indicated data type.
 825      *
 826      * @param dataType One of the {@code TIFFTag.TIFF_*} data type
 827      * constants.
 828      * @param count The number of values in the array.
 829      * @return An array appropriate for the specified data type.
 830      *
 831      * @throws IllegalArgumentException if {@code dataType} is not
 832      * one of the {@code TIFFTag.TIFF_*} data type constants.
 833      * @throws IllegalArgumentException if {@code count < 0}.
 834      */
 835     public static Object createArrayForType(int dataType, int count) {
 836         if(count < 0) {
 837             throw new IllegalArgumentException("count < 0!");
 838         }
 839         switch (dataType) {
 840         case TIFFTag.TIFF_BYTE:
 841         case TIFFTag.TIFF_SBYTE:
 842         case TIFFTag.TIFF_UNDEFINED:
 843             return new byte[count];
 844         case TIFFTag.TIFF_ASCII:
 845             return new String[count];
 846         case TIFFTag.TIFF_SHORT:
 847             return new char[count];
 848         case TIFFTag.TIFF_LONG:
 849         case TIFFTag.TIFF_IFD_POINTER:
 850             return new long[count];
 851         case TIFFTag.TIFF_RATIONAL:
 852             return new long[count][2];
 853         case TIFFTag.TIFF_SSHORT:
 854             return new short[count];
 855         case TIFFTag.TIFF_SLONG:
 856             return new int[count];
 857         case TIFFTag.TIFF_SRATIONAL:
 858             return new int[count][2];
 859         case TIFFTag.TIFF_FLOAT:
 860             return new float[count];
 861         case TIFFTag.TIFF_DOUBLE:
 862             return new double[count];
 863         default:
 864             throw new IllegalArgumentException("Unknown data type "+dataType);
 865         }
 866     }
 867 
 868     /**
 869      * Returns the {@code TIFFField} as a node named either
 870      * <tt>"TIFFField"</tt> or <tt>"TIFFIFD"</tt> as described in the
 871      * TIFF native image metadata specification. The node will be named
 872      * <tt>"TIFFIFD"</tt> if and only if {@link #hasDirectory()} returns
 873      * {@code true} and the field's type is either {@link TIFFTag#TIFF_LONG}
 874      * or {@link TIFFTag#TIFF_IFD_POINTER}.
 875      *
 876      * @return a {@code Node} named <tt>"TIFFField"</tt> or
 877      * <tt>"TIFFIFD"</tt>.
 878      */
 879     public Node getAsNativeNode() {
 880         return new TIFFFieldNode(this);
 881     }
 882 
 883     /**
 884      * Indicates whether the value associated with the field is of
 885      * integral data type.
 886      *
 887      * @return Whether the field type is integral.
 888      */
 889     public boolean isIntegral() {
 890         return isIntegral[type];
 891     }
 892 
 893     /**
 894      * Returns the number of data items present in the field.  For
 895      * {@code TIFFTag.TIFF_ASCII} fields, the value returned is the
 896      * number of {@code String}s, not the total length of the
 897      * data as in the file representation.
 898      *
 899      * @return The number of data items present in the field.
 900      */
 901     public int getCount() {
 902         return count;
 903     }
 904 
 905     /**
 906      * Returns a reference to the data object associated with the field.
 907      *
 908      * @return The data object of the field.
 909      */
 910     public Object getData() {
 911         return data;
 912     }
 913 
 914     /**
 915      * Returns the data as an uninterpreted array of
 916      * {@code byte}s.  The type of the field must be one of
 917      * {@code TIFFTag.TIFF_BYTE}, {@code TIFF_SBYTE}, or
 918      * {@code TIFF_UNDEFINED}.
 919      *
 920      * <p> For data in {@code TIFFTag.TIFF_BYTE} format, the application
 921      * must take care when promoting the data to longer integral types
 922      * to avoid sign extension.
 923      *
 924      * @throws ClassCastException if the field is not of type
 925      * {@code TIFF_BYTE}, {@code TIFF_SBYTE}, or
 926      * {@code TIFF_UNDEFINED}.
 927      * @return The data as an uninterpreted array of bytes.
 928      */
 929     public byte[] getAsBytes() {
 930         return (byte[])data;
 931     }
 932 
 933     /**
 934      * Returns {@code TIFFTag.TIFF_SHORT} data as an array of
 935      * {@code char}s (unsigned 16-bit integers).
 936      *
 937      * @throws ClassCastException if the field is not of type
 938      * {@code TIFF_SHORT}.
 939      * @return The data as an array of {@code char}s.
 940      */
 941     public char[] getAsChars() {
 942         return (char[])data;
 943     }
 944 
 945     /**
 946      * Returns {@code TIFFTag.TIFF_SSHORT} data as an array of
 947      * {@code short}s (signed 16-bit integers).
 948      *
 949      * @throws ClassCastException if the field is not of type
 950      * {@code TIFF_SSHORT}.
 951      * @return The data as an array of {@code short}s.
 952      */
 953     public short[] getAsShorts() {
 954         return (short[])data;
 955     }
 956 
 957     /**
 958      * Returns {@code TIFFTag.TIFF_SLONG} data as an array of
 959      * {@code int}s (signed 32-bit integers).
 960      *
 961      * @throws ClassCastException if the field is not of type
 962      * {@code TIFF_SHORT}, {@code TIFF_SSHORT}, or
 963      * {@code TIFF_SLONG}.
 964      * @return The data as an array of {@code int}s.
 965      */
 966     public int[] getAsInts() {
 967         if (data instanceof int[]) {
 968             return (int[])data;
 969         } else if (data instanceof char[]){
 970             char[] cdata = (char[])data;
 971             int[] idata = new int[cdata.length];
 972             for (int i = 0; i < cdata.length; i++) {
 973                 idata[i] = cdata[i] & 0xffff;
 974             }
 975             return idata;
 976         } else if (data instanceof short[]){
 977             short[] sdata = (short[])data;
 978             int[] idata = new int[sdata.length];
 979             for (int i = 0; i < sdata.length; i++) {
 980                 idata[i] = (int)sdata[i];
 981             }
 982             return idata;
 983         } else {
 984             throw new ClassCastException("Data not char[], short[], or int[]!");
 985         }
 986     }
 987 
 988     /**
 989      * Returns {@code TIFFTag.TIFF_LONG} or
 990      * {@code TIFF_IFD_POINTER} data as an array of
 991      * {@code long}s (signed 64-bit integers).
 992      *
 993      * @throws ClassCastException if the field is not of type
 994      * {@code TIFF_LONG} or {@code TIFF_IFD_POINTER}.
 995      * @return The data as an array of {@code long}s.
 996      */
 997     public long[] getAsLongs() {
 998         return (long[])data;
 999     }
1000 
1001     /**
1002      * Returns {@code TIFFTag.TIFF_FLOAT} data as an array of
1003      * {@code float}s (32-bit floating-point values).
1004      *
1005      * @throws ClassCastException if the field is not of type
1006      * {@code TIFF_FLOAT}.
1007      * @return The data as an array of {@code float}s.
1008      */
1009     public float[] getAsFloats() {
1010         return (float[])data;
1011     }
1012 
1013     /**
1014      * Returns {@code TIFFTag.TIFF_DOUBLE} data as an array of
1015      * {@code double}s (64-bit floating-point values).
1016      *
1017      * @throws ClassCastException if the field is not of type
1018      * {@code TIFF_DOUBLE}.
1019      * @return The data as an array of {@code double}s.
1020      */
1021     public double[] getAsDoubles() {
1022         return (double[])data;
1023     }
1024 
1025     /**
1026      * Returns {@code TIFFTag.TIFF_SRATIONAL} data as an array of
1027      * 2-element arrays of {@code int}s.
1028      *
1029      * @throws ClassCastException if the field is not of type
1030      * {@code TIFF_SRATIONAL}.
1031      * @return The data as an array of signed rationals.
1032      */
1033     public int[][] getAsSRationals() {
1034         return (int[][])data;
1035     }
1036 
1037     /**
1038      * Returns {@code TIFFTag.TIFF_RATIONAL} data as an array of
1039      * 2-element arrays of {@code long}s.
1040      *
1041      * @throws ClassCastException if the field is not of type
1042      * {@code TIFF_RATIONAL}.
1043      * @return The data as an array of unsigned rationals.
1044      */
1045     public long[][] getAsRationals() {
1046         return (long[][])data;
1047     }
1048 
1049     /**
1050      * Returns data in any format as an {@code int}.
1051      *
1052      * <p> {@code TIFFTag.TIFF_BYTE} values are treated as unsigned; that
1053      * is, no sign extension will take place and the returned value
1054      * will be in the range [0, 255].  {@code TIFF_SBYTE} data
1055      * will be returned in the range [-128, 127].
1056      *
1057      * <p> A {@code TIFF_UNDEFINED} value is treated as though
1058      * it were a {@code TIFF_BYTE}.
1059      *
1060      * <p> Data in {@code TIFF_SLONG}, {@code TIFF_LONG},
1061      * {@code TIFF_FLOAT}, {@code TIFF_DOUBLE} or
1062      * {@code TIFF_IFD_POINTER} format are simply cast to
1063      * {@code int} and may suffer from truncation.
1064      *
1065      * <p> Data in {@code TIFF_SRATIONAL} or
1066      * {@code TIFF_RATIONAL} format are evaluated by dividing the
1067      * numerator into the denominator using double-precision
1068      * arithmetic and then casting to {@code int}.  Loss of
1069      * precision and truncation may occur.
1070      *
1071      * <p> Data in {@code TIFF_ASCII} format will be parsed as by
1072      * the {@code Double.parseDouble} method, with the result
1073      * case to {@code int}.
1074      *
1075      * @param index The index of the data.
1076      * @return The data at the given index as an {@code int}.
1077      */
1078     public int getAsInt(int index) {
1079         switch (type) {
1080         case TIFFTag.TIFF_BYTE:
1081         case TIFFTag.TIFF_UNDEFINED:
1082             return ((byte[])data)[index] & 0xff;
1083         case TIFFTag.TIFF_SBYTE:
1084             return ((byte[])data)[index];
1085         case TIFFTag.TIFF_SHORT:
1086             return ((char[])data)[index] & 0xffff;
1087         case TIFFTag.TIFF_SSHORT:
1088             return ((short[])data)[index];
1089         case TIFFTag.TIFF_SLONG:
1090             return ((int[])data)[index];
1091         case TIFFTag.TIFF_LONG:
1092         case TIFFTag.TIFF_IFD_POINTER:
1093             return (int)((long[])data)[index];
1094         case TIFFTag.TIFF_FLOAT:
1095             return (int)((float[])data)[index];
1096         case TIFFTag.TIFF_DOUBLE:
1097             return (int)((double[])data)[index];
1098         case TIFFTag.TIFF_SRATIONAL:
1099             int[] ivalue = getAsSRational(index);
1100             return (int)((double)ivalue[0]/ivalue[1]);
1101         case TIFFTag.TIFF_RATIONAL:
1102             long[] lvalue = getAsRational(index);
1103             return (int)((double)lvalue[0]/lvalue[1]);
1104         case TIFFTag.TIFF_ASCII:
1105              String s = ((String[])data)[index];
1106              return (int)Double.parseDouble(s);
1107         default:
1108             throw new ClassCastException(); // should never happen
1109         }
1110     }
1111 
1112     /**
1113      * Returns data in any format as a {@code long}.
1114      *
1115      * <p> {@code TIFFTag.TIFF_BYTE} and {@code TIFF_UNDEFINED} data
1116      * are treated as unsigned; that is, no sign extension will take
1117      * place and the returned value will be in the range [0, 255].
1118      * {@code TIFF_SBYTE} data will be returned in the range
1119      * [-128, 127].
1120      *
1121      * <p> Data in {@code TIFF_FLOAT} and {@code TIFF_DOUBLE} are
1122      * simply cast to {@code long} and may suffer from truncation.
1123      *
1124      * <p> Data in {@code TIFF_SRATIONAL} or
1125      * {@code TIFF_RATIONAL} format are evaluated by dividing the
1126      * numerator into the denominator using double-precision
1127      * arithmetic and then casting to {@code long}.  Loss of
1128      * precision and truncation may occur.
1129      *
1130      * <p> Data in {@code TIFF_ASCII} format will be parsed as by
1131      * the {@code Double.parseDouble} method, with the result
1132      * cast to {@code long}.
1133      *
1134      * @param index The index of the data.
1135      * @return The data at the given index as a {@code long}.
1136      */
1137     public long getAsLong(int index) {
1138         switch (type) {
1139         case TIFFTag.TIFF_BYTE:
1140         case TIFFTag.TIFF_UNDEFINED:
1141             return ((byte[])data)[index] & 0xff;
1142         case TIFFTag.TIFF_SBYTE:
1143             return ((byte[])data)[index];
1144         case TIFFTag.TIFF_SHORT:
1145             return ((char[])data)[index] & 0xffff;
1146         case TIFFTag.TIFF_SSHORT:
1147             return ((short[])data)[index];
1148         case TIFFTag.TIFF_SLONG:
1149             return ((int[])data)[index];
1150         case TIFFTag.TIFF_LONG:
1151         case TIFFTag.TIFF_IFD_POINTER:
1152             return ((long[])data)[index];
1153         case TIFFTag.TIFF_FLOAT:
1154             return (long)((float[])data)[index];
1155         case TIFFTag.TIFF_DOUBLE:
1156             return (long)((double[])data)[index];
1157         case TIFFTag.TIFF_SRATIONAL:
1158             int[] ivalue = getAsSRational(index);
1159             return (long)((double)ivalue[0]/ivalue[1]);
1160         case TIFFTag.TIFF_RATIONAL:
1161             long[] lvalue = getAsRational(index);
1162             return (long)((double)lvalue[0]/lvalue[1]);
1163         case TIFFTag.TIFF_ASCII:
1164              String s = ((String[])data)[index];
1165              return (long)Double.parseDouble(s);
1166         default:
1167             throw new ClassCastException(); // should never happen
1168         }
1169     }
1170 
1171     /**
1172      * Returns data in any format as a {@code float}.
1173      *
1174      * <p> {@code TIFFTag.TIFF_BYTE} and {@code TIFF_UNDEFINED} data
1175      * are treated as unsigned; that is, no sign extension will take
1176      * place and the returned value will be in the range [0, 255].
1177      * {@code TIFF_SBYTE} data will be returned in the range
1178      * [-128, 127].
1179      *
1180      * <p> Data in {@code TIFF_SLONG}, {@code TIFF_LONG},
1181      * {@code TIFF_DOUBLE}, or {@code TIFF_IFD_POINTER} format are
1182      * simply cast to {@code float} and may suffer from
1183      * truncation.
1184      *
1185      * <p> Data in {@code TIFF_SRATIONAL} or
1186      * {@code TIFF_RATIONAL} format are evaluated by dividing the
1187      * numerator into the denominator using double-precision
1188      * arithmetic and then casting to {@code float}.
1189      *
1190      * <p> Data in {@code TIFF_ASCII} format will be parsed as by
1191      * the {@code Double.parseDouble} method, with the result
1192      * cast to {@code float}.
1193      *
1194      * @param index The index of the data.
1195      * @return The data at the given index as a {@code float}.
1196      */
1197     public float getAsFloat(int index) {
1198         switch (type) {
1199         case TIFFTag.TIFF_BYTE:
1200         case TIFFTag.TIFF_UNDEFINED:
1201             return ((byte[])data)[index] & 0xff;
1202         case TIFFTag.TIFF_SBYTE:
1203             return ((byte[])data)[index];
1204         case TIFFTag.TIFF_SHORT:
1205             return ((char[])data)[index] & 0xffff;
1206         case TIFFTag.TIFF_SSHORT:
1207             return ((short[])data)[index];
1208         case TIFFTag.TIFF_SLONG:
1209             return ((int[])data)[index];
1210         case TIFFTag.TIFF_LONG:
1211         case TIFFTag.TIFF_IFD_POINTER:
1212             return ((long[])data)[index];
1213         case TIFFTag.TIFF_FLOAT:
1214             return ((float[])data)[index];
1215         case TIFFTag.TIFF_DOUBLE:
1216             return (float)((double[])data)[index];
1217         case TIFFTag.TIFF_SRATIONAL:
1218             int[] ivalue = getAsSRational(index);
1219             return (float)((double)ivalue[0]/ivalue[1]);
1220         case TIFFTag.TIFF_RATIONAL:
1221             long[] lvalue = getAsRational(index);
1222             return (float)((double)lvalue[0]/lvalue[1]);
1223         case TIFFTag.TIFF_ASCII:
1224              String s = ((String[])data)[index];
1225              return (float)Double.parseDouble(s);
1226         default:
1227             throw new ClassCastException(); // should never happen
1228         }
1229     }
1230 
1231     /**
1232      * Returns data in any format as a {@code double}.
1233      *
1234      * <p> {@code TIFFTag.TIFF_BYTE} and {@code TIFF_UNDEFINED} data
1235      * are treated as unsigned; that is, no sign extension will take
1236      * place and the returned value will be in the range [0, 255].
1237      * {@code TIFF_SBYTE} data will be returned in the range
1238      * [-128, 127].
1239      *
1240      * <p> Data in {@code TIFF_SRATIONAL} or
1241      * {@code TIFF_RATIONAL} format are evaluated by dividing the
1242      * numerator into the denominator using double-precision
1243      * arithmetic.
1244      *
1245      * <p> Data in {@code TIFF_ASCII} format will be parsed as by
1246      * the {@code Double.parseDouble} method.
1247      *
1248      * @param index The index of the data.
1249      * @return The data at the given index as a {@code double}.
1250      */
1251     public double getAsDouble(int index) {
1252         switch (type) {
1253         case TIFFTag.TIFF_BYTE:
1254         case TIFFTag.TIFF_UNDEFINED:
1255             return ((byte[])data)[index] & 0xff;
1256         case TIFFTag.TIFF_SBYTE:
1257             return ((byte[])data)[index];
1258         case TIFFTag.TIFF_SHORT:
1259             return ((char[])data)[index] & 0xffff;
1260         case TIFFTag.TIFF_SSHORT:
1261             return ((short[])data)[index];
1262         case TIFFTag.TIFF_SLONG:
1263             return ((int[])data)[index];
1264         case TIFFTag.TIFF_LONG:
1265         case TIFFTag.TIFF_IFD_POINTER:
1266             return ((long[])data)[index];
1267         case TIFFTag.TIFF_FLOAT:
1268             return ((float[])data)[index];
1269         case TIFFTag.TIFF_DOUBLE:
1270             return ((double[])data)[index];
1271         case TIFFTag.TIFF_SRATIONAL:
1272             int[] ivalue = getAsSRational(index);
1273             return (double)ivalue[0]/ivalue[1];
1274         case TIFFTag.TIFF_RATIONAL:
1275             long[] lvalue = getAsRational(index);
1276             return (double)lvalue[0]/lvalue[1];
1277         case TIFFTag.TIFF_ASCII:
1278              String s = ((String[])data)[index];
1279              return Double.parseDouble(s);
1280         default:
1281             throw new ClassCastException(); // should never happen
1282         }
1283     }
1284 
1285     /**
1286      * Returns a {@code TIFFTag.TIFF_ASCII} value as a
1287      * {@code String}.
1288      *
1289      * @throws ClassCastException if the field is not of type
1290      * {@code TIFF_ASCII}.
1291      *
1292      * @param index The index of the data.
1293      * @return The data at the given index as a {@code String}.
1294      */
1295     public String getAsString(int index) {
1296         return ((String[])data)[index];
1297     }
1298 
1299     /**
1300      * Returns a {@code TIFFTag.TIFF_SRATIONAL} data item as a
1301      * two-element array of {@code int}s.
1302      *
1303      * @param index The index of the data.
1304      * @return The data at the given index as a signed rational.
1305      * @throws ClassCastException if the field is not of type
1306      * {@code TIFF_SRATIONAL}.
1307      */
1308     public int[] getAsSRational(int index) {
1309         return ((int[][])data)[index];
1310     }
1311 
1312     /**
1313      * Returns a TIFFTag.TIFF_RATIONAL data item as a two-element array
1314      * of ints.
1315      *
1316      * @param index The index of the data.
1317      * @return The data at the given index as an unsigned rational.
1318      * @throws ClassCastException if the field is not of type
1319      * {@code TIFF_RATIONAL}.
1320      */
1321     public long[] getAsRational(int index) {
1322         return ((long[][])data)[index];
1323     }
1324 
1325 
1326     /**
1327      * Returns a {@code String} containing a human-readable
1328      * version of the data item.  Data of type
1329      * {@code TIFFTag.TIFF_RATIONAL} or {@code TIFF_SRATIONAL} are
1330      * represented as a pair of integers separated by a
1331      * {@code '/'} character.  If the numerator of a
1332      * {@code TIFFTag.TIFF_RATIONAL} or {@code TIFF_SRATIONAL} is an integral
1333      * multiple of the denominator, then the value is represented as
1334      * {@code "q/1"} where {@code q} is the quotient of the numerator and
1335      * denominator.
1336      *
1337      * @param index The index of the data.
1338      * @return The data at the given index as a {@code String}.
1339      * @throws ClassCastException if the field is not of one of the
1340      * legal field types.
1341      */
1342     public String getValueAsString(int index) {
1343         switch (type) {
1344         case TIFFTag.TIFF_ASCII:
1345             return ((String[])data)[index];
1346         case TIFFTag.TIFF_BYTE:
1347         case TIFFTag.TIFF_UNDEFINED:
1348             return Integer.toString(((byte[])data)[index] & 0xff);
1349         case TIFFTag.TIFF_SBYTE:
1350             return Integer.toString(((byte[])data)[index]);
1351         case TIFFTag.TIFF_SHORT:
1352             return Integer.toString(((char[])data)[index] & 0xffff);
1353         case TIFFTag.TIFF_SSHORT:
1354             return Integer.toString(((short[])data)[index]);
1355         case TIFFTag.TIFF_SLONG:
1356             return Integer.toString(((int[])data)[index]);
1357         case TIFFTag.TIFF_LONG:
1358         case TIFFTag.TIFF_IFD_POINTER:
1359             return Long.toString(((long[])data)[index]);
1360         case TIFFTag.TIFF_FLOAT:
1361             return Float.toString(((float[])data)[index]);
1362         case TIFFTag.TIFF_DOUBLE:
1363             return Double.toString(((double[])data)[index]);
1364         case TIFFTag.TIFF_SRATIONAL:
1365             int[] ivalue = getAsSRational(index);
1366             String srationalString;
1367             if(ivalue[1] != 0 && ivalue[0] % ivalue[1] == 0) {
1368                 // If the denominator is a non-zero integral divisor
1369                 // of the numerator then convert the fraction to be
1370                 // with respect to a unity denominator.
1371                 srationalString =
1372                     Integer.toString(ivalue[0] / ivalue[1]) + "/1";
1373             } else {
1374                 // Use the values directly.
1375                 srationalString =
1376                     Integer.toString(ivalue[0]) +
1377                     "/" +
1378                     Integer.toString(ivalue[1]);
1379             }
1380             return srationalString;
1381         case TIFFTag.TIFF_RATIONAL:
1382             long[] lvalue = getAsRational(index);
1383             String rationalString;
1384             if(lvalue[1] != 0L && lvalue[0] % lvalue[1] == 0) {
1385                 // If the denominator is a non-zero integral divisor
1386                 // of the numerator then convert the fraction to be
1387                 // with respect to a unity denominator.
1388                 rationalString =
1389                     Long.toString(lvalue[0] / lvalue[1]) + "/1";
1390             } else {
1391                 // Use the values directly.
1392                 rationalString =
1393                     Long.toString(lvalue[0]) +
1394                     "/" +
1395                     Long.toString(lvalue[1]);
1396             }
1397             return rationalString;
1398         default:
1399             throw new ClassCastException(); // should never happen
1400         }
1401     }
1402 
1403     /**
1404      * Returns whether the field has a {@code TIFFDirectory}.
1405      *
1406      * @return true if and only if getDirectory() returns non-null.
1407      */
1408     public boolean hasDirectory() {
1409         return getDirectory() != null;
1410     }
1411 
1412     /**
1413      * Returns the associated {@code TIFFDirectory}, if available. If no
1414      * directory is set, then {@code null} will be returned.
1415      *
1416      * @return the TIFFDirectory instance or null.
1417      */
1418     public TIFFDirectory getDirectory() {
1419         return dir;
1420     }
1421 
1422     /**
1423      * Clones the field and all the information contained therein.
1424      *
1425      * @return A clone of this {@code TIFFField}.
1426      * @throws CloneNotSupportedException if the instance cannot be cloned.
1427      */
1428     @Override
1429     public TIFFField clone() throws CloneNotSupportedException {
1430         TIFFField field = (TIFFField)super.clone();
1431 
1432         Object fieldData;
1433         switch (type) {
1434         case TIFFTag.TIFF_BYTE:
1435         case TIFFTag.TIFF_UNDEFINED:
1436         case TIFFTag.TIFF_SBYTE:
1437             fieldData = ((byte[])data).clone();
1438             break;
1439         case TIFFTag.TIFF_SHORT:
1440             fieldData = ((char[])data).clone();
1441             break;
1442         case TIFFTag.TIFF_SSHORT:
1443             fieldData = ((short[])data).clone();
1444             break;
1445         case TIFFTag.TIFF_SLONG:
1446             fieldData = ((int[])data).clone();
1447             break;
1448         case TIFFTag.TIFF_LONG:
1449         case TIFFTag.TIFF_IFD_POINTER:
1450             fieldData = ((long[])data).clone();
1451             break;
1452         case TIFFTag.TIFF_FLOAT:
1453             fieldData = ((float[])data).clone();
1454             break;
1455         case TIFFTag.TIFF_DOUBLE:
1456             fieldData = ((double[])data).clone();
1457             break;
1458         case TIFFTag.TIFF_SRATIONAL:
1459             fieldData = ((int[][])data).clone();
1460             break;
1461         case TIFFTag.TIFF_RATIONAL:
1462             fieldData = ((long[][])data).clone();
1463             break;
1464         case TIFFTag.TIFF_ASCII:
1465             fieldData = ((String[])data).clone();
1466             break;
1467         default:
1468             throw new ClassCastException(); // should never happen
1469         }
1470 
1471         field.tag = tag;
1472         field.tagNumber = tagNumber;
1473         field.type = type;
1474         field.count = count;
1475         field.data = fieldData;
1476         field.dir = dir != null ? dir.clone() : null;
1477 
1478         return field;
1479     }
1480 }