So ... by not using cam_mul[] for scaling, but instead pre_mul[] and reproducing dcraw's one-step scaling-and-white-balancing I am getting a stable result.
Interestingly, this is not the (exact) same hue that dcraw (and libraw) is creating with gamma 1/1, no-auto-bright and output "raw" (unaltered camera color) *or* output "sRGB": dcraw/libraw's output is slightly (not much, really) more on the blue side, ever so slightly less saturated. Not sure why that is. Maybe because I am doing most calculations on double-precision, not integer? Since the difference is really small, I am fine with it.
I do have to normalize the image for dark/maximum (the black value and the maximum value from imgdata.rawdata.color) in order for dcraw's scaling to work correctly. I could not find the function in dcraw that is equivalent to this normalization step, but leaving it out gives too dark results, so it must be correct (I assume that scale_colors actually looks for high/low points in the image, there are some parts of the code that are still opaque to me).
This also means that my assumption above seems to be correct: Normalization is pre-demosaic, not post-demosaic.
My steps now are:
- load file
- unpack
- call "subtract_black()" (just in case black has not been subtracted by "unpack")
- normalize to embedded dark/white values (or "minimum/maximum", dcraw's mixture of terms is not helping ...)
- scale/white-balance based on pre_mul[]
- demosaic
- apply color profile (using the pre-calculated cam-rgb-to-xyz-to-output-rgb)
- apply rotation
BTW: I found lclevy’s discussion on scaling quite helpful (the site is linked from the ninedegreesbelow website).There's a caveat about that website, though (and that MAY have misled me, I cannot remember): The code quoted there about dark-subtraction uses cblack[], NOT the "global" black value. That is due to the code having populated cblack[] with "complete" black values before. This might add to why my scaling was off.
So ... by not using cam_mul[] for scaling, but instead pre_mul[] and reproducing dcraw's one-step scaling-and-white-balancing I am getting a stable result.
Interestingly, this is not the (exact) same hue that dcraw (and libraw) is creating with gamma 1/1, no-auto-bright and output "raw" (unaltered camera color) *or* output "sRGB": dcraw/libraw's output is slightly (not much, really) more on the blue side, ever so slightly less saturated. Not sure why that is. Maybe because I am doing most calculations on double-precision, not integer? Since the difference is really small, I am fine with it.
I do have to normalize the image for dark/maximum (the black value and the maximum value from imgdata.rawdata.color) in order for dcraw's scaling to work correctly. I could not find the function in dcraw that is equivalent to this normalization step, but leaving it out gives too dark results, so it must be correct (I assume that scale_colors actually looks for high/low points in the image, there are some parts of the code that are still opaque to me).
This also means that my assumption above seems to be correct: Normalization is pre-demosaic, not post-demosaic.
My steps now are:
- load file
- unpack
- call "subtract_black()" (just in case black has not been subtracted by "unpack")
- normalize to embedded dark/white values (or "minimum/maximum", dcraw's mixture of terms is not helping ...)
- scale/white-balance based on pre_mul[]
- demosaic
- apply color profile (using the pre-calculated cam-rgb-to-xyz-to-output-rgb)
- apply rotation
BTW: I found lclevy’s discussion on scaling quite helpful (the site is linked from the ninedegreesbelow website).There's a caveat about that website, though (and that MAY have misled me, I cannot remember): The code quoted there about dark-subtraction uses cblack[], NOT the "global" black value. That is due to the code having populated cblack[] with "complete" black values before. This might add to why my scaling was off.
Mact