Class ContentDeduplicator
- java.lang.Object
-
- com.pd4ml.pdf.optimizer.internal.ContentDeduplicator
-
public final class ContentDeduplicator extends java.lang.ObjectFinds indirect objects reachable from aCOSDocument's trailer that are byte-for-byte duplicates of another object -- most commonly the same font, image, or color space embedded twice under two different object numbers -- and rewrites every reference to a duplicate so it points at one surviving ("canonical") copy instead. The now-unreferenced duplicates themselves are left in the document's object table;deduplicate(com.pd4ml.pdf.cos.COSDocument)only rewrites references, on the assumption (true forcom.pd4ml.pdf.optimizer.PdfOptimizer, its only caller) that a reachability pass runs afterward and drops whatever is no longer pointed to.Content identity, not object identity. Two indirect objects are considered duplicates when their fully-resolved content is identical: same dictionary entries (order-independent -- PDF dictionaries are unordered by definition), same array elements (order-sensitive -- arrays are ordered), same raw (still-encoded) stream bytes, same primitive values. An indirect reference nested inside either object counts as identical content only if it has already been found to point at the same (possibly itself just-deduplicated) canonical object -- comparison walks the graph bottom-up, so a parent that references two now-identical children is correctly recognized as a duplicate of another parent referencing the single canonical child.
Deliberately excluded from merging (though still visited, so anything they reference is still eligible):
/Type /Pagedictionaries,/Type /Annotdictionaries, and interactive form field dictionaries (anything carrying an/FTentry, terminal or not). Two of these can be byte-identical today (e.g. two blank form fields) yet be mutated independently later by a viewer that fills them in by object identity -- collapsing them into one shared object would make filling in one silently affect the other. Everything else -- fonts, images, ExtGState/color-space/function dictionaries, content streams, and so on -- has no such identity significance and is always safe to merge when byte-identical.Cycles (a page's
/Parentchain, a structure element's/Pchain, ...) are handled defensively: an indirect reference that loops back to an object still being hashed contributes that object's own key (not yet a canonical, content-based hash) to the in-progress hash instead of recursing further. This never causes an incorrect merge -- it can only make two objects that are, transitively, actually identical fail to be recognized as such when a cycle is involved, which is a rare shape for true byte-for-byte duplicates to take in practice.
-
-
Method Summary
All Methods Static Methods Concrete Methods Modifier and Type Method Description static intdeduplicate(COSDocument document)Rewritesdocument's trailer and every indirect object's references so that every duplicate-content object is referenced only via its canonical (first-encountered) copy.
-
-
-
Method Detail
-
deduplicate
public static int deduplicate(COSDocument document)
Rewritesdocument's trailer and every indirect object's references so that every duplicate-content object is referenced only via its canonical (first-encountered) copy. Returns how many distinct objects were found to be duplicates (and so are now unreferenced, still physically present indocument's object table).
-
-