using System; using System.Collections; using com.drew.metadata; using com.utils; using System.Globalization; /// /// 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 { /// /// This class represents CANON marker note. /// public class CanonMakernoteDirectory : Directory { // CANON cameras have some funny bespoke fields that need further processing... public const int TAG_CANON_CAMERA_STATE_1 = 0x0001; public const int TAG_CANON_CAMERA_STATE_2 = 0x0004; public const int TAG_CANON_IMAGE_TYPE = 0x0006; public const int TAG_CANON_FIRMWARE_VERSION = 0x0007; public const int TAG_CANON_IMAGE_NUMBER = 0x0008; public const int TAG_CANON_OWNER_NAME = 0x0009; public const int TAG_CANON_SERIAL_NUMBER = 0x000C; public const int TAG_CANON_UNKNOWN_1 = 0x000D; public const int TAG_CANON_CUSTOM_FUNCTIONS = 0x000F; // These 'sub'-tag values have been created for consistency -- they don't exist within the exif segment public const int TAG_CANON_STATE1_MACRO_MODE = 0xC101; public const int TAG_CANON_STATE1_SELF_TIMER_DELAY = 0xC102; public const int TAG_CANON_STATE1_UNKNOWN_1 = 0xC103; public const int TAG_CANON_STATE1_FLASH_MODE = 0xC104; public const int TAG_CANON_STATE1_CONTINUOUS_DRIVE_MODE = 0xC105; public const int TAG_CANON_STATE1_UNKNOWN_2 = 0xC106; public const int TAG_CANON_STATE1_FOCUS_MODE_1 = 0xC107; public const int TAG_CANON_STATE1_UNKNOWN_3 = 0xC108; public const int TAG_CANON_STATE1_UNKNOWN_4 = 0xC109; public const int TAG_CANON_STATE1_IMAGE_SIZE = 0xC10A; public const int TAG_CANON_STATE1_EASY_SHOOTING_MODE = 0xC10B; public const int TAG_CANON_STATE1_UNKNOWN_5 = 0xC10C; public const int TAG_CANON_STATE1_CONTRAST = 0xC10D; public const int TAG_CANON_STATE1_SATURATION = 0xC10E; public const int TAG_CANON_STATE1_SHARPNESS = 0xC10F; public const int TAG_CANON_STATE1_ISO = 0xC110; public const int TAG_CANON_STATE1_METERING_MODE = 0xC111; public const int TAG_CANON_STATE1_UNKNOWN_6 = 0xC112; public const int TAG_CANON_STATE1_AF_POINT_SELECTED = 0xC113; public const int TAG_CANON_STATE1_EXPOSURE_MODE = 0xC114; public const int TAG_CANON_STATE1_UNKNOWN_7 = 0xC115; public const int TAG_CANON_STATE1_UNKNOWN_8 = 0xC116; public const int TAG_CANON_STATE1_LONG_FOCAL_LENGTH = 0xC117; public const int TAG_CANON_STATE1_SHORT_FOCAL_LENGTH = 0xC118; public const int TAG_CANON_STATE1_FOCAL_UNITS_PER_MM = 0xC119; public const int TAG_CANON_STATE1_UNKNOWN_9 = 0xC11A; public const int TAG_CANON_STATE1_UNKNOWN_10 = 0xC11B; public const int TAG_CANON_STATE1_UNKNOWN_11 = 0xC11C; public const int TAG_CANON_STATE1_FLASH_DETAILS = 0xC11D; public const int TAG_CANON_STATE1_UNKNOWN_12 = 0xC11E; public const int TAG_CANON_STATE1_UNKNOWN_13 = 0xC11F; public const int TAG_CANON_STATE1_FOCUS_MODE_2 = 0xC120; public const int TAG_CANON_STATE2_WHITE_BALANCE = 0xC207; public const int TAG_CANON_STATE2_SEQUENCE_NUMBER = 0xC209; public const int TAG_CANON_STATE2_AF_POINT_USED = 0xC20E; public const int TAG_CANON_STATE2_FLASH_BIAS = 0xC20F; public const int TAG_CANON_STATE2_SUBJECT_DISTANCE = 0xC213; protected static readonly ResourceBundle BUNDLE = new ResourceBundle("CanonMarkernote"); // 9 A B C D E F 10 11 12 13 // 9 10 11 12 13 14 15 16 17 18 19 protected static readonly IDictionary tagNameMap = CanonMakernoteDirectory.InitTagMap(); /// /// Initialize the tag map. /// /// the tag map private static IDictionary InitTagMap() { // Create a Hashtable using a case-insensitive code provider and a case-insensitive comparer, // based on the Spanish culture (es-AR), where "I" is not the uppercase version of "i". CultureInfo myCul = new CultureInfo( "es-AR" ); IDictionary resu = new Hashtable( new CaseInsensitiveHashCodeProvider( myCul ), new CaseInsensitiveComparer( myCul )); //IDictionary resu = new Hashtable(); resu.Add(TAG_CANON_FIRMWARE_VERSION, BUNDLE["TAG_CANON_FIRMWARE_VERSION"]); resu.Add(TAG_CANON_IMAGE_NUMBER, BUNDLE["TAG_CANON_IMAGE_NUMBER"]); resu.Add(TAG_CANON_IMAGE_TYPE, BUNDLE["TAG_CANON_IMAGE_TYPE"]); resu.Add(TAG_CANON_OWNER_NAME, BUNDLE["TAG_CANON_OWNER_NAME"]); resu.Add(TAG_CANON_UNKNOWN_1, BUNDLE["TAG_CANON_UNKNOWN_1"]); resu.Add(TAG_CANON_CUSTOM_FUNCTIONS, BUNDLE["TAG_CANON_CUSTOM_FUNCTIONS"]); resu.Add(TAG_CANON_SERIAL_NUMBER, BUNDLE["TAG_CANON_SERIAL_NUMBER"]); resu.Add(TAG_CANON_STATE1_AF_POINT_SELECTED, BUNDLE["TAG_CANON_STATE1_AF_POINT_SELECTED"]); resu.Add(TAG_CANON_STATE1_CONTINUOUS_DRIVE_MODE, BUNDLE["TAG_CANON_STATE1_CONTINUOUS_DRIVE_MODE"]); resu.Add(TAG_CANON_STATE1_CONTRAST, BUNDLE["TAG_CANON_STATE1_CONTRAST"]); resu.Add(TAG_CANON_STATE1_EASY_SHOOTING_MODE, BUNDLE["TAG_CANON_STATE1_EASY_SHOOTING_MODE"]); resu.Add(TAG_CANON_STATE1_EXPOSURE_MODE, BUNDLE["TAG_CANON_STATE1_EXPOSURE_MODE"]); resu.Add(TAG_CANON_STATE1_FLASH_DETAILS, BUNDLE["TAG_CANON_STATE1_FLASH_DETAILS"]); resu.Add(TAG_CANON_STATE1_FLASH_MODE, BUNDLE["TAG_CANON_STATE1_FLASH_MODE"]); resu.Add(TAG_CANON_STATE1_FOCAL_UNITS_PER_MM, BUNDLE["TAG_CANON_STATE1_FOCAL_UNITS_PER_MM"]); resu.Add(TAG_CANON_STATE1_FOCUS_MODE_1, BUNDLE["TAG_CANON_STATE1_FOCUS_MODE_1"]); resu.Add(TAG_CANON_STATE1_FOCUS_MODE_2, BUNDLE["TAG_CANON_STATE1_FOCUS_MODE_2"]); resu.Add(TAG_CANON_STATE1_IMAGE_SIZE, BUNDLE["TAG_CANON_STATE1_IMAGE_SIZE"]); resu.Add(TAG_CANON_STATE1_ISO, BUNDLE["TAG_CANON_STATE1_ISO"]); resu.Add(TAG_CANON_STATE1_LONG_FOCAL_LENGTH, BUNDLE["TAG_CANON_STATE1_LONG_FOCAL_LENGTH"]); resu.Add(TAG_CANON_STATE1_MACRO_MODE, BUNDLE["TAG_CANON_STATE1_MACRO_MODE"]); resu.Add(TAG_CANON_STATE1_METERING_MODE, BUNDLE["TAG_CANON_STATE1_METERING_MODE"]); resu.Add(TAG_CANON_STATE1_SATURATION, BUNDLE["TAG_CANON_STATE1_SATURATION"]); resu.Add(TAG_CANON_STATE1_SELF_TIMER_DELAY, BUNDLE["TAG_CANON_STATE1_SELF_TIMER_DELAY"]); resu.Add(TAG_CANON_STATE1_SHARPNESS, BUNDLE["TAG_CANON_STATE1_SHARPNESS"]); resu.Add(TAG_CANON_STATE1_SHORT_FOCAL_LENGTH, BUNDLE["TAG_CANON_STATE1_SHORT_FOCAL_LENGTH"]); resu.Add(TAG_CANON_STATE1_UNKNOWN_1, BUNDLE["TAG_CANON_STATE1_UNKNOWN_1"]); resu.Add(TAG_CANON_STATE1_UNKNOWN_2, BUNDLE["TAG_CANON_STATE1_UNKNOWN_2"]); resu.Add(TAG_CANON_STATE1_UNKNOWN_3, BUNDLE["TAG_CANON_STATE1_UNKNOWN_3"]); resu.Add(TAG_CANON_STATE1_UNKNOWN_4, BUNDLE["TAG_CANON_STATE1_UNKNOWN_4"]); resu.Add(TAG_CANON_STATE1_UNKNOWN_5, BUNDLE["TAG_CANON_STATE1_UNKNOWN_5"]); resu.Add(TAG_CANON_STATE1_UNKNOWN_6, BUNDLE["TAG_CANON_STATE1_UNKNOWN_6"]); resu.Add(TAG_CANON_STATE1_UNKNOWN_7, BUNDLE["TAG_CANON_STATE1_UNKNOWN_7"]); resu.Add(TAG_CANON_STATE1_UNKNOWN_8, BUNDLE["TAG_CANON_STATE1_UNKNOWN_8"]); resu.Add(TAG_CANON_STATE1_UNKNOWN_9, BUNDLE["TAG_CANON_STATE1_UNKNOWN_9"]); resu.Add(TAG_CANON_STATE1_UNKNOWN_10, BUNDLE["TAG_CANON_STATE1_UNKNOWN_10"]); resu.Add(TAG_CANON_STATE1_UNKNOWN_11, BUNDLE["TAG_CANON_STATE1_UNKNOWN_11"]); resu.Add(TAG_CANON_STATE1_UNKNOWN_12, BUNDLE["TAG_CANON_STATE1_UNKNOWN_12"]); resu.Add(TAG_CANON_STATE1_UNKNOWN_13, BUNDLE["TAG_CANON_STATE1_UNKNOWN_13"]); resu.Add(TAG_CANON_STATE2_WHITE_BALANCE, BUNDLE["TAG_CANON_STATE2_WHITE_BALANCE"]); resu.Add(TAG_CANON_STATE2_SEQUENCE_NUMBER, BUNDLE["TAG_CANON_STATE2_SEQUENCE_NUMBER"]); resu.Add(TAG_CANON_STATE2_AF_POINT_USED, BUNDLE["TAG_CANON_STATE2_AF_POINT_USED"]); resu.Add(TAG_CANON_STATE2_FLASH_BIAS, BUNDLE["TAG_CANON_STATE2_FLASH_BIAS"]); resu.Add(TAG_CANON_STATE2_SUBJECT_DISTANCE, BUNDLE["TAG_CANON_STATE2_SUBJECT_DISTANCE"]); return resu; } /// /// Constructor of the object. /// public CanonMakernoteDirectory() : base() { this.SetDescriptor(new CanonMakernoteDescriptor(this)); } /// /// Provides the name of the directory, for display purposes. E.g. Exif /// /// the name of the directory public override string GetName() { return BUNDLE["MARKER_NOTE_NAME"]; } /// /// Provides the map of tag names, hashed by tag type identifier. /// /// the map of tag names protected override IDictionary GetTagNameMap() { return tagNameMap; } /// /// We need special handling for selected tags. /// /// the tag type /// what to set public override void SetIntArray(int tagType, int[] ints) { if (tagType == TAG_CANON_CAMERA_STATE_1) { // this single tag has multiple values within int subTagTypeBase = 0xC100; // we intentionally skip the first array member for (int i = 1; i < ints.Length; i++) { SetObject(subTagTypeBase + i, ints[i]); } } else if (tagType == TAG_CANON_CAMERA_STATE_2) { // this single tag has multiple values within int subTagTypeBase = 0xC200; // we intentionally skip the first array member for (int i = 1; i < ints.Length; i++) { SetObject(subTagTypeBase + i, ints[i]); } } else { // no special handling... base.SetIntArray(tagType, ints); } } } }