Safe Haskell | None |
---|
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 follow.
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 read out and returned as a
String
with newlines kept intact (except for the last newline of the
last comment line, which is removed). Comments from anywhere between the
header fields are concatenated into the same document. pgmToArray
ignores comments; pgmToArrayWithComments
reads them.
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
(height
-1,width
-1).
- pgmToArray :: (Integral a, IArray UArray a) => ByteString -> Either ParseError (UArray (Int, Int) a)
- pgmsToArrays :: (Integral a, IArray UArray a) => ByteString -> Either ParseError [UArray (Int, Int) a]
- pgmToArrayWithComments :: (Integral a, IArray UArray a) => ByteString -> Either ParseError (UArray (Int, Int) a, String)
- pgmsToArraysWithComments :: (Integral a, IArray UArray a) => ByteString -> Either ParseError [(UArray (Int, Int) a, String)]
- arrayToPgmWithComment :: IArray m Word16 => m (Int, Int) Word16 -> String -> ByteString
- pgmsFromFile :: String -> IO (Either ParseError [UArray (Int, Int) Int])
- pgmsFromHandle :: Handle -> IO (Either ParseError [UArray (Int, Int) Int])
- arrayToPgm :: IArray m Word16 => m (Int, Int) Word16 -> ByteString
- arrayToFile :: IArray m Word16 => String -> m (Int, Int) Word16 -> IO ()
- arrayToHandle :: IArray m Word16 => Handle -> m (Int, Int) Word16 -> IO ()
- arraysToHandle :: IArray m Word16 => Handle -> [m (Int, Int) Word16] -> IO ()
- arraysToFile :: IArray m Word16 => String -> [m (Int, Int) Word16] -> IO ()
Documentation
pgmToArray :: (Integral a, IArray UArray a) => ByteString -> Either ParseError (UArray (Int, Int) a)Source
Parse the first (and possible only) PGM in a ByteString
into an array.
If the parsing succeeds, you will still need to match on the Right
constructor to get the array.
pgmsToArrays :: (Integral a, IArray UArray a) => ByteString -> Either ParseError [UArray (Int, Int) a]Source
Precisely the same as pgmToArray
, but this time fetches all the PGMs in
the file, and returns them as a list of arrays.
pgmToArrayWithComments :: (Integral a, IArray UArray a) => ByteString -> Either ParseError (UArray (Int, Int) a, String)Source
The same as pgmToArray
, but taking also returning the comments in the
PGM file as a String
.
pgmsToArraysWithComments :: (Integral a, IArray UArray a) => ByteString -> Either ParseError [(UArray (Int, Int) a, String)]Source
Same as pgmsToArrays
, but again returning comments.
arrayToPgmWithComment :: IArray m Word16 => m (Int, Int) Word16 -> String -> ByteStringSource
Precisely the same as arrayToPgm
, but takes a String
to encode into
the file header as a comment after the magic number but before the width
field.
pgmsFromFile :: String -> IO (Either ParseError [UArray (Int, Int) Int])Source
A wrapper around pgmsFromHandle
which also opens the file to read from.
pgmsFromHandle :: Handle -> IO (Either ParseError [UArray (Int, Int) Int])Source
Parse all PGMs in the contents of a handle, and return them as a list of arrays.
arrayToPgm :: IArray m Word16 => m (Int, Int) Word16 -> ByteStringSource
Takes an array (which must already be coerced to have element type
Word16
) and produces a ByteString
encoding of that array as a PGM.
arrayToFile :: IArray m Word16 => String -> m (Int, Int) Word16 -> IO ()Source
A wrapper around arrayToHandle
which opens the file to write to, then
closes it afterwards.
arrayToHandle :: IArray m Word16 => Handle -> m (Int, Int) Word16 -> IO ()Source
Write a single array to a given handle.
arraysToHandle :: IArray m Word16 => Handle -> [m (Int, Int) Word16] -> IO ()Source
Writes a list of arrays to a given handle. Note that most implementations of PGM will ignore all but the first when they read this file.
arraysToFile :: IArray m Word16 => String -> [m (Int, Int) Word16] -> IO ()Source
A wrapper around arraysToHandle
which opens and closes the file to write
to.