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