/** @file tst_pmMaskBadPixels.c
 *
 *  @brief Contains the tests for pmMaskBadPixels:
 *
 *    Test A - Create mask based on maskVal argument
 *    Test B - Create mask based on saturation argument
 *    Test C - Create mask based on growVal and grow arguments
 *    Test D - Auto Create mask based on maskVal argument
 *    Test E - Attempt to use null mask
 *    Test F - Attempt tp use null input image
 *    Test G - Attempt to use input image bigger than mask
 *    Test H - Attempt to use input image mask bigger than mask
 *    Test I - Attempt to use offset greater than input image
 *    Test J - Attempt to use complex input image
 *    Test K - Attempt to use non-mask type mask image
 *
 *  @author Ross Harman, MHPCC
 *
 *  @version $Revision: 1.2.2.1 $ $Name: not supported by cvs2svn $
 *  @date $Date: 2004-10-15 21:44:19 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
 */


#include "psTest.h"
#include "pslib.h"
#include "pmMaskBadPixels.h"


#define PRINT_MATRIX(IMAGE,TYPE,STRING)                                                                      \
printf(STRING);                                                                                              \
printf("\n");                                                                                                \
for(int i=IMAGE->numRows-1; i>-1; i--) {                                                                     \
    for(int j=0; j<IMAGE->numCols; j++) {                                                                    \
        if(PS_IS_PSELEMTYPE_COMPLEX(IMAGE->type.type)) {                                                     \
            printf("%f+%fi ", creal(IMAGE->data.TYPE[i][j]), cimag(IMAGE->data.TYPE[i][j]));                 \
        } else if(PS_IS_PSELEMTYPE_INT(IMAGE->type.type)) {                                                  \
            printf("%d", (int)IMAGE->data.TYPE[i][j]);                                                       \
        } else {                                                                                             \
            printf("%f", (double)IMAGE->data.TYPE[i][j]);                                                    \
        }                                                                                                    \
    }                                                                                                        \
    printf("\n");                                                                                            \
}                                                                                                            \
printf("\n");


