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 long MAX_UINT32 = 0xffffffffL;
 267 
 268     private static final String[] TYPE_NAMES = {
 269         null,
 270         "Byte", "Ascii", "Short", "Long", "Rational",
 271         "SByte", "Undefined", "SShort", "SLong", "SRational",
 272         "Float", "Double", "IFDPointer"
 273     };
 274 
 275     private static final boolean[] IS_INTEGRAL = {
 276         false,
 277         true, false, true, true, false,
 278         true, true, true, true, false,
 279         false, false, false
 280     };
 281 
 282     /** The tag. */
 283     private TIFFTag tag;
 284 
 285     /** The tag number. */
 286     private int tagNumber;
 287 
 288     /** The tag type. */
 289     private int type;
 290 
 291     /** The number of data items present in the field. */
 292     private int count;
 293 
 294     /** The field data. */
 295     private Object data;
 296 
 297     /** The IFD contents if available. This will usually be a TIFFIFD. */
 298     private TIFFDirectory dir;
 299 
 300     /** The default constructor. */
 301     private TIFFField() {}
 302 
 303     private static String getAttribute(Node node, String attrName) {
 304         NamedNodeMap attrs = node.getAttributes();
 305         return attrs.getNamedItem(attrName).getNodeValue();
 306     }
 307 
 308     private static void initData(Node node,
 309                                  int[] otype, int[] ocount, Object[] odata) {
 310         int type;
 311         int count;
 312         Object data = null;
 313 
 314         String typeName = node.getNodeName();
 315         typeName = typeName.substring(4);
 316         typeName = typeName.substring(0, typeName.length() - 1);
 317         type = TIFFField.getTypeByName(typeName);
 318         if (type == -1) {
 319             throw new IllegalArgumentException("typeName = " + typeName);
 320         }
 321 
 322         Node child = node.getFirstChild();
 323 
 324         count = 0;
 325         while (child != null) {
 326             String childTypeName = child.getNodeName().substring(4);
 327             if (!typeName.equals(childTypeName)) {
 328                 // warning
 329             }
 330 
 331             ++count;
 332             child = child.getNextSibling();
 333         }
 334 
 335         if (count > 0) {
 336             data = createArrayForType(type, count);
 337             child = node.getFirstChild();
 338             int idx = 0;
 339             while (child != null) {
 340                 String value = getAttribute(child, "value");
 341 
 342                 String numerator, denominator;
 343                 int slashPos;
 344 
 345                 switch (type) {
 346                 case TIFFTag.TIFF_ASCII:
 347                     ((String[])data)[idx] = value;
 348                     break;
 349                 case TIFFTag.TIFF_BYTE:
 350                 case TIFFTag.TIFF_SBYTE:
 351                     ((byte[])data)[idx] =
 352                         (byte)Integer.parseInt(value);
 353                     break;
 354                 case TIFFTag.TIFF_SHORT:
 355                     ((char[])data)[idx] =
 356                         (char)Integer.parseInt(value);
 357                     break;
 358                 case TIFFTag.TIFF_SSHORT:
 359                     ((short[])data)[idx] =
 360                         (short)Integer.parseInt(value);
 361                     break;
 362                 case TIFFTag.TIFF_SLONG:
 363                     ((int[])data)[idx] =
 364                         Integer.parseInt(value);
 365                     break;
 366                 case TIFFTag.TIFF_LONG:
 367                 case TIFFTag.TIFF_IFD_POINTER:
 368                     ((long[])data)[idx] =
 369                         Long.parseLong(value);
 370                     break;
 371                 case TIFFTag.TIFF_FLOAT:
 372                     ((float[])data)[idx] =
 373                         Float.parseFloat(value);
 374                     break;
 375                 case TIFFTag.TIFF_DOUBLE:
 376                     ((double[])data)[idx] =
 377                         Double.parseDouble(value);
 378                     break;
 379                 case TIFFTag.TIFF_SRATIONAL:
 380                     slashPos = value.indexOf("/");
 381                     numerator = value.substring(0, slashPos);
 382                     denominator = value.substring(slashPos + 1);
 383 
 384                     ((int[][])data)[idx] = new int[2];
 385                     ((int[][])data)[idx][0] =
 386                         Integer.parseInt(numerator);
 387                     ((int[][])data)[idx][1] =
 388                         Integer.parseInt(denominator);
 389                     break;
 390                 case TIFFTag.TIFF_RATIONAL:
 391                     slashPos = value.indexOf("/");
 392                     numerator = value.substring(0, slashPos);
 393                     denominator = value.substring(slashPos + 1);
 394 
 395                     ((long[][])data)[idx] = new long[2];
 396                     ((long[][])data)[idx][0] =
 397                         Long.parseLong(numerator);
 398                     ((long[][])data)[idx][1] =
 399                         Long.parseLong(denominator);
 400                     break;
 401                 default:
 402                     // error
 403                 }
 404 
 405                 idx++;
 406                 child = child.getNextSibling();
 407             }
 408         }
 409 
 410         otype[0] = type;
 411         ocount[0] = count;
 412         odata[0] = data;
 413     }
 414 
 415     /**
 416      * Creates a {@code TIFFField} from a TIFF native image
 417      * metadata node. If the value of the {@code "number"} attribute
 418      * of the node is not found in {@code tagSet} then a new
 419      * {@code TIFFTag} with name {@code TIFFTag.UNKNOWN_TAG_NAME}
 420      * will be created and assigned to the field.
 421      *
 422      * @param tagSet The {@code TIFFTagSet} to which the
 423      * {@code TIFFTag} of the field belongs.
 424      * @param node A native TIFF image metadata {@code TIFFField} node.
 425      * @throws IllegalArgumentException If the {@code Node} parameter content
 426      * does not adhere to the {@code TIFFField} element structure defined by
 427      * the <a href="../../metadata/doc-files/tiff_metadata.html#ImageMetadata">
 428      * TIFF native image metadata format specification</a>, or if the
 429      * combination of node attributes and data is not legal per the
 430      * {@link #TIFFField(TIFFTag,int,int,Object)} constructor specification.
 431      * Note that a cause might be set on such an exception.
 432      * @return A new {@code TIFFField}.
 433      */
 434     public static TIFFField createFromMetadataNode(TIFFTagSet tagSet,
 435                                                    Node node) {
 436         if (node == null) {
 437             // This method is specified to throw only IllegalArgumentExceptions
 438             // so we create an IAE with a NullPointerException as its cause.
 439             throw new IllegalArgumentException(new NullPointerException
 440                 ("node == null!"));
 441         }
 442         String name = node.getNodeName();
 443         if (!name.equals("TIFFField")) {
 444             throw new IllegalArgumentException("!name.equals(\"TIFFField\")");
 445         }
 446 
 447         int tagNumber = Integer.parseInt(getAttribute(node, "number"));
 448         TIFFTag tag = null;
 449         if (tagSet != null) {
 450             tag = tagSet.getTag(tagNumber);
 451         }
 452 
 453         int type = TIFFTag.TIFF_UNDEFINED;
 454         int count = 0;
 455         Object data = null;
 456 
 457         Node child = node.getFirstChild();
 458         if (child != null) {
 459             String typeName = child.getNodeName();
 460             if (typeName.equals("TIFFUndefined")) {
 461                 String values = getAttribute(child, "value");
 462                 StringTokenizer st = new StringTokenizer(values, ",");
 463                 count = st.countTokens();
 464 
 465                 byte[] bdata = new byte[count];
 466                 for (int i = 0; i < count; i++) {
 467                     bdata[i] = (byte)Integer.parseInt(st.nextToken());
 468                 }
 469 
 470                 type = TIFFTag.TIFF_UNDEFINED;
 471                 data = bdata;
 472             } else {
 473                 int[] otype = new int[1];
 474                 int[] ocount = new int[1];
 475                 Object[] odata = new Object[1];
 476 
 477                 initData(node.getFirstChild(), otype, ocount, odata);
 478                 type = otype[0];
 479                 count = ocount[0];
 480                 data = odata[0];
 481             }
 482         } else if (tag != null) {
 483             int t = TIFFTag.MAX_DATATYPE;
 484             while(t >= TIFFTag.MIN_DATATYPE && !tag.isDataTypeOK(t)) {
 485                 t--;
 486             }
 487             type = t;
 488         }
 489 
 490         if (tag == null) {
 491             tag = new TIFFTag(TIFFTag.UNKNOWN_TAG_NAME, tagNumber, 1 << type);
 492         }
 493 
 494         TIFFField field;
 495         try {
 496             field = new TIFFField(tag, type, count, data);
 497         } catch (NullPointerException npe) {
 498             // This method is specified to throw only IllegalArgumentExceptions
 499             // so we catch the NullPointerException and set it as the cause of
 500             // the IAE which is thrown.
 501             throw new IllegalArgumentException(npe);
 502         }
 503 
 504         return field;
 505     }
 506 
 507     /**
 508      * Constructs a {@code TIFFField} with arbitrary data. The
 509      * {@code type} parameter must be a value for which
 510      * {@link TIFFTag#isDataTypeOK tag.isDataTypeOK()}
 511      * returns {@code true}. The {@code data} parameter must
 512      * be an array of a Java type appropriate for the type of the TIFF
 513      * field.
 514      *
 515      * <p>Note that the value (data) of the {@code TIFFField}
 516      * will always be the actual field value regardless of the number of
 517      * bytes required for that value. This is the case despite the fact
 518      * that the TIFF <i>IFD Entry</i> corresponding to the field may
 519      * actually contain the offset to the value of the field rather than
 520      * the value itself (the latter occurring if and only if the
 521      * value fits into 4 bytes). In other words, the value of the
 522      * field will already have been read from the TIFF stream. (An exception
 523      * to this case may occur when the field represents the contents of a
 524      * non-baseline IFD. In that case the data will be a {@code long[]}
 525      * containing the offset to the IFD and the {@code TIFFDirectory}
 526      * returned by {@link #getDirectory()} will be its contents.)
 527      *
 528      * @param tag The tag to associated with this field.
 529      * @param type One of the {@code TIFFTag.TIFF_*} constants
 530      * indicating the data type of the field as written to the TIFF stream.
 531      * @param count The number of data values.
 532      * @param data The actual data content of the field.
 533      *
 534      * @throws NullPointerException if {@code tag == null}.
 535      * @throws IllegalArgumentException if {@code type} is not
 536      * one of the {@code TIFFTag.TIFF_*} data type constants.
 537      * @throws IllegalArgumentException if {@code type} is an unacceptable
 538      * data type for the supplied {@code TIFFTag}.
 539      * @throws IllegalArgumentException if {@code count < 0}.
 540      * @throws IllegalArgumentException if {@code count < 1}
 541      * and {@code type} is {@code TIFF_RATIONAL} or
 542      * {@code TIFF_SRATIONAL}.
 543      * @throws IllegalArgumentException if {@code count != 1}
 544      * and {@code type} is {@code TIFF_IFD_POINTER}.
 545      * @throws NullPointerException if {@code data == null}.
 546      * @throws IllegalArgumentException if {@code data} is an instance of
 547      * a class incompatible with the specified type.
 548      * @throws IllegalArgumentException if the size of the data array is wrong.
 549      * @throws IllegalArgumentException if the type of the data array is
 550      * {@code TIFF_LONG}, {@code TIFF_RATIONAL}, or {@code TIFF_IFD_POINTER}
 551      * and any of the elements is negative or greater than {@code 0xffffffff}.
 552      */
 553     public TIFFField(TIFFTag tag, int type, int count, Object data) {
 554         if(tag == null) {
 555             throw new NullPointerException("tag == null!");
 556         } else if(type < TIFFTag.MIN_DATATYPE || type > TIFFTag.MAX_DATATYPE) {
 557             throw new IllegalArgumentException("Unknown data type "+type);
 558         } else if(!tag.isDataTypeOK(type)) {
 559             throw new IllegalArgumentException("Illegal data type " + type
 560                 + " for " + tag.getName() + " tag");
 561         } else if(count < 0) {
 562             throw new IllegalArgumentException("count < 0!");
 563         } else if((type == TIFFTag.TIFF_RATIONAL
 564                    || type == TIFFTag.TIFF_SRATIONAL)
 565                   && count < 1) {
 566             throw new IllegalArgumentException
 567                 ("Type is TIFF_RATIONAL or TIFF_SRATIONAL and count < 1");
 568         } else if (type == TIFFTag.TIFF_IFD_POINTER && count != 1) {
 569             throw new IllegalArgumentException
 570                 ("Type is TIFF_IFD_POINTER count != 1");
 571         } else if(data == null) {
 572             throw new NullPointerException("data == null!");
 573         }
 574 
 575         boolean isDataArrayCorrect = false;
 576 
 577         switch (type) {
 578         case TIFFTag.TIFF_BYTE:
 579         case TIFFTag.TIFF_SBYTE:
 580         case TIFFTag.TIFF_UNDEFINED:
 581             isDataArrayCorrect = data instanceof byte[]
 582                 && ((byte[])data).length == count;
 583             break;
 584         case TIFFTag.TIFF_ASCII:
 585             isDataArrayCorrect = data instanceof String[]
 586                 && ((String[])data).length == count;
 587             break;
 588         case TIFFTag.TIFF_SHORT:
 589             isDataArrayCorrect = data instanceof char[]
 590                 && ((char[])data).length == count;
 591             break;
 592         case TIFFTag.TIFF_LONG:
 593             isDataArrayCorrect = data instanceof long[]
 594                 && ((long[])data).length == count;
 595             if (isDataArrayCorrect) {
 596                 for (long datum : (long[])data) {
 597                     if (datum < 0) {
 598                         throw new IllegalArgumentException
 599                             ("Negative value supplied for TIFF_LONG");
 600                     }
 601                     if (datum > MAX_UINT32) {
 602                         throw new IllegalArgumentException
 603                             ("Too large value supplied for TIFF_LONG");
 604                     }
 605                 }
 606             }
 607             break;
 608         case TIFFTag.TIFF_IFD_POINTER:
 609             isDataArrayCorrect = data instanceof long[]
 610                 && ((long[])data).length == 1;
 611             if (((long[])data)[0] < 0) {
 612                 throw new IllegalArgumentException
 613                     ("Negative value supplied for TIFF_IFD_POINTER");
 614             }
 615             if (((long[])data)[0] > MAX_UINT32) {
 616                 throw new IllegalArgumentException
 617                     ("Too large value supplied for TIFF_IFD_POINTER");
 618             }
 619             break;
 620         case TIFFTag.TIFF_RATIONAL:
 621             isDataArrayCorrect = data instanceof long[][]
 622                 && ((long[][])data).length == count;
 623             if (isDataArrayCorrect) {
 624                 for (long[] datum : (long[][])data) {
 625                     if (datum.length != 2) {
 626                         isDataArrayCorrect = false;
 627                         break;
 628                     }
 629                     if (datum[0] < 0 || datum[1] < 0) {
 630                         throw new IllegalArgumentException
 631                             ("Negative value supplied for TIFF_RATIONAL");
 632                     }
 633                     if (datum[0] > MAX_UINT32 || datum[1] > MAX_UINT32) {
 634                         throw new IllegalArgumentException
 635                             ("Too large value supplied for TIFF_RATIONAL");
 636                     }
 637                 }
 638             }
 639             break;
 640         case TIFFTag.TIFF_SSHORT:
 641             isDataArrayCorrect = data instanceof short[]
 642                 && ((short[])data).length == count;
 643             break;
 644         case TIFFTag.TIFF_SLONG:
 645             isDataArrayCorrect = data instanceof int[]
 646                 && ((int[])data).length == count;
 647             break;
 648         case TIFFTag.TIFF_SRATIONAL:
 649             isDataArrayCorrect = data instanceof int[][]
 650                 && ((int[][])data).length == count;
 651             if (isDataArrayCorrect) {
 652                 for (int[] datum : (int[][])data) {
 653                     if (datum.length != 2) {
 654                         isDataArrayCorrect = false;
 655                         break;
 656                     }
 657                 }
 658             }
 659             break;
 660         case TIFFTag.TIFF_FLOAT:
 661             isDataArrayCorrect = data instanceof float[]
 662                 && ((float[])data).length == count;
 663             break;
 664         case TIFFTag.TIFF_DOUBLE:
 665             isDataArrayCorrect = data instanceof double[]
 666                 && ((double[])data).length == count;
 667             break;
 668         default:
 669             throw new IllegalArgumentException("Unknown data type "+type);
 670         }
 671 
 672         if (!isDataArrayCorrect) {
 673             throw new IllegalArgumentException
 674                 ("Illegal class or length for data array");
 675         }
 676 
 677         this.tag = tag;
 678         this.tagNumber = tag.getNumber();
 679         this.type = type;
 680         this.count = count;
 681         this.data = data;
 682     }
 683 
 684     /**
 685      * Constructs a data array using {@link #createArrayForType
 686      * createArrayForType()} and invokes
 687      * {@link #TIFFField(TIFFTag,int,int,Object)} with the supplied
 688      * parameters and the created array.
 689      *
 690      * @param tag The tag to associated with this field.
 691      * @param type One of the {@code TIFFTag.TIFF_*} constants
 692      * indicating the data type of the field as written to the TIFF stream.
 693      * @param count The number of data values.
 694      * @throws NullPointerException if {@code tag == null}.
 695      * @throws IllegalArgumentException if {@code type} is not
 696      * one of the {@code TIFFTag.TIFF_*} data type constants.
 697      * @throws IllegalArgumentException if {@code type} is an unacceptable
 698      * data type for the supplied {@code TIFFTag}.
 699      * @throws IllegalArgumentException if {@code count < 0}.
 700      * @see #TIFFField(TIFFTag,int,int,Object)
 701      * @throws IllegalArgumentException if {@code count < 1}
 702      * and {@code type} is {@code TIFF_RATIONAL} or
 703      * {@code TIFF_SRATIONAL}.
 704      * @throws IllegalArgumentException if {@code count != 1}
 705      * and {@code type} is {@code TIFF_IFD_POINTER}.
 706      */
 707     public TIFFField(TIFFTag tag, int type, int count) {
 708         this(tag, type, count, createArrayForType(type, count));
 709     }
 710 
 711     /**
 712      * Constructs a {@code TIFFField} with a single non-negative integral
 713      * value. The field will have type {@link TIFFTag#TIFF_SHORT TIFF_SHORT}
 714      * if {@code value} is in {@code [0,0xffff]}, and type
 715      * {@link TIFFTag#TIFF_LONG TIFF_LONG} if {@code value} is in
 716      * {@code [0x10000,0xffffffff]}. The count of the field will be unity.
 717      *
 718      * @param tag The tag to associate with this field.
 719      * @param value The value to associate with this field.
 720      * @throws NullPointerException if {@code tag == null}.
 721      * @throws IllegalArgumentException if {@code value} is not in
 722      * {@code [0,0xffffffff]}.
 723      * @throws IllegalArgumentException if {@code value} is in
 724      * {@code [0,0xffff]} and {@code TIFF_SHORT} is an unacceptable type
 725      * for the {@code TIFFTag}, or if {@code value} is in
 726      * {@code [0x10000,0xffffffff]} and {@code TIFF_LONG} is an unacceptable
 727      * type for the {@code TIFFTag}.
 728      */
 729     public TIFFField(TIFFTag tag, long value) {
 730         if(tag == null) {
 731             throw new NullPointerException("tag == null!");
 732         }
 733         if (value < 0) {
 734             throw new IllegalArgumentException("value < 0!");
 735         }
 736         if (value > MAX_UINT32) {
 737             throw new IllegalArgumentException("value > 0xffffffff!");
 738         }
 739 
 740         this.tag = tag;
 741         this.tagNumber = tag.getNumber();
 742         this.count = 1;
 743 
 744         if (value < 65536) {
 745             if (!tag.isDataTypeOK(TIFFTag.TIFF_SHORT)) {
 746                 throw new IllegalArgumentException("Illegal data type "
 747                     + getTypeName(TIFFTag.TIFF_SHORT) + " for tag "
 748                     + "\"" + tag.getName() + "\"");
 749             }
 750             this.type = TIFFTag.TIFF_SHORT;
 751             char[] cdata = new char[1];
 752             cdata[0] = (char)value;
 753             this.data = cdata;
 754         } else {
 755             if (!tag.isDataTypeOK(TIFFTag.TIFF_LONG)) {
 756                 throw new IllegalArgumentException("Illegal data type "
 757                     + getTypeName(TIFFTag.TIFF_LONG) + " for tag "
 758                     + "\"" + tag.getName() + "\"");
 759             }
 760             this.type = TIFFTag.TIFF_LONG;
 761             long[] ldata = new long[1];
 762             ldata[0] = value;
 763             this.data = ldata;
 764         }
 765     }
 766 
 767     /**
 768      * Constructs a {@code TIFFField} with an IFD offset and contents.
 769      * The offset will be stored as the data of this field as
 770      * {@code long[] {offset}}. The directory will not be cloned. The count
 771      * of the field will be unity.
 772      *
 773      * @param tag The tag to associated with this field.
 774      * @param type One of the constants {@code TIFFTag.TIFF_LONG} or
 775      * {@code TIFFTag.TIFF_IFD_POINTER}.
 776      * @param offset The IFD offset.
 777      * @param dir The directory.
 778      *
 779      * @throws NullPointerException if {@code tag == null}.
 780      * @throws IllegalArgumentException if {@code type} is an unacceptable
 781      * data type for the supplied {@code TIFFTag}.
 782      * @throws IllegalArgumentException if {@code type} is neither
 783      * {@code TIFFTag.TIFF_LONG} nor {@code TIFFTag.TIFF_IFD_POINTER}.
 784      * @throws IllegalArgumentException if {@code offset <= 0}.
 785      * @throws NullPointerException if {@code dir == null}.
 786      *
 787      * @see #TIFFField(TIFFTag,int,int,Object)
 788      */
 789     public TIFFField(TIFFTag tag, int type, long offset, TIFFDirectory dir) {
 790         if (tag == null) {
 791             throw new NullPointerException("tag == null!");
 792         } else if (type < TIFFTag.MIN_DATATYPE || type > TIFFTag.MAX_DATATYPE) {
 793             throw new IllegalArgumentException("Unknown data type "+type);
 794         } else if (!tag.isDataTypeOK(type)) {
 795             throw new IllegalArgumentException("Illegal data type " + type
 796                 + " for " + tag.getName() + " tag");
 797         } else if (type != TIFFTag.TIFF_LONG
 798                    && type != TIFFTag.TIFF_IFD_POINTER) {
 799             throw new IllegalArgumentException("type " + type
 800                 + " is neither TIFFTag.TIFF_LONG nor TIFFTag.TIFF_IFD_POINTER");
 801         } else if (offset <= 0) {
 802             throw new IllegalArgumentException("offset " + offset
 803                 + " is non-positive");
 804         } else if (dir == null) {
 805             throw new NullPointerException("dir == null");
 806         }
 807 
 808         this.tag = tag;
 809         this.tagNumber = tag.getNumber();
 810         this.type = type;
 811         this.count = 1;
 812         this.data = new long[] {offset};
 813 
 814         this.dir = dir;
 815     }
 816 
 817     /**
 818      * Retrieves the tag associated with this field.
 819      *
 820      * @return The associated {@code TIFFTag}.
 821      */
 822     public TIFFTag getTag() {
 823         return tag;
 824     }
 825 
 826     /**
 827      * Retrieves the tag number in the range {@code [0,65535]}.
 828      *
 829      * @return The tag number.
 830      */
 831     public int getTagNumber() {
 832         return tagNumber;
 833     }
 834 
 835     /**
 836      * Returns the type of the data stored in the field.  For a TIFF 6.0
 837      * stream, the value will equal one of the {@code TIFFTag.TIFF_*}
 838      * constants. For future revisions of TIFF, higher values are possible.
 839      *
 840      * @return The data type of the field value.
 841      */
 842     public int getType() {
 843         return type;
 844     }
 845 
 846     /**
 847      * Returns the name of the supplied data type constant.
 848      *
 849      * @param dataType One of the {@code TIFFTag.TIFF_*} constants
 850      * indicating the data type of the field as written to the TIFF stream.
 851      * @return The type name corresponding to the supplied type constant.
 852      * @throws IllegalArgumentException if {@code dataType} is not
 853      * one of the {@code TIFFTag.TIFF_*} data type constants.
 854      */
 855     public static String getTypeName(int dataType) {
 856         if (dataType < TIFFTag.MIN_DATATYPE ||
 857             dataType > TIFFTag.MAX_DATATYPE) {
 858             throw new IllegalArgumentException("Unknown data type "+dataType);
 859         }
 860 
 861         return TYPE_NAMES[dataType];
 862     }
 863 
 864     /**
 865      * Returns the data type constant corresponding to the supplied data
 866      * type name. If the name is unknown {@code -1} will be returned.
 867      *
 868      * @param typeName The type name.
 869      * @return One of the {@code TIFFTag.TIFF_*} constants or
 870      * {@code -1} if the name is not recognized.
 871      */
 872     public static int getTypeByName(String typeName) {
 873         for (int i = TIFFTag.MIN_DATATYPE; i <= TIFFTag.MAX_DATATYPE; i++) {
 874             if (typeName.equals(TYPE_NAMES[i])) {
 875                 return i;
 876             }
 877         }
 878 
 879         return -1;
 880     }
 881 
 882     /**
 883      * Creates an array appropriate for the indicated data type.
 884      *
 885      * @param dataType One of the {@code TIFFTag.TIFF_*} data type
 886      * constants.
 887      * @param count The number of values in the array.
 888      * @return An array appropriate for the specified data type.
 889      *
 890      * @throws IllegalArgumentException if {@code dataType} is not
 891      * one of the {@code TIFFTag.TIFF_*} data type constants.
 892      * @throws IllegalArgumentException if {@code count < 0}.
 893      * @throws IllegalArgumentException if {@code count < 1}
 894      * and {@code type} is {@code TIFF_RATIONAL} or
 895      * {@code TIFF_SRATIONAL}.
 896      * @throws IllegalArgumentException if {@code count != 1}
 897      * and {@code type} is {@code TIFF_IFD_POINTER}.
 898      */
 899     public static Object createArrayForType(int dataType, int count) {
 900 
 901         if(count < 0) {
 902             throw new IllegalArgumentException("count < 0!");
 903         } else if((dataType == TIFFTag.TIFF_RATIONAL
 904                    || dataType == TIFFTag.TIFF_SRATIONAL)
 905                   && count < 1) {
 906             throw new IllegalArgumentException
 907                 ("Type is TIFF_RATIONAL or TIFF_SRATIONAL and count < 1");
 908         } else if (dataType == TIFFTag.TIFF_IFD_POINTER && count != 1) {
 909             throw new IllegalArgumentException
 910                 ("Type is TIFF_IFD_POINTER count != 1");
 911         }
 912 
 913         switch (dataType) {
 914         case TIFFTag.TIFF_BYTE:
 915         case TIFFTag.TIFF_SBYTE:
 916         case TIFFTag.TIFF_UNDEFINED:
 917             return new byte[count];
 918         case TIFFTag.TIFF_ASCII:
 919             return new String[count];
 920         case TIFFTag.TIFF_SHORT:
 921             return new char[count];
 922         case TIFFTag.TIFF_LONG:
 923         case TIFFTag.TIFF_IFD_POINTER:
 924             return new long[count];
 925         case TIFFTag.TIFF_RATIONAL:
 926             return new long[count][2];
 927         case TIFFTag.TIFF_SSHORT:
 928             return new short[count];
 929         case TIFFTag.TIFF_SLONG:
 930             return new int[count];
 931         case TIFFTag.TIFF_SRATIONAL:
 932             return new int[count][2];
 933         case TIFFTag.TIFF_FLOAT:
 934             return new float[count];
 935         case TIFFTag.TIFF_DOUBLE:
 936             return new double[count];
 937         default:
 938             throw new IllegalArgumentException("Unknown data type "+dataType);
 939         }
 940     }
 941 
 942     /**
 943      * Returns the {@code TIFFField} as a node named either
 944      * <tt>"TIFFField"</tt> or <tt>"TIFFIFD"</tt> as described in the
 945      * TIFF native image metadata specification. The node will be named
 946      * <tt>"TIFFIFD"</tt> if and only if {@link #hasDirectory()} returns
 947      * {@code true} and the field's type is either {@link TIFFTag#TIFF_LONG}
 948      * or {@link TIFFTag#TIFF_IFD_POINTER}.
 949      *
 950      * @return a {@code Node} named <tt>"TIFFField"</tt> or
 951      * <tt>"TIFFIFD"</tt>.
 952      */
 953     public Node getAsNativeNode() {
 954         return new TIFFFieldNode(this);
 955     }
 956 
 957     /**
 958      * Indicates whether the value associated with the field is of
 959      * integral data type.
 960      *
 961      * @return Whether the field type is integral.
 962      */
 963     public boolean isIntegral() {
 964         return IS_INTEGRAL[type];
 965     }
 966 
 967     /**
 968      * Returns the number of data items present in the field.  For
 969      * {@code TIFFTag.TIFF_ASCII} fields, the value returned is the
 970      * number of {@code String}s, not the total length of the
 971      * data as in the file representation.
 972      *
 973      * @return The number of data items present in the field.
 974      */
 975     public int getCount() {
 976         return count;
 977     }
 978 
 979     /**
 980      * Returns a reference to the data object associated with the field.
 981      *
 982      * @return The data object of the field.
 983      */
 984     public Object getData() {
 985         return data;
 986     }
 987 
 988     /**
 989      * Returns the data as an uninterpreted array of
 990      * {@code byte}s.  The type of the field must be one of
 991      * {@code TIFFTag.TIFF_BYTE}, {@code TIFF_SBYTE}, or
 992      * {@code TIFF_UNDEFINED}.
 993      *
 994      * <p> For data in {@code TIFFTag.TIFF_BYTE} format, the application
 995      * must take care when promoting the data to longer integral types
 996      * to avoid sign extension.
 997      *
 998      * @throws ClassCastException if the field is not of type
 999      * {@code TIFF_BYTE}, {@code TIFF_SBYTE}, or
1000      * {@code TIFF_UNDEFINED}.
1001      * @return The data as an uninterpreted array of bytes.
1002      */
1003     public byte[] getAsBytes() {
1004         return (byte[])data;
1005     }
1006 
1007     /**
1008      * Returns {@code TIFFTag.TIFF_SHORT} data as an array of
1009      * {@code char}s (unsigned 16-bit integers).
1010      *
1011      * @throws ClassCastException if the field is not of type
1012      * {@code TIFF_SHORT}.
1013      * @return The data as an array of {@code char}s.
1014      */
1015     public char[] getAsChars() {
1016         return (char[])data;
1017     }
1018 
1019     /**
1020      * Returns {@code TIFFTag.TIFF_SSHORT} data as an array of
1021      * {@code short}s (signed 16-bit integers).
1022      *
1023      * @throws ClassCastException if the field is not of type
1024      * {@code TIFF_SSHORT}.
1025      * @return The data as an array of {@code short}s.
1026      */
1027     public short[] getAsShorts() {
1028         return (short[])data;
1029     }
1030 
1031     /**
1032      * Returns {@code TIFFTag.TIFF_SLONG} data as an array of
1033      * {@code int}s (signed 32-bit integers).
1034      *
1035      * @throws ClassCastException if the field is not of type
1036      * {@code TIFF_SHORT}, {@code TIFF_SSHORT}, or
1037      * {@code TIFF_SLONG}.
1038      * @return The data as an array of {@code int}s.
1039      */
1040     public int[] getAsInts() {
1041         if (data instanceof int[]) {
1042             return (int[])data;
1043         } else if (data instanceof char[]){
1044             char[] cdata = (char[])data;
1045             int[] idata = new int[cdata.length];
1046             for (int i = 0; i < cdata.length; i++) {
1047                 idata[i] = cdata[i] & 0xffff;
1048             }
1049             return idata;
1050         } else if (data instanceof short[]){
1051             short[] sdata = (short[])data;
1052             int[] idata = new int[sdata.length];
1053             for (int i = 0; i < sdata.length; i++) {
1054                 idata[i] = (int)sdata[i];
1055             }
1056             return idata;
1057         } else {
1058             throw new ClassCastException("Data not char[], short[], or int[]!");
1059         }
1060     }
1061 
1062     /**
1063      * Returns {@code TIFFTag.TIFF_LONG} or
1064      * {@code TIFF_IFD_POINTER} data as an array of
1065      * {@code long}s (signed 64-bit integers).
1066      *
1067      * @throws ClassCastException if the field is not of type
1068      * {@code TIFF_LONG} or {@code TIFF_IFD_POINTER}.
1069      * @return The data as an array of {@code long}s.
1070      */
1071     public long[] getAsLongs() {
1072         return (long[])data;
1073     }
1074 
1075     /**
1076      * Returns {@code TIFFTag.TIFF_FLOAT} data as an array of
1077      * {@code float}s (32-bit floating-point values).
1078      *
1079      * @throws ClassCastException if the field is not of type
1080      * {@code TIFF_FLOAT}.
1081      * @return The data as an array of {@code float}s.
1082      */
1083     public float[] getAsFloats() {
1084         return (float[])data;
1085     }
1086 
1087     /**
1088      * Returns {@code TIFFTag.TIFF_DOUBLE} data as an array of
1089      * {@code double}s (64-bit floating-point values).
1090      *
1091      * @throws ClassCastException if the field is not of type
1092      * {@code TIFF_DOUBLE}.
1093      * @return The data as an array of {@code double}s.
1094      */
1095     public double[] getAsDoubles() {
1096         return (double[])data;
1097     }
1098 
1099     /**
1100      * Returns {@code TIFFTag.TIFF_SRATIONAL} data as an array of
1101      * 2-element arrays of {@code int}s.
1102      *
1103      * @throws ClassCastException if the field is not of type
1104      * {@code TIFF_SRATIONAL}.
1105      * @return The data as an array of signed rationals.
1106      */
1107     public int[][] getAsSRationals() {
1108         return (int[][])data;
1109     }
1110 
1111     /**
1112      * Returns {@code TIFFTag.TIFF_RATIONAL} data as an array of
1113      * 2-element arrays of {@code long}s.
1114      *
1115      * @throws ClassCastException if the field is not of type
1116      * {@code TIFF_RATIONAL}.
1117      * @return The data as an array of unsigned rationals.
1118      */
1119     public long[][] getAsRationals() {
1120         return (long[][])data;
1121     }
1122 
1123     /**
1124      * Returns data in any format as an {@code int}.
1125      *
1126      * <p> {@code TIFFTag.TIFF_BYTE} values are treated as unsigned; that
1127      * is, no sign extension will take place and the returned value
1128      * will be in the range [0, 255].  {@code TIFF_SBYTE} data
1129      * will be returned in the range [-128, 127].
1130      *
1131      * <p> A {@code TIFF_UNDEFINED} value is treated as though
1132      * it were a {@code TIFF_BYTE}.
1133      *
1134      * <p> Data in {@code TIFF_SLONG}, {@code TIFF_LONG},
1135      * {@code TIFF_FLOAT}, {@code TIFF_DOUBLE} or
1136      * {@code TIFF_IFD_POINTER} format are simply cast to
1137      * {@code int} and may suffer from truncation.
1138      *
1139      * <p> Data in {@code TIFF_SRATIONAL} or
1140      * {@code TIFF_RATIONAL} format are evaluated by dividing the
1141      * numerator into the denominator using double-precision
1142      * arithmetic and then casting to {@code int}.  Loss of
1143      * precision and truncation may occur.
1144      *
1145      * <p> Data in {@code TIFF_ASCII} format will be parsed as by
1146      * the {@code Double.parseDouble} method, with the result
1147      * case to {@code int}.
1148      *
1149      * @param index The index of the data.
1150      * @return The data at the given index as an {@code int}.
1151      */
1152     public int getAsInt(int index) {
1153         switch (type) {
1154         case TIFFTag.TIFF_BYTE:
1155         case TIFFTag.TIFF_UNDEFINED:
1156             return ((byte[])data)[index] & 0xff;
1157         case TIFFTag.TIFF_SBYTE:
1158             return ((byte[])data)[index];
1159         case TIFFTag.TIFF_SHORT:
1160             return ((char[])data)[index] & 0xffff;
1161         case TIFFTag.TIFF_SSHORT:
1162             return ((short[])data)[index];
1163         case TIFFTag.TIFF_SLONG:
1164             return ((int[])data)[index];
1165         case TIFFTag.TIFF_LONG:
1166         case TIFFTag.TIFF_IFD_POINTER:
1167             return (int)((long[])data)[index];
1168         case TIFFTag.TIFF_FLOAT:
1169             return (int)((float[])data)[index];
1170         case TIFFTag.TIFF_DOUBLE:
1171             return (int)((double[])data)[index];
1172         case TIFFTag.TIFF_SRATIONAL:
1173             int[] ivalue = getAsSRational(index);
1174             return (int)((double)ivalue[0]/ivalue[1]);
1175         case TIFFTag.TIFF_RATIONAL:
1176             long[] lvalue = getAsRational(index);
1177             return (int)((double)lvalue[0]/lvalue[1]);
1178         case TIFFTag.TIFF_ASCII:
1179              String s = ((String[])data)[index];
1180              return (int)Double.parseDouble(s);
1181         default:
1182             throw new ClassCastException(); // should never happen
1183         }
1184     }
1185 
1186     /**
1187      * Returns data in any format as a {@code long}.
1188      *
1189      * <p> {@code TIFFTag.TIFF_BYTE} and {@code TIFF_UNDEFINED} data
1190      * are treated as unsigned; that is, no sign extension will take
1191      * place and the returned value will be in the range [0, 255].
1192      * {@code TIFF_SBYTE} data will be returned in the range
1193      * [-128, 127].
1194      *
1195      * <p> Data in {@code TIFF_FLOAT} and {@code TIFF_DOUBLE} are
1196      * simply cast to {@code long} and may suffer from truncation.
1197      *
1198      * <p> Data in {@code TIFF_SRATIONAL} or
1199      * {@code TIFF_RATIONAL} format are evaluated by dividing the
1200      * numerator into the denominator using double-precision
1201      * arithmetic and then casting to {@code long}.  Loss of
1202      * precision and truncation may occur.
1203      *
1204      * <p> Data in {@code TIFF_ASCII} format will be parsed as by
1205      * the {@code Double.parseDouble} method, with the result
1206      * cast to {@code long}.
1207      *
1208      * @param index The index of the data.
1209      * @return The data at the given index as a {@code long}.
1210      */
1211     public long getAsLong(int index) {
1212         switch (type) {
1213         case TIFFTag.TIFF_BYTE:
1214         case TIFFTag.TIFF_UNDEFINED:
1215             return ((byte[])data)[index] & 0xff;
1216         case TIFFTag.TIFF_SBYTE:
1217             return ((byte[])data)[index];
1218         case TIFFTag.TIFF_SHORT:
1219             return ((char[])data)[index] & 0xffff;
1220         case TIFFTag.TIFF_SSHORT:
1221             return ((short[])data)[index];
1222         case TIFFTag.TIFF_SLONG:
1223             return ((int[])data)[index];
1224         case TIFFTag.TIFF_LONG:
1225         case TIFFTag.TIFF_IFD_POINTER:
1226             return ((long[])data)[index];
1227         case TIFFTag.TIFF_FLOAT:
1228             return (long)((float[])data)[index];
1229         case TIFFTag.TIFF_DOUBLE:
1230             return (long)((double[])data)[index];
1231         case TIFFTag.TIFF_SRATIONAL:
1232             int[] ivalue = getAsSRational(index);
1233             return (long)((double)ivalue[0]/ivalue[1]);
1234         case TIFFTag.TIFF_RATIONAL:
1235             long[] lvalue = getAsRational(index);
1236             return (long)((double)lvalue[0]/lvalue[1]);
1237         case TIFFTag.TIFF_ASCII:
1238              String s = ((String[])data)[index];
1239              return (long)Double.parseDouble(s);
1240         default:
1241             throw new ClassCastException(); // should never happen
1242         }
1243     }
1244 
1245     /**
1246      * Returns data in any format as a {@code float}.
1247      *
1248      * <p> {@code TIFFTag.TIFF_BYTE} and {@code TIFF_UNDEFINED} data
1249      * are treated as unsigned; that is, no sign extension will take
1250      * place and the returned value will be in the range [0, 255].
1251      * {@code TIFF_SBYTE} data will be returned in the range
1252      * [-128, 127].
1253      *
1254      * <p> Data in {@code TIFF_SLONG}, {@code TIFF_LONG},
1255      * {@code TIFF_DOUBLE}, or {@code TIFF_IFD_POINTER} format are
1256      * simply cast to {@code float} and may suffer from
1257      * truncation.
1258      *
1259      * <p> Data in {@code TIFF_SRATIONAL} or
1260      * {@code TIFF_RATIONAL} format are evaluated by dividing the
1261      * numerator into the denominator using double-precision
1262      * arithmetic and then casting to {@code float}.
1263      *
1264      * <p> Data in {@code TIFF_ASCII} format will be parsed as by
1265      * the {@code Double.parseDouble} method, with the result
1266      * cast to {@code float}.
1267      *
1268      * @param index The index of the data.
1269      * @return The data at the given index as a {@code float}.
1270      */
1271     public float getAsFloat(int index) {
1272         switch (type) {
1273         case TIFFTag.TIFF_BYTE:
1274         case TIFFTag.TIFF_UNDEFINED:
1275             return ((byte[])data)[index] & 0xff;
1276         case TIFFTag.TIFF_SBYTE:
1277             return ((byte[])data)[index];
1278         case TIFFTag.TIFF_SHORT:
1279             return ((char[])data)[index] & 0xffff;
1280         case TIFFTag.TIFF_SSHORT:
1281             return ((short[])data)[index];
1282         case TIFFTag.TIFF_SLONG:
1283             return ((int[])data)[index];
1284         case TIFFTag.TIFF_LONG:
1285         case TIFFTag.TIFF_IFD_POINTER:
1286             return ((long[])data)[index];
1287         case TIFFTag.TIFF_FLOAT:
1288             return ((float[])data)[index];
1289         case TIFFTag.TIFF_DOUBLE:
1290             return (float)((double[])data)[index];
1291         case TIFFTag.TIFF_SRATIONAL:
1292             int[] ivalue = getAsSRational(index);
1293             return (float)((double)ivalue[0]/ivalue[1]);
1294         case TIFFTag.TIFF_RATIONAL:
1295             long[] lvalue = getAsRational(index);
1296             return (float)((double)lvalue[0]/lvalue[1]);
1297         case TIFFTag.TIFF_ASCII:
1298              String s = ((String[])data)[index];
1299              return (float)Double.parseDouble(s);
1300         default:
1301             throw new ClassCastException(); // should never happen
1302         }
1303     }
1304 
1305     /**
1306      * Returns data in any format as a {@code double}.
1307      *
1308      * <p> {@code TIFFTag.TIFF_BYTE} and {@code TIFF_UNDEFINED} data
1309      * are treated as unsigned; that is, no sign extension will take
1310      * place and the returned value will be in the range [0, 255].
1311      * {@code TIFF_SBYTE} data will be returned in the range
1312      * [-128, 127].
1313      *
1314      * <p> Data in {@code TIFF_SRATIONAL} or
1315      * {@code TIFF_RATIONAL} format are evaluated by dividing the
1316      * numerator into the denominator using double-precision
1317      * arithmetic.
1318      *
1319      * <p> Data in {@code TIFF_ASCII} format will be parsed as by
1320      * the {@code Double.parseDouble} method.
1321      *
1322      * @param index The index of the data.
1323      * @return The data at the given index as a {@code double}.
1324      */
1325     public double getAsDouble(int index) {
1326         switch (type) {
1327         case TIFFTag.TIFF_BYTE:
1328         case TIFFTag.TIFF_UNDEFINED:
1329             return ((byte[])data)[index] & 0xff;
1330         case TIFFTag.TIFF_SBYTE:
1331             return ((byte[])data)[index];
1332         case TIFFTag.TIFF_SHORT:
1333             return ((char[])data)[index] & 0xffff;
1334         case TIFFTag.TIFF_SSHORT:
1335             return ((short[])data)[index];
1336         case TIFFTag.TIFF_SLONG:
1337             return ((int[])data)[index];
1338         case TIFFTag.TIFF_LONG:
1339         case TIFFTag.TIFF_IFD_POINTER:
1340             return ((long[])data)[index];
1341         case TIFFTag.TIFF_FLOAT:
1342             return ((float[])data)[index];
1343         case TIFFTag.TIFF_DOUBLE:
1344             return ((double[])data)[index];
1345         case TIFFTag.TIFF_SRATIONAL:
1346             int[] ivalue = getAsSRational(index);
1347             return (double)ivalue[0]/ivalue[1];
1348         case TIFFTag.TIFF_RATIONAL:
1349             long[] lvalue = getAsRational(index);
1350             return (double)lvalue[0]/lvalue[1];
1351         case TIFFTag.TIFF_ASCII:
1352              String s = ((String[])data)[index];
1353              return Double.parseDouble(s);
1354         default:
1355             throw new ClassCastException(); // should never happen
1356         }
1357     }
1358 
1359     /**
1360      * Returns a {@code TIFFTag.TIFF_ASCII} value as a
1361      * {@code String}.
1362      *
1363      * @throws ClassCastException if the field is not of type
1364      * {@code TIFF_ASCII}.
1365      *
1366      * @param index The index of the data.
1367      * @return The data at the given index as a {@code String}.
1368      */
1369     public String getAsString(int index) {
1370         return ((String[])data)[index];
1371     }
1372 
1373     /**
1374      * Returns a {@code TIFFTag.TIFF_SRATIONAL} data item as a
1375      * two-element array of {@code int}s.
1376      *
1377      * @param index The index of the data.
1378      * @return The data at the given index as a signed rational.
1379      * @throws ClassCastException if the field is not of type
1380      * {@code TIFF_SRATIONAL}.
1381      */
1382     public int[] getAsSRational(int index) {
1383         return ((int[][])data)[index];
1384     }
1385 
1386     /**
1387      * Returns a TIFFTag.TIFF_RATIONAL data item as a two-element array
1388      * of ints.
1389      *
1390      * @param index The index of the data.
1391      * @return The data at the given index as an unsigned rational.
1392      * @throws ClassCastException if the field is not of type
1393      * {@code TIFF_RATIONAL}.
1394      */
1395     public long[] getAsRational(int index) {
1396         return ((long[][])data)[index];
1397     }
1398 
1399 
1400     /**
1401      * Returns a {@code String} containing a human-readable
1402      * version of the data item.  Data of type
1403      * {@code TIFFTag.TIFF_RATIONAL} or {@code TIFF_SRATIONAL} are
1404      * represented as a pair of integers separated by a
1405      * {@code '/'} character.  If the numerator of a
1406      * {@code TIFFTag.TIFF_RATIONAL} or {@code TIFF_SRATIONAL} is an integral
1407      * multiple of the denominator, then the value is represented as
1408      * {@code "q/1"} where {@code q} is the quotient of the numerator and
1409      * denominator.
1410      *
1411      * @param index The index of the data.
1412      * @return The data at the given index as a {@code String}.
1413      * @throws ClassCastException if the field is not of one of the
1414      * legal field types.
1415      */
1416     public String getValueAsString(int index) {
1417         switch (type) {
1418         case TIFFTag.TIFF_ASCII:
1419             return ((String[])data)[index];
1420         case TIFFTag.TIFF_BYTE:
1421         case TIFFTag.TIFF_UNDEFINED:
1422             return Integer.toString(((byte[])data)[index] & 0xff);
1423         case TIFFTag.TIFF_SBYTE:
1424             return Integer.toString(((byte[])data)[index]);
1425         case TIFFTag.TIFF_SHORT:
1426             return Integer.toString(((char[])data)[index] & 0xffff);
1427         case TIFFTag.TIFF_SSHORT:
1428             return Integer.toString(((short[])data)[index]);
1429         case TIFFTag.TIFF_SLONG:
1430             return Integer.toString(((int[])data)[index]);
1431         case TIFFTag.TIFF_LONG:
1432         case TIFFTag.TIFF_IFD_POINTER:
1433             return Long.toString(((long[])data)[index]);
1434         case TIFFTag.TIFF_FLOAT:
1435             return Float.toString(((float[])data)[index]);
1436         case TIFFTag.TIFF_DOUBLE:
1437             return Double.toString(((double[])data)[index]);
1438         case TIFFTag.TIFF_SRATIONAL:
1439             int[] ivalue = getAsSRational(index);
1440             String srationalString;
1441             if(ivalue[1] != 0 && ivalue[0] % ivalue[1] == 0) {
1442                 // If the denominator is a non-zero integral divisor
1443                 // of the numerator then convert the fraction to be
1444                 // with respect to a unity denominator.
1445                 srationalString =
1446                     Integer.toString(ivalue[0] / ivalue[1]) + "/1";
1447             } else {
1448                 // Use the values directly.
1449                 srationalString =
1450                     Integer.toString(ivalue[0]) +
1451                     "/" +
1452                     Integer.toString(ivalue[1]);
1453             }
1454             return srationalString;
1455         case TIFFTag.TIFF_RATIONAL:
1456             long[] lvalue = getAsRational(index);
1457             String rationalString;
1458             if(lvalue[1] != 0L && lvalue[0] % lvalue[1] == 0) {
1459                 // If the denominator is a non-zero integral divisor
1460                 // of the numerator then convert the fraction to be
1461                 // with respect to a unity denominator.
1462                 rationalString =
1463                     Long.toString(lvalue[0] / lvalue[1]) + "/1";
1464             } else {
1465                 // Use the values directly.
1466                 rationalString =
1467                     Long.toString(lvalue[0]) +
1468                     "/" +
1469                     Long.toString(lvalue[1]);
1470             }
1471             return rationalString;
1472         default:
1473             throw new ClassCastException(); // should never happen
1474         }
1475     }
1476 
1477     /**
1478      * Returns whether the field has a {@code TIFFDirectory}.
1479      *
1480      * @return true if and only if getDirectory() returns non-null.
1481      */
1482     public boolean hasDirectory() {
1483         return getDirectory() != null;
1484     }
1485 
1486     /**
1487      * Returns the associated {@code TIFFDirectory}, if available. If no
1488      * directory is set, then {@code null} will be returned.
1489      *
1490      * @return the TIFFDirectory instance or null.
1491      */
1492     public TIFFDirectory getDirectory() {
1493         return dir;
1494     }
1495 
1496     /**
1497      * Clones the field and all the information contained therein.
1498      *
1499      * @return A clone of this {@code TIFFField}.
1500      * @throws CloneNotSupportedException if the instance cannot be cloned.
1501      */
1502     @Override
1503     public TIFFField clone() throws CloneNotSupportedException {
1504         TIFFField field = (TIFFField)super.clone();
1505 
1506         Object fieldData;
1507         switch (type) {
1508         case TIFFTag.TIFF_BYTE:
1509         case TIFFTag.TIFF_UNDEFINED:
1510         case TIFFTag.TIFF_SBYTE:
1511             fieldData = ((byte[])data).clone();
1512             break;
1513         case TIFFTag.TIFF_SHORT:
1514             fieldData = ((char[])data).clone();
1515             break;
1516         case TIFFTag.TIFF_SSHORT:
1517             fieldData = ((short[])data).clone();
1518             break;
1519         case TIFFTag.TIFF_SLONG:
1520             fieldData = ((int[])data).clone();
1521             break;
1522         case TIFFTag.TIFF_LONG:
1523         case TIFFTag.TIFF_IFD_POINTER:
1524             fieldData = ((long[])data).clone();
1525             break;
1526         case TIFFTag.TIFF_FLOAT:
1527             fieldData = ((float[])data).clone();
1528             break;
1529         case TIFFTag.TIFF_DOUBLE:
1530             fieldData = ((double[])data).clone();
1531             break;
1532         case TIFFTag.TIFF_SRATIONAL:
1533             fieldData = ((int[][])data).clone();
1534             break;
1535         case TIFFTag.TIFF_RATIONAL:
1536             fieldData = ((long[][])data).clone();
1537             break;
1538         case TIFFTag.TIFF_ASCII:
1539             fieldData = ((String[])data).clone();
1540             break;
1541         default:
1542             throw new ClassCastException(); // should never happen
1543         }
1544 
1545         field.tag = tag;
1546         field.tagNumber = tagNumber;
1547         field.type = type;
1548         field.count = count;
1549         field.data = fieldData;
1550         field.dir = dir != null ? dir.clone() : null;
1551 
1552         return field;
1553     }
1554 }