Please sketch the overview of color spaces.

I've been reading on the internet and digging through dcraw code for weeks now. And I can't seem to figure everything out I think I need to know in order to do proper color conversions and white balancing. I'm going to try to explain how I think things work, but it might be wrong, so please try to interpret and figure out where I'm wrong. I'm trying to wrap my head around every single part, so if there are details in anything I say where I'm wrong, please please tell me. I'd be so thankful. I know it is a very long post, but I'm trying to be very clear.

Everything is assumed to be linear.

So, we will call the color space the camera uses: "RAW".
If I want to convert this RAW colors to XYZ colors, then exactly what is the most precise way (if this is something to do that makes sense)? Right now, I'm doing this:

   XYZ_color = sRGB_to_XYZ * RAW_to_sRGB * RAW_wb_coeffs * RAW_color;

Where "RAW_to_sRGB" is the "rgb_cam" matrix and "RAW_wb_coeffs" is the "cam_mul" vector from LibRaw. The "sRGB_to_XYZ" matrix is using the D65 reference white (as Bruce Lindboom says. I calculated the matrix using the XYZ tristimulus values for the D65 whitepoint in the formula's here:
Now, a first important question is: "By using these "cam_mul" coefficients, what exactly is achieved in which color space? What is the reference white (as Bruce Lindboom is always referring to) of the output XYZ_color?" Another question that is very related to this one is: how do I convert the whitebalance coefficients "cam_mul" to chromaticity coordinates for the hypothetical illuminant? These cam_mul coefficients are coefficients that should be applied while in RAW space, I have found on this forum.

My interpretation on this would answer the question as follows: It should give my XYZ colors with the "As Shot" whitebalance. This means that the whitebalance coefficients of the camera have been used to make a white object in the scene appear like white by definition of the "D65" whitepoint (given that the whitebalance coefficitients of "cam_mul" were 'right'). Why the D65 whitepoint? Because you (I assume Alex will answer this) said this in one of your other answers that the "rgb_cam" in combination with "cam_mul" produces sRGB with respect to the D65 whitepoint (which means that RGB values 1,1,1 should look like the D65 illuminant color, which should hold true if your monitor is a good sRGB monitor with D65 whitepoint).

Now I want to do whitebalance correction on these colors. This is the part where I'm stuck (in the assumption everything else I said is correct, which would be a miracle).

It seems reasonable to simply pick different RAW whitebalance coefficients in the conversion above (so other coefficients than those in "cam_mul"). However, I do not know how to compute these coefficients. Let's say the scene was illuminated with an illuminant of color temperature 5000K, but my "As Shot" whitebalance coefficients are wrong because I misconfigured the camera to use a whitebalance of 7000K for example. So, using the default As Shot whitebalance coefficients in the conversion above, I would get colors where light falling onto my camera sensor with a color temperature of 7000K would appear as white (D65 white).

Second important question: "How do I fix this correctly?"

As I said, it seems reasonable to use other RAW whitebalance coefficients. But how do you calculate these, given that every camera uses different RGB primaries? (Again question is closely related to the first question) I can calculate the xy chromaticity coordinates for a given color temperature and convert those to XYZ. But how do I go from there, since the primaries are different for every camera? Maybe the solution lies in my last question in the last paragraph.

An approach (but an approach where I don't have much confidence in it's correctness) would be to convert those wrongly whitebalanced colors to correctly whitebalanced colors. I'm thinking of applying the process of chromatic adaptation (like the human eye does and is described on Bruce Lindboom's website, using for example Bradford adaptation) on these colors. However, this is where I am very confused: light with color temperature of 7000K is now D65 white. But what I actually want is that light with temperature of 5000K falling on my sensor turns out as D65 white. In this example: what is the source and destination reference white I should use to convert these colors using Bradford chromatic adaptation? (In terms of this page:

A last final side question: What is the difference between XYZ_to_sRGB * cam_xyz^(-1) and rgb_cam * wb_coeff? They seem to visually produce the same results. Is one deduced by the other? It seems that the first one doesn't use whitebalance coefficients? How are these two matrices "cam_xyz" and "rgb_cam" retrieved? Are the whitebalance coefficients used in while computing one of both, or is one of both "whitebalance/whitepoint agnostic?" Or are the results of using cam_xyz^(-1) always colors in XYZ space with respect to the D50 reference white (as this seems to be the "standard" for ICC profiles (not sure if XYZ is an "ICC profile"))? I'm thinking that maybe (just maybe, if the answer to the last question turns out "no") cam_xyz can be used to calculate XYZ colors with as reference whitepoint the illuminant of the scene. If from there, I want to do whitebalance corrections, I just have to convert, using chromatic adaptation, from the "by the user selected color temperature (like Lightroom lets you set the temperature of the illuminant)" as reference whitepoint to the D65 whitepoint (because sRGB uses D65 as whitepoint).


cam_mul are in 'camera color

cam_mul are in 'camera color space'.

For WB multipliers conversion to/from 'color temperature' please look into Adobe DNG SDK source (or into RawTherapee source), it it shorter way than translating Adobe code into english in this forum thread.

-- Alex Tutubalin @LibRaw LLC

I can reverse engineer Adobe

I can reverse engineer Adobe code, but I still need to know what the cam_xyz matrix exactly converts to. It converts camera space to XYZ. But is that with respect to a reference white or not? If so, which? Hopefully this question makes sense.

imgdata.color.cam_xyz[] is

imgdata.color.cam_xyz[] is exactly the same as Adobe DNG ColorMatrix2. It converts from XYZ to camera space.

-- Alex Tutubalin @LibRaw LLC