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 
btk_DCR_init(struct bbs_Context * cpA,struct btk_DCR * ptrA)37 void 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 
btk_DCR_exit(struct bbs_Context * cpA,struct btk_DCR * ptrA)46 void 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 
btk_DCR_defaultParam()55 btk_DCRCreateParam btk_DCR_defaultParam()
56 {
57 	btk_DCRCreateParam paramL;
58 	paramL.reserved = 0;
59 	return paramL;
60 }
61 
62 /* ------------------------------------------------------------------------- */
63 
btk_DCR_create(btk_HSDK hsdkA,const btk_DCRCreateParam * pCreateParamA,btk_HDCR * hpdcrA)64 btk_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 
btk_DCR_close(btk_HDCR hdcrA)106 btk_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 
btk_DCR_assignGrayByteImage(btk_HDCR hdcrA,const void * pDataA,u32 widthA,u32 heightA)128 btk_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 
btk_DCR_assignImage(btk_HDCR hdcrA,const void * pDataA,u32 widthA,u32 heightA)138 btk_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 
btk_DCR_assignGrayByteImageROI(btk_HDCR hdcrA,const void * pDataA,u32 widthA,u32 heightA,const btk_Rect * pRectA)175 btk_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 
btk_DCR_assignImageROI(btk_HDCR hdcrA,const void * pDataA,u32 widthA,u32 heightA,const btk_Rect * pRectA)186 btk_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 
btk_DCR_nodeCount(btk_HDCR hdcrA)250 u32 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 
btk_DCR_getNode(btk_HDCR hdcrA,u32 indexA,btk_Node * nodePtrA)259 btk_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 
btk_DCR_getRect(btk_HDCR hdcrA,btk_Rect * pRectA)295 btk_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 
btk_DCR_confidence(btk_HDCR hdcrA)368 s8p24 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 
btk_DCR_approved(btk_HDCR hdcrA)381 u32 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