Document Comparison
THPDFDocComparison compares two loaded THotPDF documents and returns a deterministic JSON report
Structural comparison
cmStructural starts at each document catalog, follows indirect references, and assigns paths from sorted dictionary keys and array indexes such as $Catalog/Pages/Kids[0]/Contents
Scalar values and decoded stream bytes are hashed with SHA-256, so large streams are compared incrementally without materialising another complete copy
Objects with the same path but different signatures are reported as objectChanged; equal signatures at different paths are objectMoved; remaining unmatched objects are objectInserted or objectDeleted
Page alignment
Pages with extractable text use a semantic text signature for alignment and fall back to a structural signature when text is empty or unavailable
A longest-increasing-subsequence pass preserves page order across insertions and deletions whilst reporting genuine reordering as pageMoved
Unmatched aligned pages become pageChanged, pageInserted or pageDeleted; page metadata is signed independently of /Parent, /Contents and /Resources to avoid font-subset encoding noise
Rendered comparison
cmRenderedImage and cmFull render common pages at the configured DPI and scan each bitmap once to compute changed pixels, changed-pixel ratio, mean absolute colour error, maximum colour delta and a global SSIM-like luminance score
THPDFRenderedCompareOptions selects RGB or luminance difference, per-pixel colour tolerance, minimum similarity, maximum changed-pixel ratio, tile size, changed-region retention, pixel budgets and optional PNG overlays
A page is similar only when both the changed-pixel ratio and similarity gates pass; metrics are evaluated at full precision and rounded to six decimal places only for deterministic JSON reporting
Changed tiles are joined into deterministic four-connected regions and reported with pixel-space bounds, changed-pixel counts and maximum colour deltas
When heatmaps are enabled, changed pixels are blended from yellow to red over document A and saved as page-000001-diff.png style files in the caller-selected directory
Bounds and completeness
THPDFStructuralCompareLimits controls object, edge, page, depth, difference, stream byte, value byte and path byte limits
If traversal reaches a limit, the report includes comparisonBudget, sets comparisonComplete to false, and cannot report the documents as identical
Rendered work is estimated before allocation and bounded per page and per comparison; rendering, allocation or overlay failures add renderBudget or renderError, set renderComparisonComplete and comparisonComplete to false, and fail closed
Comparison modes
cmPageCountcompares page countscmPageTextaligns and compares extracted page textcmObjectCountretains its existing selector value and now performs structural object and page comparisoncmRenderedImageperforms perceptual rendered comparison using default or caller-selected optionscmFullcombines page count, structural and rendered comparisoncmStructuralperforms page and object-graph comparison without rendering
Result format
The report includes source counts, traversal telemetry, normalised structural and rendering limits, differenceCount, reportedDifferenceCount, differencesTruncated, comparisonComplete, identical and a differences array
Rendered modes also return a renderedPages array with page status, dimensions, metrics, changed regions and optional overlay paths, plus aggregate rendered page and pixel counts
Each difference can include stable pathA and pathB values, page indexes, object numbers, a type, and a detail string
Related APIs
THPDFDocComparison · CompareWithOptions · THPDFRenderedCompareOptions · THPDFComparisonMode · HPDFDocCompareDocuments