Benjamin Low

NAME

Image::ParseGIF - Parse a GIF image into its compenent parts.

SYNOPSIS

  use Image::ParseGIF;

  $gif = new Image::ParseGIF ("image.gif") or die "failed to parse: $@\n";

  # write out a deanimated version, showing only the first frame
  $gif->deanimate(0);

  #  same again, manually printing each part
  print $gif->header;
  print $gif->part(0);
  print $gif->trailer;
  #  or, without passing scalars around:
  $gif->print_header;
  $gif->print_part(0);
  $gif->print_trailer;


  # send an animated gif frame by frame
  #  - makes for a progress bar which really means something
  $gif = new Image::ParseGIF ("progress.gif") or die "failed to parse: $@\n";

  $gif->print_header;

  $gif->print_percent(0.00);    # starting...
  do_some_work_stage1();

  $gif->print_percent(0.10);    # 10% complete
  do_some_work_stage2();

  $gif->print_percent(0.25);    # 25% complete
  do_some_work_stage3();

  $gif->print_percent(0.70);    # 70% complete
  do_some_work_stage4();

  $gif->print_percent(1.00);    # done!

  $gif->print_trailer;

DESCRIPTION

This module parses a Graphics Interchange Format (GIF) image into its component 'parts'. A GIF is essentially made up of one or more images - multiple images typically are used for animated gifs.

PURPOSE

This module was written to allow a web application to display the status of a request, without resorting to scripting or polling the server via client refresh.

Most web browsers (at least Netscape 2.02 & 4.05, Opera 3.21 and Internet Explorer 4.0) show each frame as soon as it is received. (Indeed, the GIF format is block-based so any image viewer which can handle animated GIFs should operate similarly.) So, if we can arrange for the parts of a progress bar image to be delivered to the client in sympathy with the request's progress, we'll have made a dandy real-time feedback mechanism. Contrast this with the common fixed animation used at many sites, which are uncorrelated to the request state and not at all realistic.

