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 final 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;
527 * @param type One of the {@code TIFFTag.TIFF_*} constants
528 * indicating the data type of the field as written to the TIFF stream.
529 * @param count The number of data values.
530 * @param data The actual data content of the field.
531 *
532 * @throws NullPointerException if {@code tag == null}.
533 * @throws IllegalArgumentException if {@code type} is not
534 * one of the {@code TIFFTag.TIFF_*} data type constants.
535 * @throws IllegalArgumentException if {@code type} is an unacceptable
536 * data type for the supplied {@code TIFFTag}.
537 * @throws IllegalArgumentException if {@code count < 0}.
538 * @throws IllegalArgumentException if {@code count < 1}
539 * and {@code type} is {@code TIFF_RATIONAL} or
540 * {@code TIFF_SRATIONAL}.
541 * @throws IllegalArgumentException if {@code count != 1}
542 * and {@code type} is {@code TIFF_IFD_POINTER}.
543 * @throws NullPointerException if {@code data == null}.
544 * @throws IllegalArgumentException if {@code data} is an instance of
545 * a class incompatible with the specified type.
546 * @throws IllegalArgumentException if the size of the data array is wrong.
547 */
548 public TIFFField(TIFFTag tag, int type, int count, Object data) {
549 if(tag == null) {
550 throw new NullPointerException("tag == null!");
551 } else if(type < TIFFTag.MIN_DATATYPE || type > TIFFTag.MAX_DATATYPE) {
552 throw new IllegalArgumentException("Unknown data type "+type);
553 } else if(!tag.isDataTypeOK(type)) {
554 throw new IllegalArgumentException("Illegal data type " + type
555 + " for " + tag.getName() + " tag");
556 } else if(count < 0) {
557 throw new IllegalArgumentException("count < 0!");
558 } else if((type == TIFFTag.TIFF_RATIONAL
559 || type == TIFFTag.TIFF_SRATIONAL)
560 && count < 1) {
561 throw new IllegalArgumentException
562 ("Type is TIFF_RATIONAL or TIFF_SRATIONAL and count < 1");
563 } else if (type == TIFFTag.TIFF_IFD_POINTER && count != 1) {
564 throw new IllegalArgumentException
565 ("Type is TIFF_IFD_POINTER count != 1");
566 } else if(data == null) {
570 boolean isDataArrayCorrect = false;
571
572 switch (type) {
573 case TIFFTag.TIFF_BYTE:
574 case TIFFTag.TIFF_SBYTE:
575 case TIFFTag.TIFF_UNDEFINED:
576 isDataArrayCorrect = data instanceof byte[]
577 && ((byte[])data).length == count;
578 break;
579 case TIFFTag.TIFF_ASCII:
580 isDataArrayCorrect = data instanceof String[]
581 && ((String[])data).length == count;
582 break;
583 case TIFFTag.TIFF_SHORT:
584 isDataArrayCorrect = data instanceof char[]
585 && ((char[])data).length == count;
586 break;
587 case TIFFTag.TIFF_LONG:
588 isDataArrayCorrect = data instanceof long[]
589 && ((long[])data).length == count;
590 break;
591 case TIFFTag.TIFF_IFD_POINTER:
592 isDataArrayCorrect = data instanceof long[]
593 && ((long[])data).length == 1;
594 break;
595 case TIFFTag.TIFF_RATIONAL:
596 isDataArrayCorrect = data instanceof long[][]
597 && ((long[][])data).length == count
598 && ((long[][])data)[0].length == 2;
599 break;
600 case TIFFTag.TIFF_SSHORT:
601 isDataArrayCorrect = data instanceof short[]
602 && ((short[])data).length == count;
603 break;
604 case TIFFTag.TIFF_SLONG:
605 isDataArrayCorrect = data instanceof int[]
606 && ((int[])data).length == count;
607 break;
608 case TIFFTag.TIFF_SRATIONAL:
609 isDataArrayCorrect = data instanceof int[][]
610 && ((int[][])data).length == count
611 && ((int[][])data)[0].length == 2;
612 break;
613 case TIFFTag.TIFF_FLOAT:
614 isDataArrayCorrect = data instanceof float[]
615 && ((float[])data).length == count;
616 break;
617 case TIFFTag.TIFF_DOUBLE:
618 isDataArrayCorrect = data instanceof double[]
619 && ((double[])data).length == count;
620 break;
621 default:
622 throw new IllegalArgumentException("Unknown data type "+type);
623 }
624
625 if (!isDataArrayCorrect) {
626 throw new IllegalArgumentException
627 ("Illegal class or length for data array");
628 }
629
630 this.tag = tag;
631 this.tagNumber = tag.getNumber();
782 */
783 public int getType() {
784 return type;
785 }
786
787 /**
788 * Returns the name of the supplied data type constant.
789 *
790 * @param dataType One of the {@code TIFFTag.TIFF_*} constants
791 * indicating the data type of the field as written to the TIFF stream.
792 * @return The type name corresponding to the supplied type constant.
793 * @throws IllegalArgumentException if {@code dataType} is not
794 * one of the {@code TIFFTag.TIFF_*} data type constants.
795 */
796 public static String getTypeName(int dataType) {
797 if (dataType < TIFFTag.MIN_DATATYPE ||
798 dataType > TIFFTag.MAX_DATATYPE) {
799 throw new IllegalArgumentException("Unknown data type "+dataType);
800 }
801
802 return typeNames[dataType];
803 }
804
805 /**
806 * Returns the data type constant corresponding to the supplied data
807 * type name. If the name is unknown {@code -1} will be returned.
808 *
809 * @param typeName The type name.
810 * @return One of the {@code TIFFTag.TIFF_*} constants or
811 * {@code -1} if the name is not recognized.
812 */
813 public static int getTypeByName(String typeName) {
814 for (int i = TIFFTag.MIN_DATATYPE; i <= TIFFTag.MAX_DATATYPE; i++) {
815 if (typeName.equals(typeNames[i])) {
816 return i;
817 }
818 }
819
820 return -1;
821 }
822
823 /**
824 * Creates an array appropriate for the indicated data type.
825 *
826 * @param dataType One of the {@code TIFFTag.TIFF_*} data type
827 * constants.
828 * @param count The number of values in the array.
829 * @return An array appropriate for the specified data type.
830 *
831 * @throws IllegalArgumentException if {@code dataType} is not
832 * one of the {@code TIFFTag.TIFF_*} data type constants.
833 * @throws IllegalArgumentException if {@code count < 0}.
834 */
835 public static Object createArrayForType(int dataType, int count) {
870 * <tt>"TIFFField"</tt> or <tt>"TIFFIFD"</tt> as described in the
871 * TIFF native image metadata specification. The node will be named
872 * <tt>"TIFFIFD"</tt> if and only if {@link #hasDirectory()} returns
873 * {@code true} and the field's type is either {@link TIFFTag#TIFF_LONG}
874 * or {@link TIFFTag#TIFF_IFD_POINTER}.
875 *
876 * @return a {@code Node} named <tt>"TIFFField"</tt> or
877 * <tt>"TIFFIFD"</tt>.
878 */
879 public Node getAsNativeNode() {
880 return new TIFFFieldNode(this);
881 }
882
883 /**
884 * Indicates whether the value associated with the field is of
885 * integral data type.
886 *
887 * @return Whether the field type is integral.
888 */
889 public boolean isIntegral() {
890 return isIntegral[type];
891 }
892
893 /**
894 * Returns the number of data items present in the field. For
895 * {@code TIFFTag.TIFF_ASCII} fields, the value returned is the
896 * number of {@code String}s, not the total length of the
897 * data as in the file representation.
898 *
899 * @return The number of data items present in the field.
900 */
901 public int getCount() {
902 return count;
903 }
904
905 /**
906 * Returns a reference to the data object associated with the field.
907 *
908 * @return The data object of the field.
909 */
910 public Object getData() {
|
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 final class TIFFField implements Cloneable {
265
266 private static final long MAX_UINT32 = 0xffffffffL;
267
268 private static final String[] TYPE_NAMES = {
269 null,
270 "Byte", "Ascii", "Short", "Long", "Rational",
271 "SByte", "Undefined", "SShort", "SLong", "SRational",
272 "Float", "Double", "IFDPointer"
273 };
274
275 private static final boolean[] IS_INTEGRAL = {
276 false,
277 true, false, true, true, false,
278 true, true, true, true, false,
279 false, false, false
280 };
281
282 /** The tag. */
283 private TIFFTag tag;
284
285 /** The tag number. */
286 private int tagNumber;
287
288 /** The tag type. */
289 private int type;
290
291 /** The number of data items present in the field. */
292 private int count;
293
294 /** The field data. */
295 private Object data;
529 * @param type One of the {@code TIFFTag.TIFF_*} constants
530 * indicating the data type of the field as written to the TIFF stream.
531 * @param count The number of data values.
532 * @param data The actual data content of the field.
533 *
534 * @throws NullPointerException if {@code tag == null}.
535 * @throws IllegalArgumentException if {@code type} is not
536 * one of the {@code TIFFTag.TIFF_*} data type constants.
537 * @throws IllegalArgumentException if {@code type} is an unacceptable
538 * data type for the supplied {@code TIFFTag}.
539 * @throws IllegalArgumentException if {@code count < 0}.
540 * @throws IllegalArgumentException if {@code count < 1}
541 * and {@code type} is {@code TIFF_RATIONAL} or
542 * {@code TIFF_SRATIONAL}.
543 * @throws IllegalArgumentException if {@code count != 1}
544 * and {@code type} is {@code TIFF_IFD_POINTER}.
545 * @throws NullPointerException if {@code data == null}.
546 * @throws IllegalArgumentException if {@code data} is an instance of
547 * a class incompatible with the specified type.
548 * @throws IllegalArgumentException if the size of the data array is wrong.
549 * @throws IllegalArgumentException if the type of the data array is
550 * {@code TIFF_LONG}, {@code TIFF_RATIONAL}, or {@code TIFF_IFD_POINTER}
551 * and any of the elements is negative or greater than {@code 4294967295}.
552 */
553 public TIFFField(TIFFTag tag, int type, int count, Object data) {
554 if(tag == null) {
555 throw new NullPointerException("tag == null!");
556 } else if(type < TIFFTag.MIN_DATATYPE || type > TIFFTag.MAX_DATATYPE) {
557 throw new IllegalArgumentException("Unknown data type "+type);
558 } else if(!tag.isDataTypeOK(type)) {
559 throw new IllegalArgumentException("Illegal data type " + type
560 + " for " + tag.getName() + " tag");
561 } else if(count < 0) {
562 throw new IllegalArgumentException("count < 0!");
563 } else if((type == TIFFTag.TIFF_RATIONAL
564 || type == TIFFTag.TIFF_SRATIONAL)
565 && count < 1) {
566 throw new IllegalArgumentException
567 ("Type is TIFF_RATIONAL or TIFF_SRATIONAL and count < 1");
568 } else if (type == TIFFTag.TIFF_IFD_POINTER && count != 1) {
569 throw new IllegalArgumentException
570 ("Type is TIFF_IFD_POINTER count != 1");
571 } else if(data == null) {
575 boolean isDataArrayCorrect = false;
576
577 switch (type) {
578 case TIFFTag.TIFF_BYTE:
579 case TIFFTag.TIFF_SBYTE:
580 case TIFFTag.TIFF_UNDEFINED:
581 isDataArrayCorrect = data instanceof byte[]
582 && ((byte[])data).length == count;
583 break;
584 case TIFFTag.TIFF_ASCII:
585 isDataArrayCorrect = data instanceof String[]
586 && ((String[])data).length == count;
587 break;
588 case TIFFTag.TIFF_SHORT:
589 isDataArrayCorrect = data instanceof char[]
590 && ((char[])data).length == count;
591 break;
592 case TIFFTag.TIFF_LONG:
593 isDataArrayCorrect = data instanceof long[]
594 && ((long[])data).length == count;
595 if (isDataArrayCorrect) {
596 for (long datum : (long[])data) {
597 if (datum < 0) {
598 throw new IllegalArgumentException
599 ("Negative value supplied for TIFF_LONG");
600 }
601 if (datum > MAX_UINT32) {
602 throw new IllegalArgumentException
603 ("Too large value supplied for TIFF_LONG");
604 }
605 }
606 }
607 break;
608 case TIFFTag.TIFF_IFD_POINTER:
609 isDataArrayCorrect = data instanceof long[]
610 && ((long[])data).length == 1;
611 if (((long[])data)[0] < 0) {
612 throw new IllegalArgumentException
613 ("Negative value supplied for TIFF_IFD_POINTER");
614 }
615 if (((long[])data)[0] > MAX_UINT32) {
616 throw new IllegalArgumentException
617 ("Too large value supplied for TIFF_IFD_POINTER");
618 }
619 break;
620 case TIFFTag.TIFF_RATIONAL:
621 isDataArrayCorrect = data instanceof long[][]
622 && ((long[][])data).length == count;
623 if (isDataArrayCorrect) {
624 for (long[] datum : (long[][])data) {
625 if (datum.length != 2) {
626 isDataArrayCorrect = false;
627 break;
628 }
629 if (datum[0] < 0 || datum[1] < 0) {
630 throw new IllegalArgumentException
631 ("Negative value supplied for TIFF_RATIONAL");
632 }
633 if (datum[0] > MAX_UINT32 || datum[1] > MAX_UINT32) {
634 throw new IllegalArgumentException
635 ("Too large value supplied for TIFF_RATIONAL");
636 }
637 }
638 }
639 break;
640 case TIFFTag.TIFF_SSHORT:
641 isDataArrayCorrect = data instanceof short[]
642 && ((short[])data).length == count;
643 break;
644 case TIFFTag.TIFF_SLONG:
645 isDataArrayCorrect = data instanceof int[]
646 && ((int[])data).length == count;
647 break;
648 case TIFFTag.TIFF_SRATIONAL:
649 isDataArrayCorrect = data instanceof int[][]
650 && ((int[][])data).length == count;
651 if (isDataArrayCorrect) {
652 for (int[] datum : (int[][])data) {
653 if (datum.length != 2) {
654 isDataArrayCorrect = false;
655 break;
656 }
657 }
658 }
659 break;
660 case TIFFTag.TIFF_FLOAT:
661 isDataArrayCorrect = data instanceof float[]
662 && ((float[])data).length == count;
663 break;
664 case TIFFTag.TIFF_DOUBLE:
665 isDataArrayCorrect = data instanceof double[]
666 && ((double[])data).length == count;
667 break;
668 default:
669 throw new IllegalArgumentException("Unknown data type "+type);
670 }
671
672 if (!isDataArrayCorrect) {
673 throw new IllegalArgumentException
674 ("Illegal class or length for data array");
675 }
676
677 this.tag = tag;
678 this.tagNumber = tag.getNumber();
829 */
830 public int getType() {
831 return type;
832 }
833
834 /**
835 * Returns the name of the supplied data type constant.
836 *
837 * @param dataType One of the {@code TIFFTag.TIFF_*} constants
838 * indicating the data type of the field as written to the TIFF stream.
839 * @return The type name corresponding to the supplied type constant.
840 * @throws IllegalArgumentException if {@code dataType} is not
841 * one of the {@code TIFFTag.TIFF_*} data type constants.
842 */
843 public static String getTypeName(int dataType) {
844 if (dataType < TIFFTag.MIN_DATATYPE ||
845 dataType > TIFFTag.MAX_DATATYPE) {
846 throw new IllegalArgumentException("Unknown data type "+dataType);
847 }
848
849 return TYPE_NAMES[dataType];
850 }
851
852 /**
853 * Returns the data type constant corresponding to the supplied data
854 * type name. If the name is unknown {@code -1} will be returned.
855 *
856 * @param typeName The type name.
857 * @return One of the {@code TIFFTag.TIFF_*} constants or
858 * {@code -1} if the name is not recognized.
859 */
860 public static int getTypeByName(String typeName) {
861 for (int i = TIFFTag.MIN_DATATYPE; i <= TIFFTag.MAX_DATATYPE; i++) {
862 if (typeName.equals(TYPE_NAMES[i])) {
863 return i;
864 }
865 }
866
867 return -1;
868 }
869
870 /**
871 * Creates an array appropriate for the indicated data type.
872 *
873 * @param dataType One of the {@code TIFFTag.TIFF_*} data type
874 * constants.
875 * @param count The number of values in the array.
876 * @return An array appropriate for the specified data type.
877 *
878 * @throws IllegalArgumentException if {@code dataType} is not
879 * one of the {@code TIFFTag.TIFF_*} data type constants.
880 * @throws IllegalArgumentException if {@code count < 0}.
881 */
882 public static Object createArrayForType(int dataType, int count) {
917 * <tt>"TIFFField"</tt> or <tt>"TIFFIFD"</tt> as described in the
918 * TIFF native image metadata specification. The node will be named
919 * <tt>"TIFFIFD"</tt> if and only if {@link #hasDirectory()} returns
920 * {@code true} and the field's type is either {@link TIFFTag#TIFF_LONG}
921 * or {@link TIFFTag#TIFF_IFD_POINTER}.
922 *
923 * @return a {@code Node} named <tt>"TIFFField"</tt> or
924 * <tt>"TIFFIFD"</tt>.
925 */
926 public Node getAsNativeNode() {
927 return new TIFFFieldNode(this);
928 }
929
930 /**
931 * Indicates whether the value associated with the field is of
932 * integral data type.
933 *
934 * @return Whether the field type is integral.
935 */
936 public boolean isIntegral() {
937 return IS_INTEGRAL[type];
938 }
939
940 /**
941 * Returns the number of data items present in the field. For
942 * {@code TIFFTag.TIFF_ASCII} fields, the value returned is the
943 * number of {@code String}s, not the total length of the
944 * data as in the file representation.
945 *
946 * @return The number of data items present in the field.
947 */
948 public int getCount() {
949 return count;
950 }
951
952 /**
953 * Returns a reference to the data object associated with the field.
954 *
955 * @return The data object of the field.
956 */
957 public Object getData() {
|