Home / Alt manpages / jpegtopnm(1)

  • jpegtopnm(1)
  • User command
  • linux

Convert JPEG Images to PPM or PGM with jpegtopnm

jpegtopnm turns a JPEG or JFIF file into a Netpbm PPM or PGM image, and it is also the tool you reach for when the JPEG itself is slightly broken. Allow about ten minutes for a straightforward conversion, or longer if you need to inspect EXIF data or recover a damaged image.

1. Check the installed command

This guide uses the netpbm package. The command available on this machine is Netpbm 11.5.2, built from source dated 31 March 2024, with an installed manual page dated 20 March 2023. Netpbm releases can differ, so check the local version before relying on a detail in a script.

$ command -v jpegtopnm
/usr/bin/jpegtopnm
$ jpegtopnm --version 2>&1 | head -1
jpegtopnm: Using libnetpbm from Netpbm Version: Netpbm 11.5.2

No elevated privileges are needed when the input is readable and the destination is a directory you can write to. Do not use sudo merely because the input is an image.

2. Convert one JPEG to PPM or PGM

Give the input path and redirect standard output to a new destination. A colour JPEG produces PPM; a greyscale JPEG produces PGM.

$ jpegtopnm /path/to/input.jpg > converted.ppm

The command normally prints the converted image to standard output, not a progress report. A failed conversion can still leave a partial destination behind, because the shell creates the redirected file before the program runs. Choose a new name, or use a temporary file and replace the destination only after checking the exit status:

$ tmp=$(mktemp ./converted.ppm.XXXXXX)
$ if jpegtopnm /path/to/input.jpg > "$tmp"; then
>     mv -- "$tmp" converted.ppm
> else
>     status=$?
>     rm -f -- "$tmp"
>     exit "$status"
> fi

The temporary-file example changes state in the current directory and replaces converted.ppm on success. If the conversion fails, it removes only the temporary file and leaves an existing destination alone. The final mv is local to one filesystem and does not alter the JPEG.

3. Verify the PNM output

Check that the output exists and is not empty. The file command should identify a Netpbm PPM or PGM image and report its dimensions; exact wording varies between file versions.

$ test -s converted.ppm && file converted.ppm
converted.ppm: Netpbm image data, size 1920 x 1080, rawbits, pixmap

Keep the original JPEG until you have opened or further converted the result. PPM and PGM are uncompressed interchange formats, so their files can be much larger than the source. A 12-bit JFIF input produces two bytes per sample; use pamdepth if a later tool needs one-byte samples.

4. Use standard input and output in a pipeline

With no filename, jpegtopnm reads standard input. This makes it useful in a pipeline, but binary image data must stay on standard output. Send diagnostics to a terminal or a separate file descriptor rather than mixing text into the image.

$ jpegtopnm < input.jpg > output.ppm
$ jpegtopnm input.jpg | ppmtopgm > output.pgm

The first command still chooses PPM or PGM according to the JPEG. The second explicitly turns the converted image into greyscale with ppmtopgm. If the upstream command fails, check the pipeline's exit status in the shell you use; a file can exist even when it is incomplete.

5. Convert a stream containing several JPEG images

By default, the command expects one JFIF image and stops after that image. Add -multiple when the input stream contains several JFIF images back to back:

$ cat first.jpg second.jpg > images.bin
$ jpegtopnm -multiple images.bin > images.ppm

This writes one PPM or PGM image for each input image, as a concatenated PNM stream, not automatically two files with separate names. Use a Netpbm tool that understands a multi-image stream when you need to process the results one at a time.

Do not add -multiple automatically to files that may contain data after the JPEG. The manual records that the default reverted in Netpbm 10.23 because some files contain a JFIF image followed by something else. The ordinary one-image mode is the safer choice for a normal standalone file.

6. Extract or inspect EXIF metadata

Use -dumpexif to print the interpreted EXIF header to standard error while the converted image still goes to standard output:

$ jpegtopnm -dumpexif input.jpg > output.ppm 2> exif.txt
$ sed -n '1,20p' exif.txt

If you need the original EXIF header bytes, write them to a separate file with -exif. A header file can be passed to pnmtojpeg when creating another JPEG.

$ jpegtopnm -exif=metadata.exif input.jpg > output.ppm
$ file metadata.exif

If the input has no EXIF header, the command writes two zero bytes to the requested EXIF file. Treat that file as binary data, not as text. With -exif=-, the header goes to standard output instead and the converted image is not written there, so do not combine that form with a normal PPM redirection.

7. Handle damaged or unusual JPEGs carefully

For a truncated file, the normal conversion can fail. -repair asks the program to salvage available image data and produce a valid PNM where it can. The recovered lower part may be padded with grey, so this is a recovery attempt, not a restoration of missing pixels.

$ jpegtopnm -repair damaged.jpg > recovered.ppm
$ file recovered.ppm

Keep both the damaged source and the first output. Compare the recovered image with the source in another viewer before replacing anything. Some invalid JPEG forms still fail, and some are salvaged without this option.

For CMYK or YCCK JPEGs, an incorrect Adobe colour interpretation can make the output look like a negative. The installed command normally assumes the Photoshop variation. If the result is visibly inverted, try the input-specific alternative:

$ jpegtopnm -adobe input.jpg > adobe.ppm
$ jpegtopnm -notadobe input.jpg > not-adobe.ppm

These options have no effect on ordinary non-CMYK and non-YCCK images.

Common traps

  • Wrong output type: the command chooses PGM for greyscale input and PPM otherwise; the extension you type does not control the format.
  • Overwriting a file: > truncates its destination before conversion starts. Use the temporary-file pattern when the existing output matters.
  • Unexpected quality or speed: -dct int is the default. -dct fast is faster but less accurate, while -dct float is slightly more accurate but usually slower and may vary between machines.
  • Large memory use: -maxmemory N limits processing memory in thousands of bytes, or millions when suffixed with M. The JPEGMEM environment variable supplies a default, and an explicit option overrides it.

Done means

  • Command and version checked: jpegtopnm is installed and its version is known.
  • Source untouched: the JPEG remains unchanged and the PPM or PGM destination is non-empty.
  • Output verified: file reports the expected PNM type and dimensions.
  • Extras deliberate: any EXIF extraction, repair, or multi-image handling was chosen deliberately and checked separately.