Repository navigation
What PJA handles
YadeWira edited this page Nov 7, 2026
·
4 revisions
JPEG
- baseline, extended and progressive, with Huffman or arithmetic coding
- 8 and 12 bits, any subsampling, restart markers
- the JPEGs inside a JPEG, each compressed as a JPEG of its own: EXIF thumbnails, the further images of an MPO (stereo pairs, panoramas), Ultra HDR gain maps
- lossless JPEG (SOF3), 2 to 16 bits, every predictor, point transforms, restarts
- the height given in a DNL segment
- the oddities real encoders leave: extra restart markers, EOB runs cut by the table, data after the end, a DRI with no restart markers, and refinement scans whose EOB runs end sooner than libjpeg's, as Photoshop's progressive JPEGs do (since 0.0.8)
- since 0.5.0, repaired and the repairs kept: restart markers numbered
wrong (Second Nature's slide shows) and stray bytes between a scan and
the next marker (Xara); since 0.5.2, a scan that ends before its last
block, a download cut short included, read on as libjpeg
does (kept only when smaller than as bytes);
pja asaysrepaired: ... - in 7-Zip (libpja), since 0.5.0: the JPEG tiles FlashPix, Picture It's and
PhotoDraw's
.mixand TIFF keep without their tables, given the tables their container keeps once; since 0.5.2, the standard tables when the container keeps none (Konica's Q-Photo.kqp,.pic)
JPEG-LS
- 2 to 16 bits, lossless and near-lossless, every interleave mode
- subsampled components (no interleave, or line interleave without restarts)
JPEG 2000 (since 0.9.5: JP2, JPX, JPM, Motion JPEG 2000, JPH and raw
codestreams, .jp2, .j2k, .j2c, .jpx, .mj2...)
- each Part 1 codestream taken apart, its code-blocks' decisions coded again with a context-mixing model, and put back together byte for byte (packet headers, the MQ coder and how each encoder ends its segments: OpenJPEG, JasPer, Kakadu, LuraTech, Adobe, Aware, ECW)
- a lossless codestream may instead be kept as its pixels, through a pixel model, when that is smaller: bitonal (1-bit) book pages come out more than two thirds smaller (70.6% on the Internet Archive's)
- on 113 real-world codestreams (book pages, maps, solar and satellite images, DICOM; 150 MB) 8.4% smaller, 17% on the book pages; on 30 files from seven encoders, 11.7%
- slower than JPEG: about 0.1 to 0.25 MB/s to compress and 0.2 to 0.5 MB/s to extract on one thread; a tiled codestream, the two modes of a lossless one, and a file's frames or layers use several threads
- since 0.9.6, HTJ2K (
.jph,.jhc, DICOM frames): each HT code-block's segments decoded and written again exactly as their encoder ended them (OpenJPH, Grok, OpenHTJ2K, Kakadu), its values through a model, or a lossless codestream's pixels through the pixel models: 11% smaller on 716 real codestreams (460 MB of cinema frames, DICOM and photos), 27% on lossless and lossy photos - in zpaq-std since 0.9.6 through the
pja2kcodec (Part 1, the decisions' model; its ZPAQL lets any zpaq extract it); the 7-Zip plugin leaves JPEG 2000 files as they are, for now
Anything else that starts like a JPEG still goes through, with a model
for raw bytes, and pja a says why (as bytes: ...). The JPEGs PJA does
not take as images:
- hierarchical JPEG (no encoder in use writes it)
- lossless JPEG with arithmetic coding (SOF11), or with subsampled components
- JPEG-LS with a point transform, or with subsampled components in sample interleave
- JPEG 2000 Part 2 codestreams, and damaged ones
A file that does not get smaller is stored as it is.
PJA keeps a file as an image only if it can rebuild it bit for bit from what it decoded; otherwise it falls back to bytes. Tested on a corpus of JPEGs of every kind, 151 photos, 244 arithmetic-coded JPEGs, 640 generated ones, 12-bit and lossless sets, JPEG-LS photos, and 286 JPEGs taken out of documents and archives.