Some questions to better understand the available data when opening a raw file with libraw

Hey folks,

last semester I did a nice seminar about image processing and somehow the demosaicing algorithms got me. So I'm now experimenting with different demosaicing and image processing algorithms and recently started to implement some testcode using libraw for reading DSLR photos. Now I have a few questions to better understand what's happening where the documentation didn't help or maybe I didn't understood it well.

1.) When handling data from a CFA sensor after unpacking raw_image points to an array with raw_height*raw_width as a 1D array? And this data is the untouched data contained in the file? Only raw2data does stuff like black point correction, right? And does the raw_image buffer contain the full “raw” sized image or is it already cropped to the usable pixel area? Is it safe to use a few of the pixels just outside the officially usable pixel area as a base for the demosaicing code (outside pixel used for the interpolation of the pixels on the edges)?

2.) Is the curve in libraw_colordata always populated if the raw is not linear or are there files where a formula to calculate to linear is somehow offered? Is it always fully populated? I wonder about the size of 0x4001 which seems a bit odd to me. Or is there some information about the size somewhere? I assume this LUT will also scale black and white level? Or am I wrong here? I want to have all raw data normalised to a 0.0-1.0 range for my algorithms so I search for the best way to achieve this manually (see comment after point 3.).

3.) How can I get the raw pixel order? I get that imgdata.idata.cdesc contains RGBG if it is a RGB CFA but how can I know if the first line is GR, RG, GB or BG?

My code is doing raw processing on the GPU where I also want to do all the necessary pre-processing to save some cpu time on mass processing as I will do all the image processing in the GPU anyways so that’s why I want to do as few of the tasks in libraw as possible just copying the raw_image to the GPU and go from there. Currently I hacked around libraw until I got some usable data to my debayering code implemented in CUDA but I’d like to improve my code a bit now and have a way that not only works for my specific 5DmkIII cr2 files.

PS: Sorry if I missed some stuff while browsing through the forum or the documentation but as I read in a few forum threads the documentation is also not up to all changed stuff of the most current libraw versions so I thought I’d better ask about the stuff that is still unclear.


1)Yes, raw_image is raw_width

1)Yes, raw_image is raw_width*raw_height 1D array. It is uncropped, full image (including 'masked areas') is read by unpack().

Black level is not subtracted, phase one postprocessing is not performed, but linearization curve is applied to raw_image data (see below)

2) Yes, curve is populated on the early stage of open_file() with curve[i] = i; (for full range loop, from 0 to 65535)
After open_file(), the curve[] will contain linearization curve read from file metadata.
Unfortunately, some formats (e.g. Nikon NEF) store curve not in metadata, but in raw image data itself. For these formats curve is read on unpack() stage.

curve[] size is not set anywhere: curve usage is specific for specific data format/unpacker code, curve is applied at unpack() stage.

Note: same curve[] array is used for gamma correction of output.

3) Use LibRaw::COLOR(row,col) call to get color at row,col.
Please note, that row,col are 'visible area' (cropped) coordinates (i.e. uncropped at top_margin/left_margin is COLOR(0,0))

-- Alex Tutubalin



thank you for your reply Alex! Cleared up some stuff and I'm somehow happy that unpack already applies the curve.

Regarding 1): How much can be relied on the pixels just outside of the active pixel area? Most algorithms I have currently implemented need 2-3 pixels on the outside to get the pixels at the edge. Therefore I currently copy the 2 rows/cols at the edge to the outside but would like to save the processing time of this step. Or is the usability of this pixels mostly depending on the raw format?


Pixels outside of image area

Pixels outside of image area are not image area (in most cases).
Unlike Adobe tools (e.g. DNG Converter), LibRaw tries to save as much image area as possible, without any space for demosaic to run. So, you need to crop slightly more to get demosaic some space.

There is small exclusion from 'as much as possible rule': border size is usually even, to keep bayer patern the same from both edges (uncropped and 'active area' cropped). This is not general rule, but I hold on to it when image format do not dictates other borders (such as DNG ActiveArea or so)

-- Alex Tutubalin

Ok. Thank you for your advice

Ok. Thank you for your advice. After the first feedback I hacked a small batch processing for preview images which works quite well. Even if I wondered that there is no Cam_XYZ populated with Blackmagic Production Camera raw files. But this should be another thread maybe later.


use cmatrix (this is camera

use cmatrix (this is camera raw values to output rgb space matrix) if you need to use file built-in color profile

cam_xyz is filled in by internal LibRaw color profile, but no such profile is set for BlackMagic cameras.

-- Alex Tutubalin