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/Functions.h"
     22 #include "b_ImageEm/UInt16BytePyrImage.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_UInt16BytePyrImage_init( struct bbs_Context* cpA,
     43 								  struct bim_UInt16BytePyrImage* ptrA )
     44 {
     45 	bbs_UInt16Arr_init( cpA, &ptrA->arrE );
     46 	ptrA->widthE = 0;
     47 	ptrA->heightE = 0;
     48 	ptrA->depthE = 0;
     49 	ptrA->typeE = bim_UINT16_PYRAMIDAL_IMG;
     50 }
     51 
     52 /* ------------------------------------------------------------------------- */
     53 
     54 void bim_UInt16BytePyrImage_exit( struct bbs_Context* cpA,
     55 								  struct bim_UInt16BytePyrImage* ptrA )
     56 {
     57 	bbs_UInt16Arr_exit( cpA, &ptrA->arrE );
     58 	ptrA->widthE = 0;
     59 	ptrA->heightE = 0;
     60 	ptrA->depthE = 0;
     61 }
     62 
     63 /* ------------------------------------------------------------------------- */
     64 
     65 /* ========================================================================= */
     66 /*                                                                           */
     67 /* ---- \ghd{ operators } -------------------------------------------------- */
     68 /*                                                                           */
     69 /* ========================================================================= */
     70 
     71 /* ------------------------------------------------------------------------- */
     72 
     73 void bim_UInt16BytePyrImage_copy( struct bbs_Context* cpA,
     74 								  struct bim_UInt16BytePyrImage* ptrA,
     75 								  const struct bim_UInt16BytePyrImage* srcPtrA )
     76 {
     77 #ifdef DEBUG1
     78 	if( ptrA->arrE.allocatedSizeE < srcPtrA->arrE.allocatedSizeE )
     79 	{
     80 		bbs_ERROR0( "void bim_UInt16BytePyrImage_copy( ... ):\n"
     81 				   "Unsufficient allocated memory in destination image" );
     82 		return;
     83 	}
     84 #endif
     85 	ptrA->widthE = srcPtrA->widthE;
     86 	ptrA->heightE = srcPtrA->heightE;
     87 	ptrA->depthE = srcPtrA->depthE;
     88 	bbs_UInt16Arr_copy( cpA, &ptrA->arrE, &srcPtrA->arrE );
     89 }
     90 
     91 /* ------------------------------------------------------------------------- */
     92 
     93 flag bim_UInt16BytePyrImage_equal( struct bbs_Context* cpA,
     94 								   const struct bim_UInt16BytePyrImage* ptrA,
     95 								   const struct bim_UInt16BytePyrImage* srcPtrA )
     96 {
     97 	if( ptrA->widthE != srcPtrA->widthE ) return FALSE;
     98 	if( ptrA->heightE != srcPtrA->heightE ) return FALSE;
     99 	if( ptrA->depthE != srcPtrA->depthE ) return FALSE;
    100 	return bbs_UInt16Arr_equal( cpA, &ptrA->arrE, &srcPtrA->arrE );
    101 }
    102 
    103 /* ------------------------------------------------------------------------- */
    104 
    105 /* ========================================================================= */
    106 /*                                                                           */
    107 /* ---- \ghd{ query functions } -------------------------------------------- */
    108 /*                                                                           */
    109 /* ========================================================================= */
    110 
    111 /* ------------------------------------------------------------------------- */
    112 
    113 uint16* bim_UInt16BytePyrImage_arrPtr( struct bbs_Context* cpA,
    114 									   const struct bim_UInt16BytePyrImage* ptrA,
    115 										 uint32 levelA )
    116 {
    117 	uint32 iL;
    118 	uint32 offsL = 0;
    119 	uint32 baseSizeL = ( ptrA->widthE * ptrA->heightE ) >> 1;
    120 
    121 #ifdef DEBUG2
    122 	if( levelA >= ptrA->depthE )
    123 	{
    124 		bbs_ERROR2( "uint16* bim_UInt16BytePyrImage_arrPtr( struct bim_UInt16BytePyrImage*, uint32 levelA ):\n"
    125 			       "levelA = %i out of range [0,%i]", levelA, ptrA->depthE - 1 );
    126 		return NULL;
    127 	}
    128 #endif
    129 
    130 	for( iL = 0; iL < levelA; iL++ )
    131 	{
    132 		offsL += ( baseSizeL >> ( iL * 2 ) );
    133 	}
    134 	return ptrA->arrE.arrPtrE + offsL;
    135 }
    136 
    137 /* ------------------------------------------------------------------------- */
    138 
    139 uint32 bim_UInt16BytePyrImage_heapSize( struct bbs_Context* cpA,
    140 									    const struct bim_UInt16BytePyrImage* ptrA,
    141 										  uint32 widthA, uint32 heightA,
    142 										  uint32 depthA )
    143 {
    144 	uint32 baseSizeL = ( widthA * heightA ) >> 1;
    145 	uint32 sizeL = 0;
    146 	uint32 iL;
    147 	for( iL = 0; iL < depthA; iL++ )
    148 	{
    149 		sizeL += ( baseSizeL >> ( iL * 2 ) );
    150 	}
    151 	return 	bbs_UInt16Arr_heapSize( cpA, &ptrA->arrE, sizeL );
    152 }
    153 
    154 /* ------------------------------------------------------------------------- */
    155 
    156 /* ========================================================================= */
    157 /*                                                                           */
    158 /* ---- \ghd{ modify functions } ------------------------------------------- */
    159 /*                                                                           */
    160 /* ========================================================================= */
    161 
    162 /* ------------------------------------------------------------------------- */
    163 
    164 void bim_UInt16BytePyrImage_create( struct bbs_Context* cpA,
    165 								    struct bim_UInt16BytePyrImage* ptrA,
    166 									 uint32 widthA, uint32 heightA,
    167 									 uint32 depthA,
    168 								     struct bbs_MemSeg* mspA )
    169 {
    170 	uint32 baseSizeL = ( widthA * heightA ) >> 1;
    171 	uint32 sizeL = 0;
    172 	uint32 iL;
    173 
    174 	if( bbs_Context_error( cpA ) ) return;
    175 	if( ptrA->arrE.arrPtrE != 0 )
    176 	{
    177 		bim_UInt16BytePyrImage_size( cpA, ptrA, widthA, heightA, depthA );
    178 		return;
    179 	}
    180 
    181 #ifdef DEBUG1
    182 	{
    183 		uint32 depthMaskL = ( ( int32 )1 << ( depthA - 1 ) ) - 1;
    184 		if( depthA == 0 )
    185 		{
    186 			bbs_ERROR0( "void bim_UInt16BytePyrImage_create( struct bim_UInt16BytePyrImage* ptrA, uint32 widthA, uint32 heightA, uint32 depthA ):\n"
    187 					   "depthA must be > 0" );
    188 			return;
    189 		}
    190 		if( ( ( widthA & depthMaskL ) > 0 ) || ( ( heightA & depthMaskL ) > 0 ) )
    191 		{
    192 			bbs_ERROR1( "void bim_UInt16BytePyrImage_create( struct bim_UInt16BytePyrImage* ptrA, uint32 widthA, uint32 heightA, uint32 depthA ):\n"
    193 					   "widthA and heightA must be divisible by %i", depthMaskL + 1 );
    194 			return;
    195 		}
    196 	}
    197 #endif
    198 
    199 	ptrA->widthE  = widthA;
    200 	ptrA->heightE = heightA;
    201 	ptrA->depthE  = depthA;
    202 
    203 	for( iL = 0; iL < depthA; iL++ )
    204 	{
    205 		sizeL += ( baseSizeL >> ( iL * 2 ) );
    206 	}
    207 	bbs_UInt16Arr_create( cpA, &ptrA->arrE, sizeL, mspA );
    208 }
    209 
    210 /* ------------------------------------------------------------------------- */
    211 
    212 void bim_UInt16BytePyrImage_size( struct bbs_Context* cpA,
    213 								  struct bim_UInt16BytePyrImage* ptrA,
    214 								  uint32 widthA,
    215 								  uint32 heightA,
    216 								  uint32 depthA )
    217 {
    218 	uint32 baseSizeL = ( widthA * heightA ) >> 1;
    219 	uint32 sizeL = 0;
    220 	uint32 iL;
    221 
    222 #ifdef DEBUG1
    223 	uint32 depthMaskL = ( 1 << ( depthA - 1 ) ) - 1;
    224 	if( depthA == 0 )
    225 	{
    226 		bbs_ERROR0( "void bim_UInt16BytePyrImage_size( struct bim_UInt16BytePyrImage* ptrA, uint32 widthA, uint32 heightA, uint32 depthA ):\n"
    227 			       "depthA must be > 0" );
    228 		return;
    229 	}
    230 
    231 	if( ( ( widthA & depthMaskL ) > 0 ) || ( ( heightA & depthMaskL ) > 0 ) )
    232 	{
    233 		bbs_ERROR1( "void bim_UInt16BytePyrImage_size( struct bim_UInt16BytePyrImage* ptrA, uint32 widthA, uint32 heightA, uint32 depthA ):\n"
    234 			       "widthA and heightA must be divisible by %i", depthMaskL + 1 );
    235 		return;
    236 	}
    237 #endif
    238 
    239 	ptrA->widthE  = widthA;
    240 	ptrA->heightE = heightA;
    241 	ptrA->depthE  = depthA;
    242 
    243 	for( iL = 0; iL < depthA; iL++ )
    244 	{
    245 		sizeL += ( baseSizeL >> ( iL * 2 ) );
    246 	}
    247 #ifdef DEBUG1
    248 	if( sizeL > ptrA->arrE.allocatedSizeE )
    249 	{
    250 		bbs_ERROR0( "void bim_UInt16BytePyrImage_size( struct bim_UInt16BytePyrImage* ptrA, uint32 widthA, uint32 heightA, uint32 depthA ):\n"
    251 			       "Insufficient allocated memory." );
    252 		return;
    253 	}
    254 #endif
    255 	bbs_UInt16Arr_size( cpA, &ptrA->arrE, sizeL );
    256 }
    257 
    258 /* ------------------------------------------------------------------------- */
    259 
    260 /* ========================================================================= */
    261 /*                                                                           */
    262 /* ---- \ghd{ I/O } -------------------------------------------------------- */
    263 /*                                                                           */
    264 /* ========================================================================= */
    265 
    266 /* ------------------------------------------------------------------------- */
    267 
    268 uint32 bim_UInt16BytePyrImage_memSize( struct bbs_Context* cpA,
    269 									   const struct bim_UInt16BytePyrImage* ptrA )
    270 {
    271 	return  bbs_SIZEOF16( uint32 )
    272 		  + bbs_SIZEOF16( uint32 ) /* version */
    273 		  + bbs_SIZEOF16( ptrA->widthE )
    274 		  + bbs_SIZEOF16( ptrA->heightE )
    275 		  + bbs_SIZEOF16( ptrA->depthE )
    276 		  + bbs_UInt16Arr_memSize( cpA, &ptrA->arrE );
    277 }
    278 
    279 /* ------------------------------------------------------------------------- */
    280 
    281 uint32 bim_UInt16BytePyrImage_memWrite( struct bbs_Context* cpA,
    282 									    const struct bim_UInt16BytePyrImage* ptrA,
    283 										uint16* memPtrA )
    284 {
    285 	uint32 memSizeL = bim_UInt16BytePyrImage_memSize( cpA, ptrA );
    286 	memPtrA += bbs_memWrite32( &memSizeL, memPtrA );
    287 	memPtrA += bbs_memWriteUInt32( bim_UINT16_PYRAMIDAL_IMAGE_VERSION, memPtrA );
    288 	memPtrA += bbs_memWrite32( &ptrA->widthE, memPtrA );
    289 	memPtrA += bbs_memWrite32( &ptrA->heightE, memPtrA );
    290 	memPtrA += bbs_memWrite32( &ptrA->depthE, memPtrA );
    291 	bbs_UInt16Arr_memWrite( cpA, &ptrA->arrE, memPtrA );
    292 	return memSizeL;
    293 }
    294 
    295 /* ------------------------------------------------------------------------- */
    296 
    297 uint32 bim_UInt16BytePyrImage_memRead( struct bbs_Context* cpA,
    298 									   struct bim_UInt16BytePyrImage* ptrA,
    299 									    const uint16* memPtrA,
    300  									    struct bbs_MemSeg* mspA )
    301 {
    302 	uint32 memSizeL, versionL, widthL, heightL, depthL;
    303 	if( bbs_Context_error( cpA ) ) return 0;
    304 	memPtrA += bbs_memRead32( &memSizeL, memPtrA );
    305 	memPtrA += bbs_memReadVersion32( cpA, &versionL, bim_UINT16_PYRAMIDAL_IMAGE_VERSION, memPtrA );
    306 	memPtrA += bbs_memRead32( &widthL, memPtrA );
    307 	memPtrA += bbs_memRead32( &heightL, memPtrA );
    308 	memPtrA += bbs_memRead32( &depthL, memPtrA );
    309 
    310 	ptrA->widthE  = widthL;
    311 	ptrA->heightE = heightL;
    312 	ptrA->depthE  = depthL;
    313 	bbs_UInt16Arr_memRead( cpA, &ptrA->arrE, memPtrA, mspA );
    314 
    315 	if( memSizeL != bim_UInt16BytePyrImage_memSize( cpA, ptrA ) )
    316 	{
    317 		bbs_ERR0( bbs_ERR_CORRUPT_DATA, "uint32 bim_UInt16BytePyrImage_memRead( const struct bim_UInt16BytePyrImage* ptrA, const void* memPtrA ):\n"
    318                    "size mismatch" );
    319 		return 0;
    320 	}
    321 
    322 	return memSizeL;
    323 }
    324 
    325 /* ------------------------------------------------------------------------- */
    326 
    327 /* ========================================================================= */
    328 /*                                                                           */
    329 /* ---- \ghd{ exec functions } --------------------------------------------- */
    330 /*                                                                           */
    331 /* ========================================================================= */
    332 
    333 void bim_UInt16BytePyrImage_overlayUInt16( struct bbs_Context* cpA,
    334 										   const struct bim_UInt16BytePyrImage* ptrA,
    335 											 struct bim_UInt16ByteImage* uint16ImageA )
    336 {
    337 	uint16ImageA->widthE = ptrA->widthE;
    338 	uint16ImageA->heightE = ptrA->heightE;
    339 	uint16ImageA->arrE.sizeE = ptrA->widthE * ptrA->heightE;
    340 	uint16ImageA->arrE.allocatedSizeE = ptrA->widthE * ptrA->heightE;
    341 	uint16ImageA->arrE.arrPtrE = ptrA->arrE.arrPtrE;
    342 	uint16ImageA->arrE.mspE = 0;
    343 }
    344 
    345 /* ------------------------------------------------------------------------- */
    346 
    347 /** process remaining layers */
    348 void bim_UInt16BytePyrImage_recompute( struct bbs_Context* cpA,
    349 									   struct bim_UInt16BytePyrImage* dstPtrA )
    350 {
    351 	count_t iL, jL, layerL;
    352 	uint16 tmpL;
    353 
    354 	uint32 widthL = dstPtrA->widthE;
    355 	uint32 halfWidthL = widthL >> 1;
    356 	uint32 heightL = dstPtrA->heightE;
    357 
    358 	uint16* srcL = dstPtrA->arrE.arrPtrE;
    359 	uint16* dstL = srcL + ( heightL * halfWidthL );
    360 	for( layerL = 1; layerL < dstPtrA->depthE; layerL++ )
    361 	{
    362 		for( jL = ( heightL >> 1 ); jL > 0; jL-- )
    363 		{
    364 			for( iL = ( halfWidthL >> 1 ); iL > 0; iL-- )
    365 			{
    366 				/* averaging with rounding */
    367 					tmpL = ( ( *srcL & 0x0FF ) + ( *srcL >> 8 ) + ( *( srcL + halfWidthL ) & 0x0FF ) +
    368 							 ( *( srcL + halfWidthL ) >> 8 ) + 2 ) >> 2;
    369 				#ifdef HW_BIG_ENDIAN
    370 					*dstL = tmpL << 8;
    371 				#else
    372 					*dstL = tmpL;
    373 				#endif
    374 				srcL++;
    375 
    376 					tmpL = ( ( *srcL & 0x0FF ) + ( *srcL >> 8 ) + ( *( srcL + halfWidthL ) & 0x0FF ) +
    377 							 ( *( srcL + halfWidthL ) >> 8 ) + 2 ) >> 2;
    378 				#ifdef HW_BIG_ENDIAN
    379 					*dstL |= tmpL;
    380 				#else
    381 					*dstL |= tmpL << 8;
    382 				#endif
    383 				srcL++;
    384 				dstL++;
    385 			}
    386 			srcL += halfWidthL;
    387 		}
    388 		halfWidthL >>= 1;
    389 		heightL >>= 1;
    390 	}
    391 }
    392 
    393 
    394 /* ------------------------------------------------------------------------- */
    395 
    396 
    397 void bim_UInt16BytePyrImage_importUInt16( struct bbs_Context* cpA,
    398 										  struct bim_UInt16BytePyrImage* dstPtrA,
    399 											const struct bim_UInt16ByteImage* srcPtrA,
    400 											uint32 depthA )
    401 {
    402 
    403 	bim_UInt16BytePyrImage_size( cpA, dstPtrA, srcPtrA->widthE, srcPtrA->heightE, depthA );
    404 
    405 	/* copy first layer */
    406 	bbs_memcpy16( dstPtrA->arrE.arrPtrE, srcPtrA->arrE.arrPtrE, srcPtrA->arrE.sizeE );
    407 
    408 	bim_UInt16BytePyrImage_recompute( cpA, dstPtrA );
    409 }
    410 
    411 
    412 /* ------------------------------------------------------------------------- */
    413 
    414 /* ========================================================================= */
    415 
    416 
    417