TVt2sChunkKind = (vtckInlinePdf, vtckAttachmentPdf, vtckIccProfile);
TPdfVT2sChunk = record
Kind: TVt2sChunkKind;
Bytes: TBytes;
FileName: AnsiString;
end;
TPdfVT2sChunks = array of TPdfVT2sChunk;
TAnsiStrings = array of AnsiString;
TPdfVT2sValidationResult = record
Issues: TPdfVT2sValidationIssues;
function IsCompliant: Boolean;
end;
TPdfVTPrintingConditionSource = (vtpcsNone, vtpcsEmbeddedProfile, vtpcsMimeProfile);
TPdfVTPrintingConditionEvidence = record
PartIndex: Integer;
Conformance: TPdfVTConformance;
PdfXVersion: AnsiString;
OutputIntentObjectNumber: Integer;
OutputConditionIdentifier: AnsiString;
RegistryName: AnsiString;
Source: TPdfVTPrintingConditionSource;
ProfileFileName: AnsiString;
ProfileName: AnsiString;
ProfileColorSpace: AnsiString;
ProfileByteSize: Int64;
ProfileMd5: string;
ProfileSha256: string;
ProfileVersion: string;
ProfileDeviceClass: string;
ProfilePcs: string;
ProfileComponentCount: Integer;
Resolved: Boolean;
ProfileValid: Boolean;
DPart: TPdfVTDPartEvidence;
end;
TPdfVT2sValidationReport = record
Validation: TPdfVT2sValidationResult;
PrintingConditions: TPdfVTPrintingConditionEvidenceArray;
end;
procedure BuildPdfVT2sStream(const Chunks: TPdfVT2sChunks; Dest: TStream);
function ValidatePdfVT2sStream(Source: TStream): TPdfVT2sValidationResult;
function InspectPdfVT2sStream(Source: TStream): TPdfVT2sValidationReport;
FPdfPdfvtMime 實作 ISO 16612-2 附錄定義的 PDF/VT-2s 傳輸方式,將 PDF/VT 文件連同其參照的可重用 PDF 內容與 ICC 描述檔包裝成單一 MIME multipart 串流
不同於寫出獨立 PDF/VT-1 檔案的 TPdf.SaveAsPdfVT 路徑,本單元純粹在位元組串流上運作,且從不載入 pdfium.dll,因此可在無 UI 伺服器與批次管線中執行
BuildPdfVT2sStream 依序組裝區段,輸出 StreamVersion 檔頭、部分邊界與各部分的 Content-Type / Content-Disposition 檔頭;ValidatePdfVT2sStream 重新解析既有串流,並以型別化問題集合回報結構、印刷條件與 ICC 偏差
InspectPdfVT2sStream 傳回相同的相容性結果,外加每個 PDF/VT 部分的證據,包括 PDF/VT 遵循性、PDF/X 基礎、OutputIntent 識別、描述檔來源、MD5 與 SHA-256、原始 ICC 中繼資料,以及 DPart 頁面與收件者記錄計數
每個 PDF 部分會先以 ValidatePdfVTCompliance 分類;僅 PDF/X 的可重用附件仍是合格的參照目標,但會從 PDF/VT 階層與印刷條件比較中排除
描述檔封裝依檔案基礎而定:PDF/VT-1 搭配 PDF/X-4 與 PDF/VT-2 搭配 PDF/X-5g 使用內嵌的 DestOutputProfile,而 PDF/VT-2 搭配 PDF/X-4p 或 PDF/X-5pg 則使用 DestOutputProfileRef,解析到較早的 ICC MIME 部分
| Value | MIME 角色 |
|---|---|
vtckInlinePdf | 以內嵌 application/pdf 部分承載的 PDF/VT 文件;至少需要一個 |
vtckAttachmentPdf | 由內嵌文件參照的可重用 PDF 內容部分,以帶檔名的 attachment 承載 |
vtckIccProfile | 以帶檔名附件形式提供的 ICC 描述檔部分(application/vnd.iccprofile) |
| Type | Purpose |
|---|---|
TPdfVT2sChunks | 提供給 BuildPdfVT2sStream 的有序 MIME 區段動態陣列 |
TAnsiStrings | 驗證內嵌 PDF 中外部檔案參照時使用的動態檔名陣列 |
TPdfVT2sValidationIssues | 驗證所傳回 TPdfVT2sValidationIssue 發現項目的集合 |
TPdfVTPrintingConditionSource | 描述檔證據的來源:vtpcsNone 表示未解析、vtpcsEmbeddedProfile 表示內嵌 DestOutputProfile 串流、vtpcsMimeProfile 表示從 ICC MIME 部分解析的 DestOutputProfileRef |
TPdfVTPrintingConditionEvidence | 每個部分的 PDF/VT 與 PDF/X 分類、OutputIntent、描述檔來源、識別、摘要、ICC 檔頭與 DPart 事實 |
TPdfVT2sValidationReport | InspectPdfVT2sStream 傳回的詳細結果,不變更舊版結果配置 |
| Value | 回報時機 |
|---|---|
vtmviNotMultipart | 串流不是 multipart MIME 容器 |
vtmviMissingStreamVersion | 缺少必要的 PDF/VT StreamVersion 檔頭 |
vtmviStreamVersionValue | StreamVersion 值不是預期的 1 |
vtmviStreamVersionAfterCt | StreamVersion 出現在 Content-Type 列之後而非之前 |
vtmviMissingBoundary | 缺少 Content-Type boundary 參數 |
vtmviNoInlinePdf | 沒有內嵌 PDF/VT 部分 |
vtmviInlinePdfNotPdfVT | 內嵌部分未宣告為 PDF/VT |
vtmviIccProfileBadDisposition | ICC 描述檔部分不是附件 |
vtmviAttachmentMissingFilename | 附件部分缺少必要的檔名 |
vtmviInlineHasFilename | 內嵌 PDF 部分帶有檔名,這不被允許 |
vtmviNodeNameListMismatch | 串流中的兩個 PDF/VT 檔案公開不同的 NodeNameList 值 |
vtmviRecordLevelMismatch | DPart 記錄層級在容器內不一致 |
vtmviForwardReference | 附件在出現於串流中之前就被參照 |
vtmviBoundaryInvalidChar | boundary 字串包含 RFC 2046 不允許的字元 |
vtmviDuplicateFilename | 兩個 MIME 附件公開相同且區分大小寫的檔名 |
vtmviOutputIntentAmbiguous | 某個 PDF 部分有零個或多個權威的 GTS_PDFX OutputIntent |
vtmviOutputProfilePackagingMismatch | OutputIntent 同時具有兩種描述檔形式、兩者皆無,或形式與 PDF/X-4、PDF/X-4p、PDF/X-5g 或 PDF/X-5pg 基礎不相容 |
vtmviOutputProfileReferenceInvalid | DestOutputProfileRef 遺漏必要的中繼資料或 URL 檔案規格,或使用被禁止的 ColorantTable |
vtmviReferencedPartWrongType | 被參照的檔名解析到不是 ICC 描述檔的 MIME 部分 |
vtmviIccProfileInvalid | ICC 檔頭、宣告大小、簽章、標籤表或支援的印刷色彩空間無效 |
vtmviIccChecksumMismatch | 解碼後的 16 位元組 CheckSum 與完整 ICC 檔案的 MD5 不同 |
vtmviIccVersionMismatch | 宣告的四個 ICCVersion 位元組與 ICC 檔頭第 8 到 11 位元組不同 |
vtmviIccColorSpaceMismatch | ProfileCS 與 ICC 檔頭第 16 到 19 位元組不同,或不是 GRAY、RGB 或 CMYK |
vtmviIccProfileNameMismatch | ProfileName 不符合任何有效的 profileDescriptionTag 地區設定值 |
vtmviPrintingConditionUnresolved | 無法解析權威的 OutputIntent、識別碼或外部 ICC 相依 |
vtmviPrintingConditionMismatch | PDF/VT 部分在 OutputConditionIdentifier、RegistryName 的有無或值,或印刷色彩空間上不一致 |
vtmviIccDeviceClassMismatch | 內嵌或外部目的地描述檔不是輸出裝置的 prtr 描述檔 |
BuildPdfVT2sStream 往返測試產生的任何串流,或在處理前對外部製作的 PDF/VT-2s 容器呼叫 ValidatePdfVT2sStreamTPdfVT2sValidationResult.IsCompliant 只有在 Issues 集合為空時才傳回 True
var Chunks: TPdfVT2sChunks;
begin
SetLength(Chunks, 2);
Chunks[0].Kind := vtckIccProfile;
Chunks[0].FileName := 'profile.icc';
Chunks[0].Bytes := IccBytes;
Chunks[1].Kind := vtckInlinePdf;
Chunks[1].Bytes := InlinePdfBytes;
BuildPdfVT2sStream(Chunks, MimeStream);
end;