Skip to content

Library and 7 Zip

YadeWira edited this page Nov 2, 2026 · 5 revisions

Library and 7-Zip

Since 0.2.0 every release has a pja-<version>-lib-<platform> archive: libpja (pja.dll, pja.so or pja.dylib), its header pja.h and LIBRARY.md. The one file is two things.

A codec for 7-Zip and 7-Zip-zstd

Put the library in the Codecs folder next to 7-Zip (create it if it is not there):

  • Windows: next to 7z.exe, for 7-Zip or 7-Zip-zstd, 64-bit library for 64-bit 7-Zip, 32-bit for 32-bit (the other one gives "Codec Load Error: ... is not a valid Win32 application");
  • Linux and macOS: next to 7z and 7z.so, 7-Zip 23 or later (not p7zip).

7z i then lists 37F02 PJA (and 37F01 PJA1, 0.2.0's method, for its archives), and

7z a -m0=PJA -m1=LZMA2 photos.7z photos/     # 7-Zip
7z a -m0=PJA -m1=zstd  photos.7z photos/     # 7-Zip-zstd
7z x photos.7z

From 7-Zip's window: in Add to archive (archive format 7z), write 0=PJA 1=LZMA2 in Parameters (7-Zip-zstd: 0=PJA 1=zstd). 0=PJA alone also works (a tip from maadjordan), but then nothing comes after PJA in the chain: every byte that is not a JPEG (other files, EXIF) is stored as it is. Measured with two JPEGs and a 120 KB text file: 126 KB with 0=PJA, 52 KB with 0=PJA 1=LZMA2, 55 KB with LZMA2 alone. Extracting or testing from the window needs nothing but the plugin in Codecs.

PJA works as a filter: it finds the JPEG and JPEG-LS files in the solid block, recompresses them, and hands every other byte to LZMA2 or zstd, which match what PJA leaves (EXIF blocks, other files). PJA's own data goes into the archive by a second stream, with what repeats between files taken out (one image saved several times, progressive or not, gives the same coefficients). Extracting needs the plugin too.

set 7-Zip + PJA Aqueous pja alone
151 photos 72.57%, 10.9 / 5.6 s 80.46%, 2.3 / 0.7 s 72.61%, 10.8 / 5.3 s
78 JPEGs of every kind 66.86% 71.91% 70.39%
6 MPO 73.39% 78.94% 73.38%
244 arithmetic-coded 17.25% 85.71% 74.59%
640 generated (12 images, many encodings) 16.40% 33.96% 73.73%

Since 0.5.0 it also takes the JPEGs that FlashPix, Picture It's and PhotoDraw's .mix and TIFF keep as tiles without their tables (the container keeps them once, apart): 34 such files of the sample corpus in one archive, 71.92% with 0.4.0, the same as plain LZMA2, and 59.55% now.

Speeds and the rest of the numbers: doc/LIBRARY.md. The method IDs are provisional (in 7-Zip's slot for an experimental method) until 7-Zip assigns PJA its own; archives written with them will keep opening.

A C library

pja.h, for any program:

void *out; size_t n;
if (pja_compress(jpeg, size, &out, &n, 4) == PJA_OK) {   /* a .pja */
  /* ... */
  pja_free(out);
}
  • pja_compress / pja_decompress: one file in memory to a .pja (the command's format, size and hash inside) and back.
  • pja_filter_encode / pja_filter_decode: the filter 7-Zip uses, over read and write callbacks, for an archiver that writes many files as one stream.

Every function can be called from several threads; errors are return codes. pas/lib/test_lib.c is the test and an example.

Clone this wiki locally