12523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan/* 22523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * Copyright (C) 2012 The Android Open Source Project 32523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * 42523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * Licensed under the Apache License, Version 2.0 (the "License"); 52523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * you may not use this file except in compliance with the License. 62523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * You may obtain a copy of the License at 72523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * 82523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * http://www.apache.org/licenses/LICENSE-2.0 92523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * 102523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * Unless required by applicable law or agreed to in writing, software 112523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * distributed under the License is distributed on an "AS IS" BASIS, 122523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * See the License for the specific language governing permissions and 142523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * limitations under the License. 152523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan */ 162523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 17a16e7b50f3148f581439509279f242092e254309ztenghuipackage com.android.camera.exif; 182523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 19428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ouimport android.util.Log; 20428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou 21428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ouimport java.io.UnsupportedEncodingException; 222523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanimport java.nio.ByteOrder; 232523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanimport java.util.ArrayList; 242523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyanimport java.util.Arrays; 25c274ded801f745d6318186958107622e7a4fef33Ruben Brunkimport java.util.List; 262523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 272523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan/** 28c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * This class stores the EXIF header in IFDs according to the JPEG 29c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * specification. It is the result produced by {@link ExifReader}. 30c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * 31c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * @see ExifReader 32c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * @see IfdData 332523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan */ 34c274ded801f745d6318186958107622e7a4fef33Ruben Brunkclass ExifData { 35428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou private static final String TAG = "ExifData"; 36428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou private static final byte[] USER_COMMENT_ASCII = { 37c274ded801f745d6318186958107622e7a4fef33Ruben Brunk 0x41, 0x53, 0x43, 0x49, 0x49, 0x00, 0x00, 0x00 38c274ded801f745d6318186958107622e7a4fef33Ruben Brunk }; 39428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou private static final byte[] USER_COMMENT_JIS = { 40c274ded801f745d6318186958107622e7a4fef33Ruben Brunk 0x4A, 0x49, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00 41c274ded801f745d6318186958107622e7a4fef33Ruben Brunk }; 42428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou private static final byte[] USER_COMMENT_UNICODE = { 43c274ded801f745d6318186958107622e7a4fef33Ruben Brunk 0x55, 0x4E, 0x49, 0x43, 0x4F, 0x44, 0x45, 0x00 44c274ded801f745d6318186958107622e7a4fef33Ruben Brunk }; 45670baca6f198f931be76f248b3ddcac7e2211ad4Earl Ou 462523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan private final IfdData[] mIfdDatas = new IfdData[IfdId.TYPE_IFD_COUNT]; 472523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan private byte[] mThumbnail; 482523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan private ArrayList<byte[]> mStripBytes = new ArrayList<byte[]>(); 492523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan private final ByteOrder mByteOrder; 502523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 51c274ded801f745d6318186958107622e7a4fef33Ruben Brunk ExifData(ByteOrder order) { 522523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan mByteOrder = order; 532523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 542523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 552523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan /** 56c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * Gets the compressed thumbnail. Returns null if there is no compressed 57c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * thumbnail. 582523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * 592523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * @see #hasCompressedThumbnail() 602523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan */ 61c274ded801f745d6318186958107622e7a4fef33Ruben Brunk protected byte[] getCompressedThumbnail() { 622523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan return mThumbnail; 632523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 642523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 652523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan /** 662523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * Sets the compressed thumbnail. 672523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan */ 68c274ded801f745d6318186958107622e7a4fef33Ruben Brunk protected void setCompressedThumbnail(byte[] thumbnail) { 692523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan mThumbnail = thumbnail; 702523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 712523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 722523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan /** 732523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * Returns true it this header contains a compressed thumbnail. 742523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan */ 75c274ded801f745d6318186958107622e7a4fef33Ruben Brunk protected boolean hasCompressedThumbnail() { 762523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan return mThumbnail != null; 772523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 782523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 792523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan /** 802523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * Adds an uncompressed strip. 812523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan */ 82c274ded801f745d6318186958107622e7a4fef33Ruben Brunk protected void setStripBytes(int index, byte[] strip) { 832523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan if (index < mStripBytes.size()) { 842523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan mStripBytes.set(index, strip); 852523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } else { 862523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan for (int i = mStripBytes.size(); i < index; i++) { 872523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan mStripBytes.add(null); 882523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 892523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan mStripBytes.add(strip); 902523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 912523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 922523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 932523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan /** 942523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * Gets the strip count. 952523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan */ 96c274ded801f745d6318186958107622e7a4fef33Ruben Brunk protected int getStripCount() { 972523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan return mStripBytes.size(); 982523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 992523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 1002523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan /** 1012523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * Gets the strip at the specified index. 102c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * 1032523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan * @exceptions #IndexOutOfBoundException 1042523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan */ 105c274ded801f745d6318186958107622e7a4fef33Ruben Brunk protected byte[] getStrip(int index) { 1062523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan return mStripBytes.get(index); 1072523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 1082523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 1092523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan /** 110c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * Returns true if this header contains uncompressed strip. 1112523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan */ 112c274ded801f745d6318186958107622e7a4fef33Ruben Brunk protected boolean hasUncompressedStrip() { 113c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return mStripBytes.size() != 0; 1142523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 1152523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 1162523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan /** 117c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * Gets the byte order. 1182523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan */ 119c274ded801f745d6318186958107622e7a4fef33Ruben Brunk protected ByteOrder getByteOrder() { 120c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return mByteOrder; 1212523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 1222523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 1232523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan /** 124c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * Returns the {@link IfdData} object corresponding to a given IFD if it 125c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * exists or null. 1262523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan */ 127c274ded801f745d6318186958107622e7a4fef33Ruben Brunk protected IfdData getIfdData(int ifdId) { 128c274ded801f745d6318186958107622e7a4fef33Ruben Brunk if (ExifTag.isValidIfd(ifdId)) { 129c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return mIfdDatas[ifdId]; 1302523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 131c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return null; 1322523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 1332523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 134670baca6f198f931be76f248b3ddcac7e2211ad4Earl Ou /** 135c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * Adds IFD data. If IFD data of the same type already exists, it will be 136c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * replaced by the new data. 137670baca6f198f931be76f248b3ddcac7e2211ad4Earl Ou */ 138c274ded801f745d6318186958107622e7a4fef33Ruben Brunk protected void addIfdData(IfdData data) { 139c274ded801f745d6318186958107622e7a4fef33Ruben Brunk mIfdDatas[data.getId()] = data; 140670baca6f198f931be76f248b3ddcac7e2211ad4Earl Ou } 141670baca6f198f931be76f248b3ddcac7e2211ad4Earl Ou 142670baca6f198f931be76f248b3ddcac7e2211ad4Earl Ou /** 143c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * Returns the {@link IfdData} object corresponding to a given IFD or 144c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * generates one if none exist. 145670baca6f198f931be76f248b3ddcac7e2211ad4Earl Ou */ 146c274ded801f745d6318186958107622e7a4fef33Ruben Brunk protected IfdData getOrCreateIfdData(int ifdId) { 1472523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan IfdData ifdData = mIfdDatas[ifdId]; 1482523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan if (ifdData == null) { 1492523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan ifdData = new IfdData(ifdId); 1502523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan mIfdDatas[ifdId] = ifdData; 1512523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 1522523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan return ifdData; 1532523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 1542523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 1552523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan /** 156c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * Returns the tag with a given TID in the given IFD if the tag exists. 157c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * Otherwise returns null. 1582523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan */ 159c274ded801f745d6318186958107622e7a4fef33Ruben Brunk protected ExifTag getTag(short tag, int ifd) { 160c274ded801f745d6318186958107622e7a4fef33Ruben Brunk IfdData ifdData = mIfdDatas[ifd]; 161c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return (ifdData == null) ? null : ifdData.getTag(tag); 1622523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 1632523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 1642523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan /** 165c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * Adds the given ExifTag to its default IFD and returns an existing ExifTag 166c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * with the same TID or null if none exist. 1672523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan */ 168c274ded801f745d6318186958107622e7a4fef33Ruben Brunk protected ExifTag addTag(ExifTag tag) { 169c274ded801f745d6318186958107622e7a4fef33Ruben Brunk if (tag != null) { 170c274ded801f745d6318186958107622e7a4fef33Ruben Brunk int ifd = tag.getIfd(); 171c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return addTag(tag, ifd); 172c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 173c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return null; 1742523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 1752523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 1762523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan /** 177c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * Adds the given ExifTag to the given IFD and returns an existing ExifTag 178c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * with the same TID or null if none exist. 179c06c8045b159d68f8fda051d59a0eb82215067eeEarl Ou */ 180c274ded801f745d6318186958107622e7a4fef33Ruben Brunk protected ExifTag addTag(ExifTag tag, int ifdId) { 181c274ded801f745d6318186958107622e7a4fef33Ruben Brunk if (tag != null && ExifTag.isValidIfd(ifdId)) { 182c274ded801f745d6318186958107622e7a4fef33Ruben Brunk IfdData ifdData = getOrCreateIfdData(ifdId); 183c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return ifdData.setTag(tag); 184c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 185c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return null; 186c06c8045b159d68f8fda051d59a0eb82215067eeEarl Ou } 187c06c8045b159d68f8fda051d59a0eb82215067eeEarl Ou 188c274ded801f745d6318186958107622e7a4fef33Ruben Brunk protected void clearThumbnailAndStrips() { 189c274ded801f745d6318186958107622e7a4fef33Ruben Brunk mThumbnail = null; 190c274ded801f745d6318186958107622e7a4fef33Ruben Brunk mStripBytes.clear(); 1912523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 1922523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 1932523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan /** 194c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * Removes the thumbnail and its related tags. IFD1 will be removed. 1952523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan */ 196c274ded801f745d6318186958107622e7a4fef33Ruben Brunk protected void removeThumbnailData() { 197c274ded801f745d6318186958107622e7a4fef33Ruben Brunk clearThumbnailAndStrips(); 198c274ded801f745d6318186958107622e7a4fef33Ruben Brunk mIfdDatas[IfdId.TYPE_IFD_1] = null; 1992523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 2002523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan 201cdeb78889a0a69de640fecabc40e00b106417ab8Earl Ou /** 202c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * Removes the tag with a given TID and IFD. 203cdeb78889a0a69de640fecabc40e00b106417ab8Earl Ou */ 204c274ded801f745d6318186958107622e7a4fef33Ruben Brunk protected void removeTag(short tagId, int ifdId) { 205c274ded801f745d6318186958107622e7a4fef33Ruben Brunk IfdData ifdData = mIfdDatas[ifdId]; 206c274ded801f745d6318186958107622e7a4fef33Ruben Brunk if (ifdData == null) { 207c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return; 208c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 209c274ded801f745d6318186958107622e7a4fef33Ruben Brunk ifdData.removeTag(tagId); 2102523f4344661b1e6a734d1ba20e92308c87a7c54Hung-ying Tyan } 211428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou 212428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou /** 213c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * Decodes the user comment tag into string as specified in the EXIF 214c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * standard. Returns null if decoding failed. 215428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou */ 216c274ded801f745d6318186958107622e7a4fef33Ruben Brunk protected String getUserComment() { 217428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou IfdData ifdData = mIfdDatas[IfdId.TYPE_IFD_0]; 218c274ded801f745d6318186958107622e7a4fef33Ruben Brunk if (ifdData == null) { 219c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return null; 220c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 221c274ded801f745d6318186958107622e7a4fef33Ruben Brunk ExifTag tag = ifdData.getTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_USER_COMMENT)); 222c274ded801f745d6318186958107622e7a4fef33Ruben Brunk if (tag == null) { 223c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return null; 224c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 225c274ded801f745d6318186958107622e7a4fef33Ruben Brunk if (tag.getComponentCount() < 8) { 226c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return null; 227c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 228428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou 229428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou byte[] buf = new byte[tag.getComponentCount()]; 230428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou tag.getBytes(buf); 231428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou 232428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou byte[] code = new byte[8]; 233428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou System.arraycopy(buf, 0, code, 0, 8); 234428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou 235428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou try { 236428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou if (Arrays.equals(code, USER_COMMENT_ASCII)) { 237428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou return new String(buf, 8, buf.length - 8, "US-ASCII"); 238428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou } else if (Arrays.equals(code, USER_COMMENT_JIS)) { 239428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou return new String(buf, 8, buf.length - 8, "EUC-JP"); 240428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou } else if (Arrays.equals(code, USER_COMMENT_UNICODE)) { 241428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou return new String(buf, 8, buf.length - 8, "UTF-16"); 242428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou } else { 243428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou return null; 244428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou } 245428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou } catch (UnsupportedEncodingException e) { 246428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou Log.w(TAG, "Failed to decode the user comment"); 247428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou return null; 248428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou } 249c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 250428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou 251c274ded801f745d6318186958107622e7a4fef33Ruben Brunk /** 252c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * Returns a list of all {@link ExifTag}s in the ExifData or null if there 253c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * are none. 254c274ded801f745d6318186958107622e7a4fef33Ruben Brunk */ 255c274ded801f745d6318186958107622e7a4fef33Ruben Brunk protected List<ExifTag> getAllTags() { 256c274ded801f745d6318186958107622e7a4fef33Ruben Brunk ArrayList<ExifTag> ret = new ArrayList<ExifTag>(); 257c274ded801f745d6318186958107622e7a4fef33Ruben Brunk for (IfdData d : mIfdDatas) { 258c274ded801f745d6318186958107622e7a4fef33Ruben Brunk if (d != null) { 259c274ded801f745d6318186958107622e7a4fef33Ruben Brunk ExifTag[] tags = d.getAllTags(); 260c274ded801f745d6318186958107622e7a4fef33Ruben Brunk if (tags != null) { 261c274ded801f745d6318186958107622e7a4fef33Ruben Brunk for (ExifTag t : tags) { 262c274ded801f745d6318186958107622e7a4fef33Ruben Brunk ret.add(t); 263c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 264c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 265c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 266c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 267c274ded801f745d6318186958107622e7a4fef33Ruben Brunk if (ret.size() == 0) { 268c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return null; 269c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 270c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return ret; 271428afc0b79d1fa911df89b94c6b1517688667c2dEarl Ou } 272c274ded801f745d6318186958107622e7a4fef33Ruben Brunk 273c274ded801f745d6318186958107622e7a4fef33Ruben Brunk /** 274c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * Returns a list of all {@link ExifTag}s in a given IFD or null if there 275c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * are none. 276c274ded801f745d6318186958107622e7a4fef33Ruben Brunk */ 277c274ded801f745d6318186958107622e7a4fef33Ruben Brunk protected List<ExifTag> getAllTagsForIfd(int ifd) { 278c274ded801f745d6318186958107622e7a4fef33Ruben Brunk IfdData d = mIfdDatas[ifd]; 279c274ded801f745d6318186958107622e7a4fef33Ruben Brunk if (d == null) { 280c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return null; 281c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 282c274ded801f745d6318186958107622e7a4fef33Ruben Brunk ExifTag[] tags = d.getAllTags(); 283c274ded801f745d6318186958107622e7a4fef33Ruben Brunk if (tags == null) { 284c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return null; 285c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 286c274ded801f745d6318186958107622e7a4fef33Ruben Brunk ArrayList<ExifTag> ret = new ArrayList<ExifTag>(tags.length); 287c274ded801f745d6318186958107622e7a4fef33Ruben Brunk for (ExifTag t : tags) { 288c274ded801f745d6318186958107622e7a4fef33Ruben Brunk ret.add(t); 289c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 290c274ded801f745d6318186958107622e7a4fef33Ruben Brunk if (ret.size() == 0) { 291c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return null; 292c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 293c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return ret; 294c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 295c274ded801f745d6318186958107622e7a4fef33Ruben Brunk 296c274ded801f745d6318186958107622e7a4fef33Ruben Brunk /** 297c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * Returns a list of all {@link ExifTag}s with a given TID or null if there 298c274ded801f745d6318186958107622e7a4fef33Ruben Brunk * are none. 299c274ded801f745d6318186958107622e7a4fef33Ruben Brunk */ 300c274ded801f745d6318186958107622e7a4fef33Ruben Brunk protected List<ExifTag> getAllTagsForTagId(short tag) { 301c274ded801f745d6318186958107622e7a4fef33Ruben Brunk ArrayList<ExifTag> ret = new ArrayList<ExifTag>(); 302c274ded801f745d6318186958107622e7a4fef33Ruben Brunk for (IfdData d : mIfdDatas) { 303c274ded801f745d6318186958107622e7a4fef33Ruben Brunk if (d != null) { 304c274ded801f745d6318186958107622e7a4fef33Ruben Brunk ExifTag t = d.getTag(tag); 305c274ded801f745d6318186958107622e7a4fef33Ruben Brunk if (t != null) { 306c274ded801f745d6318186958107622e7a4fef33Ruben Brunk ret.add(t); 307c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 308c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 309c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 310c274ded801f745d6318186958107622e7a4fef33Ruben Brunk if (ret.size() == 0) { 311c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return null; 312c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 313c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return ret; 314c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 315c274ded801f745d6318186958107622e7a4fef33Ruben Brunk 316c274ded801f745d6318186958107622e7a4fef33Ruben Brunk @Override 317c274ded801f745d6318186958107622e7a4fef33Ruben Brunk public boolean equals(Object obj) { 318c274ded801f745d6318186958107622e7a4fef33Ruben Brunk if (this == obj) { 319c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return true; 320c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 321c274ded801f745d6318186958107622e7a4fef33Ruben Brunk if (obj == null) { 322c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return false; 323c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 324c274ded801f745d6318186958107622e7a4fef33Ruben Brunk if (obj instanceof ExifData) { 325c274ded801f745d6318186958107622e7a4fef33Ruben Brunk ExifData data = (ExifData) obj; 326c274ded801f745d6318186958107622e7a4fef33Ruben Brunk if (data.mByteOrder != mByteOrder || 327c274ded801f745d6318186958107622e7a4fef33Ruben Brunk data.mStripBytes.size() != mStripBytes.size() || 328c274ded801f745d6318186958107622e7a4fef33Ruben Brunk !Arrays.equals(data.mThumbnail, mThumbnail)) { 329c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return false; 330c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 331c274ded801f745d6318186958107622e7a4fef33Ruben Brunk for (int i = 0; i < mStripBytes.size(); i++) { 332c274ded801f745d6318186958107622e7a4fef33Ruben Brunk if (!Arrays.equals(data.mStripBytes.get(i), mStripBytes.get(i))) { 333c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return false; 334c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 335c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 336c274ded801f745d6318186958107622e7a4fef33Ruben Brunk for (int i = 0; i < IfdId.TYPE_IFD_COUNT; i++) { 337c274ded801f745d6318186958107622e7a4fef33Ruben Brunk IfdData ifd1 = data.getIfdData(i); 338c274ded801f745d6318186958107622e7a4fef33Ruben Brunk IfdData ifd2 = getIfdData(i); 339c274ded801f745d6318186958107622e7a4fef33Ruben Brunk if (ifd1 != ifd2 && ifd1 != null && !ifd1.equals(ifd2)) { 340c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return false; 341c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 342c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 343c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return true; 344c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 345c274ded801f745d6318186958107622e7a4fef33Ruben Brunk return false; 346c274ded801f745d6318186958107622e7a4fef33Ruben Brunk } 347c274ded801f745d6318186958107622e7a4fef33Ruben Brunk 3481c515f1aed514638cc030cd5cba5258231e74bb5Hung-ying Tyan} 349