GreycLab / CImg

The CImg Library is a small and open-source C++ toolkit for image processing
http://cimg.eu
Other
1.46k stars 278 forks source link

Reading DNG file with libRaw and passing it to Cimg #405

Open seebi13 opened 6 months ago

seebi13 commented 6 months ago

I'm using Cimg on Android for some graphic manipulations which works very good. Now I read a DNG file with libraw and want to pass the data to Cimg. The saved tiff file looks weird. I use this code:

LibRaw rawProcessor;
rawProcessor.open_file("file.dng");
rawProcessor.unpack();
int  ret2=rawProcessor.dcraw_process();
libraw_processed_image_t* image = rawProcessor.dcraw_make_mem_image(&ret2);

float xres=72.0;
CImg<unsigned char> cimgOriginal(image->data,image->width,image->height, true);
cimgOriginal.shift(10*(-1), 10*(-1),0,0,0);
cimgOriginal.rotate(360.0-5, (float) 1200, (float) 800,0,0);
cimgOriginal.save_tiff("file.tiff", 0, &xres,0,false);

Is there something I must do when using the data from libraw?

Here are both images, on the left is dng file and on the right is tiff file exported from cimg (both imported into Photoshop).

Thanks!

Mike

tiff_with_cimg

seebi13 commented 6 months ago

I've figured out that the problem is how Cimg holds the data: libwraw holds the data in packed RGB (also called interleaved RGB) while Cimg uses planar RGB.

So the data must be comnverted. First I've treid it manually with copy buffer tec. But I've figired out that Cimg can do it - with a method called permute_axes(). The documentation about permute_axes() is very short and does not really help to understand what the methode does. But here is a good explanation:

https://www.codefull.org/2014/11/cimg-does-not-store-pixels-in-the-interleaved-format/

With the following code I was able to get the image in Cimg. The attached screenshots shows DNG on the left and the image exported to tiff from Cimg. The code works with 8bit and 16 bit DNG files:

LibRaw rawProcessor;
rawProcessor.imgdata.params.use_auto_wb         = 0;       
rawProcessor.imgdata.params.use_camera_wb       = 1;   
rawProcessor.imgdata.params.output_color        = 1;    
rawProcessor.imgdata.params.no_auto_bright      = 0;  

rawProcessor.open_file("file.dng");
int w = rawProcessor.imgdata.sizes.width;
int h = rawProcessor.imgdata.sizes.height;
rawProcessor.unpack();
int  ret2=rawProcessor.dcraw_process();
libraw_processed_image_t* image = rawProcessor.dcraw_make_mem_image(&ret2);

float xres=72.0;
CImg<unsigned char> cimgOriginal(image->data, 3, w, h, 1, true);
cimgOriginal.permute_axes("yzcx");
cimgOriginal.save_tiff("file.tiff", 0,
                       &xres,0,true);

dng_tiff_16bit