-
Notifications
You must be signed in to change notification settings - Fork 2
FAQ
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.
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.
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.
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.
.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.
-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.
Yes. packJPG detects the SOF marker (0xC0 baseline, 0xC1 extended sequential, 0xC2 progressive) and handles all three. No special flag needed.
- 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.
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_jpegtrails packJPG by ~4 % on tested corpora.
packJPG sits on the Pareto ratio frontier for JPEG lossless recompression.
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.
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.
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.