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 "DCR_Internal.h" 20 21/* ---- related objects --------------------------------------------------- */ 22 23/* ---- typedefs ----------------------------------------------------------- */ 24 25/* ---- constants ---------------------------------------------------------- */ 26 27/* ------------------------------------------------------------------------- */ 28 29/* ========================================================================= */ 30/* */ 31/* ---- functions ---------------------------------------------------------- */ 32/* */ 33/* ========================================================================= */ 34 35/* ------------------------------------------------------------------------- */ 36 37void btk_DCR_init( struct bbs_Context* cpA, struct btk_DCR* ptrA ) 38{ 39 ptrA->hsdkE = NULL; 40 ptrA->hidE = btk_HID_DCR; 41 bpi_DCR_init( cpA, &ptrA->dcrE ); 42} 43 44/* ------------------------------------------------------------------------- */ 45 46void btk_DCR_exit( struct bbs_Context* cpA, struct btk_DCR* ptrA ) 47{ 48 ptrA->hsdkE = NULL; 49 ptrA->hidE = btk_HID_DCR; 50 bpi_DCR_exit( cpA, &ptrA->dcrE ); 51} 52 53/* ------------------------------------------------------------------------- */ 54 55btk_DCRCreateParam btk_DCR_defaultParam() 56{ 57 btk_DCRCreateParam paramL; 58 paramL.reserved = 0; 59 return paramL; 60} 61 62/* ------------------------------------------------------------------------- */ 63 64btk_Status btk_DCR_create( btk_HSDK hsdkA, 65 const btk_DCRCreateParam* pCreateParamA, 66 btk_HDCR* hpdcrA ) 67{ 68 btk_HDCR hdcrL = NULL; 69 70 if( hpdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; 71 if( *hpdcrA != NULL ) return btk_STATUS_INVALID_HANDLE; 72 if( hsdkA == NULL ) return btk_STATUS_INVALID_HANDLE; 73 if( hsdkA->hidE != btk_HID_SDK ) return btk_STATUS_INVALID_HANDLE; 74 if( pCreateParamA == NULL ) return btk_STATUS_INVALID_HANDLE; 75 if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; 76 77 hdcrL = ( btk_HDCR )bbs_MemSeg_alloc( &hsdkA->contextE, hsdkA->contextE.memTblE.espArrE[ 0 ], bbs_SIZEOF16( struct btk_DCR ) ); 78 if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_ERROR; 79 80 btk_DCR_init( &hsdkA->contextE, hdcrL ); 81 hdcrL->hsdkE = hsdkA; 82 83 if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_ERROR; 84 85 bpi_DCR_create( &hsdkA->contextE, 86 &hdcrL->dcrE, 87 hsdkA->maxImageWidthE, 88 hsdkA->maxImageHeightE, 89#ifdef btk_FRSDK 90 6000 >> 1, 91#else 92 0, 93#endif 94 &hsdkA->contextE.memTblE ); 95 96 if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_ERROR; 97 98 *hpdcrA = hdcrL; 99 hsdkA->refCtrE++; 100 101 return btk_STATUS_OK; 102} 103 104/* ------------------------------------------------------------------------- */ 105 106btk_Status btk_DCR_close( btk_HDCR hdcrA ) 107{ 108 btk_HSDK hsdkL = NULL; 109 if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; 110 if( hdcrA->hidE != btk_HID_DCR ) return btk_STATUS_INVALID_HANDLE; 111 if( hdcrA->hsdkE == NULL ) return btk_STATUS_INVALID_HANDLE; 112 hsdkL = hdcrA->hsdkE; 113 if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; 114 115 hsdkL->refCtrE--; 116 117 btk_DCR_exit( &hsdkL->contextE, hdcrA ); 118 if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; 119 120 bbs_MemSeg_free( &hsdkL->contextE, hsdkL->contextE.memTblE.espArrE[ 0 ], hdcrA ); 121 if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; 122 123 return btk_STATUS_OK; 124} 125 126/* ------------------------------------------------------------------------- */ 127 128btk_Status btk_DCR_assignGrayByteImage( btk_HDCR hdcrA, 129 const void* pDataA, 130 u32 widthA, 131 u32 heightA ) 132{ 133 return btk_DCR_assignImage( hdcrA, pDataA, widthA, heightA ); 134} 135 136/* ------------------------------------------------------------------------- */ 137 138btk_Status btk_DCR_assignImage( btk_HDCR hdcrA, 139 const void* pDataA, 140 u32 widthA, 141 u32 heightA ) 142{ 143 const char* fNameL = "btk_DCR_assignImage"; 144 145 btk_HSDK hsdkL = NULL; 146 if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; 147 if( hdcrA->hidE != btk_HID_DCR ) return btk_STATUS_INVALID_HANDLE; 148 hsdkL = hdcrA->hsdkE; 149 if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; 150 151 if( pDataA == NULL ) 152 { 153 bbs_Context_pushError( &hsdkL->contextE, 154 bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nAssigned image references inavlid memory", fNameL ) ); 155 156 return btk_STATUS_ERROR; 157 } 158 159 if( widthA == 0 || heightA == 0 ) 160 { 161 bbs_Context_pushError( &hsdkL->contextE, 162 bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nAssigned image has size 0", fNameL ) ); 163 164 return btk_STATUS_ERROR; 165 } 166 167 bpi_DCR_assignGrayByteImage( &hsdkL->contextE, &hdcrA->dcrE, pDataA, widthA, heightA ); 168 if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; 169 170 return btk_STATUS_OK; 171} 172 173/* ------------------------------------------------------------------------- */ 174 175btk_Status btk_DCR_assignGrayByteImageROI( btk_HDCR hdcrA, 176 const void* pDataA, 177 u32 widthA, 178 u32 heightA, 179 const btk_Rect* pRectA ) 180{ 181 return btk_DCR_assignImageROI( hdcrA, pDataA, widthA, heightA, pRectA ); 182} 183 184/* ------------------------------------------------------------------------- */ 185 186btk_Status btk_DCR_assignImageROI( btk_HDCR hdcrA, 187 const void* pDataA, 188 u32 widthA, 189 u32 heightA, 190 const btk_Rect* pRectA ) 191{ 192 const char* fNameL = "btk_DCR_assignGrayByteImageROI"; 193 194 btk_HSDK hsdkL = NULL; 195 if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; 196 if( hdcrA->hidE != btk_HID_DCR ) return btk_STATUS_INVALID_HANDLE; 197 hsdkL = hdcrA->hsdkE; 198 if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; 199 200 if( pDataA == NULL ) 201 { 202 bbs_Context_pushError( &hsdkL->contextE, 203 bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nAssigned image references invalid memory", fNameL ) ); 204 return btk_STATUS_ERROR; 205 } 206 207 if( widthA == 0 || heightA == 0 ) 208 { 209 bbs_Context_pushError( &hsdkL->contextE, 210 bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nAssigned image has size 0", fNameL ) ); 211 return btk_STATUS_ERROR; 212 } 213 214 if( pRectA == NULL ) 215 { 216 bbs_Context_pushError( &hsdkL->contextE, 217 bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nAssigned ROI rectangle references invalid memory", fNameL ) ); 218 return btk_STATUS_ERROR; 219 } 220 221 if( pRectA->xMax <= pRectA->xMin || pRectA->yMax <= pRectA->yMin ) 222 { 223 bbs_Context_pushError( &hsdkL->contextE, 224 bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nAssigned ROI rectangle is inverted (max<min) or zero", fNameL ) ); 225 return btk_STATUS_ERROR; 226 } 227 228 { 229 struct bts_Int16Rect rectL; 230 rectL = bts_Int16Rect_create( pRectA->xMin >> 16, 231 pRectA->yMin >> 16, 232 pRectA->xMax >> 16, 233 pRectA->yMax >> 16 ); 234 235 /* rect must stay within image boundaries - adjust coordinates if necessary */ 236 rectL.x1E = rectL.x1E < 0 ? 0 : rectL.x1E; 237 rectL.y1E = rectL.y1E < 0 ? 0 : rectL.y1E; 238 rectL.x2E = rectL.x2E > ( int32 )widthA ? widthA : rectL.x2E; 239 rectL.y2E = rectL.y2E > ( int32 )heightA ? heightA : rectL.y2E; 240 241 bpi_DCR_assignGrayByteImageROI( &hsdkL->contextE, &hdcrA->dcrE, pDataA, widthA, heightA, &rectL ); 242 } 243 if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; 244 245 return btk_STATUS_OK; 246} 247 248/* ------------------------------------------------------------------------- */ 249 250u32 btk_DCR_nodeCount( btk_HDCR hdcrA ) 251{ 252 if( hdcrA == NULL ) return 0; 253 if( hdcrA->hidE != btk_HID_DCR ) return 0; 254 return hdcrA->dcrE.sdkClusterE.clusterE.sizeE; 255} 256 257/* ------------------------------------------------------------------------- */ 258 259btk_Status btk_DCR_getNode( btk_HDCR hdcrA, 260 u32 indexA, 261 btk_Node* nodePtrA ) 262{ 263 const char* fNameL = "btk_DCR_getNode"; 264 265 btk_HSDK hsdkL = NULL; 266 if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; 267 if( hdcrA->hidE != btk_HID_DCR ) return btk_STATUS_INVALID_HANDLE; 268 hsdkL = hdcrA->hsdkE; 269 if( nodePtrA == NULL ) return btk_STATUS_INVALID_HANDLE; 270 271 if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; 272 273 if( indexA >= hdcrA->dcrE.sdkClusterE.clusterE.sizeE ) 274 { 275 bbs_Context_pushError( &hsdkL->contextE, 276 bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nIndex is out of range", fNameL ) ); 277 return btk_STATUS_ERROR; 278 } 279 280 nodePtrA->id = hdcrA->dcrE.sdkClusterE.idArrE.arrPtrE[ indexA ]; 281 nodePtrA->x = ( ( s16p16 )hdcrA->dcrE.sdkClusterE.clusterE.vecArrE[ indexA ].xE ) << ( 16 - hdcrA->dcrE.sdkClusterE.clusterE.bbpE ); 282 nodePtrA->y = ( ( s16p16 )hdcrA->dcrE.sdkClusterE.clusterE.vecArrE[ indexA ].yE ) << ( 16 - hdcrA->dcrE.sdkClusterE.clusterE.bbpE ); 283 if( hdcrA->dcrE.roiRectE.x1E > 0 ) nodePtrA->x += ( int32 )hdcrA->dcrE.roiRectE.x1E << 16; 284 if( hdcrA->dcrE.roiRectE.y1E > 0 ) nodePtrA->y += ( int32 )hdcrA->dcrE.roiRectE.y1E << 16; 285 nodePtrA->x += ( int32 )hdcrA->dcrE.offsE.xE << 16; 286 nodePtrA->y += ( int32 )hdcrA->dcrE.offsE.yE << 16; 287 288 nodePtrA->reserved = 0; 289 290 return btk_STATUS_OK; 291} 292 293/* ------------------------------------------------------------------------- */ 294 295btk_Status btk_DCR_getRect( btk_HDCR hdcrA, 296 btk_Rect* pRectA ) 297{ 298 const char* fNameL = "btk_DCR_getRect"; 299 300 btk_HSDK hsdkL = NULL; 301 if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; 302 if( hdcrA->hidE != btk_HID_DCR ) return btk_STATUS_INVALID_HANDLE; 303 hsdkL = hdcrA->hsdkE; 304 if( pRectA == NULL ) return btk_STATUS_INVALID_HANDLE; 305 306 /* find eye nodes */ 307 { 308 const struct bbs_Int16Arr* pIdArrL = &hdcrA->dcrE.sdkClusterE.idArrE; 309 int32 lIndexL = -1; 310 int32 rIndexL = -1; 311 uint32 iL; 312 for( iL = 0; iL < pIdArrL->sizeE; iL++ ) 313 { 314 if( pIdArrL->arrPtrE[ iL ] == 0 ) 315 { 316 lIndexL = iL; 317 } 318 else if( pIdArrL->arrPtrE[ iL ] == 1 ) 319 { 320 rIndexL = iL; 321 } 322 } 323 324 if( lIndexL == -1 || rIndexL == -1 ) 325 { 326 bbs_Context_pushError( &hsdkL->contextE, 327 bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nFace rectangle is not available", fNameL ) ); 328 return btk_STATUS_ERROR; 329 } 330 331 { 332 int32 bbpL = hdcrA->dcrE.sdkClusterE.clusterE.bbpE; 333 int32 lxL = ( hdcrA->dcrE.sdkClusterE.clusterE.vecArrE[ lIndexL ].xE + ( 1 << ( bbpL - 1 ) ) ) >> bbpL; 334 int32 lyL = ( hdcrA->dcrE.sdkClusterE.clusterE.vecArrE[ lIndexL ].yE + ( 1 << ( bbpL - 1 ) ) ) >> bbpL; 335 int32 rxL = ( hdcrA->dcrE.sdkClusterE.clusterE.vecArrE[ rIndexL ].xE + ( 1 << ( bbpL - 1 ) ) ) >> bbpL; 336 int32 ryL = ( hdcrA->dcrE.sdkClusterE.clusterE.vecArrE[ rIndexL ].yE + ( 1 << ( bbpL - 1 ) ) ) >> bbpL; 337 int32 doffL = ( rxL - lxL ) >> 1; 338 339 pRectA->xMin = ( lxL - doffL ) << 16; 340 pRectA->xMax = ( rxL + doffL ) << 16; 341 pRectA->yMin = ( ( ( lyL + ryL + 1 ) >> 1 ) - doffL ) << 16; 342 pRectA->yMax = ( pRectA->yMin + ( pRectA->xMax - pRectA->xMin ) ); 343 if( hdcrA->dcrE.roiRectE.x1E > 0 ) 344 { 345 pRectA->xMin += ( int32 )hdcrA->dcrE.roiRectE.x1E << 16; 346 pRectA->xMax += ( int32 )hdcrA->dcrE.roiRectE.x1E << 16; 347 } 348 if( hdcrA->dcrE.roiRectE.y1E > 0 ) 349 { 350 pRectA->yMin += ( int32 )hdcrA->dcrE.roiRectE.y1E << 16; 351 pRectA->yMax += ( int32 )hdcrA->dcrE.roiRectE.y1E << 16; 352 } 353 354 pRectA->xMin += ( int32 )hdcrA->dcrE.offsE.xE << 16; 355 pRectA->yMin += ( int32 )hdcrA->dcrE.offsE.yE << 16; 356 pRectA->xMax += ( int32 )hdcrA->dcrE.offsE.xE << 16; 357 pRectA->yMax += ( int32 )hdcrA->dcrE.offsE.yE << 16; 358 359 } 360 } 361 362 return btk_STATUS_OK; 363} 364 365 366/* ------------------------------------------------------------------------- */ 367 368s8p24 btk_DCR_confidence( btk_HDCR hdcrA ) 369{ 370 btk_HSDK hsdkL = NULL; 371 if( hdcrA == NULL ) return 0; 372 if( hdcrA->hidE != btk_HID_DCR ) return 0; 373 hsdkL = hdcrA->hsdkE; 374 if( bbs_Context_error( &hsdkL->contextE ) ) return 0; 375 376 return hdcrA->dcrE.confidenceE; 377} 378 379/* ------------------------------------------------------------------------- */ 380 381u32 btk_DCR_approved( btk_HDCR hdcrA ) 382{ 383 btk_HSDK hsdkL = NULL; 384 if( hdcrA == NULL ) return 0; 385 if( hdcrA->hidE != btk_HID_DCR ) return 0; 386 hsdkL = hdcrA->hsdkE; 387 if( bbs_Context_error( &hsdkL->contextE ) ) return 0; 388 389 return ( u32 )hdcrA->dcrE.approvedE; 390} 391 392/* ------------------------------------------------------------------------- */ 393 394/* ========================================================================= */ 395