Odborný článok

3D farebné LUT tabuľky v PDF so vzorkovanými funkciami typu 0

Funkcie PDF patria k menej známym častiam špecifikácie. Väčšina vývojárov sa s nimi stretne len raz, ako s prvkom, ktorý axiálne tieňovanie typu 2 (Type 2 axial shading) potrebuje na plynulý prechod medzi dvoma farbami, a už sa k nim nevráti. To je škoda, pretože mechanizmus funkcií je malý univerzálny vyhodnocovač, ktorý formát opakovane používa na tieňovanie, prenosové funkcie, rastrové bodové funkcie, odtiene separácie a prenosové krivky mäkkých masiek. Zo štyroch typov funkcií je typ 0 najvýkonnejší a najmenej pochopený. Ide o vzorkovanú funkciu: viacrozmernú mriežku výstupných hodnôt, medzi ktorými čítačka interpoluje. Keďže mriežka môže obsahovať akékoľvek čísla, ktoré do nej vložite, funkcia typu 0 dokáže vyjadriť ľubovoľné nelineárne mapovanie, čo je presný tvar vyhľadávacej tabuľky farieb (color lookup table)

Tento článok prechádza slovník typu 0 tak, ako ho definuje norma ISO 32000-1 v §7.10.2, a potom ukazuje dva prípady, na ktorých najviac záleží v spracovaní dokumentov: trojvstupovú farebnú korekčnú LUT tabuľku RGB-to-RGB a jednovstupovú transformáciu odtieňa priamej farby. Obe obsluhuje rovnaký nástroj na zostavenie vzorkovanej funkcie a rozdiel medzi nimi je čisto otázkou toho, koľko vstupov mriežka má

Vzorkovaná funkcia je mriežka, ktorú čítačka interpoluje

Funkcia typu 0 mapuje m-vstupový vektor na n-výstupový vektor ukladaním vzoriek na pravidelnej mriežke a interpoláciou medzi nimi. ISO 32000-1 §7.10.2 uvádza kľúče, ktoré popisujú túto mriežku. /Domain obsahuje dve čísla na vstup, spodnú a hornú hranicu každej vstupnej osi. /Range obsahuje dve čísla na výstupnú zložku. /Size je pole m celých čísel udávajúcich počet vzoriek pozdĺž každej vstupnej osi, takže mriežka, ktorá má dvanásť vzoriek na stranu v troch rozmeroch, má /Size [12 12 12] a ukladá 1 728 bodov mriežky. /BitsPerSample nastavuje presnosť každej uloženej hodnoty; HotPDF podporuje 1, 2, 4, 8, 12, 16, 24 a 32 bitov, čo zodpovedá hodnotám, ktoré povoľuje tabuľka 38

Tok vzoriek sa číta v pevnom poradí. Najrýchlejšie sa mení prvý vstupný rozmer, potom druhý atď., pričom v každom bode mriežky sú po sebe uložené n výstupné zložky. Pre tabuľku RGB-to-RGB sú to tri bajty na bod mriežky pri ôsmich bitoch, usporiadané ako výstup červenej, výstup zelenej, výstup modrej, pričom sa najprv prechádza červený vstup. Dva ďalšie kľúče mapujú spojitý svet na celočíselnú mriežku. /Encode mapuje každý vstup z jeho intervalu /Domain do rozsahu indexov vzoriek 0Size[i] - 1 a /Decode mapuje surové uložené celé čísla späť na intervaly /Range. Ak ich ponecháte na predvolených hodnotách, vstup v rozsahu [0 1] presne pokryje celú mriežku a uložený bajt s hodnotou 255 sa dekóduje na vrchol jeho výstupného rozsahu, čo je presne to, čo vyžaduje [0,1]-normalizovaná farebná LUT

HotPDF: Anatómia vzorkovanej funkcie PDF Type 0: Domain a Encode namapujú každý vstup na indexy mriežky, vzorky sa interpolujú, potom Decode a Range škálujú výstupy
Čítačka interpoluje pravidelnú mriežku vzoriek, ktorej tvar pochádza z Size, a premetáva prvý vstup najrýchlejšie. Encode a Decode viažu spojitý svet na uložené celé čísla

