Convert PBM Images to MacPaint Files with pbmtomacp
Somebody wants a PBM turned into something classic Mac OS can open, and pbmtomacp writes that MacPaint data fork to standard output.
The route
Jump straight to the step you need, or tick off Done means at the end.
Budget about ten minutes. The examples here use the pbmtomacp installed by Netpbm 11.05.02-1.1build1 on this machine, and the local manual is dated 26 April 2015, so a version check matters before you trust anything it says.
You need a shell, a readable PBM file, and permission to write the output somewhere. The conversion is unprivileged, read-only on the input, and needs no sudo.
1. Check the installed command
Confirm the executable and package version before relying on a result:
$ command -v pbmtomacp
/usr/bin/pbmtomacp
$ dpkg-query -W -f='${Package} ${Version}\n' netpbm
netpbm 2:11.05.02-1.1build1
- Reads PBM from a named file, or from standard input when you give it none.
- Writes MacPaint data to standard output, so redirect it somewhere new.
- Keep input and output names visibly different while testing.
Checkpoint
If command -v prints nothing, install Netpbm through your normal package-management process. Do not create a replacement script with the same name in a directory earlier in PATH.
2. Convert a PBM file
Replace the two path placeholders with real files. The input is read-only; the redirection creates or truncates the output file:
$ pbmtomacp /path/to/input.pbm > /path/to/output.pntg
$ printf 'exit status: %s\n' "$?"
exit status: 0
Exit status 0 only means the program finished. It does not prove the image is the one you meant, so look at the output before you delete the PBM source.
Warning
Redirection with > truncates an existing destination before pbmtomacp even starts. That is the main destructive trap here. If the destination already matters, pick a fresh name or back it up first:
$ cp --preserve=all /path/to/output.pntg /path/to/output.pntg.bak
$ pbmtomacp /path/to/input.pbm > /path/to/output.pntg.new
$ mv /path/to/output.pntg.new /path/to/output.pntg
The old destination only changes once a new conversion has finished. If conversion fails, remove the incomplete output.pntg.new and restore the backup with mv if you need to. Do not run a blind rm against the backup until the replacement has been checked.
3. Verify the result as binary output
Check that the file exists and is not empty:
$ file /path/to/output.pntg
/path/to/output.pntg: data
$ test -s /path/to/output.pntg && echo 'output is non-empty'
output is non-empty
The exact wording from file varies. What matters is that the destination exists, has a non-zero size, and came from a command that exited cleanly. Do not expect file to recognise a MacPaint data fork as a self-describing image: the manual is explicit that this output is only the data fork.
For a size check you can actually reproduce, run the same conversion with -norle into a separate test file:
$ pbmtomacp -norle /path/to/input.pbm > /tmp/pbmtomacp-norle.pntg
$ stat -c '%s bytes' /tmp/pbmtomacp-norle.pntg
53072 bytes
Example
-norle switches off run-length encoding, and the manual documents exactly 53072 bytes for this mode: the theoretical maximum size for a MacPaint image. It is a testing tool, not a way to keep files small. Normal output is compressed, so its size depends on the image.
4. Crop an image that is too large
MacPaint has a fixed canvas. By default pbmtomacp converts the whole PBM, but an oversized image gets cut to fit from the top-left corner you specify:
- -left, -right, -top, -bottom select the rectangle (the installed manual also accepts the equivalent double-hyphen spelling).
- Use dimensions from the actual image. Do not guess a rectangle from the output file size; open the PBM or inspect it with another Netpbm tool first.
$ pbmtomacp -left 0 -top 0 -right 576 -bottom 720 \
/path/to/large.pbm > /path/to/large-crop.pntg
These crop switches exist for backward compatibility. The manual recommends pamcut for the more flexible Netpbm workflow: crop to a separate PBM, inspect that intermediate image, then convert it:
$ pamcut -left 0 -top 0 -right 576 -bottom 720 \
/path/to/large.pbm > /tmp/large-crop.pbm
$ pbmtomacp /tmp/large-crop.pbm > /path/to/large-crop.pntg
This assumes your installed pamcut accepts the same rectangle values for your image. If it reports an invalid boundary, fix the crop command rather than asking pbmtomacp to silently discard content.
5. Feed it standard input when that suits the pipeline
With no PBM file argument, pbmtomacp reads standard input, so you can chain it straight after another Netpbm producer without an intermediate file:
$ pbmmake -black 576 720 | pbmtomacp > /path/to/black.pntg
$ test -s /path/to/black.pntg && echo 'pipeline output is non-empty'
pipeline output is non-empty
Only use this when the preceding command genuinely emits PBM. If pbmtomacp reports that the first byte is not a Netpbm magic number, check the producer, the pipe, and the input path: an empty file, a text error message, or a different image format is not valid PBM input.
6. Package the data fork only when required
The output from pbmtomacp is not a complete MacBinary or BinHex file. The manual says you need a program such as mcvert to add the metadata that tells classic Mac OS this is a PNTG file. Do not rename the data fork and assume that renaming supplies it.
If a receiving workflow explicitly needs MacBinary or BinHex, check that mcvert is installed and follow its own documentation. If the consumer accepts the raw data fork, leave the pbmtomacp output as it is. This is a format boundary, not a conversion error.
Common traps
- Error about the first byte. Usually means the input is empty or is not PBM. Check with
file /path/to/input.pbmand leave the original alone. - Failure to open the input. Points to the path or read permission. Fix the path first; reach for elevated privileges only when the input directory genuinely requires them, and write output somewhere your normal account can review.
- Surprisingly large normal output. May be fine. Run a separate
-norletest to tell the fixed test size apart from ordinary compressed output. - Visually wrong result with status 0. Check PBM dimensions and crop boundaries: a clean exit code is not an image review.
There is no persistent state to undo here. To recover from a bad output, delete only the known output file or restore the backup, and keep the original PBM until the MacPaint file has been accepted by its target software.
Done means
- pbmtomacp resolves to the intended Netpbm installation.
- The conversion exits with status 0 and creates a non-empty output file.
- You have checked the image and have not accidentally overwritten a useful destination.
- You know it is a data fork only, and have reached for
mcvertif the receiving format needs it.