/* * Copyright (C) 2008 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. */ /* ---- includes ----------------------------------------------------------- */ #include "FaceFinder_Internal.h" /* ---- related objects --------------------------------------------------- */ /* ---- typedefs ----------------------------------------------------------- */ /* ---- constants ---------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ /* ========================================================================= */ /* */ /* ---- functions ---------------------------------------------------------- */ /* */ /* ========================================================================= */ /* ------------------------------------------------------------------------- */ void btk_FaceFinder_init( struct bbs_Context* cpA, struct btk_FaceFinder* ptrA ) { ptrA->hsdkE = NULL; ptrA->hidE = btk_HID_FF; bpi_FaceFinderRef_init( cpA, &ptrA->ffE ); ptrA->facesE = 0; ptrA->faceIndexE = 0; } /* ------------------------------------------------------------------------- */ void btk_FaceFinder_exit( struct bbs_Context* cpA, struct btk_FaceFinder* ptrA ) { ptrA->hsdkE = NULL; ptrA->hidE = btk_HID_FF; bpi_FaceFinderRef_exit( cpA, &ptrA->ffE ); ptrA->facesE = 0; ptrA->faceIndexE = 0; } /* ------------------------------------------------------------------------- */ btk_FaceFinderCreateParam btk_FaceFinder_defaultParam() { btk_FaceFinderCreateParam paramL; paramL.reserved = 0; paramL.pModuleParam = NULL; paramL.moduleParamSize = 0; paramL.maxDetectableFaces = 0; return paramL; } /* ------------------------------------------------------------------------- */ btk_Status btk_FaceFinder_create( btk_HSDK hsdkA, /* sdk handle */ const btk_FaceFinderCreateParam* pCreateParamA, btk_HFaceFinder* hpFaceFinderA ) { const char* fNameL = "btk_FaceFinder_create"; btk_HFaceFinder hFaceFinderL = NULL; if( hpFaceFinderA == NULL ) return btk_STATUS_INVALID_HANDLE; if( *hpFaceFinderA != NULL ) return btk_STATUS_INVALID_HANDLE; if( hsdkA == NULL ) return btk_STATUS_INVALID_HANDLE; if( hsdkA->hidE != btk_HID_SDK ) return btk_STATUS_INVALID_HANDLE; if( pCreateParamA == NULL ) return btk_STATUS_INVALID_HANDLE; if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; hFaceFinderL = ( btk_HFaceFinder )bbs_MemSeg_alloc( &hsdkA->contextE, hsdkA->contextE.memTblE.espArrE[ 0 ], bbs_SIZEOF16( struct btk_FaceFinder ) ); if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_ERROR; btk_FaceFinder_init( &hsdkA->contextE, hFaceFinderL ); if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_ERROR; hFaceFinderL->hsdkE = hsdkA; if( btk_SDK_paramConsistencyTest( hsdkA, pCreateParamA->pModuleParam, pCreateParamA->moduleParamSize, fNameL ) == btk_STATUS_ERROR ) return btk_STATUS_ERROR; if( hsdkA->maxImageWidthE * hsdkA->maxImageHeightE == 0 ) { bbs_Context_pushError( &hsdkA->contextE, bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nSDK parameter maxImageWidth or maxImageWidth is 0!\n" "Since SDK version 1.3.0 the maximum image size must be specified when creating the SDK handle.\n" "Set the values in *pCreateParamA when you call function btk_SDK_create.", fNameL ) ); return btk_STATUS_ERROR; } bpi_FaceFinderRef_memRead( &hsdkA->contextE, &hFaceFinderL->ffE, hsdkA->maxImageWidthE, hsdkA->maxImageHeightE, pCreateParamA->pModuleParam, &hsdkA->contextE.memTblE ); if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_ERROR; *hpFaceFinderA = hFaceFinderL; hsdkA->refCtrE++; return btk_STATUS_OK; } /* ------------------------------------------------------------------------- */ btk_Status btk_FaceFinder_close( btk_HFaceFinder hFaceFinderA ) { btk_HSDK hsdkL = NULL; if( hFaceFinderA == NULL ) return btk_STATUS_INVALID_HANDLE; if( hFaceFinderA->hidE != btk_HID_FF ) return btk_STATUS_INVALID_HANDLE; if( hFaceFinderA->hsdkE == NULL ) return btk_STATUS_INVALID_HANDLE; hsdkL = hFaceFinderA->hsdkE; if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; hsdkL->refCtrE--; btk_FaceFinder_exit( &hsdkL->contextE, hFaceFinderA ); if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; bbs_MemSeg_free( &hsdkL->contextE, hsdkL->contextE.memTblE.espArrE[ 0 ], hFaceFinderA ); if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; return btk_STATUS_OK; } /* ------------------------------------------------------------------------- */ btk_Status btk_FaceFinder_setRange( btk_HFaceFinder hFaceFinderA, u32 minDistA, u32 maxDistA ) { btk_HSDK hsdkL = NULL; if( hFaceFinderA == NULL ) return btk_STATUS_INVALID_HANDLE; if( hFaceFinderA->hidE != btk_HID_FF ) return btk_STATUS_INVALID_HANDLE; hsdkL = hFaceFinderA->hsdkE; if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; bpi_FaceFinderRef_setRange( &hsdkL->contextE, &hFaceFinderA->ffE, minDistA, maxDistA ); if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; return btk_STATUS_OK; } /* ------------------------------------------------------------------------- */ btk_Status btk_FaceFinder_putDCR( btk_HFaceFinder hFaceFinderA, btk_HDCR hdcrA ) { const char* fNameL = "btk_FaceFinder_putDCR"; btk_HSDK hsdkL = NULL; if( hFaceFinderA == NULL ) return btk_STATUS_INVALID_HANDLE; if( hFaceFinderA->hidE != btk_HID_FF ) return btk_STATUS_INVALID_HANDLE; if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; hsdkL = hFaceFinderA->hsdkE; if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; if( hdcrA->dcrE.imageDataPtrE == NULL ) { bbs_Context_pushError( &hsdkL->contextE, bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nNo image was assigned to data carrier", fNameL ) ); } hFaceFinderA->facesE = bpi_FaceFinderRef_putDcr( &hsdkL->contextE, &hFaceFinderA->ffE, &hdcrA->dcrE ); hFaceFinderA->faceIndexE = 0; if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; return btk_STATUS_OK; } /* ------------------------------------------------------------------------- */ u32 btk_FaceFinder_faces( btk_HFaceFinder hFaceFinderA ) { if( hFaceFinderA == NULL ) return 0; if( hFaceFinderA->hidE != btk_HID_FF ) return 0; return hFaceFinderA->facesE - hFaceFinderA->faceIndexE; } /* ------------------------------------------------------------------------- */ btk_Status btk_FaceFinder_getDCR( btk_HFaceFinder hFaceFinderA, btk_HDCR hdcrA ) { btk_HSDK hsdkL = NULL; if( hFaceFinderA == NULL ) return btk_STATUS_INVALID_HANDLE; if( hFaceFinderA->hidE != btk_HID_FF ) return btk_STATUS_INVALID_HANDLE; if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; hsdkL = hFaceFinderA->hsdkE; if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; if( hFaceFinderA->faceIndexE < hFaceFinderA->facesE ) { bpi_FaceFinderRef_getDcr( &hsdkL->contextE, &hFaceFinderA->ffE, hFaceFinderA->faceIndexE, &hdcrA->dcrE ); if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; hdcrA->dcrE.approvedE = TRUE; hFaceFinderA->faceIndexE++; } else { bpi_FaceFinderRef_getDcr( &hsdkL->contextE, &hFaceFinderA->ffE, 0, &hdcrA->dcrE ); hdcrA->dcrE.approvedE = FALSE; } return btk_STATUS_OK; } /* ------------------------------------------------------------------------- */ btk_Status btk_FaceFinder_process( btk_HFaceFinder hFaceFinderA, btk_HDCR hdcrA ) { const char* fNameL = "btk_FaceFinder_process"; int32 confL; btk_HSDK hsdkL = NULL; if( hFaceFinderA == NULL ) return btk_STATUS_INVALID_HANDLE; if( hFaceFinderA->hidE != btk_HID_FF ) return btk_STATUS_INVALID_HANDLE; if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; hsdkL = hFaceFinderA->hsdkE; if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; if( hdcrA->dcrE.imageDataPtrE == NULL ) { bbs_Context_pushError( &hsdkL->contextE, bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nNo image was assigned to data carrier", fNameL ) ); } confL = bpi_FaceFinderRef_process( &hsdkL->contextE, &hFaceFinderA->ffE, &hdcrA->dcrE ); if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; hdcrA->dcrE.confidenceE = confL; hdcrA->dcrE.approvedE = confL > ( ( int32 )1 << 23 ); hFaceFinderA->faceIndexE = 0; hFaceFinderA->facesE = 0; bts_IdCluster2D_copy( &hsdkL->contextE, &hdcrA->dcrE.sdkClusterE, &hdcrA->dcrE.mainClusterE ); if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; return btk_STATUS_OK; } /* ------------------------------------------------------------------------- */ /* ========================================================================= */