THotPDF.RegisterSampledFunction-Methode

 

THotPDF.RegisterSampledFunction

THotPDF

 

Übersicht

Deklariert ein indirektes PDF 1.3+ Function-Typ-0-Stream-Objekt (abgetastet/sampled) (ISO 32000-1 7.10.2) — Abgetastete Funktionen drücken eine beliebige Eingabe-zu-Ausgabe-Abbildung als regelmäßiges N-dimensionales Gitter aus M-dimensionalen Ausgabewerten (Samples) aus; der Renderer interpoliert linear zwischen den Gitterpunkten, um Zwischenwerte zu berechnen — Verwenden Sie dies, wenn ICC-Profil-Strukturen zu komplex sind, aber eine manuell abgestimmte Nachschlagetabelle (Lookup Table) gewünscht wird — z. B. Tonwertkurven für /TransferFunction (ExtGState /TR), abgetastete Farbton-Transformationen für /Separation oder /DeviceN (Alternative to target linear Type 2- / arithmetischen Typ 4-Pfaden), Raster-Schwellenwertkurven oder jedes andere PDF-Konstrukt, das ein Funktions-Dictionary akzeptiert

 

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

 

Beschreibung

Die Funktion wird als indirekter Stream mit /FunctionType 0, den angegebenen Einträgen /Domain, /Range, /Size, /BitsPerSample und /Order sowie dem rohen, bitgepackten Sample-Stream ausgegeben — /Encode und /Decode werden weggelassen, sodass die Standardwerte der Spezifikation gelten: /Encode bildet jeden Domain-Endpunkt auf die Gittergrenzen [0..Size[i]-1] ab, und /Decode entspricht /Range (Samples werden in Ganzzahlen entpackt und linear wieder auf die Range-Endpunkte abgebildet) — Bei Funktionen mit mehreren Eingängen folgt die Sample-Byte-Reihenfolge der PDF 1.7-Regel „Eingangskoordinaten steigen am schnellsten entlang der ersten Eingangsdimension“, d. h. der Byte-Offset für den Gitterpunkt (i_0, i_1, ..., i_{N-1}) mit M Ausgängen beträgt ((((i_{N-1} * Size[N-2] + i_{N-2}) * ...) * Size[0] + i_0) * M * BitsPerSample / 8

Order — optional, Standardwert 1 — Akzeptiert 1 (lineare Interpolation, PDF 1.7-Standard) oder 3 (kubische Spline-Interpolation) gemäß PDF 1.7 Tabelle 38 — Kubisch liefert weichere Übergänge bei geringer Gitterdichte (z. B. 17-punktige ICC-Tonwertkurven), aber einige ältere mobile Viewer greifen stillschweigend auf die lineare Interpolation zurück, wenn sie auf einen Order-Wert stoßen, den sie nicht implementieren — Verfügbar seit HotPDF v2.54.0

Für ASCII-Eingabefälle — den typischen Erstellungspfad — liefert eine einzelne Funktion mit 1 Eingang / M Ausgängen bei BitsPerSample = 8 und Size = [256] eine LUT mit 256 Samples, deren Stream genau 256 * M Bytes groß ist und als (o0_0, o1_0, ..., oM-1_0, o0_1, ..., oM-1_255) strukturiert ist

 

Domain — 2N Single-Werte, geordnet als [in0Min in0Max in1Min in1Max ...] — Die Funktion begrenzt eingehende Werte vor der Interpolation auf diesen Bereich — N wird aus Length(Domain) div 2 bestimmt

Range — 2M Single-Werte mit derselben Struktur für die M Ausgangsdimensionen; Ausgabesamples werden nach der Decodierung auf diesen Bereich begrenzt

Size — N Ganzzahlen, die die Anzahl der Gitterpunkte entlang jeder Eingangsachse angeben — Length(Size) muss gleich N sein — Die Gesamtanzahl der Gitterpunkte ist das Produkt aller Size-Einträge

BitsPerSample — einer der Werte 1, 2, 4, 8, 12, 16, 24 oder 32 gemäß PDF 1.7 Tabelle 38 — 8 ist die einfachste Wahl (roher Byte-Stream); 16 bis 32 sind byte-ausgerichtete Big-Endian-Breiten; 1 / 2 / 4 / 12 erfordern MSB-first-Bitpackung, wobei das letzte Byte bis zur Byte-Grenze mit Nullen aufgefüllt wird — Jeder andere Wert löst eine Ausnahme aus

Samples — der rohe, bitgepackte Sample-Stream — Die Länge muss mindestens ceil(GridPoints * M * BitsPerSample / 8) Bytes betragen — HotPDF kopiert die übergebenen Bytes wortwörtlich in das indirekte Stream-Objekt; die Richtigkeit der Bit-Packung liegt in der Verantwortung des Aufrufers

 

Rückgabewert: das indirekte THPDFStreamObject, sodass Aufrufer es überall dort anhängen können, wo ein Funktions-Dictionary erwartet wird (typischerweise durch Übergabe der indirekten Referenz in ein anderes Dictionary via AddValue oder an einen Schattierungs- / Separations-Builder) — Das Objekt befindet sich im Besitz der Liste IndirectObjects des Dokuments und wird am Dokumentende freigegeben — Gibt nil zurück, wenn StrictVersionLock aktiviert ist und die aktive Version unter PDF 1.3 liegt (andernfalls wird die Dokumentversion automatisch auf 1.3 erhöht)

 

Codebeispiel

// Heatmap-LUT mit 256 Samples, 1 Eingang / 3 Ausgängen (RGB) — Die LUT bildet
// einen Skalar t in [0..1] auf einen Blau -> Grün -> Rot-Verlauf ab
// über den Mittelpunkt
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 Eingangsdimension: t in [0..1]
  Domain[0] := 0; Domain[1] := 1;
  // 3 Ausgangsdimensionen: jeweils 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 ist nun ein indirektes THPDFStreamObject, das der Aufrufer an
  // jedes PDF-Dictionary-Feld anhängen kann, das eine Funktionsreferenz akzeptiert
  HPDF.EndDoc;
end;

 

Siehe auch

RegisterAxialGradient, RegisterDeviceN, RegisterSeparation, Version, PDF-Filterunterstützung