user_mul and cam_matrix parameters not working

Hi Alex,

First of all, I am amazed how you keep responding to all the comments in the forum. If there is a PayPal link to donate to your efforts, please let me know. I'd like to invite you for a beer.

Second: I am having trouble getting user_mul[] multipliers to work. In the code I am using I has the following steps

libraw_data_t *alldata = libraw_init(0);
alldata->params.user_mul = .... and all other parameters
libraw_processed_image_t *proc = libraw_dcraw_make_mem_image(alldata,&err);

and then I work with *proc. For some reason, whatever values I enter for user_mul, *proc always seems to give me the raw data.

Third: Does the algorithm use the camera matrices in its interpolation calculation? If so, can that be turned off? I tried use_camera_matrix=0, but just as user_mul, it doesn't do anything. I am processing astronomy images and there is a slight chromatic aberration to the images, causing stars to be slightly offset. Because of this, I assume, the interpolation goes nuts and yields pixels with zero values near bright sources. That's not good.


1st: We do not have donation

1st: We do not have donation link (yet). One could buy our software (RawDigger or FastRawVewer or bundle)

2nd: does dcraw_emu -r 2 1 3 1 results in different WB? If so, please start with samples/half_mt.c sample (it also uses C-API) with this additional lines below line ~80:

iprc->params.user_mul[0] = 2;
iprc->params.user_mul[2] = 3;
iprc->params.user_mul[1] =
iprc->params.user_mul[3] = 1;

This should result into bluish output.
(Note: you do not need libraw_raw2image if libraw_dcraw_process is used)

3rd: to use 'raw colors' set params.output_color to 0, this will disable camera color matrix use.

-- Alex Tutubalin @LibRaw LLC


Hi Alex,

1) Ok, I'll check them out!
2) I found the problem by digging into the code. The values set in user_mul only get applied when no_autoscale is false, i.e. auto_scaling is applied. This is counterintuitive, as setting your own multipliers does not count as auto_scaling, in my opinion. I noticed the pixel values increasing by a lot more than the multipliers I entered though, and it seems to scale the image by a value determined from a sum. Is this ok? Is this consistent from image to image? I.e., if I take a 2x long exposure, will the values scale by a factor of 2 (if gammas=1.0). I will want to combine and do arithmetics with the images and I don't want artificial scales.
3) I see a change when setting output_color=0. That's great. I'll see if it helped with the interpolation.

Thanks again!


no_auto_scale is very special

no_auto_scale is very special use parameter, quote from docs/API-datastruct.html:

Disables pixel values scaling (call to LibRaw::scale_colors()) in LibRaw::dcraw_process().
This is special use value because white balance is performed in scale_colors(), so skipping it will result in non-balanced image.
This setting is targeted to use with no_interpolation, or with own interpolation callback call.

For normal processing you probably need no_auto_bright=1 (and, may be, adjust_maximum_thr=0.0 too)

P.S. need update w/ actual LibRaw/doc/ contents (forgot to do it on LibRaw 0.20 release)

-- Alex Tutubalin @LibRaw LLC


Hi Alex,

Well, the only way I got user_mul to be applied was then no_auto_scale=0. I have always had no_auto_bright=1 and adjust_maximum_thr=0.0.

in Libraw::scale_colors() user_mul is copied to pre_mul if it is set. And then, I only see pre_mul used if use_auto_wb or use_camera_wb is set.

What I would need is to use the camera multipliers (i.e. 1.99,1.0,1.77,1.0, as defined by Canon for my camera), but no scaling done to the image.



There is no standard way to

There is no standard way to avoid full range (0..65535) scaling in LibRaw::scale_colors (not to scale is useless because of limited ushort precision).
Possible workaround:
params.no_auto_scale = 1 to avoid LibRaw::scale_colors() call
implement own scale_colors replacement (use scale_colors() source as a reference) and provide it via callbacks.pre_preinterpolate_cb

(you'll need to subclass LibRaw and implement the callback in the subclass to allow access to internal data fields)

-- Alex Tutubalin @LibRaw LLC

Ok on the scaling

Hi Alex,

Ok, thanks for that update. I wouldn't say it is useless though! For one, you don't actually get more precision by multiplying all values by a constant, unless you are talking about interpolation. Two: for scientific images count numbers are actually important. For example, if you have astronomy images with different exposures, it is nice to be able to scale them to the same level, based on exposure count.

As long as I can multiply each image output by its scaling value in my external program, that's ok. What I really need is for output_color=0 to work with scaling off.



on second though

... something to add here.

I tried converting an image that did not saturate anywhere. The maximum values I get in the image are lower that 2^16. So, I am actually not certain that the procedure really does scale to the full range. I'd really like to understand what the scaling does, as it also does not seem to be just the multiplication factors. Something else is going on.


Without auto-bright/auto

Without auto-bright/auto-maximum, scaling scales (theoretical) maximum to 2^16-1.

This is somewhat tricky, for example for 14-bit canons maximum assumed 16383-black_value, while in reality data maximum is lower (as low as ~12000 for 5D Mark II at intermediate ISOs), that's why maximum adjustment was introduced (there is no way to determine real maximum value from metadata for these camera(s)).

For most other vendors, maximum is not that tricky.

-- Alex Tutubalin @LibRaw LLC

hmm, not what I see.

This is not what I am seeing.

I have two images, one saturated where the max raw value is 14355 and another unsaturated, where the raw max values are (7560,11708,4489). Turning on interpolation (color_option=0), I get max values of (20055,19270,20076) for the saturated and for the unsaturated (8481,11708,5168). If I turn auto-scale one with user_mul[1.99,1.0,1.77,1.0], I get max values of 65535 for the saturated image (fine, its saturated here also). However, for the unsaturated image, the max values are (55594,49872,39231). So, IN FACT, it did not scale the unsaturated image up to 65535. What does the scaling actually do?


scale_colors per-channel

scale_colors per-channel multipliers are:
scale_mul[geshifilter-c] = (pre_mul[c] /= dmax) * 65535.0 / maximum;

(dmax is max(pre_mul[0...3], pre_mul is WB coeffs). <p> Final scaling is performed in copy_mem_image unless no_auto_bright is set: <ul> <li>histogram is analyzed (from right to left) to get level # where 1% of pixels are saturated <li>output curve will map 0...level# to full output range </ul>[/geshifilter-c]

-- Alex Tutubalin @LibRaw LLC


Oh, F'in aces! The interpolation is nice now. The output_color=0 helped!

All I need to know now is the scaling to the images when using user_mul.




Yes, manually changing

Yes, manually changing imgdata.color.maximum after LibRaw::unpack() will effectively disable the scaling.

-- Alex Tutubalin @LibRaw LLC