iccMAX (ICC.2:2023, profile version 5) defines its own list of tag types. Its clause 1 says that some ISO 15076-1 (ICC.1) types have been removed and others added: lut8Type, lut16Type, chromaticityType, colorantTableType, namedColor2Type, profileSequenceDescType, profileSequenceIdentifierType, responseCurveSet16Type and viewingConditionsType are not in it. It keeps the others, extends measurementType and multiProcessElementsType, and adds the types on this page, the structures and arrays built from them, and new processing elements. Its header, classes and tags are on Versions and iccMAX. As everywhere in a profile, numbers are big-endian, and each tag starts with its type signature and four reserved bytes.
Numbers and codes
| Name | Size | Meaning |
|---|---|---|
| float16Number | 2 | IEEE 754 half precision |
| float64Number | 8 | IEEE 754 double precision |
| spectralRange | 6 | Start wavelength and end wavelength (float16Numbers, nm), then the number of steps (uInt16Number); the interval is (end − start) ÷ (steps − 1) |
| valueEncodingType | 2 or 4 | How sampled values are stored: 0 float32Number, 1 float16Number, 2 uInt16Number for 0.0 to 1.0, 3 uInt8Number for 0.0 to 1.0 |
| interpolationHintType | 1 | 0 no recommendation, 1 trilinear, 2 3D tetrahedral |
| sparseMatrixEncodingType | 2 | 1 sparseMatrixUInt8, 2 sparseMatrixUInt16, 3 sparseMatrixFloat16, 4 sparseMatrixFloat32 |
| tintArray | … | N tints of M samples each, stored tint by tint (sample j of tint i at index i·M + j), in any numeric array type; used by the tintArrayElement and the namedColorStructure |
| azimuthNumber | 4 | A float: 0.0 is −180° and 1.0 is +180°, an azimuth angle input to the BRDF and directional tags |
| zenithNumber | 4 | A float: 0.0 is 0° and 1.0 is 90°, a zenith angle from the surface normal |
| horizontalNumber | 4 | A float: −1.0 the leftmost, 0.0 the centre, 1.0 the rightmost position of the viewing field (directional tags) |
| verticalNumber | 4 | A float: −1.0 the top, 0.0 the centre, 1.0 the bottom of the viewing field (directional tags) |
The BRDF and directional tags take these numbers as extra inputs to their multiProcessElementsType. The
BRDF transforms of a namedColorStructure (bcol, bspc) take five inputs, in this
order (ICC.2 Table 138): viewing azimuth Φr, viewing zenith θr, lighting azimuth Φi, lighting zenith θi,
then the tint.
Arrays and text
fl16 float16ArrayType, fl32 float32ArrayType, fl64 float64ArrayType
From byte 8, floating-point numbers of 2, 4 or 8 bytes, as many as the tag’s size allows.
utf8 utf8Type and ut16 utf16Type
From byte 8 to the end, UTF-8 text, or UTF-16 text in 16-bit big-endian units.
zut8 utf8ZipType and zxml (or ZXML) zipXmlType
From byte 8 to the end, a zlib stream (RFC 1950, Deflate) that inflates to UTF-8 text, or to XML. The explorer inflates and shows it.
meas measurementType in iccMAX
iccMAX keeps the ICC.1 layout (measurementType) and extends it (ICC.2 10.2.15). The standard illuminant may also be 9 black body defined by the colour temperature, 10 daylight defined by the colour temperature, 11 B, 12 C, 13 F1, 14 F3, 15 F4, 16 F5, 17 F6, 18 F7, 19 F9, 20 F10, 21 F11 or 22 F12, and 0 means custom. Bytes 36 to 39, when the tag is 40 bytes long, hold the ISO 13655 measurement condition: 0 unknown, 1 M0, 2 M1, 3 M2, 4 M3; a 36-byte tag means unknown.
The two parts of ICC.2 disagree on whether the tag itself belongs in a version 5 profile. Clause
10.2.15 calls the type “a backwards compatible extension of ISO 15076‐1 with the same tag
signature” (meas), but clause 9’s tag list has no measurementTag. The explorer decodes the tag and notes that it is not in ICC.2’s
tag list, rather than calling it invalid.
tstr tagStructType
A structure of named members, each a whole typed element.
| Offset | Size | Field |
|---|---|---|
| 8 | 4 | Structure type identifier |
| 12 | 4 | Number of members N |
| 16 | 12N | For each member: its signature, then a positionNumber (offset from the start of the structure, and size) |
| 16 + 12N | … | The members, each starting on a 4-byte boundary; members may share data |
Member signatures are unique within a structure. Clause 10.2.23 calls the structure element
type tags where Table 73 gives tstr; the explorer reads both.
The structures and their members
Each member is a whole typed element of the type given (“float32 array” means a float32ArrayType, and so on).
| Structure | Member | Holds | Type |
|---|---|---|---|
brdf brdfTransformStructure | type | BRDF type: mono monochrome parameters, colr parameters for each PCS channel | signature |
func | BRDF function (below) | signature | |
nprm | Parameters per channel; must match the function | uInt16 | |
xfrm | Device values to BRDF parameters | multiProcessElementsType | |
cinf colorantInfoStructure | name | Colorant name | utf8 |
lcnm | Localised name | mluc | |
pcs | PCS value | uInt8, uInt16, float16 or float32 array | |
spec | Spectral data | uInt8, uInt16, float16 or float32 array | |
cept colorEncodingParamsStructure | rXYZ gXYZ bXYZ | Red, green and blue primaries | float32 array |
func | Transfer function | segmented curve | |
lmat | Luma and chroma matrix | float32 array | |
wlum | White point luminance | float32 | |
wXYZ | White point chromaticity | float32 array | |
eRng | Encoding range | float32 array | |
bits | Bit depth | uInt8 array | |
imst | Image state: scoe, sape, fpce, rhoc, rpoc as in the ciisTag, or dorc display output referred colorimetry | signature | |
ibkg | Image background | float32 | |
srnd | Viewing surround | float32 | |
ailm | Ambient illuminance | float32 | |
awlm | Ambient white point luminance | float32 | |
awpc | Ambient white point chromaticity | float32 array | |
flar | Viewing flare | float32 | |
lrng | Valid relative luminance range | float32 array | |
mwpl | Medium white point luminance | float32 | |
mwpc | Medium white point chromaticity | float32 array | |
mbpl | Medium black point luminance | float32 | |
mbpc | Medium black point chromaticity | float32 array | |
meas measurementInfoStructure | mbak | Backing: 0 undefined, 1 white, 2 black, 3 media (self) | uInt32 |
mflr | Flare | float32 | |
mgeo | Geometry: 0 unknown, 1 0°:45° or 45°:0°, 2 0°:d or d:0° | uInt32 | |
mill | Illuminant spectral power distribution, one value for each miwr step. Clause 12.2.4.2.4 also has a “Permitted tag types: uInt32Number” line, but Table 133 and the clause’s own text both describe an array | float16 or float32 array | |
miwr | Wavelengths of the mill SPD: start, end and number of steps; required when mill is present, and its steps must equal the number of mill values. ICC.2 names no element type that holds a bare spectralRange, so the explorer reads a three-value number array | spectralRange | |
mmod | Mode: 0 undefined, 1 M0 (default, tungsten), 2 M1 (D50), 3 M2 (UV cut), 4 M3 (polarising filter) | uInt32 | |
nmcl namedColorStructure | name, lcnm | Name and localised name | utf8, mluc |
dev | Device data | uInt8, uInt16, float16 or float32 array | |
pcs | PCS data | uInt8, uInt16, float16 or float32 array | |
spec | Spectral data | numeric array | |
spcb, spcg | Spectral data over black and over grey | numeric arrays | |
tint | Tint values (a tintArray) | uInt8, uInt16 or float32 array | |
nmap | Normal map | embeddedNormalImageType | |
bcol, bspc | BRDF colorimetric and spectral transforms (five inputs, Table 138) | multiProcessElementsType | |
bcpr, bspr | BRDF colorimetric and spectral parameters | brdfTransformStructure | |
pcc pccStructure | c2sp | Custom to standard transform | multiProcessElementsType |
s2cp | Standard to custom transform | multiProcessElementsType | |
iXYZ | Illuminant | XYZ | |
mwpt | Media white point | XYZ | |
svcn | Spectral viewing conditions | spectralViewingConditionsType | |
pinf profileInfoStructure | attr | Device attributes, as in the header | uInt64 |
pdsc | Profile description | mluc | |
pid | Profile ID | uInt8 array of 16 | |
dmns, dmnd | Manufacturer signature and description | signature, mluc | |
mod , dmdd | Model signature and description | signature, mluc | |
rtrn | Rendering intent used: 0 perceptual, 1 media-relative colorimetric, 2 saturation, 3 ICC-absolute colorimetric | uInt32 | |
tech | Technology, as in the technologyTag | signature | |
tnt0 tintZeroStructure | dev | Device data of a zero tint | numeric array |
pcs | PCS data of a zero tint | numeric array | |
spec | Spectral data of a zero tint | numeric array | |
spcb | Spectral data over black | numeric array | |
spcg | Spectral data over grey | numeric array |
BRDF functions (ICC.2 Table 129), with the number of parameters each takes:
| Signature | Function | Parameters |
|---|---|---|
BPh0 | Blinn-Phong, monochrome parameters | 4 |
BPh1 | Blinn-Phong, full colour parameters | 3 |
CT10 CT20 CT30 | Cook-Torrance with 1, 2 or 3 lobes, monochrome | 6, 9, 11 |
CT11 CT21 CT31 | Cook-Torrance with 1, 2 or 3 lobes, full colour | 5, 8, 10 |
War0 War1 | Ward, monochrome and full colour | 5, 4 |
La10 La20 La30 | Lafortune with 1, 2 or 3 lobes, monochrome | 9, 16, 23 |
La11 La21 La31 | Lafortune with 1, 2 or 3 lobes, chromatic | 5, 9, 13 |
In a colorEncodingParamsStructure the members override the defaults that the reference name
implies; in a profileInfoStructure a missing member takes its default (zero, or an empty
description). The explorer names every member and code value, and checks that nprm
matches the function.
tary tagArrayType
| Offset | Size | Field |
|---|---|---|
| 8 | 4 | Array type identifier |
| 12 | 4 | Number of elements N |
| 16 | 8N | A positionNumber for each element, from the start of the array |
| 16 + 8N | … | The elements, all of one type, on 4-byte boundaries; they may share data |
| Identifier | Array |
|---|---|
ncol | namedColorArray: a tintZeroStructure, then a namedColorStructure for each colour (the iccMAX namedColorTag) |
pinf | profileInfoArray: a profileInfoStructure for each profile in a sequence, source first (profileSequenceInformationTag) |
tags | tagStructArray: tagStructTypes all of one structure type (clause 13 prints its hex as 74606773h, a misprint of 74616773h) |
cinf | Colorant information: a colorantInfoStructure for each colorant, in channel order (colorantInfoTag and colorantInfoOutTag) |
mcta | Multiplex type array: a utf8Type naming each multiplex channel (multiplexTypeArrayTag) |
smat sparseMatrixArrayType
Bytes 8 to 9 the number of equivalent output channels Q, 10 to 11 the sparseMatrixEncodingType, 12 to 15 the number of matrices N, then the N matrices, all of the same rows and columns. A sparse matrix is stored in compressed row order:
| Offset | Size | Field |
|---|---|---|
| 0 | 2 | Rows R |
| 2 | 2 | Columns C |
| 4 | 2R | Where each row’s entries start in the arrays below (not decreasing) |
| 4 + 2R | 2 | Number of stored entries N |
| 6 + 2R | 2N | The column of each entry, increasing within a row |
| … | … | Zero padding to a 4-byte boundary |
| O | N × size | The values: uInt8 or uInt16 for 0.0 to 1.0, float16 or float32 |
| … | … | Zero padding to a 4-byte boundary |
“Compact padding” places the values and the end of each matrix on 4-byte boundaries. A CMM may instead use fixed-size blocks internally; the specification gives the formulas for the largest number of entries such a block holds.
svcn spectralViewingConditionsType
| Offset | Size | Field |
|---|---|---|
| 8 | 4 | Observer: 0 custom, 1 CIE 1931, 2 CIE 1964 |
| 12 | 6 | The observer’s spectralRange (N steps) |
| 18 | 2 | Reserved, zero |
| 20 | 12N | The colour matching functions: x̄, then ȳ, then z̄ (float32) |
| 20 + 12N | 4 | Illuminant type (below) |
| 24 + 12N | 4 | (Correlated) colour temperature, float32 |
| 28 + 12N | 6 | The illuminant’s spectralRange (M steps) |
| 34 + 12N | 2 | Reserved, zero |
| 36 + 12N | 4M | The illuminant’s spectral power (float32) |
| 36 + 12N + 4M | 12 | Un-normalised XYZ of the illuminant, Y in cd/m² |
| 48 + 12N + 4M | 12 | Un-normalised XYZ of the surround, Y in cd/m² |
Illuminant types: 0 custom, 1 D50, 2 D65, 3 D93, 4 F2, 5 D55, 6 A, 7 equi-power (E), 8 F8, 9 black body defined by the colour temperature, 10 daylight defined by the colour temperature, 11 B, 12 C, 13 F1, 14 F3, 15 F4, 16 F5, 17 F6, 18 F7, 19 F9, 20 F10, 21 F11, 22 F12. When a standard observer has 0 steps, 380 to 780 nm in 81 steps and the CIE tables printed in the specification are assumed; the same for a tabulated illuminant with 0 steps. For luminous colours the illuminant fields hold the white emission spectrum instead.
gbd gamutBoundaryDescriptionType
| Offset | Size | Field |
|---|---|---|
| 8 | 2 | PCS channels P (three or more) |
| 10 | 2 | Device channels Q (or 0) |
| 12 | 4 | Vertices V (four or more) |
| 16 | 4 | Faces F (four or more) |
| 20 | 12F | Three vertex IDs (uInt32, 0 to V − 1) for each triangular face, clockwise from outside |
| 20 + 12F | 4VP | The PCS value of each vertex, float32 |
| 20 + 12F + 4VP | 4VQ | The device value of each vertex, float32 |
The faces should enclose a volume; Euler’s formula (V − E + F = 2) checks it, and the explorer does.
ehim embeddedHeightImageType and enim embeddedNormalImageType
Bytes 8 to 11: 1 if the image tiles without seams. 12 to 15: the image format, 0 PNG or 1 TIFF. A height image then has the heights in metres of the minimum and maximum pixel values (float32, bytes 16 and 20) and its data from byte 24; a normal image has its data from byte 16. The image is a whole PNG or TIFF file: greyscale heights, or RGB normals with red and green mapping to −1.0 to 1.0 for X and Y and blue to 0.0 to 1.0 for Z. Its physical size comes from the image file (pHYs, or the TIFF resolution tags). The explorer offers the image as a file to open.
Processing elements
Every element starts with its signature, four bytes that are reserved (for clut,
xclt, eclt and rclt, three reserved bytes and an interpolationHintType
in byte 7; in ICC.1 the clut element’s four bytes are all reserved), the number of
inputs P and outputs Q. Offsets inside an element count from its start.
calc calculatorElement
| Offset | Size | Field |
|---|---|---|
| 12 | 2 | Reserved, zero |
| 14 | 2 | Number of sub-elements E |
| 16 | 8 | Position of the main function |
| 24 | 8E | Positions of the sub-elements (any processing elements, shared or not overlapping) |
| 24 + 8E | 28 | Optional limits: clmt, 4 reserved bytes, maximum stack size, maximum temporary channels, maximum operations (0 for no limit), 8 reserved bytes |
| … | … | The main function and the sub-elements, with no gaps but alignment padding |
The main function is func, 4 reserved bytes, the number of operations, then the
operations, 8 bytes each: a signature and 4 bytes of data. They run in reverse Polish order on a stack
of float32 values, with input, output and temporary channels (up to 65535 each; temporaries start at
zero). The data depends on the kind of operation:
| Kind | Data | Operations |
|---|---|---|
| Constant | float32 | data push the value |
| Channel | start S, extra count T (uInt16 each) | in push inputs S to S+T; out pop into outputs; tget push temporaries; tput pop into temporaries; tsav copy into temporaries leaving the stack |
| Environment | a signature | env push a CMM environment variable and 1 if supported (or 0, 0); true and ndef always answer 1, 1 and 0, 0 |
| Sub-element | index S, 2 reserved bytes | curv mtx clut calc tint tJab fJab apply sub-element S of that kind; elem of any kind |
| Stack | S, T | copy duplicate the top S+1 values T+1 times; rotl rotr rotate them; posd duplicate the value S down; flip reverse; pop remove |
| Matrix | last row S, last column T | solv solve y = Ax (pushes x and 1 on success, zeros and 0 on failure); tran transpose |
| Sequence | extra count S | sum prod min max of S+2 values; and or (true is ≥ 0.5) |
| Function | last index S | noop scnt pi +INF -INF NaN; add sub mul div mod pow on vectors of S+1; gama sadd ssub smul sdiv with a scalar; sq sqrt cb cbrt abs neg rond flor ceil trnc exp log ln not sin cos tan asin acos atan atn2 ctop ptoc rnum; comparisons lt le eq near ge gt; vmin vmax vand vor vxor; tLab tXYZ |
| Conditional | number of operations (uInt32) | if runs its operations when the popped value is ≥ 0.5 or NaN, else the immediately following else’s; sel pops a value, rounds it and runs that case, or dflt when out of range. The if/else and sel/case/dflt headers come first, then their operation streams in order |
Before running, a CMM checks every operation, channel index and stack depth. The explorer lists the program, names every operation and checks that sub-element indices exist.
Curve sets: segment formulas, sngf and clcf
In a segmented curve (curf) iccMAX adds five formula types to the three of ICC.1 (ICC.2
Table 111). The parameters are float32Numbers in the order listed:
| Type | Parameters | Function |
|---|---|---|
| 0 | γ, a, b, c | Y = (aX + b)γ + c |
| 1 | γ, a, b, c, d | Y = a·log10(b·Xγ + c) + d |
| 2 | a, b, c, d, e | Y = a·bcX + d + e |
| 3 | γ, a, b, c, d | Y = a·(bX + c)γ + d |
| 4 | γ, a, b, c, d | Y = a·ln(d·Xγ − b) + c |
| 5 | γ, a, b, c, d, e | Y = e·exp((d·Xγ − c)/a) + b |
| 6 | ω, γ, a, b, c, d, e | Y = d·(max(e·Xγ − a, 0)/(b − c·Xγ))ω |
| 7 | ω, γ, a, b, c, d | Y = d·((a + b·Xγ)/(1 + c·Xγ))ω |
Table 111 gives type 6 a field length of 24 bytes but lists seven parameters (28 bytes); the explorer reads the seven parameters listed. Types 3 to 7 are not in ICC.1, where only 0 to 2 are allowed.
A cvst curve may also be a single sampled curve or a sampled calculator curve:
sngf: 4 reserved bytes, the number of samples N (at least 2), the inputs of the first and last samples F and L (float32, F < L), the extension outside F to L (0 clip, 1 extrapolate from the end samples), a valueEncodingType (uInt16), then the samples, interpolated linearly.clcf: 4 reserved bytes, the recommended number of samples R (at least 2), the start S and end E (float32), the extension type (uInt16), 2 reserved bytes, then a calculatorElement of one input and one output, sampled R times from S to E to fill a table.
xclt extendedCLUTElement
A valueEncodingType (uInt32, byte 12), 16 bytes of grid sizes (P used, 1 to 16 inputs), then the grid, each point Q values in that encoding.
eclt emissionCLUTElement and rclt reflectanceCLUTElement
A CLUT whose grid points are spectra, converted to colorimetry with the observer of the profile
connection conditions before interpolating; Q is 3. eclt: a spectralRange (S steps), a
valueEncodingType (uInt16), 16 grid sizes, the grid of S values a point, then the white emission
spectrum. rclt: flags (4 bytes), then the same fields with reflectance spectra and the
white reflectance, normalised for relative colorimetry.
emtx emissionMatrixElement and iemx inverseEmissionMatrixElement
A spectralRange (S steps), an absolute flag (reserved in iemx), the white emission
spectrum (S float32), then one emission spectrum for each primary and one for the offset, S float32
each. The spectra are turned into a 3 × 3 matrix and offset with the observer; iemx
applies the inverse.
eobs emissionObserverElement and robs reflectanceObserverElement
A spectralRange, an absolute flag and the white spectrum: they turn emission or reflectance spectra arriving on the inputs into XYZ (Q is 3).
smet sparseMatrixElement
A sparseMatrixEncodingType (uInt16), 2 reserved bytes, 16 grid sizes, then a sparse matrix (in the layout above) for each grid point; Q is the number of equivalent outputs.
tint tintArrayElement
One input. A valueEncodingType (uInt32), 4 reserved bytes, then the tint array: Q values for each of at least two tints, evenly spaced from 0.0 to 1.0, interpolated linearly and clipped outside.
tmap toneMapElement
Q is P − 1. The position of the luminance curve (a sngf, clcf or
curf) applied to the last input, then Q positions of mapping functions:
mapf, 4 reserved bytes, a function type (uInt16, 0 is Y = a·M·(X + b) + c with M the mapped
luminance), 2 reserved bytes and its float32 parameters.
JtoX JabToXYZElement and XtoJ XYZToJabElement
Colour appearance conversions with eight float32 viewing parameters: the white point X, Y, Z, the luminance (cd/m²), the background luminance (cd/m²), the impact of the surround (0.0 to 1.0), the chromatic induction factor and the adaptation factor.