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_BasicEm/Functions.h"
20 #include "b_BasicEm/Math.h"
21 #include "b_BitFeatureEm/LocalScanner.h"
22
23 /* ------------------------------------------------------------------------- */
24
25 /* ========================================================================= */
26 /* */
27 /* ---- \ghd{ auxiliary functions } ---------------------------------------- */
28 /* */
29 /* ========================================================================= */
30
31 /* ------------------------------------------------------------------------- */
32
33 /** allocates arays */
bbf_LocalScanner_alloc(struct bbs_Context * cpA,struct bbf_LocalScanner * ptrA,struct bbs_MemTbl * mtpA)34 void bbf_LocalScanner_alloc( struct bbs_Context* cpA,
35 struct bbf_LocalScanner* ptrA,
36 struct bbs_MemTbl* mtpA )
37 {
38 struct bbs_MemTbl memTblL = *mtpA;
39 struct bbs_MemSeg* espL = bbs_MemTbl_segPtr( cpA, &memTblL, 0 );
40 struct bbs_MemSeg* sspL = bbs_MemTbl_sharedSegPtr( cpA, &memTblL, 0 );
41
42 /* filter patch dimension */
43 uint32 proL = ptrA->maxRadiusE;
44 uint32 pwoL = ( proL << 1 ) + 1;
45
46 /* output image size (bit image) */
47 uint32 woL = ptrA->maxImageWidthE;
48 uint32 hoL = ptrA->maxImageHeightE;
49
50 if( ptrA->minScaleExpE > 0 )
51 {
52 /* allocate working image */
53 bbs_UInt8Arr_create( cpA, &ptrA->workImageBufferE, ( woL >> 1 ) * ( hoL >> 1 ), espL );
54 bbs_UInt8Arr_fill( cpA, &ptrA->workImageBufferE, 0 );
55 }
56
57 /* allocate bit image */
58 bim_UInt32Image_create( cpA, &ptrA->bitImageE, woL, ( hoL >> 5 ) + ( ( ( hoL & 0x1F ) != 0 ) ? 1 : 0 ), espL );
59 bim_UInt32Image_setAllPixels( cpA, &ptrA->bitImageE, 0, 0 );
60
61 /* allocate patch buffer */
62 bbs_UInt32Arr_create( cpA, &ptrA->patchBufferE, ptrA->bitImageE.widthE, espL );
63 bbs_UInt32Arr_fill( cpA, &ptrA->patchBufferE, 0 );
64
65 /* allocate table */
66 bim_UInt32Image_create( cpA, &ptrA->satE, woL + pwoL, pwoL + 1, sspL );
67 }
68
69 /* ------------------------------------------------------------------------- */
70
71 /** downscales original image by factor 2 */
bbf_LocalScanner_downscale0(struct bbs_Context * cpA,struct bbf_LocalScanner * ptrA)72 void bbf_LocalScanner_downscale0( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA )
73 {
74 int32 w0L = ptrA->origWidthE;
75 int32 h0L = ptrA->origHeightE;
76
77 int32 w1L = ( w0L - ptrA->xOffE ) >> 1;
78 int32 h1L = ( h0L - ptrA->yOffE ) >> 1;
79
80 const uint8* iArrL = ptrA->origImagePtrE + ptrA->xOffE + ptrA->yOffE * w0L;
81 uint8* oArrL = ptrA->workImageBufferE.arrPtrE;
82
83 int32 iL, jL;
84 int32 kL = 0;
85
86 bbs_UInt8Arr_size( cpA, &ptrA->workImageBufferE, w1L * h1L );
87 ptrA->workImagePtrE = ptrA->workImageBufferE.arrPtrE;
88 ptrA->workWidthE = w1L;
89 ptrA->workHeightE = h1L;
90
91 for( jL = 0; jL < h1L; jL++ )
92 {
93 for( iL = 0; iL < w1L; iL++ )
94 {
95 int32 idxL = jL * 2 * w0L + iL * 2;
96 oArrL[ kL++ ] = ( ( uint32 )iArrL[ idxL ] +
97 iArrL[ idxL + 1 ] +
98 iArrL[ idxL + w0L ] +
99 iArrL[ idxL + w0L + 1 ] + 2 ) >> 2;
100 }
101 }
102 }
103
104 /* ------------------------------------------------------------------------- */
105
106 /** downscales work image by factor 2 */
bbf_LocalScanner_downscale1(struct bbs_Context * cpA,struct bbf_LocalScanner * ptrA)107 void bbf_LocalScanner_downscale1( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA )
108 {
109 int32 w0L = ptrA->workWidthE;
110 int32 h0L = ptrA->workHeightE;
111 int32 w1L = w0L >> 1;
112 int32 h1L = h0L >> 1;
113
114 uint8* arrL = ptrA->workImageBufferE.arrPtrE;
115
116 int32 iL, jL;
117 int32 kL = 0;
118
119 for( jL = 0; jL < h1L; jL++ )
120 {
121 for( iL = 0; iL < w1L; iL++ )
122 {
123 int32 idxL = jL * 2 * w0L + iL * 2;
124 arrL[ kL++ ] = ( ( uint32 )arrL[ idxL ] +
125 arrL[ idxL + 1 ] +
126 arrL[ idxL + w0L ] +
127 arrL[ idxL + w0L + 1 ] + 2 ) >> 2;
128 }
129 }
130
131 ptrA->workWidthE = w1L;
132 ptrA->workHeightE = h1L;
133 }
134
135 /* ------------------------------------------------------------------------- */
136
137 /** downscales by factor 2 */
bbf_LocalScanner_downscale(struct bbs_Context * cpA,struct bbf_LocalScanner * ptrA)138 void bbf_LocalScanner_downscale( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA )
139 {
140 uint32 iL;
141 if( ptrA->scaleExpE > 0 ) bbf_LocalScanner_downscale0( cpA, ptrA );
142 for( iL = 1; iL < ptrA->scaleExpE; iL++ ) bbf_LocalScanner_downscale1( cpA, ptrA );
143 }
144
145 /* ------------------------------------------------------------------------- */
146
147 /** computes bit image */
bbf_LocalScanner_createBitImage(struct bbs_Context * cpA,struct bbf_LocalScanner * ptrA)148 void bbf_LocalScanner_createBitImage( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA )
149 {
150 bbs_DEF_fNameL( "void bbf_LocalScanner_createBitImage( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA )" )
151
152 uint32 iL, jL;
153
154 uint32 proL = ptrA->bitParamE.outerRadiusE;
155 uint32 priL = ptrA->bitParamE.innerRadiusE;
156 uint32 pwoL = ( proL << 1 ) + 1;
157 uint32 pwiL = ( priL << 1 ) + 1;
158
159 /* areas of inner and outer rectangles */
160 uint32 poAreaL = pwoL * pwoL;
161 uint32 piAreaL = pwiL * pwiL;
162
163 uint32 wL, hL; /* input image size */
164
165 uint32 wsL, hsL;
166 uint32* satL;
167 uint32 satSizeL;
168 uint32 swi1L = 0; /* writing index */
169 uint32 swi2L = 0; /* writing index */
170 uint32 sriL = 0; /* reading index */
171 uint32 siL[ 8 ];
172
173 uint32 bitMaskL;
174 uint32* bitRowL;
175
176
177 if( proL <= priL )
178 {
179 bbs_ERROR1( "%s:\n outer radius <= inner radius", fNameL );
180 return;
181 }
182
183 /* input image size */
184 wL = ptrA->workWidthE;
185 hL = ptrA->workHeightE;
186
187 if( wL <= pwoL || hL <= pwoL )
188 {
189 bbs_ERROR1( "%s:\n image is too small", fNameL );
190 return;
191 }
192
193 ptrA->currentWidthE = wL;
194 ptrA->currentHeightE = hL;
195
196 /* reset scan region */
197 ptrA->workScanRegionE = bts_Int16Rect_create( 0, 0, ptrA->currentWidthE, ptrA->currentHeightE );
198
199 /* initialize bit image */
200 bim_UInt32Image_size( cpA, &ptrA->bitImageE, wL, ( hL >> 5 ) + ( ( ( hL & 0x1F ) != 0 ) ? 1 : 0 ) );
201 bim_UInt32Image_setAllPixels( cpA, &ptrA->bitImageE, 0, 0 );
202
203 bitMaskL = 1;
204 bitRowL = ( uint32* )ptrA->bitImageE.arrE.arrPtrE;
205
206 /* width of table */
207 wsL = wL + pwoL;
208
209 /* height of table */
210 hsL = pwoL + 1;
211
212 bim_UInt32Image_size( cpA, &ptrA->satE, wsL, hsL );
213
214 satL = ( uint32* )ptrA->satE.arrE.arrPtrE;
215 satSizeL = ptrA->satE.arrE.sizeE;
216
217 /* compute table and bit image */
218 for( iL = wsL * ( proL + 1 ); iL > 0; iL-- ) satL[ swi1L++ ] = 0;
219 swi2L = swi1L - wsL;
220
221 for( jL = 0; jL < hL + proL; jL++ )
222 {
223 if( jL < hL ) /* rescale area */
224 {
225 const uint8* arr0L = &ptrA->workImagePtrE[ jL * wL ];
226 uint32 hSumL = 0;
227 for( iL = 0; iL <= proL; iL++ ) satL[ swi1L++ ] = 0;
228 swi2L += iL;
229 for( iL = 0; iL < wL; iL++ ) satL[ swi1L++ ] = ( hSumL += arr0L[ iL ] ) + satL[ swi2L++ ];
230 for( iL = 0; iL < proL; iL++ ) satL[ swi1L++ ] = hSumL + satL[ swi2L++ ];
231 }
232 else /* image is processed - fill in 0s */
233 {
234 for( iL = 0; iL < wsL; iL++ ) satL[ swi1L++ ] = satL[ swi2L++ ];
235 }
236
237 swi1L = ( swi1L < satSizeL ) ? swi1L : 0;
238 swi2L = ( swi2L < satSizeL ) ? swi2L : 0;
239
240 /* fill line in bit image */
241 if( jL >= proL )
242 {
243 const uint32* rSatL = satL;
244
245 /* table coordinate indices for outer rectangle */
246 siL[ 0 ] = sriL;
247 siL[ 1 ] = siL[ 0 ] + pwoL;
248 siL[ 2 ] = siL[ 0 ] + pwoL * wsL;
249 siL[ 2 ] -= ( siL[ 2 ] >= satSizeL ) ? satSizeL : 0;
250 siL[ 3 ] = siL[ 2 ] + pwoL;
251
252 /* table coordinate indices for inner rectangle */
253 siL[ 4 ] = siL[ 0 ] + ( proL - priL ) * wsL + ( proL - priL );
254 siL[ 4 ] -= ( siL[ 4 ] >= satSizeL ) ? satSizeL : 0;
255 siL[ 5 ] = siL[ 4 ] + pwiL;
256 siL[ 6 ] = siL[ 4 ] + pwiL * wsL;
257 siL[ 6 ] -= ( siL[ 6 ] >= satSizeL ) ? satSizeL : 0;
258 siL[ 7 ] = siL[ 6 ] + pwiL;
259 sriL += wsL;
260 if( sriL == satSizeL ) sriL = 0;
261
262 for( iL = 0; iL < wL; iL++ )
263 {
264 uint32 oAvgL = ( rSatL[ siL[ 0 ] ] - rSatL[ siL[ 1 ] ] - rSatL[ siL[ 2 ] ] + rSatL[ siL[ 3 ] ] ) * piAreaL;
265 uint32 iAvgL = ( rSatL[ siL[ 4 ] ] - rSatL[ siL[ 5 ] ] - rSatL[ siL[ 6 ] ] + rSatL[ siL[ 7 ] ] ) * poAreaL;
266 bitRowL[ iL ] |= ( iAvgL > oAvgL ) ? bitMaskL : 0;
267 rSatL++;
268 }
269 if( ( bitMaskL <<= 1 ) == 0 )
270 {
271 bitRowL += wL;
272 bitMaskL = 1;
273 }
274 }
275 }
276 }
277
278 /* -------------------------------------------------------------------------- */
279
280 /** inilialize patch buffer */
bbf_LocalScanner_initPatchBuffer(struct bbs_Context * cpA,struct bbf_LocalScanner * ptrA)281 void bbf_LocalScanner_initPatchBuffer( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA )
282 {
283 int32 ybL = ptrA->workScanRegionE.y1E >> 5;
284 int32 yoL = ptrA->workScanRegionE.y1E & 0x1F;
285 int32 xbL = ptrA->workScanRegionE.x1E;
286 uint32 wsrWidthL = ptrA->workScanRegionE.x2E - ptrA->workScanRegionE.x1E;
287
288 bbs_UInt32Arr_size( cpA, &ptrA->patchBufferE, ptrA->bitImageE.widthE );
289
290 if( yoL == 0 )
291 {
292 bbs_memcpy32( ptrA->patchBufferE.arrPtrE + xbL,
293 ptrA->bitImageE.arrE.arrPtrE + ybL * ptrA->bitImageE.widthE + xbL,
294 wsrWidthL );
295 }
296 else if( ybL == ( int32 )ptrA->bitImageE.heightE - 1 )
297 {
298 uint32* dstL = ptrA->patchBufferE.arrPtrE + xbL;
299 const uint32* srcL = ptrA->bitImageE.arrE.arrPtrE + ybL * ptrA->bitImageE.widthE + xbL;
300 uint32 iL;
301 for( iL = 0; iL < wsrWidthL; iL++ ) dstL[ iL ] = srcL[ iL ] >> yoL;
302 }
303 else
304 {
305 uint32* dstL = ptrA->patchBufferE.arrPtrE + xbL;
306 const uint32* src0L = ptrA->bitImageE.arrE.arrPtrE + ybL * ptrA->bitImageE.widthE + xbL;
307 const uint32* src1L = src0L + ptrA->bitImageE.widthE;
308 uint32 iL;
309 uint32 slL = 32 - yoL;
310 for( iL = 0; iL < wsrWidthL; iL++ ) dstL[ iL ] = ( src0L[ iL ] >> yoL ) | ( src1L[ iL ] << slL );
311 }
312 }
313
314 /* ------------------------------------------------------------------------- */
315
316 /* sets work scan region from original scan region according to scale exponent */
bbf_LocalScanner_setWorkScanRegion(struct bbs_Context * cpA,struct bbf_LocalScanner * ptrA)317 void bbf_LocalScanner_setWorkScanRegion( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA )
318 {
319 int32 xMinL = ptrA->origScanRegionE.x1E >> ptrA->scaleExpE;
320 int32 yMinL = ptrA->origScanRegionE.y1E >> ptrA->scaleExpE;
321 int32 xMaxL = ptrA->origScanRegionE.x2E >> ptrA->scaleExpE;
322 int32 yMaxL = ptrA->origScanRegionE.y2E >> ptrA->scaleExpE;
323 ptrA->workScanRegionE.x1E = ( xMinL < 0 ) ? 0 : xMinL;
324 ptrA->workScanRegionE.y1E = ( yMinL < 0 ) ? 0 : yMinL;
325 ptrA->workScanRegionE.x2E = ( xMaxL > ( int32 )ptrA->currentWidthE ) ? ptrA->currentWidthE : xMaxL;
326 ptrA->workScanRegionE.y2E = ( yMaxL > ( int32 )ptrA->currentHeightE ) ? ptrA->currentHeightE : yMaxL;
327 }
328
329 /* ------------------------------------------------------------------------- */
330
331 /* ========================================================================= */
332 /* */
333 /* ---- \ghd{ constructor / destructor } ----------------------------------- */
334 /* */
335 /* ========================================================================= */
336
337 /* ------------------------------------------------------------------------- */
338
bbf_LocalScanner_init(struct bbs_Context * cpA,struct bbf_LocalScanner * ptrA)339 void bbf_LocalScanner_init( struct bbs_Context* cpA,
340 struct bbf_LocalScanner* ptrA )
341 {
342 ptrA->xE = 0;
343 ptrA->yE = 0;
344 ptrA->xOffE = 0;
345 ptrA->yOffE = 0;
346 ptrA->currentWidthE = 0;
347 ptrA->currentHeightE = 0;
348 ptrA->workWidthE = 0;
349 ptrA->workHeightE = 0;
350 ptrA->workImagePtrE = NULL;
351 ptrA->origWidthE = 0;
352 ptrA->origHeightE = 0;
353 ptrA->origImagePtrE = NULL;
354 bbf_BitParam_init( cpA, &ptrA->bitParamE );
355 bbs_UInt8Arr_init( cpA, &ptrA->workImageBufferE );
356 bim_UInt32Image_init( cpA, &ptrA->satE );
357 bim_UInt32Image_init( cpA, &ptrA->bitImageE );
358 bbs_UInt32Arr_init( cpA, &ptrA->patchBufferE );
359 bts_Int16Rect_init( cpA, &ptrA->origScanRegionE );
360 bts_Int16Rect_init( cpA, &ptrA->workScanRegionE );
361
362 ptrA->patchWidthE = 0;
363 ptrA->patchHeightE = 0;
364 ptrA->scaleExpE = 0;
365 ptrA->maxImageWidthE = 0;
366 ptrA->maxImageHeightE = 0;
367 ptrA->minScaleExpE = 0;
368 ptrA->maxRadiusE = 0;
369 }
370
371 /* ------------------------------------------------------------------------- */
372
bbf_LocalScanner_exit(struct bbs_Context * cpA,struct bbf_LocalScanner * ptrA)373 void bbf_LocalScanner_exit( struct bbs_Context* cpA,
374 struct bbf_LocalScanner* ptrA )
375 {
376 ptrA->xE = 0;
377 ptrA->yE = 0;
378 ptrA->xOffE = 0;
379 ptrA->yOffE = 0;
380 ptrA->currentWidthE = 0;
381 ptrA->currentHeightE = 0;
382 ptrA->workWidthE = 0;
383 ptrA->workHeightE = 0;
384 ptrA->workImagePtrE = NULL;
385 ptrA->origWidthE = 0;
386 ptrA->origHeightE = 0;
387 ptrA->origImagePtrE = NULL;
388 bbf_BitParam_exit( cpA, &ptrA->bitParamE );
389 bbs_UInt8Arr_exit( cpA, &ptrA->workImageBufferE );
390 bim_UInt32Image_exit( cpA, &ptrA->satE );
391 bim_UInt32Image_exit( cpA, &ptrA->bitImageE );
392 bbs_UInt32Arr_exit( cpA, &ptrA->patchBufferE );
393 bts_Int16Rect_exit( cpA, &ptrA->origScanRegionE );
394 bts_Int16Rect_exit( cpA, &ptrA->workScanRegionE );
395
396 ptrA->patchWidthE = 0;
397 ptrA->patchHeightE = 0;
398 ptrA->scaleExpE = 0;
399 ptrA->maxImageWidthE = 0;
400 ptrA->maxImageHeightE = 0;
401 ptrA->minScaleExpE = 0;
402 ptrA->maxRadiusE = 0;
403 }
404
405 /* ------------------------------------------------------------------------- */
406
407 /* ========================================================================= */
408 /* */
409 /* ---- \ghd{ operators } -------------------------------------------------- */
410 /* */
411 /* ========================================================================= */
412
413 /* ------------------------------------------------------------------------- */
414
bbf_LocalScanner_copy(struct bbs_Context * cpA,struct bbf_LocalScanner * ptrA,const struct bbf_LocalScanner * srcPtrA)415 void bbf_LocalScanner_copy( struct bbs_Context* cpA,
416 struct bbf_LocalScanner* ptrA,
417 const struct bbf_LocalScanner* srcPtrA )
418 {
419 bbs_ERROR0( "bbf_LocalScanner_copy:\n Function is not available" );
420 }
421
422 /* ------------------------------------------------------------------------- */
423
bbf_LocalScanner_equal(struct bbs_Context * cpA,const struct bbf_LocalScanner * ptrA,const struct bbf_LocalScanner * srcPtrA)424 flag bbf_LocalScanner_equal( struct bbs_Context* cpA,
425 const struct bbf_LocalScanner* ptrA,
426 const struct bbf_LocalScanner* srcPtrA )
427 {
428 bbs_ERROR0( "bbf_LocalScanner_equal:\n Function is not available" );
429 return FALSE;
430 }
431
432 /* ------------------------------------------------------------------------- */
433
434 /* ========================================================================= */
435 /* */
436 /* ---- \ghd{ query functions } -------------------------------------------- */
437 /* */
438 /* ========================================================================= */
439
440 /* ------------------------------------------------------------------------- */
441
bbf_LocalScanner_positions(const struct bbf_LocalScanner * ptrA)442 uint32 bbf_LocalScanner_positions( const struct bbf_LocalScanner* ptrA )
443 {
444 int32 wL = ptrA->workScanRegionE.x2E - ptrA->workScanRegionE.x1E - ptrA->patchWidthE;
445 int32 hL = ptrA->workScanRegionE.y2E - ptrA->workScanRegionE.y1E - ptrA->patchHeightE;
446 return ( ( wL < 0 ) ? 0 : wL ) * ( ( hL < 0 ) ? 0 : hL );
447 }
448
449 /* ------------------------------------------------------------------------- */
450
bbf_LocalScanner_scanIndex(const struct bbf_LocalScanner * ptrA)451 uint32 bbf_LocalScanner_scanIndex( const struct bbf_LocalScanner* ptrA )
452 {
453 int32 wL = ptrA->workScanRegionE.x2E - ptrA->workScanRegionE.x1E - ptrA->patchWidthE;
454 return ( ptrA->yE - ptrA->workScanRegionE.y1E ) * wL + ( ptrA->xE - ptrA->workScanRegionE.x1E );
455 }
456
457 /* ------------------------------------------------------------------------- */
458
bbf_LocalScanner_pos(const struct bbf_LocalScanner * ptrA,int32 * xPtrA,int32 * yPtrA)459 void bbf_LocalScanner_pos( const struct bbf_LocalScanner* ptrA, int32* xPtrA, int32* yPtrA )
460 {
461 *xPtrA = ( ( ptrA->xE << ptrA->scaleExpE ) + ptrA->xOffE ) << 16;
462 *yPtrA = ( ( ptrA->yE << ptrA->scaleExpE ) + ptrA->yOffE ) << 16;
463 }
464
465 /* ------------------------------------------------------------------------- */
466
bbf_LocalScanner_idxPos(const struct bbf_LocalScanner * ptrA,uint32 scanIndexA,int32 * xPtrA,int32 * yPtrA)467 void bbf_LocalScanner_idxPos( const struct bbf_LocalScanner* ptrA, uint32 scanIndexA, int32* xPtrA, int32* yPtrA )
468 {
469 uint32 wL = ptrA->workScanRegionE.x2E - ptrA->workScanRegionE.x1E - ptrA->patchWidthE;
470 int32 xL = ( scanIndexA % wL ) + ptrA->workScanRegionE.x1E;
471 int32 yL = ( scanIndexA / wL ) + ptrA->workScanRegionE.y1E;
472 *xPtrA = ( ( xL << ptrA->scaleExpE ) + ptrA->xOffE ) << 16;
473 *yPtrA = ( ( yL << ptrA->scaleExpE ) + ptrA->yOffE ) << 16;
474 }
475
476 /* ------------------------------------------------------------------------- */
477
478 /* ========================================================================= */
479 /* */
480 /* ---- \ghd{ modify functions } ------------------------------------------- */
481 /* */
482 /* ========================================================================= */
483
484 /* ------------------------------------------------------------------------- */
485
bbf_LocalScanner_create(struct bbs_Context * cpA,struct bbf_LocalScanner * ptrA,uint32 patchWidthA,uint32 patchHeightA,uint32 scaleExpA,uint32 maxImageWidthA,uint32 maxImageHeightA,uint32 minScaleExpA,uint32 maxRadiusA,struct bbs_MemTbl * mtpA)486 void bbf_LocalScanner_create( struct bbs_Context* cpA,
487 struct bbf_LocalScanner* ptrA,
488 uint32 patchWidthA,
489 uint32 patchHeightA,
490 uint32 scaleExpA,
491 uint32 maxImageWidthA,
492 uint32 maxImageHeightA,
493 uint32 minScaleExpA,
494 uint32 maxRadiusA,
495 struct bbs_MemTbl* mtpA )
496 {
497 ptrA->patchWidthE = patchWidthA;
498 ptrA->patchHeightE = patchHeightA;
499 ptrA->scaleExpE = scaleExpA;
500 ptrA->maxImageWidthE = maxImageWidthA;
501 ptrA->maxImageHeightE = maxImageHeightA;
502 ptrA->minScaleExpE = minScaleExpA;
503 ptrA->maxRadiusE = maxRadiusA;
504 bbf_LocalScanner_alloc( cpA, ptrA, mtpA );
505 }
506
507 /* ------------------------------------------------------------------------- */
508
bbf_LocalScanner_bitParam(struct bbs_Context * cpA,struct bbf_LocalScanner * ptrA,const struct bbf_BitParam * bitParamPtrA)509 void bbf_LocalScanner_bitParam( struct bbs_Context* cpA,
510 struct bbf_LocalScanner* ptrA,
511 const struct bbf_BitParam* bitParamPtrA )
512 {
513 if( !bbf_BitParam_equal( cpA, &ptrA->bitParamE, bitParamPtrA ) )
514 {
515 bbf_BitParam_copy( cpA, &ptrA->bitParamE, bitParamPtrA );
516 bbf_LocalScanner_createBitImage( cpA, ptrA );
517 }
518
519 bbf_LocalScanner_resetScan( cpA, ptrA );
520 }
521
522 /* ------------------------------------------------------------------------- */
523
bbf_LocalScanner_origScanRegion(struct bbs_Context * cpA,struct bbf_LocalScanner * ptrA,const struct bts_Int16Rect * scanRegionPtrA)524 void bbf_LocalScanner_origScanRegion( struct bbs_Context* cpA,
525 struct bbf_LocalScanner* ptrA,
526 const struct bts_Int16Rect* scanRegionPtrA )
527 {
528 ptrA->origScanRegionE = *scanRegionPtrA;
529 bbf_LocalScanner_setWorkScanRegion( cpA, ptrA );
530 bbf_LocalScanner_resetScan( cpA, ptrA );
531 }
532
533 /* ------------------------------------------------------------------------- */
534
535 /* ========================================================================= */
536 /* */
537 /* ---- \ghd{ I/O } -------------------------------------------------------- */
538 /* */
539 /* ========================================================================= */
540
541 /* ------------------------------------------------------------------------- */
542
bbf_LocalScanner_memSize(struct bbs_Context * cpA,const struct bbf_LocalScanner * ptrA)543 uint32 bbf_LocalScanner_memSize( struct bbs_Context* cpA,
544 const struct bbf_LocalScanner* ptrA )
545 {
546 uint32 memSizeL = bbs_SIZEOF16( uint32 ) +
547 bbs_SIZEOF16( uint32 ); /* version */
548
549 memSizeL += bbs_SIZEOF16( ptrA->patchWidthE );
550 memSizeL += bbs_SIZEOF16( ptrA->patchHeightE );
551 memSizeL += bbs_SIZEOF16( ptrA->scaleExpE );
552 memSizeL += bbs_SIZEOF16( ptrA->maxImageWidthE );
553 memSizeL += bbs_SIZEOF16( ptrA->maxImageHeightE );
554 memSizeL += bbs_SIZEOF16( ptrA->minScaleExpE );
555 memSizeL += bbs_SIZEOF16( ptrA->maxRadiusE );
556
557 return memSizeL;
558 }
559
560 /* ------------------------------------------------------------------------- */
561
bbf_LocalScanner_memWrite(struct bbs_Context * cpA,const struct bbf_LocalScanner * ptrA,uint16 * memPtrA)562 uint32 bbf_LocalScanner_memWrite( struct bbs_Context* cpA,
563 const struct bbf_LocalScanner* ptrA,
564 uint16* memPtrA )
565 {
566 uint32 memSizeL = bbf_LocalScanner_memSize( cpA, ptrA );
567 memPtrA += bbs_memWrite32( &memSizeL, memPtrA );
568 memPtrA += bbs_memWriteUInt32( bbf_LOCAL_SCANNER_VERSION, memPtrA );
569
570 memPtrA += bbs_memWrite32( &ptrA->patchWidthE, memPtrA );
571 memPtrA += bbs_memWrite32( &ptrA->patchHeightE, memPtrA );
572 memPtrA += bbs_memWrite32( &ptrA->scaleExpE, memPtrA );
573 memPtrA += bbs_memWrite32( &ptrA->maxImageWidthE, memPtrA );
574 memPtrA += bbs_memWrite32( &ptrA->maxImageHeightE, memPtrA );
575 memPtrA += bbs_memWrite32( &ptrA->minScaleExpE, memPtrA );
576 memPtrA += bbs_memWrite32( &ptrA->maxRadiusE, memPtrA );
577 return memSizeL;
578 }
579
580 /* ------------------------------------------------------------------------- */
581
bbf_LocalScanner_memRead(struct bbs_Context * cpA,struct bbf_LocalScanner * ptrA,const uint16 * memPtrA,struct bbs_MemTbl * mtpA)582 uint32 bbf_LocalScanner_memRead( struct bbs_Context* cpA,
583 struct bbf_LocalScanner* ptrA,
584 const uint16* memPtrA,
585 struct bbs_MemTbl* mtpA )
586 {
587 uint32 memSizeL, versionL;
588
589 if( bbs_Context_error( cpA ) ) return 0;
590 memPtrA += bbs_memRead32( &memSizeL, memPtrA );
591 memPtrA += bbs_memReadVersion32( cpA, &versionL, bbf_LOCAL_SCANNER_VERSION, memPtrA );
592
593 memPtrA += bbs_memRead32( &ptrA->patchWidthE, memPtrA );
594 memPtrA += bbs_memRead32( &ptrA->patchHeightE, memPtrA );
595 memPtrA += bbs_memRead32( &ptrA->scaleExpE, memPtrA );
596 memPtrA += bbs_memRead32( &ptrA->maxImageWidthE, memPtrA );
597 memPtrA += bbs_memRead32( &ptrA->maxImageHeightE, memPtrA );
598 memPtrA += bbs_memRead32( &ptrA->minScaleExpE, memPtrA );
599 memPtrA += bbs_memRead32( &ptrA->maxRadiusE, memPtrA );
600
601 if( memSizeL != bbf_LocalScanner_memSize( cpA, ptrA ) )
602 {
603 bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bbf_LocalScanner_memRead( struct bem_ScanGradientMove* ptrA, const uint16* memPtrA ):\n"
604 "size mismatch" );
605 return 0;
606 }
607
608 if( bbs_Context_error( cpA ) ) return 0;
609
610 /* allocate arrays */
611 bbf_LocalScanner_alloc( cpA, ptrA, mtpA );
612
613 if( bbs_Context_error( cpA ) ) return 0;
614
615 return memSizeL;
616 }
617
618 /* ------------------------------------------------------------------------- */
619
620 /* ========================================================================= */
621 /* */
622 /* ---- \ghd{ exec functions } --------------------------------------------- */
623 /* */
624 /* ========================================================================= */
625
626 /* ------------------------------------------------------------------------- */
627
bbf_LocalScanner_resetScan(struct bbs_Context * cpA,struct bbf_LocalScanner * ptrA)628 void bbf_LocalScanner_resetScan( struct bbs_Context* cpA,
629 struct bbf_LocalScanner* ptrA )
630 {
631 ptrA->xE = ptrA->workScanRegionE.x1E;
632 ptrA->yE = ptrA->workScanRegionE.y1E;
633 bbf_LocalScanner_initPatchBuffer( cpA, ptrA );
634 }
635
636 /* ------------------------------------------------------------------------- */
637
bbf_LocalScanner_assign(struct bbs_Context * cpA,struct bbf_LocalScanner * ptrA,const uint8 * imagePtrA,uint32 imageWidthA,uint32 imageHeightA,const struct bbf_BitParam * paramPtrA)638 void bbf_LocalScanner_assign( struct bbs_Context* cpA,
639 struct bbf_LocalScanner* ptrA,
640 const uint8* imagePtrA,
641 uint32 imageWidthA,
642 uint32 imageHeightA,
643 const struct bbf_BitParam* paramPtrA )
644 {
645 if( ptrA->scaleExpE == 0 )
646 {
647 ptrA->workImagePtrE = imagePtrA;
648 ptrA->workWidthE = imageWidthA;
649 ptrA->workHeightE = imageHeightA;
650 }
651 else
652 {
653 ptrA->origImagePtrE = imagePtrA;
654 ptrA->origWidthE = imageWidthA;
655 ptrA->origHeightE = imageHeightA;
656 }
657
658 ptrA->bitParamE = *paramPtrA;
659 ptrA->xOffE = 0;
660 ptrA->yOffE = 0;
661 ptrA->origScanRegionE = bts_Int16Rect_create( 0, 0, imageWidthA, imageHeightA );
662 bbf_LocalScanner_downscale( cpA, ptrA );
663 bbf_LocalScanner_createBitImage( cpA, ptrA );
664 bbf_LocalScanner_resetScan( cpA, ptrA );
665 }
666
667 /* ------------------------------------------------------------------------- */
668
bbf_LocalScanner_getPatch(const struct bbf_LocalScanner * ptrA)669 const uint32* bbf_LocalScanner_getPatch( const struct bbf_LocalScanner* ptrA )
670 {
671 return ptrA->patchBufferE.arrPtrE + ptrA->xE;
672 }
673
674 /* ------------------------------------------------------------------------- */
675
bbf_LocalScanner_next(struct bbs_Context * cpA,struct bbf_LocalScanner * ptrA)676 flag bbf_LocalScanner_next( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA )
677 {
678 if( ( ptrA->xE + 1 ) < ptrA->workScanRegionE.x2E - ( int32 )ptrA->patchWidthE )
679 {
680 ptrA->xE++;
681 return TRUE;
682 }
683
684 if( ( ptrA->yE + 1 ) >= ptrA->workScanRegionE.y2E - ( int32 )ptrA->patchHeightE ) return FALSE;
685
686 ptrA->xE = ptrA->workScanRegionE.x1E;
687 ptrA->yE++;
688
689 {
690 uint32 offL = ( ptrA->yE & 0x1F );
691 uint32 rowL = ( ptrA->yE >> 5 ) + ( offL > 0 ? 1 : 0 );
692
693 uint32 widthL = ptrA->bitImageE.widthE;
694 uint32 sizeL = ptrA->workScanRegionE.x2E - ptrA->workScanRegionE.x1E;
695 uint32* dstL = ( uint32* )ptrA->patchBufferE.arrPtrE + ptrA->xE;
696 uint32 iL;
697
698 if( rowL < ptrA->bitImageE.heightE )
699 {
700 uint32* srcL = ptrA->bitImageE.arrE.arrPtrE + rowL * widthL + ptrA->xE;
701 if( offL > 0 )
702 {
703 uint32 shlL = 32 - offL;
704 for( iL = 0; iL < sizeL; iL++ ) dstL[ iL ] = ( dstL[ iL ] >> 1 ) | ( srcL[ iL ] << shlL );
705 }
706 else
707 {
708 bbs_memcpy32( dstL, srcL, sizeL );
709 }
710 }
711 else
712 {
713 for( iL = 0; iL < sizeL; iL++ ) dstL[ iL ] >>= 1;
714 }
715 }
716
717 return TRUE;
718 }
719
720 /* ------------------------------------------------------------------------- */
721
bbf_LocalScanner_goToXY(struct bbs_Context * cpA,struct bbf_LocalScanner * ptrA,int32 xA,int32 yA)722 void bbf_LocalScanner_goToXY( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA, int32 xA, int32 yA )
723 {
724 bbs_DEF_fNameL( "void bbf_LocalScanner_goToXY( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA, int32 xA, int32 yA )" )
725 if( xA < ptrA->workScanRegionE.x1E || xA >= ptrA->workScanRegionE.x2E - ( int32 )ptrA->patchWidthE )
726 {
727 bbs_ERROR1( "%s:\nxA out of range", fNameL );
728 return;
729 }
730 ptrA->xE = xA;
731 if( ptrA->yE == yA ) return;
732 if( yA < ptrA->workScanRegionE.y1E || yA >= ptrA->workScanRegionE.y2E - ( int32 )ptrA->patchHeightE )
733 {
734 bbs_ERROR1( "%s:\nyA out of range", fNameL );
735 return;
736 }
737 ptrA->yE = yA;
738
739 {
740 uint32 offL = ( ptrA->yE & 0x1F );
741 uint32 rowL = ( ptrA->yE >> 5 ) + ( offL > 0 ? 1 : 0 );
742
743 uint32 sizeL = ptrA->workScanRegionE.x2E - ptrA->workScanRegionE.x1E;
744 uint32 imgWidthL = ptrA->bitImageE.widthE;
745 uint32 imgOffsL = ptrA->workScanRegionE.x1E;
746 uint32* dstL = ptrA->patchBufferE.arrPtrE + imgOffsL;
747 uint32 iL;
748
749 if( rowL < ptrA->bitImageE.heightE )
750 {
751 if( offL > 0 )
752 {
753 uint32* src1L = ptrA->bitImageE.arrE.arrPtrE + rowL * imgWidthL + imgOffsL;
754 uint32* src0L = src1L - imgWidthL;
755 uint32 shlL = 32 - offL;
756 for( iL = 0; iL < sizeL; iL++ ) dstL[ iL ] = ( src0L[ iL ] >> offL ) | ( src1L[ iL ] << shlL );
757 }
758 else
759 {
760 bbs_memcpy32( dstL, ptrA->bitImageE.arrE.arrPtrE + rowL * imgWidthL + imgOffsL, sizeL );
761 }
762 }
763 else
764 {
765 uint32* srcL = ptrA->bitImageE.arrE.arrPtrE + ( rowL - 1 ) * imgWidthL + imgOffsL;
766 for( iL = 0; iL < sizeL; iL++ ) dstL[ iL ] = srcL[ iL ] >> offL;
767 }
768 }
769 }
770
771 /* ------------------------------------------------------------------------- */
772
bbf_LocalScanner_goToIndex(struct bbs_Context * cpA,struct bbf_LocalScanner * ptrA,uint32 scanIndexA)773 void bbf_LocalScanner_goToIndex( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA, uint32 scanIndexA )
774 {
775 uint32 wL = ptrA->workScanRegionE.x2E - ptrA->workScanRegionE.x1E - ptrA->patchWidthE;
776 bbf_LocalScanner_goToXY( cpA, ptrA,
777 ( scanIndexA % wL ) + ptrA->workScanRegionE.x1E,
778 ( scanIndexA / wL ) + ptrA->workScanRegionE.y1E );
779 }
780
781 /* ------------------------------------------------------------------------- */
782
bbf_LocalScanner_nextOffset(struct bbs_Context * cpA,struct bbf_LocalScanner * ptrA)783 flag bbf_LocalScanner_nextOffset( struct bbs_Context* cpA, struct bbf_LocalScanner* ptrA )
784 {
785 int32 maxL = ( 1 << ptrA->scaleExpE );
786 if( ptrA->yOffE == maxL ) return FALSE;
787
788 ptrA->xOffE++;
789
790 if( ptrA->xOffE == maxL )
791 {
792 ptrA->xOffE = 0;
793 ptrA->yOffE++;
794 if( ptrA->yOffE == maxL ) return FALSE;
795 }
796
797 bbf_LocalScanner_downscale( cpA, ptrA );
798 bbf_LocalScanner_createBitImage( cpA, ptrA );
799 bbf_LocalScanner_setWorkScanRegion( cpA, ptrA );
800 bbf_LocalScanner_resetScan( cpA, ptrA );
801
802 return TRUE;
803 }
804
805 /* ------------------------------------------------------------------------- */
806
807 /* ========================================================================= */
808