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} {
