Convert a 320x200 PPM into an Atari Spectrum 512 Image
You will finish with an uncompressed Atari Spectrum 512 image produced from a PPM file, plus a quick way to check that the input had the dimensions ppmtospu requires. The examples use Netpbm package version 2:11.05.02-1.1build1 and its installed ppmtospu(1) command.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need a readable PPM image, Netpbm, and enough disk space for a binary output file. The conversion itself normally needs no elevated privileges. This guide creates files in a working directory and does not install software, change a service, or alter the source image.
1. Check the installed command
Confirm which executable your shell will run and record the package version. These are ordinary, read-only checks:
$ command -v ppmtospu
/usr/bin/ppmtospu
$ dpkg-query -W -f='${Package} ${Version}\n' netpbm
netpbm 2:11.05.02-1.1build1
The command's help output points to the manual rather than printing a full option list, so use man ppmtospu for the local contract. The installed manual describes the program as a converter from PPM to the uncompressed Spectrum 512 format used by Atari ST computers.
Checkpoint
You have a real ppmtospu binary and know which Netpbm package provides it.
2. Confirm the source image dimensions
ppmtospu accepts exactly 320 pixels by 200 pixels. Inspect the input before starting a conversion:
$ file /path/to/source.ppm
/path/to/source.ppm: Netpbm image data, size = 320 x 200, rawbits, pixmap
The wording from file can vary. The useful part is the size. If your image is another size, use a Netpbm tool such as pamscale or pamcut to make a separate 320x200 input. Do not assume that a filename or a viewer window tells you the dimensions.
For example, this makes a resized working copy. It leaves the original untouched:
$ pamscale -width 320 -height 200 /path/to/source.ppm > /tmp/spectrum-320x200.ppm
$ file /tmp/spectrum-320x200.ppm
/tmp/spectrum-320x200.ppm: Netpbm image data, size = 320 x 200, rawbits, pixmap
Resizing changes image content, so use pamcut instead when cropping is the result you actually want. Either way, keep the original until the result has been checked.
3. Convert the PPM without overwriting an existing image
Choose a new destination name first. Shell redirection truncates an existing destination before ppmtospu gets a chance to report an error, so do not redirect straight onto a valuable file:
$ ppmtospu /tmp/spectrum-320x200.ppm > /tmp/spectrum.spu
$ printf 'exit status: %s\n' "$?"
exit status: 0
$ file /tmp/spectrum.spu
/tmp/spectrum.spu: data
$ wc -c /tmp/spectrum.spu
51104 /tmp/spectrum.spu
A successful run writes the converted image to standard output and normally writes no progress message. The output is binary, so do not inspect it with a text editor. On the tested installation the 320x200 example produced a 51,104-byte file. Treat the exact size as a useful local check, not as a substitute for opening the image in an Atari-compatible tool.
If you need to replace an existing output, write a temporary file first and move it into place only after the conversion succeeds:
$ ppmtospu /tmp/spectrum-320x200.ppm > /tmp/spectrum.spu.new
$ test -s /tmp/spectrum.spu.new
$ mv /tmp/spectrum.spu.new /path/to/final.spu
The mv command changes state and can replace /path/to/final.spu. Check the path carefully before running it. If conversion fails, remove the incomplete .new file and the old output remains in place:
$ rm /tmp/spectrum.spu.new
That removal is irreversible for the temporary file. It is not needed if you want to inspect the failed output for diagnosis.
4. Choose the dithering mode
The default is a 2x2 ordered dither. You can choose no dithering with -d0, keep the default explicit with -d2, or use a 4x4 ordered dither with -d4:
$ ppmtospu -d0 /tmp/spectrum-320x200.ppm > /tmp/spectrum-no-dither.spu
$ ppmtospu -d2 /tmp/spectrum-320x200.ppm > /tmp/spectrum-2x2.spu
$ ppmtospu -d4 /tmp/spectrum-320x200.ppm > /tmp/spectrum-4x4.spu
$ wc -c /tmp/spectrum-no-dither.spu /tmp/spectrum-2x2.spu /tmp/spectrum-4x4.spu
51104 /tmp/spectrum-no-dither.spu
51104 /tmp/spectrum-2x2.spu
51104 /tmp/spectrum-4x4.spu
Equal file sizes do not mean equal pixels. Dithering changes how colours are represented, so compare the images in the software that will display or transfer them. Start with the default, then try -d0 or -d4 if the visual result is poor for your source.
The option names can be abbreviated to their shortest unique prefix, and the manual permits one or two hyphens. Full forms such as -d2 are clearer in scripts and easier to review.
5. Use standard input when the image is in a pipeline
The input filename is optional. Without it, ppmtospu reads PPM data from standard input, while output still goes to standard output:
$ pamscale -width 320 -height 200 /path/to/source.ppm \
| ppmtospu -d2 > /tmp/piped-spectrum.spu
$ test -s /tmp/piped-spectrum.spu && echo 'non-empty Spectrum 512 output'
non-empty Spectrum 512 output
Keep the two streams separate when diagnosing a pipeline. A shell error or a diagnostic from an earlier command belongs on standard error, but redirecting a command's standard output to a file is still capable of creating an unusable result if the upstream stage supplied the wrong format. Check each stage when the pipeline matters:
$ pamscale -width 320 -height 200 /path/to/source.ppm > /tmp/check.ppm
$ file /tmp/check.ppm
/tmp/check.ppm: Netpbm image data, size = 320 x 200, rawbits, pixmap
6. Diagnose the common failures
An incorrectly sized input is rejected. For example, a 319x200 image produces a non-zero exit status and an error naming both the required and actual size:
$ ppmtospu /tmp/wrong-size.ppm > /tmp/wrong-size.spu
ppmtospu: Image size must be 320x200. This one is 319 x 200
If the error says the input cannot be opened, check the path and permissions without using sudo:
$ ls -l /path/to/source.ppm
$ test -r /path/to/source.ppm && echo readable
If the image is readable but not 320x200, make a resized or cropped working copy as in step 2. If the output exists but looks wrong, verify the source dimensions and try the three dithering modes. A zero exit status confirms that the program completed; it does not confirm that a separate viewer or Atari workflow will interpret the file as intended.
Do not run the conversion as root merely because the destination is protected. Write to a user-owned temporary path, verify the file, then use the normal administrative process to install or transfer it if that is genuinely required. Nothing in ppmtospu itself needs a service restart or persistent configuration change.
Done means
- The installed Netpbm version and
ppmtospupath are known. - The source is a readable PPM with exactly 320x200 pixels, or a separate working copy has been made at that size.
- The output was redirected to a new or temporary filename and has a successful exit status.
- The chosen dithering mode is explicit when a script or repeatable result matters.
- The binary output has been checked for existence and then opened or transferred with an Atari-compatible tool.
- The source image and any previous final output remain recoverable.