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