proc pngsize {filename} {
if {[file size $filename] < 33} {
error "File $filename not large enough to contain PNG header"
}
set f [open $filename r]
fconfigure $f -encoding binary -translation binary
# Read PNG file signature
binary scan [read $f 8] c8 sig
foreach b1 $sig b2 {-119 80 78 71 13 10 26 10} {
if {$b1 != $b2} {
close $f
error "$filename is not a PNG file"
}
}
# Read IHDR chunk signature
binary scan [read $f 8] c8 sig
foreach b1 $sig b2 {0 0 0 13 73 72 68 82} {
if {$b1 != $b2} {
close $f
error "$filename is missing a leading IHDR chunk"
}
}
# Read off the size of the image
binary scan [read $f 8] II width height
# Ignore the rest of the data, including the chunk CRC!
#binary scan [read $f 5] ccccc depth type compression filter interlace
#binary scan [read $f 4] I chunkCRC
close $f
return [list $width $height]
}See also "Reading GIF image dimensions", "CRC", and "Reading JPEG image dimensions".AM Also see Writing PNG files for sample code to write a PNG file - precursor for a package to be ... :)
AF I accidentally duplicated this, but mine is somewhat shorter and returns all of the image info:
proc read_png_header {file} {
set fh [open $file r]
fconfigure $fh -encoding binary -translation binary -eofchar {}
if {[read $fh 8] != "\x89PNG\r\n\x1a\n"} { close $fh; return }
binary scan [read $fh 8] Ia4 len type
set r [read $fh $len]
if {![eof $fh] && $type == "IHDR"} {
binary scan $r IIccccc width height depth color compression filter interlace
close $fh
return [list $width $height $depth $color $compression $filter $interlace]
}
close $fh
return
}This functionality is also present in the tcllib png module.

