Releases
v0.17.0
Compare
Sorry, something went wrong.
No results found
0.17.0 (2026-05-04)
Features
add BZZ encoder with ZP arithmetic coding (582432f )
add fit_to_width/height/box to RenderOptions (#33 ) (b371a93 )
add NAVM bookmark encoder and ANTa/ANTz annotation encoder (#133 ) (#136 ) (9e6bf66 )
api: bundled DJVM mutation + set_bookmarks (PR3 of #222 ) (#268 ) (6672a93 )
api: DjVuDocumentMut::from_bytes — chunk-replacement primitive (PR1 of #222 ) (#263 ) (b6279ae )
api: high-level setters for DjVuDocumentMut (PR2 of #222 ) (#267 ) (eec0815 )
api: raw_chunk / all_chunks / chunk_ids on DjVuPage and DjVuDocument (Issue #43 ) (#54 ) (3135627 )
async: add native lazy page loader (735a226 )
async: add wasm lazy reader entrypoint (77fc6ff )
async: async render API via tokio::task::spawn_blocking (Issue #51 ) (#61 ) (452636f )
async: load_document_async — buffered AsyncRead constructor (#196 Phase 1) (#231 ) (2d85e65 )
async: page_byte_range API + streaming async loader (#196 Phase 2) (#237 ) (a365abb )
async: progressive stream render API (Issue #81 ) (#112 ) (eaff91d )
async: resolve lazy shared dictionaries (30d8ac9 )
bench: add render_scaled and pdf_export benchmarks + BENCHMARKS.md (Issue #52 ) (#62 ) (a8523c7 )
ci: add ocr-tesseract integration test + CI job (#178 ) (220671d )
ci: continuous benchmark tracking — PR regression detection (Issue #88 ) (#109 ) (0dfade5 )
cli: implement djvu info/render/text — 24/24 tests green (eb2e9d6 )
cli: multi-page djvu encode from a directory of PNGs (#223 follow-up) (#245 ) (b8858bb )
cos-djvu: benchmark suite, corpus infrastructure, BENCHMARKS.md (closes #282 ) (#332 ) (50b6933 )
cos-djvu: phase 1 — IFF parser, typed errors, MIT skeleton (closes #267 ) (#277 ) (1943f3f )
cos-djvu: phase 2a — ZP arithmetic coder + BZZ decompressor (closes #268 ) (#279 ) (4983056 )
cos-djvu: phase-5 rendering pipeline — compositing, gamma, scaling, AA (closes #273 ) (7f5e161 )
cos-djvu: phase-6 quality — fuzz targets, benchmarks, no_std, full docs (closes #274 ) (#324 ) (67fab7f )
cos-djvu: text layer + annotations extraction (closes #272 ) (#316 ) (5beeba9 )
djvm: add merge and split commands for DjVu documents (#126 ) (37eefd8 ), closes #76
djvu render --format pdf|cbz, roadmap v0.1 finalised (7d823f6 )
DjVu to PDF converter with text, bookmarks, and hyperlinks (#2 -#6 ) (#29 ) (a6f0a74 )
djvu-enc: high-level PageEncoder for bilevel Lossless (#218 ) (#243 ) (afefcef )
djvu-enc: minimal layered Quality (segment → Sjbz + BG44) (#246 ) (2febd04 )
document model — DjVuDocument, Page, DIRM, NAVM (closes #271 ) (#283 ) (e36fd41 )
epub: DPI-aware rendering, language tag, hyperlinks, cover image (191e386 )
epub: EPUB 3 export — page images, text overlay, navigation (Issue #74 ) (9a6d155 )
epub: opt-in reflowable text section per page (#228 ) (#240 ) (8207fb9 )
ffi: add C FFI bindings via extern "C" functions (#127 ) (2226bdf ), closes #72
fgbz-enc: FGbz foreground palette encoder (#217 ) (#241 ) (e43bc9f )
fuzz: add render to fuzz_full, add CI fuzz workflow (60 s/target) (7e3e4eb )
hOCR and ALTO XML export for text layer (Issue #75 ) (#98 ) (263cf14 )
implement ImageDecoder trait for image-rs integration (Issue #80 ) (#97 ) (d7e4a64 )
import cos-djvu history, remove GPL legacy code (0f33110 )
indirect DJVM — create_indirect() and parse_from_dir() (#135 ) (#137 ) (d7fbf74 )
IW44 wavelet decoder with planar YCbCr (closes #270 ) (#281 ) (f799e70 )
IW44 wavelet encoder — BG44/FG44 chunk encoding (issue #131 ) (#139 ) (10adc4f )
JB2 bilevel decoder (closes #269 ) (#280 ) (e2a6898 )
JB2 bilevel image encoder — Sjbz chunk encoding (issue #132 ) (#140 ) (cf280ba )
jb2-enc: expose tunable shared-Djbz clustering + corpus harness (#194 Phase 2) (#219 ) (9aafe42 )
jb2-enc: multi-page shared Djbz dictionary in DJVM bundle, Phase 1 (#194 ) (#216 ) (507b061 )
jb2-enc: symbol-dictionary encoder Phases 1-3 (#188 ) (#213 ) (8a2ed15 )
jb2: DJVI shared dictionary support via INCL chunks (Issue #45 ) (#56 ) (86a63cb )
mask and foreground/background layer extraction API (#36 ) (d4c6527 )
mask: wire Smmr (G4/MMR) decoder into both render pipelines (07272b3 )
metadata: METa/METz document metadata parsing (Issue #44 ) (#55 ) (eb4515b )
mmap: add memory-mapped I/O via MmapDocument (387a2ea ), closes #70
ocr: pluggable OCR backend trait with Tesseract, ONNX, and Candle backends (#125 ) (bf26603 ), closes #77
pdf: DCTDecode background encoding — smaller PDF output (Issue #49 ) (#59 ) (de90a9f )
pdf: parallel page rendering with rayon (#148 ) (ae79a7c )
progressive DjVu rendering, multi-book cache, cos-diagnostics crate (32432d8 )
python: add Python bindings via PyO3 (#128 ) (e250fff ), closes #71
render: add rayon-based parallel page rendering (3dc06f9 ), closes #69
render: BGjp/FGjp JPEG background/foreground decoder (Issue #47 ) (#57 ) (b65bd81 )
render: grayscale output mode — GrayPixmap + render_gray8 (c13ebb7 )
render: grayscale output mode — GrayPixmap + render_gray8 (Issue #15 ) (75d7b37 )
render: Lanczos-3 separable resampling (Issue #50 ) (#60 ) (56817d1 )
render: permissive render mode — skip corrupted chunks (dc5734a )
render: permissive render mode — skip corrupted chunks (Issue #19 ) (df5a8d7 )
render: public render_streaming API (Phase 2 of #225 ) (#260 ) (b92fac7 )
render: zero-copy region render — render_region API (Issue #86 ) (#111 ) (b2aa2a8 )
segment + cli: FG/BG segmentation v1 + djvu encode subcommand (#220 , #223 ) (#244 ) (4945b06 )
serde support for metadata, annotations, bookmarks, and text zones (Issue #82 ) (#96 ) (e872ecd )
smmr-enc: public Smmr (G4/MMR) encoder API (#221 ) (#242 ) (009c706 )
smmr: add G4/MMR bilevel image decoder (issue #134 ) (#138 ) (8bd6e41 )
text: add reflowable_text() for paragraph reading-order extraction (#228 ) (#239 ) (221a49a )
text: TextLayer::transform — rotate + scale zone rects for rendered pages (Issue #46 ) (#53 ) (c4a514e )
tiff: embed DPI resolution tags in exported TIFF files (87efb14 )
tiff: TIFF export — multi-page color and bilevel modes (Issue #48 ) (#58 ) (dc90cc0 )
transfer from cos-djvu, remove legacy GPL code, add PD corpus, benchmarks (33fd496 )
ui: table of contents navigation panel (closes #60 ) (#298 ) (3fb0b2a )
user-controllable rotation in RenderOptions (#35 ) (e0f79a8 )
wasm: add WasmPage::text_zones_json() — text selection overlay API (e513bbf ), closes #119
wasm: add WasmPage::text() — expose page text layer to JS (35a776d )
wasm: progressive IW44 render API (#150 ) (35d3a30 )
wasm: WebAssembly bindings via wasm-bindgen (Issue #73 ) (#118 ) (4300939 )
Bug Fixes
add missing chunk_data binding in iw44_new doctest (d1a210b )
annotation: add MAX_SEXPR_DEPTH=64 guard to prevent stack overflow on deeply nested S-expressions (#200 ) (2f03789 )
apply gamma correction in all legacy render paths (#9 ) (#22 ) (dfba614 )
apply page rotation from INFO chunk in render_pixmap and render_coarse (#10 ) (#24 ) (adec5ee )
ci: enable cli feature for nextest to build djvu binary (576f12f )
ci: exclude djvu-py from nextest, fix audit advisories (788b0d3 )
ci: exclude fuzz/ from workspace to fix cargo-fuzz builds (330ff0a )
ci: IJG license allowlist, no_std BTreeMap, clippy errors (6a2a391 )
ci: install libleptonica-dev + libtesseract-dev for ocr-tesseract job (0410f70 )
ci: split test into test-stable + test-beta jobs (matrix.rust not allowed in job if) (0d60c76 )
ci: use core::mem::take in no_std context; fix clippy redundant-Some in ocr_export test (#101 ) (cc1cdf1 )
clippy errors and fmt — let-chain, ref on let, line wrapping (b4ba2f8 )
clippy: use contains() instead of iter().any() in tiff_export (f9b4c2b )
docs: resolve all remaining broken intra-doc links (0 warnings) (4ac8bb1 )
docs: resolve broken intra-doc links in djvu_document (8dbfda0 )
eliminate memory leaks and add OOM protection (25f041d )
exclude .cargo/config.toml from published package (fixes docs.rs build) (b9dd0da )
FGbz multi-color foreground palette — use per-glyph blit index (#12 ) (#26 ) (7897164 )
fuzz: add [workspace] to fuzz/Cargo.toml to fix cargo-fuzz build (be7a5a8 )
fuzz: revert to cargo install cargo-fuzz, add explicit binary cache (84e6eef )
fuzz: use correct public module djvu_rs::jb2 in fuzz_jb2 target (9133de6 )
hard-rule: eliminate last 5 .expect()/.unwrap() in production code (Issue #443 ) (#444 ) (e4247ea )
iff: preserve FORM length parity for byte-identical mutation (PR4 of #222 ) (#269 ) (df1e95e )
iw44: correct vext lane in prelim_flags_band0_neon horizontal-OR (#266 ) (b390681 )
jb2_encode: return empty Vec for zero-dimension bitmaps; unreachable dead branch (#142 ) (#143 ) (091b657 )
jb2-enc: cap cluster_shared_symbols pixel budget at decoder limit (#270 ) (#271 ) (78e5c79 )
jb2-enc: tile direct encoder to ≤1MP records (#198 ) (#214 ) (24ac60f )
jb2,iw44: cap comment bytes and IW44 pixel limit to prevent fuzz timeouts (49c7b1b )
jb2,iw44: prevent DoS via refinement bitmaps and uncapped total pixel budget (3e72cf6 )
jb2: add blit-pixel budget to prevent type-7 dict-copy DoS (1c03505 )
jb2: cap decode loop at 1 M records to prevent infinite spin on exhausted ZP input (0b84f2d )
jb2: correct regression test comment for fuzz2 fix (ee380ae )
jb2: guard blit against negative symbol dimensions (49a3792 )
jb2: guard blit fast path against i32 overflow and data buffer overread (be72d29 )
jb2: limit symbol bitmap size to 4 MP to prevent DoS via crafted input (943f25e )
jb2: prevent infinite loop in decode_num on corrupt streams (d7bee1e ), closes #122
jb2: reduce MAX_RECORDS and MAX_SYMBOL_PIXELS to prevent fuzz timeouts (3292193 )
ocr: resolve all clippy errors in ocr_neural, ocr_onnx, ocr_tesseract (65a0cee )
pdf: Unicode-aware glyph width for invisible text layer (2398c38 )
remove deprecated [[licenses.deny]] syntax from deny.toml (cargo-deny v2) (7971e44 )
render: add #[allow(unsafe_code)] + unsafe blocks for Rust 2024 SIMD (#169 ) (179d171 )
render: correct gamma LUT formula to match DjVuLibre (#161 ) (cd3228d )
render: resolve unsafe_code / unsafe_op_in_unsafe_fn CI conflicts (889f28f )
render: restore bilevel composite fast path, recover 2× regression from #165 (46b6931 )
render: scale page-space coords into FG44 + BG plane space (#199 ) (#248 ) (e2c07df )
render: use core::arch instead of std::arch for no_std compatibility (122b989 )
replace all internal cos-djvu/cos_djvu references with djvu-rs/djvu_rs (03fb17a )
resolve issues #164 #169 #170 #174 #176 #177 (774cbdb )
smmr: replace manual div_ceil with .div_ceil() per clippy (a8d24ca )
update MSRV to 1.88 (let-chains stabilized in 1.88) (8d5b94f )
update tesseract API and optimize JB2 inner loop (f64d884 )
vendor djvu-rs into crates/cos-djvu and fix production panics (5f6d7fe ), closes #4
wasm CI job, open_dir API, DPI scaling in OCR export, jb2_new cleanup (6cbe038 )
wasm: correct render() pixel layout and Uint8ClampedArray allocation (1a967d2 )
zp: widen a/c/fence fields from u16 to u32 to match jb2 inline decoder (fb0db12 )
Performance Improvements
allow 1.5× upscale in IW44 subsample selection for faster downscaled renders (8f0baa2 )
area-averaging downscale for better quality when rendering at reduced size (#13 ) (#28 ) (b822ded )
bitmap: packed bitwise dilation with ping-pong buffers (2887689 )
bitmap: packed bitwise dilation with ping-pong buffers (Issue #17 ) (0814f55 )
bzz: inline ZP state locals in MTF decode hot loop (bad5b21 )
bzz: parallel inverse-BWT via rayon (Issue #89 ) (#110 ) (eb5bab0 )
ci: single nextest pass on main avoids sequential overhead (f17d901 )
deps: split ocr-neural into lightweight stub + ocr-neural-candle (#175 ) (3a930b2 )
downsampled mask pyramid for composite — 8 ms vs 23 ms for 150 dpi renders (1374f27 )
eliminate bounds checks in JB2 hot loops and ZP renormalize (7e94000 )
eliminate redundant mask sampling in 3-layer composite (#14 ) (#27 ) (f601036 )
iw44-enc: NEON forward wavelet + parallel Y/Cb/Cr + skip empty passes (#206 ) (d1f2765 )
iw44: allocate chroma planes at half resolution when chroma_half=true (Issue #85 ) (#99 ) (927e7c0 )
iw44: compact-plane wavelet for sub≥2 + correct start_scale (Issue #115 ) (#116 ) (4fc8921 )
iw44: NEON decoder — column pass s=2/4, scatter, YCbCr, lifting (~25% to_rgb) (#207 ) (f570297 )
iw44: SIMD row pass — 8 rows at a time with i32x8 (#107 ) (1418ff4 )
iw44: SIMD YCbCr→RGB using wide::i32x8 (Issue #1 ) (#64 ) (abceef4 )
iw44: SIMD-accelerate inverse wavelet transform column pass (2ac4318 ), closes #68
iw44: WASM simd128 ycbcr_raw kernels (Phase 1 of #190 ) (#253 ) (d59fcee )
iw44: x86_64 AVX2 ports of prelim_flags kernels (Phase 3 of #189 ) (#261 ) (0ed7a36 )
iw44: x86_64 AVX2 ycbcr_raw kernels (Phase 1 of #189 ) (#251 ) (7f3d867 )
jb2-enc: eliminate bounds checks from JB2 encode hot loop (#205 ) (5cbeaf0 )
jb2-enc: opt-in lossy rec-7 near-duplicate substitution (Phase 4 of #224 ) (#256 ) (98fb8c7 )
jb2-enc: per-CC accounting harness for shared-Djbz (#194 Phase 2.5) (#255 ) (f09bfdf )
jb2: bit-pack Jbm to 1 bit/pixel — 8x memory, corpus −3.9% (#187 ) (17f331f )
jb2: close performance gap vs DjVuLibre + CLI improvements (#159 ) (3efc430 )
jb2: local-copy ZP state for register-allocation + hardware CLZ (0590d3c )
jb2: reuse scratch buffer across symbol decodes to eliminate per-symbol heap allocations (Issue #90 ) (#100 ) (12575d0 )
jb2: shared dict cache + split_at_mut inner loop (Issue #87 ) (#106 ) (08ca0f4 )
partial BG44 chunk decode for sub=4 renders — skip high-frequency refinement (b371e4e )
pdf: output_dpi option + bilevel fast path — 2× faster export (cfccbc6 ), closes #147
render: 66% speedup on 600 dpi bilevel pages (Issue #104 ) (#105 ) (8e5a2f4 )
render: eliminate redundant mask sampling in 3-layer composite (Issue #14 ) (#37 ) (585991d )
render: internal row-streaming refactor (Phase 1 of #225 ) (#259 ) (3d22a59 )
render: NEON bilinear vertical pass + 4-byte RGBX stride (#93 ) (b0dfdb8 )
render: precomputed coord tables, zero-copy BG path, remove PageMapper (cf1a8e9 )
render: x86_64 SSE2/SSSE3 fast paths for alpha fill and RGB→RGBA (#169 ) (0ea3f3e )
replace bg_subsample division with shift in composite hot path (0e0f2a3 )
replace mask division with bit-shift in composite hot path (e4b7982 )
use chunks_exact_mut in composite loops — eliminate per-pixel bounds checks (0176860 )
You can’t perform that action at this time.