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 materializing 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 while 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 color error, maximum color delta, and a global SSIM-like luminance score
THPDFRenderedCompareOptions selects RGB or luminance difference, per-pixel color 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 color 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, normalized 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