The AToB, BToA, gamut, preview, DToB and BToD tags hold a conversion built from a few kinds of stage: one-dimensional curves or tables for each channel, a matrix, and a multi-dimensional colour lookup table (CLUT) that is interpolated between its grid points. These types store them. Tables work on values from 0.0 to 1.0, so device values and PCS values are scaled to that range first (see Numbers and encodings).
Channel order
Each colour space’s channels are in this order, in every transform type and in chromaticityType:
| Space | Channels |
|---|---|
XYZ | X, Y, Z |
Lab | L, a, b |
Luv | L, u, v |
YCbr | Y, Cb, Cr |
Yxy | Y, x, y |
RGB | R, G, B |
GRAY | K |
HSV | H, S, V |
HLS | H, L, S |
CMYK | C, M, Y, K |
CMY | C, M, Y |
2CLR to FCLR | Channel 1, channel 2 … in numerical order |
The CLUT
A CLUT with i inputs is an i-dimensional grid. The first input varies slowest and the last fastest, and each grid point holds one value for each output, in output order. Its size is the product of the grid sizes times the number of outputs times the bytes a value. A dimension of two points must be set so that linear interpolation gives the right result.
mft1 lut8Type
Matrix → input tables → CLUT → output tables, with 8-bit tables.
| Offset | Size | Field |
|---|---|---|
| 8 | 1 | Number of input channels i |
| 9 | 1 | Number of output channels o |
| 10 | 1 | Number of CLUT grid points g, the same along every input |
| 11 | 1 | Padding, zero |
| 12 | 36 | Matrix e1 to e9, s15Fixed16Numbers, row by row |
| 48 | 256i | Input tables, 256 uInt8Numbers each |
| 48 + 256i | gio | CLUT, uInt8Numbers |
| 48 + 256i + gio | 256o | Output tables, 256 uInt8Numbers each |
The matrix is used only when the input is PCSXYZ and must otherwise be the identity. Entries
are divided by 255 to give 0.0 to 1.0. On the PCS side Lab means 8-bit PCSLAB; no
8-bit PCSXYZ encoding is defined, so lut8Type should not be used with PCSXYZ.
mft2 lut16Type
The same stages with 16-bit tables and table lengths of its own.
| Offset | Size | Field |
|---|---|---|
| 8 | 1 | Number of input channels i |
| 9 | 1 | Number of output channels o |
| 10 | 1 | Number of CLUT grid points g |
| 11 | 1 | Padding, zero |
| 12 | 36 | Matrix e1 to e9 |
| 48 | 2 | Number of input table entries n, 2 to 4096 |
| 50 | 2 | Number of output table entries m, 2 to 4096 |
| 52 | 2ni | Input tables, uInt16Numbers |
| 52 + 2ni | 2gio | CLUT, uInt16Numbers |
| 52 + 2ni + 2gio | 2mo | Output tables, uInt16Numbers |
Entries are divided by 65535. On the PCS side, Lab means the
legacy 16-bit PCSLAB encoding (FF00 is L* 100) and
XYZ the 16-bit PCSXYZ encoding.
mAB lutAToBType
Up to five stages, processed in the order “A” curves → CLUT → “M” curves → matrix → “B” curves, but stored by offset, in any order:
| Offset | Size | Field |
|---|---|---|
| 8 | 1 | Number of input channels i |
| 9 | 1 | Number of output channels o |
| 10 | 2 | Padding, zero |
| 12 | 4 | Offset to the first “B” curve |
| 16 | 4 | Offset to the matrix |
| 20 | 4 | Offset to the first “M” curve |
| 24 | 4 | Offset to the CLUT |
| 28 | 4 | Offset to the first “A” curve |
| 32 | … | The stages |
Offsets count from the start of the tag; zero means the stage is absent. At least one stage is present, and only these combinations are allowed: B; M, matrix, B; A, CLUT, B; A, CLUT, M, matrix, B. Others are made with identity stages. When i and o differ, the CLUT must be present. Every stage starts on a 4-byte boundary, and stages may share data.
- “A” curves: one for each input, used only with the CLUT.
- CLUT: 16 bytes of grid sizes (one for each input, the rest zero), one byte of precision (1 or 2 bytes a value), 3 bytes of padding, then the values.
- “M” curves: one for each output, used only with the matrix.
- Matrix: 12 s15Fixed16Numbers, e1 to e9 a 3 × 3 matrix row by row and e10 to e12 offsets: Y1 = e1·X1 + e2·X2 + e3·X3 + e10, and so on. The results are clipped to 0.0 to 1.0.
- “B” curves: one for each output.
Each curve is a whole curveType or parametricCurveType element, with its type signature and reserved bytes, padded to a 4-byte boundary before the next. lutAToBType may be used whatever the PCS field says.
mBA lutBToAType
The same header and stages, processed the other way: “B” curves → matrix → “M” curves → CLUT → “A” curves. There are as many “B” and “M” curves as inputs and as many “A” curves as outputs. The allowed combinations are B; B, matrix, M; B, CLUT, A; B, matrix, M, CLUT, A. The matrix is allowed only with three “M” curves. lutBToAType is used only when the PCS is PCSXYZ or PCSLAB.
mpet multiProcessElementsType
A chain of processing elements working on float32Numbers, any number of each kind, run in the order of the table. Each element’s inputs are the previous one’s outputs; results are not clipped between elements. A CMM that meets an element it does not know must not use the tag and falls back to the AToB or BToA tags.
| Offset | Size | Field |
|---|---|---|
| 8 | 2 | Number of input channels |
| 10 | 2 | Number of output channels |
| 12 | 4 | Number of processing elements n, at least 1 |
| 16 | 8n | Positions: offset from the start of the tag and size of each element |
| 16 + 8n | … | The elements, each on a 4-byte boundary; they may be shared |
Every element starts with its signature (4 bytes), 4 reserved bytes, the number of inputs p and the number of outputs q (2 bytes each).
cvst curve set element
After the 12-byte element header: p positions (offset from the start of the element and size), then the curves, one for each channel; q equals p. Each curve is a segmented curve:
| Offset | Size | Field |
|---|---|---|
| 0 | 4 | curf |
| 4 | 4 | Reserved, zero |
| 8 | 2 | Number of segments n |
| 10 | 2 | Reserved, zero |
| 12 | 4(n − 1) | Break-points, float32Numbers, not decreasing |
| 8 + 4n | … | The n segments |
The first segment runs from −∞ to the first break-point (included), each later one from the
previous break-point (excluded) to the next (included), and the last to +∞. The first and last
are formulas; the others may be formulas or sampled. A formula segment is parf, 4
reserved bytes, a function type (2 bytes), 2 reserved bytes and float32 parameters:
| Type | Parameters | Function |
|---|---|---|
| 0 | g a b c | Y = (aX + b)g + c |
| 1 | g a b c d | Y = a·log10(b·Xg + c) + d |
| 2 | a b c d e | Y = a·bcX + d + e |
ICC.1 defines types 0 to 2 only; iccMAX adds 3 to 7 (see iccMAX curve sets).
A sampled segment is samf, 4 reserved bytes, a count n (at least 1) and n
float32Numbers spaced evenly across the segment, the last at its end; the value at its start is
not stored but taken from the segment before.
matf matrix element
After the header, q(p + 1) float32Numbers: q rows of p coefficients, row by row, then q offsets. Yj = ej1X1 + … + ejpXp + ej. Inputs and outputs may be any float32 value.
clut CLUT element
After the header, 16 bytes of grid sizes (the first p used, each at least 2, the rest zero), then the values as float32Numbers. Inputs are clipped to 0.0 to 1.0; outputs are not.
bACS and eACS
Placeholders for future expansion: after the header a 4-byte signature. They pass their data through unchanged, with q equal to p.
In the explorer
Each transform tag opens as a view of its own, listing its stages, drawing its curves and tables on a graph, and listing the CLUT’s grid points a page at a time with their output values. Values on the PCS side (lut8Type and lut16Type output tables and CLUT outputs, or input tables for BToA, and the “B” curves of lutAToBType and lutBToAType) are also shown as L*a*b* or PCSXYZ, in the legacy encoding for lut16Type. The elements iccMAX adds to multiProcessElementsType, including the calculator and its program, are decoded too; they are described on iccMAX types and elements.