/*
* 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;
}
/* ------------------------------------------------------------------------- */
/* ========================================================================= */