djvu-rs 0.30.0 → 0.30.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -2
- package/package.json +1 -1
- package/scalar/README.md +59 -2
- package/scalar/djvu_rs_bg.wasm +0 -0
- package/simd128/README.md +59 -2
- package/simd128/djvu_rs_bg.wasm +0 -0
package/README.md
CHANGED
|
@@ -20,6 +20,7 @@ specification.
|
|
|
20
20
|
| Convert DjVu → PDF, EPUB, TIFF, PNG, CBZ | [`djvu render`](#cli) or [`djvu_to_pdf`](#pdf-export) / [`djvu_to_epub`](#epub-export) / [`djvu_to_tiff`](#tiff-export) |
|
|
21
21
|
| Extract text (plain, hOCR, ALTO XML) | [`djvu text`](#cli) or [`page.text()`](#text-extraction), [`to_hocr` / `to_alto`](#hocr-and-alto-xml-export) |
|
|
22
22
|
| Render pages to RGBA pixels | [`render_pixmap`](#quick-start) — sync, [async](#async-render), or [parallel](#feature-flags) |
|
|
23
|
+
| Build a zoomable viewer (tiles) | [`djvu_tile`](#tile-rendering) — cached, prefetchable, cancellable tile rendering |
|
|
23
24
|
| Show DjVu in the browser | [WebAssembly bindings](#webassembly), incl. lazy HTTP-Range loading |
|
|
24
25
|
| Read DjVu from Python | `pip install djvu-rs` — [PyO3 bindings](#python) |
|
|
25
26
|
| Create DjVu from images (PNG/JPEG/TIFF) | [`djvu encode`](#cli) or [`PageEncoder`](#encoding--low-level-api) |
|
|
@@ -138,6 +139,8 @@ djvu split book.djvu --pages 10-25 --output chapter.djvu
|
|
|
138
139
|
djvu optimize book.djvu --output optimized.djvu --preset lossless-cleanup --dry-run
|
|
139
140
|
djvu optimize book.djvu --output optimized.djvu --preset lossless-cleanup
|
|
140
141
|
djvu optimize book.djvu --output optimized.djvu --preset archival --target-size 26214400
|
|
142
|
+
# (--max-ssim-loss is reserved for the planned archival re-encode; the current
|
|
143
|
+
# lossless cleanup is pixel-exact by construction and reports this)
|
|
141
144
|
djvu optimize book.djvu --output optimized.djvu --max-ssim-loss 0.001
|
|
142
145
|
|
|
143
146
|
# Encode an image (PNG, JPEG, or TIFF) into a single-page DjVu (bilevel JB2, lossless)
|
|
@@ -432,6 +435,45 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
|
432
435
|
}
|
|
433
436
|
```
|
|
434
437
|
|
|
438
|
+
### Tile rendering
|
|
439
|
+
|
|
440
|
+
For viewer engines: [`djvu_tile`](https://docs.rs/djvu-rs/latest/djvu_rs/djvu_tile/)
|
|
441
|
+
renders a page as a display-space tile grid over the region renderer. Tile
|
|
442
|
+
pixels are byte-identical to the same rectangle of a full-page render, in any
|
|
443
|
+
request order.
|
|
444
|
+
|
|
445
|
+
```rust,no_run
|
|
446
|
+
use djvu_rs::{DjVuDocument, djvu_render::RenderOptions};
|
|
447
|
+
use djvu_rs::djvu_tile::{TileLayout, render_tile_cached};
|
|
448
|
+
|
|
449
|
+
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
450
|
+
let data = std::fs::read("book.djvu")?;
|
|
451
|
+
let doc = DjVuDocument::parse(&data)?;
|
|
452
|
+
let page = doc.page(0)?;
|
|
453
|
+
|
|
454
|
+
let opts = RenderOptions { width: 2400, height: 3200, ..Default::default() };
|
|
455
|
+
let layout = TileLayout::new(page, &opts, 256)?;
|
|
456
|
+
|
|
457
|
+
for row in 0..layout.rows() {
|
|
458
|
+
for col in 0..layout.cols() {
|
|
459
|
+
let tile = render_tile_cached(page, &opts, 256, col, row)?;
|
|
460
|
+
// tile.data — RGBA bytes of exactly this tile rectangle
|
|
461
|
+
let _ = tile;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
Ok(())
|
|
465
|
+
}
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
`render_tile_cached` memoizes composited tiles per page; the cache is
|
|
469
|
+
tile-granular and controllable (`tile_cache_usage`, `set_tile_cache_budget`,
|
|
470
|
+
`clear_tile_cache`, `invalidate_tile_region`). `render_tile_with` +
|
|
471
|
+
`TileRenderControls` / `TileCancelToken` add progressive quality steps and
|
|
472
|
+
cooperative cancellation, and with the `parallel` feature `prefetch_tiles` /
|
|
473
|
+
`prefetch_tiles_cancellable` warm the cache in the background with a bounded
|
|
474
|
+
worker pool. The full contract lives in
|
|
475
|
+
[`docs/tile-rendering.md`](docs/tile-rendering.md).
|
|
476
|
+
|
|
435
477
|
## Encoding & low-level API
|
|
436
478
|
|
|
437
479
|
### JB2 bilevel image encoder
|
|
@@ -551,6 +593,16 @@ whole is not transactional). Opening an indirect index directly with
|
|
|
551
593
|
`DjVuDocumentMut::from_bytes` and calling `page_mut` remains unsupported; see
|
|
552
594
|
[`docs/indirect-djvm-mutation.md`](docs/indirect-djvm-mutation.md).
|
|
553
595
|
|
|
596
|
+
The reverse direction is covered too: `djvm::to_indirect` splits a bundled
|
|
597
|
+
`FORM:DJVM` into an indirect index plus standalone component files, keeping
|
|
598
|
+
component ids, names, titles, and the document `NAVM` stable. Related
|
|
599
|
+
bundled-document operations in the same module: `djvm::remove_pages` deletes
|
|
600
|
+
pages with an explicit `UnreachablePolicy` (preserve or garbage-collect shared
|
|
601
|
+
components that lose their last including page),
|
|
602
|
+
`djvm::dedup_shared_components` merges byte-identical shared components, and
|
|
603
|
+
`djvm::DjvmStreamWriter` writes a bundle to any `io::Write` sink with memory
|
|
604
|
+
bounded to the spooled component being appended.
|
|
605
|
+
|
|
554
606
|
### Typed document editing
|
|
555
607
|
|
|
556
608
|
`DocumentEditor` provides a versioned, typed operation list with a semantic
|
|
@@ -687,7 +739,9 @@ Honest boundaries, so you can decide fast:
|
|
|
687
739
|
and single-page `FORM:DJVU` only; indirect returns a clean `Unsupported`
|
|
688
740
|
error.
|
|
689
741
|
- **`create_indirect` does not emit shared `DJVI` dictionary components** —
|
|
690
|
-
build a bundled document with `djvu merge` when pages share a dictionary
|
|
742
|
+
build a bundled document with `djvu merge` when pages share a dictionary, or
|
|
743
|
+
convert an existing bundled document with `djvm::to_indirect`, which
|
|
744
|
+
preserves shared components.
|
|
691
745
|
- **Encoder size parity is corpus- and profile-dependent.** Run the
|
|
692
746
|
reproducible [`encoder parity scorecard`](docs/encoder-parity.md) to compare
|
|
693
747
|
the same raster through DjVuLibre 3.5.29's `c44`/`cjb2` and the archival-safe
|
|
@@ -767,7 +821,10 @@ combinations and targets), and is enforced in CI. In short:
|
|
|
767
821
|
[`tests/panic_free_corpus.rs`](tests/panic_free_corpus.rs), proptests, and
|
|
768
822
|
libFuzzer/OSS-Fuzz targets.
|
|
769
823
|
- **Resource limits** — decode/render inherit documented, bounded memory/work
|
|
770
|
-
ceilings; exceeding one returns a typed error naming the codec and axis.
|
|
824
|
+
ceilings; exceeding one returns a typed error naming the codec and axis. The
|
|
825
|
+
ceilings are caller-configurable: pass `ResourceLimits` via `ParseOptions` to
|
|
826
|
+
`DjVuDocument::parse_with_options` (pages inherit them at render time), or
|
|
827
|
+
use `render_pixmap_with_limits` / `render_into_with_limits` directly. See
|
|
771
828
|
[`SECURITY.md`](SECURITY.md#decode-time-resource-ceilings).
|
|
772
829
|
|
|
773
830
|
## Performance
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "djvu-rs",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"description": "Read, render, convert, and create DjVu files. Pure-Rust DjVu decoder/encoder with CLI, WebAssembly, and Python bindings. DjVu to PDF, EPUB, TIFF, PNG, and text. MIT licensed, no GPL dependencies.",
|
|
5
|
-
"version": "0.30.
|
|
5
|
+
"version": "0.30.2",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
package/scalar/README.md
CHANGED
|
@@ -20,6 +20,7 @@ specification.
|
|
|
20
20
|
| Convert DjVu → PDF, EPUB, TIFF, PNG, CBZ | [`djvu render`](#cli) or [`djvu_to_pdf`](#pdf-export) / [`djvu_to_epub`](#epub-export) / [`djvu_to_tiff`](#tiff-export) |
|
|
21
21
|
| Extract text (plain, hOCR, ALTO XML) | [`djvu text`](#cli) or [`page.text()`](#text-extraction), [`to_hocr` / `to_alto`](#hocr-and-alto-xml-export) |
|
|
22
22
|
| Render pages to RGBA pixels | [`render_pixmap`](#quick-start) — sync, [async](#async-render), or [parallel](#feature-flags) |
|
|
23
|
+
| Build a zoomable viewer (tiles) | [`djvu_tile`](#tile-rendering) — cached, prefetchable, cancellable tile rendering |
|
|
23
24
|
| Show DjVu in the browser | [WebAssembly bindings](#webassembly), incl. lazy HTTP-Range loading |
|
|
24
25
|
| Read DjVu from Python | `pip install djvu-rs` — [PyO3 bindings](#python) |
|
|
25
26
|
| Create DjVu from images (PNG/JPEG/TIFF) | [`djvu encode`](#cli) or [`PageEncoder`](#encoding--low-level-api) |
|
|
@@ -138,6 +139,8 @@ djvu split book.djvu --pages 10-25 --output chapter.djvu
|
|
|
138
139
|
djvu optimize book.djvu --output optimized.djvu --preset lossless-cleanup --dry-run
|
|
139
140
|
djvu optimize book.djvu --output optimized.djvu --preset lossless-cleanup
|
|
140
141
|
djvu optimize book.djvu --output optimized.djvu --preset archival --target-size 26214400
|
|
142
|
+
# (--max-ssim-loss is reserved for the planned archival re-encode; the current
|
|
143
|
+
# lossless cleanup is pixel-exact by construction and reports this)
|
|
141
144
|
djvu optimize book.djvu --output optimized.djvu --max-ssim-loss 0.001
|
|
142
145
|
|
|
143
146
|
# Encode an image (PNG, JPEG, or TIFF) into a single-page DjVu (bilevel JB2, lossless)
|
|
@@ -432,6 +435,45 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
|
432
435
|
}
|
|
433
436
|
```
|
|
434
437
|
|
|
438
|
+
### Tile rendering
|
|
439
|
+
|
|
440
|
+
For viewer engines: [`djvu_tile`](https://docs.rs/djvu-rs/latest/djvu_rs/djvu_tile/)
|
|
441
|
+
renders a page as a display-space tile grid over the region renderer. Tile
|
|
442
|
+
pixels are byte-identical to the same rectangle of a full-page render, in any
|
|
443
|
+
request order.
|
|
444
|
+
|
|
445
|
+
```rust,no_run
|
|
446
|
+
use djvu_rs::{DjVuDocument, djvu_render::RenderOptions};
|
|
447
|
+
use djvu_rs::djvu_tile::{TileLayout, render_tile_cached};
|
|
448
|
+
|
|
449
|
+
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
450
|
+
let data = std::fs::read("book.djvu")?;
|
|
451
|
+
let doc = DjVuDocument::parse(&data)?;
|
|
452
|
+
let page = doc.page(0)?;
|
|
453
|
+
|
|
454
|
+
let opts = RenderOptions { width: 2400, height: 3200, ..Default::default() };
|
|
455
|
+
let layout = TileLayout::new(page, &opts, 256)?;
|
|
456
|
+
|
|
457
|
+
for row in 0..layout.rows() {
|
|
458
|
+
for col in 0..layout.cols() {
|
|
459
|
+
let tile = render_tile_cached(page, &opts, 256, col, row)?;
|
|
460
|
+
// tile.data — RGBA bytes of exactly this tile rectangle
|
|
461
|
+
let _ = tile;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
Ok(())
|
|
465
|
+
}
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
`render_tile_cached` memoizes composited tiles per page; the cache is
|
|
469
|
+
tile-granular and controllable (`tile_cache_usage`, `set_tile_cache_budget`,
|
|
470
|
+
`clear_tile_cache`, `invalidate_tile_region`). `render_tile_with` +
|
|
471
|
+
`TileRenderControls` / `TileCancelToken` add progressive quality steps and
|
|
472
|
+
cooperative cancellation, and with the `parallel` feature `prefetch_tiles` /
|
|
473
|
+
`prefetch_tiles_cancellable` warm the cache in the background with a bounded
|
|
474
|
+
worker pool. The full contract lives in
|
|
475
|
+
[`docs/tile-rendering.md`](docs/tile-rendering.md).
|
|
476
|
+
|
|
435
477
|
## Encoding & low-level API
|
|
436
478
|
|
|
437
479
|
### JB2 bilevel image encoder
|
|
@@ -551,6 +593,16 @@ whole is not transactional). Opening an indirect index directly with
|
|
|
551
593
|
`DjVuDocumentMut::from_bytes` and calling `page_mut` remains unsupported; see
|
|
552
594
|
[`docs/indirect-djvm-mutation.md`](docs/indirect-djvm-mutation.md).
|
|
553
595
|
|
|
596
|
+
The reverse direction is covered too: `djvm::to_indirect` splits a bundled
|
|
597
|
+
`FORM:DJVM` into an indirect index plus standalone component files, keeping
|
|
598
|
+
component ids, names, titles, and the document `NAVM` stable. Related
|
|
599
|
+
bundled-document operations in the same module: `djvm::remove_pages` deletes
|
|
600
|
+
pages with an explicit `UnreachablePolicy` (preserve or garbage-collect shared
|
|
601
|
+
components that lose their last including page),
|
|
602
|
+
`djvm::dedup_shared_components` merges byte-identical shared components, and
|
|
603
|
+
`djvm::DjvmStreamWriter` writes a bundle to any `io::Write` sink with memory
|
|
604
|
+
bounded to the spooled component being appended.
|
|
605
|
+
|
|
554
606
|
### Typed document editing
|
|
555
607
|
|
|
556
608
|
`DocumentEditor` provides a versioned, typed operation list with a semantic
|
|
@@ -687,7 +739,9 @@ Honest boundaries, so you can decide fast:
|
|
|
687
739
|
and single-page `FORM:DJVU` only; indirect returns a clean `Unsupported`
|
|
688
740
|
error.
|
|
689
741
|
- **`create_indirect` does not emit shared `DJVI` dictionary components** —
|
|
690
|
-
build a bundled document with `djvu merge` when pages share a dictionary
|
|
742
|
+
build a bundled document with `djvu merge` when pages share a dictionary, or
|
|
743
|
+
convert an existing bundled document with `djvm::to_indirect`, which
|
|
744
|
+
preserves shared components.
|
|
691
745
|
- **Encoder size parity is corpus- and profile-dependent.** Run the
|
|
692
746
|
reproducible [`encoder parity scorecard`](docs/encoder-parity.md) to compare
|
|
693
747
|
the same raster through DjVuLibre 3.5.29's `c44`/`cjb2` and the archival-safe
|
|
@@ -767,7 +821,10 @@ combinations and targets), and is enforced in CI. In short:
|
|
|
767
821
|
[`tests/panic_free_corpus.rs`](tests/panic_free_corpus.rs), proptests, and
|
|
768
822
|
libFuzzer/OSS-Fuzz targets.
|
|
769
823
|
- **Resource limits** — decode/render inherit documented, bounded memory/work
|
|
770
|
-
ceilings; exceeding one returns a typed error naming the codec and axis.
|
|
824
|
+
ceilings; exceeding one returns a typed error naming the codec and axis. The
|
|
825
|
+
ceilings are caller-configurable: pass `ResourceLimits` via `ParseOptions` to
|
|
826
|
+
`DjVuDocument::parse_with_options` (pages inherit them at render time), or
|
|
827
|
+
use `render_pixmap_with_limits` / `render_into_with_limits` directly. See
|
|
771
828
|
[`SECURITY.md`](SECURITY.md#decode-time-resource-ceilings).
|
|
772
829
|
|
|
773
830
|
## Performance
|
package/scalar/djvu_rs_bg.wasm
CHANGED
|
Binary file
|
package/simd128/README.md
CHANGED
|
@@ -20,6 +20,7 @@ specification.
|
|
|
20
20
|
| Convert DjVu → PDF, EPUB, TIFF, PNG, CBZ | [`djvu render`](#cli) or [`djvu_to_pdf`](#pdf-export) / [`djvu_to_epub`](#epub-export) / [`djvu_to_tiff`](#tiff-export) |
|
|
21
21
|
| Extract text (plain, hOCR, ALTO XML) | [`djvu text`](#cli) or [`page.text()`](#text-extraction), [`to_hocr` / `to_alto`](#hocr-and-alto-xml-export) |
|
|
22
22
|
| Render pages to RGBA pixels | [`render_pixmap`](#quick-start) — sync, [async](#async-render), or [parallel](#feature-flags) |
|
|
23
|
+
| Build a zoomable viewer (tiles) | [`djvu_tile`](#tile-rendering) — cached, prefetchable, cancellable tile rendering |
|
|
23
24
|
| Show DjVu in the browser | [WebAssembly bindings](#webassembly), incl. lazy HTTP-Range loading |
|
|
24
25
|
| Read DjVu from Python | `pip install djvu-rs` — [PyO3 bindings](#python) |
|
|
25
26
|
| Create DjVu from images (PNG/JPEG/TIFF) | [`djvu encode`](#cli) or [`PageEncoder`](#encoding--low-level-api) |
|
|
@@ -138,6 +139,8 @@ djvu split book.djvu --pages 10-25 --output chapter.djvu
|
|
|
138
139
|
djvu optimize book.djvu --output optimized.djvu --preset lossless-cleanup --dry-run
|
|
139
140
|
djvu optimize book.djvu --output optimized.djvu --preset lossless-cleanup
|
|
140
141
|
djvu optimize book.djvu --output optimized.djvu --preset archival --target-size 26214400
|
|
142
|
+
# (--max-ssim-loss is reserved for the planned archival re-encode; the current
|
|
143
|
+
# lossless cleanup is pixel-exact by construction and reports this)
|
|
141
144
|
djvu optimize book.djvu --output optimized.djvu --max-ssim-loss 0.001
|
|
142
145
|
|
|
143
146
|
# Encode an image (PNG, JPEG, or TIFF) into a single-page DjVu (bilevel JB2, lossless)
|
|
@@ -432,6 +435,45 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
|
432
435
|
}
|
|
433
436
|
```
|
|
434
437
|
|
|
438
|
+
### Tile rendering
|
|
439
|
+
|
|
440
|
+
For viewer engines: [`djvu_tile`](https://docs.rs/djvu-rs/latest/djvu_rs/djvu_tile/)
|
|
441
|
+
renders a page as a display-space tile grid over the region renderer. Tile
|
|
442
|
+
pixels are byte-identical to the same rectangle of a full-page render, in any
|
|
443
|
+
request order.
|
|
444
|
+
|
|
445
|
+
```rust,no_run
|
|
446
|
+
use djvu_rs::{DjVuDocument, djvu_render::RenderOptions};
|
|
447
|
+
use djvu_rs::djvu_tile::{TileLayout, render_tile_cached};
|
|
448
|
+
|
|
449
|
+
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
450
|
+
let data = std::fs::read("book.djvu")?;
|
|
451
|
+
let doc = DjVuDocument::parse(&data)?;
|
|
452
|
+
let page = doc.page(0)?;
|
|
453
|
+
|
|
454
|
+
let opts = RenderOptions { width: 2400, height: 3200, ..Default::default() };
|
|
455
|
+
let layout = TileLayout::new(page, &opts, 256)?;
|
|
456
|
+
|
|
457
|
+
for row in 0..layout.rows() {
|
|
458
|
+
for col in 0..layout.cols() {
|
|
459
|
+
let tile = render_tile_cached(page, &opts, 256, col, row)?;
|
|
460
|
+
// tile.data — RGBA bytes of exactly this tile rectangle
|
|
461
|
+
let _ = tile;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
Ok(())
|
|
465
|
+
}
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
`render_tile_cached` memoizes composited tiles per page; the cache is
|
|
469
|
+
tile-granular and controllable (`tile_cache_usage`, `set_tile_cache_budget`,
|
|
470
|
+
`clear_tile_cache`, `invalidate_tile_region`). `render_tile_with` +
|
|
471
|
+
`TileRenderControls` / `TileCancelToken` add progressive quality steps and
|
|
472
|
+
cooperative cancellation, and with the `parallel` feature `prefetch_tiles` /
|
|
473
|
+
`prefetch_tiles_cancellable` warm the cache in the background with a bounded
|
|
474
|
+
worker pool. The full contract lives in
|
|
475
|
+
[`docs/tile-rendering.md`](docs/tile-rendering.md).
|
|
476
|
+
|
|
435
477
|
## Encoding & low-level API
|
|
436
478
|
|
|
437
479
|
### JB2 bilevel image encoder
|
|
@@ -551,6 +593,16 @@ whole is not transactional). Opening an indirect index directly with
|
|
|
551
593
|
`DjVuDocumentMut::from_bytes` and calling `page_mut` remains unsupported; see
|
|
552
594
|
[`docs/indirect-djvm-mutation.md`](docs/indirect-djvm-mutation.md).
|
|
553
595
|
|
|
596
|
+
The reverse direction is covered too: `djvm::to_indirect` splits a bundled
|
|
597
|
+
`FORM:DJVM` into an indirect index plus standalone component files, keeping
|
|
598
|
+
component ids, names, titles, and the document `NAVM` stable. Related
|
|
599
|
+
bundled-document operations in the same module: `djvm::remove_pages` deletes
|
|
600
|
+
pages with an explicit `UnreachablePolicy` (preserve or garbage-collect shared
|
|
601
|
+
components that lose their last including page),
|
|
602
|
+
`djvm::dedup_shared_components` merges byte-identical shared components, and
|
|
603
|
+
`djvm::DjvmStreamWriter` writes a bundle to any `io::Write` sink with memory
|
|
604
|
+
bounded to the spooled component being appended.
|
|
605
|
+
|
|
554
606
|
### Typed document editing
|
|
555
607
|
|
|
556
608
|
`DocumentEditor` provides a versioned, typed operation list with a semantic
|
|
@@ -687,7 +739,9 @@ Honest boundaries, so you can decide fast:
|
|
|
687
739
|
and single-page `FORM:DJVU` only; indirect returns a clean `Unsupported`
|
|
688
740
|
error.
|
|
689
741
|
- **`create_indirect` does not emit shared `DJVI` dictionary components** —
|
|
690
|
-
build a bundled document with `djvu merge` when pages share a dictionary
|
|
742
|
+
build a bundled document with `djvu merge` when pages share a dictionary, or
|
|
743
|
+
convert an existing bundled document with `djvm::to_indirect`, which
|
|
744
|
+
preserves shared components.
|
|
691
745
|
- **Encoder size parity is corpus- and profile-dependent.** Run the
|
|
692
746
|
reproducible [`encoder parity scorecard`](docs/encoder-parity.md) to compare
|
|
693
747
|
the same raster through DjVuLibre 3.5.29's `c44`/`cjb2` and the archival-safe
|
|
@@ -767,7 +821,10 @@ combinations and targets), and is enforced in CI. In short:
|
|
|
767
821
|
[`tests/panic_free_corpus.rs`](tests/panic_free_corpus.rs), proptests, and
|
|
768
822
|
libFuzzer/OSS-Fuzz targets.
|
|
769
823
|
- **Resource limits** — decode/render inherit documented, bounded memory/work
|
|
770
|
-
ceilings; exceeding one returns a typed error naming the codec and axis.
|
|
824
|
+
ceilings; exceeding one returns a typed error naming the codec and axis. The
|
|
825
|
+
ceilings are caller-configurable: pass `ResourceLimits` via `ParseOptions` to
|
|
826
|
+
`DjVuDocument::parse_with_options` (pages inherit them at render time), or
|
|
827
|
+
use `render_pixmap_with_limits` / `render_into_with_limits` directly. See
|
|
771
828
|
[`SECURITY.md`](SECURITY.md#decode-time-resource-ceilings).
|
|
772
829
|
|
|
773
830
|
## Performance
|
package/simd128/djvu_rs_bg.wasm
CHANGED
|
Binary file
|