Convert processed raw to bitmap does not work well

Hi!

According to documentation which for dcraw_make_mem_image says:
This function allocates memory buffer and stores unpacked-preprocessed image into this buffer. Function returns allocated structure libraw_processed_image_t with filled fields. Always returns data as RGB bitmap
I am trying to save the image from buffer as a bitmap image.

Here are the exact steps I am doing (using the Libraw C wrapper):
1. libraw_init
2. libraw_open_file - opening a Canon CR2 file
3. libraw_unpack
4. libraw_dcraw_process
5. libraw_dcraw_make_mem_image - returns the structure libraw_processed_image_t
6. using the data, data_size fields from libraw_processed_image_t structure I am creating a 24BitsPerPixel bitmap having dimensions defined by width/height from the structure and saving it.
7. libraw_dcraw_clear_mem
8. libraw_close

Everything works without any error, but the result picture after opening is somehow wrong.

Orignal picture from CR2 file:
https://imgur.com/a/bM8bhCE

Converted and saved bitmap:
https://imgur.com/4s6hPmt

As you can see, the bitmap is B/W and somehow distorted.
Any idea?

BR,

Ladislav

Forums: 

Does mem_image_sample.cpp work

Does mem_image_sample.cpp work as expected with this file?

-- Alex Tutubalin @LibRaw LLC

Yes, it creates a PPM file.

Yes, it creates a PPM file.
But what I would like is to create a simple BMP format.

Sorry, know nothing about C#

Sorry, know nothing about C# and Windows bitmap.

According to your screenshots, there is 'line sync' error. Is there any possibility that source data for bitmap should have every row aligned (on 4 or 16 or whatever bytes)?

I do not know why your result is monochrome (never seen your code and, again, know nothing about C#). LibRaw output is definitely not, according to your test w/ PPM write.

-- Alex Tutubalin @LibRaw LLC

It's not about C#. I am just

It's not about C#. I am just calling the C methods provided by Libraw. I do not even change the bytes in data field of libraw_processed_image_t, just simply copying it to the memory allocated for Windows Bitmap.

BTW I forgot to mention that also using following Libraw setter methods for process:
libraw_set_output_bps -> 8
libraw_set_output_color -> 0

Update:
Also tried the libraw_dcraw_ppm_tiff_writer method using TIFF option which creates a correct, color TIFF file!

If windows bitmap rows are

If windows bitmap rows are aligned full data copy (not per-line copy) will result into 'lost sync' image, because libraw_processed_image_t data is not aligned, but rows are packed w/o gaps.

-- Alex Tutubalin @LibRaw LLC

According to Remarks of this

According to Remarks section of this page:
The stride is the width of a single row of pixels (a scan line), rounded up to a four-byte boundary. If the stride is positive, the bitmap is top-down. If the stride is negative, the bitmap is bottom-up.
So maybe yes, it could be an alignment problem. Otherwise I have no idea, why it doesn't work.

Finally I figured out how to

Finally I figured out how to correctly dump memory image to Windows Bitmap file.
Simple we need add some padding bytes after each line before saving to Bitmap.

Number of padding bytes is given by following formula:

num = img.width mod 4

Since I did everything in C# language, including a wrapper around LibRaw library, I can provide only C# sample code:

var num = img.width % 4;
var padding = new byte[num];
var stride = img.width * img.colors * (img.bits / 8);
var line = new byte[stride];
var tmp = new List<byte>();
for (var i = 0; i < img.height; i++) {
        // BlockCopy: src, srcIndex, dst, dstIndex, count
	Buffer.BlockCopy(img.data, stride * i, line, 0, stride);
	tmp.AddRange(line);
	tmp.AddRange(padding);
}
tmp.ToArray(); // this will contain the correct data ready for export to Bitmap