|
Declara un objeto de flujo indirecto Function Type 0 (Sampled) de PDF 1.3+ (ISO 32000-1 7.10.2) Las funciones muestreadas expresan una asignación arbitraria de entrada a salida como una rejilla regular de N dimensiones con muestras de salida de M dimensiones; el renderizador interpola linealmente entre los puntos de la rejilla para evaluar entradas intermedias. Úselo cuando la maquinaria de perfiles ICC sea excesiva pero se desee una tabla de búsqueda afinada a mano - curvas de tono para /TransferFunction (ExtGState /TR), transformaciones tintadas muestreadas para /Separation o /DeviceN (alternativa a las rutas lineales Type 2 / aritméticas Type 4), curvas de umbral de semitono o cualquier otra estructura 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 flujo indirecto con las entradas /FunctionType 0, /Domain, /Range, /Size, /BitsPerSample y /Order proporcionadas, más el flujo de muestras crudo empaquetado en 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 rejilla [0..Size[i]-1], y /Decode coincide con /Range (las muestras se desempaquetan como enteros y se vuelven a mapear linealmente a los extremos de Range). Para funciones de varias entradas, el orden de bytes de las muestras sigue la regla de PDF 1.7 "las coordenadas de entrada aumentan más rápido a lo largo de la primera dimensión de entrada", es decir, el desplazamiento de bytes para el punto de rejilla (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 con spline cúbica) según PDF 1.7 Table 38. Cubic ofrece transiciones más suaves con densidades bajas de la rejilla de muestras (por ejemplo, curvas de tono ICC de 17 puntos), pero algunos lectores celulares antiguos retroceden en silencio a lineal cuando encuentran un valor Order que no implementan. Disponible desde HotPDF v2.54.0
Para casos de uso con entrada ASCII - la ruta de autoría típica - una sola función de 1 entrada y M salidas con BitsPerSample = 8 y Size = [256] produce una LUT de 256 muestras cuyo flujo ocupa exactamente 256 * M bytes distribuidos 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 de entrada a este rango antes de interpolar. N se determina a partir de 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 decodificar
Size - N enteros que indican el recuento de puntos de rejilla en cada eje de entrada. Length(Size) debe ser igual a N. El total de puntos de rejilla es el producto de todas las entradas de 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 más práctica (flujo bruto de bytes); 16 a 32 son anchos big-endian alineados a bytes; 1 / 2 / 4 / 12 requieren empaquetado de bits con orden MSB primero y el último byte rellenado con ceros hasta el límite de byte. Cualquier otro valor provoca una excepción
Samples - el flujo bruto de muestras empaquetadas en bits. La longitud debe ser al menos ceil(GridPoints * M * BitsPerSample / 8) bytes. HotPDF copia los bytes proporcionados tal cual en el objeto de flujo 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 diccionario mediante AddValue o a un generador de sombreado / separación. 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 es inferior a 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
|