auto import from //depot/cupcake/@135843
[android/platform/external/neven.git] / Embedded / common / src / b_TensorEm / RBFMap2D.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_TensorEm/RBFMap2D.h"
20 #include "b_BasicEm/Math.h"
21 #include "b_BasicEm/Memory.h"
22 #include "b_BasicEm/Functions.h"
23
24 /* ------------------------------------------------------------------------- */
25
26 /* ========================================================================= */
27 /*                                                                           */
28 /* ---- \ghd{ auxiliary functions } ---------------------------------------- */
29 /*                                                                           */
30 /* ========================================================================= */
31
32 /* ------------------------------------------------------------------------- */
33
34 /* ========================================================================= */
35 /*                                                                           */
36 /* ---- \ghd{ constructor / destructor } ----------------------------------- */
37 /*                                                                           */
38 /* ========================================================================= */
39
40 /* ------------------------------------------------------------------------- */
41
42 void bts_RBFMap2D_init( struct bbs_Context* cpA,
43                                             struct bts_RBFMap2D* ptrA )
44 {
45         ptrA->RBFTypeE = bts_RBF_LINEAR;
46         bts_Cluster2D_init( cpA, &ptrA->srcClusterE );
47         bts_Cluster2D_init( cpA, &ptrA->rbfCoeffClusterE );
48         ptrA->altTypeE = bts_ALT_LINEAR;
49         bts_Flt16Alt2D_init( &ptrA->altE );
50
51         ptrA->altOnlyE = FALSE;
52
53         bts_Int32Mat_init( cpA, &ptrA->matE );
54         bts_Int32Mat_init( cpA, &ptrA->tempMatE );
55         bbs_Int32Arr_init( cpA, &ptrA->inVecE );
56         bbs_Int32Arr_init( cpA, &ptrA->outVecE );
57         bbs_Int32Arr_init( cpA, &ptrA->tempVecE );
58 }
59
60 /* ------------------------------------------------------------------------- */
61
62 void bts_RBFMap2D_exit( struct bbs_Context* cpA,
63                                             struct bts_RBFMap2D* ptrA )
64 {
65         ptrA->RBFTypeE = bts_RBF_LINEAR;
66         bts_Cluster2D_exit( cpA, &ptrA->srcClusterE );
67         bts_Cluster2D_exit( cpA, &ptrA->rbfCoeffClusterE );
68         ptrA->altTypeE = bts_ALT_LINEAR;
69         bts_Flt16Alt2D_exit( &ptrA->altE );
70
71         ptrA->altOnlyE = FALSE;
72
73         bts_Int32Mat_exit( cpA, &ptrA->matE );
74         bts_Int32Mat_exit( cpA, &ptrA->tempMatE );
75         bbs_Int32Arr_exit( cpA, &ptrA->inVecE );
76         bbs_Int32Arr_exit( cpA, &ptrA->outVecE );
77         bbs_Int32Arr_exit( cpA, &ptrA->tempVecE );
78 }
79
80 /* ------------------------------------------------------------------------- */
81
82 /* ========================================================================= */
83 /*                                                                           */
84 /* ---- \ghd{ operators } -------------------------------------------------- */
85 /*                                                                           */
86 /* ========================================================================= */
87
88 /* ------------------------------------------------------------------------- */
89
90 void bts_RBFMap2D_copy( struct bbs_Context* cpA,
91                                             struct bts_RBFMap2D* ptrA, 
92                                                 const struct bts_RBFMap2D* srcPtrA )
93 {
94         ptrA->RBFTypeE = srcPtrA->RBFTypeE;
95         bts_Cluster2D_copy( cpA, &ptrA->srcClusterE, &srcPtrA->srcClusterE );
96         bts_Cluster2D_copy( cpA, &ptrA->rbfCoeffClusterE, &srcPtrA->rbfCoeffClusterE );
97         ptrA->altTypeE = srcPtrA->altTypeE;
98         bts_Flt16Alt2D_copy( &ptrA->altE, &srcPtrA->altE );
99 }
100
101 /* ------------------------------------------------------------------------- */
102
103 flag bts_RBFMap2D_equal( struct bbs_Context* cpA,
104                                                  const struct bts_RBFMap2D* ptrA, 
105                                                  const struct bts_RBFMap2D* srcPtrA )
106 {
107         if( ptrA->RBFTypeE != srcPtrA->RBFTypeE ) return FALSE;
108         if( ! bts_Cluster2D_equal( cpA, &ptrA->srcClusterE, &srcPtrA->srcClusterE ) ) return FALSE;
109         if( ! bts_Cluster2D_equal( cpA, &ptrA->rbfCoeffClusterE, &srcPtrA->rbfCoeffClusterE ) ) return FALSE;
110         if( ptrA->altTypeE != srcPtrA->altTypeE ) return FALSE;
111         if( ! bts_Flt16Alt2D_equal( &ptrA->altE, &srcPtrA->altE ) ) return FALSE;
112         return TRUE;
113 }
114
115 /* ------------------------------------------------------------------------- */
116
117 /* ========================================================================= */
118 /*                                                                           */
119 /* ---- \ghd{ query functions } -------------------------------------------- */
120 /*                                                                           */
121 /* ========================================================================= */
122
123 /* ------------------------------------------------------------------------- */
124
125 /* ========================================================================= */
126 /*                                                                           */
127 /* ---- \ghd{ modify functions } ------------------------------------------- */
128 /*                                                                           */
129 /* ========================================================================= */
130
131 /* ------------------------------------------------------------------------- */
132         
133 void bts_RBFMap2D_create( struct bbs_Context* cpA,
134                                                   struct bts_RBFMap2D* ptrA,
135                                                   uint32 sizeA,
136                                           struct bbs_MemSeg* mspA )
137 {
138         if( bbs_Context_error( cpA ) ) return;
139         bts_Cluster2D_create( cpA, &ptrA->srcClusterE, sizeA, mspA );
140         bts_Cluster2D_create( cpA, &ptrA->rbfCoeffClusterE, sizeA, mspA );
141
142         bts_Int32Mat_create( cpA, &ptrA->matE, sizeA, mspA );
143         bts_Int32Mat_create( cpA, &ptrA->tempMatE, sizeA, mspA );
144         bbs_Int32Arr_create( cpA, &ptrA->inVecE, sizeA, mspA );
145         bbs_Int32Arr_create( cpA, &ptrA->outVecE, sizeA, mspA );
146         bbs_Int32Arr_create( cpA, &ptrA->tempVecE, sizeA, mspA );
147 }
148
149 /* ------------------------------------------------------------------------- */
150
151 void bts_RBFMap2D_compute( struct bbs_Context* cpA,
152                                                    struct bts_RBFMap2D* ptrA,
153                                                    const struct bts_Cluster2D* srcPtrA,
154                                                    const struct bts_Cluster2D* dstPtrA )
155 {
156         const uint32 sizeL = srcPtrA->sizeE;
157         int32 bbp_internalL = 15;
158         int32 bbp_rbfCoeffL = 12;
159
160         int32 internalShiftL = bbp_internalL - srcPtrA->bbpE;
161         int32 rbfCoeffShiftL;
162
163         uint32 iL, jL;
164
165         if( dstPtrA->sizeE != srcPtrA->sizeE )
166         {
167                 bbs_ERROR2( "void bts_RBFMap2D_compute( ... ): size mismatch, src cluster has size %d,"
168                         "but dst cluster has size %d\n", srcPtrA->sizeE, dstPtrA->sizeE );
169                 return;
170         }
171
172         ptrA->altOnlyE = FALSE;
173
174         /* if bbp of src cluster should be larger than bbp_internal, use it instead */
175         if( internalShiftL < 0 )
176         {
177                 internalShiftL = 0;
178                 bbp_internalL = srcPtrA->bbpE;
179         }
180
181         /* also checks for sizeL > allocated size */
182         bts_Cluster2D_size( cpA, &ptrA->rbfCoeffClusterE, sizeL );
183
184         /* set rbf coefficients to 0 in case they don't get computed */
185         for( iL =0; iL < sizeL; iL++ )
186         {
187                 ptrA->rbfCoeffClusterE.vecArrE[ iL ].xE = 0;
188                 ptrA->rbfCoeffClusterE.vecArrE[ iL ].yE = 0;
189         }
190
191         /* 1. Compute rigid transformation: if cluster size == 0 returns identity */
192         ptrA->altE = bts_Cluster2D_alt( cpA, srcPtrA, dstPtrA, ptrA->altTypeE );
193
194         /* if cluster size is less than 3 affine trafo covers whole transformation */
195         if( sizeL < 3 )
196         {
197                 bts_Cluster2D_copy( cpA, &ptrA->srcClusterE, srcPtrA );
198                 ptrA->altOnlyE = TRUE;
199                 return;
200         }
201
202         /* 2. Compute RBF trafo */
203         ptrA->matE.widthE = sizeL;
204         ptrA->tempMatE.widthE = sizeL;
205         
206         /* Set up linear matrix to invert */
207         switch( ptrA->RBFTypeE )
208         {
209                 case bts_RBF_IDENTITY:
210                 {
211                         return;
212                 }
213
214                 case bts_RBF_LINEAR:
215                 {
216                         /* ||r|| */
217                         for( iL = 0; iL < sizeL; iL++ )
218                         {
219                                 struct bts_Int16Vec2D vec0L = srcPtrA->vecArrE[ iL ];
220                                 int32* ptrL = ptrA->matE.arrE.arrPtrE + iL * sizeL;
221
222                                 /* set diagonal elements having null distance */
223                                 *( ptrL + iL ) = 0;
224
225                                 for( jL = 0; jL < iL; jL++ )    /* use symmetry */
226                                 {
227                                         int32 normL = 0;
228                                         struct bts_Int16Vec2D vecL = srcPtrA->vecArrE[ jL ];
229                                         vecL.xE -= vec0L.xE;
230                                         vecL.yE -= vec0L.yE;
231                                         normL = bts_Int16Vec2D_norm( &vecL );
232                                         *ptrL++ = normL << internalShiftL;
233                                 }
234                         }
235                 }
236                 break;
237
238                 /* Add a new RBF type here */
239
240                 default:
241                 {
242                         bbs_ERROR1( "void bts_RBFMap2D_compute( ... ): RBFType %d is not handled\n", ptrA->RBFTypeE );
243                         return;
244                 }
245         }
246
247         /* use symmetry: set symmetric elements in matrix */
248         for( iL = 0; iL < sizeL; iL++ )
249         {
250                 int32* basePtrL = ptrA->matE.arrE.arrPtrE;
251                 uint32 jL;
252                 for( jL = iL + 1; jL < sizeL; jL++ )
253                 {
254                         *( basePtrL + iL * sizeL + jL ) = *( basePtrL + jL * sizeL + iL );
255                 }
256         }
257
258         /* Precompute alt transformed cluster, srcClusterE will be restored at the end */
259         bts_Cluster2D_copy( cpA, &ptrA->srcClusterE, srcPtrA );
260         bts_Cluster2D_transformBbp( cpA, &ptrA->srcClusterE, ptrA->altE, dstPtrA->bbpE );
261
262         bbs_Int32Arr_size( cpA, &ptrA->inVecE, sizeL );
263         bbs_Int32Arr_size( cpA, &ptrA->outVecE, sizeL );
264         bbs_Int32Arr_size( cpA, &ptrA->tempVecE, sizeL );
265
266         {
267                 flag successL;
268
269                 /* compute right side vector of linear system to be solved, for x */
270                 int32* inPtrL = ptrA->inVecE.arrPtrE;
271                 struct bts_Int16Vec2D* dstVecL = dstPtrA->vecArrE;
272                 struct bts_Int16Vec2D* altVecL = ptrA->srcClusterE.vecArrE;
273
274                 int32 shiftL = srcPtrA->bbpE - ptrA->srcClusterE.bbpE + internalShiftL;
275                 if( shiftL >= 0 )
276                 {
277                         for( iL = 0; iL < sizeL; iL++ ) inPtrL[ iL ] = ( int32 )( dstVecL[ iL ].xE - altVecL[ iL ].xE ) << shiftL;
278                 }
279                 else
280                 {
281                         for( iL = 0; iL < sizeL; iL++ ) inPtrL[ iL ] = ( ( ( int32 )( dstVecL[ iL ].xE - altVecL[ iL ].xE ) >> ( ( -shiftL ) - 1 ) ) + 1 ) >> 1;
282                 }
283
284                 /* solve linear system in x */
285                 successL = bts_Int32Mat_solve(  cpA, 
286                                                     ptrA->matE.arrE.arrPtrE,
287                                                                                 sizeL,
288                                                                                 ptrA->inVecE.arrPtrE,
289                                                                                 ptrA->outVecE.arrPtrE,
290                                                                                 bbp_internalL,
291                                                                                 ptrA->tempMatE.arrE.arrPtrE,
292                                                                                 ptrA->tempVecE.arrPtrE );
293
294                 /* no error condition here! system must be failsafe */
295                 if( !successL ) ptrA->altOnlyE = TRUE;
296
297                 /* store rbf coefficients, x component */
298                 rbfCoeffShiftL = bbp_internalL - bbp_rbfCoeffL;
299                 for( iL = 0; iL < sizeL; iL++ )
300                 {
301                         int32 rbfCoeffL = ptrA->outVecE.arrPtrE[ iL ] >> rbfCoeffShiftL;
302                         if( rbfCoeffL < -32768 || rbfCoeffL > 32767 ) ptrA->altOnlyE = TRUE; /* check for overflow */
303                         ptrA->rbfCoeffClusterE.vecArrE[ iL ].xE = rbfCoeffL;
304                 }
305
306
307                 /* compute right side vector of linear system to be solved, for y */
308                 if( shiftL >= 0 )
309                 {
310                         for( iL = 0; iL < sizeL; iL++ ) inPtrL[ iL ] = ( int32 )( dstVecL[ iL ].yE - altVecL[ iL ].yE ) << shiftL;
311                 }
312                 else
313                 {
314                         for( iL = 0; iL < sizeL; iL++ ) inPtrL[ iL ] = ( ( ( int32 )( dstVecL[ iL ].yE - altVecL[ iL ].yE ) >> ( ( -shiftL ) - 1 ) ) + 1 ) >> 1;
315                 }
316
317                 /* solve linear system in y */
318                 successL = bts_Int32Mat_solve(  cpA, 
319                                                     ptrA->matE.arrE.arrPtrE,
320                                                                                 sizeL,
321                                                                                 ptrA->inVecE.arrPtrE,
322                                                                                 ptrA->outVecE.arrPtrE,
323                                                                                 bbp_internalL,
324                                                                                 ptrA->tempMatE.arrE.arrPtrE,
325                                                                                 ptrA->tempVecE.arrPtrE );
326                 if( !successL )
327                 {
328                         /* no error condition here! system must be failsafe */
329                         ptrA->altOnlyE = TRUE;
330                 }
331
332                 /* store rbf coefficients, y component */
333                 for( iL = 0; iL < sizeL; iL++ )
334                 {
335                         int32 rbfCoeffL = ptrA->outVecE.arrPtrE[ iL ] >> rbfCoeffShiftL;
336                         if( rbfCoeffL < -32768 || rbfCoeffL > 32767 ) ptrA->altOnlyE = TRUE; /* check for overflow */
337                         ptrA->rbfCoeffClusterE.vecArrE[ iL ].yE = rbfCoeffL;
338                 }
339
340                 /* set bbp of coeff cluster */
341                 ptrA->rbfCoeffClusterE.bbpE = bbp_rbfCoeffL;
342         }
343
344         /** after having used srcClusterE for temporary storage of the alt src cluster,
345                 restore the orig src cluster as needed for the RBF trafo */
346         bts_Cluster2D_copy( cpA, &ptrA->srcClusterE, srcPtrA );
347 }
348
349 /* ------------------------------------------------------------------------- */
350         
351 /* ========================================================================= */
352 /*                                                                           */
353 /* ---- \ghd{ I/O } -------------------------------------------------------- */
354 /*                                                                           */
355 /* ========================================================================= */
356
357 /* ------------------------------------------------------------------------- */
358         
359 uint32 bts_RBFMap2D_memSize( struct bbs_Context* cpA,
360                                                          const struct bts_RBFMap2D *ptrA )
361 {
362         return  bbs_SIZEOF16( uint32 )
363                   + bbs_SIZEOF16( uint32 ) /* version */
364                   + bbs_SIZEOF16( ptrA->RBFTypeE )
365                   + bts_Cluster2D_memSize( cpA, &ptrA->srcClusterE )
366                   + bts_Cluster2D_memSize( cpA, &ptrA->rbfCoeffClusterE )
367                   + bbs_SIZEOF16( ptrA->altTypeE ) 
368                   + bts_Flt16Alt2D_memSize( cpA, &ptrA->altE );
369 }
370
371 /* ------------------------------------------------------------------------- */
372         
373 uint32 bts_RBFMap2D_memWrite( struct bbs_Context* cpA,
374                                                           const struct bts_RBFMap2D* ptrA, 
375                                                           uint16* memPtrA )
376 {
377         uint32 memSizeL = bts_RBFMap2D_memSize( cpA, ptrA );
378         memPtrA += bbs_memWrite32( &memSizeL, memPtrA );
379         memPtrA += bbs_memWriteUInt32( bts_IRBFMAP2D_VERSION, memPtrA );
380         memPtrA += bbs_memWrite32( &ptrA->RBFTypeE, memPtrA );
381         memPtrA += bts_Cluster2D_memWrite( cpA, &ptrA->srcClusterE, memPtrA );
382         memPtrA += bts_Cluster2D_memWrite( cpA, &ptrA->rbfCoeffClusterE, memPtrA );
383         memPtrA += bbs_memWrite32( &ptrA->altTypeE, memPtrA );
384         memPtrA += bts_Flt16Alt2D_memWrite( cpA, &ptrA->altE, memPtrA );
385         return memSizeL;
386 }
387
388 /* ------------------------------------------------------------------------- */
389         
390 uint32 bts_RBFMap2D_memRead( struct bbs_Context* cpA,
391                                                          struct bts_RBFMap2D* ptrA, 
392                                                          const uint16* memPtrA,
393                                              struct bbs_MemSeg* mspA )
394 {
395         uint32 memSizeL, versionL;
396         if( bbs_Context_error( cpA ) ) return 0;
397         memPtrA += bbs_memRead32( &memSizeL, memPtrA );
398         memPtrA += bbs_memReadVersion32( cpA, &versionL, bts_IRBFMAP2D_VERSION, memPtrA );
399         memPtrA += bbs_memRead32( &ptrA->RBFTypeE, memPtrA );
400         memPtrA += bts_Cluster2D_memRead( cpA, &ptrA->srcClusterE, memPtrA, mspA );
401         memPtrA += bts_Cluster2D_memRead( cpA, &ptrA->rbfCoeffClusterE, memPtrA, mspA );
402         memPtrA += bbs_memRead32( &ptrA->altTypeE, memPtrA );
403         memPtrA += bts_Flt16Alt2D_memRead( cpA, &ptrA->altE, memPtrA );
404
405         bts_Int32Mat_create( cpA, &ptrA->matE, ptrA->srcClusterE.sizeE, mspA );
406         bts_Int32Mat_create( cpA, &ptrA->tempMatE, ptrA->srcClusterE.sizeE, mspA );
407
408         if( memSizeL != bts_RBFMap2D_memSize( cpA, ptrA ) )
409         {
410                 bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bts_RBFMap2D_memRead( ... ): size mismatch\n" ); 
411                 return 0;
412         }
413         return memSizeL;
414 }
415
416 /* ------------------------------------------------------------------------- */
417         
418 /* ========================================================================= */
419 /*                                                                           */
420 /* ---- \ghd{ exec functions } --------------------------------------------- */
421 /*                                                                           */
422 /* ========================================================================= */
423
424 /* ------------------------------------------------------------------------- */
425 /**     R, A are rbf and A affine linear transformations 
426  *      T( x ) = R( x ) + A( x )
427  */
428 struct bts_Flt16Vec2D bts_RBFMap2D_mapVector( struct bbs_Context* cpA,
429                                                                                           const struct bts_RBFMap2D* ptrA,
430                                                                                           struct bts_Flt16Vec2D vecA )
431 {
432         const uint32 sizeL = ptrA->srcClusterE.sizeE;
433         const int32 bbp_internalL = ptrA->rbfCoeffClusterE.bbpE;
434         uint32 iL;
435         int32 shL;
436
437         int32 outXL;
438         int32 outYL;
439         int32 outBbpL;
440
441         /* 1. Compute rigid transformation, i.e. A( x ) */
442         struct bts_Flt16Vec2D altVecL = bts_Flt16Alt2D_mapFlt( &ptrA->altE, &vecA );
443
444         /* compute output on 32 bit here to prevent temporary overflows (j.s.) */
445         outXL   = altVecL.xE;
446         outYL   = altVecL.yE;
447         outBbpL = altVecL.bbpE;
448
449         /* if bbp was altered, change it back to bbp of vecA ( det A is always close to 1 here ) */
450         shL = vecA.bbpE - outBbpL;
451         if( shL > 0 )
452         {
453                 outXL <<= shL;
454                 outYL <<= shL;
455         }
456         else if( shL < 0 )
457         {
458                 outXL = ( ( outXL >> ( -shL - 1 ) ) + 1 ) >> 1;
459                 outYL = ( ( outYL >> ( -shL - 1 ) ) + 1 ) >> 1;
460         }
461         outBbpL = vecA.bbpE;
462
463         /* stop here if rbf coefficients could not be computed  */
464         if( ptrA->altOnlyE )
465         {
466                 return bts_Flt16Vec2D_create32( outXL, outYL, outBbpL );
467         }
468
469         /* 2. Compute RBF transformation, i.e. R( x ) depending on type */
470         switch( ptrA->RBFTypeE )
471     {
472                 case bts_RBF_IDENTITY:
473                 break;
474
475         case bts_RBF_LINEAR:
476         {
477                         int32 xSumL = 0;
478                         int32 ySumL = 0;
479                         int32 internalShiftL = bbp_internalL - ptrA->srcClusterE.bbpE;
480
481                         /* first adapt vecA to bbp of srcCluster */
482                         int32 xL = vecA.xE;
483                         int32 yL = vecA.yE;
484                         int32 shiftL = ptrA->srcClusterE.bbpE - vecA.bbpE;
485                         if( shiftL > 0 )
486                         {
487                                 xL <<= shiftL;
488                                 yL <<= shiftL;
489                         }
490                         else if( shiftL < 0 )
491                         {
492                                 xL = ( ( xL >> ( -shiftL - 1 ) ) + 1 ) >> 1;
493                                 yL = ( ( yL >> ( -shiftL - 1 ) ) + 1 ) >> 1;
494                         }
495
496                         shiftL = ptrA->srcClusterE.bbpE;
497
498             for( iL = 0; iL < sizeL; iL++ )
499             {
500                                 struct bts_Int16Vec2D vecL = ptrA->srcClusterE.vecArrE[ iL ];
501                                 int32 normL = 0;
502                                 vecL.xE -= xL;
503                                 vecL.yE -= yL;
504                                 normL = bts_Int16Vec2D_norm( &vecL );
505
506 /* printf( "iL = %d, norm = %d\n", iL, normL ); */
507
508                                 xSumL += ( normL * ptrA->rbfCoeffClusterE.vecArrE[ iL ].xE ) >> shiftL;
509                                 ySumL += ( normL * ptrA->rbfCoeffClusterE.vecArrE[ iL ].yE ) >> shiftL;
510
511 /* printf( "iL = %d, xSumL = %d, ySumL = %d\n", iL, xSumL, ySumL ); */
512
513             }
514
515                         xSumL >>= internalShiftL;
516                         ySumL >>= internalShiftL;
517
518                         /* change bbp of result back to bbp of vecA */
519                 /*      shiftL = vecA.bbpE - ptrA->srcClusterE.bbpE - internalShiftL; */
520                         shiftL = vecA.bbpE - ptrA->srcClusterE.bbpE;
521                         if( shiftL > 0 )
522                         {
523                                 xSumL <<= shiftL;
524                                 ySumL <<= shiftL;
525                         }
526                         else if( shiftL < 0 )
527                         {
528                                 xSumL = ( ( xSumL >> ( -shiftL - 1 ) ) + 1 ) >> 1;
529                                 ySumL = ( ( ySumL >> ( -shiftL - 1 ) ) + 1 ) >> 1;
530                         }
531
532                         /* add rbf part to already computed alt part */
533                         outXL += xSumL;
534                         outYL += ySumL;
535         }
536         break;
537
538                 /* Add a new RBF type here */
539
540                 default:
541                 {
542                         bbs_ERROR1( "struct bts_Flt16Vec2D bts_RBFMap2D_mapVector( ... ): "
543                                 "RBFType %d is not handled\n", ptrA->RBFTypeE );
544                         return bts_Flt16Vec2D_create32( outXL, outYL, outBbpL );
545                 }
546         }
547
548         return bts_Flt16Vec2D_create32( outXL, outYL, outBbpL );
549 }
550
551 /* ------------------------------------------------------------------------- */
552
553 void bts_RBFMap2D_mapCluster( struct bbs_Context* cpA,
554                                                           const struct bts_RBFMap2D* ptrA,
555                                                           const struct bts_Cluster2D* srcPtrA,
556                                                           struct bts_Cluster2D* dstPtrA,
557                                                           int32 dstBbpA )
558 {
559         if( dstPtrA->sizeE != srcPtrA->sizeE )
560         {
561                 /* resizing of clusters is allowed as long as allocated size is not exceeded */
562                 bts_Cluster2D_size( cpA, dstPtrA, srcPtrA->sizeE );
563         }
564
565         {
566                 uint32 iL;
567                 int16 bbpL = srcPtrA->bbpE;
568
569                 dstPtrA->bbpE = dstBbpA;
570
571                 for( iL = 0; iL < srcPtrA->sizeE; iL++ )
572                 {
573                         struct bts_Int16Vec2D vecL = srcPtrA->vecArrE[ iL ];
574                         struct bts_Flt16Vec2D srcVecL = bts_Flt16Vec2D_create16( vecL.xE, vecL.yE, bbpL );
575                         struct bts_Flt16Vec2D dstVecL = bts_RBFMap2D_mapVector( cpA, ptrA, srcVecL );
576                         dstPtrA->vecArrE[ iL ].xE = bbs_convertS32( dstVecL.xE, dstVecL.bbpE, dstBbpA );
577                         dstPtrA->vecArrE[ iL ].yE = bbs_convertS32( dstVecL.yE, dstVecL.bbpE, dstBbpA );
578                 }
579         }
580 }
581
582 /* ------------------------------------------------------------------------- */
583
584 /* ========================================================================= */
585