View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.imaging.formats.tiff;
18  
19  import java.util.ArrayList;
20  import java.util.Collections;
21  import java.util.HashMap;
22  import java.util.List;
23  import java.util.Map;
24  
25  import org.apache.commons.imaging.formats.tiff.constants.AdobePageMaker6TagConstants;
26  import org.apache.commons.imaging.formats.tiff.constants.AdobePhotoshopTagConstants;
27  import org.apache.commons.imaging.formats.tiff.constants.AliasSketchbookProTagConstants;
28  import org.apache.commons.imaging.formats.tiff.constants.DcfTagConstants;
29  import org.apache.commons.imaging.formats.tiff.constants.DngTagConstants;
30  import org.apache.commons.imaging.formats.tiff.constants.ExifTagConstants;
31  import org.apache.commons.imaging.formats.tiff.constants.GdalLibraryTagConstants;
32  import org.apache.commons.imaging.formats.tiff.constants.GeoTiffTagConstants;
33  import org.apache.commons.imaging.formats.tiff.constants.GpsTagConstants;
34  import org.apache.commons.imaging.formats.tiff.constants.HylaFaxTagConstants;
35  import org.apache.commons.imaging.formats.tiff.constants.MicrosoftHdPhotoTagConstants;
36  import org.apache.commons.imaging.formats.tiff.constants.MicrosoftTagConstants;
37  import org.apache.commons.imaging.formats.tiff.constants.MolecularDynamicsGelTagConstants;
38  import org.apache.commons.imaging.formats.tiff.constants.OceScanjobTagConstants;
39  import org.apache.commons.imaging.formats.tiff.constants.Rfc2301TagConstants;
40  import org.apache.commons.imaging.formats.tiff.constants.Tiff4TagConstants;
41  import org.apache.commons.imaging.formats.tiff.constants.TiffDirectoryType;
42  import org.apache.commons.imaging.formats.tiff.constants.TiffEpTagConstants;
43  import org.apache.commons.imaging.formats.tiff.constants.TiffTagConstants;
44  import org.apache.commons.imaging.formats.tiff.constants.WangTagConstants;
45  import org.apache.commons.imaging.formats.tiff.taginfos.TagInfo;
46  
47  final class TiffTags {
48  
49      private static final List<TagInfo> ALL_TAGS = makeMergedTagList();
50  
51      private static final Map<Integer, List<TagInfo>> ALL_TAG_MAP = makeTagMap(TiffTags.ALL_TAGS);
52      private static final Map<Integer, Integer> TAG_COUNTS = countTags(TiffTags.ALL_TAGS);
53  
54      private static Map<Integer, Integer> countTags(final List<TagInfo> tags) {
55          final Map<Integer, Integer> map = new HashMap<>();
56  
57          for (final TagInfo tag : tags) {
58              map.merge(tag.tag, 1, Integer::sum);
59          }
60  
61          return map;
62      }
63  
64      static TagInfo getTag(final int directoryType, final int tag) {
65          final List<TagInfo> possibleMatches = ALL_TAG_MAP.get(tag);
66  
67          if (null == possibleMatches) {
68              return TiffTagConstants.TIFF_TAG_UNKNOWN;
69          }
70  
71          return getTag(directoryType, possibleMatches);
72      }
73  
74      private static TagInfo getTag(final int directoryType, final List<TagInfo> possibleMatches) {
75          // Please keep this method in sync with TiffImageMetadata's findField()
76  
77          if (possibleMatches.isEmpty()) {
78              return null;
79          }
80  
81          // first search for exact match.
82          for (final TagInfo tagInfo : possibleMatches) {
83              if (tagInfo.directoryType == TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN) {
84                  // pass
85                  continue;
86              }
87              if (directoryType == tagInfo.directoryType.directoryType) {
88                  return tagInfo;
89              }
90          }
91  
92          // accept an inexact match.
93          for (final TagInfo tagInfo : possibleMatches) {
94              if (tagInfo.directoryType == TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN) {
95                  // pass
96                  continue;
97              }
98              if (directoryType >= 0 && tagInfo.directoryType.isImageDirectory()) {
99                  return tagInfo;
100             }
101             if (directoryType < 0 && !tagInfo.directoryType.isImageDirectory()) {
102                 return tagInfo;
103             }
104         }
105 
106         // accept a wildcard match.
107         for (final TagInfo tagInfo : possibleMatches) {
108             if (tagInfo.directoryType == TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN) {
109                 return tagInfo;
110             }
111         }
112 
113         return TiffTagConstants.TIFF_TAG_UNKNOWN;
114     }
115 
116     static Integer getTagCount(final int tag) {
117         return TAG_COUNTS.get(tag);
118     }
119 
120     private static List<TagInfo> makeMergedTagList() {
121         final ArrayList<TagInfo> result = new ArrayList<>(AdobePageMaker6TagConstants.ALL_ADOBE_PAGEMAKER_6_TAGS);
122         result.addAll(AdobePhotoshopTagConstants.ALL_ADOBE_PHOTOSHOP_TAGS);
123         result.addAll(AliasSketchbookProTagConstants.ALL_ALIAS_SKETCHBOOK_PRO_TAGS);
124         result.addAll(DcfTagConstants.ALL_DCF_TAGS);
125         result.addAll(DngTagConstants.ALL_DNG_TAGS);
126         result.addAll(ExifTagConstants.ALL_EXIF_TAGS);
127         result.addAll(GeoTiffTagConstants.ALL_GEO_TIFF_TAGS);
128         result.addAll(GdalLibraryTagConstants.ALL_GDAL_LIBRARY_TAGS);
129         result.addAll(GpsTagConstants.ALL_GPS_TAGS);
130         result.addAll(HylaFaxTagConstants.ALL_HYLAFAX_TAGS);
131         result.addAll(MicrosoftTagConstants.ALL_MICROSOFT_TAGS);
132         result.addAll(MicrosoftHdPhotoTagConstants.ALL_MICROSOFT_HD_PHOTO_TAGS);
133         result.addAll(MolecularDynamicsGelTagConstants.ALL_MOLECULAR_DYNAMICS_GEL_TAGS);
134         result.addAll(OceScanjobTagConstants.ALL_OCE_SCANJOB_TAGS);
135         result.addAll(Rfc2301TagConstants.ALL_RFC_2301_TAGS);
136         result.addAll(Tiff4TagConstants.ALL_TIFF_4_TAGS);
137         result.addAll(TiffEpTagConstants.ALL_TIFF_EP_TAGS);
138         result.addAll(TiffTagConstants.ALL_TIFF_TAGS);
139         result.addAll(WangTagConstants.ALL_WANG_TAGS);
140 
141         return Collections.unmodifiableList(result);
142     }
143 
144     private static Map<Integer, List<TagInfo>> makeTagMap(final List<TagInfo> tags) {
145         // make sure to use the thread-safe version; this is shared state.
146         final Map<Integer, List<TagInfo>> map = new HashMap<>();
147 
148         for (final TagInfo tag : tags) {
149             final List<TagInfo> tagList = map.computeIfAbsent(tag.tag, k -> new ArrayList<>());
150             tagList.add(tag);
151         }
152 
153         return map;
154     }
155 
156     private TiffTags() {
157     }
158 
159 }