17f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project/* 27f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 37f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project * 47f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 57f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project * you may not use this file except in compliance with the License. 67f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project * You may obtain a copy of the License at 77f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project * 87f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 97f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project * 107f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 117f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 127f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project * See the License for the specific language governing permissions and 147f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project * limitations under the License. 157f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project */ 167f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 177f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project#include <stdlib.h> 187f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project#include <stdio.h> 197f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project#include <fcntl.h> 207f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project#include <unistd.h> 217f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 227f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project#include <utils/misc.h> 237f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project#include <utils/String8.h> 247f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project#include <utils/Log.h> 257f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 267f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project#include <core/SkBitmap.h> 277f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 287f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project#include "jni.h" 297f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project#include "JNIHelp.h" 307f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project#include "android_runtime/AndroidRuntime.h" 317f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 327f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Projectusing namespace android; 337f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 347f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Projectextern "C" 357f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project{ 367f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project #include <fd_emb_sdk.h> 377f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project} 387f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 397f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Projectstruct FaceData 407f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project{ 417f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project float confidence; 427f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project float midpointx; 437f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project float midpointy; 447f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project float eyedist; 457f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project}; 467f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 477f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Projectstruct FaceOffsets 487f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project{ 497f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jfieldID confidence; 507f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jfieldID midpointx; 517f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jfieldID midpointy; 527f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jfieldID eyedist; 537f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jfieldID eulerx; 547f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jfieldID eulery; 557f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jfieldID eulerz; 567f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project} gFaceOffsets; 577f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 587f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Projectstruct FaceDetectorOffsets 597f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project{ 607f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jfieldID fd; 617f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jfieldID sdk; 627f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jfieldID dcr; 637f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jfieldID width; 647f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jfieldID height; 657f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jfieldID maxFaces; 667f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jfieldID bwbuffer; 677f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project} gFaceDetectorOffsets; 687f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 697f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source ProjectjfieldID nativeBitmapID; 707f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 717f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project// --------------------------------------------------------------------------- 727f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 737f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Projectstatic void getFaceData(btk_HDCR hdcr, FaceData* fdata) 747f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project{ 757f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_Node leftEye, rightEye; 767f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 777f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_DCR_getNode(hdcr, 0, &leftEye); 787f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_DCR_getNode(hdcr, 1, &rightEye); 797f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 807f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project fdata->eyedist = (float)(rightEye.x - leftEye.x) / (1 << 16); 817f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project fdata->midpointx = (float)(rightEye.x + leftEye.x) / (1 << 17); 827f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project fdata->midpointy = (float)(rightEye.y + leftEye.y) / (1 << 17); 837f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project fdata->confidence = (float)btk_DCR_confidence(hdcr) / (1 << 24); 847f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project} 857f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 867f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project// --------------------------------------------------------------------------- 877f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 887f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Projectstatic void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL) 897f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project{ 907f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jclass npeClazz = env->FindClass(exc); 917f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project env->ThrowNew(npeClazz, msg); 927f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project} 937f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 947f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Projectstatic void 957f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source ProjectnativeClassInit 967f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project(JNIEnv *_env, jclass _this) 977f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project{ 987f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project gFaceDetectorOffsets.fd = _env->GetFieldID(_this, "mFD", "I"); 997f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project gFaceDetectorOffsets.sdk = _env->GetFieldID(_this, "mSDK", "I"); 1007f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project gFaceDetectorOffsets.dcr = _env->GetFieldID(_this, "mDCR", "I"); 1017f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project gFaceDetectorOffsets.width = _env->GetFieldID(_this, "mWidth", "I"); 1027f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project gFaceDetectorOffsets.height = _env->GetFieldID(_this, "mHeight", "I"); 1037f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project gFaceDetectorOffsets.maxFaces = _env->GetFieldID(_this, "mMaxFaces", "I"); 1047f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project gFaceDetectorOffsets.bwbuffer = _env->GetFieldID(_this, "mBWBuffer", "[B"); 1057f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 1067f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jclass faceClass = _env->FindClass("android/media/FaceDetector$Face"); 1077f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project gFaceOffsets.confidence = _env->GetFieldID(faceClass, "mConfidence", "F"); 1087f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project gFaceOffsets.midpointx = _env->GetFieldID(faceClass, "mMidPointX", "F"); 1097f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project gFaceOffsets.midpointy = _env->GetFieldID(faceClass, "mMidPointY", "F"); 1107f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project gFaceOffsets.eyedist = _env->GetFieldID(faceClass, "mEyesDist", "F"); 1117f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project gFaceOffsets.eulerx = _env->GetFieldID(faceClass, "mPoseEulerX", "F"); 1127f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project gFaceOffsets.eulery = _env->GetFieldID(faceClass, "mPoseEulerY", "F"); 1137f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project gFaceOffsets.eulerz = _env->GetFieldID(faceClass, "mPoseEulerZ", "F"); 1147f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 1157f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jclass bitmapClass = _env->FindClass("android/graphics/Bitmap"); 1167f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project nativeBitmapID = _env->GetFieldID(bitmapClass, "mNativeBitmap", "I"); 1177f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project} 1187f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 1197f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project// --------------------------------------------------------------------------- 1207f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 1217f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Projectstatic jint 1227f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Projectinitialize(JNIEnv *_env, jobject _this, 1237f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jint w, jint h, jint maxFaces) 1247f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project{ 1257f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project // load the configuration file 1267f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project const char* root = getenv("ANDROID_ROOT"); 1277f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project String8 path(root); 1287f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project path.appendPath("usr/share/bmd/RFFstd_501.bmd"); 1297f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project // path.appendPath("usr/share/bmd/RFFspeed_501.bmd"); 1307f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 1317f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project const int MAX_FILE_SIZE = 65536; 1327f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project void* initData = malloc( MAX_FILE_SIZE ); /* enough to fit entire file */ 1337f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project int filedesc = open(path.string(), O_RDONLY); 1347f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project int initDataSize = read(filedesc, initData, MAX_FILE_SIZE); 1357f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project close(filedesc); 1367f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 1377f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project // -------------------------------------------------------------------- 1387f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_HSDK sdk = NULL; 1397f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_SDKCreateParam sdkParam = btk_SDK_defaultParam(); 1407f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project sdkParam.fpMalloc = malloc; 1417f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project sdkParam.fpFree = free; 1427f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project sdkParam.maxImageWidth = w; 1437f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project sdkParam.maxImageHeight = h; 1447f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 1457f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_Status status = btk_SDK_create(&sdkParam, &sdk); 1467f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project // make sure everything went well 1477f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project if (status != btk_STATUS_OK) { 1487f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project // XXX: be more precise about what went wrong 1497f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project doThrow(_env, "java/lang/OutOfMemoryError", NULL); 1507f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project return 0; 1517f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project } 1527f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 1537f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_HDCR dcr = NULL; 1547f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_DCRCreateParam dcrParam = btk_DCR_defaultParam(); 1557f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_DCR_create( sdk, &dcrParam, &dcr ); 1567f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 1577f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_HFaceFinder fd = NULL; 1587f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_FaceFinderCreateParam fdParam = btk_FaceFinder_defaultParam(); 1597f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project fdParam.pModuleParam = initData; 1607f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project fdParam.moduleParamSize = initDataSize; 1617f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project fdParam.maxDetectableFaces = maxFaces; 1627f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project status = btk_FaceFinder_create( sdk, &fdParam, &fd ); 1637f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_FaceFinder_setRange(fd, 20, w/2); /* set eye distance range */ 1647f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 1657f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project // make sure everything went well 1667f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project if (status != btk_STATUS_OK) { 1677f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project // XXX: be more precise about what went wrong 1687f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project doThrow(_env, "java/lang/OutOfMemoryError", NULL); 1697f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project return 0; 1707f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project } 1717f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 1727f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project // free the configuration file 1737f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project free(initData); 1747f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 1757f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project // initialize the java object 1767f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project _env->SetIntField(_this, gFaceDetectorOffsets.fd, (jint)fd); 1777f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project _env->SetIntField(_this, gFaceDetectorOffsets.sdk, (jint)sdk); 1787f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project _env->SetIntField(_this, gFaceDetectorOffsets.dcr, (jint)dcr); 1797f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 1807f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project return 1; 1817f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project} 1827f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 1837f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Projectstatic void 1847f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Projectdestroy(JNIEnv *_env, jobject _this) 1857f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project{ 1867f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_HFaceFinder hfd = 1877f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project (btk_HFaceFinder)(_env->GetIntField(_this, gFaceDetectorOffsets.fd)); 1887f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_FaceFinder_close( hfd ); 1897f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 1907f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_HDCR hdcr = (btk_HDCR)(_env->GetIntField(_this, gFaceDetectorOffsets.dcr)); 1917f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_DCR_close( hdcr ); 1927f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 1937f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_HSDK hsdk = (btk_HSDK)(_env->GetIntField(_this, gFaceDetectorOffsets.sdk)); 1947f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_SDK_close( hsdk ); 1957f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project} 1967f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 1977f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Projectstatic jint 1987f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Projectdetect(JNIEnv *_env, jobject _this, 1997f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jobject bitmap) 2007f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project{ 2017f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project // get the fields we need 2027f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_HDCR hdcr = (btk_HDCR)(_env->GetIntField(_this, gFaceDetectorOffsets.dcr)); 2037f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_HFaceFinder hfd = 2047f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project (btk_HFaceFinder)(_env->GetIntField(_this, gFaceDetectorOffsets.fd)); 2057f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project u32 maxFaces = _env->GetIntField(_this, gFaceDetectorOffsets.maxFaces); 2067f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project u32 width = _env->GetIntField(_this, gFaceDetectorOffsets.width); 2077f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project u32 height = _env->GetIntField(_this, gFaceDetectorOffsets.height); 2087f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 2097f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jbyteArray bwbufferObject = (jbyteArray) 2107f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project _env->GetObjectField(_this, gFaceDetectorOffsets.bwbuffer); 2117f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 2127f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project // get to the native bitmap 2137f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project SkBitmap const * nativeBitmap = 2147f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project (SkBitmap const *)_env->GetIntField(bitmap, nativeBitmapID); 2157f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 2167f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project // get to our BW temporary buffer 2177f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jbyte* bwbuffer = _env->GetByteArrayElements(bwbufferObject, 0); 2187f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 2197f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project // convert the image to B/W 2207f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project uint8_t* dst = (uint8_t*)bwbuffer; 2217f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 2227f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project // manage the life-time of locking our pixels 2237f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project SkAutoLockPixels alp(*nativeBitmap); 2247f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 2257f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project uint16_t const* src = (uint16_t const*)nativeBitmap->getPixels(); 2267f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project int wpr = nativeBitmap->rowBytes() / 2; 2277f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project for (u32 y=0 ; y<height; y++) { 2287f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project for (u32 x=0 ; x<width ; x++) { 2297f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project uint16_t rgb = src[x]; 2307f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project int r = rgb >> 11; 2317f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project int g2 = (rgb >> 5) & 0x3F; 2327f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project int b = rgb & 0x1F; 2337f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project // L coefficients 0.299 0.587 0.11 2347f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project int L = (r<<1) + (g2<<1) + (g2>>1) + b; 2357f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project *dst++ = L; 2367f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project } 2377f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project src += wpr; 2387f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project } 2397f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 2407f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project // run detection 2417f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_DCR_assignGrayByteImage(hdcr, bwbuffer, width, height); 2427f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 2437f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project int numberOfFaces = 0; 2447f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project if (btk_FaceFinder_putDCR(hfd, hdcr) == btk_STATUS_OK) { 2457f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project numberOfFaces = btk_FaceFinder_faces(hfd); 246b493ba27fc74ccf339f88a48b29b4fccaf651b86Gloria Wang } else { 2477f22db82120e7ac17165ab7614e417baa2742623Steve Block ALOGE("ERROR: Return 0 faces because error exists in btk_FaceFinder_putDCR.\n"); 2487f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project } 2497f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 2507f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project // release the arrays we're using 2517f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project _env->ReleaseByteArrayElements(bwbufferObject, bwbuffer, 0); 2527f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project return numberOfFaces; 2537f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project} 2547f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 2557f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Projectstatic void 2567f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Projectget_face(JNIEnv *_env, jobject _this, 2577f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jobject face, jint index) 2587f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project{ 2597f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_HDCR hdcr = (btk_HDCR)(_env->GetIntField(_this, gFaceDetectorOffsets.dcr)); 2607f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_HFaceFinder hfd = 2617f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project (btk_HFaceFinder)(_env->GetIntField(_this, gFaceDetectorOffsets.fd)); 2627f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 2637f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project FaceData faceData; 2647f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project btk_FaceFinder_getDCR(hfd, hdcr); 2657f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project getFaceData(hdcr, &faceData); 2667f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 2677f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project const float X2F = 1.0f / 65536.0f; 2687f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project _env->SetFloatField(face, gFaceOffsets.confidence, faceData.confidence); 2697f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project _env->SetFloatField(face, gFaceOffsets.midpointx, faceData.midpointx); 2707f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project _env->SetFloatField(face, gFaceOffsets.midpointy, faceData.midpointy); 2717f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project _env->SetFloatField(face, gFaceOffsets.eyedist, faceData.eyedist); 2727f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project _env->SetFloatField(face, gFaceOffsets.eulerx, 0); 2737f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project _env->SetFloatField(face, gFaceOffsets.eulery, 0); 2747f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project _env->SetFloatField(face, gFaceOffsets.eulerz, 0); 2757f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project} 2767f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 2777f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project// --------------------------------------------------------------------------- 2787f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 2797f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Projectstatic const char *classPathName = "android/media/FaceDetector"; 2807f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 2817f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Projectstatic JNINativeMethod methods[] = { 2827f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project{"nativeClassInit", "()V", (void*)nativeClassInit }, 2837f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project{"fft_initialize", "(III)I", (void*)initialize }, 2847f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project{"fft_detect", "(Landroid/graphics/Bitmap;)I", (void*)detect }, 2857f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project{"fft_get_face", "(Landroid/media/FaceDetector$Face;I)V",(void*)get_face }, 2867f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project{"fft_destroy", "()V", (void*)destroy }, 2877f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project}; 2887f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 2897f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Projectint register_android_media_FaceDetector(JNIEnv *_env) 2907f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project{ 2917f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project return android::AndroidRuntime::registerNativeMethods( 2927f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project _env, classPathName, methods, NELEM(methods)); 2937f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project} 2947f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 2957f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project// --------------------------------------------------------------------------- 2967f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 2977f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Projectjint JNI_OnLoad(JavaVM* vm, void* reserved) 2987f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project{ 2997f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project JNIEnv* env = NULL; 3007f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project jint result = -1; 3017f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 3027f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { 3037f22db82120e7ac17165ab7614e417baa2742623Steve Block ALOGE("ERROR: GetEnv failed\n"); 3047f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project goto bail; 3057f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project } 3067f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project assert(env != NULL); 3077f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 3087f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project if (register_android_media_FaceDetector(env) < 0) { 3097f22db82120e7ac17165ab7614e417baa2742623Steve Block ALOGE("ERROR: MediaPlayer native registration failed\n"); 3107f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project goto bail; 3117f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project } 3127f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 3137f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project /* success -- return valid version number */ 3147f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project result = JNI_VERSION_1_4; 3157f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project 3167f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Projectbail: 3177f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project return result; 3187f81d9b6fa7f2ec161b682622db577a28c90b49fThe Android Open Source Project} 319