Files
Stirling-PDF/frontend/editor/src-tauri/thumbnail-handler/README.md
T
Anthony StirlingandGitHub 56ff1e5092 impl migration to pdfium for split (#6410)
## Summary

Migrates `SplitPDFController`, `SplitPdfByChaptersController`,
`SplitPdfBySizeController` from PDFBox to JPDFium.
`SplitPdfBySectionsController` and `AutoSplitPdfController` are
intentionally left on PDFBox (require JPDFium 1.0.2 features that don't
exist yet).

## Benchmark (audited on `audit/jpdfium-split`, file
`app/core/src/test/java/stirling/software/SPDF/bench/SplitBenchmark.java`)

| Workload | PDFBox heap | JPDFium heap | PDFBox wall | JPDFium wall |
|---|---|---|---|---|
| 100 pp, chunk 10 | +21-26 MB | **+0.02 MB** | 80-106 ms | **25 ms** |
| 300 pp, chunk 10 | +59 MB | **+1.0 MB** | 232 ms | **76 ms** |

**98-99.9% heap reduction. 3-4.2x faster wall.**

## Hybrid

- AcroForm-bearing splits keep PDFBox
`FormUtils.pruneOrphanedFormFields` post-pass (FPDF_ImportPagesByIndex
drops AcroForm dict). Sub-bench shows +1.0 MB / +27 ms - tightly
bounded.
- Metadata extraction stays on PDFBox.
- `SplitPdfBySectionsController` - JPDFium `PdfPageSplitter` only does
2-up halving, not arbitrary MxN.
- `AutoSplitPdfController` - needs PDFRenderer + zxing for QR markers.

## Test plan

- [ ] 30/30 unit tests pass with PDFBox `Loader.loadPDF` as the oracle
(assert page counts + document totals)
- [ ] Existing cucumber feature `split.feature` continues to pass
- [ ] AcroForm-bearing PDF round-trips without orphaned widgets (covered
by existing FormUtils tests)
2026-05-26 17:50:13 +01:00

2.6 KiB
Raw Blame History

Windows PDF Thumbnail Handler

A lightweight COM DLL that provides PDF page-preview thumbnails in Windows Explorer when Stirling-PDF is the default PDF application.

Why this exists

When Stirling-PDF registers as the default PDF handler, Windows associates .pdf files with Stirling's ProgID. Without a thumbnail handler on that ProgID, Explorer falls back to showing the application icon (the big S logo) instead of a page preview. This DLL restores thumbnail previews by implementing the Windows Shell IThumbnailProvider COM interface.

How it works

  1. Explorer requests a thumbnail — when a folder with PDFs is opened in Medium/Large icon view, Explorer loads the DLL via the registered COM CLSID.
  2. Shell calls IInitializeWithStream — passes the PDF file content as an IStream.
  3. Shell calls IThumbnailProvider::GetThumbnail(cx) — requests a bitmap of size cx × cx.
  4. The DLL renders page 1 using the built-in Windows.Data.Pdf WinRT API (the same engine Edge uses), preserving aspect ratio.
  5. WIC decodes the rendered PNG into BGRA pixels, which are copied into an HBITMAP via CreateDIBSection.
  6. Explorer displays the bitmap as the file's thumbnail.

All COM methods are wrapped in catch_unwind so a malformed PDF cannot crash Explorer.

Technical details

Language Rust (cdylib)
DLL size ~156 KB
External deps None — uses only Windows built-in APIs
PDF renderer Windows.Data.Pdf (WinRT, Windows 10+)
Image decode WIC (IWICImagingFactory) with BGRA32 format conversion
COM CLSID {2D2FBE3A-9A88-4308-A52E-7EF63CA7CF48}
Threading model Apartment (STA — standard for shell extensions)
Min Windows Windows 10

Registry entries (managed by MSI)

The WiX installer (provisioning.wxs) registers:

  • CLSID at HKLM\SOFTWARE\Classes\CLSID\{2D2FBE3A-...}\InprocServer32 pointing to the DLL
  • Shellex at HKLM\SOFTWARE\Classes\.pdf\shellex\{E357FCCD-...} linking .pdf thumbnails to our CLSID

Both are automatically removed on uninstall.

Building

The DLL is built automatically as part of the Tauri build pipeline via build-provisioner.mjs:

cd frontend
npm run tauri-build

To build the DLL standalone:

cd frontend/editor/src-tauri/thumbnail-handler
cargo build --release
# Output: target/release/stirling_thumbnail_handler.dll

Linux / macOS

This DLL is Windows-only. Linux and macOS don't need it — their thumbnail systems (thumbnailers on Linux, Quick Look on macOS) are decoupled from the default app association and continue working regardless of which app is set as default.