pub struct DocumentReader<'a> { /* private fields */ }Expand description
A read-time view of the PDF document — owns the byte slice plus a
resolved cross-reference table and a small object cache. Indirect
objects are decoded lazily via Self::resolve.
When the file’s trailer carries an /Encrypt entry, the reader
holds a StandardHandler derived from the supplied password.
Every Self::resolve call decrypts string and stream payloads
against that handler before caching them. PDFs without encryption
leave crypt = None and the decrypt path is a no-op.
Implementations§
Source§impl<'a> DocumentReader<'a>
impl<'a> DocumentReader<'a>
Sourcepub fn open(input: &'a [u8]) -> Result<Self, PdfError>
pub fn open(input: &'a [u8]) -> Result<Self, PdfError>
Parse the cross-reference table + trailer for input. Equivalent
to Self::open_with_password with the empty password — works
for unencrypted PDFs and for PDFs whose user password is empty.
Sourcepub fn open_with_password(
input: &'a [u8],
password: &[u8],
) -> Result<Self, PdfError>
pub fn open_with_password( input: &'a [u8], password: &[u8], ) -> Result<Self, PdfError>
Parse the cross-reference table + trailer for input. If the
trailer carries /Encrypt, derive a decryption handler from the
supplied password (tested first as the user password, then as
the owner password per ISO 32000-1 §7.6.3.1).
Returns PdfError::Other when the file is encrypted but the
password fails to authenticate — the typical “wrong password”
error a PDF viewer surfaces.
Sourcepub fn open_with_certificate(
input: &'a [u8],
credential: &PubSecCredential,
) -> Result<Self, PdfError>
pub fn open_with_certificate( input: &'a [u8], credential: &PubSecCredential, ) -> Result<Self, PdfError>
Parse the cross-reference table + trailer and unlock a
public-key-protected PDF using credential. Round-10
implementation; see crate::pubsec for the supported
SubFilters and crypt methods. Returns PdfError::Other when
the PDF is encrypted but the supplied certificate doesn’t
match any recipient slot in any envelope of /Recipients.
Sourcepub fn open_with_certificate_and_trust_store(
input: &'a [u8],
credential: &PubSecCredential,
trust_store: &TrustStore,
) -> Result<Self, PdfError>
pub fn open_with_certificate_and_trust_store( input: &'a [u8], credential: &PubSecCredential, trust_store: &TrustStore, ) -> Result<Self, PdfError>
Round-17: same as Self::open_with_certificate but consults a
TrustStore when a KARI envelope identifies the originator by
IssuerAndSerial or SubjectKeyIdentifier (RFC 5652 §6.2.2)
instead of carrying its public point in-band.
Sourcepub fn is_encrypted(&self) -> bool
pub fn is_encrypted(&self) -> bool
true when the underlying PDF carried an /Encrypt entry that
the supplied password successfully authenticated against.
Sourcepub fn signatures(&mut self) -> Result<Vec<PdfSignature>, PdfError>
pub fn signatures(&mut self) -> Result<Vec<PdfSignature>, PdfError>
Round-21: enumerate every /Sig form-field signature dictionary
embedded in this PDF. See crate::reader::sig::signatures for
the full contract — this is a thin convenience wrapper.
use oxideav_pdf::reader::DocumentReader;
use oxideav_pdf::pubsec::verify::{verify_signature, AttachedContent};
let mut r = DocumentReader::open(&pdf)?;
for sig in r.signatures()? {
if !sig.is_cms_detached() { continue; }
let signed = sig.signed_message(&pdf)?;
let sd = sig.signed_data.as_ref().unwrap();
// ... resolve certs from sd.certs[] ...
let ok = verify_signature(&sd.signer_infos[0], &certs,
AttachedContent::External(&signed))?;
}Sourcepub fn doc_timestamps(&mut self) -> Result<Vec<PdfDocTimestamp>, PdfError>
pub fn doc_timestamps(&mut self) -> Result<Vec<PdfDocTimestamp>, PdfError>
Round-34: surface only the document time-stamp signatures (ISO
32000-1 §12.8.5 — /Type /DocTimeStamp or /SubFilter /ETSI.RFC3161).
Sourcepub fn annotations(&mut self) -> Result<Vec<PdfAnnotation>, PdfError>
pub fn annotations(&mut self) -> Result<Vec<PdfAnnotation>, PdfError>
Round-19: surface the document-level XMP /Metadata packet
per ISO 32000-1 §14.3.2 + Adobe XMP Spec 2012. Returns
Ok(None) when the catalog has no /Metadata entry; otherwise
resolves the referenced stream and returns its decoded payload
(the raw XMP RDF/XML bytes — caller is expected to do their
own XML / RDF parse if they need structured access).
Symmetric to crate::write_pdf_from_scene_with_xmp.
Round-26: walk every page’s /Annots array and surface each
annotation as a crate::reader::annotation::PdfAnnotation
(ISO 32000-1 §12.5).
Subsumes Self::signatures (those land as Other { subtype: "Widget" } plus /FT /Sig widget hosting) at a higher level —
callers that just want the structured /Sig slot should keep
using signatures(); callers that want every annotation across
every page (Text, FreeText, Stamp, Highlight, Square, Link,
Widget, …) want annotations().
Sourcepub fn actions(&mut self) -> Result<Vec<PdfAction>, PdfError>
pub fn actions(&mut self) -> Result<Vec<PdfAction>, PdfError>
Round-36: enumerate every action attached to the document (ISO
32000-1 §12.6). Walks the catalog /OpenAction + /AA,
per-page /AA, per-annotation /A + /AA, per-form-field
/A + /AA, and the /Names /JavaScript name tree, surfacing
each as a crate::reader::actions::PdfAction with the
trigger location, the typed crate::reader::actions::ActionKind
payload, and the /Next chain depth.
Sourcepub fn optional_content(&mut self) -> Result<Option<OptionalContent>, PdfError>
pub fn optional_content(&mut self) -> Result<Option<OptionalContent>, PdfError>
Round-95: surface the catalog’s /OCProperties Optional Content
configuration (ISO 32000-1 §8.11 + §7.7.2 Table 28). Returns
Ok(None) when the document has no optional content (the
common case); returns Ok(Some(_)) carrying every OCG, the
default configuration dict, any alternate configurations, and
the resolved on/off state per group after applying the default
configuration’s BaseState / ON / OFF per §8.11.4.5.
Sourcepub fn linearization(&self) -> Result<Option<LinearizationParams>, PdfError>
pub fn linearization(&self) -> Result<Option<LinearizationParams>, PdfError>
Round-27: parse the Linearization Parameter Dictionary at the
head of the file (ISO 32000-1 §F.2 + Annex F.3). Returns
Ok(None) for non-linearized files (the common case);
returns Ok(Some(_)) with parsed /L /H /O /E /N /T for
“Fast Web View” PDFs.
Independent of the rest of the open path — the lin-dict is parsed from the raw bytes, NOT from the resolved xref. A reader can poll for linearization status without paying the xref-walk cost.
Sourcepub fn verify_hierarchy(&mut self) -> Result<HierarchyReport, PdfError>
pub fn verify_hierarchy(&mut self) -> Result<HierarchyReport, PdfError>
Round-27: walk Catalog → Pages → Page and collect every
integrity divergence per ISO 32000-1 §7.7.2 + §7.7.3. The
returned crate::reader::hierarchy::HierarchyReport is
permissive — it never aborts the walk, so callers can decide
per-issue what to do with warnings vs. errors.
Sourcepub fn pdfa_signals(&mut self) -> Result<PdfACatalogSignals, PdfError>
pub fn pdfa_signals(&mut self) -> Result<PdfACatalogSignals, PdfError>
Round-27: surface the structural PDF/A catalog signals
(/MarkInfo, /StructTreeRoot, /Lang, /OutputIntents,
/Metadata) independent of the XMP packet’s claim.
Pair with Self::xmp_packet + crate::reader::pdfa::PdfAConformance::from_signals_and_xmp
to cross-verify a pdfaid:part declaration against the
structural prerequisites ISO 19005-x requires.
Sourcepub fn pdfa_conformance(&mut self) -> Result<PdfAConformance, PdfError>
pub fn pdfa_conformance(&mut self) -> Result<PdfAConformance, PdfError>
Round-27: combined PDF/A conformance picture — the XMP
packet’s pdfaid:part / pdfaid:conformance claim cross-
verified against the catalog’s structural signals
(/MarkInfo /Marked, /StructTreeRoot, /OutputIntents).
Returns a crate::reader::pdfa::PdfAConformance whose
claim_inconsistent is true when the document declares
PDF/A in XMP but lacks one or more structural prerequisites.
Sourcepub fn xmp_packet(&mut self) -> Result<Option<XmpPacket>, PdfError>
pub fn xmp_packet(&mut self) -> Result<Option<XmpPacket>, PdfError>
Round-26: surface the document-level XMP /Metadata packet as
a structured crate::reader::xmp::XmpPacket — the most-used
Dublin Core / XMP Basic / PDF / PDF/A identification fields,
pre-decoded from the raw bytes Self::xmp_metadata returns.
Returns Ok(None) when the catalog has no /Metadata entry.
pub fn xmp_metadata(&mut self) -> Result<Option<Vec<u8>>, PdfError>
Sourcepub fn resolve(&mut self, id: ObjectId) -> Result<Object, PdfError>
pub fn resolve(&mut self, id: ObjectId) -> Result<Object, PdfError>
Decode the indirect object at id. Cached on first hit so a
second resolve(id) is O(1). When the file is encrypted, the
per-object decryption is applied here so callers above this
layer see plaintext only.
Compressed objects (xref entry type 2 — PDF 1.5+ object streams, ISO 32000-1 §7.5.7) are resolved by fetching their containing object stream, slicing the matching body out of the concatenated payload, and re-parsing it with the standard object parser.
Source§impl<'a> DocumentReader<'a>
impl<'a> DocumentReader<'a>
Sourcepub fn image_xobjects(
&mut self,
) -> Result<Vec<(ObjectId, PdfImageXObject)>, PdfError>
pub fn image_xobjects( &mut self, ) -> Result<Vec<(ObjectId, PdfImageXObject)>, PdfError>
Walk every page’s resource tree and return every JPEG-passthrough
Image XObject in stream order — one entry per surfaced
(ObjectRef, PdfImageXObject) pair. The same XObject referenced
from multiple pages is returned once (deduplicated by
ObjectId) so callers don’t have to filter.
Image XObjects with non-DCTDecode filters (FlateDecode, CCITTFaxDecode, JBIG2Decode, JPXDecode, …) are silently skipped — they exist on the page but aren’t part of the JPEG passthrough surface this round delivers.
See module documentation for the byte-level contract.
Source§impl<'a> DocumentReader<'a>
impl<'a> DocumentReader<'a>
Sourcepub fn inline_images(&mut self) -> Result<Vec<PdfInlineImage>, PdfError>
pub fn inline_images(&mut self) -> Result<Vec<PdfInlineImage>, PdfError>
Walk every page’s content stream and return every inline image
(BI … ID … EI triplet per ISO 32000-1 §8.9.7) in stream
order — one entry per inline image surfaced.
See module documentation for the byte-level contract, filter coverage, and parser-framing rule.
Source§impl<'a> DocumentReader<'a>
impl<'a> DocumentReader<'a>
Sourcepub fn read_in_logical_order(&mut self) -> Result<ReadingOrderText, PdfError>
pub fn read_in_logical_order(&mut self) -> Result<ReadingOrderText, PdfError>
Round-29: extract every text run in logical reading order
per the document’s /StructTreeRoot walk (ISO 32000-1 §14.8).
See read_in_logical_order for the full contract.
Source§impl<'a> DocumentReader<'a>
impl<'a> DocumentReader<'a>
Sourcepub fn text_extraction(&mut self) -> Result<PdfTextExtraction, PdfError>
pub fn text_extraction(&mut self) -> Result<PdfTextExtraction, PdfError>
Extract every text run from every page in stream order.
See PdfTextExtraction. This is a thin wrapper around
extract_text that walks the catalog → /Pages tree, resolves
each page’s /Resources /Font dict, and feeds the page’s
concatenated /Contents stream into the walker.
Sourcepub fn marked_text_extraction(
&mut self,
) -> Result<PdfMarkedTextExtraction, PdfError>
pub fn marked_text_extraction( &mut self, ) -> Result<PdfMarkedTextExtraction, PdfError>
Round-29: extract every text run alongside the marked-content
/MCID tag the show was issued under (ISO 32000-1 §14.6 + §14.8).
Pair with crate::reader::layout::read_in_logical_order to
reorder the resulting runs by the StructTreeRoot’s logical
/K tree.