Home | History | Annotate | Download | only in b_ImageEm
      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 
     42 void 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 
     52 void 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 
     70 void 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 
     89 flag 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 
    108 uint32 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 
    125 uint32 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 
    142 void 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 
    163 void 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 
    189 uint32 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 
    201 uint32 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 
    216 uint32 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 
    251 void 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 */
    342 void 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 
    460 void 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