From mailto:joe@perrigoue.com


proc GetJPGDimensions { filename } { set fd [ open $filename ] fconfigure $fd -translation binary set ch1 "00" while { ! [ eof $fd ] } { binary scan [ read $fd 1 ] "H2" ch2 if { ( $ch1 == "ff" ) && ( $ch2 >= "c0" ) && ($ch2 <= "c3" ) } { binary scan [ read $fd 7 ] "x3SS" height width return [ list $height $width ] } set ch1 $ch2 } error "Couldn't find JPG header for $filename" }
It turns out that the above code will not work with images from most digital cameras. They usually include a thumbnail for display on the LCD. The new code will work on any JPEG that follows the standard. This is from a script that I wrote to produce thumbnailed HTML indexes and captioned display pages automatically. You can find the entire script at http://perrigoue.com


proc get_jpg_dimensions {filename} { # open the file in binary mode (VERY important) -- no need for write access set img [open $filename rb] # read in first two bytes to check if this is a JPEG if {[read $img 2] eq "\xff\xd8"} { while {![eof $img]} { # search for the next marker, read the marker type byte, and throw out # any extra "ff"'s while {[read $img 1] ne "\xff"} {} while {[set byte [read $img 1]] eq "\xff"} {} if {$byte in {\xc0 \xc1 \xc2 \xc3 \xc5 \xc6 \xc7 \xc9 \xca \xcb \xcd \xce \xcf}} { # this is the SOF marker; read a chunk of data containing the dimensions binary scan [read $img 7] x3S2 size break } else { # this is not the the SOF marker; read in the offset of the next marker binary scan [read $img 2] S offset # the offset includes itself own two bytes so subtract them, then move # ahead to the next marker seek $img [expr {($offset & 0xffff) - 2}] current } } } close $img if {![info exists size]} { error "invalid JPEG" } else { return $size } }
JOB Removed some unnecessary code (regarding "SOF" marker) and it still works.AMG: That code is necessary for skipping thumbnails. Without it, incorrect dimensions are read for some files, such as the full-resolution version of this image: [1].I went ahead and made a few optimizations to the code, posted above. Plus I added support for some rare SOF marker types.
http://zdnet.com.com/2100-1104-945735.html

See also edit
- Reading GIF image dimensions
- Reading PNG image dimensions
- Reading JPEG comments
- Reading image type and dimensions