auto import from //depot/cupcake/@135843
[android/platform/external/neven.git] / Embedded / common / src / b_APIEm / BFFaceFinder.c
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 "b_APIEm/BFFaceFinder.h"
20 #include "b_APIEm/Functions.h"
21 #include "b_APIEm/DCR.h"
22 #include "b_BasicEm/Functions.h"
23 #include "b_BasicEm/Math.h"
24
25 /* ------------------------------------------------------------------------- */
26
27 /* ========================================================================= */
28 /*                                                                           */
29 /* ---- \ghd{ auxiliary functions } ---------------------------------------- */
30 /*                                                                           */
31 /* ========================================================================= */
32
33 /* ------------------------------------------------------------------------- */
34
35 /* ========================================================================= */
36 /*                                                                           */
37 /* ---- \ghd{ constructor / destructor } ----------------------------------- */
38 /*                                                                           */
39 /* ========================================================================= */
40
41 /* ------------------------------------------------------------------------- */
42
43 void bpi_BFFaceFinder_init( struct bbs_Context* cpA,
44                                                     struct bpi_BFFaceFinder* ptrA )
45 {
46         bpi_FaceFinder_init( cpA, &ptrA->baseE );
47         ptrA->baseE.typeE = ( uint32 )bpi_FF_BF_FACE_FINDER;
48         ptrA->baseE.vpSetParamsE = bpi_BFFaceFinder_setParams;
49         ptrA->baseE.vpSetRangeE = bpi_BFFaceFinder_setRange;
50         ptrA->baseE.vpProcessE = bpi_BFFaceFinder_processDcr;
51         ptrA->baseE.vpPutDcrE = bpi_BFFaceFinder_putDcr;
52         ptrA->baseE.vpGetDcrE = bpi_BFFaceFinder_getDcr;
53
54         ptrA->detectedFacesE = 0;
55         ptrA->availableFacesE = 0;
56         ptrA->faceDataBufferE = NULL;
57         bbf_ScanDetector_init( cpA, &ptrA->detectorE );
58 }
59
60 /* ------------------------------------------------------------------------- */
61
62 void bpi_BFFaceFinder_exit( struct bbs_Context* cpA,
63                                                     struct bpi_BFFaceFinder* ptrA )
64 {
65         ptrA->detectedFacesE = 0;
66         ptrA->availableFacesE = 0;
67         ptrA->faceDataBufferE = NULL;
68         bbf_ScanDetector_exit( cpA, &ptrA->detectorE );
69
70         bpi_FaceFinder_exit( cpA, &ptrA->baseE );
71 }
72
73 /* ------------------------------------------------------------------------- */
74
75 /* ========================================================================= */
76 /*                                                                           */
77 /* ---- \ghd{ operators } -------------------------------------------------- */
78 /*                                                                           */
79 /* ========================================================================= */
80
81 /* ------------------------------------------------------------------------- */
82
83 void bpi_BFFaceFinder_copy( struct bbs_Context* cpA,
84                                                     struct bpi_BFFaceFinder* ptrA, 
85                                                         const struct bpi_BFFaceFinder* srcPtrA )
86 {
87         bpi_FaceFinder_copy( cpA, &ptrA->baseE, &srcPtrA->baseE );
88         bbf_ScanDetector_copy( cpA, &ptrA->detectorE, &srcPtrA->detectorE );
89 }
90
91 /* ------------------------------------------------------------------------- */
92
93 flag bpi_BFFaceFinder_equal( struct bbs_Context* cpA,
94                                                          const struct bpi_BFFaceFinder* ptrA, 
95                                                          const struct bpi_BFFaceFinder* srcPtrA )
96 {
97         if( !bpi_FaceFinder_equal( cpA, &ptrA->baseE, &srcPtrA->baseE ) ) return FALSE;
98         if( !bbf_ScanDetector_equal( cpA, &ptrA->detectorE, &srcPtrA->detectorE ) ) return FALSE;
99         return TRUE;
100 }
101
102 /* ------------------------------------------------------------------------- */
103
104 /* ========================================================================= */
105 /*                                                                           */
106 /* ---- \ghd{ query functions } -------------------------------------------- */
107 /*                                                                           */
108 /* ========================================================================= */
109
110 /* ------------------------------------------------------------------------- */
111
112 uint32 bpi_BFFaceFinder_getMinEyeDistance( const struct bpi_BFFaceFinder* ptrA )
113 {
114         return ( ( ptrA->detectorE.refDistanceE >> 8 ) * ( ptrA->detectorE.minScaleE >> 12 ) ) >> 16;
115 }
116
117 /* ------------------------------------------------------------------------- */
118
119 uint32 bpi_BFFaceFinder_getMaxEyeDistance( const struct bpi_BFFaceFinder* ptrA )
120 {
121         return ( ( ptrA->detectorE.refDistanceE >> 8 ) * ( ptrA->detectorE.maxScaleE >> 12 ) ) >> 16;
122 }
123
124 /* ------------------------------------------------------------------------- */
125
126 /* ========================================================================= */
127 /*                                                                           */
128 /* ---- \ghd{ modify functions } ------------------------------------------- */
129 /*                                                                           */
130 /* ========================================================================= */
131
132 /* ------------------------------------------------------------------------- */
133         
134 void bpi_BFFaceFinder_setMinEyeDistance( struct bbs_Context* cpA,
135                                                                                  struct bpi_BFFaceFinder* ptrA, 
136                                                                                  uint32 distA )
137 {
138         ptrA->detectorE.minScaleE = ( ( distA << 16 ) / ( ptrA->detectorE.refDistanceE >> 8 ) ) << 12;
139         if( ptrA->detectorE.minScaleE < 0x100000 /* 1.0 */ ) ptrA->detectorE.minScaleE = 0x100000;
140 }
141
142 /* ------------------------------------------------------------------------- */
143         
144 void bpi_BFFaceFinder_setMaxEyeDistance( struct bbs_Context* cpA,
145                                                                                  struct bpi_BFFaceFinder* ptrA, 
146                                                                                  uint32 distA )
147 {
148         if( distA > 0x0FFFF )
149         {
150                 ptrA->detectorE.maxScaleE = 0; /* unlimited */
151         }
152         else
153         {
154                 ptrA->detectorE.maxScaleE = ( ( distA << 16 ) / ( ptrA->detectorE.refDistanceE >> 8 ) ) << 12;
155         }
156 }
157
158 /* ------------------------------------------------------------------------- */
159         
160 /* ========================================================================= */
161 /*                                                                           */
162 /* ---- \ghd{ I/O } -------------------------------------------------------- */
163 /*                                                                           */
164 /* ========================================================================= */
165
166 /* ------------------------------------------------------------------------- */
167         
168 uint32 bpi_BFFaceFinder_memSize( struct bbs_Context* cpA,
169                                                                  const struct bpi_BFFaceFinder *ptrA )
170 {
171         uint32 memSizeL = 0;
172         memSizeL += bbs_SIZEOF16( uint32 );
173         memSizeL += bbs_SIZEOF16( uint32 ); /* version */
174         memSizeL += bpi_FaceFinder_memSize( cpA, &ptrA->baseE );
175         memSizeL += bbf_ScanDetector_memSize( cpA, &ptrA->detectorE );
176         memSizeL += bbs_SIZEOF16( uint16 ); /* csa */
177         return memSizeL;
178 }
179
180 /* ------------------------------------------------------------------------- */
181         
182 uint32 bpi_BFFaceFinder_memWrite( struct bbs_Context* cpA,
183                                                                   const struct bpi_BFFaceFinder* ptrA, 
184                                                                   uint16* memPtrA )
185 {
186         uint32 memSizeL = bpi_BFFaceFinder_memSize( cpA, ptrA );
187         memPtrA += bbs_memWrite32( &memSizeL, memPtrA );
188         memPtrA += bbs_memWriteUInt32( bpi_BF_FACE_FINDER_VERSION, memPtrA );
189         memPtrA += bpi_FaceFinder_memWrite( cpA, &ptrA->baseE, memPtrA );
190         memPtrA += bbf_ScanDetector_memWrite( cpA, &ptrA->detectorE, memPtrA );
191         memPtrA += bpi_memWriteCsa16( memPtrA, memSizeL, 0xFFFF );
192         return memSizeL;
193 }
194
195 /* ------------------------------------------------------------------------- */
196         
197 uint32 bpi_BFFaceFinder_memRead( struct bbs_Context* cpA,
198                                                                  struct bpi_BFFaceFinder* ptrA, 
199                                                                  const uint16* memPtrA,
200                                                                  struct bbs_MemTbl* mtpA )
201 {
202         uint32 memSizeL, versionL;
203         if( bbs_Context_error( cpA ) ) return 0;
204         memPtrA += bbs_memRead32( &memSizeL, memPtrA );
205         memPtrA += bbs_memReadVersion32( cpA, &versionL, bpi_BF_FACE_FINDER_VERSION, memPtrA );
206         memPtrA += bpi_FaceFinder_memRead( cpA, &ptrA->baseE, memPtrA );
207         if( bbs_Context_error( cpA ) ) return 0;
208
209         memPtrA += bbf_ScanDetector_memRead( cpA, &ptrA->detectorE, memPtrA, mtpA );
210         if( bbs_Context_error( cpA ) ) return 0;
211         memPtrA += bpi_memReadCsa16( memPtrA );
212
213 /*      if( memSizeL != bpi_BFFaceFinder_memSize( cpA, ptrA ) )
214         {
215                 bbs_ERROR0( "uint32 bpi_BFFaceFinder_memRead( .... ):\n"
216                     "Module file is corrupt or incorrect. Please check if the face finder module is still supported." ); 
217                 return 0;
218         }
219 */
220         return memSizeL;
221 }
222
223 /* ------------------------------------------------------------------------- */
224         
225 /* ========================================================================= */
226 /*                                                                           */
227 /* ---- \ghd{ exec functions } --------------------------------------------- */
228 /*                                                                           */
229 /* ========================================================================= */
230         
231 /* ------------------------------------------------------------------------- */
232
233 int32 bpi_BFFaceFinder_process( struct bbs_Context* cpA,
234                                                             const struct bpi_BFFaceFinder* ptrA, 
235                                                                 void* imagePtrA,
236                                                                 uint32 imageWidthA,
237                                                                 uint32 imageHeightA,
238                                                                 const struct bts_Int16Rect* roiPtrA,
239                                                                 struct bts_Int16Vec2D* offsPtrA,
240                                                                 struct bts_IdCluster2D* idClusterPtrA )
241 {
242         int32 xL = 0; /* 16.16 */
243         int32 yL = 0; /* 16.16 */
244         uint32 scaleL = 0;
245         int32 actL = 0;
246         int32* outArrL;
247
248         struct bts_Flt16Alt2D altL;
249         struct bts_Flt16Vec2D centerL;
250
251         struct bpi_BFFaceFinder* ptrL = ( struct bpi_BFFaceFinder* )ptrA;
252
253         /* reset multi face imformation so they are not accidentally used */
254         ptrL->detectedFacesE = 0;
255         ptrL->availableFacesE = 0;
256         ptrL->faceDataBufferE = NULL;
257
258         bbf_ScanDetector_process( cpA, ( struct bbf_ScanDetector* )&ptrA->detectorE, imagePtrA, imageWidthA, imageHeightA, roiPtrA, &outArrL );
259
260         xL      = outArrL[ 0 ]; /* 16.16 */
261         yL      = outArrL[ 1 ]; /* 16.16 */
262         scaleL  = outArrL[ 2 ]; /* 12.20 */
263         actL    = outArrL[ 3 ]; /*  4.28 */
264
265         if( bbs_Context_error( cpA ) ) return 0;
266
267         offsPtrA->xE = xL >> 16;
268         offsPtrA->yE = yL >> 16;
269         xL -= ( ( int32 )offsPtrA->xE << 16 );
270         yL -= ( ( int32 )offsPtrA->yE << 16 );
271
272         centerL = bts_Flt16Vec2D_create32( 0, 0, 0 );
273         altL = bts_Flt16Alt2D_createScale( scaleL, 20, &centerL );
274         altL.vecE = bts_Flt16Vec2D_create32( xL, yL, 16 );
275
276         /* compute cluster */
277         {
278                 uint32 eyeDistL = ( ( ptrA->detectorE.refDistanceE >> 16 ) * scaleL ) >> 20;
279                 uint32 logEyeDistL = bbs_intLog2( eyeDistL );
280                 int32 bbpL = 11 - logEyeDistL;
281                 bbpL = bbpL < 0 ? 0 : bbpL;
282                 bbpL = bbpL > 6 ? 6 : bbpL;
283                 bts_IdCluster2D_copyTransform( cpA, idClusterPtrA, &ptrA->detectorE.refClusterE, altL, bbpL );
284         }
285
286
287         return ( actL + 0x10000000 ) >> 5; /*output range 0...1 in 8.24*/
288 }
289
290 /* ------------------------------------------------------------------------- */
291
292 uint32 bpi_BFFaceFinder_multiProcess( struct bbs_Context* cpA,
293                                                                           const struct bpi_BFFaceFinder* ptrA, 
294                                                                           void* imagePtrA,
295                                                                           uint32 imageWidthA,
296                                                                           uint32 imageHeightA,
297                                                                           const struct bts_Int16Rect* roiPtrA )
298 {
299         struct bpi_BFFaceFinder* ptrL = ( struct bpi_BFFaceFinder* )ptrA;
300         ptrL->detectedFacesE = bbf_ScanDetector_process( cpA, ( struct bbf_ScanDetector* )&ptrA->detectorE, imagePtrA, imageWidthA, imageHeightA, roiPtrA, &ptrL->faceDataBufferE );
301         ptrL->availableFacesE = ptrA->detectedFacesE > 0 ? ptrA->detectedFacesE : 1;
302         if( bbs_Context_error( cpA ) ) return 0;
303         return ptrL->detectedFacesE;
304 }
305
306 /* ------------------------------------------------------------------------- */
307
308 uint32 bpi_BFFaceFinder_getFace( struct bbs_Context* cpA,
309                                                                  const struct bpi_BFFaceFinder* ptrA, 
310                                                                  uint32 indexA,
311                                                                  struct bts_Int16Vec2D* offsPtrA,
312                                                                  struct bts_IdCluster2D* idClusterPtrA )
313 {
314         bbs_DEF_fNameL( "bpi_BFFaceFinder_getFace" )
315         int32 xL = 0; /* 16.16 */
316         int32 yL = 0; /* 16.16 */
317         uint32 scaleL = 0;
318         int32 actL = 0;
319         struct bts_Flt16Alt2D altL;
320         struct bts_Flt16Vec2D centerL;
321
322         if( bbs_Context_error( cpA ) ) return 0;
323
324         if( ptrA->availableFacesE == 0 || ptrA->faceDataBufferE == NULL ) 
325         {
326                 bbs_ERROR1( "%s:\nNo faces are availabe. This function was called before the face finder could detect multiple faces in an image", fNameL );
327                 return 0;
328         }
329
330         if( indexA >= ptrA->availableFacesE ) 
331         {
332                 bbs_ERROR1( "%s:\nface index exceeds number of available faces", fNameL );
333                 return 0;
334         }
335
336         xL      = ptrA->faceDataBufferE[ indexA * 4 + 0 ]; /* 16.16 */
337         yL      = ptrA->faceDataBufferE[ indexA * 4 + 1 ]; /* 16.16 */
338         scaleL  = ptrA->faceDataBufferE[ indexA * 4 + 2 ]; /* 12.20 */
339         actL    = ptrA->faceDataBufferE[ indexA * 4 + 3 ]; /*  4.28 */
340
341         offsPtrA->xE = xL >> 16;
342         offsPtrA->yE = yL >> 16;
343
344         xL -= ( ( int32 )offsPtrA->xE << 16 );
345         yL -= ( ( int32 )offsPtrA->yE << 16 );
346
347         centerL = bts_Flt16Vec2D_create32( 0, 0, 0 );
348         altL = bts_Flt16Alt2D_createScale( scaleL, 20, &centerL );
349         altL.vecE = bts_Flt16Vec2D_create32( xL, yL, 16 );
350
351         /* compute cluster */
352         {
353                 uint32 eyeDistL = ( ( ptrA->detectorE.refDistanceE >> 16 ) * scaleL ) >> 20;
354                 uint32 logEyeDistL = bbs_intLog2( eyeDistL );
355                 int32 bbpL = 11 - logEyeDistL;
356                 bbpL = bbpL < 0 ? 0 : bbpL;
357                 bbpL = bbpL > 6 ? 6 : bbpL;
358                 bts_IdCluster2D_copyTransform( cpA, idClusterPtrA, &ptrA->detectorE.refClusterE, altL, bbpL );
359         }
360
361         return ( actL + 0x10000000 ) >> 5; /*output range 0...1 in 8.24*/
362 }
363
364 /* ------------------------------------------------------------------------- */
365
366 void bpi_BFFaceFinder_getFaceDCR( struct bbs_Context* cpA,
367                                                                   const struct bpi_BFFaceFinder* ptrA, 
368                                                                   uint32 indexA,
369                                                                   struct bpi_DCR* dcrPtrA )
370 {
371         int32 confL = bpi_BFFaceFinder_getFace( cpA, ptrA, indexA, &dcrPtrA->offsE, &dcrPtrA->mainClusterE );
372         bts_IdCluster2D_copy( cpA, &dcrPtrA->sdkClusterE, &dcrPtrA->mainClusterE );
373         dcrPtrA->confidenceE = confL;
374         dcrPtrA->approvedE = confL > ( ( int32 )1 << 23 );
375 }
376
377 /* ------------------------------------------------------------------------- */
378
379 void bpi_BFFaceFinder_setMaxImageSize( struct bbs_Context* cpA,
380                                                                            struct bpi_BFFaceFinder* ptrA, 
381                                                                            uint32 maxImageWidthA,
382                                                                            uint32 maxImageHeightA )
383 {
384         ptrA->detectorE.maxImageWidthE = maxImageWidthA;
385         ptrA->detectorE.maxImageHeightE = maxImageHeightA;
386 }
387
388 /* ------------------------------------------------------------------------- */
389
390 void bpi_BFFaceFinder_setParams( struct bbs_Context* cpA,
391                                                                  struct bpi_FaceFinder* ptrA, 
392                                                                  uint32 maxImageWidthA,
393                                                                  uint32 maxImageHeightA )
394 {
395         bbs_DEF_fNameL( "bpi_BFFaceFinder_setParams" );
396
397         if( bbs_Context_error( cpA ) ) return;
398
399         if( ptrA->typeE != bpi_FF_BF_FACE_FINDER ) 
400         {
401                 bbs_ERROR1( "%s:\nObject type mismatch", fNameL );
402                 return;
403         }
404         bpi_BFFaceFinder_setMaxImageSize( cpA, ( struct bpi_BFFaceFinder* )ptrA, maxImageWidthA, maxImageHeightA );
405 }
406
407 /* ------------------------------------------------------------------------- */
408
409 void bpi_BFFaceFinder_setRange( struct bbs_Context* cpA,
410                                                                 struct bpi_FaceFinder* ptrA, 
411                                                                 uint32 minEyeDistanceA,
412                                                                 uint32 maxEyeDistanceA )
413 {
414         bbs_DEF_fNameL( "bpi_BFFaceFinder_setParams" );
415
416         if( bbs_Context_error( cpA ) ) return;
417
418         if( ptrA->typeE != bpi_FF_BF_FACE_FINDER ) 
419         {
420                 bbs_ERROR1( "%s:\nObject type mismatch", fNameL );
421                 return;
422         }
423         bpi_BFFaceFinder_setMinEyeDistance( cpA, ( struct bpi_BFFaceFinder* )ptrA, minEyeDistanceA );
424         bpi_BFFaceFinder_setMaxEyeDistance( cpA, ( struct bpi_BFFaceFinder* )ptrA, maxEyeDistanceA );
425 }
426
427 /* ------------------------------------------------------------------------- */
428
429 int32 bpi_BFFaceFinder_processDcr( struct bbs_Context* cpA,
430                                                                    const struct bpi_FaceFinder* ptrA, 
431                                                            struct bpi_DCR* dcrPtrA )
432 {
433         bbs_DEF_fNameL( "bpi_BFFaceFinder_processDcr" );
434
435         if( bbs_Context_error( cpA ) ) return 0;
436
437         if( ptrA->typeE != bpi_FF_BF_FACE_FINDER ) 
438         {
439                 bbs_ERROR1( "%s:\nObject type mismatch", fNameL );
440                 return 0;
441         }
442
443         return bpi_BFFaceFinder_process( cpA, 
444                                                                         ( const struct bpi_BFFaceFinder* )ptrA, 
445                                                                         dcrPtrA->imageDataPtrE,
446                                                                         dcrPtrA->imageWidthE,
447                                                                         dcrPtrA->imageHeightE,
448                                                                         &dcrPtrA->roiRectE,
449                                                                         &dcrPtrA->offsE,
450                                                                         &dcrPtrA->mainClusterE );
451 }
452
453 /* ------------------------------------------------------------------------- */
454
455 int32 bpi_BFFaceFinder_putDcr( struct bbs_Context* cpA,
456                                                            const struct bpi_FaceFinder* ptrA, 
457                                                            struct bpi_DCR* dcrPtrA )
458 {
459         bbs_DEF_fNameL( "bpi_BFFaceFinder_putDcr" );
460
461         if( bbs_Context_error( cpA ) ) return 0;
462
463         if( ptrA->typeE != bpi_FF_BF_FACE_FINDER ) 
464         {
465                 bbs_ERROR1( "%s:\nObject type mismatch", fNameL );
466                 return 0;
467         }
468
469         return bpi_BFFaceFinder_multiProcess( cpA, 
470                                                                                  ( const struct bpi_BFFaceFinder* )ptrA, 
471                                                                                  dcrPtrA->imageDataPtrE,
472                                                                                  dcrPtrA->imageWidthE,
473                                                                                  dcrPtrA->imageHeightE,
474                                                                                  &dcrPtrA->roiRectE );
475 }
476
477 /* ------------------------------------------------------------------------- */
478
479 void bpi_BFFaceFinder_getDcr( struct bbs_Context* cpA,
480                                                           const struct bpi_FaceFinder* ptrA, 
481                                                           uint32 indexA,
482                                                           struct bpi_DCR* dcrPtrA )
483 {
484         bbs_DEF_fNameL( "bpi_BFFaceFinder_getDcr" );
485
486         if( bbs_Context_error( cpA ) ) return;
487
488         if( ptrA->typeE != bpi_FF_BF_FACE_FINDER ) 
489         {
490                 bbs_ERROR1( "%s:\nObject type mismatch", fNameL );
491                 return;
492         }
493
494         bpi_BFFaceFinder_getFaceDCR( cpA, ( const struct bpi_BFFaceFinder* )ptrA, indexA, dcrPtrA );
495 }
496
497 /* ------------------------------------------------------------------------- */
498
499 /* ========================================================================= */