Convert Netpbm Images to PFM Floating-Point Files
You will convert a Netpbm image into a PFM file, choose its byte order and scale factor, inspect the result, and convert it back to PAM for a safe round-trip check. The examples use Netpbm 11.5.2 from the installed netpbm package.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need pamtopfm, pfmtopam, a shell, and a readable PNM or PAM image. The workflow is unprivileged: do not use sudo unless your input or output directory has deliberately restricted permissions.
1. Check the installed converters
Confirm which binaries will run before you build a script around them:
$ command -v pamtopfm
/usr/bin/pamtopfm
$ command -v pfmtopam
/usr/bin/pfmtopam
$ pamtopfm --version
pamtopfm: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
The local manpages describe the format and the converter options. PFM is similar to PPM, but its samples are 32-bit IEEE floating-point values rather than integer samples with a declared maximum. It is intended for data such as generic light intensity, not just display-ready colour.
Checkpoint: if either command is missing, stop here and install the distribution's Netpbm package through your normal package-management process. Do not copy a binary from an unrelated machine.
2. Create a small test image
Use a tiny grayscale PGM so the conversion has a known input and does not overwrite anything useful:
printf 'P2\n2 1\n255\n0 255\n' > /tmp/pfm-input.pgm
This is a two-pixel image, with one black sample and one white sample. The temporary path keeps the example separate from your working files. For a real conversion, replace the input path with an existing PNM or PAM file and keep the original unchanged.
Verify the input before converting it:
$ file /tmp/pfm-input.pgm
/tmp/pfm-input.pgm: Netpbm image data, size 2 x 1, ASCII, grayscale
3. Convert the image to PFM
Write the output to a new name. This example requests little-endian samples and a scale factor of 2:
$ pamtopfm -endian=little -scale=2 /tmp/pfm-input.pgm > /tmp/pfm-output.pfm
$ file /tmp/pfm-output.pfm
/tmp/pfm-output.pfm: data
pamtopfm writes PFM to standard output, so the shell redirection creates the file. Its input is RGB when the source is a PPM image, producing colour PFM. Other input produces non-colour PFM, such as the grayscale file above.
The default scale is 1.0. The default byte order is the machine's native order, which is convenient locally but less explicit for an interchange file. Set both options when another program or another machine must consume the result. The scale is metadata for interpreting sample units; it is not a request to brighten, resize, or otherwise display-adjust the image.
Warning: > truncates an existing destination before pamtopfm starts. Use a new filename first. If you must replace an established output, make a backup and write a separate temporary result:
cp --preserve=all /path/to/output.pfm /path/to/output.pfm.bak
pamtopfm -endian=little -scale=2 /path/to/input.pgm > /path/to/output.pfm.new
mv /path/to/output.pfm.new /path/to/output.pfm
Recovery is straightforward if the new conversion fails: remove the .new file and restore the backup with mv. Do not remove the backup until the replacement has passed its checks.
4. Read the PFM header
A PFM file begins with three ASCII fields, followed immediately by binary raster data. Inspect only the header, not the whole file:
$ od -An -tx1 -c -N 32 /tmp/pfm-output.pfm
50 66 0a 32 20 31 0a 2d 32 2e 30 30 30 30 30 30
P f \n 2 1 \n - 2 . 0 0 0 0 0 0
The identifier Pf means grayscale; PF means colour. The next line is width and height, here 2 1. The negative scale line means little-endian raster data, and its absolute value is the scale factor, here 2.0. A positive scale line means big-endian data.
Do not treat the raster as text. Each grayscale pixel has one four-byte sample. Each colour pixel has three samples. Rows are stored from the bottom upwards, and pixels within a row run from left to right. That bottom-to-top order is an easy source of an apparently upside-down image when a consumer assumes ordinary top-to-bottom storage.
5. Round-trip through PAM
Use pfmtopam to check that the header can be read and that the converter recognises the format:
$ pfmtopam -verbose /tmp/pfm-output.pfm > /tmp/pfm-roundtrip.pam
pfmtopam: width: 2, height: 1
pfmtopam: color: NO
pfmtopam: endian: LITTLE
pfmtopam: scale factor: 2.000000
$ sed -n '1,7p' /tmp/pfm-roundtrip.pam
P7
WIDTH 2
HEIGHT 1
DEPTH 1
MAXVAL 255
TUPLTYPE GRAYSCALE
ENDHDR
The PAM header confirms the dimensions, grayscale depth, byte order and scale. The pixel bytes after ENDHDR are binary, so seeing unreadable characters after the header is expected. The default PAM maximum value is 255; choose another value with -maxval only when the receiving workflow requires it.
For a production conversion, compare dimensions and colour mode with the source as well as checking that pfmtopam exits successfully. A successful parse does not prove that an unrelated application interprets the scale units or row order as you intend.
6. Keep the format boundary explicit
PFM is not an official Netpbm format. The local manual describes the form understood by these two converters, based on behaviour deduced from an earlier program. That is enough for a controlled Netpbm workflow, but it is a reason to test any external reader with a small known image before exchanging valuable data.
Keep the scale factor, endianness, dimensions and colour mode with your processing notes. PFM has no extra delimiter or trailer around the raster, and it has no built-in unit such as watts per square metre. The scale only tells a reader how sample values are scaled; separate domain knowledge still gives those values meaning.
Done means
- The installed commands report Netpbm 11.5.2 or the version you have recorded.
- The source image remains untouched and the destination was not accidentally truncated.
- The PFM header has the expected
PForPf, dimensions, sign and scale. pfmtopamreads the file and reports the expected colour mode, dimensions and byte order.- Any external consumer has been tested against a known sample, including bottom-to-top row order and scale interpretation.