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 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 }