Pdfium.Net SDK. User Manual

## Working With Functions |

This topic contains the following sections:

Overview

PDF is not a programming language, and a PDF file is not a program. However, PDF does provide several types of function objects that represent parameterized classes of functions, including mathematical formulas and sampled representations with arbitrary resolution. Functions are used in various ways in PDF, including device-dependent rasterization information for highquality printing (halftone spot functions and transfer functions), color transform functions for certain color spaces, and specification of colors as a function of position for smooth shadings.

Functions in PDF represent static, self-contained numerical transformations. A function to add two numbers has two input values and one output value:

f(x_{0} , x_{1}) = x_{0} + x_{1}

Similarly, a function that computes the arithmetic and geometric mean of two numbers could be viewed as a function of two input values and two output values. In general, a function can take any number (Inputs) of input values and produce any number (Outputs) of output values:

f(x_{0} , ..., x_{inputs - 1}) = y_{0} , y_{outputs - 1}

In PDF functions, all the input values and all the output values are numbers, and functions have no side effects.

Each function has a Domain property, the set of legal values for the input. Some types of functions also has a Range property, the set of legal values for the output. Input values passed to the function are clipped to the domain, and output values produced by the function are clipped to the range. For example, suppose the function

f(x) = x + 2

is defined with a domain of [−1 1]. If the function is called with the input value 6, that value is replaced with the nearest value in the defined domain, 1, before the function is evaluated; the resulting output value is therefore 3. Similarly, if the function

f (x_{0} , x_{1}) = 3 × x_{0} + x_{1}

is defined with a range of [0 100], and if the input values −6 and 4 are passed to the function (and are within its domain), then the output value produced by the function, −14, is replaced with 0, the nearest value in the defined range.

Four types of functions are available, as indicated by the below diagram:

PdfFuncSampled Type 0 (Sampled) Functions

PdfFuncExponential Type 2 (Exponential Interpolation) Functions

PdfFuncStitching Type 3 (Stitching) Functions

PdfFuncPostScript Type 4 (PostScript Calculator) Functions

All of the above classes are derived from the abstract class PdfFunction

The number of input values. | |

The number of output values. | |

An array of 2 × Inputs numbers. For each i from 0 to Inputs − 1,
Domain | |

An array of 2 × Outputs numbers. For each j from 0 to Outputs − 1,
Range |

Type 0 (Sampled) Functions

PdfFuncSampled functions use a sequence of sample values (contained in a Stream) to provide an approximation for functions whose domains and ranges are bounded. The samples are organized as an Inputs-dimensional table in which each entry has Outputs components.

Sampled functions are highly general and offer reasonably accurate representations of arbitrary analytic functions at low expense. For example, a 1-input sinusoidal function can be represented over the range [0 180] with an average error of only 1 percent, using just ten samples and linear interpolation. Two-input functions require significantly more samples but usually not a prohibitive number if the function does not have high frequency variations.

The dimensionality of a sampled function is restricted only by implementation limits. However, the number of samples required to represent functions with high dimensionality multiplies rapidly unless the sampling resolution is very low. Also, the process of multilinear interpolation becomes computationally intensive if the number of inputs is greater than 2. The multidimensional spline interpolation is even more computationally intensive.

An array of Inputs positive integers specifying the number of samples in each input dimension of the sample table. | |

The number of bits used to represent each sample. (If the function has multiple output values, each one occupies Bps bits.) Valid values are 1, 2, 4, 8, 12, 16, 24, and 32 | |

The order of interpolation between samples. Valid values are 1 and 3, specifying linear and cubic spline interpolation, respectively. Default value: 1. | |

