1 /*
2  * Copyright (C) 2016 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.dialer.callcomposer.camera.exif;
18 
19 import android.support.v4.util.ArrayMap;
20 import java.util.Map;
21 import java.util.Objects;
22 
23 /**
24  * This class stores all the tags in an IFD.
25  *
26  * @see ExifData
27  * @see ExifTag
28  */
29 class IfdData {
30 
31   private final int ifdId;
32   private final Map<Short, ExifTag> exifTags = new ArrayMap<>();
33   private static final int[] ifds = {
34     IfdId.TYPE_IFD_0,
35     IfdId.TYPE_IFD_1,
36     IfdId.TYPE_IFD_EXIF,
37     IfdId.TYPE_IFD_INTEROPERABILITY,
38     IfdId.TYPE_IFD_GPS
39   };
40   /**
41    * Creates an IfdData with given IFD ID.
42    *
43    * @see IfdId#TYPE_IFD_0
44    * @see IfdId#TYPE_IFD_1
45    * @see IfdId#TYPE_IFD_EXIF
46    * @see IfdId#TYPE_IFD_GPS
47    * @see IfdId#TYPE_IFD_INTEROPERABILITY
48    */
IfdData(int ifdId)49   IfdData(int ifdId) {
50     this.ifdId = ifdId;
51   }
52 
getIfds()53   static int[] getIfds() {
54     return ifds;
55   }
56 
57   /** Get a array the contains all {@link ExifTag} in this IFD. */
getAllTags()58   private ExifTag[] getAllTags() {
59     return exifTags.values().toArray(new ExifTag[exifTags.size()]);
60   }
61 
62   /**
63    * Gets the ID of this IFD.
64    *
65    * @see IfdId#TYPE_IFD_0
66    * @see IfdId#TYPE_IFD_1
67    * @see IfdId#TYPE_IFD_EXIF
68    * @see IfdId#TYPE_IFD_GPS
69    * @see IfdId#TYPE_IFD_INTEROPERABILITY
70    */
getId()71   protected int getId() {
72     return ifdId;
73   }
74 
75   /** Gets the {@link ExifTag} with given tag id. Return null if there is no such tag. */
getTag(short tagId)76   protected ExifTag getTag(short tagId) {
77     return exifTags.get(tagId);
78   }
79 
80   /** Adds or replaces a {@link ExifTag}. */
setTag(ExifTag tag)81   protected ExifTag setTag(ExifTag tag) {
82     tag.setIfd(ifdId);
83     return exifTags.put(tag.getTagId(), tag);
84   }
85 
86   /** Gets the tags count in the IFD. */
getTagCount()87   private int getTagCount() {
88     return exifTags.size();
89   }
90 
91   /**
92    * Returns true if all tags in this two IFDs are equal. Note that tags of IFDs offset or thumbnail
93    * offset will be ignored.
94    */
95   @Override
equals(Object obj)96   public boolean equals(Object obj) {
97     if (this == obj) {
98       return true;
99     }
100     if (obj == null) {
101       return false;
102     }
103     if (obj instanceof IfdData) {
104       IfdData data = (IfdData) obj;
105       if (data.getId() == ifdId && data.getTagCount() == getTagCount()) {
106         ExifTag[] tags = data.getAllTags();
107         for (ExifTag tag : tags) {
108           if (ExifInterface.isOffsetTag(tag.getTagId())) {
109             continue;
110           }
111           ExifTag tag2 = exifTags.get(tag.getTagId());
112           if (!tag.equals(tag2)) {
113             return false;
114           }
115         }
116         return true;
117       }
118     }
119     return false;
120   }
121 
122   @Override
hashCode()123   public int hashCode() {
124     return Objects.hash(ifdId, exifTags);
125   }
126 }
127