Rád 1 verzus Rád 3

Medzi bodmi mriežky musí čítačka interpolovať a /Order určuje ako. /Order 1 je multilineárna interpolácia: lineárna pozdĺž jednej osi, bilineárna naprieč dvoma, trilineárna naprieč troma. Je rýchla, je to presne to, čo robí hardvér vo väčšine prehliadačov, a pri hladkej transformácii farieb je zvyčajne nerozoznateľná od zložitejších metód. /Order 3 vyžaduje kubickú spline interpoláciu, ktorá prekladá hladšiu krivku cez vzorky za cenu väčšieho množstva práce a širšej oblasti podpory okolo každého vyhodnocovaného bodu

Kompromisom je hustota mriežky verzus hladkosť krivky. Kubický poriadok sa oplatí vtedy, keď je mriežka riedka a mapovanie má viditeľné zakrivenie, pretože priama čiara medzi dvoma vzdialenými vzorkami môže sploštiť tónovú krivku spôsobom, ktorý ojo zachytí na prechodoch. Akonáhle je mriežka hustá, segmenty sú dostatočne krátke na to, aby lineárna interpolácia tesne sledovala krivku, a kubická prináša len málo. Praktickým pravidlom je siahnuť po /Order 3 len pri malých mriežkach alebo strmých transformáciách a inak ponechať predvolenú lineárnu hodnotu. Upozorňujeme, že /Order sa vzťahuje len na funkcie typu 0 a HotPDF odmieta akúkoľvek inú hodnotu ako 1 alebo 3

3D LUT: tri vstupy, tri výstupy

Korekcia farieb RGB-to-RGB je učebnicovým príkladom pre trojvstupovú mriežku, klasickú 3D LUT používanú pri korekcii farieb a prispôsobení zariadení. Každá os kocky je jedným vstupným kanálom, každý bod mriežky ukladá opravenú trojicu RGB pre túto vstupnú súradnicu a čítačka trilineárne interpoluje rohové vzorky okolo akejkoľvek prichádzajúcej farby. Tri vstupy sú tu nevyhnutné, pretože korigovaná červená môže závisieť od vstupnej zelenej a modrej, nielen od vstupnej červenej; krivka pre jednotlivé kanály nedokáže vyjadriť presluchy medzi kanálmi, ale kocka áno

HotPDF vytvára tok typu 0 prostredníctvom RegisterSampledFunction, ktorá priamo prijíma /Domain, /Range, /Size, /BitsPerSample a bajty vzoriek a vracia objekt funkcie. Pre štandardnú normalizovanú kocku odovzdávate hranice [0,1] na všetkých troch vstupných osiach aj troch výstupoch, rozmer N x N x N a sploštenú tabuľku vzoriek. Nástroj na zostavenie overuje, či počet bajtov zodpovedá mriežke: pre hĺbku zarovnanú na bajty očakáva OutputCount x (BitsPerSample div 8) x súčin rozmerov a vyvolá chybu, ak má pole nesprávnu dĺžku, takže nesprávne vypočítaný krok zlyhá hlučne už pri registrácii, namiesto toho, aby sa neskôr zobrazil ako nečitateľný odpad

const
  N = 17;  // kocka 17 x 17 x 17, bežné rozlíšenie ICC LUT
var
  LutFn: THPDFStreamObject;
  Samples: TBytes;
begin
  // Naplňte Samples bodmi mriežky N*N*N, každý má 3 bajty (výstup R,G,B),
  // vstupná červená sa mení najrýchlejšie. Pre každý
  // súradnicu mriežky zostavte opravenú trojicu pomocou konverzie riadenej ICC a potom ju uložte
  SetLength(Samples, N * N * N * 3);
  BuildCorrectedCube(Samples, N);   // your color-managed fill

  LutFn := Pdf.RegisterSampledFunction(
    [0,1, 0,1, 0,1],   // /Domain: tri vstupné osi na [0,1]
    [0,1, 0,1, 0,1],   // /Range: tri výstupné kanály na [0,1]
    [N, N, N],         // /Size:   rozlíšenie kocky na os
    8,                 // /BitsPerSample
    Samples,
    1);                // /Order 1 = trilinear
