THotPDF Preflight Report Methods

Składnia

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;

Opis

CreatePreflightReport odczytuje wejściowy PDF i zwraca raport tekstowy z lekkimi kontrolami struktury. Przeciążenia z hasłem używają istniejącej ścieżki ładowania obsługującej hasła dla wspieranych szyfrowanych PDF. SavePreflightReport zapisuje ten sam raport do docelowego pliku tekstowego.

ValidatePDFVT uruchamia ukierunkowaną walidację PDF/VT i zwraca True tylko wtedy, gdy wymagane znaczniki i struktury są obecne. Zwrócony raport tekstowy sprawdza deklarację XMP pdfvtid:GTS_PDFVTVersion, przestrzeń nazw metadanych PDF/VT, zgodność daty modyfikacji PDF/VT z xmp:ModifyDate, bazowy znacznik PDF/X, brak szyfrowania, intencję wyjściową PDF/X, katalogowe DPartRoot, DPartRootNode, NodeNameList, obecność części dokumentu, ładowalną liczbę stron oraz pokrycie DPart na poziomie strony. Właściwości dat PDF/VT i XMP mogą być zapisane jako tekst elementu albo jako atrybuty RDF na elemencie rdf:Description.

Raport sprawdza nagłówek PDF, znacznik EOF, czy końcowy %%EOF leży blisko końca pliku, ostatni offset startxref, czy ten offset wskazuje tabelę xref albo strumień xref, liczbę znaczników %%EOF i startxref, równowagę znaczników rewizji i końcową kolejność znaczników, znacznik trailera albo strumienia XRef, ładowalną liczbę stron, stan szyfrowania, katalog, drzewo stron, znacznik obiektu strony, MediaBox, referencję słownika informacji, referencję root, liczbę obiektów pośrednich, liczbę definicji obiektów pośrednich, najwyższy numer obiektu, liczbę zduplikowanych numerów obiektów, unikalność numerów obiektów, liczbę obiektów katalogu, liczbę obiektów drzewa stron, liczbę obiektów stron, zadeklarowaną liczbę stron w drzewie stron, spójność liczby stron drzewa stron i ładowalnych stron, spójność obiektów stron i ładowalnych stron, równowagę stream i endstream, pokrycie wpisów /Length strumieni, liczbę tabel xref, liczbę podsekcji xref, liczby wpisów tabel xref, liczby wolnych i używanych wpisów xref, liczbę uszkodzonych wierszy xref, poprawność wierszy xref, pokrycie xref względem numerów obiektów, liczbę strumieni xref, liczbę strumieni obiektów, liczbę trailerów, trailer /Size, czy trailer /Size obejmuje najwyższy numer obiektu, pośrednie referencje trailera /Root i /Info, czy wskazane obiekty są zdefiniowane, czy trailer /Root wskazuje obiekt katalogu, liczbę wpisów tablicy trailer /ID i strukturę par, obecność trailer /Root, /Info, /ID i /Encrypt, szacowaną liczbę aktualizacji przyrostowych, status linearyzacji, załadowane pola stron, liczbę pól formularza, liczbę słowników zasobów, liczbę zasobów fontów, liczbę osadzonych programów fontów (/FontFile, /FontFile2, /FontFile3), liczbę image XObject, liczbę form XObject, liczbę zasobów ColorSpace, liczbę adnotacji oraz podliczby adnotacji widget/link, liczniki użycia łańcuchów filtrów dla FlateDecode, DCTDecode, CCITTFaxDecode, JBIG2Decode, LZWDecode, ASCIIHexDecode, ASCII85Decode, RunLengthDecode i JPXDecode, pokrycie osadzania fontów, spójność liczby adnotacji, wskazówki zgodności PDF/A / PDF/X / PDF/UA / Tagged PDF / transparency, wybrane flagi funkcji, ostrzeżenia JavaScript albo action (obejmujące pełny zestaw PDF 1.7 sec 12.6.4 action: GoTo*, Thread, URI, Sound, Movie, Hide, Named, SubmitForm, ResetForm, ImportData, SetOCGState, Rendition, Trans i GoTo3DView, plus starsze kontrole JavaScript / Launch / OpenAction / AdditionalActions / EmbeddedFile / RichMedia oraz ostrzeżenia wzajemnego wykluczenia PDF/A), sumy ostrzeżeń oraz ogólne podsumowanie pass/fail. Te pomocniki są przeznaczone jako szybkie kontrole in-process przed przekazaniem plików do zewnętrznych walidatorów standardów; nie zastępują pełnego silnika walidacji preflight PDF/A, PDF/X, PDF/UA ani ISO 32000.

