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