diff options
-rw-r--r-- | core/java/android/hardware/Camera.java | 22 | ||||
-rw-r--r-- | core/jni/android_hardware_Camera.cpp | 43 |
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 }, |