CheckFileCompliance

Compliance, Document inspection

Description

Reads an external PDF file and validates it against a chosen ISO compliance standard. The returned value is either zero (file passes the chosen test cleanly) or a non-zero StringListID handle that lists every issue detected. Each entry in the list is a short code, a colon, and a human-readable message — exactly the same code format used by GetPDFUADiagnostics. Enumerate the result with GetStringListCount and GetStringListItem.

The PDF/A test covers all six conformance modes (PDF/A-1a, PDF/A-1b, PDF/A-2a, PDF/A-2b, PDF/A-3a, PDF/A-3b) and reads the pdfaid:part/pdfaid:conformance XMP entries to decide which rule set to apply.

The PDF/UA-1 test (added in v3.56.0) checks an external PDF against ISO 14289-1 and emits diagnostic codes in the 10xxx range so they remain visually separate from the PDF/A 00xxx codes.

Syntax

Delphi

function TPDFlib.CheckFileCompliance(const InputFileName, Password: WideString; ComplianceTest, Options: Integer): Integer;

ActiveX

Function PDFlib::CheckFileCompliance(InputFileName As String, Password As String, ComplianceTest As Long, Options As Long) As Long

DLL

int DLCheckFileCompliance(int InstanceID, wchar_t * InputFileName, wchar_t * Password, int ComplianceTest, int Options);

Parameters

InputFileNameFull path of the PDF file to validate. The file is opened read-only and is not modified.
PasswordPassword used to open the file. Pass an empty string for unencrypted documents. Note that an encrypted document fails the PDF/A test (code 00006) regardless of whether the correct password is supplied — PDF/A forbids encryption.
ComplianceTestThe standard to check against.

1 — PDF/A (ISO 19005-1/-2/-3, all six conformance levels).
2 — PDF/UA-1 (ISO 14289-1:2014, accessible PDF).
OptionsBit flags that modify the test.

0 — Default: report every issue found in the document.
1 — Stop after the first issue and return immediately. Useful when the caller only needs a pass/fail signal.

Return values

0The file is conformant with the chosen standard.
Non-zeroA StringListID handle whose entries describe each detected non-conformance. The handle remains valid until the document is closed or ReleaseStringList is called.

PDF/A issue codes (ComplianceTest = 1)

00002PDF version exceeds the maximum allowed by the conformance level (PDF/A-1 caps at 1.4; PDF/A-2 and PDF/A-3 cap at 1.7). The detail line names the offending version and the allowed maximum.
00003The Catalog contains /OCProperties (optional content / layers), forbidden by PDF/A-1. PDF/A-2 and PDF/A-3 permit layers and do not trigger this check.
00005The XMP pdfaid:part+pdfaid:conformance pair is missing, malformed, or contains a value outside the legal set 1A, 1B, 2A, 2B, 3A, 3B. The library cannot determine which rule set to apply, so this is reported as a fatal issue regardless of Options.
00006The document is encrypted. PDF/A forbids encryption in every part.
00007The Catalog has no /OutputIntents entry. All PDF/A parts require an output intent so that the rendering colour space is unambiguously defined.
00011The Catalog has no /MarkInfo entry. Required only for a-level conformance (PDF/A-1a, 2a, 3a) — tagged PDF must declare itself.
00012The Catalog has no /StructTreeRoot entry. Required only for a-level conformance. A tagged-PDF document must have a logical structure tree.

PDF/UA-1 issue codes (ComplianceTest = 2)

