1e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor/* 2e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Copyright (C) 2012 The Android Open Source Project 3e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * 4e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Licensed under the Apache License, Version 2.0 (the "License"); 5e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * you may not use this file except in compliance with the License. 6e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * You may obtain a copy of the License at 7e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * 8e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * http://www.apache.org/licenses/LICENSE-2.0 9e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * 10e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Unless required by applicable law or agreed to in writing, software 11e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * distributed under the License is distributed on an "AS IS" BASIS, 12e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * See the License for the specific language governing permissions and 14e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * limitations under the License. 15e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor */ 16e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 17e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylorpackage com.android.mms.exif; 18e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 19e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylorimport android.util.Log; 20e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 21e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylorimport java.io.UnsupportedEncodingException; 22e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylorimport java.nio.ByteOrder; 23e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylorimport java.util.ArrayList; 24e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylorimport java.util.Arrays; 25e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylorimport java.util.List; 26e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 27e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor/** 28e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * This class stores the EXIF header in IFDs according to the JPEG 29e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * specification. It is the result produced by {@link ExifReader}. 30e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * 31e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * @see ExifReader 32e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * @see IfdData 33e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor */ 34e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylorclass ExifData { 35e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor private static final String TAG = "ExifData"; 36e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor private static final byte[] USER_COMMENT_ASCII = { 37e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 0x41, 0x53, 0x43, 0x49, 0x49, 0x00, 0x00, 0x00 38e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor }; 39e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor private static final byte[] USER_COMMENT_JIS = { 40e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 0x4A, 0x49, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00 41e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor }; 42e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor private static final byte[] USER_COMMENT_UNICODE = { 43e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 0x55, 0x4E, 0x49, 0x43, 0x4F, 0x44, 0x45, 0x00 44e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor }; 45e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 46e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor private final IfdData[] mIfdDatas = new IfdData[IfdId.TYPE_IFD_COUNT]; 47e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor private byte[] mThumbnail; 48e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor private final ArrayList<byte[]> mStripBytes = new ArrayList<byte[]>(); 49e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor private final ByteOrder mByteOrder; 50e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 51e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor ExifData(ByteOrder order) { 52e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor mByteOrder = order; 53e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 54e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 55e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor /** 56e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Gets the compressed thumbnail. Returns null if there is no compressed 57e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * thumbnail. 58e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * 59e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * @see #hasCompressedThumbnail() 60e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor */ 61e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor protected byte[] getCompressedThumbnail() { 62e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return mThumbnail; 63e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 64e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 65e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor /** 66e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Sets the compressed thumbnail. 67e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor */ 68e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor protected void setCompressedThumbnail(byte[] thumbnail) { 69e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor mThumbnail = thumbnail; 70e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 71e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 72e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor /** 73e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Returns true it this header contains a compressed thumbnail. 74e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor */ 75e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor protected boolean hasCompressedThumbnail() { 76e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return mThumbnail != null; 77e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 78e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 79e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor /** 80e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Adds an uncompressed strip. 81e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor */ 82e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor protected void setStripBytes(int index, byte[] strip) { 83e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (index < mStripBytes.size()) { 84e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor mStripBytes.set(index, strip); 85e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } else { 86e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor for (int i = mStripBytes.size(); i < index; i++) { 87e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor mStripBytes.add(null); 88e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 89e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor mStripBytes.add(strip); 90e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 91e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 92e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 93e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor /** 94e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Gets the strip count. 95e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor */ 96e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor protected int getStripCount() { 97e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return mStripBytes.size(); 98e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 99e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 100e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor /** 101e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Gets the strip at the specified index. 102e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * 103e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * @exceptions #IndexOutOfBoundException 104e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor */ 105e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor protected byte[] getStrip(int index) { 106e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return mStripBytes.get(index); 107e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 108e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 109e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor /** 110e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Returns true if this header contains uncompressed strip. 111e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor */ 112e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor protected boolean hasUncompressedStrip() { 113e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return mStripBytes.size() != 0; 114e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 115e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 116e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor /** 117e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Gets the byte order. 118e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor */ 119e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor protected ByteOrder getByteOrder() { 120e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return mByteOrder; 121e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 122e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 123e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor /** 124e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Returns the {@link IfdData} object corresponding to a given IFD if it 125e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * exists or null. 126e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor */ 127e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor protected IfdData getIfdData(int ifdId) { 128e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (ExifTag.isValidIfd(ifdId)) { 129e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return mIfdDatas[ifdId]; 130e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 131e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return null; 132e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 133e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 134e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor /** 135e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Adds IFD data. If IFD data of the same type already exists, it will be 136e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * replaced by the new data. 137e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor */ 138e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor protected void addIfdData(IfdData data) { 139e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor mIfdDatas[data.getId()] = data; 140e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 141e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 142e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor /** 143e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Returns the {@link IfdData} object corresponding to a given IFD or 144e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * generates one if none exist. 145e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor */ 146e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor protected IfdData getOrCreateIfdData(int ifdId) { 147e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor IfdData ifdData = mIfdDatas[ifdId]; 148e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (ifdData == null) { 149e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor ifdData = new IfdData(ifdId); 150e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor mIfdDatas[ifdId] = ifdData; 151e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 152e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return ifdData; 153e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 154e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 155e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor /** 156e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Returns the tag with a given TID in the given IFD if the tag exists. 157e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Otherwise returns null. 158e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor */ 159e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor protected ExifTag getTag(short tag, int ifd) { 160e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor IfdData ifdData = mIfdDatas[ifd]; 161e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return (ifdData == null) ? null : ifdData.getTag(tag); 162e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 163e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 164e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor /** 165e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Adds the given ExifTag to its default IFD and returns an existing ExifTag 166e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * with the same TID or null if none exist. 167e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor */ 168e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor protected ExifTag addTag(ExifTag tag) { 169e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (tag != null) { 170e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor int ifd = tag.getIfd(); 171e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return addTag(tag, ifd); 172e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 173e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return null; 174e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 175e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 176e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor /** 177e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Adds the given ExifTag to the given IFD and returns an existing ExifTag 178e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * with the same TID or null if none exist. 179e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor */ 180e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor protected ExifTag addTag(ExifTag tag, int ifdId) { 181e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (tag != null && ExifTag.isValidIfd(ifdId)) { 182e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor IfdData ifdData = getOrCreateIfdData(ifdId); 183e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return ifdData.setTag(tag); 184e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 185e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return null; 186e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 187e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 188e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor protected void clearThumbnailAndStrips() { 189e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor mThumbnail = null; 190e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor mStripBytes.clear(); 191e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 192e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 193e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor /** 194e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Removes the thumbnail and its related tags. IFD1 will be removed. 195e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor */ 196e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor protected void removeThumbnailData() { 197e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor clearThumbnailAndStrips(); 198e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor mIfdDatas[IfdId.TYPE_IFD_1] = null; 199e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 200e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 201e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor /** 202e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Removes the tag with a given TID and IFD. 203e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor */ 204e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor protected void removeTag(short tagId, int ifdId) { 205e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor IfdData ifdData = mIfdDatas[ifdId]; 206e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (ifdData == null) { 207e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return; 208e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 209e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor ifdData.removeTag(tagId); 210e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 211e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 212e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor /** 213e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Decodes the user comment tag into string as specified in the EXIF 214e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * standard. Returns null if decoding failed. 215e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor */ 216e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor protected String getUserComment() { 217e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor IfdData ifdData = mIfdDatas[IfdId.TYPE_IFD_0]; 218e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (ifdData == null) { 219e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return null; 220e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 221e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor ExifTag tag = ifdData.getTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_USER_COMMENT)); 222e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (tag == null) { 223e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return null; 224e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 225e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (tag.getComponentCount() < 8) { 226e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return null; 227e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 228e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 229e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor byte[] buf = new byte[tag.getComponentCount()]; 230e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor tag.getBytes(buf); 231e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 232e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor byte[] code = new byte[8]; 233e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor System.arraycopy(buf, 0, code, 0, 8); 234e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 235e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor try { 236e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (Arrays.equals(code, USER_COMMENT_ASCII)) { 237e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return new String(buf, 8, buf.length - 8, "US-ASCII"); 238e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } else if (Arrays.equals(code, USER_COMMENT_JIS)) { 239e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return new String(buf, 8, buf.length - 8, "EUC-JP"); 240e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } else if (Arrays.equals(code, USER_COMMENT_UNICODE)) { 241e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return new String(buf, 8, buf.length - 8, "UTF-16"); 242e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } else { 243e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return null; 244e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 245e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } catch (UnsupportedEncodingException e) { 246e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor Log.w(TAG, "Failed to decode the user comment"); 247e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return null; 248e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 249e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 250e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 251e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor /** 252e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Returns a list of all {@link ExifTag}s in the ExifData or null if there 253e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * are none. 254e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor */ 255e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor protected List<ExifTag> getAllTags() { 256e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor ArrayList<ExifTag> ret = new ArrayList<ExifTag>(); 257e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor for (IfdData d : mIfdDatas) { 258e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (d != null) { 259e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor ExifTag[] tags = d.getAllTags(); 260e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (tags != null) { 261e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor for (ExifTag t : tags) { 262e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor ret.add(t); 263e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 264e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 265e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 266e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 267e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (ret.size() == 0) { 268e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return null; 269e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 270e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return ret; 271e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 272e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 273e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor /** 274e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Returns a list of all {@link ExifTag}s in a given IFD or null if there 275e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * are none. 276e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor */ 277e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor protected List<ExifTag> getAllTagsForIfd(int ifd) { 278e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor IfdData d = mIfdDatas[ifd]; 279e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (d == null) { 280e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return null; 281e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 282e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor ExifTag[] tags = d.getAllTags(); 283e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (tags == null) { 284e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return null; 285e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 286e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor ArrayList<ExifTag> ret = new ArrayList<ExifTag>(tags.length); 287e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor for (ExifTag t : tags) { 288e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor ret.add(t); 289e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 290e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (ret.size() == 0) { 291e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return null; 292e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 293e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return ret; 294e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 295e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 296e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor /** 297e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * Returns a list of all {@link ExifTag}s with a given TID or null if there 298e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor * are none. 299e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor */ 300e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor protected List<ExifTag> getAllTagsForTagId(short tag) { 301e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor ArrayList<ExifTag> ret = new ArrayList<ExifTag>(); 302e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor for (IfdData d : mIfdDatas) { 303e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (d != null) { 304e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor ExifTag t = d.getTag(tag); 305e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (t != null) { 306e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor ret.add(t); 307e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 308e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 309e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 310e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (ret.size() == 0) { 311e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return null; 312e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 313e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return ret; 314e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 315e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 316e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor @Override 317e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor public boolean equals(Object obj) { 318e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (this == obj) { 319e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return true; 320e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 321e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (obj == null) { 322e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return false; 323e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 324e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (obj instanceof ExifData) { 325e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor ExifData data = (ExifData) obj; 326e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (data.mByteOrder != mByteOrder || 327e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor data.mStripBytes.size() != mStripBytes.size() || 328e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor !Arrays.equals(data.mThumbnail, mThumbnail)) { 329e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return false; 330e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 331e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor for (int i = 0; i < mStripBytes.size(); i++) { 332e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (!Arrays.equals(data.mStripBytes.get(i), mStripBytes.get(i))) { 333e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return false; 334e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 335e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 336e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor for (int i = 0; i < IfdId.TYPE_IFD_COUNT; i++) { 337e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor IfdData ifd1 = data.getIfdData(i); 338e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor IfdData ifd2 = getIfdData(i); 339e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor if (ifd1 != ifd2 && ifd1 != null && !ifd1.equals(ifd2)) { 340e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return false; 341e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 342e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 343e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return true; 344e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 345e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor return false; 346e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor } 347e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor 348e8a0d786fba1960818cb3da938cdbf2b2b11b340Tom Taylor} 349