end;

Kolorimetrická správnosť kocky spočíva v tom, ako ju naplníte, nie vo funkcii PDF. Správnou cestou je vypočítať každý bod mriežky prostredníctvom konverzie riadenej profilom ICC, rovnakým enginom, ktorý riadi soft-proof, aby čísla v mriežke znamenali niečo voči definovanému zdrojovému a cieľovému profilu. Zaregistrujte profily, ktoré ohraničujú konverziu, pomocou RegisterICCProfile, čo zaznamená farebný priestor ICCBased (1, 3 alebo 4 zložky) a vráti názov zdroja, ktorý môžete pripojiť k obsahu, ktorý LUT sýti. Funkcia typu 0 nesie interpolačnú tabuľku; ICC profil nesie význam koncových bodov

Prípad 1D: transformácia odtieňa priamej farby

Separačné farebné priestory sa opierajú o rovnaký mechanizmus pre úplne inú úlohu. Separačný priestor, definovaný v ISO 32000-1 §8.6.6.4, reprezentuje jedno farbivo, priamu farbu (spot ink) ako Pantone alebo lak, spojením názvu s transformáciou odtieňa (tint transform): funkciou, ktorá mapuje jednorozmernú hodnotu odtieňa, 0 pre žiadny atrament až po 1 pre plný atrament, na alternatívny farebný priestor, ktorý zariadenie dokáže skutočne vykresliť, zvyčajne CMYK. Táto transformácia odtieňa je často funkciou typu 0 a teraz má mriežka presne jednu vstupnú os

Toto je jasný kontrast s 3D LUT. Priama farba je jedným stupňom voľnosti, takže jej transformácia odtieňa potrebuje jeden vstup a mriežka je radom vzoriek, z ktorých každá obsahuje hodnotu CMYK (alebo inú alternatívu) na danej úrovni odtieňa. Kocka RGB potrebuje tri vstupy, pretože jej doména je trojrozmerná a kanály navzájom reagujú. Rovnaký typ funkcie, rovnaké interpolačné pravidlá, iná dimenzionalita; špecifikácia opakovane používa jeden vyhodnocovač a necháva /Size rozhodnúť, či prechádzate po čiare, rovine alebo kocke. HotPDF obaľuje celú separáciu do RegisterSeparationLUT, čo vnútorne vytvára jednovstupovú transformáciu odtieňa typu 0 z plochého poľa bajtov a vracia názov zdroja farebného priestoru

var
  SpotCS: AnsiString;
begin
  // Štyri výstupné bajty CMYK na každý bod mriežky odtieňa, doména odtieňa [0..1]
  // Tu 0% farby -> všetko nula, 100% farby -> bohatá priama zmes,
  // s dvoma vnútornými krokmi; transformácia odtieňa interpoluje medzi nimi
  SpotCS := Pdf.RegisterSeparationLUT(
    'PANTONE 286 C',         // colorant name
    'DeviceCMYK',            // alternatívny farebný priestor
    [  0,   0,   0,   0,     // tint 0.00 -> 0,0,0,0
      90,  60,   0,   0,     // tint 0.33
     100,  80,   0,  10,     // tint 0.66
     100,  72,   0,  18]);   // odtieň 1.00 -> úplná zmes farby
  // Na strane použite SpotCS s SetFillColorSpace / SetFillColor
end;

Počet vzoriek musí byť celým počtom bodov mriežky: kladným násobkom počtu zložiek alternatívneho priestoru a aspoň dvoma bodmi, aby existoval segment na interpoláciu. Odovzdajte tri bajty na bod voči alternatíve CMYK a volanie to odmietne, čo je rovnaké defenzívne overenie, aké používa zostavovač 3D, čo je presne to, čo chcete od funkcie, ktorá by inak pri tlači potichu zlyhala

