1321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou/*
2321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou * Copyright (C) 2012 The Android Open Source Project
3321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou *
4321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou * Licensed under the Apache License, Version 2.0 (the "License");
5321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou * you may not use this file except in compliance with the License.
6321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou * You may obtain a copy of the License at
7321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou *
8321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou *      http://www.apache.org/licenses/LICENSE-2.0
9321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou *
10321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou * Unless required by applicable law or agreed to in writing, software
11321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou * distributed under the License is distributed on an "AS IS" BASIS,
12321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou * See the License for the specific language governing permissions and
14321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou * limitations under the License.
15321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou */
16321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou
17321e7c477a66df696b92d1617a33f6bafab7886dEarl Oupackage com.android.gallery3d.exif;
18321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou
19321e7c477a66df696b92d1617a33f6bafab7886dEarl Ouimport java.util.HashMap;
20321e7c477a66df696b92d1617a33f6bafab7886dEarl Ouimport java.util.Map;
21321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou
224ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou/**
234ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou * This class stores all the tags in an IFD.
244ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou *
254ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou * @see ExifData
264ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou * @see ExifTag
274ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou */
2889591324c5d1097e59217177ad3ea74598867584Earl Ouclass IfdData {
29321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou
304ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou    private final int mIfdId;
31321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou    private final Map<Short, ExifTag> mExifTags = new HashMap<Short, ExifTag>();
32b0f84ee364784ffb64bb58df675a8042cbb49a6dEarl Ou    private int mOffsetToNextIfd = 0;
336e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk    private static final int[] sIfds = {
346e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk            IfdId.TYPE_IFD_0, IfdId.TYPE_IFD_1, IfdId.TYPE_IFD_EXIF,
356e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk            IfdId.TYPE_IFD_INTEROPERABILITY, IfdId.TYPE_IFD_GPS
366e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk    };
374ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou    /**
384ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou     * Creates an IfdData with given IFD ID.
394ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou     *
404ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou     * @see IfdId#TYPE_IFD_0
414ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou     * @see IfdId#TYPE_IFD_1
424ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou     * @see IfdId#TYPE_IFD_EXIF
434ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou     * @see IfdId#TYPE_IFD_GPS
444ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou     * @see IfdId#TYPE_IFD_INTEROPERABILITY
454ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou     */
466e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk    IfdData(int ifdId) {
474ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou        mIfdId = ifdId;
484ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou    }
494ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou
506e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk    static protected int[] getIfds() {
516e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk        return sIfds;
526e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk    }
536e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk
544ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou    /**
554ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou     * Get a array the contains all {@link ExifTag} in this IFD.
564ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou     */
576e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk    protected ExifTag[] getAllTags() {
589bc2a5c83de59a3131bfeb31dad45df2b47715abEarl Ou        return mExifTags.values().toArray(new ExifTag[mExifTags.size()]);
59321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou    }
60321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou
614ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou    /**
624ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou     * Gets the ID of this IFD.
634ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou     *
644ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou     * @see IfdId#TYPE_IFD_0
654ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou     * @see IfdId#TYPE_IFD_1
664ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou     * @see IfdId#TYPE_IFD_EXIF
674ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou     * @see IfdId#TYPE_IFD_GPS
684ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou     * @see IfdId#TYPE_IFD_INTEROPERABILITY
694ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou     */
706e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk    protected int getId() {
714ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou        return mIfdId;
72321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou    }
73321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou
744ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou    /**
756e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk     * Gets the {@link ExifTag} with given tag id. Return null if there is no
766e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk     * such tag.
774ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou     */
786e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk    protected ExifTag getTag(short tagId) {
79321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou        return mExifTags.get(tagId);
80321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou    }
81321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou
824ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou    /**
834ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou     * Adds or replaces a {@link ExifTag}.
844ae9b211fee74f801f003bc9ad716e214de1a4f0Earl Ou     */
856e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk    protected ExifTag setTag(ExifTag tag) {
866e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk        tag.setIfd(mIfdId);
876e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk        return mExifTags.put(tag.getTagId(), tag);
886e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk    }
896e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk
906e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk    protected boolean checkCollision(short tagId) {
916e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk        return mExifTags.get(tagId) != null;
92321e7c477a66df696b92d1617a33f6bafab7886dEarl Ou    }
93cde6ac521216801e835df1c20b68dd21d4fd04a4Earl Ou
94cde6ac521216801e835df1c20b68dd21d4fd04a4Earl Ou    /**
95b430b34197d3016d1659ed104abbd3cb5d6d881dEarl Ou     * Removes the tag of the given ID
96b430b34197d3016d1659ed104abbd3cb5d6d881dEarl Ou     */
976e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk    protected void removeTag(short tagId) {
98b430b34197d3016d1659ed104abbd3cb5d6d881dEarl Ou        mExifTags.remove(tagId);
99b430b34197d3016d1659ed104abbd3cb5d6d881dEarl Ou    }
100b430b34197d3016d1659ed104abbd3cb5d6d881dEarl Ou
101b430b34197d3016d1659ed104abbd3cb5d6d881dEarl Ou    /**
102cde6ac521216801e835df1c20b68dd21d4fd04a4Earl Ou     * Gets the tags count in the IFD.
103cde6ac521216801e835df1c20b68dd21d4fd04a4Earl Ou     */
1046e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk    protected int getTagCount() {
105cde6ac521216801e835df1c20b68dd21d4fd04a4Earl Ou        return mExifTags.size();
106cde6ac521216801e835df1c20b68dd21d4fd04a4Earl Ou    }
107cde6ac521216801e835df1c20b68dd21d4fd04a4Earl Ou
108b0f84ee364784ffb64bb58df675a8042cbb49a6dEarl Ou    /**
109b0f84ee364784ffb64bb58df675a8042cbb49a6dEarl Ou     * Sets the offset of next IFD.
110b0f84ee364784ffb64bb58df675a8042cbb49a6dEarl Ou     */
1116e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk    protected void setOffsetToNextIfd(int offset) {
112b0f84ee364784ffb64bb58df675a8042cbb49a6dEarl Ou        mOffsetToNextIfd = offset;
113b0f84ee364784ffb64bb58df675a8042cbb49a6dEarl Ou    }
114b0f84ee364784ffb64bb58df675a8042cbb49a6dEarl Ou
115b0f84ee364784ffb64bb58df675a8042cbb49a6dEarl Ou    /**
116b0f84ee364784ffb64bb58df675a8042cbb49a6dEarl Ou     * Gets the offset of next IFD.
117b0f84ee364784ffb64bb58df675a8042cbb49a6dEarl Ou     */
1186e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk    protected int getOffsetToNextIfd() {
119b0f84ee364784ffb64bb58df675a8042cbb49a6dEarl Ou        return mOffsetToNextIfd;
120b0f84ee364784ffb64bb58df675a8042cbb49a6dEarl Ou    }
121cde6ac521216801e835df1c20b68dd21d4fd04a4Earl Ou
122cde6ac521216801e835df1c20b68dd21d4fd04a4Earl Ou    /**
1236e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk     * Returns true if all tags in this two IFDs are equal. Note that tags of
1246e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk     * IFDs offset or thumbnail offset will be ignored.
125cde6ac521216801e835df1c20b68dd21d4fd04a4Earl Ou     */
126cde6ac521216801e835df1c20b68dd21d4fd04a4Earl Ou    @Override
127cde6ac521216801e835df1c20b68dd21d4fd04a4Earl Ou    public boolean equals(Object obj) {
1286e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk        if (this == obj) {
1296e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk            return true;
1306e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk        }
1316e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk        if (obj == null) {
1326e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk            return false;
1336e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk        }
134cde6ac521216801e835df1c20b68dd21d4fd04a4Earl Ou        if (obj instanceof IfdData) {
135cde6ac521216801e835df1c20b68dd21d4fd04a4Earl Ou            IfdData data = (IfdData) obj;
136cde6ac521216801e835df1c20b68dd21d4fd04a4Earl Ou            if (data.getId() == mIfdId && data.getTagCount() == getTagCount()) {
1379bc2a5c83de59a3131bfeb31dad45df2b47715abEarl Ou                ExifTag[] tags = data.getAllTags();
1386e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk                for (ExifTag tag : tags) {
1396e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk                    if (ExifInterface.isOffsetTag(tag.getTagId())) {
1406e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk                        continue;
1416e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk                    }
142cde6ac521216801e835df1c20b68dd21d4fd04a4Earl Ou                    ExifTag tag2 = mExifTags.get(tag.getTagId());
1436e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk                    if (!tag.equals(tag2)) {
1446e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk                        return false;
1456e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk                    }
146cde6ac521216801e835df1c20b68dd21d4fd04a4Earl Ou                }
147cde6ac521216801e835df1c20b68dd21d4fd04a4Earl Ou                return true;
148cde6ac521216801e835df1c20b68dd21d4fd04a4Earl Ou            }
149cde6ac521216801e835df1c20b68dd21d4fd04a4Earl Ou        }
150cde6ac521216801e835df1c20b68dd21d4fd04a4Earl Ou        return false;
151cde6ac521216801e835df1c20b68dd21d4fd04a4Earl Ou    }
1526e6a524390d8ddebce5de0dcc8ae258e652ec80aRuben Brunk}
153