Home / Alt manpages / ppmtopj(1)

  • ppmtopj(1)
  • User command
  • linux

Convert a PPM Image into an HP PaintJet File with ppmtopj

You will finish with a PaintJet-format output file generated from a PPM image, plus a repeatable way to check that the conversion wrote data. The examples use Netpbm 11.5.2, installed here as package version 2:11.05.02-1.1build1.

Allow about fifteen minutes. You need a readable PPM file, the ppmtopj command, and enough disk space for a second output file. The command produces printer data, not a replacement image for a normal image viewer. It does not need sudo, and it does not change printer configuration.

1. Check the installed command

Confirm which executable your shell will run and record the Netpbm version. These are ordinary read-only commands:

$ command -v ppmtopj
/usr/bin/ppmtopj
$ ppmtopj --version
ppmtopj: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
...

The version output includes build details after the first line. The option names in this guide are those accepted by that installed build. If your host reports a different Netpbm release, check its local manual with man ppmtopj before putting the command into a script.

2. Check the input PPM

ppmtopj accepts one optional PPM filename. With no filename, it reads standard input, which is useful in a pipeline. Start by checking the file without modifying it:

$ file /path/to/input.ppm
/path/to/input.ppm: Netpbm image data, size 640 x 480, rawbits, pixmap
$ test -r /path/to/input.ppm && echo readable
readable

The exact wording from file depends on the PPM encoding. The useful checks are that the path is the file you intend to convert and that it is readable. PPM means Portable Pixmap, and the input should be RGB data. The manual says the best results normally come from an 8-colour RGB image, using only the full-on and full-off combinations of red, green and blue.

3. Convert to a new output file

Redirect standard output to a new filename. This is the core conversion:

$ ppmtopj /path/to/input.ppm > /path/to/output.pj
$ test -s /path/to/output.pj && echo "PaintJet output is non-empty"
PaintJet output is non-empty

A successful command is usually quiet. The output is a binary printer stream, so do not open it in a text editor or expect it to contain a PPM header. The extension is only a naming convention; choose one that makes the destination clear to the next tool or operator.

Checkpoint: the source should still exist, and the destination should have a non-zero size:

$ stat -c '%n %s bytes' /path/to/input.ppm /path/to/output.pj
/path/to/input.ppm 123456 bytes
/path/to/output.pj 78901 bytes

Your sizes will differ. A non-zero file proves that data was written, not that a particular PaintJet model will accept every feature in the stream. Test the file with the intended printer workflow before deleting the source.

4. Avoid overwriting a useful result

Shell redirection with > truncates an existing destination before ppmtopj starts. Treat this as a destructive action when the output already matters. Write a temporary file in the same directory, verify it, then replace the old file deliberately:

$ ppmtopj /path/to/input.ppm > /path/to/output.pj.new
$ test -s /path/to/output.pj.new
$ mv /path/to/output.pj.new /path/to/output.pj

If conversion fails, the old output.pj remains in place. Remove the incomplete .new file only after checking why the conversion failed. If you need an additional rollback copy, make it before the replacement:

$ cp --preserve=all /path/to/output.pj /path/to/output.pj.backup
$ mv /path/to/output.pj.new /path/to/output.pj

To undo that replacement, restore the backup with mv /path/to/output.pj.backup /path/to/output.pj. Do not run the restore until you have confirmed that the backup is the file you want; mv changes directory state and can overwrite a destination.

5. Choose placement and rendering

The default internal rendering algorithm is dither. Select another documented algorithm with -render when the default gives an unsuitable result:

$ ppmtopj -render none /path/to/input.ppm > /path/to/output-none.pj
$ ppmtopj -render diffuse /path/to/input.ppm > /path/to/output-diffuse.pj

The accepted values are none, snap, bw, dither, diffuse, monodither, monodiffuse, clusterdither and monoclusterdither. Rendering is a visual and printer-dependent choice. Keep the source and compare printed results rather than assuming one algorithm is universally best.

Use the centring switch to centre the image on an 8.5 by 11 page:

$ ppmtopj -center /path/to/input.ppm > /path/to/output-centred.pj

Use -xpos and -ypos to move the image by a number of pixels in the corresponding direction:

$ ppmtopj -xpos 24 -ypos 12 /path/to/input.ppm > /path/to/output-offset.pj

These positions are output-layout settings, not image resizing. Make small changes and keep each result under a distinct filename while you find the printer's usable area.

6. Handle colour and compression options

-back dark or -back lite tells the renderer whether the background is dark or light compared with the foreground. The spelling is lite, not light:

$ ppmtopj -back lite /path/to/input.ppm > /path/to/output-light-background.pj

-gamma int applies gamma correction using an integer value. Its default is 0; leave it out unless you have a reason to change the tonal response:

$ ppmtopj -gamma 1 /path/to/input.ppm > /path/to/output-gamma1.pj

The -rle option enables run-length encoding, but the manual warns that it can make the output larger. Measure the result instead of enabling it by habit:

$ ppmtopj -rle /path/to/input.ppm > /path/to/output-rle.pj
$ stat -c '%s bytes' /path/to/output-rle.pj

None of these options requires elevated privileges. They affect the generated stream only; they do not alter the PPM source or a running print service.

7. Prepare difficult colour input

If the source has more colours than the target handles well, reduce it before conversion. Netpbm documents an 8-colour workflow using a generated map and pnmremap:

$ pamseq 3 1 -tupletype=RGB > /tmp/ppmtopj-8colour-map.pam
$ pnmremap -map /tmp/ppmtopj-8colour-map.pam /path/to/input.ppm > /tmp/ppmtopj-remapped.ppm
$ ppmtopj /tmp/ppmtopj-remapped.ppm > /path/to/output-8colour.pj
$ rm /tmp/ppmtopj-8colour-map.pam /tmp/ppmtopj-remapped.ppm

Use a private temporary directory if multiple conversions may run at once, and do not remove temporary files until the output has been checked. An alternative is ppmdither -red 2 -green 2 -blue 2, which can feed a dithered PPM stream into ppmtopj:

$ ppmdither -red 2 -green 2 -blue 2 /path/to/input.ppm | ppmtopj > /path/to/output-dithered.pj

Keep the original image. These preprocessing commands create a new representation and do not provide a useful undo operation for the colour reduction itself.

8. Diagnose a failed conversion

If the command prints its usage text and exits non-zero, check option spelling and values. For example, -render nope is invalid, and -back needs dark or lite. Re-run the simplest command first, then add one option at a time.

If the input cannot be opened, check the exact path and permissions:

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

If the output is empty or missing, inspect the command's exit status before using it in a pipeline:

$ ppmtopj /path/to/input.ppm > /path/to/output.pj
$ printf 'exit status: %s, output bytes: ' "$?"
$ wc -c < /path/to/output.pj

Do not treat a zero exit status as proof that the printer will produce the desired page. Confirm the generated file is non-empty, then test with the target PaintJet device or its approved print path. For a service or shared printer, ask the owner before sending test data; this guide does not start, stop or reconfigure services.

Done means

  • You confirmed the installed Netpbm version and the input PPM is readable.
  • ppmtopj wrote a non-empty PaintJet output file.
  • You used a new or temporary destination so an existing result was not silently truncated.
  • Any rendering, placement, gamma, background or RLE option was chosen deliberately.
  • You kept the original PPM and know how to restore a backup if a replacement was made.