Matrix multiplication

In floating point space a * (b * c) not necessarily gives the same result as (a * b) * c

Could you give an example of what you mean?

If you are talking about rounding errors from floating point math, that’s very important to keep in mind and can produce catastrophically different results given appropriately chosen input values. But I think issues with floating point calculations isn’t exactly germane to the current discussion - yes? no? I mean unless one were unfortunate enough to start with the wrong input values!

Simple example:

    float f1 = 1e38;
    float f2 = 10;
    float f3 = 0.1;
    
    std::cout << f1 << " * " << f2 << " * " << f3 << " results in  : " << (f1 * f2) * f3 << " or " << f1 * (f2 * f3) << std::endl;

(f1 * f2) * f3 = inf

f1 * (f2 * f3) = 1e+038

1 Like

Yes but what about a file that does not have a colour profile and is using the default sRGB values, what is the correct viewing environment expected to be D50 or D65?

For example when RT reads a plain TIff and assumes the values are sRGB what value for illuminant is assumed?

Is that the case?

The example I am working through which is here BTW http://www.strollswithmydog.com/determining-forward-color-matrix/

in order to get the correct result it has the last matrix that would be applied last as the first one in matrix multiplication, (if I am to get the same result as the example).

1 Like

“White point” might mean the white point of the ambient light in the room, or the white point of the display, or the white point of the sRGB color space spec, or the illuminant of the sRGB color space profile, which for V2 and V4 ICC profiles as @ggbutcher notes the illuminant is always fixed at D50.

Here are some silly examples that might help to clear up some potential areas of confusion, or maybe not :slight_smile: . Keep in mind that V2 and V4 ICC specs assume that your eyes are 100% adapted to the “color of white” of the display:

Imagine a display calibrated to exactly match the sRGB color space specs. It would have a D65 white point, same primaries as sRGB, and same TRC as sRGB.

Imagine that you send the image to the screen using GIMP or other software that can use ICC profile color management, but you disable color management. The colors would be correctly displayed.

Imagine that you told your imaging software to enable ICC profile color management, and that you assign the sRGB ICC profile as the monitor profile and also as the image profile. The image would look exactly as it did before you enabled color management, even though now you are using ICC profile color management.

Now imagine that your monitor is actually calibrated to match AdobeRGB which also has a D65 white point but is a larger color space than sRGB, and you continue using the sRGB ICC profile as the monitor profile and also as the image profile (or else you simply disable color management, same result either way). The image will not look right. The colors will be too saturated, but neutral gray and white will still look right, no yellow or blue color cast.

Now imagine that your monitor is actually calibrated to exactly match the old ColorMatch color space with its D50 white point and primaries sort of close to sRGB primaries, and you continue to use the sRGB ICC profile as the monitor profile and also the image profile - the colors will be somewhat close to correct, but there will be an overall cast - white and grey will actually look yellow.

1 Like

@Elle

Another example. This time using additions and not overflowing the max float value:

    float f1 = 1e-1f;
    float f2 = 1e9f;

    float f3 = 0.0f;
    
    // sum up small values first
    for(int i = 0; i < 100000; ++i)
        f3 = f3 + f1;
    
    // then add large value
    f3 = f3 + f2;
    std::cout << "result 1 : " << f3 << std::endl;


    f3 = 0.0f;
    // add large value first
    f3 = f3 + f2;
    // then add the small values
    for(int i = 0; i < 100000; ++i)
        f3 = f3 + f1;

    std::cout << "result 2 : " << f3 << std::endl;
result 1 : 1.00001e+009  <= correct
result 2 : 1e+009        <= wrong

I agree that in this discussion it shouldn’t play a big role. I just mentioned it because a lot of people are not aware of that.

1 Like

In most V2 or V4 ICC profile color managed applications, if the image file doesn’t have an embedded ICC profile the application assigns the sRGB ICC profile with its D50 illuminant. I know of two applications that tried to do something else, but their users complained.

Could you give a link to which spec suggests D50 as the viewing environment, and a quote of the relevant passage?

Yes as example that is how I think RT works.

https://www.w3.org/Graphics/Color/sRGB.html
check the section on sRGB reference viewing environment, it is quite confusing…

Hmm, yes, I thought maybe that might be what you were referring to. The thing is, sRGB as described in the original specs was never was meant to be a monitor profile or even an editing color space. It was meant to be used when displaying images on Rec.709 monitors - not using any kind of color management other than hopefully a properly calibrated monitor - under specific viewing conditions, meaning the brightness and color of the ambient light in the room where people are looking at stuff displayed on the monitor. Plus there is consideration of flare off the monitor which raises the effective black point of a CRT, which theoretically was zero (the CRT guns could be off), but in practice never was.

In other words, sRGB specs are trying to deal with the inescapable fact that the viewing conditions around the monitor influence how colors are perceived on the monitor, in addition to considerations of how the monitor itself should be calibrated. And sRGB specs also deal with “actual” vs theoretical black point of displays, but specifically of the old CRT displays.

