48c48 < package provide exif 1.1.2 ; # first release --- > package provide exif 1.2 ; # first release 53a54 > variable cameraMake ; # used internally to understand options 134a136 > variable cameraMake 168a171 > set cameraMake $value 220a224 > variable cameraMake 237c241,243 < array set result [makerNote $data $offset] --- > #ML > # Catch error if vendor specific makerNote is not available or fails > catch {array set result [makerNote_[string toupper [string range $cameraMake 0 3]] $data $offset]} 239,241c245,261 < # Apparently, this doesn't usually work. < set result(UserComment) "$offset - [string range $data $offset [expr {$offset+8}]]" < set result(UserComment) [string trim $result(UserComment) "\0"] --- > #ML > # The first 8Bytes specify the type. If all zero the type is undefined. > set type [string range $data $offset [expr {$offset + 7}]] > set type [string trim $type "\0"] > debug "UserComment type: '$type'" > set result(UserComment) "" > if {$type != ""} { > set value [string range $data [expr {$offset + 8}] [expr {$offset + 8 + $components - 1}]] > set value [string trim $value] > # normal string trim does not seem to work right here > for {set i 0} {$i < [string length $value]} {incr i 1} { > set a [string index $value $i] > if {![string is print $a]} { break } > append result(UserComment) $a > } > } > set result(UserComment) [string trim $result(UserComment)] 252c272 < set value [readIFDEntry $data $format $components $offset] --- > set value [readIFDEntry $data $format $components $offset] 256c276 < set result(ExposureTime) "$value seconds" --- > set result(ExposureTime) "$value s" 258c278 < set result(ExposureTime) "1/[expr {1.0/$value}] seconds" --- > set result(ExposureTime) "1/[format %.0f [expr {1.0/$value}]] s" 261a282,295 > } elseif {$tag == 0x8822} { > #ML > set result(ExposureProgram) [switch $value { > 0 {format "not defined"} > 1 {format "manual"} > 2 {format "normal program"} > 3 {format "aperture priority"} > 4 {format "shutter priority"} > 5 {format "creative program"} > 6 {format "action program"} > 7 {format "portrait mode"} > 8 {format "landscape mode"} > default {format unknown} > }] 309a344,368 > } elseif {$tag == 0x9208} { > #ML > set result(LightSource) [switch $value { > 1 {format "daylight"} > 2 {format "fluorescent"} > 3 {format "tungsten"} > 4 {format "flash"} > 9 {format "fine weather"} > 10 {format "cloudy weather"} > 11 {format "shade"} > 12 {format "daylight fluorescent"} > 13 {format "day white fluorescent"} > 14 {format "cool white fluorescent"} > 15 {format "white fluorescent"} > 17 {format "standard light A"} > 18 {format "standard light B"} > 19 {format "standard light C"} > 20 {format "D55"} > 21 {format "D65"} > 22 {format "D75"} > 23 {format "D50"} > 24 {format "ISO studio tungsten"} > 255 {format "other light source"} > default {format unknown} > }] 335a395,397 > } elseif {$tag == 0xA215} { > #ML > set result(ExposureIndex) $value 337,338c399,412 < # 2 = 1 chip color area sensor < set result(SensingMethod) $value --- > #ML > set result(SensingMethod) [switch $value { > 1 {format "not defined"} > 2 {format "one-chip color area sensor"} > 3 {format "two-chip color area sensor"} > 4 {format "three-chip color area sensor"} > 5 {format "color sequential area sensor"} > 7 {format "trilinear sensor"} > 7 {format "color sequential linear sensor"} > default {format unknown} > }] > } elseif {$tag == 0xA301} { > #ML > set result(SceneType) "directly photographed image" 369a444,475 > } elseif {$tag == 0xA408} { > #ML > set result(Contrast) [switch $value { > 0 {format "normal"} > 1 {format "soft"} > 2 {format "hard"} > default {format unknown} > }] > } elseif {$tag == 0xA409} { > #ML > set result(Saturation) [switch $value { > 0 {format "normal"} > 1 {format "low saturation"} > 2 {format "high saturation"} > default {format unknown} > }] > } elseif {$tag == 0xA40A} { > #ML > set result(Sharpness) [switch $value { > 0 {format "normal"} > 1 {format "soft"} > 2 {format "hard"} > default {format unknown} > }] > } elseif {$tag == 0xA40C} { > #ML > set result(SubjectDistanceRange) [switch $value { > 1 {format "macro"} > 2 {format "close view"} > 3 {format "distant view"} > default {format unknown} > }] 395c501,503 < error "Unrecognized EXIF Tag: $tag (0x[string toupper [format %x $tag]])" --- > #ML > debug "Unrecognized EXIF Tag: $tag (0x[format %X $tag])" > lappend result(UnrcognizedTags) "0x[format %X $tag]" 401a510,574 > #ML > # makerNote for OLYMPUS cameras > proc ::exif::makerNote_OLYM {data curoffset} { > variable cameraModel > debug "MakerNote_OLYM: offset=$curoffset" > array set result {} > > set value [readIFDEntry $data 2 5 $curoffset] > if {$value == "OLYMP"} { > incr curoffset 8 > } > set numEntries [readShort $data $curoffset] > debug "Number of directory entries: $numEntries" > incr curoffset 2 > for {set i 0} {$i < $numEntries} {incr i} { > set head [expr {$curoffset + 12 * $i}] > set entry [string range $data $head [expr {$head+11}]] > set tag [readShort $entry 0] > set format [readShort $entry 2] > set components [readLong $entry 4] > set offset [readLong $entry 8] > set value [readIFDEntry $data $format $components $offset] > debug "$i)\tTag: 0x[string toupper [format %x $tag]]" > > if {$tag == 0x0200} { > set value [readLong $data [expr {$offset + 0}]] > set result(OlympusShootingMode) [switch $value { > 0 {format "single"} > 2 {format "sequential"} > 3 {format "panoramic"} > default {format unknown} > }] > > set value [readLong $data [expr {$offset + 4}]] > set result(OlympusSequenceNumber) $value > > set value [readLong $data [expr {$offset + 8}]] > set result(OlympusPanoramicDirection) $value > > } elseif {$tag == 0x0201} { > set result(OlympusImageQuality) [switch $value { > 1 {format "SQ"} > 2 {format "HQ"} > 3 {format "SHQ"} > default {format unknown} > }] > } elseif {$tag == 0x0202} { > set result(OlympusMacroMode) [switch $value { > 0 {format "normal"} > 1 {format "macro"} > default {format unknown} > }] > } elseif {$tag == 0x0204} { > set result(OlympusDigitalZoomRatio) $value > } elseif {$tag == 0x0207} { > set result(OlympusFirmwareVersion) $value > } elseif {$tag == 0x0208} { > set result(OlympusPictureInfo) $value > } elseif {$tag == 0x0209} { > set result(OlympusCameraID) $value > } > } > return [array get result] > } > 403c576 < proc ::exif::makerNote {data curoffset} { --- > proc ::exif::makerNote_CANO {data curoffset} { 405c578 < debug "MakerNote: offset=$curoffset" --- > debug "MakerNote_CANO: offset=$curoffset" 789c962 < return $offset --- > return $offset 795c968,980 < return [expr {(1.0*$numerator)/$denominator}] --- > #ML This should not happen > if {$denominator == 0} {return 0} > return [expr {(1.0*$numerator)/$denominator}] > } elseif {$format == 7} { > #ML > # undefined 8Bit > set value "" > if {$components < 4} { > set value [string range $offset 0 [expr {$components - 1}]] > } else { > set value [string range $data $offset [expr {$offset + $components - 1}]] > } > return $value 800a986,987 > #ML This should not happen > if {$denominator == 0} {return 0} 804c991,993 < error "Invalid IFD entry format: $x" --- > #ML Return empty string is better than raising an error > debug "Invalid IFD entry format: $x" > return "" 851c1040 < foreach proc {analyze app1 exifSubIFD makerNote} { --- > foreach proc {analyze app1 exifSubIFD makerNote_CANO makerNote_OLYM} {