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
bts_RBFMap2D_init(struct bbs_Context * cpA,struct bts_RBFMap2D * ptrA)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
bts_RBFMap2D_exit(struct bbs_Context * cpA,struct bts_RBFMap2D * ptrA)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
bts_RBFMap2D_copy(struct bbs_Context * cpA,struct bts_RBFMap2D * ptrA,const struct bts_RBFMap2D * srcPtrA)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
bts_RBFMap2D_equal(struct bbs_Context * cpA,const struct bts_RBFMap2D * ptrA,const struct bts_RBFMap2D * srcPtrA)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
bts_RBFMap2D_create(struct bbs_Context * cpA,struct bts_RBFMap2D * ptrA,uint32 sizeA,struct bbs_MemSeg * mspA)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
bts_RBFMap2D_compute(struct bbs_Context * cpA,struct bts_RBFMap2D * ptrA,const struct bts_Cluster2D * srcPtrA,const struct bts_Cluster2D * dstPtrA)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
bts_RBFMap2D_memSize(struct bbs_Context * cpA,const struct bts_RBFMap2D * ptrA)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
bts_RBFMap2D_memWrite(struct bbs_Context * cpA,const struct bts_RBFMap2D * ptrA,uint16 * memPtrA)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
bts_RBFMap2D_memRead(struct bbs_Context * cpA,struct bts_RBFMap2D * ptrA,const uint16 * memPtrA,struct bbs_MemSeg * mspA)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 */
bts_RBFMap2D_mapVector(struct bbs_Context * cpA,const struct bts_RBFMap2D * ptrA,struct bts_Flt16Vec2D vecA)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
bts_RBFMap2D_mapCluster(struct bbs_Context * cpA,const struct bts_RBFMap2D * ptrA,const struct bts_Cluster2D * srcPtrA,struct bts_Cluster2D * dstPtrA,int32 dstBbpA)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
586