Always getting bayer pattern

Hey,

So I'm trying to use dcraw_make_mem_image and display the data as an Android Bitmap. Bitmaps expect ARGB at 8 bits per channel.

I start by calling method and pass in a Java string:

// C
JNIEXPORT jbyteArray JNICALL
Java_xyz_jamescarroll_layer_NativeWrapper_extractRaw(JNIEnv *env, jclass type, jstring path_) {
    const char *path = (*env)->GetStringUTFChars(env, path_, 0);
    void *re = createClass(); // RawExtractor
    libraw_processed_image_t *image_t = extractPreview(path, re); 
    jbyteArray out = (*env)->NewByteArray(env, image_t->data_size);
 
    logProcessedImageInfo(image_t);
 
    (*env)->ReleaseStringUTFChars(env, path_, path);
    (*env)->SetByteArrayRegion(env, out, 0, image_t->data_size, (const jbyte *) image_t->data);
 
    destroyClass(re); // RawExtractor
 
    return out;
}

The above code creates a class called RawExtractor and calls RawExtractor::ExtractRgbBitmap. Then it set the data to a java byte array and returns the array.

// C++
libraw_processed_image_t* RawExtractor::extractRgbBitmap(const char *filename, int shouldProcess) {
    int err = 0;
 
    if (shouldProcess) {
        process(filename);
    }
 
    rgbBitmap = imgProc.dcraw_make_mem_image(&err);
 
    if (err != LIBRAW_SUCCESS) {
        LOGE("Can't copy image as RGB Bitmap %s: %s", filename, libraw_strerror(err));
    }
}
 
void RawExtractor::process(const char *filename) {
#define OUT imgProc.imgdata.params
    int err = 1;
 
    OUT.no_auto_bright = 1;
    OUT.use_auto_wb = 0;
    OUT.use_camera_wb = 1;
    OUT.output_color = 1;
    OUT.user_qual = 3;
    OUT.half_size = 1;
    OUT.output_bps = 8;
 
    if ((err = imgProc.open_file(filename)) != LIBRAW_SUCCESS) {
        LOGE("Can't open %s: %s", filename, libraw_strerror(err));
        return;
    }
 
    if ((err = imgProc.unpack()) != LIBRAW_SUCCESS) {
        LOGE("Can't unpack %s: %s", filename, libraw_strerror(err));
        return;
    }
    if ((err = imgProc.dcraw_process()) != LIBRAW_SUCCESS) {
        LOGE("Can't process %s: %s", filename, libraw_strerror(err));
        return;
    }
}

When the array is returned to java I convert the data (libraw_processed_image_t.data) to an int array of colors and create a bitmap.

// Java
    public static Bitmap createFromColorChannels(byte[] channels, int width, int height) {
        int[] color = new int[channels.length / 3];
 
        for (int i = 0; i < color.length; i++) {
            color[i] = Color.rgb(channels[i], channels[i + 1], channels[i + 2]);
        }
 
        return Bitmap.createBitmap(color, width, height, Bitmap.Config.ARGB_8888);
    }

This seems to always create a bitmap with a bayer pattern: Original DNG vs Android Bitmap.

1.) Do you know why this might be happening?

2.) When calling dcraw_make_mem_image (or even copy_mem_image) the libraw_processed_image_t.data order is [R (0), G (0), B (0), R (1), G (1), B (1)] where (n) is the nth pixel, right? Does this change when the output is 16 bits since a char may only be 8 bits on some platforms? If so, what does the order look like?

Forums: 

dcraw_make_mem_image()

dcraw_make_mem_image() creates 24-bit RGB, not 32-bit ARGB

-- Alex Tutubalin

The following code creates 32

The following code creates 32 bit ARGB:

public static Bitmap createFromColorChannels(byte[] channels, int width, int height) {
        int[] color = new int[channels.length / 3];
 
        for (int i = 0; i < color.length; i++) {
            color[i] = Color.rgb(channels[i], channels[i + 1], channels[i + 2]);
        }
 
        ...

BTW, is byte type signed or

BTW, is byte type signed or unsigned?

Your image sample is not bayer patten, but something strange (in bayer pattern you'll see image, may be with wrong colors or reduced brigtness, but image subject will be visible).

Most likely, this is signed/unsigned conversion problem, or wrong row stride.

Use samples/mem-image.cpp as an example of dcraw_make_mem_image() call, make sure this example can process your DNG, than modify this code for your needs.

-- Alex Tutubalin

I tried mem-image.cpp (from

I tried mem-image.cpp (from terminal writing to ppm) and it worked, which means it probably is an issue when converting to Java. Byte is signed because all java data types are signed however, when casting to an int you can get the unsigned value by using & 0xFF on the byte. If I do this, or just use an int[] instead of a byte[], I lose the yellow color (new image).

When calling dcraw_make_mem

When calling dcraw_make_mem_image (or even copy_mem_image) the libraw_processed_image_t.data order is [R (0), G (0), B (0), R (1), G (1), B (1)] where (n) is the nth pixel, right? Does this change when the output is 16 bits since a char may only be 8 bits on some platforms? If so, what does the order look like?

copy_mem_image() is called

copy_mem_image() is called from dcraw_make_mem_image() with bgr parameter set to 0.

So, the order is always RGB

-- Alex Tutubalin