1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* ---- includes ----------------------------------------------------------- */ 18 19 #include "FaceFinder_Internal.h" 20 21 /* ---- related objects --------------------------------------------------- */ 22 23 /* ---- typedefs ----------------------------------------------------------- */ 24 25 /* ---- constants ---------------------------------------------------------- */ 26 27 /* ------------------------------------------------------------------------- */ 28 29 /* ========================================================================= */ 30 /* */ 31 /* ---- functions ---------------------------------------------------------- */ 32 /* */ 33 /* ========================================================================= */ 34 35 /* ------------------------------------------------------------------------- */ 36 37 void btk_FaceFinder_init( struct bbs_Context* cpA, struct btk_FaceFinder* ptrA ) 38 { 39 ptrA->hsdkE = NULL; 40 ptrA->hidE = btk_HID_FF; 41 42 bpi_FaceFinderRef_init( cpA, &ptrA->ffE ); 43 44 ptrA->facesE = 0; 45 ptrA->faceIndexE = 0; 46 } 47 48 /* ------------------------------------------------------------------------- */ 49 50 void btk_FaceFinder_exit( struct bbs_Context* cpA, struct btk_FaceFinder* ptrA ) 51 { 52 ptrA->hsdkE = NULL; 53 ptrA->hidE = btk_HID_FF; 54 55 bpi_FaceFinderRef_exit( cpA, &ptrA->ffE ); 56 57 ptrA->facesE = 0; 58 ptrA->faceIndexE = 0; 59 } 60 61 /* ------------------------------------------------------------------------- */ 62 63 btk_FaceFinderCreateParam btk_FaceFinder_defaultParam() 64 { 65 btk_FaceFinderCreateParam paramL; 66 paramL.reserved = 0; 67 paramL.pModuleParam = NULL; 68 paramL.moduleParamSize = 0; 69 paramL.maxDetectableFaces = 0; 70 return paramL; 71 } 72 73 /* ------------------------------------------------------------------------- */ 74 75 btk_Status btk_FaceFinder_create( btk_HSDK hsdkA, /* sdk handle */ 76 const btk_FaceFinderCreateParam* pCreateParamA, 77 btk_HFaceFinder* hpFaceFinderA ) 78 { 79 const char* fNameL = "btk_FaceFinder_create"; 80 81 btk_HFaceFinder hFaceFinderL = NULL; 82 83 if( hpFaceFinderA == NULL ) return btk_STATUS_INVALID_HANDLE; 84 if( *hpFaceFinderA != NULL ) return btk_STATUS_INVALID_HANDLE; 85 if( hsdkA == NULL ) return btk_STATUS_INVALID_HANDLE; 86 if( hsdkA->hidE != btk_HID_SDK ) return btk_STATUS_INVALID_HANDLE; 87 if( pCreateParamA == NULL ) return btk_STATUS_INVALID_HANDLE; 88 if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; 89 90 hFaceFinderL = ( btk_HFaceFinder )bbs_MemSeg_alloc( &hsdkA->contextE, hsdkA->contextE.memTblE.espArrE[ 0 ], bbs_SIZEOF16( struct btk_FaceFinder ) ); 91 if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_ERROR; 92 93 btk_FaceFinder_init( &hsdkA->contextE, hFaceFinderL ); 94 if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_ERROR; 95 96 hFaceFinderL->hsdkE = hsdkA; 97 98 if( btk_SDK_paramConsistencyTest( hsdkA, pCreateParamA->pModuleParam, pCreateParamA->moduleParamSize, fNameL ) == btk_STATUS_ERROR ) return btk_STATUS_ERROR; 99 100 if( hsdkA->maxImageWidthE * hsdkA->maxImageHeightE == 0 ) 101 { 102 bbs_Context_pushError( &hsdkA->contextE, 103 bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nSDK parameter maxImageWidth or maxImageWidth is 0!\n" 104 "Since SDK version 1.3.0 the maximum image size must be specified when creating the SDK handle.\n" 105 "Set the values in *pCreateParamA when you call function btk_SDK_create.", fNameL ) ); 106 return btk_STATUS_ERROR; 107 } 108 109 bpi_FaceFinderRef_memRead( &hsdkA->contextE, 110 &hFaceFinderL->ffE, 111 hsdkA->maxImageWidthE, 112 hsdkA->maxImageHeightE, 113 pCreateParamA->pModuleParam, 114 &hsdkA->contextE.memTblE ); 115 116 if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_ERROR; 117 118 *hpFaceFinderA = hFaceFinderL; 119 hsdkA->refCtrE++; 120 121 return btk_STATUS_OK; 122 } 123 124 /* ------------------------------------------------------------------------- */ 125 126 btk_Status btk_FaceFinder_close( btk_HFaceFinder hFaceFinderA ) 127 { 128 btk_HSDK hsdkL = NULL; 129 if( hFaceFinderA == NULL ) return btk_STATUS_INVALID_HANDLE; 130 if( hFaceFinderA->hidE != btk_HID_FF ) return btk_STATUS_INVALID_HANDLE; 131 if( hFaceFinderA->hsdkE == NULL ) return btk_STATUS_INVALID_HANDLE; 132 hsdkL = hFaceFinderA->hsdkE; 133 if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; 134 135 hsdkL->refCtrE--; 136 137 btk_FaceFinder_exit( &hsdkL->contextE, hFaceFinderA ); 138 if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; 139 140 bbs_MemSeg_free( &hsdkL->contextE, hsdkL->contextE.memTblE.espArrE[ 0 ], hFaceFinderA ); 141 if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; 142 143 return btk_STATUS_OK; 144 } 145 146 /* ------------------------------------------------------------------------- */ 147 148 btk_Status btk_FaceFinder_setRange( btk_HFaceFinder hFaceFinderA, 149 u32 minDistA, 150 u32 maxDistA ) 151 { 152 btk_HSDK hsdkL = NULL; 153 if( hFaceFinderA == NULL ) return btk_STATUS_INVALID_HANDLE; 154 if( hFaceFinderA->hidE != btk_HID_FF ) return btk_STATUS_INVALID_HANDLE; 155 hsdkL = hFaceFinderA->hsdkE; 156 if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; 157 158 bpi_FaceFinderRef_setRange( &hsdkL->contextE, &hFaceFinderA->ffE, minDistA, maxDistA ); 159 if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; 160 161 return btk_STATUS_OK; 162 } 163 164 /* ------------------------------------------------------------------------- */ 165 166 btk_Status btk_FaceFinder_putDCR( btk_HFaceFinder hFaceFinderA, 167 btk_HDCR hdcrA ) 168 { 169 const char* fNameL = "btk_FaceFinder_putDCR"; 170 171 btk_HSDK hsdkL = NULL; 172 if( hFaceFinderA == NULL ) return btk_STATUS_INVALID_HANDLE; 173 if( hFaceFinderA->hidE != btk_HID_FF ) return btk_STATUS_INVALID_HANDLE; 174 if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; 175 hsdkL = hFaceFinderA->hsdkE; 176 if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; 177 178 if( hdcrA->dcrE.imageDataPtrE == NULL ) 179 { 180 bbs_Context_pushError( &hsdkL->contextE, 181 bbs_Error_create( bbs_ERR_ERROR, 0, NULL, 182 "%s:\nNo image was assigned to data carrier", fNameL ) ); 183 } 184 185 hFaceFinderA->facesE = bpi_FaceFinderRef_putDcr( &hsdkL->contextE, 186 &hFaceFinderA->ffE, 187 &hdcrA->dcrE ); 188 189 hFaceFinderA->faceIndexE = 0; 190 if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; 191 192 return btk_STATUS_OK; 193 } 194 195 /* ------------------------------------------------------------------------- */ 196 197 u32 btk_FaceFinder_faces( btk_HFaceFinder hFaceFinderA ) 198 { 199 if( hFaceFinderA == NULL ) return 0; 200 if( hFaceFinderA->hidE != btk_HID_FF ) return 0; 201 return hFaceFinderA->facesE - hFaceFinderA->faceIndexE; 202 } 203 204 /* ------------------------------------------------------------------------- */ 205 206 btk_Status btk_FaceFinder_getDCR( btk_HFaceFinder hFaceFinderA, 207 btk_HDCR hdcrA ) 208 { 209 btk_HSDK hsdkL = NULL; 210 if( hFaceFinderA == NULL ) return btk_STATUS_INVALID_HANDLE; 211 if( hFaceFinderA->hidE != btk_HID_FF ) return btk_STATUS_INVALID_HANDLE; 212 if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; 213 hsdkL = hFaceFinderA->hsdkE; 214 if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; 215 216 if( hFaceFinderA->faceIndexE < hFaceFinderA->facesE ) 217 { 218 bpi_FaceFinderRef_getDcr( &hsdkL->contextE, 219 &hFaceFinderA->ffE, 220 hFaceFinderA->faceIndexE, 221 &hdcrA->dcrE ); 222 223 if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; 224 225 hdcrA->dcrE.approvedE = TRUE; 226 hFaceFinderA->faceIndexE++; 227 } 228 else 229 { 230 bpi_FaceFinderRef_getDcr( &hsdkL->contextE, 231 &hFaceFinderA->ffE, 232 0, 233 &hdcrA->dcrE ); 234 hdcrA->dcrE.approvedE = FALSE; 235 } 236 237 return btk_STATUS_OK; 238 } 239 240 /* ------------------------------------------------------------------------- */ 241 242 btk_Status btk_FaceFinder_process( btk_HFaceFinder hFaceFinderA, 243 btk_HDCR hdcrA ) 244 { 245 const char* fNameL = "btk_FaceFinder_process"; 246 int32 confL; 247 248 btk_HSDK hsdkL = NULL; 249 if( hFaceFinderA == NULL ) return btk_STATUS_INVALID_HANDLE; 250 if( hFaceFinderA->hidE != btk_HID_FF ) return btk_STATUS_INVALID_HANDLE; 251 if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; 252 hsdkL = hFaceFinderA->hsdkE; 253 if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; 254 255 if( hdcrA->dcrE.imageDataPtrE == NULL ) 256 { 257 bbs_Context_pushError( &hsdkL->contextE, 258 bbs_Error_create( bbs_ERR_ERROR, 0, NULL, 259 "%s:\nNo image was assigned to data carrier", fNameL ) ); 260 } 261 262 confL = bpi_FaceFinderRef_process( &hsdkL->contextE, 263 &hFaceFinderA->ffE, 264 &hdcrA->dcrE ); 265 266 if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; 267 268 hdcrA->dcrE.confidenceE = confL; 269 hdcrA->dcrE.approvedE = confL > ( ( int32 )1 << 23 ); 270 271 hFaceFinderA->faceIndexE = 0; 272 hFaceFinderA->facesE = 0; 273 274 bts_IdCluster2D_copy( &hsdkL->contextE, 275 &hdcrA->dcrE.sdkClusterE, 276 &hdcrA->dcrE.mainClusterE ); 277 278 if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; 279 280 return btk_STATUS_OK; 281 } 282 283 /* ------------------------------------------------------------------------- */ 284 285 /* ========================================================================= */ 286