Inconsistent color results

Hi,

First off, thanks for the library and continued support. I have been using DCRAW for a couple of
years but recently I felt the need to jump the ship and turn to LibRaw. It seams like a solid solution but
I was experiencing some problems and it's gotta be something that I did wrong or a bug. So here it goes...

The procedure I have written is simple, it takes an image that is already loaded in memory and converts it to
a Windows Bitmap. I have supplied the entire function, but the bitmap part is fine. The problem I have appears
somewhere in the first 10 lines as I have placed a call to dcraw_ppm_tiff_writer() and the output is not consistent.
On occasions,the image is loaded just fine, but most of the time, the result I get is dominantly RED or GREEN and
I can't figure out the problem.

I am using VS2013 Express for this.

Does anybody see what might have been wrong? Thanks in advance!

P.S. Test images I use are:
http://www.rawsamples.ch/raws/nikon/d3x/RAW_NIKON_D3X.NEF (comes out red)
http://www.rawsamples.ch/raws/canon/1dsm2/RAW_CANON_1DSM2.CR2 (comes out green)

// INPUT ARGUMENTS:
// lpData: in - source buffer
// uSize:  in - source buffer size
// Point:  out - width & height
//
// RETURN: Windows Bitmap
//
extern "C" DLLEXPORT HBITMAP RawLoad(void* lpData, DWORD uSize, POINT* Point)
{
	LibRaw raw;
	libraw_processed_image_t *image = NULL;
	HBITMAP hBmp = NULL;
 
	if (raw.open_buffer(lpData, uSize) != LIBRAW_SUCCESS) return NULL;
 
	raw.imgdata.params.half_size = 1;
	raw.imgdata.params.user_flip = 0;
	if (raw.unpack() != LIBRAW_SUCCESS) return NULL;
	if (raw.dcraw_process() != LIBRAW_SUCCESS) return NULL;
 
	// for debugging purposes
	raw.dcraw_ppm_tiff_writer("test.ppm");
 
	image = raw.dcraw_make_mem_image();
	if (image == NULL) return NULL;
 
	BITMAPINFO BitmapInfo;
	ZeroMemory(&BitmapInfo, sizeof BITMAPINFO);
	BitmapInfo.bmiHeader.biCompression = BI_RGB;
	BitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	BitmapInfo.bmiHeader.biPlanes = 1;
	BitmapInfo.bmiHeader.biBitCount = 32;
	BitmapInfo.bmiHeader.biWidth = image->width;
	Point->x = image->width;
	BitmapInfo.bmiHeader.biHeight = -image->height;
	Point->y = image->height;
 
	HDC hDC = GetDC(NULL);
	unsigned char* lpDib;
	hBmp = CreateDIBSection(hDC, &BitmapInfo, DIB_RGB_COLORS, (void**)&lpDib, NULL, NULL);
	ReleaseDC(NULL, hDC);
	if (hBmp == NULL) return NULL;
	if (&lpDib == NULL) return NULL;
 
	int i;
	unsigned char * src = image->data;
	unsigned char * dest = lpDib;
	for (i = image->data_size/3; --i; dest += 4, src += 3)
	{
		dest[0] = src[2];
		dest[1] = src[1];
		dest[2] = src[0];
		dest[3] = 0;
	}
	for (i = 0; i < 3; ++i)
	{
		dest[i] = src[i];
	}
	raw.dcraw_clear_mem(image);
	return hBmp;
}

Forums: 

Could you please specify,

Could you please specify, where you get incorrect colors: in .ppm-file written by LibRaw or in your Bitmap?

-- Alex Tutubalin

Hi Alex,

Hi Alex,

Initially I thought the false color is my wrong and that is why I have put in the dcraw_ppm_tiff_writer("test.ppm") line in the code and the output is corrupted.

I am now trying the C interface and MingW. I will soon know if the problem persists.

P.S. Please consider exposing copy_mem_image() in C API, it will save a lot of memory copying from one buffer to another.

Do you use same compiler

Do you use same compiler settings (esp. structure fields alignment) in LibRaw compilation and your app compilation.
If structures are aligned differently, you may think you use params.half_size, but really change other structure field.

Try to use default settings (i.e. no raw.imgdata.params.... assignment).

I've tried both your samples without any problem (using dcraw_emu LibRaw sample with -mem switch to use open_buffer() interface)

-- Alex Tutubalin

Hey Alex, I have found the

Hey Alex, I have found the problem!

As you are familiar with DCRAW and changes you've made, does it use any MMX or FPU asm code?

In my code I use FPU which is correctly initialized using the FNINIT instruction. I have found it that if I write
FNINIT or EMMS at the end of my FPU block the problem goes away and LibRaw functions as intended.

This is why I suspect some LibRaw or more likely dcraw block is not initialized with FNINIT for FPU or EMMS for MMX.

I have noticed this because the first time I use LibRaw everything works fine but the second time I try to load an image that is when everything goes green or red. Then I started commenting out code suspecting of some memory corruption until I got to FPU.

There is no ASM/intrinsinc

There is no ASM/intrinsinc code in LibRaw. Just pure C++.
The problem may relate to different MMX/SSE conventions (compiler settings) in your app and in LibRaw.
Do you recompile LibRaw or use pre-compiled DLLs from this site?

-- Alex Tutubalin

I use the pre-compiled DLL

I use the pre-compiled DLL and I have settled with calling FNINIT right before I call the procedure with LibRaw code and it works perfectly.

I guess the compiler made some assumptions (that it shouldn't have?) and the generated code is probably MMX because that and FPU do no mix well without clearing flags in between.

Not too many people will experience this problem as assembly is falling out of use so I don't know if and where this should be documented in LibRaw or if VS2010 can be told to optimize for SSE (it does not have this incompatibility) instead for MMX which I suspect is the case.

The binary libraw.dll is

The binary libraw.dll is compiled using nmake -f Makefile.msvc (this Makefile is also included into distribution) using
MSVC 2010 with current patches/serivice packs.

You may easily recompile this DLL with compiler flags you want to use

-- Alex Tutubalin