Updated 2011-02-05 19:06:35 by AMG

From a news:comp.lang.tcl posting by Berry Kercheval < mailto:berry@kerch.com >:

And this works for simple GIF files:
 proc gifsize {name} {
    set f [open $name r]
    fconfigure $f -translation binary
    # read GIF signature -- check that this is
    # either GIF87a or GIF89a
    set sig [read $f 6]
    switch $sig {
        "GIF87a" -
        "GIF89a" {
            # do nothing
        }
        default {
            close $f
            error "$f is not a GIF file"
        }
    }
    # read "logical screen size", this is USUALLY the image size too.
    # interpreting the rest of the GIF specification is left as an exercise
    binary scan [read $f 2] s wid
    binary scan [read $f 2] s hgt
    close $f

    return [list $wid $hgt]
 }

It leaked channels. Added some missing closes 11-jan-2002, Dave Griffin

http://www.onicos.com/staff/iz/formats/gif.html is a reference.

MG Apr 30 2004 - Since GIF support is built into Tcl, could you not just do
 catch {package require Img};# allow for jpeg/png/etc support, if possible
 proc imageSize {file {format ""}} {

  if { [catch {image create photo -file $file -format $format} img] } {
       if { $format == "" } {
            set form ""
          } else {
            set form "$format "
          }
       error "'$file' is not a recognisable ${form}image"
     }
  set info [list [image width $img] [image height $img]]
  image delete $img
  return $info;
 };# imageSize

 % imageSize ./path/to/image.gif
 % imageSize ./page/to/other/image.jpeg

Peter Newman 1 May 2004:

  • MG's solution above (or something similar,) is probably the best - because the GIF spec. allows various ways of specifying an image's height and width. As it says in the gifsize proc above; "logical screen size" ... is USUALLY the image size too. That's absolutely true (and I've personally never come across a GIF that didn't do this). But the GIF spec leaves the door open for people to do things differently (especially with animated GIFs) - so you'd imagine that a purpose built routine that (HOPEFULLY) copes with all the possibilities would be the most reliable solution. gifsize will probably work 99 times out of 100. But if you were coding (say) a gimp or photoshop clone, I'd personally go for something more thorough.
  • Modifying gifsize to cope with all the possibilities wouldn't be too difficult. The only real problem is that the GIF spec provides a number of ways to specify the image height and width. Which is confusing - until you realise that the answer is either; you just use logical screen size (and hope), as gifsize does above - or you support them all (which isn't really much extra work anyway).
  • There are TWO GIF specs; 87a and 89a. Both are in common use. The differences are small - mainly that 89a supports transparent pixels. Most programs write 87a files by default - unless you request otherwise - or have transparent pixels. A thorough solution should support both.

DKF: A reason for not using Tk to read the GIF image dimensions is if you are in a situation where you don't have a display (e.g. in a CGI script.)

Peter Newman 1 May 2004: That's true DKF. So an enhanced gifsize that did the job properly would be quite useful on this page. I did that many years ago in Forth and 80x86 Assembler - but I'm just to busy to convert it to Tcl (even if I could find it). But I don't think we need bother - because TclMagick doesn't need Tk - and surely it has the functionality in there. There seems to be ReadImage and GetImageInfo functions. But the docs are so complicated, I'm still not entirely sure whether it can do the job. Maybe someone familar with TclMagick can confirm whether or not it'll read GIF image dimensions (and if so, some sample code please:-).

Duoas 7 July 2006:

  • Since it has not been specifically stated, the above does in fact return the correct image dimentions of a GIF.
  • However, a GIF is potentially composed of several sub-images, if you will, all of which are composed onto the image frame (or Logical Screen Descriptor). If you want to get the dimentions of the sub-images, you'll need to parse the GIF block stream.
  • Fortunately, I've done this so oft before that I whipped-up a pure Tcl implementation for y'all: gifblock

See also edit