1 /*
2 * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package javax.imageio.plugins.tiff;
26
27 import java.util.StringTokenizer;
28 import org.w3c.dom.NamedNodeMap;
29 import org.w3c.dom.Node;
30 import com.sun.imageio.plugins.tiff.TIFFFieldNode;
31 import com.sun.imageio.plugins.tiff.TIFFIFD;
32
33 /**
34 * A class representing a field in a TIFF 6.0 Image File Directory.
35 *
36 * <p> A field in a TIFF Image File Directory (IFD) is defined as a
37 * tag number accompanied by a sequence of values of identical data type.
38 * TIFF 6.0 defines 12 data types; a 13th type {@code IFD} is
39 * defined in TIFF Tech Note 1 of TIFF Specification Supplement 1. These
40 * TIFF data types are referred to by Java constants and mapped internally
41 * onto Java language data types and type names as follows:
42 *
43 * <br>
44 * <br>
45 * <table border="1">
46 * <caption>TIFF Data Type to Java Data Type Mapping</caption>
47 *
48 * <tr>
49 * <th>
50 * <b>TIFF Data Type</b>
51 * </th>
52 * <th>
53 * <b>Java Constant</b>
54 * </th>
55 * <th>
56 * <b>Java Data Type</b>
57 * </th>
58 * <th>
59 * <b>Java Type Name</b>
60 * </th>
61 * </tr>
62 *
63 * <tr>
64 * <td>
65 * <tt>BYTE</tt>
66 * </td>
67 * <td>
68 * {@link TIFFTag#TIFF_BYTE}
69 * </td>
70 * <td>
71 * {@code byte}
72 * </td>
73 * <td>
74 * {@code "Byte"}
75 * </td>
76 * </tr>
77 *
78 * <tr>
79 * <td>
80 * <tt>ASCII</tt>
81 * </td>
82 * <td>
83 * {@link TIFFTag#TIFF_ASCII}
84 * </td>
85 * <td>
86 * {@code String}
87 * </td>
88 * <td>
89 * {@code "Ascii"}
90 * </td>
91 * </tr>
92 *
93 * <tr>
94 * <td>
95 * <tt>SHORT</tt>
96 * </td>
97 * <td>
98 * {@link TIFFTag#TIFF_SHORT}
99 * </td>
100 * <td>
101 * {@code char}
102 * </td>
103 * <td>
104 * {@code "Short"}
105 * </td>
106 * </tr>
107 *
108 * <tr>
109 * <td>
110 * <tt>LONG</tt>
111 * </td>
112 * <td>
113 * {@link TIFFTag#TIFF_LONG}
114 * </td>
115 * <td>
116 * {@code long}
117 * </td>
118 * <td>
119 * {@code "Long"}
120 * </td>
121 * </tr>
122 *
123 * <tr>
124 * <td>
125 * <tt>RATIONAL</tt>
126 * </td>
127 * <td>
128 * {@link TIFFTag#TIFF_RATIONAL}
129 * </td>
130 * <td>
131 * {@code long[2]} {numerator, denominator}
132 * </td>
133 * <td>
134 * {@code "Rational"}
135 * </td>
136 * </tr>
137 *
138 * <tr>
139 * <td>
140 * <tt>SBYTE</tt>
141 * </td>
142 * <td>
143 * {@link TIFFTag#TIFF_SBYTE}
144 * </td>
145 * <td>
146 * {@code byte}
147 * </td>
148 * <td>
149 * {@code "SByte"}
150 * </td>
151 * </tr>
152 *
153 * <tr>
154 * <td>
155 * <tt>UNDEFINED</tt>
156 * </td>
157 * <td>
158 * {@link TIFFTag#TIFF_UNDEFINED}
159 * </td>
160 * <td>
161 * {@code byte}
162 * </td>
163 * <td>
164 * {@code "Undefined"}
165 * </td>
166 * </tr>
167 *
168 * <tr>
169 * <td>
170 * <tt>SSHORT</tt>
171 * </td>
172 * <td>
173 * {@link TIFFTag#TIFF_SSHORT}
174 * </td>
175 * <td>
176 * {@code short}
177 * </td>
178 * <td>
179 * {@code "SShort"}
180 * </td>
181 * </tr>
182 *
183 * <tr>
184 * <td>
185 * <tt>SLONG</tt>
186 * </td>
187 * <td>
188 * {@link TIFFTag#TIFF_SLONG}
189 * </td>
190 * <td>
191 * {@code int}
192 * </td>
193 * <td>
194 * {@code "SLong"}
195 * </td>
196 * </tr>
197 *
198 * <tr>
199 * <td>
200 * <tt>SRATIONAL</tt>
201 * </td>
202 * <td>
203 * {@link TIFFTag#TIFF_SRATIONAL}
204 * </td>
205 * <td>
206 * {@code int[2]} {numerator, denominator}
207 * </td>
208 * <td>
209 * {@code "SRational"}
210 * </td>
211 * </tr>
212 *
213 * <tr>
214 * <td>
215 * <tt>FLOAT</tt>
216 * </td>
217 * <td>
218 * {@link TIFFTag#TIFF_FLOAT}
219 * </td>
220 * <td>
221 * {@code float}
222 * </td>
223 * <td>
224 * {@code "Float"}
225 * </td>
226 * </tr>
227 *
228 * <tr>
229 * <td>
230 * <tt>DOUBLE</tt>
231 * </td>
232 * <td>
233 * {@link TIFFTag#TIFF_DOUBLE}
234 * </td>
235 * <td>
236 * {@code double}
237 * </td>
238 * <td>
239 * {@code "Double"}
240 * </td>
241 * </tr>
242 *
243 * <tr>
244 * <td>
245 * <tt>IFD</tt>
246 * </td>
247 * <td>
248 * {@link TIFFTag#TIFF_IFD_POINTER}
249 * </td>
250 * <td>
251 * {@code long}
252 * </td>
253 * <td>
254 * {@code "IFDPointer"}
255 * </td>
256 * </tr>
257 *
258 * </table>
259 *
260 * @since 9
261 * @see TIFFDirectory
262 * @see TIFFTag
263 */
264 public 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>"tagNumber"</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 * @return A new {@code TIFFField}.
428 */
429 public static TIFFField createFromMetadataNode(TIFFTagSet tagSet,
430 Node node) {
431 if (node == null) {
432 throw new NullPointerException("node == null!");
433 }
434 String name = node.getNodeName();
435 if (!name.equals("TIFFField")) {
436 throw new IllegalArgumentException("!name.equals(\"TIFFField\")");
437 }
438
439 int tagNumber = Integer.parseInt(getAttribute(node, "number"));
440 TIFFTag tag = null;
441 if (tagSet != null) {
442 tag = tagSet.getTag(tagNumber);
443 }
444
445 int type = TIFFTag.TIFF_UNDEFINED;
446 int count = 0;
447 Object data = null;
448
449 Node child = node.getFirstChild();
450 if (child != null) {
451 String typeName = child.getNodeName();
452 if (typeName.equals("TIFFUndefined")) {
453 String values = getAttribute(child, "value");
454 StringTokenizer st = new StringTokenizer(values, ",");
455 count = st.countTokens();
456
457 byte[] bdata = new byte[count];
458 for (int i = 0; i < count; i++) {
459 bdata[i] = (byte)Integer.parseInt(st.nextToken());
460 }
461
462 type = TIFFTag.TIFF_UNDEFINED;
463 data = bdata;
464 } else {
465 int[] otype = new int[1];
466 int[] ocount = new int[1];
467 Object[] odata = new Object[1];
468
469 initData(node.getFirstChild(), otype, ocount, odata);
470 type = otype[0];
471 count = ocount[0];
472 data = odata[0];
473 }
474 } else if (tag != null) {
475 int t = TIFFTag.MAX_DATATYPE;
476 while(t >= TIFFTag.MIN_DATATYPE && !tag.isDataTypeOK(t)) {
477 t--;
478 }
479 type = t;
480 }
481
482 if (tag == null) {
483 tag = new TIFFTag(TIFFTag.UNKNOWN_TAG_NAME, tagNumber, 1 << type);
484 }
485
486 return new TIFFField(tag, type, count, data);
487 }
488
489 /**
490 * Constructs a {@code TIFFField} with arbitrary data. The
491 * {@code type} parameter must be a value for which
492 * {@link TIFFTag#isDataTypeOK tag.isDataTypeOK()}
493 * returns {@code true}. The {@code data} parameter must
494 * be an array of a Java type appropriate for the type of the TIFF
495 * field.
496 *
497 * <p>Note that the value (data) of the {@code TIFFField}
498 * will always be the actual field value regardless of the number of
499 * bytes required for that value. This is the case despite the fact
500 * that the TIFF <i>IFD Entry</i> corresponding to the field may
501 * actually contain the offset to the value of the field rather than
502 * the value itself (the latter occurring if and only if the
503 * value fits into 4 bytes). In other words, the value of the
504 * field will already have been read from the TIFF stream. (An exception
505 * to this case may occur when the field represents the contents of a
506 * non-baseline IFD. In that case the data will be a {@code long[]}
507 * containing the offset to the IFD and the {@code TIFFDirectory}
508 * returned by {@link #getDirectory()} will be its contents.)
509 *
510 * @param tag The tag to associated with this field.
511 * @param type One of the {@code TIFFTag.TIFF_*} constants
512 * indicating the data type of the field as written to the TIFF stream.
513 * @param count The number of data values.
514 * @param data The actual data content of the field.
515 *
516 * @throws NullPointerException if {@code tag == null}.
517 * @throws IllegalArgumentException if {@code type} is not
518 * one of the {@code TIFFTag.TIFF_*} data type constants.
519 * @throws IllegalArgumentException if {@code type} is an unacceptable
520 * data type for the supplied {@code TIFFTag}.
521 * @throws IllegalArgumentException if {@code count < 0}.
522 * @throws IllegalArgumentException if {@code count < 1}
523 * and {@code type} is {@code TIFF_RATIONAL} or
524 * {@code TIFF_SRATIONAL}.
525 * @throws IllegalArgumentException if {@code count ≠ 1}
526 * and {@code type} is {@code TIFF_IFD_POINTER}.
527 * @throws NullPointerException if {@code data == null}.
528 * @throws IllegalArgumentException if {@code data} is an instance of
529 * a class incompatible with the specified type.
530 * @throws IllegalArgumentException if the size of the data array is wrong.
531 */
532 public TIFFField(TIFFTag tag, int type, int count, Object data) {
533 if(tag == null) {
534 throw new NullPointerException("tag == null!");
535 } else if(type < TIFFTag.MIN_DATATYPE || type > TIFFTag.MAX_DATATYPE) {
536 throw new IllegalArgumentException("Unknown data type "+type);
537 } else if(!tag.isDataTypeOK(type)) {
538 throw new IllegalArgumentException("Illegal data type " + type
539 + " for " + tag.getName() + " tag");
540 } else if(count < 0) {
541 throw new IllegalArgumentException("count < 0!");
542 } else if((type == TIFFTag.TIFF_RATIONAL
543 || type == TIFFTag.TIFF_SRATIONAL)
544 && count < 1) {
545 throw new IllegalArgumentException
546 ("Type is TIFF_RATIONAL or TIFF_SRATIONAL and count < 1");
547 } else if (type == TIFFTag.TIFF_IFD_POINTER && count != 1) {
548 throw new IllegalArgumentException
549 ("Type is TIFF_IFD_POINTER count != 1");
550 } else if(data == null) {
551 throw new NullPointerException("data == null!");
552 }
553
554 boolean isDataArrayCorrect = false;
555
556 switch (type) {
557 case TIFFTag.TIFF_BYTE:
558 case TIFFTag.TIFF_SBYTE:
559 case TIFFTag.TIFF_UNDEFINED:
560 isDataArrayCorrect = data instanceof byte[]
561 && ((byte[])data).length == count;
562 break;
563 case TIFFTag.TIFF_ASCII:
564 isDataArrayCorrect = data instanceof String[]
565 && ((String[])data).length == count;
566 break;
567 case TIFFTag.TIFF_SHORT:
568 isDataArrayCorrect = data instanceof char[]
569 && ((char[])data).length == count;
570 break;
571 case TIFFTag.TIFF_LONG:
572 isDataArrayCorrect = data instanceof long[]
573 && ((long[])data).length == count;
574 break;
575 case TIFFTag.TIFF_IFD_POINTER:
576 isDataArrayCorrect = data instanceof long[]
577 && ((long[])data).length == 1;
578 break;
579 case TIFFTag.TIFF_RATIONAL:
580 isDataArrayCorrect = data instanceof long[][]
581 && ((long[][])data).length == count
582 && ((long[][])data)[0].length == 2;
583 break;
584 case TIFFTag.TIFF_SSHORT:
585 isDataArrayCorrect = data instanceof short[]
586 && ((short[])data).length == count;
587 break;
588 case TIFFTag.TIFF_SLONG:
589 isDataArrayCorrect = data instanceof int[]
590 && ((int[])data).length == count;
591 break;
592 case TIFFTag.TIFF_SRATIONAL:
593 isDataArrayCorrect = data instanceof int[][]
594 && ((int[][])data).length == count
595 && ((int[][])data)[0].length == 2;
596 break;
597 case TIFFTag.TIFF_FLOAT:
598 isDataArrayCorrect = data instanceof float[]
599 && ((float[])data).length == count;
600 break;
601 case TIFFTag.TIFF_DOUBLE:
602 isDataArrayCorrect = data instanceof double[]
603 && ((double[])data).length == count;
604 break;
605 default:
606 throw new IllegalArgumentException("Unknown data type "+type);
607 }
608
609 if (!isDataArrayCorrect) {
610 throw new IllegalArgumentException
611 ("Illegal class or length for data array");
612 }
613
614 this.tag = tag;
615 this.tagNumber = tag.getNumber();
616 this.type = type;
617 this.count = count;
618 this.data = data;
619 }
620
621 /**
622 * Constructs a data array using {@link #createArrayForType
623 * createArrayForType()} and invokes
624 * {@link #TIFFField(TIFFTag,int,int,Object)} with the supplied
625 * parameters and the created array.
626 *
627 * @param tag The tag to associated with this field.
628 * @param type One of the {@code TIFFTag.TIFF_*} constants
629 * indicating the data type of the field as written to the TIFF stream.
630 * @param count The number of data values.
631 * @throws NullPointerException if {@code tag == null}.
632 * @throws IllegalArgumentException if {@code type} is not
633 * one of the {@code TIFFTag.TIFF_*} data type constants.
634 * @throws IllegalArgumentException if {@code type} is an unacceptable
635 * data type for the supplied {@code TIFFTag}.
636 * @throws IllegalArgumentException if {@code count < 0}.
637 * @see #TIFFField(TIFFTag,int,int,Object)
638 */
639 public TIFFField(TIFFTag tag, int type, int count) {
640 this(tag, type, count, createArrayForType(type, count));
641 }
642
643 /**
644 * Constructs a {@code TIFFField} with a single non-negative integral
645 * value.
646 * The field will have type
647 * {@link TIFFTag#TIFF_SHORT TIFF_SHORT} if
648 * {@code val < 65536} and type
649 * {@link TIFFTag#TIFF_LONG TIFF_LONG} otherwise. The count
650 * of the field will be unity.
651 *
652 * @param tag The tag to associate with this field.
653 * @param value The value to associate with this field.
654 * @throws NullPointerException if {@code tag == null}.
655 * @throws IllegalArgumentException if the derived type is unacceptable
656 * for the supplied {@code TIFFTag}.
657 * @throws IllegalArgumentException if {@code value < 0}.
658 */
659 public TIFFField(TIFFTag tag, int value) {
660 if(tag == null) {
661 throw new NullPointerException("tag == null!");
662 }
663 if (value < 0) {
664 throw new IllegalArgumentException("value < 0!");
665 }
666
667 this.tag = tag;
668 this.tagNumber = tag.getNumber();
669 this.count = 1;
670
671 if (value < 65536) {
672 if (!tag.isDataTypeOK(TIFFTag.TIFF_SHORT)) {
673 throw new IllegalArgumentException("Illegal data type "
674 + TIFFTag.TIFF_SHORT + " for " + tag.getName() + " tag");
675 }
676 this.type = TIFFTag.TIFF_SHORT;
677 char[] cdata = new char[1];
678 cdata[0] = (char)value;
679 this.data = cdata;
680 } else {
681 if (!tag.isDataTypeOK(TIFFTag.TIFF_LONG)) {
682 throw new IllegalArgumentException("Illegal data type "
683 + TIFFTag.TIFF_LONG + " for " + tag.getName() + " tag");
684 }
685 this.type = TIFFTag.TIFF_LONG;
686 long[] ldata = new long[1];
687 ldata[0] = value;
688 this.data = ldata;
689 }
690 }
691
692 /**
693 * Constructs a {@code TIFFField} with an IFD offset and contents.
694 * The offset will be stored as the data of this field as
695 * {@code long[] {offset}}. The directory will not be cloned. The count
696 * of the field will be unity.
697 *
698 * @param tag The tag to associated with this field.
699 * @param type One of the constants {@code TIFFTag.TIFF_LONG} or
700 * {@code TIFFTag.TIFF_IFD_POINTER}.
701 * @param offset The IFD offset.
702 * @param dir The directory.
703 *
704 * @throws NullPointerException if {@code tag == null}.
705 * @throws IllegalArgumentException if {@code type} is neither
706 * {@code TIFFTag.TIFF_LONG} nor {@code TIFFTag.TIFF_IFD_POINTER}.
707 * @throws IllegalArgumentException if {@code type} is an unacceptable
708 * data type for the supplied {@code TIFFTag}.
709 * @throws IllegalArgumentException if {@code offset} is non-positive.
710 * @throws NullPointerException if {@code dir == null}.
711 *
712 * @see #TIFFField(TIFFTag,int,int,Object)
713 */
714 public TIFFField(TIFFTag tag, int type, long offset, TIFFDirectory dir) {
715 this(tag, type, 1, new long[] {offset});
716 if (type != TIFFTag.TIFF_LONG && type != TIFFTag.TIFF_IFD_POINTER) {
717 throw new IllegalArgumentException("type " + type
718 + " is neither TIFFTag.TIFF_LONG nor TIFFTag.TIFF_IFD_POINTER");
719 } else if (offset <= 0) {
720 throw new IllegalArgumentException("offset " + offset
721 + " is non-positive");
722 } else if (dir == null) {
723 throw new NullPointerException("dir == null");
724 }
725 this.dir = dir;
726 }
727
728 /**
729 * Retrieves the tag associated with this field.
730 *
731 * @return The associated {@code TIFFTag}.
732 */
733 public TIFFTag getTag() {
734 return tag;
735 }
736
737 /**
738 * Retrieves the tag number in the range {@code [0, 65535]}.
739 *
740 * @return The tag number.
741 */
742 public int getTagNumber() {
743 return tagNumber;
744 }
745
746 /**
747 * Returns the type of the data stored in the field. For a TIFF 6.0
748 * stream, the value will equal one of the {@code TIFFTag.TIFF_*}
749 * constants. For future revisions of TIFF, higher values are possible.
750 *
751 * @return The data type of the field value.
752 */
753 public int getType() {
754 return type;
755 }
756
757 /**
758 * Returns the name of the supplied data type constant.
759 *
760 * @param dataType One of the {@code TIFFTag.TIFF_*} constants
761 * indicating the data type of the field as written to the TIFF stream.
762 * @return The type name corresponding to the supplied type constant.
763 * @throws IllegalArgumentException if {@code dataType} is not
764 * one of the {@code TIFFTag.TIFF_*} data type constants.
765 */
766 public static String getTypeName(int dataType) {
767 if (dataType < TIFFTag.MIN_DATATYPE ||
768 dataType > TIFFTag.MAX_DATATYPE) {
769 throw new IllegalArgumentException("Unknown data type "+dataType);
770 }
771
772 return typeNames[dataType];
773 }
774
775 /**
776 * Returns the data type constant corresponding to the supplied data
777 * type name. If the name is unknown {@code -1} will be returned.
778 *
779 * @param typeName The type name.
780 * @return One of the {@code TIFFTag.TIFF_*} constants or
781 * {@code -1} if the name is not recognized.
782 */
783 public static int getTypeByName(String typeName) {
784 for (int i = TIFFTag.MIN_DATATYPE; i <= TIFFTag.MAX_DATATYPE; i++) {
785 if (typeName.equals(typeNames[i])) {
786 return i;
787 }
788 }
789
790 return -1;
791 }
792
793 /**
794 * Creates an array appropriate for the indicated data type.
795 *
796 * @param dataType One of the {@code TIFFTag.TIFF_*} data type
797 * constants.
798 * @param count The number of values in the array.
799 * @return An array appropriate for the specified data type.
800 *
801 * @throws IllegalArgumentException if {@code dataType} is not
802 * one of the {@code TIFFTag.TIFF_*} data type constants.
803 * @throws IllegalArgumentException if {@code count < 0}.
804 */
805 public static Object createArrayForType(int dataType, int count) {
806 if(count < 0) {
807 throw new IllegalArgumentException("count < 0!");
808 }
809 switch (dataType) {
810 case TIFFTag.TIFF_BYTE:
811 case TIFFTag.TIFF_SBYTE:
812 case TIFFTag.TIFF_UNDEFINED:
813 return new byte[count];
814 case TIFFTag.TIFF_ASCII:
815 return new String[count];
816 case TIFFTag.TIFF_SHORT:
817 return new char[count];
818 case TIFFTag.TIFF_LONG:
819 case TIFFTag.TIFF_IFD_POINTER:
820 return new long[count];
821 case TIFFTag.TIFF_RATIONAL:
822 return new long[count][2];
823 case TIFFTag.TIFF_SSHORT:
824 return new short[count];
825 case TIFFTag.TIFF_SLONG:
826 return new int[count];
827 case TIFFTag.TIFF_SRATIONAL:
828 return new int[count][2];
829 case TIFFTag.TIFF_FLOAT:
830 return new float[count];
831 case TIFFTag.TIFF_DOUBLE:
832 return new double[count];
833 default:
834 throw new IllegalArgumentException("Unknown data type "+dataType);
835 }
836 }
837
838 /**
839 * Returns the {@code TIFFField} as a node named either
840 * <tt>"TIFFField"</tt> or <tt>"TIFFIFD"</tt> as described in the
841 * TIFF native image metadata specification. The node will be named
842 * <tt>"TIFFIFD"</tt> if and only if the field's data object is an
843 * instance of {@link TIFFDirectory} or equivalently
844 * {@link TIFFTag#isIFDPointer getTag.isIFDPointer()} returns
845 * {@code true}.
846 *
847 * @return a {@code Node} named <tt>"TIFFField"</tt> or
848 * <tt>"TIFFIFD"</tt>.
849 */
850 public Node getAsNativeNode() {
851 return new TIFFFieldNode(this);
852 }
853
854 /**
855 * Indicates whether the value associated with the field is of
856 * integral data type.
857 *
858 * @return Whether the field type is integral.
859 */
860 public boolean isIntegral() {
861 return isIntegral[type];
862 }
863
864 /**
865 * Returns the number of data items present in the field. For
866 * {@code TIFFTag.TIFF_ASCII} fields, the value returned is the
867 * number of {@code String}s, not the total length of the
868 * data as in the file representation.
869 *
870 * @return The number of data items present in the field.
871 */
872 public int getCount() {
873 return count;
874 }
875
876 /**
877 * Returns a reference to the data object associated with the field.
878 *
879 * @return The data object of the field.
880 */
881 public Object getData() {
882 return data;
883 }
884
885 /**
886 * Returns the data as an uninterpreted array of
887 * {@code byte}s. The type of the field must be one of
888 * {@code TIFFTag.TIFF_BYTE}, {@code TIFF_SBYTE}, or
889 * {@code TIFF_UNDEFINED}.
890 *
891 * <p> For data in {@code TIFFTag.TIFF_BYTE} format, the application
892 * must take care when promoting the data to longer integral types
893 * to avoid sign extension.
894 *
895 * @throws ClassCastException if the field is not of type
896 * {@code TIFF_BYTE}, {@code TIFF_SBYTE}, or
897 * {@code TIFF_UNDEFINED}.
898 * @return The data as an uninterpreted array of bytes.
899 */
900 public byte[] getAsBytes() {
901 return (byte[])data;
902 }
903
904 /**
905 * Returns {@code TIFFTag.TIFF_SHORT} data as an array of
906 * {@code char}s (unsigned 16-bit integers).
907 *
908 * @throws ClassCastException if the field is not of type
909 * {@code TIFF_SHORT}.
910 * @return The data as an array of {@code char}s.
911 */
912 public char[] getAsChars() {
913 return (char[])data;
914 }
915
916 /**
917 * Returns {@code TIFFTag.TIFF_SSHORT} data as an array of
918 * {@code short}s (signed 16-bit integers).
919 *
920 * @throws ClassCastException if the field is not of type
921 * {@code TIFF_SSHORT}.
922 * @return The data as an array of {@code short}s.
923 */
924 public short[] getAsShorts() {
925 return (short[])data;
926 }
927
928 /**
929 * Returns {@code TIFFTag.TIFF_SLONG} data as an array of
930 * {@code int}s (signed 32-bit integers).
931 *
932 * @throws ClassCastException if the field is not of type
933 * {@code TIFF_SHORT}, {@code TIFF_SSHORT}, or
934 * {@code TIFF_SLONG}.
935 * @return The data as an array of {@code int}s.
936 */
937 public int[] getAsInts() {
938 if (data instanceof int[]) {
939 return (int[])data;
940 } else if (data instanceof char[]){
941 char[] cdata = (char[])data;
942 int[] idata = new int[cdata.length];
943 for (int i = 0; i < cdata.length; i++) {
944 idata[i] = cdata[i] & 0xffff;
945 }
946 return idata;
947 } else if (data instanceof short[]){
948 short[] sdata = (short[])data;
949 int[] idata = new int[sdata.length];
950 for (int i = 0; i < sdata.length; i++) {
951 idata[i] = (int)sdata[i];
952 }
953 return idata;
954 } else {
955 throw new ClassCastException("Data not char[], short[], or int[]!");
956 }
957 }
958
959 /**
960 * Returns {@code TIFFTag.TIFF_LONG} or
961 * {@code TIFF_IFD_POINTER} data as an array of
962 * {@code long}s (signed 64-bit integers).
963 *
964 * @throws ClassCastException if the field is not of type
965 * {@code TIFF_LONG} or {@code TIFF_IFD_POINTER}.
966 * @return The data as an array of {@code long}s.
967 */
968 public long[] getAsLongs() {
969 return (long[])data;
970 }
971
972 /**
973 * Returns {@code TIFFTag.TIFF_FLOAT} data as an array of
974 * {@code float}s (32-bit floating-point values).
975 *
976 * @throws ClassCastException if the field is not of type
977 * {@code TIFF_FLOAT}.
978 * @return The data as an array of {@code float}s.
979 */
980 public float[] getAsFloats() {
981 return (float[])data;
982 }
983
984 /**
985 * Returns {@code TIFFTag.TIFF_DOUBLE} data as an array of
986 * {@code double}s (64-bit floating-point values).
987 *
988 * @throws ClassCastException if the field is not of type
989 * {@code TIFF_DOUBLE}.
990 * @return The data as an array of {@code double}s.
991 */
992 public double[] getAsDoubles() {
993 return (double[])data;
994 }
995
996 /**
997 * Returns {@code TIFFTag.TIFF_SRATIONAL} data as an array of
998 * 2-element arrays of {@code int}s.
999 *
1000 * @throws ClassCastException if the field is not of type
1001 * {@code TIFF_SRATIONAL}.
1002 * @return The data as an array of signed rationals.
1003 */
1004 public int[][] getAsSRationals() {
1005 return (int[][])data;
1006 }
1007
1008 /**
1009 * Returns {@code TIFFTag.TIFF_RATIONAL} data as an array of
1010 * 2-element arrays of {@code long}s.
1011 *
1012 * @throws ClassCastException if the field is not of type
1013 * {@code TIFF_RATIONAL}.
1014 * @return The data as an array of unsigned rationals.
1015 */
1016 public long[][] getAsRationals() {
1017 return (long[][])data;
1018 }
1019
1020 /**
1021 * Returns data in any format as an {@code int}.
1022 *
1023 * <p> {@code TIFFTag.TIFF_BYTE} values are treated as unsigned; that
1024 * is, no sign extension will take place and the returned value
1025 * will be in the range [0, 255]. {@code TIFF_SBYTE} data
1026 * will be returned in the range [-128, 127].
1027 *
1028 * <p> A {@code TIFF_UNDEFINED} value is treated as though
1029 * it were a {@code TIFF_BYTE}.
1030 *
1031 * <p> Data in {@code TIFF_SLONG}, {@code TIFF_LONG},
1032 * {@code TIFF_FLOAT}, {@code TIFF_DOUBLE} or
1033 * {@code TIFF_IFD_POINTER} format are simply cast to
1034 * {@code int} and may suffer from truncation.
1035 *
1036 * <p> Data in {@code TIFF_SRATIONAL} or
1037 * {@code TIFF_RATIONAL} format are evaluated by dividing the
1038 * numerator into the denominator using double-precision
1039 * arithmetic and then casting to {@code int}. Loss of
1040 * precision and truncation may occur.
1041 *
1042 * <p> Data in {@code TIFF_ASCII} format will be parsed as by
1043 * the {@code Double.parseDouble} method, with the result
1044 * case to {@code int}.
1045 *
1046 * @param index The index of the data.
1047 * @return The data at the given index as an {@code int}.
1048 */
1049 public int getAsInt(int index) {
1050 switch (type) {
1051 case TIFFTag.TIFF_BYTE:
1052 case TIFFTag.TIFF_UNDEFINED:
1053 return ((byte[])data)[index] & 0xff;
1054 case TIFFTag.TIFF_SBYTE:
1055 return ((byte[])data)[index];
1056 case TIFFTag.TIFF_SHORT:
1057 return ((char[])data)[index] & 0xffff;
1058 case TIFFTag.TIFF_SSHORT:
1059 return ((short[])data)[index];
1060 case TIFFTag.TIFF_SLONG:
1061 return ((int[])data)[index];
1062 case TIFFTag.TIFF_LONG:
1063 case TIFFTag.TIFF_IFD_POINTER:
1064 return (int)((long[])data)[index];
1065 case TIFFTag.TIFF_FLOAT:
1066 return (int)((float[])data)[index];
1067 case TIFFTag.TIFF_DOUBLE:
1068 return (int)((double[])data)[index];
1069 case TIFFTag.TIFF_SRATIONAL:
1070 int[] ivalue = getAsSRational(index);
1071 return (int)((double)ivalue[0]/ivalue[1]);
1072 case TIFFTag.TIFF_RATIONAL:
1073 long[] lvalue = getAsRational(index);
1074 return (int)((double)lvalue[0]/lvalue[1]);
1075 case TIFFTag.TIFF_ASCII:
1076 String s = ((String[])data)[index];
1077 return (int)Double.parseDouble(s);
1078 default:
1079 throw new ClassCastException(); // should never happen
1080 }
1081 }
1082
1083 /**
1084 * Returns data in any format as a {@code long}.
1085 *
1086 * <p> {@code TIFFTag.TIFF_BYTE} and {@code TIFF_UNDEFINED} data
1087 * are treated as unsigned; that is, no sign extension will take
1088 * place and the returned value will be in the range [0, 255].
1089 * {@code TIFF_SBYTE} data will be returned in the range
1090 * [-128, 127].
1091 *
1092 * <p> Data in {@code TIFF_ASCII} format will be parsed as by
1093 * the {@code Double.parseDouble} method, with the result
1094 * cast to {@code long}.
1095 *
1096 * @param index The index of the data.
1097 * @return The data at the given index as a {@code long}.
1098 */
1099 public long getAsLong(int index) {
1100 switch (type) {
1101 case TIFFTag.TIFF_BYTE:
1102 case TIFFTag.TIFF_UNDEFINED:
1103 return ((byte[])data)[index] & 0xff;
1104 case TIFFTag.TIFF_SBYTE:
1105 return ((byte[])data)[index];
1106 case TIFFTag.TIFF_SHORT:
1107 return ((char[])data)[index] & 0xffff;
1108 case TIFFTag.TIFF_SSHORT:
1109 return ((short[])data)[index];
1110 case TIFFTag.TIFF_SLONG:
1111 return ((int[])data)[index];
1112 case TIFFTag.TIFF_LONG:
1113 case TIFFTag.TIFF_IFD_POINTER:
1114 return ((long[])data)[index];
1115 case TIFFTag.TIFF_SRATIONAL:
1116 int[] ivalue = getAsSRational(index);
1117 return (long)((double)ivalue[0]/ivalue[1]);
1118 case TIFFTag.TIFF_RATIONAL:
1119 long[] lvalue = getAsRational(index);
1120 return (long)((double)lvalue[0]/lvalue[1]);
1121 case TIFFTag.TIFF_ASCII:
1122 String s = ((String[])data)[index];
1123 return (long)Double.parseDouble(s);
1124 default:
1125 throw new ClassCastException(); // should never happen
1126 }
1127 }
1128
1129 /**
1130 * Returns data in any format as a {@code float}.
1131 *
1132 * <p> {@code TIFFTag.TIFF_BYTE} and {@code TIFF_UNDEFINED} data
1133 * are treated as unsigned; that is, no sign extension will take
1134 * place and the returned value will be in the range [0, 255].
1135 * {@code TIFF_SBYTE} data will be returned in the range
1136 * [-128, 127].
1137 *
1138 * <p> Data in {@code TIFF_SLONG}, {@code TIFF_LONG},
1139 * {@code TIFF_DOUBLE}, or {@code TIFF_IFD_POINTER} format are
1140 * simply cast to {@code float} and may suffer from
1141 * truncation.
1142 *
1143 * <p> Data in {@code TIFF_SRATIONAL} or
1144 * {@code TIFF_RATIONAL} format are evaluated by dividing the
1145 * numerator into the denominator using double-precision
1146 * arithmetic and then casting to {@code float}.
1147 *
1148 * <p> Data in {@code TIFF_ASCII} format will be parsed as by
1149 * the {@code Double.parseDouble} method, with the result
1150 * cast to {@code float}.
1151 *
1152 * @param index The index of the data.
1153 * @return The data at the given index as a {@code float}.
1154 */
1155 public float getAsFloat(int index) {
1156 switch (type) {
1157 case TIFFTag.TIFF_BYTE:
1158 case TIFFTag.TIFF_UNDEFINED:
1159 return ((byte[])data)[index] & 0xff;
1160 case TIFFTag.TIFF_SBYTE:
1161 return ((byte[])data)[index];
1162 case TIFFTag.TIFF_SHORT:
1163 return ((char[])data)[index] & 0xffff;
1164 case TIFFTag.TIFF_SSHORT:
1165 return ((short[])data)[index];
1166 case TIFFTag.TIFF_SLONG:
1167 return ((int[])data)[index];
1168 case TIFFTag.TIFF_LONG:
1169 case TIFFTag.TIFF_IFD_POINTER:
1170 return ((long[])data)[index];
1171 case TIFFTag.TIFF_FLOAT:
1172 return ((float[])data)[index];
1173 case TIFFTag.TIFF_DOUBLE:
1174 return (float)((double[])data)[index];
1175 case TIFFTag.TIFF_SRATIONAL:
1176 int[] ivalue = getAsSRational(index);
1177 return (float)((double)ivalue[0]/ivalue[1]);
1178 case TIFFTag.TIFF_RATIONAL:
1179 long[] lvalue = getAsRational(index);
1180 return (float)((double)lvalue[0]/lvalue[1]);
1181 case TIFFTag.TIFF_ASCII:
1182 String s = ((String[])data)[index];
1183 return (float)Double.parseDouble(s);
1184 default:
1185 throw new ClassCastException(); // should never happen
1186 }
1187 }
1188
1189 /**
1190 * Returns data in any format as a {@code double}.
1191 *
1192 * <p> {@code TIFFTag.TIFF_BYTE} and {@code TIFF_UNDEFINED} data
1193 * are treated as unsigned; that is, no sign extension will take
1194 * place and the returned value will be in the range [0, 255].
1195 * {@code TIFF_SBYTE} data will be returned in the range
1196 * [-128, 127].
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.
1202 *
1203 * <p> Data in {@code TIFF_ASCII} format will be parsed as by
1204 * the {@code Double.parseDouble} method.
1205 *
1206 * @param index The index of the data.
1207 * @return The data at the given index as a {@code double}.
1208 */
1209 public double getAsDouble(int index) {
1210 switch (type) {
1211 case TIFFTag.TIFF_BYTE:
1212 case TIFFTag.TIFF_UNDEFINED:
1213 return ((byte[])data)[index] & 0xff;
1214 case TIFFTag.TIFF_SBYTE:
1215 return ((byte[])data)[index];
1216 case TIFFTag.TIFF_SHORT:
1217 return ((char[])data)[index] & 0xffff;
1218 case TIFFTag.TIFF_SSHORT:
1219 return ((short[])data)[index];
1220 case TIFFTag.TIFF_SLONG:
1221 return ((int[])data)[index];
1222 case TIFFTag.TIFF_LONG:
1223 case TIFFTag.TIFF_IFD_POINTER:
1224 return ((long[])data)[index];
1225 case TIFFTag.TIFF_FLOAT:
1226 return ((float[])data)[index];
1227 case TIFFTag.TIFF_DOUBLE:
1228 return ((double[])data)[index];
1229 case TIFFTag.TIFF_SRATIONAL:
1230 int[] ivalue = getAsSRational(index);
1231 return (double)ivalue[0]/ivalue[1];
1232 case TIFFTag.TIFF_RATIONAL:
1233 long[] lvalue = getAsRational(index);
1234 return (double)lvalue[0]/lvalue[1];
1235 case TIFFTag.TIFF_ASCII:
1236 String s = ((String[])data)[index];
1237 return Double.parseDouble(s);
1238 default:
1239 throw new ClassCastException(); // should never happen
1240 }
1241 }
1242
1243 /**
1244 * Returns a {@code TIFFTag.TIFF_ASCII} value as a
1245 * {@code String}.
1246 *
1247 * @throws ClassCastException if the field is not of type
1248 * {@code TIFF_ASCII}.
1249 *
1250 * @param index The index of the data.
1251 * @return The data at the given index as a {@code String}.
1252 */
1253 public String getAsString(int index) {
1254 return ((String[])data)[index];
1255 }
1256
1257 /**
1258 * Returns a {@code TIFFTag.TIFF_SRATIONAL} data item as a
1259 * two-element array of {@code int}s.
1260 *
1261 * @param index The index of the data.
1262 * @return The data at the given index as a signed rational.
1263 * @throws ClassCastException if the field is not of type
1264 * {@code TIFF_SRATIONAL}.
1265 */
1266 public int[] getAsSRational(int index) {
1267 return ((int[][])data)[index];
1268 }
1269
1270 /**
1271 * Returns a TIFFTag.TIFF_RATIONAL data item as a two-element array
1272 * of ints.
1273 *
1274 * @param index The index of the data.
1275 * @return The data at the given index as an unsigned rational.
1276 * @throws ClassCastException if the field is not of type
1277 * {@code TIFF_RATIONAL}.
1278 */
1279 public long[] getAsRational(int index) {
1280 return ((long[][])data)[index];
1281 }
1282
1283
1284 /**
1285 * Returns a {@code String} containing a human-readable
1286 * version of the data item. Data of type
1287 * {@code TIFFTag.TIFF_RATIONAL} or {@code TIFF_SRATIONAL} are
1288 * represented as a pair of integers separated by a
1289 * {@code '/'} character.
1290 *
1291 * @param index The index of the data.
1292 * @return The data at the given index as a {@code String}.
1293 * @throws ClassCastException if the field is not of one of the
1294 * legal field types.
1295 */
1296 public String getValueAsString(int index) {
1297 switch (type) {
1298 case TIFFTag.TIFF_ASCII:
1299 return ((String[])data)[index];
1300 case TIFFTag.TIFF_BYTE:
1301 case TIFFTag.TIFF_UNDEFINED:
1302 return Integer.toString(((byte[])data)[index] & 0xff);
1303 case TIFFTag.TIFF_SBYTE:
1304 return Integer.toString(((byte[])data)[index]);
1305 case TIFFTag.TIFF_SHORT:
1306 return Integer.toString(((char[])data)[index] & 0xffff);
1307 case TIFFTag.TIFF_SSHORT:
1308 return Integer.toString(((short[])data)[index]);
1309 case TIFFTag.TIFF_SLONG:
1310 return Integer.toString(((int[])data)[index]);
1311 case TIFFTag.TIFF_LONG:
1312 case TIFFTag.TIFF_IFD_POINTER:
1313 return Long.toString(((long[])data)[index]);
1314 case TIFFTag.TIFF_FLOAT:
1315 return Float.toString(((float[])data)[index]);
1316 case TIFFTag.TIFF_DOUBLE:
1317 return Double.toString(((double[])data)[index]);
1318 case TIFFTag.TIFF_SRATIONAL:
1319 int[] ivalue = getAsSRational(index);
1320 String srationalString;
1321 if(ivalue[1] != 0 && ivalue[0] % ivalue[1] == 0) {
1322 // If the denominator is a non-zero integral divisor
1323 // of the numerator then convert the fraction to be
1324 // with respect to a unity denominator.
1325 srationalString =
1326 Integer.toString(ivalue[0] / ivalue[1]) + "/1";
1327 } else {
1328 // Use the values directly.
1329 srationalString =
1330 Integer.toString(ivalue[0]) +
1331 "/" +
1332 Integer.toString(ivalue[1]);
1333 }
1334 return srationalString;
1335 case TIFFTag.TIFF_RATIONAL:
1336 long[] lvalue = getAsRational(index);
1337 String rationalString;
1338 if(lvalue[1] != 0L && lvalue[0] % lvalue[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 rationalString =
1343 Long.toString(lvalue[0] / lvalue[1]) + "/1";
1344 } else {
1345 // Use the values directly.
1346 rationalString =
1347 Long.toString(lvalue[0]) +
1348 "/" +
1349 Long.toString(lvalue[1]);
1350 }
1351 return rationalString;
1352 default:
1353 throw new ClassCastException(); // should never happen
1354 }
1355 }
1356
1357 /**
1358 * Returns whether the field has a {@code TIFFDirectory}.
1359 *
1360 * @return true if and only if getDirectory() returns non-null.
1361 */
1362 public boolean hasDirectory() {
1363 return getDirectory() != null;
1364 }
1365
1366 /**
1367 * Returns the associated {@code TIFFDirectory}, if available. If no
1368 * directory is set, then {@code null} will be returned.
1369 *
1370 * @return the TIFFDirectory instance or null.
1371 */
1372 public TIFFDirectory getDirectory() {
1373 return dir;
1374 }
1375
1376 /**
1377 * Clones the field and all the information contained therein.
1378 *
1379 * @return A clone of this {@code TIFFField}.
1380 * @throws CloneNotSupportedException if the instance cannot be cloned.
1381 */
1382 @Override
1383 public TIFFField clone() throws CloneNotSupportedException {
1384 TIFFField field = (TIFFField)super.clone();
1385
1386 Object fieldData;
1387 switch (type) {
1388 case TIFFTag.TIFF_BYTE:
1389 case TIFFTag.TIFF_UNDEFINED:
1390 case TIFFTag.TIFF_SBYTE:
1391 fieldData = ((byte[])data).clone();
1392 break;
1393 case TIFFTag.TIFF_SHORT:
1394 fieldData = ((char[])data).clone();
1395 break;
1396 case TIFFTag.TIFF_SSHORT:
1397 fieldData = ((short[])data).clone();
1398 break;
1399 case TIFFTag.TIFF_SLONG:
1400 fieldData = ((int[])data).clone();
1401 break;
1402 case TIFFTag.TIFF_LONG:
1403 case TIFFTag.TIFF_IFD_POINTER:
1404 fieldData = ((long[])data).clone();
1405 break;
1406 case TIFFTag.TIFF_FLOAT:
1407 fieldData = ((float[])data).clone();
1408 break;
1409 case TIFFTag.TIFF_DOUBLE:
1410 fieldData = ((double[])data).clone();
1411 break;
1412 case TIFFTag.TIFF_SRATIONAL:
1413 fieldData = ((int[][])data).clone();
1414 break;
1415 case TIFFTag.TIFF_RATIONAL:
1416 fieldData = ((long[][])data).clone();
1417 break;
1418 case TIFFTag.TIFF_ASCII:
1419 fieldData = ((String[])data).clone();
1420 break;
1421 default:
1422 throw new ClassCastException(); // should never happen
1423 }
1424
1425 field.tag = tag;
1426 field.tagNumber = tagNumber;
1427 field.type = type;
1428 field.count = count;
1429 field.data = fieldData;
1430 field.dir = dir != null ? dir.clone() : null;
1431
1432 return field;
1433 }
1434 }
--- EOF ---