# DjVu reading and text-layer evidence

Test date: 2026-09-14. These are original teaching pages, not an OCR benchmark.

## Downloadable files

`samples/source-page-1.png` and `source-page-2.png` contain six original lines.
`image-only.djvu`, `correct-text.djvu`, and `wrong-text.djvu` each contain those
same two page images. We manually inserted the correct or deliberately wrong
hidden text; no OCR engine generated it. The wrong layer changes 18 to 13 and
the digit zero in B-204 to the letter O in B-2O4.

`samples/results.json` records every command, exit, raw extraction, byte count,
SHA256 and image comparison. All six DjVu page renders exactly matched the
corresponding source pixels. The output PDF was made from `correct-text.djvu`
by `ddjvu -format=pdf`; `pdftotext` returned two form feeds and no text.
The deliberately truncated negative-control DjVu is created only in a temporary
directory and is not distributed. Its decoder exited 10 rather than returning
a successful empty page/text result.

## Reproduce the original samples

Requirements: Python, Pillow (12.3.0 in this run), Poppler (`pdftotext`,
`pdfinfo`, and `pdfimages`, version 26.08.0
in this run), and DjVuLibre with TIFF/PDF output support. The supplied script
does not install software, use the network, run OCR, or process your books.
Use a **new output directory**; it refuses to overwrite an existing one.

Obtain DjVuLibre from https://djvu.sourceforge.net/ and use your platform's
installation instructions. Our private build used the official archive
`djvulibre-3.5.30.tar.gz` (SHA256
`ee5e457d4cfebe566f94b99e5e3d3cc7f5c79ddb741c2ac2ba2e456f00329644`).
The archive was labelled 3.5.30, but its configure output and compiled tools
reported 3.5.29. We retain both identifiers instead of relabelling the binary.
The macOS build enabled libtiff 4.7.2 and jpeg-turbo, with a private install
prefix; no GUI reader was built or tested.

Download the unmodified [Noto Sans font](/downloads/blog/fix-pdf-copy-paste-text/fonts/NotoSans-Regular.ttf)
and retain its [SIL Open Font License](/downloads/blog/fix-pdf-copy-paste-text/fonts/OFL.txt).
This is the same font used in our PDF text-layer examples;
the script records its hash. No font is embedded in the DjVu or PDF: their
visible text is rasterized into the original page images.

```sh
python3 reproduce.py --djvu-bin /path/to/djvulibre/bin --font NotoSans-Regular.ttf --output ./new-djvu-samples
```

The expected result is `status: PASS`, five grouped tests and 23 commands.
The groups contain additional assertions: three page counts, six pixel
comparisons, correct/empty/incorrect text checks, PDF page count and text, two
PDF embedded-image pixel comparisons, and the negative decoder
exit. `ddjvu --help` intentionally exits 1 while printing its version; that is
not a failed decode.

PDF metadata/IDs can vary by execution. Compare the semantic assertions, page
pixels and text, not a new PDF's hash against the historical PDF hash. Font,
Pillow and decoder changes can also alter regenerated image/encoding bytes.

## Reproduce the long-book check

`book-inspection.json` identifies the exact Internet Archive file and its
checksums. The file was downloaded on September 11 and matched refreshed
metadata on September 14. Obtain it from its source according to the source's
access and use conditions; we do not redistribute the scan or its full text.

Commands used (run in an empty working directory with `book.djvu` a copy of
that source and DjVuLibre available on PATH):

```sh
djvused book.djvu -e n
djvutxt book.djvu book-extracted.txt
ddjvu -format=pnm -size=600x800 -eachpage book.djvu page-%03d.pnm
ddjvu -format=pnm -page=10 book.djvu page-10-full.pnm
ddjvu -format=pdf -page=1,5,10,125,251 book.djvu selected-pages.pdf
pdftotext selected-pages.pdf selected-pages.txt
pdfinfo selected-pages.pdf
```

All 251 pages rendered at a maximum 600 × 800 pixels. Full-resolution visual
sampling covered file pages 1, 5, 10, 125 and 251; repeat the fourth command
with those numbers to inspect them. The PDF conversion covered **only those
five pages**, not the whole book. The selected PDF had five pages and no
non-whitespace extracted text. An empty final source page visibly rendered
as empty; an empty extraction is not a completeness test.

## Limitations

No GUI reader, phone, e-reader, screen reader, OCR recognizer, repair workflow,
BookTranslator upload or translation was tested. This is not a ranking of
readers or a measured OCR accuracy result. The long-book run checks decoding
and selected-page observations, not the printed volume's completeness or full
text accuracy. The two-page samples isolate mechanisms and do not model every
DjVu document or every PDF conversion program.

The writer inspected the samples and five full-resolution book pages; a
separate editorial reviewer must check the article before publication. The
fixture construction is transparent, not a blinded evaluation.
