• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
bim_UInt16ByteImage_init(struct bbs_Context * cpA,struct bim_UInt16ByteImage * ptrA)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 
bim_UInt16ByteImage_exit(struct bbs_Context * cpA,struct bim_UInt16ByteImage * ptrA)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 
bim_UInt16ByteImage_copy(struct bbs_Context * cpA,struct bim_UInt16ByteImage * ptrA,const struct bim_UInt16ByteImage * srcPtrA)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 
bim_UInt16ByteImage_equal(struct bbs_Context * cpA,const struct bim_UInt16ByteImage * ptrA,const struct bim_UInt16ByteImage * srcPtrA)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 
bim_UInt16ByteImage_checkSum(struct bbs_Context * cpA,const struct bim_UInt16ByteImage * ptrA)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 
bim_UInt16ByteImage_create(struct bbs_Context * cpA,struct bim_UInt16ByteImage * ptrA,uint32 widthA,uint32 heightA,struct bbs_MemSeg * mspA)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 
bim_UInt16ByteImage_assignExternalImage(struct bbs_Context * cpA,struct bim_UInt16ByteImage * ptrA,struct bim_UInt16ByteImage * srcPtrA)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 
bim_UInt16ByteImage_size(struct bbs_Context * cpA,struct bim_UInt16ByteImage * ptrA,uint32 widthA,uint32 heightA)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 
bim_UInt16ByteImage_memSize(struct bbs_Context * cpA,const struct bim_UInt16ByteImage * ptrA)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 
bim_UInt16ByteImage_memWrite(struct bbs_Context * cpA,const struct bim_UInt16ByteImage * ptrA,uint16 * memPtrA)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 
bim_UInt16ByteImage_memRead(struct bbs_Context * cpA,struct bim_UInt16ByteImage * ptrA,const uint16 * memPtrA,struct bbs_MemSeg * mspA)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 
bim_UInt16ByteImage_setAllPixels(struct bbs_Context * cpA,struct bim_UInt16ByteImage * ptrA,uint16 valueA)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 */
bim_UInt16ByteImage_warp(struct bbs_Context * cpA,struct bim_UInt16ByteImage * ptrA,const struct bim_UInt16ByteImage * srcPtrA,const struct bts_Flt16Alt2D * altPtrA,int32 resultWidthA,int32 resultHeightA)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 
bim_UInt16ByteImage_warp8(struct bbs_Context * cpA,struct bim_UInt16ByteImage * ptrA,const struct bim_UInt16ByteImage * srcPtrA,const struct bts_Flt16Alt2D * altPtrA,int32 resultWidthA,int32 resultHeightA)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