auto import from //depot/cupcake/@135843
[android/platform/external/neven.git] / Embedded / common / src / b_ImageEm / UInt8Image.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/UInt8Image.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_UInt8Image_init( struct bbs_Context* cpA,
42                                                   struct bim_UInt8Image* ptrA )
43 {
44         bbs_UInt8Arr_init( cpA, &ptrA->arrE );
45         ptrA->widthE = 0;
46         ptrA->heightE = 0;
47 }
48
49 /* ------------------------------------------------------------------------- */
50
51 void bim_UInt8Image_create( struct bbs_Context* cpA,
52                                                     struct bim_UInt8Image* ptrA, 
53                                                     uint32 widthA, 
54                                                         uint32 heightA,
55                                                 struct bbs_MemSeg* mspA )
56 {
57         if( bbs_Context_error( cpA ) ) return;
58         if( ptrA->arrE.arrPtrE != 0 )
59         {
60                 bim_UInt8Image_size( cpA, ptrA, widthA, heightA );
61         }
62         else
63         {
64                 bbs_UInt8Arr_create( cpA, &ptrA->arrE, widthA * heightA, mspA );
65                 ptrA->widthE  = widthA;
66                 ptrA->heightE = heightA;
67         }
68 }
69 /* ------------------------------------------------------------------------- */
70
71 void bim_UInt8Image_exit( struct bbs_Context* cpA,
72                                                   struct bim_UInt8Image* ptrA )
73 {
74         bbs_UInt8Arr_exit( cpA, &ptrA->arrE );
75         ptrA->widthE = 0;
76         ptrA->heightE = 0;      
77 }
78
79 /* ------------------------------------------------------------------------- */
80
81 /* ========================================================================= */
82 /*                                                                           */
83 /* ---- \ghd{ operators } -------------------------------------------------- */
84 /*                                                                           */
85 /* ========================================================================= */
86
87 /* ------------------------------------------------------------------------- */
88
89 void bim_UInt8Image_copy( struct bbs_Context* cpA,
90                                                   struct bim_UInt8Image* ptrA, 
91                                                   const struct bim_UInt8Image* srcPtrA )
92 {
93 #ifdef DEBUG1
94         if( ptrA->arrE.sizeE < srcPtrA->arrE.sizeE )
95         {
96                 bbs_ERROR0( "void bim_UInt8Image_copy( struct bim_UInt8Image*, const struct bim_UInt8Image* ):\n"
97                                    "Unsufficient allocated memory in destination image" );              
98                 return;
99         }
100 #endif
101         ptrA->widthE = srcPtrA->widthE;
102         ptrA->heightE = srcPtrA->heightE;
103         bbs_UInt8Arr_copy( cpA, &ptrA->arrE, &srcPtrA->arrE );
104 }
105
106 /* ------------------------------------------------------------------------- */
107
108 flag bim_UInt8Image_equal( struct bbs_Context* cpA,
109                                                    const struct bim_UInt8Image* ptrA, 
110                                                    const struct bim_UInt8Image* srcPtrA )
111 {
112         if( ptrA->widthE != srcPtrA->widthE ) return FALSE;
113         if( ptrA->heightE != srcPtrA->heightE ) return FALSE;
114         return bbs_UInt8Arr_equal( cpA, &ptrA->arrE, &srcPtrA->arrE );
115 }
116
117 /* ------------------------------------------------------------------------- */
118
119 /* ========================================================================= */
120 /*                                                                           */
121 /* ---- \ghd{ query functions } -------------------------------------------- */
122 /*                                                                           */
123 /* ========================================================================= */
124
125 /* ------------------------------------------------------------------------- */
126
127 uint32 bim_UInt8Image_checkSum( struct bbs_Context* cpA,
128                                                             const struct bim_UInt8Image* ptrA )
129 {
130         uint32 sumL =0 ;
131         uint32 iL;
132         uint32 sizeL = ptrA->arrE.sizeE;
133         const uint8* ptrL = ptrA->arrE.arrPtrE;
134         for( iL =0; iL < sizeL; iL++ )
135         {
136                 sumL += *ptrL++;
137         }
138         return sumL;
139 }
140
141 /* ------------------------------------------------------------------------- */
142
143 /* ========================================================================= */
144 /*                                                                           */
145 /* ---- \ghd{ modify functions } ------------------------------------------- */
146 /*                                                                           */
147 /* ========================================================================= */
148
149 /* ------------------------------------------------------------------------- */
150         
151 void bim_UInt8Image_assignExternalImage( struct bbs_Context* cpA,
152                                                                                  struct bim_UInt8Image* ptrA, 
153                                                                                  struct bim_UInt8Image* srcPtrA )
154 {
155         struct bbs_MemSeg sharedSegL = bbs_MemSeg_createShared( cpA, srcPtrA->arrE.arrPtrE, ( srcPtrA->widthE * srcPtrA->heightE ) / 2 );
156
157         if( ptrA->arrE.arrPtrE != 0 )
158         {
159                 bbs_ERROR0( "void bim_UInt8Image_assignExternalImage( ... ): image was already created once" );
160                 return;
161         }
162
163         bim_UInt8Image_create( cpA, ptrA, 
164                                                srcPtrA->widthE, 
165                                                    srcPtrA->heightE,
166                                                    &sharedSegL );
167 }
168
169 /* ------------------------------------------------------------------------- */
170         
171 void bim_UInt8Image_size( struct bbs_Context* cpA,
172                                                   struct bim_UInt8Image* ptrA, 
173                                                   uint32 widthA, 
174                                                   uint32 heightA )
175 {
176         if( ptrA->arrE.allocatedSizeE < widthA * heightA )
177         {
178                 bbs_ERROR0( "void bim_UInt8Image_size( struct bim_UInt8Image*, uint32 sizeA ):\n"
179                                    "Unsufficient allocated memory" );
180                 return;
181         }
182         bbs_UInt8Arr_size( cpA, &ptrA->arrE, widthA * heightA );
183         ptrA->widthE  = widthA;
184         ptrA->heightE = heightA;
185 }
186
187 /* ------------------------------------------------------------------------- */
188         
189 /* ========================================================================= */
190 /*                                                                           */
191 /* ---- \ghd{ I/O } -------------------------------------------------------- */
192 /*                                                                           */
193 /* ========================================================================= */
194
195 /* ------------------------------------------------------------------------- */
196         
197 uint32 bim_UInt8Image_memSize( struct bbs_Context* cpA,
198                                                            const struct bim_UInt8Image* ptrA )
199 {
200         return  bbs_SIZEOF16( uint32 )
201                   + bbs_SIZEOF16( uint32 ) /* version */
202                   + bbs_SIZEOF16( ptrA->widthE ) 
203                   + bbs_SIZEOF16( ptrA->heightE )
204                   + bbs_UInt8Arr_memSize( cpA, &ptrA->arrE ); 
205 }
206
207 /* ------------------------------------------------------------------------- */
208         
209 uint32 bim_UInt8Image_memWrite( struct bbs_Context* cpA,
210                                                             const struct bim_UInt8Image* ptrA, 
211                                                                 uint16* memPtrA )
212 {
213         uint32 memSizeL = bim_UInt8Image_memSize( cpA, ptrA );
214         memPtrA += bbs_memWrite32( &memSizeL, memPtrA );
215         memPtrA += bbs_memWriteUInt32( bim_UINT8_IMAGE_VERSION, memPtrA );
216         memPtrA += bbs_memWrite32( &ptrA->widthE, memPtrA );
217         memPtrA += bbs_memWrite32( &ptrA->heightE, memPtrA );
218         bbs_UInt8Arr_memWrite( cpA, &ptrA->arrE, memPtrA );
219         return memSizeL;
220 }
221
222 /* ------------------------------------------------------------------------- */
223         
224 uint32 bim_UInt8Image_memRead( struct bbs_Context* cpA,
225                                                            struct bim_UInt8Image* ptrA, 
226                                                            const uint16* memPtrA,
227                                                    struct bbs_MemSeg* mspA )
228 {
229         uint32 memSizeL, versionL, widthL, heightL;
230         if( bbs_Context_error( cpA ) ) return 0;
231         memPtrA += bbs_memRead32( &memSizeL, memPtrA );
232         memPtrA += bbs_memReadVersion32( cpA, &versionL, bim_UINT8_IMAGE_VERSION, memPtrA );
233         memPtrA += bbs_memRead32( &widthL, memPtrA );
234         memPtrA += bbs_memRead32( &heightL, memPtrA );
235
236         ptrA->widthE  = widthL;
237         ptrA->heightE = heightL;
238         bbs_UInt8Arr_memRead( cpA, &ptrA->arrE, memPtrA, mspA );
239
240         if( memSizeL != bim_UInt8Image_memSize( cpA, ptrA ) )
241         {
242                 bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bim_UInt8Image_memRead( const struct bim_UInt8Image* ptrA, const void* memPtrA ):\n"
243                    "size mismatch" ); 
244                 return 0;
245         }
246         return memSizeL;
247 }
248
249 /* ------------------------------------------------------------------------- */
250         
251 /* ========================================================================= */
252 /*                                                                           */
253 /* ---- \ghd{ exec functions } --------------------------------------------- */
254 /*                                                                           */
255 /* ========================================================================= */
256
257 /* ------------------------------------------------------------------------- */
258
259 void bim_UInt8Image_setAllPixels( struct bbs_Context* cpA,
260                                                                   struct bim_UInt8Image* ptrA, 
261                                                                   uint8 valueA )
262 {
263         long iL;
264         uint8* ptrL = ptrA->arrE.arrPtrE;
265         for( iL = ptrA->widthE * ptrA->heightE; iL > 0; iL-- )
266         {
267                 *ptrL++ = valueA;
268         }
269 }
270
271 /* ------------------------------------------------------------------------- */
272
273 /**
274                         |                               |                               |                               |
275                         |       (loop x1)       |       (loop x2)       |       (loop x3)       |
276                         o------------->-o------------>--o------------->-o
277                         |                               |                               |                               |
278                         |                               |                               |                               |
279                         |                               |                               |                               |
280                         |                               |                               |                               |
281         ( sectionL->x1E, sectionL->y1E )                |                               |
282 ---------o-     R-------------------------------|----------------
283                  |      |                               |                               |                               |
284                  |      |                               |                               |                               |
285                  |      |                               |                               |                               |
286                  |      |                               |                               |                               |
287    (loop y1)|                           |                               |                               |
288                  |      |                               |                               |                               |
289                  V      |                               |                               |                               |
290                  |      |                               |( 0, 0 )               |                               |               X
291 ---------o------------------I------------------------------------------------->
292                  |      |                               |                               |                               |
293                  |      |                               |                               |                               |
294                  |      |                               |                               |                               |
295                  |      |                               |                               |                               |
296                  |      |                               |                               |                               |
297    (loop y2)|                           |                               |                               |
298                  |      |                               |                               |                               |
299                  |      |                               |                               |                               |
300                  |      |                               |                               |                               |
301                  V      |                               |                               |                               |
302                  |      |                               |                               |                               |
303 ---------o------------------|---------------I                           |
304                  |      |                               |               ( srcPtrA->widthE, srcPtrA->heightE )
305                  |      |                               |                                                               |
306                  |      |                               |                                                               |
307                  |      |                               |                                                               |
308                  |      |                               |                                                               |
309                  |      |                               |                                                               |
310    (loop y3)|                           |                                                               |
311                  |      |                               |                                                               |
312                  |      |                               |                                                               |
313                  V      |                               |                                                               |
314                  |      |                               |                                                               |
315 ---------o--------------------------------------------------R
316                                                         |                               ( sectionL->x2E, sectionL->y2E )
317                                                         |
318                                                   Y     |
319                                                         |
320                                                         |
321                                                         V
322
323   To understand how the algorithm work refer to the diagram above.
324   The image boundaries are indicated by letter "I" ( 0, 0 ) to ( srcPtrA->widthE, srcPtrA->heightE )
325   The rectangle boundaries are indicated by letter "R" ( sectionPtrA->x1E, sectionPtrA->y1E ) to ( sectionPtrA->x2E, sectionPtrA->y2E )
326
327   In the above example the intersection of the image and the rectange is
328   ( 0, 0 ), ( srcPtrA->widthE, srcPtrA->heightE )
329
330   The size of the destination image is always ( ( sectionL->x2E, sectionL->y2E ) - ( sectionL->x1E, sectionL->y1E ) )
331
332   All coordinates are assumed to be relative to the original image.
333
334   1. parse all pixels in "loop y1"
335         1.a. parse all pixels in "loop x1"
336         1.b. parse all pixels in "loop x2"
337         1.c. parse all pixels in "loop x3"
338   2. parse all pixels in "loop y2"
339         2.a. parse all pixels in "loop x1"
340         2.b. parse all pixels in "loop x2"
341         2.c. parse all pixels in "loop x3"
342   3. parse all pixels in "loop y3"
343         3.a. parse all pixels in "loop x1"
344         3.b. parse all pixels in "loop x2"
345         3.c. parse all pixels in "loop x3"
346
347 */
348
349 /** copies a section of given image */
350 void bim_UInt8Image_copySection( struct bbs_Context* cpA,
351                                                                  struct bim_UInt8Image* ptrA, 
352                                                                  const struct bim_UInt8Image* srcPtrA, 
353                                                                  const struct bts_Int16Rect* sectionPtrA )
354 {
355
356         uint8* srcPixelPtrL;
357         uint8* dstPixelPtrL;
358         int32 yIndexL;
359         int32 xIndexL;
360
361         struct bts_Int16Rect srcImageSubSectionL;
362         struct bts_Int16Rect sectionL;
363
364         /* make sure that the rectangle passed is correct, in case the x2 < x1 or y2 < y1, swap them */
365         sectionL.x1E = bbs_min( sectionPtrA->x1E, sectionPtrA->x2E );
366         sectionL.x2E = bbs_max( sectionPtrA->x1E, sectionPtrA->x2E );
367         sectionL.y1E = bbs_min( sectionPtrA->y1E, sectionPtrA->y2E );
368         sectionL.y2E = bbs_max( sectionPtrA->y1E, sectionPtrA->y2E );
369
370         /* find the intersection betweem the rectangle and the image, the image always starts at 0,0 */
371         srcImageSubSectionL.x1E = bbs_max( 0, sectionL.x1E );
372         srcImageSubSectionL.y1E = bbs_max( 0, sectionL.y1E );
373         srcImageSubSectionL.x2E = bbs_min( ( int32 ) srcPtrA->widthE, sectionL.x2E );
374         srcImageSubSectionL.y2E = bbs_min( ( int32 ) srcPtrA->heightE, sectionL.y2E );
375
376         /* If the image and the rectangle do not intersect in X direction, set the intersecting rectangle to the image coordinates */
377         if( srcImageSubSectionL.x2E < srcImageSubSectionL.x1E )
378         {
379                 srcImageSubSectionL.x1E = 0;
380                 srcImageSubSectionL.x2E = srcPtrA->widthE;
381         }
382         /* do the same as above in the Y direction */
383         if( srcImageSubSectionL.y2E < srcImageSubSectionL.y1E )
384         {
385                 srcImageSubSectionL.y1E = 0;
386                 srcImageSubSectionL.y2E = srcPtrA->heightE;
387         }
388
389         /* set size, and allocate required memory for the destination image if required */
390         bim_UInt8Image_size( cpA, ptrA, sectionL.x2E - sectionL.x1E, sectionL.y2E - sectionL.y1E );
391
392         /* get the pointer to the destination image */
393         dstPixelPtrL = ptrA->arrE.arrPtrE;
394
395         /* 1. parse all pixels in "loop y1" */
396         for( yIndexL = sectionL.y1E; yIndexL < srcImageSubSectionL.y1E && yIndexL < sectionL.y2E; yIndexL++ )
397         {
398                 /* move to the first pixel that needs to be copied. */
399                 srcPixelPtrL = srcPtrA->arrE.arrPtrE;
400
401                 /* 1.a. parse all pixels in "loop x1" */
402                 for( xIndexL = sectionL.x1E; xIndexL < srcImageSubSectionL.x1E && xIndexL < sectionL.x2E; xIndexL++ )
403                 {
404                         *dstPixelPtrL++ = *srcPixelPtrL;
405                 }
406                 /* 1.b. parse all pixels in "loop x2" */
407                 for( ; xIndexL < srcImageSubSectionL.x2E && xIndexL < sectionL.x2E; xIndexL++ )
408                 {
409                         *dstPixelPtrL++ = *srcPixelPtrL++;
410                 }
411                 srcPixelPtrL--;
412                 /* 1.c. parse all pixels in "loop x3" */
413                 for( ; xIndexL < sectionL.x2E; xIndexL++ )
414                 {
415                         *dstPixelPtrL++ = *srcPixelPtrL;
416                 }
417         }
418         /* 2. parse all pixels in "loop y2" */
419         for( ; yIndexL < srcImageSubSectionL.y2E && yIndexL < sectionL.y2E; yIndexL++ )
420         {
421                 /* move to the first pixel that needs to be copied. */
422                 srcPixelPtrL = srcPtrA->arrE.arrPtrE + yIndexL * srcPtrA->widthE + srcImageSubSectionL.x1E;
423
424                 /* 2.a. parse all pixels in "loop x1" */
425                 for( xIndexL = sectionL.x1E; xIndexL < srcImageSubSectionL.x1E && xIndexL < sectionL.x2E; xIndexL++ )
426                 {
427                         *dstPixelPtrL++ = *srcPixelPtrL;
428                 }
429                 /* 2.b. parse all pixels in "loop x2" */
430                 for( ; xIndexL < srcImageSubSectionL.x2E && xIndexL < sectionL.x2E; xIndexL++ )
431                 {
432                         *dstPixelPtrL++ = *srcPixelPtrL++;
433                 }
434                 srcPixelPtrL--;
435                 /* 2.c. parse all pixels in "loop x3" */
436                 for( ; xIndexL < sectionL.x2E; xIndexL++ )
437                 {
438                         *dstPixelPtrL++ = *srcPixelPtrL;
439                 }
440         }
441         /* 3. parse all pixels in "loop y3" */
442         for( ; yIndexL < sectionL.y2E; yIndexL++ )
443         {
444                 srcPixelPtrL = srcPtrA->arrE.arrPtrE + ( srcImageSubSectionL.y2E - 1 ) * srcPtrA->widthE + srcImageSubSectionL.x1E;
445
446                 /* 3.a. parse all pixels in "loop x1" */
447                 for( xIndexL = sectionL.x1E; xIndexL < srcImageSubSectionL.x1E && xIndexL < sectionL.x2E; xIndexL++ )
448                 {
449                         *dstPixelPtrL++ = *srcPixelPtrL;
450                 }
451                 /* 3.b. parse all pixels in "loop x3" */
452                 for( ; xIndexL < srcImageSubSectionL.x2E && xIndexL < sectionL.x2E; xIndexL++ )
453                 {
454                         *dstPixelPtrL++ = *srcPixelPtrL++;
455                 }
456                 srcPixelPtrL--;
457                 /* 3.c. parse all pixels in "loop x3" */
458                 for( ; xIndexL < sectionL.x2E; xIndexL++ )
459                 {
460                         *dstPixelPtrL++ = *srcPixelPtrL;
461                 }
462         }
463
464 }
465
466 /* ------------------------------------------------------------------------- */
467
468 /**
469
470  
471                 M-------------------------------------------------------M
472                 |                               |                                               |                               |
473                 |                               |                                               |                               |
474                 |                               |                                               |                               |
475                 |                               |                                               |                               |
476                 |       region x0y0     |               region x1y0             |       region x2y0     |
477                 |                               |                                               |                               |
478                 |                               |                                               |                               |
479                 |                               |                                               |                               |
480                 |---------------I-----------------------I---------------|
481                 |                               |                                               |                               |
482                 |                               |                                               |                               |
483                 |                               |                                               |                               |
484                 |                               |                                               |                               |
485                 |                               |                                               |                               |
486                 |                               |                                               |                               |
487                 |       region x0y1     |               region x1y1             |       region x2y1     |
488                 |                               |                                               |                               |
489                 |                               |                                               |                               |
490                 |                               |                                               |                               |
491                 |                               |                                               |                               |
492                 |                               |                                               |                               |
493                 |                               |                                               |                               |
494                 |                               |                                               |                               |
495                 |---------------I-----------------------I---------------|
496                 |                               |                                               |                               |
497                 |                               |                                               |                               |
498                 |                               |                                               |                               |
499                 |                               |                                               |                               |
500                 |       region x0y2     |               region x1y2             |       region x2y2     |
501                 |                               |                                               |                               |
502                 |                               |                                               |                               |
503                 |                               |                                               |                               |
504                 M-------------------------------------------------------M
505
506
507   To see how the code is organized. Refer to the diagram above.
508   Assume the original image after applying the tranzformations(translation, rotation and scaling) is "O" 
509         (boundaries of the image are shown above bounded by the letter 'O').
510   This image is being Warped to the area "M" (boundaries of this area are bounded by the letter 'M').
511   
512         Refer to the source code below to point to the loop that maps pixels in the particular region.
513
514  */
515
516 /** applies affine linear warping to pixels positions of imageA before copying the into *ptrA */
517 void bim_UInt8Image_warpOffs( struct bbs_Context* cpA,
518                                                   struct bim_UInt8Image* ptrA, 
519                                                   const struct bim_UInt8Image* srcPtrA, 
520                                                   int32 xOffsA,
521                                                   int32 yOffsA,
522                                                   const struct bts_Flt16Alt2D* altPtrA,
523                                       int32 resultWidthA,
524                                       int32 resultHeightA )
525 {
526         long srcWidthL = srcPtrA->widthE;
527         long srcHeightL = srcPtrA->heightE;
528         
529         struct bts_Flt16Alt2D invAlt2DL;
530         
531         uint8* dstPtrL;
532         const uint8* ulPtrL = srcPtrA->arrE.arrPtrE;
533         const uint8* urPtrL = ulPtrL + srcWidthL - 1;
534         const uint8* llPtrL = ulPtrL + ( srcHeightL - 1 ) * srcWidthL;
535         const uint8* lrPtrL = llPtrL + srcWidthL - 1;
536         
537         uint32 iL, jL;
538         int32 shiftL;
539
540         const uint16 bbpL = 16;
541         int32 maxInt32Value8bbpL  = 0x7FFFFFFF;
542
543         /* The bbp for all these variables is the same as bbpL */
544         int32 mxxL;
545         int32 mxyL;
546         int32 myxL;
547         int32 myyL;
548
549         int32 txL;
550         int32 tyL;
551
552         int32 xL;
553         int32 yL;
554
555         bim_UInt8Image_size( cpA, ptrA, resultWidthA, resultHeightA );
556         dstPtrL = ptrA->arrE.arrPtrE;
557         
558         /* compute inverse */
559         invAlt2DL = bts_Flt16Alt2D_inverted( altPtrA );
560         
561         if( srcWidthL == 0 || srcHeightL == 0 )
562         {
563                 bim_UInt8Image_size( cpA, ptrA, srcWidthL, srcHeightL );
564                 bbs_ERROR2( "Size of output image is %d/%d", srcWidthL, srcHeightL );
565                 return;
566         }
567
568         /* align Matrix and Vector to 8 bits bbp */
569         shiftL = invAlt2DL.matE.bbpE - bbpL;
570         if( shiftL >= 0 )
571         {
572                 mxxL = invAlt2DL.matE.xxE >> shiftL;
573                 mxyL = invAlt2DL.matE.xyE >> shiftL;
574                 myxL = invAlt2DL.matE.yxE >> shiftL;
575                 myyL = invAlt2DL.matE.yyE >> shiftL;
576         }
577         else
578         {
579                 /* Check for overflow since we are left shifting. */
580                 maxInt32Value8bbpL >>= -shiftL;
581                 if( invAlt2DL.matE.xxE > maxInt32Value8bbpL ||
582                         invAlt2DL.matE.xyE > maxInt32Value8bbpL ||
583                         invAlt2DL.matE.yxE > maxInt32Value8bbpL ||
584                         invAlt2DL.matE.yyE > maxInt32Value8bbpL )
585                 {
586                         /* Overflow error */
587                         bbs_ERROR5( "The values in the transformation matrix cause overflow during bitshift\n%d, %d,\n%d, %d\n"
588                                                 "The maximum allowed value is %d", 
589                                                 invAlt2DL.matE.xxE >> invAlt2DL.matE.bbpE,
590                                                 invAlt2DL.matE.xyE >> invAlt2DL.matE.bbpE,
591                                                 invAlt2DL.matE.yxE >> invAlt2DL.matE.bbpE,
592                                                 invAlt2DL.matE.yyE >> invAlt2DL.matE.bbpE,
593                                                 maxInt32Value8bbpL >> ( bbpL - ( -shiftL ) ) );
594                         return;
595                 }
596
597                 mxxL = invAlt2DL.matE.xxE << -shiftL;
598                 mxyL = invAlt2DL.matE.xyE << -shiftL;
599                 myxL = invAlt2DL.matE.yxE << -shiftL;
600                 myyL = invAlt2DL.matE.yyE << -shiftL;
601                 maxInt32Value8bbpL <<= -shiftL;
602         }
603
604         /* invAlt2DL.matE.bbpE = bbpL; nonsense! */
605
606         shiftL = invAlt2DL.vecE.bbpE - bbpL;
607         if( shiftL >= 0 )
608         {
609                 txL  = invAlt2DL.vecE.xE >> shiftL;
610                 tyL  = invAlt2DL.vecE.yE >> shiftL;
611         }
612         else
613         {
614                 /* Check for overflow since we are left shifting. */
615                 maxInt32Value8bbpL >>= -shiftL;
616                 if(     invAlt2DL.vecE.xE  > maxInt32Value8bbpL ||
617                         invAlt2DL.vecE.yE  > maxInt32Value8bbpL )
618                 {
619                         /* Overflow error */
620                         bbs_ERROR3( "The values in the vector cause overflow during bitshift\n%d, %d,\n"
621                                                 "The maximum allowed value is %d", 
622                                                 invAlt2DL.vecE.xE >> invAlt2DL.vecE.bbpE,
623                                                 invAlt2DL.vecE.yE >> invAlt2DL.vecE.bbpE,
624                                                 maxInt32Value8bbpL >> ( bbpL - ( -shiftL ) ) );
625                         return;
626                 }
627                 txL  = invAlt2DL.vecE.xE << -shiftL;
628                 tyL  = invAlt2DL.vecE.yE << -shiftL;
629                 maxInt32Value8bbpL <<= -shiftL;
630         }
631
632         /* invAlt2DL.vecE.bbpE = bbpL; nonsense! */
633
634         /* adjust offset */
635         txL += xOffsA << bbpL;
636         tyL += yOffsA << bbpL;
637
638         /* For each destination pixel find the correspoding source pixel by applying the inverse transformation */
639         for( jL = 0; jL < ptrA->heightE; jL++ )
640         {
641                 xL = txL + mxyL * jL;
642                 yL = tyL + myyL * jL;
643                 for( iL = 0; iL < ptrA->widthE; iL++ )
644                 {
645                         const uint16 bbpLby2L = bbpL / 2;
646                         const int32 oneL = 0x00000001 << bbpLby2L;
647                         const int32 fractionOnlyL = 0xFFFFFFFF >> ( 32 - bbpL );
648
649                         /* The bbp for all these variables is the same as bbpLby2L */
650                         int32 f2xL;
651                         int32 f2yL;
652                         int32 f1xL;
653                         int32 f1yL;
654
655                         /* always whole numbers with a bbp of 0 */
656                         int32 kL;
657                         int32 lL;
658
659                         /* The bbpE for these variables is bbpLby2L */
660                         int32 valL;
661
662                         /* Get the whole numbers only and make the bbp 0. */
663                         kL = xL >> bbpL;
664                         lL = yL >> bbpL;
665
666                         /* fraction of destination pixel in the next source pixel */
667                         f2xL = ( xL & fractionOnlyL ) >> bbpLby2L;
668                         f2yL = ( yL & fractionOnlyL ) >> bbpLby2L;
669                         /* fraction of destination pixel in the current source pixel */
670                         f1xL = oneL - f2xL;
671                         f1yL = oneL - f2yL;
672
673                         /* increment values for next loop */
674                         xL += mxxL;
675                         yL += myxL;
676
677                         if( lL < 0 )
678                         {
679                                 if( kL < 0 )
680                                 {
681                                         /* handle all pixels in region x0y0 */
682                                         *dstPtrL++ = *ulPtrL;
683                                 }
684                                 else if( kL >= srcWidthL - 1 )
685                                 {
686                                         /* handle all pixels in region x2y0 */
687                                         *dstPtrL++ = *urPtrL;
688                                 }
689                                 else
690                                 {
691                                         /* handle all pixels in region x1y0 */
692                                         /* The bbp has shifted left by bbpLby2L */
693                                         valL =  *( ulPtrL + kL ) * f1xL + *( ulPtrL + kL + 1 ) * f2xL;
694                                         *dstPtrL++ = valL >> bbpLby2L;
695                                 }
696                         } /* if( lL < 0 ) */
697                         else if( lL >= srcHeightL - 1 )
698                         {
699                                 if( kL < 0 )
700                                 {
701                                         /* handle all pixels in region x0y2 */
702                                         *dstPtrL++ = *llPtrL;
703                                 }
704                                 else if( kL >= srcWidthL - 1 )
705                                 {
706                                         /* handle all pixels in region x2y2 */
707                                         *dstPtrL++ = *lrPtrL;
708                                 }
709                                 else
710                                 {
711                                         /* handle all pixels in region x1y2 */
712                                         /* The bbp has shifted left by bbpLby2L */
713                                         valL =   *( llPtrL + kL ) * f1xL + *( llPtrL +  kL + 1 ) * f2xL;
714                                         *dstPtrL++ = valL >> bbpLby2L;
715                                 }
716                         } /* if( lL >= srcHeightL - 1 ) */
717                         else
718                         {
719                                 const uint8* ptr1L;
720                                 const uint8* ptr2L;
721
722                                 ptr1L = ulPtrL + lL * srcWidthL;
723                                 /* point to the pixel in the same column */
724                                 ptr2L = ptr1L + srcWidthL;
725                                 if( kL < 0 )
726                                 {
727                                         /* handle all pixels in region x0y1 */
728                                         /* The bbp has shifted left by bbpLby2L */
729                                         valL = *ptr1L * f1yL + *ptr2L * f2yL ;
730                                         *dstPtrL++ = valL >> bbpLby2L;
731                                 }
732                                 else if( kL >= srcWidthL - 1 )
733                                 {
734                                         /* handle all pixels in region x2y1 */
735                                         /* The bbp has shifted left by bbpLby2L */
736                                         valL =  *( ptr1L + srcWidthL - 1 ) * f1yL + *( ptr2L  + srcWidthL - 1 ) * f2yL;
737                                         *dstPtrL++ = valL >> bbpLby2L;
738                                 }
739                                 else
740                                 {
741                                         /* assuming that bbpL = bbpLby2 * 2 */
742                                         /* The bbp for these variables is bbpLby2L */
743                                         int32 v1L;
744                                         int32 v2L;
745                                         /* The bbp for these variables is bbpL */
746                                         const int32 halfL = 0x00000001 << ( bbpL - 1 );
747         
748                                         /* handle all pixels in region x1y1 */
749                                         /* The bbp has shifted left by bbpLby2L */
750                                         v1L = *( ptr1L + kL ) * f1xL + *( ptr1L + kL + 1 ) * f2xL;
751                                         v2L = *( ptr2L + kL ) * f1xL + *( ptr2L + kL + 1 ) * f2xL;
752                                         /* The bbp has shifted left again by bbpLby2L */
753                                         /* adding the half to round off the resulting value */
754                                         valL = v1L * f1yL + v2L * f2yL + halfL;
755                                         *dstPtrL++ = valL >> bbpL;
756                                 }
757                         }
758                 } /* iL loop */
759         } /* jL loop */
760
761 }
762
763 /* ------------------------------------------------------------------------- */
764
765 void bim_UInt8Image_warp( struct bbs_Context* cpA,
766                                                   struct bim_UInt8Image* ptrA, 
767                                                   const struct bim_UInt8Image* srcPtrA, 
768                                                   const struct bts_Flt16Alt2D* altPtrA,
769                                       int32 resultWidthA,
770                                       int32 resultHeightA )
771 {
772         bim_UInt8Image_warpOffs( cpA, ptrA, srcPtrA, 0, 0, altPtrA, resultWidthA, resultHeightA );
773 }
774
775 /* ========================================================================= */
776
777