pgm: Pure Haskell implementation of PGM image format

[ bsd3, graphics, library ] [ Propose Tags ]

Reads and writes 8 and 16 bit PGM images, loading them into Haskell as arrays.

[Skip to Readme]




Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


  • No Candidates
Versions [RSS] 0.1, 0.1.1, 0.1.2, 0.1.3, 0.1.4
Dependencies array (<1), base (>=3 && <5), bytestring (<1), parsec (>=3 && <4) [details]
License BSD-3-Clause
Author Frederick Ross <>
Maintainer Sergey Astanin <>
Category Graphics
Home page
Source repo head: git clone
Uploaded by SergeyAstanin at 2014-06-05T11:01:49Z
Distributions NixOS:0.1.4
Reverse Dependencies 1 direct, 0 indirect [details]
Downloads 4138 total (15 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Successful builds reported [all 1 reports]

Readme for pgm-0.1.4

[back to package description]
pgm, A pure Haskell library for reading and writing PGM images
by Fred Ross <fred dot ross at epfl dot ch>


Unpack the archive, and in the produced directory run

$ cabal configure
$ cabal build
$ cabal install

If you don't have cabal installed, replace it with 'runhaskell Setup.lhs'


Graphics.Pgm is a pure Haskell library to read and write PGM images. It
properly supports both 8 bit and 16 bit pixels, and multiple PGMs per file. The
PGM is the lowest common denominator of useful image file formats. It consists
of a header of the form

P5 width height maxVal

followed by a single whitespace character, usually a newline, where width,
height, and maxVal are positive integers consisting of digits only giving the
number of columns, number of rows, and the highest grey level in the image to

If maxVal < 256, then the format uses 1 byte per pixel; otherwise it uses 2.
The routines in this library properly handle both, including automatically
determining which to write when writing an array to disk.

The header can also contain comments, starting with # on a new line, and
continuing to the end of the line. These are ignored by this module.

After the header, the pixel data is written in big-endian binary form, most
significant byte first for 16 bit pixels. The pixels are a single row-major
raster through the image.

To put multiple PGMs in a file, append them. This module allows you to put
white space between them, though this might choke other implementations.

All arrays returned by this library from PGMs have pixel type Int, since this
is simply more useful for most purposes. If you want to write a PGM back out,
you must first coerce your pixel type to Word16! There are too many possible
ways of handling negative values, larger depths, or other things beyond the
comprehension of Word16 to handle with a simple wrapper function. If you know
you have positive values less than 2^16, then you can coerce an array arr to
Word16 with

> amap (fromIntegral :: Int -> Word16) arr

The array's indices (of the form (row,column)) start at (0,0) and run to


The library was originally licensed under the terms of GPL license, but since
2011 the original authors have given their permission to dual-license the code
under both GPLv3 (see LICENSE2) and BSD (see LICENSE). The users may choose
whichever license that suits them most.

Permission from Frederick Ross:
Permission from Brian Lewis has been obtained in private e-mail on 18-03-2011.