IccColorTransform Class

An ICC color conversion from the device color space of a source profile to the device color space of a destination profile. Instances are immutable and thread-safe: create a transform once and reuse it.

public sealed class IccColorTransform

Remarks

Supported profiles are ICC version 2 and version 4 input, display, output and color space profiles whose data color space is grayscale, RGB or CMYK, based on a matrix and tone curves or on lookup tables. A destination profile must describe the conversion from the profile connection space, which input profiles often do not. Device link and abstract profiles are supported in a sequence of profiles (IccColorTransform.Create).

Samples are interleaved device values without alpha: one sample per color for grayscale, three (red, green, blue) for RGB, four (cyan, magenta, yellow, black) for CMYK, where the smallest sample value is no light or no ink and the largest value is full light or full ink. Integer samples cover the whole range of their type; floating-point samples are in [0, 1]. Colors that the destination cannot represent are clipped per channel, unless IccColorTransformOptions.GamutMapping maps them into its gamut.

The rendering intent (IccColorTransformOptions.Intent) selects the conversion of each profile, from its device values to the profile connection space and back: IccRenderingIntent.Perceptual and IccRenderingIntent.Saturation use the tables a profile has for them, which map its gamut as its author chose; IccRenderingIntent.RelativeColorimetric keeps the colors relative to the media white; IccRenderingIntent.AbsoluteColorimetric keeps them relative to the illuminant. A sequence of profiles (IccColorTransform.Create) adds device link and abstract profiles.

When the two profiles have identical bytes, the samples are copied unchanged.

Properties

NameDescription
DestinationChannelCountGets the number of samples per destination color: 1 (grayscale), 3 (RGB) or 4 (CMYK).
SourceChannelCountGets the number of samples per source color: 1 (grayscale), 3 (RGB) or 4 (CMYK).

DestinationChannelCount

IccColorTransform.cs

Gets the number of samples per destination color: 1 (grayscale), 3 (RGB) or 4 (CMYK).

public int DestinationChannelCount { get; }

Property value

int

SourceChannelCount

IccColorTransform.cs

Gets the number of samples per source color: 1 (grayscale), 3 (RGB) or 4 (CMYK).

public int SourceChannelCount { get; }

Property value

int

Methods

NameDescription
Convert(ReadOnlySpan<byte>, Span<byte>)Converts 8-bit samples.
Convert(ReadOnlySpan<float>, Span<float>)Converts floating-point samples in [0, 1], or of any value when the transform does not clip them.
Convert(ReadOnlySpan<ushort>, Span<ushort>)Converts 16-bit samples.
Create(IccProfile, IccProfile, IccColorTransformOptions?)Creates the conversion from a source profile to a destination profile.
Create(IReadOnlyList<IccProfile>, IccColorTransformOptions?)Creates the conversion through a sequence of profiles: device profiles (input, display, output and color space profiles), device link profiles and abstract profiles, in the order the colors go through them.

Convert overloads

Convert(ReadOnlySpan<byte>, Span<byte>)

IccColorTransform.cs

Converts 8-bit samples.

public void Convert(ReadOnlySpan<byte> source, Span<byte> destination)
Parameters
source ReadOnlySpan<byte>
The source samples: a whole number of colors of IccColorTransform.SourceChannelCount samples.
destination Span<byte>
The converted samples: exactly IccColorTransform.DestinationChannelCount samples per source color. It may be the same memory as source when both profiles have the same number of channels.
Exceptions
ArgumentException
The length of source is not a multiple of IccColorTransform.SourceChannelCount, the length of destination does not match, or the spans overlap without being the same memory.

Convert(ReadOnlySpan<float>, Span<float>)

IccColorTransform.cs

Converts floating-point samples in [0, 1], or of any value when the transform does not clip them.

public void Convert(ReadOnlySpan<float> source, Span<float> destination)
Parameters
source ReadOnlySpan<float>
The source samples: a whole number of colors of IccColorTransform.SourceChannelCount samples. Values outside [0, 1] are clipped, unless IccColorTransformOptions.ClipFloatingPointSamples was false, and values that are not a number are read as 0.
destination Span<float>
The converted samples, in [0, 1] unless IccColorTransformOptions.ClipFloatingPointSamples was false: exactly IccColorTransform.DestinationChannelCount samples per source color. It may be the same memory as source when both profiles have the same number of channels.
Exceptions
ArgumentException
The length of source is not a multiple of IccColorTransform.SourceChannelCount, the length of destination does not match, or the spans overlap without being the same memory.