#define CREATE_AND_SET_IMAGE(NAME,TYPE,VALUE,NROWS,NCOLS)                                                    \
psImage *NAME = (psImage*)psImageAlloc(NCOLS,NROWS,PS_TYPE_##TYPE);                                          \
for(int i=0; i<NAME->numRows; i++) {                                                                         \
    for(int j=0; j<NAME->numCols; j++) {                                                                     \
        NAME->data.TYPE[i][j] = VALUE;                                                                       \
    }                                                                                                        \
}


static int testMaskBadPixels1(void);
static int testMaskBadPixels2(void);
static int testMaskBadPixels3(void);
static int testMaskBadPixels4(void);
static int testMaskBadPixels5(void);
static int testMaskBadPixels6(void);
static int testMaskBadPixels7(void);
static int testMaskBadPixels8(void);
static int testMaskBadPixels9(void);
static int testMaskBadPixels10(void);
static int testMaskBadPixels11(void);


testDescription tests[] = {
                              {testMaskBadPixels1, 885, "pmMaskBadPixels - Create mask based on maskVal argument", 0, false},
                              {testMaskBadPixels2, 885, "pmMaskBadPixels - Create mask based on saturation argument", 0, false},
                              {testMaskBadPixels3, 885, "pmMaskBadPixels - Create mask based on growVal and grow arguments", 0, false},
                              {testMaskBadPixels4, 885, "pmMaskBadPixels - Auto create mask based on maskVal argument", 0, false},
                              {testMaskBadPixels5, 885, "pmMaskBadPixels - Attempt to use null mask", 0, false},
                              {testMaskBadPixels6, 885, "pmMaskBadPixels - Attempt tp use null input image", 0, false},
                              {testMaskBadPixels7, 885, "pmMaskBadPixels - Attempt to use input image bigger than mask", 0, false},
                              {testMaskBadPixels8, 885, "pmMaskBadPixels - Attempt to use input image mask bigger than mask", 0, false},
                              {testMaskBadPixels9, 885, "pmMaskBadPixels - Attempt to use offset greater than input image", 0, false},
                              {testMaskBadPixels10, 885, "pmMaskBadPixels - Attempt to use complex input image", 0, false},
                              {testMaskBadPixels11, 885, "pmMaskBadPixels - Attempt to use non-mask type mask image", 0, false},
                              {NULL}
                          };


int main(int argc, char* argv[])
{
    return !runTestSuite(stderr, "Test Point Driver", tests, argc, argv);
}


int testMaskBadPixels1( void )
{
    // Test A - Create mask based on maskVal argument
    CREATE_AND_SET_IMAGE(inImage1,F64,0,50,50);
    CREATE_AND_SET_IMAGE(mask1,U8,0,50,50)
    psReadout *inReadout = psReadoutAlloc(0, 0, inImage1);
    mask1->data.PS_TYPE_MASK_DATA[24][24]=1;
    PRINT_MATRIX(mask1, U8, "Data mask:");
    pmMaskBadPixels(inReadout, mask1, 1, 100.0, 0, 0);
    PRINT_MATRIX(inReadout->mask, U8, "Resulting mask:");
    psFree(mask1);
    psFree(inReadout);

    return 0;
}

int testMaskBadPixels2( void )
{
    // Test B - Create mask based on saturation argument
    CREATE_AND_SET_IMAGE(inImage2,F64,150.0,50,50);
    CREATE_AND_SET_IMAGE(mask2,U8,0,50,50)
    psReadout *inReadout2 = psReadoutAlloc(0, 0, inImage2);
    PRINT_MATRIX(mask2, U8, "Data mask:");
    pmMaskBadPixels(inReadout2, mask2, 0, 100.0, 0, 0);
    PRINT_MATRIX(inReadout2->mask, U8, "Resulting mask:");
    psFree(mask2);
    psFree(inReadout2);

    return 0;
}

int testMaskBadPixels3( void )
{
    // Test C - Create mask based on growVal and grow arguments
    CREATE_AND_SET_IMAGE(inImage3,F64,50.0,50,50);
    CREATE_AND_SET_IMAGE(mask3,U8,0,50,50)
    psReadout *inReadout3 = psReadoutAlloc(0, 0, inImage3);
    mask3->data.PS_TYPE_MASK_DATA[24][24]=1;
    mask3->data.PS_TYPE_MASK_DATA[4][3]=1;
    mask3->data.PS_TYPE_MASK_DATA[4][46]=1;
    PRINT_MATRIX(mask3, U8, "Data mask:");
    pmMaskBadPixels(inReadout3, mask3, 0, 100.0, 1, 10);
    PRINT_MATRIX(inReadout3->mask, U8, "Resulting mask:");
    psFree(mask3);
    psFree(inReadout3);

    return 0;
}

int testMaskBadPixels4( void )
{
    // Test D - Auto Create mask based on maskVal argument
    CREATE_AND_SET_IMAGE(inImage4,F64,50.0,50,50);
    CREATE_AND_SET_IMAGE(mask4,U8,0,50,50)
    CREATE_AND_SET_IMAGE(mask4i,U8,0,50,50)
    psReadout *inReadout4 = psReadoutAlloc(0, 0, inImage4);
    inReadout4->mask = mask4i;
    mask4->data.PS_TYPE_MASK_DATA[24][24]=1;
    PRINT_MATRIX(mask4, U8, "Data mask:");
    pmMaskBadPixels(inReadout4, mask4, 0, 100.0, 1, 10);
    PRINT_MATRIX(inReadout4->mask, U8, "Resulting mask:");
    psFree(mask4);
    psFree(inReadout4);

    return 0;
}

int testMaskBadPixels5( void )
{
    // Test E - Attempt to use null mask
    CREATE_AND_SET_IMAGE(inImage5,F64,50.0,50,50);
    psReadout *inReadout5 = psReadoutAlloc(0, 0, inImage5);
    pmMaskBadPixels(inReadout5, NULL, 0, 100.0, 1, 10);
    psFree(inReadout5);

    return 0;
}

int testMaskBadPixels6( void )
{
    // Test F - Attempt tp use null input image
    CREATE_AND_SET_IMAGE(mask6,U8,0,50,50)
    psReadout *inReadout6 = psReadoutAlloc(0, 0, NULL);
    inReadout6->mask = mask6;
    pmMaskBadPixels(inReadout6, mask6, 0, 100.0, 1, 10);
    psFree(inReadout6);

    return 0;
}

int testMaskBadPixels7( void )
{
    // Test G - Attempt to use input image bigger than mask
    CREATE_AND_SET_IMAGE(inImage7,F64,0.0,60,60);
    CREATE_AND_SET_IMAGE(mask7,U8,0,50,50)
    CREATE_AND_SET_IMAGE(mask7i,U8,0,50,50)
    psReadout *inReadout7 = psReadoutAlloc(0, 0, inImage7);
    inReadout7->mask = mask7i;
    pmMaskBadPixels(inReadout7, mask7, 0, 100.0, 1, 10);
    psFree(mask7);
    psFree(inReadout7);

    return 0;
}

int testMaskBadPixels8( void )
{
    // Test H - Attempt to use input image mask bigger than mask
    CREATE_AND_SET_IMAGE(inImage8,F64,0.0,50,50);
    CREATE_AND_SET_IMAGE(mask8,U8,0,50,50)
    CREATE_AND_SET_IMAGE(mask8i,U8,0,60,60)
    psReadout *inReadout8 = psReadoutAlloc(0, 0, inImage8);
    inReadout8->mask = mask8i;
    pmMaskBadPixels(inReadout8, mask8, 0, 100.0, 1, 10);
    psFree(mask8);
    psFree(inReadout8);

    return 0;
}

int testMaskBadPixels9( void )
{
    // Test I - Attempt to use offset greater than input image
    CREATE_AND_SET_IMAGE(inImage9,F64,0.0,50,50);
    CREATE_AND_SET_IMAGE(mask9,U8,0,50,50)
    CREATE_AND_SET_IMAGE(mask9i,U8,0,50,50)
    psReadout *inReadout9 = psReadoutAlloc(0, 0, inImage9);
    inReadout9->mask = mask9i;
    *(int*)&inReadout9->col0 = 150;
    *(int*)&inReadout9->row0 = 150;
    pmMaskBadPixels(inReadout9, mask9, 0, 100.0, 1, 10);
    psFree(mask9);
    psFree(inReadout9);

    return 0;
}

int testMaskBadPixels10( void )
{
    // Test J - Attempt to use complex input image
    CREATE_AND_SET_IMAGE(inImage10,C64,50.0,50,50);
    CREATE_AND_SET_IMAGE(mask10,U8,0,50,50)
    CREATE_AND_SET_IMAGE(mask10i,U8,0,50,50)
    psReadout *inReadout10 = psReadoutAlloc(0, 0, inImage10);
    inReadout10->mask = mask10i;
    pmMaskBadPixels(inReadout10, mask10, 0, 100.0, 1, 10);
    psFree(mask10);
    psFree(inReadout10);

    return 0;
}

int testMaskBadPixels11( void )
{
    // Test K - Attempt to use non-mask type mask image
    CREATE_AND_SET_IMAGE(inImage11,F64,50.0,50,50);
    CREATE_AND_SET_IMAGE(mask11,F64,0,50,50)
    CREATE_AND_SET_IMAGE(mask11i,U8,0,50,50)
    psReadout *inReadout11 = psReadoutAlloc(0, 0, inImage11);
    inReadout11->mask = mask11i;
    pmMaskBadPixels(inReadout11, mask11, 0, 100.0, 1, 10);
    psFree(mask11);
    psFree(inReadout11);

    return 0;
}

