Hi,
Anyone figure out how to modify curves for the SX10 12 bit raw? I have looked at the code and it is a mystery to me.
Jon
Sorry for the absence of response.
Here is how the curve data is stored -
RGB curves: ouput = curve[input]
L curves: output = curve[L] *(input-black) + black
RGB curves and L curves are 4 colors curves
L curves contain multiplicator factor (value = multiplicator * 2^12)
DR curves: output = curve[L] *(input-black) + black
DR curves are gray scale only
For RGB:
If you have a 12 bit sensor you will need to extend the "curve" table to 4096 elements per channel *4 channels.
You may want to consider using a different extension for the file name (e.g. C12 instead of CV).
Next step is to figure out how the camera stored each of the channel in raw format (see raw.c).
The process is:
1. Extract channel data
2. Apply RGB curve (lookup table)
3. Repack data and store
For L curves
The curve table uses multiplicator of value ranged from [1/2^12 to 2^4]. This multiplicator is stored as
(multiplicator * 2^12). 2^12 is used to allow fast division by logical shift. The multiplicator is selected via lookup table
using the green value as index.
As we are multiplying, a control for overflow is done before storing the data back. We also redivide by 2^12 as in
the following macro:
#define CURVE0( a, b ) (((a) * curve0[b]) >> 12)
- No change needed here.
See this macro for 10 bits(1023=2^10-1):
#define LIM( a ) (((a)>1023) ? 1023: a )
- Change needed here (4095 vs 1023)
The process is same as above.
Last but not least - Update the curve generation utility for 12 bits. As I am getting lazy I don't mind pasting the VB code here
if you want. Please let me know. You will need to have different extension for the name (eg. C12 v.s. CV and F12 v.s. CVF)
I will suggest to change the extension name of curve files as follow:
-C10 for 10 bit RGB curves
-C12 for 12 bit RGB curves
-F10 for 10 bit L curves
-F12 for 12 bit L curves
Toine
PS: The code gets a bit more complex as we want to avoid the black hole (dead pixel) and not converting them to black. The internal JPEG engine will take care of those.
// In this context pixVal1 is a green pixel
// If it is dead (i.e. 0) leave the corresponding red or blue untouched
if (pixVal1) {
// if not substract the standard black level
// with a min value of 0 in case it gets negative
pixVal1 = RBLACK( pixVal1 );
// if the corresponding red or blue pixel is not dead
// apply curve after removal of black value and add it back after multiplicator and adjust for overflow.
if (pixVal0) {
pixVal0 = RBLACK( pixVal0 );
pixVal0 = CURVE0( pixVal0, pixVal1 ) + BLACK;
pixVal0 = LIM( pixVal0 );
}
// apply curve to the green value
pixVal1 = CURVE1( pixVal1, pixVal1 ) + BLACK;
pixVal1 = LIM( pixVal1 );
}
No need to change the above code.