Technical Article

3D barvni LUT v PDF z vzorčenimi funkcijami vrste 0

Funkcije PDF so eden bolj tihih kotov specifikacije. Večina razvijalcev se z njimi sreča le enkrat, kot s stvarjo, ki jo aksialno senčenje vrste 2 (Type 2 axial shading) potrebuje za prelivanje med dvema barvama, in nikoli več ne pogleda nazaj. To je škoda, saj je mehanizem funkcij majhen splošnonamenski ocenjevalnik, ki ga format ponovno uporabi za senčenja, prenosne funkcije, rastrske točkovne funkcije, tone ločevanja in prenosne krivulje mehkih mask. Od štirih vrst funkcij je vrsta 0 (Type 0) najmočnejša in najmanj razumljena. Gre za vzorčeno funkcijo: večdimenzionalno mrežo izhodnih vrednosti, med katerimi bralnik interpolira. Ker lahko mreža vsebuje poljubne številke, ki jih vnesete vanjo, lahko funkcija vrste 0 izrazi poljubno nelinearno preslikavo, kar je natančna oblika barvne iskalne tabele (lookup table).

Ta članek obravnava slovar vrste 0, kot ga definira standard ISO 32000-1 v §7.10.2, nato pa prikazuje dva primera, ki sta najbolj pomembna v dokumentnem cevovodu: LUT za barvno korekcijo RGB-v-RGB s tremi vhodi in transformacijo tona točkovne barve z enim vhodom. Isti gradnik vzorčenih funkcij služi obema, razlika med njima pa je v celoti vprašanje števila vhodov, ki jih ima mreža.

Vzorčena funkcija je mreža, ki jo bralnik interpolira

Funkcija vrste 0 preslika vektor z m vhodi v vektor z n izhodi tako, da shrani vzorce na pravilni mreži in interpolira med njimi. ISO 32000-1 §7.10.2 navaja ključe, ki opisujejo to mrežo. /Domain vsebuje dve številki na vhod, spodnjo in zgornjo mejo vsake vhodne osi. /Range vsebuje dve številki na izhodno komponento. /Size je matrika m celih števil, ki podaja število vzorcev vzdolž vsake vhodne osi, tako da ima mreža z dvanajstimi vzorci na stranico v treh dimenzijah velikost /Size [12 12 12] in hrani 1.728 mrežnih točk. /BitsPerSample določa natančnost vsake shranjene vrednosti; HotPDF sprejema 1, 2, 4, 8, 12, 16, 24 in 32 bitov, kar ustreza vrednostim, ki jih dovoljuje tabela 38.

Tok vzorcev se bere v določenem vrstnem redu. Prva vhodna dimenzija se spreminja najhitreje, nato druga in tako naprej, na vsaki mrežni točki pa so n izhodne komponente shranjene po vrstnem redu. Za tabelo RGB-v-RGB so to trije bajti na mrežno točko pri osmih bitih, razporejeni kot rdeči izhod, zeleni izhod, modri izhod, pri čemer se najprej sprehodi čez rdeči vhod. Še dva ključa preslikata zvezni svet na celoštevilsko mrežo. /Encode preslika vsak vhod iz njegovega intervala /Domain v območje indeksa vzorcev od 0 do Size[i] - 1, /Decode pa preslika surova shranjena cela števila nazaj na intervale /Range. Če jih pustite na privzetih vrednostih, se vhod, ki obsega [0 1], natančno prilega celotni mreži, shranjen bajt z vrednostjo 255 pa se dekodira na vrh svojega izhodnega območja, kar je natanko tisto, kar želi [0,1]-normaliziran barvni LUT.

Vrstni red 1 proti vrstnemu redu 3

Med mrežnimi točkami mora bralnik interpolirati, pri čemer /Order določi način. /Order 1 predstavlja večlinearno interpolacijo: linearno vzdolž ene osi, bilinearno čez dve, trilinearno čez tri. Je hitra, je natanko tisto, kar počne strojna oprema v večini pregledovalnikov, in pri gladki transformaciji barv je običajno nerazločljiva od česa bolj zapletenega. /Order 3 zahteva kubično interpolacijo s splajni, ki skozi vzorce prilagodi gladkejšo krivuljo na račun večjega obsega dela in širšega podpornega območja okoli vsake ocenjene točke.

