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