Since we want to work with barcodes (which are sequences of black and white stripes) and we want to write a simple decoder, an easy representation to work with will be a monochrome image, in which each pixel is either black or white.
As we mentioned earlier, we’ll work with netpbm images. The netpbm color image format is only slightly more complicated than the grayscale image format that we parsed in Chapter 10. The identifying string in a header is “P6,” with the rest of the header layout identical to the grayscale format. In the body of an image, each pixel is represented as three bytes, one each for red, green, and blue.
We’ll represent the image data as a two-dimensional array of pixels. We’re using arrays here purely to gain experience with them. For this application, we could just as well use a list of lists. The only advantage of an array is slight—we can efficiently extract a row:
-- file: ch12/Barcode.hs type Pixel = Word8 type RGB = (Pixel, Pixel, Pixel) type Pixmap = Array (Int,Int) RGB
We provide a few type synonyms to make our type signatures more readable.
Since Haskell gives us considerable
freedom in how we lay out an array, we must choose a representation.
We’ll play it safe and follow a popular convention: indices begin at
zero. We don’t need to store the dimensions of the image explicitly,
since we can extract them using the
The actual parser is mercifully short, thanks to the combinators ...