/* * 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 "DCR_Internal.h" /* ---- related objects --------------------------------------------------- */ /* ---- typedefs ----------------------------------------------------------- */ /* ---- constants ---------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ /* ========================================================================= */ /* */ /* ---- functions ---------------------------------------------------------- */ /* */ /* ========================================================================= */ /* ------------------------------------------------------------------------- */ void btk_DCR_init( struct bbs_Context* cpA, struct btk_DCR* ptrA ) { ptrA->hsdkE = NULL; ptrA->hidE = btk_HID_DCR; bpi_DCR_init( cpA, &ptrA->dcrE ); } /* ------------------------------------------------------------------------- */ void btk_DCR_exit( struct bbs_Context* cpA, struct btk_DCR* ptrA ) { ptrA->hsdkE = NULL; ptrA->hidE = btk_HID_DCR; bpi_DCR_exit( cpA, &ptrA->dcrE ); } /* ------------------------------------------------------------------------- */ btk_DCRCreateParam btk_DCR_defaultParam() { btk_DCRCreateParam paramL; paramL.reserved = 0; return paramL; } /* ------------------------------------------------------------------------- */ btk_Status btk_DCR_create( btk_HSDK hsdkA, const btk_DCRCreateParam* pCreateParamA, btk_HDCR* hpdcrA ) { btk_HDCR hdcrL = NULL; if( hpdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; if( *hpdcrA != 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; hdcrL = ( btk_HDCR )bbs_MemSeg_alloc( &hsdkA->contextE, hsdkA->contextE.memTblE.espArrE[ 0 ], bbs_SIZEOF16( struct btk_DCR ) ); if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_ERROR; btk_DCR_init( &hsdkA->contextE, hdcrL ); hdcrL->hsdkE = hsdkA; if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_ERROR; bpi_DCR_create( &hsdkA->contextE, &hdcrL->dcrE, hsdkA->maxImageWidthE, hsdkA->maxImageHeightE, #ifdef btk_FRSDK 6000 >> 1, #else 0, #endif &hsdkA->contextE.memTblE ); if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_ERROR; *hpdcrA = hdcrL; hsdkA->refCtrE++; return btk_STATUS_OK; } /* ------------------------------------------------------------------------- */ btk_Status btk_DCR_close( btk_HDCR hdcrA ) { btk_HSDK hsdkL = NULL; if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; if( hdcrA->hidE != btk_HID_DCR ) return btk_STATUS_INVALID_HANDLE; if( hdcrA->hsdkE == NULL ) return btk_STATUS_INVALID_HANDLE; hsdkL = hdcrA->hsdkE; if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; hsdkL->refCtrE--; btk_DCR_exit( &hsdkL->contextE, hdcrA ); if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; bbs_MemSeg_free( &hsdkL->contextE, hsdkL->contextE.memTblE.espArrE[ 0 ], hdcrA ); if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; return btk_STATUS_OK; } /* ------------------------------------------------------------------------- */ btk_Status btk_DCR_assignGrayByteImage( btk_HDCR hdcrA, const void* pDataA, u32 widthA, u32 heightA ) { return btk_DCR_assignImage( hdcrA, pDataA, widthA, heightA ); } /* ------------------------------------------------------------------------- */ btk_Status btk_DCR_assignImage( btk_HDCR hdcrA, const void* pDataA, u32 widthA, u32 heightA ) { const char* fNameL = "btk_DCR_assignImage"; btk_HSDK hsdkL = NULL; if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; if( hdcrA->hidE != btk_HID_DCR ) return btk_STATUS_INVALID_HANDLE; hsdkL = hdcrA->hsdkE; if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; if( pDataA == NULL ) { bbs_Context_pushError( &hsdkL->contextE, bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nAssigned image references inavlid memory", fNameL ) ); return btk_STATUS_ERROR; } if( widthA == 0 || heightA == 0 ) { bbs_Context_pushError( &hsdkL->contextE, bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nAssigned image has size 0", fNameL ) ); return btk_STATUS_ERROR; } bpi_DCR_assignGrayByteImage( &hsdkL->contextE, &hdcrA->dcrE, pDataA, widthA, heightA ); if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; return btk_STATUS_OK; } /* ------------------------------------------------------------------------- */ btk_Status btk_DCR_assignGrayByteImageROI( btk_HDCR hdcrA, const void* pDataA, u32 widthA, u32 heightA, const btk_Rect* pRectA ) { return btk_DCR_assignImageROI( hdcrA, pDataA, widthA, heightA, pRectA ); } /* ------------------------------------------------------------------------- */ btk_Status btk_DCR_assignImageROI( btk_HDCR hdcrA, const void* pDataA, u32 widthA, u32 heightA, const btk_Rect* pRectA ) { const char* fNameL = "btk_DCR_assignGrayByteImageROI"; btk_HSDK hsdkL = NULL; if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; if( hdcrA->hidE != btk_HID_DCR ) return btk_STATUS_INVALID_HANDLE; hsdkL = hdcrA->hsdkE; if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; if( pDataA == NULL ) { bbs_Context_pushError( &hsdkL->contextE, bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nAssigned image references invalid memory", fNameL ) ); return btk_STATUS_ERROR; } if( widthA == 0 || heightA == 0 ) { bbs_Context_pushError( &hsdkL->contextE, bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nAssigned image has size 0", fNameL ) ); return btk_STATUS_ERROR; } if( pRectA == NULL ) { bbs_Context_pushError( &hsdkL->contextE, bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nAssigned ROI rectangle references invalid memory", fNameL ) ); return btk_STATUS_ERROR; } if( pRectA->xMax <= pRectA->xMin || pRectA->yMax <= pRectA->yMin ) { bbs_Context_pushError( &hsdkL->contextE, bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nAssigned ROI rectangle is inverted (max<min) or zero", fNameL ) ); return btk_STATUS_ERROR; } { struct bts_Int16Rect rectL; rectL = bts_Int16Rect_create( pRectA->xMin >> 16, pRectA->yMin >> 16, pRectA->xMax >> 16, pRectA->yMax >> 16 ); /* rect must stay within image boundaries - adjust coordinates if necessary */ rectL.x1E = rectL.x1E < 0 ? 0 : rectL.x1E; rectL.y1E = rectL.y1E < 0 ? 0 : rectL.y1E; rectL.x2E = rectL.x2E > ( int32 )widthA ? widthA : rectL.x2E; rectL.y2E = rectL.y2E > ( int32 )heightA ? heightA : rectL.y2E; bpi_DCR_assignGrayByteImageROI( &hsdkL->contextE, &hdcrA->dcrE, pDataA, widthA, heightA, &rectL ); } if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR; return btk_STATUS_OK; } /* ------------------------------------------------------------------------- */ u32 btk_DCR_nodeCount( btk_HDCR hdcrA ) { if( hdcrA == NULL ) return 0; if( hdcrA->hidE != btk_HID_DCR ) return 0; return hdcrA->dcrE.sdkClusterE.clusterE.sizeE; } /* ------------------------------------------------------------------------- */ btk_Status btk_DCR_getNode( btk_HDCR hdcrA, u32 indexA, btk_Node* nodePtrA ) { const char* fNameL = "btk_DCR_getNode"; btk_HSDK hsdkL = NULL; if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; if( hdcrA->hidE != btk_HID_DCR ) return btk_STATUS_INVALID_HANDLE; hsdkL = hdcrA->hsdkE; if( nodePtrA == NULL ) return btk_STATUS_INVALID_HANDLE; if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_PREEXISTING_ERROR; if( indexA >= hdcrA->dcrE.sdkClusterE.clusterE.sizeE ) { bbs_Context_pushError( &hsdkL->contextE, bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nIndex is out of range", fNameL ) ); return btk_STATUS_ERROR; } nodePtrA->id = hdcrA->dcrE.sdkClusterE.idArrE.arrPtrE[ indexA ]; nodePtrA->x = ( ( s16p16 )hdcrA->dcrE.sdkClusterE.clusterE.vecArrE[ indexA ].xE ) << ( 16 - hdcrA->dcrE.sdkClusterE.clusterE.bbpE ); nodePtrA->y = ( ( s16p16 )hdcrA->dcrE.sdkClusterE.clusterE.vecArrE[ indexA ].yE ) << ( 16 - hdcrA->dcrE.sdkClusterE.clusterE.bbpE ); if( hdcrA->dcrE.roiRectE.x1E > 0 ) nodePtrA->x += ( int32 )hdcrA->dcrE.roiRectE.x1E << 16; if( hdcrA->dcrE.roiRectE.y1E > 0 ) nodePtrA->y += ( int32 )hdcrA->dcrE.roiRectE.y1E << 16; nodePtrA->x += ( int32 )hdcrA->dcrE.offsE.xE << 16; nodePtrA->y += ( int32 )hdcrA->dcrE.offsE.yE << 16; nodePtrA->reserved = 0; return btk_STATUS_OK; } /* ------------------------------------------------------------------------- */ btk_Status btk_DCR_getRect( btk_HDCR hdcrA, btk_Rect* pRectA ) { const char* fNameL = "btk_DCR_getRect"; btk_HSDK hsdkL = NULL; if( hdcrA == NULL ) return btk_STATUS_INVALID_HANDLE; if( hdcrA->hidE != btk_HID_DCR ) return btk_STATUS_INVALID_HANDLE; hsdkL = hdcrA->hsdkE; if( pRectA == NULL ) return btk_STATUS_INVALID_HANDLE; /* find eye nodes */ { const struct bbs_Int16Arr* pIdArrL = &hdcrA->dcrE.sdkClusterE.idArrE; int32 lIndexL = -1; int32 rIndexL = -1; uint32 iL; for( iL = 0; iL < pIdArrL->sizeE; iL++ ) { if( pIdArrL->arrPtrE[ iL ] == 0 ) { lIndexL = iL; } else if( pIdArrL->arrPtrE[ iL ] == 1 ) { rIndexL = iL; } } if( lIndexL == -1 || rIndexL == -1 ) { bbs_Context_pushError( &hsdkL->contextE, bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nFace rectangle is not available", fNameL ) ); return btk_STATUS_ERROR; } { int32 bbpL = hdcrA->dcrE.sdkClusterE.clusterE.bbpE; int32 lxL = ( hdcrA->dcrE.sdkClusterE.clusterE.vecArrE[ lIndexL ].xE + ( 1 << ( bbpL - 1 ) ) ) >> bbpL; int32 lyL = ( hdcrA->dcrE.sdkClusterE.clusterE.vecArrE[ lIndexL ].yE + ( 1 << ( bbpL - 1 ) ) ) >> bbpL; int32 rxL = ( hdcrA->dcrE.sdkClusterE.clusterE.vecArrE[ rIndexL ].xE + ( 1 << ( bbpL - 1 ) ) ) >> bbpL; int32 ryL = ( hdcrA->dcrE.sdkClusterE.clusterE.vecArrE[ rIndexL ].yE + ( 1 << ( bbpL - 1 ) ) ) >> bbpL; int32 doffL = ( rxL - lxL ) >> 1; pRectA->xMin = ( lxL - doffL ) << 16; pRectA->xMax = ( rxL + doffL ) << 16; pRectA->yMin = ( ( ( lyL + ryL + 1 ) >> 1 ) - doffL ) << 16; pRectA->yMax = ( pRectA->yMin + ( pRectA->xMax - pRectA->xMin ) ); if( hdcrA->dcrE.roiRectE.x1E > 0 ) { pRectA->xMin += ( int32 )hdcrA->dcrE.roiRectE.x1E << 16; pRectA->xMax += ( int32 )hdcrA->dcrE.roiRectE.x1E << 16; } if( hdcrA->dcrE.roiRectE.y1E > 0 ) { pRectA->yMin += ( int32 )hdcrA->dcrE.roiRectE.y1E << 16; pRectA->yMax += ( int32 )hdcrA->dcrE.roiRectE.y1E << 16; } pRectA->xMin += ( int32 )hdcrA->dcrE.offsE.xE << 16; pRectA->yMin += ( int32 )hdcrA->dcrE.offsE.yE << 16; pRectA->xMax += ( int32 )hdcrA->dcrE.offsE.xE << 16; pRectA->yMax += ( int32 )hdcrA->dcrE.offsE.yE << 16; } } return btk_STATUS_OK; } /* ------------------------------------------------------------------------- */ s8p24 btk_DCR_confidence( btk_HDCR hdcrA ) { btk_HSDK hsdkL = NULL; if( hdcrA == NULL ) return 0; if( hdcrA->hidE != btk_HID_DCR ) return 0; hsdkL = hdcrA->hsdkE; if( bbs_Context_error( &hsdkL->contextE ) ) return 0; return hdcrA->dcrE.confidenceE; } /* ------------------------------------------------------------------------- */ u32 btk_DCR_approved( btk_HDCR hdcrA ) { btk_HSDK hsdkL = NULL; if( hdcrA == NULL ) return 0; if( hdcrA->hidE != btk_HID_DCR ) return 0; hsdkL = hdcrA->hsdkE; if( bbs_Context_error( &hsdkL->contextE ) ) return 0; return ( u32 )hdcrA->dcrE.approvedE; } /* ------------------------------------------------------------------------- */ /* ========================================================================= */