source: josm/trunk/src/com/drew/metadata/exif/makernotes/PanasonicMakernoteDescriptor.java@ 10746

Last change on this file since 10746 was 8132, checked in by Don-vip, 10 years ago

fix #11162 - update to metadata-extractor 2.7.2

File size: 19.4 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.ByteArrayReader;
24import com.drew.lang.RandomAccessReader;
25import com.drew.lang.annotations.NotNull;
26import com.drew.lang.annotations.Nullable;
27import com.drew.metadata.Age;
28import com.drew.metadata.Face;
29import com.drew.metadata.TagDescriptor;
30
31import java.io.IOException;
32
33import static com.drew.metadata.exif.makernotes.PanasonicMakernoteDirectory.*;
34
35/**
36 * Provides human-readable string representations of tag values stored in a {@link PanasonicMakernoteDirectory}.
37 * <p>
38 * Some information about this makernote taken from here:
39 * <ul>
40 * <li><a href="http://www.ozhiker.com/electronics/pjmt/jpeg_info/panasonic_mn.html">http://www.ozhiker.com/electronics/pjmt/jpeg_info/panasonic_mn.html</a></li>
41 * <li><a href="http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Panasonic.html">http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Panasonic.html</a></li>
42 * </ul>
43 *
44 * @author Drew Noakes https://drewnoakes.com
45 * @author Philipp Sandhaus
46 */
47public class PanasonicMakernoteDescriptor extends TagDescriptor<PanasonicMakernoteDirectory>
48{
49 public PanasonicMakernoteDescriptor(@NotNull PanasonicMakernoteDirectory directory)
50 {
51 super(directory);
52 }
53
54 @Override
55 @Nullable
56 public String getDescription(int tagType)
57 {
58 switch (tagType) {
59 case TAG_QUALITY_MODE:
60 return getQualityModeDescription();
61 case TAG_FIRMWARE_VERSION:
62 return getVersionDescription();
63 case TAG_WHITE_BALANCE:
64 return getWhiteBalanceDescription();
65 case TAG_FOCUS_MODE:
66 return getFocusModeDescription();
67 case TAG_AF_AREA_MODE:
68 return getAfAreaModeDescription();
69 case TAG_IMAGE_STABILIZATION:
70 return getImageStabilizationDescription();
71 case TAG_MACRO_MODE:
72 return getMacroModeDescription();
73 case TAG_RECORD_MODE:
74 return getRecordModeDescription();
75 case TAG_AUDIO:
76 return getAudioDescription();
77 case TAG_UNKNOWN_DATA_DUMP:
78 return getUnknownDataDumpDescription();
79 case TAG_COLOR_EFFECT:
80 return getColorEffectDescription();
81 case TAG_UPTIME:
82 return getUptimeDescription();
83 case TAG_BURST_MODE:
84 return getBurstModeDescription();
85 case TAG_CONTRAST_MODE:
86 return getContrastModeDescription();
87 case TAG_NOISE_REDUCTION:
88 return getNoiseReductionDescription();
89 case TAG_SELF_TIMER:
90 return getSelfTimerDescription();
91 case TAG_ROTATION:
92 return getRotationDescription();
93 case TAG_AF_ASSIST_LAMP:
94 return getAfAssistLampDescription();
95 case TAG_COLOR_MODE:
96 return getColorModeDescription();
97 case TAG_OPTICAL_ZOOM_MODE:
98 return getOpticalZoomModeDescription();
99 case TAG_CONVERSION_LENS:
100 return getConversionLensDescription();
101 case TAG_CONTRAST:
102 return getContrastDescription();
103 case TAG_WORLD_TIME_LOCATION:
104 return getWorldTimeLocationDescription();
105 case TAG_ADVANCED_SCENE_MODE:
106 return getAdvancedSceneModeDescription();
107 case TAG_FACE_DETECTION_INFO:
108 return getDetectedFacesDescription();
109 case TAG_TRANSFORM:
110 return getTransformDescription();
111 case TAG_TRANSFORM_1:
112 return getTransform1Description();
113 case TAG_INTELLIGENT_EXPOSURE:
114 return getIntelligentExposureDescription();
115 case TAG_FLASH_WARNING:
116 return getFlashWarningDescription();
117 case TAG_COUNTRY:
118 return getCountryDescription();
119 case TAG_STATE:
120 return getStateDescription();
121 case TAG_CITY:
122 return getCityDescription();
123 case TAG_LANDMARK:
124 return getLandmarkDescription();
125 case TAG_INTELLIGENT_RESOLUTION:
126 return getIntelligentResolutionDescription();
127 case TAG_FACE_RECOGNITION_INFO:
128 return getRecognizedFacesDescription();
129 case TAG_PRINT_IMAGE_MATCHING_INFO:
130 return getPrintImageMatchingInfoDescription();
131 case TAG_SCENE_MODE:
132 return getSceneModeDescription();
133 case TAG_FLASH_FIRED:
134 return getFlashFiredDescription();
135 case TAG_TEXT_STAMP:
136 return getTextStampDescription();
137 case TAG_TEXT_STAMP_1:
138 return getTextStamp1Description();
139 case TAG_TEXT_STAMP_2:
140 return getTextStamp2Description();
141 case TAG_TEXT_STAMP_3:
142 return getTextStamp3Description();
143 case TAG_MAKERNOTE_VERSION:
144 return getMakernoteVersionDescription();
145 case TAG_EXIF_VERSION:
146 return getExifVersionDescription();
147 case TAG_INTERNAL_SERIAL_NUMBER:
148 return getInternalSerialNumberDescription();
149 case TAG_TITLE:
150 return getTitleDescription();
151 case TAG_BABY_NAME:
152 return getBabyNameDescription();
153 case TAG_LOCATION:
154 return getLocationDescription();
155 case TAG_BABY_AGE:
156 return getBabyAgeDescription();
157 case TAG_BABY_AGE_1:
158 return getBabyAge1Description();
159 default:
160 return super.getDescription(tagType);
161 }
162 }
163
164 @Nullable
165 public String getPrintImageMatchingInfoDescription()
166 {
167 return getByteLengthDescription(TAG_PRINT_IMAGE_MATCHING_INFO);
168 }
169
170 @Nullable
171 public String getTextStampDescription()
172 {
173 return getIndexedDescription(TAG_TEXT_STAMP, 1, "Off", "On");
174 }
175
176 @Nullable
177 public String getTextStamp1Description()
178 {
179 return getIndexedDescription(TAG_TEXT_STAMP_1, 1, "Off", "On");
180 }
181
182 @Nullable
183 public String getTextStamp2Description()
184 {
185 return getIndexedDescription(TAG_TEXT_STAMP_2, 1, "Off", "On");
186 }
187
188 @Nullable
189 public String getTextStamp3Description()
190 {
191 return getIndexedDescription(TAG_TEXT_STAMP_3, 1, "Off", "On");
192 }
193
194 @Nullable
195 public String getMacroModeDescription()
196 {
197 return getIndexedDescription(TAG_MACRO_MODE, 1, "Off", "On");
198 }
199
200 @Nullable
201 public String getFlashFiredDescription()
202 {
203 return getIndexedDescription(TAG_FLASH_FIRED, 1, "Off", "On");
204 }
205
206 @Nullable
207 public String getImageStabilizationDescription()
208 {
209 return getIndexedDescription(TAG_IMAGE_STABILIZATION,
210 2,
211 "On, Mode 1",
212 "Off",
213 "On, Mode 2"
214 );
215 }
216
217 @Nullable
218 public String getAudioDescription()
219 {
220 return getIndexedDescription(TAG_AUDIO, 1, "Off", "On");
221 }
222
223 @Nullable
224 public String getTransformDescription()
225 {
226 return getTransformDescription(TAG_TRANSFORM);
227 }
228
229 @Nullable
230 public String getTransform1Description()
231 {
232 return getTransformDescription(TAG_TRANSFORM_1);
233 }
234
235 @Nullable
236 private String getTransformDescription(int tag)
237 {
238 byte[] values = _directory.getByteArray(tag);
239 if (values == null)
240 return null;
241
242 RandomAccessReader reader = new ByteArrayReader(values);
243
244 try
245 {
246 int val1 = reader.getUInt16(0);
247 int val2 = reader.getUInt16(2);
248
249 if (val1 == -1 && val2 == 1)
250 return "Slim Low";
251 if (val1 == -3 && val2 == 2)
252 return "Slim High";
253 if (val1 == 0 && val2 == 0)
254 return "Off";
255 if (val1 == 1 && val2 == 1)
256 return "Stretch Low";
257 if (val1 == 3 && val2 == 2)
258 return "Stretch High";
259
260 return "Unknown (" + val1 + " " + val2 + ")";
261 } catch (IOException e) {
262 return null;
263 }
264 }
265
266 @Nullable
267 public String getIntelligentExposureDescription()
268 {
269 return getIndexedDescription(TAG_INTELLIGENT_EXPOSURE,
270 "Off", "Low", "Standard", "High");
271 }
272
273 @Nullable
274 public String getFlashWarningDescription()
275 {
276 return getIndexedDescription(TAG_FLASH_WARNING,
277 "No", "Yes (Flash required but disabled)");
278 }
279
280 @Nullable
281 public String getCountryDescription()
282 {
283 return getAsciiStringFromBytes(TAG_COUNTRY);
284 }
285
286 @Nullable
287 public String getStateDescription()
288 {
289 return getAsciiStringFromBytes(TAG_STATE);
290 }
291
292 @Nullable
293 public String getCityDescription()
294 {
295 return getAsciiStringFromBytes(TAG_CITY);
296 }
297
298 @Nullable
299 public String getLandmarkDescription()
300 {
301 return getAsciiStringFromBytes(TAG_LANDMARK);
302 }
303
304 @Nullable
305 public String getTitleDescription()
306 {
307 return getAsciiStringFromBytes(TAG_TITLE);
308 }
309
310 @Nullable
311 public String getBabyNameDescription()
312 {
313 return getAsciiStringFromBytes(TAG_BABY_NAME);
314 }
315
316 @Nullable
317 public String getLocationDescription()
318 {
319 return getAsciiStringFromBytes(TAG_LOCATION);
320 }
321
322 @Nullable
323 public String getIntelligentResolutionDescription()
324 {
325 return getIndexedDescription(TAG_INTELLIGENT_RESOLUTION,
326 "Off", null, "Auto", "On");
327 }
328
329 @Nullable
330 public String getContrastDescription()
331 {
332 return getIndexedDescription(TAG_CONTRAST, "Normal");
333 }
334
335 @Nullable
336 public String getWorldTimeLocationDescription()
337 {
338 return getIndexedDescription(TAG_WORLD_TIME_LOCATION,
339 1, "Home", "Destination");
340 }
341
342 @Nullable
343 public String getAdvancedSceneModeDescription()
344 {
345 return getIndexedDescription(TAG_ADVANCED_SCENE_MODE,
346 1,
347 "Normal",
348 "Outdoor/Illuminations/Flower/HDR Art",
349 "Indoor/Architecture/Objects/HDR B&W",
350 "Creative",
351 "Auto",
352 null,
353 "Expressive",
354 "Retro",
355 "Pure",
356 "Elegant",
357 null,
358 "Monochrome",
359 "Dynamic Art",
360 "Silhouette"
361 );
362 }
363
364 @Nullable
365 public String getUnknownDataDumpDescription()
366 {
367 return getByteLengthDescription(TAG_UNKNOWN_DATA_DUMP);
368 }
369
370 @Nullable
371 public String getColorEffectDescription()
372 {
373 return getIndexedDescription(TAG_COLOR_EFFECT,
374 1, "Off", "Warm", "Cool", "Black & White", "Sepia"
375 );
376 }
377
378 @Nullable
379 public String getUptimeDescription()
380 {
381 Integer value = _directory.getInteger(TAG_UPTIME);
382 if (value == null)
383 return null;
384 return value / 100f + " s";
385 }
386
387 @Nullable
388 public String getBurstModeDescription()
389 {
390 return getIndexedDescription(TAG_BURST_MODE,
391 "Off", null, "On", "Indefinite", "Unlimited"
392 );
393 }
394
395 @Nullable
396 public String getContrastModeDescription()
397 {
398 Integer value = _directory.getInteger(TAG_CONTRAST_MODE);
399 if (value == null)
400 return null;
401 switch (value) {
402 case 0x0: return "Normal";
403 case 0x1: return "Low";
404 case 0x2: return "High";
405 case 0x6: return "Medium Low";
406 case 0x7: return "Medium High";
407 case 0x100: return "Low";
408 case 0x110: return "Normal";
409 case 0x120: return "High";
410 default:
411 return "Unknown (" + value + ")";
412 }
413 }
414
415 @Nullable
416 public String getNoiseReductionDescription()
417 {
418 return getIndexedDescription(TAG_NOISE_REDUCTION,
419 "Standard (0)", "Low (-1)", "High (+1)", "Lowest (-2)", "Highest (+2)"
420 );
421 }
422
423 @Nullable
424 public String getSelfTimerDescription()
425 {
426 return getIndexedDescription(TAG_SELF_TIMER,
427 1, "Off", "10 s", "2 s"
428 );
429 }
430
431 @Nullable
432 public String getRotationDescription()
433 {
434 Integer value = _directory.getInteger(TAG_ROTATION);
435 if (value == null)
436 return null;
437 switch (value) {
438 case 1: return "Horizontal";
439 case 3: return "Rotate 180";
440 case 6: return "Rotate 90 CW";
441 case 8: return "Rotate 270 CW";
442 default:
443 return "Unknown (" + value + ")";
444 }
445 }
446
447 @Nullable
448 public String getAfAssistLampDescription()
449 {
450 return getIndexedDescription(TAG_AF_ASSIST_LAMP,
451 1, "Fired", "Enabled but not used", "Disabled but required", "Disabled and not required"
452 );
453 }
454
455 @Nullable
456 public String getColorModeDescription()
457 {
458 return getIndexedDescription(TAG_COLOR_MODE,
459 "Normal", "Natural", "Vivid"
460 );
461 }
462
463 @Nullable
464 public String getOpticalZoomModeDescription()
465 {
466 return getIndexedDescription(TAG_OPTICAL_ZOOM_MODE,
467 1, "Standard", "Extended"
468 );
469 }
470
471 @Nullable
472 public String getConversionLensDescription()
473 {
474 return getIndexedDescription(TAG_CONVERSION_LENS,
475 1, "Off", "Wide", "Telephoto", "Macro"
476 );
477 }
478
479 @Nullable
480 public String getDetectedFacesDescription()
481 {
482 return buildFacesDescription(_directory.getDetectedFaces());
483 }
484
485 @Nullable
486 public String getRecognizedFacesDescription()
487 {
488 return buildFacesDescription(_directory.getRecognizedFaces());
489 }
490
491 @Nullable
492 private String buildFacesDescription(@Nullable Face[] faces)
493 {
494 if (faces == null)
495 return null;
496
497 StringBuilder result = new StringBuilder();
498
499 for (int i = 0; i < faces.length; i++)
500 result.append("Face ").append(i + 1).append(": ").append(faces[i].toString()).append("\n");
501
502 return result.length() > 0 ? result.substring(0, result.length() - 1) : null;
503
504 }
505
506 private static final String[] _sceneModes = new String[] {
507 "Normal", // 1
508 "Portrait",
509 "Scenery",
510 "Sports",
511 "Night Portrait",
512 "Program",
513 "Aperture Priority",
514 "Shutter Priority",
515 "Macro",
516 "Spot", // 10
517 "Manual",
518 "Movie Preview",
519 "Panning",
520 "Simple",
521 "Color Effects",
522 "Self Portrait",
523 "Economy",
524 "Fireworks",
525 "Party",
526 "Snow", // 20
527 "Night Scenery",
528 "Food",
529 "Baby",
530 "Soft Skin",
531 "Candlelight",
532 "Starry Night",
533 "High Sensitivity",
534 "Panorama Assist",
535 "Underwater",
536 "Beach", // 30
537 "Aerial Photo",
538 "Sunset",
539 "Pet",
540 "Intelligent ISO",
541 "Clipboard",
542 "High Speed Continuous Shooting",
543 "Intelligent Auto",
544 null,
545 "Multi-aspect",
546 null, // 40
547 "Transform",
548 "Flash Burst",
549 "Pin Hole",
550 "Film Grain",
551 "My Color",
552 "Photo Frame",
553 null,
554 null,
555 null,
556 null, // 50
557 "HDR"
558 };
559
560 @Nullable
561 public String getRecordModeDescription()
562 {
563 return getIndexedDescription(TAG_RECORD_MODE, 1, _sceneModes);
564 }
565
566 @Nullable
567 public String getSceneModeDescription()
568 {
569 return getIndexedDescription(TAG_SCENE_MODE, 1, _sceneModes);
570 }
571
572 @Nullable
573 public String getFocusModeDescription()
574 {
575 return getIndexedDescription(TAG_FOCUS_MODE, 1,
576 "Auto", "Manual", null, "Auto, Focus Button", "Auto, Continuous");
577 }
578
579 @Nullable
580 public String getAfAreaModeDescription()
581 {
582 int[] value = _directory.getIntArray(TAG_AF_AREA_MODE);
583 if (value == null || value.length < 2)
584 return null;
585 switch (value[0]) {
586 case 0:
587 switch (value[1]) {
588 case 1: return "Spot Mode On";
589 case 16: return "Spot Mode Off";
590 default: return "Unknown (" + value[0] + " " + value[1] + ")";
591 }
592 case 1:
593 switch (value[1]) {
594 case 0: return "Spot Focusing";
595 case 1: return "5-area";
596 default: return "Unknown (" + value[0] + " " + value[1] + ")";
597 }
598 case 16:
599 switch (value[1]) {
600 case 0: return "1-area";
601 case 16: return "1-area (high speed)";
602 default: return "Unknown (" + value[0] + " " + value[1] + ")";
603 }
604 case 32:
605 switch (value[1]) {
606 case 0: return "Auto or Face Detect";
607 case 1: return "3-area (left)";
608 case 2: return "3-area (center)";
609 case 3: return "3-area (right)";
610 default: return "Unknown (" + value[0] + " " + value[1] + ")";
611 }
612 case 64: return "Face Detect";
613 default: return "Unknown (" + value[0] + " " + value[1] + ")";
614 }
615 }
616
617 @Nullable
618 public String getQualityModeDescription()
619 {
620 return getIndexedDescription(TAG_QUALITY_MODE,
621 2,
622 "High", // 2
623 "Normal",
624 null,
625 null,
626 "Very High",
627 "Raw",
628 null,
629 "Motion Picture" // 9
630 );
631 }
632
633 @Nullable
634 public String getVersionDescription()
635 {
636 return getVersionBytesDescription(TAG_FIRMWARE_VERSION, 2);
637 }
638
639 @Nullable
640 public String getMakernoteVersionDescription()
641 {
642 return getVersionBytesDescription(TAG_MAKERNOTE_VERSION, 2);
643 }
644
645 @Nullable
646 public String getExifVersionDescription()
647 {
648 return getVersionBytesDescription(TAG_EXIF_VERSION, 2);
649 }
650
651 @Nullable
652 public String getInternalSerialNumberDescription()
653 {
654 return get7BitStringFromBytes(TAG_INTERNAL_SERIAL_NUMBER);
655 }
656
657 @Nullable
658 public String getWhiteBalanceDescription()
659 {
660 return getIndexedDescription(TAG_WHITE_BALANCE,
661 1,
662 "Auto", // 1
663 "Daylight",
664 "Cloudy",
665 "Incandescent",
666 "Manual",
667 null,
668 null,
669 "Flash",
670 null,
671 "Black & White", // 10
672 "Manual",
673 "Shade" // 12
674 );
675 }
676
677 @Nullable
678 public String getBabyAgeDescription()
679 {
680 final Age age = _directory.getAge(TAG_BABY_AGE);
681 return age == null ? null : age.toFriendlyString();
682 }
683
684 @Nullable
685 public String getBabyAge1Description()
686 {
687 final Age age = _directory.getAge(TAG_BABY_AGE_1);
688 return age == null ? null : age.toFriendlyString();
689 }
690}
Note: See TracBrowser for help on using the repository browser.