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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 669 const uint32* bbf_LocalScanner_getPatch( const struct bbf_LocalScanner* ptrA ) 670 { 671 return ptrA->patchBufferE.arrPtrE + ptrA->xE; 672 } 673 674 /* ------------------------------------------------------------------------- */ 675 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 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 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 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