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?
dcraw_make_mem_image()
dcraw_make_mem_image() creates 24-bit RGB, not 32-bit ARGB
-- Alex Tutubalin @LibRaw LLC
The following code creates 32
The following code creates 32 bit ARGB:
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 @LibRaw LLC
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 @LibRaw LLC