Changeset 12154 for trunk/psLib/test/fft/tap_psImageFFT.c
- Timestamp:
- Mar 1, 2007, 1:35:33 PM (19 years ago)
- File:
-
- 1 edited
-
trunk/psLib/test/fft/tap_psImageFFT.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/test/fft/tap_psImageFFT.c
r11685 r12154 1 /** @file tst_psImageFFT.c2 *3 * @brief Contains the tests for psFFT.[ch]4 *5 *6 * @author Robert DeSonia, MHPCC7 *8 * @version $Revision: 1.2 $ $Name: not supported by cvs2svn $9 * @date $Date: 2007-02-07 22:50:18 $10 *11 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii12 */13 1 #include <stdio.h> 14 #include < string.h>2 #include <math.h> 15 3 #include <pslib.h> 4 16 5 #include "tap.h" 17 6 #include "pstap.h" 18 7 19 #define GENIMAGE(img,c,r,TYP, valueFcn) \ 20 img = psImageAlloc(c,r,PS_TYPE_##TYP); \ 21 for (psU32 row=0;row<r;row++) { \ 22 ps##TYP* imgRow = img->data.TYP[row]; \ 23 for (psU32 col=0;col<c;col++) { \ 24 imgRow[col] = (ps##TYP)(valueFcn); \ 25 } \ 8 #define TOL 2.0e-6 // Tolerance for comparison 9 10 11 // Generate image with single high pixel 12 static psImage *generateImage(int numCols, int numRows) 13 { 14 psImage *image = psImageAlloc(numCols, numRows, PS_TYPE_F32); 15 for (int y = 0; y < numRows; y++) { 16 for (int x = 0; x < numCols; x++) { 17 image->data.F32[y][x] = 1.2 * cos(2.0 * M_PI * x / numCols + M_PI / 4.0) + 18 3.4 * sin(2.0 * M_PI * y / numRows + M_PI); 19 } 20 } 21 return image; 26 22 } 27 23 28 psS32 main(psS32 argc, char* argv[]) 24 // FFT forward, then back --- do I get what I started with? 25 // A total of 6 tests here. 26 static void testFFT(int numCols, int numRows) 29 27 { 30 psLogSetFormat("HLNM"); 31 psLogSetLevel(PS_LOG_INFO); 32 plan_tests(68); 28 psMemId id = psMemGetId(); 33 29 34 // psImageFFT(void) 30 diag("Testing %dx%d", numCols, numRows); 31 psImage *old = generateImage(numCols, numRows); 32 psImage *fftReal = NULL, *fftImag = NULL; 33 bool result = psImageForwardFFT(&fftReal, &fftImag, old); 34 ok(result, "forward fft result"); 35 skip_start(!result || !fftReal || !fftImag, 3, "forward fft failed"); 36 ok(fftReal->type.type == PS_TYPE_F32 && fftImag->type.type == PS_TYPE_F32, "forward fft types"); 37 psImage *new = NULL; 38 result = psImageBackwardFFT(&new, fftReal, fftImag, old->numCols); 39 ok(result, "backward fft result"); 40 skip_start(!result || !new, 2, "backward fft failed"); 41 ok(new->type.type == PS_TYPE_F32, "backward fft type"); 42 float maxDev = 0.0; // Maximum deviation from expected 43 for (int y = 0; y < old->numRows; y++) { 44 for (int x = 0; x < old->numCols; x++) { 45 float dev = fabs(new->data.F32[y][x] / numCols / numRows - old->data.F32[y][x]); 46 if (dev > maxDev) { 47 maxDev = dev; 48 } 49 } 50 } 51 ok(maxDev < TOL, "maximum deviation: %f", maxDev); 52 psFree(new); 53 skip_end(); 54 skip_end(); 55 56 psFree(fftReal); 57 psFree(fftImag); 58 psFree(old); 59 ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks"); 60 61 return; 62 } 63 64 65 int main(int argc, char *argv[]) 66 { 67 plan_tests(8 + 6 * 5); 68 69 // Test with NULL real arg 35 70 { 36 71 psMemId id = psMemGetId(); 37 psImage* img = NULL; 38 psImage* img2 = NULL; 39 psImage* img3 = NULL; 40 psU32 m = 128; 41 psU32 n = 64; 42 psImage* img4 = NULL; 43 psImage* img5 = NULL; 44 45 // 1. assign a image to a radial sinisoid 46 // 2. perform forward transform 47 // 3. verify that the only significant component cooresponds to the freqency of the input in step 1. 48 // 4. perform reverse transform 49 // 5. compare to original (should be equal to within a reasonable error) 50 51 // 1. assign a image to a radial sinisoid 52 GENIMAGE(img,m,n,F32, sinf((32.0f-row)/32.0f*M_PI)+sinf((64.0f-col)/64.0f*M_PI)); 53 54 // 2. perform forward transform 55 img2 = psImageFFT(img2,img,PS_FFT_FORWARD); 56 ok(img2 != NULL, "psImageFFT() returned non-NULL"); 57 skip_start(img2 == NULL, 1, "Skipping tests because psImageFFT() returned NULL"); 58 ok(img2->type.type == PS_TYPE_C32, "FFT produced complex values"); 59 ok(img2->numCols == m && img2->numRows == n, "FFT produced proper size result (%dx%d vs. expected %dx%d).", 60 img2->numCols,img2->numRows,m,n); 61 62 // 3. verify that the only significant component cooresponds to the freqency of the input in step 1. 63 bool errorFlag = false; 64 for (psU32 row=0;row<n;row++) 65 { 66 psC32* img2Row = img2->data.C32[row]; 67 for (psU32 col=0;col<m;col++) { 68 psF32 mag = cabsf(img2Row[col])/m/n; 69 if (mag > 0.1f) { 70 // must be (0,1) or (0,n-1) or (1,0) or (m-1,0) 71 if (! (col == 0 && (row == 1 || row == n-1)) 72 && ! (row == 0 && (col==1 || col == m-1)) ) { 73 diag("Result incorrect at %d,%d (%.2f)",col,row,mag); 74 errorFlag = true; 75 } 76 } else { 77 if ( (col == 0 && (row == 1 || row == n-1)) 78 || (row == 0 && (col==1 || col == m-1)) ) { 79 diag("Result incorrect at %d,%d (%.2f)",col,row,mag); 80 errorFlag = true; 81 } 82 } 83 } 84 } 85 ok(!errorFlag, "FFT produced correct data values"); 86 87 88 89 // 4. perform reverse transform 90 img3 = psImageFFT(img3,img2,PS_FFT_REVERSE); 91 ok(img3 != NULL, "psImageFFT() returned non-NULL"); 92 skip_start(img3 == NULL, 1, "Skipping tests because psImageFFT() returned NULL"); 93 ok(img3->type.type == PS_TYPE_C32, "FFT produced complex values"); 94 95 ok(img3->numCols == m && img3->numRows == n, "FFT didt produce proper size result (%dx%d vs. expected %dx%d).", 96 img3->numCols,img3->numRows,m,n); 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 errorFlag = false; 114 for (psU32 row=0;row<n;row++) 115 { 116 psC32* img3Row = img3->data.C32[row]; 117 psF32* imgRow = img->data.F32[row]; 118 for (psU32 col=0;col<m;col++) { 119 psF32 pixel = creal(img3Row[col])/m/n; 120 if (fabsf(pixel-imgRow[col]) > 0.1) { 121 diag("Reverse FFT gave original image back (%d,%d %.2f vs %.2f)", 122 col,row,pixel,imgRow[col]); 123 errorFlag = true; 124 } 125 } 126 } 127 ok(!errorFlag, "FFT produced correct data values"); 128 ok(!errorFlag, "FFT produced correct data values"); 129 130 131 132 // 4. perform reverse transform to real result 133 img3 = psImageFFT(img3,img2,PS_FFT_REVERSE|PS_FFT_REAL_RESULT); 134 ok(img3 != NULL, "psImageFFT() returned non-NULL"); 135 skip_start(img3 == NULL, 1, "Skipping tests because psImageFFT() returned NULL"); 136 ok(img3->type.type == PS_TYPE_F32, "FFT asked to make real result"); 137 ok(img3->numCols == m && img3->numRows == n, "FFT produced proper size result (%dx%d vs. expected %dx%d).", 138 img3->numCols,img3->numRows,m,n); 139 140 errorFlag = false; 141 for (psU32 row=0;row<n;row++) 142 { 143 psF32* img3Row = img3->data.F32[row]; 144 psF32* imgRow = img->data.F32[row]; 145 for (psU32 col=0;col<m;col++) { 146 psF32 pixel = img3Row[col]/m/n; 147 if (fabsf(pixel-imgRow[col]) > 0.1) { 148 diag("Reverse FFT gave original image back (%d,%d %.2f vs %.2f)", 149 col,row,pixel,imgRow[col]); 150 errorFlag = true; 151 } 152 } 153 } 154 ok(!errorFlag, "FFT produced correct data values"); 155 ok(!errorFlag, "FFT produced correct data values"); 156 157 158 159 // check if error occurs if FORWARD and REVERSE are both given. 160 // Following should be an error 161 // XXX: werify error 162 ok(psImageFFT(NULL,img2,PS_FFT_REVERSE|PS_FFT_FORWARD) == NULL, 163 "PS_FFT_REVERSE|PS_FFT_FORWARD returned NULL"); 164 165 // Following should be an error 166 // XXX: werify error 167 ok(psImageFFT(NULL,img2,PS_FFT_FORWARD|PS_FFT_REAL_RESULT) == NULL, 168 "PS_FFT_FORWARD|PS_FFT_REAL_RESULT returned NULL"); 169 170 // Verify return null and program execution doesn't stop if input image is null 171 img4 = psImageFFT(NULL,NULL,PS_FFT_FORWARD); 172 ok(img4 == NULL, "psImageFFT should return null for a null input image"); 173 174 // Verify return null and program execution doesn't stop if input image is incorrect direction 175 // Following should generate error for incorrect direction 176 // XXX: werify error 177 GENIMAGE(img4,8,8,S8,row+col); 178 img5 = psImageFFT(NULL,img4,PS_FFT_REAL_RESULT); 179 ok(img5 == NULL, "psImageFFT should return null for an incorrect FFT direction"); 180 181 psFree(img4); 182 psFree(img); 183 psFree(img2); 184 psFree(img3); 185 skip_end(); 186 skip_end(); 187 skip_end(); 188 ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks"); 72 psImage *real = psImageAlloc(512, 512, PS_TYPE_F32); 73 psImage *imag = psImageAlloc(512, 512, PS_TYPE_F32); 74 psImage *in = psImageAlloc(512, 512, PS_TYPE_F32); 75 bool rc = psImageForwardFFT(NULL, &imag, in); 76 ok(rc == false, "psImageForwardFFT() returned FALSE with a NULL real image input"); 77 psFree(real); 78 psFree(imag); 79 psFree(in); 80 ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks"); 189 81 } 190 82 191 // 1. create a C64 complex vector with distinctly different real and imaginary parts. 192 // 2. call psImageReal and psImageImaginary 193 // 3. compare results to the real/imaginary components of input 83 // Test with NULL imag arg 194 84 { 195 85 psMemId id = psMemGetId(); 196 psImage* c64Img = NULL; 197 psImage* c64Img2 = NULL; 198 psImage* c64Img3 = NULL; 199 psU32 m = 128; 200 psU32 n = 64; 201 202 // XXX: What is I? 203 GENIMAGE(c64Img,m,n,C64, row + I * col); 204 c64Img2 = psImageReal(c64Img2,c64Img); 205 ok(c64Img2 != NULL, "psImageReal() returned non-NULL"); 206 ok(c64Img2->type.type == PS_TYPE_F64, "psImageReal() returned the correct type"); 207 c64Img3 = psImageImaginary(c64Img3,c64Img); 208 ok(c64Img3 != NULL, "psImageImaginary() returned non-NULL"); 209 ok(c64Img3->type.type == PS_TYPE_F64, "psImageImaginary() returned the correct type"); 210 211 bool errorFlag = false; 212 for (psU32 row=0;row<n;row++) 213 { 214 psF64* img2Row = c64Img2->data.F64[row]; 215 psF64* img3Row = c64Img3->data.F64[row]; 216 for (psU32 col=0;col<m;col++) { 217 if (fabsf(img2Row[col] - row) > FLT_EPSILON) { 218 diag("psImageReal didn't return the real portion at n=%d", n); 219 errorFlag = true; 220 } 221 if (fabsf(img3Row[col] - col) > FLT_EPSILON) { 222 diag("psImageImaginary didn't return the imag portion at n=%d", n); 223 errorFlag = true; 224 } 225 } 226 } 227 ok(!errorFlag, "psImageReal() and psImageImaginary() returned the correct data"); 228 psFree(c64Img); 229 psFree(c64Img2); 230 psFree(c64Img3); 231 ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks"); 86 psImage *real = psImageAlloc(512, 512, PS_TYPE_F32); 87 psImage *imag = psImageAlloc(512, 512, PS_TYPE_F32); 88 psImage *in = psImageAlloc(512, 512, PS_TYPE_F32); 89 bool rc = psImageForwardFFT(&real, NULL, in); 90 ok(rc == false, "psImageForwardFFT() returned FALSE with a NULL imaginary image input"); 91 psFree(real); 92 psFree(imag); 93 psFree(in); 94 ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks"); 232 95 } 233 96 234 235 97 // Test with NULL input arg 236 98 { 237 99 psMemId id = psMemGetId(); 238 psImage* ncImg = NULL; 239 psImage* ncImg2 = NULL; 240 psImage* ncImg3 = NULL; 241 psU32 m = 128; 242 psU32 n = 64; 243 244 GENIMAGE(ncImg,m,n,F32,row+col); 245 ncImg2 = psImageReal(ncImg2,ncImg); 246 ncImg3 = psImageImaginary(ncImg3,ncImg); 247 ok(ncImg2 != NULL, "psImageReal() returned non-NULL"); 248 ok(ncImg2->type.type == PS_TYPE_F32, "psImageReal() returned the correct type"); 249 ok(ncImg3 != NULL, "psImageImaginary() returned non-NULL"); 250 ok(ncImg3->type.type == PS_TYPE_F32, "psImageImaginary() returned the correct type"); 251 252 bool errorFlag = false; 253 for(psU32 row=0; row<n; row++) 254 { 255 psF32* ncImg2Row = ncImg2->data.F32[row]; 256 psF32* ncImg3Row = ncImg3->data.F32[row]; 257 for(psU32 col=0; col<m; col++) { 258 if(fabsf(ncImg2Row[col] - (row+col)) > FLT_EPSILON) { 259 diag("psImageReal didn't return the real portion"); 260 errorFlag = true; 261 } 262 if(fabsf(ncImg3Row[col] - 0) > FLT_EPSILON) { 263 diag("psImageImaginary didn't return the imaginary portion"); 264 errorFlag = true; 265 } 266 } 267 } 268 ok(!errorFlag, "psImageReal() and psImageImaginary() returned the correct data"); 269 psFree(ncImg); 270 psFree(ncImg2); 271 psFree(ncImg3); 272 ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks"); 100 psImage *real = psImageAlloc(512, 512, PS_TYPE_F32); 101 psImage *imag = psImageAlloc(512, 512, PS_TYPE_F32); 102 psImage *in = psImageAlloc(512, 512, PS_TYPE_F32); 103 bool rc = psImageForwardFFT(&real, &imag, NULL); 104 ok(rc == false, "psImageForwardFFT() returned FALSE with a NULL real image input"); 105 psFree(real); 106 psFree(imag); 107 psFree(in); 108 ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks"); 273 109 } 274 110 275 276 277 // Perform psImageReal with null input 111 // Test with incorrect input image type 278 112 { 279 113 psMemId id = psMemGetId(); 280 ok(psImageReal(NULL,NULL) == NULL, "psImageReal() returned NULL with NULL inputs"); 281 ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks"); 114 psImage *real = psImageAlloc(512, 512, PS_TYPE_F32); 115 psImage *imag = psImageAlloc(512, 512, PS_TYPE_F32); 116 psImage *in = psImageAlloc(512, 512, PS_TYPE_F64); 117 bool rc = psImageForwardFFT(NULL, &imag, in); 118 ok(rc == false, "psImageForwardFFT() returned FALSE with incorrect input image type"); 119 psFree(real); 120 psFree(imag); 121 psFree(in); 122 ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks"); 282 123 } 283 124 284 285 // Perform psImageImaginary with null input 286 { 287 psMemId id = psMemGetId(); 288 ok(psImageImaginary(NULL,NULL) == NULL, "psImageImaginary() returned NULL with NULL inputs"); 289 ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks"); 290 } 291 292 293 // testImageComplex() 294 // 1. create two unique psF32 vectors of the same size 295 // 2. call psImageComplex 296 // 3. verify that the result is a psC32 297 // 4. use crealf and cimagf on step 2 results 298 // 5. compare step 4 results to input. 299 // 6. create a psF32 and a psF64 vector of the same size 300 // 7. call psImageComplex 301 // 8. verify that an appropriate error occurred. 302 // 9. create two psf32 vectors of different sizes 303 // 10. call psImageComplex 304 // 11. verify thet an appropriate error occurred. 305 { 306 psMemId id = psMemGetId(); 307 psImage* img = NULL; 308 psImage* img2 = NULL; 309 psImage* img3 = NULL; 310 psImage* c64Img = NULL; 311 psImage* c64Img2 = NULL; 312 psImage* c64Img3 = NULL; 313 psImage* pImg = NULL; 314 psImage* pImg2 = NULL; 315 psImage* pImg3 = NULL; 316 psU32 m = 128; 317 psU32 n = 64; 318 GENIMAGE(img,m,n,F32,row); 319 GENIMAGE(img2,m,n,F32,col); 320 GENIMAGE(c64Img,m,n,F64,row); 321 GENIMAGE(c64Img2,m,n,F64,col); 322 GENIMAGE(pImg,m,n,S16,row); 323 GENIMAGE(pImg2,m,n,S16,col); 324 img3 = psImageComplex(img3,img,img2); 325 ok(img3 != NULL, "psImageComplex() returned non-NULL"); 326 ok(img3->type.type == PS_TYPE_C32, "psImageComplex() returned the correct type"); 327 c64Img3 = psImageComplex(c64Img3,c64Img,c64Img2); 328 ok(c64Img3 != NULL, "psImageComplex() returned non-NULL"); 329 ok(c64Img3->type.type == PS_TYPE_C64, "psImageComplex() returned the correct type"); 330 bool errorFlag = false; 331 for (psU32 row=0;row<n;row++) 332 { 333 psC32* img3Row = img3->data.C32[row]; 334 psC64* c64Img3Row = c64Img3->data.C64[row]; 335 for (psU32 col=0;col<m;col++) { 336 if (fabsf(crealf(img3Row[col]) - row) > FLT_EPSILON || 337 fabsf(cimagf(img3Row[col]) - col) > FLT_EPSILON) { 338 diag("psImageComplex result is incorrect (%d,%d, %.2f+%.2fi)", 339 col,row,crealf(img3Row[col]),cimagf(img3Row[col])); 340 errorFlag = true; 341 } 342 if (fabsf(crealf(c64Img3Row[col]) - row) > FLT_EPSILON || 343 fabsf(cimagf(c64Img3Row[col]) - col) > FLT_EPSILON) { 344 diag("psImageComplex result is incorrect"); 345 errorFlag = true; 346 347 } 348 } 349 } 350 ok(!errorFlag, "psImageComplex() returned correct results"); 351 352 img2 = psImageRecycle(img2,m,n,PS_TYPE_F64); 353 354 // Following should be an error (type mismatch) 355 // Verify that an appropriate error occurred 356 img3 = psImageComplex(img3,img,img2); 357 ok(img3 == NULL, "psImageComplex() returned NULL when input types mismatched."); 358 359 // Following should be an error (size mismatch) 360 img2 = psImageRecycle(img2,m/2,n,PS_TYPE_F32); 361 img3 = psImageComplex(img3,img,img2); 362 ok(img3 == NULL, "psImageComplex() returned a NULL when input sizes mismatched"); 363 364 // Perform psImageComplex with incorrect type 365 // Following should generate an error message."); 366 pImg3 = psImageComplex(pImg3,pImg,pImg2); 367 ok(pImg3 == NULL, "psImageComplex returned NULL with incorrect type input"); 368 369 psFree(img); 370 psFree(img2); 371 psFree(img3); 372 psFree(c64Img); 373 psFree(c64Img2); 374 psFree(c64Img3); 375 psFree(pImg); 376 psFree(pImg2); 377 378 // Perform psImageComplex with null input 379 ok(psImageComplex(NULL,NULL,NULL) == NULL, "psImageComplex() returned NULL with null input"); 380 ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks"); 381 } 382 383 // 1. create a psC32 with unique real and imaginary values. 384 // 2. call psImageConjugate 385 // 3. verify result is psC32 386 // 4. verify each value is conjugate of input (a+bi -> a-bi) 387 // testImageConjugate() 388 { 389 psMemId id = psMemGetId(); 390 psImage* img = NULL; 391 psImage* img2 = NULL; 392 psImage* c64Img = NULL; 393 psImage* c64Img2 = NULL; 394 psImage* pImg = NULL; 395 psImage* pImg2 = NULL; 396 psU32 m = 128; 397 psU32 n = 64; 398 GENIMAGE(img,m,n,C32, row + I * col); 399 GENIMAGE(c64Img,m,n,C64,row + I*col); 400 GENIMAGE(pImg,m,n,F32,row+col); 401 402 403 img2 = psImageConjugate(img2,img); 404 ok(img2 != NULL, "psImageConjugate() returned non-NULL"); 405 c64Img2 = psImageConjugate(c64Img2,c64Img); 406 ok(c64Img2 != NULL, "psImageConjugate() returned non-NULL"); 407 pImg2 = psImageConjugate(pImg2,pImg); 408 ok(pImg2 != NULL, "psImageConjugate() returned non-NULL"); 409 410 ok(img2->type.type == PS_TYPE_C32, "psImageConjugate() returned the correct type"); 411 ok(c64Img2->type.type == PS_TYPE_C64, "psImageConjugate() returned the correct type"); 412 ok(pImg2->type.type == PS_TYPE_F32, "psImageConjugate() returned the correct type"); 413 414 bool errorFlag = false; 415 for (psU32 row=0;row<n;row++) 416 { 417 psC32* img2Row = img2->data.C32[row]; 418 psC64* c64Img2Row = c64Img2->data.C64[row]; 419 psF32* pImg2Row = pImg2->data.F32[row]; 420 for (psU32 col=0;col<m;col++) { 421 if (fabsf(crealf(img2Row[col]) - row) > FLT_EPSILON || 422 fabsf(cimagf(img2Row[col]) + col) > FLT_EPSILON) { 423 diag("psImageComplex result is incorrect (%d,%d, %.2f+%.2fi)", 424 col,row,crealf(img2Row[col]),cimagf(img2Row[col])); 425 errorFlag = true; 426 } 427 if (fabsf(crealf(c64Img2Row[col]) - row) > FLT_EPSILON || 428 fabsf(cimagf(c64Img2Row[col]) + col) > FLT_EPSILON) { 429 diag("psImageComplex result is incorrect"); 430 errorFlag = true; 431 } 432 if (fabsf(pImg2Row[col] - (row+col)) > FLT_EPSILON) { 433 diag("psImageComplex result is incorrect"); 434 errorFlag = true; 435 } 436 } 437 } 438 ok(!errorFlag, "psImageConjugate() generated the correct data values"); 439 psFree(img); 440 psFree(img2); 441 psFree(c64Img); 442 psFree(c64Img2); 443 psFree(pImg); 444 psFree(pImg2); 445 446 // Perform psImageConjugate with null input 447 ok(psImageConjugate(NULL,NULL) == NULL, "psImageConjugate() returned NULL with NULL input"); 448 ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks"); 449 } 450 451 // testImagePowerSpectrum() 452 // 1. create a psC32 vector with unique real and imaginary components 453 // 2. call psImagePowerSpectrum 454 // 3. verify result is psF32 455 // 4. verify the values are the square of the absolute values of the original 456 { 457 psMemId id = psMemGetId(); 458 psImage* img = NULL; 459 psImage* img2 = NULL; 460 psImage* c64Img = NULL; 461 psImage* c64Img2 = NULL; 462 psImage* pImg = NULL; 463 psU32 m = 128; 464 psU32 n = 64; 465 466 GENIMAGE(img,m,n,C32, row + I * col); 467 GENIMAGE(c64Img,m,n,C64,row+I*col); 468 GENIMAGE(pImg,m,n,F32,row+col); 469 470 img2 = psImagePowerSpectrum(img2,img); 471 c64Img2 = psImagePowerSpectrum(c64Img2, c64Img); 472 ok(img2 != NULL, "psImagePowerSpectrum() returned non-NULL"); 473 ok(c64Img2 != NULL, "psImagePowerSpectrum() returned non-NULL"); 474 ok(img2->type.type == PS_TYPE_F32, "psImagePowerSpectrum() returned the correct type"); 475 ok(c64Img2->type.type == PS_TYPE_F64, "psImagePowerSpectrum() returned the correct type"); 476 477 bool errorFlag = false; 478 for (psU32 row=0;row<n;row++) 479 { 480 psC32* imgRow = img->data.C32[row]; 481 psF32* img2Row = img2->data.F32[row]; 482 psC64* c64ImgRow = c64Img->data.C64[row]; 483 psF64* c64Img2Row = c64Img2->data.F64[row]; 484 for (psU32 col=0;col<m;col++) { 485 psF32 power = cabs(imgRow[col]); 486 psF64 power64 = cabs(c64ImgRow[col]); 487 power *= power/n/n/m/m; 488 power64 *= power64/n/n/m/m; 489 490 if (fabsf(img2Row[col] - power) > 2.0f*FLT_EPSILON) { 491 diag("psImagePowerSpectrum result is incorrect (%d,%d, %.2f vs %.2f)", 492 col,row,img2Row[col],power); 493 errorFlag = true; 494 } 495 if (fabsf(c64Img2Row[col] - power64) > 2.0f*FLT_EPSILON) { 496 diag("psImagePowerSpectrum result is incorrect"); 497 errorFlag = true; 498 } 499 } 500 } 501 ok(!errorFlag, "psImagePowerSPectrum() generated the correct data values"); 502 psFree(img); 503 psFree(img2); 504 psFree(c64Img); 505 psFree(c64Img2); 506 507 // Perform psImagePowerSpectrum with incorrect input 508 // Following should generate error message 509 // XXX: Verify error 510 ok(psImagePowerSpectrum(NULL,pImg) == NULL, "psImagePowerSpectrum() returned NULL with incorrect type"); 511 psFree(pImg); 512 513 // Perform psImagePowerSpectrum with NULL input 514 ok(psImagePowerSpectrum(NULL,NULL) == NULL, "psImagePowerSpectrum() returned NULL with NULL input"); 515 ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks"); 516 } 517 518 519 // testImageRealImaginary() 520 // 1. create a C32 complex image with distinctly different real and imaginary parts 521 // 2. call psImageReal and psImageImaginary 522 // 3. compare results to the real/imaginary components of input 523 // XXX: If we put this block above the previous 2 blocks, then we get memory errors 524 { 525 psMemId id = psMemGetId(); 526 psImage* img = NULL; 527 psImage* img3 = NULL; 528 psU32 m = 128; 529 psU32 n = 64; 530 GENIMAGE(img,m,n,C32, row + I * col); 531 psImage* img2 = psImageReal(NULL,img); 532 ok(img2 != NULL, "psImageReal returned non-NULL"); 533 skip_start(img2 == NULL, 4, "Skipping tests because psImageReal() returned NULL"); 534 ok(img2->type.type == PS_TYPE_F32, "psImageReal returned the correct type"); 535 img3 = psImageImaginary(img3,img); 536 ok(img3 != NULL, "psImageImaginary() returned non-NULL"); 537 skip_start(img3 == NULL, 2, "Skipping tests because psImageImaginary() returned NULL"); 538 ok(img3->type.type == PS_TYPE_F32, "psImageImaginary() returned the correct type"); 539 540 bool errorFlag = false; 541 for (psU32 row=0;row<n;row++) 542 { 543 psF32* img2Row = img2->data.F32[row]; 544 psF32* img3Row = img3->data.F32[row]; 545 for (psU32 col=0;col<m;col++) { 546 if (fabsf(img2Row[col] - row) > FLT_EPSILON) { 547 diag("psImageReal didn't return the real portion at n=%d", n); 548 errorFlag = true; 549 } 550 if (fabsf(img3Row[col] - col) > FLT_EPSILON) { 551 diag("psImageImaginary didn't return the imag portion at n=%d", n); 552 errorFlag = true; 553 } 554 } 555 } 556 ok(!errorFlag, "psImageReal(), psImageImaginary() returned the correct data"); 557 skip_end(); 558 skip_end(); 559 psFree(img); 560 psFree(img2); 561 psFree(img3); 562 ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks"); 563 } 564 565 125 testFFT(10, 10); // Real quick test 126 testFFT(10, 20); // Testing differing numCols, numRows 127 testFFT(20, 10); // Testing differing numCols, numRows 128 testFFT(611, 610); // Test something like an OTA cell 129 testFFT(2048, 4096); // Test something like a megacam chip 566 130 }
Note:
See TracChangeset
for help on using the changeset viewer.
