THotPDF Preflight Report Methods

Syntax

type
  THPDFPreflightFormat = (pfText, pfJSON, pfHTML, pfCSV);

function CreatePreflightReport(const SourceFile: TFileName): AnsiString;
function CreatePreflightReport(
  const SourceFile: TFileName;
  const Password  : AnsiString): AnsiString;
function CreatePreflightReport(
  const SourceFile: TFileName;
  const Password  : AnsiString;
  const Format    : THPDFPreflightFormat): AnsiString;
procedure SavePreflightReport(
  const SourceFile: TFileName;
  const ReportFile: TFileName);
procedure SavePreflightReport(
  const SourceFile: TFileName;
  const ReportFile: TFileName;
  const Password  : AnsiString);
procedure SavePreflightReport(
  const SourceFile: TFileName;
  const ReportFile: TFileName;
  const Password  : AnsiString;
  const Format    : THPDFPreflightFormat);
function ValidatePDFVT(
  const SourceFile: TFileName;
  out Report      : AnsiString): Boolean;
function ValidatePDFVT(
  const SourceFile: TFileName;
  const Password  : AnsiString;
  out Report      : AnsiString): Boolean;
procedure EmbedPreflightReportInPDF(
  const SourceFile: TFileName;
  const TargetFile: TFileName);
procedure EmbedPreflightReportInPDF(
  const SourceFile: TFileName;
  const TargetFile: TFileName;
  const Password  : AnsiString);
function LoadAndValidatePreflightReport(
  const EmbeddedFile  : TFileName;
  out OriginalReport: AnsiString;
  out CurrentReport : AnsiString): Boolean;
function LoadAndValidatePreflightReport(
  const EmbeddedFile  : TFileName;
  const Password      : AnsiString;
  out OriginalReport: AnsiString;
  out CurrentReport : AnsiString): Boolean;
function ComparePreflightReports(
  const ReportA: AnsiString;
  const ReportB: AnsiString): AnsiString;
function RepairPDFFromPreflightReport(
  const SourceFile: TFileName;
  const TargetFile: TFileName;
  out RepairsApplied: AnsiString): Boolean;
function RepairPDFFromPreflightReport(
  const SourceFile: TFileName;
  const TargetFile: TFileName;
  const Password  : AnsiString;
  out RepairsApplied: AnsiString): Boolean;
function AggregatePreflightReports(
  const Reports: array of AnsiString): AnsiString;
type
  THPDFPreflightProfile = record
    DisableChecks  : AnsiString;
    DisableWarnings: AnsiString;
    DisableHints   : Boolean;
  end;
function LoadPreflightProfile(
  const ProfileFile: TFileName): THPDFPreflightProfile;
function ApplyPreflightProfile(
  const Report : AnsiString;
  const Profile: THPDFPreflightProfile): AnsiString;
function ValidatePreflightProfile(
  const Profile: THPDFPreflightProfile;
  out UnknownNames: AnsiString): Boolean;
function GetBuiltInPreflightProfile(
  const Name: AnsiString): THPDFPreflightProfile;
procedure SavePreflightProfile(
  const Profile    : THPDFPreflightProfile;
  const ProfileFile: TFileName);
function CreatePreflightReportWithProfile(
  const SourceFile : TFileName;
  const Password   : AnsiString;
  const ProfileFile: TFileName;
  const Format     : THPDFPreflightFormat): AnsiString;
function MergePreflightProfiles(
  const A, B: THPDFPreflightProfile): THPDFPreflightProfile;
function DiffPreflightProfiles(
  const A, B  : THPDFPreflightProfile;
  out OnlyInA: AnsiString;
  out OnlyInB: AnsiString): Boolean;
procedure EmbedPreflightReportAsXMP(
  const SourceFile: TFileName;
  const TargetFile: TFileName);
procedure EmbedPreflightReportAsXMP(
  const SourceFile: TFileName;
  const TargetFile: TFileName;
  const Password  : AnsiString);
function ConvertPreflightReportToVeraPDFStyle(
  const Report: AnsiString): AnsiString;

Опис

CreatePreflightReport читає input PDF і повертає text report з lightweight structural checks Password overloads використовують наявний password-aware load path для supported encrypted PDFs SavePreflightReport записує той самий report у target text file

