Home / Alt manpages / ppmtopj(1)

  • ppmtopj(1)
  • User command
  • linux

Convert a PPM Image into an HP PaintJet File with ppmtopj

An old HP PaintJet only understands its own printer language, and ppmtopj is the Netpbm tool that gets a PPM image into that format. You will finish with a PaintJet-format output file and a repeatable way to check that the conversion actually 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 viewer. It does not need sudo, and it does not touch 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. What matters is 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 a PPM header. The extension is only a naming convention; pick one that tells the next tool or operator what it is.

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 data was written, not that a particular PaintJet model will accept every feature in the stream. Test with the intended printer workflow before deleting the source.

4. Avoid overwriting a useful result

Warning

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 stays in place. Remove the incomplete .new file only after checking why it failed. If you want an extra 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

Recovery

Restore the backup with mv /path/to/output.pj.backup /path/to/output.pj. Do not run that restore until you have confirmed 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
  • Accepted values: none, snap, bw, dither, diffuse, monodither, monodiffuse, clusterdither and monoclusterdither.
  • It is visual and printer-dependent. Keep the source and compare printed results rather than assuming one algorithm wins outright.

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 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. Note the spelling: 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 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 needs 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 several conversions may run at once, and do not remove temporary files until you have checked the output. An alternative is ppmdither -red 2 -green 2 -blue 2, which can feed a dithered PPM stream straight 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 there is no useful undo 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

A zero exit status is not proof the printer will produce the page you want. Confirm the 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.