/* * Copyright (c) 2001-2003, Eric M. Johnston * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Eric M. Johnston. * 4. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: canon.c,v 1.38 2003/08/08 20:40:55 ejohnst Exp $ */ /* * Exif tag definitions for Canon maker notes. * Developed from http://www.burren.cx/david/canon.html. * EOS 1D and 1Ds contributions from Stan Jirman . * EOS 10D contributions from Jason Montojo . * */ #include #include #include #include "makers.h" /* Macro mode. */ static struct descrip canon_macro[] = { { 1, "Macro" }, { 2, "Normal" }, { -1, "Unknown" }, }; /* Focus type. */ static struct descrip canon_focustype[] = { { 0, "Manual" }, { 1, "Auto" }, { 2, "Auto" }, { 3, "Close-Up (Macro Mode)" }, { 7, "Infinity Mode" }, { 8, "Locked (Pan Mode)" }, { -1, "Unknown" }, }; /* Quality. */ static struct descrip canon_quality[] = { { 2, "Normal" }, { 3, "Fine" }, { 5, "Superfine" }, { -1, "Unknown" }, }; /* Flash mode. */ static struct descrip canon_flash[] = { { 0, "Off" }, { 1, "Auto" }, { 2, "On" }, { 3, "Red-Eye Reduction" }, { 4, "Slow-Synchro" }, { 5, "Red-Eye Reduction (Auto)" }, { 6, "Red-Eye Reduction (On)" }, { 16, "External Flash" }, { -1, "Unknown" }, }; /* Flash bias. Is this ever something other than 0? */ static struct descrip canon_fbias[] = { { 0x0000, "0 EV" }, { 0x000c, "0.33 EV" }, { 0x0010, "0.50 EV" }, { 0x0014, "0.67 EV" }, { 0x0020, "1 EV" }, { 0x002c, "1.33 EV" }, { 0x0030, "1.50 EV" }, { 0x0034, "1.67 EV" }, { 0x0040, "2 EV" }, { 0xffc0, "-2 EV" }, { 0xffcc, "-1.67 EV" }, { 0xffd0, "-1.50 EV" }, { 0xffd4, "-1.33 EV" }, { 0xffe0, "-1 EV" }, { 0xffec, "-0.67 EV" }, { 0xfff0, "-0.50 EV" }, { 0xfff4, "-0.33 EV" }, { -1, "Unknown" }, }; /* Drive mode. */ static struct descrip canon_drive[] = { { 0, "Single" }, /* "Timed" when field 2 is > 0. */ { 1, "Continuous" }, { -1, "Unknown" }, }; /* Focus mode. */ static struct descrip canon_focus1[] = { { 0, "One-Shot" }, { 1, "AI Servo" }, { 2, "AI Focus" }, { 3, "Manual" }, { 4, "Single" }, { 5, "Continuous" }, { 6, "Manual" }, { -1, "Unknown" }, }; /* Image size. */ static struct descrip canon_imagesz[] = { { 0, "Large" }, { 1, "Medium" }, { 2, "Small" }, { -1, "Unknown" }, }; /* Shooting mode. */ static struct descrip canon_shoot[] = { { 0, "Full Auto" }, { 1, "Manual" }, { 2, "Landscape" }, { 3, "Fast Shutter" }, { 4, "Slow Shutter" }, { 5, "Night" }, { 6, "Black & White" }, { 7, "Sepia" }, { 8, "Portrait" }, { 9, "Sports" }, { 10, "Macro/Close-Up" }, { 11, "Pan Focus" }, { -1, "Unknown" }, }; /* Digital zoom. */ static struct descrip canon_dzoom[] = { { 0, "None" }, { 1, "x2" }, { 2, "x4" }, { -1, "Unknown" }, }; /* Contrast, saturation, & sharpness. */ static struct descrip canon_range[] = { { 0, "Normal" }, { 1, "High" }, { 0xffff, "Low" }, { -1, "Unknown" }, }; /* ISO speed rating. */ static struct descrip canon_iso[] = { { 15, "Auto" }, { 16, "50" }, { 17, "100" }, { 18, "200" }, { 19, "400" }, { -1, "Unknown" }, }; /* Metering mode. */ static struct descrip canon_meter[] = { { 3, "Evaluative" }, { 4, "Partial" }, { 5, "Center-Weighted" }, { -1, "Unknown" }, }; /* Exposure mode. */ static struct descrip canon_expmode[] = { { 0, "Easy Shooting" }, { 1, "Program" }, { 2, "Tv-Priority" }, { 3, "Av-Priority" }, { 4, "Manual" }, { 5, "A-DEP" }, { 6, "DEP" }, { -1, "Unknown" }, }; /* White balance. */ static struct descrip canon_whitebal[] = { { 0, "Auto" }, { 1, "Daylight" }, { 2, "Cloudy" }, { 3, "Tungsten" }, { 4, "Fluorescent" }, { 5, "Flash" }, { 6, "Custom" }, { 7, "Black & White" }, { 8, "Shade" }, { 9, "Manual Temperature" }, { -1, "Unknown" }, }; /* Maker note IFD tags. */ static struct exiftag canon_tags[] = { { 0x0001, TIFF_SHORT, 0, ED_UNK, "Canon1Tag", "Canon Tag1 Offset", NULL }, { 0x0004, TIFF_SHORT, 0, ED_UNK, "Canon4Tag", "Canon Tag4 Offset", NULL }, { 0x0006, TIFF_ASCII, 32, ED_VRB, "ImageType", "Image Type", NULL }, { 0x0007, TIFF_ASCII, 24, ED_CAM, "FirmwareVer", "Firmware Version", NULL }, { 0x0008, TIFF_LONG, 1, ED_IMG, "ImgNum", "Image Number", NULL }, { 0x0009, TIFF_ASCII, 32, ED_CAM, "OwnerName", "Owner Name", NULL }, { 0x000c, TIFF_LONG, 1, ED_CAM, "Serial", "Serial Number", NULL }, { 0x000f, TIFF_SHORT, 0, ED_UNK, "CustomFunc", "Custom Function", NULL }, { 0x0090, TIFF_SHORT, 0, ED_UNK, "CustomFunc", "Custom Function", NULL }, { 0x00a0, TIFF_SHORT, 0, ED_UNK, "CanonA0Tag", "Canon TagA0 Offset", NULL }, { 0xffff, TIFF_UNKN, 0, ED_UNK, "CanonUnknown", "Canon Unknown", NULL }, }; /* Fields under tag 0x0001. */ static struct exiftag canon_tags01[] = { { 0, TIFF_SHORT, 0, ED_VRB, "Canon1Len", "Canon Tag1 Length", NULL }, { 1, TIFF_SHORT, 0, ED_IMG, "CanonMacroMode", "Macro Mode", canon_macro }, { 2, TIFF_SHORT, 0, ED_VRB, "CanonTimerLen", "Self-Timer Length", NULL }, { 3, TIFF_SHORT, 0, ED_IMG, "CanonQuality", "Compression Setting", canon_quality }, { 4, TIFF_SHORT, 0, ED_IMG, "CanonFlashMode", "Flash Mode", canon_flash }, { 5, TIFF_SHORT, 0, ED_IMG, "CanonDriveMode", "Drive Mode", canon_drive }, { 7, TIFF_SHORT, 0, ED_IMG, "CanonFocusMode", "Focus Mode", canon_focus1 }, { 10, TIFF_SHORT, 0, ED_IMG, "CanonImageSize", "Image Size", canon_imagesz }, { 11, TIFF_SHORT, 0, ED_IMG, "CanonShootMode", "Shooting Mode", canon_shoot }, { 12, TIFF_SHORT, 0, ED_VRB, "CanonDigiZoom", "Digital Zoom", NULL }, { 13, TIFF_SHORT, 0, ED_IMG, "CanonContrast", "Contrast", canon_range }, { 14, TIFF_SHORT, 0, ED_IMG, "CanonSaturate", "Saturation", canon_range }, { 15, TIFF_SHORT, 0, ED_IMG, "CanonSharpness", "Sharpness", canon_range }, { 16, TIFF_SHORT, 0, ED_IMG, "CanonISO", "ISO Speed Rating", canon_iso }, { 17, TIFF_SHORT, 0, ED_IMG, "CanonMeterMode", "Metering Mode", canon_meter }, { 18, TIFF_SHORT, 0, ED_IMG, "CanonFocusType", "Focus Type", canon_focustype }, { 19, TIFF_SHORT, 0, ED_UNK, "CanonAFPoint", "Autofocus Point", NULL }, { 20, TIFF_SHORT, 0, ED_IMG, "CanonExpMode", "Exposure Mode", canon_expmode }, { 23, TIFF_SHORT, 0, ED_UNK, "CanonMaxFocal", "Max Focal Length", NULL }, { 24, TIFF_SHORT, 0, ED_UNK, "CanonMinFocal", "Min Focal Length", NULL }, { 25, TIFF_SHORT, 0, ED_UNK, "CanonFocalUnits", "Focal Units/mm", NULL }, { 28, TIFF_SHORT, 0, ED_UNK, "CanonFlashAct", "Flash Activity", NULL }, { 29, TIFF_SHORT, 0, ED_UNK, "CanonFlashDet", "Flash Details", NULL }, { 36, TIFF_SHORT, 0, ED_VRB, "CanonDZoomRes", "Zoomed Resolution", NULL }, { 37, TIFF_SHORT, 0, ED_VRB, "CanonBZoomRes", "Base Zoom Resolution", NULL }, { 0xffff, TIFF_SHORT, 0, ED_UNK, "Canon01Unknown", "Canon Tag1 Unknown", NULL }, }; /* Fields under tag 0x0004. */ static struct exiftag canon_tags04[] = { { 0, TIFF_SHORT, 0, ED_VRB, "Canon4Len", "Canon Tag4 Length", NULL }, { 7, TIFF_SHORT, 0, ED_IMG, "CanonWhiteB", "White Balance", canon_whitebal }, { 9, TIFF_SHORT, 0, ED_IMG, "CanonSequence", "Sequence Number", NULL }, { 14, TIFF_SHORT, 0, ED_UNK, "CanonAFPoint2", "Autofocus Point", NULL }, { 15, TIFF_SHORT, 0, ED_VRB, "CanonFlashBias", "Flash Bias", canon_fbias }, { 19, TIFF_SHORT, 0, ED_UNK, "CanonSubjDst", "Subject Distance", NULL }, { 0xffff, TIFF_SHORT, 0, ED_UNK, "Canon04Unknown", "Canon Tag4 Unknown", NULL }, }; /* Fields under tag 0x00a0 (EOS 1D, 1Ds). */ static struct exiftag canon_tagsA0[] = { { 9, TIFF_SHORT, 0, ED_IMG, "CanonColorTemp", "Color Temperature", NULL }, { 10, TIFF_SHORT, 0, ED_IMG, "CanonColorMatrix", "Color Matrix", NULL }, { 0xffff, TIFF_SHORT, 0, ED_UNK, "CanonA0Unknown", "Canon TagA0 Unknown", NULL }, }; /* Placeholder for unknown fields. */ static struct exiftag canon_tagsunk[] = { { 0xffff, TIFF_SHORT, 0, ED_UNK, "CanonUnknown", "Canon Unknown", NULL }, }; /* Value descriptions for custom functions. */ static struct descrip ccstm_offon[] = { { 0, "Off" }, { 1, "On" }, { -1, "Unknown" }, }; static struct descrip ccstm_shutter[] = { { 0, "AF/AE Lock" }, { 1, "AE Lock/AF" }, { 2, "AF/AF Lock" }, { 3, "AE+Release/AE+AF" }, { -1, "Unknown" }, }; static struct descrip ccstm_disen[] = { { 0, "Disabled" }, { 1, "Enabled" }, { -1, "Unknown" }, }; static struct descrip ccstm_explvl[] = { { 0, "1/2 Stop" }, { 1, "1/3 Stop" }, { -1, "Unknown" }, }; static struct descrip ccstm_autooff[] = { { 0, "Auto" }, { 1, "Off" }, { -1, "Unknown" }, }; static struct descrip ccstm_shutspd[] = { { 0, "Auto" }, { 1, "1/200 (Fixed)" }, { -1, "Unknown" }, }; static struct descrip ccstm_aebseq[] = { { 0, "0,-,+/Enabled" }, { 1, "0,-,+/Disabled" }, { 2, "-,0,+/Enabled" }, { 3, "-,0,+/Disabled" }, { -1, "Unknown" }, }; static struct descrip ccstm_shutsync[] = { { 0, "1st-Curtain Sync" }, { 1, "2nd-Curtain Sync" }, { -1, "Unknown" }, }; static struct descrip ccstm_lensaf[] = { { 0, "AF Stop" }, { 1, "Operate AF" }, { 2, "Lock AE & Start Timer" }, { -1, "Unknown" }, }; static struct descrip ccstm_endis[] = { { 0, "Enabled" }, { 1, "Disabled" }, { -1, "Unknown" }, }; static struct descrip ccstm_menubut[] = { { 0, "Top" }, { 1, "Previous (Volatile)" }, { 2, "Previous" }, { -1, "Unknown" }, }; static struct descrip ccstm_setbut[] = { { 0, "Not Assigned" }, { 1, "Change Quality" }, { 2, "Change ISO Speed" }, { 3, "Select Parameters" }, { -1, "Unknown" }, }; static struct descrip ccstm_yesno[] = { { 0, "Yes" }, { 1, "No" }, { -1, "Unknown" }, }; static struct descrip ccstm_noyes[] = { { 0, "No" }, { 1, "Yes" }, { -1, "Unknown" }, }; static struct descrip ccstm_onoff[] = { { 0, "On" }, { 1, "Off" }, { -1, "Unknown" }, }; static struct descrip ccstm_afsel[] = { { 0, "H=AF+Main/V=AF+Command" }, { 1, "H=Comp+Main/V=Comp+Command" }, { 2, "H=Command Only/V=Assist+Main" }, { 3, "H=FEL+Main/V=FEL+Command" }, { -1, "Unknown" }, }; static struct descrip ccstm_afill[] = { { 0, "On" }, { 1, "Off" }, { 2, "On Without Dimming" }, { 3, "Brighter" }, { -1, "Unknown" }, }; static struct descrip ccstm_lcdpanels[] = { { 0, "Remain. Shots/File No." }, { 1, "ISO/Remain. Shots" }, { 2, "ISO/File No." }, { 3, "Shots In Folder/Remain. Shots" }, { -1, "Unknown" }, }; static struct descrip ccstm_usmmf[] = { { 0, "Turns On After One-Shot AF" }, { 1, "Turns Off After One-Shot AF" }, { 2, "Always Turned Off" }, { -1, "Unknown" }, }; static struct descrip ccstm_explvlinc[] = { { 0, "1/3-Stop Set, 1/3-Stop Comp" }, { 1, "1-Stop Set, 1/3-Stop Comp" }, { 2, "1/2-Stop Set, 1/2-Stop Comp" }, { -1, "Unknown" }, }; static struct descrip ccstm_tvavform[] = { { 0, "Tv=Main/Av=Control" }, { 1, "Tv=Control/Av=Main" }, { 2, "Tv=Main/Av=Main w/o Lens" }, { 3, "Tv=Control/Av=Main w/o Lens" }, { -1, "Unknown" }, }; static struct descrip ccstm_shutterael[] = { { 0, "AF/AE Lock Stop" }, { 1, "AE Lock/AF" }, { 2, "AF/AF Lock, No AE Lock" }, { 3, "AE/AF, No AE Lock" }, { -1, "Unknown" }, }; static struct descrip ccstm_afspot[] = { { 0, "45/Center AF Point" }, { 1, "11/Active AF Point" }, { 2, "11/Center AF Point" }, { 3, "9/Active AF Point" }, { -1, "Unknown" }, }; static struct descrip ccstm_afact[] = { { 0, "Single AF Point" }, { 1, "Expanded (TTL. of 7 AF Points)" }, { 2, "Automatic Expanded (Max. 13)" }, { -1, "Unknown" }, }; static struct descrip ccstm_regaf[] = { { 0, "Assist + AF" }, { 1, "Assist" }, { 2, "Only While Pressing Assist" }, { -1, "Unknown" }, }; static struct descrip ccstm_lensaf1[] = { { 0, "AF Stop" }, { 1, "AF Start" }, { 2, "AE Lock While Metering" }, { 3, "AF Point: M->Auto/Auto->Ctr" }, { 4, "AF Mode: ONESHOT<->SERVO" }, { 5, "IS Start" }, { -1, "Unknown" }, }; static struct descrip ccstm_aisens[] = { { 0, "Standard" }, { 1, "Slow" }, { 2, "Moderately Slow" }, { 3, "Moderately Fast" }, { 4, "Fast" }, { -1, "Unknown" }, }; static struct descrip ccstm_fscr[] = { { 0, "Ec-N, R" }, { 1, "Ec-A,B,C,CII,CIII,D,H,I,L" }, { -1, "Unknown" }, }; static struct descrip ccstm_10dsetbut[] = { { 0, "Not Assigned" }, { 1, "Change Quality" }, { 2, "Change Parameters" }, { 3, "Menu Display" }, { 4, "Image Replay" }, { -1, "Unknown" }, }; static struct descrip ccstm_10dshutter[] = { { 0, "AF/AE Lock" }, { 1, "AE Lock/AF" }, { 2, "AF/AF Lock, No AE Lock" }, { 3, "AE/AF, No AE Lock" }, { -1, "Unknown" }, }; static struct descrip ccstm_assistflash[] = { { 0, "Emits/Fires" }, { 1, "Does Not Emit/Fires" }, { 2, "Only Ext. Flash Emits/Fires" }, { 3, "Emits/Does Not Fire" }, { -1, "Unknown" }, }; static struct descrip ccstm_afptreg[] = { { 0, "Center" }, { 1, "Bottom" }, { 2, "Right" }, { 3, "Extreme Right" }, { 4, "Automatic" }, { 5, "Extreme Left" }, { 6, "Left" }, { 7, "Top" }, { -1, "Unknown" }, }; static struct descrip ccstm_rawjpeg[] = { { 0, "RAW+Small/Normal" }, { 1, "RAW+Small/Fine" }, { 2, "RAW+Medium/Normal" }, { 3, "RAW+Medium/Fine" }, { 4, "RAW+Large/Normal" }, { 5, "RAW+Large/Fine" }, { -1, "Unknown" }, }; static struct descrip ccstm_10dmenubut[] = { { 0, "Previous (Volatile)" }, { 1, "Previous" }, { 2, "Top" }, { -1, "Unknown" }, }; static struct descrip ccstm_assistbut[] = { { 0, "Normal" }, { 1, "Select Home Position" }, { 2, "Select HP (while pressing)" }, { 3, "Av+/- (AF point by QCD)" }, { 4, "FE lock" }, { -1, "Unknown" }, }; /* D30/D60 custom functions. */ static struct exiftag canon_d30custom[] = { { 1, TIFF_SHORT, 0, ED_VRB, "D30Custom", "Long exposure noise reduction", ccstm_offon }, { 2, TIFF_SHORT, 0, ED_VRB, "D30Custom", "Shutter/AE lock buttons", ccstm_shutter }, { 3, TIFF_SHORT, 0, ED_VRB, "D30Custom", "Mirror lockup", ccstm_disen }, { 4, TIFF_SHORT, 0, ED_VRB, "D30Custom", "Tv/Av and exposure level", ccstm_explvl }, { 5, TIFF_SHORT, 0, ED_VRB, "D30Custom", "AF-assist light", ccstm_autooff }, { 6, TIFF_SHORT, 0, ED_VRB, "D30Custom", "Av mode shutter speed", ccstm_shutspd }, { 7, TIFF_SHORT, 0, ED_VRB, "D30Custom", "AEB sequence/auto cancellation", ccstm_aebseq }, { 8, TIFF_SHORT, 0, ED_VRB, "D30Custom", "Shutter curtain sync", ccstm_shutsync }, { 9, TIFF_SHORT, 0, ED_VRB, "D30Custom", "Lens AF stop button", ccstm_lensaf }, { 10, TIFF_SHORT, 0, ED_VRB, "D30Custom", "Fill flash auto reduction", ccstm_endis }, { 11, TIFF_SHORT, 0, ED_VRB, "D30Custom", "Menu button return position", ccstm_menubut }, { 12, TIFF_SHORT, 0, ED_VRB, "D30Custom", "Shooting Set button function", ccstm_setbut }, { 13, TIFF_SHORT, 0, ED_VRB, "D30Custom", "Sensor cleaning", ccstm_disen }, { 14, TIFF_SHORT, 0, ED_VRB, "D30Custom", "Superimposed display", ccstm_onoff }, { 15, TIFF_SHORT, 0, ED_VRB, "D30Custom", "Shutter release w/o CF card", ccstm_yesno }, { 0xffff, TIFF_SHORT, 0, ED_UNK, "D30CustomUnknown", "Canon D30/D60 Custom Unknown", NULL }, }; /* EOS-1D/1Ds custom functions. */ static struct exiftag canon_1dcustom[] = { { 0, TIFF_SHORT, 0, ED_VRB, "1DCustom", "Focusing screen", ccstm_fscr }, { 1, TIFF_SHORT, 0, ED_VRB, "1DCustom", "Finder display during exposure", ccstm_offon }, { 2, TIFF_SHORT, 0, ED_VRB, "1DCustom", "Shutter release w/o CF card", ccstm_yesno }, { 3, TIFF_SHORT, 0, ED_VRB, "1DCustom", "ISO speed expansion", ccstm_noyes }, { 4, TIFF_SHORT, 0, ED_VRB, "1DCustom", "Shutter button/AEL button", ccstm_shutterael }, { 5, TIFF_SHORT, 0, ED_VRB, "1DCustom", "Manual Tv/Av for M", ccstm_tvavform }, { 6, TIFF_SHORT, 0, ED_VRB, "1DCustom", "Exposure level increments", ccstm_explvlinc }, { 7, TIFF_SHORT, 0, ED_VRB, "1DCustom", "USM lens electronic MF", ccstm_usmmf }, { 8, TIFF_SHORT, 0, ED_VRB, "1DCustom", "Top/back LCD panels", ccstm_lcdpanels }, { 9, TIFF_SHORT, 0, ED_VRB, "1DCustom", "AEB sequence/auto cancellation", ccstm_aebseq }, { 10, TIFF_SHORT, 0, ED_VRB, "1DCustom", "AF point illumination", ccstm_afill }, { 11, TIFF_SHORT, 0, ED_VRB, "1DCustom", "AF point selection", ccstm_afsel }, { 12, TIFF_SHORT, 0, ED_VRB, "1DCustom", "Mirror lockup", ccstm_disen }, { 13, TIFF_SHORT, 0, ED_VRB, "1DCustom", "# AF points/spot metering", ccstm_afspot }, { 14, TIFF_SHORT, 0, ED_VRB, "1DCustom", "Fill flash auto reduction", ccstm_endis }, { 15, TIFF_SHORT, 0, ED_VRB, "1DCustom", "Shutter curtain sync", ccstm_shutsync }, { 16, TIFF_SHORT, 0, ED_VRB, "1DCustom", "Safety shift in Av or Tv", ccstm_disen }, { 17, TIFF_SHORT, 0, ED_VRB, "1DCustom", "AF point activation area", ccstm_afact }, { 18, TIFF_SHORT, 0, ED_VRB, "1DCustom", "Switch to registered AF point", ccstm_regaf }, { 19, TIFF_SHORT, 0, ED_VRB, "1DCustom", "Lens AF stop button", ccstm_lensaf1 }, { 20, TIFF_SHORT, 0, ED_VRB, "1DCustom", "AI servo tracking sensitivity", ccstm_aisens }, { 0xffff, TIFF_SHORT, 0, ED_UNK, "1DCustomUnknown", "Canon 1D/1Ds Custom Unknown", NULL }, }; /* 10D custom functions. */ static struct exiftag canon_10dcustom[] = { { 1, TIFF_SHORT, 0, ED_VRB, "10DCustom", "SET button function when shooting", ccstm_10dsetbut }, { 2, TIFF_SHORT, 0, ED_VRB, "10DCustom", "Shutter release w/o CF card", ccstm_yesno }, { 3, TIFF_SHORT, 0, ED_VRB, "10DCustom", "Flash sync speed in Av mode", ccstm_shutspd }, { 4, TIFF_SHORT, 0, ED_VRB, "10DCustom", "Shutter button/AE lock button", ccstm_10dshutter }, { 5, TIFF_SHORT, 0, ED_VRB, "10DCustom", "AF-assist beam/Flash firing", ccstm_assistflash }, { 6, TIFF_SHORT, 0, ED_VRB, "10DCustom", "Exposure level increments", ccstm_explvl }, { 7, TIFF_SHORT, 0, ED_VRB, "10DCustom", "AF point registration", ccstm_afptreg }, { 8, TIFF_SHORT, 0, ED_VRB, "10DCustom", "RAW+JPEG recording", ccstm_rawjpeg }, { 9, TIFF_SHORT, 0, ED_VRB, "10DCustom", "AEB sequence/auto cancellation", ccstm_aebseq }, { 10, TIFF_SHORT, 0, ED_VRB, "10DCustom", "Superimposed display", ccstm_onoff }, { 11, TIFF_SHORT, 0, ED_VRB, "10DCustom", "Menu button display position", ccstm_10dmenubut }, { 12, TIFF_SHORT, 0, ED_VRB, "10DCustom", "Mirror lockup", ccstm_disen }, { 13, TIFF_SHORT, 0, ED_VRB, "10DCustom", "Assist button function", ccstm_assistbut }, { 14, TIFF_SHORT, 0, ED_VRB, "10DCustom", "Fill flash auto reduction", ccstm_endis }, { 15, TIFF_SHORT, 0, ED_VRB, "10DCustom", "Shutter curtain sync", ccstm_shutsync }, { 16, TIFF_SHORT, 0, ED_VRB, "10DCustom", "Safety shift in Av or Tv", ccstm_disen }, { 17, TIFF_SHORT, 0, ED_VRB, "10DCustom", "Lens AF stop button", ccstm_lensaf }, { 0xffff, TIFF_SHORT, 0, ED_UNK, "10DCustomUnknown", "Canon 10D Custom Unknown", NULL }, }; /* * Process maker note tag 0x0001 values. */ static int canon_prop01(struct exifprop *aprop, struct exifprop *prop, unsigned char *off, enum byteorder o) { u_int16_t v = (u_int16_t)aprop->value; switch (aprop->tag) { case 2: aprop->lvl = v ? ED_IMG : ED_VRB; exifstralloc(&aprop->str, 32); snprintf(aprop->str, 31, "%d sec", v / 10); break; case 5: /* Change "Single" to "Timed" if #2 > 0. */ if (!v && exif2byte(off + 2 * 2, o)) strcpy(aprop->str, "Timed"); break; case 12: aprop->lvl = v ? ED_IMG : ED_VRB; /* * Looks like we can calculate zoom level when value * is 3 (ref S110). Calculation is (2 * #37 / #36). */ if (v == 3 && prop->count >= 37) { exifstralloc(&aprop->str, 32); snprintf(aprop->str, 31, "x%.1f", 2 * (float)exif2byte(off + 37 * 2, o) / (float)exif2byte(off + 36 * 2, o)); } else aprop->str = finddescr(canon_dzoom, v); break; case 16: /* ISO overrides standard one if known. */ if (!strcmp(aprop->str, "Unknown")) { aprop->lvl = ED_VRB; break; } aprop->override = EXIF_T_ISOSPEED; break; case 17: /* Maker meter mode overrides standard one if known. */ if (!strcmp(aprop->str, "Unknown")) { aprop->lvl = ED_VRB; break; } aprop->override = EXIF_T_METERMODE; break; default: return (FALSE); } return (TRUE); } /* * Process maker note tag 0x0004 values. */ static int canon_prop04(struct exifprop *aprop, struct exifprop *prop, unsigned char *off, enum byteorder o) { switch (aprop->tag) { case 7: aprop->override = EXIF_T_WHITEBAL; break; case 9: aprop->lvl = aprop->value ? ED_IMG : ED_VRB; break; default: return (FALSE); } return (TRUE); } /* * Process maker note tag 0x00a0 values. */ static int canon_propA0(struct exifprop *aprop, struct exifprop *prop, unsigned char *off, enum byteorder o) { switch (aprop->tag) { case 9: exifstralloc(&aprop->str, 32); snprintf(aprop->str, 31, "%d K", aprop->value); break; default: return (FALSE); } return (TRUE); } /* * Common function for a tag's child values. Pass in the list of tags * and a function to process them. */ static int canon_subval(struct exifprop *prop, struct exiftags *t, struct exiftag *subtags, int (*valfun)()) { int i, j; u_int16_t v; struct exifprop *aprop; unsigned char *off = t->md.btiff + prop->value; /* Check size of tag (first value) if we're not debugging. */ if (valfun && exif2byte(off, t->md.order) != 2 * prop->count) { exifwarn("Canon maker tag appears corrupt"); return (FALSE); } if (debug) printf("Processing %s (0x%04X) directory, %d entries\n", prop->name, prop->tag, prop->count); for (i = 0; i < (int)prop->count; i++) { v = exif2byte(off + i * 2, t->md.order); aprop = childprop(prop); aprop->value = (u_int32_t)v; aprop->tag = i; aprop->tagset = subtags; /* Lookup property name and description. */ for (j = 0; subtags[j].tag < EXIF_T_UNKNOWN && subtags[j].tag != i; j++); aprop->name = subtags[j].name; aprop->descr = subtags[j].descr; aprop->lvl = subtags[j].lvl; if (subtags[j].table) aprop->str = finddescr(subtags[j].table, v); dumpprop(aprop, NULL); /* Process individual values. Returns false if unknown. */ if (valfun && !valfun(aprop, prop, off, t)) { if (aprop->lvl != ED_UNK) continue; exifstralloc(&aprop->str, 32); snprintf(aprop->str, 31, "num %02d, val 0x%04X", i, v); } } if (debug) printf("\n"); return (TRUE); } /* * Process custom function tag values. */ static void canon_custom(struct exifprop *prop, unsigned char *off, enum byteorder o, struct exiftag *table) { int i, j = -1; const char *cn; char *cv = NULL; u_int16_t v; struct exifprop *aprop; /* * Check size of tag (first value). * XXX There seems to be a problem with the D60 where it reports the * wrong size, hence the 2nd clause in the if(). Could be related * to the second value being zero? */ if (exif2byte(off, o) != 2 * prop->count && exif2byte(off, o) != 2 * (prop->count - 1)) { exifwarn("Canon custom tag appears corrupt"); return; } if (debug) printf("Processing %s directory, %d entries\n", prop->name, prop->count); for (i = 1; i < (int)prop->count; i++) { v = exif2byte(off + i * 2, o); aprop = childprop(prop); aprop->value = v & 0xff; aprop->tag = v >> 8 & 0xff; aprop->tagset = table; /* * Lookup function name and value. First byte is function * number; second is function value. */ for (j = 0; table[j].tag != EXIF_T_UNKNOWN && table[j].tag != (v >> 8 & 0xff); j++); aprop->name = table[j].name; aprop->descr = prop->descr; aprop->lvl = table[j].lvl; if (table[j].table) cv = finddescr(table[j].table, (u_int16_t)(v & 0xff)); cn = table[j].descr; dumpprop(aprop, NULL); exifstralloc(&aprop->str, 4 + strlen(cn) + (cv ? strlen(cv) : 10)); if (cv && j != -1) { snprintf(aprop->str, 4 + strlen(cn) + strlen(cv), "%s - %s", cn, cv); free(cv); cv = NULL; } else { snprintf(aprop->str, 4 + strlen(cn) + 10, "%s %d - %d", cn, v >> 8 & 0xff, v & 0xff); aprop->str[3 + strlen(cn) + 10] = '\0'; aprop->lvl = ED_UNK; } } if (debug) printf("\n"); } /* * Process Canon maker note tags. */ void canon_prop(struct exifprop *prop, struct exiftags *t) { unsigned char *offset; u_int16_t flmin = 0, flmax = 0, flunit = 0; struct exifprop *tmpprop; switch (prop->tag) { /* Various image data. */ case 0x0001: if (!canon_subval(prop, t, canon_tags01, canon_prop01)) break; /* * Create a new value for the lens' focal length range. If * it's not a zoom lens, we'll make it verbose (it should * match the existing focal length Exif tag). */ if (prop->count >= 25) { offset = t->md.btiff + prop->value; flmax = exif2byte(offset + 23 * 2, t->md.order); flmin = exif2byte(offset + 24 * 2, t->md.order); flunit = exif2byte(offset + 25 * 2, t->md.order); } if (flunit && (flmin || flmax)) { tmpprop = childprop(prop); tmpprop->name = "CanonLensSz"; tmpprop->descr = "Lens Size"; exifstralloc(&tmpprop->str, 32); if (flmin == flmax) { snprintf(tmpprop->str, 31, "%.2f mm", (float)flmax / (float)flunit); tmpprop->lvl = ED_VRB; } else { snprintf(tmpprop->str, 31, "%.2f - %.2f mm", (float)flmin / (float)flunit, (float)flmax / (float)flunit); tmpprop->lvl = ED_PAS; } } break; case 0x0004: canon_subval(prop, t, canon_tags04, canon_prop04); break; case 0x00a0: if (!canon_subval(prop, t, canon_tagsA0, canon_propA0)) break; /* Color temp is bad if white balance isn't manual. */ if ((tmpprop = findprop(t->props, canon_tags04, 7))) if (tmpprop->value != 9) { if ((tmpprop = findprop(prop, canon_tagsA0, 9))) tmpprop->lvl = ED_BAD; } break; /* Image number. */ case 0x0008: exifstralloc(&prop->str, 32); snprintf(prop->str, 31, "%03d-%04d", prop->value / 10000, prop->value % 10000); break; /* Serial number. */ case 0x000c: exifstralloc(&prop->str, 11); snprintf(prop->str, 11, "%010d", prop->value); break; /* Custom functions. */ case 0x000f: /* * Canon annoyingly reuses this tag value for different sets * of custom functions (e.g., D30/60, 10D). Therefore, we * won't try to interpret them unless we know for sure that * the camera model is supported. */ if (!t->model) { exifwarn("Canon model unset; please report to author"); break; } if (strstr(t->model, "10D")) canon_custom(prop, t->md.btiff + prop->value, t->md.order, canon_10dcustom); else if (strstr(t->model, "D30") || strstr(t->model, "D60")) canon_custom(prop, t->md.btiff + prop->value, t->md.order, canon_d30custom); else exifwarn2("Custom function unsupported for %s; please " "report to author", t->model); break; case 0x0090: canon_custom(prop, t->md.btiff + prop->value, t->md.order, canon_1dcustom); break; /* Dump debug for tags of type short w/count > 1. */ default: if (prop->type == TIFF_SHORT && prop->count > 1 && debug) canon_subval(prop, t, canon_tagsunk, NULL); break; } } /* * Try to read Canon maker note IFDs. */ struct ifd * canon_ifd(u_int32_t offset, struct tiffmeta *md) { return(readifds(offset, canon_tags, md)); }