auto import from //depot/cupcake/@135843
[android/platform/external/neven.git] / Embedded / common / src / b_ImageEm / UInt8PyramidalImage.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/Functions.h"
22 #include "b_ImageEm/UInt8PyramidalImage.h"
23
24 /* ------------------------------------------------------------------------- */
25
26 /* ========================================================================= */
27 /*                                                                           */
28 /* ---- \ghd{ auxiliary functions } ---------------------------------------- */
29 /*                                                                           */
30 /* ========================================================================= */
31
32 /* ------------------------------------------------------------------------- */
33
34 /* ========================================================================= */
35 /*                                                                           */
36 /* ---- \ghd{ constructor / destructor } ----------------------------------- */
37 /*                                                                           */
38 /* ========================================================================= */
39
40 /* ------------------------------------------------------------------------- */
41
42 void bim_UInt8PyramidalImage_init( struct bbs_Context* cpA,
43                                                                    struct bim_UInt8PyramidalImage* ptrA )
44 {
45         bbs_UInt8Arr_init( cpA, &ptrA->arrE );
46         ptrA->widthE = 0;
47         ptrA->heightE = 0;
48         ptrA->depthE = 0;
49         ptrA->typeE = bim_UINT8_PYRAMIDAL_IMG;
50 }
51
52 /* ------------------------------------------------------------------------- */
53
54 void bim_UInt8PyramidalImage_exit( struct bbs_Context* cpA,
55                                                                    struct bim_UInt8PyramidalImage* ptrA )
56 {
57         bbs_UInt8Arr_exit( cpA, &ptrA->arrE );
58         ptrA->widthE = 0;
59         ptrA->heightE = 0;      
60         ptrA->depthE = 0;
61 }
62
63 /* ------------------------------------------------------------------------- */
64
65 /* ========================================================================= */
66 /*                                                                           */
67 /* ---- \ghd{ operators } -------------------------------------------------- */
68 /*                                                                           */
69 /* ========================================================================= */
70
71 /* ------------------------------------------------------------------------- */
72
73 void bim_UInt8PyramidalImage_copy( struct bbs_Context* cpA,
74                                                                    struct bim_UInt8PyramidalImage* ptrA, 
75                                                                    const struct bim_UInt8PyramidalImage* srcPtrA )
76 {
77 #ifdef DEBUG1
78         if( ptrA->arrE.allocatedSizeE < srcPtrA->arrE.allocatedSizeE )
79         {
80                 bbs_ERROR0( "void bim_UInt8PyramidalImage_copy( ... ):\n"
81                                    "Unsufficient allocated memory in destination image" );              
82                 return;
83         }
84 #endif
85         ptrA->widthE = srcPtrA->widthE;
86         ptrA->heightE = srcPtrA->heightE;
87         ptrA->depthE = srcPtrA->depthE;
88         bbs_UInt8Arr_copy( cpA, &ptrA->arrE, &srcPtrA->arrE );
89 }
90
91 /* ------------------------------------------------------------------------- */
92
93 flag bim_UInt8PyramidalImage_equal( struct bbs_Context* cpA,
94                                                                     const struct bim_UInt8PyramidalImage* ptrA, 
95                                                                         const struct bim_UInt8PyramidalImage* srcPtrA )
96 {
97         if( ptrA->widthE != srcPtrA->widthE ) return FALSE;
98         if( ptrA->heightE != srcPtrA->heightE ) return FALSE;
99         if( ptrA->depthE != srcPtrA->depthE ) return FALSE;
100         return bbs_UInt8Arr_equal( cpA, &ptrA->arrE, &srcPtrA->arrE );
101 }
102
103 /* ------------------------------------------------------------------------- */
104
105 /* ========================================================================= */
106 /*                                                                           */
107 /* ---- \ghd{ query functions } -------------------------------------------- */
108 /*                                                                           */
109 /* ========================================================================= */
110
111 /* ------------------------------------------------------------------------- */
112
113 uint8* bim_UInt8PyramidalImage_arrPtr( struct bbs_Context* cpA,
114                                                                            const struct bim_UInt8PyramidalImage* ptrA, 
115                                                                            uint32 levelA )
116 {
117         uint32 iL;
118         uint32 offsL = 0;
119         uint32 baseSizeL = ptrA->widthE * ptrA->heightE;
120
121 #ifdef DEBUG2
122         if( levelA >= ptrA->depthE )
123         {
124                 bbs_ERROR2( "uint8* bim_UInt8PyramidalImage_arrPtr( struct bim_UInt8PyramidalImage* ptrA, uint32 levelA ):\n"
125                                "levelA = %i out of range [0,%i]", levelA, ptrA->depthE - 1 );
126                 return NULL;
127         }
128 #endif
129
130         for( iL = 0; iL < levelA; iL++ )
131         {
132                 offsL += ( baseSizeL >> ( iL * 2 ) );
133         }
134         return ptrA->arrE.arrPtrE + offsL;
135 }
136
137 /* ------------------------------------------------------------------------- */
138
139 uint32 bim_UInt8PyramidalImage_heapSize( struct bbs_Context* cpA,
140                                                                                  const struct bim_UInt8PyramidalImage* ptrA, 
141                                                                                  uint32 widthA, 
142                                                                                  uint32 heightA, 
143                                                                                  uint32 depthA )
144 {
145         uint32 baseSizeL = widthA * heightA;
146         uint32 sizeL = 0;
147         uint32 iL;
148         for( iL = 0; iL < depthA; iL++ )
149         {
150                 sizeL += ( baseSizeL >> ( iL * 2 ) );
151         }
152         return  bbs_UInt8Arr_heapSize( cpA, &ptrA->arrE, sizeL );
153 }
154
155 /* ------------------------------------------------------------------------- */
156
157 /* ========================================================================= */
158 /*                                                                           */
159 /* ---- \ghd{ modify functions } ------------------------------------------- */
160 /*                                                                           */
161 /* ========================================================================= */
162
163 /* ------------------------------------------------------------------------- */
164         
165 void bim_UInt8PyramidalImage_create( struct bbs_Context* cpA,
166                                                                          struct bim_UInt8PyramidalImage* ptrA, 
167                                                                          uint32 widthA, uint32 heightA, 
168                                                                          uint32 depthA,
169                                                                      struct bbs_MemSeg* mspA )
170 {
171         uint32 baseSizeL = widthA * heightA;
172         uint32 sizeL = 0;
173         uint32 iL;
174         if( bbs_Context_error( cpA ) ) return;
175         for( iL = 0; iL < depthA; iL++ )
176         {
177                 sizeL += ( baseSizeL >> ( iL * 2 ) );
178         }
179
180         if( ptrA->arrE.arrPtrE != 0 )
181         {
182                 bim_UInt8PyramidalImage_size( cpA, ptrA, widthA, heightA, depthA );
183                 return;
184         }
185
186 #ifdef DEBUG1
187         {
188                 uint32 depthMaskL = ( 1 << ( depthA - 1 ) ) - 1;
189                 if( depthA == 0 )
190                 {
191                         bbs_ERROR0( "void bim_UInt8PyramidalImage_create( struct bim_UInt8PyramidalImage* ptrA, uint32 widthA, uint32 heightA, uint32 depthA ):\n"
192                                            "depthA must be > 0" );
193                         return;
194                 }
195                 if( ( ( widthA & depthMaskL ) > 0 ) || ( ( heightA & depthMaskL ) > 0 ) )
196                 {
197                         bbs_ERROR1( "void bim_UInt8PyramidalImage_create( struct bim_UInt8PyramidalImage* ptrA, uint32 widthA, uint32 heightA, uint32 depthA ):\n"
198                                            "widthA and heightA must be divisible by %i", depthMaskL + 1 );
199                         return;
200                 }
201         }
202 #endif
203
204         ptrA->widthE  = widthA;
205         ptrA->heightE = heightA;
206         ptrA->depthE  = depthA;
207
208         bbs_UInt8Arr_create( cpA, &ptrA->arrE, sizeL, mspA );
209 }
210
211 /* ------------------------------------------------------------------------- */
212
213 void bim_UInt8PyramidalImage_size( struct bbs_Context* cpA,
214                                                                    struct bim_UInt8PyramidalImage* ptrA, 
215                                                                    uint32 widthA, 
216                                                                    uint32 heightA, 
217                                                                    uint32 depthA )
218 {
219         uint32 baseSizeL = widthA * heightA;
220         uint32 sizeL = 0;
221         uint32 iL;
222
223 #ifdef DEBUG1
224         uint32 depthMaskL = ( 1 << ( depthA - 1 ) ) - 1;
225         if( depthA == 0 )
226         {
227                 bbs_ERROR0( "void bim_UInt8PyramidalImage_size( struct bim_UInt8PyramidalImage* ptrA, uint32 widthA, uint32 heightA, uint32 depthA ):\n"
228                                "depthA must be > 0" );
229                 return;
230         }
231
232         if( ( ( widthA & depthMaskL ) > 0 ) || ( ( heightA & depthMaskL ) > 0 ) )
233         {
234                 bbs_ERROR1( "void bim_UInt8PyramidalImage_size( struct bim_UInt8PyramidalImage* ptrA, uint32 widthA, uint32 heightA, uint32 depthA ):\n"
235                                "widthA and heightA must be divisible by %i", depthMaskL + 1 );
236                 return;
237         }
238 #endif
239
240         ptrA->widthE  = widthA;
241         ptrA->heightE = heightA;
242         ptrA->depthE  = depthA;
243
244         for( iL = 0; iL < depthA; iL++ )
245         {
246                 sizeL += ( baseSizeL >> ( iL * 2 ) );
247         }
248 #ifdef DEBUG1
249         if( sizeL > ptrA->arrE.allocatedSizeE )
250         {
251                 bbs_ERROR0( "void bim_UInt8PyramidalImage_size( struct bim_UInt8PyramidalImage* ptrA, uint32 widthA, uint32 heightA, uint32 depthA ):\n"
252                                "Insufficient allocated memory." );
253                 return;
254         }
255 #endif
256         bbs_UInt8Arr_size( cpA, &ptrA->arrE, sizeL );
257 }
258
259 /* ------------------------------------------------------------------------- */
260         
261 /* ========================================================================= */
262 /*                                                                           */
263 /* ---- \ghd{ I/O } -------------------------------------------------------- */
264 /*                                                                           */
265 /* ========================================================================= */
266
267 /* ------------------------------------------------------------------------- */
268         
269 uint32 bim_UInt8PyramidalImage_memSize( struct bbs_Context* cpA,
270                                                                             const struct bim_UInt8PyramidalImage* ptrA )
271 {
272         return  bbs_SIZEOF16( uint32 )
273                   + bbs_SIZEOF16( uint32 ) /* version */
274                   + bbs_SIZEOF16( ptrA->widthE ) 
275                   + bbs_SIZEOF16( ptrA->heightE )
276                   + bbs_SIZEOF16( ptrA->depthE )
277                   + bbs_UInt8Arr_memSize( cpA, &ptrA->arrE ); 
278 }
279
280 /* ------------------------------------------------------------------------- */
281         
282 uint32 bim_UInt8PyramidalImage_memWrite( struct bbs_Context* cpA,
283                                                                                  const struct bim_UInt8PyramidalImage* ptrA, 
284                                                                                  uint16* memPtrA )
285 {
286         uint32 memSizeL = bim_UInt8PyramidalImage_memSize( cpA, ptrA );
287         memPtrA += bbs_memWrite32( &memSizeL, memPtrA );
288         memPtrA += bbs_memWriteUInt32( bim_UINT8_PYRAMIDAL_IMAGE_VERSION, memPtrA );
289         memPtrA += bbs_memWrite32( &ptrA->widthE, memPtrA );
290         memPtrA += bbs_memWrite32( &ptrA->heightE, memPtrA );
291         memPtrA += bbs_memWrite32( &ptrA->depthE, memPtrA );
292         bbs_UInt8Arr_memWrite( cpA, &ptrA->arrE, memPtrA );
293         return memSizeL;
294 }
295
296 /* ------------------------------------------------------------------------- */
297         
298 uint32 bim_UInt8PyramidalImage_memRead( struct bbs_Context* cpA,
299                                                                             struct bim_UInt8PyramidalImage* ptrA, 
300                                                                             const uint16* memPtrA,
301                                                                             struct bbs_MemSeg* mspA )
302 {
303         uint32 memSizeL, versionL, widthL, heightL, depthL;
304         if( bbs_Context_error( cpA ) ) return 0;
305         memPtrA += bbs_memRead32( &memSizeL, memPtrA );
306         memPtrA += bbs_memReadVersion32( cpA, &versionL, bim_UINT8_PYRAMIDAL_IMAGE_VERSION, memPtrA );
307         memPtrA += bbs_memRead32( &widthL, memPtrA );
308         memPtrA += bbs_memRead32( &heightL, memPtrA );
309         memPtrA += bbs_memRead32( &depthL, memPtrA );
310
311         ptrA->widthE  = widthL;
312         ptrA->heightE = heightL;
313         ptrA->depthE  = depthL;
314         bbs_UInt8Arr_memRead( cpA, &ptrA->arrE, memPtrA, mspA );
315
316         if( memSizeL != bim_UInt8PyramidalImage_memSize( cpA, ptrA ) )
317         {
318                 bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bim_UInt8PyramidalImage_memRead( const struct bim_UInt8PyramidalImage* ptrA, const void* memPtrA ):\n"
319                    "size mismatch" ); 
320                 return 0;
321         }
322
323         return memSizeL;
324 }
325
326 /* ------------------------------------------------------------------------- */
327         
328 /* ========================================================================= */
329 /*                                                                           */
330 /* ---- \ghd{ exec functions } --------------------------------------------- */
331 /*                                                                           */
332 /* ========================================================================= */
333
334 void bim_UInt8PyramidalImage_overlayUInt8( struct bbs_Context* cpA,
335                                                                                    const struct bim_UInt8PyramidalImage* ptrA,  
336                                                                                    struct bim_UInt8Image* uint8ImageA )
337 {
338         uint8ImageA->widthE = ptrA->widthE;
339         uint8ImageA->heightE = ptrA->heightE;
340         uint8ImageA->arrE.sizeE = ptrA->widthE * ptrA->heightE;
341         uint8ImageA->arrE.allocatedSizeE = ptrA->widthE * ptrA->heightE;
342         uint8ImageA->arrE.arrPtrE = ptrA->arrE.arrPtrE;
343         uint8ImageA->arrE.mspE = 0;
344 }
345
346 /* ------------------------------------------------------------------------- */
347
348 void bim_UInt8PyramidalImage_recompute( struct bbs_Context* cpA,
349                                                                             struct bim_UInt8PyramidalImage* dstPtrA )
350 {
351         uint32 iL, jL, layerL, widthL, heightL;
352         uint8 *srcL, *dstL;
353
354         /* process remaining layers */
355         widthL = dstPtrA->widthE;
356         heightL = dstPtrA->heightE;
357         srcL = dstPtrA->arrE.arrPtrE;
358         dstL = srcL + widthL * heightL;
359         for( layerL = 1; layerL < dstPtrA->depthE; layerL++ )
360         {
361                 for( jL = ( heightL >> 1 ); jL > 0; jL-- )
362                 {
363                         for( iL = ( widthL >> 1 ); iL > 0; iL-- )
364                         {
365                                 /* averaging with roundig */
366                                 *dstL++ = ( ( *srcL + *( srcL + 1 ) + *( srcL + widthL ) + *( srcL + widthL + 1 ) ) + 2 ) >> 2;
367                                 srcL += 2;
368                         }
369                         srcL += widthL;
370                 }
371                 widthL >>= 1;
372                 heightL >>= 1;
373         }
374
375
376 /* ------------------------------------------------------------------------- */
377
378 void bim_UInt8PyramidalImage_importUInt8( struct bbs_Context* cpA,
379                                                                                   struct bim_UInt8PyramidalImage* dstPtrA, 
380                                                                               const struct bim_UInt8Image* srcPtrA,
381                                                                                   uint32 depthA )
382 {
383
384         bim_UInt8PyramidalImage_size( cpA, dstPtrA, srcPtrA->widthE, srcPtrA->heightE, depthA );
385
386         if( srcPtrA->arrE.sizeE & 1 )
387         {
388                 bbs_ERROR0( "void bim_UInt8PyramidalImage_importUInt8(....):\n"
389                                "Size of source image must be even.\n" );
390                 return;
391
392         }
393
394         /* copy first layer */
395         bbs_memcpy16( dstPtrA->arrE.arrPtrE, srcPtrA->arrE.arrPtrE, srcPtrA->arrE.sizeE >> 1 );
396
397         bim_UInt8PyramidalImage_recompute( cpA, dstPtrA );
398 }
399
400 /* ------------------------------------------------------------------------- */
401
402 /* ========================================================================= */
403
404