source: josm/trunk/src/com/drew/metadata/exif/makernotes/CanonMakernoteDescriptor.java@ 8564

Last change on this file since 8564 was 8243, checked in by Don-vip, 11 years ago

fix #11359 - update to metadata-extractor 2.8.1

File size: 22.6 KB
Line 
1/*
2 * Copyright 2002-2015 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.annotations.NotNull;
24import com.drew.lang.annotations.Nullable;
25import com.drew.metadata.TagDescriptor;
26
27import static com.drew.metadata.exif.makernotes.CanonMakernoteDirectory.*;
28
29/**
30 * Provides human-readable string representations of tag values stored in a {@link CanonMakernoteDirectory}.
31 *
32 * @author Drew Noakes https://drewnoakes.com
33 */
34public class CanonMakernoteDescriptor extends TagDescriptor<CanonMakernoteDirectory>
35{
36 public CanonMakernoteDescriptor(@NotNull CanonMakernoteDirectory directory)
37 {
38 super(directory);
39 }
40
41 @Override
42 @Nullable
43 public String getDescription(int tagType)
44 {
45 switch (tagType) {
46 case TAG_CANON_SERIAL_NUMBER:
47 return getSerialNumberDescription();
48 case CameraSettings.TAG_FLASH_ACTIVITY:
49 return getFlashActivityDescription();
50 case CameraSettings.TAG_FOCUS_TYPE:
51 return getFocusTypeDescription();
52 case CameraSettings.TAG_DIGITAL_ZOOM:
53 return getDigitalZoomDescription();
54 case CameraSettings.TAG_QUALITY:
55 return getQualityDescription();
56 case CameraSettings.TAG_MACRO_MODE:
57 return getMacroModeDescription();
58 case CameraSettings.TAG_SELF_TIMER_DELAY:
59 return getSelfTimerDelayDescription();
60 case CameraSettings.TAG_FLASH_MODE:
61 return getFlashModeDescription();
62 case CameraSettings.TAG_CONTINUOUS_DRIVE_MODE:
63 return getContinuousDriveModeDescription();
64 case CameraSettings.TAG_FOCUS_MODE_1:
65 return getFocusMode1Description();
66 case CameraSettings.TAG_IMAGE_SIZE:
67 return getImageSizeDescription();
68 case CameraSettings.TAG_EASY_SHOOTING_MODE:
69 return getEasyShootingModeDescription();
70 case CameraSettings.TAG_CONTRAST:
71 return getContrastDescription();
72 case CameraSettings.TAG_SATURATION:
73 return getSaturationDescription();
74 case CameraSettings.TAG_SHARPNESS:
75 return getSharpnessDescription();
76 case CameraSettings.TAG_ISO:
77 return getIsoDescription();
78 case CameraSettings.TAG_METERING_MODE:
79 return getMeteringModeDescription();
80 case CameraSettings.TAG_AF_POINT_SELECTED:
81 return getAfPointSelectedDescription();
82 case CameraSettings.TAG_EXPOSURE_MODE:
83 return getExposureModeDescription();
84 case CameraSettings.TAG_LENS_TYPE:
85 return getLensTypeDescription();
86 case CameraSettings.TAG_LONG_FOCAL_LENGTH:
87 return getLongFocalLengthDescription();
88 case CameraSettings.TAG_SHORT_FOCAL_LENGTH:
89 return getShortFocalLengthDescription();
90 case CameraSettings.TAG_FOCAL_UNITS_PER_MM:
91 return getFocalUnitsPerMillimetreDescription();
92 case CameraSettings.TAG_FLASH_DETAILS:
93 return getFlashDetailsDescription();
94 case CameraSettings.TAG_FOCUS_MODE_2:
95 return getFocusMode2Description();
96 case FocalLength.TAG_WHITE_BALANCE:
97 return getWhiteBalanceDescription();
98 case FocalLength.TAG_AF_POINT_USED:
99 return getAfPointUsedDescription();
100 case FocalLength.TAG_FLASH_BIAS:
101 return getFlashBiasDescription();
102
103 // It turns out that these values are dependent upon the camera model and therefore the below code was
104 // incorrect for some Canon models. This needs to be revisited.
105
106// case TAG_CANON_CUSTOM_FUNCTION_LONG_EXPOSURE_NOISE_REDUCTION:
107// return getLongExposureNoiseReductionDescription();
108// case TAG_CANON_CUSTOM_FUNCTION_SHUTTER_AUTO_EXPOSURE_LOCK_BUTTONS:
109// return getShutterAutoExposureLockButtonDescription();
110// case TAG_CANON_CUSTOM_FUNCTION_MIRROR_LOCKUP:
111// return getMirrorLockupDescription();
112// case TAG_CANON_CUSTOM_FUNCTION_TV_AV_AND_EXPOSURE_LEVEL:
113// return getTvAndAvExposureLevelDescription();
114// case TAG_CANON_CUSTOM_FUNCTION_AF_ASSIST_LIGHT:
115// return getAutoFocusAssistLightDescription();
116// case TAG_CANON_CUSTOM_FUNCTION_SHUTTER_SPEED_IN_AV_MODE:
117// return getShutterSpeedInAvModeDescription();
118// case TAG_CANON_CUSTOM_FUNCTION_BRACKETING:
119// return getAutoExposureBracketingSequenceAndAutoCancellationDescription();
120// case TAG_CANON_CUSTOM_FUNCTION_SHUTTER_CURTAIN_SYNC:
121// return getShutterCurtainSyncDescription();
122// case TAG_CANON_CUSTOM_FUNCTION_AF_STOP:
123// return getLensAutoFocusStopButtonDescription();
124// case TAG_CANON_CUSTOM_FUNCTION_FILL_FLASH_REDUCTION:
125// return getFillFlashReductionDescription();
126// case TAG_CANON_CUSTOM_FUNCTION_MENU_BUTTON_RETURN:
127// return getMenuButtonReturnPositionDescription();
128// case TAG_CANON_CUSTOM_FUNCTION_SET_BUTTON_FUNCTION:
129// return getSetButtonFunctionWhenShootingDescription();
130// case TAG_CANON_CUSTOM_FUNCTION_SENSOR_CLEANING:
131// return getSensorCleaningDescription();
132 default:
133 return super.getDescription(tagType);
134 }
135 }
136
137 @Nullable
138 public String getSerialNumberDescription()
139 {
140 Integer value = _directory.getInteger(TAG_CANON_SERIAL_NUMBER);
141 if (value == null)
142 return null;
143 return String.format("%04X%05d", (value >> 8) & 0xFF, value & 0xFF);
144 }
145
146/*
147 @Nullable
148 public String getLongExposureNoiseReductionDescription()
149 {
150 Integer value = _directory.getInteger(TAG_CANON_CUSTOM_FUNCTION_LONG_EXPOSURE_NOISE_REDUCTION);
151 if (value==null)
152 return null;
153 switch (value) {
154 case 0: return "Off";
155 case 1: return "On";
156 default: return "Unknown (" + value + ")";
157 }
158 }
159
160 @Nullable
161 public String getShutterAutoExposureLockButtonDescription()
162 {
163 Integer value = _directory.getInteger(TAG_CANON_CUSTOM_FUNCTION_SHUTTER_AUTO_EXPOSURE_LOCK_BUTTONS);
164 if (value==null)
165 return null;
166 switch (value) {
167 case 0: return "AF/AE lock";
168 case 1: return "AE lock/AF";
169 case 2: return "AF/AF lock";
170 case 3: return "AE+release/AE+AF";
171 default: return "Unknown (" + value + ")";
172 }
173 }
174
175 @Nullable
176 public String getMirrorLockupDescription()
177 {
178 Integer value = _directory.getInteger(TAG_CANON_CUSTOM_FUNCTION_MIRROR_LOCKUP);
179 if (value==null)
180 return null;
181 switch (value) {
182 case 0: return "Disabled";
183 case 1: return "Enabled";
184 default: return "Unknown (" + value + ")";
185 }
186 }
187
188 @Nullable
189 public String getTvAndAvExposureLevelDescription()
190 {
191 Integer value = _directory.getInteger(TAG_CANON_CUSTOM_FUNCTION_TV_AV_AND_EXPOSURE_LEVEL);
192 if (value==null)
193 return null;
194 switch (value) {
195 case 0: return "1/2 stop";
196 case 1: return "1/3 stop";
197 default: return "Unknown (" + value + ")";
198 }
199 }
200
201 @Nullable
202 public String getAutoFocusAssistLightDescription()
203 {
204 Integer value = _directory.getInteger(TAG_CANON_CUSTOM_FUNCTION_AF_ASSIST_LIGHT);
205 if (value==null)
206 return null;
207 switch (value) {
208 case 0: return "On (Auto)";
209 case 1: return "Off";
210 default: return "Unknown (" + value + ")";
211 }
212 }
213
214 @Nullable
215 public String getShutterSpeedInAvModeDescription()
216 {
217 Integer value = _directory.getInteger(TAG_CANON_CUSTOM_FUNCTION_SHUTTER_SPEED_IN_AV_MODE);
218 if (value==null)
219 return null;
220 switch (value) {
221 case 0: return "Automatic";
222 case 1: return "1/200 (fixed)";
223 default: return "Unknown (" + value + ")";
224 }
225 }
226
227 @Nullable
228 public String getAutoExposureBracketingSequenceAndAutoCancellationDescription()
229 {
230 Integer value = _directory.getInteger(TAG_CANON_CUSTOM_FUNCTION_BRACKETING);
231 if (value==null)
232 return null;
233 switch (value) {
234 case 0: return "0,-,+ / Enabled";
235 case 1: return "0,-,+ / Disabled";
236 case 2: return "-,0,+ / Enabled";
237 case 3: return "-,0,+ / Disabled";
238 default: return "Unknown (" + value + ")";
239 }
240 }
241
242 @Nullable
243 public String getShutterCurtainSyncDescription()
244 {
245 Integer value = _directory.getInteger(TAG_CANON_CUSTOM_FUNCTION_SHUTTER_CURTAIN_SYNC);
246 if (value==null)
247 return null;
248 switch (value) {
249 case 0: return "1st Curtain Sync";
250 case 1: return "2nd Curtain Sync";
251 default: return "Unknown (" + value + ")";
252 }
253 }
254
255 @Nullable
256 public String getLensAutoFocusStopButtonDescription()
257 {
258 Integer value = _directory.getInteger(TAG_CANON_CUSTOM_FUNCTION_AF_STOP);
259 if (value==null)
260 return null;
261 switch (value) {
262 case 0: return "AF stop";
263 case 1: return "Operate AF";
264 case 2: return "Lock AE and start timer";
265 default: return "Unknown (" + value + ")";
266 }
267 }
268
269 @Nullable
270 public String getFillFlashReductionDescription()
271 {
272 Integer value = _directory.getInteger(TAG_CANON_CUSTOM_FUNCTION_FILL_FLASH_REDUCTION);
273 if (value==null)
274 return null;
275 switch (value) {
276 case 0: return "Enabled";
277 case 1: return "Disabled";
278 default: return "Unknown (" + value + ")";
279 }
280 }
281
282 @Nullable
283 public String getMenuButtonReturnPositionDescription()
284 {
285 Integer value = _directory.getInteger(TAG_CANON_CUSTOM_FUNCTION_MENU_BUTTON_RETURN);
286 if (value==null)
287 return null;
288 switch (value) {
289 case 0: return "Top";
290 case 1: return "Previous (volatile)";
291 case 2: return "Previous";
292 default: return "Unknown (" + value + ")";
293 }
294 }
295
296 @Nullable
297 public String getSetButtonFunctionWhenShootingDescription()
298 {
299 Integer value = _directory.getInteger(TAG_CANON_CUSTOM_FUNCTION_SET_BUTTON_FUNCTION);
300 if (value==null)
301 return null;
302 switch (value) {
303 case 0: return "Not Assigned";
304 case 1: return "Change Quality";
305 case 2: return "Change ISO Speed";
306 case 3: return "Select Parameters";
307 default: return "Unknown (" + value + ")";
308 }
309 }
310
311 @Nullable
312 public String getSensorCleaningDescription()
313 {
314 Integer value = _directory.getInteger(TAG_CANON_CUSTOM_FUNCTION_SENSOR_CLEANING);
315 if (value==null)
316 return null;
317 switch (value) {
318 case 0: return "Disabled";
319 case 1: return "Enabled";
320 default: return "Unknown (" + value + ")";
321 }
322 }
323*/
324
325 @Nullable
326 public String getFlashBiasDescription()
327 {
328 Integer value = _directory.getInteger(FocalLength.TAG_FLASH_BIAS);
329
330 if (value == null)
331 return null;
332
333 boolean isNegative = false;
334 if (value > 0xF000) {
335 isNegative = true;
336 value = 0xFFFF - value;
337 value++;
338 }
339
340 // this tag is interesting in that the values returned are:
341 // 0, 0.375, 0.5, 0.626, 1
342 // not
343 // 0, 0.33, 0.5, 0.66, 1
344
345 return ((isNegative) ? "-" : "") + Float.toString(value / 32f) + " EV";
346 }
347
348 @Nullable
349 public String getAfPointUsedDescription()
350 {
351 Integer value = _directory.getInteger(FocalLength.TAG_AF_POINT_USED);
352 if (value == null)
353 return null;
354 if ((value & 0x7) == 0) {
355 return "Right";
356 } else if ((value & 0x7) == 1) {
357 return "Centre";
358 } else if ((value & 0x7) == 2) {
359 return "Left";
360 } else {
361 return "Unknown (" + value + ")";
362 }
363 }
364
365 @Nullable
366 public String getWhiteBalanceDescription()
367 {
368 return getIndexedDescription(
369 FocalLength.TAG_WHITE_BALANCE,
370 "Auto",
371 "Sunny",
372 "Cloudy",
373 "Tungsten",
374 "Florescent",
375 "Flash",
376 "Custom"
377 );
378 }
379
380 @Nullable
381 public String getFocusMode2Description()
382 {
383 return getIndexedDescription(CameraSettings.TAG_FOCUS_MODE_2, "Single", "Continuous");
384 }
385
386 @Nullable
387 public String getFlashDetailsDescription()
388 {
389 Integer value = _directory.getInteger(CameraSettings.TAG_FLASH_DETAILS);
390 if (value == null)
391 return null;
392 if (((value >> 14) & 1) > 0) {
393 return "External E-TTL";
394 }
395 if (((value >> 13) & 1) > 0) {
396 return "Internal flash";
397 }
398 if (((value >> 11) & 1) > 0) {
399 return "FP sync used";
400 }
401 if (((value >> 4) & 1) > 0) {
402 return "FP sync enabled";
403 }
404 return "Unknown (" + value + ")";
405 }
406
407 @Nullable
408 public String getFocalUnitsPerMillimetreDescription()
409 {
410 Integer value = _directory.getInteger(CameraSettings.TAG_FOCAL_UNITS_PER_MM);
411 if (value == null)
412 return null;
413 if (value != 0) {
414 return Integer.toString(value);
415 } else {
416 return "";
417 }
418 }
419
420 @Nullable
421 public String getShortFocalLengthDescription()
422 {
423 Integer value = _directory.getInteger(CameraSettings.TAG_SHORT_FOCAL_LENGTH);
424 if (value == null)
425 return null;
426 String units = getFocalUnitsPerMillimetreDescription();
427 return Integer.toString(value) + " " + units;
428 }
429
430 @Nullable
431 public String getLongFocalLengthDescription()
432 {
433 Integer value = _directory.getInteger(CameraSettings.TAG_LONG_FOCAL_LENGTH);
434 if (value == null)
435 return null;
436 String units = getFocalUnitsPerMillimetreDescription();
437 return Integer.toString(value) + " " + units;
438 }
439
440 @Nullable
441 public String getExposureModeDescription()
442 {
443 return getIndexedDescription(
444 CameraSettings.TAG_EXPOSURE_MODE,
445 "Easy shooting",
446 "Program",
447 "Tv-priority",
448 "Av-priority",
449 "Manual",
450 "A-DEP"
451 );
452 }
453
454 @Nullable
455 public String getLensTypeDescription() {
456 Integer value = _directory.getInteger(CameraSettings.TAG_LENS_TYPE);
457 if (value == null)
458 return null;
459
460 return "Lens type: " + Integer.toString(value);
461 }
462
463 @Nullable
464 public String getAfPointSelectedDescription()
465 {
466 return getIndexedDescription(
467 CameraSettings.TAG_AF_POINT_SELECTED,
468 0x3000,
469 "None (MF)",
470 "Auto selected",
471 "Right",
472 "Centre",
473 "Left"
474 );
475 }
476
477 @Nullable
478 public String getMeteringModeDescription()
479 {
480 return getIndexedDescription(
481 CameraSettings.TAG_METERING_MODE,
482 3,
483 "Evaluative",
484 "Partial",
485 "Centre weighted"
486 );
487 }
488
489 @Nullable
490 public String getIsoDescription()
491 {
492 Integer value = _directory.getInteger(CameraSettings.TAG_ISO);
493 if (value == null)
494 return null;
495
496 // Canon PowerShot S3 is special
497 int canonMask = 0x4000;
498 if ((value & canonMask) > 0)
499 return "" + (value & ~canonMask);
500
501 switch (value) {
502 case 0:
503 return "Not specified (see ISOSpeedRatings tag)";
504 case 15:
505 return "Auto";
506 case 16:
507 return "50";
508 case 17:
509 return "100";
510 case 18:
511 return "200";
512 case 19:
513 return "400";
514 default:
515 return "Unknown (" + value + ")";
516 }
517 }
518
519 @Nullable
520 public String getSharpnessDescription()
521 {
522 Integer value = _directory.getInteger(CameraSettings.TAG_SHARPNESS);
523 if (value == null)
524 return null;
525 switch (value) {
526 case 0xFFFF:
527 return "Low";
528 case 0x000:
529 return "Normal";
530 case 0x001:
531 return "High";
532 default:
533 return "Unknown (" + value + ")";
534 }
535 }
536
537 @Nullable
538 public String getSaturationDescription()
539 {
540 Integer value = _directory.getInteger(CameraSettings.TAG_SATURATION);
541 if (value == null)
542 return null;
543 switch (value) {
544 case 0xFFFF:
545 return "Low";
546 case 0x000:
547 return "Normal";
548 case 0x001:
549 return "High";
550 default:
551 return "Unknown (" + value + ")";
552 }
553 }
554
555 @Nullable
556 public String getContrastDescription()
557 {
558 Integer value = _directory.getInteger(CameraSettings.TAG_CONTRAST);
559 if (value == null)
560 return null;
561 switch (value) {
562 case 0xFFFF:
563 return "Low";
564 case 0x000:
565 return "Normal";
566 case 0x001:
567 return "High";
568 default:
569 return "Unknown (" + value + ")";
570 }
571 }
572
573 @Nullable
574 public String getEasyShootingModeDescription()
575 {
576 return getIndexedDescription(
577 CameraSettings.TAG_EASY_SHOOTING_MODE,
578 "Full auto",
579 "Manual",
580 "Landscape",
581 "Fast shutter",
582 "Slow shutter",
583 "Night",
584 "B&W",
585 "Sepia",
586 "Portrait",
587 "Sports",
588 "Macro / Closeup",
589 "Pan focus"
590 );
591 }
592
593 @Nullable
594 public String getImageSizeDescription()
595 {
596 return getIndexedDescription(
597 CameraSettings.TAG_IMAGE_SIZE,
598 "Large",
599 "Medium",
600 "Small"
601 );
602 }
603
604 @Nullable
605 public String getFocusMode1Description()
606 {
607 return getIndexedDescription(
608 CameraSettings.TAG_FOCUS_MODE_1,
609 "One-shot",
610 "AI Servo",
611 "AI Focus",
612 "Manual Focus",
613 // TODO should check field 32 here (FOCUS_MODE_2)
614 "Single",
615 "Continuous",
616 "Manual Focus"
617 );
618 }
619
620 @Nullable
621 public String getContinuousDriveModeDescription()
622 {
623 Integer value = _directory.getInteger(CameraSettings.TAG_CONTINUOUS_DRIVE_MODE);
624 if (value == null)
625 return null;
626 switch (value) {
627 case 0:
628 final Integer delay = _directory.getInteger(CameraSettings.TAG_SELF_TIMER_DELAY);
629 if (delay != null)
630 return delay == 0 ? "Single shot" : "Single shot with self-timer";
631 case 1:
632 return "Continuous";
633 }
634 return "Unknown (" + value + ")";
635 }
636
637 @Nullable
638 public String getFlashModeDescription()
639 {
640 Integer value = _directory.getInteger(CameraSettings.TAG_FLASH_MODE);
641 if (value == null)
642 return null;
643 switch (value) {
644 case 0:
645 return "No flash fired";
646 case 1:
647 return "Auto";
648 case 2:
649 return "On";
650 case 3:
651 return "Red-eye reduction";
652 case 4:
653 return "Slow-synchro";
654 case 5:
655 return "Auto and red-eye reduction";
656 case 6:
657 return "On and red-eye reduction";
658 case 16:
659 // note: this value not set on Canon D30
660 return "External flash";
661 default:
662 return "Unknown (" + value + ")";
663 }
664 }
665
666 @Nullable
667 public String getSelfTimerDelayDescription()
668 {
669 Integer value = _directory.getInteger(CameraSettings.TAG_SELF_TIMER_DELAY);
670 if (value == null)
671 return null;
672 if (value == 0) {
673 return "Self timer not used";
674 } else {
675 // TODO find an image that tests this calculation
676 return Double.toString((double)value * 0.1d) + " sec";
677 }
678 }
679
680 @Nullable
681 public String getMacroModeDescription()
682 {
683 return getIndexedDescription(CameraSettings.TAG_MACRO_MODE, 1, "Macro", "Normal");
684 }
685
686 @Nullable
687 public String getQualityDescription()
688 {
689 return getIndexedDescription(CameraSettings.TAG_QUALITY, 2, "Normal", "Fine", null, "Superfine");
690 }
691
692 @Nullable
693 public String getDigitalZoomDescription()
694 {
695 return getIndexedDescription(CameraSettings.TAG_DIGITAL_ZOOM, "No digital zoom", "2x", "4x");
696 }
697
698 @Nullable
699 public String getFocusTypeDescription()
700 {
701 Integer value = _directory.getInteger(CameraSettings.TAG_FOCUS_TYPE);
702 if (value == null)
703 return null;
704 switch (value) {
705 case 0:
706 return "Manual";
707 case 1:
708 return "Auto";
709 case 3:
710 return "Close-up (Macro)";
711 case 8:
712 return "Locked (Pan Mode)";
713 default:
714 return "Unknown (" + value + ")";
715 }
716 }
717
718 @Nullable
719 public String getFlashActivityDescription()
720 {
721 return getIndexedDescription(CameraSettings.TAG_FLASH_ACTIVITY, "Flash did not fire", "Flash fired");
722 }
723}
Note: See TracBrowser for help on using the repository browser.