Technical Article

Tip 0 Örneklenmiş Fonksiyonlarla PDF'de 3B Renk LUT'ları

PDF Fonksiyonları, spesifikasyonun daha sessiz köşelerinden biridir. Çoğu geliştirici onlarla yalnızca bir kez, Tip 2 eksenel gölgelendirmenin iki renk arasında geçiş yapmak için ihtiyaç duyduğu bir şey olarak karşılaşır ve bir daha asla bakmaz. Bu yazık, çünkü fonksiyon mekanizması, biçimin gölgelendirmeler, aktarım fonksiyonları, yarım ton nokta fonksiyonları, ayırma tonları ve yumuşak maske aktarım eğrileri için yeniden kullandığı küçük, genel amaçlı bir değerlendiricidir. Dört fonksiyon tipinden Tip 0, en güçlü olanı ve en az anlaşılanıdır. Bu örneklenmiş bir fonksiyondur (sampled function): okuyucunun aralarında enterpolasyon yaptığı çok boyutlu bir çıktı değerleri ızgarasıdır. Izgara içine koyduğunuz herhangi bir sayıyı tutabildiğinden, bir Tip 0 fonksiyonu, bir renk arama tablosunun (color lookup table - LUT) tam şekli olan keyfi bir doğrusal olmayan eşlemeyi ifade edebilir。

Bu makale, ISO 32000-1 §7.10.2'de tanımlanan Tip 0 sözlüğünü inceliyor, ardından bir belge işlem hattında en önemli iki durumu gösteriyor: üç girişli bir RGB'den RGB'ye renk düzeltme LUT'u ve tek girişli bir spot renk tonu dönüşümü. Aynı örneklenmiş fonksiyon oluşturucu her ikisine de hizmet eder ve aralarındaki fark tamamen ızgaranın kaç girişe sahip olduğu sorusudur。

Örneklenmiş fonksiyon okuyucunun enterpole ettiği bir ızgaradır

Bir Tip 0 fonksiyonu, düzenli bir ızgarada örnekleri depolayarak ve aralarında enterpolasyon yaparak m girişli bir vektörü n çıkışlı bir vektöre eşler. ISO 32000-1 §7.10.2 bu ızgarayı tanımlayan anahtarları listeler. /Domain, her giriş ekseninin alt ve üst sınırı olmak üzere giriş başına iki sayı tutar. /Range, her çıkış bileşeni için iki sayı tutar. /Size, her giriş ekseni boyunca örneklerin sayısını veren m tamsayıdan oluşan bir dizidir; dolayısıyla üç boyutta bir kenarı on iki örnek olan bir ızgara /Size [12 12 12] değerine sahiptir ve 1.728 ızgara noktası depolar. /BitsPerSample, depolanan her değerin hassasiyetini ayarlar; HotPDF, Tablo 38'in izin verdiği değerlerle eşleşen 1, 2, 4, 8, 12, 16, 24 ve 32 bit değerlerini kabul eder。

Örnek akışı sabit bir sırada okunur. İlk giriş boyutu en hızlı değişir, ardından ikincisi gelir ve bu şekilde devam eder; her ızgara noktasında n çıkış bileşeni sırayla depolanır. Bir RGB'den RGB'ye tablosu için bu, sekiz bitte ızgara noktası başına üç bayttır ve kırmızı çıkış, yeşil çıkış, mavi çıkış şeklinde düzenlenir ve önce kırmızı giriş taranır. İki anahtar daha sürekli dünyayı tamsayı ızgarasına eşler. /Encode, her girişi kendi /Domain aralığından 0 ile Size[i] - 1 örnek dizini aralığına eşler ve /Decode, depolanan ham tamsayıları /Range aralıklarına geri eşler. Bunları varsayılan değerlerinde bıraktığınızda, [0 1] aralığındaki bir giriş tam olarak tüm ızgaraya denk gelir ve depolanan 255 baytı çıkış aralığının en üstüne kod çözer, ki bu da [0,1] normalize edilmiş bir renk LUT'unun istediği şeydir。

Düzen 1'e karşı Düzen 3

Izgara noktaları arasında okuyucunun enterpolasyon yapması gerekir ve /Order bunun nasıl olacağını seçer. /Order 1 çoklu doğrusal enterpolasyondur (multilinear interpolation): bir eksen boyunca doğrusal, iki eksen boyunca iki doğrusal, üç eksen boyunca üç doğrusal. Hızlıdır, çoğu görüntüleyicideki donanımın tam olarak yaptığı şeydir ve düzgün bir renk dönüşümü için genellikle daha süslü şeylerden ayırt edilemez. /Order 3, değerlendirilen her noktanın etrafında daha fazla çalışma ve daha geniş bir destek bölgesi pahasına, örnekler üzerinden daha düzgün bir eğri uyduran kübik spline (cubic-spline) enterpolasyonu talep eder。