Convert(ReadOnlySpan<ushort>, Span<ushort>)

IccColorTransform.cs

Converts 16-bit samples.

public void Convert(ReadOnlySpan<ushort> source, Span<ushort> destination)
Parameters
source ReadOnlySpan<ushort>
The source samples: a whole number of colors of IccColorTransform.SourceChannelCount samples.
destination Span<ushort>
The converted samples: exactly IccColorTransform.DestinationChannelCount samples per source color. It may be the same memory as source when both profiles have the same number of channels.
Exceptions
ArgumentException
The length of source is not a multiple of IccColorTransform.SourceChannelCount, the length of destination does not match, or the spans overlap without being the same memory.

Create overloads

Create(IccProfile, IccProfile, IccColorTransformOptions?)

IccColorTransform.cs

Creates the conversion from a source profile to a destination profile.

public static IccColorTransform Create(IccProfile source, IccProfile destination, IccColorTransformOptions? options = null)
Parameters
source IccProfile
The profile describing the source samples.
destination IccProfile
The profile describing the converted samples.
options IccColorTransformOptions?
The options, or null for IccColorTransformOptions.Default.
Returns

IccColorTransform The transform.

Exceptions
ArgumentNullException
source or destination is null.
InvalidImageContentException
A profile is malformed.
UnsupportedImageFeatureException
A profile is valid but not supported, or cannot be used as a destination; or IccColorTransformOptions.ClipFloatingPointSamples is false and the conversion goes through a lookup table or a gamut mapping.

Create(IReadOnlyList<IccProfile>, IccColorTransformOptions?)

IccColorTransform.cs

Creates the conversion through a sequence of profiles: device profiles (input, display, output and color space profiles), device link profiles and abstract profiles, in the order the colors go through them.

public static IccColorTransform Create(IReadOnlyList<IccProfile> profiles, IccColorTransformOptions? options = null)
Parameters
profiles IReadOnlyList<IccProfile>
The profiles, at least one; the first one describes the source samples and the last one the converted samples.
options IccColorTransformOptions?
The options, or null for IccColorTransformOptions.Default.
Returns

IccColorTransform The transform.

Exceptions
ArgumentNullException
profiles or one of its profiles is null.
ArgumentException
profiles is empty.
InvalidImageContentException
A profile is malformed.
UnsupportedImageFeatureException
A profile is valid but not supported, or the sequence does not connect: an abstract profile entered with device values, a device link profile entered from the connection space or with device values of another color space, or a sequence that ends in the connection space; or IccColorTransformOptions.ClipFloatingPointSamples is false and the conversion goes through a lookup table or a gamut mapping.
Remarks

The samples are device values of the first profile and the converted samples device values of the last one. A device profile entered with device values converts them to the profile connection space, and a device profile entered from the connection space converts the colors to its device values. To go through the device values of a profile in the middle, the profile appears twice: display, printer, printer, display previews a print on the display (a soft proof), with the colors the printer can reproduce. A device link profile converts the device values of its input color space to those of its output color space with its AToB0 table, whatever the rendering intent (it was chosen when the link was made). An abstract profile converts colors of the connection space with its AToB0 table, between two device profiles.

The options apply where the colors cross the connection space. There, the abstract profiles convert colors relative to the media white of the device profile before them, after its black point compensation, or ICC-absolute colors (relative to the illuminant of the connection space) with IccRenderingIntent.AbsoluteColorimetric. A sequence of two device profiles is the same conversion as IccColorTransform.Create, which copies the samples unchanged when the two profiles have identical bytes; a longer sequence never does.

Example
public static ushort[] SoftProof(IccProfile display, IccProfile printer, ReadOnlySpan<ushort> rgb)
{
    // The printer profile appears twice: the colors enter it from the profile connection space to become inks, then
    // leave it as the colors of these inks. The colors the printer cannot reproduce lose chroma at constant
    // lightness and hue, instead of being clipped channel by channel.
    var proof = IccColorTransform.Create([display, printer, printer, display], new IccColorTransformOptions
    {
        Intent = IccRenderingIntent.RelativeColorimetric,
        GamutMapping = GamutMapping.ReduceChroma,
    });

    // A transform is immutable and thread-safe: create it once and reuse it
    var preview = new ushort[rgb.Length];
    proof.Convert(rgb, preview);
    return preview;
}