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