Buradaki denge, ızgara yoğunluğuna karşı eğri düzgünlüğüdür. Kübik düzen, ızgara kaba olduğunda ve eşleme görünür bir eğriliğe sahip olduğunda değerini kanıtlar; çünkü iki uzak örnek arasındaki düz bir çizgi, ton eğrisini gözün gradyanlarda yakalayabileceği bir şekilde düzleştirebilir. Izgara yoğunlaştığında, segmentler doğrusal enterpolasyonun eğriyi yakından takip etmesi için yeterince kısadır ve kübik çok az şey kazandırır. Pratik bir kural, /Order 3 seçeneğine yalnızca küçük ızgaralarda veya dik dönüşümlerde başvurmak ve aksi takdirde doğrusal varsayılanda bırakmaktır. /Order seçeneğinin yalnızca Tip 0 fonksiyonları için geçerli olduğunu ve HotPDF'nin 1 veya 3 dışındaki herhangi bir değeri reddettiğini unutmayın。

3B LUT: üç giriş, üç çıkış

Bir RGB'den RGB'ye renk düzeltmesi, renk derecelendirme ve cihaz eşleştirmede kullanılan klasik 3B LUT olan üç girişli bir ızgara için ders kitabı niteliğindeki durumdur. Küpün her bir ekseni bir giriş kanalıdır, every grid point stores the corrected RGB triple for that input coordinate, and the reader trilinearly interpolates the corner samples around any incoming color. Three inputs are unavoidable here because the corrected red can depend on the input green and blue, not just on the input red; a per-channel curve cannot express channel crosstalk, but a cube can.

HotPDF, /Domain, /Range, /Size, /BitsPerSample ve örnek baytlarını doğrudan alan ve fonksiyon nesnesini döndüren RegisterSampledFunction aracılığıyla Tip 0 akışını oluşturur. Standart bir normalize edilmiş küp için, üç giriş ekseninin tümünde ve üç çıkışın tümünde [0,1] sınırlarını, N x N x N boyutunu ve düzleştirilmiş örnek tablosunu iletirsiniz. Oluşturucu, bayt sayısının ızgara ile eşleştiğini doğrular: bayt hizalı bir derinlik için ÇıkışSayısı x (BitsPerSample div 8) x boyutların çarpımını bekler ve dizi yanlış uzunluktaysa hata verir; böylece yanlış hesaplanmış bir adım kayıt sırasında yüksek sesle başarısız olur ve daha sonra çöp olarak işlenmez。

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;

Küpün kolorimetrik doğruluğu, onu nasıl doldurduğunuzda yatar, PDF fonksiyonunda değil. Güvenilir yol, her ızgara noktasını bir provayı (soft-proof) çalıştıran motorun aynısı olan ICC yönetimli bir dönüşüm aracılığıyla hesaplamaktır; böylece ızgaradaki sayılar tanımlanmış bir kaynak ve hedef profile karşı bir anlam ifade eder. Dönüşümü sınırlayan profilleri, ICCBased bir renk uzayı (1, 3 veya 4 bileşenli) kaydeden ve LUT'un beslediği içeriğe ekleyebileceğiniz bir kaynak adı döndüren RegisterICCProfile ile kaydedin. Tip 0 fonksiyonu enterpolasyon tablosunu taşır; ICC profili uç noktaların anlamını taşır。

1B durum: bir spot renk tonu dönüşümü

Ayrım (Separation) renk uzayları, tamamen farklı bir iş için aynı mekanizmaya dayanır. ISO 32000-1 §8.6.6.4'te tanımlanan bir Ayrım uzayı, bir adı bir ton dönüşümü (tint transform) ile eşleştirerek tek bir renklendiriciyi, örneğin bir Pantone veya vernik gibi bir spot mürekkebi temsil eder: tek boyutlu ton değerini (mürekkep yoksa 0, tam mürekkep varsa 1) cihazın gerçekten işleyebileceği alternatif bir renk uzayına (genellikle CMYK) eşleyen bir fonksiyondur. Bu ton dönüşümü sıklıkla bir Tip 0 fonksiyonudur ve artık ızgara tam olarak bir giriş eksenine sahiptir。

