Changeset 1407 for trunk/psLib/src/image/psImageExtraction.c
- Timestamp:
- Aug 6, 2004, 2:06:06 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/image/psImageExtraction.c (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/image/psImageExtraction.c
r1406 r1407 1 1 2 /** @file psImageExtraction.c 2 3 * … … 9 10 * @author Robert DeSonia, MHPCC 10 11 * 11 * @version $Revision: 1. 7$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-08-0 6 22:34:05$12 * @version $Revision: 1.8 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-07 00:06:06 $ 13 14 * 14 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 22 23 #include "psError.h" 23 24 24 psImage *psImageSubset( psImage *out, psImage *image, unsigned int numCols,25 unsigned int numRows, unsigned int col0,26 unsigned int row0)25 psImage *psImageSubset(psImage * out, 26 psImage * image, 27 unsigned int numCols, unsigned int numRows, unsigned int col0, unsigned int row0) 27 28 { 28 unsigned int elementSize; // size of image element in bytes 29 unsigned int outputRowSize; // output row size in bytes 30 unsigned int inputColOffset; // offset in bytes to first subset pixel in input row 31 32 if ( image == NULL || image->data.V == NULL ) { 33 psError( __func__, "Can not subset image because input image or its pixel buffer is NULL." ); 34 return NULL; 35 } 36 37 if ( image->type.dimen != PS_DIMEN_IMAGE ) { 38 psError( __func__, "Can not subset image because input image is not an image." ); 39 return NULL; 40 } 41 42 if ( numCols < 1 || numRows < 1 ) { 43 psError( __func__, "Can not subset image because number of rows or columns are zero (%dx%d).", 44 numCols, numRows ); 45 return NULL; 46 } 47 48 if ( col0 >= image->numCols || row0 >= image->numRows ) { 49 psError( __func__, "Can not subset image because col0,row0 (%d,%d) is not a valid pixel location.", 50 col0, row0 ); 29 unsigned int elementSize; // size of image 30 31 // element in 32 // bytes 33 unsigned int outputRowSize; // output row 34 35 // size in bytes 36 unsigned int inputColOffset; // offset 37 38 // in 39 // bytes 40 // to 41 // first 42 // subset 43 44 // pixel in input row 45 46 if (image == NULL || image->data.V == NULL) { 47 psError(__func__, "Can not subset image because input image or its pixel buffer is NULL."); 48 return NULL; 49 } 50 51 if (image->type.dimen != PS_DIMEN_IMAGE) { 52 psError(__func__, "Can not subset image because input image is not an image."); 53 return NULL; 54 } 55 56 if (numCols < 1 || numRows < 1) { 57 psError(__func__, 58 "Can not subset image because number of rows or columns are zero (%dx%d).", numCols, numRows); 59 return NULL; 60 } 61 62 if (col0 >= image->numCols || row0 >= image->numRows) { 63 psError(__func__, 64 "Can not subset image because col0,row0 (%d,%d) is not a valid pixel location.", col0, row0); 51 65 return NULL; 52 66 } 53 67 54 68 /* validate subimage size */ 55 if ( col0 + numCols >= image->numCols || row0 + numRows >= image->numRows ) { 56 psError( __func__, "Can not subset image outside of image boundaries (size=%dx%d, " 57 "subset=[%d:%d,%d:%d]).", image->numCols, image->numRows, col0, 58 col0 + numCols, row0, row0 + numRows ); 59 return NULL; 60 } 61 62 63 elementSize = PSELEMTYPE_SIZEOF( image->type.type ); 64 65 out = psImageRecycle( out, numCols, numRows, image->type.type ); 66 67 // set the parent information into the child output image 68 *( int* ) & out->row0 = row0; 69 *( int* ) & out->col0 = col0; 70 *( psImage** ) & out->parent = ( psImage* ) image; 71 72 // add output image as a child of the input image. 69 if (col0 + numCols >= image->numCols || row0 + numRows >= image->numRows) { 70 psError(__func__, 71 "Can not subset image outside of image boundaries (size=%dx%d, " 72 "subset=[%d:%d,%d:%d]).", 73 image->numCols, image->numRows, col0, col0 + numCols, row0, row0 + numRows); 74 return NULL; 75 } 76 77 elementSize = PSELEMTYPE_SIZEOF(image->type.type); 78 79 out = psImageRecycle(out, numCols, numRows, image->type.type); 80 81 // set the parent information into the child 82 // output image 83 *(int *)&out->row0 = row0; 84 *(int *)&out->col0 = col0; 85 *(psImage **) & out->parent = (psImage *) image; 86 87 // add output image as a child of the input 88 // image. 73 89 image->nChildren++; 74 image->children = ( psImage ** ) psRealloc( image->children, 75 image->nChildren * sizeof( psImage* ) ); 76 image->children[ image->nChildren - 1 ] = out; 90 image->children = (psImage **) psRealloc(image->children, image->nChildren * sizeof(psImage *)); 91 image->children[image->nChildren - 1] = out; 77 92 78 93 inputColOffset = elementSize * col0; 79 94 outputRowSize = elementSize * numCols; 80 95 81 for ( int row = 0; row < numRows; row++ ) { 82 memcpy( out->data.V[ row ], image->data.U8[ row0 + row ] + inputColOffset, 83 outputRowSize ); 84 } 85 86 return ( out ); 96 for (int row = 0; row < numRows; row++) { 97 memcpy(out->data.V[row], image->data.U8[row0 + row] + inputColOffset, outputRowSize); 98 } 99 100 return (out); 87 101 } 88 102 89 90 psImage *psImageCopy( psImage* restrict output, const psImage *input, 91 psElemType type ) 103 psImage *psImageCopy(psImage * restrict output, const psImage * input, psElemType type) 92 104 { 93 105 psElemType inDatatype; … … 97 109 int numCols; 98 110 99 if ( input == NULL || input->data.V == NULL ) { 100 psError( __func__, "Can not copy image because input image or its pixel buffer is NULL." ); 101 psFree( output ); 102 return NULL; 103 } 104 105 if ( input == output ) { 106 psError( __func__, "Can not copy image because given input and output " 107 "parameter reference the same psImage struct." ); 108 psFree( output ); 109 return NULL; 110 } 111 112 if ( input->type.dimen != PS_DIMEN_IMAGE ) { 113 psError( __func__, "Can not copy image because input image is not actually an image." ); 114 psFree( output ); 111 if (input == NULL || input->data.V == NULL) { 112 psError(__func__, "Can not copy image because input image or its pixel buffer is NULL."); 113 psFree(output); 114 return NULL; 115 } 116 117 if (input == output) { 118 psError(__func__, 119 "Can not copy image because given input and output " 120 "parameter reference the same psImage struct."); 121 psFree(output); 122 return NULL; 123 } 124 125 if (input->type.dimen != PS_DIMEN_IMAGE) { 126 psError(__func__, "Can not copy image because input image is not actually an image."); 127 psFree(output); 115 128 return NULL; 116 129 } … … 120 133 numCols = input->numCols; 121 134 elements = numRows * numCols; 122 elementSize = PSELEMTYPE_SIZEOF( inDatatype ); 123 124 if ( inDatatype == PS_TYPE_PTR || type == PS_TYPE_PTR ) { 125 psError( __func__, "Can not copy image to/from a void* matrix" ); 126 psFree( output ); 127 return NULL; 128 } 129 130 output = psImageRecycle( output, numCols, numRows, type ); 131 132 // cover the trival case of copy of the same datatype. 133 if ( type == inDatatype ) { 134 memcpy( output->data.V[ 0 ], input->data.V[ 0 ], elementSize * elements ); 135 elementSize = PSELEMTYPE_SIZEOF(inDatatype); 136 137 if (inDatatype == PS_TYPE_PTR || type == PS_TYPE_PTR) { 138 psError(__func__, "Can not copy image to/from a void* matrix"); 139 psFree(output); 140 return NULL; 141 } 142 143 output = psImageRecycle(output, numCols, numRows, type); 144 145 // cover the trival case of copy of the same 146 // datatype. 147 if (type == inDatatype) { 148 memcpy(output->data.V[0], input->data.V[0], elementSize * elements); 135 149 return output; 136 150 } 137 138 151 #define PSIMAGE_ELEMENT_COPY(IN,INTYPE,OUT,OUTTYPE,ELEMENTS) { \ 139 152 ps##INTYPE *in = IN->data.INTYPE[0]; \ … … 186 199 } 187 200 188 switch ( type) {201 switch (type) { 189 202 case PS_TYPE_S8: 190 PSIMAGE_COPY_CASE( output, S8);203 PSIMAGE_COPY_CASE(output, S8); 191 204 break; 192 205 case PS_TYPE_S16: 193 PSIMAGE_COPY_CASE( output, S16);206 PSIMAGE_COPY_CASE(output, S16); 194 207 break; 195 208 case PS_TYPE_S32: 196 PSIMAGE_COPY_CASE( output, S32);209 PSIMAGE_COPY_CASE(output, S32); 197 210 break; 198 211 case PS_TYPE_S64: 199 PSIMAGE_COPY_CASE( output, S64);212 PSIMAGE_COPY_CASE(output, S64); 200 213 break; 201 214 case PS_TYPE_U8: 202 PSIMAGE_COPY_CASE( output, U8);215 PSIMAGE_COPY_CASE(output, U8); 203 216 break; 204 217 case PS_TYPE_U16: 205 PSIMAGE_COPY_CASE( output, U16);218 PSIMAGE_COPY_CASE(output, U16); 206 219 break; 207 220 case PS_TYPE_U32: 208 PSIMAGE_COPY_CASE( output, U32);221 PSIMAGE_COPY_CASE(output, U32); 209 222 break; 210 223 case PS_TYPE_U64: 211 PSIMAGE_COPY_CASE( output, U64);224 PSIMAGE_COPY_CASE(output, U64); 212 225 break; 213 226 case PS_TYPE_F32: 214 PSIMAGE_COPY_CASE( output, F32);227 PSIMAGE_COPY_CASE(output, F32); 215 228 break; 216 229 case PS_TYPE_F64: 217 PSIMAGE_COPY_CASE( output, F64);230 PSIMAGE_COPY_CASE(output, F64); 218 231 break; 219 232 case PS_TYPE_C32: 220 PSIMAGE_COPY_CASE( output, C32);233 PSIMAGE_COPY_CASE(output, C32); 221 234 break; 222 235 case PS_TYPE_C64: 223 PSIMAGE_COPY_CASE( output, C64);236 PSIMAGE_COPY_CASE(output, C64); 224 237 break; 225 238 default: … … 229 242 } 230 243 231 psVector* psImageSlice( psVector* out, 232 psVector* slicePositions, 233 const psImage* restrict in, 234 const psImage* restrict mask, 235 unsigned int maskVal, 236 unsigned int col, 237 unsigned int row, 238 unsigned int numCols, 239 unsigned int numRows, 240 psImageCutDirection direction, 241 const psStats* stats ) 244 psVector *psImageSlice(psVector * out, 245 psVector * slicePositions, 246 const psImage * restrict in, 247 const psImage * restrict mask, 248 unsigned int maskVal, 249 unsigned int col, 250 unsigned int row, 251 unsigned int numCols, 252 unsigned int numRows, psImageCutDirection direction, const psStats * stats) 242 253 { 243 254 double statVal; 244 psStats *myStats;255 psStats *myStats; 245 256 psElemType type; 246 257 int inRows; 247 258 int inCols; 248 259 int delta = 1; 249 psF64* outData; 250 251 if ( in == NULL || in->data.V == NULL ) { 252 psError( __func__, "Input image can not be NULL." ); 253 psFree( out ); 254 return NULL; 255 } 256 257 if ( numRows == 0 || numCols == 0 ) { 258 psError( __func__, "The specified region contains no data (%dx%d)", 259 numCols, numRows ); 260 psFree( out ); 260 psF64 *outData; 261 262 if (in == NULL || in->data.V == NULL) { 263 psError(__func__, "Input image can not be NULL."); 264 psFree(out); 265 return NULL; 266 } 267 268 if (numRows == 0 || numCols == 0) { 269 psError(__func__, "The specified region contains no data (%dx%d)", numCols, numRows); 270 psFree(out); 261 271 return NULL; 262 272 } … … 266 276 inCols = in->numCols; 267 277 268 if ( direction == PS_CUT_X_NEG || direction == PS_CUT_Y_NEG) {278 if (direction == PS_CUT_X_NEG || direction == PS_CUT_Y_NEG) { 269 279 delta = -1; 270 280 } 271 272 // if numRows/numCols is negative, invert the problem to give positive 273 // numRows/numCols (and cut in opposite direction). 274 if ( numRows < 0 ) { 281 // if numRows/numCols is negative, invert the 282 // problem to give positive 283 // numRows/numCols (and cut in opposite 284 // direction). 285 if (numRows < 0) { 275 286 numRows = -numRows; 276 row -= ( numRows - 1);287 row -= (numRows - 1); 277 288 delta = -delta; 278 289 } 279 290 280 if ( numCols < 0) {291 if (numCols < 0) { 281 292 numCols = -numCols; 282 col -= ( numCols - 1);293 col -= (numCols - 1); 283 294 delta = -delta; 284 295 } 285 296 286 if ( mask != NULL) {287 if ( inRows != mask->numRows || inCols != mask->numCols) {288 psError( __func__, "The mask and image dimensions did not match (%dx%d vs %dx%d)",289 mask->numCols, mask->numRows, in->numCols, in->numRows );290 psFree( out);291 }292 if ( mask->type.type != PS_TYPE_MASK ) {293 psError( __func__, "The mask datatype (%d) must be %s.",294 mask->type.type, PS_TYPE_MASK_NAME);295 psFree( out);296 } 297 } 298 299 if ( row >= inRows || col >= inCols ||300 col + numCols > in->numCols || row + numRows > in->numRows ) {301 psError( __func__,"The specified image region (%d,%d to %d,%d) is outside of image area (0,0 to %d,%d).",302 col, row, col + numCols - 1, row + numRows - 1, in->numCols - 1, in->numRows - 1);303 psFree( out);304 return NULL; 305 } 306 307 // verify that the stats struct specifies asingle stats operation308 if ( stats == NULL || p_psGetStatValue( stats, &statVal ) == false) {309 psError( __func__, "The stat options didn't specify a single supported statistic type.");310 psFree( out);311 return NULL; 312 } 313 314 // since stats input is const, I need tocreate a 'scratch' stats struct315 myStats = psAlloc( sizeof( psStats ));297 if (mask != NULL) { 298 if (inRows != mask->numRows || inCols != mask->numCols) { 299 psError(__func__, 300 "The mask and image dimensions did not match (%dx%d vs %dx%d)", 301 mask->numCols, mask->numRows, in->numCols, in->numRows); 302 psFree(out); 303 } 304 if (mask->type.type != PS_TYPE_MASK) { 305 psError(__func__, "The mask datatype (%d) must be %s.", mask->type.type, PS_TYPE_MASK_NAME); 306 psFree(out); 307 } 308 } 309 310 if (row >= inRows || col >= inCols || col + numCols > in->numCols || row + numRows > in->numRows) { 311 psError(__func__, 312 "The specified image region (%d,%d to %d,%d) is outside of image area (0,0 to %d,%d).", 313 col, row, col + numCols - 1, row + numRows - 1, in->numCols - 1, in->numRows - 1); 314 psFree(out); 315 return NULL; 316 } 317 // verify that the stats struct specifies a 318 // single stats operation 319 if (stats == NULL || p_psGetStatValue(stats, &statVal) == false) { 320 psError(__func__, "The stat options didn't specify a single supported statistic type."); 321 psFree(out); 322 return NULL; 323 } 324 // since stats input is const, I need to 325 // create a 'scratch' stats struct 326 myStats = psAlloc(sizeof(psStats)); 316 327 *myStats = *stats; 317 328 318 319 320 if ( direction == PS_CUT_X_POS || direction == PS_CUT_X_NEG ) { 321 psVector * imgVec = psVectorAlloc( numRows, type ); 322 psVector* maskVec = NULL; 323 psMaskType* maskData = NULL; 324 psU32* outPosition = NULL; 325 326 // recycle output to make a proper sized/type output structure 327 // n.b. type is double as that is the type given for all stats in psStats. 328 out = psVectorRecycle( out, numCols, PS_TYPE_F64); 329 if (direction == PS_CUT_X_POS || direction == PS_CUT_X_NEG) { 330 psVector *imgVec = psVectorAlloc(numRows, type); 331 psVector *maskVec = NULL; 332 psMaskType *maskData = NULL; 333 psU32 *outPosition = NULL; 334 335 // recycle output to make a proper 336 // sized/type output structure 337 // n.b. type is double as that is the 338 // type given for all stats in 339 // psStats. 340 out = psVectorRecycle(out, numCols, PS_TYPE_F64); 329 341 if (slicePositions != NULL) { 330 slicePositions = psVectorRecycle(slicePositions, numCols,PS_TYPE_U32);342 slicePositions = psVectorRecycle(slicePositions, numCols, PS_TYPE_U32); 331 343 outPosition = slicePositions->data.U32; 332 344 } 333 345 outData = out->data.F64; 334 if ( delta < 0) {346 if (delta < 0) { 335 347 outData += numCols - 1; 336 348 if (outPosition != NULL) { … … 339 351 } 340 352 341 if ( mask != NULL ) { 342 maskVec = psVectorAlloc( numRows, mask->type.type ); 343 } 344 353 if (mask != NULL) { 354 maskVec = psVectorAlloc(numRows, mask->type.type); 355 } 345 356 #define PSIMAGE_CUT_VERTICAL(TYPE) \ 346 357 case PS_TYPE_##TYPE: { \ … … 373 384 } 374 385 375 switch ( type) {376 PSIMAGE_CUT_VERTICAL( U8);377 PSIMAGE_CUT_VERTICAL( U16);378 PSIMAGE_CUT_VERTICAL( U32);379 PSIMAGE_CUT_VERTICAL( U64);380 PSIMAGE_CUT_VERTICAL( S8);381 PSIMAGE_CUT_VERTICAL( S16);382 PSIMAGE_CUT_VERTICAL( S32);383 PSIMAGE_CUT_VERTICAL( S64);384 PSIMAGE_CUT_VERTICAL( F32);385 PSIMAGE_CUT_VERTICAL( F64);386 PSIMAGE_CUT_VERTICAL( C32);387 PSIMAGE_CUT_VERTICAL( C64);386 switch (type) { 387 PSIMAGE_CUT_VERTICAL(U8); 388 PSIMAGE_CUT_VERTICAL(U16); 389 PSIMAGE_CUT_VERTICAL(U32); 390 PSIMAGE_CUT_VERTICAL(U64); 391 PSIMAGE_CUT_VERTICAL(S8); 392 PSIMAGE_CUT_VERTICAL(S16); 393 PSIMAGE_CUT_VERTICAL(S32); 394 PSIMAGE_CUT_VERTICAL(S64); 395 PSIMAGE_CUT_VERTICAL(F32); 396 PSIMAGE_CUT_VERTICAL(F64); 397 PSIMAGE_CUT_VERTICAL(C32); 398 PSIMAGE_CUT_VERTICAL(C64); 388 399 default: 389 psError( __func__, "Unsupported datatype (%d)", type);390 psFree( out);400 psError(__func__, "Unsupported datatype (%d)", type); 401 psFree(out); 391 402 out = NULL; 392 403 } 393 psFree( imgVec ); 394 psFree( maskVec ); 395 } else 396 if ( direction == PS_CUT_Y_POS || direction == PS_CUT_Y_NEG ) { // Cut in Y direction 397 psVector * imgVec = NULL; 398 psVector* maskVec = NULL; 399 int elementSize = PSELEMTYPE_SIZEOF( type ); 400 psU32* outPosition = NULL; 401 402 // fill in psVectors to fake out the statistics functions. 403 imgVec = psAlloc( sizeof( psVector ) ); 404 imgVec->type = in->type; 405 imgVec->n = imgVec->nalloc = numCols; 406 if ( mask != NULL ) { 407 maskVec = psAlloc( sizeof( psVector ) ); 408 maskVec->type = mask->type; 409 maskVec->n = maskVec->nalloc = numCols; 404 psFree(imgVec); 405 psFree(maskVec); 406 } else if (direction == PS_CUT_Y_POS || direction == PS_CUT_Y_NEG) { // Cut 407 // 408 // 409 // 410 // 411 // 412 // 413 // 414 // 415 // 416 // in 417 // Y 418 // direction 419 psVector *imgVec = NULL; 420 psVector *maskVec = NULL; 421 int elementSize = PSELEMTYPE_SIZEOF(type); 422 psU32 *outPosition = NULL; 423 424 // fill in psVectors to fake out the 425 // statistics functions. 426 imgVec = psAlloc(sizeof(psVector)); 427 imgVec->type = in->type; 428 imgVec->n = imgVec->nalloc = numCols; 429 if (mask != NULL) { 430 maskVec = psAlloc(sizeof(psVector)); 431 maskVec->type = mask->type; 432 maskVec->n = maskVec->nalloc = numCols; 433 } 434 // recycle output to make a proper 435 // sized/type output structure 436 // n.b. type is double as that is the 437 // type given for all stats in 438 // psStats. 439 out = psVectorRecycle(out, numRows, PS_TYPE_F64); 440 if (slicePositions != NULL) { 441 slicePositions = psVectorRecycle(slicePositions, numRows, PS_TYPE_U32); 442 outPosition = slicePositions->data.U32; 443 } 444 outData = out->data.F64; 445 if (delta < 0) { 446 outData += numRows - 1; 447 if (outPosition != NULL) { 448 outPosition += numRows - 1; 410 449 } 411 412 // recycle output to make a proper sized/type output structure 413 // n.b. type is double as that is the type given for all stats in psStats. 414 out = psVectorRecycle( out, numRows, PS_TYPE_F64 ); 415 if (slicePositions != NULL) { 416 slicePositions = psVectorRecycle(slicePositions,numRows,PS_TYPE_U32); 417 outPosition = slicePositions->data.U32; 450 } 451 452 for (int r = 0; r < numRows; r++) { 453 // point the vector struct to the 454 // data to calculate the stats 455 imgVec->data.V = (void *)(in->data.U8[row + r] + col * elementSize); 456 if (maskVec != NULL) { 457 maskVec->data.V = (void *)(mask->data.U8[row + r] + col * sizeof(psMaskType)); 418 458 } 419 outData = out->data.F64; 420 if ( delta < 0 ) { 421 outData += numRows - 1; 422 if (outPosition != NULL) { 423 outPosition += numRows - 1; 424 } 459 myStats = psVectorStats(myStats, imgVec, maskVec, maskVal); 460 (void)p_psGetStatValue(myStats, &statVal); // we 461 // know 462 // it 463 // works 464 // cause we tested it 465 // above 466 *outData = statVal; 467 if (outPosition != NULL) { 468 *outPosition = row + r; 469 outPosition += delta; 470 425 471 } 426 427 for ( int r = 0;r < numRows;r++ ) { 428 // point the vector struct to the data to calculate the stats 429 imgVec->data.V = ( void* ) ( in->data.U8[ row + r ] + col * elementSize ); 430 if ( maskVec != NULL ) { 431 maskVec->data.V = ( void* ) ( mask->data.U8[ row + r ] + col * sizeof( psMaskType ) ); 432 } 433 myStats = psVectorStats( myStats, imgVec, maskVec, maskVal ); 434 ( void ) p_psGetStatValue( myStats, &statVal ); // we know it works cause we tested it above 435 *outData = statVal; 436 if (outPosition != NULL) { 437 *outPosition = row+r; 438 outPosition += delta; 439 \ 440 } 441 outData += delta; 442 } 443 psFree( imgVec ); 444 psFree( maskVec ); 445 } else { // don't know what the direction flag is 446 psError( __func__, "Invalid direction flag (%d)", direction ); 447 psFree( out ); 448 out = NULL; 449 } 450 451 psFree( myStats ); 472 outData += delta; 473 } 474 psFree(imgVec); 475 psFree(maskVec); 476 } else { // don't 477 // know 478 // what 479 // the 480 // direction 481 // flag 482 // is 483 psError(__func__, "Invalid direction flag (%d)", direction); 484 psFree(out); 485 out = NULL; 486 } 487 488 psFree(myStats); 452 489 453 490 return out; 454 491 } 455
Note:
See TracChangeset
for help on using the changeset viewer.
