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