blob: 4d247ab73f7c65256b3e7b7d534538cbd2b3294f [file] [log] [blame]
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "com_android_cts_verifier_camera_analyzer_ColorChecker.h"
#include "utils/Log.h"
#include "android/bitmap.h"
#include "colorchecker.h"
jboolean Java_com_android_cts_verifier_camera_analyzer_ColorChecker_findNative(
JNIEnv* env,
jobject thiz,
jobject inputBitmap) {
// Verify that we can handle the input bitmap
AndroidBitmapInfo inputInfo;
AndroidBitmap_getInfo(env, inputBitmap, &inputInfo);
if (inputInfo.format != ANDROID_BITMAP_FORMAT_RGBA_8888 &&
inputInfo.format != ANDROID_BITMAP_FORMAT_RGB_565) {
LOGE("Only RGBA_8888 and RGB_565 bitmaps are supported, was given type %d.", inputInfo.format);
return JNI_FALSE;
}
// Get some references to the fields and class type of ColorChecker
jclass thizCls = env->GetObjectClass(thiz);
jfieldID patchId = env->GetFieldID(thizCls, "mPatchValues", "[F");
jfieldID outputId = env->GetFieldID(thizCls, "mDebugOutput", "Landroid/graphics/Bitmap;");
jfloatArray patchValues = (jfloatArray)env->GetObjectField(thiz, patchId);
// Get raw inputs and outputs ready
uint8_t *inputBuffer;
int result = AndroidBitmap_lockPixels(
env,
inputBitmap,
reinterpret_cast<void**>(&inputBuffer) );
if (result != ANDROID_BITMAP_RESUT_SUCCESS) {
LOGE("Unable to lock input bitmap");
return JNI_FALSE;
}
float *patchRawArray = env->GetFloatArrayElements(patchValues,
NULL);
uint8_t *outputImage = NULL;
int outputWidth, outputHeight;
// Find the color checker
bool success;
uint8_t *inputBufferRGBA = NULL;
int inputStride;
bool freeInputRGBA = false;
switch (inputInfo.format) {
case ANDROID_BITMAP_FORMAT_RGB_565: {
// First convert to RGBA_8888
inputBufferRGBA = new uint8_t[inputInfo.width *
inputInfo.height *
4];
inputStride = inputInfo.width * 4;
uint8_t *outP = inputBufferRGBA;
for (int y = 0; y < inputInfo.height; y++ ) {
uint16_t *inP = (uint16_t*)(&inputBuffer[y * inputInfo.stride]);
for (int x = 0; x < inputInfo.width; x++) {
*(outP++) = ( ((*inP) >> 0) & 0x001F) << 3;
*(outP++) = ( ((*inP) >> 5) & 0x003F) << 2;
*(outP++) = ( ((*inP) >> 11) & 0x001F) << 3;
outP++;
inP++;
}
}
freeInputRGBA = true;
break;
}
case ANDROID_BITMAP_FORMAT_RGBA_8888:
// Already in RGBA
inputBufferRGBA = inputBuffer;
inputStride = inputInfo.stride;
break;
}
success = findColorChecker(inputBufferRGBA,
inputInfo.width,
inputStride,
inputInfo.height,
patchRawArray,
&outputImage,
&outputWidth,
&outputHeight);
// Clean up raw inputs/outputs
env->ReleaseFloatArrayElements(patchValues, patchRawArray, 0);
result = AndroidBitmap_unlockPixels(env, inputBitmap);
if (result != ANDROID_BITMAP_RESUT_SUCCESS) {
LOGE("Unable to unlock input bitmap");
return JNI_FALSE;
}
if (freeInputRGBA) {
delete inputBufferRGBA;
}
// Create debug bitmap from output image data
if (outputImage != NULL) {
// Get method handles, create inputs to createBitmap
jclass bitmapClass =
env->FindClass("android/graphics/Bitmap");
jclass bitmapConfigClass =
env->FindClass("android/graphics/Bitmap$Config");
jmethodID createBitmap = env->GetStaticMethodID(
bitmapClass, "createBitmap",
"(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
jmethodID getConfig = env->GetStaticMethodID(
bitmapConfigClass, "valueOf",
"(Ljava/lang/String;)Landroid/graphics/Bitmap$Config;");
// Create bitmap config and bitmap
jstring bitmapConfigValue = env->NewStringUTF("ARGB_8888");
jobject rgbaConfig = env->CallStaticObjectMethod(bitmapConfigClass,
getConfig,
bitmapConfigValue);
jobject outputBitmap = env->CallStaticObjectMethod(bitmapClass,
createBitmap,
outputWidth,
outputHeight,
rgbaConfig);
// Copy output image into it
uint8_t *outputBuffer;
int result = AndroidBitmap_lockPixels(
env,
outputBitmap,
reinterpret_cast<void**>(&outputBuffer) );
if (result != ANDROID_BITMAP_RESUT_SUCCESS) {
LOGE("Unable to lock output bitmap");
return JNI_FALSE;
}
memcpy(outputBuffer, outputImage, outputWidth * outputHeight * 4);
result = AndroidBitmap_unlockPixels(env, outputBitmap);
if (result != ANDROID_BITMAP_RESUT_SUCCESS) {
LOGE("Unable to unlock output bitmap");
return JNI_FALSE;
}
// Write new Bitmap reference into mDebugOutput class member
env->SetObjectField(thiz, outputId, outputBitmap);
delete outputImage;
}
if (!success) return JNI_FALSE;
return JNI_TRUE;
}