/* * Copyright 2002-2016 Drew Noakes * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * More information about this project is available at: * * https://drewnoakes.com/code/exif/ * https://github.com/drewnoakes/metadata-extractor */ package com.drew.metadata.exif.makernotes; import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; import com.drew.metadata.TagDescriptor; import static com.drew.metadata.exif.makernotes.SonyType1MakernoteDirectory.*; /** * Provides human-readable string representations of tag values stored in a {@link SonyType1MakernoteDirectory}. * Thanks to David Carson for the initial version of this class. * * @author Drew Noakes https://drewnoakes.com */ public class SonyType1MakernoteDescriptor extends TagDescriptor<SonyType1MakernoteDirectory> { public SonyType1MakernoteDescriptor(@NotNull SonyType1MakernoteDirectory directory) { super(directory); } @Override @Nullable public String getDescription(int tagType) { switch (tagType) { case TAG_IMAGE_QUALITY: return getImageQualityDescription(); case TAG_FLASH_EXPOSURE_COMP: return getFlashExposureCompensationDescription(); case TAG_TELECONVERTER: return getTeleconverterDescription(); case TAG_WHITE_BALANCE: return getWhiteBalanceDescription(); case TAG_COLOR_TEMPERATURE: return getColorTemperatureDescription(); case TAG_SCENE_MODE: return getSceneModeDescription(); case TAG_ZONE_MATCHING: return getZoneMatchingDescription(); case TAG_DYNAMIC_RANGE_OPTIMISER: return getDynamicRangeOptimizerDescription(); case TAG_IMAGE_STABILISATION: return getImageStabilizationDescription(); // Unfortunately it seems that there is no definite mapping between a lens ID and a lens model // http://gvsoft.homedns.org/exif/makernote-sony-type1.html#0xb027 // case TAG_LENS_ID: // return getLensIDDescription(); case TAG_COLOR_MODE: return getColorModeDescription(); case TAG_MACRO: return getMacroDescription(); case TAG_EXPOSURE_MODE: return getExposureModeDescription(); case TAG_JPEG_QUALITY: return getJpegQualityDescription(); case TAG_ANTI_BLUR: return getAntiBlurDescription(); case TAG_LONG_EXPOSURE_NOISE_REDUCTION_OR_FOCUS_MODE: return getLongExposureNoiseReductionDescription(); case TAG_HIGH_ISO_NOISE_REDUCTION: return getHighIsoNoiseReductionDescription(); case TAG_PICTURE_EFFECT: return getPictureEffectDescription(); case TAG_SOFT_SKIN_EFFECT: return getSoftSkinEffectDescription(); case TAG_VIGNETTING_CORRECTION: return getVignettingCorrectionDescription(); case TAG_LATERAL_CHROMATIC_ABERRATION: return getLateralChromaticAberrationDescription(); case TAG_DISTORTION_CORRECTION: return getDistortionCorrectionDescription(); case TAG_AUTO_PORTRAIT_FRAMED: return getAutoPortraitFramedDescription(); case TAG_FOCUS_MODE: return getFocusModeDescription(); case TAG_AF_POINT_SELECTED: return getAFPointSelectedDescription(); case TAG_SONY_MODEL_ID: return getSonyModelIdDescription(); case TAG_AF_MODE: return getAFModeDescription(); case TAG_AF_ILLUMINATOR: return getAFIlluminatorDescription(); case TAG_FLASH_LEVEL: return getFlashLevelDescription(); case TAG_RELEASE_MODE: return getReleaseModeDescription(); case TAG_SEQUENCE_NUMBER: return getSequenceNumberDescription(); default: return super.getDescription(tagType); } } @Nullable public String getImageQualityDescription() { return getIndexedDescription(TAG_IMAGE_QUALITY, "RAW", "Super Fine", "Fine", "Standard", "Economy", "Extra Fine", "RAW + JPEG", "Compressed RAW", "Compressed RAW + JPEG"); } @Nullable public String getFlashExposureCompensationDescription() { return getFormattedInt(TAG_FLASH_EXPOSURE_COMP, "%d EV"); } @Nullable public String getTeleconverterDescription() { Integer value = _directory.getInteger(TAG_TELECONVERTER); if (value == null) return null; switch (value) { case 0x00: return "None"; case 0x48: return "Minolta/Sony AF 2x APO (D)"; case 0x50: return "Minolta AF 2x APO II"; case 0x60: return "Minolta AF 2x APO"; case 0x88: return "Minolta/Sony AF 1.4x APO (D)"; case 0x90: return "Minolta AF 1.4x APO II"; case 0xa0: return "Minolta AF 1.4x APO"; default: return "Unknown (" + value + ")"; } } @Nullable public String getWhiteBalanceDescription() { Integer value = _directory.getInteger(TAG_WHITE_BALANCE); if (value == null) return null; switch (value) { case 0x00: return "Auto"; case 0x01: return "Color Temperature/Color Filter"; case 0x10: return "Daylight"; case 0x20: return "Cloudy"; case 0x30: return "Shade"; case 0x40: return "Tungsten"; case 0x50: return "Flash"; case 0x60: return "Fluorescent"; case 0x70: return "Custom"; default: return "Unknown (" + value + ")"; } } @Nullable public String getColorTemperatureDescription() { Integer value = _directory.getInteger(TAG_COLOR_TEMPERATURE); if (value == null) return null; if (value == 0) return "Auto"; int kelvin = ((value & 0x00FF0000) >> 8) | ((value & 0xFF000000) >> 24); return String.format("%d K", kelvin); } @Nullable public String getZoneMatchingDescription() { return getIndexedDescription(TAG_ZONE_MATCHING, "ISO Setting Used", "High Key", "Low Key"); } @Nullable public String getDynamicRangeOptimizerDescription() { Integer value = _directory.getInteger(TAG_DYNAMIC_RANGE_OPTIMISER); if (value == null) return null; switch (value) { case 0: return "Off"; case 1: return "Standard"; case 2: return "Advanced Auto"; case 3: return "Auto"; case 8: return "Advanced LV1"; case 9: return "Advanced LV2"; case 10: return "Advanced LV3"; case 11: return "Advanced LV4"; case 12: return "Advanced LV5"; case 16: return "LV1"; case 17: return "LV2"; case 18: return "LV3"; case 19: return "LV4"; case 20: return "LV5"; default: return String.format("Unknown (%d)", value); } } @Nullable public String getImageStabilizationDescription() { Integer value = _directory.getInteger(TAG_IMAGE_STABILISATION); if (value == null) return null; switch (value) { case 0: return "Off"; case 1: return "On"; default: return "N/A"; } } @Nullable public String getColorModeDescription() { Integer value = _directory.getInteger(TAG_COLOR_MODE); if (value == null) return null; switch (value) { case 0: return "Standard"; case 1: return "Vivid"; case 2: return "Portrait"; case 3: return "Landscape"; case 4: return "Sunset"; case 5: return "Night Portrait"; case 6: return "Black & White"; case 7: return "Adobe RGB"; case 12: case 100: return "Neutral"; case 13: case 101: return "Clear"; case 14: case 102: return "Deep"; case 15: case 103: return "Light"; case 16: return "Autumn"; case 17: return "Sepia"; case 104: return "Night View"; case 105: return "Autumn Leaves"; default: return String.format("Unknown (%d)", value); } } @Nullable public String getMacroDescription() { Integer value = _directory.getInteger(TAG_MACRO); if (value == null) return null; switch (value) { case 0: return "Off"; case 1: return "On"; case 2: return "Magnifying Glass/Super Macro"; case 0xFFFF: return "N/A"; default: return String.format("Unknown (%d)", value); } } @Nullable public String getExposureModeDescription() { Integer value = _directory.getInteger(TAG_EXPOSURE_MODE); if (value == null) return null; switch (value) { case 0: return "Program"; case 1: return "Portrait"; case 2: return "Beach"; case 3: return "Sports"; case 4: return "Snow"; case 5: return "Landscape"; case 6: return "Auto"; case 7: return "Aperture Priority"; case 8: return "Shutter Priority"; case 9: return "Night Scene / Twilight"; case 10: return "Hi-Speed Shutter"; case 11: return "Twilight Portrait"; case 12: return "Soft Snap/Portrait"; case 13: return "Fireworks"; case 14: return "Smile Shutter"; case 15: return "Manual"; case 18: return "High Sensitivity"; case 19: return "Macro"; case 20: return "Advanced Sports Shooting"; case 29: return "Underwater"; case 33: return "Food"; case 34: return "Panorama"; case 35: return "Handheld Night Shot"; case 36: return "Anti Motion Blur"; case 37: return "Pet"; case 38: return "Backlight Correction HDR"; case 39: return "Superior Auto"; case 40: return "Background Defocus"; case 41: return "Soft Skin"; case 42: return "3D Image"; case 0xFFFF: return "N/A"; default: return String.format("Unknown (%d)", value); } } @Nullable public String getJpegQualityDescription() { Integer value = _directory.getInteger(TAG_JPEG_QUALITY); if (value == null) return null; switch (value) { case 0: return "Normal"; case 1: return "Fine"; case 2: return "Extra Fine"; case 0xFFFF: return "N/A"; default: return String.format("Unknown (%d)", value); } } @Nullable public String getAntiBlurDescription() { Integer value = _directory.getInteger(TAG_ANTI_BLUR); if (value == null) return null; switch (value) { case 0: return "Off"; case 1: return "On (Continuous)"; case 2: return "On (Shooting)"; case 0xFFFF: return "N/A"; default: return String.format("Unknown (%d)", value); } } @Nullable public String getLongExposureNoiseReductionDescription() { Integer value = _directory.getInteger(TAG_LONG_EXPOSURE_NOISE_REDUCTION_OR_FOCUS_MODE); if (value == null) return null; switch (value) { case 0: return "Off"; case 1: return "On"; case 0xFFFF: return "N/A"; default: return String.format("Unknown (%d)", value); } } @Nullable public String getHighIsoNoiseReductionDescription() { Integer value = _directory.getInteger(TAG_HIGH_ISO_NOISE_REDUCTION); if (value == null) return null; switch (value) { case 0: return "Off"; case 1: return "On"; case 2: return "Normal"; case 3: return "High"; case 0x100: return "Auto"; case 0xffff: return "N/A"; default: return String.format("Unknown (%d)", value); } } @Nullable public String getPictureEffectDescription() { Integer value = _directory.getInteger(TAG_PICTURE_EFFECT); if (value == null) return null; switch (value) { case 0: return "Off"; case 1: return "Toy Camera"; case 2: return "Pop Color"; case 3: return "Posterization"; case 4: return "Posterization B/W"; case 5: return "Retro Photo"; case 6: return "Soft High Key"; case 7: return "Partial Color (red)"; case 8: return "Partial Color (green)"; case 9: return "Partial Color (blue)"; case 10: return "Partial Color (yellow)"; case 13: return "High Contrast Monochrome"; case 16: return "Toy Camera (normal)"; case 17: return "Toy Camera (cool)"; case 18: return "Toy Camera (warm)"; case 19: return "Toy Camera (green)"; case 20: return "Toy Camera (magenta)"; case 32: return "Soft Focus (low)"; case 33: return "Soft Focus"; case 34: return "Soft Focus (high)"; case 48: return "Miniature (auto)"; case 49: return "Miniature (top)"; case 50: return "Miniature (middle horizontal)"; case 51: return "Miniature (bottom)"; case 52: return "Miniature (left)"; case 53: return "Miniature (middle vertical)"; case 54: return "Miniature (right)"; case 64: return "HDR Painting (low)"; case 65: return "HDR Painting"; case 66: return "HDR Painting (high)"; case 80: return "Rich-tone Monochrome"; case 97: return "Water Color"; case 98: return "Water Color 2"; case 112: return "Illustration (low)"; case 113: return "Illustration"; case 114: return "Illustration (high)"; default: return String.format("Unknown (%d)", value); } } @Nullable public String getSoftSkinEffectDescription() { return getIndexedDescription(TAG_SOFT_SKIN_EFFECT, "Off", "Low", "Mid", "High"); } @Nullable public String getVignettingCorrectionDescription() { return getIndexedDescription(TAG_VIGNETTING_CORRECTION, "Off", null, "Auto"); } @Nullable public String getLateralChromaticAberrationDescription() { return getIndexedDescription(TAG_LATERAL_CHROMATIC_ABERRATION, "Off", null, "Auto"); } @Nullable public String getDistortionCorrectionDescription() { return getIndexedDescription(TAG_DISTORTION_CORRECTION, "Off", null, "Auto"); } @Nullable public String getAutoPortraitFramedDescription() { return getIndexedDescription(TAG_AUTO_PORTRAIT_FRAMED, "No", "Yes"); } @Nullable public String getFocusModeDescription() { return getIndexedDescription(TAG_FOCUS_MODE, "Manual", null, "AF-A", "AF-C", "AF-S", null, "DMF", "AF-D"); } @Nullable public String getAFPointSelectedDescription() { return getIndexedDescription(TAG_AF_POINT_SELECTED, "Auto", // 0 "Center", // 1 "Top", // 2 "Upper-right", // 3 "Right", // 4 "Lower-right", // 5 "Bottom", // 6 "Lower-left", // 7 "Left", // 8 "Upper-left ", // 9 "Far Right", // 10 "Far Left", // 11 "Upper-middle", // 12 "Near Right", // 13 "Lower-middle", // 14 "Near Left", // 15 "Upper Far Right", // 16 "Lower Far Right", // 17 "Lower Far Left", // 18 "Upper Far Left" // 19 ); } @Nullable public String getSonyModelIdDescription() { Integer value = _directory.getInteger(TAG_SONY_MODEL_ID); if (value == null) return null; switch (value) { case 2: return "DSC-R1"; case 256: return "DSLR-A100"; case 257: return "DSLR-A900"; case 258: return "DSLR-A700"; case 259: return "DSLR-A200"; case 260: return "DSLR-A350"; case 261: return "DSLR-A300"; case 262: return "DSLR-A900 (APS-C mode)"; case 263: return "DSLR-A380/A390"; case 264: return "DSLR-A330"; case 265: return "DSLR-A230"; case 266: return "DSLR-A290"; case 269: return "DSLR-A850"; case 270: return "DSLR-A850 (APS-C mode)"; case 273: return "DSLR-A550"; case 274: return "DSLR-A500"; case 275: return "DSLR-A450"; case 278: return "NEX-5"; case 279: return "NEX-3"; case 280: return "SLT-A33"; case 281: return "SLT-A55V"; case 282: return "DSLR-A560"; case 283: return "DSLR-A580"; case 284: return "NEX-C3"; case 285: return "SLT-A35"; case 286: return "SLT-A65V"; case 287: return "SLT-A77V"; case 288: return "NEX-5N"; case 289: return "NEX-7"; case 290: return "NEX-VG20E"; case 291: return "SLT-A37"; case 292: return "SLT-A57"; case 293: return "NEX-F3"; case 294: return "SLT-A99V"; case 295: return "NEX-6"; case 296: return "NEX-5R"; case 297: return "DSC-RX100"; case 298: return "DSC-RX1"; default: return "Unknown (" + value + ")"; } } @Nullable public String getSceneModeDescription() { Integer value = _directory.getInteger(TAG_SCENE_MODE); if (value == null) return null; switch (value) { case 0: return "Standard"; case 1: return "Portrait"; case 2: return "Text"; case 3: return "Night Scene"; case 4: return "Sunset"; case 5: return "Sports"; case 6: return "Landscape"; case 7: return "Night Portrait"; case 8: return "Macro"; case 9: return "Super Macro"; case 16: return "Auto"; case 17: return "Night View/Portrait"; case 18: return "Sweep Panorama"; case 19: return "Handheld Night Shot"; case 20: return "Anti Motion Blur"; case 21: return "Cont. Priority AE"; case 22: return "Auto+"; case 23: return "3D Sweep Panorama"; case 24: return "Superior Auto"; case 25: return "High Sensitivity"; case 26: return "Fireworks"; case 27: return "Food"; case 28: return "Pet"; default: return "Unknown (" + value + ")"; } } @Nullable public String getAFModeDescription() { Integer value = _directory.getInteger(TAG_AF_MODE); if (value == null) return null; switch (value) { case 0: return "Default"; case 1: return "Multi"; case 2: return "Center"; case 3: return "Spot"; case 4: return "Flexible Spot"; case 6: return "Touch"; case 14: return "Manual Focus"; case 15: return "Face Detected"; case 0xffff: return "n/a"; default: return "Unknown (" + value + ")"; } } @Nullable public String getAFIlluminatorDescription() { Integer value = _directory.getInteger(TAG_AF_ILLUMINATOR); if (value == null) return null; switch (value) { case 0: return "Off"; case 1: return "Auto"; case 0xffff: return "n/a"; default: return "Unknown (" + value + ")"; } } @Nullable public String getFlashLevelDescription() { Integer value = _directory.getInteger(TAG_FLASH_LEVEL); if (value == null) return null; switch (value) { case -32768: return "Low"; case -3: return "-3/3"; case -2: return "-2/3"; case -1: return "-1/3"; case 0: return "Normal"; case 1: return "+1/3"; case 2: return "+2/3"; case 3: return "+3/3"; case 128: return "n/a"; case 32767: return "High"; default: return "Unknown (" + value + ")"; } } @Nullable public String getReleaseModeDescription() { Integer value = _directory.getInteger(TAG_RELEASE_MODE); if (value == null) return null; switch (value) { case 0: return "Normal"; case 2: return "Continuous"; case 5: return "Exposure Bracketing"; case 6: return "White Balance Bracketing"; case 65535: return "n/a"; default: return "Unknown (" + value + ")"; } } @Nullable public String getSequenceNumberDescription() { Integer value = _directory.getInteger(TAG_RELEASE_MODE); if (value == null) return null; switch (value) { case 0: return "Single"; case 65535: return "n/a"; default: return value.toString(); } } }