Skip to content
YadeWira edited this page Jun 10, 2026 · 2 revisions

FAQ

Is it really lossless?

Yes. The .pjg decompresses back to a byte-exact copy of the original .jpg. SHA-256 comparison passes. The whole point of packJPG is that you get the original file back — every byte, including all metadata, EXIF, ICC profiles, comment markers, and any non-standard segments.

If you want to verify on your own files, use -ver:

packJPG a -ver photo.jpg

-ver decompresses and compares against the source after each encode. Slower, but proves the roundtrip.


Why doesn't it compress more?

JPEG is already a lossy DCT-compressed format. The redundancy packJPG removes is in the Huffman entropy coding stage plus contextual correlations between neighbour DCT blocks. There isn't much more left after that.

Typical ratios:

Image type Reduction
Natural photo, JPEG quality 80–95 18–25 %
Synthetic / sharp-edge image 25–35 %
Already-very-aggressive JPEG (Q < 60) 10–15 %
Already-recompressed-by-something-else usually nothing

If you're seeing < 5 %, the file probably isn't a normal JPEG — check that it's actually JPEG (look for the 0xFFD8 start-of-image marker) and not a renamed PNG/HEIC.


Will it lose my EXIF / metadata?

No, by default. Everything between the JPEG markers is preserved bit-for-bit, including non-standard application markers.

If you want to discard metadata for size, use -d:

packJPG a -d photo.jpg

That drops EXIF/ICC/comment segments before recompression. The decompressed JPEG will be missing those segments — irreversible.


Is it safe to use on hosted images / production?

For archival use, yes — the roundtrip is bit-exact and packJPG has been around since 2007. The format has been stable across the v4.0 LTS line.

For serving over HTTP, no — .pjg isn't a browser-supported image format. Decode to .jpg first, or use a different format (WebP, JXL, AVIF) for web delivery.


Why is .pjg not a regular JPEG file?

.pjg is packJPG's intermediate format. Browsers can't display it. To view, decompress back to .jpg first:

packJPG x photo.pjg

If you need .jpg files at rest and .pjg only for transport / backups, packJPG fits well. If you need the file on disk to also be a viewable image, packJPG isn't the right tool.


What's -sfth and when should I use it?

-sfth is "single-file three-cores threading" — it parallelizes the pre-pack stages of a single file across 3 CPU cores. Useful when you have one large JPEG to compress and want it done faster.

For batch compression of many JPEGs, -th<N> is better — it parallelizes by file instead, scaling with core count up to whatever you set. Example: -th8 runs 8 JPEGs in parallel.

-sfth and -th<N> produce slightly different .pjg formats internally (sub-marker 0x01 for -sfth), but both roundtrip to identical .jpg output.


Does it work on progressive JPEGs?

Yes. packJPG detects the SOF marker (0xC0 baseline, 0xC1 extended sequential, 0xC2 progressive) and handles all three. No special flag needed.


What about CMYK / 16-bit / weird JPEGs?

  • CMYK (4 components): supported.
  • Grayscale (1 component): supported.
  • YCbCr 4:4:4 / 4:2:0 / 4:2:2: supported.
  • 12-bit JPEG: not supported. Convert to 8-bit first, or keep the original.
  • Lossless JPEG (ITU-T T.81 Annex H): not supported — packJPG handles standard DCT-based JPEGs only.
  • JPEG 2000 / JPEG XR / JPEG XL: completely different formats, not supported.

How does packJPG compare to Brunsli, Lepton, JXL?

See Comparison with other tools for the full table. Short version:

  • Brunsli is faster on decode but loses 1–2 % ratio.
  • Lepton matches packJPG on ratio (NSDI '17 paper). Repo archived since 2023.
  • JXL --lossless_jpeg trails packJPG by ~4 % on tested corpora.

packJPG sits on the Pareto ratio frontier for JPEG lossless recompression.


Is the format frozen?

The v4.0 line is format-stable since v4.0b. v4.0c, v4.0d and v4.0e added no new format markers — .pjg output is byte-exact across v4.0b/c/d/e. (v4.0e added an embedding library API and a decompression guard, but nothing that touches the on-disk format.)

A future major version (v4.1 / v5.0) could introduce a format break, but none is currently planned. The ratio plateau has been confirmed empirically (see Comparison with other tools) so format breaks targeting better ratios aren't on the roadmap.


Can I use it as a library?

Yes. Build with make lib for a static library (packJPGlib.a) or make dll for a shared library. Headers:

  • source/packjpglib.h — static library API.
  • source/packjpgdll.h — shared library API.

See docs/howtocompile.md.


Is this the original packJPG?

This repo (YadeWira/packJPG) is a maintained fork of packjpg/packJPG by the original author Matthias Stirner. The original is GPL-3.0, has been mostly inactive since 2017, and last shipped v2.5k.

This fork picks up where it stopped: re-licensed compatible (LGPL-3.0), C++17 modernization, thread safety, SoF1 / SoF2 progressive support, native parallelism, and the v4.x format generation. See Migration from upstream if you're switching from the original.