jdk/src/java.desktop/share/classes/javax/imageio/plugins/tiff/TIFFField.java
changeset 34416 68c0d866db5d
child 35302 e4d2275861c3
equal deleted inserted replaced
34415:098d54b4051d 34416:68c0d866db5d
       
     1 /*
       
     2  * Copyright (c) 2005, 2015, 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</code> 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</code>
       
    72  * </td>
       
    73  * <td>
       
    74  * <code>"Byte"</code>
       
    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</code>
       
    87  * </td>
       
    88  * <td>
       
    89  * <code>"Ascii"</code>
       
    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</code>
       
   102  * </td>
       
   103  * <td>
       
   104  * <code>"Short"</code>
       
   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</code>
       
   117  * </td>
       
   118  * <td>
       
   119  * <code>"Long"</code>
       
   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]</code> {numerator, denominator}
       
   132  * </td>
       
   133  * <td>
       
   134  * <code>"Rational"</code>
       
   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</code>
       
   147  * </td>
       
   148  * <td>
       
   149  * <code>"SByte"</code>
       
   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</code>
       
   162  * </td>
       
   163  * <td>
       
   164  * <code>"Undefined"</code>
       
   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</code>
       
   177  * </td>
       
   178  * <td>
       
   179  * <code>"SShort"</code>
       
   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</code>
       
   192  * </td>
       
   193  * <td>
       
   194  * <code>"SLong"</code>
       
   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]</code> {numerator, denominator}
       
   207  * </td>
       
   208  * <td>
       
   209  * <code>"SRational"</code>
       
   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</code>
       
   222  * </td>
       
   223  * <td>
       
   224  * <code>"Float"</code>
       
   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</code>
       
   237  * </td>
       
   238  * <td>
       
   239  * <code>"Double"</code>
       
   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</code>
       
   252  * </td>
       
   253  * <td>
       
   254  * <code>"IFDPointer"</code>
       
   255  * </td>
       
   256  * </tr>
       
   257  *
       
   258  * </table>
       
   259  *
       
   260  * @since 1.9
       
   261  * @see   TIFFDirectory
       
   262  * @see   TIFFTag
       
   263  */
       
   264 public 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</code> from a TIFF native image
       
   415      * metadata node. If the value of the <tt>"tagNumber"</tt> attribute
       
   416      * of the node is not found in <code>tagSet</code> then a new
       
   417      * <code>TIFFTag</code> with name <code>TIFFTag.UNKNOWN_TAG_NAME</code>
       
   418      * will be created and assigned to the field.
       
   419      *
       
   420      * @param tagSet The <code>TIFFTagSet</code> to which the
       
   421      * <code>TIFFTag</code> of the field belongs.
       
   422      * @param node A native TIFF image metadata <code>TIFFField</code> node.
       
   423      * @throws NullPointerException if <code>node</code> is
       
   424      * <code>null</code>.
       
   425      * @throws IllegalArgumentException if the name of the node is not
       
   426      * <code>"TIFFField"</code>.
       
   427      * @return A new {@code TIFFField}.
       
   428      */
       
   429     public static TIFFField createFromMetadataNode(TIFFTagSet tagSet,
       
   430                                                    Node node) {
       
   431         if (node == null) {
       
   432             throw new NullPointerException("node == null!");
       
   433         }
       
   434         String name = node.getNodeName();
       
   435         if (!name.equals("TIFFField")) {
       
   436             throw new IllegalArgumentException("!name.equals(\"TIFFField\")");
       
   437         }
       
   438 
       
   439         int tagNumber = Integer.parseInt(getAttribute(node, "number"));
       
   440         TIFFTag tag = null;
       
   441         if (tagSet != null) {
       
   442             tag = tagSet.getTag(tagNumber);
       
   443         }
       
   444 
       
   445         int type = TIFFTag.TIFF_UNDEFINED;
       
   446         int count = 0;
       
   447         Object data = null;
       
   448 
       
   449         Node child = node.getFirstChild();
       
   450         if (child != null) {
       
   451             String typeName = child.getNodeName();
       
   452             if (typeName.equals("TIFFUndefined")) {
       
   453                 String values = getAttribute(child, "value");
       
   454                 StringTokenizer st = new StringTokenizer(values, ",");
       
   455                 count = st.countTokens();
       
   456 
       
   457                 byte[] bdata = new byte[count];
       
   458                 for (int i = 0; i < count; i++) {
       
   459                     bdata[i] = (byte)Integer.parseInt(st.nextToken());
       
   460                 }
       
   461 
       
   462                 type = TIFFTag.TIFF_UNDEFINED;
       
   463                 data = bdata;
       
   464             } else {
       
   465                 int[] otype = new int[1];
       
   466                 int[] ocount = new int[1];
       
   467                 Object[] odata = new Object[1];
       
   468 
       
   469                 initData(node.getFirstChild(), otype, ocount, odata);
       
   470                 type = otype[0];
       
   471                 count = ocount[0];
       
   472                 data = odata[0];
       
   473             }
       
   474         } else if (tag != null) {
       
   475             int t = TIFFTag.MAX_DATATYPE;
       
   476             while(t >= TIFFTag.MIN_DATATYPE && !tag.isDataTypeOK(t)) {
       
   477                 t--;
       
   478             }
       
   479             type = t;
       
   480         }
       
   481 
       
   482         if (tag == null) {
       
   483             tag = new TIFFTag(TIFFTag.UNKNOWN_TAG_NAME, tagNumber, 1 << type);
       
   484         }
       
   485 
       
   486         return new TIFFField(tag, type, count, data);
       
   487     }
       
   488 
       
   489     /**
       
   490      * Constructs a <code>TIFFField</code> with arbitrary data. The
       
   491      * <code>type</code> parameter must be a value for which
       
   492      * {@link TIFFTag#isDataTypeOK tag.isDataTypeOK()}
       
   493      * returns <code>true</code>. The <code>data</code> parameter must
       
   494      * be an array of a Java type appropriate for the type of the TIFF
       
   495      * field.
       
   496      *
       
   497      * <p>Note that the value (data) of the <code>TIFFField</code>
       
   498      * will always be the actual field value regardless of the number of
       
   499      * bytes required for that value. This is the case despite the fact
       
   500      * that the TIFF <i>IFD Entry</i> corresponding to the field may
       
   501      * actually contain the offset to the value of the field rather than
       
   502      * the value itself (the latter occurring if and only if the
       
   503      * value fits into 4 bytes). In other words, the value of the
       
   504      * field will already have been read from the TIFF stream. (An exception
       
   505      * to this case may occur when the field represents the contents of a
       
   506      * non-baseline IFD. In that case the data will be a <code>long[]</code>
       
   507      * containing the offset to the IFD and the <code>TIFFDirectory</code>
       
   508      * returned by {@link #getDirectory()} will be its contents.)
       
   509      *
       
   510      * @param tag The tag to associated with this field.
       
   511      * @param type One of the <code>TIFFTag.TIFF_*</code> constants
       
   512      * indicating the data type of the field as written to the TIFF stream.
       
   513      * @param count The number of data values.
       
   514      * @param data The actual data content of the field.
       
   515      *
       
   516      * @throws NullPointerException if <code>tag&nbsp;==&nbsp;null</code>.
       
   517      * @throws IllegalArgumentException if <code>type</code> is not
       
   518      * one of the <code>TIFFTag.TIFF_*</code> data type constants.
       
   519      * @throws IllegalArgumentException if <code>type</code> is an unacceptable
       
   520      * data type for the supplied <code>TIFFTag</code>.
       
   521      * @throws IllegalArgumentException if <code>count&nbsp;&lt;&nbsp;0</code>.
       
   522      * @throws NullPointerException if <code>data&nbsp;==&nbsp;null</code>.
       
   523      * @throws IllegalArgumentException if <code>data</code> is an instance of
       
   524      * a class incompatible with the specified type.
       
   525      * @throws IllegalArgumentException if the size of the data array is wrong.
       
   526      */
       
   527     public TIFFField(TIFFTag tag, int type, int count, Object data) {
       
   528         if(tag == null) {
       
   529             throw new NullPointerException("tag == null!");
       
   530         } else if(type < TIFFTag.MIN_DATATYPE || type > TIFFTag.MAX_DATATYPE) {
       
   531             throw new IllegalArgumentException("Unknown data type "+type);
       
   532         } else if(!tag.isDataTypeOK(type)) {
       
   533             throw new IllegalArgumentException("Illegal data type " + type
       
   534                 + " for " + tag.getName() + " tag");
       
   535         } else if(count < 0) {
       
   536             throw new IllegalArgumentException("count < 0!");
       
   537         } else if(data == null) {
       
   538             throw new NullPointerException("data == null!");
       
   539         }
       
   540 
       
   541         boolean isDataArrayCorrect = false;
       
   542 
       
   543         switch (type) {
       
   544         case TIFFTag.TIFF_BYTE:
       
   545         case TIFFTag.TIFF_SBYTE:
       
   546         case TIFFTag.TIFF_UNDEFINED:
       
   547             isDataArrayCorrect = data instanceof byte[]
       
   548                 && ((byte[])data).length == count;
       
   549             break;
       
   550         case TIFFTag.TIFF_ASCII:
       
   551             isDataArrayCorrect = data instanceof String[]
       
   552                 && ((String[])data).length == count;
       
   553             break;
       
   554         case TIFFTag.TIFF_SHORT:
       
   555             isDataArrayCorrect = data instanceof char[]
       
   556                 && ((char[])data).length == count;
       
   557             break;
       
   558         case TIFFTag.TIFF_LONG:
       
   559             isDataArrayCorrect = data instanceof long[]
       
   560                 && ((long[])data).length == count;
       
   561             break;
       
   562         case TIFFTag.TIFF_IFD_POINTER:
       
   563             isDataArrayCorrect = data instanceof long[]
       
   564                 && ((long[])data).length == 1;
       
   565             break;
       
   566         case TIFFTag.TIFF_RATIONAL:
       
   567             isDataArrayCorrect = data instanceof long[][]
       
   568                 && ((long[][])data).length == count
       
   569                 && ((long[][])data)[0].length == 2;
       
   570             break;
       
   571         case TIFFTag.TIFF_SSHORT:
       
   572             isDataArrayCorrect = data instanceof short[]
       
   573                 && ((short[])data).length == count;
       
   574             break;
       
   575         case TIFFTag.TIFF_SLONG:
       
   576             isDataArrayCorrect = data instanceof int[]
       
   577                 && ((int[])data).length == count;
       
   578             break;
       
   579         case TIFFTag.TIFF_SRATIONAL:
       
   580             isDataArrayCorrect = data instanceof int[][]
       
   581                 && ((int[][])data).length == count
       
   582                 && ((int[][])data)[0].length == 2;
       
   583             break;
       
   584         case TIFFTag.TIFF_FLOAT:
       
   585             isDataArrayCorrect = data instanceof float[]
       
   586                 && ((float[])data).length == count;
       
   587             break;
       
   588         case TIFFTag.TIFF_DOUBLE:
       
   589             isDataArrayCorrect = data instanceof double[]
       
   590                 && ((double[])data).length == count;
       
   591             break;
       
   592         default:
       
   593             throw new IllegalArgumentException("Unknown data type "+type);
       
   594         }
       
   595 
       
   596         if (!isDataArrayCorrect) {
       
   597             throw new IllegalArgumentException
       
   598                 ("Illegal class or length for data array");
       
   599         }
       
   600 
       
   601         this.tag = tag;
       
   602         this.tagNumber = tag.getNumber();
       
   603         this.type = type;
       
   604         this.count = count;
       
   605         this.data = data;
       
   606     }
       
   607 
       
   608     /**
       
   609      * Constructs a data array using {@link #createArrayForType
       
   610      * createArrayForType()} and invokes
       
   611      * {@link #TIFFField(TIFFTag,int,int,Object)} with the supplied
       
   612      * parameters and the created array.
       
   613      *
       
   614      * @param tag The tag to associated with this field.
       
   615      * @param type One of the <code>TIFFTag.TIFF_*</code> constants
       
   616      * indicating the data type of the field as written to the TIFF stream.
       
   617      * @param count The number of data values.
       
   618      * @throws NullPointerException if <code>tag&nbsp;==&nbsp;null</code>.
       
   619      * @throws IllegalArgumentException if <code>type</code> is not
       
   620      * one of the <code>TIFFTag.TIFF_*</code> data type constants.
       
   621      * @throws IllegalArgumentException if <code>type</code> is an unacceptable
       
   622      * data type for the supplied <code>TIFFTag</code>.
       
   623      * @throws IllegalArgumentException if <code>count&nbsp;&lt;&nbsp;0</code>.
       
   624      * @see #TIFFField(TIFFTag,int,int,Object)
       
   625      */
       
   626     public TIFFField(TIFFTag tag, int type, int count) {
       
   627         this(tag, type, count, createArrayForType(type, count));
       
   628     }
       
   629 
       
   630     /**
       
   631      * Constructs a <code>TIFFField</code> with a single non-negative integral
       
   632      * value.
       
   633      * The field will have type
       
   634      * {@link TIFFTag#TIFF_SHORT  TIFF_SHORT} if
       
   635      * <code>val&nbsp;&lt;&nbsp;65536</code> and type
       
   636      * {@link TIFFTag#TIFF_LONG TIFF_LONG} otherwise.  The count
       
   637      * of the field will be unity.
       
   638      *
       
   639      * @param tag The tag to associate with this field.
       
   640      * @param value The value to associate with this field.
       
   641      * @throws NullPointerException if <code>tag&nbsp;==&nbsp;null</code>.
       
   642      * @throws IllegalArgumentException if the derived type is unacceptable
       
   643      * for the supplied <code>TIFFTag</code>.
       
   644      * @throws IllegalArgumentException if <code>value&nbsp;&lt;&nbsp;0</code>.
       
   645      */
       
   646     public TIFFField(TIFFTag tag, int value) {
       
   647         if(tag == null) {
       
   648             throw new NullPointerException("tag == null!");
       
   649         }
       
   650         if (value < 0) {
       
   651             throw new IllegalArgumentException("value < 0!");
       
   652         }
       
   653 
       
   654         this.tag = tag;
       
   655         this.tagNumber = tag.getNumber();
       
   656         this.count = 1;
       
   657 
       
   658         if (value < 65536) {
       
   659             if (!tag.isDataTypeOK(TIFFTag.TIFF_SHORT)) {
       
   660                 throw new IllegalArgumentException("Illegal data type "
       
   661                     + TIFFTag.TIFF_SHORT + " for " + tag.getName() + " tag");
       
   662             }
       
   663             this.type = TIFFTag.TIFF_SHORT;
       
   664             char[] cdata = new char[1];
       
   665             cdata[0] = (char)value;
       
   666             this.data = cdata;
       
   667         } else {
       
   668             if (!tag.isDataTypeOK(TIFFTag.TIFF_LONG)) {
       
   669                 throw new IllegalArgumentException("Illegal data type "
       
   670                     + TIFFTag.TIFF_LONG + " for " + tag.getName() + " tag");
       
   671             }
       
   672             this.type = TIFFTag.TIFF_LONG;
       
   673             long[] ldata = new long[1];
       
   674             ldata[0] = value;
       
   675             this.data = ldata;
       
   676         }
       
   677     }
       
   678 
       
   679     /**
       
   680      * Constructs a <code>TIFFField</code> with an IFD offset and contents.
       
   681      * The offset will be stored as the data of this field as
       
   682      * <code>long[] {offset}</code>. The directory will not be cloned. The count
       
   683      * of the field will be unity.
       
   684      *
       
   685      * @param tag The tag to associated with this field.
       
   686      * @param type One of the constants <code>TIFFTag.TIFF_LONG</code> or
       
   687      * <code>TIFFTag.TIFF_IFD_POINTER</code>.
       
   688      * @param offset The IFD offset.
       
   689      * @param dir The directory.
       
   690      *
       
   691      * @throws NullPointerException if <code>tag&nbsp;==&nbsp;null</code>.
       
   692      * @throws IllegalArgumentException if <code>type</code> is neither
       
   693      * <code>TIFFTag.TIFF_LONG</code> nor <code>TIFFTag.TIFF_IFD_POINTER</code>.
       
   694      * @throws IllegalArgumentException if <code>type</code> is an unacceptable
       
   695      * data type for the supplied <code>TIFFTag</code>.
       
   696      * @throws IllegalArgumentException if <code>offset</code> is non-positive.
       
   697      * @throws NullPointerException if <code>dir&nbsp;==&nbsp;null</code>.
       
   698      *
       
   699      * @see #TIFFField(TIFFTag,int,int,Object)
       
   700      */
       
   701     public TIFFField(TIFFTag tag, int type, long offset, TIFFDirectory dir) {
       
   702         this(tag, type, 1, new long[] {offset});
       
   703         if (type != TIFFTag.TIFF_LONG && type != TIFFTag.TIFF_IFD_POINTER) {
       
   704             throw new IllegalArgumentException("type " + type
       
   705                 + " is neither TIFFTag.TIFF_LONG nor TIFFTag.TIFF_IFD_POINTER");
       
   706         } else if (offset <= 0) {
       
   707             throw new IllegalArgumentException("offset " + offset
       
   708                 + " is non-positive");
       
   709         } else if (dir == null) {
       
   710             throw new NullPointerException("dir == null");
       
   711         }
       
   712         this.dir = dir;
       
   713     }
       
   714 
       
   715     /**
       
   716      * Retrieves the tag associated with this field.
       
   717      *
       
   718      * @return The associated <code>TIFFTag</code>.
       
   719      */
       
   720     public TIFFTag getTag() {
       
   721         return tag;
       
   722     }
       
   723 
       
   724     /**
       
   725      * Retrieves the tag number in the range <code>[0,&nbsp;65535]</code>.
       
   726      *
       
   727      * @return The tag number.
       
   728      */
       
   729     public int getTagNumber() {
       
   730         return tagNumber;
       
   731     }
       
   732 
       
   733     /**
       
   734      * Returns the type of the data stored in the field.  For a TIFF 6.0
       
   735      * stream, the value will equal one of the <code>TIFFTag.TIFF_*</code>
       
   736      * constants. For future revisions of TIFF, higher values are possible.
       
   737      *
       
   738      * @return The data type of the field value.
       
   739      */
       
   740     public int getType() {
       
   741         return type;
       
   742     }
       
   743 
       
   744     /**
       
   745      * Returns the name of the supplied data type constant.
       
   746      *
       
   747      * @param dataType One of the <code>TIFFTag.TIFF_*</code> constants
       
   748      * indicating the data type of the field as written to the TIFF stream.
       
   749      * @return The type name corresponding to the supplied type constant.
       
   750      * @throws IllegalArgumentException if <code>dataType</code> is not
       
   751      * one of the <code>TIFFTag.TIFF_*</code> data type constants.
       
   752      */
       
   753     public static String getTypeName(int dataType) {
       
   754         if (dataType < TIFFTag.MIN_DATATYPE ||
       
   755             dataType > TIFFTag.MAX_DATATYPE) {
       
   756             throw new IllegalArgumentException("Unknown data type "+dataType);
       
   757         }
       
   758 
       
   759         return typeNames[dataType];
       
   760     }
       
   761 
       
   762     /**
       
   763      * Returns the data type constant corresponding to the supplied data
       
   764      * type name. If the name is unknown <code>-1</code> will be returned.
       
   765      *
       
   766      * @param typeName The type name.
       
   767      * @return One of the <code>TIFFTag.TIFF_*</code> constants or
       
   768      * <code>-1</code> if the name is not recognized.
       
   769      */
       
   770     public static int getTypeByName(String typeName) {
       
   771         for (int i = TIFFTag.MIN_DATATYPE; i <= TIFFTag.MAX_DATATYPE; i++) {
       
   772             if (typeName.equals(typeNames[i])) {
       
   773                 return i;
       
   774             }
       
   775         }
       
   776 
       
   777         return -1;
       
   778     }
       
   779 
       
   780     /**
       
   781      * Creates an array appropriate for the indicated data type.
       
   782      *
       
   783      * @param dataType One of the <code>TIFFTag.TIFF_*</code> data type
       
   784      * constants.
       
   785      * @param count The number of values in the array.
       
   786      * @return An array appropriate for the specified data type.
       
   787      *
       
   788      * @throws IllegalArgumentException if <code>dataType</code> is not
       
   789      * one of the <code>TIFFTag.TIFF_*</code> data type constants.
       
   790      * @throws IllegalArgumentException if <code>count&nbsp;&lt;&nbsp;0</code>.
       
   791      */
       
   792     public static Object createArrayForType(int dataType, int count) {
       
   793         if(count < 0) {
       
   794             throw new IllegalArgumentException("count < 0!");
       
   795         }
       
   796         switch (dataType) {
       
   797         case TIFFTag.TIFF_BYTE:
       
   798         case TIFFTag.TIFF_SBYTE:
       
   799         case TIFFTag.TIFF_UNDEFINED:
       
   800             return new byte[count];
       
   801         case TIFFTag.TIFF_ASCII:
       
   802             return new String[count];
       
   803         case TIFFTag.TIFF_SHORT:
       
   804             return new char[count];
       
   805         case TIFFTag.TIFF_LONG:
       
   806         case TIFFTag.TIFF_IFD_POINTER:
       
   807             return new long[count];
       
   808         case TIFFTag.TIFF_RATIONAL:
       
   809             return new long[count][2];
       
   810         case TIFFTag.TIFF_SSHORT:
       
   811             return new short[count];
       
   812         case TIFFTag.TIFF_SLONG:
       
   813             return new int[count];
       
   814         case TIFFTag.TIFF_SRATIONAL:
       
   815             return new int[count][2];
       
   816         case TIFFTag.TIFF_FLOAT:
       
   817             return new float[count];
       
   818         case TIFFTag.TIFF_DOUBLE:
       
   819             return new double[count];
       
   820         default:
       
   821             throw new IllegalArgumentException("Unknown data type "+dataType);
       
   822         }
       
   823     }
       
   824 
       
   825     /**
       
   826      * Returns the <code>TIFFField</code> as a node named either
       
   827      * <tt>"TIFFField"</tt> or <tt>"TIFFIFD"</tt> as described in the
       
   828      * TIFF native image metadata specification. The node will be named
       
   829      * <tt>"TIFFIFD"</tt> if and only if the field's data object is an
       
   830      * instance of {@link TIFFDirectory} or equivalently
       
   831      * {@link TIFFTag#isIFDPointer getTag.isIFDPointer()} returns
       
   832      * <code>true</code>.
       
   833      *
       
   834      * @return a <code>Node</code> named <tt>"TIFFField"</tt> or
       
   835      * <tt>"TIFFIFD"</tt>.
       
   836      */
       
   837     public Node getAsNativeNode() {
       
   838         return new TIFFFieldNode(this);
       
   839     }
       
   840 
       
   841     /**
       
   842      * Indicates whether the value associated with the field is of
       
   843      * integral data type.
       
   844      *
       
   845      * @return Whether the field type is integral.
       
   846      */
       
   847     public boolean isIntegral() {
       
   848         return isIntegral[type];
       
   849     }
       
   850 
       
   851     /**
       
   852      * Returns the number of data items present in the field.  For
       
   853      * <code>TIFFTag.TIFF_ASCII</code> fields, the value returned is the
       
   854      * number of <code>String</code>s, not the total length of the
       
   855      * data as in the file representation.
       
   856      *
       
   857      * @return The number of data items present in the field.
       
   858      */
       
   859     public int getCount() {
       
   860         return count;
       
   861     }
       
   862 
       
   863     /**
       
   864      * Returns a reference to the data object associated with the field.
       
   865      *
       
   866      * @return The data object of the field.
       
   867      */
       
   868     public Object getData() {
       
   869         return data;
       
   870     }
       
   871 
       
   872     /**
       
   873      * Returns the data as an uninterpreted array of
       
   874      * <code>byte</code>s.  The type of the field must be one of
       
   875      * <code>TIFFTag.TIFF_BYTE</code>, <code>TIFF_SBYTE</code>, or
       
   876      * <code>TIFF_UNDEFINED</code>.
       
   877      *
       
   878      * <p> For data in <code>TIFFTag.TIFF_BYTE</code> format, the application
       
   879      * must take care when promoting the data to longer integral types
       
   880      * to avoid sign extension.
       
   881      *
       
   882      * @throws ClassCastException if the field is not of type
       
   883      * <code>TIFF_BYTE</code>, <code>TIFF_SBYTE</code>, or
       
   884      * <code>TIFF_UNDEFINED</code>.
       
   885      * @return The data as an uninterpreted array of bytes.
       
   886      */
       
   887     public byte[] getAsBytes() {
       
   888         return (byte[])data;
       
   889     }
       
   890 
       
   891     /**
       
   892      * Returns <code>TIFFTag.TIFF_SHORT</code> data as an array of
       
   893      * <code>char</code>s (unsigned 16-bit integers).
       
   894      *
       
   895      * @throws ClassCastException if the field is not of type
       
   896      * <code>TIFF_SHORT</code>.
       
   897      * @return The data as an array of {@code char}s.
       
   898      */
       
   899     public char[] getAsChars() {
       
   900         return (char[])data;
       
   901     }
       
   902 
       
   903     /**
       
   904      * Returns <code>TIFFTag.TIFF_SSHORT</code> data as an array of
       
   905      * <code>short</code>s (signed 16-bit integers).
       
   906      *
       
   907      * @throws ClassCastException if the field is not of type
       
   908      * <code>TIFF_SSHORT</code>.
       
   909      * @return The data as an array of {@code short}s.
       
   910      */
       
   911     public short[] getAsShorts() {
       
   912         return (short[])data;
       
   913     }
       
   914 
       
   915     /**
       
   916      * Returns <code>TIFFTag.TIFF_SLONG</code> data as an array of
       
   917      * <code>int</code>s (signed 32-bit integers).
       
   918      *
       
   919      * @throws ClassCastException if the field is not of type
       
   920      * <code>TIFF_SHORT</code>, <code>TIFF_SSHORT</code>, or
       
   921      * <code>TIFF_SLONG</code>.
       
   922      * @return The data as an array of {@code int}s.
       
   923      */
       
   924     public int[] getAsInts() {
       
   925         if (data instanceof int[]) {
       
   926             return (int[])data;
       
   927         } else if (data instanceof char[]){
       
   928             char[] cdata = (char[])data;
       
   929             int[] idata = new int[cdata.length];
       
   930             for (int i = 0; i < cdata.length; i++) {
       
   931                 idata[i] = cdata[i] & 0xffff;
       
   932             }
       
   933             return idata;
       
   934         } else if (data instanceof short[]){
       
   935             short[] sdata = (short[])data;
       
   936             int[] idata = new int[sdata.length];
       
   937             for (int i = 0; i < sdata.length; i++) {
       
   938                 idata[i] = (int)sdata[i];
       
   939             }
       
   940             return idata;
       
   941         } else {
       
   942             throw new ClassCastException("Data not char[], short[], or int[]!");
       
   943         }
       
   944     }
       
   945 
       
   946     /**
       
   947      * Returns <code>TIFFTag.TIFF_LONG</code> or
       
   948      * <code>TIFF_IFD_POINTER</code> data as an array of
       
   949      * <code>long</code>s (signed 64-bit integers).
       
   950      *
       
   951      * @throws ClassCastException if the field is not of type
       
   952      * <code>TIFF_LONG</code> or <code>TIFF_IFD_POINTER</code>.
       
   953      * @return The data as an array of {@code long}s.
       
   954      */
       
   955     public long[] getAsLongs() {
       
   956         return (long[])data;
       
   957     }
       
   958 
       
   959     /**
       
   960      * Returns <code>TIFFTag.TIFF_FLOAT</code> data as an array of
       
   961      * <code>float</code>s (32-bit floating-point values).
       
   962      *
       
   963      * @throws ClassCastException if the field is not of type
       
   964      * <code>TIFF_FLOAT</code>.
       
   965      * @return The data as an array of {@code float}s.
       
   966      */
       
   967     public float[] getAsFloats() {
       
   968         return (float[])data;
       
   969     }
       
   970 
       
   971     /**
       
   972      * Returns <code>TIFFTag.TIFF_DOUBLE</code> data as an array of
       
   973      * <code>double</code>s (64-bit floating-point values).
       
   974      *
       
   975      * @throws ClassCastException if the field is not of type
       
   976      * <code>TIFF_DOUBLE</code>.
       
   977      * @return The data as an array of {@code double}s.
       
   978      */
       
   979     public double[] getAsDoubles() {
       
   980         return (double[])data;
       
   981     }
       
   982 
       
   983     /**
       
   984      * Returns <code>TIFFTag.TIFF_SRATIONAL</code> data as an array of
       
   985      * 2-element arrays of <code>int</code>s.
       
   986      *
       
   987      * @throws ClassCastException if the field is not of type
       
   988      * <code>TIFF_SRATIONAL</code>.
       
   989      * @return The data as an array of signed rationals.
       
   990      */
       
   991     public int[][] getAsSRationals() {
       
   992         return (int[][])data;
       
   993     }
       
   994 
       
   995     /**
       
   996      * Returns <code>TIFFTag.TIFF_RATIONAL</code> data as an array of
       
   997      * 2-element arrays of <code>long</code>s.
       
   998      *
       
   999      * @throws ClassCastException if the field is not of type
       
  1000      * <code>TIFF_RATIONAL</code>.
       
  1001      * @return The data as an array of unsigned rationals.
       
  1002      */
       
  1003     public long[][] getAsRationals() {
       
  1004         return (long[][])data;
       
  1005     }
       
  1006 
       
  1007     /**
       
  1008      * Returns data in any format as an <code>int</code>.
       
  1009      *
       
  1010      * <p> <code>TIFFTag.TIFF_BYTE</code> values are treated as unsigned; that
       
  1011      * is, no sign extension will take place and the returned value
       
  1012      * will be in the range [0, 255].  <code>TIFF_SBYTE</code> data
       
  1013      * will be returned in the range [-128, 127].
       
  1014      *
       
  1015      * <p> A <code>TIFF_UNDEFINED</code> value is treated as though
       
  1016      * it were a <code>TIFF_BYTE</code>.
       
  1017      *
       
  1018      * <p> Data in <code>TIFF_SLONG</code>, <code>TIFF_LONG</code>,
       
  1019      * <code>TIFF_FLOAT</code>, <code>TIFF_DOUBLE</code> or
       
  1020      * <code>TIFF_IFD_POINTER</code> format are simply cast to
       
  1021      * <code>int</code> and may suffer from truncation.
       
  1022      *
       
  1023      * <p> Data in <code>TIFF_SRATIONAL</code> or
       
  1024      * <code>TIFF_RATIONAL</code> format are evaluated by dividing the
       
  1025      * numerator into the denominator using double-precision
       
  1026      * arithmetic and then casting to <code>int</code>.  Loss of
       
  1027      * precision and truncation may occur.
       
  1028      *
       
  1029      * <p> Data in <code>TIFF_ASCII</code> format will be parsed as by
       
  1030      * the <code>Double.parseDouble</code> method, with the result
       
  1031      * case to <code>int</code>.
       
  1032      *
       
  1033      * @param index The index of the data.
       
  1034      * @return The data at the given index as an {@code int}.
       
  1035      */
       
  1036     public int getAsInt(int index) {
       
  1037         switch (type) {
       
  1038         case TIFFTag.TIFF_BYTE:
       
  1039         case TIFFTag.TIFF_UNDEFINED:
       
  1040             return ((byte[])data)[index] & 0xff;
       
  1041         case TIFFTag.TIFF_SBYTE:
       
  1042             return ((byte[])data)[index];
       
  1043         case TIFFTag.TIFF_SHORT:
       
  1044             return ((char[])data)[index] & 0xffff;
       
  1045         case TIFFTag.TIFF_SSHORT:
       
  1046             return ((short[])data)[index];
       
  1047         case TIFFTag.TIFF_SLONG:
       
  1048             return ((int[])data)[index];
       
  1049         case TIFFTag.TIFF_LONG:
       
  1050         case TIFFTag.TIFF_IFD_POINTER:
       
  1051             return (int)((long[])data)[index];
       
  1052         case TIFFTag.TIFF_FLOAT:
       
  1053             return (int)((float[])data)[index];
       
  1054         case TIFFTag.TIFF_DOUBLE:
       
  1055             return (int)((double[])data)[index];
       
  1056         case TIFFTag.TIFF_SRATIONAL:
       
  1057             int[] ivalue = getAsSRational(index);
       
  1058             return (int)((double)ivalue[0]/ivalue[1]);
       
  1059         case TIFFTag.TIFF_RATIONAL:
       
  1060             long[] lvalue = getAsRational(index);
       
  1061             return (int)((double)lvalue[0]/lvalue[1]);
       
  1062         case TIFFTag.TIFF_ASCII:
       
  1063              String s = ((String[])data)[index];
       
  1064              return (int)Double.parseDouble(s);
       
  1065         default:
       
  1066             throw new ClassCastException(); // should never happen
       
  1067         }
       
  1068     }
       
  1069 
       
  1070     /**
       
  1071      * Returns data in any format as a <code>long</code>.
       
  1072      *
       
  1073      * <p> <code>TIFFTag.TIFF_BYTE</code> and <code>TIFF_UNDEFINED</code> data
       
  1074      * are treated as unsigned; that is, no sign extension will take
       
  1075      * place and the returned value will be in the range [0, 255].
       
  1076      * <code>TIFF_SBYTE</code> data will be returned in the range
       
  1077      * [-128, 127].
       
  1078      *
       
  1079      * <p> Data in <code>TIFF_ASCII</code> format will be parsed as by
       
  1080      * the <code>Double.parseDouble</code> method, with the result
       
  1081      * cast to <code>long</code>.
       
  1082      *
       
  1083      * @param index The index of the data.
       
  1084      * @return The data at the given index as a {@code long}.
       
  1085      */
       
  1086     public long getAsLong(int index) {
       
  1087         switch (type) {
       
  1088         case TIFFTag.TIFF_BYTE:
       
  1089         case TIFFTag.TIFF_UNDEFINED:
       
  1090             return ((byte[])data)[index] & 0xff;
       
  1091         case TIFFTag.TIFF_SBYTE:
       
  1092             return ((byte[])data)[index];
       
  1093         case TIFFTag.TIFF_SHORT:
       
  1094             return ((char[])data)[index] & 0xffff;
       
  1095         case TIFFTag.TIFF_SSHORT:
       
  1096             return ((short[])data)[index];
       
  1097         case TIFFTag.TIFF_SLONG:
       
  1098             return ((int[])data)[index];
       
  1099         case TIFFTag.TIFF_LONG:
       
  1100         case TIFFTag.TIFF_IFD_POINTER:
       
  1101             return ((long[])data)[index];
       
  1102         case TIFFTag.TIFF_SRATIONAL:
       
  1103             int[] ivalue = getAsSRational(index);
       
  1104             return (long)((double)ivalue[0]/ivalue[1]);
       
  1105         case TIFFTag.TIFF_RATIONAL:
       
  1106             long[] lvalue = getAsRational(index);
       
  1107             return (long)((double)lvalue[0]/lvalue[1]);
       
  1108         case TIFFTag.TIFF_ASCII:
       
  1109              String s = ((String[])data)[index];
       
  1110              return (long)Double.parseDouble(s);
       
  1111         default:
       
  1112             throw new ClassCastException(); // should never happen
       
  1113         }
       
  1114     }
       
  1115 
       
  1116     /**
       
  1117      * Returns data in any format as a <code>float</code>.
       
  1118      *
       
  1119      * <p> <code>TIFFTag.TIFF_BYTE</code> and <code>TIFF_UNDEFINED</code> data
       
  1120      * are treated as unsigned; that is, no sign extension will take
       
  1121      * place and the returned value will be in the range [0, 255].
       
  1122      * <code>TIFF_SBYTE</code> data will be returned in the range
       
  1123      * [-128, 127].
       
  1124      *
       
  1125      * <p> Data in <code>TIFF_SLONG</code>, <code>TIFF_LONG</code>,
       
  1126      * <code>TIFF_DOUBLE</code>, or <code>TIFF_IFD_POINTER</code> format are
       
  1127      * simply cast to <code>float</code> and may suffer from
       
  1128      * truncation.
       
  1129      *
       
  1130      * <p> Data in <code>TIFF_SRATIONAL</code> or
       
  1131      * <code>TIFF_RATIONAL</code> format are evaluated by dividing the
       
  1132      * numerator into the denominator using double-precision
       
  1133      * arithmetic and then casting to <code>float</code>.
       
  1134      *
       
  1135      * <p> Data in <code>TIFF_ASCII</code> format will be parsed as by
       
  1136      * the <code>Double.parseDouble</code> method, with the result
       
  1137      * cast to <code>float</code>.
       
  1138      *
       
  1139      * @param index The index of the data.
       
  1140      * @return The data at the given index as a {@code float}.
       
  1141      */
       
  1142     public float getAsFloat(int index) {
       
  1143         switch (type) {
       
  1144         case TIFFTag.TIFF_BYTE:
       
  1145         case TIFFTag.TIFF_UNDEFINED:
       
  1146             return ((byte[])data)[index] & 0xff;
       
  1147         case TIFFTag.TIFF_SBYTE:
       
  1148             return ((byte[])data)[index];
       
  1149         case TIFFTag.TIFF_SHORT:
       
  1150             return ((char[])data)[index] & 0xffff;
       
  1151         case TIFFTag.TIFF_SSHORT:
       
  1152             return ((short[])data)[index];
       
  1153         case TIFFTag.TIFF_SLONG:
       
  1154             return ((int[])data)[index];
       
  1155         case TIFFTag.TIFF_LONG:
       
  1156         case TIFFTag.TIFF_IFD_POINTER:
       
  1157             return ((long[])data)[index];
       
  1158         case TIFFTag.TIFF_FLOAT:
       
  1159             return ((float[])data)[index];
       
  1160         case TIFFTag.TIFF_DOUBLE:
       
  1161             return (float)((double[])data)[index];
       
  1162         case TIFFTag.TIFF_SRATIONAL:
       
  1163             int[] ivalue = getAsSRational(index);
       
  1164             return (float)((double)ivalue[0]/ivalue[1]);
       
  1165         case TIFFTag.TIFF_RATIONAL:
       
  1166             long[] lvalue = getAsRational(index);
       
  1167             return (float)((double)lvalue[0]/lvalue[1]);
       
  1168         case TIFFTag.TIFF_ASCII:
       
  1169              String s = ((String[])data)[index];
       
  1170              return (float)Double.parseDouble(s);
       
  1171         default:
       
  1172             throw new ClassCastException(); // should never happen
       
  1173         }
       
  1174     }
       
  1175 
       
  1176     /**
       
  1177      * Returns data in any format as a <code>double</code>.
       
  1178      *
       
  1179      * <p> <code>TIFFTag.TIFF_BYTE</code> and <code>TIFF_UNDEFINED</code> data
       
  1180      * are treated as unsigned; that is, no sign extension will take
       
  1181      * place and the returned value will be in the range [0, 255].
       
  1182      * <code>TIFF_SBYTE</code> data will be returned in the range
       
  1183      * [-128, 127].
       
  1184      *
       
  1185      * <p> Data in <code>TIFF_SRATIONAL</code> or
       
  1186      * <code>TIFF_RATIONAL</code> format are evaluated by dividing the
       
  1187      * numerator into the denominator using double-precision
       
  1188      * arithmetic.
       
  1189      *
       
  1190      * <p> Data in <code>TIFF_ASCII</code> format will be parsed as by
       
  1191      * the <code>Double.parseDouble</code> method.
       
  1192      *
       
  1193      * @param index The index of the data.
       
  1194      * @return The data at the given index as a {@code double}.
       
  1195      */
       
  1196     public double getAsDouble(int index) {
       
  1197         switch (type) {
       
  1198         case TIFFTag.TIFF_BYTE:
       
  1199         case TIFFTag.TIFF_UNDEFINED:
       
  1200             return ((byte[])data)[index] & 0xff;
       
  1201         case TIFFTag.TIFF_SBYTE:
       
  1202             return ((byte[])data)[index];
       
  1203         case TIFFTag.TIFF_SHORT:
       
  1204             return ((char[])data)[index] & 0xffff;
       
  1205         case TIFFTag.TIFF_SSHORT:
       
  1206             return ((short[])data)[index];
       
  1207         case TIFFTag.TIFF_SLONG:
       
  1208             return ((int[])data)[index];
       
  1209         case TIFFTag.TIFF_LONG:
       
  1210         case TIFFTag.TIFF_IFD_POINTER:
       
  1211             return ((long[])data)[index];
       
  1212         case TIFFTag.TIFF_FLOAT:
       
  1213             return ((float[])data)[index];
       
  1214         case TIFFTag.TIFF_DOUBLE:
       
  1215             return ((double[])data)[index];
       
  1216         case TIFFTag.TIFF_SRATIONAL:
       
  1217             int[] ivalue = getAsSRational(index);
       
  1218             return (double)ivalue[0]/ivalue[1];
       
  1219         case TIFFTag.TIFF_RATIONAL:
       
  1220             long[] lvalue = getAsRational(index);
       
  1221             return (double)lvalue[0]/lvalue[1];
       
  1222         case TIFFTag.TIFF_ASCII:
       
  1223              String s = ((String[])data)[index];
       
  1224              return Double.parseDouble(s);
       
  1225         default:
       
  1226             throw new ClassCastException(); // should never happen
       
  1227         }
       
  1228     }
       
  1229 
       
  1230     /**
       
  1231      * Returns a <code>TIFFTag.TIFF_ASCII</code> value as a
       
  1232      * <code>String</code>.
       
  1233      *
       
  1234      * @throws ClassCastException if the field is not of type
       
  1235      * <code>TIFF_ASCII</code>.
       
  1236      *
       
  1237      * @param index The index of the data.
       
  1238      * @return The data at the given index as a {@code String}.
       
  1239      */
       
  1240     public String getAsString(int index) {
       
  1241         return ((String[])data)[index];
       
  1242     }
       
  1243 
       
  1244     /**
       
  1245      * Returns a <code>TIFFTag.TIFF_SRATIONAL</code> data item as a
       
  1246      * two-element array of <code>int</code>s.
       
  1247      *
       
  1248      * @param index The index of the data.
       
  1249      * @return The data at the given index as a signed rational.
       
  1250      * @throws ClassCastException if the field is not of type
       
  1251      * <code>TIFF_SRATIONAL</code>.
       
  1252      */
       
  1253     public int[] getAsSRational(int index) {
       
  1254         return ((int[][])data)[index];
       
  1255     }
       
  1256 
       
  1257     /**
       
  1258      * Returns a TIFFTag.TIFF_RATIONAL data item as a two-element array
       
  1259      * of ints.
       
  1260      *
       
  1261      * @param index The index of the data.
       
  1262      * @return The data at the given index as an unsigned rational.
       
  1263      * @throws ClassCastException if the field is not of type
       
  1264      * <code>TIFF_RATIONAL</code>.
       
  1265      */
       
  1266     public long[] getAsRational(int index) {
       
  1267         return ((long[][])data)[index];
       
  1268     }
       
  1269 
       
  1270 
       
  1271     /**
       
  1272      * Returns a <code>String</code> containing a human-readable
       
  1273      * version of the data item.  Data of type
       
  1274      * <code>TIFFTag.TIFF_RATIONAL</code> or <code>TIFF_SRATIONAL</code> are
       
  1275      * represented as a pair of integers separated by a
       
  1276      * <code>'/'</code> character.
       
  1277      *
       
  1278      * @param index The index of the data.
       
  1279      * @return The data at the given index as a {@code String}.
       
  1280      * @throws ClassCastException if the field is not of one of the
       
  1281      * legal field types.
       
  1282      */
       
  1283     public String getValueAsString(int index) {
       
  1284         switch (type) {
       
  1285         case TIFFTag.TIFF_ASCII:
       
  1286             return ((String[])data)[index];
       
  1287         case TIFFTag.TIFF_BYTE:
       
  1288         case TIFFTag.TIFF_UNDEFINED:
       
  1289             return Integer.toString(((byte[])data)[index] & 0xff);
       
  1290         case TIFFTag.TIFF_SBYTE:
       
  1291             return Integer.toString(((byte[])data)[index]);
       
  1292         case TIFFTag.TIFF_SHORT:
       
  1293             return Integer.toString(((char[])data)[index] & 0xffff);
       
  1294         case TIFFTag.TIFF_SSHORT:
       
  1295             return Integer.toString(((short[])data)[index]);
       
  1296         case TIFFTag.TIFF_SLONG:
       
  1297             return Integer.toString(((int[])data)[index]);
       
  1298         case TIFFTag.TIFF_LONG:
       
  1299         case TIFFTag.TIFF_IFD_POINTER:
       
  1300             return Long.toString(((long[])data)[index]);
       
  1301         case TIFFTag.TIFF_FLOAT:
       
  1302             return Float.toString(((float[])data)[index]);
       
  1303         case TIFFTag.TIFF_DOUBLE:
       
  1304             return Double.toString(((double[])data)[index]);
       
  1305         case TIFFTag.TIFF_SRATIONAL:
       
  1306             int[] ivalue = getAsSRational(index);
       
  1307             String srationalString;
       
  1308             if(ivalue[1] != 0 && ivalue[0] % ivalue[1] == 0) {
       
  1309                 // If the denominator is a non-zero integral divisor
       
  1310                 // of the numerator then convert the fraction to be
       
  1311                 // with respect to a unity denominator.
       
  1312                 srationalString =
       
  1313                     Integer.toString(ivalue[0] / ivalue[1]) + "/1";
       
  1314             } else {
       
  1315                 // Use the values directly.
       
  1316                 srationalString =
       
  1317                     Integer.toString(ivalue[0]) +
       
  1318                     "/" +
       
  1319                     Integer.toString(ivalue[1]);
       
  1320             }
       
  1321             return srationalString;
       
  1322         case TIFFTag.TIFF_RATIONAL:
       
  1323             long[] lvalue = getAsRational(index);
       
  1324             String rationalString;
       
  1325             if(lvalue[1] != 0L && lvalue[0] % lvalue[1] == 0) {
       
  1326                 // If the denominator is a non-zero integral divisor
       
  1327                 // of the numerator then convert the fraction to be
       
  1328                 // with respect to a unity denominator.
       
  1329                 rationalString =
       
  1330                     Long.toString(lvalue[0] / lvalue[1]) + "/1";
       
  1331             } else {
       
  1332                 // Use the values directly.
       
  1333                 rationalString =
       
  1334                     Long.toString(lvalue[0]) +
       
  1335                     "/" +
       
  1336                     Long.toString(lvalue[1]);
       
  1337             }
       
  1338             return rationalString;
       
  1339         default:
       
  1340             throw new ClassCastException(); // should never happen
       
  1341         }
       
  1342     }
       
  1343 
       
  1344     /**
       
  1345      * Returns whether the field has a <code>TIFFDirectory</code>.
       
  1346      *
       
  1347      * @return true if and only if getDirectory() returns non-null.
       
  1348      */
       
  1349     public boolean hasDirectory() {
       
  1350         return getDirectory() != null;
       
  1351     }
       
  1352 
       
  1353     /**
       
  1354      * Returns the associated <code>TIFFDirectory</code>, if available. If no
       
  1355      * directory is set, then <code>null</code> will be returned.
       
  1356      *
       
  1357      * @return the TIFFDirectory instance or null.
       
  1358      */
       
  1359     public TIFFDirectory getDirectory() {
       
  1360         return dir;
       
  1361     }
       
  1362 
       
  1363     /**
       
  1364      * Clones the field and all the information contained therein.
       
  1365      *
       
  1366      * @return A clone of this <code>TIFFField</code>.
       
  1367      * @throws CloneNotSupportedException if the instance cannot be cloned.
       
  1368      */
       
  1369     @Override
       
  1370     public TIFFField clone() throws CloneNotSupportedException {
       
  1371         TIFFField field = (TIFFField)super.clone();
       
  1372 
       
  1373         Object fieldData;
       
  1374         switch (type) {
       
  1375         case TIFFTag.TIFF_BYTE:
       
  1376         case TIFFTag.TIFF_UNDEFINED:
       
  1377         case TIFFTag.TIFF_SBYTE:
       
  1378             fieldData = ((byte[])data).clone();
       
  1379             break;
       
  1380         case TIFFTag.TIFF_SHORT:
       
  1381             fieldData = ((char[])data).clone();
       
  1382             break;
       
  1383         case TIFFTag.TIFF_SSHORT:
       
  1384             fieldData = ((short[])data).clone();
       
  1385             break;
       
  1386         case TIFFTag.TIFF_SLONG:
       
  1387             fieldData = ((int[])data).clone();
       
  1388             break;
       
  1389         case TIFFTag.TIFF_LONG:
       
  1390         case TIFFTag.TIFF_IFD_POINTER:
       
  1391             fieldData = ((long[])data).clone();
       
  1392             break;
       
  1393         case TIFFTag.TIFF_FLOAT:
       
  1394             fieldData = ((float[])data).clone();
       
  1395             break;
       
  1396         case TIFFTag.TIFF_DOUBLE:
       
  1397             fieldData = ((double[])data).clone();
       
  1398             break;
       
  1399         case TIFFTag.TIFF_SRATIONAL:
       
  1400             fieldData = ((int[][])data).clone();
       
  1401             break;
       
  1402         case TIFFTag.TIFF_RATIONAL:
       
  1403             fieldData = ((long[][])data).clone();
       
  1404             break;
       
  1405         case TIFFTag.TIFF_ASCII:
       
  1406             fieldData = ((String[])data).clone();
       
  1407             break;
       
  1408         default:
       
  1409             throw new ClassCastException(); // should never happen
       
  1410         }
       
  1411 
       
  1412         field.tag = tag;
       
  1413         field.tagNumber = tagNumber;
       
  1414         field.type = type;
       
  1415         field.count = count;
       
  1416         field.data = fieldData;
       
  1417         field.dir = dir != null ? dir.clone() : null;
       
  1418 
       
  1419         return field;
       
  1420     }
       
  1421 }