Home / Alt manpages / pamtohdiff(1)

  • pamtohdiff(1)
  • User command
  • linux

Create reversible horizontal difference images with pamtohdiff

You will convert a PAM or PNM image into a PAM horizontal difference image, check the result, and recover the original with hdifftopam. This is useful when repeated rows should compress well or when you need Netpbm's hdiff representation for another processing step. Allow about 10 minutes if Netpbm is already installed. The examples read and write files as your normal user, so they do not need sudo.

1. Check the installed Netpbm tools

This guide is verified against the installed netpbm package, version 2:11.05.02-1.1build1, which provides Netpbm 11.5.2. The local pamtohdiff(1) manual is dated 15 April 2002, so the commands below describe this installed implementation. Check your own binary before copying the result into a portable script:

$ command -v pamtohdiff
/usr/bin/pamtohdiff
$ pamtohdiff -version 2>&1 | head -2
pamtohdiff: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
pamtohdiff: Built from source dated 2024-03-31 09:09:47

The input can be supplied as the optional positional pamfile argument, or read from standard input. The output is written to standard output. That separation is useful, but it also means an accidental redirection can overwrite a file before conversion has succeeded.

2. Convert a PAM image to hdiff

Choose an output name that does not already contain useful data. The converter does not alter the input file:

$ pamtohdiff /path/to/source.pam > /path/to/source.hdiff.pam

For a pipeline, omit the input path:

$ cat /path/to/source.pam | pamtohdiff > /path/to/source.hdiff.pam

Verify the new file as PAM and check that its tuple type is hdiff:

$ pamfile /path/to/source.hdiff.pam
/path/to/source.hdiff.pam: PAM, 1920 by 1080 by 3 maxval 255
    Tuple type: hdiff

Your dimensions, depth and maxval will differ. The useful checks are that the file is non-empty, the geometry matches the source, and the tuple type is hdiff.

3. Understand what changed

For each sample, pamtohdiff compares the current row with the row directly above it. A run of unchanged rows therefore produces many zero differences, which is the property that can make the result compress better. The first row still has to be represented, so do not treat the file as a general-purpose compressed image format.

PAM samples are unsigned, while a difference can be negative. Netpbm stores the difference modulo maxval + 1, preserving enough context for the inverse operation. It also adds a half-maxval visual bias before the modulus operation. As a result, the output can be displayed as a PNM-style image: zero difference appears around the middle of the intensity range, negative differences appear darker and positive differences lighter when the changes stay within the expected range.

This visual interpretation is a diagnostic aid, not a reason to edit the hdiff samples by hand. If you need the visual mapping to remain useful for larger differences, the manual recommends applying ppmdim 50 to the original and doubling maxval first with pamdepth. Those transformations change the image data, so keep a copy of the original.

4. Recover the original image

Use hdifftopam to reverse the conversion. Without options it emits a PAM image:

$ hdifftopam /path/to/source.hdiff.pam > /path/to/recovered.pam
$ pamfile /path/to/recovered.pam
/path/to/recovered.pam: PAM, 1920 by 1080 by 3 maxval 255
    Tuple type: unhdiff

The unhdiff tuple type identifies the recovered PAM. If you need a PGM or PPM instead, use the documented -pnm option. It only succeeds when the depth is 1 or 3:

$ hdifftopam -pnm /path/to/source.hdiff.pam > /path/to/recovered.pnm
$ pamfile /path/to/recovered.pnm
/path/to/recovered.pnm: PPM, 1920 by 1080 255

For a stronger check, compare the pixel content with a trusted image tool or convert both files to the same canonical format before comparing. The PAM headers are allowed to differ: the recovered file normally has tuple type unhdiff, not the source header's original tuple name.

5. Avoid losing an existing output

Shell redirection with > truncates its destination before pamtohdiff starts. For an existing result, write a temporary file in the same directory and replace the destination only after checking it:

$ pamtohdiff /path/to/source.pam > /path/to/source.hdiff.pam.new
$ pamfile /path/to/source.hdiff.pam.new
$ mv /path/to/source.hdiff.pam.new /path/to/source.hdiff.pam

The mv command changes the destination and is normally irreversible if the old file has no backup. Stop before it if pamfile reports an error. If the conversion fails, remove only the incomplete .new file and leave the old result in place:

$ rm /path/to/source.hdiff.pam.new

Run that removal only when the path is exactly the temporary output you chose. Keep the source image until the reverse conversion has been checked.

6. Diagnose the common traps

  • An end-of-file error usually means the input is truncated or is not a valid PAM or PNM stream. Check it with pamfile /path/to/source.pam before changing anything.
  • A file with the wrong dimensions is not repaired by renaming it. Recheck the source and its header, then rerun the conversion.
  • -verbose is accepted by this implementation but currently has no effect. Do not rely on it for progress or metadata.
  • Do not use -pnm with hdifftopam for an hdiff image whose depth is not 1 or 3; the documented command will fail.

Done means

  • pamtohdiff accepted a readable PAM or PNM input without elevated privileges.
  • pamfile reports the output tuple type as hdiff and preserves the expected geometry.
  • The original file remains untouched and any replacement was checked before mv.
  • hdifftopam recovered a PAM, or a PGM/PPM with -pnm when the depth permits it.