Copy PNM Images and Choose Plain or Raw Output with pnmtopnm
You will finish with a repeatable way to copy a PBM, PGM or PPM image through pnmtopnm, while deliberately choosing the plain ASCII or raw binary PNM subformat. The examples use Netpbm 11.5.2, provided here by package version 2:11.05.02-1.1build1.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about ten minutes. You need a shell, the Netpbm package and one PNM image. This guide reads the input and writes output; it does not modify the source image. No command here needs elevated privileges. If your input is valuable, keep the original and write to a new file until the result has been checked.
1. Check the installed command
Confirm which executable will run and ask it for the linked Netpbm library version:
$ command -v pnmtopnm
/usr/bin/pnmtopnm
$ pnmtopnm -version
pnmtopnm: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
pnmtopnm: Built from source dated 2024-03-31 09:09:47
The exact build lines can differ between distributions. The useful check is that the command exists and reports the library version you expect. The installed manual describes pnmtopnm as a copy operation: it preserves the major format, such as PGM, and the input maxval.
Checkpoint
If command -v prints nothing, install the Netpbm package using your normal package-management process. Do not replace it with an unrelated image converter when you need PNM-preserving behaviour.
2. Copy an image to a new file
Pass one input filename and redirect standard output to a separate destination:
$ pnmtopnm INPUT.pgm > copied.pgm
Replace INPUT.pgm with an existing PBM, PGM or PPM file. The argument is optional, so the same command can read from standard input:
$ some-pnm-producing-command | pnmtopnm > copied.pnm
There is no separate output filename option. Shell redirection owns the destination, which makes the usual shell cautions apply. Do not use the same path for input and output: the shell opens the destination before pnmtopnm reads the source, so you can truncate your only copy.
For a first test, make the destination a new path. The command normally produces no progress message, and a successful exit status is zero:
$ printf 'copy exit status: %s\n' "$?"
copy exit status: 0
Run that status check immediately after pnmtopnm. A later command would replace the status you are trying to inspect.
3. Force human-readable plain PNM
PNM has plain, also called ASCII, and raw, also called binary, subformats. Add the common Netpbm option -plain when another tool or a person needs the samples as text:
$ pnmtopnm -plain INPUT.pgm > readable.pgm
$ head -n 4 readable.pgm
P2
2 1
255
0 255
The header identifies P2 as plain grayscale PGM. A colour image would retain its major format and use the corresponding plain PNM magic number. Do not mistake a readable header for proof that every value is in the form you expected; inspect the complete file or use a PNM-aware checker when the data matters.
Plain output is useful for debugging a small image or inspecting a pipeline. It is usually larger and slower to parse than raw output. It is not a new image format and does not change the image's major type or maxval.
4. Force raw binary PNM
Omit -plain when you want raw output. This is the normal choice for programs that accept raw PNM or for a compact pipeline:
$ pnmtopnm INPUT.pgm > raw-copy.pgm
For the same 2 by 1, 8-bit grayscale image, the raw header begins with P5, followed by binary sample bytes. Do not inspect raw output with a terminal. Binary data may contain control characters, may alter terminal state and is difficult to compare by eye.
Use a byte-oriented command for a small verification instead:
$ od -An -tx1 -c raw-copy.pgm | head
50 35 0a 32 20 31 0a 32 35 35 0a 00 ff
P 5 \n 2 1 \n 2 5 5 \n \0 377
The bytes shown are an example for exactly that small input. Your dimensions, maxval and pixel bytes will differ. The first four fields should agree with the source's major type and geometry; the payload is binary and should be treated as data.
5. Verify the copy without overwriting the source
Compare the two files only after you have decided whether a byte-for-byte match is the right test. A raw input copied without -plain should normally produce the same bytes, but a plain input copied without that option is converted to raw, so the files represent the same image without being byte-identical:
$ file INPUT.pgm copied.pgm
$ wc -c INPUT.pgm copied.pgm
For a conversion where both files use the same subformat, a checksum is a useful exact check:
$ sha256sum INPUT.pgm copied.pgm
HASH INPUT.pgm
HASH copied.pgm
Matching hashes prove that the bytes match. Different hashes do not automatically mean the pixels changed: plain and raw encodings can differ while preserving the same PNM image. If the two encodings differ, verify with a reader that understands PNM, or compare the header fields and decoded samples.
Recovery
If you redirected output to the wrong new file, stop using that file and generate it again. If you accidentally used the input path as the destination, restore the original from a backup. pnmtopnm has no undo operation because shell redirection can truncate the file before the program starts.
6. Handle common failures
A missing input file, malformed PNM header or unreadable path produces a non-zero exit status and a diagnostic on standard error. Keep the diagnostic separate from image data: standard output is the image stream, while standard error is for messages.
$ pnmtopnm DOES-NOT-EXIST.pgm > failed-output.pgm
pnmtopnm: ...: No such file or directory
$ printf 'status: %s\n' "$?"
status: 1
The wording and the path details vary by build. A failed redirection may still leave an empty destination file, so check it before treating it as an output image. Replace it by rerunning to a known new path after fixing the input.
Do not add -plain to a command merely because the input is plain, and do not assume the absence of that option means the image has been recompressed. This program copies the PNM image and selects the output subformat; it is not a lossy photo encoder. Programs using the Netpbm library generally read both PNM subformats directly, while older or narrowly implemented tools may require raw or plain specifically.
Done means
- You confirmed the installed
pnmtopnmand Netpbm 11.5.2 version. - You wrote output to a new path instead of risking the source file.
- You used
-plainwhen text inspection or an ASCII-only consumer required it. - You omitted
-plainwhen raw binary PNM was the required output. - You checked the exit status and kept diagnostics separate from image data.
- You know that different plain and raw bytes can still represent the same image.