Changeset 1359 for trunk/psLib/src/image/psImageExtraction.c
- Timestamp:
- Jul 30, 2004, 4:27:43 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/image/psImageExtraction.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/image/psImageExtraction.c
r1292 r1359 1 1 /** @file psImageManip.h 2 *3 * @brief Contains basic image extraction operations, as specified in the4 * PSLIB SDRS sections "Image Pixel Extractions" and "Image Structure5 * Manipulation".6 *7 * @ingroup Image8 *9 * @author Robert DeSonia, MHPCC10 *11 * @version $Revision: 1.2$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-07-24 02:00:21$13 *14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii15 *16 */2 * 3 * @brief Contains basic image extraction operations, as specified in the 4 * PSLIB SDRS sections "Image Pixel Extractions" and "Image Structure 5 * Manipulation". 6 * 7 * @ingroup Image 8 * 9 * @author Robert DeSonia, MHPCC 10 * 11 * @version $Revision: 1.3 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-07-31 02:27:43 $ 13 * 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii 15 * 16 */ 17 17 18 18 #include <string.h> … … 22 22 #include "psError.h" 23 23 24 psImage *psImageSubset( psImage *out,psImage *image,unsigned int numCols,25 unsigned int numRows, unsigned int col0,26 unsigned int row0)24 psImage *psImageSubset( psImage *out, psImage *image, unsigned int numCols, 25 unsigned int numRows, unsigned int col0, 26 unsigned int row0 ) 27 27 { 28 28 unsigned int elementSize; // size of image element in bytes 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 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);51 return NULL;52 }53 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 ); 51 return NULL; 52 } 53 54 54 /* 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 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 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 68 *( int* ) & out->row0 = row0; 69 *( int* ) & out->col0 = col0; 70 *( psImage** ) & out->parent = ( psImage* ) image; 71 72 72 // add output image as a child of the input image. 73 73 image->nChildren++; 74 image->children = ( psImage **) psRealloc(image->children,75 image->nChildren * sizeof( psImage*) );76 image->children[ image->nChildren-1] = out;77 78 inputColOffset = elementSize *col0;79 outputRowSize = elementSize *numCols;80 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);74 image->children = ( psImage ** ) psRealloc( image->children, 75 image->nChildren * sizeof( psImage* ) ); 76 image->children[ image->nChildren - 1 ] = out; 77 78 inputColOffset = elementSize * col0; 79 outputRowSize = elementSize * numCols; 80 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 ); 87 87 } 88 88 89 89 90 psImage *psImageCopy( psImage* restrict output, const psImage *input,91 psElemType type)90 psImage *psImageCopy( psImage* restrict output, const psImage *input, 91 psElemType type ) 92 92 { 93 93 psElemType inDatatype; … … 96 96 int numRows; 97 97 int numCols; 98 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);115 return NULL;116 }117 98 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 ); 115 return NULL; 116 } 117 118 118 inDatatype = input->type.type; 119 119 numRows = input->numRows; 120 120 numCols = input->numCols; 121 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 121 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 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 return output;136 }137 133 if ( type == inDatatype ) { 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 } \142 *(out++) = *(in++); \ 143 } \ 144 144 } 145 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 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 }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 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 } 228 228 return output; 229 229 } 230 230 231 psVector* psImageSlice( psVector* out,232 const psImage*in,233 const psImage* restrict mask,234 unsigned int maskVal,235 unsigned int col,236 unsigned int row,237 unsigned int numCols,238 unsigned int numRows,239 psImageCutDirection direction,240 const psStats* stats)231 psVector* psImageSlice( psVector* out, 232 const psImage* restrict in, 233 const psImage* restrict mask, 234 unsigned int maskVal, 235 unsigned int col, 236 unsigned int row, 237 unsigned int numCols, 238 unsigned int numRows, 239 psImageCutDirection direction, 240 const psStats* stats ) 241 241 { 242 242 double statVal; … … 247 247 int delta = 1; 248 248 psF64* outData; 249 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 249 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 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 256 263 type = in->type.type; 257 264 inRows = in->numRows; 258 265 inCols = in->numCols; 259 260 if (mask != NULL) { 261 if (inRows!=mask->numRows || inCols!=mask->numCols) { 262 psError(__func__,"The mask and image dimensions did not match (%dx%d vs %dx%d)", 263 mask->numCols,mask->numRows,in->numCols,in->numRows); 264 psFree(out); 265 } 266 if (mask->type.type != PS_TYPE_MASK) { 267 psError(__func__,"The mask datatype (%d) must be %s.", 268 mask->type.type, PS_TYPE_MASK_NAME); 269 psFree(out); 270 } 271 } 272 273 if (row >= inRows || col >= inCols || 274 col+numCols > in->numCols || row+numRows > in->numRows) { 275 psError(__func__,"The specified image region (%d,%d to %d,%d) is outside of image area (0,0 to %d,%d).", 276 col, row, col+numCols-1, row+numRows-1, in->numCols-1, in->numRows-1); 277 psFree(out); 278 return NULL; 279 } 280 266 267 if ( direction == PS_CUT_X_NEG || direction == PS_CUT_Y_NEG ) { 268 delta = -1; 269 } 270 271 // if numRows/numCols is negative, invert the problem to give positive 272 // numRows/numCols (and cut in opposite direction). 273 if ( numRows < 0 ) { 274 numRows = -numRows; 275 row -= ( numRows - 1 ); 276 delta = -delta; 277 } 278 279 if ( numCols < 0 ) { 280 numCols = -numCols; 281 col -= ( numCols - 1 ); 282 delta = -delta; 283 } 284 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 298 if ( row >= inRows || col >= inCols || 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 281 306 // verify that the stats struct specifies a single stats operation 282 if ( p_psGetStatValue(stats,&statVal) == false) {283 psError(__func__,"The stat options didn't specify a single supported statistic type.");284 psFree(out);285 return NULL;286 }287 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 288 313 // since stats input is const, I need to create a 'scratch' stats struct 289 myStats = psAlloc( sizeof(psStats));314 myStats = psAlloc( sizeof( psStats ) ); 290 315 *myStats = *stats; 291 292 293 if (direction == PS_CUT_X_NEG || direction == PS_CUT_Y_NEG) { 294 delta = -1; 295 } 296 297 if (direction == PS_CUT_X_POS || direction == PS_CUT_X_NEG) { 298 psVector* imgVec = psVectorAlloc(numRows,type); 299 psVector* maskVec = NULL; 300 psMaskType* maskData = NULL; 301 302 // recycle output to make a proper sized/type output structure 303 // n.b. type is double as that is the type given for all stats in psStats. 304 out = psVectorRecycle(out,numCols,PS_TYPE_F64); 305 outData = out->data.F64; 306 if (delta < 0) { 307 outData += numCols - 1; 308 } 309 310 if (mask != NULL) { 311 maskVec = psVectorAlloc(numRows,mask->type.type); 312 } 313 314 #define PSIMAGE_CUT_VERTICAL(TYPE) \ 315 case PS_TYPE_##TYPE: { \ 316 ps##TYPE *imgVecData = imgVec->data.TYPE; \ 317 psMaskType* maskVecData = NULL; \ 318 if (maskVec != NULL) { \ 319 maskVecData = maskVec->data.V; \ 320 } \ 321 for (int c=0;c<numCols;c++) { \ 322 ps##TYPE *imgData = in->data.TYPE[row] + col + c; \ 323 if (maskVec != NULL) { \ 324 maskData = (psMaskType*)(mask->data.V[row]) + col + c; \ 325 } \ 326 for (int r=0;r<numRows;r++) { \ 327 *(imgVecData++) = *imgData; \ 328 imgData += inCols; \ 329 if (maskVecData != NULL) { \ 330 *(maskVecData++) = *maskData; \ 331 maskData += inCols; \ 316 317 318 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; \ 332 358 } \ 333 } \ 334 myStats = psVectorStats(myStats,imgVec,maskVec,maskVal); \ 335 (void)p_psGetStatValue(myStats,&statVal); \ 336 *outData = statVal; \ 337 outData += delta; \ 338 } \ 339 break; \ 340 } 341 342 switch (type) { 343 PSIMAGE_CUT_VERTICAL(U8); 344 PSIMAGE_CUT_VERTICAL(U16); 345 PSIMAGE_CUT_VERTICAL(U32); 346 PSIMAGE_CUT_VERTICAL(U64); 347 PSIMAGE_CUT_VERTICAL(S8); 348 PSIMAGE_CUT_VERTICAL(S16); 349 PSIMAGE_CUT_VERTICAL(S32); 350 PSIMAGE_CUT_VERTICAL(S64); 351 PSIMAGE_CUT_VERTICAL(F32); 352 PSIMAGE_CUT_VERTICAL(F64); 353 PSIMAGE_CUT_VERTICAL(C32); 354 PSIMAGE_CUT_VERTICAL(C64); 355 default: 356 psError(__func__,"Unsupported datatype (%d)",type); 357 psFree(out); 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 383 psVector * imgVec = NULL; 384 psVector* maskVec = NULL; 385 int elementSize = PSELEMTYPE_SIZEOF( type ); 386 387 // fill in psVectors to fake out the statistics functions. 388 imgVec = psAlloc( sizeof( psVector ) ); 389 imgVec->type = in->type; 390 imgVec->n = imgVec->nalloc = numCols; 391 if ( mask != NULL ) { 392 maskVec = psAlloc( sizeof( psVector ) ); 393 maskVec->type = mask->type; 394 maskVec->n = maskVec->nalloc = numCols; 395 } 396 397 // recycle output to make a proper sized/type output structure 398 // n.b. type is double as that is the type given for all stats in psStats. 399 out = psVectorRecycle( out, PS_TYPE_F64, numRows ); 400 outData = out->data.F64; 401 if ( delta < 0 ) { 402 outData += numRows - 1; 403 } 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 } 416 psFree( imgVec ); 417 psFree( maskVec ); 418 } else { // don't know what the direction flag is 419 psError( __func__, "Invalid direction flag (%d)", direction ); 420 psFree( out ); 358 421 out = NULL; 359 422 } 360 psFree(imgVec); 361 psFree(maskVec); 362 } else { // Cut in Y direction 363 psVector* imgVec = NULL; 364 psVector* maskVec = NULL; 365 int elementSize = PSELEMTYPE_SIZEOF(type); 366 367 // fill in psVectors to fake out the statistics functions. 368 imgVec = psAlloc(sizeof(psVector)); 369 imgVec->type = in->type; 370 imgVec->n = imgVec->nalloc = numCols; 371 if (mask != NULL) { 372 maskVec = psAlloc(sizeof(psVector)); 373 maskVec->type = mask->type; 374 maskVec->n = maskVec->nalloc = numCols; 375 } 376 377 // recycle output to make a proper sized/type output structure 378 // n.b. type is double as that is the type given for all stats in psStats. 379 out = psVectorRecycle(out,numRows,PS_TYPE_F64); 380 outData = out->data.F64; 381 if (delta < 0) { 382 outData += numCols - 1; 383 } 384 385 for (int r=0;r<numRows;r++) { 386 // point the vector struct to the data to calculate the stats 387 imgVec->data.V = (void*)(in->data.U8[row+r]+col*elementSize); 388 if (maskVec!=NULL) { 389 maskVec->data.V = (void*)(mask->data.U8[row+r]+col*sizeof(psMaskType)); 390 } 391 myStats = psVectorStats(myStats,imgVec,maskVec,maskVal); 392 (void)p_psGetStatValue(myStats,&statVal); // we know it works cause we tested it above 393 *outData = statVal; 394 outData += delta; 395 } 396 } 397 423 424 psFree( myStats ); 425 398 426 return out; 399 427 }
Note:
See TracChangeset
for help on using the changeset viewer.