Bu, 3B LUT ile olan net karşıtlıktır. Bir spot mürekkep bir serbestlik derecesidir, dolayısıyla ton dönüşümü tek bir girişe ihtiyaç duyar ve ızgara, her biri o ton seviyesindeki CMYK (veya diğer alternatif) değerini tutan bir örnek çizgisidir. RGB küpü üç girişe ihtiyaç duyar çünkü etki alanı üç boyutludur ve kanallar etkileşime girer. Aynı fonksiyon tipi, aynı enterpolasyon kuralları, farklı boyutlar; spesifikasyon tek bir değerlendiriciyi yeniden kullanır ve /Size seçeneğinin bir çizgide mi, bir düzlemde mi yoksa bir küpte mi yürüdüğünüze karar vermesine izin verir. HotPDF, tüm ayrımı, dahili olarak düz bir bayt dizisinden tek girişli Tip 0 ton dönüşümünü oluşturan ve renk uzayı kaynak adını döndüren RegisterSeparationLUT içinde sarar。

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;

Örnek sayısının tam bir ızgara noktası sayısı olması gerekir: alternatif uzayın bileşen sayısının pozitif bir katı ve enterpolasyon yapılacak bir segment olması için en az iki nokta. CMYK alternatifine karşı nokta başına üç bayt iletirseniz çağrı bunu reddeder; bu, 3B oluşturucunun uyguladığı savunma amaçlı doğrulamanın aynısıdır ve aksi takdirde yazdırma zamanında sessizce başarısız olacak bir fonksiyondan isteyeceğiniz şeydir。

Aynı mekanizmanın tekrar ortaya çıktığı yerler

Tip 0'ı genel bir enterpolasyon tablosu olarak gördüğünüzde, iki cihaz kontrol özelliği daha özel durumlar gibi görünmeyi bırakır. Bir aktarım fonksiyonu, bileşen değerlerini çıkış cihazına giderken ayarlar ve bu sadece kanal başına bir fonksiyondur; HotPDF bunu, tek bir birleşik fonksiyonu veya kanal başına fonksiyon dizisini kabul eden RegisterTransferFunctionState aracılığıyla bir ExtGState olarak kaydeder. Bu fonksiyonlar sıradan fonksiyon nesneleri olduğundan, RegisterSampledFunction'ın döndürdüğü THPDFStreamObject'i doğrudan ona verebilir ve bir aktarım eğrisini bir formül yerine örneklenmiş bir tablodan yönlendirebilirsiniz。

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;

Siyah oluşturma (black generation) ve renk altı çıkarma (undercolor removal) aynı ailede yer alır. Bir cihaz RGB'yi CMYK'ye dönüştürürken, gri bileşenin ne kadarını siyah mürekkep olarak taşıyacağına karar verir ve spesifikasyon bu kararı, bir grafik durumu sözlüğünün /BG2 and /UCR2 girişleri olarak ifade eder; bunların her biri hesaplanan griden siyah miktarına kadar tek girişli bir eğridir. Analitik bir eğri yerine ölçülmüş bir eğri istediğinizde bunlar da Tip 0 fonksiyonlarıdır, aynı şekilde RegisterSampledFunction aracılığıyla oluşturulur ve grafik durumuna yerleştirilir. Unutulmaması gereken ders, PDF fonksiyonunun asla renk yönetiminin gerçekleştiği yer olmadığıdır; o, gerçek bir renk motoruyla verdiğiniz kararı taşıyan bir arama tablosudur ve Tip 0, herhangi bir kararı taşıyacak kadar esnek olan tek fonksiyon tipidir。

Yazı tiplerinin, resimlerin ve renk kaynaklarının bitmiş bir belgeye nasıl aktarıldığına dair daha geniş resim için, yazı tipleri ve resimlerle rapor çıktısı kılavuzumuza bakın. Çıktının bir arşiv veya yazdırma uçuş öncesi (preflight) kontrolünden geçmesi gerektiğinde, PDF/A, PDF/X ve PDF/UA doğrulama kılavuzunda ele alınan renk uzayı ve çıktı amacı kuralları bu fonksiyonlardan hangilerine izin verildiğini ve cihaz renginin nasıl etiketlenmesi gerektiğini yönetir. Tüm bunlar, aynı Tip 0 çekirdeği üzerine inşa edilen gölgelendirme, ICC ve ayırma API'lerinin yanı sıra Delphi ve C++Builder için HotPDF Bileşeni içinde sunulur。