An array of 2 × Inputs numbers specifying the linear mapping of input values into the domain of the function’s sample table.
Default value: [0 (NumOfSamples | |

An array of 2 × Outputs numbers specifying the linear mapping of sample values into the range appropriate for the function’s output values. Default value: same as the value of Range. | |

The sample table. |

The Domain, Encode, and NumOfSamples properties determine how the function’s input variable values are mapped into the sample table. For example, if NumOfSamples is [21 31], the default Encode array is [0 20 0 30], which maps the entire domain into the full set of sample table entries. Other values of Encode may be used.

To explain the relationship between Domain, Encode, NumOfSamples, Decode, and Range, we use the following notation:

y = Interpolate(x, x_{min} , x_{max} , y_{min} , y_{max}) = y_{min} + (x - x_{min}) × (y_{max} - y_{min}) / (x_{max} - x_{min})

For a given value of x, Interpolate calculates the y value on the line defined by the
two points (x_{min} , y_{min}) and (x_{max} , y_{max}).

When a sampled function is called, each input value x_{i} , for 0 ≤ i < Inputs, is clipped to the domain:

x_{i}' = min(max(x_{i} , Domain_{2i}), Domain_{2i + 1})

That value is encoded:

e_{i} = Interpolate(x_{i}' , Domain_{2i}, Domain_{2i + 1} , Encode_{2i} , Encode_{2i + 1})

That value is clipped to the size of the sample table in that dimension:

e_{i}' = min(max(e_{i} , 0), NumOfSamples_{i} - 1)

The encoded input values are real numbers, not restricted to integers.
Interpolation is used to determine output values from the nearest surrounding
values in the sample table. Each output value r_{j}, for 0 ≤ j < Outputs, is then decoded:

r_{j}' = Interpolate(r_{j} , 0, 2^{Bps} - 1 , Decode_{2j} , Decode_{2j + 1})

Finally, each decoded value is clipped to the range:

y_{j} = min(max(r_{j}' , Range_{2j}), Range_{2j + 1})

Sample data int the Stream is represented as a stream of unsigned 8-bit bytes (integers in the range 0 to 255). The bytes constitute a continuous bit stream, with the high-order bit of each byte first. Each sample value is represented as a sequence of Bps bits. Successive values are adjacent in the bit stream; there is no padding at byte boundaries.

For a function with multidimensional input (more than one input variable), the sample values in the first dimension vary fastest, and the values in the last dimension vary slowest. For example, for a function f(a, b, c), where a, b, and c vary from 0 to 9 in steps of 1, the sample values would appear in this order: f(0, 0, 0), f(1, 0, 0), …, f(9, 0, 0), f(0, 1, 0), f(1, 1, 0), …, f(9, 1, 0), f(0, 2, 0), f(1, 2, 0), …, f(9, 9, 0), f(0, 0, 1), f(1, 0, 1), and so on.

For a function with multidimensional output (more than one output value), the values are stored in the same order as Range.

Type 2 (Exponential Interpolation) Functions

PdfFuncExponential functions include a set of parameters that define an exponential interpolation of one input value and Outputs output values:

f(x) = y_{0} , ..., y_{outputs - 1}

An array of Outputs numbers defining the function result when x = 0.0. Default value: [0.0]. | |

An array of Outputs numbers defining the function result when x = 1.0. Default value: [1.0]. | |

The interpolation exponent. Each input value x will return Outputs values, given by
y |

Values of Domain must constrain x in such a way that if Exponent is not an integer, all values of x must be non-negative, and if Exponent is negative, no value of x may be zero. Typically, Domain is declared as [0.0 1.0], and Exponent is a positive number. The Range is optional and can be used to clip the output to a specified range. Note that when Exponent is 1, the function performs a linear interpolation between ValuesAt0 and ValuesAt1; therefore, the function can also be expressed as a sampled function (PdfFuncsampled).

Type 3 (Stitching) Functions

PdfFuncStitching functions define a stitching of the subdomains of several 1-input
functions to produce a single new 1-input function. Since the resulting stitching
function is a 1-input function, the domain is given by a two-element array,
[Domain_{0} Domain_{1}].

An array of k 1-input functions making up the stitching function. The output dimensionality of all functions must be the same, and compatible with the value of Range if Range is present. | |

An array of k − 1 numbers that, in combination with Domain, define the intervals to which each function from the Functions array applies. Bounds elements must be in order of increasing value, and each value must be within the domain defined by Domain. | |

An array of 2 × k numbers that, taken in pairs, map each subset of the domain defined by Domain and the Bounds array to the domain of the corresponding function. |

Domain must be of size 2 (that is, Inputs = 1), and Domain_{0} must be strictly less than
Domain_{1} unless k = 1. The domain is partitioned into k subdomains, as indicated
by the Bounds property, which is an array of k - 1 numbers that obey the
following relationships (with exceptions as noted below):

Domain_{0}< Bounds_{0}< Bounds_{1}< ... < Bounds_{k - 2}< Domain_{1}

The Bounds array describes a series of half-open intervals, closed on the left and
open on the right (except the last, which is closed on the right as well). The value of the Functions property
is an array of k functions. The first function applies to x values in the first subdomain,
Domain_{0} ≤ x < Bounds_{0}; the second function applies to
x values in the second subdomain, Bounds_{0} ≤ x < Bounds_{1}; and so on.

The last function applies to x values in the last subdomain, which includes the upper bound:
Bounds_{k − 2} ≤ x ≤ Domain_{1}. The value of k may be 1, in which case
the Bounds array is empty and the single item in the Functions array applies to all
x values, Domain_{0} ≤ x ≤ Domain_{1}.

The Encode array contains 2 × k numbers. A value x from the ith subdomain is encoded as follows:

x' = Interpolate(x, Bounds_{i - 1} , Bounds_{i} , Encode_{2i} , Encode_{2i + 1})

for 0 ≤ i < k. In this equation, Bounds_{-1} means
Domain_{0}, and Bounds_{k - 1} means Domain_{1}.
If the last bound, Bounds_{k - 2}, is equal to Domain_{1}, then x'
is defined to be Encode_{2i}.

The stitching function is designed to make it easy to combine several functions to be used within one shading pattern over different parts of the shading’s domain. (Shading patterns are discussed in section “Shading Patterns.”) The same effect could be achieved by creating a separate shading for each of the functions, with adjacent domains. However, since each shading would have similar parameters, and because the overall effect is one shading, it is more convenient to have a single shading with multiple function definitions.

Type 4 (PostScript Calculator) Functions

A PdfFuncPostScript function, also called a PostScript calculator function, is represented as a stream containing code written in a small subset of the PostScript language.
Although any function can be sampled (in a PdfFuncSampled function) and others can be described with exponential functions (PdfFuncExponential),
PdfFuncPostScript functions offer greater flexibility and potentially greater accuracy.
For example, a tint transformation function for a hexachrome (six-component) CsDeviceN color space
with an alternate color space of CsDeviceCMYK (see “DeviceN Color Spaces”)
requires a 6-in, 4-out function. If such a function were sampled with Inputs values for each input variable,
the number of samples, 4 × Inputs^{6}, could be prohibitively large.
In practice, such functions are often written as short, simple PostScript functions.

PdfFuncPostScript functions also make it possible to include a wide variety of halftone spot functions without the loss of accuracy that comes from sampling, and without adding to the list of predefined spot functions. All of the predefined spot functions can be written as PdfFuncPostScript functions.

The language that can be used in a PdfFuncPostScript function contains expressions involving integers, real numbers, and boolean values only. There are no composite data structures such as strings or arrays, no procedures, and no variables or names. The below Table lists the operators that can be used in this type of function.

The operand syntax for PdfFuncPostScript functions follows PDF conventions rather than PostScript conventions.
The entire code stream defining the function is enclosed in braces { }. Braces also delimit expressions that are executed conditionally by the **if** and **ifelse** operators:

boolean {expression} if

boolean {expression_{1}} {expression_{2}} ifelse

The Domain and Range are both required. The input variables constitute the initial operand stack; the items remaining on the operand stack after execution of the function are the output variables. It is an error for the number of remaining operands to differ from the number of output variables specified by Range property or for any of them to be objects other than numbers.

Pdfium.Net SDK provide a stack with room for 100 entries.

This section summarizes the PostScript operators that can appear in a PdfFuncPostScript function. For details on these operators, see the PostScript Language Reference.

operands | operator | result | description |
---|---|---|---|

num |
| sum | return num |

num |
| difference | return num |

num |
| product | return num |

num |
| quotient | return num |

int |
| quotient | return int |

int |
| remainder | return remainder after dividing int |

num |
| num | return negative of num |

num |
| num | return absolute value of num |

num |
| num | return ceiling of num |

num |
| num | return floor of num |

num |
| num | round num |

num |
| num | remove fractional part of num |

num |
| real | return square root of num |

angle |
| real | return sine of angle degrees |

angle |
| real | return cosine of angle degrees |

num den |
| angle | return arc tangent of num den in degrees |

base exponent |
| real | raise base to exponent power |

num |
| real | return natural logarithm (base e) |

num |
| real | return common logarithm (base 10) |

num |
| int | convert to integer |

num |
| real | convert to real |

operands | operator | result | description |
---|---|---|---|

any |
| bool | test equal |

any |
| bool | test not equal |

num |
| bool | test greater than |

num |
| bool | test greater than or equal |

num |
| bool | test less than |

num |
| bool | test less than or equal |

bool |
| bool | perform logical|bitwise and |

bool |
| bool | perform logical|bitwise inclusive or |

bool |
| bool | perform logical|bitwise exclusive or |

bool |
| bool | perform logical|bitwise not |

int |
| int | perform bitwise shift of int |

- |
| true | return boolean value true |

- |
| false | return boolean value false |

operands | operator | result | description |
---|---|---|---|

bool {expr} |
| - | execute expr if bool is true |

bool {expr |
| - | execute expr |

operands | operator | result | description |
---|---|---|---|

any |
| - | discard top element |

any |
| any | exchange top two elements |

any |
| any any | duplicate top element |

any |
| any | duplicate top n elements |

any |
| any | duplicate arbitrary element |

any |
| any | roll n elements up j times |

Any errors detected by the scanner are considered to be errors in the PDF file.

See Also