Optional module · pdftoolkit/pdf-reader 0.1.7
English | Français
The root namespace is PDF\Reading. Primitives such as DictionaryType,
ArrayType, NameType, IntegerType, StringType and ObjectIdentifier come
from the shared PDF model.
Document and source objects
| Component | Construction and role |
|---|---|
FileBytes |
new FileBytes($bytes) retains explicitly supplied bytes. No file or network access. |
DocumentReader |
new DocumentReader($limits); read(FileBytes): ReadDocument opens the structural document. Limits have explicit defaults. |
ReadDocument |
Carries the source, header, effective trailer, index, budgets and caches. Normally constructed by DocumentReader. |
ObjectResolver |
resolve(BasicType): BasicType interface. Resolves a reference in a document without traversing the entire graph. |
ObjectReference |
new ObjectReference(ObjectIdentifier); identifier property. The reference carries an identifier, without a target or resolver. Serialisation is rejected. |
EncodedStream |
new EncodedStream(DictionaryType, string); dictionary() and encodedBytes() expose structure and original bytes. Serialisation is rejected. |
ReadDocument methods
| Method | Result and behaviour |
|---|---|
header(): FileHeader |
Version declared in the physical header. An optional catalog /Version remains accessible in its dictionary. |
trailer(): DictionaryType |
Effective trailer, assembled with priority given to recent revisions. In an xref-stream document it contains that stream dictionary's entries. |
catalog(): DictionaryType |
Resolves /Root; checks /Type /Catalog, the /Pages reference and declared version. |
object(ObjectIdentifier): BasicType |
Loads the identified object; returns null for a missing, free, unavailable or different-generation object. |
resolve(BasicType): BasicType |
Calls object() for a reference; preserves a direct value unchanged. |
streamData(EncodedStream): string |
Decodes the stream under document budgets. Subsequent accesses reuse the result. |
These operations load the base graph. The page services below add explicitly requested traversal; loading the catalog alone does not visit that tree.
Pages, inheritance and contents
| Component | Construction and role |
|---|---|
PageTreeReader |
new PageTreeReader(ReadDocument, PageTreeLimits); read(): ReadPageTree traverses the complete tree in /Kids order. Checks types, counts, parents, cycles, repeated identities and ceilings. |
ReadPageTree |
Immutable countable, iterable collection produced after validation. Properties document, root and pages; page(int $index): ReadPage is zero-based and rejects an out-of-range index. |
ReadPage |
Immutable leaf view: properties document, reference, dictionary and attributes. Retains the source dictionary. |
PageAttributes |
Effective resources as DictionaryType, MediaBox and CropBox as Rectangle, rotation as IntegerType. normalizedRotation(): int derives a 0/90/180/270 orientation without replacing the original integer. |
PageInheritance |
An ancestor's partial values, all optional. effective(): PageAttributes requires Resources/MediaBox and applies defaults only at the leaf. |
PageAttributeReader |
Receives an ObjectResolver. read(DictionaryType, PageInheritance): PageInheritance resolves the four inheritable entries and their types without visiting resource contents. |
PageTreeTraversal |
State for one traversal operation: explicit stack, visited identities, leaf order and subtree counts. |
PageTreeFrame |
A branch in progress: reference, inheritance, declared count and remaining children. Validates its count after visiting its descendants. |
PageTreeLimits |
Strictly positive ceilings: defaults are maxDepth 64, maxNodes 100,000 and maxPages 100,000. |
PageContentsReader |
new PageContentsReader(ReadDocument, PageContentLimits); read(ReadPage): PageContents resolves local contents of a page from the same document. |
PageContents |
Immutable countable, iterable collection: properties page and streams, preserved in order. No concatenation or decompression. |
PageContentLimits |
Strictly positive maxStreams ceiling, default 1,024 per page. |
The four inheritable entries are Resources, MediaBox, CropBox and Rotate.
Local Resources replaces the inherited dictionary without merging. Null is
treated as absence. CropBox defaults to MediaBox and Rotate to zero; other
page attributes remain accessible in the source dictionary. Contents is never
inherited. Absence, null and an empty array yield an empty content collection.
ReadDocument budgets remain shared during these operations. Tree and content
ceilings belong to each traversal or reading request. See the
page guide for an explained example.
Syntax and structures
| Component | Role |
|---|---|
ByteCursor |
Bounded byte view, constructed with an offset and optional end. position(), remaining(), peek(), read(), seek(), eof() and skipWhitespaceAndComments() control movement. |
SyntaxParser |
Receives a cursor, limits and optional budget. read() reads a PDF value; unsignedInteger(), keyword() and atKeyword() support structural readers. Does not resolve references. |
IndirectObjectReader |
Receives source, limits and budget. read($offset, $expected, $resolver) validates an object's envelope, identifier and exact stream extent. |
CrossReferenceReader |
Receives source, limits, budget and decoder. read($offset) produces a CrossReference\Section from a table or xref stream. |
ObjectStreamReader |
Receives limits and budget. read($stream, $decodedBytes, $resolver) parses ObjStm members in their respective slices. |
DictionaryAccess |
Typed structural access to a dictionary, with an optional ObjectResolver: value(), integer() and hasName(). |
PDF\Reading\CrossReference namespace
| Component | Role |
|---|---|
EntryKind |
Enum distinguishing Free, Uncompressed, Compressed and Unavailable entries. |
Entry |
Value carrying a number, type and two type-specific fields. generation() gives the effective generation; compressed members have generation zero. |
Section |
Revision value: offset, trailer, optional /Prev offset and entry list. |
Index |
Effective sparse index, constructed from newest to oldest sections. entry($number) retrieves the prevailing entry. |
The index retains recent free entries to prevent a deleted old object from reappearing. Unknown xref types remain unavailable and resolve to null.
Filters and predictors
StreamDecoder::decode(EncodedStream, ReadBudget, ?ObjectResolver): string
interprets the /Filter chain and its /DecodeParms. Full filter names are
used. An unknown filter is rejected at decoding time without preventing its
encoded bytes from being retained.
PDF\Reading\Filters namespace
| Component | Role |
|---|---|
Decoder |
Transformations' decode(string, ReadBudget): string interface. |
FlateDecoder |
Incremental zlib decompression in small slices, with checks for invalid or truncated data and trailing bytes. |
AsciiHexDecoder |
ASCIIHex decoding: PDF whitespace, hexadecimal digits and an optional final nibble. |
Ascii85Decoder |
ASCII85 decoding, complete or partial blocks and the z shorthand. |
RunLengthDecoder |
Decodes RunLength repetitions and literal segments. |
PredictorParameters |
Predictor, Colors, BitsPerComponent, Columns value. Predictors 1, 2 or 10–15; active predictors require 8-bit components. |
PredictorDecoder |
Reconstructs TIFF or PNG rows after Flate. PNG row tags identify the applied algorithm. |
DecodedBytes |
Accumulator checking the output limit and cumulative budget before retaining a slice. |
DCTDecode, JPXDecode, CCITTFaxDecode, JBIG2Decode, LZWDecode and Crypt are not implemented. Structural reading of an image stream may therefore succeed while a decoding request is rejected.
Limits and diagnostics
| Component | Role |
|---|---|
ReaderLimits |
Immutable ceiling values, configurable through named arguments. All must be strictly positive. |
ReadBudget |
Cumulative counters for parsed values, xref entries, retained bytes and decoded bytes, scoped to one read. |
ParseException |
Structure or budget error; optional offset property for a position in bytes. |
UnsupportedPdfFeature |
ParseException subtype distinguishing a deliberately unsupported mechanism. |
Configuration example:
use PDF\Reading\DocumentReader;
use PDF\Reading\ReaderLimits;
$reader = new DocumentReader(new ReaderLimits(
maxFileBytes: 8 * 1024 * 1024,
maxObjects: 10_000,
maxCrossReferenceEntries: 20_000,
maxDecodedStreamBytes: 16 * 1024 * 1024,
maxTotalDecodedBytes: 32 * 1024 * 1024,
maxRetainedBytes: 16 * 1024 * 1024,
));
Low-level calls can receive an explicitly supplied budget. To retain the same
ceilings throughout a read, use the same ReaderLimits and ReadBudget
within the composed components.