|
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는 입력 PDF를 읽고 lightweight structural check가 포함된 text report를 반환합니다. Password overload는 지원되는 encrypted PDF에 대해 기존 password-aware load path를 사용합니다. SavePreflightReport는 같은 report를 대상 text file에 씁니다
ValidatePDFVT는 집중적인 PDF/VT validation pass를 실행하고 필요한 marker와 structure가 있을 때만 True를 반환합니다. 반환되는 text report는 pdfvtid:GTS_PDFVTVersion XMP claim, PDF/VT metadata namespace, PDF/VT modification date와 xmp:ModifyDate 일치, PDF/X base marker, encryption 부재, PDF/X output intent, catalog DPartRoot, DPartRootNode, NodeNameList, document part 존재, loadable page count, page-level DPart coverage를 검사합니다. PDF/VT 및 XMP date property는 element text 또는 rdf:Description element의 RDF attribute로 작성될 수 있습니다
Report는 PDF header, EOF marker, 최종 %%EOF marker가 파일 끝 근처에 있는지 여부, 마지막 startxref offset, 해당 offset이 xref table 또는 xref stream을 가리키는지 여부, %%EOF 및 startxref marker count, 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, page tree count/loadable page consistency, page object/loadable page consistency, stream 및 endstream balance, stream /Length entry coverage, xref table count, xref subsection count, xref table entry count, xref free 및 in-use entry count, malformed xref row count, xref row validity, object number 대비 xref coverage, xref stream count, object stream count, trailer count, trailer /Size, trailer /Size가 highest object number를 포함하는지 여부, trailer /Root 및 /Info indirect reference, 참조된 object가 정의되어 있는지 여부, trailer /Root가 catalog object를 가리키는지 여부, trailer /ID array entry count와 pair structure, trailer /Root, /Info, /ID, /Encrypt 존재 여부, estimated incremental update count, linearization status, loaded page boxes, form field count, resource dictionary count, font resource count, embedded font program count(/FontFile, /FontFile2, /FontFile3), image XObject count, form XObject count, ColorSpace resource count, annotation count 및 widget/link annotation subcount, FlateDecode, DCTDecode, CCITTFaxDecode, JBIG2Decode, LZWDecode, ASCIIHexDecode, ASCII85Decode, RunLengthDecode, JPXDecode에 대한 filter chain usage count, font embedding coverage, annotation count consistency, PDF/A / PDF/X / PDF/UA / Tagged PDF / transparency compliance hint, selected feature flags, JavaScript 또는 action warning(PDF 1.7 sec 12.6.4 전체 action set인 GoTo*, Thread, URI, Sound, Movie, Hide, Named, SubmitForm, ResetForm, ImportData, SetOCGState, Rendition, Trans, GoTo3DView와 legacy JavaScript / Launch / OpenAction / AdditionalActions / EmbeddedFile / RichMedia check 및 PDF/A mutual-exclusion warning 포함), warning total, 전체 pass/fail summary를 검사합니다. 이 helper는 외부 standards validator에 파일을 넘기기 전 빠른 in-process check를 위한 것이며, 전체 PDF/A, PDF/X, PDF/UA 또는 ISO 32000 preflight validation engine을 대체하지 않습니다
Format overload는 pfText(기본 plain-text path, legacy overload와 byte-stable), pfJSON(CI 친화 JSON document), pfHTML(inline CSS와 severity-colored row가 있는 dashboard-ready self-contained HTML report), pfCSV(metadata, checks, hints, warnings, summary value를 위한 spreadsheet-friendly row)를 받습니다. JSON output은 entry를 input, size, pdfVersion, xrefStyle top-level field와 checks, info, hints, warnings array 및 failed, warnings, result 값을 담는 summary object로 묶습니다. CSV output은 안정적인 header category,name,status,value,spec을 사용하며 diagnostic에 mapping된 standard clause가 있으면 spec에 ISO reference text를 넣습니다. 내장 JSON encoder는 ", \, control byte를 escape하고 UTF-8 byte sequence는 그대로 통과시킵니다
각 checks, hints, warnings entry는 diagnostic이 대상으로 하는 ISO clause를 이름으로 담는 선택적 spec field를 가집니다(예: trailer 관련 check는 ISO 32000-1 sec 7.5.5, PDF/A with JavaScript mutual-exclusion warning은 ISO 19005-1 sec 6.6.2). 이 mapping은 v2.122.0까지 report가 내보내는 모든 check, hint, warning을 포함합니다. pfJSON output 구조를 설명하는 공식 JSON Schema(draft 2020-12)는 Docs/preflight-schema.json에 게시되어 downstream consumer가 parsing 전에 output을 validate할 수 있습니다
EmbedPreflightReportInPDF는 source PDF의 사본을 TargetFile에 쓰고, legacy text-format preflight report를 마지막 %%EOF 뒤에 PDF-style comment line(각 줄은 % prefix)으로 붙입니다. 추가된 byte는 object graph 밖에 있으므로 PDF reader는 무시하지만 archive workflow, text editor, grep-style tool은 나중의 audit을 위해 embedded report를 표시할 수 있습니다. 원래 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는 두 report에 대해 unified-diff와 유사한 body를 내보냅니다. 공통 line은 two-space prefix로 표시되고, ReportA에만 있는 line은 - , ReportB에만 있는 line은 + prefix로 표시됩니다. 이 알고리즘은 line order가 deterministic한 CreatePreflightReport의 well-formed key/value output에 맞춰 조정되어 있습니다. 범용 LCS 구현은 아니지만 대부분 변경되지 않은 report의 일반적인 경우에 compact하고 readable한 diff를 생성합니다
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는 per-file report array를 받아 하나의 batch summary를 생성합니다. Array의 각 entry에서 Input, Size, Summary field를 parsing하며, aggregate는 파일당 한 줄과 함께 passed, failed, warning report 수, scan한 총 byte, 전체 result count를 출력합니다. PDF directory를 처리하고 끝에 간결한 summary 하나를 원하는 CI pipeline과 shell loop에 유용합니다
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은 로드된 profile의 DisableChecks 및 DisableWarnings list를 순회하며 현재 preflight implementation이 인식하지 못하는 이름을 보고합니다. 이름이 어떤 emitted check나 warning과도 일치하지 않아 실제로는 아무것도 disable하지 않는, 더 새롭거나 오래된 HotPDF version을 기준으로 작성된 profile file을 감지하는 데 유용합니다
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은 기존 CreatePreflightReport, LoadPreflightProfile, ApplyPreflightProfile, format converter를 조합한 one-stop convenience wrapper입니다. Source PDF, optional password, profile file, target format을 이미 가진 호출자는 네 단계를 연결하는 대신 한 번만 호출하면 됩니다. 빈 ProfileFile을 전달하면 profile 단계는 건너뜁니다
MergePreflightProfiles는 두 profile의 deduplicated union을 반환합니다. DisableChecks와 DisableWarnings는 양쪽 입력의 이름을 모으고, DisableHints는 logical OR가 됩니다. Project-specific tweak 위에 preset을 겹쳐 적용할 때 유용합니다
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를 veraPDF validation output의 큰 윤곽을 따르는 JSON document로 구성합니다. Top-level profile field, itemDetails / taskResult / validationResult를 포함하는 jobs array, validationResult.details 아래의 ruleViolations array를 가집니다. veraPDF와 wire-compatible하기보다는 HotPDF 스타일에 맞춘 형식이며, 목표는 이미 veraPDF JSON을 소비하는 downstream tooling이 완전히 다른 data layout을 새로 익히지 않고 최소한의 field-name remapping으로 HotPDF output에 적응할 수 있게 하는 것입니다
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
|