The ISO 32000-1 corpus uses the PDF32000_2008.pdf preserved in the core repository: ISO 32000-1:2008, PDF 1.7. The additional adobe_supplement_iso32000.pdf describes Adobe ExtensionLevel 3; its separate coverage and source catalogue preserve the distinction between ISO definitions, Adobe extensions and Acrobat implementation notes. The retained Adobe PDF 1.7 reference, errata and redaction addendum have a separate archival catalogue, including the original portfolio and its embedded-document relationships. They support comparison and targeted audits; their preservation does not alter the active definition inventories or establish implementation of all their procedures. Core series 0.6 and optional module releases 0.1.7 require PHP 8.3 or later; the older core 0.1 tags retain their PHP 8.5 requirement. These PHP versions are independent of the PDF format version. Core 0.6 introduces first PDF 2.0 mechanisms and a separate ISO 32000-2:2020 EC3 pilot. Its four tables and 53 entry classes do not change the ISO1 counts below or establish full PDF 2.0 conformance.

The source contains 756 PDF pages, 823 outline entries, 370 main numbered tables and 22 annex tables. The catalogue inventories all 392 tables and all 73 content stream operator tokens, including the obsolete F and inline image delimiters BI, ID, and EI.

The 263 tables describing dictionary entries, parameters, or attribute entries produce 263 concrete dictionary classes, 263 immutable table definition classes, 1,399 concrete fixed entry classes and six concrete variable entry classes. Table identifiers remain in class names to distinguish similarly named dictionaries and to make each source definition traceable. PDF names are case sensitive; PHP class names are not. For conflicting names such as /OP and /op, the generated class name includes the hexadecimal spelling of its PDF name.

Each entry accepts PDF objects, with a PHP union matching the source's object types. References remain explicit objects. An indirect reference is checked against its target type. Stream values require an IndirectReference; callers never pass a direct stream as a dictionary value. Known fixed Type names are validated. Rectangles require four direct numbers. Cross-reference stream entries and their Index/W array elements must remain direct.

Each definition is an object composed of SourceReference, Requirement, ObjectTypeConstraint, and EntryDefinition objects. TableDefinition composes common dictionary tables explicitly. Catalogue is an immutable collection constructed by the caller. There is no singleton, shared cache, global service registry, or runtime JSON lookup. The JSON files are source inventories used by the reproducible build tools.

Dictionary classes allow incremental construction through immutable with() operations. Serializing them checks unconditional required entries. Conditional requirements, inherited entries, numeric limits, enumerations other than fixed Type names, relationships between dictionaries, and algorithm-specific rules are preserved in the source description but are not all automatically checked. Specialized document, page, font, content stream and function objects provide additional behavior and constraints.

This is an inventory and a low-level object construction model. It is not a claim that every algorithm or every valid document allowed by the 756-page standard has an implemented, independently verified semantic model. Native signing, tagging, compression, colour/shading and linearization now have executable models and independent validations. Remaining variants, constraints and external processors are tracked in the mechanism coverage guide and its source inventory. Named dictionary classes alone do not implement algorithms. Rendering, external image/font conversion, script execution and multimedia playback retain separate responsibilities.

The additional historical AES-256 revision 5 backend implements the algorithms of the retained Adobe supplement with explicit credentials, permissions, SASLprep Unicode 3.2 and writer integration. This is an opt-in legacy protocol. The ISO R=2/3/4 and public-key s3/s4/s5 handlers also have explicit writer operations. AES-CBC does not authenticate file contents.

The supplement also has separately validated historical R=2–R=4 key derivation, an ordered public-key recipient digest, 3D unit mapping and barcode data preparation/module-width calculation. Their APIs state their exact inputs and limits. Native CMS backends and public-key operations are composed explicitly; media rendering and barcode symbology encoding still require external processors. See the supplement guide and its versioned coverage inventory for each algorithm's status.

Implemented mechanisms beyond the syntax model

The core implements the PDF objects and mechanisms described by the Adobe/ISO reference. External TrueType, JPEG and PNG parsing is supplied by optional packages; reading existing PDFs is also a separate package. Modules depend on the core, which has no production dependency on them. See the package boundaries and installation guide.

