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

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

update to metadata-extractor 2.9.1

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