ValidatePDFVT запускає focused PDF/VT validation pass і повертає True лише коли потрібні markers і structures присутні Returned text report перевіряє XMP claim pdfvtid:GTS_PDFVTVersion, namespace metadata PDF/VT, збіг PDF/VT modification date і xmp:ModifyDate, marker PDF/X base, відсутність encryption, PDF/X output intent, catalog DPartRoot, DPartRootNode, NodeNameList, presence document part, loadable page count і page-level DPart coverage Властивості date PDF/VT і XMP можуть бути записані як element text або як RDF attributes на rdf:Description element

Report перевіряє PDF header, EOF marker, чи фінальний %%EOF marker близький до кінця file, last startxref offset, чи цей offset вказує на xref table або xref stream, counts %%EOF і startxref markers, revision marker balance і final marker ordering, trailer або XRef stream marker, loadable page count, encryption state, catalog, page tree, page object marker, MediaBox, information dictionary reference, root reference, indirect object count, indirect object definition count, highest object number, duplicate object number count, object number uniqueness, catalog object count, page tree object count, page object count, page tree declared page count, consistency page tree count/loadable page, consistency page object/loadable page, stream/endstream balance, stream /Length coverage, counts xref table/subsection/entries, free та in-use xref entries, malformed xref rows, xref validity і coverage щодо object numbers

The Format overload accepts pfText (default plain-text path, byte-stable with the legacy overloads), pfJSON (CI-friendly JSON document), pfHTML (dashboard-ready, self-contained HTML report with inline CSS and severity-colored rows), or pfCSV (spreadsheet-friendly rows for metadata, checks, hints, warnings, and summary values). The JSON output groups entries into input, size, pdfVersion, and xrefStyle top-level fields plus checks, info, hints, and warnings arrays and a summary object carrying failed, warnings, and result values. The CSV output uses the stable header category,name,status,value,spec, with ISO reference text in spec when the diagnostic has a mapped standard clause. The built-in JSON encoder escapes ", \, and control bytes; UTF-8 byte sequences pass through unchanged.

Кожен entry у checks, hints і warnings має optional field spec, що називає ISO clause, на який спрямована diagnostic (наприклад ISO 32000-1 sec 7.5.5 для trailer-related checks, ISO 19005-1 sec 6.6.2 для warning PDF/A з взаємовиключенням JavaScript) Mapping покриває кожен check, hint і warning, emitted report до v2.122.0 Formal JSON Schema (draft 2020-12), що описує pfJSON output structure, опублікована в Docs/preflight-schema.json, щоб downstream consumers могли validate output перед parsing

EmbedPreflightReportInPDF записує copy source PDF у TargetFile з legacy text-format preflight report, appended після останнього %%EOF як PDF-style comment lines (кожен рядок prefixed with % ) PDF readers ignore appended bytes, бо вони поза object graph, але archive workflows, text editors і grep-style tools усе ще можуть показати embedded report для later audit Original object graph, cross-reference table і trailer не змінюються

LoadAndValidatePreflightReport extracts the report that EmbedPreflightReportInPDF previously appended, re-runs the current preflight algorithm against the source bytes preceding the embedded comment block, and compares the InputFingerprint values. The function returns True when both fingerprints match, indicating the embedded report still describes the file as it exists on disk When validation fails, callers can inspect OriginalReport and CurrentReport to diff what changed.

ComparePreflightReports emits a unified-diff-like body for two reports. Shared lines appear with a two-space prefix, lines unique to ReportA are prefixed with , and lines unique to ReportB are prefixed with . The algorithm is tuned for the well-formed key/value output produced by CreatePreflightReport where line order is deterministic; it is not a general-purpose LCS implementation but produces compact, readable diffs for the typical case of mostly-unchanged reports.

RepairPDFFromPreflightReport applies a conservative subset of byte-level repairs to a damaged PDF: it drops trailing bytes that follow the final %%EOF marker, and appends a missing %%EOF when one is not present anywhere. The function returns True when at least one repair was applied; RepairsApplied lists the repairs as one line per change. Object-graph repairs (rebuilding xref tables, patching stream lengths, fixing trailer dictionaries) are intentionally out of scope because such fixes can make a partially-recoverable file less recoverable; use a dedicated PDF recovery tool for deeper damage.

AggregatePreflightReports приймає array per-file reports і створює single batch summary Кожен entry array parse для fields Input, Size і Summary; aggregate emit один рядок на file плюс totals для passed, failed і warning reports, total bytes scanned і overall result counts Корисно для CI pipelines і shell loops, що обробляють directory PDFs і хочуть short summary наприкінці

