Netpbm and PFM codec support

August 12, 2026 ยท View on GitHub

This document defines the implemented boundary of the first-party Netpbm codec family.

Integer Netpbm decode

  • PBM P1 ASCII and P4 packed binary
  • PGM P2 ASCII and P5 binary
  • PPM P3 ASCII and P6 binary
  • PAM P7 BLACKANDWHITE, BLACKANDWHITE_ALPHA, GRAYSCALE, GRAYSCALE_ALPHA, RGB, and RGB_ALPHA tuples
  • Comments and Netpbm whitespace between header tokens
  • MAXVAL from 1 through 65535
  • Native big-endian gray16, rgb16, and rgba16 blocks for 16-bit samples
  • Bounded row output
  • Multiple concatenated images
  • Nonstandard PAM tuple types

Integer Netpbm encode

  • P1 and P4 PBM
  • P2 and P5 PGM
  • P3 and P6 PPM
  • P7 PAM grayscale, grayscale-alpha, RGB, and RGBA
  • Deterministic 8-bit and 16-bit output

PFM convention

PureJsImage implements the Netpbm-documented PFM convention. Pf stores one grayscale float32 sample and PF stores three RGB float32 samples. A negative scale selects little-endian storage and a positive scale selects big-endian storage. The scale magnitude multiplies samples on decode and samples are divided by it on encode. Raster rows are stored bottom to top.

  • Pf grayscale and PF RGB
  • Little-endian and big-endian float32 samples
  • Non-unit finite scale magnitudes
  • Negative, greater-than-one, NaN, and infinite samples
  • Native grayf32 and rgbf32 output
  • Deterministic little- or big-endian encoding

Validation

  • Capped token and header parsing
  • Dimension, MAXVAL, tuple, sample-range, raster-size, and truncation checks
  • CC0 Imazen PNM conformance fixtures
  • FFmpeg PFM interoperability fixture derived from a CC0 Poly Haven HDR