2 * Copyright (C) 2012 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.gallery3d.exif;
19 import java.nio.charset.Charset;
20 import java.text.SimpleDateFormat;
21 import java.util.Arrays;
22 import java.util.Date;
25 * This class stores information of an EXIF tag. For more information about
26 * defined EXIF tags, please read the Jeita EXIF 2.2 standard. Tags should be
27 * instantiated using {@link ExifInterface#buildTag}.
31 public class ExifTag {
33 * The BYTE type in the EXIF standard. An 8-bit unsigned integer.
35 public static final short TYPE_UNSIGNED_BYTE = 1;
37 * The ASCII type in the EXIF standard. An 8-bit byte containing one 7-bit
38 * ASCII code. The final byte is terminated with NULL.
40 public static final short TYPE_ASCII = 2;
42 * The SHORT type in the EXIF standard. A 16-bit (2-byte) unsigned integer
44 public static final short TYPE_UNSIGNED_SHORT = 3;
46 * The LONG type in the EXIF standard. A 32-bit (4-byte) unsigned integer
48 public static final short TYPE_UNSIGNED_LONG = 4;
50 * The RATIONAL type of EXIF standard. It consists of two LONGs. The first
51 * one is the numerator and the second one expresses the denominator.
53 public static final short TYPE_UNSIGNED_RATIONAL = 5;
55 * The UNDEFINED type in the EXIF standard. An 8-bit byte that can take any
56 * value depending on the field definition.
58 public static final short TYPE_UNDEFINED = 7;
60 * The SLONG type in the EXIF standard. A 32-bit (4-byte) signed integer
61 * (2's complement notation).
63 public static final short TYPE_LONG = 9;
65 * The SRATIONAL type of EXIF standard. It consists of two SLONGs. The first
66 * one is the numerator and the second one is the denominator.
68 public static final short TYPE_RATIONAL = 10;
70 private static Charset US_ASCII = Charset.forName("US-ASCII");
71 private static final int TYPE_TO_SIZE_MAP[] = new int[11];
72 private static final int UNSIGNED_SHORT_MAX = 65535;
73 private static final long UNSIGNED_LONG_MAX = 4294967295L;
74 private static final long LONG_MAX = Integer.MAX_VALUE;
75 private static final long LONG_MIN = Integer.MIN_VALUE;
78 TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_BYTE] = 1;
79 TYPE_TO_SIZE_MAP[TYPE_ASCII] = 1;
80 TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_SHORT] = 2;
81 TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_LONG] = 4;
82 TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_RATIONAL] = 8;
83 TYPE_TO_SIZE_MAP[TYPE_UNDEFINED] = 1;
84 TYPE_TO_SIZE_MAP[TYPE_LONG] = 4;
85 TYPE_TO_SIZE_MAP[TYPE_RATIONAL] = 8;
88 static final int SIZE_UNDEFINED = 0;
91 private final short mTagId;
93 private final short mDataType;
94 // If tag has defined count
95 private boolean mHasDefinedDefaultComponentCount;
96 // Actual data count in tag (should be number of elements in value array)
97 private int mComponentCountActual;
98 // The ifd that this tag should be put in
100 // The value (array of elements of type Tag Type)
101 private Object mValue;
102 // Value offset in exif header.
105 private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("yyyy:MM:dd kk:mm:ss");
108 * Returns true if the given IFD is a valid IFD.
110 public static boolean isValidIfd(int ifdId) {
111 return ifdId == IfdId.TYPE_IFD_0 || ifdId == IfdId.TYPE_IFD_1
112 || ifdId == IfdId.TYPE_IFD_EXIF || ifdId == IfdId.TYPE_IFD_INTEROPERABILITY
113 || ifdId == IfdId.TYPE_IFD_GPS;
117 * Returns true if a given type is a valid tag type.
119 public static boolean isValidType(short type) {
120 return type == TYPE_UNSIGNED_BYTE || type == TYPE_ASCII ||
121 type == TYPE_UNSIGNED_SHORT || type == TYPE_UNSIGNED_LONG ||
122 type == TYPE_UNSIGNED_RATIONAL || type == TYPE_UNDEFINED ||
123 type == TYPE_LONG || type == TYPE_RATIONAL;
126 // Use builtTag in ExifInterface instead of constructor.
127 ExifTag(short tagId, short type, int componentCount, int ifd,
128 boolean hasDefinedComponentCount) {
131 mComponentCountActual = componentCount;
132 mHasDefinedDefaultComponentCount = hasDefinedComponentCount;
138 * Gets the element size of the given data type in bytes.
142 * @see #TYPE_RATIONAL
143 * @see #TYPE_UNDEFINED
144 * @see #TYPE_UNSIGNED_BYTE
145 * @see #TYPE_UNSIGNED_LONG
146 * @see #TYPE_UNSIGNED_RATIONAL
147 * @see #TYPE_UNSIGNED_SHORT
149 public static int getElementSize(short type) {
150 return TYPE_TO_SIZE_MAP[type];
154 * Returns the ID of the IFD this tag belongs to.
156 * @see IfdId#TYPE_IFD_0
157 * @see IfdId#TYPE_IFD_1
158 * @see IfdId#TYPE_IFD_EXIF
159 * @see IfdId#TYPE_IFD_GPS
160 * @see IfdId#TYPE_IFD_INTEROPERABILITY
162 public int getIfd() {
166 protected void setIfd(int ifdId) {
171 * Gets the TID of this tag.
173 public short getTagId() {
178 * Gets the data type of this tag
182 * @see #TYPE_RATIONAL
183 * @see #TYPE_UNDEFINED
184 * @see #TYPE_UNSIGNED_BYTE
185 * @see #TYPE_UNSIGNED_LONG
186 * @see #TYPE_UNSIGNED_RATIONAL
187 * @see #TYPE_UNSIGNED_SHORT
189 public short getDataType() {
194 * Gets the total data size in bytes of the value of this tag.
196 public int getDataSize() {
197 return getComponentCount() * getElementSize(getDataType());
201 * Gets the component count of this tag.
204 // TODO: fix integer overflows with this
205 public int getComponentCount() {
206 return mComponentCountActual;
210 * Sets the component count of this tag. Call this function before
211 * setValue() if the length of value does not match the component count.
213 protected void forceSetComponentCount(int count) {
214 mComponentCountActual = count;
218 * Returns true if this ExifTag contains value; otherwise, this tag will
219 * contain an offset value that is determined when the tag is written.
221 public boolean hasValue() {
222 return mValue != null;
226 * Sets integer values into this tag. This method should be used for tags of
227 * type {@link #TYPE_UNSIGNED_SHORT}. This method will fail if:
229 * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_SHORT},
230 * {@link #TYPE_UNSIGNED_LONG}, or {@link #TYPE_LONG}.</li>
231 * <li>The value overflows.</li>
232 * <li>The value.length does NOT match the component count in the definition
236 public boolean setValue(int[] value) {
237 if (checkBadComponentCount(value.length)) {
240 if (mDataType != TYPE_UNSIGNED_SHORT && mDataType != TYPE_LONG &&
241 mDataType != TYPE_UNSIGNED_LONG) {
244 if (mDataType == TYPE_UNSIGNED_SHORT && checkOverflowForUnsignedShort(value)) {
246 } else if (mDataType == TYPE_UNSIGNED_LONG && checkOverflowForUnsignedLong(value)) {
250 long[] data = new long[value.length];
251 for (int i = 0; i < value.length; i++) {
255 mComponentCountActual = value.length;
260 * Sets integer value into this tag. This method should be used for tags of
261 * type {@link #TYPE_UNSIGNED_SHORT}, or {@link #TYPE_LONG}. This method
264 * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_SHORT},
265 * {@link #TYPE_UNSIGNED_LONG}, or {@link #TYPE_LONG}.</li>
266 * <li>The value overflows.</li>
267 * <li>The component count in the definition of this tag is not 1.</li>
270 public boolean setValue(int value) {
271 return setValue(new int[] {
277 * Sets long values into this tag. This method should be used for tags of
278 * type {@link #TYPE_UNSIGNED_LONG}. This method will fail if:
280 * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_LONG}.</li>
281 * <li>The value overflows.</li>
282 * <li>The value.length does NOT match the component count in the definition
286 public boolean setValue(long[] value) {
287 if (checkBadComponentCount(value.length) || mDataType != TYPE_UNSIGNED_LONG) {
290 if (checkOverflowForUnsignedLong(value)) {
294 mComponentCountActual = value.length;
299 * Sets long values into this tag. This method should be used for tags of
300 * type {@link #TYPE_UNSIGNED_LONG}. This method will fail if:
302 * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_LONG}.</li>
303 * <li>The value overflows.</li>
304 * <li>The component count in the definition for this tag is not 1.</li>
307 public boolean setValue(long value) {
308 return setValue(new long[] {
314 * Sets a string value into this tag. This method should be used for tags of
315 * type {@link #TYPE_ASCII}. The string is converted to an ASCII string.
316 * Characters that cannot be converted are replaced with '?'. The length of
317 * the string must be equal to either (component count -1) or (component
318 * count). The final byte will be set to the string null terminator '\0',
319 * overwriting the last character in the string if the value.length is equal
320 * to the component count. This method will fail if:
322 * <li>The data type is not {@link #TYPE_ASCII} or {@link #TYPE_UNDEFINED}.</li>
323 * <li>The length of the string is not equal to (component count -1) or
324 * (component count) in the definition for this tag.</li>
327 public boolean setValue(String value) {
328 if (mDataType != TYPE_ASCII && mDataType != TYPE_UNDEFINED) {
332 byte[] buf = value.getBytes(US_ASCII);
333 byte[] finalBuf = (buf[buf.length - 1] == 0 || mDataType == TYPE_UNDEFINED) ? buf : Arrays
334 .copyOf(buf, buf.length + 1);
335 int count = finalBuf.length;
336 if (checkBadComponentCount(count)) {
339 mComponentCountActual = count;
345 * Sets Rational values into this tag. This method should be used for tags
346 * of type {@link #TYPE_UNSIGNED_RATIONAL}, or {@link #TYPE_RATIONAL}. This
347 * method will fail if:
349 * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_RATIONAL}
350 * or {@link #TYPE_RATIONAL}.</li>
351 * <li>The value overflows.</li>
352 * <li>The value.length does NOT match the component count in the definition
358 public boolean setValue(Rational[] value) {
359 if (checkBadComponentCount(value.length)) {
362 if (mDataType != TYPE_UNSIGNED_RATIONAL && mDataType != TYPE_RATIONAL) {
365 if (mDataType == TYPE_UNSIGNED_RATIONAL && checkOverflowForUnsignedRational(value)) {
367 } else if (mDataType == TYPE_RATIONAL && checkOverflowForRational(value)) {
372 mComponentCountActual = value.length;
377 * Sets a Rational value into this tag. This method should be used for tags
378 * of type {@link #TYPE_UNSIGNED_RATIONAL}, or {@link #TYPE_RATIONAL}. This
379 * method will fail if:
381 * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_RATIONAL}
382 * or {@link #TYPE_RATIONAL}.</li>
383 * <li>The value overflows.</li>
384 * <li>The component count in the definition for this tag is not 1.</li>
389 public boolean setValue(Rational value) {
390 return setValue(new Rational[] {
396 * Sets byte values into this tag. This method should be used for tags of
397 * type {@link #TYPE_UNSIGNED_BYTE} or {@link #TYPE_UNDEFINED}. This method
400 * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_BYTE} or
401 * {@link #TYPE_UNDEFINED} .</li>
402 * <li>The length does NOT match the component count in the definition for
406 public boolean setValue(byte[] value, int offset, int length) {
407 if (checkBadComponentCount(length)) {
410 if (mDataType != TYPE_UNSIGNED_BYTE && mDataType != TYPE_UNDEFINED) {
413 mValue = new byte[length];
414 System.arraycopy(value, offset, mValue, 0, length);
415 mComponentCountActual = length;
420 * Equivalent to setValue(value, 0, value.length).
422 public boolean setValue(byte[] value) {
423 return setValue(value, 0, value.length);
427 * Sets byte value into this tag. This method should be used for tags of
428 * type {@link #TYPE_UNSIGNED_BYTE} or {@link #TYPE_UNDEFINED}. This method
431 * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_BYTE} or
432 * {@link #TYPE_UNDEFINED} .</li>
433 * <li>The component count in the definition for this tag is not 1.</li>
436 public boolean setValue(byte value) {
437 return setValue(new byte[] {
443 * Sets the value for this tag using an appropriate setValue method for the
444 * given object. This method will fail if:
446 * <li>The corresponding setValue method for the class of the object passed
447 * in would fail.</li>
448 * <li>There is no obvious way to cast the object passed in into an EXIF tag
452 public boolean setValue(Object obj) {
455 } else if (obj instanceof Short) {
456 return setValue(((Short) obj).shortValue() & 0x0ffff);
457 } else if (obj instanceof String) {
458 return setValue((String) obj);
459 } else if (obj instanceof int[]) {
460 return setValue((int[]) obj);
461 } else if (obj instanceof long[]) {
462 return setValue((long[]) obj);
463 } else if (obj instanceof Rational) {
464 return setValue((Rational) obj);
465 } else if (obj instanceof Rational[]) {
466 return setValue((Rational[]) obj);
467 } else if (obj instanceof byte[]) {
468 return setValue((byte[]) obj);
469 } else if (obj instanceof Integer) {
470 return setValue(((Integer) obj).intValue());
471 } else if (obj instanceof Long) {
472 return setValue(((Long) obj).longValue());
473 } else if (obj instanceof Byte) {
474 return setValue(((Byte) obj).byteValue());
475 } else if (obj instanceof Short[]) {
476 // Nulls in this array are treated as zeroes.
477 Short[] arr = (Short[]) obj;
478 int[] fin = new int[arr.length];
479 for (int i = 0; i < arr.length; i++) {
480 fin[i] = (arr[i] == null) ? 0 : arr[i].shortValue() & 0x0ffff;
482 return setValue(fin);
483 } else if (obj instanceof Integer[]) {
484 // Nulls in this array are treated as zeroes.
485 Integer[] arr = (Integer[]) obj;
486 int[] fin = new int[arr.length];
487 for (int i = 0; i < arr.length; i++) {
488 fin[i] = (arr[i] == null) ? 0 : arr[i].intValue();
490 return setValue(fin);
491 } else if (obj instanceof Long[]) {
492 // Nulls in this array are treated as zeroes.
493 Long[] arr = (Long[]) obj;
494 long[] fin = new long[arr.length];
495 for (int i = 0; i < arr.length; i++) {
496 fin[i] = (arr[i] == null) ? 0 : arr[i].longValue();
498 return setValue(fin);
499 } else if (obj instanceof Byte[]) {
500 // Nulls in this array are treated as zeroes.
501 Byte[] arr = (Byte[]) obj;
502 byte[] fin = new byte[arr.length];
503 for (int i = 0; i < arr.length; i++) {
504 fin[i] = (arr[i] == null) ? 0 : arr[i].byteValue();
506 return setValue(fin);
513 * Sets a timestamp to this tag. The method converts the timestamp with the
514 * format of "yyyy:MM:dd kk:mm:ss" and calls {@link #setValue(String)}. This
515 * method will fail if the data type is not {@link #TYPE_ASCII} or the
516 * component count of this tag is not 20 or undefined.
518 * @param time the number of milliseconds since Jan. 1, 1970 GMT
519 * @return true on success
521 public boolean setTimeValue(long time) {
522 // synchronized on TIME_FORMAT as SimpleDateFormat is not thread safe
523 synchronized (TIME_FORMAT) {
524 return setValue(TIME_FORMAT.format(new Date(time)));
529 * Gets the value as a String. This method should be used for tags of type
530 * {@link #TYPE_ASCII}.
532 * @return the value as a String, or null if the tag's value does not exist
533 * or cannot be converted to a String.
535 public String getValueAsString() {
536 if (mValue == null) {
538 } else if (mValue instanceof String) {
539 return (String) mValue;
540 } else if (mValue instanceof byte[]) {
541 return new String((byte[]) mValue, US_ASCII);
547 * Gets the value as a String. This method should be used for tags of type
548 * {@link #TYPE_ASCII}.
550 * @param defaultValue the String to return if the tag's value does not
551 * exist or cannot be converted to a String.
552 * @return the tag's value as a String, or the defaultValue.
554 public String getValueAsString(String defaultValue) {
555 String s = getValueAsString();
563 * Gets the value as a byte array. This method should be used for tags of
564 * type {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE}.
566 * @return the value as a byte array, or null if the tag's value does not
567 * exist or cannot be converted to a byte array.
569 public byte[] getValueAsBytes() {
570 if (mValue instanceof byte[]) {
571 return (byte[]) mValue;
577 * Gets the value as a byte. If there are more than 1 bytes in this value,
578 * gets the first byte. This method should be used for tags of type
579 * {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE}.
581 * @param defaultValue the byte to return if tag's value does not exist or
582 * cannot be converted to a byte.
583 * @return the tag's value as a byte, or the defaultValue.
585 public byte getValueAsByte(byte defaultValue) {
586 byte[] b = getValueAsBytes();
587 if (b == null || b.length < 1) {
594 * Gets the value as an array of Rationals. This method should be used for
595 * tags of type {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}.
597 * @return the value as as an array of Rationals, or null if the tag's value
598 * does not exist or cannot be converted to an array of Rationals.
600 public Rational[] getValueAsRationals() {
601 if (mValue instanceof Rational[]) {
602 return (Rational[]) mValue;
608 * Gets the value as a Rational. If there are more than 1 Rationals in this
609 * value, gets the first one. This method should be used for tags of type
610 * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}.
612 * @param defaultValue the Rational to return if tag's value does not exist
613 * or cannot be converted to a Rational.
614 * @return the tag's value as a Rational, or the defaultValue.
616 public Rational getValueAsRational(Rational defaultValue) {
617 Rational[] r = getValueAsRationals();
618 if (r == null || r.length < 1) {
625 * Gets the value as a Rational. If there are more than 1 Rationals in this
626 * value, gets the first one. This method should be used for tags of type
627 * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}.
629 * @param defaultValue the numerator of the Rational to return if tag's
630 * value does not exist or cannot be converted to a Rational (the
631 * denominator will be 1).
632 * @return the tag's value as a Rational, or the defaultValue.
634 public Rational getValueAsRational(long defaultValue) {
635 Rational defaultVal = new Rational(defaultValue, 1);
636 return getValueAsRational(defaultVal);
640 * Gets the value as an array of ints. This method should be used for tags
641 * of type {@link #TYPE_UNSIGNED_SHORT}, {@link #TYPE_UNSIGNED_LONG}.
643 * @return the value as as an array of ints, or null if the tag's value does
644 * not exist or cannot be converted to an array of ints.
646 public int[] getValueAsInts() {
647 if (mValue == null) {
649 } else if (mValue instanceof long[]) {
650 long[] val = (long[]) mValue;
651 int[] arr = new int[val.length];
652 for (int i = 0; i < val.length; i++) {
653 arr[i] = (int) val[i]; // Truncates
661 * Gets the value as an int. If there are more than 1 ints in this value,
662 * gets the first one. This method should be used for tags of type
663 * {@link #TYPE_UNSIGNED_SHORT}, {@link #TYPE_UNSIGNED_LONG}.
665 * @param defaultValue the int to return if tag's value does not exist or
666 * cannot be converted to an int.
667 * @return the tag's value as a int, or the defaultValue.
669 public int getValueAsInt(int defaultValue) {
670 int[] i = getValueAsInts();
671 if (i == null || i.length < 1) {
678 * Gets the value as an array of longs. This method should be used for tags
679 * of type {@link #TYPE_UNSIGNED_LONG}.
681 * @return the value as as an array of longs, or null if the tag's value
682 * does not exist or cannot be converted to an array of longs.
684 public long[] getValueAsLongs() {
685 if (mValue instanceof long[]) {
686 return (long[]) mValue;
692 * Gets the value or null if none exists. If there are more than 1 longs in
693 * this value, gets the first one. This method should be used for tags of
694 * type {@link #TYPE_UNSIGNED_LONG}.
696 * @param defaultValue the long to return if tag's value does not exist or
697 * cannot be converted to a long.
698 * @return the tag's value as a long, or the defaultValue.
700 public long getValueAsLong(long defaultValue) {
701 long[] l = getValueAsLongs();
702 if (l == null || l.length < 1) {
709 * Gets the tag's value or null if none exists.
711 public Object getValue() {
716 * Gets a long representation of the value.
718 * @param defaultValue value to return if there is no value or value is a
719 * rational with a denominator of 0.
720 * @return the tag's value as a long, or defaultValue if no representation
723 public long forceGetValueAsLong(long defaultValue) {
724 long[] l = getValueAsLongs();
725 if (l != null && l.length >= 1) {
728 byte[] b = getValueAsBytes();
729 if (b != null && b.length >= 1) {
732 Rational[] r = getValueAsRationals();
733 if (r != null && r.length >= 1 && r[0].getDenominator() != 0) {
734 return (long) r[0].toDouble();
740 * Gets a string representation of the value.
742 public String forceGetValueAsString() {
743 if (mValue == null) {
745 } else if (mValue instanceof byte[]) {
746 if (mDataType == TYPE_ASCII) {
747 return new String((byte[]) mValue, US_ASCII);
749 return Arrays.toString((byte[]) mValue);
751 } else if (mValue instanceof long[]) {
752 if (((long[]) mValue).length == 1) {
753 return String.valueOf(((long[]) mValue)[0]);
755 return Arrays.toString((long[]) mValue);
757 } else if (mValue instanceof Object[]) {
758 if (((Object[]) mValue).length == 1) {
759 Object val = ((Object[]) mValue)[0];
763 return val.toString();
766 return Arrays.toString((Object[]) mValue);
769 return mValue.toString();
774 * Gets the value for type {@link #TYPE_ASCII}, {@link #TYPE_LONG},
775 * {@link #TYPE_UNDEFINED}, {@link #TYPE_UNSIGNED_BYTE},
776 * {@link #TYPE_UNSIGNED_LONG}, or {@link #TYPE_UNSIGNED_SHORT}. For
777 * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}, call
778 * {@link #getRational(int)} instead.
780 * @exception IllegalArgumentException if the data type is
781 * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}.
783 protected long getValueAt(int index) {
784 if (mValue instanceof long[]) {
785 return ((long[]) mValue)[index];
786 } else if (mValue instanceof byte[]) {
787 return ((byte[]) mValue)[index];
789 throw new IllegalArgumentException("Cannot get integer value from "
790 + convertTypeToString(mDataType));
794 * Gets the {@link #TYPE_ASCII} data.
796 * @exception IllegalArgumentException If the type is NOT
797 * {@link #TYPE_ASCII}.
799 protected String getString() {
800 if (mDataType != TYPE_ASCII) {
801 throw new IllegalArgumentException("Cannot get ASCII value from "
802 + convertTypeToString(mDataType));
804 return new String((byte[]) mValue, US_ASCII);
808 * Get the converted ascii byte. Used by ExifOutputStream.
810 protected byte[] getStringByte() {
811 return (byte[]) mValue;
815 * Gets the {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL} data.
817 * @exception IllegalArgumentException If the type is NOT
818 * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}.
820 protected Rational getRational(int index) {
821 if ((mDataType != TYPE_RATIONAL) && (mDataType != TYPE_UNSIGNED_RATIONAL)) {
822 throw new IllegalArgumentException("Cannot get RATIONAL value from "
823 + convertTypeToString(mDataType));
825 return ((Rational[]) mValue)[index];
829 * Equivalent to getBytes(buffer, 0, buffer.length).
831 protected void getBytes(byte[] buf) {
832 getBytes(buf, 0, buf.length);
836 * Gets the {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE} data.
838 * @param buf the byte array in which to store the bytes read.
839 * @param offset the initial position in buffer to store the bytes.
840 * @param length the maximum number of bytes to store in buffer. If length >
841 * component count, only the valid bytes will be stored.
842 * @exception IllegalArgumentException If the type is NOT
843 * {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE}.
845 protected void getBytes(byte[] buf, int offset, int length) {
846 if ((mDataType != TYPE_UNDEFINED) && (mDataType != TYPE_UNSIGNED_BYTE)) {
847 throw new IllegalArgumentException("Cannot get BYTE value from "
848 + convertTypeToString(mDataType));
850 System.arraycopy(mValue, 0, buf, offset,
851 (length > mComponentCountActual) ? mComponentCountActual : length);
855 * Gets the offset of this tag. This is only valid if this data size > 4 and
856 * contains an offset to the location of the actual value.
858 protected int getOffset() {
863 * Sets the offset of this tag.
865 protected void setOffset(int offset) {
869 protected void setHasDefinedCount(boolean d) {
870 mHasDefinedDefaultComponentCount = d;
873 private boolean checkBadComponentCount(int count) {
874 if (mHasDefinedDefaultComponentCount && (mComponentCountActual != count)) {
880 private static String convertTypeToString(short type) {
882 case TYPE_UNSIGNED_BYTE:
883 return "UNSIGNED_BYTE";
886 case TYPE_UNSIGNED_SHORT:
887 return "UNSIGNED_SHORT";
888 case TYPE_UNSIGNED_LONG:
889 return "UNSIGNED_LONG";
890 case TYPE_UNSIGNED_RATIONAL:
891 return "UNSIGNED_RATIONAL";
903 private boolean checkOverflowForUnsignedShort(int[] value) {
904 for (int v : value) {
905 if (v > UNSIGNED_SHORT_MAX || v < 0) {
912 private boolean checkOverflowForUnsignedLong(long[] value) {
913 for (long v : value) {
914 if (v < 0 || v > UNSIGNED_LONG_MAX) {
921 private boolean checkOverflowForUnsignedLong(int[] value) {
922 for (int v : value) {
930 private boolean checkOverflowForUnsignedRational(Rational[] value) {
931 for (Rational v : value) {
932 if (v.getNumerator() < 0 || v.getDenominator() < 0
933 || v.getNumerator() > UNSIGNED_LONG_MAX
934 || v.getDenominator() > UNSIGNED_LONG_MAX) {
941 private boolean checkOverflowForRational(Rational[] value) {
942 for (Rational v : value) {
943 if (v.getNumerator() < LONG_MIN || v.getDenominator() < LONG_MIN
944 || v.getNumerator() > LONG_MAX
945 || v.getDenominator() > LONG_MAX) {
953 public boolean equals(Object obj) {
957 if (obj instanceof ExifTag) {
958 ExifTag tag = (ExifTag) obj;
959 if (tag.mTagId != this.mTagId
960 || tag.mComponentCountActual != this.mComponentCountActual
961 || tag.mDataType != this.mDataType) {
964 if (mValue != null) {
965 if (tag.mValue == null) {
967 } else if (mValue instanceof long[]) {
968 if (!(tag.mValue instanceof long[])) {
971 return Arrays.equals((long[]) mValue, (long[]) tag.mValue);
972 } else if (mValue instanceof Rational[]) {
973 if (!(tag.mValue instanceof Rational[])) {
976 return Arrays.equals((Rational[]) mValue, (Rational[]) tag.mValue);
977 } else if (mValue instanceof byte[]) {
978 if (!(tag.mValue instanceof byte[])) {
981 return Arrays.equals((byte[]) mValue, (byte[]) tag.mValue);
983 return mValue.equals(tag.mValue);
986 return tag.mValue == null;
993 public String toString() {
994 return String.format("tag id: %04X\n", mTagId) + "ifd id: " + mIfd + "\ntype: "
995 + convertTypeToString(mDataType) + "\ncount: " + mComponentCountActual
996 + "\noffset: " + mOffset + "\nvalue: " + forceGetValueAsString() + "\n";