Home / Alt manpages / pamtopfm(1)

  • pamtopfm(1)
  • User command
  • linux

Convert Netpbm Images to Portable Float Maps with pamtopfm

pamtopfm turns a PNM or PAM image into a PFM file, the format that stores raw floating-point light intensity instead of ordinary display values. Give it ten minutes if Netpbm is already installed: convert, set scale and byte order where needed, then check the result without touching the source.

PFM, short for Portable Float Map, looks like PPM on the surface but stores four-byte IEEE floats per sample and has no maxval. That makes it a better fit for high dynamic range or generic intensity data than for a picture you are about to look at on screen. The command writes to standard output, so redirect it to a new file.

1. Check the installed command

Confirm the binary exists and note its version before it goes anywhere near a script:

$ command -v pamtopfm
/usr/bin/pamtopfm
$ pamtopfm --version
pamtopfm: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
pamtopfm: Built from source dated 2024-03-31 09:09:47
pamtopfm: Built by Debian

Build details will differ on another machine. What the installed manual promises is an optional input filename plus two options, -scale=float and -endian={big|little}. It also says option names can be abbreviated to their shortest unique prefix, though full names read better in a script.

Checkpoint: if command -v prints nothing, install the Netpbm package through your normal channel and stop there. Neither conversion nor verification needs elevated privileges as long as you own the input and output directories.

2. Convert a colour PPM image

Pick a destination with nothing worth keeping in it yet, then redirect:

$ pamtopfm /path/to/input.ppm > output.pfm
$ printf 'exit status: %s\n' "$?"
exit status: 0

An RGB input becomes a colour PFM. This installed build produced the PF magic number and a two-pixel, one-row image for a small test file:

$ head -n 3 output.pfm
PF
2 1
-1.000000

The PFM raster underneath is binary floating-point data, so head only ever shows you the text header. A clean exit status is not proof the image looks right. Check its dimensions and open it with a tool that actually understands PFM, or convert it onward with an installed Netpbm program.

3. Keep the original and avoid truncating output

Here is the trap: > truncates an existing destination the moment the shell opens it, before pamtopfm has read a single byte. Write to a temporary name and move it only once the command has actually succeeded:

$ pamtopfm /path/to/input.ppm > output.pfm.new
$ status=$?
$ if [ "$status" -eq 0 ] && [ -s output.pfm.new ]; then
>     mv output.pfm.new output.pfm
> else
>     printf 'conversion failed with status %s\n' "$status" >&2
>     exit "$status"
> fi

That only changes the output path. On failure, the old output.pfm stays put and the incomplete output.pfm.new can be removed once you have read the error. Removing a file cannot be undone, so do not wire an automatic cleanup step into a batch job until its failure handling has actually been tested.

PFM output can dwarf a compressed display format in size. Keep the original PNM or PAM around until the PFM has been checked, pamtopfm reads it and leaves it alone either way.

4. Set the PFM scale

Scale is part of the format, and defaults to 1.0. Set a different floating-point value when whatever consumes the PFM expects one:

$ pamtopfm -scale=0.5 /path/to/input.ppm > output-half-scale.pfm
$ head -n 3 output-half-scale.pfm
PF
2 1
-0.500000

The header is a handy quick check that your requested value actually made it into the file. It is not a substitute for the consuming program's own check, since scale only has meaning to that consumer, not to pamtopfm itself.

Do not confuse scale with resizing. pamtopfm converts sample data, full stop; it has no width or height option. Output dimensions come straight from the input image.

5. Choose byte order when interoperability requires it

Each sample is a four-byte IEEE float, and by default it is written in whatever byte order is native to the machine running pamtopfm, chosen purely for speed. Set it explicitly when another program or file spec demands a particular order:

$ pamtopfm -endian=little /path/to/input.ppm > output-little.pfm
$ head -n 3 output-little.pfm
PF
2 1
-1.000000

Use -endian=big for the other order. This is not a cosmetic choice: it changes how a reader decodes the binary raster. A file can have a perfectly normal-looking header and still be unusable to a reader expecting the opposite order, so agree the setting with the receiving tool rather than guessing at it.

Both options combine freely:

$ pamtopfm -scale=0.5 -endian=little /path/to/input.ppm > output-little-half.pfm

6. Convert from standard input and diagnose failures

The input filename is optional, so a pipeline can hand pamtopfm a Netpbm image directly:

$ cat /path/to/input.ppm | pamtopfm > output.pfm

For a one-off conversion, naming the file makes the command easier to review later. Either way, check the exit status immediately. If the command cannot read the input at all, verify the path and permissions without changing anything:

$ ls -l /path/to/input.ppm
$ test -r /path/to/input.ppm && echo 'input is readable'

Got a non-colour PFM when you expected colour? Check the input type first. pamtopfm only produces colour output for RGB PPM input, everything else comes out non-colour. A header starting PF means colour; use a proper PFM-aware checker for anything beyond that header line, a text editor will not help you here.

The option syntax accepts -scale=0.5 or -scale 0.5, and the manual allows two hyphens too. Pick one consistent, explicit form for automation. An invalid option or an unreadable image should stop the pipeline outright, do not let a partial redirected file sit there looking valid.

Done means

  • Installed and versioned: pamtopfm is on your path and its Netpbm version is known.
  • Source untouched: the original PNM or PAM file is unchanged.
  • Output verified: the destination is a non-empty PFM file with the expected kind and dimensions.
  • Scale and endianness explicit: set whenever a downstream reader actually requires them.
  • Failure-safe: a failed conversion cannot overwrite the previous destination.