1104c45677660586026a7e74ef8c47d396403d50eMichael Jurka/* 2104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Copyright (C) 2012 The Android Open Source Project 3104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 4104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Licensed under the Apache License, Version 2.0 (the "License"); 5104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * you may not use this file except in compliance with the License. 6104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * You may obtain a copy of the License at 7104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 8104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * http://www.apache.org/licenses/LICENSE-2.0 9104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 10104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Unless required by applicable law or agreed to in writing, software 11104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * distributed under the License is distributed on an "AS IS" BASIS, 12104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * See the License for the specific language governing permissions and 14104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * limitations under the License. 15104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 16104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 17104c45677660586026a7e74ef8c47d396403d50eMichael Jurkapackage com.android.gallery3d.exif; 18104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 19104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport java.nio.charset.Charset; 20104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport java.text.SimpleDateFormat; 21104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport java.util.Arrays; 22104c45677660586026a7e74ef8c47d396403d50eMichael Jurkaimport java.util.Date; 23104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 24104c45677660586026a7e74ef8c47d396403d50eMichael Jurka/** 25104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * This class stores information of an EXIF tag. For more information about 26104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * defined EXIF tags, please read the Jeita EXIF 2.2 standard. Tags should be 27104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * instantiated using {@link ExifInterface#buildTag}. 28104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 29104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see ExifInterface 30104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 31104c45677660586026a7e74ef8c47d396403d50eMichael Jurkapublic class ExifTag { 32104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 33104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * The BYTE type in the EXIF standard. An 8-bit unsigned integer. 34104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 35104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public static final short TYPE_UNSIGNED_BYTE = 1; 36104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 37104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * The ASCII type in the EXIF standard. An 8-bit byte containing one 7-bit 38104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * ASCII code. The final byte is terminated with NULL. 39104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 40104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public static final short TYPE_ASCII = 2; 41104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 42104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * The SHORT type in the EXIF standard. A 16-bit (2-byte) unsigned integer 43104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 44104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public static final short TYPE_UNSIGNED_SHORT = 3; 45104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 46104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * The LONG type in the EXIF standard. A 32-bit (4-byte) unsigned integer 47104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 48104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public static final short TYPE_UNSIGNED_LONG = 4; 49104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 50104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * The RATIONAL type of EXIF standard. It consists of two LONGs. The first 51104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * one is the numerator and the second one expresses the denominator. 52104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 53104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public static final short TYPE_UNSIGNED_RATIONAL = 5; 54104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 55104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * The UNDEFINED type in the EXIF standard. An 8-bit byte that can take any 56104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * value depending on the field definition. 57104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 58104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public static final short TYPE_UNDEFINED = 7; 59104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 60104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * The SLONG type in the EXIF standard. A 32-bit (4-byte) signed integer 61104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * (2's complement notation). 62104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 63104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public static final short TYPE_LONG = 9; 64104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 65104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * The SRATIONAL type of EXIF standard. It consists of two SLONGs. The first 66104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * one is the numerator and the second one is the denominator. 67104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 68104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public static final short TYPE_RATIONAL = 10; 69104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 70104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private static Charset US_ASCII = Charset.forName("US-ASCII"); 71104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private static final int TYPE_TO_SIZE_MAP[] = new int[11]; 72104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private static final int UNSIGNED_SHORT_MAX = 65535; 73104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private static final long UNSIGNED_LONG_MAX = 4294967295L; 74104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private static final long LONG_MAX = Integer.MAX_VALUE; 75104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private static final long LONG_MIN = Integer.MIN_VALUE; 76104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 77104c45677660586026a7e74ef8c47d396403d50eMichael Jurka static { 78104c45677660586026a7e74ef8c47d396403d50eMichael Jurka TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_BYTE] = 1; 79104c45677660586026a7e74ef8c47d396403d50eMichael Jurka TYPE_TO_SIZE_MAP[TYPE_ASCII] = 1; 80104c45677660586026a7e74ef8c47d396403d50eMichael Jurka TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_SHORT] = 2; 81104c45677660586026a7e74ef8c47d396403d50eMichael Jurka TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_LONG] = 4; 82104c45677660586026a7e74ef8c47d396403d50eMichael Jurka TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_RATIONAL] = 8; 83104c45677660586026a7e74ef8c47d396403d50eMichael Jurka TYPE_TO_SIZE_MAP[TYPE_UNDEFINED] = 1; 84104c45677660586026a7e74ef8c47d396403d50eMichael Jurka TYPE_TO_SIZE_MAP[TYPE_LONG] = 4; 85104c45677660586026a7e74ef8c47d396403d50eMichael Jurka TYPE_TO_SIZE_MAP[TYPE_RATIONAL] = 8; 86104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 87104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 88104c45677660586026a7e74ef8c47d396403d50eMichael Jurka static final int SIZE_UNDEFINED = 0; 89104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 90104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // Exif TagId 91104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private final short mTagId; 92104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // Exif Tag Type 93104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private final short mDataType; 94104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // If tag has defined count 95104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private boolean mHasDefinedDefaultComponentCount; 96104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // Actual data count in tag (should be number of elements in value array) 97104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private int mComponentCountActual; 98104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // The ifd that this tag should be put in 99104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private int mIfd; 100104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // The value (array of elements of type Tag Type) 101104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private Object mValue; 102104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // Value offset in exif header. 103104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private int mOffset; 104104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 105104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("yyyy:MM:dd kk:mm:ss"); 106104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 107104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 108104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Returns true if the given IFD is a valid IFD. 109104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 110104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public static boolean isValidIfd(int ifdId) { 111104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return ifdId == IfdId.TYPE_IFD_0 || ifdId == IfdId.TYPE_IFD_1 112104c45677660586026a7e74ef8c47d396403d50eMichael Jurka || ifdId == IfdId.TYPE_IFD_EXIF || ifdId == IfdId.TYPE_IFD_INTEROPERABILITY 113104c45677660586026a7e74ef8c47d396403d50eMichael Jurka || ifdId == IfdId.TYPE_IFD_GPS; 114104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 115104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 116104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 117104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Returns true if a given type is a valid tag type. 118104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 119104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public static boolean isValidType(short type) { 120104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return type == TYPE_UNSIGNED_BYTE || type == TYPE_ASCII || 121104c45677660586026a7e74ef8c47d396403d50eMichael Jurka type == TYPE_UNSIGNED_SHORT || type == TYPE_UNSIGNED_LONG || 122104c45677660586026a7e74ef8c47d396403d50eMichael Jurka type == TYPE_UNSIGNED_RATIONAL || type == TYPE_UNDEFINED || 123104c45677660586026a7e74ef8c47d396403d50eMichael Jurka type == TYPE_LONG || type == TYPE_RATIONAL; 124104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 125104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 126104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // Use builtTag in ExifInterface instead of constructor. 127104c45677660586026a7e74ef8c47d396403d50eMichael Jurka ExifTag(short tagId, short type, int componentCount, int ifd, 128104c45677660586026a7e74ef8c47d396403d50eMichael Jurka boolean hasDefinedComponentCount) { 129104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mTagId = tagId; 130104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mDataType = type; 131104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mComponentCountActual = componentCount; 132104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mHasDefinedDefaultComponentCount = hasDefinedComponentCount; 133104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mIfd = ifd; 134104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mValue = null; 135104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 136104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 137104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 138104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets the element size of the given data type in bytes. 139104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 140104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see #TYPE_ASCII 141104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see #TYPE_LONG 142104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see #TYPE_RATIONAL 143104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see #TYPE_UNDEFINED 144104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see #TYPE_UNSIGNED_BYTE 145104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see #TYPE_UNSIGNED_LONG 146104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see #TYPE_UNSIGNED_RATIONAL 147104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see #TYPE_UNSIGNED_SHORT 148104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 149104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public static int getElementSize(short type) { 150104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return TYPE_TO_SIZE_MAP[type]; 151104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 152104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 153104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 154104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Returns the ID of the IFD this tag belongs to. 155104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 156104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see IfdId#TYPE_IFD_0 157104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see IfdId#TYPE_IFD_1 158104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see IfdId#TYPE_IFD_EXIF 159104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see IfdId#TYPE_IFD_GPS 160104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see IfdId#TYPE_IFD_INTEROPERABILITY 161104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 162104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public int getIfd() { 163104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return mIfd; 164104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 165104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 166104c45677660586026a7e74ef8c47d396403d50eMichael Jurka protected void setIfd(int ifdId) { 167104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mIfd = ifdId; 168104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 169104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 170104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 171104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets the TID of this tag. 172104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 173104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public short getTagId() { 174104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return mTagId; 175104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 176104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 177104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 178104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets the data type of this tag 179104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 180104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see #TYPE_ASCII 181104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see #TYPE_LONG 182104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see #TYPE_RATIONAL 183104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see #TYPE_UNDEFINED 184104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see #TYPE_UNSIGNED_BYTE 185104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see #TYPE_UNSIGNED_LONG 186104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see #TYPE_UNSIGNED_RATIONAL 187104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see #TYPE_UNSIGNED_SHORT 188104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 189104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public short getDataType() { 190104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return mDataType; 191104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 192104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 193104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 194104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets the total data size in bytes of the value of this tag. 195104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 196104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public int getDataSize() { 197104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return getComponentCount() * getElementSize(getDataType()); 198104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 199104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 200104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 201104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets the component count of this tag. 202104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 203104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 204104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // TODO: fix integer overflows with this 205104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public int getComponentCount() { 206104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return mComponentCountActual; 207104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 208104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 209104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 210104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Sets the component count of this tag. Call this function before 211104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * setValue() if the length of value does not match the component count. 212104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 213104c45677660586026a7e74ef8c47d396403d50eMichael Jurka protected void forceSetComponentCount(int count) { 214104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mComponentCountActual = count; 215104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 216104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 217104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 218104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Returns true if this ExifTag contains value; otherwise, this tag will 219104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * contain an offset value that is determined when the tag is written. 220104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 221104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public boolean hasValue() { 222104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return mValue != null; 223104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 224104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 225104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 226104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Sets integer values into this tag. This method should be used for tags of 227104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * type {@link #TYPE_UNSIGNED_SHORT}. This method will fail if: 228104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <ul> 229104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_SHORT}, 230104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * {@link #TYPE_UNSIGNED_LONG}, or {@link #TYPE_LONG}.</li> 231104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The value overflows.</li> 232104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The value.length does NOT match the component count in the definition 233104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * for this tag.</li> 234104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * </ul> 235104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 236104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public boolean setValue(int[] value) { 237104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (checkBadComponentCount(value.length)) { 238104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 239104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 240104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mDataType != TYPE_UNSIGNED_SHORT && mDataType != TYPE_LONG && 241104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mDataType != TYPE_UNSIGNED_LONG) { 242104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 243104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 244104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mDataType == TYPE_UNSIGNED_SHORT && checkOverflowForUnsignedShort(value)) { 245104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 246104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (mDataType == TYPE_UNSIGNED_LONG && checkOverflowForUnsignedLong(value)) { 247104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 248104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 249104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 250104c45677660586026a7e74ef8c47d396403d50eMichael Jurka long[] data = new long[value.length]; 251104c45677660586026a7e74ef8c47d396403d50eMichael Jurka for (int i = 0; i < value.length; i++) { 252104c45677660586026a7e74ef8c47d396403d50eMichael Jurka data[i] = value[i]; 253104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 254104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mValue = data; 255104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mComponentCountActual = value.length; 256104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return true; 257104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 258104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 259104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 260104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Sets integer value into this tag. This method should be used for tags of 261104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * type {@link #TYPE_UNSIGNED_SHORT}, or {@link #TYPE_LONG}. This method 262104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * will fail if: 263104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <ul> 264104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_SHORT}, 265104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * {@link #TYPE_UNSIGNED_LONG}, or {@link #TYPE_LONG}.</li> 266104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The value overflows.</li> 267104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The component count in the definition of this tag is not 1.</li> 268104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * </ul> 269104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 270104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public boolean setValue(int value) { 271104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return setValue(new int[] { 272104c45677660586026a7e74ef8c47d396403d50eMichael Jurka value 273104c45677660586026a7e74ef8c47d396403d50eMichael Jurka }); 274104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 275104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 276104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 277104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Sets long values into this tag. This method should be used for tags of 278104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * type {@link #TYPE_UNSIGNED_LONG}. This method will fail if: 279104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <ul> 280104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_LONG}.</li> 281104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The value overflows.</li> 282104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The value.length does NOT match the component count in the definition 283104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * for this tag.</li> 284104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * </ul> 285104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 286104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public boolean setValue(long[] value) { 287104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (checkBadComponentCount(value.length) || mDataType != TYPE_UNSIGNED_LONG) { 288104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 289104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 290104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (checkOverflowForUnsignedLong(value)) { 291104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 292104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 293104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mValue = value; 294104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mComponentCountActual = value.length; 295104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return true; 296104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 297104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 298104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 299104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Sets long values into this tag. This method should be used for tags of 300104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * type {@link #TYPE_UNSIGNED_LONG}. This method will fail if: 301104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <ul> 302104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_LONG}.</li> 303104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The value overflows.</li> 304104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The component count in the definition for this tag is not 1.</li> 305104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * </ul> 306104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 307104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public boolean setValue(long value) { 308104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return setValue(new long[] { 309104c45677660586026a7e74ef8c47d396403d50eMichael Jurka value 310104c45677660586026a7e74ef8c47d396403d50eMichael Jurka }); 311104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 312104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 313104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 314104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Sets a string value into this tag. This method should be used for tags of 315104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * type {@link #TYPE_ASCII}. The string is converted to an ASCII string. 316104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Characters that cannot be converted are replaced with '?'. The length of 317104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * the string must be equal to either (component count -1) or (component 318104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * count). The final byte will be set to the string null terminator '\0', 319104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * overwriting the last character in the string if the value.length is equal 320104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * to the component count. This method will fail if: 321104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <ul> 322104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The data type is not {@link #TYPE_ASCII} or {@link #TYPE_UNDEFINED}.</li> 323104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The length of the string is not equal to (component count -1) or 324104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * (component count) in the definition for this tag.</li> 325104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * </ul> 326104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 327104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public boolean setValue(String value) { 328104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mDataType != TYPE_ASCII && mDataType != TYPE_UNDEFINED) { 329104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 330104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 331104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 332104c45677660586026a7e74ef8c47d396403d50eMichael Jurka byte[] buf = value.getBytes(US_ASCII); 333104c45677660586026a7e74ef8c47d396403d50eMichael Jurka byte[] finalBuf = buf; 334104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (buf.length > 0) { 335104c45677660586026a7e74ef8c47d396403d50eMichael Jurka finalBuf = (buf[buf.length - 1] == 0 || mDataType == TYPE_UNDEFINED) ? buf : Arrays 336104c45677660586026a7e74ef8c47d396403d50eMichael Jurka .copyOf(buf, buf.length + 1); 337104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (mDataType == TYPE_ASCII && mComponentCountActual == 1) { 338104c45677660586026a7e74ef8c47d396403d50eMichael Jurka finalBuf = new byte[] { 0 }; 339104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 340104c45677660586026a7e74ef8c47d396403d50eMichael Jurka int count = finalBuf.length; 341104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (checkBadComponentCount(count)) { 342104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 343104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 344104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mComponentCountActual = count; 345104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mValue = finalBuf; 346104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return true; 347104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 348104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 349104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 350104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Sets Rational values into this tag. This method should be used for tags 351104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * of type {@link #TYPE_UNSIGNED_RATIONAL}, or {@link #TYPE_RATIONAL}. This 352104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * method will fail if: 353104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <ul> 354104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_RATIONAL} 355104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * or {@link #TYPE_RATIONAL}.</li> 356104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The value overflows.</li> 357104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The value.length does NOT match the component count in the definition 358104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * for this tag.</li> 359104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * </ul> 360104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 361104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see Rational 362104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 363104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public boolean setValue(Rational[] value) { 364104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (checkBadComponentCount(value.length)) { 365104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 366104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 367104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mDataType != TYPE_UNSIGNED_RATIONAL && mDataType != TYPE_RATIONAL) { 368104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 369104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 370104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mDataType == TYPE_UNSIGNED_RATIONAL && checkOverflowForUnsignedRational(value)) { 371104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 372104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (mDataType == TYPE_RATIONAL && checkOverflowForRational(value)) { 373104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 374104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 375104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 376104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mValue = value; 377104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mComponentCountActual = value.length; 378104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return true; 379104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 380104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 381104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 382104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Sets a Rational value into this tag. This method should be used for tags 383104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * of type {@link #TYPE_UNSIGNED_RATIONAL}, or {@link #TYPE_RATIONAL}. This 384104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * method will fail if: 385104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <ul> 386104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_RATIONAL} 387104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * or {@link #TYPE_RATIONAL}.</li> 388104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The value overflows.</li> 389104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The component count in the definition for this tag is not 1.</li> 390104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * </ul> 391104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 392104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @see Rational 393104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 394104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public boolean setValue(Rational value) { 395104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return setValue(new Rational[] { 396104c45677660586026a7e74ef8c47d396403d50eMichael Jurka value 397104c45677660586026a7e74ef8c47d396403d50eMichael Jurka }); 398104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 399104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 400104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 401104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Sets byte values into this tag. This method should be used for tags of 402104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * type {@link #TYPE_UNSIGNED_BYTE} or {@link #TYPE_UNDEFINED}. This method 403104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * will fail if: 404104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <ul> 405104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_BYTE} or 406104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * {@link #TYPE_UNDEFINED} .</li> 407104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The length does NOT match the component count in the definition for 408104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * this tag.</li> 409104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * </ul> 410104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 411104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public boolean setValue(byte[] value, int offset, int length) { 412104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (checkBadComponentCount(length)) { 413104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 414104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 415104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mDataType != TYPE_UNSIGNED_BYTE && mDataType != TYPE_UNDEFINED) { 416104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 417104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 418104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mValue = new byte[length]; 419104c45677660586026a7e74ef8c47d396403d50eMichael Jurka System.arraycopy(value, offset, mValue, 0, length); 420104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mComponentCountActual = length; 421104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return true; 422104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 423104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 424104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 425104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Equivalent to setValue(value, 0, value.length). 426104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 427104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public boolean setValue(byte[] value) { 428104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return setValue(value, 0, value.length); 429104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 430104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 431104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 432104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Sets byte value into this tag. This method should be used for tags of 433104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * type {@link #TYPE_UNSIGNED_BYTE} or {@link #TYPE_UNDEFINED}. This method 434104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * will fail if: 435104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <ul> 436104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_BYTE} or 437104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * {@link #TYPE_UNDEFINED} .</li> 438104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The component count in the definition for this tag is not 1.</li> 439104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * </ul> 440104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 441104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public boolean setValue(byte value) { 442104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return setValue(new byte[] { 443104c45677660586026a7e74ef8c47d396403d50eMichael Jurka value 444104c45677660586026a7e74ef8c47d396403d50eMichael Jurka }); 445104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 446104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 447104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 448104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Sets the value for this tag using an appropriate setValue method for the 449104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * given object. This method will fail if: 450104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <ul> 451104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>The corresponding setValue method for the class of the object passed 452104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * in would fail.</li> 453104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * <li>There is no obvious way to cast the object passed in into an EXIF tag 454104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * type.</li> 455104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * </ul> 456104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 457104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public boolean setValue(Object obj) { 458104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (obj == null) { 459104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 460104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (obj instanceof Short) { 461104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return setValue(((Short) obj).shortValue() & 0x0ffff); 462104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (obj instanceof String) { 463104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return setValue((String) obj); 464104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (obj instanceof int[]) { 465104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return setValue((int[]) obj); 466104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (obj instanceof long[]) { 467104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return setValue((long[]) obj); 468104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (obj instanceof Rational) { 469104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return setValue((Rational) obj); 470104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (obj instanceof Rational[]) { 471104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return setValue((Rational[]) obj); 472104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (obj instanceof byte[]) { 473104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return setValue((byte[]) obj); 474104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (obj instanceof Integer) { 475104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return setValue(((Integer) obj).intValue()); 476104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (obj instanceof Long) { 477104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return setValue(((Long) obj).longValue()); 478104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (obj instanceof Byte) { 479104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return setValue(((Byte) obj).byteValue()); 480104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (obj instanceof Short[]) { 481104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // Nulls in this array are treated as zeroes. 482104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Short[] arr = (Short[]) obj; 483104c45677660586026a7e74ef8c47d396403d50eMichael Jurka int[] fin = new int[arr.length]; 484104c45677660586026a7e74ef8c47d396403d50eMichael Jurka for (int i = 0; i < arr.length; i++) { 485104c45677660586026a7e74ef8c47d396403d50eMichael Jurka fin[i] = (arr[i] == null) ? 0 : arr[i].shortValue() & 0x0ffff; 486104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 487104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return setValue(fin); 488104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (obj instanceof Integer[]) { 489104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // Nulls in this array are treated as zeroes. 490104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Integer[] arr = (Integer[]) obj; 491104c45677660586026a7e74ef8c47d396403d50eMichael Jurka int[] fin = new int[arr.length]; 492104c45677660586026a7e74ef8c47d396403d50eMichael Jurka for (int i = 0; i < arr.length; i++) { 493104c45677660586026a7e74ef8c47d396403d50eMichael Jurka fin[i] = (arr[i] == null) ? 0 : arr[i].intValue(); 494104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 495104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return setValue(fin); 496104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (obj instanceof Long[]) { 497104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // Nulls in this array are treated as zeroes. 498104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Long[] arr = (Long[]) obj; 499104c45677660586026a7e74ef8c47d396403d50eMichael Jurka long[] fin = new long[arr.length]; 500104c45677660586026a7e74ef8c47d396403d50eMichael Jurka for (int i = 0; i < arr.length; i++) { 501104c45677660586026a7e74ef8c47d396403d50eMichael Jurka fin[i] = (arr[i] == null) ? 0 : arr[i].longValue(); 502104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 503104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return setValue(fin); 504104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (obj instanceof Byte[]) { 505104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // Nulls in this array are treated as zeroes. 506104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Byte[] arr = (Byte[]) obj; 507104c45677660586026a7e74ef8c47d396403d50eMichael Jurka byte[] fin = new byte[arr.length]; 508104c45677660586026a7e74ef8c47d396403d50eMichael Jurka for (int i = 0; i < arr.length; i++) { 509104c45677660586026a7e74ef8c47d396403d50eMichael Jurka fin[i] = (arr[i] == null) ? 0 : arr[i].byteValue(); 510104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 511104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return setValue(fin); 512104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else { 513104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 514104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 515104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 516104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 517104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 518104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Sets a timestamp to this tag. The method converts the timestamp with the 519104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * format of "yyyy:MM:dd kk:mm:ss" and calls {@link #setValue(String)}. This 520104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * method will fail if the data type is not {@link #TYPE_ASCII} or the 521104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * component count of this tag is not 20 or undefined. 522104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 523104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @param time the number of milliseconds since Jan. 1, 1970 GMT 524104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @return true on success 525104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 526104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public boolean setTimeValue(long time) { 527104c45677660586026a7e74ef8c47d396403d50eMichael Jurka // synchronized on TIME_FORMAT as SimpleDateFormat is not thread safe 528104c45677660586026a7e74ef8c47d396403d50eMichael Jurka synchronized (TIME_FORMAT) { 529104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return setValue(TIME_FORMAT.format(new Date(time))); 530104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 531104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 532104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 533104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 534104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets the value as a String. This method should be used for tags of type 535104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * {@link #TYPE_ASCII}. 536104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 537104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @return the value as a String, or null if the tag's value does not exist 538104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * or cannot be converted to a String. 539104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 540104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public String getValueAsString() { 541104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mValue == null) { 542104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return null; 543104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (mValue instanceof String) { 544104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return (String) mValue; 545104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (mValue instanceof byte[]) { 546104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return new String((byte[]) mValue, US_ASCII); 547104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 548104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return null; 549104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 550104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 551104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 552104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets the value as a String. This method should be used for tags of type 553104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * {@link #TYPE_ASCII}. 554104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 555104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @param defaultValue the String to return if the tag's value does not 556104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * exist or cannot be converted to a String. 557104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @return the tag's value as a String, or the defaultValue. 558104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 559104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public String getValueAsString(String defaultValue) { 560104c45677660586026a7e74ef8c47d396403d50eMichael Jurka String s = getValueAsString(); 561104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (s == null) { 562104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return defaultValue; 563104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 564104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return s; 565104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 566104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 567104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 568104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets the value as a byte array. This method should be used for tags of 569104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * type {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE}. 570104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 571104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @return the value as a byte array, or null if the tag's value does not 572104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * exist or cannot be converted to a byte array. 573104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 574104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public byte[] getValueAsBytes() { 575104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mValue instanceof byte[]) { 576104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return (byte[]) mValue; 577104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 578104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return null; 579104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 580104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 581104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 582104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets the value as a byte. If there are more than 1 bytes in this value, 583104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * gets the first byte. This method should be used for tags of type 584104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE}. 585104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 586104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @param defaultValue the byte to return if tag's value does not exist or 587104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * cannot be converted to a byte. 588104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @return the tag's value as a byte, or the defaultValue. 589104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 590104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public byte getValueAsByte(byte defaultValue) { 591104c45677660586026a7e74ef8c47d396403d50eMichael Jurka byte[] b = getValueAsBytes(); 592104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (b == null || b.length < 1) { 593104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return defaultValue; 594104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 595104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return b[0]; 596104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 597104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 598104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 599104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets the value as an array of Rationals. This method should be used for 600104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * tags of type {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}. 601104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 602104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @return the value as as an array of Rationals, or null if the tag's value 603104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * does not exist or cannot be converted to an array of Rationals. 604104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 605104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public Rational[] getValueAsRationals() { 606104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mValue instanceof Rational[]) { 607104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return (Rational[]) mValue; 608104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 609104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return null; 610104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 611104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 612104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 613104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets the value as a Rational. If there are more than 1 Rationals in this 614104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * value, gets the first one. This method should be used for tags of type 615104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}. 616104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 617104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @param defaultValue the Rational to return if tag's value does not exist 618104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * or cannot be converted to a Rational. 619104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @return the tag's value as a Rational, or the defaultValue. 620104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 621104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public Rational getValueAsRational(Rational defaultValue) { 622104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Rational[] r = getValueAsRationals(); 623104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (r == null || r.length < 1) { 624104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return defaultValue; 625104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 626104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return r[0]; 627104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 628104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 629104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 630104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets the value as a Rational. If there are more than 1 Rationals in this 631104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * value, gets the first one. This method should be used for tags of type 632104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}. 633104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 634104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @param defaultValue the numerator of the Rational to return if tag's 635104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * value does not exist or cannot be converted to a Rational (the 636104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * denominator will be 1). 637104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @return the tag's value as a Rational, or the defaultValue. 638104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 639104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public Rational getValueAsRational(long defaultValue) { 640104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Rational defaultVal = new Rational(defaultValue, 1); 641104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return getValueAsRational(defaultVal); 642104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 643104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 644104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 645104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets the value as an array of ints. This method should be used for tags 646104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * of type {@link #TYPE_UNSIGNED_SHORT}, {@link #TYPE_UNSIGNED_LONG}. 647104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 648104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @return the value as as an array of ints, or null if the tag's value does 649104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * not exist or cannot be converted to an array of ints. 650104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 651104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public int[] getValueAsInts() { 652104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mValue == null) { 653104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return null; 654104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (mValue instanceof long[]) { 655104c45677660586026a7e74ef8c47d396403d50eMichael Jurka long[] val = (long[]) mValue; 656104c45677660586026a7e74ef8c47d396403d50eMichael Jurka int[] arr = new int[val.length]; 657104c45677660586026a7e74ef8c47d396403d50eMichael Jurka for (int i = 0; i < val.length; i++) { 658104c45677660586026a7e74ef8c47d396403d50eMichael Jurka arr[i] = (int) val[i]; // Truncates 659104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 660104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return arr; 661104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 662104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return null; 663104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 664104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 665104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 666104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets the value as an int. If there are more than 1 ints in this value, 667104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * gets the first one. This method should be used for tags of type 668104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * {@link #TYPE_UNSIGNED_SHORT}, {@link #TYPE_UNSIGNED_LONG}. 669104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 670104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @param defaultValue the int to return if tag's value does not exist or 671104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * cannot be converted to an int. 672104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @return the tag's value as a int, or the defaultValue. 673104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 674104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public int getValueAsInt(int defaultValue) { 675104c45677660586026a7e74ef8c47d396403d50eMichael Jurka int[] i = getValueAsInts(); 676104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (i == null || i.length < 1) { 677104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return defaultValue; 678104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 679104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return i[0]; 680104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 681104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 682104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 683104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets the value as an array of longs. This method should be used for tags 684104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * of type {@link #TYPE_UNSIGNED_LONG}. 685104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 686104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @return the value as as an array of longs, or null if the tag's value 687104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * does not exist or cannot be converted to an array of longs. 688104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 689104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public long[] getValueAsLongs() { 690104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mValue instanceof long[]) { 691104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return (long[]) mValue; 692104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 693104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return null; 694104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 695104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 696104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 697104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets the value or null if none exists. If there are more than 1 longs in 698104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * this value, gets the first one. This method should be used for tags of 699104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * type {@link #TYPE_UNSIGNED_LONG}. 700104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 701104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @param defaultValue the long to return if tag's value does not exist or 702104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * cannot be converted to a long. 703104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @return the tag's value as a long, or the defaultValue. 704104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 705104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public long getValueAsLong(long defaultValue) { 706104c45677660586026a7e74ef8c47d396403d50eMichael Jurka long[] l = getValueAsLongs(); 707104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (l == null || l.length < 1) { 708104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return defaultValue; 709104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 710104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return l[0]; 711104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 712104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 713104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 714104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets the tag's value or null if none exists. 715104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 716104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public Object getValue() { 717104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return mValue; 718104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 719104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 720104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 721104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets a long representation of the value. 722104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 723104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @param defaultValue value to return if there is no value or value is a 724104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * rational with a denominator of 0. 725104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @return the tag's value as a long, or defaultValue if no representation 726104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * exists. 727104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 728104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public long forceGetValueAsLong(long defaultValue) { 729104c45677660586026a7e74ef8c47d396403d50eMichael Jurka long[] l = getValueAsLongs(); 730104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (l != null && l.length >= 1) { 731104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return l[0]; 732104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 733104c45677660586026a7e74ef8c47d396403d50eMichael Jurka byte[] b = getValueAsBytes(); 734104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (b != null && b.length >= 1) { 735104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return b[0]; 736104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 737104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Rational[] r = getValueAsRationals(); 738104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (r != null && r.length >= 1 && r[0].getDenominator() != 0) { 739104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return (long) r[0].toDouble(); 740104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 741104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return defaultValue; 742104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 743104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 744104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 745104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets a string representation of the value. 746104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 747104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public String forceGetValueAsString() { 748104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mValue == null) { 749104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return ""; 750104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (mValue instanceof byte[]) { 751104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mDataType == TYPE_ASCII) { 752104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return new String((byte[]) mValue, US_ASCII); 753104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else { 754104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return Arrays.toString((byte[]) mValue); 755104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 756104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (mValue instanceof long[]) { 757104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (((long[]) mValue).length == 1) { 758104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return String.valueOf(((long[]) mValue)[0]); 759104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else { 760104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return Arrays.toString((long[]) mValue); 761104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 762104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (mValue instanceof Object[]) { 763104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (((Object[]) mValue).length == 1) { 764104c45677660586026a7e74ef8c47d396403d50eMichael Jurka Object val = ((Object[]) mValue)[0]; 765104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (val == null) { 766104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return ""; 767104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else { 768104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return val.toString(); 769104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 770104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else { 771104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return Arrays.toString((Object[]) mValue); 772104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 773104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else { 774104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return mValue.toString(); 775104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 776104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 777104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 778104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 779104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets the value for type {@link #TYPE_ASCII}, {@link #TYPE_LONG}, 780104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * {@link #TYPE_UNDEFINED}, {@link #TYPE_UNSIGNED_BYTE}, 781104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * {@link #TYPE_UNSIGNED_LONG}, or {@link #TYPE_UNSIGNED_SHORT}. For 782104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}, call 783104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * {@link #getRational(int)} instead. 784104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 785104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @exception IllegalArgumentException if the data type is 786104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}. 787104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 788104c45677660586026a7e74ef8c47d396403d50eMichael Jurka protected long getValueAt(int index) { 789104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mValue instanceof long[]) { 790104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return ((long[]) mValue)[index]; 791104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (mValue instanceof byte[]) { 792104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return ((byte[]) mValue)[index]; 793104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 794104c45677660586026a7e74ef8c47d396403d50eMichael Jurka throw new IllegalArgumentException("Cannot get integer value from " 795104c45677660586026a7e74ef8c47d396403d50eMichael Jurka + convertTypeToString(mDataType)); 796104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 797104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 798104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 799104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets the {@link #TYPE_ASCII} data. 800104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 801104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @exception IllegalArgumentException If the type is NOT 802104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * {@link #TYPE_ASCII}. 803104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 804104c45677660586026a7e74ef8c47d396403d50eMichael Jurka protected String getString() { 805104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mDataType != TYPE_ASCII) { 806104c45677660586026a7e74ef8c47d396403d50eMichael Jurka throw new IllegalArgumentException("Cannot get ASCII value from " 807104c45677660586026a7e74ef8c47d396403d50eMichael Jurka + convertTypeToString(mDataType)); 808104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 809104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return new String((byte[]) mValue, US_ASCII); 810104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 811104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 812104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /* 813104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Get the converted ascii byte. Used by ExifOutputStream. 814104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 815104c45677660586026a7e74ef8c47d396403d50eMichael Jurka protected byte[] getStringByte() { 816104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return (byte[]) mValue; 817104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 818104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 819104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 820104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets the {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL} data. 821104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 822104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @exception IllegalArgumentException If the type is NOT 823104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}. 824104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 825104c45677660586026a7e74ef8c47d396403d50eMichael Jurka protected Rational getRational(int index) { 826104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if ((mDataType != TYPE_RATIONAL) && (mDataType != TYPE_UNSIGNED_RATIONAL)) { 827104c45677660586026a7e74ef8c47d396403d50eMichael Jurka throw new IllegalArgumentException("Cannot get RATIONAL value from " 828104c45677660586026a7e74ef8c47d396403d50eMichael Jurka + convertTypeToString(mDataType)); 829104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 830104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return ((Rational[]) mValue)[index]; 831104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 832104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 833104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 834104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Equivalent to getBytes(buffer, 0, buffer.length). 835104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 836104c45677660586026a7e74ef8c47d396403d50eMichael Jurka protected void getBytes(byte[] buf) { 837104c45677660586026a7e74ef8c47d396403d50eMichael Jurka getBytes(buf, 0, buf.length); 838104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 839104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 840104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 841104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets the {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE} data. 842104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * 843104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @param buf the byte array in which to store the bytes read. 844104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @param offset the initial position in buffer to store the bytes. 845104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @param length the maximum number of bytes to store in buffer. If length > 846104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * component count, only the valid bytes will be stored. 847104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * @exception IllegalArgumentException If the type is NOT 848104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE}. 849104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 850104c45677660586026a7e74ef8c47d396403d50eMichael Jurka protected void getBytes(byte[] buf, int offset, int length) { 851104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if ((mDataType != TYPE_UNDEFINED) && (mDataType != TYPE_UNSIGNED_BYTE)) { 852104c45677660586026a7e74ef8c47d396403d50eMichael Jurka throw new IllegalArgumentException("Cannot get BYTE value from " 853104c45677660586026a7e74ef8c47d396403d50eMichael Jurka + convertTypeToString(mDataType)); 854104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 855104c45677660586026a7e74ef8c47d396403d50eMichael Jurka System.arraycopy(mValue, 0, buf, offset, 856104c45677660586026a7e74ef8c47d396403d50eMichael Jurka (length > mComponentCountActual) ? mComponentCountActual : length); 857104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 858104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 859104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 860104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Gets the offset of this tag. This is only valid if this data size > 4 and 861104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * contains an offset to the location of the actual value. 862104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 863104c45677660586026a7e74ef8c47d396403d50eMichael Jurka protected int getOffset() { 864104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return mOffset; 865104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 866104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 867104c45677660586026a7e74ef8c47d396403d50eMichael Jurka /** 868104c45677660586026a7e74ef8c47d396403d50eMichael Jurka * Sets the offset of this tag. 869104c45677660586026a7e74ef8c47d396403d50eMichael Jurka */ 870104c45677660586026a7e74ef8c47d396403d50eMichael Jurka protected void setOffset(int offset) { 871104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mOffset = offset; 872104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 873104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 874104c45677660586026a7e74ef8c47d396403d50eMichael Jurka protected void setHasDefinedCount(boolean d) { 875104c45677660586026a7e74ef8c47d396403d50eMichael Jurka mHasDefinedDefaultComponentCount = d; 876104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 877104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 878104c45677660586026a7e74ef8c47d396403d50eMichael Jurka protected boolean hasDefinedCount() { 879104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return mHasDefinedDefaultComponentCount; 880104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 881104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 882104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private boolean checkBadComponentCount(int count) { 883104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mHasDefinedDefaultComponentCount && (mComponentCountActual != count)) { 884104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return true; 885104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 886104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 887104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 888104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 889104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private static String convertTypeToString(short type) { 890104c45677660586026a7e74ef8c47d396403d50eMichael Jurka switch (type) { 891104c45677660586026a7e74ef8c47d396403d50eMichael Jurka case TYPE_UNSIGNED_BYTE: 892104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return "UNSIGNED_BYTE"; 893104c45677660586026a7e74ef8c47d396403d50eMichael Jurka case TYPE_ASCII: 894104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return "ASCII"; 895104c45677660586026a7e74ef8c47d396403d50eMichael Jurka case TYPE_UNSIGNED_SHORT: 896104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return "UNSIGNED_SHORT"; 897104c45677660586026a7e74ef8c47d396403d50eMichael Jurka case TYPE_UNSIGNED_LONG: 898104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return "UNSIGNED_LONG"; 899104c45677660586026a7e74ef8c47d396403d50eMichael Jurka case TYPE_UNSIGNED_RATIONAL: 900104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return "UNSIGNED_RATIONAL"; 901104c45677660586026a7e74ef8c47d396403d50eMichael Jurka case TYPE_UNDEFINED: 902104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return "UNDEFINED"; 903104c45677660586026a7e74ef8c47d396403d50eMichael Jurka case TYPE_LONG: 904104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return "LONG"; 905104c45677660586026a7e74ef8c47d396403d50eMichael Jurka case TYPE_RATIONAL: 906104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return "RATIONAL"; 907104c45677660586026a7e74ef8c47d396403d50eMichael Jurka default: 908104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return ""; 909104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 910104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 911104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 912104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private boolean checkOverflowForUnsignedShort(int[] value) { 913104c45677660586026a7e74ef8c47d396403d50eMichael Jurka for (int v : value) { 914104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (v > UNSIGNED_SHORT_MAX || v < 0) { 915104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return true; 916104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 917104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 918104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 919104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 920104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 921104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private boolean checkOverflowForUnsignedLong(long[] value) { 922104c45677660586026a7e74ef8c47d396403d50eMichael Jurka for (long v : value) { 923104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (v < 0 || v > UNSIGNED_LONG_MAX) { 924104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return true; 925104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 926104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 927104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 928104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 929104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 930104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private boolean checkOverflowForUnsignedLong(int[] value) { 931104c45677660586026a7e74ef8c47d396403d50eMichael Jurka for (int v : value) { 932104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (v < 0) { 933104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return true; 934104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 935104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 936104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 937104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 938104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 939104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private boolean checkOverflowForUnsignedRational(Rational[] value) { 940104c45677660586026a7e74ef8c47d396403d50eMichael Jurka for (Rational v : value) { 941104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (v.getNumerator() < 0 || v.getDenominator() < 0 942104c45677660586026a7e74ef8c47d396403d50eMichael Jurka || v.getNumerator() > UNSIGNED_LONG_MAX 943104c45677660586026a7e74ef8c47d396403d50eMichael Jurka || v.getDenominator() > UNSIGNED_LONG_MAX) { 944104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return true; 945104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 946104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 947104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 948104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 949104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 950104c45677660586026a7e74ef8c47d396403d50eMichael Jurka private boolean checkOverflowForRational(Rational[] value) { 951104c45677660586026a7e74ef8c47d396403d50eMichael Jurka for (Rational v : value) { 952104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (v.getNumerator() < LONG_MIN || v.getDenominator() < LONG_MIN 953104c45677660586026a7e74ef8c47d396403d50eMichael Jurka || v.getNumerator() > LONG_MAX 954104c45677660586026a7e74ef8c47d396403d50eMichael Jurka || v.getDenominator() > LONG_MAX) { 955104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return true; 956104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 957104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 958104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 959104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 960104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 961104c45677660586026a7e74ef8c47d396403d50eMichael Jurka @Override 962104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public boolean equals(Object obj) { 963104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (obj == null) { 964104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 965104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 966104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (obj instanceof ExifTag) { 967104c45677660586026a7e74ef8c47d396403d50eMichael Jurka ExifTag tag = (ExifTag) obj; 968104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (tag.mTagId != this.mTagId 969104c45677660586026a7e74ef8c47d396403d50eMichael Jurka || tag.mComponentCountActual != this.mComponentCountActual 970104c45677660586026a7e74ef8c47d396403d50eMichael Jurka || tag.mDataType != this.mDataType) { 971104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 972104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 973104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (mValue != null) { 974104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (tag.mValue == null) { 975104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 976104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (mValue instanceof long[]) { 977104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (!(tag.mValue instanceof long[])) { 978104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 979104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 980104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return Arrays.equals((long[]) mValue, (long[]) tag.mValue); 981104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (mValue instanceof Rational[]) { 982104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (!(tag.mValue instanceof Rational[])) { 983104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 984104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 985104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return Arrays.equals((Rational[]) mValue, (Rational[]) tag.mValue); 986104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else if (mValue instanceof byte[]) { 987104c45677660586026a7e74ef8c47d396403d50eMichael Jurka if (!(tag.mValue instanceof byte[])) { 988104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 989104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 990104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return Arrays.equals((byte[]) mValue, (byte[]) tag.mValue); 991104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else { 992104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return mValue.equals(tag.mValue); 993104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 994104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } else { 995104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return tag.mValue == null; 996104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 997104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 998104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return false; 999104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 1000104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 1001104c45677660586026a7e74ef8c47d396403d50eMichael Jurka @Override 1002104c45677660586026a7e74ef8c47d396403d50eMichael Jurka public String toString() { 1003104c45677660586026a7e74ef8c47d396403d50eMichael Jurka return String.format("tag id: %04X\n", mTagId) + "ifd id: " + mIfd + "\ntype: " 1004104c45677660586026a7e74ef8c47d396403d50eMichael Jurka + convertTypeToString(mDataType) + "\ncount: " + mComponentCountActual 1005104c45677660586026a7e74ef8c47d396403d50eMichael Jurka + "\noffset: " + mOffset + "\nvalue: " + forceGetValueAsString() + "\n"; 1006104c45677660586026a7e74ef8c47d396403d50eMichael Jurka } 1007104c45677660586026a7e74ef8c47d396403d50eMichael Jurka 1008104c45677660586026a7e74ef8c47d396403d50eMichael Jurka} 1009