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