12523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan/*
22523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * Copyright (C) 2012 The Android Open Source Project
32523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan *
42523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * Licensed under the Apache License, Version 2.0 (the "License");
52523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * you may not use this file except in compliance with the License.
62523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * You may obtain a copy of the License at
72523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan *
82523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan *      http://www.apache.org/licenses/LICENSE-2.0
92523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan *
102523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * Unless required by applicable law or agreed to in writing, software
112523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * distributed under the License is distributed on an "AS IS" BASIS,
122523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * See the License for the specific language governing permissions and
142523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * limitations under the License.
152523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan */
162523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
17a16e7b50f3148f581439509279f242092e254309ztenghuipackage com.android.camera.exif;
182523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
19ff0f96c07827c39df5a0b408a028e7198dc8294bEarl Ouimport java.nio.charset.Charset;
202523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanimport java.text.SimpleDateFormat;
212523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanimport java.util.Arrays;
222523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanimport java.util.Date;
232523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
242523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan/**
25c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * This class stores information of an EXIF tag. For more information about
26c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * defined EXIF tags, please read the Jeita EXIF 2.2 standard. Tags should be
27c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * instantiated using {@link ExifInterface#buildTag}.
28c274ded801f745d6318186958107622e7a4fef33Ruben Brunk *
29c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * @see ExifInterface
302523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan */
312523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanpublic class ExifTag {
322523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
332523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * The BYTE type in the EXIF standard. An 8-bit unsigned integer.
342523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
352523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public static final short TYPE_UNSIGNED_BYTE = 1;
362523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
37c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * The ASCII type in the EXIF standard. An 8-bit byte containing one 7-bit
38c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * ASCII code. The final byte is terminated with NULL.
392523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
402523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public static final short TYPE_ASCII = 2;
412523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
422523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * The SHORT type in the EXIF standard. A 16-bit (2-byte) unsigned integer
432523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
442523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public static final short TYPE_UNSIGNED_SHORT = 3;
452523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
462523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * The LONG type in the EXIF standard. A 32-bit (4-byte) unsigned integer
472523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
482523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public static final short TYPE_UNSIGNED_LONG = 4;
492523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
50c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * The RATIONAL type of EXIF standard. It consists of two LONGs. The first
51c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * one is the numerator and the second one expresses the denominator.
522523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
532523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public static final short TYPE_UNSIGNED_RATIONAL = 5;
542523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
55c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * The UNDEFINED type in the EXIF standard. An 8-bit byte that can take any
56c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * value depending on the field definition.
572523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
582523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public static final short TYPE_UNDEFINED = 7;
592523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
602523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * The SLONG type in the EXIF standard. A 32-bit (4-byte) signed integer
612523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * (2's complement notation).
622523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
632523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public static final short TYPE_LONG = 9;
642523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
65c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * The SRATIONAL type of EXIF standard. It consists of two SLONGs. The first
66c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * one is the numerator and the second one is the denominator.
672523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
682523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public static final short TYPE_RATIONAL = 10;
692523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
70c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    private static Charset US_ASCII = Charset.forName("US-ASCII");
712523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    private static final int TYPE_TO_SIZE_MAP[] = new int[11];
72c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    private static final int UNSIGNED_SHORT_MAX = 65535;
73c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    private static final long UNSIGNED_LONG_MAX = 4294967295L;
74c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    private static final long LONG_MAX = Integer.MAX_VALUE;
75c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    private static final long LONG_MIN = Integer.MIN_VALUE;
76c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
772523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    static {
782523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_BYTE] = 1;
792523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        TYPE_TO_SIZE_MAP[TYPE_ASCII] = 1;
802523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_SHORT] = 2;
812523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_LONG] = 4;
822523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_RATIONAL] = 8;
832523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        TYPE_TO_SIZE_MAP[TYPE_UNDEFINED] = 1;
842523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        TYPE_TO_SIZE_MAP[TYPE_LONG] = 4;
852523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        TYPE_TO_SIZE_MAP[TYPE_RATIONAL] = 8;
862523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
872523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
88c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    static final int SIZE_UNDEFINED = 0;
892523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
90c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    // Exif TagId
912523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    private final short mTagId;
92c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    // Exif Tag Type
932523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    private final short mDataType;
94c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    // If tag has defined count
95c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    private boolean mHasDefinedDefaultComponentCount;
96c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    // Actual data count in tag (should be number of elements in value array)
97c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    private int mComponentCountActual;
98c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    // The ifd that this tag should be put in
99c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    private int mIfd;
100c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    // The value (array of elements of type Tag Type)
1012523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    private Object mValue;
102c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    // Value offset in exif header.
1032523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    private int mOffset;
1042523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
105c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("yyyy:MM:dd kk:mm:ss");
1062523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
1072523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
108c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Returns true if the given IFD is a valid IFD.
1092523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
110c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public static boolean isValidIfd(int ifdId) {
111c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return ifdId == IfdId.TYPE_IFD_0 || ifdId == IfdId.TYPE_IFD_1
112c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                || ifdId == IfdId.TYPE_IFD_EXIF || ifdId == IfdId.TYPE_IFD_INTEROPERABILITY
113c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                || ifdId == IfdId.TYPE_IFD_GPS;
1142523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
1152523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
1162523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
117c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Returns true if a given type is a valid tag type.
1182523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
119c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public static boolean isValidType(short type) {
120c57d5a6b1e5e85c40d751b33dd868e29ccf4504eEarl Ou        return type == TYPE_UNSIGNED_BYTE || type == TYPE_ASCII ||
121c06c8045b159d68f8fda051d59a0eb82215067eeEarl Ou                type == TYPE_UNSIGNED_SHORT || type == TYPE_UNSIGNED_LONG ||
122c06c8045b159d68f8fda051d59a0eb82215067eeEarl Ou                type == TYPE_UNSIGNED_RATIONAL || type == TYPE_UNDEFINED ||
123c06c8045b159d68f8fda051d59a0eb82215067eeEarl Ou                type == TYPE_LONG || type == TYPE_RATIONAL;
124c57d5a6b1e5e85c40d751b33dd868e29ccf4504eEarl Ou    }
125c57d5a6b1e5e85c40d751b33dd868e29ccf4504eEarl Ou
126c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    // Use builtTag in ExifInterface instead of constructor.
127c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    ExifTag(short tagId, short type, int componentCount, int ifd,
128c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            boolean hasDefinedComponentCount) {
1292523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        mTagId = tagId;
1302523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        mDataType = type;
131c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        mComponentCountActual = componentCount;
132c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        mHasDefinedDefaultComponentCount = hasDefinedComponentCount;
1332523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        mIfd = ifd;
134c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        mValue = null;
135c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    }
136c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
137c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    /**
138c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Gets the element size of the given data type in bytes.
139c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *
140c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @see #TYPE_ASCII
141c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @see #TYPE_LONG
142c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @see #TYPE_RATIONAL
143c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @see #TYPE_UNDEFINED
144c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @see #TYPE_UNSIGNED_BYTE
145c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @see #TYPE_UNSIGNED_LONG
146c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @see #TYPE_UNSIGNED_RATIONAL
147c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @see #TYPE_UNSIGNED_SHORT
148c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     */
149c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public static int getElementSize(short type) {
150c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return TYPE_TO_SIZE_MAP[type];
1512523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
1522523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
1532523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
1542523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * Returns the ID of the IFD this tag belongs to.
1552523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     *
1562523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * @see IfdId#TYPE_IFD_0
1572523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * @see IfdId#TYPE_IFD_1
1582523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * @see IfdId#TYPE_IFD_EXIF
1592523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * @see IfdId#TYPE_IFD_GPS
1602523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * @see IfdId#TYPE_IFD_INTEROPERABILITY
1612523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
1622523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public int getIfd() {
1632523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        return mIfd;
1642523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
1652523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
166c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    protected void setIfd(int ifdId) {
167c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        mIfd = ifdId;
168c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    }
169c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
1702523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
171c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Gets the TID of this tag.
1722523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
1732523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public short getTagId() {
1742523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        return mTagId;
1752523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
1762523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
1772523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
1782523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * Gets the data type of this tag
1792523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     *
1802523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * @see #TYPE_ASCII
1812523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * @see #TYPE_LONG
1822523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * @see #TYPE_RATIONAL
1832523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * @see #TYPE_UNDEFINED
1842523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * @see #TYPE_UNSIGNED_BYTE
1852523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * @see #TYPE_UNSIGNED_LONG
1862523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * @see #TYPE_UNSIGNED_RATIONAL
1872523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * @see #TYPE_UNSIGNED_SHORT
1882523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
1892523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public short getDataType() {
1902523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        return mDataType;
1912523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
1922523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
1932523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
1942523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * Gets the total data size in bytes of the value of this tag.
1952523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
1962523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public int getDataSize() {
1972523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        return getComponentCount() * getElementSize(getDataType());
1982523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
1992523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
2002523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
2012523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * Gets the component count of this tag.
2022523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
203c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
204c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    // TODO: fix integer overflows with this
2052523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public int getComponentCount() {
206c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return mComponentCountActual;
2072523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
2082523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
2092523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
210c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Sets the component count of this tag. Call this function before
211c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * setValue() if the length of value does not match the component count.
212ff0f96c07827c39df5a0b408a028e7198dc8294bEarl Ou     */
213c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    protected void forceSetComponentCount(int count) {
214c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        mComponentCountActual = count;
215ff0f96c07827c39df5a0b408a028e7198dc8294bEarl Ou    }
216ff0f96c07827c39df5a0b408a028e7198dc8294bEarl Ou
217ff0f96c07827c39df5a0b408a028e7198dc8294bEarl Ou    /**
218c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Returns true if this ExifTag contains value; otherwise, this tag will
219c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * contain an offset value that is determined when the tag is written.
2202523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
2212523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public boolean hasValue() {
2222523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        return mValue != null;
2232523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
2242523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
2252523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
226c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Sets integer values into this tag. This method should be used for tags of
227c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * type {@link #TYPE_UNSIGNED_SHORT}. This method will fail if:
228c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <ul>
229c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_SHORT},
230c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * {@link #TYPE_UNSIGNED_LONG}, or {@link #TYPE_LONG}.</li>
231c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The value overflows.</li>
232c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The value.length does NOT match the component count in the definition
233c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * for this tag.</li>
234c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * </ul>
2352523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
236c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public boolean setValue(int[] value) {
237c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (checkBadComponentCount(value.length)) {
238c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return false;
239c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        }
240c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (mDataType != TYPE_UNSIGNED_SHORT && mDataType != TYPE_LONG &&
241c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                mDataType != TYPE_UNSIGNED_LONG) {
242c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return false;
243c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        }
244c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (mDataType == TYPE_UNSIGNED_SHORT && checkOverflowForUnsignedShort(value)) {
245c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return false;
246c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else if (mDataType == TYPE_UNSIGNED_LONG && checkOverflowForUnsignedLong(value)) {
247c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return false;
248c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        }
249c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
250c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        long[] data = new long[value.length];
2512e47253cfb049943199faa43c04f77d0bab0b5eenicolasroard        for (int i = 0; i < value.length; i++) {
2522e47253cfb049943199faa43c04f77d0bab0b5eenicolasroard            data[i] = value[i];
2532e47253cfb049943199faa43c04f77d0bab0b5eenicolasroard        }
254c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        mValue = data;
255c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        mComponentCountActual = value.length;
256c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return true;
2572523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
2582523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
2592523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
260c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Sets integer value into this tag. This method should be used for tags of
261c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * type {@link #TYPE_UNSIGNED_SHORT}, or {@link #TYPE_LONG}. This method
262c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * will fail if:
263c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <ul>
264c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_SHORT},
265c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * {@link #TYPE_UNSIGNED_LONG}, or {@link #TYPE_LONG}.</li>
266c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The value overflows.</li>
267c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The component count in the definition of this tag is not 1.</li>
268c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * </ul>
2692523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
270c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public boolean setValue(int value) {
271c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return setValue(new int[] {
272c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                value
273c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        });
2742523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
2752523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
276c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    /**
277c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Sets long values into this tag. This method should be used for tags of
278c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * type {@link #TYPE_UNSIGNED_LONG}. This method will fail if:
279c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <ul>
280c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_LONG}.</li>
281c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The value overflows.</li>
282c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The value.length does NOT match the component count in the definition
283c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * for this tag.</li>
284c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * </ul>
285c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     */
286c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public boolean setValue(long[] value) {
287c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (checkBadComponentCount(value.length) || mDataType != TYPE_UNSIGNED_LONG) {
288c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return false;
289c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        }
290c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (checkOverflowForUnsignedLong(value)) {
291c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return false;
2922523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        }
293c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        mValue = value;
294c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        mComponentCountActual = value.length;
295c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return true;
2962523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
2972523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
298c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    /**
299c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Sets long values into this tag. This method should be used for tags of
300c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * type {@link #TYPE_UNSIGNED_LONG}. This method will fail if:
301c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <ul>
302c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_LONG}.</li>
303c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The value overflows.</li>
304c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The component count in the definition for this tag is not 1.</li>
305c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * </ul>
306c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     */
307c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public boolean setValue(long value) {
308c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return setValue(new long[] {
309c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                value
310c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        });
3112523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
3122523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
313c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    /**
314c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Sets a string value into this tag. This method should be used for tags of
315c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * type {@link #TYPE_ASCII}. The string is converted to an ASCII string.
316c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Characters that cannot be converted are replaced with '?'. The length of
317c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * the string must be equal to either (component count -1) or (component
318c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * count). The final byte will be set to the string null terminator '\0',
319c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * overwriting the last character in the string if the value.length is equal
320c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * to the component count. This method will fail if:
321c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <ul>
322c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The data type is not {@link #TYPE_ASCII} or {@link #TYPE_UNDEFINED}.</li>
323c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The length of the string is not equal to (component count -1) or
324c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * (component count) in the definition for this tag.</li>
325c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * </ul>
326c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     */
327c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public boolean setValue(String value) {
328c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (mDataType != TYPE_ASCII && mDataType != TYPE_UNDEFINED) {
329c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return false;
3302523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        }
3312523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
332c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        byte[] buf = value.getBytes(US_ASCII);
333310ef8d4745a15f04e647b834a7d94e9dc7e1cabRuben Brunk        byte[] finalBuf = buf;
334310ef8d4745a15f04e647b834a7d94e9dc7e1cabRuben Brunk        if (buf.length > 0) {
335310ef8d4745a15f04e647b834a7d94e9dc7e1cabRuben Brunk            finalBuf = (buf[buf.length - 1] == 0 || mDataType == TYPE_UNDEFINED) ? buf : Arrays
336c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                .copyOf(buf, buf.length + 1);
337310ef8d4745a15f04e647b834a7d94e9dc7e1cabRuben Brunk        } else if (mDataType == TYPE_ASCII && mComponentCountActual == 1) {
338310ef8d4745a15f04e647b834a7d94e9dc7e1cabRuben Brunk            finalBuf = new byte[] { 0 };
339310ef8d4745a15f04e647b834a7d94e9dc7e1cabRuben Brunk        }
340c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        int count = finalBuf.length;
341c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (checkBadComponentCount(count)) {
342c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return false;
3432523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        }
344c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        mComponentCountActual = count;
345c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        mValue = finalBuf;
346c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return true;
3472523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
3482523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
349c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    /**
350c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Sets Rational values into this tag. This method should be used for tags
351c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * of type {@link #TYPE_UNSIGNED_RATIONAL}, or {@link #TYPE_RATIONAL}. This
352c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * method will fail if:
353c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <ul>
354c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_RATIONAL}
355c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * or {@link #TYPE_RATIONAL}.</li>
356c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The value overflows.</li>
357c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The value.length does NOT match the component count in the definition
358c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * for this tag.</li>
359c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * </ul>
360c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *
361c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @see Rational
362c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     */
363c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public boolean setValue(Rational[] value) {
364c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (checkBadComponentCount(value.length)) {
365c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return false;
3662523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        }
367c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (mDataType != TYPE_UNSIGNED_RATIONAL && mDataType != TYPE_RATIONAL) {
368c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return false;
3692523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        }
370c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (mDataType == TYPE_UNSIGNED_RATIONAL && checkOverflowForUnsignedRational(value)) {
371c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return false;
372c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else if (mDataType == TYPE_RATIONAL && checkOverflowForRational(value)) {
373c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return false;
3742523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        }
375c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
376c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        mValue = value;
377c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        mComponentCountActual = value.length;
378c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return true;
3792523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
3802523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
381c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    /**
382c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Sets a Rational value into this tag. This method should be used for tags
383c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * of type {@link #TYPE_UNSIGNED_RATIONAL}, or {@link #TYPE_RATIONAL}. This
384c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * method will fail if:
385c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <ul>
386c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_RATIONAL}
387c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * or {@link #TYPE_RATIONAL}.</li>
388c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The value overflows.</li>
389c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The component count in the definition for this tag is not 1.</li>
390c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * </ul>
391c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *
392c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @see Rational
393c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     */
394c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public boolean setValue(Rational value) {
395c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return setValue(new Rational[] {
396c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                value
397c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        });
3982523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
3992523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
4002523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
401c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Sets byte values into this tag. This method should be used for tags of
402c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * type {@link #TYPE_UNSIGNED_BYTE} or {@link #TYPE_UNDEFINED}. This method
403c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * will fail if:
4042523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * <ul>
405c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_BYTE} or
406c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * {@link #TYPE_UNDEFINED} .</li>
407c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The length does NOT match the component count in the definition for
408c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * this tag.</li>
4092523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * </ul>
4102523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
411c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public boolean setValue(byte[] value, int offset, int length) {
412c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (checkBadComponentCount(length)) {
413c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return false;
4142523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        }
415c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (mDataType != TYPE_UNSIGNED_BYTE && mDataType != TYPE_UNDEFINED) {
416c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return false;
4172523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        }
418c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        mValue = new byte[length];
419c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        System.arraycopy(value, offset, mValue, 0, length);
420c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        mComponentCountActual = length;
421c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return true;
422c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    }
4232523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
424c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    /**
425c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Equivalent to setValue(value, 0, value.length).
426c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     */
427c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public boolean setValue(byte[] value) {
428c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return setValue(value, 0, value.length);
4292523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
4302523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
4312523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
432c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Sets byte value into this tag. This method should be used for tags of
433c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * type {@link #TYPE_UNSIGNED_BYTE} or {@link #TYPE_UNDEFINED}. This method
434c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * will fail if:
4352523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * <ul>
436c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_BYTE} or
437c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * {@link #TYPE_UNDEFINED} .</li>
438c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The component count in the definition for this tag is not 1.</li>
4392523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * </ul>
4402523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
441c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public boolean setValue(byte value) {
442c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return setValue(new byte[] {
443c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                value
444c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        });
4452523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
4462523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
4472523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
448c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Sets the value for this tag using an appropriate setValue method for the
449c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * given object. This method will fail if:
4502523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * <ul>
451c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>The corresponding setValue method for the class of the object passed
452c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * in would fail.</li>
453c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * <li>There is no obvious way to cast the object passed in into an EXIF tag
454c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * type.</li>
4552523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * </ul>
4562523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
457c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public boolean setValue(Object obj) {
458c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (obj == null) {
459c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return false;
460c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else if (obj instanceof Short) {
461c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return setValue(((Short) obj).shortValue() & 0x0ffff);
462c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else if (obj instanceof String) {
463c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return setValue((String) obj);
464c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else if (obj instanceof int[]) {
465c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return setValue((int[]) obj);
466c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else if (obj instanceof long[]) {
467c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return setValue((long[]) obj);
468c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else if (obj instanceof Rational) {
469c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return setValue((Rational) obj);
470c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else if (obj instanceof Rational[]) {
471c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return setValue((Rational[]) obj);
472c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else if (obj instanceof byte[]) {
473c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return setValue((byte[]) obj);
474c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else if (obj instanceof Integer) {
475c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return setValue(((Integer) obj).intValue());
476c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else if (obj instanceof Long) {
477c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return setValue(((Long) obj).longValue());
478c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else if (obj instanceof Byte) {
479c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return setValue(((Byte) obj).byteValue());
480c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else if (obj instanceof Short[]) {
481c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            // Nulls in this array are treated as zeroes.
482c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            Short[] arr = (Short[]) obj;
483c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            int[] fin = new int[arr.length];
484c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            for (int i = 0; i < arr.length; i++) {
485c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                fin[i] = (arr[i] == null) ? 0 : arr[i].shortValue() & 0x0ffff;
486c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            }
487c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return setValue(fin);
488c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else if (obj instanceof Integer[]) {
489c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            // Nulls in this array are treated as zeroes.
490c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            Integer[] arr = (Integer[]) obj;
491c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            int[] fin = new int[arr.length];
492c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            for (int i = 0; i < arr.length; i++) {
493c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                fin[i] = (arr[i] == null) ? 0 : arr[i].intValue();
494c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            }
495c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return setValue(fin);
496c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else if (obj instanceof Long[]) {
497c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            // Nulls in this array are treated as zeroes.
498c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            Long[] arr = (Long[]) obj;
499c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            long[] fin = new long[arr.length];
500c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            for (int i = 0; i < arr.length; i++) {
501c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                fin[i] = (arr[i] == null) ? 0 : arr[i].longValue();
502c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            }
503c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return setValue(fin);
504c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else if (obj instanceof Byte[]) {
505c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            // Nulls in this array are treated as zeroes.
506c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            Byte[] arr = (Byte[]) obj;
507c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            byte[] fin = new byte[arr.length];
508c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            for (int i = 0; i < arr.length; i++) {
509c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                fin[i] = (arr[i] == null) ? 0 : arr[i].byteValue();
510c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            }
511c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return setValue(fin);
512c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else {
513c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return false;
5142523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        }
5152523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
5162523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
5172523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
518c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Sets a timestamp to this tag. The method converts the timestamp with the
519c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * format of "yyyy:MM:dd kk:mm:ss" and calls {@link #setValue(String)}. This
520c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * method will fail if the data type is not {@link #TYPE_ASCII} or the
521c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * component count of this tag is not 20 or undefined.
522c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *
523c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @param time the number of milliseconds since Jan. 1, 1970 GMT
524c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @return true on success
5252523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
526c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public boolean setTimeValue(long time) {
527c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        // synchronized on TIME_FORMAT as SimpleDateFormat is not thread safe
528c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        synchronized (TIME_FORMAT) {
529c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return setValue(TIME_FORMAT.format(new Date(time)));
530c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        }
5312523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
5322523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
5332523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
534c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Gets the value as a String. This method should be used for tags of type
535c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * {@link #TYPE_ASCII}.
536ff0f96c07827c39df5a0b408a028e7198dc8294bEarl Ou     *
537c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @return the value as a String, or null if the tag's value does not exist
538c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *         or cannot be converted to a String.
539c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     */
540c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public String getValueAsString() {
541c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (mValue == null) {
542c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return null;
543c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else if (mValue instanceof String) {
544c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return (String) mValue;
545c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else if (mValue instanceof byte[]) {
546c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return new String((byte[]) mValue, US_ASCII);
5472523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        }
548c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return null;
549c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    }
550ff0f96c07827c39df5a0b408a028e7198dc8294bEarl Ou
551c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    /**
552c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Gets the value as a String. This method should be used for tags of type
553c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * {@link #TYPE_ASCII}.
554c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *
555c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @param defaultValue the String to return if the tag's value does not
556c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *            exist or cannot be converted to a String.
557c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @return the tag's value as a String, or the defaultValue.
558c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     */
559c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public String getValueAsString(String defaultValue) {
560c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        String s = getValueAsString();
561c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (s == null) {
562c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return defaultValue;
563ff0f96c07827c39df5a0b408a028e7198dc8294bEarl Ou        }
564c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return s;
565c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    }
566ff0f96c07827c39df5a0b408a028e7198dc8294bEarl Ou
567c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    /**
568c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Gets the value as a byte array. This method should be used for tags of
569c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * type {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE}.
570c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *
571c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @return the value as a byte array, or null if the tag's value does not
572c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *         exist or cannot be converted to a byte array.
573c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     */
574c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public byte[] getValueAsBytes() {
575c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (mValue instanceof byte[]) {
576c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return (byte[]) mValue;
577ff0f96c07827c39df5a0b408a028e7198dc8294bEarl Ou        }
578c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return null;
5792523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
5802523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
5812523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
582c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Gets the value as a byte. If there are more than 1 bytes in this value,
583c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * gets the first byte. This method should be used for tags of type
584c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE}.
585c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *
586c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @param defaultValue the byte to return if tag's value does not exist or
587c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *            cannot be converted to a byte.
588c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @return the tag's value as a byte, or the defaultValue.
589c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     */
590c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public byte getValueAsByte(byte defaultValue) {
591c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        byte[] b = getValueAsBytes();
592c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (b == null || b.length < 1) {
593c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return defaultValue;
594c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        }
595c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return b[0];
596c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    }
597c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
598c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    /**
599c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Gets the value as an array of Rationals. This method should be used for
600c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * tags of type {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}.
601c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *
602c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @return the value as as an array of Rationals, or null if the tag's value
603c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *         does not exist or cannot be converted to an array of Rationals.
6042523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
605c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public Rational[] getValueAsRationals() {
606c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (mValue instanceof Rational[]) {
607c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return (Rational[]) mValue;
6082523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        }
609c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return null;
6102523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
6112523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
6122523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
613c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Gets the value as a Rational. If there are more than 1 Rationals in this
614c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * value, gets the first one. This method should be used for tags of type
615c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}.
616c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *
617c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @param defaultValue the Rational to return if tag's value does not exist
618c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *            or cannot be converted to a Rational.
619c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @return the tag's value as a Rational, or the defaultValue.
620c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     */
621c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public Rational getValueAsRational(Rational defaultValue) {
622c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        Rational[] r = getValueAsRationals();
623c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (r == null || r.length < 1) {
624c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return defaultValue;
625c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        }
626c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return r[0];
6272523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
6282523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
6292523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
630c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Gets the value as a Rational. If there are more than 1 Rationals in this
631c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * value, gets the first one. This method should be used for tags of type
632c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}.
633c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *
634c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @param defaultValue the numerator of the Rational to return if tag's
635c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *            value does not exist or cannot be converted to a Rational (the
636c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *            denominator will be 1).
637c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @return the tag's value as a Rational, or the defaultValue.
638c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     */
639c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public Rational getValueAsRational(long defaultValue) {
640c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        Rational defaultVal = new Rational(defaultValue, 1);
641c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return getValueAsRational(defaultVal);
642c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    }
643c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
644c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    /**
645c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Gets the value as an array of ints. This method should be used for tags
646c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * of type {@link #TYPE_UNSIGNED_SHORT}, {@link #TYPE_UNSIGNED_LONG}.
647c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *
648c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @return the value as as an array of ints, or null if the tag's value does
649c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *         not exist or cannot be converted to an array of ints.
650c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     */
651c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public int[] getValueAsInts() {
652c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (mValue == null) {
653c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return null;
654c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else if (mValue instanceof long[]) {
655c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            long[] val = (long[]) mValue;
656c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            int[] arr = new int[val.length];
657c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            for (int i = 0; i < val.length; i++) {
658c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                arr[i] = (int) val[i]; // Truncates
659c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            }
660c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return arr;
6612523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        }
662c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return null;
6632523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
6642523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
6652523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
666c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Gets the value as an int. If there are more than 1 ints in this value,
667c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * gets the first one. This method should be used for tags of type
668c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * {@link #TYPE_UNSIGNED_SHORT}, {@link #TYPE_UNSIGNED_LONG}.
669c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *
670c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @param defaultValue the int to return if tag's value does not exist or
671c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *            cannot be converted to an int.
672c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @return the tag's value as a int, or the defaultValue.
673c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     */
674c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public int getValueAsInt(int defaultValue) {
675c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        int[] i = getValueAsInts();
676c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (i == null || i.length < 1) {
677c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return defaultValue;
678c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        }
679c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return i[0];
680c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    }
681c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
682c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    /**
683c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Gets the value as an array of longs. This method should be used for tags
684c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * of type {@link #TYPE_UNSIGNED_LONG}.
685c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *
686c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @return the value as as an array of longs, or null if the tag's value
687c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *         does not exist or cannot be converted to an array of longs.
6882523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
689c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public long[] getValueAsLongs() {
690c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (mValue instanceof long[]) {
691c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return (long[]) mValue;
692c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        }
693c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return null;
6942523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
6952523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
696c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    /**
697c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Gets the value or null if none exists. If there are more than 1 longs in
698c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * this value, gets the first one. This method should be used for tags of
699c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * type {@link #TYPE_UNSIGNED_LONG}.
700c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *
701c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @param defaultValue the long to return if tag's value does not exist or
702c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *            cannot be converted to a long.
703c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @return the tag's value as a long, or the defaultValue.
704c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     */
705c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public long getValueAsLong(long defaultValue) {
706c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        long[] l = getValueAsLongs();
707c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (l == null || l.length < 1) {
708c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return defaultValue;
709c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        }
710c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return l[0];
711c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    }
7122523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
7132523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
714c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Gets the tag's value or null if none exists.
715c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     */
716c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public Object getValue() {
717c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return mValue;
718c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    }
719c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
720c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    /**
721c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Gets a long representation of the value.
7222523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     *
723c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @param defaultValue value to return if there is no value or value is a
724c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *            rational with a denominator of 0.
725c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @return the tag's value as a long, or defaultValue if no representation
726c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *         exists.
727c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     */
728c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public long forceGetValueAsLong(long defaultValue) {
729c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        long[] l = getValueAsLongs();
730c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (l != null && l.length >= 1) {
731c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return l[0];
732c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        }
733c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        byte[] b = getValueAsBytes();
734c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (b != null && b.length >= 1) {
735c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return b[0];
736c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        }
737c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        Rational[] r = getValueAsRationals();
738c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (r != null && r.length >= 1 && r[0].getDenominator() != 0) {
739c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return (long) r[0].toDouble();
740c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        }
741c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return defaultValue;
742c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    }
743c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
744c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    /**
745c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Gets a string representation of the value.
7462523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
747c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public String forceGetValueAsString() {
748c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (mValue == null) {
749c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return "";
750c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else if (mValue instanceof byte[]) {
751c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            if (mDataType == TYPE_ASCII) {
752c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                return new String((byte[]) mValue, US_ASCII);
753c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            } else {
754c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                return Arrays.toString((byte[]) mValue);
755c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            }
756c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else if (mValue instanceof long[]) {
757c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            if (((long[]) mValue).length == 1) {
758c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                return String.valueOf(((long[]) mValue)[0]);
759c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            } else {
760c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                return Arrays.toString((long[]) mValue);
761c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            }
762c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else if (mValue instanceof Object[]) {
763c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            if (((Object[]) mValue).length == 1) {
764c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                Object val = ((Object[]) mValue)[0];
765c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                if (val == null) {
766c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                    return "";
767c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                } else {
768c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                    return val.toString();
769c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                }
770c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            } else {
771c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                return Arrays.toString((Object[]) mValue);
772c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            }
773c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        } else {
774c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return mValue.toString();
7752523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        }
7762523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
777c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
7782523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
779994234e5b04864c9ac12a78de5ccdbe966cb8fa7Earl Ou     * Gets the value for type {@link #TYPE_ASCII}, {@link #TYPE_LONG},
780c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * {@link #TYPE_UNDEFINED}, {@link #TYPE_UNSIGNED_BYTE},
781c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * {@link #TYPE_UNSIGNED_LONG}, or {@link #TYPE_UNSIGNED_SHORT}. For
782c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}, call
783c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * {@link #getRational(int)} instead.
784994234e5b04864c9ac12a78de5ccdbe966cb8fa7Earl Ou     *
785c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @exception IllegalArgumentException if the data type is
786c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *                {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}.
7872523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
788c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    protected long getValueAt(int index) {
789994234e5b04864c9ac12a78de5ccdbe966cb8fa7Earl Ou        if (mValue instanceof long[]) {
790c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return ((long[]) mValue)[index];
791994234e5b04864c9ac12a78de5ccdbe966cb8fa7Earl Ou        } else if (mValue instanceof byte[]) {
792c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return ((byte[]) mValue)[index];
7932523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        }
794994234e5b04864c9ac12a78de5ccdbe966cb8fa7Earl Ou        throw new IllegalArgumentException("Cannot get integer value from "
795994234e5b04864c9ac12a78de5ccdbe966cb8fa7Earl Ou                + convertTypeToString(mDataType));
7962523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
7972523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
7982523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
7992523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * Gets the {@link #TYPE_ASCII} data.
800c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *
801c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @exception IllegalArgumentException If the type is NOT
802c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *                {@link #TYPE_ASCII}.
8032523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
804c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    protected String getString() {
8052523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        if (mDataType != TYPE_ASCII) {
8062523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan            throw new IllegalArgumentException("Cannot get ASCII value from "
8072523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan                    + convertTypeToString(mDataType));
8082523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        }
809ff0f96c07827c39df5a0b408a028e7198dc8294bEarl Ou        return new String((byte[]) mValue, US_ASCII);
810ff0f96c07827c39df5a0b408a028e7198dc8294bEarl Ou    }
811ff0f96c07827c39df5a0b408a028e7198dc8294bEarl Ou
812ff0f96c07827c39df5a0b408a028e7198dc8294bEarl Ou    /*
813ff0f96c07827c39df5a0b408a028e7198dc8294bEarl Ou     * Get the converted ascii byte. Used by ExifOutputStream.
814ff0f96c07827c39df5a0b408a028e7198dc8294bEarl Ou     */
815c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    protected byte[] getStringByte() {
816ff0f96c07827c39df5a0b408a028e7198dc8294bEarl Ou        return (byte[]) mValue;
8172523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
8182523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
8192523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
8202523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * Gets the {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL} data.
821c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *
822c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @exception IllegalArgumentException If the type is NOT
823c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *                {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}.
8242523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
825c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    protected Rational getRational(int index) {
8262523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        if ((mDataType != TYPE_RATIONAL) && (mDataType != TYPE_UNSIGNED_RATIONAL)) {
8272523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan            throw new IllegalArgumentException("Cannot get RATIONAL value from "
8282523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan                    + convertTypeToString(mDataType));
8292523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        }
830c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return ((Rational[]) mValue)[index];
8312523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
8322523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
8332523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
8342523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * Equivalent to getBytes(buffer, 0, buffer.length).
8352523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
836c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    protected void getBytes(byte[] buf) {
8372523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        getBytes(buf, 0, buf.length);
8382523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
8392523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
8402523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
8412523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * Gets the {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE} data.
8422523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     *
8432523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * @param buf the byte array in which to store the bytes read.
8442523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     * @param offset the initial position in buffer to store the bytes.
845c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @param length the maximum number of bytes to store in buffer. If length >
846c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *            component count, only the valid bytes will be stored.
847c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * @exception IllegalArgumentException If the type is NOT
848c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     *                {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE}.
8492523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
850c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    protected void getBytes(byte[] buf, int offset, int length) {
8512523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        if ((mDataType != TYPE_UNDEFINED) && (mDataType != TYPE_UNSIGNED_BYTE)) {
8522523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan            throw new IllegalArgumentException("Cannot get BYTE value from "
8532523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan                    + convertTypeToString(mDataType));
8542523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        }
8552523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        System.arraycopy(mValue, 0, buf, offset,
856c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                (length > mComponentCountActual) ? mComponentCountActual : length);
8572523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
8582523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
8592523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    /**
860c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Gets the offset of this tag. This is only valid if this data size > 4 and
861c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * contains an offset to the location of the actual value.
8622523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan     */
863c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    protected int getOffset() {
864c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return mOffset;
8652523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
8662523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan
8671c515f1aed514638cc030cd5cba5258231e74bb5Hung-ying Tyan    /**
868c274ded801f745d6318186958107622e7a4fef33Ruben Brunk     * Sets the offset of this tag.
8691c515f1aed514638cc030cd5cba5258231e74bb5Hung-ying Tyan     */
870c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    protected void setOffset(int offset) {
871c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        mOffset = offset;
872c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    }
873c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
874c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    protected void setHasDefinedCount(boolean d) {
875c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        mHasDefinedDefaultComponentCount = d;
876c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    }
877c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
878310ef8d4745a15f04e647b834a7d94e9dc7e1cabRuben Brunk    protected boolean hasDefinedCount() {
879310ef8d4745a15f04e647b834a7d94e9dc7e1cabRuben Brunk        return mHasDefinedDefaultComponentCount;
880310ef8d4745a15f04e647b834a7d94e9dc7e1cabRuben Brunk    }
881310ef8d4745a15f04e647b834a7d94e9dc7e1cabRuben Brunk
882c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    private boolean checkBadComponentCount(int count) {
883c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (mHasDefinedDefaultComponentCount && (mComponentCountActual != count)) {
884c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return true;
885c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        }
886c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return false;
887c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    }
888c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
889c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    private static String convertTypeToString(short type) {
890c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        switch (type) {
891c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            case TYPE_UNSIGNED_BYTE:
892c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                return "UNSIGNED_BYTE";
893c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            case TYPE_ASCII:
894c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                return "ASCII";
895c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            case TYPE_UNSIGNED_SHORT:
896c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                return "UNSIGNED_SHORT";
897c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            case TYPE_UNSIGNED_LONG:
898c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                return "UNSIGNED_LONG";
899c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            case TYPE_UNSIGNED_RATIONAL:
900c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                return "UNSIGNED_RATIONAL";
901c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            case TYPE_UNDEFINED:
902c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                return "UNDEFINED";
903c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            case TYPE_LONG:
904c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                return "LONG";
905c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            case TYPE_RATIONAL:
906c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                return "RATIONAL";
907c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            default:
908c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                return "";
909c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        }
910c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    }
911c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
912c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    private boolean checkOverflowForUnsignedShort(int[] value) {
913c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        for (int v : value) {
914c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            if (v > UNSIGNED_SHORT_MAX || v < 0) {
915c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                return true;
916c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            }
917c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        }
918c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return false;
9191c515f1aed514638cc030cd5cba5258231e74bb5Hung-ying Tyan    }
920c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
921c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    private boolean checkOverflowForUnsignedLong(long[] value) {
922c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        for (long v : value) {
923c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            if (v < 0 || v > UNSIGNED_LONG_MAX) {
924c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                return true;
925c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            }
926c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        }
927c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return false;
928c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    }
929c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
930c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    private boolean checkOverflowForUnsignedLong(int[] value) {
931c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        for (int v : value) {
932c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            if (v < 0) {
933c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                return true;
934c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            }
935c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        }
936c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return false;
937c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    }
938c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
939c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    private boolean checkOverflowForUnsignedRational(Rational[] value) {
940c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        for (Rational v : value) {
941c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            if (v.getNumerator() < 0 || v.getDenominator() < 0
942c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                    || v.getNumerator() > UNSIGNED_LONG_MAX
943c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                    || v.getDenominator() > UNSIGNED_LONG_MAX) {
944c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                return true;
945c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            }
946c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        }
947c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return false;
948c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    }
949c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
950c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    private boolean checkOverflowForRational(Rational[] value) {
951c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        for (Rational v : value) {
952c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            if (v.getNumerator() < LONG_MIN || v.getDenominator() < LONG_MIN
953c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                    || v.getNumerator() > LONG_MAX
954c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                    || v.getDenominator() > LONG_MAX) {
955c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                return true;
956c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            }
957c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        }
958c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return false;
959c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    }
960c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
9612523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    @Override
9622523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    public boolean equals(Object obj) {
963c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        if (obj == null) {
964c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            return false;
965c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        }
9662523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        if (obj instanceof ExifTag) {
9672523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan            ExifTag tag = (ExifTag) obj;
968c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            if (tag.mTagId != this.mTagId
969c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                    || tag.mComponentCountActual != this.mComponentCountActual
970c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                    || tag.mDataType != this.mDataType) {
971c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                return false;
972c274ded801f745d6318186958107622e7a4fef33Ruben Brunk            }
9732523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan            if (mValue != null) {
974c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                if (tag.mValue == null) {
975c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                    return false;
976c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                } else if (mValue instanceof long[]) {
977c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                    if (!(tag.mValue instanceof long[])) {
978c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                        return false;
979c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                    }
9802523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan                    return Arrays.equals((long[]) mValue, (long[]) tag.mValue);
9812523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan                } else if (mValue instanceof Rational[]) {
982c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                    if (!(tag.mValue instanceof Rational[])) {
983c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                        return false;
984c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                    }
9852523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan                    return Arrays.equals((Rational[]) mValue, (Rational[]) tag.mValue);
9862523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan                } else if (mValue instanceof byte[]) {
987c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                    if (!(tag.mValue instanceof byte[])) {
988c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                        return false;
989c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                    }
9902523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan                    return Arrays.equals((byte[]) mValue, (byte[]) tag.mValue);
9912523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan                } else {
9922523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan                    return mValue.equals(tag.mValue);
9932523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan                }
9942523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan            } else {
9952523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan                return tag.mValue == null;
9962523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan            }
9972523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        }
9982523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan        return false;
9992523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan    }
1000c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
1001c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    @Override
1002c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    public String toString() {
1003c274ded801f745d6318186958107622e7a4fef33Ruben Brunk        return String.format("tag id: %04X\n", mTagId) + "ifd id: " + mIfd + "\ntype: "
1004c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                + convertTypeToString(mDataType) + "\ncount: " + mComponentCountActual
1005c274ded801f745d6318186958107622e7a4fef33Ruben Brunk                + "\noffset: " + mOffset + "\nvalue: " + forceGetValueAsString() + "\n";
1006c274ded801f745d6318186958107622e7a4fef33Ruben Brunk    }
1007c274ded801f745d6318186958107622e7a4fef33Ruben Brunk
10082523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan}
1009