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
17package com.android.camera.exif;
18
19import java.util.HashMap;
20import java.util.Map;
21
22/**
23 * This class stores all the tags in an IFD.
24 *
25 * @see ExifData
26 * @see ExifTag
27 */
28class 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     */
46    IfdData(int ifdId) {
47        mIfdId = ifdId;
48    }
49
50    static protected int[] getIfds() {
51        return sIfds;
52    }
53
54    /**
55     * Get a array the contains all {@link ExifTag} in this IFD.
56     */
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     */
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     */
78    protected ExifTag getTag(short tagId) {
79        return mExifTags.get(tagId);
80    }
81
82    /**
83     * Adds or replaces a {@link ExifTag}.
84     */
85    protected ExifTag setTag(ExifTag tag) {
86        tag.setIfd(mIfdId);
87        return mExifTags.put(tag.getTagId(), tag);
88    }
89
90    protected boolean checkCollision(short tagId) {
91        return mExifTags.get(tagId) != null;
92    }
93
94    /**
95     * Removes the tag of the given ID
96     */
97    protected void removeTag(short tagId) {
98        mExifTags.remove(tagId);
99    }
100
101    /**
102     * Gets the tags count in the IFD.
103     */
104    protected int getTagCount() {
105        return mExifTags.size();
106    }
107
108    /**
109     * Sets the offset of next IFD.
110     */
111    protected void setOffsetToNextIfd(int offset) {
112        mOffsetToNextIfd = offset;
113    }
114
115    /**
116     * Gets the offset of next IFD.
117     */
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
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