Skip to content

What PJA handles

YadeWira edited this page Nov 7, 2026 · 4 revisions

What PJA handles

Modeled as images

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 a says repaired: ...
  • in 7-Zip (libpja), since 0.5.0: the JPEG tiles FlashPix, Picture It's and PhotoDraw's .mix and 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 pja2k codec (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

As bytes

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.

Every case is checked

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.

Clone this wiki locally