HotPDF: Farebná korekcia RGB-do-RGB nakreslená ako kocka 3D LUT: každá os je jeden vstupný kanál a osem okolitých vrcholov kŕmi trilineárne miešanie pre prichádzajúcu farbu
Každý roh ukladá opravenú trojicu vypočítanú pod ICC riadenou konverziou. Trilineárne miešanie reprodukuje krížový prenik kanálov, ktorý krivky na kanál nedokážu vyjadriť

Kde sa rovnaký mechanizmus objavuje znova

Akonáhle uvidíte typ 0 ako generickú interpolačnú tabuľku, ďalšie dve funkcie riadenia zariadenia prestanú vyzerať ako špeciálne prípady. Prenosová funkcia upravuje hodnoty zložiek na ich ceste k výstupnému zariadeniu, a ide len o funkciu pre každý kanál; HotPDF ju registruje ako ExtGState prostredníctvom RegisterTransferFunctionState, čo preberá buď jednu kombinovanú funkciu, alebo pole funkcií pre jednotlivé kanály. Keďže tieto funkcie sú bežnými objektmi funkcií, môžete im odovzdať presne ten THPDFStreamObject, ktorý vracia RegisterSampledFunction, a riadiť prenosovú krivku zo vzorkovanej tabuľky, a nie zo vzorca

var
  ToneFn: THPDFStreamObject;
  GsName: AnsiString;
begin
  // Jednovstupová, jednovýstupová vzorkovaná tónová krivka na [0,1]
  ToneFn := Pdf.RegisterSampledFunction(
    [0,1], [0,1], [256], 8, ToneCurveBytes, 1);

  // Aplikujte ju na všetky kanály ako kombinovanú prenosovú funkciu /TR2
  GsName := Pdf.RegisterTransferFunctionState(ToneFn, []);
  // Pred vykreslením ovplyvneného obsahu vyberte na strane GsName
end;

Tvorba čiernej (black generation) a odstránenie podkladovej farby (undercolor removal) patria do rovnakej rodiny. Keď zariadenie prevádza RGB na CMYK, rozhoduje o tom, koľko sivej zložky prenesie ako čierny atrament, a špecifikácia vyjadruje toto rozhodnutie ako funkciu, položky /BG2 a /UCR2 slovníka grafického stavu (graphics-state), pričom každá je jednovstupovou krivkou od vypočítanej sivej k množstvu čiernej. Sú to tiež funkcie typu 0, ak chcete meranú krivku namiesto analytickej, vytvorené rovnakým spôsobom pomocou RegisterSampledFunction a umiestnené v grafickom stave. Ponaučenie, ktoré stojí za to si zapamätať, je, že funkcia PDF nie je nikdy miestom, kde dochádza k správe farieb; je to vyhľadávacia tabuľka, ktorá nesie rozhodnutie, ktoré ste urobili so skutočným farebným enginom, a typ 0 je jediný typ funkcie dostatočne flexibilný na to, aby niesol akékoľvek rozhodnutie

Pre širší obraz o tom, ako sa písma, obrázky a farebné zdroje emitujú do hotového dokumentu, si pozrite nášho sprievodcu výstupom reportov s písmami a obrázkami. Keď musí výstup prežiť kontrolu predletovej prípravy (preflight) pre archív alebo tlač, pravidlá pre farebný priestor a výstupný zámer popísané v príručke na overenie PDF/A, PDF/X a PDF/UA riadia, ktoré z týchto funkcií sú povolené a ako sa musí označiť farba zariadenia. To všetko sa dodáva v komponente HotPDF Delphi Component pre Delphi a C++Builder spolu so shading, ICC a separačnými API, ktoré stavajú na rovnakom jadre typu 0

HotPDF: Transformácia tónu Type 0 s jedným vstupom pre bodové farbivo: línia vzoriek tónu, každá držiaca hodnotu DeviceCMYK pre alternatívny priestor
Spot farba má jeden stupeň voľnosti, takže jej mriežka sa zrúti na líniu vzoriek. Ten istý evaluator prechádza túto líniu, rovinu alebo RGB kocku