Home / Alt manpages / ppmshift(1)

  • ppmshift(1)
  • User command
  • linux

Randomly Shift PPM Rows with ppmshift

Glitch art and VHS-style artefacts start with ppmshift, which nudges each row of a PPM by a random amount. Left or right, within a range you set, so you end up with a shifted PPM and a checked output file ready for the next tool in your pipeline. The examples use ppmshift from Netpbm package version 2:11.05.02-1.1build1, as installed on this machine.

Allow about ten minutes. You need a readable PPM image, a shell, and enough free space for a second image. This is an ordinary transformation: no sudo, no change to the input, no change to system configuration.

1. Check the installed command

Confirm the binary is available and note the package version before you build a script around it:

$ command -v ppmshift
/usr/bin/ppmshift
$ dpkg-query -W -f='${Package} ${Version}\n' netpbm
netpbm 2:11.05.02-1.1build1

ppmshift has no useful option summary of its own. Its interface is a required shift value followed by an optional PPM file:

$ man ppmshift

The first argument is a range in pixels, not a fixed displacement. Each row moves left or right by a random amount within that range, uniformly distributed and centred on zero. A value of 0 therefore means no movement at all. Output goes to standard output.

Checkpoint

You have a readable source and a shift range chosen for the effect you want. For a subtle distortion on a large image, start small, something like 10, rather than guessing with a big displacement.

2. Inspect the source without changing it

Use file or your usual inspection tool to confirm the input really is PPM, and note its dimensions:

$ file /path/to/input.ppm
/path/to/input.ppm: Netpbm image data, size = 800 x 600, rawbits, pixmap

Wording varies between file versions. Look for a PPM or Netpbm pixmap description and the width and height you expect; do not assume a .ppm extension means valid PPM. If the file will not read, fix its path or permissions, elevated privileges are not a substitute for checking the input.

Keep the original: ppmshift reads it and writes a new image, so there is no reason to overwrite the source during a first test.

3. Write a shifted image to a new file

Pick a new destination and redirect standard output there:

$ ppmshift 10 /path/to/input.ppm > /path/to/input-shifted-10.ppm
$ printf 'exit status: %s\n' "$?"
exit status: 0

A zero exit status means the command finished, not that the visual result is any good, so verify the destination before you use it anywhere:

$ file /path/to/input-shifted-10.ppm
/path/to/input-shifted-10.ppm: Netpbm image data, size = 800 x 600, rawbits, pixmap
$ test -s /path/to/input-shifted-10.ppm && echo 'output is non-empty'
output is non-empty

ppmshift can emit a rawbits PPM even when the source was ASCII PPM; that is still a valid representation. Check the image in a viewer, or convert it with another Netpbm tool, before deleting the source.

4. Use standard input in a pipeline

Drop the optional filename when another command supplies the PPM on standard input, handy when you want to crop or otherwise prepare the image first:

$ pamcut -width 800 -height 300 /path/to/input.ppm | \
    ppmshift 10 > /path/to/cropped-shifted.ppm
$ file /path/to/cropped-shifted.ppm
/path/to/cropped-shifted.ppm: Netpbm image data, size = 800 x 300, rawbits, pixmap

Every stage in a pipeline has to write a format the next stage accepts. If a pipeline fails, test each command separately so a diagnostic from one tool is not mistaken for a ppmshift error. The pipeline above stays unprivileged unless you deliberately read or write a protected path.

5. Avoid accidental overwrites

Shell redirection with > truncates an existing destination before ppmshift starts, destructive if that destination is the only copy of something useful. Write to a temporary name, inspect it, then replace the old file once you are satisfied:

$ ppmshift 10 /path/to/input.ppm > /path/to/input-shifted-10.ppm.new
$ test -s /path/to/input-shifted-10.ppm.new
$ file /path/to/input-shifted-10.ppm.new
/path/to/input-shifted-10.ppm.new: Netpbm image data, size = 800 x 600, rawbits, pixmap
$ mv /path/to/input-shifted-10.ppm.new /path/to/input-shifted-10.ppm

mv replaces the old destination if one already exists. Want an undo path? Make a backup first:

$ cp --preserve=all /path/to/input-shifted-10.ppm /path/to/input-shifted-10.ppm.bak

Restore that backup with mv afterwards if you need to. Do not delete the backup until you have another verified copy, deleting it is irreversible within this workflow.

6. Diagnose the common failures

A negative range is rejected by the installed program:

$ ppmshift -1 /path/to/input.ppm > /tmp/unused.ppm
ppmshift: shift factor must be 0 or more

Use zero or a positive integer instead. If the input path is missing or unreadable, ppmshift exits non-zero and says it cannot open the file. Check that without changing anything:

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

Keep the shift argument numeric, and put the input filename in the optional second position. A typo in the first argument is not a safe stand-in for a filename, and can make the command behave differently from the one you meant. Quote paths that might contain spaces:

$ ppmshift 10 "/path/to/source image.ppm" > "/path/to/source image-shifted.ppm"

Repeated runs are expected to differ, the displacement is random. The manual notes that versions before Netpbm 10.37 could produce identical output when run twice in the same second. The installed package is newer than that, but do not treat randomness as a reproducibility mechanism either way: keep the generated file whenever a particular result matters.

Done means

  • Version noted: ppmshift is installed and its Netpbm version is recorded.
  • Source verified: the input is a readable PPM with the dimensions you expected.
  • Output written: a non-empty file was created with a non-negative numeric shift range.
  • Checked before use: the output dimensions were confirmed and the image inspected.
  • Source intact: the original remains, and any destination replacement has a recovery copy if you need one.