half_size and dcraw_make_mem_image()

AttachmentSize
Plain text icon dcraw.txt3.21 KB
Image icon first_image.jpg21.67 KB
Image icon next_images.jpg26.2 KB

Hi.

Thanks for LibRaw; it's a very convenient way to process raw images. However, I've run into a problem.

I'm using half_size = 1 to get small images without color interpolation fast,
and dcraw_make_mem_image() to get a copy in memory.

If I run this several times on the same image, the first image is different from the following images.

I've added a small test program, and sample images.

regards,

koen

Forums: 

Source of test program:

#ifdef WIN32
// suppress sprintf-related warning. sprintf() is permitted in sample code
#define _CRT_SECURE_NO_WARNINGS
#endif
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#ifndef WIN32
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/time.h>
#endif
 
#include "libraw/libraw.h"
#ifdef WIN32
#define snprintf _snprintf
#include <windows.h>
#endif
 
 
void write_ppm(libraw_processed_image_t *img, const char *basename)
{
    if(!img) return;
    // type SHOULD be LIBRAW_IMAGE_BITMAP, but we'll check
    if(img->type != LIBRAW_IMAGE_BITMAP) return;
    // only 3-color images supported...
    if(img->colors != 3) return;
 
    char fn[1024];
    snprintf(fn,1024,"%s.ppm",basename);
    FILE *f = fopen(fn,"wb");
    if(!f) return;
    fprintf (f, "P6\n%d %d\n%d\n", img->width, img->height, (1 << img->bits)-1);
/*
  NOTE:
  data in img->data is not converted to network byte order.
  So, we should swap values on some architectures for dcraw compatibility
  (unfortunately, xv cannot display 16-bit PPMs with network byte order data
 
#define SWAP(a,b) { a ^= b; a ^= (b ^= a); }
    if (img->bits == 16 && htons(0x55aa) != 0x55aa)
        for(unsigned i=0; i< img->data_size; i+=2)
            SWAP(img->data[i],img->data[i+1]);
#undef SWAP
*/
    fwrite(img->data,img->data_size,1,f);
    fclose(f);
}
 
int main(int argc, char *argv[])
{
	char filename[] = "raw_canon_550d.cr2";
	LibRaw rawProcessor_;
	int rc;
	for (int i = 0; i < 10; i++)
	{
		libraw_processed_image_t* rawImg = NULL;
		rc = rawProcessor_.open_file(filename);
		rc = rawProcessor_.unpack();
		rawProcessor_.imgdata.params.filtering_mode = LIBRAW_FILTERING_AUTOMATIC;
		rawProcessor_.imgdata.params.output_bps = 16; // Write 16 bits per color value
//		rawProcessor_.imgdata.params.gamm[0] = rawProcessor_.imgdata.params.gamm[1] = 1.0; // linear gamma curve
//		rawProcessor_.imgdata.params.no_auto_bright = 1; // Don't use automatic increase of brightness by histogram.
		rawProcessor_.imgdata.params.document_mode = 0; // standard processing (with white balance)
		rawProcessor_.imgdata.params.use_camera_wb = 1; // If possible, use the white balance from the camera.
		rawProcessor_.imgdata.params.half_size = 1;
		rc = rawProcessor_.dcraw_process();
		rawImg = rawProcessor_.dcraw_make_mem_image(&rc);
		char ppmfname[128];
		snprintf(ppmfname,1024,"%04i",i);
		write_ppm(rawImg, ppmfname);
		rawProcessor_.dcraw_clear_mem(rawImg);
		rawProcessor_.recycle();
	} 
	return 0;
}
//not truncated

Any idiot can face a crisis - it's day to day living that wears you out.
Anton Chekov

Thanks for bug report. It

Thanks for bug report.
It looks very strange for me because I use half_mode in my programs without any problem, but I'll test your code sample.

What version of LibRaw do you use?

-- Alex Tutubalin

I'm using LibRaw 0.13.1. I've

I'm using LibRaw 0.13.1. I've tested on Windows and macosx; and in each case there is a difference between the first and the second decoded image.

Any idiot can face a crisis - it's day to day living that wears you out.
Anton Chekov

The case is confirmed, your

The case is confirmed, your code really produces different first image (have not looked into it, but see by different MD5 sums).

Thanks again for your bug report. I'll write another comment here when bug will be fixed

-- Alex Tutubalin

Solved!

The problem is very simple:
- you have set half_size=1 *after* unpack is called. So for the very first run the half_size is not set for unpack stage but set for postprocessing stage.

But half_size option is heavily used on unpack() stage (only 1/4 of image array allocated, pixel data placement is very different).

You need to move
rawProcessor_.imgdata.params.half_size = 1;
line above of unpack() call.

-- Alex Tutubalin

Perfect, thank you!

Perfect, everything works. Thank you!

Any idiot can face a crisis - it's day to day living that wears you out.
Anton Chekov