1e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka/* 2e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Copyright (C) 2012 The Android Open Source Project 3e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 4e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Licensed under the Apache License, Version 2.0 (the "License"); 5e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * you may not use this file except in compliance with the License. 6e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * You may obtain a copy of the License at 7e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 8e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * http://www.apache.org/licenses/LICENSE-2.0 9e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 10e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Unless required by applicable law or agreed to in writing, software 11e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * distributed under the License is distributed on an "AS IS" BASIS, 12e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * See the License for the specific language governing permissions and 14e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * limitations under the License. 15e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 16e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 17e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurkapackage com.android.gallery3d.exif; 18e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 19e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurkaimport java.util.HashMap; 20e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurkaimport java.util.Map; 21e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 22e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka/** 23e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * This class stores all the tags in an IFD. 24e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 25e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see ExifData 26e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see ExifTag 27e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 28e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurkaclass IfdData { 29e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 30e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private final int mIfdId; 31e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private final Map<Short, ExifTag> mExifTags = new HashMap<Short, ExifTag>(); 32e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private int mOffsetToNextIfd = 0; 33e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka private static final int[] sIfds = { 34e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka IfdId.TYPE_IFD_0, IfdId.TYPE_IFD_1, IfdId.TYPE_IFD_EXIF, 35e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka IfdId.TYPE_IFD_INTEROPERABILITY, IfdId.TYPE_IFD_GPS 36e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka }; 37e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 38e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Creates an IfdData with given IFD ID. 39e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 40e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see IfdId#TYPE_IFD_0 41e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see IfdId#TYPE_IFD_1 42e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see IfdId#TYPE_IFD_EXIF 43e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see IfdId#TYPE_IFD_GPS 44e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see IfdId#TYPE_IFD_INTEROPERABILITY 45e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 46e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka IfdData(int ifdId) { 47e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mIfdId = ifdId; 48e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 49e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 50e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka static protected int[] getIfds() { 51e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return sIfds; 52e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 53e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 54e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 55e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Get a array the contains all {@link ExifTag} in this IFD. 56e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 57e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka protected ExifTag[] getAllTags() { 58e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return mExifTags.values().toArray(new ExifTag[mExifTags.size()]); 59e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 60e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 61e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 62e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the ID of this IFD. 63e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * 64e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see IfdId#TYPE_IFD_0 65e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see IfdId#TYPE_IFD_1 66e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see IfdId#TYPE_IFD_EXIF 67e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see IfdId#TYPE_IFD_GPS 68e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * @see IfdId#TYPE_IFD_INTEROPERABILITY 69e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 70e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka protected int getId() { 71e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return mIfdId; 72e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 73e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 74e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 75e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the {@link ExifTag} with given tag id. Return null if there is no 76e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * such tag. 77e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 78e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka protected ExifTag getTag(short tagId) { 79e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return mExifTags.get(tagId); 80e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 81e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 82e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 83e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Adds or replaces a {@link ExifTag}. 84e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 85e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka protected ExifTag setTag(ExifTag tag) { 86e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka tag.setIfd(mIfdId); 87e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return mExifTags.put(tag.getTagId(), tag); 88e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 89e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 90e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka protected boolean checkCollision(short tagId) { 91e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return mExifTags.get(tagId) != null; 92e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 93e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 94e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 95e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Removes the tag of the given ID 96e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 97e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka protected void removeTag(short tagId) { 98e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mExifTags.remove(tagId); 99e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 100e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 101e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 102e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the tags count in the IFD. 103e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 104e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka protected int getTagCount() { 105e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return mExifTags.size(); 106e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 107e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 108e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 109e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Sets the offset of next IFD. 110e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 111e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka protected void setOffsetToNextIfd(int offset) { 112e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka mOffsetToNextIfd = offset; 113e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 114e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 115e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 116e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Gets the offset of next IFD. 117e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 118e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka protected int getOffsetToNextIfd() { 119e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return mOffsetToNextIfd; 120e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 121e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka 122e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka /** 123e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * Returns true if all tags in this two IFDs are equal. Note that tags of 124e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka * IFDs offset or thumbnail offset will be ignored. 125e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka */ 126e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka @Override 127e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka public boolean equals(Object obj) { 128e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (this == obj) { 129e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return true; 130e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 131e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (obj == null) { 132e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 133e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 134e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (obj instanceof IfdData) { 135e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka IfdData data = (IfdData) obj; 136e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (data.getId() == mIfdId && data.getTagCount() == getTagCount()) { 137e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka ExifTag[] tags = data.getAllTags(); 138e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka for (ExifTag tag : tags) { 139e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (ExifInterface.isOffsetTag(tag.getTagId())) { 140e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka continue; 141e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 142e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka ExifTag tag2 = mExifTags.get(tag.getTagId()); 143e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka if (!tag.equals(tag2)) { 144e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 145e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 146e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 147e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return true; 148e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 149e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 150e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka return false; 151e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka } 152e8d1bf7a439450b9979701909164a6baffbe8baeMichael Jurka} 153