Changeset 1385 for trunk/psLib/src/image
- Timestamp:
- Aug 4, 2004, 1:37:39 PM (22 years ago)
- Location:
- trunk/psLib/src/image
- Files:
-
- 6 edited
-
psImage.c (modified) (1 diff)
-
psImage.h (modified) (1 diff)
-
psImageExtraction.c (modified) (9 diffs)
-
psImageIO.c (modified) (2 diffs)
-
psImageManip.c (modified) (2 diffs)
-
psImageStats.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/image/psImage.c
r1263 r1385 9 9 * @author Ross Harman, MHPCC 10 10 * 11 * @version $Revision: 1.3 5$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-0 7-22 20:42:22$11 * @version $Revision: 1.36 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-08-04 23:37:39 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/image/psImage.h
r1263 r1385 11 11 * @author Ross Harman, MHPCC 12 12 * 13 * @version $Revision: 1.2 5$ $Name: not supported by cvs2svn $14 * @date $Date: 2004-0 7-22 20:42:22$13 * @version $Revision: 1.26 $ $Name: not supported by cvs2svn $ 14 * @date $Date: 2004-08-04 23:37:39 $ 15 15 * 16 16 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii -
trunk/psLib/src/image/psImageExtraction.c
r1374 r1385 9 9 * @author Robert DeSonia, MHPCC 10 10 * 11 * @version $Revision: 1. 4$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-08-04 00:55:17$11 * @version $Revision: 1.5 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-08-04 23:37:39 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 29 29 unsigned int outputRowSize; // output row size in bytes 30 30 unsigned int inputColOffset; // offset in bytes to first subset pixel in input row 31 31 32 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 33 psError( __func__, "Can not subset image because input image or its pixel buffer is NULL." ); 34 return NULL; 35 } 36 37 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 38 psError( __func__, "Can not subset image because input image is not an image." ); 39 return NULL; 40 } 41 42 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 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 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 );51 return NULL;52 }53 49 psError( __func__, "Can not subset image because col0,row0 (%d,%d) is not a valid pixel location.", 50 col0, row0 ); 51 return NULL; 52 } 53 54 54 /* validate subimage size */ 55 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 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 63 elementSize = PSELEMTYPE_SIZEOF( image->type.type ); 64 64 65 65 out = psImageRecycle( out, numCols, numRows, image->type.type ); 66 66 67 67 // set the parent information into the child output image 68 68 *( int* ) & out->row0 = row0; 69 69 *( int* ) & out->col0 = col0; 70 70 *( psImage** ) & out->parent = ( psImage* ) image; 71 71 72 72 // add output image as a child of the input image. 73 73 image->nChildren++; … … 75 75 image->nChildren * sizeof( psImage* ) ); 76 76 image->children[ image->nChildren - 1 ] = out; 77 77 78 78 inputColOffset = elementSize * col0; 79 79 outputRowSize = elementSize * numCols; 80 80 81 81 for ( int row = 0; row < numRows; row++ ) { 82 memcpy( out->data.V[ row ], image->data.U8[ row0 + row ] + inputColOffset,83 outputRowSize );84 }85 82 memcpy( out->data.V[ row ], image->data.U8[ row0 + row ] + inputColOffset, 83 outputRowSize ); 84 } 85 86 86 return ( out ); 87 87 } … … 96 96 int numRows; 97 97 int numCols; 98 98 99 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 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 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 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 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 );115 return NULL;116 }117 113 psError( __func__, "Can not copy image because input image is not actually an image." ); 114 psFree( output ); 115 return NULL; 116 } 117 118 118 inDatatype = input->type.type; 119 119 numRows = input->numRows; … … 121 121 elements = numRows * numCols; 122 122 elementSize = PSELEMTYPE_SIZEOF( inDatatype ); 123 123 124 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 125 psError( __func__, "Can not copy image to/from a void* matrix" ); 126 psFree( output ); 127 return NULL; 128 } 129 130 130 output = psImageRecycle( output, numCols, numRows, type ); 131 131 132 132 // cover the trival case of copy of the same datatype. 133 133 if ( type == inDatatype ) { 134 memcpy( output->data.V[ 0 ], input->data.V[ 0 ], elementSize * elements );135 return output;136 }137 134 memcpy( output->data.V[ 0 ], input->data.V[ 0 ], elementSize * elements ); 135 return output; 136 } 137 138 138 #define PSIMAGE_ELEMENT_COPY(IN,INTYPE,OUT,OUTTYPE,ELEMENTS) { \ 139 139 ps##INTYPE *in = IN->data.INTYPE[0]; \ 140 140 ps##OUTTYPE *out = OUT->data.OUTTYPE[0]; \ 141 141 for (int e=0;e<ELEMENTS;e++) { \ 142 *(out++) = *(in++); \143 } \144 } 145 142 *(out++) = *(in++); \ 143 } \ 144 } 145 146 146 #define PSIMAGE_COPY_CASE(OUT,OUTTYPE) \ 147 147 switch (inDatatype) { \ 148 case PS_TYPE_S8: \149 PSIMAGE_ELEMENT_COPY(input,S8,OUT,OUTTYPE,elements); \150 break; \151 case PS_TYPE_S16: \152 PSIMAGE_ELEMENT_COPY(input,S16,OUT,OUTTYPE,elements); \153 break; \154 case PS_TYPE_S32: \155 PSIMAGE_ELEMENT_COPY(input,S32,OUT,OUTTYPE,elements); \156 break; \157 case PS_TYPE_S64: \158 PSIMAGE_ELEMENT_COPY(input,S64,OUT,OUTTYPE,elements); \159 break; \160 case PS_TYPE_U8: \161 PSIMAGE_ELEMENT_COPY(input,U8,OUT,OUTTYPE,elements); \162 break; \163 case PS_TYPE_U16: \164 PSIMAGE_ELEMENT_COPY(input,U16,OUT,OUTTYPE,elements); \165 break; \166 case PS_TYPE_U32: \167 PSIMAGE_ELEMENT_COPY(input,U32,OUT,OUTTYPE,elements); \168 break; \169 case PS_TYPE_U64: \170 PSIMAGE_ELEMENT_COPY(input,U64,OUT,OUTTYPE,elements); \171 break; \172 case PS_TYPE_F32: \173 PSIMAGE_ELEMENT_COPY(input,F32,OUT,OUTTYPE,elements); \174 break; \175 case PS_TYPE_F64: \176 PSIMAGE_ELEMENT_COPY(input,F64,OUT,OUTTYPE,elements); \177 break; \178 case PS_TYPE_C32: \179 PSIMAGE_ELEMENT_COPY(input,C32,OUT,OUTTYPE,elements); \180 break; \181 case PS_TYPE_C64: \182 PSIMAGE_ELEMENT_COPY(input,C64,OUT,OUTTYPE,elements); \183 break; \184 default: \185 break; \186 }187 148 case PS_TYPE_S8: \ 149 PSIMAGE_ELEMENT_COPY(input,S8,OUT,OUTTYPE,elements); \ 150 break; \ 151 case PS_TYPE_S16: \ 152 PSIMAGE_ELEMENT_COPY(input,S16,OUT,OUTTYPE,elements); \ 153 break; \ 154 case PS_TYPE_S32: \ 155 PSIMAGE_ELEMENT_COPY(input,S32,OUT,OUTTYPE,elements); \ 156 break; \ 157 case PS_TYPE_S64: \ 158 PSIMAGE_ELEMENT_COPY(input,S64,OUT,OUTTYPE,elements); \ 159 break; \ 160 case PS_TYPE_U8: \ 161 PSIMAGE_ELEMENT_COPY(input,U8,OUT,OUTTYPE,elements); \ 162 break; \ 163 case PS_TYPE_U16: \ 164 PSIMAGE_ELEMENT_COPY(input,U16,OUT,OUTTYPE,elements); \ 165 break; \ 166 case PS_TYPE_U32: \ 167 PSIMAGE_ELEMENT_COPY(input,U32,OUT,OUTTYPE,elements); \ 168 break; \ 169 case PS_TYPE_U64: \ 170 PSIMAGE_ELEMENT_COPY(input,U64,OUT,OUTTYPE,elements); \ 171 break; \ 172 case PS_TYPE_F32: \ 173 PSIMAGE_ELEMENT_COPY(input,F32,OUT,OUTTYPE,elements); \ 174 break; \ 175 case PS_TYPE_F64: \ 176 PSIMAGE_ELEMENT_COPY(input,F64,OUT,OUTTYPE,elements); \ 177 break; \ 178 case PS_TYPE_C32: \ 179 PSIMAGE_ELEMENT_COPY(input,C32,OUT,OUTTYPE,elements); \ 180 break; \ 181 case PS_TYPE_C64: \ 182 PSIMAGE_ELEMENT_COPY(input,C64,OUT,OUTTYPE,elements); \ 183 break; \ 184 default: \ 185 break; \ 186 } 187 188 188 switch ( type ) { 189 case PS_TYPE_S8:190 PSIMAGE_COPY_CASE( output, S8 );191 break;192 case PS_TYPE_S16:193 PSIMAGE_COPY_CASE( output, S16 );194 break;195 case PS_TYPE_S32:196 PSIMAGE_COPY_CASE( output, S32 );197 break;198 case PS_TYPE_S64:199 PSIMAGE_COPY_CASE( output, S64 );200 break;201 case PS_TYPE_U8:202 PSIMAGE_COPY_CASE( output, U8 );203 break;204 case PS_TYPE_U16:205 PSIMAGE_COPY_CASE( output, U16 );206 break;207 case PS_TYPE_U32:208 PSIMAGE_COPY_CASE( output, U32 );209 break;210 case PS_TYPE_U64:211 PSIMAGE_COPY_CASE( output, U64 );212 break;213 case PS_TYPE_F32:214 PSIMAGE_COPY_CASE( output, F32 );215 break;216 case PS_TYPE_F64:217 PSIMAGE_COPY_CASE( output, F64 );218 break;219 case PS_TYPE_C32:220 PSIMAGE_COPY_CASE( output, C32 );221 break;222 case PS_TYPE_C64:223 PSIMAGE_COPY_CASE( output, C64 );224 break;225 default:226 break;227 }189 case PS_TYPE_S8: 190 PSIMAGE_COPY_CASE( output, S8 ); 191 break; 192 case PS_TYPE_S16: 193 PSIMAGE_COPY_CASE( output, S16 ); 194 break; 195 case PS_TYPE_S32: 196 PSIMAGE_COPY_CASE( output, S32 ); 197 break; 198 case PS_TYPE_S64: 199 PSIMAGE_COPY_CASE( output, S64 ); 200 break; 201 case PS_TYPE_U8: 202 PSIMAGE_COPY_CASE( output, U8 ); 203 break; 204 case PS_TYPE_U16: 205 PSIMAGE_COPY_CASE( output, U16 ); 206 break; 207 case PS_TYPE_U32: 208 PSIMAGE_COPY_CASE( output, U32 ); 209 break; 210 case PS_TYPE_U64: 211 PSIMAGE_COPY_CASE( output, U64 ); 212 break; 213 case PS_TYPE_F32: 214 PSIMAGE_COPY_CASE( output, F32 ); 215 break; 216 case PS_TYPE_F64: 217 PSIMAGE_COPY_CASE( output, F64 ); 218 break; 219 case PS_TYPE_C32: 220 PSIMAGE_COPY_CASE( output, C32 ); 221 break; 222 case PS_TYPE_C64: 223 PSIMAGE_COPY_CASE( output, C64 ); 224 break; 225 default: 226 break; 227 } 228 228 return output; 229 229 } … … 247 247 int delta = 1; 248 248 psF64* outData; 249 249 250 250 if ( in == NULL || in->data.V == NULL ) { 251 psError( __func__, "Input image can not be NULL." );252 psFree( out );253 return NULL;254 }255 251 psError( __func__, "Input image can not be NULL." ); 252 psFree( out ); 253 return NULL; 254 } 255 256 256 if ( numRows == 0 || numCols == 0 ) { 257 psError( __func__, "The specified region contains no data (%dx%d)",258 numCols, numRows );259 psFree( out );260 return NULL;261 }262 257 psError( __func__, "The specified region contains no data (%dx%d)", 258 numCols, numRows ); 259 psFree( out ); 260 return NULL; 261 } 262 263 263 type = in->type.type; 264 264 inRows = in->numRows; 265 265 inCols = in->numCols; 266 266 267 267 if ( direction == PS_CUT_X_NEG || direction == PS_CUT_Y_NEG ) { 268 delta = -1;269 }270 268 delta = -1; 269 } 270 271 271 // if numRows/numCols is negative, invert the problem to give positive 272 272 // numRows/numCols (and cut in opposite direction). 273 273 if ( numRows < 0 ) { 274 numRows = -numRows;275 row -= ( numRows - 1 );276 delta = -delta;277 }278 274 numRows = -numRows; 275 row -= ( numRows - 1 ); 276 delta = -delta; 277 } 278 279 279 if ( numCols < 0 ) { 280 numCols = -numCols;281 col -= ( numCols - 1 );282 delta = -delta;283 }284 280 numCols = -numCols; 281 col -= ( numCols - 1 ); 282 delta = -delta; 283 } 284 285 285 if ( mask != NULL ) { 286 if ( inRows != mask->numRows || inCols != mask->numCols ) {287 psError( __func__, "The mask and image dimensions did not match (%dx%d vs %dx%d)",288 mask->numCols, mask->numRows, in->numCols, in->numRows );289 psFree( out );290 }291 if ( mask->type.type != PS_TYPE_MASK ) {292 psError( __func__, "The mask datatype (%d) must be %s.",293 mask->type.type, PS_TYPE_MASK_NAME );294 psFree( out );295 }296 }297 286 if ( inRows != mask->numRows || inCols != mask->numCols ) { 287 psError( __func__, "The mask and image dimensions did not match (%dx%d vs %dx%d)", 288 mask->numCols, mask->numRows, in->numCols, in->numRows ); 289 psFree( out ); 290 } 291 if ( mask->type.type != PS_TYPE_MASK ) { 292 psError( __func__, "The mask datatype (%d) must be %s.", 293 mask->type.type, PS_TYPE_MASK_NAME ); 294 psFree( out ); 295 } 296 } 297 298 298 if ( row >= inRows || col >= inCols || 299 299 col + numCols > in->numCols || row + numRows > in->numRows ) { 300 psError( __func__, "The specified image region (%d,%d to %d,%d) is outside of image area (0,0 to %d,%d).",301 col, row, col + numCols - 1, row + numRows - 1, in->numCols - 1, in->numRows - 1 );302 psFree( out );303 return NULL;304 }305 300 psError( __func__, "The specified image region (%d,%d to %d,%d) is outside of image area (0,0 to %d,%d).", 301 col, row, col + numCols - 1, row + numRows - 1, in->numCols - 1, in->numRows - 1 ); 302 psFree( out ); 303 return NULL; 304 } 305 306 306 // verify that the stats struct specifies a single stats operation 307 307 if ( stats == NULL || p_psGetStatValue( stats, &statVal ) == false ) { 308 psError( __func__, "The stat options didn't specify a single supported statistic type." );309 psFree( out );310 return NULL;311 }312 308 psError( __func__, "The stat options didn't specify a single supported statistic type." ); 309 psFree( out ); 310 return NULL; 311 } 312 313 313 // since stats input is const, I need to create a 'scratch' stats struct 314 314 myStats = psAlloc( sizeof( psStats ) ); 315 315 *myStats = *stats; 316 317 318 316 317 318 319 319 if ( direction == PS_CUT_X_POS || direction == PS_CUT_X_NEG ) { 320 psVector * imgVec = psVectorAlloc( numRows, type ); 321 psVector* maskVec = NULL; 322 psMaskType* maskData = NULL; 323 324 // recycle output to make a proper sized/type output structure 325 // n.b. type is double as that is the type given for all stats in psStats. 326 out = psVectorRecycle( out, PS_TYPE_F64, numCols ); 327 outData = out->data.F64; 328 if ( delta < 0 ) { 329 outData += numCols - 1; 330 } 331 332 if ( mask != NULL ) { 333 maskVec = psVectorAlloc( numRows, mask->type.type ); 334 } 335 336 #define PSIMAGE_CUT_VERTICAL(TYPE) \ 337 case PS_TYPE_##TYPE: { \ 338 psMaskType* maskVecData = NULL; \ 339 for (int c=0;c<numCols;c++) { \ 340 ps##TYPE *imgData = in->data.TYPE[row] + col + c; \ 341 ps##TYPE *imgVecData = imgVec->data.TYPE; \ 342 if (maskVec != NULL) { \ 343 maskVecData = maskVec->data.V; \ 344 maskData = (psMaskType*)(mask->data.V[row]) + col + c; \ 345 } \ 346 for (int r=0;r<numRows;r++) { \ 347 *(imgVecData++) = *imgData; \ 348 imgData += inCols; \ 349 if (maskVecData != NULL) { \ 350 *(maskVecData++) = *maskData; \ 351 maskData += inCols; \ 352 } \ 353 } \ 354 myStats = psVectorStats(myStats,imgVec,maskVec,maskVal); \ 355 (void)p_psGetStatValue(myStats,&statVal); \ 356 *outData = statVal; \ 357 outData += delta; \ 320 psVector * imgVec = psVectorAlloc( numRows, type ); 321 psVector* maskVec = NULL; 322 psMaskType* maskData = NULL; 323 324 // recycle output to make a proper sized/type output structure 325 // n.b. type is double as that is the type given for all stats in psStats. 326 out = psVectorRecycle( out, PS_TYPE_F64, numCols ); 327 outData = out->data.F64; 328 if ( delta < 0 ) { 329 outData += numCols - 1; 330 } 331 332 if ( mask != NULL ) { 333 maskVec = psVectorAlloc( numRows, mask->type.type ); 334 } 335 336 #define PSIMAGE_CUT_VERTICAL(TYPE) \ 337 case PS_TYPE_##TYPE: { \ 338 psMaskType* maskVecData = NULL; \ 339 for (int c=0;c<numCols;c++) { \ 340 ps##TYPE *imgData = in->data.TYPE[row] + col + c; \ 341 ps##TYPE *imgVecData = imgVec->data.TYPE; \ 342 if (maskVec != NULL) { \ 343 maskVecData = maskVec->data.V; \ 344 maskData = (psMaskType*)(mask->data.V[row]) + col + c; \ 345 } \ 346 for (int r=0;r<numRows;r++) { \ 347 *(imgVecData++) = *imgData; \ 348 imgData += inCols; \ 349 if (maskVecData != NULL) { \ 350 *(maskVecData++) = *maskData; \ 351 maskData += inCols; \ 358 352 } \ 359 break; \ 360 } 361 362 switch ( type ) { 363 PSIMAGE_CUT_VERTICAL( U8 ); 364 PSIMAGE_CUT_VERTICAL( U16 ); 365 PSIMAGE_CUT_VERTICAL( U32 ); 366 PSIMAGE_CUT_VERTICAL( U64 ); 367 PSIMAGE_CUT_VERTICAL( S8 ); 368 PSIMAGE_CUT_VERTICAL( S16 ); 369 PSIMAGE_CUT_VERTICAL( S32 ); 370 PSIMAGE_CUT_VERTICAL( S64 ); 371 PSIMAGE_CUT_VERTICAL( F32 ); 372 PSIMAGE_CUT_VERTICAL( F64 ); 373 PSIMAGE_CUT_VERTICAL( C32 ); 374 PSIMAGE_CUT_VERTICAL( C64 ); 375 default: 376 psError( __func__, "Unsupported datatype (%d)", type ); 377 psFree( out ); 378 out = NULL; 379 } 380 psFree( imgVec ); 381 psFree( maskVec ); 382 } else if ( direction == PS_CUT_Y_POS || direction == PS_CUT_Y_NEG ) { // Cut in Y direction 353 } \ 354 myStats = psVectorStats(myStats,imgVec,maskVec,maskVal); \ 355 (void)p_psGetStatValue(myStats,&statVal); \ 356 *outData = statVal; \ 357 outData += delta; \ 358 } \ 359 break; \ 360 } 361 362 switch ( type ) { 363 PSIMAGE_CUT_VERTICAL( U8 ); 364 PSIMAGE_CUT_VERTICAL( U16 ); 365 PSIMAGE_CUT_VERTICAL( U32 ); 366 PSIMAGE_CUT_VERTICAL( U64 ); 367 PSIMAGE_CUT_VERTICAL( S8 ); 368 PSIMAGE_CUT_VERTICAL( S16 ); 369 PSIMAGE_CUT_VERTICAL( S32 ); 370 PSIMAGE_CUT_VERTICAL( S64 ); 371 PSIMAGE_CUT_VERTICAL( F32 ); 372 PSIMAGE_CUT_VERTICAL( F64 ); 373 PSIMAGE_CUT_VERTICAL( C32 ); 374 PSIMAGE_CUT_VERTICAL( C64 ); 375 default: 376 psError( __func__, "Unsupported datatype (%d)", type ); 377 psFree( out ); 378 out = NULL; 379 } 380 psFree( imgVec ); 381 psFree( maskVec ); 382 } else 383 if ( direction == PS_CUT_Y_POS || direction == PS_CUT_Y_NEG ) { // Cut in Y direction 383 384 psVector * imgVec = NULL; 384 385 psVector* maskVec = NULL; 385 386 int elementSize = PSELEMTYPE_SIZEOF( type ); 386 387 387 388 // fill in psVectors to fake out the statistics functions. 388 389 imgVec = psAlloc( sizeof( psVector ) ); … … 390 391 imgVec->n = imgVec->nalloc = numCols; 391 392 if ( mask != NULL ) { 392 maskVec = psAlloc( sizeof( psVector ) );393 maskVec->type = mask->type;394 maskVec->n = maskVec->nalloc = numCols;395 }396 393 maskVec = psAlloc( sizeof( psVector ) ); 394 maskVec->type = mask->type; 395 maskVec->n = maskVec->nalloc = numCols; 396 } 397 397 398 // recycle output to make a proper sized/type output structure 398 399 // n.b. type is double as that is the type given for all stats in psStats. … … 400 401 outData = out->data.F64; 401 402 if ( delta < 0 ) { 402 outData += numRows - 1; 403 outData += numRows - 1; 404 } 405 406 for ( int r = 0;r < numRows;r++ ) { 407 // point the vector struct to the data to calculate the stats 408 imgVec->data.V = ( void* ) ( in->data.U8[ row + r ] + col * elementSize ); 409 if ( maskVec != NULL ) { 410 maskVec->data.V = ( void* ) ( mask->data.U8[ row + r ] + col * sizeof( psMaskType ) ); 403 411 } 404 405 for ( int r = 0;r < numRows;r++ ) { 406 // point the vector struct to the data to calculate the stats 407 imgVec->data.V = ( void* ) ( in->data.U8[ row + r ] + col * elementSize ); 408 if ( maskVec != NULL ) { 409 maskVec->data.V = ( void* ) ( mask->data.U8[ row + r ] + col * sizeof( psMaskType ) ); 410 } 411 myStats = psVectorStats( myStats, imgVec, maskVec, maskVal ); 412 ( void ) p_psGetStatValue( myStats, &statVal ); // we know it works cause we tested it above 413 *outData = statVal; 414 outData += delta; 415 } 412 myStats = psVectorStats( myStats, imgVec, maskVec, maskVal ); 413 ( void ) p_psGetStatValue( myStats, &statVal ); // we know it works cause we tested it above 414 *outData = statVal; 415 outData += delta; 416 } 416 417 psFree( imgVec ); 417 418 psFree( maskVec ); … … 421 422 out = NULL; 422 423 } 423 424 424 425 psFree( myStats ); 425 426 426 427 return out; 427 428 } -
trunk/psLib/src/image/psImageIO.c
r1301 r1385 7 7 * @author Robert DeSonia, MHPCC 8 8 * 9 * @version $Revision: 1. 6$ $Name: not supported by cvs2svn $10 * @date $Date: 2004-0 7-27 23:09:23$9 * @version $Revision: 1.7 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2004-08-04 23:37:39 $ 11 11 * 12 12 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 303 303 extnum, numHDUs); 304 304 return false; 305 } else if (numHDUs == extnum) { 306 createNewHDU = true; 307 } else if (fits_movabs_hdu(fptr, extnum+1, &hduType, &status) != 0) { 308 fits_get_errstatus(status, fitsErr); 309 status = 0; 310 (void)fits_close_file(fptr, &status); 311 psError(__func__,"Could not index to HDU #%d for file %s. (%s)", 312 extnum, filename, fitsErr); 313 return false; 314 } 305 } else 306 if (numHDUs == extnum) { 307 createNewHDU = true; 308 } else 309 if (fits_movabs_hdu(fptr, extnum+1, &hduType, &status) != 0) { 310 fits_get_errstatus(status, fitsErr); 311 status = 0; 312 (void)fits_close_file(fptr, &status); 313 psError(__func__,"Could not index to HDU #%d for file %s. (%s)", 314 extnum, filename, fitsErr); 315 return false; 316 } 315 317 } 316 318 -
trunk/psLib/src/image/psImageManip.c
r1319 r1385 10 10 * @author Ross Harman, MHPCC 11 11 * 12 * @version $Revision: 1. 8$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-0 7-29 01:20:10$12 * @version $Revision: 1.9 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2004-08-04 23:37:39 $ 14 14 * 15 15 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 582 582 return NULL; 583 583 } 584 } else if (fabsf(angle-180.0f) < FLT_EPSILON) { 585 // perform 1/2 rotate 586 int numRows = in->numRows; 587 int lastRow = numRows - 1; 588 int numCols = in->numCols; 589 int lastCol = numCols - 1; 590 psElemType type = in->type.type; 591 out = psImageRecycle(out,numCols,numRows,type); 592 593 #define PSIMAGE_ROTATE_180_CASE(TYPE) \ 594 case PS_TYPE_##TYPE: { \ 595 for (int row=0;row<numRows;row++) { \ 596 ps##TYPE* outRow = out->data.TYPE[row]; \ 597 ps##TYPE* inRow = in->data.TYPE[lastRow-row]; \ 598 for (int col=0;col<numCols;col++) { \ 599 outRow[col] = inRow[lastCol - col]; \ 584 } else 585 if (fabsf(angle-180.0f) < FLT_EPSILON) { 586 // perform 1/2 rotate 587 int numRows = in->numRows; 588 int lastRow = numRows - 1; 589 int numCols = in->numCols; 590 int lastCol = numCols - 1; 591 psElemType type = in->type.type; 592 out = psImageRecycle(out,numCols,numRows,type); 593 594 #define PSIMAGE_ROTATE_180_CASE(TYPE) \ 595 case PS_TYPE_##TYPE: { \ 596 for (int row=0;row<numRows;row++) { \ 597 ps##TYPE* outRow = out->data.TYPE[row]; \ 598 ps##TYPE* inRow = in->data.TYPE[lastRow-row]; \ 599 for (int col=0;col<numCols;col++) { \ 600 outRow[col] = inRow[lastCol - col]; \ 601 } \ 600 602 } \ 601 603 } \ 602 } \ 603 break; 604 605 switch (type) { 606 PSIMAGE_ROTATE_180_CASE(U8); 607 PSIMAGE_ROTATE_180_CASE(U16); 608 PSIMAGE_ROTATE_180_CASE(U32); 609 PSIMAGE_ROTATE_180_CASE(U64); 610 PSIMAGE_ROTATE_180_CASE(S8); 611 PSIMAGE_ROTATE_180_CASE(S16); 612 PSIMAGE_ROTATE_180_CASE(S32); 613 PSIMAGE_ROTATE_180_CASE(S64); 614 PSIMAGE_ROTATE_180_CASE(F32); 615 PSIMAGE_ROTATE_180_CASE(F64); 616 PSIMAGE_ROTATE_180_CASE(C32); 617 PSIMAGE_ROTATE_180_CASE(C64); 618 default: 619 psError(__func__,"Unsupported type (%d)",type); 620 psFree(out); 621 return NULL; 622 } 623 } else if (fabsf(angle-270.0f) < FLT_EPSILON) { 624 // perform 1/4 rotate clockwise 625 int numRows = in->numCols; 626 int lastRow = numRows - 1; 627 int numCols = in->numRows; 628 psElemType type = in->type.type; 629 out = psImageRecycle(out,numCols,numRows,type); 630 631 #define PSIMAGE_ROTATE_RIGHT_90(TYPE) \ 632 case PS_TYPE_##TYPE: { \ 633 ps##TYPE** inData = in->data.TYPE; \ 634 for (int row=0;row<numRows;row++) { \ 635 ps##TYPE* outRow = out->data.TYPE[row]; \ 636 for (int col=0;col<numCols;col++) { \ 637 outRow[col] = inData[col][lastRow-row]; \ 604 break; 605 606 switch (type) { 607 PSIMAGE_ROTATE_180_CASE(U8); 608 PSIMAGE_ROTATE_180_CASE(U16); 609 PSIMAGE_ROTATE_180_CASE(U32); 610 PSIMAGE_ROTATE_180_CASE(U64); 611 PSIMAGE_ROTATE_180_CASE(S8); 612 PSIMAGE_ROTATE_180_CASE(S16); 613 PSIMAGE_ROTATE_180_CASE(S32); 614 PSIMAGE_ROTATE_180_CASE(S64); 615 PSIMAGE_ROTATE_180_CASE(F32); 616 PSIMAGE_ROTATE_180_CASE(F64); 617 PSIMAGE_ROTATE_180_CASE(C32); 618 PSIMAGE_ROTATE_180_CASE(C64); 619 default: 620 psError(__func__,"Unsupported type (%d)",type); 621 psFree(out); 622 return NULL; 623 } 624 } else 625 if (fabsf(angle-270.0f) < FLT_EPSILON) { 626 // perform 1/4 rotate clockwise 627 int numRows = in->numCols; 628 int lastRow = numRows - 1; 629 int numCols = in->numRows; 630 psElemType type = in->type.type; 631 out = psImageRecycle(out,numCols,numRows,type); 632 633 #define PSIMAGE_ROTATE_RIGHT_90(TYPE) \ 634 case PS_TYPE_##TYPE: { \ 635 ps##TYPE** inData = in->data.TYPE; \ 636 for (int row=0;row<numRows;row++) { \ 637 ps##TYPE* outRow = out->data.TYPE[row]; \ 638 for (int col=0;col<numCols;col++) { \ 639 outRow[col] = inData[col][lastRow-row]; \ 640 } \ 641 } \ 638 642 } \ 639 } \ 640 } \ 641 break; 642 643 switch (type) { 644 PSIMAGE_ROTATE_RIGHT_90(U8); 645 PSIMAGE_ROTATE_RIGHT_90(U16); 646 PSIMAGE_ROTATE_RIGHT_90(U32); 647 PSIMAGE_ROTATE_RIGHT_90(U64); 648 PSIMAGE_ROTATE_RIGHT_90(S8); 649 PSIMAGE_ROTATE_RIGHT_90(S16); 650 PSIMAGE_ROTATE_RIGHT_90(S32); 651 PSIMAGE_ROTATE_RIGHT_90(S64); 652 PSIMAGE_ROTATE_RIGHT_90(F32); 653 PSIMAGE_ROTATE_RIGHT_90(F64); 654 PSIMAGE_ROTATE_RIGHT_90(C32); 655 PSIMAGE_ROTATE_RIGHT_90(C64); 656 default: 657 psError(__func__,"Unsupported type (%d)",type); 658 psFree(out); 659 return NULL; 660 } 661 } else if (fabsf(angle) < FLT_EPSILON) { 662 out = psImageCopy(out,in,in->type.type); 663 } else { 664 psElemType type = in->type.type; 665 int numRows = in->numRows; 666 int numCols = in->numCols; 667 double centerX = (float)(numCols) / 2.0f; 668 float centerY = (float)(numRows) / 2.0f; 669 float t = angle*(3.14159265358f/180.0f); 670 float cosT = cosf(t); 671 float sinT = sinf(t); 672 673 // calculate the corners of the rotated image so we know the proper output image size. 674 // x' = x cos(t) + y sin(t); i.e, x' = (x-centerX)*cosT + (y-centerY)*sinT; 675 // y' = y cos(t) - x sin(t); i.e. y' = (y-centerY)*cosT - (x-centerX)*sinT; 676 677 678 int outCols = ceil(abs(numCols*cosT)+abs(numRows*sinT))+1; 679 int outRows = ceil(abs(numCols*sinT)+abs(numRows*cosT))+1; 680 float minX = (float)outCols/-2.0f; 681 int intMinY = outRows/-2; 682 683 out = psImageRecycle(out,outCols,outRows,type); 684 685 /* optimized public domain rotation routine by Karl Lager 686 float cosT,sinT; 687 cosT = cos(t); 688 sinT = sin(t); 689 for (y = min_y; y <= max_y; y++) 690 { x' = min_x * cosT + y * sinT + x1'; 691 y' = y * cosT - min_x * sinT + y1'; 692 for (x = min_x; x <= max_x; x++) 693 { if (x', y') is in the bounds of the bitmap, 694 get pixel(x', y') and plot the pixel to 695 (x, y) on screen. 696 x' += cosT; 697 y' -= sinT; 698 } 699 } 700 */ 701 702 // precalculate some figures that are used within loop 703 float minXTimesCosTPlusCenterX = minX*cosT+centerX; 704 float CenterYMinusminXTimesSinT = centerY-minX*sinT; 705 706 #define PSIMAGE_ROTATE_ARBITRARY_LOOP(TYPE,MODE) { \ 707 if (unexposedValue < PS_MIN_##TYPE || unexposedValue > PS_MAX_##TYPE) { \ 708 psError(__func__,"The given unexposedValue (%g) is outside of the " \ 709 "image type's range (%g->%g).", \ 710 unexposedValue, (double)PS_MIN_##TYPE,(double)PS_MAX_##TYPE); \ 711 psFree(out); \ 712 out = NULL; \ 713 break; \ 714 } \ 715 float inX; \ 716 float inY; \ 717 ps##TYPE* outRow; \ 718 for (int y = 0; y < outRows; y++) { \ 719 inX = minXTimesCosTPlusCenterX + (y+intMinY) * sinT; \ 720 inY = CenterYMinusminXTimesSinT + (y+intMinY) * cosT; \ 721 outRow = out->data.TYPE[y]; \ 722 for (int x = 0; x < outCols; x++) { \ 723 outRow[x] = p_psImagePixelInterpolate##MODE##_##TYPE(in,inX,inY,unexposedValue); \ 724 inX += cosT; \ 725 inY -= sinT; \ 726 } \ 727 } \ 728 } 729 730 #define PSIMAGE_ROTATE_ARBITRARY_CASE(MODE) \ 731 case PS_INTERPOLATE_##MODE: \ 732 switch (type) { \ 733 case PS_TYPE_U8: \ 734 PSIMAGE_ROTATE_ARBITRARY_LOOP(U8,MODE); \ 735 break; \ 736 case PS_TYPE_U16: \ 737 PSIMAGE_ROTATE_ARBITRARY_LOOP(U16,MODE); \ 738 break; \ 739 case PS_TYPE_U32: \ 740 PSIMAGE_ROTATE_ARBITRARY_LOOP(U32,MODE); \ 741 break; \ 742 case PS_TYPE_U64: \ 743 PSIMAGE_ROTATE_ARBITRARY_LOOP(U64,MODE); \ 744 break; \ 745 case PS_TYPE_S8: \ 746 PSIMAGE_ROTATE_ARBITRARY_LOOP(S8,MODE); \ 747 break; \ 748 case PS_TYPE_S16: \ 749 PSIMAGE_ROTATE_ARBITRARY_LOOP(S16,MODE); \ 750 break; \ 751 case PS_TYPE_S32: \ 752 PSIMAGE_ROTATE_ARBITRARY_LOOP(S32,MODE); \ 753 break; \ 754 case PS_TYPE_S64: \ 755 PSIMAGE_ROTATE_ARBITRARY_LOOP(S64,MODE); \ 756 break; \ 757 case PS_TYPE_F32: \ 758 PSIMAGE_ROTATE_ARBITRARY_LOOP(F32,MODE); \ 759 break; \ 760 case PS_TYPE_F64: \ 761 PSIMAGE_ROTATE_ARBITRARY_LOOP(F64,MODE); \ 762 break; \ 763 case PS_TYPE_C32: \ 764 PSIMAGE_ROTATE_ARBITRARY_LOOP(C32,MODE); \ 765 break; \ 766 case PS_TYPE_C64: \ 767 PSIMAGE_ROTATE_ARBITRARY_LOOP(C64,MODE); \ 768 break; \ 769 default: \ 770 psError(__func__,"Image type (%d) not supported",type); \ 771 psFree(out); \ 772 out = NULL; \ 773 } \ 774 break; 775 776 switch (mode) { 777 PSIMAGE_ROTATE_ARBITRARY_CASE(FLAT); 778 PSIMAGE_ROTATE_ARBITRARY_CASE(BILINEAR); 779 default: 780 psError(__func__,"Unsupported interpolation mode (%d)",mode); 781 psFree(out); 782 out = NULL; 783 } 784 } 643 break; 644 645 switch (type) { 646 PSIMAGE_ROTATE_RIGHT_90(U8); 647 PSIMAGE_ROTATE_RIGHT_90(U16); 648 PSIMAGE_ROTATE_RIGHT_90(U32); 649 PSIMAGE_ROTATE_RIGHT_90(U64); 650 PSIMAGE_ROTATE_RIGHT_90(S8); 651 PSIMAGE_ROTATE_RIGHT_90(S16); 652 PSIMAGE_ROTATE_RIGHT_90(S32); 653 PSIMAGE_ROTATE_RIGHT_90(S64); 654 PSIMAGE_ROTATE_RIGHT_90(F32); 655 PSIMAGE_ROTATE_RIGHT_90(F64); 656 PSIMAGE_ROTATE_RIGHT_90(C32); 657 PSIMAGE_ROTATE_RIGHT_90(C64); 658 default: 659 psError(__func__,"Unsupported type (%d)",type); 660 psFree(out); 661 return NULL; 662 } 663 } else 664 if (fabsf(angle) < FLT_EPSILON) { 665 out = psImageCopy(out,in,in->type.type); 666 } else { 667 psElemType type = in->type.type; 668 int numRows = in->numRows; 669 int numCols = in->numCols; 670 double centerX = (float)(numCols) / 2.0f; 671 float centerY = (float)(numRows) / 2.0f; 672 float t = angle*(3.14159265358f/180.0f); 673 float cosT = cosf(t); 674 float sinT = sinf(t); 675 676 // calculate the corners of the rotated image so we know the proper output image size. 677 // x' = x cos(t) + y sin(t); i.e, x' = (x-centerX)*cosT + (y-centerY)*sinT; 678 // y' = y cos(t) - x sin(t); i.e. y' = (y-centerY)*cosT - (x-centerX)*sinT; 679 680 681 int outCols = ceil(abs(numCols*cosT)+abs(numRows*sinT))+1; 682 int outRows = ceil(abs(numCols*sinT)+abs(numRows*cosT))+1; 683 float minX = (float)outCols/-2.0f; 684 int intMinY = outRows/-2; 685 686 out = psImageRecycle(out,outCols,outRows,type); 687 688 /* optimized public domain rotation routine by Karl Lager 689 float cosT,sinT; 690 cosT = cos(t); 691 sinT = sin(t); 692 for (y = min_y; y <= max_y; y++) 693 { x' = min_x * cosT + y * sinT + x1'; 694 y' = y * cosT - min_x * sinT + y1'; 695 for (x = min_x; x <= max_x; x++) 696 { if (x', y') is in the bounds of the bitmap, 697 get pixel(x', y') and plot the pixel to 698 (x, y) on screen. 699 x' += cosT; 700 y' -= sinT; 701 } 702 } 703 */ 704 705 // precalculate some figures that are used within loop 706 float minXTimesCosTPlusCenterX = minX*cosT+centerX; 707 float CenterYMinusminXTimesSinT = centerY-minX*sinT; 708 709 #define PSIMAGE_ROTATE_ARBITRARY_LOOP(TYPE,MODE) { \ 710 if (unexposedValue < PS_MIN_##TYPE || unexposedValue > PS_MAX_##TYPE) { \ 711 psError(__func__,"The given unexposedValue (%g) is outside of the " \ 712 "image type's range (%g->%g).", \ 713 unexposedValue, (double)PS_MIN_##TYPE,(double)PS_MAX_##TYPE); \ 714 psFree(out); \ 715 out = NULL; \ 716 break; \ 717 } \ 718 float inX; \ 719 float inY; \ 720 ps##TYPE* outRow; \ 721 for (int y = 0; y < outRows; y++) { \ 722 inX = minXTimesCosTPlusCenterX + (y+intMinY) * sinT; \ 723 inY = CenterYMinusminXTimesSinT + (y+intMinY) * cosT; \ 724 outRow = out->data.TYPE[y]; \ 725 for (int x = 0; x < outCols; x++) { \ 726 outRow[x] = p_psImagePixelInterpolate##MODE##_##TYPE(in,inX,inY,unexposedValue); \ 727 inX += cosT; \ 728 inY -= sinT; \ 729 } \ 730 } \ 731 } 732 733 #define PSIMAGE_ROTATE_ARBITRARY_CASE(MODE) \ 734 case PS_INTERPOLATE_##MODE: \ 735 switch (type) { \ 736 case PS_TYPE_U8: \ 737 PSIMAGE_ROTATE_ARBITRARY_LOOP(U8,MODE); \ 738 break; \ 739 case PS_TYPE_U16: \ 740 PSIMAGE_ROTATE_ARBITRARY_LOOP(U16,MODE); \ 741 break; \ 742 case PS_TYPE_U32: \ 743 PSIMAGE_ROTATE_ARBITRARY_LOOP(U32,MODE); \ 744 break; \ 745 case PS_TYPE_U64: \ 746 PSIMAGE_ROTATE_ARBITRARY_LOOP(U64,MODE); \ 747 break; \ 748 case PS_TYPE_S8: \ 749 PSIMAGE_ROTATE_ARBITRARY_LOOP(S8,MODE); \ 750 break; \ 751 case PS_TYPE_S16: \ 752 PSIMAGE_ROTATE_ARBITRARY_LOOP(S16,MODE); \ 753 break; \ 754 case PS_TYPE_S32: \ 755 PSIMAGE_ROTATE_ARBITRARY_LOOP(S32,MODE); \ 756 break; \ 757 case PS_TYPE_S64: \ 758 PSIMAGE_ROTATE_ARBITRARY_LOOP(S64,MODE); \ 759 break; \ 760 case PS_TYPE_F32: \ 761 PSIMAGE_ROTATE_ARBITRARY_LOOP(F32,MODE); \ 762 break; \ 763 case PS_TYPE_F64: \ 764 PSIMAGE_ROTATE_ARBITRARY_LOOP(F64,MODE); \ 765 break; \ 766 case PS_TYPE_C32: \ 767 PSIMAGE_ROTATE_ARBITRARY_LOOP(C32,MODE); \ 768 break; \ 769 case PS_TYPE_C64: \ 770 PSIMAGE_ROTATE_ARBITRARY_LOOP(C64,MODE); \ 771 break; \ 772 default: \ 773 psError(__func__,"Image type (%d) not supported",type); \ 774 psFree(out); \ 775 out = NULL; \ 776 } \ 777 break; 778 779 switch (mode) { 780 PSIMAGE_ROTATE_ARBITRARY_CASE(FLAT); 781 PSIMAGE_ROTATE_ARBITRARY_CASE(BILINEAR); 782 default: 783 psError(__func__,"Unsupported interpolation mode (%d)",mode); 784 psFree(out); 785 out = NULL; 786 } 787 } 785 788 786 789 return out; -
trunk/psLib/src/image/psImageStats.c
r1341 r1385 271 271 if ((i != 0) && (j != 0)) { 272 272 coeffs->coeff[i][j]*= 4.0; 273 } else if ((i == 0) && (j == 0)) { 274 coeffs->coeff[i][j]*= 1.0; 275 } else { 276 coeffs->coeff[i][j]*= 2.0; 277 } 273 } else 274 if ((i == 0) && (j == 0)) { 275 coeffs->coeff[i][j]*= 1.0; 276 } else { 277 coeffs->coeff[i][j]*= 2.0; 278 } 278 279 } 279 280 }
Note:
See TracChangeset
for help on using the changeset viewer.
