Swap Byte Order in Netpbm Images with pamendian
An ancient viewer chokes on a perfectly good PGM, and the fix is pamendian. It flips a Netpbm image between the normal big-endian sample order and the little-endian variant some old programs expect. Allow about ten minutes once you know which order the receiving program wants.
The route
Jump straight to the step you need, or tick off Done means at the end.
pamendian reads only from standard input and writes only to standard output, so every example here is a pipe or a redirected file. This guide uses Netpbm 11.5.2, installed as package netpbm version 2:11.05.02-1.1build1, whose manual page is dated 16 March 2002: treat the specifics here as verified on this machine, not guaranteed on every Netpbm build.
1. Check the installed command
Confirm the binary exists and note the library version. Ordinary read-only checks, no sudo needed:
$ command -v pamendian
/usr/bin/pamendian
$ pamendian --help
pamendian: Use 'man pamendian' for help.
$ pamendian --version
pamendian: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
pamendian: Built from source dated 2024-03-31 09:09:47
--help comes from the common Netpbm command interface; the manual defines no pamendian-specific options. There is no input filename and no endian-selection switch: the image always travels through standard input, and pamendian always reverses the sample byte order.
Checkpoint
If command -v finds nothing, stop and install or repair Netpbm through your normal package manager. Do not copy a random binary into a system directory.
2. Confirm the format and the actual problem
Netpbm's binary formats with multi-byte samples are defined big-endian, most significant byte first. Some older programs use a little-endian variant of otherwise normal PGM, PPM or PAM data: the manual specifically names the X viewer xv and Independent JPEG Group tools as consumers of that older variant.
Use pamendian only when the program on the other end genuinely needs that variant. Images from current Netpbm programs and libraries already have the correct byte order; if one of those needs pamendian, chase down the conversion or library boundary rather than bolting a workaround onto every pipeline.
Check an existing image first:
$ pamfile /path/to/input.pgm
/path/to/input.pgm: PGM raw, 2 by 1 65535 maxval
Your dimensions and maximum value will differ. What matters is the format, dimensions and maximum value: above 255 means each sample spans multiple bytes, so byte order actually matters. An 8-bit image has one byte per sample, so reversing it cannot change anything useful.
3. Convert to the opposite byte order
Redirect the input into pamendian and write a new file; this never alters the source:
$ pamendian < /path/to/input.pgm > /path/to/output-little-endian.pgm
$ pamfile /path/to/output-little-endian.pgm
/path/to/output-little-endian.pgm: PGM raw, 2 by 1 65535 maxval
$ test -s /path/to/output-little-endian.pgm && echo "output is non-empty"
output is non-empty
The header still reports the same dimensions and maximum value: only the binary sample bytes after the header actually change. Pass the result to whichever older consumer needs little-endian samples. The same standard-in, standard-out rule applies to PPM and true PAM:
$ pamendian < /path/to/input.ppm > /path/to/output-little-endian.ppm
$ pamendian < /path/to/input.pam > /path/to/output-opposite-order.pam
Do not add a filename after pamendian: it is not a positional argument, and the contract is specifically standard input to standard output.
4. Verify the byte-level change safely
For a two-byte-sample PGM, compare the payload with a hex dump, keeping the header in view so its ASCII digits do not get mistaken for sample data:
$ xxd -g1 /path/to/input.pgm | tail -n 2
00000000: 50 35 0a 32 20 31 0a 36 35 35 33 35 0a 01 02 P5.2 1.65535...
00000010: 03 04 ..
$ xxd -g1 /path/to/output-little-endian.pgm | tail -n 2
00000000: 50 35 0a 32 20 31 0a 36 35 35 33 35 0a 02 01 P5.2 1.65535...
00000010: 04 03 ..
Each byte pair flips: 01 02 became 02 01, and 03 04 became 04 03. Your own output will have a different header and payload length; for a bigger image, use pamfile for structure and let the receiving program do its own image-level check.
Tip
A good reversibility test is running pamendian a second time into a fresh file, then comparing it against the original:
$ pamendian < /path/to/output-little-endian.pgm > /tmp/input-round-trip.pgm
$ cmp -- /path/to/input.pgm /tmp/input-round-trip.pgm
$ echo $?
0
Status 0 means the bytes match exactly. Remove the temporary round-trip file once you are done checking it if it holds sensitive image data.
5. Avoid truncating a useful image
Warning
Shell redirection with > truncates an existing destination before pamendian even starts, which is the main destructive trap in this whole workflow. Write to a temporary file and rename it only after validation:
$ tmp_output=$(mktemp --tmpdir pamendian.XXXXXX.pgm)
$ pamendian < /path/to/input.pgm > "$tmp_output"
$ pamfile "$tmp_output"
$ mv -- "$tmp_output" /path/to/output-little-endian.pgm
mv replaces an existing destination on the same filesystem, so back up anything that matters or choose a versioned name. If conversion fails, do not rename the incomplete temporary file: remove it after checking the error and the original stays untouched. Nothing here needs elevated privileges unless your chosen directories themselves deny your normal access.
Common traps
If the receiving program rejects the result, first check that the input really is a binary PGM, PPM or PAM image whose maximum value needs multi-byte samples. pamendian is not a general converter, resizer or format detector; it only reverses sample byte order.
If the image looks corrupted but the command exits cleanly, compare dimensions, maximum value and the first few payload pairs. The most common mistake is running the conversion on data already in the byte order the consumer expected, reversing it twice relative to that consumer. Keep the original file and regenerate output from it, rather than repeatedly running pamendian on the latest result.
For raw sample streams, the manual recommends declaring input endianness with rawtopgm or rawtoppm so those tools produce correctly ordered Netpbm output in the first place, rather than repairing every result afterwards.
Done means
- Version noted.
pamendianis the installed Netpbm 11.5.2 command, or you have recorded your own host's version. - Need confirmed. The input is a compatible binary PGM, PPM or PAM image whose consumer genuinely needs the opposite byte order.
- Pipe respected. The command read from standard input and wrote to a new standard-output destination.
- Result checked.
pamfileconfirms the expected format, dimensions and maximum value. - Original preserved. The source image remains available, and a failed conversion cannot destroy the previous output.