ICC's D50 vs sRGB D65 problems

I had to check, so I ran dcraw against one of my files like this:

dcraw -T -4 DSG_3111.NEF

Which defaults to spitting out the TIFF as sRGB, with sRGB (2.4, IIRC) gamma. Here’s the [ICC_PROFILE] output from:

exiftool -G DSG_3111.tiff

[ICC_Profile]   Profile CMM Type                : 
[ICC_Profile]   Profile Version                 : 2.1.0
[ICC_Profile]   Profile Class                   : Display Device Profile
[ICC_Profile]   Color Space Data                : RGB
[ICC_Profile]   Profile Connection Space        : XYZ
[ICC_Profile]   Profile Date Time               : 0000:00:00 00:00:00
[ICC_Profile]   Profile File Signature          : acsp
[ICC_Profile]   Primary Platform                : Unknown ()
[ICC_Profile]   CMM Flags                       : Not Embedded, Independent
[ICC_Profile]   Device Manufacturer             : none
[ICC_Profile]   Device Model                    : 
[ICC_Profile]   Device Attributes               : Reflective, Glossy, Positive, Color
[ICC_Profile]   Rendering Intent                : Perceptual
[ICC_Profile]   Connection Space Illuminant     : 0.9642 1 0.82491
[ICC_Profile]   Profile Creator                 : 
[ICC_Profile]   Profile ID                      : 0
[ICC_Profile]   Profile Copyright               : auto-generated by dcraw
[ICC_Profile]   Profile Description             : sRGB
[ICC_Profile]   Media White Point               : 0.95045 1 1.08905
[ICC_Profile]   Media Black Point               : 0 0 0
[ICC_Profile]   Red Tone Reproduction Curve     : (Binary data 14 bytes, use -b option to extract)
[ICC_Profile]   Green Tone Reproduction Curve   : (Binary data 14 bytes, use -b option to extract)
[ICC_Profile]   Blue Tone Reproduction Curve    : (Binary data 14 bytes, use -b option to extract)
[ICC_Profile]   Red Matrix Column               : 0.43608 0.2225 0.01393
[ICC_Profile]   Green Matrix Column             : 0.38509 0.71689 0.09709
[ICC_Profile]   Blue Matrix Column              : 0.14305 0.06061 0.71402

The Media White Point, 0.95045 1.0, 1.08905, is what @Elle uses in her profile generation code as the D65 media white point:

Hmm, I’m scratching my head. Possibly dcraw is confused about what type of profile it is creating?

Exiftool says this about the ICC profile that dcraw embeds in my tiff:

[ICC_Profile]   Profile Class                   : Display Device Profile
[ICC_Profile]   Color Space Data                : RGB
[ICC_Profile]   Profile Connection Space        : XYZ
:
[ICC_Profile]   Connection Space Illuminant     : 0.9642 1 0.82491
[ICC_Profile]   Profile Description             : sRGB
[ICC_Profile]   Media White Point               : 0.95045 1 1.08905

