THotPDF.RegisterSampledFunction Method

 

THotPDF.RegisterSampledFunction

THotPDF

 

先頭

PDF 1.3+ の Function Type 0 (Sampled) indirect stream object (ISO 32000-1 7.10.2) を宣言します。sampled functions は任意の input-to-output mapping を、M-dimensional output samples の regular N-dimensional grid として表現します。renderer は grid points 間を linear interpolation して intermediate inputs を評価します。ICC profile machinery は大げさだが hand-tuned lookup table が必要な場合に使用します。/TransferFunction (ExtGState /TR) 用 tone curves、linear Type 2 / arithmetic Type 4 paths の代替となる /Separation または /DeviceN 用 sampled tint transforms、halftone threshold curves、または Function dictionary を受け付けるその他の PDF construct に適しています

 

Delphi syntax:

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;

 

C++ syntax:

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);

 

説明

function は /FunctionType 0、supplied /Domain/Range/Size/BitsPerSample/Order entries、および raw bit-packed sample stream を持つ indirect stream として出力されます。/Encode/Decode は omit されるため spec defaults が適用されます。/Encode は各 Domain endpoint を grid extents [0..Size[i]-1] に map し、/Decode/Range と一致します (samples は integers に unpack され Range endpoints へ linear remap されます)。multi-input functions では、sample byte order は PDF 1.7 rule の「input coordinates increase fastest along the first input dimension」に従います。つまり M outputs を持つ grid point (i_0, i_1, ..., i_{N-1}) の byte offset は ((((i_{N-1} * Size[N-2] + i_{N-2}) * ...) * Size[0] + i_0) * M * BitsPerSample / 8 です

Order - optional で default は 1 です。PDF 1.7 Table 38 に従い、1 (linear interpolation、PDF 1.7 default) または 3 (cubic-spline interpolation) を受け付けます。cubic は low sample-grid densities (例: 17-point ICC tone curves) でより滑らかな transition を与えますが、古い mobile readers の一部は実装していない Order value に遭遇すると silently linear に fallback します。HotPDF v2.54.0 以降で利用可能です

ASCII-input use cases、つまり典型的な authoring path では、BitsPerSample = 8 かつ Size = [256] の single 1-input / M-output function により、stream が正確に 256 * M bytes の 256-sample LUT になります。layout は (o0_0, o1_0, ..., oM-1_0, o0_1, ..., oM-1_255) です

 

Domain - [in0Min in0Max in1Min in1Max ...] order の 2N Single values です。function は interpolation 前に incoming values をこの range に clamp します。N は Length(Domain) div 2 から決まります

Range - M output dimensions と同じ shape を持つ 2M Single values です。output samples は decoding 後にこの range に clamp されます

Size - 各 input axis に沿った grid-point count を与える N 個の integers です。Length(Size) は N と等しくなければなりません。total grid points はすべての Size entries の積です

BitsPerSample - PDF 1.7 Table 38 に従い、1、2、4、8、12、16、24、32 のいずれかです。8 は扱いやすい選択肢です (raw byte stream)。16 から 32 は byte-aligned big-endian widths です。1 / 2 / 4 / 12 では MSB-first bit packing が必要で、最後の byte は byte boundary まで zero-pad されます。それ以外の値は exception を発生させます

Samples - raw bit-packed sample stream です。length は少なくとも ceil(GridPoints * M * BitsPerSample / 8) bytes でなければなりません。HotPDF は supplied bytes を indirect stream object にそのまま copy します。bit-pack correctness は caller の責任です

 

戻り値: indirect THPDFStreamObject です。callers は Function dictionary が期待される任意の場所に attach できます (通常は indirect reference を AddValue 経由で別の dict に渡すか、shading / separation builder に渡します)。object は document の IndirectObjects list が所有し、document end で解放されます。StrictVersionLock が on で active Version が PDF 1.3 未満の場合は nil を返します (それ以外では document version は 1.3 に auto-bump されます)

 

Code Example

// 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;

 

関連項目

RegisterAxialGradient, RegisterDeviceN, RegisterSeparation, Version, PDF Filter Support