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