Mechanism Executable behavior Explicit limits
PDF fonts — core Explicit font programs and metrics, simple and composite fonts, encodings, horizontal/vertical CID widths, CMaps, UseCMap and Unicode mappings. The core receives normalized programs and values; external font parsing, subsetting and shaping need their own processors.
TrueType conversion — pdf-fonts Static sfnt/glyf validation, Unicode cmap 4/12, metrics, full-glyph CIDFont program and conversion factories producing core font objects. No font collections, CFF/variable fonts, glyph subsetting, vertical writing, kerning or complex-script shaping. The derived CIDFontProgram removes cmap as required by 9.9 and the invalidated DSIG. The original font's embedding permissions are checked.
PDF images — core Explicit dimensions, sample layouts, colour spaces, Decode, image stencils, colour-key/explicit/soft masks and declarations of encoded image data. Encoded data and its colour/alpha semantics are caller-declared. External codecs and file inspection belong to optional converters.
JPEG conversion — pdf-images Marker/frame/table validation, baseline and progressive eight-bit grayscale/RGB JPEG and Adobe CMYK transform zero into a core DCTImage. Original DCT bytes are preserved. No entropy decoding or JPEG encoding; the reader decodes the coefficients. ICC, YCCK and ambiguous colour semantics are rejected. EXIF orientation is not applied.
PNG conversion — pdf-images CRC/framing/order checks, bounded zlib decoding, all five scanline filters, eight-bit grayscale/RGB/indexed/alpha samples and tRNS into core sample objects. Static non-interlaced PNG only; other depths, APNG and embedded colour profiles are rejected. Ancillary colour metadata does not create calibrated PDF spaces. Import limits are explicit objects.
Incremental revisions Exact frozen FileRevision snapshots and timeline, additions/replacements, linked free lists, release/reuse, retired generations and aliases, offsets and Prev, ordinary/stream/hybrid xrefs, encrypted variants and updates after initial linearization. Generated revisions only. Replacing a live value retains its object family and dictionary Type; a new identity reusing a free number may have a different type. Old bytes remain, so updates cannot erase confidential content.
Navigation Page labels, explicit and named destinations, viewport calculations, article rings and page drawing order, transitions and presentation sequences. Native graph and arithmetic are checked against the effective catalog; a viewer renders and animates their presentation.
Files and collections Supplied embedded bytes, Size/MD5 metadata, Mac information, EF/RF/CI, attachment name trees and typed collection schemas/items/sorts; external-stream declarations. No implicit filesystem/URL loading, platform conversion or collection UI execution.
Signature field policies Written seeds/locks, actual certificate/digest/backend/appearance choices, verified output before finalization and intrinsic historical signing permissions. Full authenticated revision-difference analysis and UR authority/intersection remain open; timestamp, revocation and PKI trust need explicit external components.
External PDF reading — pdf-reader PDF 1.0–1.7 object syntax, traditional and stream xrefs, Prev revisions, object streams, explicit reference resolution, encoded stream retention and bounded Flate/ASCIIHex/ASCII85/RunLength decoding with eight-bit TIFF/PNG predictors. Ordered page-tree traversal checks counts, parents and unique identities; effective Resources, MediaBox, CropBox and Rotate preserve PDF objects. Page-local Contents streams are resolved separately in order. No PDF 2.0, encrypted documents, hybrid XRefStm, repair, content interpretation, rendering or text extraction. Unknown codecs can be retained encoded but cannot be decoded. Page traversal does not inspect all resource contents. Contents inspection does not concatenate or decode streams. Reading does not implement import or remapping into the writer.

The initial writer emits free records for every unused object number below Size. Incremental sections emit changed records and newly introduced free holes, keeping the previous free-list chain. CrossReferenceLimits caps cumulative Size at 100,000 entries by default, before allocating gap records; applications can supply an explicit capacity to a writer. New objects have generation zero, while a live replacement retains its existing generation. Release increments the free generation, reuse uses that stored generation, and generation 65535 is permanent. A number from the free list cannot create a new ObjStm container or compressed member.

The tutorials for embedded fonts, image files and incremental updates explain their object graphs and include executable documents. None of these mechanisms adds an application-global registry or automatic layout engine.

Rebuilding the source inventory

Use Python with pypdf and pdfplumber installed:

python tools/extract_spec.py
python tools/generate_specification.py
python tools/generate_specification.py --check

extract_spec.py verifies that all main table identifiers from 1 to 370 are present, extracts ruled table cells, checks the complete 73-token operator list, and records unresolved extraction problems in extraction-issues.json. The checked-in inventory has zero unresolved extraction problems. It records the SHA-256 fingerprint of the source PDF and physical PDF page numbers.

generate_specification.py emits named classes and immutable definition objects. Its --check mode compares the generated files without modifying them. Only stale PHP files bearing this generator's marker in its two generated directories may be removed during regeneration. The Python tools are development tools; the PHP library has no Python runtime dependency.

The generated source and its inventory must be reviewed together. Extraction repairs are narrow and documented in the tool: two wrapped key names and two OPI keys that overflow their printed table cells. Variable names remain variable; descriptive phrases such as “Other keys” are never emitted as fixed PDF keys.

corrections.json records explicit implementation decisions where the source wording is inconsistent. In Table 15 the ISO 2008 qualifier for /Prev says it shall be indirect, whereas Adobe PDF Reference 1.7, Table 3.13 requires a direct integer. This implementation keeps /Prev direct so that the previous cross-reference section can be located before indirect objects are resolved. The original description and qualifier are retained, and an immutable ImplementationCorrection object exposes the rationale and evidence. This is a documented implementation decision, not a claim of an official ISO erratum. Negative qualifiers such as “shall not be an indirect reference” are interpreted as direct-object constraints without changing their source wording.

Extending semantic coverage

Add a specialized immutable object for the normative concept, its exact source clause, and the meaningful constraints on its values and relationships. Compose existing entry definitions rather than maintaining a second catalogue of names. Keep parsers, encoders, compression, encryption, signatures, document writing, and rendering separate from the definition objects, with explicit dependencies. External-format parsing belongs in optional modules; normalized PDF values and mechanisms remain in the core. Use independent readers and validators to test emitted bytes, alongside focused unit tests for invalid cases. An entry's implementation status should distinguish its object model, its serialization, its constraints and its associated algorithm.

Guide source at the documented commit ↗