|
Declara un objeto stream indirecto Function Type 0 (Sampled) PDF 1.3+ (ISO 32000-1 7.10.2). Las funciones muestreadas expresan una asignación arbitraria de entrada a salida como una cuadrícula N-dimensional regular de muestras de salida M-dimensionales; el renderizador interpola linealmente entre puntos de cuadrícula para evaluar entradas intermedias. Use esto cuando la maquinaria de perfil ICC sea excesiva pero se necesite una lookup table ajustada a mano: curvas de tono para /TransferFunction (ExtGState /TR), transformaciones tint muestreadas para /Separation o /DeviceN (alternativa a las rutas lineales Type 2 / aritméticas Type 4), curvas de umbral de halftone o cualquier otra construcción PDF que acepte un diccionario Function
Sintaxis 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;
Sintaxis 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);
Descripción
La función se emite como un stream indirecto con /FunctionType 0, las entradas suministradas /Domain, /Range, /Size, /BitsPerSample y /Order, más el stream de muestras raw empaquetado por bits. /Encode y /Decode se omiten para que se apliquen los valores predeterminados de la especificación: /Encode mapea cada extremo de Domain a las extensiones de cuadrícula [0..Size[i]-1], y /Decode coincide con /Range (las muestras se desempaquetan a enteros y se remapean linealmente de vuelta a los extremos de Range). Para funciones con varias entradas, el orden de bytes de muestra sigue la regla PDF 1.7 "input coordinates increase fastest along the first input dimension", es decir, el offset de byte para el punto de cuadrícula (i_0, i_1, ..., i_{N-1}) con M salidas es ((((i_{N-1} * Size[N-2] + i_{N-2}) * ...) * Size[0] + i_0) * M * BitsPerSample / 8
Order - opcional, predeterminado 1. Acepta 1 (interpolación lineal, valor predeterminado de PDF 1.7) o 3 (interpolación cubic-spline) según PDF 1.7 Table 38. Cubic ofrece transiciones más suaves con densidades bajas de cuadrícula de muestras (por ejemplo, curvas de tono ICC de 17 puntos), pero algunos lectores móviles antiguos vuelven silenciosamente a lineal cuando encuentran un valor Order que no implementan. Disponible desde HotPDF v2.54.0
Para casos de uso con entrada ASCII, que son la ruta típica de autoría, una única función de 1 entrada / M salidas con BitsPerSample = 8 y Size = [256] produce una LUT de 256 muestras cuyo stream tiene exactamente 256 * M bytes dispuestos como (o0_0, o1_0, ..., oM-1_0, o0_1, ..., oM-1_255)
Domain - 2N valores Single, ordenados como [in0Min in0Max in1Min in1Max ...]. La función limita los valores entrantes a este rango antes de la interpolación. N se determina con Length(Domain) div 2
Range - 2M valores Single con la misma forma para las M dimensiones de salida; las muestras de salida se limitan a este rango después de la decodificación
Size - N enteros que indican el recuento de puntos de cuadrícula a lo largo de cada eje de entrada. Length(Size) debe ser igual a N. El total de puntos de cuadrícula es el producto de todas las entradas Size
BitsPerSample - uno de 1, 2, 4, 8, 12, 16, 24 o 32 según PDF 1.7 Table 38. 8 es la opción ergonómica (stream de bytes raw); 16 a 32 son anchos big-endian alineados a byte; 1 / 2 / 4 / 12 requieren empaquetado de bits MSB-first con el byte final rellenado con ceros hasta un límite de byte. Cualquier otro valor lanza una excepción
Samples - stream de muestras raw empaquetado por bits. La longitud debe ser de al menos ceil(GridPoints * M * BitsPerSample / 8) bytes. HotPDF copia literalmente los bytes suministrados al objeto stream indirecto; la corrección del empaquetado de bits es responsabilidad del llamador
Valor devuelto: el THPDFStreamObject indirecto para que los llamadores puedan adjuntarlo donde se espere un diccionario Function (normalmente pasando su referencia indirecta a otro dict mediante AddValue, o a un constructor de shading / separation). El objeto pertenece a la lista IndirectObjects del documento y se libera al final del documento. Devuelve nil cuando StrictVersionLock está activado y la Version activa está por debajo de PDF 1.3 (en caso contrario, la versión del documento sube automáticamente a 1.3)
Ejemplo de código
// 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;
Véase también
RegisterAxialGradient, RegisterDeviceN, RegisterSeparation, Version, Soporte de filtros PDF
|