A pixmap is the color variant of a PNM image: each pixel is represented by three numeric values, stored as RGB components. In PNM headers, pixmaps use magic number P3 for ASCII data or P6 for binary data; bitmap and graymap pixels instead use one value. section 12.2.3 section 13.1.1
An ASCII pixmap writes three decimal values per pixel. A parser reads the red value, skips whitespace, then reads green and blue, constructing an RGB value. Raw parsed values are not immediately checked against the header’s maximum color value. section 12.2.3
Listing 12.24 Parsers for ASCII-encoded PNM image data
p1PixelP :: Parser RawPixel
p1PixelP =
Single
<$> choice #1
[ 1 <$ C8.char '1',
0 <$ C8.char '0'
]
p2PixelP :: Parser RawPixel
p2PixelP = Single <$> C8.decimal #2
p3PixelP :: Parser RawPixel
p3PixelP = do #3
r <- C8.decimal
whitespaces
g <- C8.decimal
whitespaces
b <- C8.decimal
return $ RGB r g b
The P3 parser makes the three-component structure explicit: one decimal value each for red, green, and blue. section 12.2.3
Binary P6 pixmaps follow the same three-component layout, but each component is read from binary data. A component normally occupies one byte; when the header maximum exceeds 255, it occupies two bytes and is combined into a 16-bit value. Thus an 8-bit P6 pixel contains three byte values, while a 16-bit one contains three 16-bit values. section 12.2.3
Before a parsed pixmap is safe to use, validation must establish that:
- The pixel count equals the width multiplied by the height in the header. section 13.1.1
- The RGB pixel form agrees with the pixmap magic number. section 13.1.1
- No color component exceeds the maximum value declared in the header. section 13.1.1
Representing parsed RGB data
A raw PNM parser can represent pixels as either Single Word16 for bitmap or graymap data, or RGB Word16 Word16 Word16 for pixmap data. After validation, an image representation can retain whether its RGB pixels use 8-bit or 16-bit channel values, including types supplied by JuicyPixels for later PNG conversion. section 13.1.1
