Skip to content
Validate PDF/A-2 Standard

Validate PDF/A-2 Standard

Validation checks a file against a profile and returns the rules it breaks. It needs a CompliancePdfReader, which parses in compliance mode and keeps the byte-level detail the header, trailer and cross-reference rules depend on. A plain PdfReader will not type-check against ValidateStandard.

Doing it

detailedReader, err := model.NewCompliancePdfReader(inputFile)
if err != nil {
    return err
}

for _, profile := range []model.StandardImplementer{
    pdfa.NewProfile2A(nil),
    pdfa.NewProfile2B(nil),
    pdfa.NewProfile2U(nil),
} {
    if err := profile.ValidateStandard(detailedReader); err != nil {
        fmt.Printf("%s: %v\n", profile.StandardName(), err)
    }
}

nil means nothing was found. Anything else is a pdfa.VerificationError holding a ViolatedRule per failed check, with the ISO clause number in RuleNo and the requirement text in Detail, sorted by clause.

Reading the result

Running all three profiles over one file is the pattern the example uses, and its output needs the conformance hierarchy to make sense. The pdfaid:conformance check accepts a level at least as strict as the one being tested: a file marked A passes all three checks, a file marked U passes the U and B checks, and a file marked B passes only the B check. So a valid 2B file reports two failures out of three, both on rule 6.6.4-3. That is the expected result, not a problem with the file.

Beyond that identification rule, the levels differ in what else runs. 2U and 2A require every composite font to carry a usable ToUnicode CMap unless it is a Type 1 font, and report 6.2.11.7-1 when one does not. 2A additionally runs the logical structure checks, which want MarkInfo Marked set to true, a StructTreeRoot in the catalog, and non-standard structure types mapped in the role map.

What part 2 checks that part 1 does not

Part 2 permits transparency, layers and JPEG 2000, so those rules disappear. In their place it adds checks part 1 had no need for:

  • 6.1.12 permissions. The catalog’s Perms dictionary may only carry DocMDP and UR3.
  • 6.4.3 digital signatures.
  • 6.2.8.3 JPEG 2000 image data, which is permitted but constrained.
  • 6.8 embedded files. A file specification with an EF entry needs F, UF and AFRelationship, and the embedded stream’s MIME type has to be application/pdf. Rule 6.8-4 covers that last requirement, and it is the one part 3 drops.
  • 6.9 optional content configuration.
  • 6.10 alternate presentations, and 6.11 the catalog Requirements entry, both forbidden.

Limitations

Validation is not complete, and the package documents itself as experimental. Several clauses exist in the source as unimplemented placeholders, including parts of the object syntax checks, the rendering intent check, the check that embedded font programs are one of the permitted formats, the Lang identifier check and the page PresSteps check. A clean result means the document passed the rules UniPDF checks. Use veraPDF as the oracle for a conformance claim.

Run the example

pdfa2_validate_standard.go opens a file with NewCompliancePdfReader, then loops over a slice of model.StandardImplementer holding all three part 2 profiles and prints the violations for each.

git clone https://github.com/unidoc/unipdf-examples.git
cd unipdf-examples/pdfa
go run pdfa2_validate_standard.go <input.pdf>

If this is your first time using UniPDF, follow the getting started guide to create an API key and set up your development environment.

View the full source
Processing time: 22.19 ms

Sample output

The same file checked with veraPDF:

veraPDF report showing the file passing PDF/A-2 validation

Last updated on