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