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/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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 */
    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 
    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