I am having some trouble determining the maximum or saturation level for my pixels, I thought it was LibRaw::imgdata.color.maximum, however I find in some cases that after processing I have values bigger than this value. My code is below:
// Create an image processor LibRaw iProcessor; // Open the file and read the metadata iProcessor.open_file(filename.c_str()); size_t width = iProcessor.imgdata.sizes.width; size_t height = iProcessor.imgdata.sizes.height; // Unpack the image iProcessor.unpack(); iProcessor.imgdata.params.user_qual=4; // DCB interpolation iProcessor.imgdata.params.output_color = 0; // Raw output //do no white balance iProcessor.imgdata.params.use_camera_wb = 0; iProcessor.imgdata.params.user_mul[0] = 1.0f; iProcessor.imgdata.params.user_mul[1] = 1.0f; iProcessor.imgdata.params.user_mul[2] = 1.0f; iProcessor.imgdata.params.user_mul[3] = 1.0f; //Process iProcessor.dcraw_process(); //Copy the luminosity into a vector std::vector<unsigned short> data(width * height); unsigned int maxLuminosity = 0; for (size_t i = 0; i < data.size(); ++i) { unsigned int luminosity = ((unsigned int)iProcessor.imgdata.image[i][0] * 2 + (unsigned int)iProcessor.imgdata.image[i][1] * 3 + (unsigned int)iProcessor.imgdata.image[i][2])/6; data[i] = luminosity; maxLuminosity = luminosity > maxLuminosity ? luminosity : maxLuminosity; if (luminosity > iProcessor.imgdata.color.maximum) std::cout << "Pixel " << i << " has luminosity too high\n"; }
If I break in my debugger where I do the std::cout, then I can see that individual pixel values are higher than iProcessor.imgdata.color.maximum.
Is there something I am doing wrong? The region where I am getting the higher values is probably overexposed in one or both of red and green ( it is a sunset picture). I have just spotted the highlight option, but this is set to 0, which I think should clip. Is this correct?
color.maximum is 'maximum
color.maximum is 'maximum data value permitted by data format'.
In some cases, real maximum is smaller.
There is color.data_maximum field, but it is filled /based on real data/ on raw2image (or dcraw_process) stage, so not available just after unpack().
In your example you compare raw data maximum (so, data range of raw data) with processed values.
This is not correct, because output data are scaled to use full data range (16 bit).
-- Alex Tutubalin @LibRaw LLC
Hmm, It seems to me that
Hmm, It seems to me that processed data are not being scaled to the 0-65535 range. In fact the data that are not saturated fall into the range 0 - colour.maximum, only saturated values are larger than color.maximum.
Is there a way I can upload an image to the forum? I have generated a greyscale jpeg from the data vector in my code above using
The ouput shows the buffer overrun from conversion to unsigned char very clearly.
Phil
imgdata.image is indeed
imgdata.image is indeed scaled in LibRaw::scale_colors() call
For your test: what contained in data array?
-- Alex Tutubalin @LibRaw LLC
The data array is set in my
The data array is set in my first example. It is just an approximation of the luminosity of each pixel. (2*red+3*green_blue)/6.
This link should show you the output of the above as jpeg files. You can see the integer overflow in the overexposed clouds https://1drv.ms/f/s!AgLCmsxNxVV_jelOf_MIR7MeGcsXvQ
Not so. It looks like you've
Not so. It looks like you've divided data by 256 (than recover it back?). This step is missing
In your code:
data should be in 16bit (64k) range.
Next step:
Data is upscaled to 24 bit?
-- Alex Tutubalin @LibRaw LLC
And if data is scaled to 8
And if data is scaled to 8 bit somewhere, your result looks correct.
coloir.maximum is in RAW data domain, so for 14-bit camera it is about 16000.
imgdata.image[], after processing, is in 0..64k range.
your luminocity calculation, in first assumption, is in same range as imdata.image, so 64k.
So your jpeg generation code will show upper two stops of image as 'overflow'
-- Alex Tutubalin @LibRaw LLC