The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Image::PBMlib - Helper functions for PBM/PGM/PPM image file formats

SYNOPSIS

    use Image::PBMlib;

    ... open(PPM, "< image.ppm")...

    my $ref = readppmheader(\*PPM);

    my @pixels = readpixels_raw(\*PPM, $$ref{type}, 
                                ($$ref{width} * $$ref{height}) );

    my @pixels = readpixels_dec(\*PPM, $$ref{type}, 
                                ($$ref{width} * $$ref{height}) );

    my @rgb = hextriplettoraw("F00BA4");

    my @rgb = dectriplettoraw("17:34:51");

    my $header = makeppmheader($ref);

DESCRIPTION

This is primarily a library for reading portable bitmap (PBM), portable graymap (PGM), and portable pixmap (PPM) files. These image formats are only the barest step up from raw data, and have a very simple format which is the key to be "portable". Writing out images in these formats is very easy.

Reading images in these formats is also easy, but not quite "very easy". Proper reading of the file needs to happen one byte at a time, since there is no fixed header length. Headers can also contain comments, which must be ignored. Then, once past the header, there are a total of six different ways that the data might need to be read: a raw and an ascii encoding of each image color level.

makeppmheader($hashref)

Takes a hash reference similar to readppmheader() would return and makes a PBM, PGM, or PPM header from it. makeppmheader first looks for a type in the hash and uses that, otherwise it expects bgp and raw to be set in the hash (and it will set type for you then). If there is a non-empty comments in the hash, that will be put in as one or more lines of comments. There must be sizes for width and height, and if the image is not a bitmap, there should be one for max. A missing max will result in makeppmheader guessing 255. A max of more than 255 cannot be written as a raw file, but makeppmheader will not check for that.

  my %info = (
     type => 6,                                 # raw pixmap
     comments => "Made with Image::PBM!",
     width => 100,
     height => 100,
     max => 255
  );
  my $header = makeppmheader(\%info);

Returns undef if there is an error.

readppmheader($globref)

Reads byte-by-byte from the glob until a full header has been found, then parses it and returns a hashref with information about the file.

  if(open(PPM, "< image.ppm")) {
    my $info_r = readppmheader(\*PPM);
    # Now %{$info_r} will have:
    #
    # $$info_r{error}      undef if no errors, otherwise a problem
    #                      desciption
    # $$info_r{type}       the number part of the magic number of the
    #                      image format:
    #                           1  ascii bitmap
    #                           2  ascii graymap
    #                           3  ascii pixmap
    #                           4  raw   bitmap
    #                           5  raw   graymap
    #                           6  raw   pixmap
    # $$info_r{raw}         boolean, is this a raw format?
    # $$info_r{bgp}         "b" for bitmap, "g" for graymap, "p" for
    #                       pixmap
    # $$info_r{width}       image width
    # $$info_r{height}      image height
    # $$info_r{max}         max color value (1 for bitmap, usually 255
    #                       for others)
    # $$info_r{comments}    comments found in the header (all catinated)
    # $$info_r{fullheader}  the complete, unparsed, header
  }

If there was an error, the error hash element will be set with a problem description, and the other hash elements may or may not be set or trustworthy.

readpixels_dec($globref, $type, $count)

This will attempt to read $count pixels from the GLOB. To know how to interpret the file, the file type (1 to 6) is required. An EOF may cause readpixels_dec() to return fewer than $count pixels. Type 4 (raw bitmap) images can only be read 8 pixels at a time, so the count will be rounded up to the next multiple of 8.

Returned will be an array of the decimal values of each pixel. Color images will be returned as an array of arrays of RGB values.

  @pixels = readpixels_dec(\*PPM, $$info_r{type}, 1);
  my ($r, $g, $b) = ( $pixels[0][0], $pixels[0][1], $pixels[0][2] );
  # If it was a blue pixel, $r == 0, $g == 0, $b == 255.
  

Short reads will result in short pixel arrays returned. Invalid format or nothing to read will result in undef being returned.

readpixels_raw($globref, $type, $count)

This will attempt to read $count pixels from the GLOB. To know how to interpret the file, the file type (1 to 6) is required. An EOF may cause readpixels_dec() to return fewer than $count pixels. Type 4 (raw bitmap) images can only be read 8 pixels at a time, so the count will be rounded up to the next multiple of 8.

Returned will be an array of the raw color values of each pixel. Color images will be returned as an array of arrays of RGB values.

  @pixels = readpixels_dec(\*PPM, $$info_r{type}, 1);
  my ($r, $g, $b) = ( $pixels[0][0], $pixels[0][1], $pixels[0][2] );
  # If it was a blue pixel, $r == chr(0), $g == chr(0), $b == chr(255).
  

Short reads will result in short pixel arrays returned. Invalid format or nothing to read will result in undef being returned.

hextriplettoraw($string)

Parses a six character hexstring into an R, G, B triplet and returns an array of the raw bytes.

   @rgb_raw = hextriplettoraw("FF0000"); # red

Returns undef if there is an error.

dectriplettoraw($string)

Parse a colon seperated list into an R, G, B triplet and returns an array of the raw bytes.

   @rgb_raw = hextriplettoraw("0:255:0"); # green

Returns undef if there is an error.

PORTABILITY

This code is pure perl for maximum portability, as befitting the PBM/PGM/PPM philiosophy.

BUGS

The maximum color value is never used.

No attempt is made to deal with comments after the header of ascii formatted files.

Not all PBM/PGM/PPM tools are safe for images from untrusted sources but this one should be. Be careful what you use this with.

SEE ALSO

The manual pages for pbm(5), pgm(5), and ppm(5) define the various file formats.

COPYRIGHT

Copyright 2003 Benjamin Elijah Griffin / Eli the Bearded <elijah@cpan.org>

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