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