Home / Alt manpages / sputoppm(1)

  • sputoppm(1)
  • User command
  • linux

Convert an Atari Spectrum File to PPM with sputoppm

sputoppm turns an uncompressed Atari Spectrum file into a PPM image, and this guide checks the result comes out at the expected 320 x 200. The examples use Netpbm 11.5.2, Debian package version 2:11.05.02-1.1build1.

Ten minutes. You need a shell, the netpbm package, and a readable uncompressed Spectrum file. No elevated privileges required. The input format is specialised: a plain PPM, a PNG, or a compressed Spectrum file will not do.

1. Check the installed command

Confirm which executable runs and record the local Netpbm version. Both are read-only checks:

$ command -v sputoppm
/usr/bin/sputoppm
$ dpkg-query -W -f='${Package} ${Version}\n' netpbm
netpbm 2:11.05.02-1.1build1
$ sputoppm --version 2>&1 | head -n 2
sputoppm: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
sputoppm: Built from source dated 2024-03-31 09:09:47

The manpage defines one optional positional argument, spufile. There are no sputoppm-specific options. With a filename it reads that file; with none, it reads standard input.

Checkpoint

Stop here if command -v finds nothing, or the package query says Netpbm is not installed. Do not work around a missing command by guessing at a different converter.

2. Confirm the input is the right kind of file

Never trust the filename alone. Check path, size and read permission without touching the file:

$ INPUT='/path/to/image.spu'
$ test -r "$INPUT" && echo 'input is readable'
input is readable
$ stat -c '%n %s bytes' "$INPUT"
/path/to/image.spu 51104 bytes

That size is the fixed shape this implementation expects: 32,000 bytes of screen data followed by 19,104 bytes of palette data. A file of that exact length can still be malformed, so treat this as a quick sanity check, not format authentication. If the file is compressed, reach for spctoppm instead; sputoppm only handles the uncompressed form.

Do not edit, truncate or rename the original while testing. Keep a copy of anything irreplaceable before you process it.

3. Convert to a new PPM file

Redirect standard output to a new destination. The command normally prints the image data itself, not a progress report:

$ sputoppm "$INPUT" > image.ppm
$ printf 'exit status: %s\n' "$?"
exit status: 0

Ordinary, unprivileged command. The output is raw PPM, marked with the P6 magic number, width 320, height 200, maximum channel value 7. Those values come straight from the decoded Spectrum data; the converter neither resizes the image nor preserves the original file as metadata.

Warning

Shell redirection with > truncates image.ppm before sputoppm even starts. If that file matters, write to a temporary destination first and only replace the old one after verification:

$ sputoppm "$INPUT" > image.ppm.new
$ file image.ppm.new
$ mv image.ppm.new image.ppm

That mv just renames within the current directory. If conversion fails, leave the existing image.ppm alone and remove the incomplete image.ppm.new once you have confirmed nothing else needs it.

4. Verify the PPM header and dimensions

Use file for a quick independent look, then check only the text header. Do not run binary pixel data through tools that might alter it:

$ file image.ppm
image.ppm: Netpbm image data, size = 320 x 200, rawbits, pixmap
$ head -c 12 image.ppm | od -An -tc
   P   6  \n   3   2   0       2   0   0  \n   7  \n

The whitespace in that od display can vary, but the sequence that matters is P6, then 320 200, then 7. Exit status alone only tells you the process completed; open the PPM with an image viewer or another Netpbm converter if you need to check the actual picture.

Checkpoint

Before archiving the result, confirm all three: the file exists, file reports 320 x 200, and the header starts with P6.

5. Read from standard input when that helps

The filename is optional, so a pipeline can supply the uncompressed Spectrum bytes directly. Output format does not change:

$ sputoppm < "$INPUT" > image-from-stdin.ppm
$ file image-from-stdin.ppm
image-from-stdin.ppm: Netpbm image data, size = 320 x 200, rawbits, pixmap

Only pipe from a command you actually understand. If you decompress an archive first, confirm the result really is the uncompressed Spectrum representation before handing it to sputoppm. Never assume a .spc or .spu extension tells you which converter is correct; check the content.

6. Diagnose failures without changing the source

An error opening the input usually means the path, permissions or file type is wrong. Recheck exactly what is held in INPUT:

$ printf 'input: %s\n' "$INPUT"
input: /path/to/image.spu
$ ls -l -- "$INPUT"
$ test -r "$INPUT" && echo readable || echo 'not readable'

Readable input but a broken output means: keep the source and inspect it with a format-aware tool, or find an actually uncompressed copy. Never fix a damaged file by padding it with zeros and then treat the result as authentic; a zero-filled file of the right length is only useful as a local smoke test of the converter itself.

If you end up with an incomplete replacement, delete only that temporary output after confirming its exact path:

$ test -f image.ppm.new && printf 'review before deleting: %s\n' "$PWD/image.ppm.new"
review before deleting: /current/directory/image.ppm.new
$ rm -- image.ppm.new

Warning

That last command is irreversible. It needs no sudo, and it should never point at the original Spectrum file or a PPM you have already verified.

Done means

  • Version checked. Installed Netpbm version and input path both confirmed.
  • Source protected. The uncompressed Spectrum file stayed untouched throughout.
  • Clean conversion. sputoppm produced a P6 PPM with no elevated privileges.
  • Dimensions right. Output reports 320 x 200 and a maximum channel value of 7.
  • Existing output safe. Anything valuable was protected from shell redirection.
  • Image checked before cleanup. You verified the result before discarding source or backups.