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/Math.h" 20 #include "b_BasicEm/Functions.h" 21 #include "b_ImageEm/UInt16ByteImage.h" 22 23 /* ------------------------------------------------------------------------- */ 24 25 /* ========================================================================= */ 26 /* */ 27 /* ---- \ghd{ auxiliary functions } ---------------------------------------- */ 28 /* */ 29 /* ========================================================================= */ 30 31 /* ------------------------------------------------------------------------- */ 32 33 /* ========================================================================= */ 34 /* */ 35 /* ---- \ghd{ constructor / destructor } ----------------------------------- */ 36 /* */ 37 /* ========================================================================= */ 38 39 /* ------------------------------------------------------------------------- */ 40 41 void bim_UInt16ByteImage_init( struct bbs_Context* cpA, 42 struct bim_UInt16ByteImage* ptrA ) 43 { 44 bbs_UInt16Arr_init( cpA, &ptrA->arrE ); 45 ptrA->widthE = 0; 46 ptrA->heightE = 0; 47 } 48 49 /* ------------------------------------------------------------------------- */ 50 51 void bim_UInt16ByteImage_exit( struct bbs_Context* cpA, 52 struct bim_UInt16ByteImage* ptrA ) 53 { 54 bbs_UInt16Arr_exit( cpA, &ptrA->arrE ); 55 ptrA->widthE = 0; 56 ptrA->heightE = 0; 57 } 58 59 /* ------------------------------------------------------------------------- */ 60 61 /* ========================================================================= */ 62 /* */ 63 /* ---- \ghd{ operators } -------------------------------------------------- */ 64 /* */ 65 /* ========================================================================= */ 66 67 /* ------------------------------------------------------------------------- */ 68 69 void bim_UInt16ByteImage_copy( struct bbs_Context* cpA, 70 struct bim_UInt16ByteImage* ptrA, 71 const struct bim_UInt16ByteImage* srcPtrA ) 72 { 73 #ifdef DEBUG1 74 if( ptrA->arrE.sizeE < srcPtrA->arrE.sizeE ) 75 { 76 bbs_ERROR0( "void bim_UInt16ByteImage_copy( struct bim_UInt16ByteImage*, const struct bim_UInt16ByteImage* ):\n" 77 "Unsufficient allocated memory in destination image" ); 78 return; 79 } 80 #endif 81 ptrA->widthE = srcPtrA->widthE; 82 ptrA->heightE = srcPtrA->heightE; 83 bbs_UInt16Arr_copy( cpA, &ptrA->arrE, &srcPtrA->arrE ); 84 } 85 86 /* ------------------------------------------------------------------------- */ 87 88 flag bim_UInt16ByteImage_equal( struct bbs_Context* cpA, 89 const struct bim_UInt16ByteImage* ptrA, 90 const struct bim_UInt16ByteImage* srcPtrA ) 91 { 92 if( ptrA->widthE != srcPtrA->widthE ) return FALSE; 93 if( ptrA->heightE != srcPtrA->heightE ) return FALSE; 94 return bbs_UInt16Arr_equal( cpA, &ptrA->arrE, &srcPtrA->arrE ); 95 } 96 97 /* ------------------------------------------------------------------------- */ 98 99 /* ========================================================================= */ 100 /* */ 101 /* ---- \ghd{ query functions } -------------------------------------------- */ 102 /* */ 103 /* ========================================================================= */ 104 105 /* ------------------------------------------------------------------------- */ 106 107 uint32 bim_UInt16ByteImage_checkSum( struct bbs_Context* cpA, 108 const struct bim_UInt16ByteImage* ptrA ) 109 { 110 uint32 sumL =0 ; 111 uint32 iL; 112 uint32 sizeL = ptrA->arrE.sizeE; 113 const uint16* ptrL = ptrA->arrE.arrPtrE; 114 for( iL =0; iL < sizeL; iL++ ) 115 { 116 sumL += *ptrL++; 117 } 118 return sumL; 119 } 120 121 /* ------------------------------------------------------------------------- */ 122 123 /* ========================================================================= */ 124 /* */ 125 /* ---- \ghd{ modify functions } ------------------------------------------- */ 126 /* */ 127 /* ========================================================================= */ 128 129 /* ------------------------------------------------------------------------- */ 130 131 void bim_UInt16ByteImage_create( struct bbs_Context* cpA, 132 struct bim_UInt16ByteImage* ptrA, 133 uint32 widthA, 134 uint32 heightA, 135 struct bbs_MemSeg* mspA ) 136 { 137 if( bbs_Context_error( cpA ) ) return; 138 if( widthA & 1 ) 139 { 140 bbs_ERROR0( "bim_UInt16ByteImage_create( .... ): width of image must be even" ); 141 return; 142 } 143 144 if( ptrA->arrE.arrPtrE != 0 ) 145 { 146 bim_UInt16ByteImage_size( cpA, ptrA, widthA, heightA ); 147 } 148 else 149 { 150 bbs_UInt16Arr_create( cpA, &ptrA->arrE, ( widthA * heightA ) >> 1, mspA ); 151 ptrA->widthE = widthA; 152 ptrA->heightE = heightA; 153 } 154 } 155 156 /* ------------------------------------------------------------------------- */ 157 158 void bim_UInt16ByteImage_assignExternalImage( struct bbs_Context* cpA, 159 struct bim_UInt16ByteImage* ptrA, 160 struct bim_UInt16ByteImage* srcPtrA ) 161 { 162 struct bbs_MemSeg sharedSegL = bbs_MemSeg_createShared( cpA, srcPtrA->arrE.arrPtrE, ( srcPtrA->widthE * srcPtrA->heightE ) / 2 ); 163 164 if( ptrA->arrE.arrPtrE != 0 ) 165 { 166 bbs_ERROR0( "void bim_UInt16ByteImage_assignExternalImage( ... ): image was already created once" ); 167 return; 168 } 169 170 bim_UInt16ByteImage_create( cpA, ptrA, 171 srcPtrA->widthE, 172 srcPtrA->heightE, 173 &sharedSegL ); 174 } 175 176 /* ------------------------------------------------------------------------- */ 177 178 void bim_UInt16ByteImage_size( struct bbs_Context* cpA, 179 struct bim_UInt16ByteImage* ptrA, 180 uint32 widthA, uint32 heightA ) 181 { 182 if( widthA & 1 ) 183 { 184 bbs_ERROR0( "bim_UInt16ByteImage_size( .... ): width of image must be even" ); 185 return; 186 } 187 188 if( ptrA->arrE.allocatedSizeE < ( ( widthA * heightA ) >> 1 ) ) 189 { 190 bbs_ERROR0( "void bim_UInt16ByteImage_size( struct bim_UInt16ByteImage*, uint32 sizeA ):\n" 191 "Unsufficient allocated memory" ); 192 return; 193 } 194 bbs_UInt16Arr_size( cpA, &ptrA->arrE, ( widthA * heightA ) >> 1 ); 195 ptrA->widthE = widthA; 196 ptrA->heightE = heightA; 197 } 198 199 /* ------------------------------------------------------------------------- */ 200 201 /* ========================================================================= */ 202 /* */ 203 /* ---- \ghd{ I/O } -------------------------------------------------------- */ 204 /* */ 205 /* ========================================================================= */ 206 207 /* ------------------------------------------------------------------------- */ 208 209 uint32 bim_UInt16ByteImage_memSize( struct bbs_Context* cpA, 210 const struct bim_UInt16ByteImage* ptrA ) 211 { 212 return bbs_SIZEOF16( uint32 ) 213 + bbs_SIZEOF16( uint32 ) /* version */ 214 + bbs_SIZEOF16( ptrA->widthE ) 215 + bbs_SIZEOF16( ptrA->heightE ) 216 + bbs_UInt16Arr_memSize( cpA, &ptrA->arrE ); 217 } 218 219 /* ------------------------------------------------------------------------- */ 220 221 uint32 bim_UInt16ByteImage_memWrite( struct bbs_Context* cpA, 222 const struct bim_UInt16ByteImage* ptrA, 223 uint16* memPtrA ) 224 { 225 uint32 memSizeL = bim_UInt16ByteImage_memSize( cpA, ptrA ); 226 memPtrA += bbs_memWrite32( &memSizeL, memPtrA ); 227 memPtrA += bbs_memWriteUInt32( bim_UINT16_IMAGE_VERSION, memPtrA ); 228 memPtrA += bbs_memWrite32( &ptrA->widthE, memPtrA ); 229 memPtrA += bbs_memWrite32( &ptrA->heightE, memPtrA ); 230 bbs_UInt16Arr_memWrite( cpA, &ptrA->arrE, memPtrA ); 231 return memSizeL; 232 } 233 234 /* ------------------------------------------------------------------------- */ 235 236 uint32 bim_UInt16ByteImage_memRead( struct bbs_Context* cpA, 237 struct bim_UInt16ByteImage* ptrA, 238 const uint16* memPtrA, 239 struct bbs_MemSeg* mspA ) 240 { 241 uint32 memSizeL, versionL, widthL, heightL; 242 if( bbs_Context_error( cpA ) ) return 0; 243 memPtrA += bbs_memRead32( &memSizeL, memPtrA ); 244 memPtrA += bbs_memReadVersion32( cpA, &versionL, bim_UINT16_IMAGE_VERSION, memPtrA ); 245 memPtrA += bbs_memRead32( &widthL, memPtrA ); 246 memPtrA += bbs_memRead32( &heightL, memPtrA ); 247 248 ptrA->widthE = widthL; 249 ptrA->heightE = heightL; 250 bbs_UInt16Arr_memRead( cpA, &ptrA->arrE, memPtrA, mspA ); 251 252 if( memSizeL != bim_UInt16ByteImage_memSize( cpA, ptrA ) ) 253 { 254 bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bim_UInt16ByteImage_memRead( const struct bim_UInt16ByteImage* ptrA, const void* memPtrA ):\n" 255 "size mismatch" ); 256 return 0; 257 } 258 return memSizeL; 259 } 260 261 /* ------------------------------------------------------------------------- */ 262 263 /* ========================================================================= */ 264 /* */ 265 /* ---- \ghd{ exec functions } --------------------------------------------- */ 266 /* */ 267 /* ========================================================================= */ 268 269 /* ------------------------------------------------------------------------- */ 270 271 void bim_UInt16ByteImage_setAllPixels( struct bbs_Context* cpA, 272 struct bim_UInt16ByteImage* ptrA, 273 uint16 valueA ) 274 { 275 long iL; 276 uint16* ptrL = ptrA->arrE.arrPtrE; 277 uint16 fillL = ( valueA & 0x0FF ) | ( ( valueA & 0x0FF ) << 8 ); 278 for( iL = ptrA->arrE.sizeE; iL > 0; iL-- ) 279 { 280 *ptrL++ = fillL; 281 } 282 } 283 284 /* ------------------------------------------------------------------------- */ 285 286 /** 287 M-------------------------------------------------------M 288 | | | | 289 | | | | 290 | | | | 291 | | | | 292 | region x0y0 | region x1y0 | region x2y0 | 293 | | | | 294 | | | | 295 | | | | 296 |---------------I-----------------------I---------------| 297 | | | | 298 | | | | 299 | | | | 300 | | | | 301 | | | | 302 | | | | 303 | region x0y1 | region x1y1 | region x2y1 | 304 | | | | 305 | | | | 306 | | | | 307 | | | | 308 | | | | 309 | | | | 310 | | | | 311 |---------------I-----------------------I---------------| 312 | | | | 313 | | | | 314 | | | | 315 | | | | 316 | region x0y2 | region x1y2 | region x2y2 | 317 | | | | 318 | | | | 319 | | | | 320 M-------------------------------------------------------M 321 322 323 To see how the code is organized. Refer to the diagram above. 324 Assume the original image after applying the tranzformations(translation, rotation and scaling) is "O" 325 (boundaries of the image are shown above bounded by the letter 'O'). 326 This image is being Warped to the area "M" (boundaries of this area are bounded by the letter 'M'). 327 328 Refer to the source code below to point to the loop that maps pixels in the particular region. 329 */ 330 331 /** applies affine linear warping to pixels positions of imageA before copying the into *ptrA */ 332 void bim_UInt16ByteImage_warp( struct bbs_Context* cpA, 333 struct bim_UInt16ByteImage* ptrA, 334 const struct bim_UInt16ByteImage* srcPtrA, 335 const struct bts_Flt16Alt2D* altPtrA, 336 int32 resultWidthA, 337 int32 resultHeightA ) 338 { 339 long srcWidthL = srcPtrA->widthE; 340 long srcHeightL = srcPtrA->heightE; 341 long halfSrcWidthL = srcWidthL >> 1; 342 343 struct bts_Flt16Alt2D invAlt2DL; 344 345 uint16* dstPtrL; 346 const uint16* ulPtrL = srcPtrA->arrE.arrPtrE; 347 const uint16* urPtrL = ulPtrL + halfSrcWidthL - 1; 348 const uint16* llPtrL = ulPtrL + ( srcHeightL - 1 ) * halfSrcWidthL; 349 const uint16* lrPtrL = llPtrL + halfSrcWidthL - 1; 350 351 uint32 iL, jL; 352 int32 shiftL; 353 354 const uint16 bbpL = 16; 355 int32 maxInt32Value8bbpL = 0x7FFFFFFF; 356 357 /* The bbp for all these variables is the same as bbpL */ 358 int32 mxxL; 359 int32 mxyL; 360 int32 myxL; 361 int32 myyL; 362 363 int32 txL; 364 int32 tyL; 365 366 int32 xL; 367 int32 yL; 368 369 bim_UInt16ByteImage_size( cpA, ptrA, resultWidthA, resultHeightA ); 370 dstPtrL = ptrA->arrE.arrPtrE; 371 372 /* compute inverse */ 373 invAlt2DL = bts_Flt16Alt2D_inverted( altPtrA ); 374 375 if( srcWidthL == 0 || srcHeightL == 0 ) 376 { 377 bim_UInt16ByteImage_size( cpA, ptrA, srcWidthL, srcHeightL ); 378 bbs_ERROR2( "Size of output image is %d/%d", srcWidthL, srcHeightL ); 379 return; 380 } 381 382 /* align Matrix and Vector to 8 bits bbp */ 383 shiftL = invAlt2DL.matE.bbpE - bbpL; 384 if( shiftL >= 0 ) 385 { 386 mxxL = ( int32 )invAlt2DL.matE.xxE >> shiftL; 387 mxyL = ( int32 )invAlt2DL.matE.xyE >> shiftL; 388 myxL = ( int32 )invAlt2DL.matE.yxE >> shiftL; 389 myyL = ( int32 )invAlt2DL.matE.yyE >> shiftL; 390 } 391 else 392 { 393 /* Check for overflow since we are left shifting. */ 394 maxInt32Value8bbpL >>= -shiftL; 395 if( invAlt2DL.matE.xxE > maxInt32Value8bbpL || 396 invAlt2DL.matE.xyE > maxInt32Value8bbpL || 397 invAlt2DL.matE.yxE > maxInt32Value8bbpL || 398 invAlt2DL.matE.yyE > maxInt32Value8bbpL ) 399 { 400 /* Overflow error */ 401 bbs_ERROR5( "The values in the transformation matrix cause overflow during bitshift\n%d, %d,\n%d, %d\n" 402 "The maximum allowed value is %d", 403 invAlt2DL.matE.xxE >> invAlt2DL.matE.bbpE, 404 invAlt2DL.matE.xyE >> invAlt2DL.matE.bbpE, 405 invAlt2DL.matE.yxE >> invAlt2DL.matE.bbpE, 406 invAlt2DL.matE.yyE >> invAlt2DL.matE.bbpE, 407 maxInt32Value8bbpL >> ( bbpL - ( -shiftL ) ) ); 408 return; 409 } 410 411 mxxL = ( int32 )invAlt2DL.matE.xxE << -shiftL; 412 mxyL = ( int32 )invAlt2DL.matE.xyE << -shiftL; 413 myxL = ( int32 )invAlt2DL.matE.yxE << -shiftL; 414 myyL = ( int32 )invAlt2DL.matE.yyE << -shiftL; 415 maxInt32Value8bbpL <<= -shiftL; 416 } 417 invAlt2DL.matE.bbpE = bbpL; 418 419 shiftL = invAlt2DL.vecE.bbpE - bbpL; 420 if( shiftL >= 0 ) 421 { 422 txL = ( int32 )invAlt2DL.vecE.xE >> shiftL; 423 tyL = ( int32 )invAlt2DL.vecE.yE >> shiftL; 424 } 425 else 426 { 427 /* Check for overflow since we are left shifting. */ 428 maxInt32Value8bbpL >>= -shiftL; 429 if( invAlt2DL.vecE.xE > maxInt32Value8bbpL || 430 invAlt2DL.vecE.yE > maxInt32Value8bbpL ) 431 { 432 /* Overflow error */ 433 bbs_ERROR3( "The values in the vector cause overflow during bitshift\n%d, %d,\n" 434 "The maximum allowed value is %d", 435 invAlt2DL.vecE.xE >> invAlt2DL.vecE.bbpE, 436 invAlt2DL.vecE.yE >> invAlt2DL.vecE.bbpE, 437 maxInt32Value8bbpL >> ( bbpL - ( -shiftL ) ) ); 438 return; 439 } 440 txL = ( int32 )invAlt2DL.vecE.xE << -shiftL; 441 tyL = ( int32 )invAlt2DL.vecE.yE << -shiftL; 442 maxInt32Value8bbpL <<= -shiftL; 443 } 444 invAlt2DL.vecE.bbpE = bbpL; 445 446 /* For each destination pixel find the correspoding source pixel by applying the inverse transformation */ 447 for( jL = 0; jL < ptrA->heightE; jL++ ) 448 { 449 xL = txL + mxyL * jL; 450 yL = tyL + myyL * jL; 451 for( iL = 0; iL < ptrA->widthE; iL++ ) 452 { 453 const uint16 bbpLby2L = bbpL / 2; 454 const int32 oneL = ( int32 )0x00000001 << bbpLby2L; 455 const int32 fractionOnlyL = 0xFFFFFFFF >> ( 32 - bbpL ); 456 uint16 dstPixelL; 457 458 /* The bbp for all these variables is the same as bbpLby2L */ 459 int32 f2xL; 460 int32 f2yL; 461 int32 f1xL; 462 int32 f1yL; 463 464 /* always whole numbers with a bbp of 0 */ 465 int32 kL, khL; 466 int32 lL; 467 468 flag kEvenL; 469 470 /* The bbpE for these variables is bbpLby2L */ 471 int32 valL; 472 473 /* Get the whole numbers only and make the bbp 0. */ 474 kL = xL >> bbpL; 475 lL = yL >> bbpL; 476 477 khL = kL >> 1; 478 kEvenL = !( kL & 1 ); 479 480 /* fraction of destination pixel in the next source pixel */ 481 f2xL = ( xL & fractionOnlyL ) >> bbpLby2L; 482 f2yL = ( yL & fractionOnlyL ) >> bbpLby2L; 483 /* fraction of destination pixel in the current source pixel */ 484 f1xL = oneL - f2xL; 485 f1yL = oneL - f2yL; 486 487 /* increment values for next loop */ 488 xL += mxxL; 489 yL += myxL; 490 491 if( lL < 0 ) 492 { 493 if( kL < 0 ) 494 { 495 /* handle all pixels in region x0y0 */ 496 dstPixelL = *ulPtrL & 0x0FF; 497 } 498 else if( kL >= srcWidthL - 1 ) 499 { 500 /* handle all pixels in region x2y0 */ 501 dstPixelL = *urPtrL >> 8; 502 } 503 else 504 { 505 /* handle all pixels in region x1y0 */ 506 /* The bbp has shifted left by bbpLby2L */ 507 if( kEvenL ) 508 { 509 uint16 srcL = *( ulPtrL + khL ); 510 valL = f1xL * ( srcL & 0x00FF ) + f2xL * ( srcL >> 8 ); 511 } 512 else 513 { 514 valL = f1xL * ( *( ulPtrL + khL ) >> 8 ) + f2xL * ( *( ulPtrL + khL + 1 ) & 0x0FF ); 515 } 516 dstPixelL = valL >> bbpLby2L; 517 } 518 } /* if( lL < 0 ) */ 519 else if( lL >= srcHeightL - 1 ) 520 { 521 if( kL < 0 ) 522 { 523 /* handle all pixels in region x0y2 */ 524 dstPixelL = *llPtrL & 0x0FF; 525 } 526 else if( kL >= srcWidthL - 1 ) 527 { 528 /* handle all pixels in region x2y2 */ 529 dstPixelL = *lrPtrL >> 8; 530 } 531 else 532 { 533 /* handle all pixels in region x1y2 */ 534 /* The bbp has shifted left by bbpLby2L */ 535 if( kEvenL ) 536 { 537 uint16 srcL = *( llPtrL + khL ); 538 valL = f1xL * ( srcL & 0x00FF ) + f2xL * ( srcL >> 8 ); 539 } 540 else 541 { 542 valL = f1xL * ( *( llPtrL + khL ) >> 8 ) + f2xL * ( *( llPtrL + khL + 1 ) & 0x0FF ); 543 } 544 545 dstPixelL = valL >> bbpLby2L; 546 } 547 } /* if( lL >= srcHeightL - 1 ) */ 548 else 549 { 550 const uint16* ptr1L; 551 const uint16* ptr2L; 552 553 ptr1L = ulPtrL + lL * halfSrcWidthL; 554 /* point to the pixel in the same column */ 555 ptr2L = ptr1L + halfSrcWidthL; 556 if( kL < 0 ) 557 { 558 /* handle all pixels in region x0y1 */ 559 valL = f1yL * ( *ptr1L & 0x0FF ) + f2yL * ( *ptr2L & 0x0FF ); 560 dstPixelL = valL >> bbpLby2L; 561 } 562 else if( kL >= srcWidthL - 1 ) 563 { 564 /* handle all pixels in region x2y1 */ 565 valL = f1yL * ( *( ptr1L + halfSrcWidthL - 1 ) >> 8 ) + 566 f2yL * ( *( ptr2L + halfSrcWidthL - 1 ) >> 8 ); 567 dstPixelL = valL >> bbpLby2L; 568 } 569 else 570 { 571 /* assuming that bbpL = bbpLby2 * 2 */ 572 /* The bbp for these variables is bbpL */ 573 int32 v1L; 574 int32 v2L; 575 const int32 halfL = ( int32 )0x00000001 << ( bbpL - 1 ); 576 577 /* handle all pixels in region x1y1 */ 578 if( kEvenL ) 579 { 580 #ifdef HW_BIG_ENDIAN 581 /* Our images are in byte order for big & little endian so when using a 582 16bit ptr our bytes will be swapped on big endian hardware shift and mask*/ 583 v1L = f1xL * ( *( ptr1L + khL ) >> 8 ) + f2xL * ( *( ptr1L + khL ) & 0x0FF ); 584 v2L = f1xL * ( *( ptr2L + khL ) >> 8 ) + f2xL * ( *( ptr2L + khL ) & 0x0FF ); 585 #else 586 v1L = f1xL * ( *( ptr1L + khL ) & 0x0FF ) + f2xL * ( *( ptr1L + khL ) >> 8 ); 587 v2L = f1xL * ( *( ptr2L + khL ) & 0x0FF ) + f2xL * ( *( ptr2L + khL ) >> 8 ); 588 #endif 589 } 590 else 591 { 592 #ifdef HW_BIG_ENDIAN 593 v1L = f1xL * ( *( ptr1L + khL ) & 0x0FF ) + f2xL * ( *( ptr1L + khL + 1 ) >> 8 ); 594 v2L = f1xL * ( *( ptr2L + khL ) & 0x0FF ) + f2xL * ( *( ptr2L + khL + 1 ) >> 8 ); 595 #else 596 v1L = f1xL * ( *( ptr1L + khL ) >> 8 ) + f2xL * ( *( ptr1L + khL + 1 ) & 0x0FF ); 597 v2L = f1xL * ( *( ptr2L + khL ) >> 8 ) + f2xL * ( *( ptr2L + khL + 1 ) & 0x0FF ); 598 #endif 599 } 600 /* adding the half to round off the resulting value */ 601 valL = v1L * f1yL + v2L * f2yL + halfL; 602 dstPixelL = valL >> bbpL; 603 } 604 } 605 606 if( iL & 1 ) 607 { 608 #ifdef HW_BIG_ENDIAN 609 *dstPtrL |= dstPixelL & 0x0FF; 610 #else 611 *dstPtrL |= dstPixelL << 8; 612 #endif 613 dstPtrL++; 614 } 615 else 616 { 617 #ifdef HW_BIG_ENDIAN 618 *dstPtrL = dstPixelL << 8; 619 #else 620 *dstPtrL = dstPixelL & 0x0FF; 621 #endif 622 } 623 624 } /* iL loop */ 625 } /* jL loop */ 626 627 } 628 629 /* ------------------------------------------------------------------------- */ 630 631 #ifndef HW_TMS320C5x /* 16bit architecture excluded */ 632 633 void bim_UInt16ByteImage_warp8( struct bbs_Context* cpA, 634 struct bim_UInt16ByteImage* ptrA, 635 const struct bim_UInt16ByteImage* srcPtrA, 636 const struct bts_Flt16Alt2D* altPtrA, 637 int32 resultWidthA, 638 int32 resultHeightA ) 639 { 640 long srcWidthL = srcPtrA->widthE; 641 long srcHeightL = srcPtrA->heightE; 642 643 struct bts_Flt16Alt2D invAlt2DL; 644 645 uint8* dstPtrL; 646 const uint8* ulPtrL = ( const uint8* )srcPtrA->arrE.arrPtrE; 647 const uint8* urPtrL = ulPtrL + srcWidthL - 1; 648 const uint8* llPtrL = ulPtrL + ( srcHeightL - 1 ) * srcWidthL; 649 const uint8* lrPtrL = llPtrL + srcWidthL - 1; 650 651 uint32 iL, jL; 652 int32 shiftL; 653 654 const uint16 bbpL = 16; 655 int32 maxInt32Value8bbpL = 0x7FFFFFFF; 656 657 /* The bbp for all these variables is the same as bbpL */ 658 int32 mxxL; 659 int32 mxyL; 660 int32 myxL; 661 int32 myyL; 662 663 int32 txL; 664 int32 tyL; 665 666 int32 xL; 667 int32 yL; 668 669 bim_UInt16ByteImage_size( cpA, ptrA, resultWidthA, resultHeightA ); 670 dstPtrL = ( uint8* )ptrA->arrE.arrPtrE; 671 672 /* compute inverse */ 673 invAlt2DL = bts_Flt16Alt2D_inverted( altPtrA ); 674 675 if( srcWidthL == 0 || srcHeightL == 0 ) 676 { 677 bbs_ERROR2( "Size of output image is %d/%d", srcWidthL, srcHeightL ); 678 return; 679 } 680 681 /* align Matrix and Vector to 8 bits bbp */ 682 shiftL = invAlt2DL.matE.bbpE - bbpL; 683 if( shiftL >= 0 ) 684 { 685 mxxL = ( int32 )invAlt2DL.matE.xxE >> shiftL; 686 mxyL = ( int32 )invAlt2DL.matE.xyE >> shiftL; 687 myxL = ( int32 )invAlt2DL.matE.yxE >> shiftL; 688 myyL = ( int32 )invAlt2DL.matE.yyE >> shiftL; 689 } 690 else 691 { 692 /* Check for overflow since we are left shifting. */ 693 maxInt32Value8bbpL >>= -shiftL; 694 if( invAlt2DL.matE.xxE > maxInt32Value8bbpL || 695 invAlt2DL.matE.xyE > maxInt32Value8bbpL || 696 invAlt2DL.matE.yxE > maxInt32Value8bbpL || 697 invAlt2DL.matE.yyE > maxInt32Value8bbpL ) 698 { 699 /* Overflow error */ 700 bbs_ERROR5( "The values in the transformation matrix cause overflow during bitshift\n%d, %d,\n%d, %d\n" 701 "The maximum allowed value is %d", 702 ( int32 )invAlt2DL.matE.xxE >> invAlt2DL.matE.bbpE, 703 ( int32 )invAlt2DL.matE.xyE >> invAlt2DL.matE.bbpE, 704 ( int32 )invAlt2DL.matE.yxE >> invAlt2DL.matE.bbpE, 705 ( int32 )invAlt2DL.matE.yyE >> invAlt2DL.matE.bbpE, 706 maxInt32Value8bbpL >> ( bbpL - ( -shiftL ) ) ); 707 return; 708 } 709 710 mxxL = ( int32 )invAlt2DL.matE.xxE << -shiftL; 711 mxyL = ( int32 )invAlt2DL.matE.xyE << -shiftL; 712 myxL = ( int32 )invAlt2DL.matE.yxE << -shiftL; 713 myyL = ( int32 )invAlt2DL.matE.yyE << -shiftL; 714 maxInt32Value8bbpL <<= -shiftL; 715 } 716 invAlt2DL.matE.bbpE = bbpL; 717 718 shiftL = invAlt2DL.vecE.bbpE - bbpL; 719 if( shiftL >= 0 ) 720 { 721 txL = ( int32 )invAlt2DL.vecE.xE >> shiftL; 722 tyL = ( int32 )invAlt2DL.vecE.yE >> shiftL; 723 } 724 else 725 { 726 /* Check for overflow since we are left shifting. */ 727 maxInt32Value8bbpL >>= -shiftL; 728 if( invAlt2DL.vecE.xE > maxInt32Value8bbpL || 729 invAlt2DL.vecE.yE > maxInt32Value8bbpL ) 730 { 731 /* Overflow error */ 732 bbs_ERROR3( "The values in the vector cause overflow during bitshift\n%d, %d,\n" 733 "The maximum allowed value is %d", 734 invAlt2DL.vecE.xE >> invAlt2DL.vecE.bbpE, 735 invAlt2DL.vecE.yE >> invAlt2DL.vecE.bbpE, 736 maxInt32Value8bbpL >> ( bbpL - ( -shiftL ) ) ); 737 return; 738 } 739 txL = ( int32 )invAlt2DL.vecE.xE << -shiftL; 740 tyL = ( int32 )invAlt2DL.vecE.yE << -shiftL; 741 maxInt32Value8bbpL <<= -shiftL; 742 } 743 invAlt2DL.vecE.bbpE = bbpL; 744 745 /* For each destination pixel find the correspoding source pixel by applying the inverse transformation */ 746 for( jL = 0; jL < ptrA->heightE; jL++ ) 747 { 748 xL = txL + mxyL * jL; 749 yL = tyL + myyL * jL; 750 for( iL = 0; iL < ptrA->widthE; iL++ ) 751 { 752 const uint16 bbpLby2L = bbpL / 2; 753 const int32 oneL = ( int32 )0x00000001 << bbpLby2L; 754 const int32 fractionOnlyL = 0xFFFFFFFF >> ( 32 - bbpL ); 755 756 /* The bbp for all these variables is the same as bbpLby2L */ 757 int32 f2xL; 758 int32 f2yL; 759 int32 f1xL; 760 int32 f1yL; 761 762 /* always whole numbers with a bbp of 0 */ 763 int32 kL; 764 int32 lL; 765 766 /* The bbpE for these variables is bbpLby2L */ 767 int32 valL; 768 769 /* Get the whole numbers only and make the bbp 0. */ 770 kL = xL >> bbpL; 771 lL = yL >> bbpL; 772 773 /* fraction of destination pixel in the next source pixel */ 774 f2xL = ( xL & fractionOnlyL ) >> bbpLby2L; 775 f2yL = ( yL & fractionOnlyL ) >> bbpLby2L; 776 /* fraction of destination pixel in the current source pixel */ 777 f1xL = oneL - f2xL; 778 f1yL = oneL - f2yL; 779 780 /* increment values for next loop */ 781 xL += mxxL; 782 yL += myxL; 783 784 if( lL < 0 ) 785 { 786 if( kL < 0 ) 787 { 788 /* handle all pixels in region x0y0 */ 789 *dstPtrL++ = *ulPtrL; 790 } 791 else if( kL >= srcWidthL - 1 ) 792 { 793 /* handle all pixels in region x2y0 */ 794 *dstPtrL++ = *urPtrL; 795 } 796 else 797 { 798 /* handle all pixels in region x1y0 */ 799 /* The bbp has shifted left by bbpLby2L */ 800 valL = *( ulPtrL + kL ) * f1xL + *( ulPtrL + kL + 1 ) * f2xL; 801 *dstPtrL++ = valL >> bbpLby2L; 802 } 803 } /* if( lL < 0 ) */ 804 else if( lL >= srcHeightL - 1 ) 805 { 806 if( kL < 0 ) 807 { 808 /* handle all pixels in region x0y2 */ 809 *dstPtrL++ = *llPtrL; 810 } 811 else if( kL >= srcWidthL - 1 ) 812 { 813 /* handle all pixels in region x2y2 */ 814 *dstPtrL++ = *lrPtrL; 815 } 816 else 817 { 818 /* handle all pixels in region x1y2 */ 819 /* The bbp has shifted left by bbpLby2L */ 820 valL = *( llPtrL + kL ) * f1xL + *( llPtrL + kL + 1 ) * f2xL; 821 *dstPtrL++ = valL >> bbpLby2L; 822 } 823 } /* if( lL >= srcHeightL - 1 ) */ 824 else 825 { 826 const uint8* ptr1L; 827 const uint8* ptr2L; 828 829 ptr1L = ulPtrL + lL * srcWidthL; 830 /* point to the pixel in the same column */ 831 ptr2L = ptr1L + srcWidthL; 832 if( kL < 0 ) 833 { 834 /* handle all pixels in region x0y1 */ 835 /* The bbp has shifted left by bbpLby2L */ 836 valL = *ptr1L * f1yL + *ptr2L * f2yL ; 837 *dstPtrL++ = valL >> bbpLby2L; 838 } 839 else if( kL >= srcWidthL - 1 ) 840 { 841 /* handle all pixels in region x2y1 */ 842 /* The bbp has shifted left by bbpLby2L */ 843 valL = *( ptr1L + srcWidthL - 1 ) * f1yL + *( ptr2L + srcWidthL - 1 ) * f2yL; 844 *dstPtrL++ = valL >> bbpLby2L; 845 } 846 else 847 { 848 /* assuming that bbpL = bbpLby2 * 2 */ 849 /* The bbp for these variables is bbpLby2L */ 850 int32 v1L; 851 int32 v2L; 852 /* The bbp for these variables is bbpL */ 853 const int32 halfL = ( int32 )0x00000001 << ( bbpL - 1 ); 854 855 /* handle all pixels in region x1y1 */ 856 /* The bbp has shifted left by bbpLby2L */ 857 v1L = *( ptr1L + kL ) * f1xL + *( ptr1L + kL + 1 ) * f2xL; 858 v2L = *( ptr2L + kL ) * f1xL + *( ptr2L + kL + 1 ) * f2xL; 859 /* The bbp has shifted left again by bbpLby2L */ 860 /* adding the half to round off the resulting value */ 861 valL = v1L * f1yL + v2L * f2yL + halfL; 862 *dstPtrL++ = valL >> bbpL; 863 } 864 } 865 } /* iL loop */ 866 } /* jL loop */ 867 868 } 869 870 #endif 871 872 /* ------------------------------------------------------------------------- */ 873 874 /* ========================================================================= */ 875 876 877