auto import from //depot/cupcake/@135843
[android/platform/external/neven.git] / Embedded / common / src / b_ImageEm / UInt16ByteImage.c
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