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