IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Mar 1, 2007, 1:35:33 PM (19 years ago)
Author:
gusciora
Message:

Formally tap_psImageFFT2.c tap_psVectorFFT2.c. Since much of the tests
in the original files of this name test psLib functions which were removed
from the SDRS, I simply took Paul's tests for the new FFT functions, added
some tests for bad input parameter combinations, and renamed them here.

Will remove the tap_psImageFFT2.c tap_psVectorFFT2.c from CVS tree.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/test/fft/tap_psImageFFT.c

    r11685 r12154  
    1 /** @file  tst_psImageFFT.c
    2  *
    3  *  @brief Contains the tests for psFFT.[ch]
    4  *
    5  *
    6  *  @author Robert DeSonia, MHPCC
    7  *
    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 Hawaii
    12  */
    131#include <stdio.h>
    14 #include <string.h>
     2#include <math.h>
    153#include <pslib.h>
     4
    165#include "tap.h"
    176#include "pstap.h"
    187
    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
     12static 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;
    2622}
    2723
    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.
     26static void testFFT(int numCols, int numRows)
    2927{
    30     psLogSetFormat("HLNM");
    31     psLogSetLevel(PS_LOG_INFO);
    32     plan_tests(68);
     28    psMemId id = psMemGetId();
    3329
    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
     65int main(int argc, char *argv[])
     66{
     67    plan_tests(8 + 6 * 5);
     68
     69    // Test with NULL real arg
    3570    {
    3671        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");
    18981    }
    19082
    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
    19484    {
    19585        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");
    23295    }
    23396
    234 
    235 
     97    // Test with NULL input arg
    23698    {
    23799        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");
    273109    }
    274110
    275 
    276 
    277     // Perform psImageReal with null input
     111    // Test with incorrect input image type
    278112    {
    279113        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");
    282123    }
    283124
    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
    566130}
Note: See TracChangeset for help on using the changeset viewer.