source: josm/trunk/src/com/drew/metadata/exif/makernotes/FujifilmMakernoteDescriptor.java@ 13061

Last change on this file since 13061 was 13061, checked in by Don-vip, 6 years ago

fix #15505 - update to metadata-extractor 2.10.1

File size: 15.2 KB
Line 
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 */
21package com.drew.metadata.exif.makernotes;
22
23import com.drew.lang.Rational;
24import com.drew.lang.annotations.NotNull;
25import com.drew.lang.annotations.Nullable;
26import com.drew.metadata.TagDescriptor;
27
28import static com.drew.metadata.exif.makernotes.FujifilmMakernoteDirectory.*;
29
30/**
31 * Provides human-readable string representations of tag values stored in a {@link FujifilmMakernoteDirectory}.
32 * <p>
33 * Fujifilm added their Makernote tag from the Year 2000's models (e.g.Finepix1400,
34 * Finepix4700). It uses IFD format and start from ASCII character 'FUJIFILM', and next 4
35 * bytes (value 0x000c) points the offset to first IFD entry.
36 * <pre><code>
37 * :0000: 46 55 4A 49 46 49 4C 4D-0C 00 00 00 0F 00 00 00 :0000: FUJIFILM........
38 * :0010: 07 00 04 00 00 00 30 31-33 30 00 10 02 00 08 00 :0010: ......0130......
39 * </code></pre>
40 * There are two big differences to the other manufacturers.
41 * <ul>
42 * <li>Fujifilm's Exif data uses Motorola align, but Makernote ignores it and uses Intel align.</li>
43 * <li>
44 * The other manufacturer's Makernote counts the "offset to data" from the first byte of TIFF header
45 * (same as the other IFD), but Fujifilm counts it from the first byte of Makernote itself.
46 * </li>
47 * </ul>
48 *
49 * @author Drew Noakes https://drewnoakes.com
50 */
51@SuppressWarnings("WeakerAccess")
52public class FujifilmMakernoteDescriptor extends TagDescriptor<FujifilmMakernoteDirectory>
53{
54 public FujifilmMakernoteDescriptor(@NotNull FujifilmMakernoteDirectory directory)
55 {
56 super(directory);
57 }
58
59 @Override
60 @Nullable
61 public String getDescription(int tagType)
62 {
63 switch (tagType) {
64 case TAG_MAKERNOTE_VERSION:
65 return getMakernoteVersionDescription();
66 case TAG_SHARPNESS:
67 return getSharpnessDescription();
68 case TAG_WHITE_BALANCE:
69 return getWhiteBalanceDescription();
70 case TAG_COLOR_SATURATION:
71 return getColorSaturationDescription();
72 case TAG_TONE:
73 return getToneDescription();
74 case TAG_CONTRAST:
75 return getContrastDescription();
76 case TAG_NOISE_REDUCTION:
77 return getNoiseReductionDescription();
78 case TAG_HIGH_ISO_NOISE_REDUCTION:
79 return getHighIsoNoiseReductionDescription();
80 case TAG_FLASH_MODE:
81 return getFlashModeDescription();
82 case TAG_FLASH_EV:
83 return getFlashExposureValueDescription();
84 case TAG_MACRO:
85 return getMacroDescription();
86 case TAG_FOCUS_MODE:
87 return getFocusModeDescription();
88 case TAG_SLOW_SYNC:
89 return getSlowSyncDescription();
90 case TAG_PICTURE_MODE:
91 return getPictureModeDescription();
92 case TAG_EXR_AUTO:
93 return getExrAutoDescription();
94 case TAG_EXR_MODE:
95 return getExrModeDescription();
96 case TAG_AUTO_BRACKETING:
97 return getAutoBracketingDescription();
98 case TAG_FINE_PIX_COLOR:
99 return getFinePixColorDescription();
100 case TAG_BLUR_WARNING:
101 return getBlurWarningDescription();
102 case TAG_FOCUS_WARNING:
103 return getFocusWarningDescription();
104 case TAG_AUTO_EXPOSURE_WARNING:
105 return getAutoExposureWarningDescription();
106 case TAG_DYNAMIC_RANGE:
107 return getDynamicRangeDescription();
108 case TAG_FILM_MODE:
109 return getFilmModeDescription();
110 case TAG_DYNAMIC_RANGE_SETTING:
111 return getDynamicRangeSettingDescription();
112 default:
113 return super.getDescription(tagType);
114 }
115 }
116
117 @Nullable
118 private String getMakernoteVersionDescription()
119 {
120 return getVersionBytesDescription(TAG_MAKERNOTE_VERSION, 2);
121 }
122
123 @Nullable
124 public String getSharpnessDescription()
125 {
126 final Integer value = _directory.getInteger(TAG_SHARPNESS);
127 if (value == null)
128 return null;
129 switch (value) {
130 case 1: return "Softest";
131 case 2: return "Soft";
132 case 3: return "Normal";
133 case 4: return "Hard";
134 case 5: return "Hardest";
135 case 0x82: return "Medium Soft";
136 case 0x84: return "Medium Hard";
137 case 0x8000: return "Film Simulation";
138 case 0xFFFF: return "N/A";
139 default:
140 return "Unknown (" + value + ")";
141 }
142 }
143
144 @Nullable
145 public String getWhiteBalanceDescription()
146 {
147 final Integer value = _directory.getInteger(TAG_WHITE_BALANCE);
148 if (value == null)
149 return null;
150 switch (value) {
151 case 0x000: return "Auto";
152 case 0x100: return "Daylight";
153 case 0x200: return "Cloudy";
154 case 0x300: return "Daylight Fluorescent";
155 case 0x301: return "Day White Fluorescent";
156 case 0x302: return "White Fluorescent";
157 case 0x303: return "Warm White Fluorescent";
158 case 0x304: return "Living Room Warm White Fluorescent";
159 case 0x400: return "Incandescence";
160 case 0x500: return "Flash";
161 case 0xf00: return "Custom White Balance";
162 case 0xf01: return "Custom White Balance 2";
163 case 0xf02: return "Custom White Balance 3";
164 case 0xf03: return "Custom White Balance 4";
165 case 0xf04: return "Custom White Balance 5";
166 case 0xff0: return "Kelvin";
167 default:
168 return "Unknown (" + value + ")";
169 }
170 }
171
172 @Nullable
173 public String getColorSaturationDescription()
174 {
175 final Integer value = _directory.getInteger(TAG_COLOR_SATURATION);
176 if (value == null)
177 return null;
178 switch (value) {
179 case 0x000: return "Normal";
180 case 0x080: return "Medium High";
181 case 0x100: return "High";
182 case 0x180: return "Medium Low";
183 case 0x200: return "Low";
184 case 0x300: return "None (B&W)";
185 case 0x301: return "B&W Green Filter";
186 case 0x302: return "B&W Yellow Filter";
187 case 0x303: return "B&W Blue Filter";
188 case 0x304: return "B&W Sepia";
189 case 0x8000: return "Film Simulation";
190 default:
191 return "Unknown (" + value + ")";
192 }
193 }
194
195 @Nullable
196 public String getToneDescription()
197 {
198 final Integer value = _directory.getInteger(TAG_TONE);
199 if (value == null)
200 return null;
201 switch (value) {
202 case 0x000: return "Normal";
203 case 0x080: return "Medium High";
204 case 0x100: return "High";
205 case 0x180: return "Medium Low";
206 case 0x200: return "Low";
207 case 0x300: return "None (B&W)";
208 case 0x8000: return "Film Simulation";
209 default:
210 return "Unknown (" + value + ")";
211 }
212 }
213
214 @Nullable
215 public String getContrastDescription()
216 {
217 final Integer value = _directory.getInteger(TAG_CONTRAST);
218 if (value == null)
219 return null;
220 switch (value) {
221 case 0x000: return "Normal";
222 case 0x100: return "High";
223 case 0x300: return "Low";
224 default:
225 return "Unknown (" + value + ")";
226 }
227 }
228
229 @Nullable
230 public String getNoiseReductionDescription()
231 {
232 final Integer value = _directory.getInteger(TAG_NOISE_REDUCTION);
233 if (value == null)
234 return null;
235 switch (value) {
236 case 0x040: return "Low";
237 case 0x080: return "Normal";
238 case 0x100: return "N/A";
239 default:
240 return "Unknown (" + value + ")";
241 }
242 }
243
244 @Nullable
245 public String getHighIsoNoiseReductionDescription()
246 {
247 final Integer value = _directory.getInteger(TAG_HIGH_ISO_NOISE_REDUCTION);
248 if (value == null)
249 return null;
250 switch (value) {
251 case 0x000: return "Normal";
252 case 0x100: return "Strong";
253 case 0x200: return "Weak";
254 default:
255 return "Unknown (" + value + ")";
256 }
257 }
258
259 @Nullable
260 public String getFlashModeDescription()
261 {
262 return getIndexedDescription(
263 TAG_FLASH_MODE,
264 "Auto",
265 "On",
266 "Off",
267 "Red-eye Reduction",
268 "External"
269 );
270 }
271
272 @Nullable
273 public String getFlashExposureValueDescription()
274 {
275 Rational value = _directory.getRational(TAG_FLASH_EV);
276 return value == null ? null : value.toSimpleString(false) + " EV (Apex)";
277 }
278
279 @Nullable
280 public String getMacroDescription()
281 {
282 return getIndexedDescription(TAG_MACRO, "Off", "On");
283 }
284
285 @Nullable
286 public String getFocusModeDescription()
287 {
288 return getIndexedDescription(TAG_FOCUS_MODE, "Auto Focus", "Manual Focus");
289 }
290
291 @Nullable
292 public String getSlowSyncDescription()
293 {
294 return getIndexedDescription(TAG_SLOW_SYNC, "Off", "On");
295 }
296
297 @Nullable
298 public String getPictureModeDescription()
299 {
300 final Integer value = _directory.getInteger(TAG_PICTURE_MODE);
301 if (value == null)
302 return null;
303 switch (value) {
304 case 0x000: return "Auto";
305 case 0x001: return "Portrait scene";
306 case 0x002: return "Landscape scene";
307 case 0x003: return "Macro";
308 case 0x004: return "Sports scene";
309 case 0x005: return "Night scene";
310 case 0x006: return "Program AE";
311 case 0x007: return "Natural Light";
312 case 0x008: return "Anti-blur";
313 case 0x009: return "Beach & Snow";
314 case 0x00a: return "Sunset";
315 case 0x00b: return "Museum";
316 case 0x00c: return "Party";
317 case 0x00d: return "Flower";
318 case 0x00e: return "Text";
319 case 0x00f: return "Natural Light & Flash";
320 case 0x010: return "Beach";
321 case 0x011: return "Snow";
322 case 0x012: return "Fireworks";
323 case 0x013: return "Underwater";
324 case 0x014: return "Portrait with Skin Correction";
325 // skip 0x015
326 case 0x016: return "Panorama";
327 case 0x017: return "Night (Tripod)";
328 case 0x018: return "Pro Low-light";
329 case 0x019: return "Pro Focus";
330 // skip 0x01a
331 case 0x01b: return "Dog Face Detection";
332 case 0x01c: return "Cat Face Detection";
333 case 0x100: return "Aperture priority AE";
334 case 0x200: return "Shutter priority AE";
335 case 0x300: return "Manual exposure";
336 default:
337 return "Unknown (" + value + ")";
338 }
339 }
340
341 @Nullable
342 public String getExrAutoDescription()
343 {
344 return getIndexedDescription(TAG_EXR_AUTO, "Auto", "Manual");
345 }
346
347 @Nullable
348 public String getExrModeDescription()
349 {
350 final Integer value = _directory.getInteger(TAG_EXR_MODE);
351 if (value == null)
352 return null;
353 switch (value) {
354 case 0x100: return "HR (High Resolution)";
355 case 0x200: return "SN (Signal to Noise Priority)";
356 case 0x300: return "DR (Dynamic Range Priority)";
357 default:
358 return "Unknown (" + value + ")";
359 }
360 }
361
362 @Nullable
363 public String getAutoBracketingDescription()
364 {
365 return getIndexedDescription(
366 TAG_AUTO_BRACKETING,
367 "Off",
368 "On",
369 "No Flash & Flash"
370 );
371 }
372
373 @Nullable
374 public String getFinePixColorDescription()
375 {
376 final Integer value = _directory.getInteger(TAG_FINE_PIX_COLOR);
377 if (value == null)
378 return null;
379 switch (value) {
380 case 0x00: return "Standard";
381 case 0x10: return "Chrome";
382 case 0x30: return "B&W";
383 default:
384 return "Unknown (" + value + ")";
385 }
386 }
387
388 @Nullable
389 public String getBlurWarningDescription()
390 {
391 return getIndexedDescription(
392 TAG_BLUR_WARNING,
393 "No Blur Warning",
394 "Blur warning"
395 );
396 }
397
398 @Nullable
399 public String getFocusWarningDescription()
400 {
401 return getIndexedDescription(
402 TAG_FOCUS_WARNING,
403 "Good Focus",
404 "Out Of Focus"
405 );
406 }
407
408 @Nullable
409 public String getAutoExposureWarningDescription()
410 {
411 return getIndexedDescription(
412 TAG_AUTO_EXPOSURE_WARNING,
413 "AE Good",
414 "Over Exposed"
415 );
416 }
417
418 @Nullable
419 public String getDynamicRangeDescription()
420 {
421 return getIndexedDescription(
422 TAG_DYNAMIC_RANGE,
423 1,
424 "Standard",
425 null,
426 "Wide"
427 );
428 }
429
430 @Nullable
431 public String getFilmModeDescription()
432 {
433 final Integer value = _directory.getInteger(TAG_FILM_MODE);
434 if (value == null)
435 return null;
436 switch (value) {
437 case 0x000: return "F0/Standard (Provia) ";
438 case 0x100: return "F1/Studio Portrait";
439 case 0x110: return "F1a/Studio Portrait Enhanced Saturation";
440 case 0x120: return "F1b/Studio Portrait Smooth Skin Tone (Astia)";
441 case 0x130: return "F1c/Studio Portrait Increased Sharpness";
442 case 0x200: return "F2/Fujichrome (Velvia)";
443 case 0x300: return "F3/Studio Portrait Ex";
444 case 0x400: return "F4/Velvia";
445 case 0x500: return "Pro Neg. Std";
446 case 0x501: return "Pro Neg. Hi";
447 default:
448 return "Unknown (" + value + ")";
449 }
450 }
451
452 @Nullable
453 public String getDynamicRangeSettingDescription()
454 {
455 final Integer value = _directory.getInteger(TAG_DYNAMIC_RANGE_SETTING);
456 if (value == null)
457 return null;
458 switch (value) {
459 case 0x000: return "Auto (100-400%)";
460 case 0x001: return "Manual";
461 case 0x100: return "Standard (100%)";
462 case 0x200: return "Wide 1 (230%)";
463 case 0x201: return "Wide 2 (400%)";
464 case 0x8000: return "Film Simulation";
465 default:
466 return "Unknown (" + value + ")";
467 }
468 }
469}
Note: See TracBrowser for help on using the repository browser.