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