using System; using com.drew.metadata; /// /// This class was first written by Drew Noakes in Java. /// /// This is public domain software - that is, you can do whatever you want /// with it, and include it software that is licensed under the GNU or the /// BSD license, or whatever other licence you choose, including proprietary /// closed source licenses. I do ask that you leave this header in tact. /// /// If you make modifications to this code that you think would benefit the /// wider community, please send me a copy and I'll post it on my site. /// /// If you make use of this code, Drew Noakes will appreciate hearing /// about it: drew@drewnoakes.com /// /// Latest Java version of this software kept at /// http://drewnoakes.com/ /// /// The C# class was made by Ferret Renaud: /// renaud91@free.fr /// If you find a bug in the C# code, feel free to mail me. /// namespace com.drew.metadata.exif { /// /// Tag descriptor for a Canon camera /// public class CanonMakernoteDescriptor : TagDescriptor { /// /// Constructor of the object /// /// a directory public CanonMakernoteDescriptor(Directory directory) : base(directory) { } /// /// Returns a descriptive value of the the specified tag for this image. /// Where possible, known values will be substituted here in place of the raw tokens actually /// kept in the Exif segment. /// If no substitution is available, the value provided by GetString(int) will be returned. /// This and GetString(int) are the only 'get' methods that won't throw an exception. /// /// the tag to find a description for /// a description of the image's value for the specified tag, or null if the tag hasn't been defined. public override string GetDescription(int tagType) { switch(tagType) { case CanonMakernoteDirectory.TAG_CANON_STATE1_MACRO_MODE : return GetMacroModeDescription(); case CanonMakernoteDirectory.TAG_CANON_STATE1_SELF_TIMER_DELAY: return GetSelfTimerDelayDescription(); case CanonMakernoteDirectory.TAG_CANON_STATE1_FLASH_MODE : return GetFlashModeDescription(); case CanonMakernoteDirectory.TAG_CANON_STATE1_CONTINUOUS_DRIVE_MODE: return GetContinuousDriveModeDescription(); case CanonMakernoteDirectory.TAG_CANON_STATE1_FOCUS_MODE_1: return GetFocusMode1Description(); case CanonMakernoteDirectory.TAG_CANON_STATE1_IMAGE_SIZE: return GetImageSizeDescription(); case CanonMakernoteDirectory.TAG_CANON_STATE1_EASY_SHOOTING_MODE: return GetEasyShootingModeDescription(); case CanonMakernoteDirectory.TAG_CANON_STATE1_CONTRAST: return GetContrastDescription(); case CanonMakernoteDirectory.TAG_CANON_STATE1_SATURATION: return GetSaturationDescription(); case CanonMakernoteDirectory.TAG_CANON_STATE1_SHARPNESS: return GetSharpnessDescription(); case CanonMakernoteDirectory.TAG_CANON_STATE1_ISO: return GetIsoDescription(); case CanonMakernoteDirectory.TAG_CANON_STATE1_METERING_MODE: return GetMeteringModeDescription(); case CanonMakernoteDirectory.TAG_CANON_STATE1_AF_POINT_SELECTED: return GetAfPointSelectedDescription(); case CanonMakernoteDirectory.TAG_CANON_STATE1_EXPOSURE_MODE: return GetExposureModeDescription(); case CanonMakernoteDirectory.TAG_CANON_STATE1_LONG_FOCAL_LENGTH: return GetLongFocalLengthDescription(); case CanonMakernoteDirectory.TAG_CANON_STATE1_SHORT_FOCAL_LENGTH: return GetShortFocalLengthDescription(); case CanonMakernoteDirectory.TAG_CANON_STATE1_FOCAL_UNITS_PER_MM: return GetFocalUnitsPerMillimetreDescription(); case CanonMakernoteDirectory.TAG_CANON_STATE1_FLASH_DETAILS: return GetFlashDetailsDescription(); case CanonMakernoteDirectory.TAG_CANON_STATE1_FOCUS_MODE_2: return GetFocusMode2Description(); case CanonMakernoteDirectory.TAG_CANON_STATE2_WHITE_BALANCE: return GetWhiteBalanceDescription(); case CanonMakernoteDirectory.TAG_CANON_STATE2_AF_POINT_USED: return GetAfPointUsedDescription(); case CanonMakernoteDirectory.TAG_CANON_STATE2_FLASH_BIAS: return GetFlashBiasDescription(); default : return _directory.GetString(tagType); } } /// /// Returns the Flash Bias Description. /// /// the Flash Bias Description. private string GetFlashBiasDescription() { if (!_directory .ContainsTag(CanonMakernoteDirectory.TAG_CANON_STATE2_FLASH_BIAS)) return null; int aValue = _directory.GetInt( CanonMakernoteDirectory.TAG_CANON_STATE2_FLASH_BIAS); switch (aValue) { case 0xffc0 : return BUNDLE["FLASH_BIAS_N_2"]; case 0xffcc : return BUNDLE["FLASH_BIAS_N_167"]; case 0xffd0 : return BUNDLE["FLASH_BIAS_N_150"]; case 0xffd4 : return BUNDLE["FLASH_BIAS_N_133"]; case 0xffe0 : return BUNDLE["FLASH_BIAS_N_1"]; case 0xffec : return BUNDLE["FLASH_BIAS_N_067"]; case 0xfff0 : return BUNDLE["FLASH_BIAS_N_050"]; case 0xfff4 : return BUNDLE["FLASH_BIAS_N_033"]; case 0x0000 : return BUNDLE["FLASH_BIAS_P_0"]; case 0x000c : return BUNDLE["FLASH_BIAS_P_033"]; case 0x0010 : return BUNDLE["FLASH_BIAS_P_050"]; case 0x0014 : return BUNDLE["FLASH_BIAS_P_067"]; case 0x0020 : return BUNDLE["FLASH_BIAS_P_1"]; case 0x002c : return BUNDLE["FLASH_BIAS_P_133"]; case 0x0030 : return BUNDLE["FLASH_BIAS_P_150"]; case 0x0034 : return BUNDLE["FLASH_BIAS_P_167"]; case 0x0040 : return BUNDLE["FLASH_BIAS_P_2"]; default : return BUNDLE["UNKNOWN", aValue.ToString()]; } } /// /// Returns Af Point Used Description. /// /// the Af Point Used Description. private string GetAfPointUsedDescription() { if (!_directory .ContainsTag( CanonMakernoteDirectory.TAG_CANON_STATE2_AF_POINT_USED)) return null; int aValue = _directory.GetInt( CanonMakernoteDirectory.TAG_CANON_STATE2_AF_POINT_USED); if ((aValue & 0x7) == 0) { return BUNDLE["RIGHT"]; } else if ((aValue & 0x7) == 1) { return BUNDLE["CENTER"];; } else if ((aValue & 0x7) == 2) { return BUNDLE["LEFT"]; } else { return BUNDLE["UNKNOWN", aValue.ToString()]; } } /// /// Returns White Balance Description. /// /// the White Balance Description. private string GetWhiteBalanceDescription() { if (!_directory .ContainsTag( CanonMakernoteDirectory.TAG_CANON_STATE2_WHITE_BALANCE)) return null; int aValue = _directory.GetInt( CanonMakernoteDirectory.TAG_CANON_STATE2_WHITE_BALANCE); switch (aValue) { case 0 : return BUNDLE["AUTO"]; case 1 : return BUNDLE["SUNNY"]; case 2 : return BUNDLE["CLOUDY"]; case 3 : return BUNDLE["TUNGSTEN"]; case 4 : return BUNDLE["FLOURESCENT"]; case 5 : return BUNDLE["FLASH"]; case 6 : return BUNDLE["CUSTOM"]; default : return BUNDLE["UNKNOWN", aValue.ToString()]; } } /// /// Returns Focus Mode 2 description. /// /// the Focus Mode 2 description private string GetFocusMode2Description() { if (!_directory .ContainsTag(CanonMakernoteDirectory.TAG_CANON_STATE1_FOCUS_MODE_2)) return null; int aValue = _directory.GetInt( CanonMakernoteDirectory.TAG_CANON_STATE1_FOCUS_MODE_2); switch (aValue) { case 0 : return BUNDLE["SINGLE"]; case 1 : return BUNDLE["CONTINUOUS"]; default : return BUNDLE["UNKNOWN", aValue.ToString()]; } } /// /// Returns Flash Details description. /// /// the Flash Details description private string GetFlashDetailsDescription() { if (!_directory .ContainsTag( CanonMakernoteDirectory.TAG_CANON_STATE1_FLASH_DETAILS)) return null; int aValue = _directory.GetInt( CanonMakernoteDirectory.TAG_CANON_STATE1_FLASH_DETAILS); if (((aValue << 14) & 1) > 0) { return BUNDLE["EXTERNAL_E_TTL"]; } if (((aValue << 13) & 1) > 0) { return BUNDLE["INTERNAL_FLASH"]; } if (((aValue << 11) & 1) > 0) { return BUNDLE["FP_SYNC_USED"]; } if (((aValue << 4) & 1) > 0) { return BUNDLE["FP_SYNC_ENABLED"]; } return BUNDLE["UNKNOWN", aValue.ToString()]; } /// /// Returns Focal Units Per Millimetre description. /// /// the Focal Units Per Millimetre description private string GetFocalUnitsPerMillimetreDescription() { if (!_directory .ContainsTag( CanonMakernoteDirectory.TAG_CANON_STATE1_FOCAL_UNITS_PER_MM)) return ""; int aValue = _directory.GetInt( CanonMakernoteDirectory.TAG_CANON_STATE1_FOCAL_UNITS_PER_MM); if (aValue != 0) { return aValue.ToString(); } else { return ""; } } /// /// Returns Short Focal Length description. /// /// the Short Focal Length description private string GetShortFocalLengthDescription() { if (!_directory .ContainsTag( CanonMakernoteDirectory.TAG_CANON_STATE1_SHORT_FOCAL_LENGTH)) return null; int aValue = _directory.GetInt( CanonMakernoteDirectory.TAG_CANON_STATE1_SHORT_FOCAL_LENGTH); string units = GetFocalUnitsPerMillimetreDescription(); return BUNDLE["FOCAL_LENGTH", aValue.ToString(), units]; } /// /// Returns Long Focal Length description. /// /// the Long Focal Length description private string GetLongFocalLengthDescription() { if (!_directory .ContainsTag( CanonMakernoteDirectory.TAG_CANON_STATE1_LONG_FOCAL_LENGTH)) return null; int aValue = _directory.GetInt( CanonMakernoteDirectory.TAG_CANON_STATE1_LONG_FOCAL_LENGTH); string units = GetFocalUnitsPerMillimetreDescription(); return BUNDLE["FOCAL_LENGTH", aValue.ToString(), units]; } /// /// Returns Exposure Mode description. /// /// the Exposure Mode description private string GetExposureModeDescription() { if (!_directory .ContainsTag( CanonMakernoteDirectory.TAG_CANON_STATE1_EXPOSURE_MODE)) return null; int aValue = _directory.GetInt( CanonMakernoteDirectory.TAG_CANON_STATE1_EXPOSURE_MODE); switch (aValue) { case 0 : return BUNDLE["EASY_SHOOTING"]; case 1 : return BUNDLE["PROGRAM"]; case 2 : return BUNDLE["TV_PRIORITY"]; case 3 : return BUNDLE["AV_PRIORITY"]; case 4 : return BUNDLE["MANUAL"]; case 5 : return BUNDLE["A_DEP"]; default : return BUNDLE["UNKNOWN", aValue.ToString()]; } } /// /// Returns Af Point Selected description. /// /// the Af Point Selected description private string GetAfPointSelectedDescription() { if (!_directory .ContainsTag( CanonMakernoteDirectory.TAG_CANON_STATE1_AF_POINT_SELECTED)) return null; int aValue = _directory.GetInt( CanonMakernoteDirectory.TAG_CANON_STATE1_AF_POINT_SELECTED); switch (aValue) { case 0x3000 : return BUNDLE["NONE_MF"]; case 0x3001 : return BUNDLE["AUTO_SELECTED"]; case 0x3002 : return BUNDLE["RIGHT"]; case 0x3003 : return BUNDLE["CENTER"]; case 0x3004 : return BUNDLE["LEFT"]; default : return BUNDLE["UNKNOWN", aValue.ToString()]; } } /// /// Returns Metering Mode description. /// /// the Metering Mode description private string GetMeteringModeDescription() { if (!_directory .ContainsTag( CanonMakernoteDirectory.TAG_CANON_STATE1_METERING_MODE)) return null; int aValue = _directory.GetInt( CanonMakernoteDirectory.TAG_CANON_STATE1_METERING_MODE); switch (aValue) { case 3 : return BUNDLE["EVALUATIVE"]; case 4 : return BUNDLE["PARTIAL"]; case 5 : return BUNDLE["CENTRE_WEIGHTED"]; default : return BUNDLE["UNKNOWN", aValue.ToString()]; } } /// /// Returns ISO description. /// /// the ISO description private string GetIsoDescription() { if (!_directory .ContainsTag(CanonMakernoteDirectory.TAG_CANON_STATE1_ISO)) return null; int aValue = _directory.GetInt(CanonMakernoteDirectory.TAG_CANON_STATE1_ISO); switch (aValue) { case 0 : return BUNDLE["ISO_NOT_SPECIFIED"]; case 15 : return BUNDLE["AUTO"]; case 16 : return BUNDLE["ISO_50"]; case 17 : return BUNDLE["ISO_100"]; case 18 : return BUNDLE["ISO_200"]; case 19 : return BUNDLE["ISO_400"]; default : return BUNDLE["UNKNOWN", aValue.ToString()]; } } /// /// Returns Sharpness description. /// /// the Sharpness description private string GetSharpnessDescription() { if (!_directory .ContainsTag(CanonMakernoteDirectory.TAG_CANON_STATE1_SHARPNESS)) return null; int aValue = _directory.GetInt( CanonMakernoteDirectory.TAG_CANON_STATE1_SHARPNESS); switch (aValue) { case 0xFFFF : return BUNDLE["LOW"]; case 0x000 : return BUNDLE["NORMAL"]; case 0x001 : return BUNDLE["HIGH"]; default : return BUNDLE["UNKNOWN", aValue.ToString()]; } } /// /// Returns Saturation description. /// /// the Saturation description private string GetSaturationDescription() { if (!_directory .ContainsTag(CanonMakernoteDirectory.TAG_CANON_STATE1_SATURATION)) return null; int aValue = _directory.GetInt( CanonMakernoteDirectory.TAG_CANON_STATE1_SATURATION); switch (aValue) { case 0xFFFF : return BUNDLE["LOW"]; case 0x000 : return BUNDLE["NORMAL"]; case 0x001 : return BUNDLE["HIGH"]; default : return BUNDLE["UNKNOWN", aValue.ToString()]; } } /// /// Returns Contrast description. /// /// the Contrast description private string GetContrastDescription() { if (!_directory .ContainsTag(CanonMakernoteDirectory.TAG_CANON_STATE1_CONTRAST)) return null; int aValue = _directory.GetInt( CanonMakernoteDirectory.TAG_CANON_STATE1_CONTRAST); switch (aValue) { case 0xFFFF : return BUNDLE["LOW"]; case 0x000 : return BUNDLE["NORMAL"]; case 0x001 : return BUNDLE["HIGH"]; default : return BUNDLE["UNKNOWN", aValue.ToString()]; } } /// /// Returns Easy Shooting Mode description. /// /// the Easy Shooting Mode description private string GetEasyShootingModeDescription() { if (!_directory .ContainsTag( CanonMakernoteDirectory.TAG_CANON_STATE1_EASY_SHOOTING_MODE)) return null; int aValue = _directory.GetInt( CanonMakernoteDirectory.TAG_CANON_STATE1_EASY_SHOOTING_MODE); switch (aValue) { case 0 : return BUNDLE["FULL_AUTO"]; case 1 : return BUNDLE["MANUAL"]; case 2 : return BUNDLE["LANDSCAPE"]; case 3 : return BUNDLE["FAST_SHUTTER"]; case 4 : return BUNDLE["SLOW_SHUTTER"]; case 5 : return BUNDLE["NIGHT"]; case 6 : return BUNDLE["B_W"]; case 7 : return BUNDLE["SEPIA"]; case 8 : return BUNDLE["PORTRAIT"]; case 9 : return BUNDLE["SPORTS"]; case 10 : return BUNDLE["MACRO_CLOSEUP"]; case 11 : return BUNDLE["PAN_FOCUS"]; default : return BUNDLE["UNKNOWN", aValue.ToString()]; } } /// /// Returns Image Size description. /// /// the Image Size description private string GetImageSizeDescription() { if (!_directory .ContainsTag(CanonMakernoteDirectory.TAG_CANON_STATE1_IMAGE_SIZE)) return null; int aValue = _directory.GetInt( CanonMakernoteDirectory.TAG_CANON_STATE1_IMAGE_SIZE); switch (aValue) { case 0 : return BUNDLE["LARGE"]; case 1 : return BUNDLE["MEDIUM"]; case 2 : return BUNDLE["SMALL"]; default : return BUNDLE["UNKNOWN", aValue.ToString()]; } } /// /// Returns Focus Mode 1 description. /// /// the Focus Mode 1 description private string GetFocusMode1Description() { if (!_directory .ContainsTag(CanonMakernoteDirectory.TAG_CANON_STATE1_FOCUS_MODE_1)) return null; int aValue = _directory.GetInt( CanonMakernoteDirectory.TAG_CANON_STATE1_FOCUS_MODE_1); switch (aValue) { case 0 : return BUNDLE["ONE_SHOT"]; case 1 : return BUNDLE["AI_SERVO"]; case 2 : return BUNDLE["AI_FOCUS"]; case 3 : return BUNDLE["MF"]; case 4 : // TODO should check field 32 here (FOCUS_MODE_2) return BUNDLE["SINGLE"]; case 5 : return BUNDLE["CONTINUOUS"]; case 6 : return BUNDLE["MF"]; default : return BUNDLE["UNKNOWN", aValue.ToString()]; } } /// /// Returns Continuous Drive Mode description. /// /// the Continuous Drive Mode description private string GetContinuousDriveModeDescription() { if (!_directory .ContainsTag( CanonMakernoteDirectory .TAG_CANON_STATE1_CONTINUOUS_DRIVE_MODE)) return null; int aValue = _directory.GetInt( CanonMakernoteDirectory.TAG_CANON_STATE1_CONTINUOUS_DRIVE_MODE); switch (aValue) { case 0 : if (_directory .GetInt( CanonMakernoteDirectory .TAG_CANON_STATE1_SELF_TIMER_DELAY) == 0) { return BUNDLE["SINGLE_SHOT"]; } else { return BUNDLE["SINGLE_SHOT_WITH_SELF_TIMER"]; } case 1 : return BUNDLE["CONTINUOUS"]; default : return BUNDLE["UNKNOWN", aValue.ToString()]; } } /// /// Returns Flash Mode description. /// /// the Flash Mode description private string GetFlashModeDescription() { if (!_directory .ContainsTag(CanonMakernoteDirectory.TAG_CANON_STATE1_FLASH_MODE)) return null; int aValue = _directory.GetInt( CanonMakernoteDirectory.TAG_CANON_STATE1_FLASH_MODE); switch (aValue) { case 0 : return BUNDLE["NO_FLASH_FIRED"]; case 1 : return BUNDLE["AUTO"]; case 2 : return BUNDLE["ON"]; case 3 : return BUNDLE["RED_YEY_REDUCTION"]; case 4 : return BUNDLE["SLOW_SYNCHRO"]; case 5 : return BUNDLE["AUTO_AND_RED_YEY_REDUCTION"]; case 6 : return BUNDLE["ON_AND_RED_YEY_REDUCTION"]; case 16 : // note: this aValue not set on Canon D30 return BUNDLE["EXTERNAL_FLASH"]; default : return BUNDLE["UNKNOWN", aValue.ToString()]; } } /// /// Returns Self Timer Delay description. /// /// the Self Timer Delay description private string GetSelfTimerDelayDescription() { if (!_directory .ContainsTag( CanonMakernoteDirectory.TAG_CANON_STATE1_SELF_TIMER_DELAY)) return null; int aValue = _directory.GetInt( CanonMakernoteDirectory.TAG_CANON_STATE1_SELF_TIMER_DELAY); if (aValue == 0) { return BUNDLE["SELF_TIMER_DELAY_NOT_USED"]; } else { // TODO find an image that tests this calculation return BUNDLE["SELF_TIMER_DELAY", ((double) aValue * 0.1d).ToString()]; } } /// /// Returns Macro Mode description. /// /// the Macro Mode description private string GetMacroModeDescription() { if (!_directory .ContainsTag(CanonMakernoteDirectory.TAG_CANON_STATE1_MACRO_MODE)) return null; int aValue = _directory.GetInt( CanonMakernoteDirectory.TAG_CANON_STATE1_MACRO_MODE); switch (aValue) { case 1 : return BUNDLE["MACRO"]; case 2 : return BUNDLE["NORMAL"]; default : return BUNDLE["UNKNOWN", aValue.ToString()]; } } } }