1 | /*
|
---|
2 | * Copyright 2002-2017 Drew Noakes
|
---|
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 | * More information about this project is available at:
|
---|
17 | *
|
---|
18 | * https://drewnoakes.com/code/exif/
|
---|
19 | * https://github.com/drewnoakes/metadata-extractor
|
---|
20 | */
|
---|
21 | package com.drew.metadata.iptc;
|
---|
22 |
|
---|
23 | import com.drew.lang.annotations.NotNull;
|
---|
24 | import com.drew.lang.annotations.Nullable;
|
---|
25 | import com.drew.metadata.Directory;
|
---|
26 |
|
---|
27 | import java.text.DateFormat;
|
---|
28 | import java.text.ParseException;
|
---|
29 | import java.text.SimpleDateFormat;
|
---|
30 | import java.util.Arrays;
|
---|
31 | import java.util.Date;
|
---|
32 | import java.util.HashMap;
|
---|
33 | import java.util.List;
|
---|
34 |
|
---|
35 | /**
|
---|
36 | * Describes tags used by the International Press Telecommunications Council (IPTC) metadata format.
|
---|
37 | *
|
---|
38 | * @author Drew Noakes https://drewnoakes.com
|
---|
39 | */
|
---|
40 | @SuppressWarnings("WeakerAccess")
|
---|
41 | public class IptcDirectory extends Directory
|
---|
42 | {
|
---|
43 | // IPTC EnvelopeRecord Tags
|
---|
44 | public static final int TAG_ENVELOPE_RECORD_VERSION = 0x0100; // 0 + 0x0100
|
---|
45 | public static final int TAG_DESTINATION = 0x0105; // 5
|
---|
46 | public static final int TAG_FILE_FORMAT = 0x0114; // 20
|
---|
47 | public static final int TAG_FILE_VERSION = 0x0116; // 22
|
---|
48 | public static final int TAG_SERVICE_ID = 0x011E; // 30
|
---|
49 | public static final int TAG_ENVELOPE_NUMBER = 0x0128; // 40
|
---|
50 | public static final int TAG_PRODUCT_ID = 0x0132; // 50
|
---|
51 | public static final int TAG_ENVELOPE_PRIORITY = 0x013C; // 60
|
---|
52 | public static final int TAG_DATE_SENT = 0x0146; // 70
|
---|
53 | public static final int TAG_TIME_SENT = 0x0150; // 80
|
---|
54 | public static final int TAG_CODED_CHARACTER_SET = 0x015A; // 90
|
---|
55 | public static final int TAG_UNIQUE_OBJECT_NAME = 0x0164; // 100
|
---|
56 | public static final int TAG_ARM_IDENTIFIER = 0x0178; // 120
|
---|
57 | public static final int TAG_ARM_VERSION = 0x017a; // 122
|
---|
58 |
|
---|
59 | // IPTC ApplicationRecord Tags
|
---|
60 | public static final int TAG_APPLICATION_RECORD_VERSION = 0x0200; // 0 + 0x0200
|
---|
61 | public static final int TAG_OBJECT_TYPE_REFERENCE = 0x0203; // 3
|
---|
62 | public static final int TAG_OBJECT_ATTRIBUTE_REFERENCE = 0x0204; // 4
|
---|
63 | public static final int TAG_OBJECT_NAME = 0x0205; // 5
|
---|
64 | public static final int TAG_EDIT_STATUS = 0x0207; // 7
|
---|
65 | public static final int TAG_EDITORIAL_UPDATE = 0x0208; // 8
|
---|
66 | public static final int TAG_URGENCY = 0X020A; // 10
|
---|
67 | public static final int TAG_SUBJECT_REFERENCE = 0X020C; // 12
|
---|
68 | public static final int TAG_CATEGORY = 0x020F; // 15
|
---|
69 | public static final int TAG_SUPPLEMENTAL_CATEGORIES = 0x0214; // 20
|
---|
70 | public static final int TAG_FIXTURE_ID = 0x0216; // 22
|
---|
71 | public static final int TAG_KEYWORDS = 0x0219; // 25
|
---|
72 | public static final int TAG_CONTENT_LOCATION_CODE = 0x021A; // 26
|
---|
73 | public static final int TAG_CONTENT_LOCATION_NAME = 0x021B; // 27
|
---|
74 | public static final int TAG_RELEASE_DATE = 0X021E; // 30
|
---|
75 | public static final int TAG_RELEASE_TIME = 0x0223; // 35
|
---|
76 | public static final int TAG_EXPIRATION_DATE = 0x0225; // 37
|
---|
77 | public static final int TAG_EXPIRATION_TIME = 0x0226; // 38
|
---|
78 | public static final int TAG_SPECIAL_INSTRUCTIONS = 0x0228; // 40
|
---|
79 | public static final int TAG_ACTION_ADVISED = 0x022A; // 42
|
---|
80 | public static final int TAG_REFERENCE_SERVICE = 0x022D; // 45
|
---|
81 | public static final int TAG_REFERENCE_DATE = 0x022F; // 47
|
---|
82 | public static final int TAG_REFERENCE_NUMBER = 0x0232; // 50
|
---|
83 | public static final int TAG_DATE_CREATED = 0x0237; // 55
|
---|
84 | public static final int TAG_TIME_CREATED = 0X023C; // 60
|
---|
85 | public static final int TAG_DIGITAL_DATE_CREATED = 0x023E; // 62
|
---|
86 | public static final int TAG_DIGITAL_TIME_CREATED = 0x023F; // 63
|
---|
87 | public static final int TAG_ORIGINATING_PROGRAM = 0x0241; // 65
|
---|
88 | public static final int TAG_PROGRAM_VERSION = 0x0246; // 70
|
---|
89 | public static final int TAG_OBJECT_CYCLE = 0x024B; // 75
|
---|
90 | public static final int TAG_BY_LINE = 0x0250; // 80
|
---|
91 | public static final int TAG_BY_LINE_TITLE = 0x0255; // 85
|
---|
92 | public static final int TAG_CITY = 0x025A; // 90
|
---|
93 | public static final int TAG_SUB_LOCATION = 0x025C; // 92
|
---|
94 | public static final int TAG_PROVINCE_OR_STATE = 0x025F; // 95
|
---|
95 | public static final int TAG_COUNTRY_OR_PRIMARY_LOCATION_CODE = 0x0264; // 100
|
---|
96 | public static final int TAG_COUNTRY_OR_PRIMARY_LOCATION_NAME = 0x0265; // 101
|
---|
97 | public static final int TAG_ORIGINAL_TRANSMISSION_REFERENCE = 0x0267; // 103
|
---|
98 | public static final int TAG_HEADLINE = 0x0269; // 105
|
---|
99 | public static final int TAG_CREDIT = 0x026E; // 110
|
---|
100 | public static final int TAG_SOURCE = 0x0273; // 115
|
---|
101 | public static final int TAG_COPYRIGHT_NOTICE = 0x0274; // 116
|
---|
102 | public static final int TAG_CONTACT = 0x0276; // 118
|
---|
103 | public static final int TAG_CAPTION = 0x0278; // 120
|
---|
104 | public static final int TAG_LOCAL_CAPTION = 0x0279; // 121
|
---|
105 | public static final int TAG_CAPTION_WRITER = 0x027A; // 122
|
---|
106 | public static final int TAG_RASTERIZED_CAPTION = 0x027D; // 125
|
---|
107 | public static final int TAG_IMAGE_TYPE = 0x0282; // 130
|
---|
108 | public static final int TAG_IMAGE_ORIENTATION = 0x0283; // 131
|
---|
109 | public static final int TAG_LANGUAGE_IDENTIFIER = 0x0287; // 135
|
---|
110 | public static final int TAG_AUDIO_TYPE = 0x0296; // 150
|
---|
111 | public static final int TAG_AUDIO_SAMPLING_RATE = 0x0297; // 151
|
---|
112 | public static final int TAG_AUDIO_SAMPLING_RESOLUTION = 0x0298; // 152
|
---|
113 | public static final int TAG_AUDIO_DURATION = 0x0299; // 153
|
---|
114 | public static final int TAG_AUDIO_OUTCUE = 0x029A; // 154
|
---|
115 |
|
---|
116 | public static final int TAG_JOB_ID = 0x02B8; // 184
|
---|
117 | public static final int TAG_MASTER_DOCUMENT_ID = 0x02B9; // 185
|
---|
118 | public static final int TAG_SHORT_DOCUMENT_ID = 0x02BA; // 186
|
---|
119 | public static final int TAG_UNIQUE_DOCUMENT_ID = 0x02BB; // 187
|
---|
120 | public static final int TAG_OWNER_ID = 0x02BC; // 188
|
---|
121 |
|
---|
122 | public static final int TAG_OBJECT_PREVIEW_FILE_FORMAT = 0x02C8; // 200
|
---|
123 | public static final int TAG_OBJECT_PREVIEW_FILE_FORMAT_VERSION = 0x02C9; // 201
|
---|
124 | public static final int TAG_OBJECT_PREVIEW_DATA = 0x02CA; // 202
|
---|
125 |
|
---|
126 | @NotNull
|
---|
127 | protected static final HashMap<Integer, String> _tagNameMap = new HashMap<Integer, String>();
|
---|
128 |
|
---|
129 | static
|
---|
130 | {
|
---|
131 | _tagNameMap.put(TAG_ENVELOPE_RECORD_VERSION, "Enveloped Record Version");
|
---|
132 | _tagNameMap.put(TAG_DESTINATION, "Destination");
|
---|
133 | _tagNameMap.put(TAG_FILE_FORMAT, "File Format");
|
---|
134 | _tagNameMap.put(TAG_FILE_VERSION, "File Version");
|
---|
135 | _tagNameMap.put(TAG_SERVICE_ID, "Service Identifier");
|
---|
136 | _tagNameMap.put(TAG_ENVELOPE_NUMBER, "Envelope Number");
|
---|
137 | _tagNameMap.put(TAG_PRODUCT_ID, "Product Identifier");
|
---|
138 | _tagNameMap.put(TAG_ENVELOPE_PRIORITY, "Envelope Priority");
|
---|
139 | _tagNameMap.put(TAG_DATE_SENT, "Date Sent");
|
---|
140 | _tagNameMap.put(TAG_TIME_SENT, "Time Sent");
|
---|
141 | _tagNameMap.put(TAG_CODED_CHARACTER_SET, "Coded Character Set");
|
---|
142 | _tagNameMap.put(TAG_UNIQUE_OBJECT_NAME, "Unique Object Name");
|
---|
143 | _tagNameMap.put(TAG_ARM_IDENTIFIER, "ARM Identifier");
|
---|
144 | _tagNameMap.put(TAG_ARM_VERSION, "ARM Version");
|
---|
145 |
|
---|
146 | _tagNameMap.put(TAG_APPLICATION_RECORD_VERSION, "Application Record Version");
|
---|
147 | _tagNameMap.put(TAG_OBJECT_TYPE_REFERENCE, "Object Type Reference");
|
---|
148 | _tagNameMap.put(TAG_OBJECT_ATTRIBUTE_REFERENCE, "Object Attribute Reference");
|
---|
149 | _tagNameMap.put(TAG_OBJECT_NAME, "Object Name");
|
---|
150 | _tagNameMap.put(TAG_EDIT_STATUS, "Edit Status");
|
---|
151 | _tagNameMap.put(TAG_EDITORIAL_UPDATE, "Editorial Update");
|
---|
152 | _tagNameMap.put(TAG_URGENCY, "Urgency");
|
---|
153 | _tagNameMap.put(TAG_SUBJECT_REFERENCE, "Subject Reference");
|
---|
154 | _tagNameMap.put(TAG_CATEGORY, "Category");
|
---|
155 | _tagNameMap.put(TAG_SUPPLEMENTAL_CATEGORIES, "Supplemental Category(s)");
|
---|
156 | _tagNameMap.put(TAG_FIXTURE_ID, "Fixture Identifier");
|
---|
157 | _tagNameMap.put(TAG_KEYWORDS, "Keywords");
|
---|
158 | _tagNameMap.put(TAG_CONTENT_LOCATION_CODE, "Content Location Code");
|
---|
159 | _tagNameMap.put(TAG_CONTENT_LOCATION_NAME, "Content Location Name");
|
---|
160 | _tagNameMap.put(TAG_RELEASE_DATE, "Release Date");
|
---|
161 | _tagNameMap.put(TAG_RELEASE_TIME, "Release Time");
|
---|
162 | _tagNameMap.put(TAG_EXPIRATION_DATE, "Expiration Date");
|
---|
163 | _tagNameMap.put(TAG_EXPIRATION_TIME, "Expiration Time");
|
---|
164 | _tagNameMap.put(TAG_SPECIAL_INSTRUCTIONS, "Special Instructions");
|
---|
165 | _tagNameMap.put(TAG_ACTION_ADVISED, "Action Advised");
|
---|
166 | _tagNameMap.put(TAG_REFERENCE_SERVICE, "Reference Service");
|
---|
167 | _tagNameMap.put(TAG_REFERENCE_DATE, "Reference Date");
|
---|
168 | _tagNameMap.put(TAG_REFERENCE_NUMBER, "Reference Number");
|
---|
169 | _tagNameMap.put(TAG_DATE_CREATED, "Date Created");
|
---|
170 | _tagNameMap.put(TAG_TIME_CREATED, "Time Created");
|
---|
171 | _tagNameMap.put(TAG_DIGITAL_DATE_CREATED, "Digital Date Created");
|
---|
172 | _tagNameMap.put(TAG_DIGITAL_TIME_CREATED, "Digital Time Created");
|
---|
173 | _tagNameMap.put(TAG_ORIGINATING_PROGRAM, "Originating Program");
|
---|
174 | _tagNameMap.put(TAG_PROGRAM_VERSION, "Program Version");
|
---|
175 | _tagNameMap.put(TAG_OBJECT_CYCLE, "Object Cycle");
|
---|
176 | _tagNameMap.put(TAG_BY_LINE, "By-line");
|
---|
177 | _tagNameMap.put(TAG_BY_LINE_TITLE, "By-line Title");
|
---|
178 | _tagNameMap.put(TAG_CITY, "City");
|
---|
179 | _tagNameMap.put(TAG_SUB_LOCATION, "Sub-location");
|
---|
180 | _tagNameMap.put(TAG_PROVINCE_OR_STATE, "Province/State");
|
---|
181 | _tagNameMap.put(TAG_COUNTRY_OR_PRIMARY_LOCATION_CODE, "Country/Primary Location Code");
|
---|
182 | _tagNameMap.put(TAG_COUNTRY_OR_PRIMARY_LOCATION_NAME, "Country/Primary Location Name");
|
---|
183 | _tagNameMap.put(TAG_ORIGINAL_TRANSMISSION_REFERENCE, "Original Transmission Reference");
|
---|
184 | _tagNameMap.put(TAG_HEADLINE, "Headline");
|
---|
185 | _tagNameMap.put(TAG_CREDIT, "Credit");
|
---|
186 | _tagNameMap.put(TAG_SOURCE, "Source");
|
---|
187 | _tagNameMap.put(TAG_COPYRIGHT_NOTICE, "Copyright Notice");
|
---|
188 | _tagNameMap.put(TAG_CONTACT, "Contact");
|
---|
189 | _tagNameMap.put(TAG_CAPTION, "Caption/Abstract");
|
---|
190 | _tagNameMap.put(TAG_LOCAL_CAPTION, "Local Caption");
|
---|
191 | _tagNameMap.put(TAG_CAPTION_WRITER, "Caption Writer/Editor");
|
---|
192 | _tagNameMap.put(TAG_RASTERIZED_CAPTION, "Rasterized Caption");
|
---|
193 | _tagNameMap.put(TAG_IMAGE_TYPE, "Image Type");
|
---|
194 | _tagNameMap.put(TAG_IMAGE_ORIENTATION, "Image Orientation");
|
---|
195 | _tagNameMap.put(TAG_LANGUAGE_IDENTIFIER, "Language Identifier");
|
---|
196 | _tagNameMap.put(TAG_AUDIO_TYPE, "Audio Type");
|
---|
197 | _tagNameMap.put(TAG_AUDIO_SAMPLING_RATE, "Audio Sampling Rate");
|
---|
198 | _tagNameMap.put(TAG_AUDIO_SAMPLING_RESOLUTION, "Audio Sampling Resolution");
|
---|
199 | _tagNameMap.put(TAG_AUDIO_DURATION, "Audio Duration");
|
---|
200 | _tagNameMap.put(TAG_AUDIO_OUTCUE, "Audio Outcue");
|
---|
201 |
|
---|
202 | _tagNameMap.put(TAG_JOB_ID, "Job Identifier");
|
---|
203 | _tagNameMap.put(TAG_MASTER_DOCUMENT_ID, "Master Document Identifier");
|
---|
204 | _tagNameMap.put(TAG_SHORT_DOCUMENT_ID, "Short Document Identifier");
|
---|
205 | _tagNameMap.put(TAG_UNIQUE_DOCUMENT_ID, "Unique Document Identifier");
|
---|
206 | _tagNameMap.put(TAG_OWNER_ID, "Owner Identifier");
|
---|
207 |
|
---|
208 | _tagNameMap.put(TAG_OBJECT_PREVIEW_FILE_FORMAT, "Object Data Preview File Format");
|
---|
209 | _tagNameMap.put(TAG_OBJECT_PREVIEW_FILE_FORMAT_VERSION, "Object Data Preview File Format Version");
|
---|
210 | _tagNameMap.put(TAG_OBJECT_PREVIEW_DATA, "Object Data Preview Data");
|
---|
211 | }
|
---|
212 |
|
---|
213 | public IptcDirectory()
|
---|
214 | {
|
---|
215 | this.setDescriptor(new IptcDescriptor(this));
|
---|
216 | }
|
---|
217 |
|
---|
218 | @Override
|
---|
219 | @NotNull
|
---|
220 | public String getName()
|
---|
221 | {
|
---|
222 | return "IPTC";
|
---|
223 | }
|
---|
224 |
|
---|
225 | @Override
|
---|
226 | @NotNull
|
---|
227 | protected HashMap<Integer, String> getTagNameMap()
|
---|
228 | {
|
---|
229 | return _tagNameMap;
|
---|
230 | }
|
---|
231 |
|
---|
232 | /**
|
---|
233 | * Returns any keywords contained in the IPTC data. This value may be <code>null</code>.
|
---|
234 | */
|
---|
235 | @Nullable
|
---|
236 | public List<String> getKeywords()
|
---|
237 | {
|
---|
238 | final String[] array = getStringArray(TAG_KEYWORDS);
|
---|
239 | if (array==null)
|
---|
240 | return null;
|
---|
241 | return Arrays.asList(array);
|
---|
242 | }
|
---|
243 |
|
---|
244 | /**
|
---|
245 | * Parses the Date Sent tag and the Time Sent tag to obtain a single Date object representing the
|
---|
246 | * date and time when the service sent this image.
|
---|
247 | * @return A Date object representing when the service sent this image, if possible, otherwise null
|
---|
248 | */
|
---|
249 | @Nullable
|
---|
250 | public Date getDateSent()
|
---|
251 | {
|
---|
252 | return getDate(TAG_DATE_SENT, TAG_TIME_SENT);
|
---|
253 | }
|
---|
254 |
|
---|
255 | /**
|
---|
256 | * Parses the Release Date tag and the Release Time tag to obtain a single Date object representing the
|
---|
257 | * date and time when this image was released.
|
---|
258 | * @return A Date object representing when this image was released, if possible, otherwise null
|
---|
259 | */
|
---|
260 | @Nullable
|
---|
261 | public Date getReleaseDate()
|
---|
262 | {
|
---|
263 | return getDate(TAG_RELEASE_DATE, TAG_RELEASE_TIME);
|
---|
264 | }
|
---|
265 |
|
---|
266 | /**
|
---|
267 | * Parses the Expiration Date tag and the Expiration Time tag to obtain a single Date object representing
|
---|
268 | * that this image should not used after this date and time.
|
---|
269 | * @return A Date object representing when this image was released, if possible, otherwise null
|
---|
270 | */
|
---|
271 | @Nullable
|
---|
272 | public Date getExpirationDate()
|
---|
273 | {
|
---|
274 | return getDate(TAG_EXPIRATION_DATE, TAG_EXPIRATION_TIME);
|
---|
275 | }
|
---|
276 |
|
---|
277 | /**
|
---|
278 | * Parses the Date Created tag and the Time Created tag to obtain a single Date object representing the
|
---|
279 | * date and time when this image was captured.
|
---|
280 | * @return A Date object representing when this image was captured, if possible, otherwise null
|
---|
281 | */
|
---|
282 | @Nullable
|
---|
283 | public Date getDateCreated()
|
---|
284 | {
|
---|
285 | return getDate(TAG_DATE_CREATED, TAG_TIME_CREATED);
|
---|
286 | }
|
---|
287 |
|
---|
288 | /**
|
---|
289 | * Parses the Digital Date Created tag and the Digital Time Created tag to obtain a single Date object
|
---|
290 | * representing the date and time when the digital representation of this image was created.
|
---|
291 | * @return A Date object representing when the digital representation of this image was created,
|
---|
292 | * if possible, otherwise null
|
---|
293 | */
|
---|
294 | @Nullable
|
---|
295 | public Date getDigitalDateCreated()
|
---|
296 | {
|
---|
297 | return getDate(TAG_DIGITAL_DATE_CREATED, TAG_DIGITAL_TIME_CREATED);
|
---|
298 | }
|
---|
299 |
|
---|
300 | @Nullable
|
---|
301 | private Date getDate(int dateTagType, int timeTagType)
|
---|
302 | {
|
---|
303 | String date = getString(dateTagType);
|
---|
304 | String time = getString(timeTagType);
|
---|
305 |
|
---|
306 | if (date == null)
|
---|
307 | return null;
|
---|
308 | if (time == null)
|
---|
309 | return null;
|
---|
310 |
|
---|
311 | try {
|
---|
312 | DateFormat parser = new SimpleDateFormat("yyyyMMddHHmmssZ");
|
---|
313 | return parser.parse(date + time);
|
---|
314 | } catch (ParseException e) {
|
---|
315 | return null;
|
---|
316 | }
|
---|
317 | }
|
---|
318 | }
|
---|