summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/hardware/Camera.java22
-rw-r--r--core/jni/android_hardware_Camera.cpp43
2 files changed, 64 insertions, 1 deletions
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index dd15d38..16727fe 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -1147,7 +1147,16 @@ public class Camera {
// Set to oneshot mode again.
setHasPreviewCallback(true, false);
}
- pCb.onPreviewFrame((byte[])msg.obj, mCamera);
+
+ byte[] luminances = (byte[])msg.obj;
+ if(getParameters().getPreviewFormat() == ImageFormat.RGB_565)
+ // Convert to greyscale
+ // Apps expect YUV as default format. Greyscale is
+ // only the first layer of YUV, but it's all that's
+ // needed by barcode scanner apps.
+ rgbToBw(luminances);
+
+ pCb.onPreviewFrame(luminances, mCamera);
}
return;
@@ -1216,6 +1225,17 @@ public class Camera {
}
}
+ private void rgbToBw(byte[] pixels)
+ {
+ Size previewsize = getParameters().getPreviewSize();
+ int height = previewsize.height;
+ int width = previewsize.width;
+
+ native_rgbToBw(pixels, width, height);
+ }
+
+ private native void native_rgbToBw(byte[] pixelBuffer, int bufWidth, int bufHeight);
+
private static void postEventFromNative(Object camera_ref,
int what, int arg1, int arg2, Object obj)
{
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 4cf317e..3bb6af3 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -79,6 +79,8 @@ struct fields_t {
static fields_t fields;
static Mutex sLock;
+int bwDataSize = 0;
+
// provides persistent context for calls from native code to Java
class JNICameraContext: public CameraListener
{
@@ -933,6 +935,44 @@ static jstring android_hardware_Camera_getParameters(JNIEnv *env, jobject thiz)
return env->NewStringUTF(params8.string());
}
+static void android_hardware_Camera_rgbToBw(JNIEnv *env, jobject thiz, jbyteArray pixelBuffer, jint bufWidth, jint bufHeight)
+{
+ int width = bufWidth;
+ int height = bufHeight;
+ int size = width * height;
+
+ static jbyte* pixeldata;
+ static jbyte* luminances;
+
+ if(bwDataSize != size) {
+ pixeldata = (jbyte *)malloc(size*2);
+ luminances = (jbyte *)malloc(size);
+ bwDataSize = size;
+ ALOGV("Allocated buffer of size %d", size);
+ }
+
+ env->GetByteArrayRegion(pixelBuffer, 0, size*2, pixeldata);
+
+ // Convert the entire image to grayscale
+ for (int y = 0; y < height; y++) {
+ int offset = y * width *2;
+ for (int x = 0; x < width *2; x+=2) {
+ jbyte pixel = pixeldata[offset +x];
+ jbyte pixel2 = pixeldata[offset +x + 1];
+ // little endian
+ // GGGBBBBB | RRRRRGGG
+ jbyte b = (jbyte)(pixel & 0x1f); // 5 bits
+ jbyte g = (jbyte)(((pixel >> 5) & 0x07) | ((pixel2 & 0x07) << 3)); // 6 bits
+ jbyte r = (jbyte)((pixel2 >> 3) & 0x1f); // 5 bits
+
+ // Calculate luminance cheaply, favoring green.
+ luminances[(offset + x)/2] = (jbyte)((r + g + b) << 1);
+ }
+ }
+
+ env->SetByteArrayRegion(pixelBuffer, 0, size, luminances);
+}
+
static void android_hardware_Camera_reconnect(JNIEnv *env, jobject thiz)
{
ALOGV("reconnect");
@@ -1146,6 +1186,9 @@ static JNINativeMethod camMethods[] = {
{ "native_getParameters",
"()Ljava/lang/String;",
(void *)android_hardware_Camera_getParameters },
+ { "native_rgbToBw",
+ "([BII)V",
+ (void *)android_hardware_Camera_rgbToBw },
{ "reconnect",
"()V",
(void*)android_hardware_Camera_reconnect },