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/APhImage.h"
22 #include "b_ImageEm/ComplexImage.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
bim_APhImage_init(struct bbs_Context * cpA,struct bim_APhImage * ptrA)42 void bim_APhImage_init( struct bbs_Context* cpA,
43 struct bim_APhImage* ptrA )
44 {
45 bbs_APhArr_init( cpA, &ptrA->arrE );
46 ptrA->widthE = 0;
47 ptrA->heightE = 0;
48 }
49
50 /* ------------------------------------------------------------------------- */
51
bim_APhImage_create(struct bbs_Context * cpA,struct bim_APhImage * ptrA,uint32 widthA,uint32 heightA,struct bbs_MemSeg * mspA)52 void bim_APhImage_create( struct bbs_Context* cpA,
53 struct bim_APhImage* ptrA,
54 uint32 widthA,
55 uint32 heightA,
56 struct bbs_MemSeg* mspA )
57 {
58 if( bbs_Context_error( cpA ) ) return;
59 if( ptrA->arrE.arrPtrE != 0 )
60 {
61 bim_APhImage_size( cpA, ptrA, widthA, heightA );
62 }
63 else
64 {
65 bbs_APhArr_create( cpA, &ptrA->arrE, widthA * heightA, mspA );
66 ptrA->widthE = widthA;
67 ptrA->heightE = heightA;
68 }
69 }
70
71 /* ------------------------------------------------------------------------- */
72
bim_APhImage_exit(struct bbs_Context * cpA,struct bim_APhImage * ptrA)73 void bim_APhImage_exit( struct bbs_Context* cpA,
74 struct bim_APhImage* ptrA )
75 {
76 bbs_APhArr_exit( cpA, &ptrA->arrE );
77 ptrA->widthE = 0;
78 ptrA->heightE = 0;
79 }
80
81 /* ------------------------------------------------------------------------- */
82
83 /* ========================================================================= */
84 /* */
85 /* ---- \ghd{ operators } -------------------------------------------------- */
86 /* */
87 /* ========================================================================= */
88
89 /* ------------------------------------------------------------------------- */
90
bim_APhImage_copy(struct bbs_Context * cpA,struct bim_APhImage * ptrA,const struct bim_APhImage * srcPtrA)91 void bim_APhImage_copy( struct bbs_Context* cpA,
92 struct bim_APhImage* ptrA,
93 const struct bim_APhImage* srcPtrA )
94 {
95 #ifdef DEBUG1
96 if( ptrA->arrE.allocatedSizeE < srcPtrA->arrE.allocatedSizeE )
97 {
98 bbs_ERROR0( "void bim_APhImage_copy( struct bim_APhImage*, uint32 sizeA ):\n"
99 "Unsufficient allocated memory" );
100 return;
101 }
102 #endif
103 ptrA->widthE = srcPtrA->widthE;
104 ptrA->heightE = srcPtrA->heightE;
105 bbs_APhArr_copy( cpA, &ptrA->arrE, &srcPtrA->arrE );
106 }
107
108 /* ------------------------------------------------------------------------- */
109
bim_APhImage_equal(struct bbs_Context * cpA,const struct bim_APhImage * ptrA,const struct bim_APhImage * srcPtrA)110 flag bim_APhImage_equal( struct bbs_Context* cpA,
111 const struct bim_APhImage* ptrA,
112 const struct bim_APhImage* srcPtrA )
113 {
114 if( ptrA->widthE != srcPtrA->widthE ) return FALSE;
115 if( ptrA->heightE != srcPtrA->heightE ) return FALSE;
116 return bbs_APhArr_equal( cpA, &ptrA->arrE, &srcPtrA->arrE );
117 }
118
119 /* ------------------------------------------------------------------------- */
120
121 /* ========================================================================= */
122 /* */
123 /* ---- \ghd{ query functions } -------------------------------------------- */
124 /* */
125 /* ========================================================================= */
126
127 /* ------------------------------------------------------------------------- */
128
129 /* ========================================================================= */
130 /* */
131 /* ---- \ghd{ modify functions } ------------------------------------------- */
132 /* */
133 /* ========================================================================= */
134
135 /* ------------------------------------------------------------------------- */
136
bim_APhImage_size(struct bbs_Context * cpA,struct bim_APhImage * ptrA,uint32 widthA,uint32 heightA)137 void bim_APhImage_size( struct bbs_Context* cpA,
138 struct bim_APhImage* ptrA,
139 uint32 widthA,
140 uint32 heightA )
141 {
142 #ifdef DEBUG1
143 if( ptrA->arrE.allocatedSizeE < widthA * heightA )
144 {
145 bbs_ERROR0( "void bim_APhImage_size( struct bim_APhImage*, uint32 sizeA ):\n"
146 "Unsufficient allocated memory" );
147 return;
148 }
149 #endif
150 ptrA->widthE = widthA;
151 ptrA->heightE = heightA;
152 bbs_APhArr_size( cpA, &ptrA->arrE, widthA * heightA );
153 }
154
155 /* ------------------------------------------------------------------------- */
156
157 /* ========================================================================= */
158 /* */
159 /* ---- \ghd{ I/O } -------------------------------------------------------- */
160 /* */
161 /* ========================================================================= */
162
163 /* ------------------------------------------------------------------------- */
164
bim_APhImage_memSize(struct bbs_Context * cpA,const struct bim_APhImage * ptrA)165 uint32 bim_APhImage_memSize( struct bbs_Context* cpA,
166 const struct bim_APhImage* ptrA )
167 {
168 return bbs_SIZEOF16( uint32 )
169 + bbs_SIZEOF16( uint32 ) /* version */
170 + bbs_SIZEOF16( ptrA->widthE )
171 + bbs_SIZEOF16( ptrA->heightE )
172 + bbs_APhArr_memSize( cpA, &ptrA->arrE );
173 }
174
175 /* ------------------------------------------------------------------------- */
176
bim_APhImage_memWrite(struct bbs_Context * cpA,const struct bim_APhImage * ptrA,uint16 * memPtrA)177 uint32 bim_APhImage_memWrite( struct bbs_Context* cpA,
178 const struct bim_APhImage* ptrA,
179 uint16* memPtrA )
180 {
181 uint32 memSizeL = bim_APhImage_memSize( cpA, ptrA );
182 memPtrA += bbs_memWrite32( &memSizeL, memPtrA );
183 memPtrA += bbs_memWriteUInt32( bim_APH_IMAGE_VERSION, memPtrA );
184 memPtrA += bbs_memWrite32( &ptrA->widthE, memPtrA );
185 memPtrA += bbs_memWrite32( &ptrA->heightE, memPtrA );
186 bbs_APhArr_memWrite( cpA, &ptrA->arrE, memPtrA );
187 return memSizeL;
188 }
189
190 /* ------------------------------------------------------------------------- */
191
bim_APhImage_memRead(struct bbs_Context * cpA,struct bim_APhImage * ptrA,const uint16 * memPtrA,struct bbs_MemSeg * mspA)192 uint32 bim_APhImage_memRead( struct bbs_Context* cpA,
193 struct bim_APhImage* ptrA,
194 const uint16* memPtrA,
195 struct bbs_MemSeg* mspA )
196 {
197 uint32 memSizeL, widthL, heightL, versionL;
198 if( bbs_Context_error( cpA ) ) return 0;
199 memPtrA += bbs_memRead32( &memSizeL, memPtrA );
200 memPtrA += bbs_memReadVersion32( cpA, &versionL, bim_APH_IMAGE_VERSION, memPtrA );
201 memPtrA += bbs_memRead32( &widthL, memPtrA );
202 memPtrA += bbs_memRead32( &heightL, memPtrA );
203
204 ptrA->widthE = widthL;
205 ptrA->heightE = heightL;
206 bbs_APhArr_memRead( cpA, &ptrA->arrE, memPtrA, mspA );
207
208 if( memSizeL != bim_APhImage_memSize( cpA, ptrA ) )
209 {
210 bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bim_APhImage_memRead( const struct bim_APhImage*, const void* ):\n"
211 "size mismatch" );
212 return 0;
213 }
214 return memSizeL;
215 }
216
217 /* ------------------------------------------------------------------------- */
218
219 /* ========================================================================= */
220 /* */
221 /* ---- \ghd{ exec functions } --------------------------------------------- */
222 /* */
223 /* ========================================================================= */
224
225 /* ------------------------------------------------------------------------- */
226
bim_APhImage_setAllPixels(struct bbs_Context * cpA,struct bim_APhImage * ptrA,struct bbs_APh valueA)227 void bim_APhImage_setAllPixels( struct bbs_Context* cpA,
228 struct bim_APhImage* ptrA,
229 struct bbs_APh valueA )
230 {
231 long iL;
232 struct bbs_APh* ptrL = ptrA->arrE.arrPtrE;
233 for( iL = ptrA->widthE * ptrA->heightE; iL > 0; iL-- )
234 {
235 *ptrL++ = valueA;
236 }
237 }
238
239 /* ------------------------------------------------------------------------- */
240
241 /**
242 | | | |
243 | (loop x1) | (loop x2) | (loop x3) |
244 o------------->-o------------>--o------------->-o
245 | | | |
246 | | | |
247 | | | |
248 | | | |
249 ( sectionL->x1E, sectionL->y1E ) | |
250 ---------o- R-------------------------------|----------------
251 | | | | |
252 | | | | |
253 | | | | |
254 | | | | |
255 (loop y1)| | | |
256 | | | | |
257 V | | | |
258 | | |( 0, 0 ) | | X
259 ---------o------------------I------------------------------------------------->
260 | | | | |
261 | | | | |
262 | | | | |
263 | | | | |
264 | | | | |
265 (loop y2)| | | |
266 | | | | |
267 | | | | |
268 | | | | |
269 V | | | |
270 | | | | |
271 ---------o------------------|---------------I |
272 | | | ( srcPtrA->widthE, srcPtrA->heightE )
273 | | | |
274 | | | |
275 | | | |
276 | | | |
277 | | | |
278 (loop y3)| | |
279 | | | |
280 | | | |
281 V | | |
282 | | | |
283 ---------o--------------------------------------------------R
284 | ( sectionL->x2E, sectionL->y2E )
285 |
286 Y |
287 |
288 |
289 V
290
291 To understand how the algorithm work refer to the diagram above.
292 The image boundaries are indicated by letter "I" ( 0, 0 ) to ( srcPtrA->widthE, srcPtrA->heightE )
293 The rectangle boundaries are indicated by letter "R" ( sectionPtrA->x1E, sectionPtrA->y1E ) to ( sectionPtrA->x2E, sectionPtrA->y2E )
294
295 In the above example the intersection of the image and the rectange is
296 ( 0, 0 ), ( srcPtrA->widthE, srcPtrA->heightE )
297
298 The size of the destination image is always ( ( sectionL->x2E, sectionL->y2E ) - ( sectionL->x1E, sectionL->y1E ) )
299
300 All coordinates are assumed to be relative to the original image.
301
302 1. parse all pixels in "loop y1"
303 1.a. parse all pixels in "loop x1"
304 1.b. parse all pixels in "loop x2"
305 1.c. parse all pixels in "loop x3"
306 2. parse all pixels in "loop y2"
307 2.a. parse all pixels in "loop x1"
308 2.b. parse all pixels in "loop x2"
309 2.c. parse all pixels in "loop x3"
310 3. parse all pixels in "loop y3"
311 3.a. parse all pixels in "loop x1"
312 3.b. parse all pixels in "loop x2"
313 3.c. parse all pixels in "loop x3"
314
315 */
316
317 /** copies a section of given image */
bim_APhImage_copySection(struct bbs_Context * cpA,struct bim_APhImage * ptrA,const struct bim_APhImage * srcPtrA,const struct bts_Int16Rect * sectionPtrA)318 void bim_APhImage_copySection( struct bbs_Context* cpA,
319 struct bim_APhImage* ptrA,
320 const struct bim_APhImage* srcPtrA,
321 const struct bts_Int16Rect* sectionPtrA )
322 {
323
324 struct bbs_APh* srcPixelPtrL;
325 struct bbs_APh* dstPixelPtrL;
326 int32 yIndexL;
327 int32 xIndexL;
328
329 struct bts_Int16Rect srcImageSubSectionL;
330 struct bts_Int16Rect sectionL;
331
332 /* make sure that the rectangle passed is correct, in case the x2 < x1 or y2 < y1, swap them */
333 sectionL.x1E = bbs_min( sectionPtrA->x1E, sectionPtrA->x2E );
334 sectionL.x2E = bbs_max( sectionPtrA->x1E, sectionPtrA->x2E );
335 sectionL.y1E = bbs_min( sectionPtrA->y1E, sectionPtrA->y2E );
336 sectionL.y2E = bbs_max( sectionPtrA->y1E, sectionPtrA->y2E );
337
338 /* find the intersection betweem the rectangle and the image, the image always starts at 0,0 */
339 srcImageSubSectionL.x1E = bbs_max( 0, sectionL.x1E );
340 srcImageSubSectionL.y1E = bbs_max( 0, sectionL.y1E );
341 srcImageSubSectionL.x2E = bbs_min( ( int32 ) srcPtrA->widthE, sectionL.x2E );
342 srcImageSubSectionL.y2E = bbs_min( ( int32 ) srcPtrA->heightE, sectionL.y2E );
343
344 /* If the image and the rectangle do not intersect in X direction, set the intersecting rectangle to the image coordinates */
345 if( srcImageSubSectionL.x2E < srcImageSubSectionL.x1E )
346 {
347 srcImageSubSectionL.x1E = 0;
348 srcImageSubSectionL.x2E = srcPtrA->widthE;
349 }
350 /* do the same as above in the Y direction */
351 if( srcImageSubSectionL.y2E < srcImageSubSectionL.y1E )
352 {
353 srcImageSubSectionL.y1E = 0;
354 srcImageSubSectionL.y2E = srcPtrA->heightE;
355 }
356
357 /* set size, and allocate required memory for the destination image if required */
358 bim_APhImage_size( cpA, ptrA, sectionL.x2E - sectionL.x1E, sectionL.y2E - sectionL.y1E );
359
360 /* get the pointer to the destination image */
361 dstPixelPtrL = ptrA->arrE.arrPtrE;
362
363 /* 1. parse all pixels in "loop y1" */
364 for( yIndexL = sectionL.y1E; yIndexL < srcImageSubSectionL.y1E && yIndexL < sectionL.y2E; yIndexL++ )
365 {
366 /* move to the first pixel that needs to be copied. */
367 srcPixelPtrL = srcPtrA->arrE.arrPtrE;
368
369 /* 1.a. parse all pixels in "loop x1" */
370 for( xIndexL = sectionL.x1E; xIndexL < srcImageSubSectionL.x1E && xIndexL < sectionL.x2E; xIndexL++ )
371 {
372 *dstPixelPtrL++ = *srcPixelPtrL;
373 }
374 /* 1.b. parse all pixels in "loop x2" */
375 for( ; xIndexL < srcImageSubSectionL.x2E && xIndexL < sectionL.x2E; xIndexL++ )
376 {
377 *dstPixelPtrL++ = *srcPixelPtrL++;
378 }
379 srcPixelPtrL--;
380 /* 1.c. parse all pixels in "loop x3" */
381 for( ; xIndexL < sectionL.x2E; xIndexL++ )
382 {
383 *dstPixelPtrL++ = *srcPixelPtrL;
384 }
385 }
386 /* 2. parse all pixels in "loop y2" */
387 for( ; yIndexL < srcImageSubSectionL.y2E && yIndexL < sectionL.y2E; yIndexL++ )
388 {
389 /* move to the first pixel that needs to be copied. */
390 srcPixelPtrL = srcPtrA->arrE.arrPtrE + yIndexL * srcPtrA->widthE + srcImageSubSectionL.x1E;
391
392 /* 2.a. parse all pixels in "loop x1" */
393 for( xIndexL = sectionL.x1E; xIndexL < srcImageSubSectionL.x1E && xIndexL < sectionL.x2E; xIndexL++ )
394 {
395 *dstPixelPtrL++ = *srcPixelPtrL;
396 }
397 /* 2.b. parse all pixels in "loop x2" */
398 for( ; xIndexL < srcImageSubSectionL.x2E && xIndexL < sectionL.x2E; xIndexL++ )
399 {
400 *dstPixelPtrL++ = *srcPixelPtrL++;
401 }
402 srcPixelPtrL--;
403 /* 2.c. parse all pixels in "loop x3" */
404 for( ; xIndexL < sectionL.x2E; xIndexL++ )
405 {
406 *dstPixelPtrL++ = *srcPixelPtrL;
407 }
408 }
409 /* 3. parse all pixels in "loop y3" */
410 for( ; yIndexL < sectionL.y2E; yIndexL++ )
411 {
412 srcPixelPtrL = srcPtrA->arrE.arrPtrE + ( srcImageSubSectionL.y2E - 1 ) * srcPtrA->widthE + srcImageSubSectionL.x1E;
413
414 /* 3.a. parse all pixels in "loop x1" */
415 for( xIndexL = sectionL.x1E; xIndexL < srcImageSubSectionL.x1E && xIndexL < sectionL.x2E; xIndexL++ )
416 {
417 *dstPixelPtrL++ = *srcPixelPtrL;
418 }
419 /* 3.b. parse all pixels in "loop x3" */
420 for( ; xIndexL < srcImageSubSectionL.x2E && xIndexL < sectionL.x2E; xIndexL++ )
421 {
422 *dstPixelPtrL++ = *srcPixelPtrL++;
423 }
424 srcPixelPtrL--;
425 /* 3.c. parse all pixels in "loop x3" */
426 for( ; xIndexL < sectionL.x2E; xIndexL++ )
427 {
428 *dstPixelPtrL++ = *srcPixelPtrL;
429 }
430 }
431
432 }
433
434 /* ------------------------------------------------------------------------- */
435
bim_APhImage_importComplex(struct bbs_Context * cpA,struct bim_APhImage * dstPtrA,const struct bim_ComplexImage * srcPtrA)436 void bim_APhImage_importComplex( struct bbs_Context* cpA,
437 struct bim_APhImage* dstPtrA,
438 const struct bim_ComplexImage* srcPtrA )
439 {
440 long iL;
441 struct bbs_APh* dstL;
442 const struct bbs_Complex* srcL;
443 bim_APhImage_size( cpA, dstPtrA, srcPtrA->widthE, srcPtrA->heightE );
444 dstL = dstPtrA->arrE.arrPtrE;
445 srcL = srcPtrA->arrE.arrPtrE;
446 for( iL = srcPtrA->widthE * srcPtrA->heightE; iL > 0; iL-- )
447 {
448 bbs_APh_importComplex( dstL++, srcL++ );
449 }
450 }
451
452 /* ------------------------------------------------------------------------- */
453
454 /* ========================================================================= */
455
456
457