LoadPreflightProfile and ApplyPreflightProfile let callers tailor the report output without re-running the analysis. The profile file uses an INI-style format with three optional sections: [disable-checks] lists check names to suppress; [disable-warnings] lists warning names to suppress; and [options] accepts hints=false to suppress every Hint line. After filtering, the Summary line is recomputed so the suppressed entries no longer contribute to the Failed and Warnings totals; the rest of the report passes through unchanged.

ValidatePreflightProfile проходить lists DisableChecks і DisableWarnings завантаженого profile і reports будь-яке name, не відоме current preflight implementation Корисно для detecting profile files, authored against newer або older HotPDF version, які інакше silently disable nothing, бо names не match emitted check або warning

GetBuiltInPreflightProfile returns ready-to-use profile records for common workflows. Recognized names (case-insensitive): default / '' returns an empty profile; compact disables every Hint line for shorter reports; silent-actions disables every PDF 1.7 sec 12.6.4 action warning plus EmbeddedFile and RichMedia, intended for workflows that intentionally embed multimedia or interactive actions and do not want the preflight report to flag them. Unknown names also return an empty profile.

SavePreflightProfile writes a THPDFPreflightProfile record back to an INI file in the same format that LoadPreflightProfile consumes The two functions are exact inverses for well-formed profiles, so callers can build a 'load preset, tweak, save' workflow: P := GetBuiltInPreflightProfile('compact'), edit P.DisableChecks, then SavePreflightProfile(P, 'tuned.ini') for later reuse.

CreatePreflightReportWithProfile є one-stop convenience wrapper, що composes existing CreatePreflightReport, LoadPreflightProfile, ApplyPreflightProfile і format converters, щоб caller з source PDF, optional password, profile file і target format міг issue single call замість chaining four Передавання empty ProfileFile пропускає profile step

MergePreflightProfiles повертає deduplicated union двох profiles: DisableChecks і DisableWarnings collect names з обох inputs, DisableHints є logical OR Корисно для layering preset поверх project-specific tweaks

DiffPreflightProfiles reports the structural difference between two profiles. Returns True when they are equivalent; otherwise False with OnlyInA and OnlyInB filled with newline-separated lines of the form check:<name>, warn:<name>, or option:hints=false describing which entries are exclusive to each side.

EmbedPreflightReportAsXMP is an archival-friendly variant of EmbedPreflightReportInPDF: it writes a copy of the source PDF with the preflight report appended as a PDF-style comment block whose payload is XMP / RDF (xmlns:hotpdf="http://www.loslab.com/hotpdf/preflight/") Each report line becomes a hotpdf:<name> element with severity carried as an attribute on check rows XMP-aware tools that scan a file for xpacket markers can surface the embedded report; PDF readers continue to ignore the appended bytes because they fall outside the object graph. This is intentionally not a spec-compliant XMP integration: the XMP payload is not referenced from the catalog /Metadata entry, so XMP readers that only follow the catalog reference will not see it.

ConvertPreflightReportToVeraPDFStyle формує HotPDF preflight report у JSON document, що наслідує broad outline validation output veraPDF, з top-level profile field, jobs array з itemDetails / taskResult / validationResult і ruleViolations array у validationResult.details Це HotPDF-styled, а не wire-compatible з veraPDF; мета - дозволити downstream tooling, яке вже consumes veraPDF JSON, адаптуватися до HotPDF output з мінімальним remapping field-name замість вивчати зовсім іншу data layout

Example

var
  PDF: THotPDF;
begin
  PDF := THotPDF.Create(nil);
  try
    PDF.SavePreflightReport('Input.pdf', 'PreflightReport.txt');
    PDF.SavePreflightReport('Encrypted.pdf', 'EncryptedReport.txt', 'user-password');
    PDF.SavePreflightReport('Input.pdf', 'PreflightReport.json', '', pfJSON);
    PDF.SavePreflightReport('Input.pdf', 'PreflightReport.html', '', pfHTML);
    PDF.SavePreflightReport('Input.pdf', 'PreflightReport.csv', '', pfCSV);
    PDF.EmbedPreflightReportInPDF('Input.pdf', 'Input-with-report.pdf');
    if not PDF.LoadAndValidatePreflightReport(
      'Input-with-report.pdf', OriginalReport, CurrentReport)
    then
      WriteLn('Embedded preflight report no longer matches the source.');
  finally
    PDF.Free;
  end;
end;

See Also