In yet other words, sRGB specs are trying to deal with what we refer to more broadly as color appearance considerations, plus some considerations that were specifically an aspect of looking at a CRT in a dim viewing environment.

All this stuff is important, but the specific numbers and such in the spec only apply to actually looking at a monitor calibrated to Rec.709 under specified viewing conditions and not using ICC profile color management. How many people looking at this thread fit this description?

In a practical sense, the only part of the original sRGB specs that we incorporate in V2 and V4 ICC profile color-managed editing applications is the primaries and the white point, which we then immediately adapt to D50 to make the sRGB ICC profile.

We really should also pay attention to other things mentioned in the original sRGB specs, like “how bright is the room” vs “how bright is the monitor” and “what color of white for display” vs “what color of light for the surrounding ambient light” and “how dark is the darkest displayable dark” and etc.

But the specifics of how to manage these ambient light levels and “colors of lights” will depend on one’s very specific editing goals. An ICC profile color-managed print-oriented workflow on modern LCD monitors probably wouldn’t involve using any specific numbers from the original sRGB specs even if the person actually intends only to print sRGB images.

Perhaps the other reason, is that many people myself included probably expect a color managed file with the correct sRGB profile applied to look the same a plain file with assumed sRGB values to look identical?

Hi,

I haven’t checked the link, so I’m not exactly sure of what you are trying to
do, but here’s my understanding of your problem (if I got it wrong, sorry).

You have a column vector rgb (i.e. a “colour”) that you want to convert to another one RGB in a different space. You can do that by “applying” two matrices M1 and M2, and you would like to see whether you can do it by just using one matrix M. Did I get it right?

Then, you have this:

xyz = M1 . rgb

RGB = M2 . xyz

substituting for xyz in the 2nd equation:

RGB = M2 . (M1 . rgb)

Knowing that matrix multiplication is associative (forgetting about what @heckflosse wrote about floating-point operations, it is definitely true but I think it can be left out of the conversation here), you get:

RGB = (M2 . M1) . rgb

Therefore, M = M2 . M1, i.e. you would multiply “in reverse”. Does that make sense?

2 Likes

Could you give an explicit example of the problem you are talking about, perhaps with screenshots? You mentioned RawTherapee a couple of different times - is there something RawTherapee is doing with sRGB images with and without embedded sRGB profiles, that somehow seems unexpected?

Spot on!

Yes that is very helpful! and is exactly in agreement with several examples I have.

I am using the RT code as reference, for what I am trying to do. Ideally I would like to incorporate my work into at RT some point!

Specifically I am trying to create a matrix that will take color values that I have computed from density readings of a film scan, that should be in a particular colorspace. Lets call that colorspace RA4 space. (i.e. the colorspace that is created by using the CMY dyes in a RA4 processed color print)

I then want to transform that data to sRGB correctly. At least that is what I want to do initially…

That’s why I want understand how to do it properly! Once I have got the method correct I may do things slightly differently. But my goal initially is to do it correctly.

I can make up some examples using generated solid colors, and compare the results that I get from RT.

I’m totally confused as to how your inquiries regarding viewing conditions is related to "Perhaps the other reason . . . " as quoted above.

There are many web browsers that fail this test of “sRGB image looks the same with and without an embedded sRGB ICC profile” - are you talking about something you see in a web browser?

Perhaps a step back is order.

What I am trying to should be straight forward in that I want use the exact same methods that are used in digital photography and some extent even more so those used in RT. (which I hope are same etc…) The only difference is my values “camera” to XYZ are unique.

This involves a lot of trial and error, trying different things, and each time I try something I like to understand the process, the values used etc.

I understand this because the software simply ignores the values. But in the case of software that processes ICC profiles correctly what should happen?

Perhaps I can ask the question in different way. Let take two tiff files. File A has the correct sRGB value attached with D50. and File B which has the exact same data inside but no profile.

When the same file is displayed in RT should they appear the same or different? Or what color values does the internals or RT thinks it has?

Hmm, I thought I already answered this question above :slight_smile: . The files should look the same assuming the software assigns sRGB to images without embedded ICC profiles, which I’m sure RT does, leastways I can’t see any change in how a sample image looks before and after assigning an sRGB profile to an image with no embedded ICC profile. Do you see a visual difference?

I’m not sure what you mean by “ignores” but the problem is that those web browsers are flawed :slight_smile: . They should all by default assign sRGB to images without embedded ICC profiles, and then convert to the monitor profile.

No, hence my point that when no profile is applied RT assumes it sRGB at D50, and I assume so does many other applications. If it assumed the file without the profile was D65 it should apply an adjustment and the result should look different to the one with D50 profile?

Putting aside applications that don’t do things correctly I am looking to understand what the correct behaviour should be. Does that make my question clear?

If a V2 or V4 ICC profile color-managed editing application assumed an image without an embedded ICC profile was somehow “D65” and then tried to apply an adjustment to somehow compensate for the difference between D65 and D50, it would be a very confused ICC profile color-managed editing application.

If I were using software that behaved in this fashion, I’d file a bug report.