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 реалізує транспорт PDF/VT-2s, визначений у додатку ISO 16612-2, де документ PDF/VT плюс його referenced повторно використовуваний PDF-вміст і профіль ICC пакуються як єдиний MIME multipart-потік
На відміну від шляху TPdf.SaveAsPdfVT, що записує окремий файл PDF/VT-1, цей модуль працює суто з потоками байтів і ніколи не завантажує pdfium.dll, тож може виконуватися в headless-серверах і пакетних конвеєрах
BuildPdfVT2sStream збирає фрагменти в порядку та випромінює заголовок StreamVersion, межі частин і заголовки Content-Type / Content-Disposition для кожної частини; ValidatePdfVT2sStream розбирає наявний потік назад і звітує структурні, printing-condition та ICC-відхилення як типізовану множину проблем
InspectPdfVT2sStream повертає той самий результат сумісності плюс свідчення для кожної частини PDF/VT, зокрема конформність PDF/VT, базу PDF/X, ідентичність OutputIntent, походження профілю, MD5 і SHA-256, сирі метадані ICC та кількості сторінок і записів отримувачів DPart
Кожна PDF-частина спершу класифікується через ValidatePdfVTCompliance; повторно використовувані вкладення лише з PDF/X залишаються придатними цілями посилань, але виключаються з ієрархії PDF/VT і порівнянь printing-condition
Упакування профілю слідує базі файлу: 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 role |
|---|---|
vtckInlinePdf | Документ PDF/VT, що переноситься як вбудована частина application/pdf; потрібна принаймні одна |
vtckAttachmentPdf | Частина повторно використовуваного PDF-вмісту, на яку посилається вбудований документ, що переноситься як attachment з ім'ям файлу |
vtckIccProfile | Частина профілю ICC (application/vnd.iccprofile), подана як attachment з ім'ям файлу |
| Type | Purpose |
|---|---|
TPdfVT2sChunks | Динамічний масив упорядкованих MIME-фрагментів, що подається до BuildPdfVT2sStream |
TAnsiStrings | Динамічний масив імен файлів, який використовується під час валідації посилань на зовнішні файли у вбудованому PDF |
TPdfVT2sValidationIssues | Множина знахідок TPdfVT2sValidationIssue, яку повертає валідація |
TPdfVTPrintingConditionSource | Походження свідчень профілю: vtpcsNone, коли не розв'язано, vtpcsEmbeddedProfile для вбудованого потоку DestOutputProfile, vtpcsMimeProfile для DestOutputProfileRef, розв'язаного з ICC MIME-частини |
TPdfVTPrintingConditionEvidence | Класифікація PDF/VT і PDF/X, OutputIntent, джерело профілю, ідентичність, дайджест, заголовок ICC і факти DPart для кожної частини |
TPdfVT2sValidationReport | Докладний результат, який повертає InspectPdfVT2sStream, не змінюючи застарілу композицію результату |
| Value | Reported when |
|---|---|
vtmviNotMultipart | Потік не є MIME-контейнером multipart |
vtmviMissingStreamVersion | Відсутній потрібний заголовок PDF/VT StreamVersion |
vtmviStreamVersionValue | Значення StreamVersion не є очікуваним 1 |
vtmviStreamVersionAfterCt | StreamVersion з'являється після рядка Content-Type замість перед ним |
vtmviMissingBoundary | Відсутній параметр boundary у Content-Type |
vtmviNoInlinePdf | Немає вбудованої частини PDF/VT |
vtmviInlinePdfNotPdfVT | Вбудована частина не оголошена як PDF/VT |
vtmviIccProfileBadDisposition | Частина профілю ICC не є attachment |
vtmviAttachmentMissingFilename | Частина-attachment не має потрібного імені файлу |
vtmviInlineHasFilename | Вбудована PDF-частина несе ім'я файлу, що не дозволено |
vtmviNodeNameListMismatch | Два файли PDF/VT у потоці відкривають різні значення NodeNameList |
vtmviRecordLevelMismatch | Рівні записів DPart неузгоджені по контейнеру |
vtmviForwardReference | На вкладення посилаються до того, як воно з'являється в потоці |
vtmviBoundaryInvalidChar | Рядок boundary містить символи, не дозволені RFC 2046 |
vtmviDuplicateFilename | Два MIME-вкладення відкривають те саме ім'я файлу з урахуванням регістру |
vtmviOutputIntentAmbiguous | PDF-частина має нуль або кілька авторитетних OutputIntents GTS_PDFX |
vtmviOutputProfilePackagingMismatch | OutputIntent має обидві форми профілю, жодної форми або форму, несумісну з базою PDF/X-4, PDF/X-4p, PDF/X-5g чи PDF/X-5pg |
vtmviOutputProfileReferenceInvalid | DestOutputProfileRef опускає потрібні метадані, файлову специфікацію URL або використовує заборонений ColorantTable |
vtmviReferencedPartWrongType | Referenced ім'я файлу розв'язується в MIME-частину, яка не є профілем ICC |
vtmviIccProfileInvalid | Заголовок ICC, оголошений розмір, підпис, таблиця тегів чи підтримуваний процесний колірний простір некоректні |
vtmviIccChecksumMismatch | Декодований 16-байтовий CheckSum відрізняється від MD5 повного файлу ICC |
vtmviIccVersionMismatch | Оголошені чотири байти ICCVersion відрізняються від байтів 8–11 заголовка ICC |
vtmviIccColorSpaceMismatch | ProfileCS відрізняється від байтів 16–19 заголовка ICC або не є GRAY, RGB чи CMYK |
vtmviIccProfileNameMismatch | ProfileName не збігається з жодним коректним локальним значенням profileDescriptionTag |
vtmviPrintingConditionUnresolved | Авторитетний OutputIntent, ідентифікатор чи зовнішня залежність ICC не можуть бути розв'язані |
vtmviPrintingConditionMismatch | Частини PDF/VT розходяться в OutputConditionIdentifier, наявності чи значенні RegistryName або процесному колірному просторі |
vtmviIccDeviceClassMismatch | Вбудований чи зовнішній профіль призначення не є профілем пристрою виводу prtr |
ValidatePdfVT2sStream на будь-якому потоці, створеному BuildPdfVT2sStream під час round-trip-тестування, або на зовнішніх контейнерах PDF/VT-2s перед обробкоюTPdfVT2sValidationResult.IsCompliant повертає True, лише коли множина Issues порожня
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;