10001The XMP metadata stream does not contain pdfuaid:part, or the value is not 1. ISO 14289-1 §5 requires a conforming file to identify itself via this property; ISO 14289-1 §6.2 forbids reporting conformance without it.
10002The document Catalog has no /Metadata stream. A PDF/UA-1 conformance claim is recorded inside this stream; without it the file cannot announce itself as accessible.
10003The Catalog /MarkInfo dictionary is missing or /Marked is not true. ISO 14289-1 §7.1 requires every conforming file to declare itself as tagged so that assistive technology can rely on the structure tree.
10004The Catalog has no /StructTreeRoot entry. A PDF/UA-1 file must include a logical structure tree describing the document's reading order and semantics.
10005The /ViewerPreferences dictionary is missing or its /DisplayDocTitle entry is not true. ISO 14289-1 §7.1 requires conforming readers to surface the document title in their window chrome instead of the file name.
10006The Catalog /Lang entry is missing or empty. ISO 14289-1 §7.2 (referring to ISO 32000-1 §14.9.2) requires every conforming file to declare its natural language so screen readers select the correct voice and pronunciation rules.
10007The XMP metadata stream does not carry a non-empty Dublin Core dc:title. ISO 14289-1 §7.1 requires "a dc:title entry which clearly identifies the document".
10008The /MarkInfo dictionary has /Suspects set to true. ISO 14289-1 §7.1: files claiming PDF/UA conformance must have a Suspects value of false — a true value marks the tagging as known to contain errors.
10009The document /RoleMap remaps one or more standard structure types. ISO 14289-1 §7.1: standard tags defined in ISO 32000-1 §14.8.4 (P, H1..H6, Figure, Table, etc.) shall not be remapped. The detail line names the first standard tag that was remapped.
10010The file is encrypted, but bit 10 of the encryption /P permission key (mask 512, "Extract for accessibility") is not set. ISO 14289-1 §7.16 requires every encrypted conforming file to permit accessibility extraction so assistive technology can reach the content.
10011A dynamic XFA form was detected: the XFA XDP packet contains <dynamicRender>required</dynamicRender>. ISO 14289-1 §7.15 forbids dynamic XFA forms in conforming files; static XFA is permitted.
10012A Reference XObject (Form XObject carrying a /Ref entry) was detected. ISO 14289-1 §7.20 forbids reference XObjects because they let one PDF embed another by reference without exposing the referenced content to assistive technology.
10013One or more TrapNet annotations were detected. ISO 14289-1 §7.18.2 explicitly forbids TrapNet in conforming files. The detail line reports how many annotations were found.
10014One or more pages carry annotations but do not set /Tabs /S in their page dictionary. ISO 14289-1 §7.18.3 requires tab order on such pages to follow the structure tree, which is signalled by /Tabs /S. The detail line reports the count of offending pages.
10015One or more Link annotations lack a non-empty /Contents alternate description. ISO 14289-1 §7.18.5 requires each Link annotation to carry an accessible description so that screen readers can announce the link target. The detail line reports the count of offending Link annotations.
10016One or more embedded-file FileSpec dictionaries are missing the /F file-name key. ISO 14289-1 §7.11 requires every embedded-file FileSpec to carry both /F and /UF.
10017One or more embedded-file FileSpec dictionaries are missing the /UF Unicode file-name key. ISO 14289-1 §7.11 requires every embedded-file FileSpec to carry both /F and /UF.
10018One or more optional-content configuration dictionaries are missing a non-empty /Name text string. ISO 14289-1 §7.10 requires every OCG configuration dictionary (the default D entry plus every dictionary in OCProperties/Configs) to carry a non-empty /Name.
10019One or more optional-content configuration dictionaries contain the forbidden /AS key. ISO 14289-1 §7.10 explicitly forbids /AS in any OCG configuration dictionary to prevent automatic state adjustments driven by usage information.
10020One or more non-Standard-14 fonts referenced by the document do not embed their font program (no FontFile, FontFile2, or FontFile3 entry on the FontDescriptor). ISO 14289-1 §7.21.4.1 requires every font used for rendering to embed its program. Type 3 fonts skip this check because their glyphs are inline CharProcs.
10021One or more CIDFontType2 descendants are missing the /CIDToGIDMap entry. ISO 14289-1 §7.21.3.2 requires every embedded Type 2 CIDFont to carry /CIDToGIDMap (either as a stream mapping CIDs to glyph indices, or as the name Identity).
10022One or more Standard 14 fonts (Helvetica, Times, Courier, Symbol, ZapfDingbats and their bold / oblique variants) are referenced without an embedded font program. ISO 14289-1 §7.21.4 NOTE 5 makes clear there is no exemption from embedding for the 14 standard Type 1 fonts.
10023One or more fonts are missing a /ToUnicode CMap and do not match the §7.21.7 exemption list. The exemption list covers the predefined MacRomanEncoding / MacExpertEncoding / WinAnsiEncoding, Type 0 fonts whose descendant CIDFont uses the Adobe GB1 / CNS1 / Japan1 / Korea1 character collections, and non-symbolic TrueType fonts.
10024The first heading element in document order is not H1 (or the strongly-structured H). ISO 14289-1 §7.4.2: "If any heading tags are used, H1 shall be the first."
10025One or more heading-level skips were detected in document order — e.g. an H1 immediately followed by an H3, skipping H2. ISO 14289-1 §7.4.2 requires descending heading sequences to proceed in strict numerical order without skipping intervening levels.
10026One or more Widget annotations lack a /StructParent entry. ISO 14289-1 §7.18.4 requires Widget annotations to be nested within a Form structure tag; without /StructParent the Widget cannot possibly be reached from the structure tree. The detail line reports the count.
10027One or more Widget annotations have a /StructParent entry but the value does not resolve through StructTreeRoot/ParentTree to a structure element with /S = Form. ISO 14289-1 §7.18.4 requires every Widget annotation to be nested within a Form structure tag. Possible causes: the /ParentTree entry is missing entirely, points to a non-StructElem (raw integer / MCR dict), or names a non-Form tag.
10028One or more non-symbolic TrueType fonts have /Encoding (or an Encoding dictionary's /BaseEncoding) that is not MacRomanEncoding or WinAnsiEncoding. ISO 14289-1 §7.21.6 restricts non-symbolic TrueType encoding to these two predefined names.
10029One or more symbolic TrueType fonts carry an /Encoding entry in the font dictionary. ISO 14289-1 §7.21.6 fourth paragraph forbids that — symbolic TrueType encoding must be expressed through the embedded font program's cmap table only.
10030One or more L (list) structure elements lack the ListNumbering attribute. ISO 14289-1 §7.6 requires every L tag to declare its numbering style via this attribute. Valid values are None, Disc, Circle, Square, Decimal, UpperRoman, LowerRoman, UpperAlpha, and LowerAlpha (ISO 32000-1 Table 347).
10031One or more Link annotations carry a URI action dictionary whose /IsMap entry is true. ISO 14289-1 §7.18.5 forbids /IsMap = true on a URI action unless equivalent functionality is provided elsewhere in the content without an /IsMap key. Authors with a legitimate IsMap use case should suppress this diagnostic on their own.
10032One or more Note structure elements lack the /ID entry. ISO 14289-1 §7.9 requires every Note tag to declare a unique /ID so cross-references can land on a stable target.
10033Two or more Note structure elements share the same /ID value. The detail line reports the number of duplicate pairs detected. ISO 14289-1 §7.9 requires Note IDs to be unique within the document.
10034One or more non-symbolic TrueType programs (FontDescriptor with Symbolic flag cleared, FontFile2 stream present) embed a cmap table whose only subtable is the symbolic (3,0) Microsoft entry. ISO 14289-1 §7.21.6 first paragraph requires at least one non-symbolic cmap subtable so the program can render the codepoints declared by its /Encoding.
10035One or more non-symbolic TrueType fonts declare an /Encoding with a /Differences array containing glyph names that are not members of the Adobe Glyph List 2.0. .notdef is whitelisted because the spec implicitly allows it. ISO 14289-1 §7.21.6 third paragraph requires every Differences entry to land in AGL.
10042One or more media clip data dictionaries (identified by /S /MCD, optionally /Type /MediaClip) lack the required /CT content-type entry. ISO 14289-1 §7.18.6 promotes this ISO 32000-1 Table 274 optional key to required.
10043One or more media clip data dictionaries lack the required /Alt array (language-string + alternate-text pairs). ISO 14289-1 §7.18.6 promotes this ISO 32000-1 Table 274 optional key to required so assistive technology can announce a description for embedded multimedia.
10044One or more structure tree nodes carry more than one direct H (generic heading) child. ISO 14289-1 §7.4.4 explicitly forbids this — split the section, or replace the H tags with numbered H1..H6 levels.

Remarks

The PDF/A test is intended as a fast self-check before delivery. It catches the document-level issues that disqualify a file outright (wrong PDF version, missing OutputIntent, missing structure tree at the A level, encryption, layers in PDF/A-1). It does not walk every content-stream operator nor verify font embedding or colour-space references for each painted object — those validations require a dedicated PDF/A validator (such as veraPDF). Use this function as a first-line check and as a regression gate in build pipelines. Use CreatePreflightReport or SavePreflightReport when you want the library to format the issue lists into a reusable text report. Use CreatePreflightReportEx or SavePreflightReportEx for text, JSON, HTML, or CSV report output, or see Preflight Reports for the complete report workflow.

The companion API GetPDFUADiagnostics performs analogous checks for PDF/UA-1 (ISO 14289-1) on the in-memory document currently being built, rather than on an external file.

When producing PDF/A output with this library, call SetPDFAMode before adding any content. The generation-side guard inside SetPDFAMode blocks the operations forbidden by the chosen part, so a document built that way will normally pass CheckFileCompliance automatically.

Example

// Validate a delivered PDF/A file and print all issues
var
  Issues, Count, I: Integer;
begin
  Issues := PDF.CheckFileCompliance('archive.pdf', '', 1, 0);
  if Issues = 0 then
    WriteLn('archive.pdf: PDF/A conformant')
  else
  begin
    Count := PDF.GetStringListCount(Issues);
    WriteLn('archive.pdf: ', Count, ' PDF/A issue(s) detected:');
    for I := 1 to Count do
      WriteLn('  ', PDF.GetStringListItem(Issues, I));
  end;
end;

// Fast pass/fail gate in a CI pipeline — stop on the first issue
var
  Failed: Boolean;
begin
  Failed := PDF.CheckFileCompliance('build/output.pdf', '', 1, 1) <> 0;
  if Failed then
    Halt(1);
end;

See also

Preflight Reports, CreatePreflightReport, CreatePreflightReportEx, SavePreflightReport, SavePreflightReportEx, ComparePreflightReports, SetPDFAMode, GetPDFUADiagnostics, GetStringListCount, GetStringListItem, SetPDFUAMode