Changeset 1407 for trunk/psLib/src/image
- Timestamp:
- Aug 6, 2004, 2:06:06 PM (22 years ago)
- Location:
- trunk/psLib/src/image
- Files:
-
- 10 edited
-
psImage.c (modified) (15 diffs)
-
psImage.h (modified) (8 diffs)
-
psImageExtraction.c (modified) (10 diffs)
-
psImageExtraction.h (modified) (5 diffs)
-
psImageIO.c (modified) (19 diffs)
-
psImageIO.h (modified) (4 diffs)
-
psImageManip.c (modified) (34 diffs)
-
psImageManip.h (modified) (8 diffs)
-
psImageStats.c (modified) (21 diffs)
-
psImageStats.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/image/psImage.c
r1406 r1407 1 1 2 /** @file psImage.c 2 3 * … … 9 10 * @author Ross Harman, MHPCC 10 11 * 11 * @version $Revision: 1.3 7$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-08-0 6 22:34:05$12 * @version $Revision: 1.38 $ $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 … … 18 19 19 20 /******************************************************************************/ 21 20 22 /* INCLUDE FILES */ 23 21 24 /******************************************************************************/ 22 25 … … 29 32 #include "psImage.h" 30 33 31 static void imageFree(psImage * image);34 static void imageFree(psImage * image); 32 35 33 36 /*****************************************************************************/ 37 34 38 /* FUNCTION IMPLEMENTATION - PUBLIC */ 39 35 40 /*****************************************************************************/ 36 41 37 psImage *psImageAlloc(unsigned int numCols, unsigned int numRows, 38 const psElemType type) 42 psImage *psImageAlloc(unsigned int numCols, unsigned int numRows, const psElemType type) 39 43 { 40 44 int area = 0; 41 int elementSize = PSELEMTYPE_SIZEOF(type); // element size in bytes 42 int rowSize = numCols*elementSize; // row size in bytes. 43 44 area = numCols*numRows; 45 int elementSize = PSELEMTYPE_SIZEOF(type); // element 46 47 // size in 48 // bytes 49 int rowSize = numCols * elementSize; // row 50 51 // size 52 53 // in bytes. 54 55 area = numCols * numRows; 45 56 46 57 if (area < 1) { 47 psError(__func__, "Invalid value for number of rows or columns "48 " (numRows=%d, numCols=%d).", numRows, numCols);58 psError(__func__, 59 "Invalid value for number of rows or columns " "(numRows=%d, numCols=%d).", numRows, numCols); 49 60 return NULL; 50 61 } 51 62 52 psImage *image = (psImage *) psAlloc(sizeof(psImage));53 if(image == NULL) { 54 psAbort(__func__," : Line %d - Failed to allocate memory", __LINE__);55 }56 57 p_psMemSetDeallocator(image,(psFreeFcn)imageFree); 58 59 image->data.V = psAlloc(sizeof(void*)*numRows); 60 i f(image->data.V == NULL) {61 psAbort(__func__," : Line %d - Failed to allocate memory", __LINE__);62 }63 64 65 image->data.V[0] = psAlloc(area *elementSize);66 if (image->data.V[0] == NULL) {67 psAbort(__func__, " : Line %d - Failed to allocate memory", __LINE__);68 } 69 70 for (int i = 1; i < numRows; i++) {71 image->data.V[i] = (void *)((int8_t*)image->data.V[i-1]+rowSize);72 } 73 74 *(int *)&image->col0 = 0;75 *(int *)&image->row0 = 0;76 *(unsigned int *)&image->numCols = numCols;77 *(unsigned int *)&image->numRows = numRows;78 *(psDimen *)&image->type.dimen = PS_DIMEN_IMAGE;79 *(psElemType *)&image->type.type = type;63 psImage *image = (psImage *) psAlloc(sizeof(psImage)); 64 65 if (image == NULL) { 66 psAbort(__func__, " : Line %d - Failed to allocate memory", __LINE__); 67 } 68 69 p_psMemSetDeallocator(image, (psFreeFcn) imageFree); 70 71 image->data.V = psAlloc(sizeof(void *) * numRows); 72 if (image->data.V == NULL) { 73 psAbort(__func__, " : Line %d - Failed to allocate memory", __LINE__); 74 } 75 76 image->data.V[0] = psAlloc(area * elementSize); 77 if (image->data.V[0] == NULL) { 78 psAbort(__func__, " : Line %d - Failed to allocate memory", __LINE__); 79 } 80 81 for (int i = 1; i < numRows; i++) { 82 image->data.V[i] = (void *)((int8_t *) image->data.V[i - 1] + rowSize); 83 } 84 85 *(int *)&image->col0 = 0; 86 *(int *)&image->row0 = 0; 87 *(unsigned int *)&image->numCols = numCols; 88 *(unsigned int *)&image->numRows = numRows; 89 *(psDimen *) & image->type.dimen = PS_DIMEN_IMAGE; 90 *(psElemType *) & image->type.type = type; 80 91 image->parent = NULL; 81 92 image->nChildren = 0; … … 85 96 } 86 97 87 static void imageFree(psImage * image)98 static void imageFree(psImage * image) 88 99 { 89 100 if (image == NULL) { … … 92 103 93 104 if (image->type.type == PS_TYPE_PTR) { 94 // 2-D array of pointers -- must dereference 105 // 2-D array of pointers -- must 106 // dereference 95 107 unsigned int oldNumRows = image->numRows; 96 108 unsigned int oldNumCols = image->numCols; 97 psPTR *rowPtr;98 99 for (unsigned int row=0;row<oldNumRows;row++) {109 psPTR *rowPtr; 110 111 for (unsigned int row = 0; row < oldNumRows; row++) { 100 112 rowPtr = image->data.PTR[row]; 101 for (unsigned int col =0;col<oldNumCols;col++) {113 for (unsigned int col = 0; col < oldNumCols; col++) { 102 114 psMemDecrRefCounter(rowPtr[col]); 103 115 } … … 112 124 } 113 125 114 psImage* psImageRecycle(psImage* old, 115 unsigned int numCols, 116 unsigned int numRows, 117 const psElemType type) 126 psImage *psImageRecycle(psImage * old, unsigned int numCols, unsigned int numRows, const psElemType type) 118 127 { 119 int elementSize = PSELEMTYPE_SIZEOF(type); // element size in bytes 120 int rowSize = numCols*elementSize; // row size in bytes. 128 int elementSize = PSELEMTYPE_SIZEOF(type); // element 129 130 // size in 131 // bytes 132 int rowSize = numCols * elementSize; // row 133 134 // size 135 136 // in bytes. 121 137 122 138 if (old == NULL) { 123 old = psImageAlloc(numCols, numRows,type);139 old = psImageAlloc(numCols, numRows, type); 124 140 return old; 125 141 } 126 142 127 143 if (old->type.dimen != PS_DIMEN_IMAGE) { 128 psError(__func__, "Can not realloc image because input is not an image.");144 psError(__func__, "Can not realloc image because input is not an image."); 129 145 return NULL; 130 146 } 131 147 132 148 if (old->type.type == PS_TYPE_PTR) { 133 // 2-D array of pointers -- must dereference 149 // 2-D array of pointers -- must 150 // dereference 134 151 unsigned int oldNumRows = old->numRows; 135 152 unsigned int oldNumCols = old->numCols; 136 psPTR *rowPtr;137 138 for (unsigned int row=0;row<oldNumRows;row++) {153 psPTR *rowPtr; 154 155 for (unsigned int row = 0; row < oldNumRows; row++) { 139 156 rowPtr = old->data.PTR[row]; 140 for (unsigned int col =0;col<oldNumCols;col++) {157 for (unsigned int col = 0; col < oldNumCols; col++) { 141 158 psMemDecrRefCounter(rowPtr[col]); 142 159 rowPtr[col] = NULL; … … 146 163 147 164 /* image already the right size/type? */ 148 if (numCols == old->numCols && numRows == old->numRows && 149 type == old->type.type) { 165 if (numCols == old->numCols && numRows == old->numRows && type == old->type.type) { 150 166 return old; 151 167 } 152 153 168 // Resize the image buffer 154 old->data.V[0] = psRealloc(old->data.V[0], numCols * numRows * elementSize);155 old->data.V = (void **) psRealloc(old->data.V,numRows * sizeof(void*));169 old->data.V[0] = psRealloc(old->data.V[0], numCols * numRows * elementSize); 170 old->data.V = (void **)psRealloc(old->data.V, numRows * sizeof(void *)); 156 171 157 172 // recreate the row pointers 158 for (int i = 1; i < numRows; i++) {159 old->data.V[i] = (void *)((int8_t*)old->data.V[i-1]+rowSize);160 } 161 162 *(unsigned int *)&old->numCols = numCols;163 *(unsigned int *)&old->numRows = numRows;164 *(psElemType *)&old->type.type = type;173 for (int i = 1; i < numRows; i++) { 174 old->data.V[i] = (void *)((int8_t *) old->data.V[i - 1] + rowSize); 175 } 176 177 *(unsigned int *)&old->numCols = numCols; 178 *(unsigned int *)&old->numRows = numRows; 179 *(psElemType *) & old->type.type = type; 165 180 166 181 return old; 167 182 } 168 183 169 int psImageFreeChildren(psImage * image)184 int psImageFreeChildren(psImage * image) 170 185 { 171 186 int i = 0; … … 181 196 children = image->children; 182 197 183 for (i=0; i<nChildren; i++) {198 for (i = 0; i < nChildren; i++) { 184 199 if (children[i] != NULL) { 185 200 numFreed++; … … 191 206 image->nChildren = 0; 192 207 image->children = NULL; 193 194 208 195 209 return numFreed; … … 202 216 linear interpolation is performed on the image. 203 217 *****************************************************************************/ 204 psF32 psImagePixelInterpolate( 205 const psImage *input, 206 float x, 207 float y, 208 psF32 unexposedValue, 209 psImageInterpolateMode mode) 218 psF32 psImagePixelInterpolate(const psImage * input, 219 float x, float y, psF32 unexposedValue, psImageInterpolateMode mode) 210 220 { 211 221 212 222 if (input == NULL) { 213 psError(__func__, "Image can not be NULL.");223 psError(__func__, "Image can not be NULL."); 214 224 return unexposedValue; 215 225 } 216 217 226 #define PSIMAGE_PIXEL_INTERPOLATE_CASE(TYPE) \ 218 227 case PS_TYPE_##TYPE: \ … … 243 252 PSIMAGE_PIXEL_INTERPOLATE_CASE(C64); 244 253 default: 245 psError(__func__, "Unsupported image datatype (%d)",input->type.type);254 psError(__func__, "Unsupported image datatype (%d)", input->type.type); 246 255 } 247 256 … … 303 312 PSIMAGE_PIXEL_INTERPOLATE_FLAT_COMPLEX(C32) 304 313 PSIMAGE_PIXEL_INTERPOLATE_FLAT_COMPLEX(C64) 305 306 314 #define PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(TYPE) \ 307 315 inline psF64 p_psImagePixelInterpolateBILINEAR_##TYPE(const psImage *input, \ … … 359 367 return(pixel); \ 360 368 } 361 362 369 #define PSIMAGE_PIXEL_INTERPOLATE_BILINEAR_COMPLEX(TYPE) \ 363 370 inline psC64 p_psImagePixelInterpolateBILINEAR_##TYPE(const psImage *input, \ … … 428 435 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR_COMPLEX(C32) 429 436 PSIMAGE_PIXEL_INTERPOLATE_BILINEAR_COMPLEX(C64) 430 431 -
trunk/psLib/src/image/psImage.h
r1406 r1407 1 1 2 /** @file psImage.h 2 3 * … … 11 12 * @author Ross Harman, MHPCC 12 13 * 13 * @version $Revision: 1.2 7$ $Name: not supported by cvs2svn $14 * @date $Date: 2004-08-0 6 22:34:05$14 * @version $Revision: 1.28 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2004-08-07 00:06:06 $ 15 16 * 16 17 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii 17 18 */ 18 # ifndef PS_IMAGE_H19 # define PS_IMAGE_H19 #ifndef PS_IMAGE_H 20 # define PS_IMAGE_H 20 21 21 # include <complex.h>22 # include <complex.h> 22 23 23 # include "psType.h"24 # include "psType.h" 24 25 25 26 /// @addtogroup Image … … 39 40 typedef struct psImage 40 41 { 41 const psType type; ///< Image data type and dimension.42 const unsigned int numCols; ///< Number of columns in image43 const unsigned int numRows; ///< Number of rows in image.44 const int col0; ///< Column position relative to parent.45 const int row0; ///< Row position relative to parent.42 const psType type; // /< Image data type and dimension. 43 const unsigned int numCols; // /< Number of columns in image 44 const unsigned int numRows; // /< Number of rows in image. 45 const int col0; // /< Column position relative to parent. 46 const int row0; // /< Row position relative to parent. 46 47 47 48 union { 48 psU8 **U8; ///< Unsigned 8-bit integer data.49 psU16 **U16; ///< Unsigned 16-bit integer data.50 psU32 **U32; ///< Unsigned 32-bit integer data.51 psU64 **U64; ///< Unsigned 64-bit integer data.52 psS8 **S8; ///< Signed 8-bit integer data.53 psS16 **S16; ///< Signed 16-bit integer data.54 psS32 **S32; ///< Signed 32-bit integer data.55 psS64 **S64; ///< Signed 64-bit integer data.56 psF32 **F32; ///< Single-precision float data.57 psF64 **F64; ///< Double-precision float data.58 psC32 **C32; ///< Single-precision complex data.59 psC64 **C64; ///< Double-precision complex data.60 psPTR **PTR; ///< Void pointers.61 psPTR *V; ///< Pointer to data.62 } data; ///< Union for data types.63 const struct psImage *parent; // /< Parent, if a subimage.64 int nChildren; ///< Number of subimages.65 struct psImage ** children; ///< Children of this region.49 psU8 **U8; // /< Unsigned 8-bit integer data. 50 psU16 **U16; // /< Unsigned 16-bit integer data. 51 psU32 **U32; // /< Unsigned 32-bit integer data. 52 psU64 **U64; // /< Unsigned 64-bit integer data. 53 psS8 **S8; // /< Signed 8-bit integer data. 54 psS16 **S16; // /< Signed 16-bit integer data. 55 psS32 **S32; // /< Signed 32-bit integer data. 56 psS64 **S64; // /< Signed 64-bit integer data. 57 psF32 **F32; // /< Single-precision float data. 58 psF64 **F64; // /< Double-precision float data. 59 psC32 **C32; // /< Single-precision complex data. 60 psC64 **C64; // /< Double-precision complex data. 61 psPTR **PTR; // /< Void pointers. 62 psPTR *V; // /< Pointer to data. 63 } data; // /< Union for data types. 64 const struct psImage *parent; // /< Parent, if a subimage. 65 int nChildren; // /< Number of subimages. 66 struct psImage **children; // /< Children of this region. 66 67 } 67 68 psImage; 68 69 69 70 /*****************************************************************************/ 71 70 72 /* FUNCTION PROTOTYPES */ 73 71 74 /*****************************************************************************/ 72 73 75 74 76 /** Create an image of the specified size and type. … … 80 82 * 81 83 */ 82 psImage *psImageAlloc( 83 unsigned int numCols, ///< Number of rows in image. 84 unsigned int numRows, ///< Number of columns in image. 85 const psElemType type ///< Type of data for image. 86 ); 84 psImage *psImageAlloc(unsigned int numCols, // /< Number of rows in image. 85 unsigned int numRows, // /< Number of columns in image. 86 const psElemType type // /< Type of data for image. 87 ); 87 88 88 89 /** Resize a given image to the given size/type. … … 91 92 * 92 93 */ 93 psImage* psImageRecycle( 94 psImage* old, ///< the psImage to recycle by resizing image buffer 95 unsigned int numCols, ///< the desired number of columns in image 96 unsigned int numRows, ///< the desired number of rows in image 97 const psElemType type ///< the desired datatype of the image 98 ); 99 94 psImage *psImageRecycle(psImage * old, // /< the psImage to recycle by resizing image buffer 95 unsigned int numCols, // /< the desired number of columns in image 96 unsigned int numRows, // /< the desired number of rows in image 97 const psElemType type // /< the desired datatype of the image 98 ); 100 99 101 100 /** Frees all children of a psImage. … … 104 103 * 105 104 */ 106 int psImageFreeChildren( 107 psImage* image 108 /**< psImage in which all children shall be deallocated */ 109 ); 105 int psImageFreeChildren(psImage * image 110 106 111 psF32 psImagePixelInterpolate( 112 const psImage *input, 113 float x, 114 float y, 115 psF32 unexposedValue, 116 psImageInterpolateMode mode 117 ); 107 /**< psImage in which all children shall be deallocated */ 108 ); 118 109 119 #define p_psImagePixelInterpolateFcns(TYPE) \ 110 psF32 psImagePixelInterpolate(const psImage * input, 111 float x, float y, psF32 unexposedValue, psImageInterpolateMode mode); 112 113 # define p_psImagePixelInterpolateFcns(TYPE) \ 120 114 inline psF64 p_psImagePixelInterpolateFLAT_##TYPE( \ 121 115 const psImage *input, \ … … 131 125 ); 132 126 133 # define p_psImagePixelInterpolateComplexFcns(TYPE) \127 # define p_psImagePixelInterpolateComplexFcns(TYPE) \ 134 128 inline psC64 p_psImagePixelInterpolateFLAT_##TYPE( \ 135 129 const psImage *input, \ … … 157 151 p_psImagePixelInterpolateComplexFcns(C32) 158 152 p_psImagePixelInterpolateComplexFcns(C64) 159 160 153 /// @} 161 162 154 #endif -
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 -
trunk/psLib/src/image/psImageExtraction.h
r1404 r1407 1 1 2 /** @file psImageExtraction.h 2 3 * … … 9 10 * @author Robert DeSonia, MHPCC 10 11 * 11 * @version $Revision: 1. 5$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-08-0 6 21:50:13$12 * @version $Revision: 1.6 $ $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 … … 16 17 17 18 #ifndef PSIMAGEEXTRACTION_H 18 # define PSIMAGEEXTRACTION_H19 # define PSIMAGEEXTRACTION_H 19 20 20 # include "psImage.h"21 # include "psVector.h"22 # include "psStats.h"21 # include "psImage.h" 22 # include "psVector.h" 23 # include "psStats.h" 23 24 24 25 /// @addtogroup Image … … 40 41 * 41 42 */ 42 psImage *psImageSubset( 43 psImage *out, ///< Subimage to return, or NULL. 44 psImage *image, ///< Parent image. 45 unsigned int numCols, ///< Subimage width (<= image.nCols - col0). 46 unsigned int numRows, ///< Subimage height (<= image.nRows - row0). 47 unsigned int col0, ///< Subimage col-offset (0 <= col0 < nCol). 48 unsigned int row0 ///< Subimage row-offset (0 <= row0 < nCol). 49 ); 43 psImage *psImageSubset(psImage * out, // /< Subimage to return, or NULL. 44 psImage * image, // /< Parent image. 45 unsigned int numCols, // /< Subimage width (<= image.nCols - col0). 46 unsigned int numRows, // /< Subimage height (<= image.nRows - row0). 47 unsigned int col0, // /< Subimage col-offset (0 <= col0 < nCol). 48 unsigned int row0 // /< Subimage row-offset (0 <= row0 < nCol). 49 ); 50 50 51 51 /** Makes a copy of a psImage … … 55 55 * 56 56 */ 57 psImage *psImageCopy( 58 psImage* restrict output, 59 /**< if not NULL, a psImage that could be recycled. If it can not be used, 60 * it will be freed via psImageFree 61 */ 62 const psImage *input, 63 /**< the psImage to copy */ 64 psElemType type 65 /**< the desired datatype of the returned copy */ 66 ); 57 psImage *psImageCopy(psImage * restrict output, 67 58 68 psVector* psImageSlice( 69 psVector* out, 70 psVector* slicePositions, 71 const psImage* restrict input, 72 const psImage* restrict mask, 73 unsigned int maskVal, 74 unsigned int col, 75 unsigned int row, 76 unsigned int numCols, 77 unsigned int numRows, 78 psImageCutDirection direction, 79 const psStats* stats 80 ); 59 /**< if not NULL, a psImage that could be recycled. If it can not be used, 60 * it will be freed via psImageFree 61 */ 62 const psImage * input, 81 63 82 psVector* psImageCut( 83 psVector* out, 84 const psImage* input, 85 const psImage* restrict mask, 86 unsigned int maskVal, 87 float startCol, 88 float startRow, 89 float endCol, 90 float endRow, 91 float width, 92 const psStats* stats 93 ); 64 /**< the psImage to copy */ 65 psElemType type 94 66 95 psVector* psImageRadialCut( 96 psVector* out, 97 const psImage* input, 98 const psImage* restrict mask, 99 unsigned int maskVal, 100 float centerCol, 101 float centerRow, 102 const psVector* radii, 103 const psStats* stats 104 ); 67 /**< the desired datatype of the returned copy */ 68 ); 69 70 psVector *psImageSlice(psVector * out, 71 psVector * slicePositions, 72 const psImage * restrict input, 73 const psImage * restrict mask, 74 unsigned int maskVal, 75 unsigned int col, 76 unsigned int row, 77 unsigned int numCols, 78 unsigned int numRows, psImageCutDirection direction, const psStats * stats); 79 80 psVector *psImageCut(psVector * out, 81 const psImage * input, 82 const psImage * restrict mask, 83 unsigned int maskVal, 84 float startCol, 85 float startRow, float endCol, float endRow, float width, const psStats * stats); 86 87 psVector *psImageRadialCut(psVector * out, 88 const psImage * input, 89 const psImage * restrict mask, 90 unsigned int maskVal, 91 float centerCol, float centerRow, const psVector * radii, const psStats * stats); 105 92 106 93 /// @} -
trunk/psLib/src/image/psImageIO.c
r1406 r1407 1 1 2 /** @file psImageIO.c 2 3 * … … 7 8 * @author Robert DeSonia, MHPCC 8 9 * 9 * @version $Revision: 1. 8$ $Name: not supported by cvs2svn $10 * @date $Date: 2004-08-0 6 22:34:05$10 * @version $Revision: 1.9 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2004-08-07 00:06:06 $ 11 12 * 12 13 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 21 22 #include "psMemory.h" 22 23 23 psImage* psImageReadSection(psImage* output, int col, int row, int numCols, 24 int numRows, int z, char* extname, int extnum, char* filename) 24 psImage *psImageReadSection(psImage * output, 25 int col, 26 int row, 27 int numCols, int numRows, int z, char *extname, int extnum, char *filename) 25 28 { 26 fitsfile *fptr=NULL; /*Pointer to the FITS file*/27 int status=0; /*CFITSIO file vars*/28 int nAxis=0;29 int anynull=0;30 int bitPix=0; /*Pixel type*/31 long nAxes[3];32 long firstPixel[3];/* lower-left corner of image subset */33 long lastPixel[3];/* upper-right corner of image subset */34 long increment[3];/* increment for image subset */35 char fitsErr[80] = ""; /*CFITSIO error message string */36 int hduType = IMAGE_HDU;37 int fitsDatatype = 0;38 int datatype = 0;29 fitsfile *fptr = NULL; /* Pointer to the FITS file */ 30 int status = 0; /* CFITSIO file vars */ 31 int nAxis = 0; 32 int anynull = 0; 33 int bitPix = 0; /* Pixel type */ 34 long nAxes[3]; 35 long firstPixel[3]; /* lower-left corner of image subset */ 36 long lastPixel[3]; /* upper-right corner of image subset */ 37 long increment[3]; /* increment for image subset */ 38 char fitsErr[80] = ""; /* CFITSIO error message string */ 39 int hduType = IMAGE_HDU; 40 int fitsDatatype = 0; 41 int datatype = 0; 39 42 40 43 if (filename == NULL) { 41 psError(__func__, "Must specify filename; it can not be NULL.");44 psError(__func__, "Must specify filename; it can not be NULL."); 42 45 psFree(output); 43 46 return NULL; … … 47 50 (void)fits_open_file(&fptr, filename, READONLY, &status); 48 51 if (fptr == NULL || status != 0) { 49 fits_get_errstatus(status,fitsErr); 50 psError(__func__,"Could not open file '%s'. (%s)", 51 filename, fitsErr); 52 fits_get_errstatus(status, fitsErr); 53 psError(__func__, "Could not open file '%s'. (%s)", filename, fitsErr); 52 54 psFree(output); 53 55 return NULL; … … 56 58 /* find the specified extension */ 57 59 if (extname != NULL) { 58 if (fits_movnam_hdu(fptr, hduType, extname, 0, &status) != 0) {60 if (fits_movnam_hdu(fptr, hduType, extname, 0, &status) != 0) { 59 61 fits_get_errstatus(status, fitsErr); 60 62 status = 0; 61 63 (void)fits_close_file(fptr, &status); 62 psError(__func__,"Could not index to '%s' HDU for file %s. (%s)", 63 extname, filename, fitsErr); 64 psError(__func__, "Could not index to '%s' HDU for file %s. (%s)", extname, filename, fitsErr); 64 65 psFree(output); 65 66 return NULL; 66 67 } 67 68 } else { 68 if (fits_movabs_hdu(fptr, extnum +1, &hduType, &status) != 0) {69 if (fits_movabs_hdu(fptr, extnum + 1, &hduType, &status) != 0) { 69 70 fits_get_errstatus(status, fitsErr); 70 71 status = 0; 71 72 (void)fits_close_file(fptr, &status); 72 psError(__func__,"Could not index to HDU #%d for file %s. (%s)", 73 extnum, filename, fitsErr); 73 psError(__func__, "Could not index to HDU #%d for file %s. (%s)", extnum, filename, fitsErr); 74 74 psFree(output); 75 75 return NULL; … … 82 82 status = 0; 83 83 (void)fits_close_file(fptr, &status); 84 psError("Could not determine image data type of '%s'. (%s)", 85 filename, fitsErr); 84 psError("Could not determine image data type of '%s'. (%s)", filename, fitsErr); 86 85 psFree(output); 87 86 return NULL; … … 93 92 status = 0; 94 93 (void)fits_close_file(fptr, &status); 95 psError("Could not determine dimensions of '%s'. (%s)", 96 filename,fitsErr); 94 psError("Could not determine dimensions of '%s'. (%s)", filename, fitsErr); 97 95 psFree(output); 98 96 return NULL; … … 100 98 101 99 /* Validate the number of axis */ 102 if ( (nAxis < 2) || (nAxis > 3) ) { 103 status=0; 104 (void)fits_close_file(fptr, &status); 105 psError("Dimensions of '%s' are not supported (NAXIS=%i).", 106 filename, nAxis); 107 psFree(output); 108 return NULL; 109 } 110 111 /* Get the Image size from the FITS file */ 112 if ( fits_get_img_size(fptr, nAxis, nAxes, &status) != 0) { 100 if ((nAxis < 2) || (nAxis > 3)) { 101 status = 0; 102 (void)fits_close_file(fptr, &status); 103 psError("Dimensions of '%s' are not supported (NAXIS=%i).", filename, nAxis); 104 psFree(output); 105 return NULL; 106 } 107 108 /* Get the Image size from the FITS file */ 109 if (fits_get_img_size(fptr, nAxis, nAxes, &status) != 0) { 113 110 (void)fits_get_errstatus(status, fitsErr); 114 111 status = 0; 115 112 (void)fits_close_file(fptr, &status); 116 psError("Could not determine image size of '%s'. (%s)", 117 filename,fitsErr); 113 psError("Could not determine image size of '%s'. (%s)", filename, fitsErr); 118 114 psFree(output); 119 115 return NULL; … … 127 123 } 128 124 129 firstPixel[0] = col +1;130 firstPixel[1] = row +1;131 firstPixel[2] = z +1;125 firstPixel[0] = col + 1; 126 firstPixel[1] = row + 1; 127 firstPixel[2] = z + 1; 132 128 133 129 lastPixel[0] = firstPixel[0] + numCols - 1; 134 130 lastPixel[1] = firstPixel[1] + numRows - 1; 135 lastPixel[2] = z +1;131 lastPixel[2] = z + 1; 136 132 137 133 increment[0] = 1; … … 139 135 increment[2] = 1; 140 136 141 // turn off the BSCALE/BZERO processing in CFITSIO 142 // (void)fits_set_bscale(fptr, 1.0,0.0,&status); 137 // turn off the BSCALE/BZERO processing in 138 // CFITSIO 139 // (void)fits_set_bscale(fptr, 140 // 1.0,0.0,&status); 143 141 144 142 switch (bitPix) { … … 180 178 break; 181 179 default: 182 psError(__func__, "Unsupported bitpix value (%d) in FITS file %s.",183 bitPix,filename);184 psFree(output);185 return NULL;186 }187 output = psImageRecycle(output,numCols,numRows,datatype);188 if (fits_read_subset(fptr, fitsDatatype, firstPixel, lastPixel, increment,189 NULL, output->data.V[0], &anynull, &status) != 0) {180 psError(__func__, "Unsupported bitpix value (%d) in FITS file %s.", bitPix, filename); 181 psFree(output); 182 return NULL; 183 } 184 output = psImageRecycle(output, numCols, numRows, datatype); 185 if (fits_read_subset 186 (fptr, fitsDatatype, firstPixel, 187 lastPixel, increment, NULL, output->data.V[0], &anynull, &status) != 0) { 190 188 psFree(output); 191 189 (void)fits_get_errstatus(status, fitsErr); 192 190 status = 0; 193 191 (void)fits_close_file(fptr, &status); 194 psError(__func__,"Failed to read image [%s]", 195 filename, fitsErr); 192 psError(__func__, "Failed to read image [%s]", filename, fitsErr); 196 193 return NULL; 197 194 } … … 202 199 } 203 200 204 205 bool psImageWriteSection(psImage* input, int col0,int row0,int z, 206 char* extname, int extnum, char* filename) 201 bool psImageWriteSection(psImage * input, int col0, int row0, int z, char *extname, int extnum, 202 char *filename) 207 203 { 208 int numCols = 0;209 int numRows = 0;210 211 int status=0; /* CFITSIOstatus */212 fitsfile *fptr=NULL;/* pointer to the FITS file */213 long nAxes[3];/* Image axis vars */214 long firstPixel[3];/* First Pixel to read */215 long lastPixel[3];/* Last Pixel to read */216 char fitsErr[80];/* FITSIO message string */217 int datatype = 0; /* the datatype of the image */218 int bitPix = 0; /* FITS bitPix value */219 int hduType = IMAGE_HDU; /* the HDU type (image,table, etc.) */220 double bscale = 1.0;221 double bzero = 0.0;222 bool createNewHDU = false;204 int numCols = 0; 205 int numRows = 0; 206 207 int status = 0; /* CFITSIO status */ 208 fitsfile *fptr = NULL; /* pointer to the FITS file */ 209 long nAxes[3]; /* Image axis vars */ 210 long firstPixel[3]; /* First Pixel to read */ 211 long lastPixel[3]; /* Last Pixel to read */ 212 char fitsErr[80]; /* FITSIO message string */ 213 int datatype = 0; /* the datatype of the image */ 214 int bitPix = 0; /* FITS bitPix value */ 215 int hduType = IMAGE_HDU; /* the HDU type (image,table, etc.) */ 216 double bscale = 1.0; 217 double bzero = 0.0; 218 bool createNewHDU = false; 223 219 224 220 /* need a valid image to write */ 225 if(input==NULL) { 226 psError(__func__, "Can not write %s. Input psImage is NULL.", 227 filename); 221 if (input == NULL) { 222 psError(__func__, "Can not write %s. Input psImage is NULL.", filename); 228 223 return false; 229 224 } … … 244 239 case PS_TYPE_U16: 245 240 bitPix = SHORT_IMG; 246 bzero = -1.0f *INT16_MIN;241 bzero = -1.0f * INT16_MIN; 247 242 datatype = TUSHORT; 248 243 break; … … 253 248 case PS_TYPE_U32: 254 249 bitPix = LONG_IMG; 255 bzero = -1.0f *INT32_MIN;250 bzero = -1.0f * INT32_MIN; 256 251 datatype = TUINT; 257 252 break; … … 269 264 break; 270 265 default: 271 psError(__func__, "psImage datatype (%d) not supported. File %s not written.",272 input->type.type,filename);266 psError(__func__, 267 "psImage datatype (%d) not supported. File %s not written.", input->type.type, filename); 273 268 return false; 274 269 } 275 270 276 271 /* Open the FITS file */ 277 if (access(filename, F_OK) == 0) { // file exists 272 if (access(filename, F_OK) == 0) { // file 273 // exists 278 274 (void)fits_open_file(&fptr, filename, READWRITE, &status); 279 275 if (fptr == NULL || status != 0) { 280 fits_get_errstatus(status,fitsErr); 281 psError(__func__,"Could not open file '%s'. FITS error:%s", 282 filename, fitsErr); 276 fits_get_errstatus(status, fitsErr); 277 psError(__func__, "Could not open file '%s'. FITS error:%s", filename, fitsErr); 283 278 return false; 284 279 } … … 286 281 /* find the specified extension */ 287 282 if (extname != NULL) { 288 if (fits_movnam_hdu(fptr, hduType, extname, 0, &status) != 0) {283 if (fits_movnam_hdu(fptr, hduType, extname, 0, &status) != 0) { 289 284 fits_get_errstatus(status, fitsErr); 290 285 status = 0; 291 286 (void)fits_close_file(fptr, &status); 292 psError(__func__, "Could not index to '%s' HDU for file %s. (%s)",293 extname, filename, fitsErr);287 psError(__func__, 288 "Could not index to '%s' HDU for file %s. (%s)", extname, filename, fitsErr); 294 289 return false; 295 290 } 296 291 } else { 297 292 int numHDUs = 0; 298 fits_get_num_hdus(fptr,&numHDUs,&status); 293 294 fits_get_num_hdus(fptr, &numHDUs, &status); 299 295 if (numHDUs < extnum) { 300 296 status = 0; 301 297 (void)fits_close_file(fptr, &status); 302 psError(__func__, "extnum (%d) must not exceed number of HDUs (%d) by more than one.",303 extnum, numHDUs);298 psError(__func__, 299 "extnum (%d) must not exceed number of HDUs (%d) by more than one.", extnum, numHDUs); 304 300 return false; 305 } else 306 if (numHDUs == extnum) {307 createNewHDU = true;308 } else309 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 }317 }318 319 } else { // file does notexist320 321 (void)fits_create_file(&fptr, filename,&status);301 } else if (numHDUs == extnum) { 302 createNewHDU = true; 303 } else if (fits_movabs_hdu(fptr, extnum + 1, &hduType, &status) != 0) { 304 fits_get_errstatus(status, fitsErr); 305 status = 0; 306 (void)fits_close_file(fptr, &status); 307 psError(__func__, "Could not index to HDU #%d for file %s. (%s)", extnum, filename, fitsErr); 308 return false; 309 } 310 } 311 312 } else { // file 313 // does 314 // not 315 // exist 316 317 (void)fits_create_file(&fptr, filename, &status); 322 318 if (fptr == NULL || status != 0) { 323 fits_get_errstatus(status,fitsErr); 324 psError(__func__,"Could not create file '%s'. (%s)", 325 filename, fitsErr); 319 fits_get_errstatus(status, fitsErr); 320 psError(__func__, "Could not create file '%s'. (%s)", filename, fitsErr); 326 321 return false; 327 322 } … … 330 325 331 326 if (createNewHDU) { 332 /* create the mandatory image keywords */333 nAxes[0] = col0 +numCols;334 nAxes[1] = row0 +numRows;335 nAxes[2] = z +1;327 /* create the mandatory image keywords */ 328 nAxes[0] = col0 + numCols; 329 nAxes[1] = row0 + numRows; 330 nAxes[2] = z + 1; 336 331 if (fits_create_img(fptr, bitPix, 3, nAxes, &status) != 0) { 337 332 (void)fits_get_errstatus(status, fitsErr); 338 333 status = 0; 339 334 (void)fits_close_file(fptr, &status); 340 psError(__func__,"Could not create image HDU in FITS file '%s'. %s", 341 filename, fitsErr); 335 psError(__func__, "Could not create image HDU in FITS file '%s'. %s", filename, fitsErr); 342 336 return false; 343 337 } 344 345 338 // set the bscale/bzero 346 fits_write_key_dbl(fptr, "BZERO", bzero,12,"Pixel Value Offset",&status);347 fits_write_key_dbl(fptr, "BSCALE", bscale,12,"Pixel Value Scale",&status);348 fits_set_bscale(fptr, bscale,bzero,&status);339 fits_write_key_dbl(fptr, "BZERO", bzero, 12, "Pixel Value Offset", &status); 340 fits_write_key_dbl(fptr, "BSCALE", bscale, 12, "Pixel Value Scale", &status); 341 fits_set_bscale(fptr, bscale, bzero, &status); 349 342 350 343 if (extname != NULL) { … … 354 347 status = 0; 355 348 (void)fits_close_file(fptr, &status); 356 psError(__func__, "Could not create EXTNAME keyword in FITS file '%s'. (%s)",357 filename, fitsErr);349 psError(__func__, 350 "Could not create EXTNAME keyword in FITS file '%s'. (%s)", filename, fitsErr); 358 351 return false; 359 352 } … … 361 354 } 362 355 363 firstPixel[0] = col0 +1;364 firstPixel[1] = row0 +1;365 firstPixel[2] = z +1;356 firstPixel[0] = col0 + 1; 357 firstPixel[1] = row0 + 1; 358 firstPixel[2] = z + 1; 366 359 367 360 lastPixel[0] = firstPixel[0] + numCols - 1; 368 361 lastPixel[1] = firstPixel[1] + numRows - 1; 369 lastPixel[2] = z +1;370 371 if ( fits_write_subset(fptr, datatype, firstPixel, lastPixel, input->data.V[0], &status) != 0) {362 lastPixel[2] = z + 1; 363 364 if (fits_write_subset(fptr, datatype, firstPixel, lastPixel, input->data.V[0], &status) != 0) { 372 365 (void)fits_get_errstatus(status, fitsErr); 373 366 status = 0; 374 367 (void)fits_close_file(fptr, &status); 375 psError(__func__, "Could not write image data to '%s'. (%s)", 376 filename, fitsErr); 368 psError(__func__, "Could not write image data to '%s'. (%s)", filename, fitsErr); 377 369 return false; 378 370 } -
trunk/psLib/src/image/psImageIO.h
r1241 r1407 1 1 2 /** @file psImageIO.h 2 3 * … … 9 10 * @author Robert DeSonia, MHPCC 10 11 * 11 * @version $Revision: 1. 3$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-0 7-19 22:01:19$12 * @version $Revision: 1.4 $ $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 15 16 */ 16 # ifndef PS_IMAGEIO_H17 # define PS_IMAGEIO_H17 #ifndef PS_IMAGEIO_H 18 # define PS_IMAGEIO_H 18 19 19 # include <stdbool.h>20 # include <stdbool.h> 20 21 21 # include "psImage.h"22 # include "psImage.h" 22 23 23 24 /// @addtogroup ImageIO … … 29 30 * signifies that a problem had occured. 30 31 */ 31 psImage* psImageReadSection( 32 psImage* output, 33 /**< the output psImage to recycle, or NULL if new psImage desired */ 34 int col0, 35 /**< the column index of the origin to start reading */ 36 int row0, 37 /**< the row index of the origin to start reading */ 38 int numCols, 39 /**< the number of desired columns to read */ 40 int numRows, 41 /**< the number of desired rows to read */ 42 int z, 43 /**< the z index to read if file is organized as a 3D image cube. */ 44 char* extname, 45 /**< the image extension to read (this should match the EXTNAME keyword in 46 * the extension If NULL, the extnum parameter is to be used instead 47 */ 48 int extnum, 49 /**< the image extension to read (0=PHU, 1=first extension, etc.) This is 50 * only used if extname is NULL 51 */ 52 char* filename 53 /**< the filename of the FITS image file to read */ 54 ); 32 psImage *psImageReadSection(psImage * output, 33 34 /**< the output psImage to recycle, or NULL if new psImage desired */ 35 int col0, 36 37 /**< the column index of the origin to start reading */ 38 int row0, 39 40 /**< the row index of the origin to start reading */ 41 int numCols, 42 43 /**< the number of desired columns to read */ 44 int numRows, 45 46 /**< the number of desired rows to read */ 47 int z, 48 49 /**< the z index to read if file is organized as a 3D image cube. */ 50 char *extname, 51 52 /**< the image extension to read (this should match the EXTNAME keyword in 53 * the extension If NULL, the extnum parameter is to be used instead 54 */ 55 int extnum, 56 57 /**< the image extension to read (0=PHU, 1=first extension, etc.) This is 58 * only used if extname is NULL 59 */ 60 char *filename 61 62 /**< the filename of the FITS image file to read */ 63 ); 55 64 56 65 /** Read an image or subimage from a FITS file specified by a filename. … … 58 67 * return bool TRUE is successful, otherwise FALSE. 59 68 */ 60 bool psImageWriteSection( 61 psImage* input, 62 /**< the psImage to write */ 63 int col0, 64 /**< the column index of the origin to start writing */ 65 int row0, 66 /**< the row index of the origin to start writing */ 67 int z, 68 /**< the z index to start writing */ 69 char* extname, 70 /**< the image extension to write (this should match the EXTNAME keyword in 71 * the extension If NULL, the extnum parameter is to be used instead 72 */ 73 int extnum, 74 /**< the image extension to write (0=PHU, 1=first extension, etc.) This is 75 * only used if extname is NULL. 76 */ 77 char* filename 78 /**< the filename of the FITS image file to write */ 79 ); 69 bool psImageWriteSection(psImage * input, 70 71 /**< the psImage to write */ 72 int col0, 73 74 /**< the column index of the origin to start writing */ 75 int row0, 76 77 /**< the row index of the origin to start writing */ 78 int z, 79 80 /**< the z index to start writing */ 81 char *extname, 82 83 /**< the image extension to write (this should match the EXTNAME keyword in 84 * the extension If NULL, the extnum parameter is to be used instead 85 */ 86 int extnum, 87 88 /**< the image extension to write (0=PHU, 1=first extension, etc.) This is 89 * only used if extname is NULL. 90 */ 91 char *filename 92 93 /**< the filename of the FITS image file to write */ 94 ); 80 95 81 96 /// @} -
trunk/psLib/src/image/psImageManip.c
r1406 r1407 1 1 2 /** @file psImageManip.c 2 3 * … … 10 11 * @author Ross Harman, MHPCC 11 12 * 12 * @version $Revision: 1.1 0$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-08-0 6 22:34:05$13 * @version $Revision: 1.11 $ $Name: not supported by cvs2svn $ 14 * @date $Date: 2004-08-07 00:06:06 $ 14 15 * 15 16 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii 16 17 */ 17 #include <math.h> // for isfinite(), etc. 18 #include <math.h> // for 19 // isfinite(), 20 // etc. 18 21 #include <stdlib.h> 19 22 #include <stdbool.h> 20 #include <string.h> // for memcpy, etc. 23 #include <string.h> // for 24 // memcpy, 25 // etc. 21 26 22 27 #include "psError.h" … … 26 31 #include "psImageExtraction.h" 27 32 28 int psImageClip(psImage * input, psF64 min, psF64 vmin, psF64 max, psF64 vmax)33 int psImageClip(psImage * input, psF64 min, psF64 vmin, psF64 max, psF64 vmax) 29 34 { 30 35 int numClipped = 0; … … 37 42 38 43 if (max < min) { 39 psError(__func__, "psImageClip can not be invoked with max < min.");44 psError(__func__, "psImageClip can not be invoked with max < min."); 40 45 return 0; 41 46 } … … 100 105 break; 101 106 102 psImageClipCase(S8, "psS8")103 psImageClipCase(S16, "psS16")104 psImageClipCase(S32, "psS32")105 psImageClipCase(S64, "psS64")106 psImageClipCase(U8, "psU8")107 psImageClipCase(U16, "psU16")108 psImageClipCase(U32, "psU32")109 psImageClipCase(U64, "psU64")110 psImageClipCase(F32, "psF32")111 psImageClipCase(F64, "psF64")112 psImageClipCaseComplex(C32, "psC32",cabsf)113 psImageClipCaseComplex(C64, "psC64",cabs)107 psImageClipCase(S8, "psS8") 108 psImageClipCase(S16, "psS16") 109 psImageClipCase(S32, "psS32") 110 psImageClipCase(S64, "psS64") 111 psImageClipCase(U8, "psU8") 112 psImageClipCase(U16, "psU16") 113 psImageClipCase(U32, "psU32") 114 psImageClipCase(U64, "psU64") 115 psImageClipCase(F32, "psF32") 116 psImageClipCase(F64, "psF64") 117 psImageClipCaseComplex(C32, "psC32", cabsf) 118 psImageClipCaseComplex(C64, "psC64", cabs) 114 119 115 120 default: 116 psError(__func__,"psImageClip does not support the given datatype (%d)", 117 input->type.type); 121 psError(__func__, "psImageClip does not support the given datatype (%d)", input->type.type); 118 122 } 119 123 … … 121 125 } 122 126 123 int psImageClipNaN(psImage * input,psF64 value)127 int psImageClipNaN(psImage * input, psF64 value) 124 128 { 125 129 int numClipped = 0; … … 154 158 155 159 default: 156 psError(__func__,"psImageClip does not support the given datatype (%d)", 157 input->type.type); 160 psError(__func__, "psImageClip does not support the given datatype (%d)", input->type.type); 158 161 } 159 162 … … 161 164 } 162 165 163 int psImageOverlaySection(psImage* image, const psImage* overlay, int col0, 164 int row0, const char* op) 166 int psImageOverlaySection(psImage * image, const psImage * overlay, int col0, int row0, const char *op) 165 167 { 166 168 unsigned int imageNumRows; … … 170 172 unsigned int imageRowLimit; 171 173 unsigned int imageColLimit; 172 psElemType type;174 psElemType type; 173 175 174 176 if (image == NULL || overlay == NULL) { 175 psError(__func__, "one of the input images was NULL.");177 psError(__func__, "one of the input images was NULL."); 176 178 return 1; 177 179 } 178 180 179 181 if (op == NULL) { 180 psError(__func__, "Operation can not be NULL.");182 psError(__func__, "Operation can not be NULL."); 181 183 return 1; 182 184 } … … 185 187 186 188 if (type != overlay->type.type) { 187 psError(__func__,"Image and overlay datatypes must match. (%d vs %d)", 188 type,overlay->type.type); 189 psError(__func__, "Image and overlay datatypes must match. (%d vs %d)", type, overlay->type.type); 189 190 return 2; 190 191 } … … 197 198 /* check row0/col0 to see if it is within the image size */ 198 199 if (row0 < 0 || col0 < 0 || row0 >= imageNumRows || col0 >= imageNumCols) { 199 psError(__func__, "Overlay origin of (%d,%d) is outside of the image dimensions (%d x %d).", 200 psError(__func__, 201 "Overlay origin of (%d,%d) is outside of the image dimensions (%d x %d).", 200 202 col0, row0, imageNumCols, imageNumRows); 201 203 return 3; … … 203 205 204 206 /* check if overlay is totally withing input image */ 205 imageRowLimit = row0 +overlayNumRows;206 imageColLimit = col0 +overlayNumCols;207 imageRowLimit = row0 + overlayNumRows; 208 imageColLimit = col0 + overlayNumCols; 207 209 if (imageRowLimit > imageNumRows || imageColLimit > imageNumCols) { 208 psError(__func__, "Overlay image (%d,%d -> %d,%d) is partially outside" 210 psError(__func__, 211 "Overlay image (%d,%d -> %d,%d) is partially outside" 209 212 " of the input image (%d x %d).", 210 col0, row0, col0+overlayNumCols-1, row0+overlayNumRows-1, 211 imageNumCols,imageNumRows); 213 col0, row0, col0 + overlayNumCols - 1, row0 + overlayNumRows - 1, imageNumCols, imageNumRows); 212 214 return 4; 213 215 } … … 259 261 260 262 default: 261 psError(__func__, "Can not operate on type %d.",type);263 psError(__func__, "Can not operate on type %d.", type); 262 264 } 263 265 … … 265 267 } 266 268 267 int psImageClipComplexRegion(psImage * input, psC64 min, psC64 vmin, psC64 max, psC64 vmax)269 int psImageClipComplexRegion(psImage * input, psC64 min, psC64 vmin, psC64 max, psC64 vmax) 268 270 { 269 271 int numClipped = 0; … … 276 278 277 279 if (input == NULL) { 278 psError(__func__, "Can not perform clip on NULL image");280 psError(__func__, "Can not perform clip on NULL image"); 279 281 return 0; 280 282 } 281 283 282 if ( realMax < realMin) {283 psError(__func__, "psImageClipComplexRegion can not be invoked with "284 " max < min in the real image space.");284 if (realMax < realMin) { 285 psError(__func__, 286 "psImageClipComplexRegion can not be invoked with " "max < min in the real image space."); 285 287 return 0; 286 288 } 287 if ( imagMax < imagMin ) { 288 psError(__func__,"psImageClipComplexRegion can not be invoked with " 289 if (imagMax < imagMin) { 290 psError(__func__, 291 "psImageClipComplexRegion can not be invoked with " 289 292 "max < min in the imaginary image space."); 290 293 return 0; … … 294 297 numCols = input->numCols; 295 298 299 #define psImageClipComplexRegionCase(type,typename,realfcn,imagfcn) \ 300 case PS_TYPE_##type: { \ 301 if (realfcn(vmin) < PS_MIN_##type || imagfcn(vmin) < PS_MIN_##type || \ 302 realfcn(vmin) > PS_MAX_##type || imagfcn(vmin) > PS_MAX_##type ) { \ 303 psError(__func__, "Specified vmin (%g%+gi) is outside of image's " \ 304 typename " pixel range", \ 305 creal(vmin),cimag(vmin)); \ 306 break; \ 307 } \ 308 if (realfcn(vmax) > PS_MAX_##type || imagfcn(vmax) > PS_MAX_##type || \ 309 realfcn(vmax) < PS_MIN_##type || imagfcn(vmax) < PS_MIN_##type ) { \ 310 psError(__func__, "Specified vmax (%g%+gi) is outside of image's " \ 311 typename " pixel range", \ 312 creal(vmax),cimag(vmax)); \ 313 break; \ 314 } \ 315 for (unsigned int row = 0;row<numRows;row++) { \ 316 ps##type* inputRow = input->data.type[row]; \ 317 for (unsigned int col = 0; col < numCols; col++) { \ 318 if ( (realfcn(inputRow[col]) > realMax) || (imagfcn(inputRow[col]) > imagMax) ) { \ 319 inputRow[col] = (ps##type)vmax; \ 320 numClipped++; \ 321 } else if ( (realfcn(inputRow[col]) < realMin) || (imagfcn(inputRow[col]) < imagMin) ){ \ 322 inputRow[col] = (ps##type)vmin; \ 323 numClipped++; \ 324 } \ 325 } \ 326 } \ 327 } \ 328 break; 329 296 330 switch (input->type.type) { 297 331 298 #define psImageClipComplexRegionCase(type,typename,realfcn,imagfcn) \ 299 case PS_TYPE_##type: { \ 300 if (realfcn(vmin) < PS_MIN_##type || imagfcn(vmin) < PS_MIN_##type || \ 301 realfcn(vmin) > PS_MAX_##type || imagfcn(vmin) > PS_MAX_##type ) { \ 302 psError(__func__, "Specified vmin (%g%+gi) is outside of image's " \ 303 typename " pixel range", \ 304 creal(vmin),cimag(vmin)); \ 305 break; \ 306 } \ 307 if (realfcn(vmax) > PS_MAX_##type || imagfcn(vmax) > PS_MAX_##type || \ 308 realfcn(vmax) < PS_MIN_##type || imagfcn(vmax) < PS_MIN_##type ) { \ 309 psError(__func__, "Specified vmax (%g%+gi) is outside of image's " \ 310 typename " pixel range", \ 311 creal(vmax),cimag(vmax)); \ 312 break; \ 313 } \ 314 for (unsigned int row = 0;row<numRows;row++) { \ 315 ps##type* inputRow = input->data.type[row]; \ 316 for (unsigned int col = 0; col < numCols; col++) { \ 317 if ( (realfcn(inputRow[col]) > realMax) || (imagfcn(inputRow[col]) > imagMax) ) { \ 318 inputRow[col] = (ps##type)vmax; \ 319 numClipped++; \ 320 } else if ( (realfcn(inputRow[col]) < realMin) || (imagfcn(inputRow[col]) < imagMin) ){ \ 321 inputRow[col] = (ps##type)vmin; \ 322 numClipped++; \ 323 } \ 324 } \ 325 } \ 326 } \ 327 break; 328 329 psImageClipComplexRegionCase(C32,"psC32",crealf,cimagf) 330 psImageClipComplexRegionCase(C64,"psC64",creal,cimag) 332 psImageClipComplexRegionCase(C32, "psC32", crealf, cimagf) 333 psImageClipComplexRegionCase(C64, "psC64", creal, cimag) 331 334 332 335 default: 333 psError(__func__,"psImageClip does not support the given datatype (%d)", 334 input->type.type); 336 psError(__func__, "psImageClip does not support the given datatype (%d)", input->type.type); 335 337 } 336 338 … … 338 340 } 339 341 340 341 psImage* psImageRebin(psImage* out,const psImage* in,unsigned int scale,const psStats* stats) 342 psImage *psImageRebin(psImage * out, const psImage * in, unsigned int scale, const psStats * stats) 342 343 { 343 344 int inRows; … … 345 346 int outRows; 346 347 int outCols; 347 psVector* vec; // vector to hold the values of a single bin. 348 psStats* myStats; 348 psVector *vec; // vector to hold 349 350 // the values of 351 // a single bin. 352 psStats *myStats; 349 353 double statVal; 350 354 351 355 if (in == NULL) { 352 psError(__func__, "Input image is NULL.");356 psError(__func__, "Input image is NULL."); 353 357 psFree(out); 354 358 return NULL; … … 356 360 357 361 if (scale < 1) { 358 psError(__func__, "The scale must be positive.");362 psError(__func__, "The scale must be positive."); 359 363 psFree(out); 360 364 return NULL; … … 362 366 363 367 if (stats == NULL) { 364 psError(__func__, "The stats input can not be NULL.");368 psError(__func__, "The stats input can not be NULL."); 365 369 psFree(out); 366 370 return NULL; 367 371 } 368 372 369 if (p_psGetStatValue(stats, &statVal) == false) {370 psError(__func__, "The stat options didn't specify a single supported statistic type.");373 if (p_psGetStatValue(stats, &statVal) == false) { 374 psError(__func__, "The stat options didn't specify a single supported statistic type."); 371 375 psFree(out); 372 376 return NULL; … … 376 380 *myStats = *stats; 377 381 378 vec = psVectorAlloc(scale *scale,in->type.type);382 vec = psVectorAlloc(scale * scale, in->type.type); 379 383 380 384 // create output image. 381 385 inRows = in->numRows; 382 386 inCols = in->numCols; 383 outRows = (inRows+scale-1) / scale; // round-up for remainders 384 outCols = (inCols+scale-1) / scale; // round-up for remainders 385 out = psImageRecycle(out,outCols,outRows,in->type.type); 387 outRows = (inRows + scale - 1) / scale; // round-up 388 // for 389 // remainders 390 outCols = (inCols + scale - 1) / scale; // round-up 391 // for 392 // remainders 393 out = psImageRecycle(out, outCols, outRows, in->type.type); 386 394 387 395 #define PS_IMAGE_REBIN_CASE(type) \ … … 425 433 PS_IMAGE_REBIN_CASE(C64); 426 434 default: 427 psError(__func__, "Input image type not supported.");435 psError(__func__, "Input image type not supported."); 428 436 psFree(out); 429 437 out = NULL; … … 435 443 return out; 436 444 } 437 psImage* psImageResample(psImage* out, const psImage* in, int scale, psImageInterpolateMode mode) 445 446 psImage *psImageResample(psImage * out, const psImage * in, int scale, psImageInterpolateMode mode) 438 447 { 439 448 int outRows; … … 442 451 443 452 if (in == NULL) { 444 psError(__func__, "Input image can not be NULL.");453 psError(__func__, "Input image can not be NULL."); 445 454 psFree(out); 446 455 return NULL; 447 456 } 448 449 // create an output image of the same sizeand type450 outRows = in->numRows *scale;451 outCols = in->numCols *scale;457 // create an output image of the same size 458 // and type 459 outRows = in->numRows * scale; 460 outCols = in->numCols * scale; 452 461 invScale = 1.0f / (float)scale; 453 454 462 455 463 #define PSIMAGE_RESAMPLE_CASE(TYPE) \ … … 466 474 } 467 475 468 switch (in->type.type) {476 switch (in->type.type) { 469 477 PSIMAGE_RESAMPLE_CASE(U8) 470 478 PSIMAGE_RESAMPLE_CASE(U16) … … 480 488 PSIMAGE_RESAMPLE_CASE(C64) 481 489 default: 482 psError(__func__, "Unsupported type (%d)",in->type.type);490 psError(__func__, "Unsupported type (%d)", in->type.type); 483 491 psFree(out); 484 492 return NULL; … … 488 496 } 489 497 490 psImage * psImageRoll(psImage* out, const psImage* in, int dx, int dy)498 psImage *psImageRoll(psImage * out, const psImage * in, int dx, int dy) 491 499 { 492 500 int outRows; … … 495 503 496 504 if (in == NULL) { 497 psError(__func__, "Input image can not be NULL.");505 psError(__func__, "Input image can not be NULL."); 498 506 psFree(out); 499 507 return NULL; 500 508 } 501 502 // create an output image of the same sizeand type509 // create an output image of the same size 510 // and type 503 511 outRows = in->numRows; 504 512 outCols = in->numCols; 505 513 elementSize = PSELEMTYPE_SIZEOF(in->type.type); 506 out = psImageRecycle(out,outCols, outRows, in->type.type); 507 508 // make dx and dy between 0 and outCols or outRows, respectively 514 out = psImageRecycle(out, outCols, outRows, in->type.type); 515 516 // make dx and dy between 0 and outCols or 517 // outRows, respectively 509 518 dx = dx % outCols; 510 519 dy = dy % outRows; … … 516 525 } 517 526 518 int segment1Size = elementSize*(outCols-dx); 519 int segment2Size = elementSize*dx; 520 521 for (int row=0;row<outRows;row++) { 522 int inRowNumber = row+dy; 527 int segment1Size = elementSize * (outCols - dx); 528 int segment2Size = elementSize * dx; 529 530 for (int row = 0; row < outRows; row++) { 531 int inRowNumber = row + dy; 532 523 533 if (inRowNumber >= outRows) { 524 534 inRowNumber -= outRows; 525 535 } 526 psU8* inRow = in->data.U8[inRowNumber]; // to allow byte arithmetic, but for all types 527 psU8* outRow = out->data.U8[row]; 528 memcpy(outRow,inRow+segment2Size,segment1Size); 529 memcpy(outRow+segment1Size,inRow,segment2Size); 536 psU8 *inRow = in->data.U8[inRowNumber]; // to 537 538 // allow 539 540 // byte 541 // arithmetic, 542 543 // but for all types 544 psU8 *outRow = out->data.U8[row]; 545 546 memcpy(outRow, inRow + segment2Size, segment1Size); 547 memcpy(outRow + segment1Size, inRow, segment2Size); 530 548 } 531 549 … … 533 551 } 534 552 535 psImage* psImageRotate(psImage* out, const psImage* in, float angle, float unexposedValue, psImageInterpolateMode mode) 553 psImage *psImageRotate(psImage * out, 554 const psImage * in, float angle, float unexposedValue, psImageInterpolateMode mode) 536 555 { 537 556 if (in == NULL) { 538 psError(__func__, "The input image was NULL.");557 psError(__func__, "The input image was NULL."); 539 558 psFree(out); 540 559 return NULL; 541 560 } 542 543 561 // put the angle in the range of 0...360. 544 angle = angle - 360.0f *floor(angle/360.0f);545 546 if (fabsf(angle -90.0f) < FLT_EPSILON) {562 angle = angle - 360.0f * floor(angle / 360.0f); 563 564 if (fabsf(angle - 90.0f) < FLT_EPSILON) { 547 565 // perform 1/4 rotate counter-clockwise 548 566 int numRows = in->numCols; … … 550 568 int lastCol = numCols - 1; 551 569 psElemType type = in->type.type; 552 out = psImageRecycle(out,numCols,numRows,type); 570 571 out = psImageRecycle(out, numCols, numRows, type); 553 572 554 573 #define PSIMAGE_ROTATE_LEFT_90(TYPE) \ … … 578 597 PSIMAGE_ROTATE_LEFT_90(C64); 579 598 default: 580 psError(__func__, "Unsupported type (%d)",type);599 psError(__func__, "Unsupported type (%d)", type); 581 600 psFree(out); 582 601 return NULL; 583 602 } 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 } \ 602 } \ 603 } \ 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 } \ 642 } \ 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 } 603 } else if (fabsf(angle - 180.0f) < FLT_EPSILON) { 604 // perform 1/2 rotate 605 int numRows = in->numRows; 606 int lastRow = numRows - 1; 607 int numCols = in->numCols; 608 int lastCol = numCols - 1; 609 psElemType type = in->type.type; 610 611 out = psImageRecycle(out, numCols, numRows, type); 612 613 #define PSIMAGE_ROTATE_180_CASE(TYPE) \ 614 case PS_TYPE_##TYPE: { \ 615 for (int row=0;row<numRows;row++) { \ 616 ps##TYPE* outRow = out->data.TYPE[row]; \ 617 ps##TYPE* inRow = in->data.TYPE[lastRow-row]; \ 618 for (int col=0;col<numCols;col++) { \ 619 outRow[col] = inRow[lastCol - col]; \ 620 } \ 621 } \ 622 } \ 623 break; 624 625 switch (type) { 626 PSIMAGE_ROTATE_180_CASE(U8); 627 PSIMAGE_ROTATE_180_CASE(U16); 628 PSIMAGE_ROTATE_180_CASE(U32); 629 PSIMAGE_ROTATE_180_CASE(U64); 630 PSIMAGE_ROTATE_180_CASE(S8); 631 PSIMAGE_ROTATE_180_CASE(S16); 632 PSIMAGE_ROTATE_180_CASE(S32); 633 PSIMAGE_ROTATE_180_CASE(S64); 634 PSIMAGE_ROTATE_180_CASE(F32); 635 PSIMAGE_ROTATE_180_CASE(F64); 636 PSIMAGE_ROTATE_180_CASE(C32); 637 PSIMAGE_ROTATE_180_CASE(C64); 638 default: 639 psError(__func__, "Unsupported type (%d)", type); 640 psFree(out); 641 return NULL; 642 } 643 } else if (fabsf(angle - 270.0f) < FLT_EPSILON) { 644 // perform 1/4 rotate clockwise 645 int numRows = in->numCols; 646 int lastRow = numRows - 1; 647 int numCols = in->numRows; 648 psElemType type = in->type.type; 649 650 out = psImageRecycle(out, numCols, numRows, type); 651 652 #define PSIMAGE_ROTATE_RIGHT_90(TYPE) \ 653 case PS_TYPE_##TYPE: { \ 654 ps##TYPE** inData = in->data.TYPE; \ 655 for (int row=0;row<numRows;row++) { \ 656 ps##TYPE* outRow = out->data.TYPE[row]; \ 657 for (int col=0;col<numCols;col++) { \ 658 outRow[col] = inData[col][lastRow-row]; \ 659 } \ 660 } \ 661 } \ 662 break; 663 664 switch (type) { 665 PSIMAGE_ROTATE_RIGHT_90(U8); 666 PSIMAGE_ROTATE_RIGHT_90(U16); 667 PSIMAGE_ROTATE_RIGHT_90(U32); 668 PSIMAGE_ROTATE_RIGHT_90(U64); 669 PSIMAGE_ROTATE_RIGHT_90(S8); 670 PSIMAGE_ROTATE_RIGHT_90(S16); 671 PSIMAGE_ROTATE_RIGHT_90(S32); 672 PSIMAGE_ROTATE_RIGHT_90(S64); 673 PSIMAGE_ROTATE_RIGHT_90(F32); 674 PSIMAGE_ROTATE_RIGHT_90(F64); 675 PSIMAGE_ROTATE_RIGHT_90(C32); 676 PSIMAGE_ROTATE_RIGHT_90(C64); 677 default: 678 psError(__func__, "Unsupported type (%d)", type); 679 psFree(out); 680 return NULL; 681 } 682 } else if (fabsf(angle) < FLT_EPSILON) { 683 out = psImageCopy(out, in, in->type.type); 684 } else { 685 psElemType type = in->type.type; 686 int numRows = in->numRows; 687 int numCols = in->numCols; 688 double centerX = (float)(numCols) / 2.0f; 689 float centerY = (float)(numRows) / 2.0f; 690 float t = angle * (3.14159265358f / 180.0f); 691 float cosT = cosf(t); 692 float sinT = sinf(t); 693 694 // calculate the corners of the rotated 695 // image so we know the proper 696 // output image size. 697 // x' = x cos(t) + y sin(t); i.e, x' = 698 // (x-centerX)*cosT + 699 // (y-centerY)*sinT; 700 // y' = y cos(t) - x sin(t); i.e. y' = 701 // (y-centerY)*cosT - 702 // (x-centerX)*sinT; 703 704 int outCols = ceil(abs(numCols * cosT) + abs(numRows * sinT)) + 1; 705 int outRows = ceil(abs(numCols * sinT) + abs(numRows * cosT)) + 1; 706 float minX = (float)outCols / -2.0f; 707 int intMinY = outRows / -2; 708 709 out = psImageRecycle(out, outCols, outRows, type); 710 711 /* optimized public domain rotation routine by Karl Lager float cosT,sinT; cosT = cos(t); sinT = 712 * sin(t); for (y = min_y; y <= max_y; y++) { x' = min_x * cosT + y * sinT + x1'; y' = y * cosT - 713 * min_x * sinT + y1'; for (x = min_x; x <= max_x; x++) { if (x', y') * * * * * * * * is in the 714 * bounds of the bitmap, get pixel(x', y') and plot the pixel to (x, y) on screen. x' += cosT; y' -= 715 * sinT; } } */ 716 717 // precalculate some figures that are 718 // used within loop 719 float minXTimesCosTPlusCenterX = minX * cosT + centerX; 720 float CenterYMinusminXTimesSinT = centerY - minX * sinT; 721 722 #define PSIMAGE_ROTATE_ARBITRARY_LOOP(TYPE,MODE) { \ 723 if (unexposedValue < PS_MIN_##TYPE || unexposedValue > PS_MAX_##TYPE) { \ 724 psError(__func__,"The given unexposedValue (%g) is outside of the " \ 725 "image type's range (%g->%g).", \ 726 unexposedValue, (double)PS_MIN_##TYPE,(double)PS_MAX_##TYPE); \ 727 psFree(out); \ 728 out = NULL; \ 729 break; \ 730 } \ 731 float inX; \ 732 float inY; \ 733 ps##TYPE* outRow; \ 734 for (int y = 0; y < outRows; y++) { \ 735 inX = minXTimesCosTPlusCenterX + (y+intMinY) * sinT; \ 736 inY = CenterYMinusminXTimesSinT + (y+intMinY) * cosT; \ 737 outRow = out->data.TYPE[y]; \ 738 for (int x = 0; x < outCols; x++) { \ 739 outRow[x] = p_psImagePixelInterpolate##MODE##_##TYPE(in,inX,inY,unexposedValue); \ 740 inX += cosT; \ 741 inY -= sinT; \ 742 } \ 743 } \ 744 } 745 746 #define PSIMAGE_ROTATE_ARBITRARY_CASE(MODE) \ 747 case PS_INTERPOLATE_##MODE: \ 748 switch (type) { \ 749 case PS_TYPE_U8: \ 750 PSIMAGE_ROTATE_ARBITRARY_LOOP(U8,MODE); \ 751 break; \ 752 case PS_TYPE_U16: \ 753 PSIMAGE_ROTATE_ARBITRARY_LOOP(U16,MODE); \ 754 break; \ 755 case PS_TYPE_U32: \ 756 PSIMAGE_ROTATE_ARBITRARY_LOOP(U32,MODE); \ 757 break; \ 758 case PS_TYPE_U64: \ 759 PSIMAGE_ROTATE_ARBITRARY_LOOP(U64,MODE); \ 760 break; \ 761 case PS_TYPE_S8: \ 762 PSIMAGE_ROTATE_ARBITRARY_LOOP(S8,MODE); \ 763 break; \ 764 case PS_TYPE_S16: \ 765 PSIMAGE_ROTATE_ARBITRARY_LOOP(S16,MODE); \ 766 break; \ 767 case PS_TYPE_S32: \ 768 PSIMAGE_ROTATE_ARBITRARY_LOOP(S32,MODE); \ 769 break; \ 770 case PS_TYPE_S64: \ 771 PSIMAGE_ROTATE_ARBITRARY_LOOP(S64,MODE); \ 772 break; \ 773 case PS_TYPE_F32: \ 774 PSIMAGE_ROTATE_ARBITRARY_LOOP(F32,MODE); \ 775 break; \ 776 case PS_TYPE_F64: \ 777 PSIMAGE_ROTATE_ARBITRARY_LOOP(F64,MODE); \ 778 break; \ 779 case PS_TYPE_C32: \ 780 PSIMAGE_ROTATE_ARBITRARY_LOOP(C32,MODE); \ 781 break; \ 782 case PS_TYPE_C64: \ 783 PSIMAGE_ROTATE_ARBITRARY_LOOP(C64,MODE); \ 784 break; \ 785 default: \ 786 psError(__func__,"Image type (%d) not supported",type); \ 787 psFree(out); \ 788 out = NULL; \ 789 } \ 790 break; 791 792 switch (mode) { 793 PSIMAGE_ROTATE_ARBITRARY_CASE(FLAT); 794 PSIMAGE_ROTATE_ARBITRARY_CASE(BILINEAR); 795 default: 796 psError(__func__, "Unsupported interpolation mode (%d)", mode); 797 psFree(out); 798 out = NULL; 799 } 800 } 788 801 789 802 return out; 790 803 } 791 804 792 psImage* psImageShift(psImage* out, const psImage* in, float dx, float dy, psF64 unexposedValue, psImageInterpolateMode mode) 805 psImage *psImageShift(psImage * out, 806 const psImage * in, 807 float dx, float dy, psF64 unexposedValue, psImageInterpolateMode mode) 793 808 { 794 809 int outRows; … … 798 813 799 814 if (in == NULL) { 800 psError(__func__, "Input image can not be NULL.");815 psError(__func__, "Input image can not be NULL."); 801 816 return NULL; 802 817 } 803 804 // create an output image of the same sizeand type818 // create an output image of the same size 819 // and type 805 820 outRows = in->numRows; 806 821 outCols = in->numCols; 807 822 type = in->type.type; 808 823 elementSize = PSELEMTYPE_SIZEOF(type); 809 out = psImageRecycle(out, outCols, outRows, type);824 out = psImageRecycle(out, outCols, outRows, type); 810 825 811 826 #define PSIMAGE_SHIFT_CASE(TYPE) \ … … 842 857 PSIMAGE_SHIFT_CASE(C64); 843 858 default: 844 psError(__func__, "Image type (%d) not supported.",type);859 psError(__func__, "Image type (%d) not supported.", type); 845 860 psFree(out); 846 861 out = NULL; -
trunk/psLib/src/image/psImageManip.h
r1263 r1407 1 1 2 /** @file psImageManip.h 2 3 * … … 10 11 * @author Ross Harman, MHPCC 11 12 * 12 * @version $Revision: 1. 6$ $Name: not supported by cvs2svn $13 * @date $Date: 2004-0 7-22 20:42:22$13 * @version $Revision: 1.7 $ $Name: not supported by cvs2svn $ 14 * @date $Date: 2004-08-07 00:06:06 $ 14 15 * 15 16 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii 16 17 */ 17 18 #ifndef PS_IMAGE_MANIP_H 18 # define PS_IMAGE_MANIP_H19 # define PS_IMAGE_MANIP_H 19 20 20 # include "psImage.h"21 # include "psImage.h" 21 22 22 23 /// @addtogroup Image … … 31 32 * @return int The number of clipped pixels 32 33 */ 33 int psImageClip( 34 psImage* input, ///< the image to clip 35 psF64 min, ///< the minimum image value allowed 36 psF64 vmin, ///< the value pixels < min are set to 37 psF64 max, ///< the maximum image value allowed 38 psF64 vmax ///< the value pixels > max are set to 39 ); 34 int psImageClip(psImage * input, // /< the image to clip 35 psF64 min, // /< the minimum image value allowed 36 psF64 vmin, // /< the value pixels < min are set to 37 psF64 max, // /< the maximum image value allowed 38 psF64 vmax // /< the value pixels > max are set to 39 ); 40 40 41 41 /** Clip image values outside of a specified complex region … … 48 48 * @return int The number of clipped pixels 49 49 */ 50 int psImageClipComplexRegion( 51 psImage* input, ///< the image to clip 52 psC64 min, ///< the minimum image value allowed 53 psC64 vmin, ///< the value pixels < min are set to 54 psC64 max, ///< the maximum image value allowed 55 psC64 vmax ///< the value pixels > max are set to 56 ); 50 int psImageClipComplexRegion(psImage * input, // /< the image to clip 51 psC64 min, // /< the minimum image value allowed 52 psC64 vmin, // /< the value pixels < min are set to 53 psC64 max, // /< the maximum image value allowed 54 psC64 vmax // /< the value pixels > max are set to 55 ); 57 56 58 57 /** Clip NaN image pixels to given value. … … 63 62 * @return int The number of clipped pixels 64 63 */ 65 int psImageClipNaN( 66 psImage* input, ///< the image to clip 67 psF64 value ///< the value to set all NaN/Inf values to 68 ); 64 int psImageClipNaN(psImage * input, // /< the image to clip 65 psF64 value // /< the value to set all NaN/Inf values to 66 ); 69 67 70 68 /** Overlay subregion of image with another image … … 79 77 * @return int 0 if success, non-zero if failed. 80 78 */ 81 int psImageOverlaySection( 82 psImage* image, ///< target image 83 const psImage* overlay, ///< the overlay image 84 int col0, ///< the column to start overlay 85 int row0, ///< the row to start overlay 86 const char* op ///< the operation to perform for overlay 87 ); 79 int psImageOverlaySection(psImage * image, // /< target image 80 const psImage * overlay, // /< the overlay image 81 int col0, // /< the column to start overlay 82 int row0, // /< the row to start overlay 83 const char *op // /< the operation to perform for overlay 84 ); 88 85 89 86 /** Rebin image to new scale. … … 97 94 * @return psImage new image formed by rebinning input image. 98 95 */ 99 psImage * psImageRebin(100 psImage* out, ///< an psImage to recycle. If NULL, a new image is created101 const psImage* in, ///< input image102 unsigned int scale, ///< the scale to rebin for each dimension103 const psStats* stats ///< the statistic to perform when rebinning. Only onemethod should be set.104 );96 psImage *psImageRebin(psImage * out, // /< an psImage to recycle. If NULL, a new image is created 97 const psImage * in, // /< input image 98 unsigned int scale, // /< the scale to rebin for each dimension 99 const psStats * stats // /< the statistic to perform when rebinning. Only one 100 // method should be set. 101 ); 105 102 106 psImage* psImageResample( 107 psImage* out, ///< an psImage to recycle. If NULL, a new image is created 108 const psImage* in, ///< input image 109 int scale, 110 psImageInterpolateMode mode 111 ); 103 psImage *psImageResample(psImage * out, // /< an psImage to recycle. If NULL, a new image is created 104 const psImage * in, // /< input image 105 int scale, psImageInterpolateMode mode); 112 106 113 psImage* psImageRotate( 114 psImage* out, ///< an psImage to recycle. If NULL, a new image is created 115 const psImage* in, ///< input image 116 float angle, 117 float unexposedValue, 118 psImageInterpolateMode mode 119 ); 107 psImage *psImageRotate(psImage * out, // /< an psImage to recycle. If NULL, a new image is created 108 const psImage * in, // /< input image 109 float angle, float unexposedValue, psImageInterpolateMode mode); 120 110 121 psImage* psImageShift( 122 psImage* out, ///< an psImage to recycle. If NULL, a new image is created 123 const psImage* in, ///< input image 124 float dx, 125 float dy, 126 float unexposedValue, 127 psImageInterpolateMode mode 128 ); 111 psImage *psImageShift(psImage * out, // /< an psImage to recycle. If NULL, a new image is created 112 const psImage * in, // /< input image 113 float dx, float dy, float unexposedValue, psImageInterpolateMode mode); 129 114 130 115 /** Roll image by an integer number of pixels in either direction. … … 136 121 * @return psImage* the rolled version of the input image. 137 122 */ 138 psImage* psImageRoll( 139 psImage* out, ///< an psImage to recycle. If NULL, a new image is created 140 const psImage* in, ///< input image 141 int dx, ///< number of pixels to roll in the x-dimension 142 int dy ///< number of pixels to roll in the y-dimension 143 ); 123 psImage *psImageRoll(psImage * out, // /< an psImage to recycle. If NULL, a new image is created 124 const psImage * in, // /< input image 125 int dx, // /< number of pixels to roll in the x-dimension 126 int dy // /< number of pixels to roll in the y-dimension 127 ); 144 128 145 129 #endif 146 -
trunk/psLib/src/image/psImageStats.c
r1406 r1407 1 1 2 /** @file psImageStats.c 2 3 * \brief Routines for calculating statistics on images. … … 9 10 * @author George Gusciora, MHPCC 10 11 * 11 * @version $Revision: 1. 29$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-08-0 6 22:34:05$12 * @version $Revision: 1.30 $ $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 … … 32 33 33 34 /// This routine must determine the various statistics for the image. 35 34 36 /***************************************************************************** 35 37 NOTE: verify that image/mask have the correct types, and sizes. 36 38 *****************************************************************************/ 37 psStats *psImageStats(psStats *stats, 38 psImage *in, 39 psImage *mask, 40 int maskVal) 41 { 42 psVector* junkData=NULL; 43 psVector* junkMask=NULL; 39 psStats *psImageStats(psStats * stats, psImage * in, psImage * mask, int maskVal) 40 { 41 psVector *junkData = NULL; 42 psVector *junkMask = NULL; 44 43 45 44 if (stats == NULL) { 46 psError(__func__, "The input psStats struct can not be NULL.");45 psError(__func__, "The input psStats struct can not be NULL."); 47 46 return NULL; 48 47 } 49 48 50 49 if (in == NULL) { 51 psError(__func__, "The input image can not be NULL.");50 psError(__func__, "The input image can not be NULL."); 52 51 return NULL; 53 52 } 54 53 55 54 if (stats->options == 0) { 56 psError(__func__, "No statistic option/operation was specified.");55 psError(__func__, "No statistic option/operation was specified."); 57 56 return stats; 58 57 } 59 60 // st uff the image data into a psVector struct.58 // stuff the image data into a psVector 59 // struct. 61 60 junkData = psAlloc(sizeof(psVector)); 62 61 junkData->type = in->type; 63 junkData->nalloc = in->numRows *in->numCols;62 junkData->nalloc = in->numRows * in->numCols; 64 63 junkData->n = junkData->nalloc; 65 junkData->data.V = in->data.V[0]; // since psImage data is contiguous... 64 junkData->data.V = in->data.V[0]; // since 65 // psImage 66 // data 67 // is 68 // contiguous... 66 69 67 70 if (mask != NULL) { 68 71 if (mask->type.type != PS_TYPE_MASK) { 69 psError(__func__, "Expected the mask image type not found (type=%x)", 70 mask->type.type); 72 psError(__func__, "Expected the mask image type not found (type=%x)", mask->type.type); 71 73 psFree(junkData); 72 74 return NULL; 73 75 } 74 75 // st uff the mask data into a psVector struct.76 // stuff the mask data into a psVector 77 // struct. 76 78 junkMask = psAlloc(sizeof(psVector)); 77 79 junkMask->type = mask->type; 78 junkMask->nalloc = mask->numRows *mask->numCols;80 junkMask->nalloc = mask->numRows * mask->numCols; 79 81 junkMask->n = junkMask->nalloc; 80 82 junkMask->data.V = mask->data.V[0]; … … 85 87 psFree(junkMask); 86 88 psFree(junkData); 87 return (stats);89 return (stats); 88 90 } 89 91 … … 93 95 NOTE: verify that image/mask have the, correct types and sizes. 94 96 *****************************************************************************/ 95 psHistogram *psImageHistogram(psHistogram *out, 96 psImage *in, 97 psImage *mask, 98 unsigned int maskVal) 99 { 100 psVector *junkData=NULL; 101 psVector *junkMask=NULL; 97 psHistogram *psImageHistogram(psHistogram * out, psImage * in, psImage * mask, unsigned int maskVal) 98 { 99 psVector *junkData = NULL; 100 psVector *junkMask = NULL; 102 101 103 102 // NOTE: Verify this action. 104 if ((out == NULL) || 105 (in == NULL)) { 106 return(NULL); 103 if ((out == NULL) || (in == NULL)) { 104 return (NULL); 107 105 } 108 106 109 107 junkData = psAlloc(sizeof(psVector)); 110 108 junkData->type = in->type; 111 junkData->nalloc = in->numRows *in->numCols;109 junkData->nalloc = in->numRows * in->numCols; 112 110 junkData->n = junkData->nalloc; 113 junkData->data.V = in->data.V[0]; // since psImage data is contiguous... 111 junkData->data.V = in->data.V[0]; // since 112 // psImage 113 // data 114 // is 115 // contiguous... 114 116 115 117 if (mask != NULL) { 116 118 if (mask->type.type != PS_TYPE_MASK) { 117 psError(__func__, "Expected the mask image type not found (type=%x)", 118 mask->type.type); 119 psError(__func__, "Expected the mask image type not found (type=%x)", mask->type.type); 119 120 psFree(junkData); 120 121 return NULL; 121 122 } 122 123 // st uff the mask data into a psVector struct.123 // stuff the mask data into a psVector 124 // struct. 124 125 junkMask = psAlloc(sizeof(psVector)); 125 126 junkMask->type = mask->type; 126 junkMask->nalloc = mask->numRows *mask->numCols;127 junkMask->nalloc = mask->numRows * mask->numCols; 127 128 junkMask->n = junkMask->nalloc; 128 129 junkMask->data.V = mask->data.V[0]; … … 134 135 psFree(junkData); 135 136 136 return (out);137 return (out); 137 138 } 138 139 … … 141 142 int i = 0; 142 143 float tmp = 0.0; 143 float *scalingFactors = (float *) psAlloc(n * sizeof(float)); 144 145 for (i=0;i<n;i++) { 146 // ((2.0 * (float) i) / ((float) (n-1))) - 1.0; 147 // tmp = (float) (i + 1); 148 tmp = (float) (n - i); 149 tmp = (M_PI * (tmp - 0.5)) / ((float) n); 144 float *scalingFactors = (float *)psAlloc(n * sizeof(float)); 145 146 for (i = 0; i < n; i++) { 147 // ((2.0 * (float) i) / ((float) (n-1))) 148 // - 1.0; 149 // tmp = (float) (i + 1); 150 tmp = (float)(n - i); 151 tmp = (M_PI * (tmp - 0.5)) / ((float)n); 150 152 scalingFactors[i] = cos(tmp); 151 153 } 152 154 153 return (scalingFactors);155 return (scalingFactors); 154 156 } 155 157 … … 165 167 int i = 0; 166 168 float tmp = 0.0; 169 167 170 return p_psCalcScaleFactorsFit(n); 168 171 169 172 printf("Should not get here\n"); 170 float *scalingFactors = (float *) psAlloc(n * sizeof(float)); 171 for (i=0;i<n;i++) { 172 // scalingFactors[i] = ((2.0 * (float) i) / ((float) (n-1))) - 1.0; 173 tmp = (float) (n - i); 174 tmp = (M_PI * (tmp - 0.5)) / ((float) n); 173 float *scalingFactors = (float *)psAlloc(n * sizeof(float)); 174 175 for (i = 0; i < n; i++) { 176 // scalingFactors[i] = ((2.0 * (float) i) 177 // / ((float) (n-1))) - 1.0; 178 tmp = (float)(n - i); 179 tmp = (M_PI * (tmp - 0.5)) / ((float)n); 175 180 scalingFactors[i] = cos(tmp); 176 181 } 177 return (scalingFactors);182 return (scalingFactors); 178 183 } 179 184 … … 184 189 int j = 0; 185 190 186 chebPolys = (psPolynomial1D **) psAlloc(maxChebyPoly * 187 sizeof(psPolynomial1D *));188 for (i=0;i<maxChebyPoly;i++) {189 chebPolys[i] = psPolynomial1DAlloc(i+1);190 } 191 192 // Create the Chebyshev polynomials.Polynomial i has i-th order.191 chebPolys = (psPolynomial1D **) psAlloc(maxChebyPoly * sizeof(psPolynomial1D *)); 192 for (i = 0; i < maxChebyPoly; i++) { 193 chebPolys[i] = psPolynomial1DAlloc(i + 1); 194 } 195 196 // Create the Chebyshev polynomials. 197 // Polynomial i has i-th order. 193 198 chebPolys[0]->coeff[0] = 1; 194 199 chebPolys[1]->coeff[1] = 1; 195 for (i=2;i<maxChebyPoly;i++) { 196 for (j=0;j<chebPolys[i-1]->n;j++) { 197 chebPolys[i]->coeff[j+1] = 2 * chebPolys[i-1]->coeff[j]; 198 } 199 for (j=0;j<chebPolys[i-2]->n;j++) { 200 chebPolys[i]->coeff[j]-= chebPolys[i-2]->coeff[j]; 201 } 202 } 203 204 return(chebPolys); 205 } 206 200 for (i = 2; i < maxChebyPoly; i++) { 201 for (j = 0; j < chebPolys[i - 1]->n; j++) { 202 chebPolys[i]->coeff[j + 1] = 2 * chebPolys[i - 1]->coeff[j]; 203 } 204 for (j = 0; j < chebPolys[i - 2]->n; j++) { 205 chebPolys[i]->coeff[j] -= chebPolys[i - 2]->coeff[j]; 206 } 207 } 208 209 return (chebPolys); 210 } 207 211 208 212 /***************************************************************************** … … 220 224 over all pixels (x,y) in the image. 221 225 *****************************************************************************/ 222 psPolynomial2D * 223 psImageFitPolynomial(const psImage *input, 224 psPolynomial2D *coeffs) 226 psPolynomial2D *psImageFitPolynomial(const psImage * input, psPolynomial2D * coeffs) 225 227 { 226 228 int x = 0; … … 235 237 float tmp = 0.0; 236 238 237 // Create the sums[][] data structure. This will hold the LHS of equation 238 // 29 in the ADD: sums[k][l] = SUM { image(x,y) * Tk(x) * Tl(y) } 239 sums = (float **) psAlloc(coeffs->nX * sizeof(float *)); 240 for (i=0;i<coeffs->nX;i++) { 241 sums[i] = (float *) psAlloc(coeffs->nY * sizeof(float)); 242 } 243 244 // We scale the pixel positions to values between -1.0 and 1.0 239 // Create the sums[][] data structure. This 240 // will hold the LHS of 241 // equation 242 // 29 in the ADD: sums[k][l] = SUM { 243 // image(x,y) * Tk(x) * Tl(y) } 244 sums = (float **)psAlloc(coeffs->nX * sizeof(float *)); 245 for (i = 0; i < coeffs->nX; i++) { 246 sums[i] = (float *)psAlloc(coeffs->nY * sizeof(float)); 247 } 248 249 // We scale the pixel positions to values 250 // between -1.0 and 1.0 245 251 rScalingFactors = p_psCalcScaleFactorsFit(input->numRows); 246 252 cScalingFactors = p_psCalcScaleFactorsFit(input->numCols); 247 253 248 // Determine how many Chebyshev polynomials are needed, then create them. 254 // Determine how many Chebyshev polynomials 255 // are needed, then create them. 249 256 maxChebyPoly = coeffs->nX; 250 257 if (coeffs->nY > coeffs->nX) { … … 254 261 255 262 // Sanity check for the Chebyshevs. 256 for (i =0;i<coeffs->nX;i++) {257 for (j =0;j<coeffs->nY;j++) {263 for (i = 0; i < coeffs->nX; i++) { 264 for (j = 0; j < coeffs->nY; j++) { 258 265 tmp = 0.0; 259 for (x=0;x<input->numRows;x++) { 260 tmp+= psPolynomial1DEval(rScalingFactors[x], chebPolys[i]) * 261 psPolynomial1DEval(rScalingFactors[x], chebPolys[j]); 266 for (x = 0; x < input->numRows; x++) { 267 tmp += 268 psPolynomial1DEval 269 (rScalingFactors[x], chebPolys[i]) * psPolynomial1DEval(rScalingFactors[x], chebPolys[j]); 262 270 263 271 } 264 //printf("SUM(Cheby(%d) * Cheby(%d)) is %f\n", i, j, tmp); 272 // printf("SUM(Cheby(%d) * Cheby(%d)) 273 // is %f\n", i, j, tmp); 265 274 } 266 275 } 267 276 268 277 // Compute the sums[][] data structure. 269 for (i =0;i<coeffs->nX;i++) {270 for (j =0;j<coeffs->nY;j++) {278 for (i = 0; i < coeffs->nX; i++) { 279 for (j = 0; j < coeffs->nY; j++) { 271 280 sums[i][j] = 0.0; 272 for (x=0;x<input->numRows;x++) { 273 for (y=0;y<input->numCols;y++) { 274 sums[i][j]+= input->data.F32[x][y] * 275 psPolynomial1DEval(rScalingFactors[x], chebPolys[i]) * 276 psPolynomial1DEval(cScalingFactors[y], chebPolys[j]); 281 for (x = 0; x < input->numRows; x++) { 282 for (y = 0; y < input->numCols; y++) { 283 sums[i][j] += 284 input->data.F32[x][y] * 285 psPolynomial1DEval 286 (rScalingFactors[x], 287 chebPolys[i]) * psPolynomial1DEval(cScalingFactors[y], chebPolys[j]); 277 288 } 278 289 } … … 280 291 } 281 292 282 for (i =0;i<coeffs->nX;i++) {283 for (j =0;j<coeffs->nY;j++) {293 for (i = 0; i < coeffs->nX; i++) { 294 for (j = 0; j < coeffs->nY; j++) { 284 295 coeffs->coeff[i][j] = sums[i][j]; 285 coeffs->coeff[i][j] /= (float)(input->numRows * input->numCols);296 coeffs->coeff[i][j] /= (float)(input->numRows * input->numCols); 286 297 287 298 if ((i != 0) && (j != 0)) { 288 coeffs->coeff[i][j] *= 4.0;289 } else 290 if ((i == 0) && (j == 0)) {291 coeffs->coeff[i][j]*= 1.0;292 } else {293 coeffs->coeff[i][j]*= 2.0;294 }295 }296 } 297 298 // Free the Chebyshev polynomials that werecreated in this routine.299 for (i =0;i<maxChebyPoly;i++) {299 coeffs->coeff[i][j] *= 4.0; 300 } else if ((i == 0) && (j == 0)) { 301 coeffs->coeff[i][j] *= 1.0; 302 } else { 303 coeffs->coeff[i][j] *= 2.0; 304 } 305 } 306 } 307 308 // Free the Chebyshev polynomials that were 309 // created in this routine. 310 for (i = 0; i < maxChebyPoly; i++) { 300 311 psFree(chebPolys[i]); 301 312 } … … 303 314 304 315 // Free some data 305 for (i =0;i<coeffs->nX;i++) {316 for (i = 0; i < coeffs->nX; i++) { 306 317 psFree(sums[i]); 307 318 } … … 310 321 psFree(rScalingFactors); 311 322 312 return (coeffs);323 return (coeffs); 313 324 } 314 325 … … 316 327 317 328 *****************************************************************************/ 318 int 319 psImageEvalPolynomial(const psImage *input, 320 const psPolynomial2D *coeffs) 329 int psImageEvalPolynomial(const psImage * input, const psPolynomial2D * coeffs) 321 330 { 322 331 int x = 0; … … 331 340 float polySum = 0.0; 332 341 333 // Create the sums[][] data structure. This will hold the LHS of equation 334 // 29 in the ADD: sums[k][l] = SUM { image(x,y) * Tk(x) * Tl(y) } 335 sums = (float **) psAlloc(coeffs->nX * sizeof(float *)); 336 for (i=0;i<coeffs->nX;i++) { 337 sums[i] = (float *) psAlloc(coeffs->nY * sizeof(float)); 338 } 339 for (i=0;i<coeffs->nX;i++) { 340 for (j=0;j<coeffs->nY;j++) { 342 // Create the sums[][] data structure. This 343 // will hold the LHS of 344 // equation 345 // 29 in the ADD: sums[k][l] = SUM { 346 // image(x,y) * Tk(x) * Tl(y) } 347 sums = (float **)psAlloc(coeffs->nX * sizeof(float *)); 348 for (i = 0; i < coeffs->nX; i++) { 349 sums[i] = (float *)psAlloc(coeffs->nY * sizeof(float)); 350 } 351 for (i = 0; i < coeffs->nX; i++) { 352 for (j = 0; j < coeffs->nY; j++) { 341 353 sums[i][j] = 0.0; 342 354 } 343 355 } 344 356 345 // We scale the pixel positions to values between -1.0 and 1.0 357 // We scale the pixel positions to values 358 // between -1.0 and 1.0 346 359 rScalingFactors = p_psCalcScaleFactorsEval(input->numRows); 347 360 cScalingFactors = p_psCalcScaleFactorsEval(input->numCols); 348 361 349 // Determine how many Chebyshev polynomials are needed, then create them. 362 // Determine how many Chebyshev polynomials 363 // are needed, then create them. 350 364 maxChebyPoly = coeffs->nX; 351 365 if (coeffs->nY > coeffs->nX) { … … 355 369 chebPolys = p_psCreateChebyshevPolys(maxChebyPoly); 356 370 357 for (x =0;x<input->numRows;x++) {358 for (y =0;y<input->numCols;y++) {371 for (x = 0; x < input->numRows; x++) { 372 for (y = 0; y < input->numCols; y++) { 359 373 polySum = 0.0; 360 for (i=0;i<coeffs->nX;i++) { 361 for (j=0;j<coeffs->nY;j++) { 362 polySum+= psPolynomial1DEval(rScalingFactors[x], chebPolys[i]) * 363 psPolynomial1DEval(cScalingFactors[y], chebPolys[j]) * 364 coeffs->coeff[i][j]; 374 for (i = 0; i < coeffs->nX; i++) { 375 for (j = 0; j < coeffs->nY; j++) { 376 polySum += 377 psPolynomial1DEval 378 (rScalingFactors[x], 379 chebPolys[i]) * 380 psPolynomial1DEval(cScalingFactors[y], chebPolys[j]) * coeffs->coeff[i][j]; 365 381 366 382 } … … 370 386 } 371 387 372 // Free the Chebyshev polynomials that were created in this routine. 373 for (i=0;i<maxChebyPoly;i++) { 388 // Free the Chebyshev polynomials that were 389 // created in this routine. 390 for (i = 0; i < maxChebyPoly; i++) { 374 391 psFree(chebPolys[i]); 375 392 } … … 377 394 378 395 // Free some data 379 for (i =0;i<coeffs->nX;i++) {396 for (i = 0; i < coeffs->nX; i++) { 380 397 psFree(sums[i]); 381 398 } … … 384 401 psFree(rScalingFactors); 385 402 386 return (0);387 } 403 return (0); 404 } -
trunk/psLib/src/image/psImageStats.h
r1374 r1407 1 1 2 /** @file psImageStats.h 2 3 * \brief Routines for calculating statistics on images. … … 9 10 * @author George Gusciora, MHPCC 10 11 * 11 * @version $Revision: 1.1 0$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-08-0 4 00:55:17$12 * @version $Revision: 1.11 $ $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 15 16 */ 16 17 #if !defined(PS_IMAGE_STATS_H) 17 # define PS_IMAGE_STATS_H18 # define PS_IMAGE_STATS_H 18 19 19 20 #include "psType.h" 21 #include "psVector.h" 22 #include "psImage.h" 23 #include "psStats.h" 24 #include "psFunctions.h" 20 # include "psType.h" 21 # include "psVector.h" 22 # include "psImage.h" 23 # include "psStats.h" 24 # include "psFunctions.h" 25 25 26 26 /// @addtogroup ImageStats … … 28 28 29 29 /// This routine must determine the various statistics for the image. 30 psStats *psImageStats( psStats *stats, ///< defines statistics to be calculated 31 psImage *in, ///< image (or subimage) to calculate stats 32 psImage *mask, ///< mask data for image (NULL ok) 33 int maskVal ); ///< mask Mask for mask 34 35 36 psHistogram *psImageHistogram( psHistogram *out, ///< input histogram description & target 37 psImage *in, ///< Image data to be histogramed. 38 psImage *mask, ///< mask data for image (NULL ok) 39 unsigned int maskVal ); ///< mask Mask for mask 40 30 psStats *psImageStats(psStats * stats, // /< defines statistics to be calculated 31 psImage * in, // /< image (or subimage) to calculate stats 32 psImage * mask, // /< mask data for image (NULL ok) 33 int maskVal); // /< mask Mask for mask 34 35 psHistogram *psImageHistogram(psHistogram * out, // /< input histogram description & target 36 psImage * in, // /< Image data to be histogramed. 37 psImage * mask, // /< mask data for image (NULL ok) 38 unsigned int maskVal); // /< mask Mask for mask 39 41 40 /// Fit a 2-D polynomial surface to an image. 42 psPolynomial2D * 43 psImageFitPolynomial( const psImage *input, ///< image to fit 44 psPolynomial2D *coeffs ///< coefficient structure carries indesired terms & target45 );46 41 psPolynomial2D *psImageFitPolynomial(const psImage * input, // /< image to fit 42 psPolynomial2D * coeffs // /< coefficient structure carries in 43 // desired terms & target 44 ); 45 47 46 /// Evaluate a 2-D polynomial surface to image pixels. 48 int 49 psImageEvalPolynomial( const psImage *input, ///< image to fit 50 const psPolynomial2D *coeffs ///< coefficient structure carries in desired terms 51 ); 52 47 int psImageEvalPolynomial(const psImage * input, // /< image to fit 48 const psPolynomial2D * coeffs // /< coefficient structure carries in desired terms 49 ); 50 53 51 /// @} 54 52
Note:
See TracChangeset
for help on using the changeset viewer.