The Format overload accepts pfText (default plain-text path, byte-stable with the legacy overloads), pfJSON (CI-friendly JSON document), or pfHTML (dashboard-ready, self-contained HTML report with inline CSS and severity-coloured rows). 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 built-in JSON encoder escapes ", \, and control bytes; UTF-8 byte sequences pass through unchanged.

Każdy wpis checks, hints i warnings niesie opcjonalne pole spec, które wskazuje klauzulę ISO docelową dla diagnostyki (na przykład ISO 32000-1 sec 7.5.5 dla kontroli trailera, ISO 19005-1 sec 6.6.2 dla ostrzeżenia wzajemnego wykluczenia PDF/A z JavaScript). Mapowanie obejmuje każdą kontrolę, wskazówkę i ostrzeżenie emitowane przez raport do v2.122.0. Formalny JSON Schema (draft 2020-12) opisujący strukturę wyjścia pfJSON jest publikowany w Docs/preflight-schema.json, aby odbiorcy downstream mogli zwalidować wyjście przed parsowaniem.

EmbedPreflightReportInPDF zapisuje kopię źródłowego PDF do TargetFile z raportem preflight w starszym formacie tekstowym dołączonym po ostatnim %%EOF jako linie komentarzy w stylu PDF (każda linia poprzedzona ). Czytniki PDF ignorują dołączone bajty, ponieważ znajdują się poza grafem obiektów, ale przepływy archiwizacji, edytory tekstu i narzędzia w stylu grep mogą nadal odnaleźć osadzony raport do późniejszego audytu. Oryginalny graf obiektów, tabela cross-reference i trailer nie są modyfikowane.

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 przyjmuje tablicę raportów per plik i tworzy jedno podsumowanie batch. Każdy wpis tablicy jest parsowany pod kątem pól Input, Size i Summary; agregat emituje jedną linię na plik oraz sumy liczby raportów passed, failed i warning, łącznych przeskanowanych bajtów oraz ogólnych liczników wyników. Przydatne dla potoków CI i pętli shell, które przetwarzają katalog PDF i chcą jednego zwięzłego podsumowania na końcu.

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 przechodzi przez listy DisableChecks i DisableWarnings załadowanego profilu i zgłasza każdą nazwę nierozpoznawaną przez bieżącą implementację preflight. Pomaga wykryć pliki profili napisane dla nowszej lub starszej wersji HotPDF, które w przeciwnym razie po cichu nie wyłączyłyby niczego, ponieważ nazwy nie pasują do żadnej emitowanej kontroli ani ostrzeżenia.

GetBuiltInPreflightProfile returns ready-to-use profile records for common workflows. Recognised 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 to wygodny wrapper jednego kroku, który składa istniejące CreatePreflightReport, LoadPreflightProfile, ApplyPreflightProfile i konwertery formatów, dzięki czemu wywołujący mający już źródłowy PDF, opcjonalne hasło, plik profilu i format docelowy może wykonać jedno wywołanie zamiast łączyć cztery. Przekazanie pustego ProfileFile pomija krok profilu.

MergePreflightProfiles zwraca zdeduplikowaną sumę dwóch profili: DisableChecks i DisableWarnings zbierają nazwy z obu wejść, a DisableHints jest logicznym OR. Przydatne do nakładania presetu na poprawki specyficzne dla projektu.

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 formuje raport preflight HotPDF w dokument JSON zgodny z ogólnym zarysem wyjścia walidacji veraPDF, z polem najwyższego poziomu profile, tablicą jobs zawierającą itemDetails / taskResult / validationResult oraz tablicą ruleViolations pod validationResult.details. Jest stylizowany na HotPDF, a nie binarnie zgodny z veraPDF; celem jest umożliwienie narzędziom downstream, które już konsumują JSON veraPDF, adaptacji do wyjścia HotPDF przy minimalnym remapowaniu nazw pól zamiast uczenia się całkowicie innego układu danych.

Przykład

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;

Zobacz też