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

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

update to metadata-extractor 2.9.1

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