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