Questions about color matrices in colordata

I am trying to understand the behaviour/purpose of the various color conversion matrices that are present in the colordata struct. I was able to glean some information from the various forum posts dating back several years but I still have a bunch of clarifications. I am little new to raw processing and so I want to ensure that any erroneous results I am getting is not due to my misunderstanding of how the library returns these coefficients.

* This appears to be convert from XYZ colorspace to the camera colorspace (R G1 B G2). Does this do this conversion for the specific camera or for a reference camera? I noticed that DNG does AnalogBalance*CameraCalibrationN*CameraMatrixN to get this matrix. Is cam_xyz equivalent to this for DNG and for other formats?
* Do cam_xyz[1..4][] always correspond to the the channel order R G1 B G2?
* When you say cam_xyz has last all zeros on the last row for an RGB image, I am unclear on what that means. Is RGB image a Foveon image or does it mean for any Bayer CFA?

* Are they the R G1 B G2 values that correspond to white as set by the camera?
* Is the order always R G1 B G2 irrespective of the layout?
* I noticed that WB_coeffs has coefficients for standard illuminants for some formats. So will XYZ = inv(cam_xyz)*WB_coeffs[21][...] corresponds to the XYZ for d65 white point?

* Does this equal WB_coeffs[21][...] if set?

cmatrix[3][4]. Not clear what this really does? From the dimensions, it appears to operate on the linear color space of the camera. But not clear what it transforms it to.

rgb_cam[3][4]. Am I correct in assuming this converts the linear camera values R G1 B G2 into RGB in the sRGB colorspace?

ccm[3][4]. Not clear what this really is doing?

In general, for non-demosaiced image, each pixel only has one color component? So how exactly can I use a matrix such as rgb_cam?

Thanks for all your help in advance. libraw is really powerful but kinda hard to understand (atleast for me personally!).




I will take a look at that link. I will get back to you if I have any questions.


Some follow ups

I am not clear if my earlier follow up was actually posted. So apologies for a repeated post.

The link you had sent me was really helpful. I think I now understand how the cam_xyz, rgb_cam, cam_mul and pre_mul matrices work.

However, the code referenced in the link appears to be older and hence does not contain any reference to ccm. Also, the link does not contain any information/comments about cmatrix.

I just noticed from the latest code that appears to populate cmatrix primarily through calls to cam_xyz_coeff.

Would appreciate any help about these two matrices (ccm and cmatrix)?


cmatrix is camera color data

cmatrix is camera color data similar to rgb_cam, but calculated from in-RAW color data.

ccm is also 'camera color matrix' retireved from RAW in 'as is' (excl. normalizing) form.

-- Alex Tutubalin


So it looks like cmatrix and ccm are also for converting from camera space to sRGB. Correct?

The ccm appears to be only read from the file and not computed and it appears to be normalized by sum(imgdata.colors.ccm).

cmatrix also appears to be either read from the file or derived from camera properties.

So, if these are not available in the file, I can assume this to be all zeros?

Is it safe to assume that cam_xyz and rgb_cam are sufficient for most color space transformations?
* rgb_cam for direct conversion to sRGB?
* pseudoinverse(cam_xyz) to move to XYZ space and then apply any suitable transformation to move to a colorspace such as Rec.2020 or ProPhoto of my choice?

Also, a quick question about wb_coeffs. Are the coeffs in the order of the CFA pattern OR are they always R G1 B G2?


wb_coeffs are in channel

wb_coeffs are in channel numbering order (as returned by COLOR(row,col))

-- Alex Tutubalin

ccm vs cmatrix

A quick follow up. So based on your descriptions, cmatrix is the transformation from Camera Space to sRGB.

Is ccm similar to cam_xyz i.e. transformation between Camera Space and XYZ?

I have a DNG file shot from a Google Pixel 3 that has all-zeros for cam_xyz and ccm. The rgb_cam and cmatrix have the same values. The profile is also not available.

For such files, how do I convert from input space/camera space to XYZ?

ccm is not similar to cmatrix

ccm is not similar to cmatrix.

To convert to XYZ use cmatrix or rgb_cam, multiplied by srgb2xyz conversion matrix, see convert_to_rgb() source for details.

-- Alex Tutubalin


That makes perfect sense. So, the matrix to convert from camera space to XYZ becomes xyz_rgb*rgb_cam. Does that impact the gamut of colors that can be represented as Camera Space -> sRGB is a narrowing conversion?

But, what exactly is ccm? I know in your earlier comment you mentioned

"ccm is also 'camera color matrix' retireved from RAW in 'as is' (excl. normalizing) form."

but could you provide more details?


Matrix conversion is not

Matrix conversion is not gamut limited (unless you cut negative values in some intermediate steps)

ccm is 'camera matrix parsed from metadata. period', it is preserved as is (w/ possible value normalization). Usually it 'just some color data with not known camera/vendor specific meaning'.

-- Alex Tutubalin