Kompromis je med gostoto mreže in gladkostjo krivulje. Rešitev s kubičnim redom se obnese, ko je mreža redka in ima preslikava vidno ukrivljenost, saj lahko ravna črta med dvema oddaljenima vzorcema splošči ton krivulje na način, ki ga oko opazi na prelivih. Ko je mreža gosta, so odseki dovolj kratki, da linearna interpolacija tesno sledi krivulji, kubična pa prinese malo koristi. Praktično pravilo je, da posežete po /Order 3 le pri majhnih mrežah ali strmih transformacijah, sicer pa jo pustite na linearni privzeti vrednosti. Upoštevajte, da velja /Order le za funkcije vrste 0, HotPDF pa zavrne vsako vrednost, ki ni 1 ali 3.

Dve plasti na stran, ne eno

Barvna korekcija RGB-v-RGB je šolski primer za mrežo s tremi vhodi, klasičen 3D LUT, ki se uporablja pri barvnem ocenjevanju in usklajevanju naprav. Vsaka os kocke predstavlja en vhodni kanal, vsaka mrežna točka hrani popravljeno trojico RGB za to vhodno koordinato, bralnik pa trilinearno interpolira vogalne vzorce okoli katere koli dohodne barve. Trije vhodi so tu neizogibni, saj je lahko popravljena rdeča odvisna od vhodne zelene in modre, ne le od vhodne rdeče; krivulja za posamezen kanal ne more izraziti presluha med kanali (crosstalk), kocka pa jo lahko.

HotPDF zgradi tok vrste 0 prek RegisterSampledFunction, ki neposredno sprejme parametre /Domain, /Range, /Size, /BitsPerSample ter bajte vzorcev in vrne objekt funkcije. Za standardno normalizirano kocko posredujete meje [0,1] na vseh treh vhodnih oseh in vseh treh izhodih, velikost N x N x N ter sploščeno tabelo vzorcev. Gradnik preveri, ali se število bajtov ujema z mrežo: za bajtno poravnano globino pričakuje OutputCount x (BitsPerSample div 8) x produkt velikosti in sproži izjemo, če je dolžina matrike napačna, tako da napačno izračunan korak odpove že ob registraciji in ne kasneje v obliki popačenega izrisa.

const
  N = 17;  // 17 x 17 x 17 cube, the common ICC LUT resolution
var
  LutFn: THPDFStreamObject;
  Samples: TBytes;
begin
  // Fill Samples with N*N*N grid points, 3 bytes each (R,G,B output),
  // red input varying fastest. Build the corrected triple for each
  // grid coordinate with your ICC-managed conversion, then store it.
  SetLength(Samples, N * N * N * 3);
  BuildCorrectedCube(Samples, N);   // your color-managed fill

  LutFn := Pdf.RegisterSampledFunction(
    [0,1, 0,1, 0,1],   // /Domain: three input axes on [0,1]
    [0,1, 0,1, 0,1],   // /Range:  three output channels on [0,1]
    [N, N, N],         // /Size:   the cube resolution per axis
    8,                 // /BitsPerSample
    Samples,
    1);                // /Order 1 = trilinear
end;

Kolorimetrična pravilnost kocke se skriva v tem, kako jo napolnite, in ne v funkciji PDF. Edina pravilna pot je izračun vsake mrežne točke prek pretvorbe pod upravljanjem ICC, torej z istim pogonom, ki poganja mehki predogled (soft-proof), tako da številke v mreži pomenijo nekaj glede na določen izvorni in ciljni profil. Registrirajte profile, ki omejujejo pretvorbo, z metodo RegisterICCProfile, ki zabeleži barvni prostor na osnovi ICC (1, 3 ali 4 komponente) in vrne ime vira, ki ga lahko pripnete vsebini, ki jo LUT napaja. Funkcija vrste 0 nosi interpolacijsko tabelo; profil ICC pa nosi pomen končnih točk.

Primer 1D: transformacija tona točkovne barve

Ločeni barvni prostori (Separation color spaces) se opirajo na isto mehanizacijo za povsem drugo delo. Prostor ločevanja (Separation space), opredeljen v ISO 32000-1 §8.6.6.4, predstavlja eno barvilo, točkovno črnilo, kot je Pantone ali lak, tako da poveže ime s transformacijo tona: funkcijo, ki preslika enodimenzionalno vrednost tona (0 za brez črnila do 1 za polno črnilo) v alternativni barvni prostor, ki ga naprava dejansko lahko izriše, običajno CMYK. Ta transformacija tona je pogosto funkcija vrste 0 (Type 0), zdaj pa ima mreža natanko eno vhodno os.

