1e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka/* 2e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Copyright (C) 2012 The Android Open Source Project 3e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 4e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Licensed under the Apache License, Version 2.0 (the "License"); 5e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * you may not use this file except in compliance with the License. 6e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * You may obtain a copy of the License at 7e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 8e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * http://www.apache.org/licenses/LICENSE-2.0 9e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 10e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Unless required by applicable law or agreed to in writing, software 11e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * distributed under the License is distributed on an "AS IS" BASIS, 12e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * See the License for the specific language governing permissions and 14e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * limitations under the License. 15e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 16e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 17e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurkapackage com.android.gallery3d.exif; 18e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 19e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurkaimport java.nio.charset.Charset; 20e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurkaimport java.text.SimpleDateFormat; 21e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurkaimport java.util.Arrays; 22e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurkaimport java.util.Date; 23e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 24e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka/** 25e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * This class stores information of an EXIF tag. For more information about 26e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * defined EXIF tags, please read the Jeita EXIF 2.2 standard. Tags should be 27e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * instantiated using {@link ExifInterface#buildTag}. 28e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 29e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see ExifInterface 30e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 31e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurkapublic class ExifTag { 32e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 33e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * The BYTE type in the EXIF standard. An 8-bit unsigned integer. 34e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 35e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public static final short TYPE_UNSIGNED_BYTE = 1; 36e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 37e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * The ASCII type in the EXIF standard. An 8-bit byte containing one 7-bit 38e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * ASCII code. The final byte is terminated with NULL. 39e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 40e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public static final short TYPE_ASCII = 2; 41e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 42e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * The SHORT type in the EXIF standard. A 16-bit (2-byte) unsigned integer 43e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 44e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public static final short TYPE_UNSIGNED_SHORT = 3; 45e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 46e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * The LONG type in the EXIF standard. A 32-bit (4-byte) unsigned integer 47e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 48e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public static final short TYPE_UNSIGNED_LONG = 4; 49e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 50e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * The RATIONAL type of EXIF standard. It consists of two LONGs. The first 51e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * one is the numerator and the second one expresses the denominator. 52e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 53e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public static final short TYPE_UNSIGNED_RATIONAL = 5; 54e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 55e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * The UNDEFINED type in the EXIF standard. An 8-bit byte that can take any 56e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * value depending on the field definition. 57e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 58e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public static final short TYPE_UNDEFINED = 7; 59e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 60e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * The SLONG type in the EXIF standard. A 32-bit (4-byte) signed integer 61e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * (2's complement notation). 62e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 63e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public static final short TYPE_LONG = 9; 64e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 65e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * The SRATIONAL type of EXIF standard. It consists of two SLONGs. The first 66e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * one is the numerator and the second one is the denominator. 67e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 68e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public static final short TYPE_RATIONAL = 10; 69e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 70e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private static Charset US_ASCII = Charset.forName("US-ASCII"); 71e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private static final int TYPE_TO_SIZE_MAP[] = new int[11]; 72e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private static final int UNSIGNED_SHORT_MAX = 65535; 73e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private static final long UNSIGNED_LONG_MAX = 4294967295L; 74e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private static final long LONG_MAX = Integer.MAX_VALUE; 75e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private static final long LONG_MIN = Integer.MIN_VALUE; 76e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 77e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka static { 78e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_BYTE] = 1; 79e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka TYPE_TO_SIZE_MAP[TYPE_ASCII] = 1; 80e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_SHORT] = 2; 81e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_LONG] = 4; 82e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_RATIONAL] = 8; 83e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka TYPE_TO_SIZE_MAP[TYPE_UNDEFINED] = 1; 84e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka TYPE_TO_SIZE_MAP[TYPE_LONG] = 4; 85e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka TYPE_TO_SIZE_MAP[TYPE_RATIONAL] = 8; 86e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 87e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 88e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka static final int SIZE_UNDEFINED = 0; 89e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 90e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka // Exif TagId 91e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private final short mTagId; 92e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka // Exif Tag Type 93e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private final short mDataType; 94e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka // If tag has defined count 95e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private boolean mHasDefinedDefaultComponentCount; 96e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka // Actual data count in tag (should be number of elements in value array) 97e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private int mComponentCountActual; 98e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka // The ifd that this tag should be put in 99e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private int mIfd; 100e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka // The value (array of elements of type Tag Type) 101e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private Object mValue; 102e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka // Value offset in exif header. 103e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private int mOffset; 104e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 105e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("yyyy:MM:dd kk:mm:ss"); 106e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 107e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 108e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Returns true if the given IFD is a valid IFD. 109e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 110e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public static boolean isValidIfd(int ifdId) { 111e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return ifdId == IfdId.TYPE_IFD_0 || ifdId == IfdId.TYPE_IFD_1 112e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka || ifdId == IfdId.TYPE_IFD_EXIF || ifdId == IfdId.TYPE_IFD_INTEROPERABILITY 113e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka || ifdId == IfdId.TYPE_IFD_GPS; 114e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 115e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 116e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 117e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Returns true if a given type is a valid tag type. 118e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 119e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public static boolean isValidType(short type) { 120e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return type == TYPE_UNSIGNED_BYTE || type == TYPE_ASCII || 121e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka type == TYPE_UNSIGNED_SHORT || type == TYPE_UNSIGNED_LONG || 122e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka type == TYPE_UNSIGNED_RATIONAL || type == TYPE_UNDEFINED || 123e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka type == TYPE_LONG || type == TYPE_RATIONAL; 124e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 125e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 126e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka // Use builtTag in ExifInterface instead of constructor. 127e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka ExifTag(short tagId, short type, int componentCount, int ifd, 128e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka boolean hasDefinedComponentCount) { 129e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mTagId = tagId; 130e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mDataType = type; 131e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mComponentCountActual = componentCount; 132e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mHasDefinedDefaultComponentCount = hasDefinedComponentCount; 133e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mIfd = ifd; 134e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mValue = null; 135e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 136e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 137e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 138e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the element size of the given data type in bytes. 139e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 140e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see #TYPE_ASCII 141e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see #TYPE_LONG 142e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see #TYPE_RATIONAL 143e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see #TYPE_UNDEFINED 144e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see #TYPE_UNSIGNED_BYTE 145e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see #TYPE_UNSIGNED_LONG 146e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see #TYPE_UNSIGNED_RATIONAL 147e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see #TYPE_UNSIGNED_SHORT 148e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 149e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public static int getElementSize(short type) { 150e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return TYPE_TO_SIZE_MAP[type]; 151e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 152e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 153e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 154e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Returns the ID of the IFD this tag belongs to. 155e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 156e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see IfdId#TYPE_IFD_0 157e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see IfdId#TYPE_IFD_1 158e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see IfdId#TYPE_IFD_EXIF 159e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see IfdId#TYPE_IFD_GPS 160e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see IfdId#TYPE_IFD_INTEROPERABILITY 161e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 162e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public int getIfd() { 163e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return mIfd; 164e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 165e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 166e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka protected void setIfd(int ifdId) { 167e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mIfd = ifdId; 168e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 169e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 170e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 171e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the TID of this tag. 172e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 173e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public short getTagId() { 174e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return mTagId; 175e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 176e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 177e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 178e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the data type of this tag 179e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 180e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see #TYPE_ASCII 181e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see #TYPE_LONG 182e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see #TYPE_RATIONAL 183e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see #TYPE_UNDEFINED 184e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see #TYPE_UNSIGNED_BYTE 185e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see #TYPE_UNSIGNED_LONG 186e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see #TYPE_UNSIGNED_RATIONAL 187e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see #TYPE_UNSIGNED_SHORT 188e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 189e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public short getDataType() { 190e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return mDataType; 191e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 192e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 193e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 194e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the total data size in bytes of the value of this tag. 195e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 196e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public int getDataSize() { 197e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return getComponentCount() * getElementSize(getDataType()); 198e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 199e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 200e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 201e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the component count of this tag. 202e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 203e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 204e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka // TODO: fix integer overflows with this 205e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public int getComponentCount() { 206e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return mComponentCountActual; 207e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 208e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 209e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 210e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Sets the component count of this tag. Call this function before 211e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * setValue() if the length of value does not match the component count. 212e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 213e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka protected void forceSetComponentCount(int count) { 214e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mComponentCountActual = count; 215e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 216e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 217e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 218e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Returns true if this ExifTag contains value; otherwise, this tag will 219e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * contain an offset value that is determined when the tag is written. 220e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 221e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public boolean hasValue() { 222e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return mValue != null; 223e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 224e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 225e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 226e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Sets integer values into this tag. This method should be used for tags of 227e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * type {@link #TYPE_UNSIGNED_SHORT}. This method will fail if: 228e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <ul> 229e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_SHORT}, 230e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * {@link #TYPE_UNSIGNED_LONG}, or {@link #TYPE_LONG}.</li> 231e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The value overflows.</li> 232e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The value.length does NOT match the component count in the definition 233e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * for this tag.</li> 234e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * </ul> 235e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 236e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public boolean setValue(int[] value) { 237e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (checkBadComponentCount(value.length)) { 238e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 239e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 240e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (mDataType != TYPE_UNSIGNED_SHORT && mDataType != TYPE_LONG && 241e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mDataType != TYPE_UNSIGNED_LONG) { 242e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 243e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 244e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (mDataType == TYPE_UNSIGNED_SHORT && checkOverflowForUnsignedShort(value)) { 245e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 246e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (mDataType == TYPE_UNSIGNED_LONG && checkOverflowForUnsignedLong(value)) { 247e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 248e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 249e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 250e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka long[] data = new long[value.length]; 251e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka for (int i = 0; i < value.length; i++) { 252e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka data[i] = value[i]; 253e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 254e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mValue = data; 255e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mComponentCountActual = value.length; 256e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return true; 257e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 258e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 259e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 260e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Sets integer value into this tag. This method should be used for tags of 261e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * type {@link #TYPE_UNSIGNED_SHORT}, or {@link #TYPE_LONG}. This method 262e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * will fail if: 263e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <ul> 264e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_SHORT}, 265e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * {@link #TYPE_UNSIGNED_LONG}, or {@link #TYPE_LONG}.</li> 266e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The value overflows.</li> 267e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The component count in the definition of this tag is not 1.</li> 268e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * </ul> 269e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 270e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public boolean setValue(int value) { 271e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return setValue(new int[] { 272e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka value 273e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka }); 274e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 275e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 276e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 277e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Sets long values into this tag. This method should be used for tags of 278e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * type {@link #TYPE_UNSIGNED_LONG}. This method will fail if: 279e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <ul> 280e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_LONG}.</li> 281e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The value overflows.</li> 282e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The value.length does NOT match the component count in the definition 283e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * for this tag.</li> 284e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * </ul> 285e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 286e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public boolean setValue(long[] value) { 287e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (checkBadComponentCount(value.length) || mDataType != TYPE_UNSIGNED_LONG) { 288e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 289e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 290e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (checkOverflowForUnsignedLong(value)) { 291e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 292e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 293e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mValue = value; 294e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mComponentCountActual = value.length; 295e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return true; 296e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 297e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 298e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 299e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Sets long values into this tag. This method should be used for tags of 300e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * type {@link #TYPE_UNSIGNED_LONG}. This method will fail if: 301e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <ul> 302e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_LONG}.</li> 303e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The value overflows.</li> 304e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The component count in the definition for this tag is not 1.</li> 305e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * </ul> 306e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 307e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public boolean setValue(long value) { 308e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return setValue(new long[] { 309e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka value 310e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka }); 311e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 312e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 313e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 314e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Sets a string value into this tag. This method should be used for tags of 315e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * type {@link #TYPE_ASCII}. The string is converted to an ASCII string. 316e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Characters that cannot be converted are replaced with '?'. The length of 317e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * the string must be equal to either (component count -1) or (component 318e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * count). The final byte will be set to the string null terminator '\0', 319e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * overwriting the last character in the string if the value.length is equal 320e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * to the component count. This method will fail if: 321e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <ul> 322e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The data type is not {@link #TYPE_ASCII} or {@link #TYPE_UNDEFINED}.</li> 323e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The length of the string is not equal to (component count -1) or 324e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * (component count) in the definition for this tag.</li> 325e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * </ul> 326e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 327e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public boolean setValue(String value) { 328e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (mDataType != TYPE_ASCII && mDataType != TYPE_UNDEFINED) { 329e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 330e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 331e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 332e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka byte[] buf = value.getBytes(US_ASCII); 333e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka byte[] finalBuf = buf; 334e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (buf.length > 0) { 335e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka finalBuf = (buf[buf.length - 1] == 0 || mDataType == TYPE_UNDEFINED) ? buf : Arrays 336e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka .copyOf(buf, buf.length + 1); 337e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (mDataType == TYPE_ASCII && mComponentCountActual == 1) { 338e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka finalBuf = new byte[] { 0 }; 339e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 340e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka int count = finalBuf.length; 341e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (checkBadComponentCount(count)) { 342e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 343e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 344e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mComponentCountActual = count; 345e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mValue = finalBuf; 346e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return true; 347e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 348e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 349e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 350e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Sets Rational values into this tag. This method should be used for tags 351e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * of type {@link #TYPE_UNSIGNED_RATIONAL}, or {@link #TYPE_RATIONAL}. This 352e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * method will fail if: 353e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <ul> 354e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_RATIONAL} 355e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * or {@link #TYPE_RATIONAL}.</li> 356e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The value overflows.</li> 357e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The value.length does NOT match the component count in the definition 358e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * for this tag.</li> 359e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * </ul> 360e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 361e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see Rational 362e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 363e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public boolean setValue(Rational[] value) { 364e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (checkBadComponentCount(value.length)) { 365e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 366e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 367e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (mDataType != TYPE_UNSIGNED_RATIONAL && mDataType != TYPE_RATIONAL) { 368e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 369e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 370e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (mDataType == TYPE_UNSIGNED_RATIONAL && checkOverflowForUnsignedRational(value)) { 371e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 372e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (mDataType == TYPE_RATIONAL && checkOverflowForRational(value)) { 373e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 374e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 375e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 376e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mValue = value; 377e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mComponentCountActual = value.length; 378e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return true; 379e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 380e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 381e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 382e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Sets a Rational value into this tag. This method should be used for tags 383e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * of type {@link #TYPE_UNSIGNED_RATIONAL}, or {@link #TYPE_RATIONAL}. This 384e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * method will fail if: 385e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <ul> 386e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_RATIONAL} 387e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * or {@link #TYPE_RATIONAL}.</li> 388e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The value overflows.</li> 389e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The component count in the definition for this tag is not 1.</li> 390e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * </ul> 391e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 392e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see Rational 393e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 394e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public boolean setValue(Rational value) { 395e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return setValue(new Rational[] { 396e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka value 397e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka }); 398e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 399e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 400e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 401e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Sets byte values into this tag. This method should be used for tags of 402e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * type {@link #TYPE_UNSIGNED_BYTE} or {@link #TYPE_UNDEFINED}. This method 403e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * will fail if: 404e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <ul> 405e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_BYTE} or 406e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * {@link #TYPE_UNDEFINED} .</li> 407e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The length does NOT match the component count in the definition for 408e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * this tag.</li> 409e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * </ul> 410e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 411e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public boolean setValue(byte[] value, int offset, int length) { 412e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (checkBadComponentCount(length)) { 413e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 414e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 415e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (mDataType != TYPE_UNSIGNED_BYTE && mDataType != TYPE_UNDEFINED) { 416e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 417e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 418e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mValue = new byte[length]; 419e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka System.arraycopy(value, offset, mValue, 0, length); 420e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mComponentCountActual = length; 421e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return true; 422e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 423e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 424e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 425e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Equivalent to setValue(value, 0, value.length). 426e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 427e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public boolean setValue(byte[] value) { 428e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return setValue(value, 0, value.length); 429e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 430e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 431e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 432e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Sets byte value into this tag. This method should be used for tags of 433e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * type {@link #TYPE_UNSIGNED_BYTE} or {@link #TYPE_UNDEFINED}. This method 434e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * will fail if: 435e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <ul> 436e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_BYTE} or 437e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * {@link #TYPE_UNDEFINED} .</li> 438e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The component count in the definition for this tag is not 1.</li> 439e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * </ul> 440e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 441e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public boolean setValue(byte value) { 442e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return setValue(new byte[] { 443e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka value 444e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka }); 445e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 446e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 447e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 448e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Sets the value for this tag using an appropriate setValue method for the 449e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * given object. This method will fail if: 450e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <ul> 451e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>The corresponding setValue method for the class of the object passed 452e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * in would fail.</li> 453e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * <li>There is no obvious way to cast the object passed in into an EXIF tag 454e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * type.</li> 455e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * </ul> 456e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 457e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public boolean setValue(Object obj) { 458e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (obj == null) { 459e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 460e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (obj instanceof Short) { 461e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return setValue(((Short) obj).shortValue() & 0x0ffff); 462e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (obj instanceof String) { 463e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return setValue((String) obj); 464e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (obj instanceof int[]) { 465e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return setValue((int[]) obj); 466e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (obj instanceof long[]) { 467e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return setValue((long[]) obj); 468e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (obj instanceof Rational) { 469e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return setValue((Rational) obj); 470e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (obj instanceof Rational[]) { 471e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return setValue((Rational[]) obj); 472e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (obj instanceof byte[]) { 473e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return setValue((byte[]) obj); 474e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (obj instanceof Integer) { 475e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return setValue(((Integer) obj).intValue()); 476e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (obj instanceof Long) { 477e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return setValue(((Long) obj).longValue()); 478e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (obj instanceof Byte) { 479e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return setValue(((Byte) obj).byteValue()); 480e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (obj instanceof Short[]) { 481e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka // Nulls in this array are treated as zeroes. 482e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka Short[] arr = (Short[]) obj; 483e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka int[] fin = new int[arr.length]; 484e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka for (int i = 0; i < arr.length; i++) { 485e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka fin[i] = (arr[i] == null) ? 0 : arr[i].shortValue() & 0x0ffff; 486e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 487e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return setValue(fin); 488e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (obj instanceof Integer[]) { 489e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka // Nulls in this array are treated as zeroes. 490e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka Integer[] arr = (Integer[]) obj; 491e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka int[] fin = new int[arr.length]; 492e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka for (int i = 0; i < arr.length; i++) { 493e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka fin[i] = (arr[i] == null) ? 0 : arr[i].intValue(); 494e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 495e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return setValue(fin); 496e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (obj instanceof Long[]) { 497e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka // Nulls in this array are treated as zeroes. 498e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka Long[] arr = (Long[]) obj; 499e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka long[] fin = new long[arr.length]; 500e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka for (int i = 0; i < arr.length; i++) { 501e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka fin[i] = (arr[i] == null) ? 0 : arr[i].longValue(); 502e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 503e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return setValue(fin); 504e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (obj instanceof Byte[]) { 505e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka // Nulls in this array are treated as zeroes. 506e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka Byte[] arr = (Byte[]) obj; 507e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka byte[] fin = new byte[arr.length]; 508e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka for (int i = 0; i < arr.length; i++) { 509e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka fin[i] = (arr[i] == null) ? 0 : arr[i].byteValue(); 510e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 511e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return setValue(fin); 512e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else { 513e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 514e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 515e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 516e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 517e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 518e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Sets a timestamp to this tag. The method converts the timestamp with the 519e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * format of "yyyy:MM:dd kk:mm:ss" and calls {@link #setValue(String)}. This 520e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * method will fail if the data type is not {@link #TYPE_ASCII} or the 521e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * component count of this tag is not 20 or undefined. 522e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 523e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @param time the number of milliseconds since Jan. 1, 1970 GMT 524e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @return true on success 525e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 526e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public boolean setTimeValue(long time) { 527e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka // synchronized on TIME_FORMAT as SimpleDateFormat is not thread safe 528e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka synchronized (TIME_FORMAT) { 529e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return setValue(TIME_FORMAT.format(new Date(time))); 530e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 531e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 532e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 533e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 534e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the value as a String. This method should be used for tags of type 535e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * {@link #TYPE_ASCII}. 536e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 537e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @return the value as a String, or null if the tag's value does not exist 538e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * or cannot be converted to a String. 539e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 540e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public String getValueAsString() { 541e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (mValue == null) { 542e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return null; 543e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (mValue instanceof String) { 544e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return (String) mValue; 545e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (mValue instanceof byte[]) { 546e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return new String((byte[]) mValue, US_ASCII); 547e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 548e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return null; 549e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 550e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 551e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 552e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the value as a String. This method should be used for tags of type 553e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * {@link #TYPE_ASCII}. 554e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 555e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @param defaultValue the String to return if the tag's value does not 556e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * exist or cannot be converted to a String. 557e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @return the tag's value as a String, or the defaultValue. 558e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 559e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public String getValueAsString(String defaultValue) { 560e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka String s = getValueAsString(); 561e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (s == null) { 562e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return defaultValue; 563e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 564e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return s; 565e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 566e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 567e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 568e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the value as a byte array. This method should be used for tags of 569e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * type {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE}. 570e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 571e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @return the value as a byte array, or null if the tag's value does not 572e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * exist or cannot be converted to a byte array. 573e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 574e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public byte[] getValueAsBytes() { 575e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (mValue instanceof byte[]) { 576e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return (byte[]) mValue; 577e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 578e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return null; 579e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 580e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 581e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 582e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the value as a byte. If there are more than 1 bytes in this value, 583e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * gets the first byte. This method should be used for tags of type 584e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE}. 585e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 586e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @param defaultValue the byte to return if tag's value does not exist or 587e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * cannot be converted to a byte. 588e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @return the tag's value as a byte, or the defaultValue. 589e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 590e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public byte getValueAsByte(byte defaultValue) { 591e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka byte[] b = getValueAsBytes(); 592e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (b == null || b.length < 1) { 593e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return defaultValue; 594e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 595e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return b[0]; 596e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 597e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 598e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 599e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the value as an array of Rationals. This method should be used for 600e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * tags of type {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}. 601e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 602e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @return the value as as an array of Rationals, or null if the tag's value 603e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * does not exist or cannot be converted to an array of Rationals. 604e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 605e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public Rational[] getValueAsRationals() { 606e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (mValue instanceof Rational[]) { 607e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return (Rational[]) mValue; 608e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 609e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return null; 610e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 611e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 612e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 613e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the value as a Rational. If there are more than 1 Rationals in this 614e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * value, gets the first one. This method should be used for tags of type 615e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}. 616e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 617e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @param defaultValue the Rational to return if tag's value does not exist 618e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * or cannot be converted to a Rational. 619e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @return the tag's value as a Rational, or the defaultValue. 620e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 621e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public Rational getValueAsRational(Rational defaultValue) { 622e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka Rational[] r = getValueAsRationals(); 623e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (r == null || r.length < 1) { 624e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return defaultValue; 625e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 626e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return r[0]; 627e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 628e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 629e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 630e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the value as a Rational. If there are more than 1 Rationals in this 631e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * value, gets the first one. This method should be used for tags of type 632e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}. 633e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 634e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @param defaultValue the numerator of the Rational to return if tag's 635e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * value does not exist or cannot be converted to a Rational (the 636e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * denominator will be 1). 637e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @return the tag's value as a Rational, or the defaultValue. 638e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 639e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public Rational getValueAsRational(long defaultValue) { 640e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka Rational defaultVal = new Rational(defaultValue, 1); 641e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return getValueAsRational(defaultVal); 642e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 643e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 644e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 645e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the value as an array of ints. This method should be used for tags 646e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * of type {@link #TYPE_UNSIGNED_SHORT}, {@link #TYPE_UNSIGNED_LONG}. 647e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 648e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @return the value as as an array of ints, or null if the tag's value does 649e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * not exist or cannot be converted to an array of ints. 650e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 651e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public int[] getValueAsInts() { 652e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (mValue == null) { 653e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return null; 654e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (mValue instanceof long[]) { 655e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka long[] val = (long[]) mValue; 656e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka int[] arr = new int[val.length]; 657e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka for (int i = 0; i < val.length; i++) { 658e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka arr[i] = (int) val[i]; // Truncates 659e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 660e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return arr; 661e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 662e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return null; 663e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 664e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 665e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 666e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the value as an int. If there are more than 1 ints in this value, 667e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * gets the first one. This method should be used for tags of type 668e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * {@link #TYPE_UNSIGNED_SHORT}, {@link #TYPE_UNSIGNED_LONG}. 669e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 670e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @param defaultValue the int to return if tag's value does not exist or 671e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * cannot be converted to an int. 672e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @return the tag's value as a int, or the defaultValue. 673e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 674e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public int getValueAsInt(int defaultValue) { 675e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka int[] i = getValueAsInts(); 676e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (i == null || i.length < 1) { 677e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return defaultValue; 678e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 679e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return i[0]; 680e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 681e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 682e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 683e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the value as an array of longs. This method should be used for tags 684e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * of type {@link #TYPE_UNSIGNED_LONG}. 685e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 686e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @return the value as as an array of longs, or null if the tag's value 687e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * does not exist or cannot be converted to an array of longs. 688e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 689e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public long[] getValueAsLongs() { 690e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (mValue instanceof long[]) { 691e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return (long[]) mValue; 692e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 693e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return null; 694e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 695e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 696e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 697e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the value or null if none exists. If there are more than 1 longs in 698e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * this value, gets the first one. This method should be used for tags of 699e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * type {@link #TYPE_UNSIGNED_LONG}. 700e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 701e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @param defaultValue the long to return if tag's value does not exist or 702e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * cannot be converted to a long. 703e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @return the tag's value as a long, or the defaultValue. 704e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 705e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public long getValueAsLong(long defaultValue) { 706e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka long[] l = getValueAsLongs(); 707e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (l == null || l.length < 1) { 708e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return defaultValue; 709e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 710e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return l[0]; 711e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 712e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 713e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 714e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the tag's value or null if none exists. 715e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 716e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public Object getValue() { 717e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return mValue; 718e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 719e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 720e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 721e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets a long representation of the value. 722e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 723e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @param defaultValue value to return if there is no value or value is a 724e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * rational with a denominator of 0. 725e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @return the tag's value as a long, or defaultValue if no representation 726e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * exists. 727e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 728e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public long forceGetValueAsLong(long defaultValue) { 729e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka long[] l = getValueAsLongs(); 730e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (l != null && l.length >= 1) { 731e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return l[0]; 732e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 733e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka byte[] b = getValueAsBytes(); 734e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (b != null && b.length >= 1) { 735e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return b[0]; 736e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 737e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka Rational[] r = getValueAsRationals(); 738e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (r != null && r.length >= 1 && r[0].getDenominator() != 0) { 739e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return (long) r[0].toDouble(); 740e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 741e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return defaultValue; 742e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 743e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 744e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 745e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets a string representation of the value. 746e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 747e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public String forceGetValueAsString() { 748e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (mValue == null) { 749e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return ""; 750e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (mValue instanceof byte[]) { 751e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (mDataType == TYPE_ASCII) { 752e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return new String((byte[]) mValue, US_ASCII); 753e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else { 754e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return Arrays.toString((byte[]) mValue); 755e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 756e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (mValue instanceof long[]) { 757e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (((long[]) mValue).length == 1) { 758e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return String.valueOf(((long[]) mValue)[0]); 759e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else { 760e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return Arrays.toString((long[]) mValue); 761e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 762e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (mValue instanceof Object[]) { 763e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (((Object[]) mValue).length == 1) { 764e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka Object val = ((Object[]) mValue)[0]; 765e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (val == null) { 766e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return ""; 767e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else { 768e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return val.toString(); 769e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 770e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else { 771e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return Arrays.toString((Object[]) mValue); 772e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 773e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else { 774e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return mValue.toString(); 775e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 776e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 777e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 778e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 779e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the value for type {@link #TYPE_ASCII}, {@link #TYPE_LONG}, 780e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * {@link #TYPE_UNDEFINED}, {@link #TYPE_UNSIGNED_BYTE}, 781e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * {@link #TYPE_UNSIGNED_LONG}, or {@link #TYPE_UNSIGNED_SHORT}. For 782e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}, call 783e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * {@link #getRational(int)} instead. 784e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 785e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @exception IllegalArgumentException if the data type is 786e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}. 787e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 788e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka protected long getValueAt(int index) { 789e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (mValue instanceof long[]) { 790e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return ((long[]) mValue)[index]; 791e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (mValue instanceof byte[]) { 792e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return ((byte[]) mValue)[index]; 793e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 794e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka throw new IllegalArgumentException("Cannot get integer value from " 795e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka + convertTypeToString(mDataType)); 796e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 797e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 798e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 799e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the {@link #TYPE_ASCII} data. 800e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 801e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @exception IllegalArgumentException If the type is NOT 802e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * {@link #TYPE_ASCII}. 803e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 804e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka protected String getString() { 805e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (mDataType != TYPE_ASCII) { 806e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka throw new IllegalArgumentException("Cannot get ASCII value from " 807e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka + convertTypeToString(mDataType)); 808e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 809e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return new String((byte[]) mValue, US_ASCII); 810e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 811e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 812e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /* 813e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Get the converted ascii byte. Used by ExifOutputStream. 814e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 815e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka protected byte[] getStringByte() { 816e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return (byte[]) mValue; 817e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 818e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 819e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 820e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL} data. 821e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 822e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @exception IllegalArgumentException If the type is NOT 823e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}. 824e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 825e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka protected Rational getRational(int index) { 826e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if ((mDataType != TYPE_RATIONAL) && (mDataType != TYPE_UNSIGNED_RATIONAL)) { 827e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka throw new IllegalArgumentException("Cannot get RATIONAL value from " 828e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka + convertTypeToString(mDataType)); 829e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 830e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return ((Rational[]) mValue)[index]; 831e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 832e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 833e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 834e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Equivalent to getBytes(buffer, 0, buffer.length). 835e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 836e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka protected void getBytes(byte[] buf) { 837e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka getBytes(buf, 0, buf.length); 838e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 839e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 840e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 841e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE} data. 842e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 843e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @param buf the byte array in which to store the bytes read. 844e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @param offset the initial position in buffer to store the bytes. 845e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @param length the maximum number of bytes to store in buffer. If length > 846e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * component count, only the valid bytes will be stored. 847e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @exception IllegalArgumentException If the type is NOT 848e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE}. 849e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 850e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka protected void getBytes(byte[] buf, int offset, int length) { 851e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if ((mDataType != TYPE_UNDEFINED) && (mDataType != TYPE_UNSIGNED_BYTE)) { 852e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka throw new IllegalArgumentException("Cannot get BYTE value from " 853e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka + convertTypeToString(mDataType)); 854e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 855e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka System.arraycopy(mValue, 0, buf, offset, 856e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka (length > mComponentCountActual) ? mComponentCountActual : length); 857e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 858e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 859e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 860e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the offset of this tag. This is only valid if this data size > 4 and 861e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * contains an offset to the location of the actual value. 862e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 863e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka protected int getOffset() { 864e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return mOffset; 865e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 866e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 867e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 868e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Sets the offset of this tag. 869e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 870e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka protected void setOffset(int offset) { 871e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mOffset = offset; 872e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 873e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 874e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka protected void setHasDefinedCount(boolean d) { 875e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mHasDefinedDefaultComponentCount = d; 876e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 877e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 878e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka protected boolean hasDefinedCount() { 879e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return mHasDefinedDefaultComponentCount; 880e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 881e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 882e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private boolean checkBadComponentCount(int count) { 883e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (mHasDefinedDefaultComponentCount && (mComponentCountActual != count)) { 884e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return true; 885e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 886e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 887e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 888e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 889e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private static String convertTypeToString(short type) { 890e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka switch (type) { 891e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka case TYPE_UNSIGNED_BYTE: 892e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return "UNSIGNED_BYTE"; 893e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka case TYPE_ASCII: 894e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return "ASCII"; 895e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka case TYPE_UNSIGNED_SHORT: 896e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return "UNSIGNED_SHORT"; 897e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka case TYPE_UNSIGNED_LONG: 898e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return "UNSIGNED_LONG"; 899e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka case TYPE_UNSIGNED_RATIONAL: 900e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return "UNSIGNED_RATIONAL"; 901e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka case TYPE_UNDEFINED: 902e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return "UNDEFINED"; 903e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka case TYPE_LONG: 904e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return "LONG"; 905e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka case TYPE_RATIONAL: 906e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return "RATIONAL"; 907e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka default: 908e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return ""; 909e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 910e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 911e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 912e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private boolean checkOverflowForUnsignedShort(int[] value) { 913e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka for (int v : value) { 914e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (v > UNSIGNED_SHORT_MAX || v < 0) { 915e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return true; 916e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 917e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 918e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 919e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 920e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 921e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private boolean checkOverflowForUnsignedLong(long[] value) { 922e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka for (long v : value) { 923e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (v < 0 || v > UNSIGNED_LONG_MAX) { 924e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return true; 925e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 926e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 927e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 928e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 929e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 930e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private boolean checkOverflowForUnsignedLong(int[] value) { 931e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka for (int v : value) { 932e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (v < 0) { 933e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return true; 934e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 935e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 936e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 937e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 938e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 939e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private boolean checkOverflowForUnsignedRational(Rational[] value) { 940e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka for (Rational v : value) { 941e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (v.getNumerator() < 0 || v.getDenominator() < 0 942e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka || v.getNumerator() > UNSIGNED_LONG_MAX 943e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka || v.getDenominator() > UNSIGNED_LONG_MAX) { 944e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return true; 945e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 946e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 947e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 948e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 949e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 950e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private boolean checkOverflowForRational(Rational[] value) { 951e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka for (Rational v : value) { 952e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (v.getNumerator() < LONG_MIN || v.getDenominator() < LONG_MIN 953e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka || v.getNumerator() > LONG_MAX 954e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka || v.getDenominator() > LONG_MAX) { 955e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return true; 956e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 957e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 958e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 959e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 960e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 961e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka @Override 962e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public boolean equals(Object obj) { 963e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (obj == null) { 964e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 965e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 966e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (obj instanceof ExifTag) { 967e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka ExifTag tag = (ExifTag) obj; 968e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (tag.mTagId != this.mTagId 969e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka || tag.mComponentCountActual != this.mComponentCountActual 970e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka || tag.mDataType != this.mDataType) { 971e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 972e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 973e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (mValue != null) { 974e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (tag.mValue == null) { 975e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 976e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (mValue instanceof long[]) { 977e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (!(tag.mValue instanceof long[])) { 978e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 979e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 980e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return Arrays.equals((long[]) mValue, (long[]) tag.mValue); 981e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (mValue instanceof Rational[]) { 982e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (!(tag.mValue instanceof Rational[])) { 983e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 984e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 985e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return Arrays.equals((Rational[]) mValue, (Rational[]) tag.mValue); 986e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else if (mValue instanceof byte[]) { 987e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (!(tag.mValue instanceof byte[])) { 988e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 989e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 990e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return Arrays.equals((byte[]) mValue, (byte[]) tag.mValue); 991e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else { 992e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return mValue.equals(tag.mValue); 993e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 994e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } else { 995e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return tag.mValue == null; 996e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 997e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 998e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 999e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 1000e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 1001e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka @Override 1002e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public String toString() { 1003e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return String.format("tag id: %04X\n", mTagId) + "ifd id: " + mIfd + "\ntype: " 1004e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka + convertTypeToString(mDataType) + "\ncount: " + mComponentCountActual 1005e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka + "\noffset: " + mOffset + "\nvalue: " + forceGetValueAsString() + "\n"; 1006e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 1007e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 1008e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka} 1009