One implementation of this status mechanism involves the main application returning a page containing an image tag to a 'status' script (e.g. <img src="status.cgi?id="request_id">). The status script interrogates the request's status (perhaps by reading from a pipe), and prints image frames as the request progresses.

At the moment the image is wholly read into memory. File pointers could be used to operate from disk, however, given that most web images are on the order of 1-100k, I don't see a lot of benefit in bothering to do so. Also, if a persistant application is used (i.e. FCGI), the same image can be reused for many requests.

BACKGROUND

A gif image consists of:

  1. a 'header' (including the GIF header (signature string) and logical screen descriptor)

  2. a global colour map

  3. zero or more 'graphic blocks' or 'extensions'

    • a block/extension header

    • one or more sub-blocks per part

  4. a trailer

Note that this module groups the GIF header, logical screen descriptor and any global colour map into the 'header' part.

There are two types of 'descriptor blocks/extensions' defined in the GIF specification [1]: an image descriptor; or an extension. Extensions can contain 'control' information for things like animated gifs. Each descriptor block/extension has its own 'header', often followed by one or more data blocks. This module extracts only image descriptors and graphic control extensions. Moreover, this module treats associated descriptor blocks and extensions as a 'part' - an image 'part' is considered to be the extension/s leading up to an image descriptor, plus the image descriptor.

CONSTRUCTOR / CLASS METHODS

In general, all Image::ParseGIF methods return undef on error, possibly with an explanatory message in $@.

autoflush ( STATE )

Class method (i.e. Image::ParseGIF::autoflush(0)). Sets default autoflush() state for new output streams. On by default.

new ( [FILENAME] )
new ( FILENAME [, ARGUMENTS ] )
new ( FILENAME [, {ARGUMENTS}] )

Creates a new Image::ParseGIF object.

If FILENAME is supplied, opens and parses the given file.

ARGUMENTS may be:

'debug' (natural number)

Set the debug level.

'output' (IO::Handle/filehandle/glob)

Sets the default output stream (default STDOUT). (See perl's binmode() regarding writing binary output.)

'invert' (natural number)

Adjusts the colour inversion feature (default 0 is off).

'posterize' (natural number) =item 'posterise' (natural number)

Adjusts the colour posterization (high pass filtering) feature (default 0 is off, positive values increase the resulting gamut).

'desaturate' (natural number)

Adjusts the colour-to-grayscale feature (default 0 is off).

METHODS

debug ( LEVEL )

If LEVEL is omitted, returns the current debug level setting.

If LEVEL is defined, sets the current debug level. The higher the debug level, the more output.

invert ( EXPR )

If EXPR is omitted, returns the current colour inversion setting.

If EXPR is defined, sets the current colour inversion setting. Zero is off, nonzero inverts RGB colour table values, leaving each one as a photo-negative colour instead. Default is 0.

posterize ( EXPR ) =item posterise ( EXPR )

If EXPR is omitted, returns the current colour posterization setting.

If EXPR is defined (N), sets the current colour posterization setting. Zero is off, nonzero posterizes RGB colour table values, leaving each one to be one of N colors. Default is 0.

desaturate ( EXPR )

If EXPR is omitted, returns the current colour desaturization setting.

If EXPR is defined, sets the current colour desaturization setting. Zero is off, nonzero desaturizes RGB colour table values, leaving each one as a mean grayscale value. Default is 0.

open ( FILENAME )

Opens the given file and parses it.

parse ( IO )

Parse a GIF, reading from a given filehandle / IO::Handle.

(header|trailer)

Returns the image (header|trailer) as a scalar.

parts

Returns a list of the image parts in array context, or the number of parts in scalar context. Does not include header or trailer.

part ( PART )

Returns an image part as a scalar. If PART == undef, returns header; if PART > number of parts, returns trailer.

= item output ( IO )

Specifies the default output filehandle / IO::Handle for all subsequent print_ calls. (See perl's binmode() regarding writing binary output.)

Prints the (header|trailer) to the supplied / default output stream.

Prints the given PART to the supplied / default output stream.

Remembers which part it was up to (PreviousPART), prints from from PreviousPART to PART to the supplied / default output stream.

Prints PERCENT percent of the image frames. Remembers where it was up to, and will only print increasing part numbers (i.e. it won't duplicate parts). Note you'll still need to print the header and trailer.

deanimate ( [PART] [, IO ] )

Prints header, given part (or part 0 if unspecified) and trailer to the supplied / default output stream.

NOTES

You should be able to parse an image contained in any object which has a read() method (e.g. IO::Scalar), however the object will have to support the OFFSET read() argument. As at version 1.114, IO::Scalar does not.

For example: $io = new IO::File ('blah'); $gif = new Image::ParseGIF; $gif->parse($io) or die "failed to parse: $@\n";

"BUGS"

  • It'd be nice to have a more generic interface to handle all GIF extensions, etc.

  • And from the "In case you've ever wondered" department:

    Natural Number (http://mathworld.wolfram.com/NaturalNumber.html)

    "A positive integer 1, 2, 3, ... ([ref]). The set of natural numbers is denoted N or Z+. Unfortunately, 0 is sometimes also included in the list of ``natural'' numbers (Bourbaki 1968, Halmos 1974), and there seems to be no general agreement about whether to include it. In fact, Ribenboim (1996) states ``Let [P] be a set of natural numbers; whenever convenient, it may be assumed that [0 <element of> P].''"

COPYRIGHT

Copyright (c) 1999/2000 University of New South Wales Benjamin Low <b.d.low@unsw.edu.au>. All rights reserved.

Colour-table portions added 1 June 2000 Ed Halley <ed@explorati.com>.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Artistic License for more details.

AUTHORS

Benjamin Low <b.d.low@unsw.edu.au>

Ed Halley <ed@explorati.com>

SEE ALSO

This code was based on the CGI 89a spec [1] and the Image::DeAnim module by Ken MacFarlane.

[1] http://member.aol.com/royalef/gif89a.txt