Home | History | Annotate | Download | only in b_ImageEm
      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