ICC (http://color.org/specification/ICC1v43_2010-12.pdf) says:

So this is a display profile, so the media white point should be the same as the Profile Connection Space Illuminant. But it isn’t. I don’t know why.

Perhaps LCMS ignores the Media White Point. Certainly, when I use ImageMagick to use LCMS to give the chromaticities, I get the numbers in my previous post, D50.

@Elle has an article that talks about that, too, relevant to the white point:

I think the embedded profile is correctly classed, because the destination of the output image is nominally a display. The input profile was used internally by dcraw, as the camera profile created from the adobe_coeff lookup. The image was transformed from camera space to sRGB using the

adobe_coeff profile -> XYZ -> sRGB,

just like any regular transform.

There may be a bug in the way I’m getting my numbers. I’ll work on that. But it’s snowing outside, and well past my bedtime. G’night all.

I haven’t read @Elle’s articles in a while so I don’t remember where the relevant info is. Try reading Programmer's Guide to XYZ, RGB. There is also a place where she includes ODS and XLS files that show her calculations but I forgot where.

PS sRGB color space to profile might be helpful but I still can’t find the spreadsheets…

PPS I changed the category and added a tag.

Yes and No. It’s absolute in a chromaticity sense, but is often used as a relative space in terms of luminance (i.e. XYZ measurements may be scaled to some reference having Y = 100). In some contexts it may be a percentage of reflectance or transmittance. In other context it may be a percentage of a devices white luminance.

Yes and No. If a display is adjusted to conform to the sRGB specification, then yes, it will have a D65 white point. But an sRGB ICC profile is not the sRGB colorspace, it is a profile representing sRGB response in the ICC prescribed manner. And this means that its native model of how the profile behaves is as if its white has been chromatically adapted to the ICC profile connection space (PCS) D50 white point.

Now if you use a suitably constructed ICCV2 profile in absolute colorimetric intent mode, you should get the native display sRGB colorspace response D65 values. But if you try this with an ICCV4 sRGB profile with most CMMs, you will get a D50 white point, because the V4 spec. disabled absolute colorimetric intent for display profiles.

(ArgyllCMS is an exception, since it will reverse the ICCV4 display profile ‘chad’ tag in absolute colorimetric mode, restoring absolute colorimetric intent behavior for these profiles.)

2 Likes

Hmm, sorry, for now I’ll have to say: I don’t fully understand ICC profiles.

However, I’ll make a couple of observations:

  1. An ICC profile contains instructions for converting between a colorspace and the connection space which is either XYZ or LAB, in principle in either direction. So it may have two different whitepoints: one for the colorspace, the other for the connection space. In ICC v2 and v4, the connection space WP is always D50, so the tag is technically redundant. (But ICCmax allows other connection space WPs.) However, the colorspace WP doesn’t need to be D50.

  2. dcraw embeds an sRGB profile with these primaries:

    <XYZType>
      <TagSignature>rXYZ</TagSignature>
      <XYZNumber X="0.43608093" Y="0.22250366" Z="0.01393127"/>
    </XYZType>
    <XYZType>
      <TagSignature>gXYZ</TagSignature>
      <XYZNumber X="0.38508606" Y="0.71688843" Z="0.09709167"/>
    </XYZType>
    <XYZType>
      <TagSignature>bXYZ</TagSignature>
      <XYZNumber X="0.14305115" Y="0.06060791" Z="0.71401978"/>
    </XYZType>

Using the formulae…

x = X / (X+Y+Z)
y = Y / (X+Y+Z)

… we can easily calculate the chromaticies (x,y) of the primaries to 6 decimal places…

red = (0.648432, 0.330853)
green = (0.321155, 0.597872)
blue = (0.155884, 0.066045)

These are the sRGB standard primaries, chromatically adapted from D65 to D50. But if the primaries are D50, how come the media white point is D65? I don’t know.

I fear that to understand ICC profiles, I need to play with LCMS. I don’t currently have time.

Neither XYZ nor sRGB for a D65 monitor need D50, nor do you need D50 to describe how to convert sRGB D65 to XYZ.

What is the reason why ICC involves D50 in here anyway, and why does ICC’s design not allow you to give chromaticities in the whitepoint you want (you can give a whitepoint with the wtpt tag, so why does it not treat the rXYZ, gXYZ and bXYZ compared to that one?), or better, just the 3x3 matrix values to convert between the RGB and XYZ values?

To repeat very clearly:

If neither your RGB model nor XYZ use D50, why is the design of ICC forcing you to involve D50 and Bradford adaptions anyway while this is not necessary?

Maybe I am missing some extra layer, what required this extra complexity?

And asked from a different angle:

AFAIK the only thing you need the rXYZ, gXYZ, bXYZ chromaticities for, is for converting the RGB to XYZ. Yet converting RGB to XYZ is simpler when not involving an additional whitepoint. So why is it involved at all? Don’t you know everything once you know how to convert to XYZ, and simplest would be best (less numerical precesion errors, less confusion and wrongly made profiles, …)?

Because the intention of ICC profiles is to provide conversions from one device space to another, and 99.9% of the time, people want white on one device to be white on the other.

The way this is done is to either measure the devices with a D50 illuminant (print, transparency), or chromatically transform the device white to D50 (the Profile Connection Space white). This naturally gives you an overall transform (Device → PCS → Device) that is Relative Colorimetric intent.

2 Likes

XYZ on its own is not sufficient to describe the appearance of a colour. You also need to know the conditions under which it is viewed (surrounding colour, illumination etc.).

In a typical colour management workflow, you have to deal with many different white points and viewing conditions. Rather than having specific conversions between each pair of devices in a system (which results in a LOT of possible transforms), ICC colour management uses a common Profile Connection Space (PCS) as the target for ICC profiles. That way, each ICC profile converts from a device colourspace to the PCS (or the other way around). You can build colour transforms by plugging profiles together using the PCS as a common intermediate space. The ICC PCS just happens to be D50 based.

Conversion between device white points and the PCS whitepoint is handled in the profiles. There is some extra complexity in putting the profile together to account for viewing conditions, but using the profiles is simplified.

The full explanation of the reasons for a D50 whitepoint in Display profiles is on the ICC website here:
Why is the media point of a display profile always D50?

Quote from the book by Charles Poynton (2012, page 272):
“Tristimulus values are computed from a continuous spectral power distribution (SPD) by integrating the SPD under the colour matching functions.”

This is also detailed on Bruce Lindbloom’s math-page “Computing XYZ From Spectral Data”.

One SPD is D50, another is D65, so both will give different XYZ values according to this.

Hermann-Josef

Its slightly different for measurement of self-luminous sources (e.g. a display) vs. reflective samples (e.g. a print). For the display, the SPD is whatever light comes out of the screen*, there is no separate illuminant involved. For the reflective print, the SPD is the product of the reflectance spectrum of the print and the illuminant (D65, D50 etc.).

*ignoring any ambient light reflected from the surface of the display, which you usually try to minimise.

The notion of a “common ground” intermediary is replete through resilient architectures. Network byte order, for instance, helps to keep the endians straight between computers without everyone maintaining a big table of architectures’ endians.

XYZ/D50 forms that common ground in ICC profile-based color management. Cameras don’t have to know about display characteristics including white point, and vice versa. And, more fundamentally, you need both primaries and a white point to transform color image data from one color space to another.

Network byte order

Since at least the 80s computers used little endian instead, why is big endian still being used in standards…

Take that question to a networking forum. I was using network order as an example of a “connection space”, where the endpoints didn’t need to know each other’s specifics. That’s what XYZ/D50 is to ICC profile-based color management. And again, you do need both primaries and a white point to do the transform math.

Thanks all for the patient explanations by the way!

Recently, I’ve been messing with baking white balance into my camera profiles. By way of background, most tutorials about making camera profiles tells you to shoot the target, then develop it to a TIFF including white balance correction. Based on recent discussions here, I decided to try making target TIFFs without white balance correction, and let the conversion from camera space to a working space like Rec2020 also handle the chromatic adaptation from camera white to the working profile’s white point. For grins, here’s the XYZ media white point of such a camera profile:

[ICC_Profile] Media White Point : 4.89584 5.11565 4.00757

The color management library I’m using in my programs, LittleCMS, does the chromatic adaptation from that wild triplet to the destination’s white point, then it does the color transform. Sounds weird, but it does work.

Thing is, XZY/D50 as the intermediary keeps me from having to develop a different camera profile for every destination space. Not so bad for going to a working profile, but displays and printers all have their particular white points, so some common ground color space and white point is needed to keep from having to maintain a rat’s nest of device->device transforms.

It didn’t have to be D50; they could have picked D65, or some other triplet. The key point is, they picked one, and all parties know what it is…

1 Like

FSVO computers. I spend my working day on current big endian computers. And many computers are now “bi-endian”. But as Glenn said, that’s just an aside, not the topic at hand.

Here are my 2cts, after having spent quite some time trying to understand the role of D50 in ICC profiles and applying the math to see if I got the concepts right.

I think that one of the main points is that one should not look at the intermediate XYZ values in an RGB -> RGB ICC conversion. Independently from ICC profiles, a conversion between two matrix-based colorspaces (i.e. defined by some primaries, like sRGB, AdobeRGB, Rec.2020, etc…) processes in the following way:

  • RGBin -> XYZ(WPin) using the source colorspace primaries, therefore giving XYZ values relative to the WP of the source colorspace (for ex. D65 in the sRGB case)

  • chromatic adaptation from source to destination WP. If the Bradford method is used, this bold down to multiplying a 3x3 matrix that I will call WPin_to_WPout

  • XYZ(WPout) -> RGBout using the primaries of the destination colorspace

More schematically:


XYZ(WPin) = RGBin_to_XYZ * RGBin

XYZ(WPout) = WPin_to_WPout * XYZ(WPin)

RGBout = XYZ_to_RGBout * XYZ(WPout)

Since the Bradford chromatic adaptation is a linear operation, an arbitrary number of intermediate adaptations can be inserted without changing the result (apart maybe from numerical precision considerations). Therefore, the above is equivalent to


XYZ(WPin) = RGBin_to_XYZ * RGBin

XYZ(D50) = WPin_to_D50 * XYZ(WPin)

XYZ(WPout) = D50_to_WPout * XYZ(D50)

RGBout = XYZ_to_RGBout * XYZ(WPout)

This is what an ICC conversion actually does. However, instead of explicitly doing the chromatic adaptations at each conversion, the ICC profiles store the pre-calculated D50-adapted primaries.

This becomes more clear if we re-write the above like this:


XYZ(D50) = WPin_to_D50 * RGBin_to_XYZ * RGBin

RGBout = XYZ_to_RGBout * D50_to_WPout * XYZ(D50)

The two matrix products WPin_to_D50 * RGBin_to_XYZ and XYZ_to_RGBout * D50_to_WPout are pre-computed when the ICC profile is generated, thus providing the D50-adapted primaries that are stored in the ICC profile instead of the original primaries found in the colorspace definition.

To be more precise, the ICC profile stores WPout_to_D50 * RGBin_to_XYZ for the destination profile, and the resulting matrix is then inverted to provide the XYZ->RGB conversion…

Why D50? So far I could not grab wether the choice of D50 is totally arbitrary or if it has some practical consequences. Someone told me that it has to do with the fact that D50 is the reference illuminant when viewing printed images, and that ICCs where originally developed for the print industry, but I still don’t know if replacing D50 with dome other reference illuminant would change anything…

One practical consequence is that the luminance Y that one computes from the ICC primaries is relative to D50, and so rather far from daylight conditions. I have the idea that for the B&W conversion of a daylight scene one would rather prefer to use the D65-adapted luminance, but I do not have strong arguments to support my intuition…

Hope this helps!

1 Like

iccMAX is coming soon.

The specification is currently at Final Draft International Standard stage, and is being balloted by ISO TC130 member bodies. If passed, it is expected that it will be published as ISO 20677 in 2019.

What is iccMAX?

iccMAX is a new color management system that goes beyond D50 colorimetry. This new specification has been approved by the ICC Steering Committee.

iccMAX profiles show v5 in the header to distinguish them from v4 and v2. iccMAX profiles also have class, sub-class, versioning and header information that differs from v4.

Users and developers are encouraged to make comments on the specification.

Profile Connection Space

The ICC v4 PCS has fixed D50 colorimetry, considered necessary until now to ensure interoperability and prevent ambiguity in colour transforms. iccMAX allows flexibility in the selection of illuminant and color matching functions. It supports spectral communication of colour information through an optional spectral PCS, and also supports the use of color appearance processing in the PCS, with the facility to store appearance attributes in a v5 profile.