veraPDF flaguje ISO 19005-1 6.2.3.3 na pliku, który nigdy nie rysuje RGB, nazywa gołe re f nieskalibrowanym albo zawala stronę 2, gdy identyczna strona 1 przechodzi. PDF/A rozsądza te reguły po tym, co każda strona maluje, więc walidator PDF/A w PDFium Component dla Delphi śledzi każdą stronę w głąb, do Form XObjectów, patternów, glifów i adnotacji, zanim orzeka o kolorze i przezroczystości
Czego 6.2.3.3 i 6.2.4.3 faktycznie wymagają
ISO 19005-1 6.2.3.3 pakuje trzy niezależne reguły w jeden akapit. Zgodny plik może użyć DeviceRGB albo DeviceCMYK, ale nie może użyć obu; jeśli użyto jakakolwiek nieskalibrowana przestrzeń kolorów, plik ma zawierać PDF/A-1 OutputIntent; a DeviceRGB jest dozwolony tylko z intencją, której profil to RGB, DeviceCMYK tylko z CMYK-ową. DeviceGray wypadł z tej listy, bo punkt ciągnie dalej objaśnienie konwersji szarości pod każdą z intencji. Sama intencja jest opcjonalna: 6.2.2 mówi, że plik może ją podać, i liczy tylko wpis OutputIntents z /S /GTS_PDFA1 i poprawnym strumieniem profilu ICC w /DestOutputProfile. Kontroler żądający intencji od każdego pliku odrzuca więc zgodne dokumenty, które nigdy nie malują kolorem urządzenia. Część 1 nie wspomina DefaultRGB ani DefaultCMYK, a jednak kolor przemapowany przez nie jest renderowany w przestrzeni opartej na CIE (ISO 32000-1 §8.6.5.6), co zaspokaja wymóg niezależności od urządzenia z 6.2.3.1; zestaw testowy veraPDF dla 6.2.3.3 traktuje to jako skalibrowane i PDFium Component czyta ten punkt tak samo. Zakaz mieszania stoi osobno: plik PDF/A-1, który maluje i RGB, i CMYK, zawodzi nawet, gdy wpisy Default kalibrują oba. ISO 19005-2 6.2.4.3 zrzuca ten zakaz i kalibruje każdą przestrzeń na własnych warunkach, jak pokazuje prawa kolumna niżej, więc PDFium Component robi jedno skanowanie na każdą część i stosuje kontrolę mieszania wyłącznie do deklaracji PDF/A-1
| Namalowana przestrzeń urządzenia | PDF/A-1 (ISO 19005-1 6.2.3.3) | PDF/A-2 i późniejsze (ISO 19005-2 6.2.4.3) |
|---|---|---|
| DeviceRGB | DefaultRGB w zasobach albo intencja RGB; nie razem z DeviceCMYK | DefaultRGB w zasobach, albo RGB OutputIntent |
| DeviceCMYK | DefaultCMYK w zasobach albo intencja CMYK; nie razem z DeviceRGB | DefaultCMYK w zasobach, albo CMYK OutputIntent |
| DeviceGray | DefaultGray w zasobach, albo jakikolwiek PDF/A-1 OutputIntent | DefaultGray w zasobach, albo jakikolwiek PDF/A OutputIntent |
Co liczy się jako użycie przestrzeni kolorów?
Użycie przestrzeni kolorów znaczy malowanie nią po ścieżce, którą czytnik wyrenderuje. Samo zadeklarowanie nie wystarcza. Zestaw veraPDF robi ten punkt plikiem pass dla 6.2.3.3: nazwany Form XObject ustawia CMYK przez K i k, siedzi w słowniku zasobów strony, nigdy nie jest referencjonowany z treści strony, a OutputIntent pliku to RGB. Poszukiwanie nazw kolorów urządzenia po całym pliku zawali ten plik, a przegapi inny, malujący tylko DeviceRGB pod intencją CMYK, gdzie żadne dwie nazwy nie kolidują. PDFium Component zamiast tego przechodzi graf rysowania, zbudowany na swoim skanerze preflight PDF/A poziomu bajtów. Od każdej strony przejście liczy kolor namalowany przez:
- strumienie treści strony i każdy Form XObject, który wywołują przez
Do, zagnieżdżone formy wliczone - pattern wybrany przez
scnalboSCN, czytany z własnymiResourcespatternu CharProcsfontu Type 3 wybranego przezTf- image XObjecty i obrazy inline, po przestrzeni kolorów, którą nazywa ich własny słownik
- strumienie wyglądu adnotacji, malowane na wierzchu strony; gdy
/AP /Nwidgeta jest słownikiem stanów, liczy się każdy stan, bo przełączenie pola maluje ten, którego/ASnie wybrało
Subtelniejsza połowa osiągalności to kolor, którego treść nigdy nie nazwie. q 0 0 10 10 re f Q nie zawiera operatora koloru. Wciąż maluje. Początkowa przestrzeń kolorów stanu grafiki to DeviceGray (ISO 32000-1 tabela 52), więc wypełnienie to czarny DeviceGray, nieskalibrowany pod każdą część, chyba że istnieje PDF/A OutputIntent albo DefaultGray. Skan śledzi więc, czy cokolwiek wybrało już kolor: rg, k, g i ich odpowiedniki obrysu wybierają przestrzeń urządzenia, cs i CS wybierają to, co nazwą, a operator wypełnienia, obrysu albo tekstu dosięgnięty przed jakimkolwiek wyborem zapisuje DeviceGray. /CS0 cs 1 0 0 /P0 scn już wybrał przestrzeń, więc ten scn nie jest szary
Obrazy inline wnoszą swoją przestrzeń kolorów i surowe próbki prosto do strumienia treści, i skaner musi czytać jedno i drugie uważnie. /CS może być skrótem (G, RGB, CMYK, I) albo nazwą zasobu, taką jak rozwiązującą się do [/Indexed /DeviceRGB 255 13 0 R], której baza się liczy; a bajty między ID i EI są dowolnym binarium, więc EI kończy obraz tylko między białymi znakami, inaczej rg wewnątrz skompresowanych próbek zamienia się w operatora-widmo
% strona 1: DefaultRGB w zasobach i XObject, którego nic nie wywołuje
4 0 obj << /Type /Page /Parent 2 0 R /Contents 5 0 R
/Resources << /ColorSpace << /DefaultRGB 9 0 R >>
/XObject << /Fm0 6 0 R >> >> >>
endobj
% strona 2: ten sam strumień treści, bez podsłownika ColorSpace
7 0 obj << /Type /Page /Parent 2 0 R /Contents 5 0 R /Resources << >> >>
endobj
5 0 obj << /Length 46 >> stream
1 0 0 rg 72 72 200 100 re f
q 0 0 10 10 re f Q
endstream
endobj
6 0 obj << /Type /XObject /Subtype /Form /BBox [0 0 50 50] /Length 24 >> stream
0 0 0 1 k 0 0 50 50 re f
endstream
endobj
9 0 obj [/ICCBased 10 0 R]
endobj
Każdy objaw z otwarcia wypada z tego fragmentu. /Fm0 nigdy nie spotyka Do, więc jego k jest bez znaczenia. Gołe re f na obu stronach to DeviceGray bez niczego do skalibrowania. rg na stronie 1 jest przykryty DefaultRGB w zasobach, z którymi strona 1 maluje; strona 2 puszcza identyczny strumień przeciw zasobom bez tej mapy, więc te same bajty są tam nieskalibrowane. Oczekiwane dla deklaracji PDF/A-1b: pvaiMissingOutputIntent z pvaiMissingIccProfile, pchane przez RGB strony 2 i szarość obu stron. Forma nie wnosi nic; wywołana, jej CMYK dołożyłby zakaz mieszania PDF/A-1 na wierzch
Domyślne przestrzenie kolorów należą do słownika zasobów, który maluje
Mapy Default są szukane w podsłowniku ColorSpace bieżącego słownika zasobów (ISO 32000-1 §8.6.5.6), co czyni je dokładnie tak lokalnymi, jak same zasoby; dokument nie ma globalnego domyślnego. Image XObject nie ma własnych Resources, więc obraz, którego słownik mówi /ColorSpace /DeviceCMYK, jest skalibrowany DefaultCMYK strony albo formy, która go rysuje, i ten sam obraz rysowany z dwóch miejsc może być skalibrowany w jednym, a w drugim nie. Form XObjecty, patterny tilingowe i procedury glifów Type 3 niosą własne Resources, więc DefaultCMYK strony nie sięga do ich wnętrza, a mapa we własnym słowniku tak. PDFium Component zakresuje mapy tak samo. Werdykt wraca jako rekord TPdfAValidationResult: wykryte Conformance plus zbiór Issues. To dość, żeby przetrageować folder
uses
System.SysUtils, System.Classes, System.TypInfo, FPdfPdfa;
procedure ReportColorFindings(const FileName: string; Log: TStrings);
const
ColorRules: TPdfAValidationIssues = [pvaiMissingOutputIntent,
pvaiMissingIccProfile, pvaiMixedDeviceColorSpaces, pvaiBlendSpaceUndefined];
var
Source: TFileStream;
Res: TPdfAValidationResult;
Found: TPdfAValidationIssues;
Issue: TPdfAValidationIssue;
begin
Source := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
Res := ValidatePdfACompliance(Source); // czyta od pozycji 0
finally
Source.Free;
end;
Log.Add(ExtractFileName(FileName) + ': ' +
GetEnumName(TypeInfo(TPdfAConformance), Ord(Res.Conformance)));
Found := Res.Issues * ColorRules;
for Issue in Found do
case Issue of
pvaiMissingOutputIntent:
Log.Add(' reachable uncalibrated device color, no PDF/A OutputIntent');
pvaiMissingIccProfile:
Log.Add(' no OutputIntent with a DestOutputProfile ICC stream');
pvaiMixedDeviceColorSpaces:
Log.Add(' RGB/CMYK use disagrees with the intent, or PDF/A-1 paints both');
pvaiBlendSpaceUndefined:
Log.Add(' transparent page without a blending color space');
end;
if Found = [] then
Log.Add(' device color and blending rules satisfied');
end;
pvaiMissingOutputIntent i pvaiMissingIccProfile pojawiają się razem, gdy przejście dosięga nieskalibrowanego koloru urządzenia, a żaden PDF/A OutputIntent nie istnieje. pvaiMissingIccProfile sam w sobie znaczy, że intencja istnieje, ale nie niesie profilu, czego 6.2.2 nie przyjmuje jako intencji PDF/A. pvaiMixedDeviceColorSpaces przykrywa i zakaz mieszania PDF/A-1, i niezgodność składowych: nieskalibrowany DeviceRGB pod intencją czteroskładnikową albo DeviceCMYK pod trójskładnikową. Zbiór nazywa regułę, nie stronę, więc w długim albo sklejanym dokumencie porównaj, które strony deklarują wpisy Default, a które nie
Kiedy przezroczysta strona potrzebuje własnej przestrzeni blendingu?
Przezroczysta strona potrzebuje własnej przestrzeni blendingu tylko wtedy, gdy dokument nie ma PDF/A OutputIntent. ISO 19005-2 6.2.10 (6.2.9 w PDF/A-4) czyni intencję domyślną przestrzenią blendingu w sensie ISO 32000-1 §11.3.4; bez intencji każda strona zawierająca przezroczystość ma nieść Group, którego słownik atrybutów (ISO 32000-1 tabela 147) zawiera CS. Tamto CS też podlega 6.2.4, więc grupa strony /DeviceCMYK pod intencją sRGB jest raportowana jak brakująca, a PDFium Component podnosi pvaiBlendSpaceUndefined dla obu; CalRGB albo grupowa przestrzeń ICCBased nie ma takiej zależności. PDF/A-1 nie dochodzi do tego pytania, bo ISO 19005-1 6.4 wyklucza przezroczystość całkowicie
Trudna jest fraza zawiera przezroczystość. Załącznik A ISO 19005-2 jest normatywny i testuje od strony na zewnątrz; plikowe liczenie kluczy /SMask albo wartości /ca odpowiada na inne pytanie. Szukanie bajtów koliduje też ze składnią przezroczystości gdzie indziej: /S /Trans, zakazana akcja przejścia, jest prefiksem każdej grupy /S /Transparency, a /Screen to jednocześnie zakazany podtyp adnotacji i standardowy tryb blendingu, więc nazwa nie znaczy nic, dopóki nie jest sparowana ze swoim kluczem. Za załącznikiem A PDFium Component uznaje stronę za przezroczystą, gdy z niej da się dosięgnąć czegokolwiek z tej listy:
- ExtGState wybrany przez treść przez
gs, który ma słownik maski miękkiej,caalboCAponiżej 1, albo tryb blendingu inny niżNormal; zadeklarowany, ale nigdy niewybrany, się nie liczy - Form XObject wywołany przez
Do, którego/Groupma/S /Transparency, albo którego własna treść spełnia jeden z tych warunków; pattern tilingowy jest sądzony jak forma - image XObject ze strumieniem
SMaskalbo wartościąSMaskInDatapowyżej 0 - opis glifu fontu Type 3, którym strona pokazuje tekst, sądzony jak forma
- strumień wyglądu adnotacji, ze każdym stanem widgeta wliczonym, i tryb blendingu na samym słowniku adnotacji
Grupy też cofają się do reguły koloru urządzenia, i tu korpus nas skorygował. Zestaw veraPDF dla 6.2.4.3 trzyma pliki PDF/A-4 bez żadnego OutputIntent, które malują RGB urządzenia i mają przechodzić, bo /Group każdej strony nazywa skalibrowane CS. Założyliśmy, że kalibrować mogą tylko grupy izolowane, bo grupa nieizolowana kompozytuje się w swoje tło, i to było złe dla grup stron: tabela 147 notuje, że strona nałożona bezpośrednio na medium wyjściowe jest faktycznie izolowana niezależnie od I, więc jej CS jest honorowany. Na Form XObject albo wyglądzie adnotacji flaga faktycznie rozstrzyga; zestaw ma plik pass i plik fail różniące się tylko /I true. DeviceGray nie bierze kalibracji z grupy, bo 6.2.4.3 żąda DefaultGray albo intencji, a grupa, której CS to przestrzeń urządzenia, sama potrzebuje kalibracji. PDFium Component pozwala więc grupie strony kalibrować niezależnie od tego, co mówi jej /I, pozwala grupie formy albo wyglądu kalibrować tylko gdy izolowana, trzyma szarość poza kalibracją grupową i wciąż sprawdza przestrzeń urządzenia, którą grupa nazywa
Jeden OutputIntent zamiast grupy na każdej stronie
Jeśli własny kod pisze archiwum, zacznij od dokumentowego PDF/A OutputIntent. Jeden wpis katalogu kalibruje DeviceGray wszędzie, przykrywa pasującą przestrzeń urządzenia na każdej stronie i jest domyślną przestrzenią blendingu dla każdej przezroczystej strony. Grupy stron i wpisy Default są zakresowane każde do jednego słownika zasobów, a strona, którą późniejszy merge doda bez nich, to ta, która zawiedzie. PDF 2.0 dodaje OutputIntents do obiektu strony (ISO 32000-2 §7.7.3.3 i §14.11.5); PDFium Component przyjmuje intencję poziomu strony dla PDF/A-4, gdy katalog nie ma żadnej, podczas gdy części 1–3, zbudowane na PDF 1.4–1.7, patrzą tylko w katalog. Dla treści RGB SaveAsPdfAToStream dodaje intencję katalogu zbudowaną na osadzonym profilu ICC sRGB pisarza PDF/A, a walidacja wyjścia pokazuje, czy treść naprawdę była tylko RGB
uses
System.SysUtils, System.Classes, PDFium, FPdfPdfa;
function ArchiveWithSrgbIntent(const InFile, OutFile: string;
out Remaining: TPdfAValidationIssues): Boolean;
var
Pdf: TPdf;
Opts: TPdfASaveOptions;
Output: TMemoryStream;
Check: TPdfAValidationResult;
begin
Result := False;
Remaining := [];
Pdf := TPdf.Create(nil);
Output := TMemoryStream.Create;
try
Pdf.FileName := InFile;
Pdf.Active := True;
if not Pdf.Active then
Exit; // pliku nie dało się otworzyć
Opts := TPdfASaveOptions.Default;
Opts.Conformance := pac2b; // PDF/A-1 zakazałby przezroczystości wprost
// IccProfileData zostaje puste: użyty jest wbudowany profil sRGB IEC61966-2.1
if not Pdf.SaveAsPdfAToStream(Output, Opts) then
Exit;
Check := ValidatePdfACompliance(Output);
Remaining := Check.Issues;
// Oczekiwane dla treści tylko RGB: pvaiMissingOutputIntent i
// pvaiBlendSpaceUndefined znikają. pvaiMixedDeviceColorSpaces znaczy teraz,
// że osiągalna ścieżka maluje DeviceCMYK, którego nie kalibruje DefaultCMYK.
if Check.IsCompliant then
begin
Output.SaveToFile(OutFile);
Result := True;
end;
finally
Output.Free;
Pdf.Free;
end;
end;
pvaiMixedDeviceColorSpaces, które przeżywa intencję sRGB, to przejście raportujące DeviceCMYK na osiągalnej ścieżce, i ten dokument potrzebuje mapy DefaultCMYK na stronach, które go malują, albo profilu wyjścia CMYK, zanim PDFium Component przyjmie go jako PDF/A-2b