Skip to content

Use cases

YadeWira edited this page May 6, 2026 · 1 revision

Use cases

When packJPG is the right tool, when it isn't, and what people actually use it for.


What packJPG is good for

1. Long-term archival of JPEG photos

You have a folder of family photos, a wedding shoot, a client deliverable — JPEGs you'll keep for decades but rarely access. packJPG cuts ~20 % off the storage with bit-exact recovery on demand. Cheaper backup bills, identical originals when you need them.

packJPG a -r -od /backup/photos /source/photos

2. Version control of image-heavy repositories

Git LFS billing scales with bandwidth and storage. Storing .pjg instead of .jpg shaves 20 % off both axes for free, and the decode is fast enough that a pre-commit / post-checkout hook can transparently convert.

3. "Download original" buttons on image-hosting sites

Flickr, DeviantArt, ArtStation, Wikimedia Commons, photo stock sites — anywhere users upload a JPEG and expect to download the same JPEG byte-for-byte. Storing in .pjg form on the server saves hosting cost; decode on demand when the user clicks "download original".

This is where re-encoding to WebP/JXL/AVIF would break the contract. The user uploaded a JPEG; they expect a JPEG back. packJPG keeps that promise.

4. Email / message attachments where the recipient might re-share

When a JPEG bounces through messaging platforms, each platform's recompression destroys quality. Pre-compressing with packJPG and asking the recipient to decode preserves the original. Niche but real for photographers exchanging proofs.

5. Digital forensics / legal hold

Any context where the JPEG bytes themselves are evidence — chain-of-custody requires the bit-exact file. packJPG's roundtrip guarantees this; lossy re-encoders don't.

6. Bandwidth-constrained transfer

Mobile uploads, satellite links, slow rural internet. Compressing with packJPG before transmission and decoding on arrival saves ~20 % on every transfer.

7. Cold storage compression layer

Tier-2 / tier-3 storage (S3 Glacier, etc.) where retrieval is rare. Apply packJPG before the cold-storage upload, decode on retrieval. The CPU cost amortizes against months of cheaper storage.


What packJPG is NOT for

Web image delivery

Browsers don't render .pjg. Don't put .pjg files behind a <img src>. Use WebP / JXL / AVIF for HTTP delivery — they're smaller AND browser-native.

Lossy compression / quality reduction

packJPG is lossless. If your goal is "make the JPEG smaller at a quality cost", use a re-encoder (mozjpeg, guetzli, cjxl, imagemagick -quality). packJPG won't do that — by design.

Non-JPEG inputs

PNG, WebP, HEIC, RAW formats — none of these are JPEG. packJPG won't touch them. For PNG, see packPNG (sister project, same author).

Real-time video frames

JPEG-encoded video frames (MJPEG, motion-JPEG security cameras) work in principle, but the per-frame overhead is high. Real-time pipelines should use a video codec, not per-frame packJPG.

Already-recompressed JPEGs

If a JPEG has been through several lossy round-trips (e.g., uploaded → resized → re-encoded → re-uploaded by various platforms), the redundancy structure is already disturbed and packJPG yields modest gains. It still works, just less impressively.


Real-world deployment patterns

Backup script (Linux, cron)

#!/bin/sh
# Compress new JPEGs in $SRC into $DST as .pjg, daily.
SRC=/photos
DST=/backup/photos.pjg
find "$SRC" -name '*.jpg' -newer "$DST/.lastrun" \
    | xargs -P4 -I{} packJPG a -od"$DST" {}
touch "$DST/.lastrun"

Application library integration

Build packJPG as a static library:

make lib

Link against packJPGlib.a, include packjpglib.h. The library API exposes encode/decode for in-memory buffers — useful for embedding in upload pipelines, image-hosting backends, etc.

Pre-commit Git LFS hook (sketch)

# .git/hooks/pre-commit
for f in $(git diff --cached --name-only --diff-filter=A | grep '\.jpg$'); do
    packJPG a -np "$f"
    git rm --cached "$f"
    git add "${f%.jpg}.pjg"
done

(Don't actually deploy this without thinking about the team workflow — this is a sketch.)


Sizing intuition

Input Typical .pjg size
5 MB DSLR JPEG, quality 95 ~3.9 MB (-22 %)
1 MB phone photo, quality 90 ~810 KB (-19 %)
50 KB thumbnail, quality 80 ~42 KB (-16 %)
100 KB scanner output, quality 100 ~75 KB (-25 %)
10 KB favicon-style JPEG ~9 KB (overhead dominates at this size)

CPU cost on a modern desktop CPU: encode at ~20-30 MB/s of raw JPEG input, decode at ~25-40 MB/s. Embarrassingly parallel via -thN.