Why does color.pre_mul change after postprocessing?


I'm trying to process a sequence of images using the same white balance correction. I need daylight white balance so I thought that I just read out pre_mul (docs say "White balance coefficients for daylight (daylight balance). Either read from file, or calculated on the basis of file data, or taken from hardcoded constants.") and then use that for all images. However I found an odd behaviour. When I do open_file and unpack, then pre_mul is [1.912400484085083, 0.9313587546348572, 1.0938434600830078, 0.0]. When I then call dcraw_process, pre_mul changed to [2.0533447265625, 1.0, 1.1744598150253296, 1.0] which seems more like the correct values. What is happening here?



Use imgdata.params.user_mul[]

Use imgdata.params.user_mul[] if you need to use your own WB coeffs.

[1.912400484085083, 0.9313587546348572, 1.0938434600830078, 0.0] are coeffs read from camera
[2.0533447265625, 1.0, 1.1744598150253296, 1.0] - are normalized (G2 set to G, all divided by G
These two sets of coeffs will result into same image.

-- Alex Tutubalin

I see, is there some way to

I see, is there some way to get the normalized coeffs without postprocessing in a generic way? I imagine it depends on which colors there are, e.g. RGBE probably doesn't have a 0.0 in the unnormalized coeffs, and I don't really want to implement this logic myself. I need to store the coeffs for future reference and like to have them in a standard format, the normalized one in this case.

You may always use 4 coeff

You may always use 4 coeff (copy G-coeff to G2-one for 3-color images).
Normalization does not matter because scale_colors() will re-normalize each call.

To normalize, just divide all four to smallest coeff.

-- Alex Tutubalin

What I also find a bit

What I also find a bit strange is that user_mul is copied into pre_mul if it's given. This essentially means that you violate the API contract which says that pre_mul are the coeffs for daylight.

You don't need daylight

You don't need daylight coeffs *after* postprocessing stage.
If you need it, there is 'rawdata' copy in imgdata.rawdata.color

-- Alex Tutubalin

Thanks, maybe this should be

Thanks, maybe this should be added to the docs, that imgdata.rawdata.color etc. are the original values which won't be changed by postprocessing.

Regarding normalization, what

Regarding normalization, what about GBTG colors? If the last multiplier would be 0.0 then this line in scale_colors wouldn't work: if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1;
Or can the last multiplier only be 0 for RGBG?

What is 'GBTG'?

What is 'GBTG'?

-- Alex Tutubalin

I don't know, but it says so

I don't know, but it says so in the libraw API docs:

char cdesc[5];
Description of colors numbered from 0 to 3 (RGBG,RGBE,GMCY, or GBTG).


For 4-color images you need to specify 4 coeffs in user_mul. If 4th coeff is missing then
* for 3 color images G2 assumed to be equal to G
* for 4-color images 4th coeff assumed to be 1.0

-- Alex Tutubalin

So GBTG is a 3 color image.

So GBTG is a 3 color image. Then pre_mul[3] = colors < 4 ? pre_mul[1] : 1; is wrong, isn't it? It should be pre_mul[3] = colors < 4 ? pre_mul[0] : 1 in this case, or not?

color count is in imgdata

color count is in imgdata.idata.colors

Examine it just after open_file, not after postprocessing.

-- Alex Tutubalin

Hm? I was just referring to

Hm? I was just referring to the letters. There are three, G, B and T, so the image has 3 colors, right?

DO NOT count letters, use

DO NOT count letters, use colors field.
For example, old Olympus cameras (E-520 and so) are RGBG, but two greens are different, so you need different WB coeffs for two green channels.

-- Alex Tutubalin