|
Deklaruje nepřímý streamový objekt PDF 1.3+ Function Type 0 (Sampled) (ISO 32000-1 7.10.2). Vzorkované funkce vyjadřují libovolné mapování vstupu na výstup jako pravidelnou N-rozměrnou mřížku M-rozměrných výstupních vzorků; renderer lineárně interpoluje mezi body mřížky, aby vyhodnotil mezilehlé vstupy. Použijte to tam, kde je mechanismus profilů ICC zbytečně těžký, ale je žádoucí ručně laděná vyhledávací tabulka - tónové křivky pro /TransferFunction (ExtGState /TR), vzorkované transformace tint pro /Separation nebo /DeviceN (alternativa k lineárním cestám Type 2 / aritmetickým cestám Type 4), prahové křivky polotónování nebo jakýkoli jiný konstrukt PDF, který přijímá slovník Function
Syntaxe Delphi:
function RegisterSampledFunction(const Domain: array of Single; const Range: array of Single; const Size: array of Integer; BitsPerSample: Integer; const Samples: array of byte; Order: Integer = 1): THPDFStreamObject;
Syntaxe C++:
THPDFStreamObject* RegisterSampledFunction(const float* Domain, int DomainCount, const float* Range, int RangeCount, const int* Size, int SizeCount, int BitsPerSample, const unsigned char* Samples, int SamplesCount, int Order = 1);
Popis
Funkce se vydává jako nepřímý stream s položkami /FunctionType 0, dodanými /Domain, /Range, /Size, /BitsPerSample a /Order, plus surovým bitově zabaleným streamem vzorků. /Encode a /Decode se vynechávají, takže platí výchozí hodnoty specifikace: /Encode mapuje každý koncový bod Domain na rozsahy mřížky [0..Size[i]-1] a /Decode odpovídá /Range (vzorky se rozbalí na celá čísla a lineárně se přemapují zpět na koncové body Range). U funkcí s více vstupy pořadí bajtů vzorků sleduje pravidlo PDF 1.7 "input coordinates increase fastest along the first input dimension", tj. bajtový offset pro bod mřížky (i_0, i_1, ..., i_{N-1}) s M výstupy je ((((i_{N-1} * Size[N-2] + i_{N-2}) * ...) * Size[0] + i_0) * M * BitsPerSample / 8
Order - volitelné, výchozí 1. Přijímá 1 (lineární interpolace, výchozí PDF 1.7) nebo 3 (kubická spline interpolace) podle PDF 1.7 Table 38. Kubická volba poskytuje hladší přechody při nízké hustotě vzorkovací mřížky (např. 17bodové tónové křivky ICC), ale někteří starší mobilní čteči se tiše vrátí k lineární interpolaci, když narazí na hodnotu Order, kterou neimplementují. Dostupné od HotPDF v2.54.0
Pro případy použití se vstupem ASCII - typickou autorskou cestu - jediná funkce s 1 vstupem / M výstupy s BitsPerSample = 8 a Size = [256] poskytne 256vzorkovou LUT, jejíž stream má přesně 256 * M bajtů rozložených jako (o0_0, o1_0, ..., oM-1_0, o0_1, ..., oM-1_255)
Domain - 2N hodnot Single, v pořadí [in0Min in0Max in1Min in1Max ...]. Funkce před interpolací ořízne příchozí hodnoty na tento rozsah. N se určí z Length(Domain) div 2
Range - 2M hodnot Single se stejným tvarem pro M výstupních rozměrů; výstupní vzorky se po dekódování oříznou na tento rozsah
Size - N celých čísel udávajících počet bodů mřížky podél každé vstupní osy. Length(Size) se musí rovnat N. Celkový počet bodů mřížky je součin všech položek Size
BitsPerSample - jedna z hodnot 1, 2, 4, 8, 12, 16, 24 nebo 32 podle PDF 1.7 Table 38. 8 je ergonomická volba (surový bajtový stream); 16 až 32 jsou big-endian šířky zarovnané na bajty; 1 / 2 / 4 / 12 vyžadují bitové balení MSB-first s koncovým bajtem doplněným nulami na hranici bajtu. Jakákoli jiná hodnota vyvolá výjimku
Samples - surový bitově zabalený stream vzorků. Length musí být alespoň ceil(GridPoints * M * BitsPerSample / 8) bajtů. HotPDF zkopíruje dodané bajty doslova do nepřímého streamového objektu; správnost bitového balení je odpovědností volajícího
Vrácená hodnota: nepřímý THPDFStreamObject, aby jej volající mohli připojit všude, kde se očekává slovník Function (typicky předáním jeho nepřímé reference do jiného slovníku přes AddValue nebo do builderu shading / separation). Objekt vlastní seznam IndirectObjects dokumentu a uvolní se na konci dokumentu. Vrací nil, když je zapnutý StrictVersionLock a aktivní Verze je pod PDF 1.3 (jinak se verze dokumentu automaticky zvýší na 1.3)
Příklad kódu
// 256-sample 1-input / 3-output (RGB) heatmap LUT. The LUT maps a
// scalar t in [0..1] to a blue -> green -> red gradient through the
// midpoint
uses
HPDFObjs;
var
Func: THPDFStreamObject;
Domain: array[0..1] of Single;
Range: array[0..5] of Single;
Size: array[0..0] of Integer;
Samples: array[0..767] of byte; // 256 grid points * 3 outputs
I: Integer;
T: Single;
begin
HPDF.BeginDoc;
// 1 input dim: t in [0..1]
Domain[0] := 0; Domain[1] := 1;
// 3 output dims: each in [0..1]
Range[0] := 0; Range[1] := 1;
Range[2] := 0; Range[3] := 1;
Range[4] := 0; Range[5] := 1;
// 256 sample points along the single input axis
Size[0] := 256;
for I := 0 to 255 do
begin
T := I / 255.0;
if T < 0.5 then
begin
Samples[I*3 + 0] := 0;
Samples[I*3 + 1] := byte(Round(2.0 * T * 255.0));
Samples[I*3 + 2] := byte(Round((1.0 - 2.0*T) * 255.0));
end
else
begin
Samples[I*3 + 0] := byte(Round(2.0 * (T - 0.5) * 255.0));
Samples[I*3 + 1] := byte(Round((1.0 - 2.0*(T - 0.5)) * 255.0));
Samples[I*3 + 2] := 0;
end;
end;
Func := HPDF.RegisterSampledFunction(Domain, Range, Size, 8, Samples);
// Func is now an indirect THPDFStreamObject the caller can attach
// to any PDF dict slot that accepts a Function reference
HPDF.EndDoc;
end;
Viz také
RegisterAxialGradient, RegisterDeviceN, RegisterSeparation, Verze, PDF Filter Support
|