To je jasna razlika v primerjavi z RGB kocko. Točkovno črnilo predstavlja eno prostostno stopnjo, zato njegova transformacija tona potrebuje en vhod, mreža pa je linija vzorcev, pri čemer vsak vsebuje vrednost CMYK (ali drugo alternativo) na tej ravni tona. RGB kocka potrebuje tri vhode, ker je njena domena tridimenzionalna in kanali medsebojno delujejo. Enaka vrsta funkcije, enaka pravila interpolacije, drugačna dimenzionalnost; specifikacija ponovno uporabi en ocenjevalnik in prepusti parametru /Size odločitev o tem, ali hodite po črti, ravnini ali kocki. HotPDF ovije celotno ločevanje v RegisterSeparationLUT, ki interno zgradi transformacijo tona vrste 0 z enim vhodom iz ploske matrike bajtov in vrne ime vira barvnega prostora.

var
  SpotCS: AnsiString;
begin
  // Four CMYK output bytes per tint grid point, tint domain [0..1].
  // Here 0% ink -> all zero, 100% ink -> a rich spot build,
  // with two interior steps; the tint transform interpolates between.
  SpotCS := Pdf.RegisterSeparationLUT(
    'PANTONE 286 C',         // colorant name
    'DeviceCMYK',            // alternate color space
    [  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]);   // tint 1.00 -> full ink build
  // Use SpotCS with SetFillColorSpace / SetFillColor on a page.
end;

Število vzorcev mora biti celo število mrežnih točk: pozitivni večkratnik števila komponent alternativnega prostora in vsaj dve točki, da obstaja odsek za interpolacijo. Če posredujete tri bajte na točko proti alternativi CMYK, klic to zavrne – to je enako obrambno preverjanje, kot ga izvaja 3D gradnik, kar je natanko tisto, kar želite od funkcije, ki bi sicer ob tiskanju tiho odpovedala.

Kje se isti mehanizem ponovno pojavi

Ko enkrat razumete vrsto 0 kot splošno interpolacijsko tabelo, dve dodatni funkciji za nadzor naprav prenehata izgledati kot posebna primera. Prenosna funkcija (transfer function) prilagaja vrednosti komponent na njihovi poti do izhodne naprave in je preprosto le funkcija na kanal; HotPDF jo registrira kot ExtGState prek RegisterTransferFunctionState, ki sprejme bodisi eno kombinirano funkcijo bodisi matriko funkcij za posamezne kanale. Ker so te funkcije običajni objekti funkcij, jim lahko posredujete natanko tisti THPDFStreamObject, ki ga vrne RegisterSampledFunction, in krmilite prenosno krivuljo iz vzorčene tabele namesto iz formule.

var
  ToneFn: THPDFStreamObject;
  GsName: AnsiString;
begin
  // A single-input, single-output sampled tone curve on [0,1].
  ToneFn := Pdf.RegisterSampledFunction(
    [0,1], [0,1], [256], 8, ToneCurveBytes, 1);

  // Apply it to all channels as a combined /TR2 transfer function.
  GsName := Pdf.RegisterTransferFunctionState(ToneFn, []);
  // Select GsName on the page before drawing the affected content.
end;

Generiranje črne barve (black generation) in odstranjevanje podbarve (undercolor removal) spadata v isto družino. Ko naprava pretvori RGB v CMYK, se odloči, kolikšen del sive komponente bo prenesla kot črno črnilo, specifikacija pa to odločitev izraža kot funkcijo, vnosa /BG2 in /UCR2 v slovarju grafičnega stanja (graphics-state dictionary), pri čemer je vsak krivulja z enim vhodom od izračunane sive do količine črne. To so prav tako funkcije vrste 0, kadar želite izmerjeno krivuljo namesto analitične, zgrajene na enak način prek RegisterSampledFunction in umeščene v grafično stanje. Lekcija, ki si jo velja zapomniti, je, da se funkcija PDF nikoli ne uporablja za upravljanje barv; je le iskalna tabela, ki nosi odločitev, ki ste jo sprejeli z resničnim barvnim pogonom, vrsta 0 pa je edina vrsta funkcije, ki je dovolj prilagodljiva, da lahko nosi katero koli odločitev.

Za širšo sliko o tem, kako se pisave, slike in barvni viri oddajajo v končni dokument, si oglejte naš vodič po izhodih poročil s pisavami in slikami. Ko mora izhod prestati preverjanje arhiviranja ali predpriprave za tisk, pravila barvnih prostorov in izhodnih namenov, ki so obravnavani v priročniku za validacijo PDF/A, PDF/X in PDF/UA, določajo, katere od teh funkcij so dovoljene in kako morajo biti označene barve naprav. Vse to je na voljo v komponenti HotPDF Component za Delphi in C++Builder, skupaj z vmesniki API za senčenje, ICC in ločevanje, ki gradijo na enakem jedru vrste 0.