Index: trunk/psLib/test/image/Makefile.am
===================================================================
--- trunk/psLib/test/image/Makefile.am	(revision 3941)
+++ trunk/psLib/test/image/Makefile.am	(revision 3973)
@@ -18,7 +18,9 @@
 	tst_psImage \
 	tst_psImageFFT \
-	tst_psImageManip \
+	tst_psImageGeomManip \
+	tst_psImagePixelManip \
 	tst_psImageStats \
-	tst_psImageExtraction \
+	tst_psImagePixelExtract \
+	tst_psImageStructManip \
 	tst_psImageConvolve \
 	tst_psImageIO \
@@ -41,7 +43,9 @@
 tst_psImage_SOURCES =  tst_psImage.c
 tst_psImageFFT_SOURCES =  tst_psImageFFT.c
-tst_psImageManip_SOURCES =  tst_psImageManip.c
+tst_psImagePixelManip_SOURCES =  tst_psImagePixelManip.c
+tst_psImageGeomManip_SOURCES =  tst_psImageGeomManip.c
 tst_psImageStats_SOURCES =  tst_psImageStats.c
-tst_psImageExtraction_SOURCES =  tst_psImageExtraction.c
+tst_psImagePixelExtract_SOURCES =  tst_psImagePixelExtract.c
+tst_psImageStructManip_SOURCES =  tst_psImageStructManip.c
 tst_psImageConvolve_SOURCES =  tst_psImageConvolve.c
 tst_psImageIO_SOURCES =  tst_psImageIO.c
Index: trunk/psLib/test/image/tst_psImage.c
===================================================================
--- trunk/psLib/test/image/tst_psImage.c	(revision 3941)
+++ trunk/psLib/test/image/tst_psImage.c	(revision 3973)
@@ -6,6 +6,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.32 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-04-07 20:27:42 $
+ *  @version $Revision: 1.33 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-05-19 02:49:40 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -223,6 +223,12 @@
     // children is freed.
     image = psImageAlloc(100,100,PS_TYPE_F32);
-    psImageSubset(image,50,0,70,20);
-    psImageSubset(image,70,20,90,40);
+    psImageSubset(image,(psRegion) {
+                      50,0,70,20
+                  }
+                 );
+    psImageSubset(image,(psRegion) {
+                      70,20,90,40
+                  }
+                 );
 
     psFree(image);
Index: trunk/psLib/test/image/tst_psImageExtraction.c
===================================================================
--- trunk/psLib/test/image/tst_psImageExtraction.c	(revision 3941)
+++ 	(revision )
@@ -1,1418 +1,0 @@
-/** @file  tst_psImageExtraction.c
-*
-*  @brief Contains the tests for psImageExtraction.[ch]
-*
-*
-*  @author Robert DeSonia, MHPCC
-*
-*  @version $Revision: 1.22 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2005-04-07 20:27:42 $
-*
-*  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
-*/
-#include<stdlib.h>
-#include<string.h>
-
-#include "psTest.h"
-#include "pslib_strict.h"
-#include "psType.h"
-
-static psS32 testImageSlice(void);
-static psS32 testImageSubset(void);
-static psS32 testImageSubsection(void);
-static psS32 testImageTrim(void);
-static psS32 testImageCut(void);
-static psS32 testImageRadialCut(void);
-
-
-testDescription tests[] = {
-                              {testImageSubset,547,"psImageSubset",0,false},
-                              {testImageSubset,550,"psImageSubset",0,true},
-                              {testImageSubsection,730,"psImageSubsection",0,false},
-                              {testImageSlice, 552, "psImageSlice", 0, false},
-                              {testImageTrim, 744, "psImageTrim", 0, false},
-                              {testImageCut, 555, "psImageCut", 0, false},
-                              {testImageRadialCut, 557, "psImageRadialCut", 0, false},
-                              {NULL}
-                          };
-
-psS32 main( psS32 argc, char* argv[] )
-{
-    return ! runTestSuite( stderr, "psImage", tests, argc, argv );
-}
-
-psS32 testImageSlice(void)
-{
-    const psS32 r = 200;
-    const psS32 c = 300;
-    const psS32 m = r / 2 -1;
-    const psS32 n = r / 4 -1;
-    psVector* out = NULL;
-    psImage* image;
-    psVector* positions = psVectorAlloc( r, PS_TYPE_U32 );
-    psImage* mask = psImageAlloc( c, r, PS_TYPE_MASK );
-    psStats* stat = psStatsAlloc( PS_STAT_SAMPLE_MEDIAN );
-
-    /*
-        This function shall extract pixels from a specified region of a psImage
-        structure into a vector using a specified statistical method.
-
-        Verify the returned psVector structure contains expected data, if the 
-        input psImage input has known data and the psStats structure specifies 
-        a known statistical method. At least two different statistical methods 
-        should be used within a valid range of psImage data. Allow for a delta 
-        when comparing results to allow for testing a different platforms. Two 
-        cases should be used for each possible direction. Data region cases 
-        should include 0x0, 1x1, Nx1, 1xN, NxN, MxN
-     
-     */
-
-    for ( psS32 row = 0;row < r;row++ ) {
-        psMaskType* maskRow = mask->data.PS_TYPE_MASK_DATA[row];
-        for ( psS32 col = 0;col < c;col++ ) {
-            maskRow[ col ] = 0;
-        }
-    }
-
-    #define PSIMAGESLICE_TEST1(TYPE,M,N,DIRECTION,TRUTH_SIZE,TRUTHPIX_X,TRUTHPIX_Y,TESTNUM) \
-    image = psImageAlloc( c, r, PS_TYPE_##TYPE ); \
-    for ( psS32 row = 0;row < r;row++ ) { \
-        ps##TYPE *imageRow = image->data.TYPE[ row ]; \
-        ps##TYPE rowOffset = row * 2; \
-        for ( psS32 col = 0;col < c;col++ ) { \
-            imageRow[ col ] = col + rowOffset; \
-        } \
-    } \
-    out = psImageSlice(out,positions,image,mask,1,c/10,r/10,c/10+M,r/10+N,DIRECTION,stat); \
-    \
-    if (out->n != TRUTH_SIZE) { \
-        psError(PS_ERR_UNKNOWN,true,"Number of results is wrong (%d, not %d)", \
-                out->n,n); \
-        return TESTNUM*4+1; \
-    } \
-    \
-    if (positions->n != TRUTH_SIZE) { \
-        psError(PS_ERR_UNKNOWN,true,"Number of results for positions vector is wrong (%d, not %d)", \
-                out->n,n); \
-        return TESTNUM*4+2; \
-    } \
-    \
-    for (psS32 i=0;i<out->n;i++) { \
-        if (fabs(out->data.F64[i]-image->data.TYPE[r/10+TRUTHPIX_Y][c/10+TRUTHPIX_X]) > 1.0/(psF64)r) { \
-            psError(PS_ERR_UNKNOWN,true,"Improper result at position %d.  Got %g, expected %g",i, \
-                    out->data.F64[i],image->data.TYPE[r/10+TRUTHPIX_Y][c/10+TRUTHPIX_X]); \
-            return TESTNUM*4+3; \
-        } \
-        if (DIRECTION == PS_CUT_X_POS || DIRECTION == PS_CUT_X_NEG) { \
-            if (positions->data.U32[i] != c/10+TRUTHPIX_X) { \
-                psError(PS_ERR_UNKNOWN,true,"Improper positions (%d vs %d) result @ %d.", \
-                        positions->data.U32[i],c/10+TRUTHPIX_X,i); \
-                return TESTNUM*4+4; \
-            } \
-        } else { \
-            if (positions->data.U32[i] != r/10+TRUTHPIX_Y) { \
-                psError(PS_ERR_UNKNOWN,true,"Improper positions (%d vs %d) result @ %d.", \
-                        positions->data.U32[i],r/10+TRUTHPIX_Y,i); \
-                return TESTNUM*4+4; \
-            } \
-        } \
-    } \
-    psFree(image);
-
-    #define PSIMAGESLICE_TEST(TYPE) \
-    /* test MxN case */ \
-    PSIMAGESLICE_TEST1(TYPE, m, n, PS_CUT_X_POS, m, i, n / 2, 0 ); \
-    PSIMAGESLICE_TEST1(TYPE, m, n, PS_CUT_X_NEG, m, m - 1 - i, n / 2, 1 ); \
-    PSIMAGESLICE_TEST1(TYPE, m, n, PS_CUT_Y_POS, n, m / 2, i, 2 ); \
-    PSIMAGESLICE_TEST1(TYPE, m, n, PS_CUT_Y_NEG, n, m / 2, n - 1 - i, 3 ); \
-    \
-    /* test Mx1 case */ \
-    PSIMAGESLICE_TEST1(TYPE, m, 1, PS_CUT_X_POS, m, i, 0, 4 ); \
-    PSIMAGESLICE_TEST1(TYPE, m, 1, PS_CUT_X_NEG, m, m - 1 - i, 0, 5 ); \
-    PSIMAGESLICE_TEST1(TYPE, m, 1, PS_CUT_Y_POS, 1, m / 2, 0, 6 ); \
-    PSIMAGESLICE_TEST1(TYPE, m, 1, PS_CUT_Y_NEG, 1, m / 2, 0, 7 ); \
-    \
-    /* test 1xN case */ \
-    PSIMAGESLICE_TEST1(TYPE, 1, n, PS_CUT_X_POS, 1, 0, n / 2, 8 ); \
-    PSIMAGESLICE_TEST1(TYPE, 1, n, PS_CUT_X_NEG, 1, 0, n / 2, 9 ); \
-    PSIMAGESLICE_TEST1(TYPE, 1, n, PS_CUT_Y_POS, n, 0, i, 10 ); \
-    PSIMAGESLICE_TEST1(TYPE, 1, n, PS_CUT_Y_NEG, n, 0, n - 1 - i, 11 ); \
-    \
-    /* test 1x1 case */ \
-    PSIMAGESLICE_TEST1(TYPE, 1, 1, PS_CUT_X_POS, 1, 0, 0, 12 ); \
-    PSIMAGESLICE_TEST1(TYPE, 1, 1, PS_CUT_X_NEG, 1, 0, 0, 13 ); \
-    PSIMAGESLICE_TEST1(TYPE, 1, 1, PS_CUT_Y_POS, 1, 0, 0, 14 ); \
-    PSIMAGESLICE_TEST1(TYPE, 1, 1, PS_CUT_Y_NEG, 1, 0, 0, 15 ); \
-
-    PSIMAGESLICE_TEST(F32);
-    PSIMAGESLICE_TEST(F64);
-    PSIMAGESLICE_TEST(U16);
-
-    image = psImageAlloc( c, r, PS_TYPE_F32 );
-
-    /*
-       Verify the returned psVector structure pointer is null and program 
-       execution doesn't stop, if input psImage input is null.
-
-    */
-    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
-    out = psImageSlice( out,
-                        NULL, NULL,
-                        NULL, 0,
-                        c/10, r/10,
-                        c/10 + 1, r/10 + 1,
-                        PS_CUT_X_POS,
-                        stat );
-    if ( out != NULL ) {
-        psError( PS_ERR_UNKNOWN,true, "Giving a NULL image, psImageSlice didn't return NULL as expected" );
-        return 101;
-    }
-
-
-    /*
-       Verify the returned psVector structure pointer is null and program 
-       execution doesn't stop, if input psStats stats is null.
-    */
-    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
-    out = psImageSlice( out,
-                        NULL, image,
-                        mask, 1,
-                        c/10, r/10,
-                        c/10 + 1,
-                        r/10 + 1,
-                        PS_CUT_X_POS,
-                        NULL );
-    if ( out != NULL ) {
-        psError( PS_ERR_UNKNOWN,true, "Giving a NULL stat struct, psImageSlice didn't return NULL as expected" );
-        return 102;
-    }
-    /*
-
-       Verify the returned psVector structure pointer is null and program 
-       executions doesn't stop, if the input direction is not set to one of 
-       the two valid values.
-    */
-    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
-    out = psImageSlice( out, NULL,
-                        image,
-                        mask, 1,
-                        c/10, r/10,
-                        c/10+1, r/10+1,
-                        5,
-                        stat);
-    if ( out != NULL ) {
-        psError( PS_ERR_UNKNOWN,true, "Giving a bogus direction flag, psImageSlice didn't return NULL as expected" );
-        return 103;
-    }
-
-    /*
-       Verify the returned psVector structure pointer is null and program 
-       execution doesn't stop, if the input nrow and/or ncol are zero.
-    */
-    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
-    out = psImageSlice( out,
-                        NULL,
-                        image,
-                        mask, 1,
-                        c/10, r/10,
-                        c/10, r/10,
-                        PS_CUT_X_POS,
-                        stat );
-    if ( out != NULL ) {
-        psError( PS_ERR_UNKNOWN,true, "Giving a 0x0 region, psImageSlice didn't return NULL as expected" );
-        return 104;
-    }
-
-    /*
-       Verify the returned psVector structure pointer is null and program 
-       execution doesn't stop, if the inputs row, col, nrow, ncol specify a 
-       regions of data that is not within the input psImage structure.
-    */
-    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
-    out = psImageSlice( out, NULL,
-                        image,
-                        mask, 1,
-                        c+1, r/10,
-                        c+2, r/10+10,
-                        PS_CUT_X_POS,
-                        stat );
-    if ( out != NULL ) {
-        psError( PS_ERR_UNKNOWN,true, "Giving an invalid x position, psImageSlice didn't return NULL as expected" );
-        return 105;
-    }
-
-    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
-    out = psImageSlice( out, NULL,
-                        image,
-                        mask, 1,
-                        c/10, r+1,
-                        c/10+1,r+5,
-                        PS_CUT_X_POS,
-                        stat );
-    if ( out != NULL ) {
-        psError( PS_ERR_UNKNOWN,true, "Giving an invalid y position, psImageSlice didn't return NULL as expected" );
-        return 106;
-    }
-
-    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
-    out = psImageSlice( out, NULL,
-                        image,
-                        mask, 1,
-                        c/10, r/10,
-                        c+1, r/10+1,
-                        PS_CUT_X_POS,
-                        stat);
-    if ( out != NULL ) {
-        psError( PS_ERR_UNKNOWN,true, "Giving an invalid numCols, psImageSlice didn't return NULL as expected" );
-        return 107;
-    }
-
-    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
-    out = psImageSlice( out, NULL,
-                        image,
-                        mask, 1,
-                        c/10, r/10,
-                        c/10+1, r + 1,
-                        PS_CUT_X_POS,
-                        stat);
-    if ( out != NULL ) {
-        psError( PS_ERR_UNKNOWN,true, "Giving an invalid numRows, psImageSlice didn't return NULL as expected" );
-        return 108;
-    }
-
-    /*
-       Verify the returned psVector structure pointer is null and program 
-       execution doesn't stop, if the input psStat structure member options is 
-       zero which indicates no statistic method specified.
-    */
-    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
-    stat->options = 0;
-    out = psImageSlice( out, NULL,
-                        image,
-                        mask, 1,
-                        c/10, r/10,
-                        c/10+1, r/10+1,
-                        PS_CUT_X_POS,
-                        stat);
-    if ( out != NULL ) {
-        psError( PS_ERR_UNKNOWN,true, "Giving an invalid numRows, psImageSlice didn't return NULL as expected" );
-        return 109;
-    }
-
-    /* Verify that a mask of different size than the input image returns null and program
-       execution doesn't stop.
-    */
-    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error mask size != image size.");
-    stat->options = PS_STAT_SAMPLE_MEDIAN;
-    psImage* maskSz = psImageAlloc( r, c, PS_TYPE_MASK );
-    out = psImageSlice( out, NULL,
-                        image,
-                        maskSz, 1,
-                        c/10, r/10,
-                        c/10+1, r/10+1,
-                        PS_CUT_X_POS,
-                        stat);
-    if ( out != NULL ) {
-        psError( PS_ERR_UNKNOWN,true, "Mask size different than image size didn't return NULL as expected" );
-        return 110;
-    }
-
-    /* Verify the a invalid type mask returns null and program execution doesn't stop.
-    */
-    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error invalid mask type.");
-    psImage* maskS8 = psImageAlloc( c, r, PS_TYPE_S8 );
-    out =  psImageSlice( out, NULL,
-                         image,
-                         maskS8, 1,
-                         c/10, r/10,
-                         c/10+1, r/10+1,
-                         PS_CUT_X_POS,
-                         stat);
-    if ( out != NULL ) {
-        psError( PS_ERR_UNKNOWN,true, "Mask invalid type didn't return NULL as expected.");
-        return 111;
-    }
-
-    psFree( image );
-    psFree( positions );
-    psFree( mask );
-    psFree( out );
-    psFree( stat );
-    psFree( maskS8 );
-    psFree( maskSz );
-
-    return 0;
-
-}
-
-// #547: psImageSubset shall create child image of a specified size from a parent psImage structure
-psS32 testImageSubset(void)
-{
-    psImage preSubsetStruct;
-    psImage* original;
-    psImage* subset1 = NULL;
-    psImage* subset2 = NULL;
-    psImage* subset3 = NULL;
-    psS32 c = 128;
-    psS32 r = 256;
-
-    original = psImageAlloc(c,r,PS_TYPE_U32);
-    for (psS32 row=0;row<r;row++) {
-        for (psS32 col=0;col<c;col++) {
-            original->data.F32[row][col] = row*1000+col;
-        }
-    }
-
-    memcpy(&preSubsetStruct,original,sizeof(psImage));
-
-    subset2 = psImageSubset(original,c/4,r/4,c/4+c/2,r/4+r/2);
-
-    subset3 = psImageSubset(original,0,0,c/2,r/2);
-
-    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure members nrow and ncol are equal to "
-             "the input parameter nrow and ncol respectively.");
-
-    if (subset2->numCols != c/2 || subset2->numRows != r/2) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubset output size was not proper(%dx%d, should be %dx%d).",
-                subset2->numCols, subset2->numRows, c/2,r/2);
-        return 1;
-    }
-
-    if (subset3->numCols != c/2 || subset3->numRows != r/2) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubset output size was not proper(%dx%d, should be %dx%d).",
-                subset3->numCols, subset3->numRows, c/2,r/2);
-        return 2;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure contains expected values in the "
-             "row member, if the input psImage structure image contains known values.");
-
-    for (psS32 row=0;row<r/2;row++) {
-        for (psS32 col=0;col<c/2;col++) {
-            if (subset2->data.U32[row][col] != original->data.U32[row+r/4][col+c/4]) {
-                psError(PS_ERR_UNKNOWN,true,"psImageSubset output #1 was wrong at %dx%d (%d vs %d).",
-                        row,col,subset2->data.U32[row][col], original->data.U32[row+r/4][col+c/4]);
-                return 3;
-            }
-            if (subset3->data.U32[row][col] != original->data.U32[row][col]) {
-                psError(PS_ERR_UNKNOWN,true,"psImageSubset output #1 was wrong at %dx%d (%d vs %d).",
-                        row,col,subset2->data.U32[row][col], original->data.U32[row][col]);
-                return 4;
-            }
-        }
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure member type is equal to the input "
-             "psImage structure member type.");
-
-    if (subset2->type.type != PS_TYPE_U32) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubset output type was not proper(%d, should be %d).",
-                subset2->type.type, PS_TYPE_U32);
-        return 6;
-    }
-    if (subset3->type.type != PS_TYPE_U32) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubset output type was not proper(%d, should be %d).",
-                subset3->type.type, PS_TYPE_U32);
-        return 7;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure members row0 and col0 are equal to "
-             "the input parameters row0 and col0 respectively.");
-
-    if (subset2->col0 != c/4 || subset2->row0 != r/4) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't set col0/row0 for subset2 (%d/%d, should be %d/%d).",
-                subset2->col0,subset2->row0,c/4,r/4);
-        return 8;
-    }
-    if (subset3->col0 != 0 || subset3->row0 != 0) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't set col0/row0 for subset3 (%d/%d, should be %d/%d).",
-                subset3->col0,subset3->row0,0,0);
-        return 9;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure member parent is equal to the "
-             "input psImage structure pointer image.");
-
-    if (subset2->parent != original || subset3->parent != original) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't set parent.");
-        return 10;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure member children is null.");
-
-    if (subset2->children != NULL || subset3->children != NULL) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't set children to NULL.");
-        return 11;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"Verify the input psImage structure image only has the following members "
-             "changed: 1) Nchildren is increased by one. 2) parent contains pointer psImage structure "
-             "out at parent[Nchildren-1].");
-
-    if (original->children == NULL || original->children->n != 2) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't increment number of children by one per subset.");
-        return 12;
-    }
-    if (original->children->data[0] != subset2 || original->children->data[1] != subset3) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't properly store the children pointers.");
-        return 13;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure pointer is null and program "
-             "execution doesn't stop, if the input parameter image is null. Also verified the input "
-             "psImage structure is not modified.");
-
-    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
-    subset1 = psImageSubset(NULL,0,0,c/2,r/2);
-    if (subset1 != NULL) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't return NULL when input image was NULL.");
-        return 14;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure pointer is null and program "
-             " execution doesn't stop, if the input parameters nrow and/or ncol are zero. Also verify "
-             "input psImage structure is not modified.");
-
-    memcpy(&preSubsetStruct,original,sizeof(psImage));
-    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
-    subset1 = psImageSubset(original,0,r/2,c/2,r/2);
-    if (subset1 != NULL) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't return NULL when numRows=0.");
-        return 15;
-    }
-    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
-    subset1 = psImageSubset(original,c/2,0,c/2,r/2);
-    if (subset1 != NULL) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't return NULL when numCols=0.");
-        return 16;
-    }
-    if (memcmp(original,&preSubsetStruct,sizeof(psImage)) != 0) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubset changed the original struct though it failed to subset.");
-        return 17;
-    }
-
-
-    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure pointer is null and program "
-             "execution doesn't stop, if the input parameters row0 and col0 are not within the range of "
-             "values of psImage structure image.");
-
-    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
-    subset1 = psImageSubset(original,0,0,c/2,r*2);
-    if (subset1 != NULL) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't return NULL when subset origin was outside of "
-                "image (via cols).");
-        return 18;
-    }
-    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
-    subset1 = psImageSubset(original,0,0,c*2,r/2);
-    if (subset1 != NULL) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't return NULL when subset origin was outside of "
-                "image (via rows).");
-        return 19;
-    }
-    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
-    subset1 = psImageSubset(original,-1,0,c/2,r/2);
-    if (subset1 != NULL) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't return NULL when subset origin was outside of "
-                "image (col0=-1).");
-        return 20;
-    }
-    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
-    subset1 = psImageSubset(original,0,-1,c/2,r/2);
-    if (subset1 != NULL) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't return NULL when subset origin was outside of "
-                "image (row0=-1).");
-        return 21;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure pointer is null and program "
-             "execution doesn't stop if the input parameters nrow, ncol, row0 and col0 specify a range of "
-             "data not within the input psImage structure image.  Also verify the input psImage structure "
-             "is not modified.");
-
-    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
-    subset1 = psImageSubset(original,0,0,c/2,r+1);
-    if (subset1 != NULL) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't return NULL when subset was outside of image (via rows).");
-        return 22;
-    }
-    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
-    subset1 = psImageSubset(original,0,0,c+1,r/2);
-    if (subset1 != NULL) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't return NULL when subset was outside of image (via cols).");
-        return 23;
-    }
-    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
-    subset1 = psImageSubset(original,0,0,c+1,r+1);
-    if (subset1 != NULL) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't return NULL when subset was outside of image (via row+cols).");
-        return 24;
-    }
-
-    psLogMsg(__func__, PS_LOG_INFO, "psImageFreeChildren shall deallocate any children images of a "
-             "psImage structure");
-
-    memcpy(&preSubsetStruct,original,sizeof(psImage));
-
-    psImageFreeChildren(original);
-
-    // Verify the returned psImage structure member Nchildren is set to zero.
-    if (original->children != NULL && original->children->n > 0) {
-        psError(PS_ERR_UNKNOWN,true,"psImageFreeChildren didn't set number of children to zero.");
-        return 25;
-    }
-
-    //Verify the returned psImage structure members type, nrow, ncol, row0, col0, rows and parent are not
-    // modified.
-    if (preSubsetStruct.numRows != original->numRows ||
-            preSubsetStruct.numCols != original->numCols ||
-            preSubsetStruct.row0 != original->row0 ||
-            preSubsetStruct.col0 != original->col0) {
-
-        psError(PS_ERR_UNKNOWN,true,"psImageFreeChildren modified parent's non-children elements.");
-        return 27;
-    }
-
-    psFree(original);
-
-    return 0;
-}
-
-// #730: psImageSubsection shall create child image of a specified size from a parent psImage structure
-psS32 testImageSubsection(void)
-{
-    psImage* original;
-    psImage* subset;
-    psS32 c = 128;
-    psS32 r = 256;
-    psS32 i;
-    psS32 numRegions = 4;
-    psS32 x1[] = {  0, 32, 64, 32};
-    psS32 x2[] = { 32, 64,127, 64};
-    psS32 y1[] = {  0, 32, 32,128};
-    psS32 y2[] = { 32, 64, 64,255};
-
-    original = psImageAlloc(c,r,PS_TYPE_U32);
-    for (psS32 row=0;row<r;row++) {
-        for (psS32 col=0;col<c;col++) {
-            original->data.F32[row][col] = row*1000+col;
-        }
-    }
-
-    for (i=0; i<numRegions; i++) {
-        char sectionStr[64];
-        sprintf(sectionStr,"[%d:%d,%d:%d]",x1[i],x2[i],y1[i],y2[i]);
-
-        psLogMsg(__func__,PS_LOG_INFO,"Testing subsection %s.",
-                 sectionStr);
-
-        subset = psImageSubsection(original,sectionStr);
-
-        if (subset == NULL) {
-            psError(PS_ERR_UNKNOWN,true,"psImageSubsection returned a NULL with a subset of %s.",
-                    sectionStr);
-            return 10*i+1;
-        }
-
-        if (subset->type.type != PS_TYPE_U32) {
-            psError(PS_ERR_UNKNOWN,true,"psImageSubsection output type was not proper(%d, should be %d).",
-                    subset->type.type, PS_TYPE_U32);
-            return 10*i+2;
-        }
-
-        if (subset->col0 != x1[i] || subset->row0 != y1[i]) {
-            psError(PS_ERR_UNKNOWN,true,"psImageSubsection didn't set properly col0/row0 (%d/%d, should be %d/%d).",
-                    subset->col0,subset->row0,x1[i],y1[i]);
-            return 10*i+3;
-        }
-
-        if (subset->parent != original) {
-            psError(PS_ERR_UNKNOWN,true,"psImageSubsection didn't set parent.");
-            return 10*i+4;
-        }
-
-        if (subset->children != NULL) {
-            psError(PS_ERR_UNKNOWN,true,"psImageSubsection didn't set children to NULL.");
-            return 10*i+5;
-        }
-
-        if (original->children == NULL || original->children->n != i+1) {
-            psError(PS_ERR_UNKNOWN,true,"psImageSubsection didn't increment number of children by one per subset.");
-            return 10*i+6;
-        }
-
-
-        if (original->children->data[i] != subset) {
-            psError(PS_ERR_UNKNOWN,true,"psImageSubsection didn't properly store the children pointer.");
-            return 10*i+7;
-        }
-
-        psS32 numCols = x2[i]-x1[i]+1;
-        psS32 numRows = y2[i]-y1[i]+1;
-        if (subset->numCols != numCols || subset->numRows != numRows) {
-            psError(PS_ERR_UNKNOWN,true,"psImageSubsection output size was not proper(%dx%d, should be %dx%d).",
-                    subset->numCols, subset->numRows, numCols, numRows);
-            return 10*i+8;
-        }
-
-        for (psS32 row=0;row<numRows;row++) {
-            for (psS32 col=0;col<numCols;col++) {
-                if (subset->data.U32[row][col] != original->data.U32[row+y1[i]][col+x1[i]]) {
-                    psError(PS_ERR_UNKNOWN,true,"psImageSubset output #1 was wrong at %dx%d (%d vs %d).",
-                            row,col,subset->data.U32[row][col], original->data.U32[row+y1[i]][col+x1[i]]);
-                    return 10*i+9;
-                }
-            }
-        }
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (x1>x2)");
-    subset = psImageSubsection(original,"[64:32,32:64]");
-    if (subset != NULL) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubsection didn't return NULL when x1 > x2.");
-        return 10*i+10;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (y1>y2)");
-    subset = psImageSubsection(original,"[32:64,64:32]");
-    if (subset != NULL) {
-        psError(PS_ERR_UNKNOWN,true,"psImageSubsection didn't return NULL when y1 > y2.");
-        return 10*i+11;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (x2>nCols)");
-    subset = psImageSubsection(original,"[64:256,32:64]"); // assumes c<256
-    if (subset != NULL) {
-        psError(PS_ERR_UNKNOWN, true,"psImageSubsection didn't return NULL when x2 > c.");
-        return 10*i+12;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (y2>=nRows)");
-    subset = psImageSubsection(original,"[32:64,64:256]"); // assumes r==256
-    if (subset != NULL) {
-        psError(PS_ERR_UNKNOWN, true,"psImageSubsection didn't return NULL when y2 > r.");
-        return 10*i+13;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (malformed string - no brackets)");
-    subset = psImageSubsection(original,"32:64,32:64");
-    if (subset != NULL) {
-        psError(PS_ERR_UNKNOWN, true,"psImageSubsection didn't return NULL when subsection was '32:64,32:64'.");
-        return 10*i+14;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (malformed string - no colons)");
-    subset = psImageSubsection(original,"[32-64,32-64]");
-    if (subset != NULL) {
-        psError(PS_ERR_UNKNOWN, true,"psImageSubsection didn't return NULL when subsection was '[32-64,32-64]'.");
-        return 10*i+15;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (malformed string - not four numbers)");
-    subset = psImageSubsection(original,"[32:64,32]");
-    if (subset != NULL) {
-        psError(PS_ERR_UNKNOWN, true,"psImageSubsection didn't return NULL when subsection was '[32:64,32]'.");
-        return 10*i+16;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (image is NULL)");
-    subset = psImageSubsection(NULL,"[32:64,32:64]");
-    if (subset != NULL) {
-        psError(PS_ERR_UNKNOWN, true,"psImageSubsection didn't return NULL when image was NULL.");
-        return 10*i+17;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (subsection string is NULL)");
-    subset = psImageSubsection(original,NULL);
-    if (subset != NULL) {
-        psError(PS_ERR_UNKNOWN, true,"psImageSubsection didn't return NULL when subsection was NULL.");
-        return 10*i+18;
-    }
-
-    psFree(original);
-
-    return 0;
-}
-
-static psS32 testImageTrim(void)
-{
-    psS32 r = 200;
-    psS32 c = 300;
-    psS32 qtrR = r/4;
-    psS32 qtrC = c/4;
-    psS32 halfR = r/2;
-    psS32 halfC = c/2;
-
-    psImage* image = psImageAlloc(c,r,PS_TYPE_F32);
-    for (psS32 row = 0; row < image->numRows; row++) {
-        for (psS32 col = 0; col < image->numCols; col++) {
-            image->data.F32[row][col] = (psF32)col + (psF32)row/1000.0f;
-        }
-    }
-
-    /*
-        1. invoke psImageTrim with non-NULL image, and a valid region 
-           x0,y0->x1,y1 (using only positive values). Verify that:
-            a. the return psImage is the same as the input psImage.
-            b. the size of the psImage is x1-x0 by y1-y0.
-            c. the pixel values coorespond to the region [x0:x1-1,y0:y1-1].
-    */
-    psImage* image1 = psImageCopy(NULL,image,PS_TYPE_F32);
-    psImage* image2 = psImageTrim(image1,qtrC,qtrR,qtrC+halfC,qtrR+halfR);
-
-    if (image1 != image2) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "Return value not same as input value.  Not done in-place?");
-        return 1;
-    }
-
-    if (image2->numCols != halfC ||
-            image2->numRows != halfR) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "The resulting image size was %dx%d, but should be %dx%d.",
-                 image2->numCols, image2->numRows,
-                 halfC, halfR);
-        return 2;
-    }
-
-    for (psS32 row = 0; row < image2->numRows; row++) {
-        for (psS32 col = 0; col < image2->numCols; col++) {
-            if (fabsf(image2->data.F32[row][col] - image->data.F32[row+qtrR][col+qtrC]) > FLT_EPSILON) {
-                psLogMsg(__func__,PS_LOG_ERROR,
-                         "The value at (%d,%d) was %g, but should be %g.",
-                         col,row,
-                         image2->data.F32[row][col],
-                         image->data.F32[row+qtrR][col+qtrC]);
-                return 3;
-            }
-        }
-    }
-
-    /*
-        2. invoke psImageTrim with non-NULL image and valid region where x1=0, 
-           y1=0. Verify that:
-            a. the return psImage size is numCols-x0 by numRows-y0
-            b. the pixel values coorespond to the region 
-               [x0:numCols-1,y0:numRows-1].
-    */
-    image1 = psImageCopy(image1,image,PS_TYPE_F32);
-    image2 = psImageTrim(image1,qtrC,qtrR,0,0);
-
-    if (image1 != image2) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "Return value not same as input value.  Not done in-place?");
-        return 11;
-    }
-
-    if (image2->numCols != image->numCols-qtrC ||
-            image2->numRows != image->numRows-qtrR) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "The resulting image size was %dx%d, but should be %dx%d.",
-                 image2->numCols, image2->numRows,
-                 image->numCols-qtrC, image->numRows-qtrR);
-        return 12;
-    }
-
-    for (psS32 row = 0; row < image2->numRows; row++) {
-        for (psS32 col = 0; col < image2->numCols; col++) {
-            if (fabsf(image2->data.F32[row][col] -
-                      image->data.F32[row+qtrR][col+qtrC]) > FLT_EPSILON) {
-                psLogMsg(__func__,PS_LOG_ERROR,
-                         "The value at (%d,%d) was %g, but should be %g.",
-                         col,row,
-                         image2->data.F32[row][col],
-                         image->data.F32[row+qtrR][col+qtrC]);
-                return 13;
-            }
-        }
-    }
-
-    /*
-        4. invoke psImageTrim with x1<0, y1<0. Verify:
-            a. the psImage size is (numCols+x1)-x0 by (numRows+y1)-y0.
-            b. the pixel values coorespond to the region 
-               [x0:numCols+x1-1,y0:numRows+y1-1].
-
-    */
-    image1 = psImageCopy(image1,image,PS_TYPE_F32);
-    image2 = psImageTrim(image1,qtrC,qtrR,-qtrC,-qtrR);
-
-    if (image1 != image2) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "Return value not same as input value.  Not done in-place?");
-        return 21;
-    }
-
-    if (image2->numCols != image->numCols-qtrC-qtrC ||
-            image2->numRows != image->numRows-qtrR-qtrR) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "The resulting image size was %dx%d, but should be %dx%d.",
-                 image2->numCols, image2->numRows,
-                 image->numCols-qtrC, image->numRows-qtrR);
-        return 22;
-    }
-
-    for (psS32 row = 0; row < image2->numRows; row++) {
-        for (psS32 col = 0; col < image2->numCols; col++) {
-            if (fabsf(image2->data.F32[row][col] -
-                      image->data.F32[row+qtrR][col+qtrC]) > FLT_EPSILON) {
-                psLogMsg(__func__,PS_LOG_ERROR,
-                         "The value at (%d,%d) was %g, but should be %g.",
-                         col,row,
-                         image2->data.F32[row][col],
-                         image->data.F32[row+qtrR][col+qtrC]);
-                return 23;
-            }
-        }
-    }
-
-    psFree(image2);
-
-    /*
-        6. invoke psImageTrim with image=NULL Verify:
-            a. execution does not cease.
-            b. return value is NULL
-            c. appropriate error is generated.
-    */
-
-    image2 = psImageTrim(NULL,qtrC,qtrR,0,0);
-
-    if (image2 != NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageTrim did not return NULL given a NULL input image.");
-        return 31;
-    }
-    psErr* err = psErrorLast();
-    if (err == NULL || err->code != PS_ERR_BAD_PARAMETER_NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageTrim did not generate an appropriate error for NULL input image.");
-        psErrorStackPrint(stderr,"Error Stack:");
-        return 32;
-    }
-    psFree(err);
-
-    image1 = psImageCopy(NULL,image,PS_TYPE_F32);
-    image2 = psImageTrim(image1,-1,0,0,0);
-
-    if (image2 != NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageTrim did not return NULL given x0=-1.");
-        return 33;
-    }
-    err = psErrorLast();
-    if (err == NULL || err->code != PS_ERR_BAD_PARAMETER_VALUE) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageTrim did not generate an appropriate error for x0=-1.");
-        psErrorStackPrint(stderr,"Error Stack:");
-        return 34;
-    }
-    psFree(err);
-
-    image1 = psImageCopy(NULL,image,PS_TYPE_F32);
-    image2 = psImageTrim(image1,0,-1,0,0);
-
-    if (image2 != NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageTrim did not return NULL given y0=-1.");
-        return 35;
-    }
-    err = psErrorLast();
-    if (err == NULL || err->code != PS_ERR_BAD_PARAMETER_VALUE) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageTrim did not generate an appropriate error for y0=-1.");
-        psErrorStackPrint(stderr,"Error Stack:");
-        return 36;
-    }
-    psFree(err);
-
-    image1 = psImageCopy(NULL,image,PS_TYPE_F32);
-    image2 = psImageTrim(image1,0,0,image->numCols+1,0);
-
-    if (image2 != NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageTrim did not return NULL given x1=numCols+1.");
-        return 37;
-    }
-    err = psErrorLast();
-    if (err == NULL || err->code != PS_ERR_BAD_PARAMETER_VALUE) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageTrim did not generate an appropriate error for x1=numCols+1.");
-        psErrorStackPrint(stderr,"Error Stack:");
-        return 38;
-    }
-    psFree(err);
-
-    image1 = psImageCopy(NULL,image,PS_TYPE_F32);
-    image2 = psImageTrim(image1,0,0,0,image->numRows+1);
-
-    if (image2 != NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageTrim did not return NULL given y1=numRows+1.");
-        return 39;
-    }
-    err = psErrorLast();
-    if (err == NULL || err->code != PS_ERR_BAD_PARAMETER_VALUE) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageTrim did not generate an appropriate error for y1=numRows+1.");
-        psErrorStackPrint(stderr,"Error Stack:");
-        return 40;
-    }
-    psFree(err);
-
-    image1 = psImageCopy(NULL,image,PS_TYPE_F32);
-    image2 = psImageTrim(image1,0,0,-image->numCols,0);
-
-    if (image2 != NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageTrim did not return NULL given x1=-numCols.");
-        return 41;
-    }
-    err = psErrorLast();
-    if (err == NULL || err->code != PS_ERR_BAD_PARAMETER_VALUE) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageTrim did not generate an appropriate error for x1=-numCols.");
-        psErrorStackPrint(stderr,"Error Stack:");
-        return 42;
-    }
-    psFree(err);
-
-    image1 = psImageCopy(NULL,image,PS_TYPE_F32);
-    image2 = psImageTrim(image1,0,0,0,-image->numRows);
-
-    if (image2 != NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageTrim did not return NULL given y1=-numRows.");
-        return 41;
-    }
-    err = psErrorLast();
-    if (err == NULL || err->code != PS_ERR_BAD_PARAMETER_VALUE) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageTrim did not generate an appropriate error for y1=-numRows.");
-        psErrorStackPrint(stderr,"Error Stack:");
-        return 42;
-    }
-    psFree(err);
-
-    psFree(image);
-    return 0;
-}
-
-static psS32 testImageCut(void)
-{
-    psS32 c = 300;
-    psS32 r = 200;
-    psS32 numPoints = 15;
-    float startCol[] = { 40,150, 40,  0,280, 40,280, -1,300, 20, 20, 20, 20, 20, 20};
-    float endCol[] =   {240,150,240,299, 40,240, 40,240,240, -1,300,240,240,240,240};
-    float startRow[] = { 20, 10,100,  0, 20,180,180, 10, 10, 10, 10, -1,200, 10, 10};
-    float endRow[] =   {160,180,100,199,160, 10, 10,180,180,180,180,180,180, -1,200};
-    psBool success[] = {true,true,true,true,true,true,true,false,false,false,false,false,false,false,false};
-    psU32 length = 100;
-
-    psImage* image = psImageAlloc(c,r,PS_TYPE_F32);
-    psImage* mask = psImageAlloc(c,r,PS_TYPE_MASK);
-    for (psS32 row = 0; row < image->numRows; row++) {
-        for (psS32 col = 0; col < image->numCols; col++) {
-            image->data.F32[row][col] = (psF32)col + (psF32)row/1000.0f;
-            if ((row & 0x0F) == 0) {
-                mask->data.PS_TYPE_MASK_DATA[row][col] = 1;
-            } else {
-                mask->data.PS_TYPE_MASK_DATA[row][col] = 0;
-            }
-        }
-    }
-    psVector* rows = psVectorAlloc(length,PS_TYPE_F32);
-    psVector* cols = psVectorAlloc(length,PS_TYPE_F32);
-
-    psVector* result = NULL;
-    for (psS32 n = 0; n < numPoints; n++) {
-        psVector* orig = result;
-        if (! success[n]) {
-            psLogMsg(__func__,PS_LOG_INFO,"The following should be an error.");
-        }
-        if (n == 1) {
-            result = psImageCut(result,
-                                cols,rows,
-                                image,
-                                NULL,0,
-                                startCol[n], startRow[n],
-                                endCol[n], endRow[n],
-                                length,
-                                PS_INTERPOLATE_FLAT);
-        } else {
-            result = psImageCut(result,
-                                cols,rows,
-                                image,
-                                mask,1,
-                                startCol[n], startRow[n],
-                                endCol[n], endRow[n],
-                                length,
-                                PS_INTERPOLATE_FLAT);
-        }
-
-        if (success[n]) {
-            if (result == NULL) {
-                psLogMsg(__func__,PS_LOG_ERROR,
-                         "psImageCut returned NULL instead of a valid result.");
-                return n*10+1;
-            }
-
-            if (orig != NULL && orig != result) {
-                psLogMsg(__func__,PS_LOG_ERROR,
-                         "psImageCut didn't recycle the out parameter properly.");
-                return n*10+2;
-            }
-
-            float deltaRow = (endRow[n]-startRow[n])/(length-1);
-            float deltaCol = (endCol[n]-startCol[n])/(length-1);
-            psF32 truth;
-            for (psS32 i = 0; i < length; i++) {
-                float x = (float)startCol[n]+(float)i*deltaCol;
-                float y = (float)startRow[n]+(float)i*deltaRow;
-                if (n == 1) {
-                    truth = psImagePixelInterpolate( image, x, y,
-                                                     NULL,0,0,PS_INTERPOLATE_FLAT);
-                } else {
-                    truth = psImagePixelInterpolate( image, x, y,
-                                                     mask,1,0,PS_INTERPOLATE_FLAT);
-                }
-                if (fabs(result->data.F32[i]-truth) > FLT_EPSILON) {
-                    psLogMsg(__func__,PS_LOG_ERROR,
-                             "Bad result in position %d; Found %g but expected %g.",
-                             i, result->data.F32[i], truth);
-                    return n*10+5;
-                }
-                if (fabsf(x - cols->data.F32[i]) > FLT_EPSILON ||
-                        fabsf(y - rows->data.F32[i]) > FLT_EPSILON) {
-                    psLogMsg(__func__,PS_LOG_ERROR,
-                             "Bad resulting col/row at index %d; Found (%g,%g) but expected (%g,%g).",
-                             i, cols->data.F32[i], rows->data.F32[i], x, y);
-                    return n*10+6;
-                }
-            }
-        } else {
-            if (result != NULL) {
-                psLogMsg(__func__,PS_LOG_ERROR,
-                         "psImageCut did not return NULL with a cut of (%g,%g)->(%g,%g).",
-                         startCol[n],startRow[n],endCol[n],endRow[n]);
-                return n*10+7;
-            }
-            psErr* err = psErrorLast();
-            if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
-                psLogMsg(__func__,PS_LOG_ERROR,
-                         "psImageCut did not generate proper error message.");
-                return 105;
-            }
-            psFree(err);
-        }
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error (NULL image).");
-    result = psImageCut(result,
-                        cols,rows,
-                        NULL,
-                        mask,1,
-                        startCol[0], startRow[0],
-                        endCol[0], endRow[0],
-                        length,
-                        PS_INTERPOLATE_FLAT);
-    if (result != NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageCut did not return NULL given NULL image.");
-        return 100;
-    }
-    psErr* err = psErrorLast();
-    if (err->code != PS_ERR_BAD_PARAMETER_NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageCut did not generate proper error message given NULL image.");
-        return 101;
-    }
-    psFree(err);
-
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error (length=0).");
-    result = psImageCut(result,
-                        cols,rows,
-                        image,
-                        mask,1,
-                        startCol[0], startRow[0],
-                        endCol[0], endRow[0],
-                        0,
-                        PS_INTERPOLATE_FLAT);
-    if (result != NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageCut did not return NULL given length=0.");
-        return 102;
-    }
-    err = psErrorLast();
-    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageCut did not generate proper error message given length=0.");
-        return 103;
-    }
-    psFree(err);
-
-    psFree(result);
-    psFree(image);
-    psFree(mask);
-    psFree(rows);
-    psFree(cols);
-
-    return 0;
-}
-
-static psS32 testImageRadialCut(void)
-{
-    psS32 c = 300;
-    psS32 r = 200;
-    psS32 centerX = c/2;
-    psS32 centerY = r/2;
-    psErr* err = NULL;
-
-    psImage* image = psImageAlloc(c,r,PS_TYPE_F32);
-    psImage* mask = psImageAlloc(c,r,PS_TYPE_MASK);
-    for (psS32 row = 0; row < image->numRows; row++) {
-        for (psS32 col = 0; col < image->numCols; col++) {
-            image->data.F32[row][col] = sqrtf((col-centerX)*(col-centerX)+(row-centerY)*(row-centerY));
-            if ((row & 0x0F) == 0) {
-                mask->data.PS_TYPE_MASK_DATA[row][col] = 1;
-            } else {
-                mask->data.PS_TYPE_MASK_DATA[row][col] = 0;
-            }
-        }
-    }
-
-    psStats* stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
-    psVector* radii = psVectorAlloc(10,PS_TYPE_F32);
-    for (psS32 i=0; i < 10; i++) {
-        radii->data.F32[i] = 10+i*10;
-    }
-
-    psVector* result = NULL;
-
-    result = psImageRadialCut(result,image,mask,1,centerX,centerY,radii,stat);
-
-    if (result == NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "Return value of NULL unexpected.");
-        return 1;
-    }
-
-    if (result->type.type != PS_TYPE_F64) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "Return type not psF64, as expected.");
-        return 2;
-    }
-
-    for (psS32 i=0; i < 9; i++) {
-        if (fabs(result->data.F64[i] - (15.0+i*10)) > 1) {
-            psLogMsg(__func__,PS_LOG_ERROR,
-                     "Result was not as expected for radii #%d (%g, expected %d +/- 1)",
-                     result->data.F64[i], (15.0+i*10) );
-            return 3+i;
-        }
-    }
-
-    // again, but without mask
-    psVector* orig = result;
-    result = psImageRadialCut(result,image,NULL,1,centerX,centerY,radii,stat);
-
-    if (result == NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "Return value of NULL unexpected.");
-        return 12;
-    }
-
-    if (result != orig) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "Return value of is not same as input parameter 'out'.");
-        return 13;
-    }
-
-    for (psS32 i=0; i < 9; i++) {
-        if (fabs(result->data.F64[i] - (15.0+i*10)) > 1) {
-            psLogMsg(__func__,PS_LOG_ERROR,
-                     "Result was not as expected for radii #%d (%g, expected %d +/- 1)",
-                     result->data.F64[i], (15.0+i*10) );
-            return 14+i;
-        }
-    }
-
-    // NULL input image...
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
-    result = psImageRadialCut(result,NULL,NULL,1,centerX,centerY,radii,stat);
-
-    if (result != NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "Return value not NULL as expected.");
-        return 23;
-    }
-
-    err = psErrorLast();
-    if (err->code != PS_ERR_BAD_PARAMETER_NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageRadialCut did not generate proper error message.");
-        return 24;
-    }
-    psFree(err);
-
-    // NULL input radii...
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
-    result = psImageRadialCut(result,image,mask,1,centerX,centerY,NULL,stat);
-
-    if (result != NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "Return value not NULL as expected.");
-        return 23;
-    }
-
-    err = psErrorLast();
-    if (err->code != PS_ERR_BAD_PARAMETER_NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageRadialCut did not generate proper error message.");
-        return 24;
-    }
-    psFree(err);
-
-    // NULL input stat...
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
-    result = psImageRadialCut(result,image,mask,1,centerX,centerY,radii,NULL);
-
-    if (result != NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "Return value not NULL as expected.");
-        return 23;
-    }
-
-    err = psErrorLast();
-    if (err->code != PS_ERR_BAD_PARAMETER_NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageRadialCut did not generate proper error message.");
-        return 24;
-    }
-    psFree(err);
-
-    // Bad center X
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
-    result = psImageRadialCut(result,image,mask,1,
-                              c+1,centerY,radii,stat);
-
-    if (result != NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "Return value not NULL as expected.");
-        return 25;
-    }
-
-    err = psErrorLast();
-    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageRadialCut did not generate proper error message.");
-        return 26;
-    }
-    psFree(err);
-
-    // Bad center Y
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
-    result = psImageRadialCut(result,image,mask,1,
-                              centerX,r+1,radii,stat);
-
-    if (result != NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "Return value not NULL as expected.");
-        return 27;
-    }
-
-    err = psErrorLast();
-    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageRadialCut did not generate proper error message.");
-        return 28;
-    }
-    psFree(err);
-
-    // Bad mask type (N.B., swapped image/mask to do this)
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
-    result = psImageRadialCut(result,mask,image,1,
-                              centerX,r+1,radii,stat);
-
-    if (result != NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "Return value not NULL as expected.");
-        return 29;
-    }
-
-    err = psErrorLast();
-    if (err->code != PS_ERR_BAD_PARAMETER_TYPE) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageRadialCut did not generate proper error message.");
-        return 30;
-    }
-    psFree(err);
-
-    // Bad mask size
-    psImage* mask2 = psImageAlloc(c/2,r/2,PS_TYPE_MASK);
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
-    result = psImageRadialCut(result,image, mask2, 1,
-                              centerX,centerY,radii,stat);
-    psFree(mask2);
-    if (result != NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "Return value not NULL as expected.");
-        return 31;
-    }
-
-    err = psErrorLast();
-    if (err->code != PS_ERR_BAD_PARAMETER_SIZE) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageRadialCut did not generate proper error message.");
-        return 32;
-    }
-    psFree(err);
-
-    // Bad radii size
-    psVector* radii2 = psVectorAlloc(1,PS_TYPE_MASK);
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
-    result = psImageRadialCut(result,image, mask, 1,
-                              centerX,centerY,radii2,stat);
-    psFree(radii2);
-    if (result != NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "Return value not NULL as expected.");
-        return 33;
-    }
-
-    err = psErrorLast();
-    if (err->code != PS_ERR_BAD_PARAMETER_SIZE) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageRadialCut did not generate proper error message.");
-        return 34;
-    }
-    psFree(err);
-
-    // bad input stat option...
-    stat->options = 0;
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
-    result = psImageRadialCut(result,image,mask,1,centerX,centerY,radii,stat);
-    stat->options = PS_STAT_SAMPLE_MEAN;
-
-    if (result != NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "Return value not NULL as expected.");
-        return 35;
-    }
-
-    err = psErrorLast();
-    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "psImageRadialCut did not generate proper error message.");
-        return 36;
-    }
-    psFree(err);
-
-    psFree(image);
-    psFree(mask);
-    psFree(radii);
-    psFree(stat);
-    psFree(result);
-
-    return 0;
-}
Index: trunk/psLib/test/image/tst_psImageGeomManip.c
===================================================================
--- trunk/psLib/test/image/tst_psImageGeomManip.c	(revision 3973)
+++ trunk/psLib/test/image/tst_psImageGeomManip.c	(revision 3973)
@@ -0,0 +1,1050 @@
+/** @file  tst_psImageGeomManip.c
+ *
+ *  @brief Contains the tests for psImageManip.[ch]
+ *
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-05-19 02:49:40 $
+ *
+ *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <complex.h>
+#include <math.h>
+#include <float.h>
+#include <string.h>
+#include <stdlib.h>
+#include <string.h>                    // for memset
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "psTest.h"
+#include "pslib_strict.h"
+#include "psType.h"
+
+static psS32 testImageRebin(void);
+static psS32 testImageRoll(void);
+static psS32 testImageRotate(void);
+static psS32 testImageShift(void);
+static psS32 testImageShiftCase(psS32 cols, psS32 rows, float colShift,float rowShift);
+static psS32 testImageResample(void);
+
+testDescription tests[] = {
+                              {testImageRebin,559,"psImageRebin",0,false},
+                              {testImageRoll,562,"psImageRoll",0,false},
+                              {testImageRotate,560,"psImageRotate",0,false},
+                              {testImageShift,561,"psImageShift",0,false},
+                              {testImageResample,743,"psImageResample",0,false},
+                              {NULL}
+                          };
+
+psS32 main(psS32 argc, char* argv[])
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    return ! runTestSuite(stderr,"psImage",tests,argc,argv);
+}
+
+static psS32 testImageRebin(void)
+{
+
+    /*
+    This function shall generate a rescaled version of a psImage structure
+    derived from a specified statistics method.
+    */
+
+    psImage* in = NULL;
+    psImage* out = NULL;
+    psImage* out2 = NULL;
+    psImage* out3 = NULL;
+    psImage* mask = NULL;
+    psImage* meanTruth = NULL;
+    psImage* meanTruthWMask = NULL;
+    psImage* maxTruth = NULL;
+    psStats stats;
+
+    /*
+    Verify the returned psImage structure contains expected values, if the
+    input parameter input contains known data, the input scale is a known
+    value with a known statistical method specified in stats. Cases should
+    include at least two different scales and statistical methods. Comparison
+    of expected values should include a delta to allow testing on different
+    platforms.
+    */
+
+    #define testRebinType(DATATYPE)  \
+    in = psImageAlloc(16,16,PS_TYPE_##DATATYPE); \
+    mask = psImageAlloc(16,16,PS_TYPE_U8); \
+    meanTruth = psImageAlloc(4,4,PS_TYPE_F32); \
+    meanTruthWMask = psImageAlloc(4,4,PS_TYPE_F32); \
+    maxTruth = psImageAlloc(6,6,PS_TYPE_F32); \
+    memset(meanTruth->data.F32[0],0,sizeof(psF32)*4*4); \
+    memset(meanTruthWMask->data.F32[0],0,sizeof(psF32)*4*4); \
+    memset(maxTruth->data.F32[0],0,sizeof(psF32)*6*6); \
+    for (psS32 row = 0; row<16; row++) { \
+        ps##DATATYPE* inRow = in->data.DATATYPE[row]; \
+        psF32* meanTruthRow = meanTruth->data.F32[row/4]; \
+        psF32* meanTruthWMaskRow = meanTruthWMask->data.F32[row/4]; \
+        psF32* maxTruthRow = maxTruth->data.F32[row/3]; \
+        psU8* maskRow = mask->data.U8[row]; \
+        for (psS32 col = 0; col<16; col++) { \
+            if(col != 15) { \
+                maskRow[col] = 0; \
+            } else { \
+                maskRow[col] = 1; \
+            } \
+            inRow[col] = row + col; \
+            meanTruthRow[col/4] += row + col; \
+            if (maxTruthRow[col/3] < row + col) { \
+                maxTruthRow[col/3] = row+col; \
+            } \
+            if(maskRow[col] == 0 ) { \
+                meanTruthWMaskRow[col/4] += row + col; \
+            } \
+        } \
+    } \
+    for (psS32 row = 0; row<4; row++) { \
+        psF32* meanTruthRow = meanTruth->data.F32[row]; \
+        psF32* meanTruthWMaskRow = meanTruthWMask->data.F32[row]; \
+        for (psS32 col = 0; col<4; col++) { \
+            meanTruthRow[col] /= 16; \
+            if ( col == 3 ) { \
+                meanTruthWMaskRow[col] /= 12; \
+            } else { \
+                meanTruthWMaskRow[col] /= 16; \
+            } \
+        } \
+    } \
+    stats.options = PS_STAT_SAMPLE_MEAN; \
+    out = psImageRebin(NULL,in,NULL,0,4,&stats); \
+    if (out == NULL) { \
+        psError(PS_ERR_UNKNOWN, true,"psImageRebin returned a NULL pointer!?"); \
+        return 1; \
+    } \
+    if (out->numRows != 4 || out->numCols != 4) { \
+        psError(PS_ERR_UNKNOWN, true,"psImageRebin didn't produce the proper size image " \
+                "(%d x %d).", \
+                out->numCols, out->numRows); \
+        return 2; \
+    } \
+    for (psS32 row = 0; row<4; row++) { \
+        ps##DATATYPE* outRow = out->data.DATATYPE[row]; \
+        psF32* truthRow = meanTruth->data.F32[row]; \
+        for (psS32 col = 0; col<4; col++) { \
+            if (fabsf((float)outRow[col]-(float)truthRow[col]) > FLT_EPSILON) { \
+                psError(PS_ERR_UNKNOWN, true,"psImageRebin didn't produce the proper mean " \
+                        "result at (%d,%d) [%f vs %f].", \
+                        col,row,outRow[col],truthRow[col]); \
+                return 3; \
+            } \
+        } \
+    } \
+    stats.options = PS_STAT_SAMPLE_MEAN; \
+    out3 = psImageRebin(NULL,in,mask,1,4,&stats); \
+    for (psS32 row = 0; row<4; row++) { \
+        ps##DATATYPE* outRow = out3->data.DATATYPE[row]; \
+        psF32* truthRow = meanTruthWMask->data.F32[row]; \
+        for ( psS32 col = 0; col<4; col++) { \
+            if(abs((psS32)outRow[col]-(psS32)truthRow[col]) > FLT_EPSILON) { \
+                psError(PS_ERR_UNKNOWN, true,"psImageRebin with mask didn't produce the proper mean " \
+                        "result at (%d,%d) [%f vs %f].", \
+                        col,row,outRow[col],truthRow[col]); \
+                return 3; \
+            } \
+        } \
+    } \
+    stats.options = PS_STAT_MAX; \
+    out2 = psImageRebin(out,in,NULL,0,3,&stats); \
+    if (out != out2) { \
+        psError(PS_ERR_UNKNOWN, true,"psImageRebin didn't recycle a psImage properly!?"); \
+        return 7; \
+    } \
+    if (out == NULL) { \
+        psError(PS_ERR_UNKNOWN, true,"psImageRebin returned a NULL pointer!?"); \
+        return 4; \
+    } \
+    if (out->numRows != 6 || out->numCols != 6) { \
+        psError(PS_ERR_UNKNOWN, true,"psImageRebin didn't produce the proper size image " \
+                "(%d x %d).", \
+                out->numCols, out->numRows); \
+        return 5; \
+    } \
+    for (psS32 row = 0; row<6; row++) { \
+        ps##DATATYPE* outRow = out->data.DATATYPE[row]; \
+        psF32* truthRow = maxTruth->data.F32[row]; \
+        for (psS32 col = 0; col<6; col++) { \
+            if (fabsf((float)outRow[col]-(float)truthRow[col]) > FLT_EPSILON) { \
+                psError(PS_ERR_UNKNOWN, true,"psImageRebin didn't produce the proper " \
+                        "max result at (%d,%d) [%f vs %f].", \
+                        col,row,outRow[col],truthRow[col]); \
+                return 6; \
+            } \
+        } \
+    } \
+    psFree(in); \
+    psFree(out); \
+    psFree(out3); \
+    psFree(mask); \
+    psFree(meanTruth); \
+    psFree(meanTruthWMask); \
+    psFree(maxTruth);
+
+    testRebinType(F32);
+    testRebinType(F64);
+    testRebinType(U16);
+    testRebinType(S8);
+
+    // Verify the returned psImage structure is null and program execution
+    // doesn't stop, if the input image type is not supported.
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for unsupported type.");
+    in = psImageAlloc(16,16,PS_TYPE_U8);
+    mask = psImageAlloc(16,16,PS_TYPE_F32);
+    stats.options = PS_STAT_SAMPLE_MEAN;
+    out = psImageRebin(NULL,in,NULL,0,4,&stats);
+    if(out != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psImageRebin return an image eventhough the "
+                "type is not handled.");
+        return 14;
+    }
+    // Verify the returned psImage structure is null and program execution
+    // doesn't stop, if the mask type is not U8
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for invallid mask type.");
+    out = psImageRebin(NULL,in,mask,1,4,&stats);
+    if(out != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psImageRebin return an image eventhough the "
+                "mask is not the correct type.");
+        return 17;
+    }
+    psFree(mask);
+    psFree(in);
+
+    // Verify the returned psImage structure is null and program execution
+    // doesn't stop, if the input parameter input is null.
+
+    out2 = psImageRebin(NULL,NULL,NULL,0,1,&stats);
+
+    if (out2 != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psImageRebin returned an image though the input was "
+                "NULL!?");
+        return 8;
+    }
+
+    // Verify the returned psImage structure is null and program execution
+    // doesn't stop, if the input parameter scale is less than or equal to zero.
+    in = psImageAlloc(16, 16, PS_TYPE_F32);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for scale < 0.");
+    out2 = psImageRebin(NULL,in,NULL,0,0,&stats);
+
+    if (out2 != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psImageRebin returned an image though the scale was "
+                "zero!?");
+        return 9;
+    }
+
+    // Verify the returned psImage structure is null and program execution
+    // doesn't stop, if the input parameter stats is null.
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for stats null.");
+    out2 = psImageRebin(NULL,in,NULL,0,1,NULL);
+
+    if (out2 != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psImageRebin returned an image though the stats was "
+                "NULL!?");
+        return 10;
+    }
+
+    // Verify the returned psImage structure is null and program execution
+    // doesn't stop, if the input parameter psStats structure member options
+    // is zero or any value which doesn't correspond to a valid statistical
+    // method.
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for stats options 0.");
+    stats.options = 0;
+    out2 = psImageRebin(NULL,in,NULL,0,1,&stats);
+
+    if (out2 != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psImageRebin returned an image though the stats "
+                "options was zero!?");
+        return 11;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for stat options use range.");
+    stats.options = PS_STAT_USE_RANGE;
+    out2 = psImageRebin(NULL,in,NULL,0,1,&stats);
+
+    if (out2 != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psImageRebin returned an image though the stats "
+                "options was PS_STAT_USE_RANGE!?");
+        return 12;
+    }
+
+    // Verify the returned psImage structure is null and program execution
+    // doesn't stop, if the input parameter psStats structure member options
+    // specifies more than one valid statistical method.
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for stats with multiple options.");
+    stats.options = PS_STAT_SAMPLE_MEAN + PS_STAT_MAX;
+    out2 = psImageRebin(NULL,in,NULL,0,1,&stats);
+
+    if (out2 != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psImageRebin returned an image though the stats "
+                "options was PS_STAT_SAMPLE_MEAN+PS_STAT_MAX!?");
+        return 13;
+    }
+
+    psFree(in);
+
+    return 0;
+}
+
+static psS32 testImageRoll(void)
+{
+
+    psImage* in;
+    psImage* out;
+    psImage* out2;
+    psS32 rows = 64;
+    psS32 cols = 64;
+    psS32 rows1 = 8;
+    psS32 cols1 = 8;
+
+    /*
+     The function psImageRoll shall generate a new psImage structure by
+     rolling the input image the correponding number of pixels in the vertical
+     and/or horizontal direction. The image output image shall be the same size
+     as the input image. Values which roll off the image are wrapped to the
+     other side.
+
+     Verify the returned psImage structure contains expected values, if the
+     input image contains known values and the roll performed is known.
+     Cases should include no roll, vertical roll, horizontal roll and
+     combination vertical/horizontal rolls. Positive and negative rolls
+     should be performed.
+    */
+
+    in = psImageAlloc(cols,rows,PS_TYPE_F32);
+    for (psS32 row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[row];
+        for (psS32 col=0;col<cols;col++) {
+            inRow[col] = (psF32)row+(psF32)col/1000.0f;
+        }
+    }
+
+    out = psImageRoll(NULL,in,0,0);
+    for (psS32 row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[row];
+        psF32* outRow = out->data.F32[row];
+        for (psS32 col=0;col<cols;col++) {
+            if (inRow[col] != outRow[col]) {
+                psError(PS_ERR_UNKNOWN, true,"psImageRoll didn't produce expected result "
+                        "at %d,%d (%f vs %f) for dx=0, dy=0.",
+                        col,row,inRow[col],outRow[col]);
+                return 3;
+            }
+        }
+    }
+
+    out2 = psImageRoll(out,in,cols/4,0);
+    for (psS32 row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[row];
+        psF32* outRow = out->data.F32[row];
+        for (psS32 col=0;col<cols;col++) {
+            if (inRow[(col+cols/4) % cols] != outRow[col]) {
+                psError(PS_ERR_UNKNOWN, true,"psImageRoll didn't produce expected result "
+                        "at %d,%d (%f vs %f) for dx=cols/4, dy=0.",
+                        col,row,inRow[(col+cols/4) % cols],outRow[col]);
+                return 4;
+            }
+        }
+    }
+
+    // Verify the returned psImage structure pointer is equal to the input
+    // parameter out if provided.
+    if (out2 != out) {
+        psError(PS_ERR_UNKNOWN, true,"psImageRoll didn't recycle my out psImage!?");
+        return 1;
+    }
+
+    out = psImageRoll(out,in,0,rows/4);
+    for (psS32 row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[(row+rows/4)%rows];
+        psF32* outRow = out->data.F32[row];
+        for (psS32 col=0;col<cols;col++) {
+            if (inRow[col] != outRow[col]) {
+                psError(PS_ERR_UNKNOWN, true,"psImageRoll didn't produce expected result "
+                        "at %d,%d (%f vs %f) for dx=0, dy=rows/4.",
+                        col,row,inRow[col],outRow[col]);
+                return 5;
+            }
+        }
+    }
+
+    out = psImageRoll(out,in,cols/4,rows/4);
+    for (psS32 row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[(row+rows/4)%rows];
+        psF32* outRow = out->data.F32[row];
+        for (psS32 col=0;col<cols;col++) {
+            if (inRow[(col+cols/4) % cols] != outRow[col]) {
+                psError(PS_ERR_UNKNOWN, true,"psImageRoll didn't produce expected result "
+                        "at %d,%d (%f vs %f) for dx=cols/4, dy=rows/4.",
+                        col,row,inRow[(col+cols/4) % cols],outRow[col]);
+                return 6;
+            }
+        }
+    }
+
+    out = psImageRoll(out,in,-cols/4,0);
+    for (psS32 row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[row];
+        psF32* outRow = out->data.F32[row];
+        for (psS32 col=0;col<cols;col++) {
+            if (inRow[(col+(cols-cols/4)) % cols] != outRow[col]) {
+                psError(PS_ERR_UNKNOWN, true,"psImageRoll didn't produce expected result "
+                        "at %d,%d (%f vs %f) for dx=-cols/4, dy=0.",
+                        col,row,inRow[(col+(cols-cols/4)) % cols],outRow[col]);
+                return 7;
+            }
+        }
+    }
+
+    out = psImageRoll(out,in,0,-rows/4);
+    for (psS32 row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[(row+rows-rows/4)%rows];
+        psF32* outRow = out->data.F32[row];
+        for (psS32 col=0;col<cols;col++) {
+            if (inRow[col] != outRow[col]) {
+                psError(PS_ERR_UNKNOWN, true,"psImageRoll didn't produce expected result "
+                        "at %d,%d (%f vs %f) for dx=0, dy=-rows/4.",
+                        col,row,inRow[col],outRow[col]);
+                return 8;
+            }
+        }
+    }
+
+    out = psImageRoll(out,in,-cols/4,-rows/4);
+    for (psS32 row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[(row+rows-rows/4)%rows];
+        psF32* outRow = out->data.F32[row];
+        for (psS32 col=0;col<cols;col++) {
+            if (inRow[(col+cols-cols/4) % cols] != outRow[col]) {
+                psError(PS_ERR_UNKNOWN, true,"psImageRoll didn't produce expected result "
+                        "at %d,%d (%f vs %f) for dx=cols/4, dy=rows/4.",
+                        col,row,inRow[(col+cols-cols/4) % cols],outRow[col]);
+                return 9;
+            }
+        }
+    }
+
+
+    // Verify the returned psImage structure pointer is null and program
+    // execution doesn't stop, if input parameter input is null.
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error.");
+    out2 = psImageRoll(NULL,NULL,0,0);
+    if (out2 != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psImageRoll did not return NULL though input image was NULL!?");
+        return 2;
+    }
+
+    psFree(in);
+    psFree(out);
+
+    #define testRollType(DATATYPE) \
+    in = psImageAlloc(rows1,cols1,PS_TYPE_##DATATYPE); \
+    \
+    for (psS32 row=0;row<rows1;row++) { \
+        ps##DATATYPE* inRow = in->data.DATATYPE[row]; \
+        for (psS32 col=0;col<cols1;col++) { \
+            inRow[col] = (ps##DATATYPE)row+(ps##DATATYPE)col; \
+        } \
+    } \
+    \
+    out = psImageRoll(NULL,in,rows1/4,cols1/4); \
+    for (psS32 row=0;row<rows1;row++) { \
+        ps##DATATYPE* inRow = in->data.DATATYPE[(row+rows1/4)%rows1]; \
+        ps##DATATYPE* outRow = out->data.DATATYPE[row]; \
+        for (psS32 col=0;col<cols1;col++) { \
+            if (inRow[(col+cols1/4)%cols1] != outRow[col]) { \
+                psError(PS_ERR_UNKNOWN, true,"psImageRoll didn't produce expected result " \
+                        "at %d,%d (%f vs %f) for dx=0, dy=0.", \
+                        col,row,(float)inRow[col],(float)outRow[col]); \
+                return 3; \
+            } \
+        } \
+    } \
+    psFree(in); \
+    psFree(out);
+
+    testRollType(U8);
+    testRollType(U16);
+    testRollType(S8);
+    testRollType(S16);
+    testRollType(F64);
+    testRollType(C32);
+    testRollType(C64);
+
+    return 0;
+}
+
+psS32 testImageRotate(void)
+{
+    /*
+
+    This function shall calculate a new psImage structure based upon the
+    rotation of a given psImage structure. The center of rotation shall be the
+    center pixel of the input image.
+
+    The following steps of the testpoint are done manually via inspection of
+    temp/fOut.fits & temp/sOut.fits.
+
+        * Verify the returned psImage structure contains expected values, if
+          the input parameter psImage contains known values. Cases should
+          include rotations of 0, 45, 90, 135, 180, 225, 270, 315, 360 and at leat one
+          other arbitrary angle. Cases of the input image should include image
+          with a center pixel and an image without a center pixel.
+        * Verify the returned psImage structure contains pixels set to exposed value, if
+          the rotation and input psImage to not correspond to the output image.
+
+    */
+
+    psImage* fOut = NULL;
+    psImage* sOut = NULL;
+    psImage* fBiOut = NULL;
+    psImage* sBiOut = NULL;
+    psImage* fTruth = NULL;
+    psImage* sTruth = NULL;
+    psImage* fBiTruth = NULL;
+    psImage* sBiTruth = NULL;
+    psS32 rows = 64;
+    psS32 cols = 64;
+    psImage* fImg = psImageAlloc(cols,rows,PS_TYPE_F32);
+    psImage* sImg = psImageAlloc(cols,rows,PS_TYPE_S16);
+
+    for(psS32 row=0;row<rows;row++) {
+        psF32* fRow = fImg->data.F32[row];
+        psS16* sRow = sImg->data.S16[row];
+        for (psS32 col=0;col<cols;col++) {
+            fRow[col] = (psF32)(row)+(psF32)(col)/100.0f;
+            sRow[col] = row-2*col;
+        }
+    }
+
+    // since interpolation is involved, etc., the simplist way to verify things
+    // is to verify the results manually and bless it for automated comparison
+    // thereafter
+
+
+    // write results of various rotates to a file and verify with truth images
+    mkdir("temp",0777);
+    remove
+        ("temp/fOut.fits")
+        ;
+    remove
+        ("temp/sOut.fits")
+        ;
+    remove
+        ("temp/fBiOut.fits")
+        ;
+    remove
+        ("temp/sBiOut.fits");
+    ;
+    psS32 index = 0;
+    psBool fail = false;
+    psF32 radianRot;
+    for (psS32 rot=-180;rot<=180;rot+=45) {
+        psImage* oldOut = fOut;
+        psImage* oldBiOut = fBiOut;
+
+        if (rot == 90) {
+            radianRot = M_PI_2;
+        } else if (rot == -90) {
+            radianRot = M_PI+M_PI_2;
+        } else if (rot == 180 || rot == -180) {
+            radianRot = M_PI;
+        } else {
+            radianRot = ((float)rot)*M_PI/180.0;
+        }
+
+        fOut = psImageRotate(fOut,fImg,radianRot,-1.0,PS_INTERPOLATE_FLAT);
+        fBiOut = psImageRotate(fBiOut,fImg,radianRot,-1.0,PS_INTERPOLATE_BILINEAR);
+        // Verify the returned psImage structure is equal to the input
+        // parameter out if provided.
+        if (oldOut != NULL && oldOut != fOut) {
+            psError(PS_ERR_UNKNOWN, true,"the output recycle functionality failed");
+            return 2;
+        }
+        if (oldBiOut != NULL && oldBiOut != fBiOut) {
+            psError(PS_ERR_UNKNOWN, true,"the output recycle functionality failed");
+            return 4;
+        }
+        sOut = psImageRotate(sOut,sImg,radianRot,-1.0,PS_INTERPOLATE_FLAT);
+        sBiOut = psImageRotate(sBiOut,sImg,radianRot,-1.0,PS_INTERPOLATE_BILINEAR);
+        if (! psImageWriteSection(fOut,0,0,0,NULL,index,"temp/fOut.fits") ) {
+            psError(PS_ERR_UNKNOWN, true,"Can not write to temp/fOut.fits, so why continue!?");
+            return 20;
+        }
+        if (! psImageWriteSection(sOut,0,0,0,NULL,index,"temp/sOut.fits") ) {
+            psError(PS_ERR_UNKNOWN, true,"Can not write to temp/sOut.fits, so why continue!?");
+            return 21;
+        }
+        if (! psImageWriteSection(fBiOut,0,0,0,NULL,index,"temp/fBiOut.fits") ) {
+            psError(PS_ERR_UNKNOWN, true,"Can not write to temp/fBiOut.fits, so why continue!?");
+            return 40;
+        }
+        if (! psImageWriteSection(sBiOut,0,0,0,NULL,index,"temp/sBiOut.fits") ) {
+            psError(PS_ERR_UNKNOWN, true,"Can not write to temp/sBiOut.fits, so why continue!?");
+            return 41;
+        }
+
+        // now, let's compare this with the verified file
+        fTruth = psImageReadSection(fTruth,0,0,0,0,0,NULL,index,"temp/fOut.fits");
+        sTruth = psImageReadSection(sTruth,0,0,0,0,0,NULL,index,"temp/sOut.fits");
+        fBiTruth = psImageReadSection(fBiTruth,0,0,0,0,0,NULL,index,"temp/fBiOut.fits");
+        sBiTruth = psImageReadSection(sBiTruth,0,0,0,0,0,NULL,index,"temp/sBiOut.fits");
+        if (fTruth == NULL) {
+            psError(PS_ERR_UNKNOWN, true,"verified psF32 image failed to be read (%d deg. rotation)",
+                    rot);
+            fail = true;
+        } else {
+            if (fTruth->numRows != fOut->numRows || fTruth->numCols != fOut->numCols) {
+                psError(PS_ERR_UNKNOWN, true,"Rotated float image size did not match truth "
+                        "image for %d deg rotation (%dx%d vs %dx%d).",
+                        rot,fOut->numCols,fOut->numRows,fTruth->numCols,fTruth->numRows);
+                fail = true;
+            } else {
+                for (psS32 row=0;row<fTruth->numRows;row++) {
+                    psF32* truthRow = fTruth->data.F32[row];
+                    psF32* outRow = fOut->data.F32[row];
+                    for (psS32 col=0;col<fTruth->numCols;col++) {
+                        if (fabsf(truthRow[col]-outRow[col]) > 1) {
+                            psError(PS_ERR_UNKNOWN, true,"Float Image mismatch (%f vs %f) at %d,%d.",
+                                    outRow[col], truthRow[col],col,row);
+                            fail = true;
+                        }
+                    }
+                }
+            }
+        }
+
+        if (sTruth == NULL) {
+            psError(PS_ERR_UNKNOWN, true,"verified psS16 image failed to be read "
+                    "(%d deg. rotation)",rot);
+            fail = true;
+        } else {
+            if (sTruth->numRows != sOut->numRows ||
+                    sTruth->numCols != sOut->numCols) {
+                psError(PS_ERR_UNKNOWN, true,"Rotated psS16 image size did not match truth "
+                        "image for %d deg rotation.",rot);
+                fail = true;
+            } else {
+                for (psS32 row=0;row<sTruth->numRows;row++) {
+                    psS16* truthRow = sTruth->data.S16[row];
+                    psS16* outRow = sOut->data.S16[row];
+                    for (psS32 col=0;col<sTruth->numCols;col++) {
+                        if (fabsf(truthRow[col]-outRow[col]) > 1) {
+                            psError(PS_ERR_UNKNOWN, true,"Short Image mismatch (%d vs %d) "
+                                    "at %d,%d.",
+                                    outRow[col], truthRow[col],col,row);
+                            fail = true;
+                        }
+                    }
+                }
+            }
+        }
+
+
+        if (fBiTruth == NULL) {
+            psError(PS_ERR_UNKNOWN, true,"verified psF32 Bi image failed to be read (%d deg. rotation)",
+                    rot);
+            fail = true;
+        } else {
+            if (fBiTruth->numRows != fBiOut->numRows || fBiTruth->numCols != fBiOut->numCols) {
+                psError(PS_ERR_UNKNOWN, true,"Rotated float image size did not match truth "
+                        "image for %d deg rotation (%dx%d vs %dx%d). BILINEAR",
+                        rot,fBiOut->numCols,fBiOut->numRows,fBiTruth->numCols,fBiTruth->numRows);
+                fail = true;
+            } else {
+                for (psS32 row=0;row<fBiTruth->numRows;row++) {
+                    psF32* truthRow = fBiTruth->data.F32[row];
+                    psF32* outRow = fBiOut->data.F32[row];
+                    for (psS32 col=0;col<fBiTruth->numCols;col++) {
+                        if (fabsf(truthRow[col]-outRow[col]) > 1) {
+                            psError(PS_ERR_UNKNOWN, true,"Float Image mismatch (%f vs %f) at %d,%d. BILINEAR",
+                                    outRow[col], truthRow[col],col,row);
+                            fail = true;
+                        }
+                    }
+                }
+            }
+        }
+
+        if (sBiTruth == NULL) {
+            psError(PS_ERR_UNKNOWN, true,"verified psS16 image failed to be read "
+                    "(%d deg. rotation) BILINEAR",rot);
+            fail = true;
+        } else {
+            if (sBiTruth->numRows != sBiOut->numRows ||
+                    sBiTruth->numCols != sBiOut->numCols) {
+                psError(PS_ERR_UNKNOWN, true,"Rotated psS16 image size did not match truth "
+                        "image for %d deg rotation. BILINEAR",rot);
+                fail = true;
+            } else {
+                for (psS32 row=0;row<sBiTruth->numRows;row++) {
+                    psS16* truthRow = sBiTruth->data.S16[row];
+                    psS16* outRow = sBiOut->data.S16[row];
+                    for (psS32 col=0;col<sBiTruth->numCols;col++) {
+                        if (fabsf(truthRow[col]-outRow[col]) > 1) {
+                            psError(PS_ERR_UNKNOWN, true,"Short Image mismatch (%d vs %d) "
+                                    "at %d,%d. BILINEAR",
+                                    outRow[col], truthRow[col],col,row);
+                            fail = true;
+                        }
+                    }
+                }
+            }
+        }
+
+        index++;
+    }
+
+    if (fail) {
+        psError(PS_ERR_UNKNOWN, true,"One or more images didn't match truth or truth did "
+                "not exist.");
+        return 10;
+    }
+
+
+    // Verify the returned psImage structure pointer is null and program
+    // execution doesn't stop, if the input parameter input is null.
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error");
+    fOut = psImageRotate(fOut,NULL,0,0,PS_INTERPOLATE_FLAT);
+    if (fOut != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"NULL wasn't returned though the input image was NULL.");
+        return 3;
+    }
+
+    // Verify the returned psImage structure pointer is null and program
+    // execution doesn't stop, if the specified interpolation mode is invalid
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for invalid "
+             "interpolation type.");
+    fOut = psImageRotate(fOut, fImg, 33, 0, -1);
+    if (fOut != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"NULL wasn't returned though the interpolation mode "
+                "is invalid.");
+        return 4;
+    }
+
+    psFree(sOut);
+    psFree(fImg);
+    psFree(sImg);
+    psFree(fTruth);
+    psFree(sTruth);
+    psFree(sBiOut);
+    psFree(fBiTruth);
+    psFree(sBiTruth);
+    psFree(fBiOut);
+
+    return 0;
+}
+
+static psS32 testImageShift(void)
+{
+    /* psImageShift:
+
+       This functions shall generate a new psImage structure by shifting the
+       input psImage structure a specified number of pixels in the horizontal
+       and/or vertical directions.
+
+       Verify the returned psImage structure contains expected values, if the
+       input psImage structure contains known values and a know shift in the
+       vertical and/or horizontal directions. Cases should include no shift,
+       vertical only(up,down), horizontal only(right, left), and combination
+       shift. Cases should include fractional shifts. Comparison of expected
+       values should include a delta to allow for testing on different
+       platforms.
+
+       Verify the returned psImage structure contains values for pixels not in
+       the original image set to the input parameter exposed.
+
+    */
+
+    psS32 retVal=0;
+
+    // integer shift
+    retVal |= testImageShiftCase(64,128,0.0f,0.0f);
+    retVal |= testImageShiftCase(64,128,0.0f,16.0f);
+    retVal |= testImageShiftCase(64,128,0.0f,-16.0f);
+    retVal |= testImageShiftCase(64,128,32.0f,0.0f);
+    retVal |= testImageShiftCase(64,128,-32.0f,0.0f);
+    retVal |= testImageShiftCase(64,128,32.0f,16.0f);
+    retVal |= testImageShiftCase(64,128,32.0f,-16.0f);
+    retVal |= testImageShiftCase(64,128,-32.0f,16.0f);
+    retVal |= testImageShiftCase(64,128,-32.0f,-16.0f);
+
+    if (retVal != 0) {
+        return retVal;
+    }
+
+    // fractional shift
+    retVal |= testImageShiftCase(64,128,0.0f,16.4f);
+    retVal |= testImageShiftCase(64,128,0.0f,-16.4f);
+    retVal |= testImageShiftCase(64,128,32.7f,0.0f);
+    retVal |= testImageShiftCase(64,128,-32.7f,0.0f);
+    retVal |= testImageShiftCase(64,128,32.6f,16.2f);
+    retVal |= testImageShiftCase(64,128,32.6f,-16.2f);
+    retVal |= testImageShiftCase(64,128,-32.6f,16.2f);
+    retVal |= testImageShiftCase(64,128,-32.6f,-16.2f);
+
+    if (retVal != 0) {
+        return retVal;
+    }
+
+    /*
+       Verify the returned psImage structure pointer is equal to the input
+       parameter out if provided.
+    */
+    psImage* fImg = psImageAlloc(32,32,PS_TYPE_F32);
+    psImage* fRecycle = psImageAlloc(32,32,PS_TYPE_F32);
+    psImage* fOut = psImageShift(fRecycle, fImg, 8,8, NAN, PS_INTERPOLATE_FLAT);
+
+    if (fRecycle != fOut) {
+        psError(PS_ERR_UNKNOWN, true,"psImageShift didn't recycle my image?");
+        return 10;
+    }
+
+    /*
+       Verify the returned psImage structure pointer is null and program
+       execution doesn't stop, if the input psImage structure pointer is null.
+    */
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error...");
+    fOut = psImageShift(fOut,NULL,8,8,NAN,PS_INTERPOLATE_FLAT);
+    if (fOut != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psImageShift didn't return NULL given a NULL input image.");
+        return 11;
+    }
+
+    // Verify the returned psImage structure is null and program execution
+    // doesn't stop, if the specified interpolation mode is invalid.
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for invalid interpolation mode.");
+    fOut = psImageShift(fOut,fImg,8,8,NAN,-1);
+    if (fOut != NULL ) {
+        psError(PS_ERR_UNKNOWN, true,"psImageShift didn't return NULL given an invalid interpolation mode.");
+        return 12;
+    }
+
+    psFree(fImg);
+
+    return 0;
+}
+
+static psS32 testImageShiftCase(psS32 cols,
+                                psS32 rows,
+                                float colShift,
+                                float rowShift)
+{
+    psImage* fOut = NULL;
+    psImage* sOut = NULL;
+
+    psLogMsg(__func__,PS_LOG_INFO,"Testing psImageShift with a %dx%d image for "
+             "a shift of %g,%g.",cols,rows,colShift,rowShift);
+
+    psImage* fImg = psImageAlloc(cols,rows,PS_TYPE_F32);
+    psImage* sImg = psImageAlloc(cols,rows,PS_TYPE_S16);
+    psImage* fBiOut = psImageAlloc(cols,rows,PS_TYPE_F32);
+    psImage* sBiOut = psImageAlloc(cols,rows,PS_TYPE_S16);
+
+    for(psS32 row=0;row<rows;row++) {
+        psF32* fRow = fImg->data.F32[row];
+        psS16* sRow = sImg->data.S16[row];
+        for (psS32 col=0;col<cols;col++) {
+            fRow[col] = (psF32)(row)+(psF32)(col)/100.0f;
+            sRow[col] = row-2*col;
+        }
+    }
+
+    fOut = psImageShift(fOut, fImg, colShift, rowShift, NAN, PS_INTERPOLATE_FLAT);
+    sOut = psImageShift(sOut, sImg, colShift, rowShift, -1, PS_INTERPOLATE_FLAT);
+    fBiOut = psImageShift(fBiOut, fImg, colShift, rowShift, NAN, PS_INTERPOLATE_BILINEAR);
+    sBiOut = psImageShift(sBiOut, sImg, colShift, rowShift, -1, PS_INTERPOLATE_BILINEAR);
+
+    for(psS32 row=0;row<rows;row++) {
+        psF32* fRow = fOut->data.F32[row];
+        psS16* sRow = sOut->data.S16[row];
+        psF32* fBiRow = fBiOut->data.F32[row];
+        psS16* sBiRow = sBiOut->data.S16[row];
+
+        for (psS32 col=0;col<cols;col++) {
+            psF32 fValue = psImagePixelInterpolate(fImg,col+colShift,
+                                                   row+rowShift,NULL,0,NAN,PS_INTERPOLATE_FLAT);
+            psS16 sValue = (psS16)psImagePixelInterpolate(sImg,col+colShift,
+                           row+rowShift,NULL,0,-1,PS_INTERPOLATE_FLAT);
+
+            psF32 fBiValue = psImagePixelInterpolate(fImg,col+colShift,
+                             row+rowShift,NULL,0,NAN,PS_INTERPOLATE_BILINEAR);
+            psS16 sBiValue = (psS16)psImagePixelInterpolate(sImg,col+colShift,
+                             row+rowShift,NULL,0,-1,PS_INTERPOLATE_BILINEAR);
+
+            if (fabsf(fRow[col] - fValue) > FLT_EPSILON) {
+                psError(PS_ERR_UNKNOWN, true,"Float image not shifted correctly at %d,%d (%g vs %g)",
+                        col,row,fRow[col],fValue);
+                return 1;
+            }
+            if (sRow[col] != sValue) {
+                psError(PS_ERR_UNKNOWN, true,"Short image not shifted correctly at %d,%d (%d vs %d)",
+                        col,row,sRow[col],sValue);
+                return 2;
+            }
+            if (fabsf(fBiRow[col] - fBiValue) > FLT_EPSILON) {
+                psError(PS_ERR_UNKNOWN, true,"Float image not shifted correctly at %d,%d (%g vs %g)",
+                        col,row,fBiRow[col],fBiValue);
+                return 1;
+            }
+            if (sBiRow[col] != sBiValue) {
+                psError(PS_ERR_UNKNOWN, true,"Short image not shifted correctly at %d,%d (%d vs %d)",
+                        col,row,sBiRow[col],sBiValue);
+                return 2;
+            }
+        }
+    }
+
+    psFree(fImg);
+    psFree(sImg);
+    psFree(fOut);
+    psFree(sOut);
+    psFree(fBiOut);
+    psFree(sBiOut);
+
+    return 0;
+}
+
+static psS32 testImageResample(void)
+{
+
+    psS32 rows = 60;
+    psS32 cols = 80;
+    psImage* result = NULL;
+    psS32 scale = 4;
+    psErr* err;
+
+    psImage* image = psImageAlloc(cols,rows,PS_TYPE_F32);
+    for(psS32 row=0;row<rows;row++) {
+        psF32* imageRow = image->data.F32[row];
+        for (psS32 col=0;col<cols;col++) {
+            imageRow[col] = row+2*col;
+        }
+    }
+    result = psImageCopy(NULL,image,PS_TYPE_F64);
+    psImage* orig = result;
+    result = psImageResample(result,image,scale,PS_INTERPOLATE_FLAT);
+
+    if (result == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "NULL return unexpected");
+        return 1;
+    }
+
+    if (result != orig) {
+        psLogMsg(__func__,PS_LOG_ERROR,"failure to recycle image.");
+        return 2;
+    }
+
+    if (result->type.type != PS_TYPE_F32) {
+        psLogMsg(__func__,PS_LOG_ERROR,"unexpected type");
+        return 3;
+    }
+
+
+    if (result->numCols != image->numCols*scale ||
+            result->numRows != image->numRows*scale) {
+        psLogMsg(__func__,PS_LOG_ERROR,"The size of the result is %dx%d, but %dx%d was expected.",
+                 result->numCols,result->numRows,
+                 image->numCols*scale, image->numRows*scale);
+        return 4;
+    }
+
+    psF32 truthValue;
+    for(psS32 row=0;row<result->numRows;row++) {
+        for (psS32 col=0;col<result->numCols;col++) {
+            truthValue = psImagePixelInterpolate(image,
+                                                 (float)col/(float)scale,(float)row/(float)scale,
+                                                 NULL,0,-1,PS_INTERPOLATE_FLAT);
+            if (fabs(truthValue - result->data.F32[row][col]) > FLT_EPSILON) {
+                psLogMsg(__func__,PS_LOG_ERROR,"value bad at (%d,%d).  Got %g, expected %g.",
+                         col,row,result->data.F32[row][col], truthValue);
+                return 5;
+            }
+        }
+    }
+
+    // verify that image=null is handled properly.
+    psErrorClear();
+    result = psImageResample(result,NULL,scale,PS_INTERPOLATE_FLAT);
+
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "return was not NULL, as expected.");
+        return 6;
+    }
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "error message was not appropriate type.");
+        return 7;
+    }
+    psFree(err);
+
+    // verify that scale < 1 is handled properly
+    psErrorClear();
+    result = psImageResample(result,image,0,PS_INTERPOLATE_FLAT);
+
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "return was not NULL, as expected.");
+        return 8;
+    }
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "error message was not appropriate type.");
+        return 9;
+    }
+    psFree(err);
+
+    // verify that invalid interpolation mode is handled properly
+    psErrorClear();
+    result = psImageResample(result,image,2,-1);
+
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "return was not NULL, as expected.");
+        return 10;
+    }
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "error message was not appropriate type.");
+        return 11;
+    }
+    psFree(err);
+
+    // Verify that that an invalid image type is handled properly
+    psErrorClear();
+    psImage* invImage = psImageAlloc(cols,rows,PS_TYPE_BOOL);
+    memset(invImage->rawDataBuffer,0,cols*rows*sizeof(psBool)); // make sure the image is of all NULLs
+    result = psImageResample(result,invImage,2,PS_INTERPOLATE_FLAT);
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"return was not NULL, as expected.");
+        return 20;
+    }
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_TYPE) {
+        psLogMsg(__func__,PS_LOG_ERROR,"error message was not appropriate type.");
+        return 21;
+    }
+    psFree(err);
+
+    psFree(image);
+    psFree(result);
+    psFree(invImage);
+
+    return 0;
+}
+
Index: trunk/psLib/test/image/tst_psImageManip.c
===================================================================
--- trunk/psLib/test/image/tst_psImageManip.c	(revision 3941)
+++ 	(revision )
@@ -1,1810 +1,0 @@
-/** @file  tst_psImageManip.c
- *
- *  @brief Contains the tests for psImageManip.[ch]
- *
- *
- *  @author Robert DeSonia, MHPCC
- *
- *  @version $Revision: 1.43 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-05-12 00:54:49 $
- *
- *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
- */
-
-#include <complex.h>
-#include <math.h>
-#include <float.h>
-#include <string.h>
-#include <stdlib.h>
-#include <string.h>                    // for memset
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "psTest.h"
-#include "pslib_strict.h"
-#include "psType.h"
-
-static psS32 testImageClip(void);
-static psS32 testImageClipNAN(void);
-static psS32 testImageClipComplexRegion(void);
-static psS32 testImageOverlay(void);
-static psS32 testImageRebin(void);
-static psS32 testImageRoll(void);
-static psS32 testImageRotate(void);
-static psS32 testImageShift(void);
-static psS32 testImageShiftCase(psS32 cols, psS32 rows, float colShift,float rowShift);
-static psS32 testImageResample(void);
-
-testDescription tests[] = {
-                              {testImageClip,571,"psImageClip",0,false},
-                              {testImageClipNAN,572,"psImageClipNAN",0,false},
-                              {testImageClipComplexRegion,673,"psImageClipComplexRegion",0,false},
-                              {testImageOverlay,573,"psImageOverlay",0,false},
-                              {testImageRebin,559,"psImageRebin",0,false},
-                              {testImageRoll,562,"psImageRoll",0,false},
-                              {testImageRotate,560,"psImageRotate",0,false},
-                              {testImageShift,561,"psImageShift",0,false},
-                              {testImageResample,743,"psImageResample",0,false},
-                              {NULL}
-                          };
-
-psS32 main(psS32 argc, char* argv[])
-{
-    psLogSetLevel(PS_LOG_INFO);
-
-    return ! runTestSuite(stderr,"psImage",tests,argc,argv);
-}
-
-
-psS32 testImageClip(void)
-{
-    psImage* img = NULL;
-    psU32 c = 128;
-    psU32 r = 256;
-    psF64 min;
-    psF64 max;
-    psS32 numClipped = 0;
-    psS32 retVal;
-
-    psLogMsg(__func__,PS_LOG_INFO,
-             "psImageClip shall limit the minimum and maximum data value within a psImage structure");
-
-    /*
-
-        psImageClip shall limit the minimum and maximum data value within a
-        psImage structure to a specified min and max value.
-
-        Verify the returned integer is equal to the number of pixels clipped,
-        if the input psImage structure contains known values and input parameters
-        min and max have know values.
-
-        Verify the psImage structure specified by the input parameter input is
-        modified to contain the expected values, if the input psImage structure
-        contains known values, min and max are specified and vmin and vmax
-        parameters are known.
-
-        Verify the retuned integer is zero, psImage structure input is unmodified
-        and program executions doesn't stop, if input parameter psImage structure
-        pointer is null.
-
-        Verify the retuned integer is zero, psImage structure input is unmodified
-        and program executions doesn't stop, if input parameter min is larger than max.
-    */
-
-    // create image
-    #define testImageClipByType(datatype) \
-    img = psImageAlloc(c,r,PS_TYPE_##datatype); \
-    for (psU32 row=0;row<r;row++) { \
-        ps##datatype* imgRow = img->data.datatype[row]; \
-        for (psU32 col=0;col<c;col++) { \
-            imgRow[col] = (ps##datatype)(row+col); \
-        } \
-    } \
-    min = (psF64)r/2.0; \
-    max = (psF64)r; \
-    \
-    retVal = psImageClip(img,min,(double)PS_MIN_##datatype,max,(double)PS_MAX_##datatype); \
-    \
-    numClipped = 0; \
-    for (psU32 row=0;row<r;row++) { \
-        ps##datatype* imgRow = img->data.datatype[row]; \
-        for (psU32 col=0;col<c;col++) { \
-            ps##datatype value = (ps##datatype)(row+col); \
-            if (value < min) { \
-                numClipped++; \
-                value = PS_MIN_##datatype; \
-            } else if (value > max) { \
-                numClipped++; \
-                value = PS_MAX_##datatype; \
-            } \
-            if (fabsf(imgRow[col]-value) > FLT_EPSILON) { \
-                psError(PS_ERR_UNKNOWN, true,"Pixel value is not as expected (%g vs %g) at %u,%u", \
-                        (psF64)imgRow[col],(psF64)value,col,row); \
-                return 1; \
-            } \
-        } \
-    } \
-    if (retVal != numClipped) { \
-        psError(PS_ERR_UNKNOWN, true,"Expected %d clips, but got %d", \
-                numClipped,retVal); \
-        return 2; \
-    } \
-    psFree(img);
-
-    #define testImageClipByComplexType(datatype) \
-    img = psImageAlloc(c,r,PS_TYPE_##datatype); \
-    for (psU32 row=0;row<r;row++) { \
-        ps##datatype* imgRow = img->data.datatype[row]; \
-        for (psU32 col=0;col<c;col++) { \
-            imgRow[col] = (ps##datatype)(row+I*col); \
-        } \
-    } \
-    min = (float)r/2.0f; \
-    max = (float)r; \
-    \
-    retVal = psImageClip(img,min,-1.0f,max,-2.0f); \
-    \
-    numClipped = 0; \
-    for (psU32 row=0;row<r;row++) { \
-        ps##datatype* imgRow = img->data.datatype[row]; \
-        for (psU32 col=0;col<c;col++) { \
-            ps##datatype value = row+I*col; \
-            if (cabs(value) < min) { \
-                numClipped++; \
-                value = -1.0f; \
-            } else if (cabs(value) > max) { \
-                numClipped++; \
-                value = -2.0f; \
-            } \
-            if (fabsf(creal(imgRow[col])-creal(value)) > FLT_EPSILON || \
-                    fabsf(cimag(imgRow[col])-cimag(value)) > FLT_EPSILON) { \
-                psError(PS_ERR_UNKNOWN, true,"Pixel value is not as expected (%.2f+%.2fi vs %.2f+%.2fi) at %u,%u", \
-                        creal(imgRow[col]),cimag(imgRow[col]),creal(value),cimag(value),col,row); \
-                return 1; \
-            } \
-        } \
-    } \
-    if (retVal != numClipped) { \
-        psError(PS_ERR_UNKNOWN, true,"Expected %d clips, but got %d", \
-                numClipped,retVal); \
-        return 2; \
-    } \
-    psFree(img);
-
-    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of F64 imagery");
-    testImageClipByType(F64);
-    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of F32 imagery");
-    testImageClipByType(F32);
-    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of S32 imagery");
-    testImageClipByType(S32);
-    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of S16 imagery");
-    testImageClipByType(S16);
-    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of S8 imagery");
-    testImageClipByType(S8);
-    //    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of U32 imagery");
-    //    testImageClipByType(U32);
-    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of U16 imagery");
-    testImageClipByType(U16);
-    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of U8 imagery");
-    testImageClipByType(U8);
-    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of C32 imagery");
-    testImageClipByComplexType(C32);
-    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of C64 imagery");
-    testImageClipByComplexType(C64);
-
-    // Verify the retuned integer is zero, psImage structure input is unmodified
-    // and program executions doesn't stop, if input parameter psImage structure
-    // pointer is null.
-    retVal = psImageClip(NULL,min,-1.0f,max,-2.0f);
-    if (retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"Expected zero return for clips of a NULL image.");
-        return 3;
-    }
-
-    // Verify the retuned integer is zero, psImage structure input is unmodified
-    // and program executions doesn't stop, if input parameter min is larger than max.
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error (max<min)");
-    retVal = psImageClip(img,max,-1.0f,min,-2.0f);
-    if (retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"Expected zero return for clips when max < min.");
-        return 4;
-    }
-
-    return 0;
-}
-
-psS32 testImageClipNAN(void)
-{
-    psImage* img = NULL;
-    psU32 c = 128;
-    psU32 r = 256;
-    psS32 numClipped = 0;
-    psS32 retVal;
-
-    psLogMsg(__func__,PS_LOG_INFO,
-             "psImageClipNaN shall modified pixel values of NaN with a specified value");
-
-    /*
-        psImageClipNaN shall modify a psImage structure with pixel values set
-        to NaN to a value specified as an input parameter.
-
-        Verify the returned integer is equal to the number of pixels modified
-        and the psImage is modified at locations where NaN pixels where
-        located to the value specified in the input parameter value.
-
-        Verify the returned integer is zero and program execution doesn't stop,
-        if the input parameter psImage structure pointer is null.
-    */
-
-    // create image
-    #define testImageClipNaNByType(datatype) \
-    img = psImageAlloc(c,r,PS_TYPE_##datatype); \
-    for (unsigned row=0;row<r;row++) { \
-        ps##datatype* imgRow = img->data.datatype[row]; \
-        for (unsigned col=0;col<c;col++) { \
-            if (row == col) { \
-                imgRow[col] = NAN; \
-            } else if (row+1 == col) { \
-                imgRow[col] = INFINITY; \
-            } else { \
-                imgRow[col] = (ps##datatype)(row+col); \
-            } \
-        } \
-    } \
-    \
-    retVal = psImageClipNaN(img,-1.0f); \
-    \
-    numClipped = 0; \
-    for (unsigned row=0;row<r;row++) { \
-        ps##datatype* imgRow = img->data.datatype[row]; \
-        for (unsigned col=0;col<c;col++) { \
-            ps##datatype value = (ps##datatype)(row+col); \
-            if ( (row == col) || (row+1 == col) ) { \
-                numClipped++; \
-                value = -1.0; \
-            } \
-            if (fabsf(imgRow[col]-value) > FLT_EPSILON) { \
-                psError(PS_ERR_UNKNOWN, true,"Pixel value is not as expected (%f vs %f) at %d,%d", \
-                        imgRow[col],value,col,row); \
-                return 1; \
-            } \
-        } \
-    } \
-    if (retVal != numClipped) { \
-        psError(PS_ERR_UNKNOWN, true,"Expected %d clips, but got %d", \
-                numClipped,retVal); \
-        return 2; \
-    } \
-    psFree(img);
-
-    testImageClipNaNByType(F32);
-    testImageClipNaNByType(F64);
-    testImageClipNaNByType(C32);
-    testImageClipNaNByType(C64);
-
-    // Verify the retuned integer is zero, psImage structure input is unmodified
-    // and program executions doesn't stop, if input parameter psImage structure
-    // pointer is null.
-    retVal = psImageClipNaN(NULL,-1.0f);
-    if (retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"Expected zero return for clips of a NULL image.");
-        return 3;
-    }
-
-    // Verify program execution doesn't stop if the input image type is something
-    // other than F32, F64, C32, C64.
-    img = psImageAlloc(c,r,PS_TYPE_S32);
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error (invalid type)");
-    retVal = psImageClipNaN(img,2.0f);
-    if (retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"Expected zero return for clip of invalid image type.");
-        return 4;
-    }
-    psFree(img);
-
-    return 0;
-}
-
-psS32 testImageClipComplexRegion(void)
-{
-    psImage* img = NULL;
-    psU32 c = 1024;
-    psU32 r = 2048;
-    psS32 numClipped = 0;
-    psS32 retVal;
-
-    psLogMsg(__func__,PS_LOG_INFO,
-             "psImageClipNaN shall modified pixel values of NaN with a specified value");
-
-    /*
-    1. Create a complex image with a wide range of complex values
-
-    2. call psImageClipComplexRegion with min and max where there is at least
-       2 pixels in the image above) that is:
-        a) real(p) < real(min) && complex(p) < complex(min),
-        b) real(p) < real(min) && complex(min) < complex(p) < complex(max)
-        c) real(min) < real(p) < real(max) && complex(p) < complex(min)
-        d) real(min) < real(p) < real(max) && complex(min) < complex(p) < complex(max)
-        e) real(p) > real(max) && complex(min) < complex(p) < complex(max)
-        f) real(pmin) < real(p) < real(max) && complex(p) > complex(max)
-        g) real(p) > real(max) && complex(p) > complex(max)
-        h) real(p) < real(min) && complex(p) > complex(max)
-        i) real(p) > real(max) && complex(p) < complex(min)
-
-    3. verify that All pixels in case (a), (b), and (c) have the value vmin
-
-    4. verify that all pixels in case (d) are unchanged from input
-
-    5. verify that all pixels in case (e), (f), (g), (h), and (i) have the
-       value vmax
-
-    */
-
-    #define testImageClipComplexByType(datatype,MIN,MAX) /* datatype must be complex */ \
-    /* create image */ \
-    img = psImageAlloc(c,r,PS_TYPE_##datatype); \
-    for (unsigned row=0;row<r;row++) { \
-        ps##datatype* imgRow = img->data.datatype[row]; \
-        for (unsigned col=0;col<c;col++) { \
-            imgRow[col] = row+I*col; \
-        } \
-    } \
-    \
-    retVal = psImageClipComplexRegion(img,MIN,-1.0-1.0*I,MAX,-2.0-2.0*I); \
-    \
-    numClipped = 0; \
-    for (unsigned row=0;row<r;row++) { \
-        ps##datatype* imgRow = img->data.datatype[row]; \
-        for (unsigned col=0;col<c;col++) { \
-            ps##datatype value = (ps##datatype)(row+I*col); \
-            if ( (row > creal(MAX)) || (col > cimag(MAX)) ) { \
-                numClipped++; \
-                value = -2.0-2.0*I; \
-            } else if ((row < creal(MIN)) || (col < cimag(MIN)) ) { \
-                numClipped++; \
-                value = -1.0-1.0*I; \
-            } \
-            if (cabs(imgRow[col]-value) > FLT_EPSILON) { \
-                psError(PS_ERR_UNKNOWN, true,"Pixel value is not as expected (%g%+gi vs %g%+gi) at %d,%d", \
-                        creal(imgRow[col]),cimag(imgRow[col]),creal(value),cimag(value),col,row); \
-                return 1; \
-            } \
-        } \
-    } \
-    if (retVal != numClipped) { \
-        psError(PS_ERR_UNKNOWN, true,"Expected %d clips, but got %d", \
-                numClipped,retVal); \
-        return 2; \
-    } \
-    psFree(img);
-
-    complex double min = ((double)r)/5.0+I*((double)c)/4.0;
-    complex double max = ((double)r)/3.0+I*((double)c)/2.0;
-
-    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping at %g%+gi to %g%+gi for psC32",
-             creal(min),cimag(min),creal(max),cimag(max));
-
-    testImageClipComplexByType(C32,min,max);
-
-    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping at %g%+gi to %g%+gi for psC64",
-             creal(min),cimag(min),creal(max),cimag(max));
-    testImageClipComplexByType(C64,min,max);
-
-    //  6. Call psImageClipComplexRegion with NULL input parameter; should error
-    //     but not stop execution.
-
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
-    retVal = psImageClipComplexRegion(NULL,0,0,0,0);
-    if (retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"Expected zero return for clips of a NULL image.");
-        return 3;
-    }
-
-
-    img = psImageAlloc(c,r,PS_TYPE_C32);
-    for (unsigned row=0;row<r;row++) {
-        psC32* imgRow = img->data.C32[row];
-        for (unsigned col=0;col<c;col++) {
-            imgRow[col] = row+I*col;
-        }
-    }
-
-    //  7. Call psImageClipComplexRegion with min > max; should error and return 0,
-    //     but not stop execution
-
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
-    retVal = psImageClipComplexRegion(img,10.0+I*1.0,-1.0,5.0+5.0*I,-2.0);
-    if (retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"Expected zero return for creal(min)>creal(max).");
-        return 3;
-    }
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
-    retVal = psImageClipComplexRegion(img,1.0+I*10.0,-1.0,5.0+5.0*I,-2.0);
-    if (retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"Expected zero return for cimag(min)>cimag(max).");
-        return 3;
-    }
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
-    retVal = psImageClipComplexRegion(img,10.0+I*10.0,-1.0,5.0+5.0*I,-2.0);
-    if (retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"Expected zero return for min>max.");
-        return 3;
-    }
-
-    //  8. Call psImageClipComplexRegion with the follow vmin/vmax values; each
-    //     should error and return 0, but not stop execution
-    //      a) vmin < datatype region's minimum
-    //      b) vmax < datatype region's minimum
-    //      c) vmin > datatype region's maximum
-    //      d) vmax > datatype region's maximum
-
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
-    retVal = psImageClipComplexRegion(img,
-                                      1.0+I*1.0,
-                                      -2.0*(double)FLT_MAX,
-                                      5.0+5.0*I,
-                                      0.0);
-    if (retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"Expected zero return for vmin not in datatype range.");
-        return 80;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
-    retVal = psImageClipComplexRegion(img,
-                                      1.0+I*1.0,
-                                      2.0*(double)FLT_MAX,
-                                      5.0+5.0*I,
-                                      0.0);
-    if (retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"Expected zero return for vmin not in datatype range.");
-        return 81;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
-    retVal = psImageClipComplexRegion(img,
-                                      1.0+I*1.0,
-                                      -2.0*(double)FLT_MAX*I,
-                                      5.0+5.0*I,
-                                      0.0);
-    if (retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"Expected zero return for vmin not in datatype range.");
-        return 82;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
-    retVal = psImageClipComplexRegion(img,
-                                      1.0+I*1.0,
-                                      2.0*(double)FLT_MAX*I,
-                                      5.0+5.0*I,
-                                      0.0);
-    if (retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"Expected zero return for vmin not in datatype range.");
-        return 83;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
-    retVal = psImageClipComplexRegion(img,
-                                      1.0+I*1.0,
-                                      0.0,
-                                      5.0+5.0*I,
-                                      -2.0*(double)FLT_MAX);
-    if (retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"Expected zero return for vmax not in datatype range.");
-        return 84;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
-    retVal = psImageClipComplexRegion(img,
-                                      1.0+I*1.0,
-                                      0.0,
-                                      5.0+5.0*I,
-                                      2.0*(double)FLT_MAX);
-    if (retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"Expected zero return for vmax not in datatype range.");
-        return 85;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
-    retVal = psImageClipComplexRegion(img,
-                                      1.0+I*1.0,
-                                      0.0,
-                                      5.0+5.0*I,
-                                      -2.0*(double)FLT_MAX*I);
-    if (retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"Expected zero return for vmax not in datatype range.");
-        return 87;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
-    retVal = psImageClipComplexRegion(img,
-                                      1.0+I*1.0,
-                                      0.0,
-                                      5.0+5.0*I,
-                                      2.0*(double)FLT_MAX*I);
-    if (retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"Expected zero return for vmax not in datatype range.");
-        return 88;
-    }
-
-
-    // now check if vmin > vmax is OK
-    for (unsigned row=0;row<r;row++) {
-        psC32* imgRow = img->data.C32[row];
-        for (unsigned col=0;col<c;col++) {
-            imgRow[col] = row+I*col;
-        }
-    }
-    retVal = psImageClipComplexRegion(img,
-                                      1.0+I*1.0,
-                                      10.0,
-                                      5.0+5.0*I,
-                                      0.0);
-    if (retVal == 0) {
-        psError(PS_ERR_UNKNOWN, true,"Didn't expect zero return for vmin > vmax.");
-        return 83;
-    }
-
-
-    psFree(img);
-    img = NULL;
-
-    //  9. Call psImageClipComplexRegion with the max value out of datatype's
-    //     range; should clip as expected (see step 1-5). Repeat with min value
-    //     out of datatype's range.
-
-    testImageClipComplexByType(C32,-(double)FLT_MAX*2.0-I*(double)FLT_MAX*2.0,10.0+I*10.0);
-    testImageClipComplexByType(C32,10.0+I*10.0,(double)FLT_MAX*2.0+I*(double)FLT_MAX*2.0);
-
-    // Verify program execution doesn't stop if the input image type is something
-    // other than C32, C64.
-    img = psImageAlloc(c,r,PS_TYPE_S32);
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error (invalid type)");
-    retVal = psImageClipComplexRegion(img,2.0,10.0,5.0,0.0);
-    if (retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"Expected zero return for clip of invalid image type.");
-        return 84;
-    }
-    psFree(img);
-
-    return 0;
-}
-
-psS32 testImageOverlay(void)
-{
-
-    psImage* img = NULL;
-    psImage* img2 = NULL;
-    psImage* img3 = NULL;
-    psImage* img4 = NULL;
-    psU32 c = 128;
-    psU32 r = 256;
-    psS32 retVal;
-
-    /*
-    psImageSectionOverlay shall modified pixel values in a psImage structure to
-    be equal to the value of the originaldata and an overlay image with a
-    specified operation. Valid operations include =, +, -, *, /.
-
-    Verify the returned integer is zero
-    and the input parameter psImage structure is modified at the specified
-    location and range with the given overlay image and the specified
-    function. Cases should include all the valid operations. Comparison of
-    expected values should include a delta to allow for testing on
-    different platforms.
-
-    */
-
-    #define testOverlayTypeOP(DATATYPE,OP,OPSTRING) \
-    img = psImageAlloc(c,r,PS_TYPE_##DATATYPE); \
-    for (unsigned row=0;row<r;row++) { \
-        ps##DATATYPE* imgRow = img->data.DATATYPE[row]; \
-        for (unsigned col=0;col<c;col++) { \
-            imgRow[col] = 6.0; \
-        } \
-    } \
-    img2 = psImageAlloc(c/2,r/2,PS_TYPE_##DATATYPE); \
-    for (unsigned row=0;row<r/2;row++) { \
-        ps##DATATYPE* img2Row = img2->data.DATATYPE[row]; \
-        for (unsigned col=0;col<c/2;col++) { \
-            img2Row[col] = 2.0; \
-        } \
-    } \
-    retVal = psImageOverlaySection(img,img2,c/4,r/4,OPSTRING); \
-    if (retVal == 0) { \
-        psError(PS_ERR_UNKNOWN, true,"psImageOverlaySection returned zero with %s op", \
-                OPSTRING); \
-        return 1; \
-    } \
-    for (unsigned row=0;row<r;row++) { \
-        ps##DATATYPE* imgRow = img->data.DATATYPE[row]; \
-        ps##DATATYPE* img2Row = img2->data.DATATYPE[row]; \
-        for (unsigned col=0;col<c;col++) { \
-            ps##DATATYPE val = 6.0; \
-            if ( ! (row < r/4 || row >= r/2+r/4 || col < c/4 || col >= c/2+c/4)) { \
-                val OP 2.0; \
-            } \
-            if (fabsf(imgRow[col] - val) > FLT_EPSILON) { \
-                psError(PS_ERR_UNKNOWN, true,"Value incorrect at %d,%d (%.2f vs %.2f for %s)", \
-                        col,row,imgRow[col],val,OPSTRING); \
-                return 2; \
-            } \
-            if (row < r/2 && col < c/2 && fabsf(img2Row[col] - 2.0) > FLT_EPSILON) { \
-                psError(PS_ERR_UNKNOWN, true,"Overlay modified at %d,%d (%.2f for %s)", \
-                        col,row,img2Row[col],OPSTRING); \
-                return 2; \
-            } \
-        } \
-    } \
-    psFree(img); \
-    psFree(img2);
-
-    #define testOverlayType(DATATYPE) \
-    testOverlayTypeOP(DATATYPE,+=,"+"); \
-    testOverlayTypeOP(DATATYPE,-=,"-"); \
-    testOverlayTypeOP(DATATYPE,*=,"*");\
-    testOverlayTypeOP(DATATYPE,/=,"/");\
-    testOverlayTypeOP(DATATYPE,=,"=");
-
-    testOverlayType(C64);
-    testOverlayType(C32);
-    testOverlayType(F64);
-    testOverlayType(F32);
-    testOverlayType(S16);
-    testOverlayType(S8);
-    testOverlayType(U16);
-    testOverlayType(U8);
-
-    /*
-    Verify the returned integer is equal to non-zero and the input psImage structure
-    is unmodified, if the overlay specified is not within the data range of the
-    input psImage structure.
-    */
-
-    img = psImageAlloc(c,r,PS_TYPE_F32);
-    for (unsigned row=0;row<r;row++) {
-        psF32* imgRow = img->data.F32[row];
-        for (unsigned col=0;col<c;col++) {
-            imgRow[col] = 6.0f;
-        }
-    }
-    img2 = psImageAlloc(c,r,PS_TYPE_F32);
-    for (unsigned row=0;row<r;row++) {
-        psF32* img2Row = img2->data.F32[row];
-        for (unsigned col=0;col<c;col++) {
-            img2Row[col] = 2.0f;
-        }
-    }
-    img3 = psImageAlloc(c,r,PS_TYPE_S64);
-    for (unsigned row=0;row<r;row++) {
-        psS64* img3Row = img3->data.S64[row];
-        for (unsigned col=0;col<c;col++) {
-            img3Row[col] = 6.0f;
-        }
-    }
-    img4 = psImageAlloc(c,r,PS_TYPE_S64);
-    for (unsigned row=0;row<r;row++) {
-        psS64* img4Row = img4->data.S64[row];
-        for (unsigned col=0;col<c;col++) {
-            img4Row[col] = 2.0f;
-        }
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"Following should error as overlay isn't "
-             "within image boundaries");
-    retVal = psImageOverlaySection(img,img2,c/4,r/4,"+");
-    if (retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"psImageOverlaySection did not return "
-                "zero even though overlay too big");
-        return 3;
-    }
-    for (unsigned row=0;row<r;row++) {
-        psF32* imgRow = img->data.F32[row];
-        for (unsigned col=0;col<c;col++) {
-            if (imgRow[col] != 6.0f) {
-                psError(PS_ERR_UNKNOWN, true,"Input image modified when overlay size too big");
-                return 4;
-            }
-        }
-    }
-
-    /*
-    Verify the returned integer is equal to non-zero, the input psImage
-    structure is unmodified and program execution doesn't stop, if the
-    overlay specified is null.
-    */
-
-    psLogMsg(__func__,PS_LOG_INFO,"Following should error as overlay is NULL");
-    retVal = psImageOverlaySection(img,NULL,c/4,r/4,"+");
-    if (retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"psImageOverlaySection did not return "
-                "zero even though overlay too big");
-        return 5;
-    }
-    for (unsigned row=0;row<r;row++) {
-        psF32* imgRow = img->data.F32[row];
-        for (unsigned col=0;col<c;col++) {
-            if (imgRow[col] != 6.0f) {
-                psError(PS_ERR_UNKNOWN, true,"Input image modified when overlay NULL");
-                return 6;
-            }
-        }
-    }
-
-    /*
-    Verify the returned integer is equal to non-zero and program execution
-    doesn't stop, if the input parameter image is null.
-    */
-
-    psLogMsg(__func__,PS_LOG_INFO,"Following should error as image input is NULL");
-    retVal = psImageOverlaySection(NULL,img2,c/4,r/4,"+");
-    if (retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"psImageOverlaySection returned non-zero even though "
-                "overlay too big");
-        return 7;
-    }
-
-    /*
-    Verify the return integer is equal to non-zero and program execution
-    doesn't stop, if the specified operator is not =,+,-,*,/
-    */
-
-    psLogMsg(__func__,PS_LOG_INFO,"Following should error as operator is invalid");
-    retVal = psImageOverlaySection(img,img2,0,0,"$");
-    if (retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"psImageOverlaySection returned non-zero even though "
-                "overlay operator is invalid");
-        return 8;
-    }
-
-    /*
-    Verify the return integer is equal to non-zero and program execution
-    doesn't stop, if the specified operator is NULL
-    */
-
-    psLogMsg(__func__,PS_LOG_INFO,"Following should error as operator is invalid");
-    retVal = psImageOverlaySection(img,img2,0,0,NULL);
-    if(retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"psImageOverlaySection returned non-zero even though "
-                "overlay operator is NULL");
-        return 9;
-    }
-
-    /*
-    Verify the return integer is equal to non-zero and program execution
-    doesn't stop, if overlay image is a different type than the input image
-    */
-    psLogMsg(__func__,PS_LOG_INFO,"Following should error as overlay is "
-             "a different type");
-    retVal = psImageOverlaySection(img,img3,0,0,"+");
-    if(retVal != 0) {
-        psError(PS_ERR_UNKNOWN, true,"psImageOverlaySection returned nonzero eventhough "
-                " overlay image type is different than input image.");
-        return 10;
-    }
-
-    /*
-    Verify program execution doen't stop, if the overly image contains
-    zero values with division operation is specified.
-    */
-    for (unsigned row=0;row<r;row++) {
-        psF32* img2Row = img2->data.F32[row];
-        for (unsigned col=0;col<c;col++) {
-            img2Row[col] = 0.0f;
-        }
-    }
-    retVal = psImageOverlaySection(img,img2,0,0,"/");
-    if (retVal == 0) {
-        psError(PS_ERR_UNKNOWN, true,"psImageOverlaySection returned zero when "
-                "checking divide-by-zero.");
-        return 12;
-    }
-
-    psFree(img);
-    psFree(img2);
-    psFree(img3);
-    psFree(img4);
-
-    return 0;
-}
-
-static psS32 testImageRebin(void)
-{
-
-    /*
-    This function shall generate a rescaled version of a psImage structure
-    derived from a specified statistics method.
-    */
-
-    psImage* in = NULL;
-    psImage* out = NULL;
-    psImage* out2 = NULL;
-    psImage* out3 = NULL;
-    psImage* mask = NULL;
-    psImage* meanTruth = NULL;
-    psImage* meanTruthWMask = NULL;
-    psImage* maxTruth = NULL;
-    psStats stats;
-
-    /*
-    Verify the returned psImage structure contains expected values, if the
-    input parameter input contains known data, the input scale is a known
-    value with a known statistical method specified in stats. Cases should
-    include at least two different scales and statistical methods. Comparison
-    of expected values should include a delta to allow testing on different
-    platforms.
-    */
-
-    #define testRebinType(DATATYPE)  \
-    in = psImageAlloc(16,16,PS_TYPE_##DATATYPE); \
-    mask = psImageAlloc(16,16,PS_TYPE_U8); \
-    meanTruth = psImageAlloc(4,4,PS_TYPE_F32); \
-    meanTruthWMask = psImageAlloc(4,4,PS_TYPE_F32); \
-    maxTruth = psImageAlloc(6,6,PS_TYPE_F32); \
-    memset(meanTruth->data.F32[0],0,sizeof(psF32)*4*4); \
-    memset(meanTruthWMask->data.F32[0],0,sizeof(psF32)*4*4); \
-    memset(maxTruth->data.F32[0],0,sizeof(psF32)*6*6); \
-    for (psS32 row = 0; row<16; row++) { \
-        ps##DATATYPE* inRow = in->data.DATATYPE[row]; \
-        psF32* meanTruthRow = meanTruth->data.F32[row/4]; \
-        psF32* meanTruthWMaskRow = meanTruthWMask->data.F32[row/4]; \
-        psF32* maxTruthRow = maxTruth->data.F32[row/3]; \
-        psU8* maskRow = mask->data.U8[row]; \
-        for (psS32 col = 0; col<16; col++) { \
-            if(col != 15) { \
-                maskRow[col] = 0; \
-            } else { \
-                maskRow[col] = 1; \
-            } \
-            inRow[col] = row + col; \
-            meanTruthRow[col/4] += row + col; \
-            if (maxTruthRow[col/3] < row + col) { \
-                maxTruthRow[col/3] = row+col; \
-            } \
-            if(maskRow[col] == 0 ) { \
-                meanTruthWMaskRow[col/4] += row + col; \
-            } \
-        } \
-    } \
-    for (psS32 row = 0; row<4; row++) { \
-        psF32* meanTruthRow = meanTruth->data.F32[row]; \
-        psF32* meanTruthWMaskRow = meanTruthWMask->data.F32[row]; \
-        for (psS32 col = 0; col<4; col++) { \
-            meanTruthRow[col] /= 16; \
-            if ( col == 3 ) { \
-                meanTruthWMaskRow[col] /= 12; \
-            } else { \
-                meanTruthWMaskRow[col] /= 16; \
-            } \
-        } \
-    } \
-    stats.options = PS_STAT_SAMPLE_MEAN; \
-    out = psImageRebin(NULL,in,NULL,0,4,&stats); \
-    if (out == NULL) { \
-        psError(PS_ERR_UNKNOWN, true,"psImageRebin returned a NULL pointer!?"); \
-        return 1; \
-    } \
-    if (out->numRows != 4 || out->numCols != 4) { \
-        psError(PS_ERR_UNKNOWN, true,"psImageRebin didn't produce the proper size image " \
-                "(%d x %d).", \
-                out->numCols, out->numRows); \
-        return 2; \
-    } \
-    for (psS32 row = 0; row<4; row++) { \
-        ps##DATATYPE* outRow = out->data.DATATYPE[row]; \
-        psF32* truthRow = meanTruth->data.F32[row]; \
-        for (psS32 col = 0; col<4; col++) { \
-            if (fabsf((float)outRow[col]-(float)truthRow[col]) > FLT_EPSILON) { \
-                psError(PS_ERR_UNKNOWN, true,"psImageRebin didn't produce the proper mean " \
-                        "result at (%d,%d) [%f vs %f].", \
-                        col,row,outRow[col],truthRow[col]); \
-                return 3; \
-            } \
-        } \
-    } \
-    stats.options = PS_STAT_SAMPLE_MEAN; \
-    out3 = psImageRebin(NULL,in,mask,1,4,&stats); \
-    for (psS32 row = 0; row<4; row++) { \
-        ps##DATATYPE* outRow = out3->data.DATATYPE[row]; \
-        psF32* truthRow = meanTruthWMask->data.F32[row]; \
-        for ( psS32 col = 0; col<4; col++) { \
-            if(abs((psS32)outRow[col]-(psS32)truthRow[col]) > FLT_EPSILON) { \
-                psError(PS_ERR_UNKNOWN, true,"psImageRebin with mask didn't produce the proper mean " \
-                        "result at (%d,%d) [%f vs %f].", \
-                        col,row,outRow[col],truthRow[col]); \
-                return 3; \
-            } \
-        } \
-    } \
-    stats.options = PS_STAT_MAX; \
-    out2 = psImageRebin(out,in,NULL,0,3,&stats); \
-    if (out != out2) { \
-        psError(PS_ERR_UNKNOWN, true,"psImageRebin didn't recycle a psImage properly!?"); \
-        return 7; \
-    } \
-    if (out == NULL) { \
-        psError(PS_ERR_UNKNOWN, true,"psImageRebin returned a NULL pointer!?"); \
-        return 4; \
-    } \
-    if (out->numRows != 6 || out->numCols != 6) { \
-        psError(PS_ERR_UNKNOWN, true,"psImageRebin didn't produce the proper size image " \
-                "(%d x %d).", \
-                out->numCols, out->numRows); \
-        return 5; \
-    } \
-    for (psS32 row = 0; row<6; row++) { \
-        ps##DATATYPE* outRow = out->data.DATATYPE[row]; \
-        psF32* truthRow = maxTruth->data.F32[row]; \
-        for (psS32 col = 0; col<6; col++) { \
-            if (fabsf((float)outRow[col]-(float)truthRow[col]) > FLT_EPSILON) { \
-                psError(PS_ERR_UNKNOWN, true,"psImageRebin didn't produce the proper " \
-                        "max result at (%d,%d) [%f vs %f].", \
-                        col,row,outRow[col],truthRow[col]); \
-                return 6; \
-            } \
-        } \
-    } \
-    psFree(in); \
-    psFree(out); \
-    psFree(out3); \
-    psFree(mask); \
-    psFree(meanTruth); \
-    psFree(meanTruthWMask); \
-    psFree(maxTruth);
-
-    testRebinType(F32);
-    testRebinType(F64);
-    testRebinType(U16);
-    testRebinType(S8);
-
-    // Verify the returned psImage structure is null and program execution
-    // doesn't stop, if the input image type is not supported.
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for unsupported type.");
-    in = psImageAlloc(16,16,PS_TYPE_U8);
-    mask = psImageAlloc(16,16,PS_TYPE_F32);
-    stats.options = PS_STAT_SAMPLE_MEAN;
-    out = psImageRebin(NULL,in,NULL,0,4,&stats);
-    if(out != NULL) {
-        psError(PS_ERR_UNKNOWN, true,"psImageRebin return an image eventhough the "
-                "type is not handled.");
-        return 14;
-    }
-    // Verify the returned psImage structure is null and program execution
-    // doesn't stop, if the mask type is not U8
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for invallid mask type.");
-    out = psImageRebin(NULL,in,mask,1,4,&stats);
-    if(out != NULL) {
-        psError(PS_ERR_UNKNOWN, true,"psImageRebin return an image eventhough the "
-                "mask is not the correct type.");
-        return 17;
-    }
-    psFree(mask);
-    psFree(in);
-
-    // Verify the returned psImage structure is null and program execution
-    // doesn't stop, if the input parameter input is null.
-
-    out2 = psImageRebin(NULL,NULL,NULL,0,1,&stats);
-
-    if (out2 != NULL) {
-        psError(PS_ERR_UNKNOWN, true,"psImageRebin returned an image though the input was "
-                "NULL!?");
-        return 8;
-    }
-
-    // Verify the returned psImage structure is null and program execution
-    // doesn't stop, if the input parameter scale is less than or equal to zero.
-    in = psImageAlloc(16, 16, PS_TYPE_F32);
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for scale < 0.");
-    out2 = psImageRebin(NULL,in,NULL,0,0,&stats);
-
-    if (out2 != NULL) {
-        psError(PS_ERR_UNKNOWN, true,"psImageRebin returned an image though the scale was "
-                "zero!?");
-        return 9;
-    }
-
-    // Verify the returned psImage structure is null and program execution
-    // doesn't stop, if the input parameter stats is null.
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for stats null.");
-    out2 = psImageRebin(NULL,in,NULL,0,1,NULL);
-
-    if (out2 != NULL) {
-        psError(PS_ERR_UNKNOWN, true,"psImageRebin returned an image though the stats was "
-                "NULL!?");
-        return 10;
-    }
-
-    // Verify the returned psImage structure is null and program execution
-    // doesn't stop, if the input parameter psStats structure member options
-    // is zero or any value which doesn't correspond to a valid statistical
-    // method.
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for stats options 0.");
-    stats.options = 0;
-    out2 = psImageRebin(NULL,in,NULL,0,1,&stats);
-
-    if (out2 != NULL) {
-        psError(PS_ERR_UNKNOWN, true,"psImageRebin returned an image though the stats "
-                "options was zero!?");
-        return 11;
-    }
-
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for stat options use range.");
-    stats.options = PS_STAT_USE_RANGE;
-    out2 = psImageRebin(NULL,in,NULL,0,1,&stats);
-
-    if (out2 != NULL) {
-        psError(PS_ERR_UNKNOWN, true,"psImageRebin returned an image though the stats "
-                "options was PS_STAT_USE_RANGE!?");
-        return 12;
-    }
-
-    // Verify the returned psImage structure is null and program execution
-    // doesn't stop, if the input parameter psStats structure member options
-    // specifies more than one valid statistical method.
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for stats with multiple options.");
-    stats.options = PS_STAT_SAMPLE_MEAN + PS_STAT_MAX;
-    out2 = psImageRebin(NULL,in,NULL,0,1,&stats);
-
-    if (out2 != NULL) {
-        psError(PS_ERR_UNKNOWN, true,"psImageRebin returned an image though the stats "
-                "options was PS_STAT_SAMPLE_MEAN+PS_STAT_MAX!?");
-        return 13;
-    }
-
-    psFree(in);
-
-    return 0;
-}
-
-static psS32 testImageRoll(void)
-{
-
-    psImage* in;
-    psImage* out;
-    psImage* out2;
-    psS32 rows = 64;
-    psS32 cols = 64;
-    psS32 rows1 = 8;
-    psS32 cols1 = 8;
-
-    /*
-     The function psImageRoll shall generate a new psImage structure by
-     rolling the input image the correponding number of pixels in the vertical
-     and/or horizontal direction. The image output image shall be the same size
-     as the input image. Values which roll off the image are wrapped to the
-     other side.
-
-     Verify the returned psImage structure contains expected values, if the
-     input image contains known values and the roll performed is known.
-     Cases should include no roll, vertical roll, horizontal roll and
-     combination vertical/horizontal rolls. Positive and negative rolls
-     should be performed.
-    */
-
-    in = psImageAlloc(cols,rows,PS_TYPE_F32);
-    for (psS32 row=0;row<rows;row++) {
-        psF32* inRow = in->data.F32[row];
-        for (psS32 col=0;col<cols;col++) {
-            inRow[col] = (psF32)row+(psF32)col/1000.0f;
-        }
-    }
-
-    out = psImageRoll(NULL,in,0,0);
-    for (psS32 row=0;row<rows;row++) {
-        psF32* inRow = in->data.F32[row];
-        psF32* outRow = out->data.F32[row];
-        for (psS32 col=0;col<cols;col++) {
-            if (inRow[col] != outRow[col]) {
-                psError(PS_ERR_UNKNOWN, true,"psImageRoll didn't produce expected result "
-                        "at %d,%d (%f vs %f) for dx=0, dy=0.",
-                        col,row,inRow[col],outRow[col]);
-                return 3;
-            }
-        }
-    }
-
-    out2 = psImageRoll(out,in,cols/4,0);
-    for (psS32 row=0;row<rows;row++) {
-        psF32* inRow = in->data.F32[row];
-        psF32* outRow = out->data.F32[row];
-        for (psS32 col=0;col<cols;col++) {
-            if (inRow[(col+cols/4) % cols] != outRow[col]) {
-                psError(PS_ERR_UNKNOWN, true,"psImageRoll didn't produce expected result "
-                        "at %d,%d (%f vs %f) for dx=cols/4, dy=0.",
-                        col,row,inRow[(col+cols/4) % cols],outRow[col]);
-                return 4;
-            }
-        }
-    }
-
-    // Verify the returned psImage structure pointer is equal to the input
-    // parameter out if provided.
-    if (out2 != out) {
-        psError(PS_ERR_UNKNOWN, true,"psImageRoll didn't recycle my out psImage!?");
-        return 1;
-    }
-
-    out = psImageRoll(out,in,0,rows/4);
-    for (psS32 row=0;row<rows;row++) {
-        psF32* inRow = in->data.F32[(row+rows/4)%rows];
-        psF32* outRow = out->data.F32[row];
-        for (psS32 col=0;col<cols;col++) {
-            if (inRow[col] != outRow[col]) {
-                psError(PS_ERR_UNKNOWN, true,"psImageRoll didn't produce expected result "
-                        "at %d,%d (%f vs %f) for dx=0, dy=rows/4.",
-                        col,row,inRow[col],outRow[col]);
-                return 5;
-            }
-        }
-    }
-
-    out = psImageRoll(out,in,cols/4,rows/4);
-    for (psS32 row=0;row<rows;row++) {
-        psF32* inRow = in->data.F32[(row+rows/4)%rows];
-        psF32* outRow = out->data.F32[row];
-        for (psS32 col=0;col<cols;col++) {
-            if (inRow[(col+cols/4) % cols] != outRow[col]) {
-                psError(PS_ERR_UNKNOWN, true,"psImageRoll didn't produce expected result "
-                        "at %d,%d (%f vs %f) for dx=cols/4, dy=rows/4.",
-                        col,row,inRow[(col+cols/4) % cols],outRow[col]);
-                return 6;
-            }
-        }
-    }
-
-    out = psImageRoll(out,in,-cols/4,0);
-    for (psS32 row=0;row<rows;row++) {
-        psF32* inRow = in->data.F32[row];
-        psF32* outRow = out->data.F32[row];
-        for (psS32 col=0;col<cols;col++) {
-            if (inRow[(col+(cols-cols/4)) % cols] != outRow[col]) {
-                psError(PS_ERR_UNKNOWN, true,"psImageRoll didn't produce expected result "
-                        "at %d,%d (%f vs %f) for dx=-cols/4, dy=0.",
-                        col,row,inRow[(col+(cols-cols/4)) % cols],outRow[col]);
-                return 7;
-            }
-        }
-    }
-
-    out = psImageRoll(out,in,0,-rows/4);
-    for (psS32 row=0;row<rows;row++) {
-        psF32* inRow = in->data.F32[(row+rows-rows/4)%rows];
-        psF32* outRow = out->data.F32[row];
-        for (psS32 col=0;col<cols;col++) {
-            if (inRow[col] != outRow[col]) {
-                psError(PS_ERR_UNKNOWN, true,"psImageRoll didn't produce expected result "
-                        "at %d,%d (%f vs %f) for dx=0, dy=-rows/4.",
-                        col,row,inRow[col],outRow[col]);
-                return 8;
-            }
-        }
-    }
-
-    out = psImageRoll(out,in,-cols/4,-rows/4);
-    for (psS32 row=0;row<rows;row++) {
-        psF32* inRow = in->data.F32[(row+rows-rows/4)%rows];
-        psF32* outRow = out->data.F32[row];
-        for (psS32 col=0;col<cols;col++) {
-            if (inRow[(col+cols-cols/4) % cols] != outRow[col]) {
-                psError(PS_ERR_UNKNOWN, true,"psImageRoll didn't produce expected result "
-                        "at %d,%d (%f vs %f) for dx=cols/4, dy=rows/4.",
-                        col,row,inRow[(col+cols-cols/4) % cols],outRow[col]);
-                return 9;
-            }
-        }
-    }
-
-
-    // Verify the returned psImage structure pointer is null and program
-    // execution doesn't stop, if input parameter input is null.
-    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error.");
-    out2 = psImageRoll(NULL,NULL,0,0);
-    if (out2 != NULL) {
-        psError(PS_ERR_UNKNOWN, true,"psImageRoll did not return NULL though input image was NULL!?");
-        return 2;
-    }
-
-    psFree(in);
-    psFree(out);
-
-    #define testRollType(DATATYPE) \
-    in = psImageAlloc(rows1,cols1,PS_TYPE_##DATATYPE); \
-    \
-    for (psS32 row=0;row<rows1;row++) { \
-        ps##DATATYPE* inRow = in->data.DATATYPE[row]; \
-        for (psS32 col=0;col<cols1;col++) { \
-            inRow[col] = (ps##DATATYPE)row+(ps##DATATYPE)col; \
-        } \
-    } \
-    \
-    out = psImageRoll(NULL,in,rows1/4,cols1/4); \
-    for (psS32 row=0;row<rows1;row++) { \
-        ps##DATATYPE* inRow = in->data.DATATYPE[(row+rows1/4)%rows1]; \
-        ps##DATATYPE* outRow = out->data.DATATYPE[row]; \
-        for (psS32 col=0;col<cols1;col++) { \
-            if (inRow[(col+cols1/4)%cols1] != outRow[col]) { \
-                psError(PS_ERR_UNKNOWN, true,"psImageRoll didn't produce expected result " \
-                        "at %d,%d (%f vs %f) for dx=0, dy=0.", \
-                        col,row,(float)inRow[col],(float)outRow[col]); \
-                return 3; \
-            } \
-        } \
-    } \
-    psFree(in); \
-    psFree(out);
-
-    testRollType(U8);
-    testRollType(U16);
-    testRollType(S8);
-    testRollType(S16);
-    testRollType(F64);
-    testRollType(C32);
-    testRollType(C64);
-
-    return 0;
-}
-
-psS32 testImageRotate(void)
-{
-    /*
-
-    This function shall calculate a new psImage structure based upon the
-    rotation of a given psImage structure. The center of rotation shall be the
-    center pixel of the input image.
-
-    The following steps of the testpoint are done manually via inspection of
-    temp/fOut.fits & temp/sOut.fits.
-
-        * Verify the returned psImage structure contains expected values, if
-          the input parameter psImage contains known values. Cases should
-          include rotations of 0, 45, 90, 135, 180, 225, 270, 315, 360 and at leat one
-          other arbitrary angle. Cases of the input image should include image
-          with a center pixel and an image without a center pixel.
-        * Verify the returned psImage structure contains pixels set to exposed value, if
-          the rotation and input psImage to not correspond to the output image.
-
-    */
-
-    psImage* fOut = NULL;
-    psImage* sOut = NULL;
-    psImage* fBiOut = NULL;
-    psImage* sBiOut = NULL;
-    psImage* fTruth = NULL;
-    psImage* sTruth = NULL;
-    psImage* fBiTruth = NULL;
-    psImage* sBiTruth = NULL;
-    psS32 rows = 64;
-    psS32 cols = 64;
-    psImage* fImg = psImageAlloc(cols,rows,PS_TYPE_F32);
-    psImage* sImg = psImageAlloc(cols,rows,PS_TYPE_S16);
-
-    for(psS32 row=0;row<rows;row++) {
-        psF32* fRow = fImg->data.F32[row];
-        psS16* sRow = sImg->data.S16[row];
-        for (psS32 col=0;col<cols;col++) {
-            fRow[col] = (psF32)(row)+(psF32)(col)/100.0f;
-            sRow[col] = row-2*col;
-        }
-    }
-
-    // since interpolation is involved, etc., the simplist way to verify things
-    // is to verify the results manually and bless it for automated comparison
-    // thereafter
-
-
-    // write results of various rotates to a file and verify with truth images
-    mkdir("temp",0777);
-    remove
-        ("temp/fOut.fits")
-        ;
-    remove
-        ("temp/sOut.fits")
-        ;
-    remove
-        ("temp/fBiOut.fits")
-        ;
-    remove
-        ("temp/sBiOut.fits");
-    ;
-    psS32 index = 0;
-    psBool fail = false;
-    psF32 radianRot;
-    for (psS32 rot=-180;rot<=180;rot+=45) {
-        psImage* oldOut = fOut;
-        psImage* oldBiOut = fBiOut;
-
-        if (rot == 90) {
-            radianRot = M_PI_2;
-        } else if (rot == -90) {
-            radianRot = M_PI+M_PI_2;
-        } else if (rot == 180 || rot == -180) {
-            radianRot = M_PI;
-        } else {
-            radianRot = ((float)rot)*M_PI/180.0;
-        }
-
-        fOut = psImageRotate(fOut,fImg,radianRot,-1.0,PS_INTERPOLATE_FLAT);
-        fBiOut = psImageRotate(fBiOut,fImg,radianRot,-1.0,PS_INTERPOLATE_BILINEAR);
-        // Verify the returned psImage structure is equal to the input
-        // parameter out if provided.
-        if (oldOut != NULL && oldOut != fOut) {
-            psError(PS_ERR_UNKNOWN, true,"the output recycle functionality failed");
-            return 2;
-        }
-        if (oldBiOut != NULL && oldBiOut != fBiOut) {
-            psError(PS_ERR_UNKNOWN, true,"the output recycle functionality failed");
-            return 4;
-        }
-        sOut = psImageRotate(sOut,sImg,radianRot,-1.0,PS_INTERPOLATE_FLAT);
-        sBiOut = psImageRotate(sBiOut,sImg,radianRot,-1.0,PS_INTERPOLATE_BILINEAR);
-        if (! psImageWriteSection(fOut,0,0,0,NULL,index,"temp/fOut.fits") ) {
-            psError(PS_ERR_UNKNOWN, true,"Can not write to temp/fOut.fits, so why continue!?");
-            return 20;
-        }
-        if (! psImageWriteSection(sOut,0,0,0,NULL,index,"temp/sOut.fits") ) {
-            psError(PS_ERR_UNKNOWN, true,"Can not write to temp/sOut.fits, so why continue!?");
-            return 21;
-        }
-        if (! psImageWriteSection(fBiOut,0,0,0,NULL,index,"temp/fBiOut.fits") ) {
-            psError(PS_ERR_UNKNOWN, true,"Can not write to temp/fBiOut.fits, so why continue!?");
-            return 40;
-        }
-        if (! psImageWriteSection(sBiOut,0,0,0,NULL,index,"temp/sBiOut.fits") ) {
-            psError(PS_ERR_UNKNOWN, true,"Can not write to temp/sBiOut.fits, so why continue!?");
-            return 41;
-        }
-
-        // now, let's compare this with the verified file
-        fTruth = psImageReadSection(fTruth,0,0,0,0,0,NULL,index,"temp/fOut.fits");
-        sTruth = psImageReadSection(sTruth,0,0,0,0,0,NULL,index,"temp/sOut.fits");
-        fBiTruth = psImageReadSection(fBiTruth,0,0,0,0,0,NULL,index,"temp/fBiOut.fits");
-        sBiTruth = psImageReadSection(sBiTruth,0,0,0,0,0,NULL,index,"temp/sBiOut.fits");
-        if (fTruth == NULL) {
-            psError(PS_ERR_UNKNOWN, true,"verified psF32 image failed to be read (%d deg. rotation)",
-                    rot);
-            fail = true;
-        } else {
-            if (fTruth->numRows != fOut->numRows || fTruth->numCols != fOut->numCols) {
-                psError(PS_ERR_UNKNOWN, true,"Rotated float image size did not match truth "
-                        "image for %d deg rotation (%dx%d vs %dx%d).",
-                        rot,fOut->numCols,fOut->numRows,fTruth->numCols,fTruth->numRows);
-                fail = true;
-            } else {
-                for (psS32 row=0;row<fTruth->numRows;row++) {
-                    psF32* truthRow = fTruth->data.F32[row];
-                    psF32* outRow = fOut->data.F32[row];
-                    for (psS32 col=0;col<fTruth->numCols;col++) {
-                        if (fabsf(truthRow[col]-outRow[col]) > 1) {
-                            psError(PS_ERR_UNKNOWN, true,"Float Image mismatch (%f vs %f) at %d,%d.",
-                                    outRow[col], truthRow[col],col,row);
-                            fail = true;
-                        }
-                    }
-                }
-            }
-        }
-
-        if (sTruth == NULL) {
-            psError(PS_ERR_UNKNOWN, true,"verified psS16 image failed to be read "
-                    "(%d deg. rotation)",rot);
-            fail = true;
-        } else {
-            if (sTruth->numRows != sOut->numRows ||
-                    sTruth->numCols != sOut->numCols) {
-                psError(PS_ERR_UNKNOWN, true,"Rotated psS16 image size did not match truth "
-                        "image for %d deg rotation.",rot);
-                fail = true;
-            } else {
-                for (psS32 row=0;row<sTruth->numRows;row++) {
-                    psS16* truthRow = sTruth->data.S16[row];
-                    psS16* outRow = sOut->data.S16[row];
-                    for (psS32 col=0;col<sTruth->numCols;col++) {
-                        if (fabsf(truthRow[col]-outRow[col]) > 1) {
-                            psError(PS_ERR_UNKNOWN, true,"Short Image mismatch (%d vs %d) "
-                                    "at %d,%d.",
-                                    outRow[col], truthRow[col],col,row);
-                            fail = true;
-                        }
-                    }
-                }
-            }
-        }
-
-
-        if (fBiTruth == NULL) {
-            psError(PS_ERR_UNKNOWN, true,"verified psF32 Bi image failed to be read (%d deg. rotation)",
-                    rot);
-            fail = true;
-        } else {
-            if (fBiTruth->numRows != fBiOut->numRows || fBiTruth->numCols != fBiOut->numCols) {
-                psError(PS_ERR_UNKNOWN, true,"Rotated float image size did not match truth "
-                        "image for %d deg rotation (%dx%d vs %dx%d). BILINEAR",
-                        rot,fBiOut->numCols,fBiOut->numRows,fBiTruth->numCols,fBiTruth->numRows);
-                fail = true;
-            } else {
-                for (psS32 row=0;row<fBiTruth->numRows;row++) {
-                    psF32* truthRow = fBiTruth->data.F32[row];
-                    psF32* outRow = fBiOut->data.F32[row];
-                    for (psS32 col=0;col<fBiTruth->numCols;col++) {
-                        if (fabsf(truthRow[col]-outRow[col]) > 1) {
-                            psError(PS_ERR_UNKNOWN, true,"Float Image mismatch (%f vs %f) at %d,%d. BILINEAR",
-                                    outRow[col], truthRow[col],col,row);
-                            fail = true;
-                        }
-                    }
-                }
-            }
-        }
-
-        if (sBiTruth == NULL) {
-            psError(PS_ERR_UNKNOWN, true,"verified psS16 image failed to be read "
-                    "(%d deg. rotation) BILINEAR",rot);
-            fail = true;
-        } else {
-            if (sBiTruth->numRows != sBiOut->numRows ||
-                    sBiTruth->numCols != sBiOut->numCols) {
-                psError(PS_ERR_UNKNOWN, true,"Rotated psS16 image size did not match truth "
-                        "image for %d deg rotation. BILINEAR",rot);
-                fail = true;
-            } else {
-                for (psS32 row=0;row<sBiTruth->numRows;row++) {
-                    psS16* truthRow = sBiTruth->data.S16[row];
-                    psS16* outRow = sBiOut->data.S16[row];
-                    for (psS32 col=0;col<sBiTruth->numCols;col++) {
-                        if (fabsf(truthRow[col]-outRow[col]) > 1) {
-                            psError(PS_ERR_UNKNOWN, true,"Short Image mismatch (%d vs %d) "
-                                    "at %d,%d. BILINEAR",
-                                    outRow[col], truthRow[col],col,row);
-                            fail = true;
-                        }
-                    }
-                }
-            }
-        }
-
-        index++;
-    }
-
-    if (fail) {
-        psError(PS_ERR_UNKNOWN, true,"One or more images didn't match truth or truth did "
-                "not exist.");
-        return 10;
-    }
-
-
-    // Verify the returned psImage structure pointer is null and program
-    // execution doesn't stop, if the input parameter input is null.
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error");
-    fOut = psImageRotate(fOut,NULL,0,0,PS_INTERPOLATE_FLAT);
-    if (fOut != NULL) {
-        psError(PS_ERR_UNKNOWN, true,"NULL wasn't returned though the input image was NULL.");
-        return 3;
-    }
-
-    // Verify the returned psImage structure pointer is null and program
-    // execution doesn't stop, if the specified interpolation mode is invalid
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for invalid "
-             "interpolation type.");
-    fOut = psImageRotate(fOut, fImg, 33, 0, -1);
-    if (fOut != NULL) {
-        psError(PS_ERR_UNKNOWN, true,"NULL wasn't returned though the interpolation mode "
-                "is invalid.");
-        return 4;
-    }
-
-    psFree(sOut);
-    psFree(fImg);
-    psFree(sImg);
-    psFree(fTruth);
-    psFree(sTruth);
-    psFree(sBiOut);
-    psFree(fBiTruth);
-    psFree(sBiTruth);
-    psFree(fBiOut);
-
-    return 0;
-}
-
-static psS32 testImageShift(void)
-{
-    /* psImageShift:
-
-       This functions shall generate a new psImage structure by shifting the
-       input psImage structure a specified number of pixels in the horizontal
-       and/or vertical directions.
-
-       Verify the returned psImage structure contains expected values, if the
-       input psImage structure contains known values and a know shift in the
-       vertical and/or horizontal directions. Cases should include no shift,
-       vertical only(up,down), horizontal only(right, left), and combination
-       shift. Cases should include fractional shifts. Comparison of expected
-       values should include a delta to allow for testing on different
-       platforms.
-
-       Verify the returned psImage structure contains values for pixels not in
-       the original image set to the input parameter exposed.
-
-    */
-
-    psS32 retVal=0;
-
-    // integer shift
-    retVal |= testImageShiftCase(64,128,0.0f,0.0f);
-    retVal |= testImageShiftCase(64,128,0.0f,16.0f);
-    retVal |= testImageShiftCase(64,128,0.0f,-16.0f);
-    retVal |= testImageShiftCase(64,128,32.0f,0.0f);
-    retVal |= testImageShiftCase(64,128,-32.0f,0.0f);
-    retVal |= testImageShiftCase(64,128,32.0f,16.0f);
-    retVal |= testImageShiftCase(64,128,32.0f,-16.0f);
-    retVal |= testImageShiftCase(64,128,-32.0f,16.0f);
-    retVal |= testImageShiftCase(64,128,-32.0f,-16.0f);
-
-    if (retVal != 0) {
-        return retVal;
-    }
-
-    // fractional shift
-    retVal |= testImageShiftCase(64,128,0.0f,16.4f);
-    retVal |= testImageShiftCase(64,128,0.0f,-16.4f);
-    retVal |= testImageShiftCase(64,128,32.7f,0.0f);
-    retVal |= testImageShiftCase(64,128,-32.7f,0.0f);
-    retVal |= testImageShiftCase(64,128,32.6f,16.2f);
-    retVal |= testImageShiftCase(64,128,32.6f,-16.2f);
-    retVal |= testImageShiftCase(64,128,-32.6f,16.2f);
-    retVal |= testImageShiftCase(64,128,-32.6f,-16.2f);
-
-    if (retVal != 0) {
-        return retVal;
-    }
-
-    /*
-       Verify the returned psImage structure pointer is equal to the input
-       parameter out if provided.
-    */
-    psImage* fImg = psImageAlloc(32,32,PS_TYPE_F32);
-    psImage* fRecycle = psImageAlloc(32,32,PS_TYPE_F32);
-    psImage* fOut = psImageShift(fRecycle, fImg, 8,8, NAN, PS_INTERPOLATE_FLAT);
-
-    if (fRecycle != fOut) {
-        psError(PS_ERR_UNKNOWN, true,"psImageShift didn't recycle my image?");
-        return 10;
-    }
-
-    /*
-       Verify the returned psImage structure pointer is null and program
-       execution doesn't stop, if the input psImage structure pointer is null.
-    */
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error...");
-    fOut = psImageShift(fOut,NULL,8,8,NAN,PS_INTERPOLATE_FLAT);
-    if (fOut != NULL) {
-        psError(PS_ERR_UNKNOWN, true,"psImageShift didn't return NULL given a NULL input image.");
-        return 11;
-    }
-
-    // Verify the returned psImage structure is null and program execution
-    // doesn't stop, if the specified interpolation mode is invalid.
-    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for invalid interpolation mode.");
-    fOut = psImageShift(fOut,fImg,8,8,NAN,-1);
-    if (fOut != NULL ) {
-        psError(PS_ERR_UNKNOWN, true,"psImageShift didn't return NULL given an invalid interpolation mode.");
-        return 12;
-    }
-
-    psFree(fImg);
-
-    return 0;
-}
-
-static psS32 testImageShiftCase(psS32 cols,
-                                psS32 rows,
-                                float colShift,
-                                float rowShift)
-{
-    psImage* fOut = NULL;
-    psImage* sOut = NULL;
-
-    psLogMsg(__func__,PS_LOG_INFO,"Testing psImageShift with a %dx%d image for "
-             "a shift of %g,%g.",cols,rows,colShift,rowShift);
-
-    psImage* fImg = psImageAlloc(cols,rows,PS_TYPE_F32);
-    psImage* sImg = psImageAlloc(cols,rows,PS_TYPE_S16);
-    psImage* fBiOut = psImageAlloc(cols,rows,PS_TYPE_F32);
-    psImage* sBiOut = psImageAlloc(cols,rows,PS_TYPE_S16);
-
-    for(psS32 row=0;row<rows;row++) {
-        psF32* fRow = fImg->data.F32[row];
-        psS16* sRow = sImg->data.S16[row];
-        for (psS32 col=0;col<cols;col++) {
-            fRow[col] = (psF32)(row)+(psF32)(col)/100.0f;
-            sRow[col] = row-2*col;
-        }
-    }
-
-    fOut = psImageShift(fOut, fImg, colShift, rowShift, NAN, PS_INTERPOLATE_FLAT);
-    sOut = psImageShift(sOut, sImg, colShift, rowShift, -1, PS_INTERPOLATE_FLAT);
-    fBiOut = psImageShift(fBiOut, fImg, colShift, rowShift, NAN, PS_INTERPOLATE_BILINEAR);
-    sBiOut = psImageShift(sBiOut, sImg, colShift, rowShift, -1, PS_INTERPOLATE_BILINEAR);
-
-    for(psS32 row=0;row<rows;row++) {
-        psF32* fRow = fOut->data.F32[row];
-        psS16* sRow = sOut->data.S16[row];
-        psF32* fBiRow = fBiOut->data.F32[row];
-        psS16* sBiRow = sBiOut->data.S16[row];
-
-        for (psS32 col=0;col<cols;col++) {
-            psF32 fValue = psImagePixelInterpolate(fImg,col+colShift,
-                                                   row+rowShift,NULL,0,NAN,PS_INTERPOLATE_FLAT);
-            psS16 sValue = (psS16)psImagePixelInterpolate(sImg,col+colShift,
-                           row+rowShift,NULL,0,-1,PS_INTERPOLATE_FLAT);
-
-            psF32 fBiValue = psImagePixelInterpolate(fImg,col+colShift,
-                             row+rowShift,NULL,0,NAN,PS_INTERPOLATE_BILINEAR);
-            psS16 sBiValue = (psS16)psImagePixelInterpolate(sImg,col+colShift,
-                             row+rowShift,NULL,0,-1,PS_INTERPOLATE_BILINEAR);
-
-            if (fabsf(fRow[col] - fValue) > FLT_EPSILON) {
-                psError(PS_ERR_UNKNOWN, true,"Float image not shifted correctly at %d,%d (%g vs %g)",
-                        col,row,fRow[col],fValue);
-                return 1;
-            }
-            if (sRow[col] != sValue) {
-                psError(PS_ERR_UNKNOWN, true,"Short image not shifted correctly at %d,%d (%d vs %d)",
-                        col,row,sRow[col],sValue);
-                return 2;
-            }
-            if (fabsf(fBiRow[col] - fBiValue) > FLT_EPSILON) {
-                psError(PS_ERR_UNKNOWN, true,"Float image not shifted correctly at %d,%d (%g vs %g)",
-                        col,row,fBiRow[col],fBiValue);
-                return 1;
-            }
-            if (sBiRow[col] != sBiValue) {
-                psError(PS_ERR_UNKNOWN, true,"Short image not shifted correctly at %d,%d (%d vs %d)",
-                        col,row,sBiRow[col],sBiValue);
-                return 2;
-            }
-        }
-    }
-
-    psFree(fImg);
-    psFree(sImg);
-    psFree(fOut);
-    psFree(sOut);
-    psFree(fBiOut);
-    psFree(sBiOut);
-
-    return 0;
-}
-
-static psS32 testImageResample(void)
-{
-
-    psS32 rows = 60;
-    psS32 cols = 80;
-    psImage* result = NULL;
-    psS32 scale = 4;
-    psErr* err;
-
-    psImage* image = psImageAlloc(cols,rows,PS_TYPE_F32);
-    for(psS32 row=0;row<rows;row++) {
-        psF32* imageRow = image->data.F32[row];
-        for (psS32 col=0;col<cols;col++) {
-            imageRow[col] = row+2*col;
-        }
-    }
-    result = psImageCopy(NULL,image,PS_TYPE_F64);
-    psImage* orig = result;
-    result = psImageResample(result,image,scale,PS_INTERPOLATE_FLAT);
-
-    if (result == NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "NULL return unexpected");
-        return 1;
-    }
-
-    if (result != orig) {
-        psLogMsg(__func__,PS_LOG_ERROR,"failure to recycle image.");
-        return 2;
-    }
-
-    if (result->type.type != PS_TYPE_F32) {
-        psLogMsg(__func__,PS_LOG_ERROR,"unexpected type");
-        return 3;
-    }
-
-
-    if (result->numCols != image->numCols*scale ||
-            result->numRows != image->numRows*scale) {
-        psLogMsg(__func__,PS_LOG_ERROR,"The size of the result is %dx%d, but %dx%d was expected.",
-                 result->numCols,result->numRows,
-                 image->numCols*scale, image->numRows*scale);
-        return 4;
-    }
-
-    psF32 truthValue;
-    for(psS32 row=0;row<result->numRows;row++) {
-        for (psS32 col=0;col<result->numCols;col++) {
-            truthValue = psImagePixelInterpolate(image,
-                                                 (float)col/(float)scale,(float)row/(float)scale,
-                                                 NULL,0,-1,PS_INTERPOLATE_FLAT);
-            if (fabs(truthValue - result->data.F32[row][col]) > FLT_EPSILON) {
-                psLogMsg(__func__,PS_LOG_ERROR,"value bad at (%d,%d).  Got %g, expected %g.",
-                         col,row,result->data.F32[row][col], truthValue);
-                return 5;
-            }
-        }
-    }
-
-    // verify that image=null is handled properly.
-    psErrorClear();
-    result = psImageResample(result,NULL,scale,PS_INTERPOLATE_FLAT);
-
-    if (result != NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "return was not NULL, as expected.");
-        return 6;
-    }
-    err = psErrorLast();
-    if (err->code != PS_ERR_BAD_PARAMETER_NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "error message was not appropriate type.");
-        return 7;
-    }
-    psFree(err);
-
-    // verify that scale < 1 is handled properly
-    psErrorClear();
-    result = psImageResample(result,image,0,PS_INTERPOLATE_FLAT);
-
-    if (result != NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "return was not NULL, as expected.");
-        return 8;
-    }
-    err = psErrorLast();
-    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "error message was not appropriate type.");
-        return 9;
-    }
-    psFree(err);
-
-    // verify that invalid interpolation mode is handled properly
-    psErrorClear();
-    result = psImageResample(result,image,2,-1);
-
-    if (result != NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "return was not NULL, as expected.");
-        return 10;
-    }
-    err = psErrorLast();
-    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
-        psLogMsg(__func__,PS_LOG_ERROR,
-                 "error message was not appropriate type.");
-        return 11;
-    }
-    psFree(err);
-
-    // Verify that that an invalid image type is handled properly
-    psErrorClear();
-    psImage* invImage = psImageAlloc(cols,rows,PS_TYPE_BOOL);
-    memset(invImage->rawDataBuffer,0,cols*rows*sizeof(psBool)); // make sure the image is of all NULLs
-    result = psImageResample(result,invImage,2,PS_INTERPOLATE_FLAT);
-    if (result != NULL) {
-        psLogMsg(__func__,PS_LOG_ERROR,"return was not NULL, as expected.");
-        return 20;
-    }
-    err = psErrorLast();
-    if (err->code != PS_ERR_BAD_PARAMETER_TYPE) {
-        psLogMsg(__func__,PS_LOG_ERROR,"error message was not appropriate type.");
-        return 21;
-    }
-    psFree(err);
-
-    psFree(image);
-    psFree(result);
-    psFree(invImage);
-
-    return 0;
-}
-
Index: trunk/psLib/test/image/tst_psImagePixelExtract.c
===================================================================
--- trunk/psLib/test/image/tst_psImagePixelExtract.c	(revision 3973)
+++ trunk/psLib/test/image/tst_psImagePixelExtract.c	(revision 3973)
@@ -0,0 +1,759 @@
+/** @file  tst_psImageExtraction.c
+*
+*  @brief Contains the tests for psImageExtraction.[ch]
+*
+*
+*  @author Robert DeSonia, MHPCC
+*
+*  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-05-19 02:49:40 $
+*
+*  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
+*/
+#include<stdlib.h>
+#include<string.h>
+
+#include "psTest.h"
+#include "pslib_strict.h"
+#include "psType.h"
+
+static psS32 testImageSlice(void);
+static psS32 testImageCut(void);
+static psS32 testImageRadialCut(void);
+
+
+testDescription tests[] = {
+                              {testImageSlice, 552, "psImageSlice", 0, false},
+                              {testImageCut, 555, "psImageCut", 0, false},
+                              {testImageRadialCut, 557, "psImageRadialCut", 0, false},
+                              {NULL}
+                          };
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    return ! runTestSuite( stderr, "psImage", tests, argc, argv );
+}
+
+psS32 testImageSlice(void)
+{
+    const psS32 r = 200;
+    const psS32 c = 300;
+    const psS32 m = r / 2 -1;
+    const psS32 n = r / 4 -1;
+    psVector* out = NULL;
+    psImage* image;
+    psVector* positions = psVectorAlloc( r, PS_TYPE_U32 );
+    psImage* mask = psImageAlloc( c, r, PS_TYPE_MASK );
+    psStats* stat = psStatsAlloc( PS_STAT_SAMPLE_MEDIAN );
+
+    /*
+        This function shall extract pixels from a specified region of a psImage
+        structure into a vector using a specified statistical method.
+
+        Verify the returned psVector structure contains expected data, if the
+        input psImage input has known data and the psStats structure specifies
+        a known statistical method. At least two different statistical methods
+        should be used within a valid range of psImage data. Allow for a delta
+        when comparing results to allow for testing a different platforms. Two
+        cases should be used for each possible direction. Data region cases
+        should include 0x0, 1x1, Nx1, 1xN, NxN, MxN
+
+     */
+
+    for ( psS32 row = 0;row < r;row++ ) {
+        psMaskType* maskRow = mask->data.PS_TYPE_MASK_DATA[row];
+        for ( psS32 col = 0;col < c;col++ ) {
+            maskRow[ col ] = 0;
+        }
+    }
+
+    #define PSIMAGESLICE_TEST1(TYPE,M,N,DIRECTION,TRUTH_SIZE,TRUTHPIX_X,TRUTHPIX_Y,TESTNUM) \
+    image = psImageAlloc( c, r, PS_TYPE_##TYPE ); \
+    for ( psS32 row = 0;row < r;row++ ) { \
+        ps##TYPE *imageRow = image->data.TYPE[ row ]; \
+        ps##TYPE rowOffset = row * 2; \
+        for ( psS32 col = 0;col < c;col++ ) { \
+            imageRow[ col ] = col + rowOffset; \
+        } \
+    } \
+    out = psImageSlice(out,positions,image,mask,1,c/10,r/10,c/10+M,r/10+N,DIRECTION,stat); \
+    \
+    if (out->n != TRUTH_SIZE) { \
+        psError(PS_ERR_UNKNOWN,true,"Number of results is wrong (%d, not %d)", \
+                out->n,n); \
+        return TESTNUM*4+1; \
+    } \
+    \
+    if (positions->n != TRUTH_SIZE) { \
+        psError(PS_ERR_UNKNOWN,true,"Number of results for positions vector is wrong (%d, not %d)", \
+                out->n,n); \
+        return TESTNUM*4+2; \
+    } \
+    \
+    for (psS32 i=0;i<out->n;i++) { \
+        if (fabs(out->data.F64[i]-image->data.TYPE[r/10+TRUTHPIX_Y][c/10+TRUTHPIX_X]) > 1.0/(psF64)r) { \
+            psError(PS_ERR_UNKNOWN,true,"Improper result at position %d.  Got %g, expected %g",i, \
+                    out->data.F64[i],image->data.TYPE[r/10+TRUTHPIX_Y][c/10+TRUTHPIX_X]); \
+            return TESTNUM*4+3; \
+        } \
+        if (DIRECTION == PS_CUT_X_POS || DIRECTION == PS_CUT_X_NEG) { \
+            if (positions->data.U32[i] != c/10+TRUTHPIX_X) { \
+                psError(PS_ERR_UNKNOWN,true,"Improper positions (%d vs %d) result @ %d.", \
+                        positions->data.U32[i],c/10+TRUTHPIX_X,i); \
+                return TESTNUM*4+4; \
+            } \
+        } else { \
+            if (positions->data.U32[i] != r/10+TRUTHPIX_Y) { \
+                psError(PS_ERR_UNKNOWN,true,"Improper positions (%d vs %d) result @ %d.", \
+                        positions->data.U32[i],r/10+TRUTHPIX_Y,i); \
+                return TESTNUM*4+4; \
+            } \
+        } \
+    } \
+    psFree(image);
+
+    #define PSIMAGESLICE_TEST(TYPE) \
+    /* test MxN case */ \
+    PSIMAGESLICE_TEST1(TYPE, m, n, PS_CUT_X_POS, m, i, n / 2, 0 ); \
+    PSIMAGESLICE_TEST1(TYPE, m, n, PS_CUT_X_NEG, m, m - 1 - i, n / 2, 1 ); \
+    PSIMAGESLICE_TEST1(TYPE, m, n, PS_CUT_Y_POS, n, m / 2, i, 2 ); \
+    PSIMAGESLICE_TEST1(TYPE, m, n, PS_CUT_Y_NEG, n, m / 2, n - 1 - i, 3 ); \
+    \
+    /* test Mx1 case */ \
+    PSIMAGESLICE_TEST1(TYPE, m, 1, PS_CUT_X_POS, m, i, 0, 4 ); \
+    PSIMAGESLICE_TEST1(TYPE, m, 1, PS_CUT_X_NEG, m, m - 1 - i, 0, 5 ); \
+    PSIMAGESLICE_TEST1(TYPE, m, 1, PS_CUT_Y_POS, 1, m / 2, 0, 6 ); \
+    PSIMAGESLICE_TEST1(TYPE, m, 1, PS_CUT_Y_NEG, 1, m / 2, 0, 7 ); \
+    \
+    /* test 1xN case */ \
+    PSIMAGESLICE_TEST1(TYPE, 1, n, PS_CUT_X_POS, 1, 0, n / 2, 8 ); \
+    PSIMAGESLICE_TEST1(TYPE, 1, n, PS_CUT_X_NEG, 1, 0, n / 2, 9 ); \
+    PSIMAGESLICE_TEST1(TYPE, 1, n, PS_CUT_Y_POS, n, 0, i, 10 ); \
+    PSIMAGESLICE_TEST1(TYPE, 1, n, PS_CUT_Y_NEG, n, 0, n - 1 - i, 11 ); \
+    \
+    /* test 1x1 case */ \
+    PSIMAGESLICE_TEST1(TYPE, 1, 1, PS_CUT_X_POS, 1, 0, 0, 12 ); \
+    PSIMAGESLICE_TEST1(TYPE, 1, 1, PS_CUT_X_NEG, 1, 0, 0, 13 ); \
+    PSIMAGESLICE_TEST1(TYPE, 1, 1, PS_CUT_Y_POS, 1, 0, 0, 14 ); \
+    PSIMAGESLICE_TEST1(TYPE, 1, 1, PS_CUT_Y_NEG, 1, 0, 0, 15 ); \
+
+    PSIMAGESLICE_TEST(F32);
+    PSIMAGESLICE_TEST(F64);
+    PSIMAGESLICE_TEST(U16);
+
+    image = psImageAlloc( c, r, PS_TYPE_F32 );
+
+    /*
+       Verify the returned psVector structure pointer is null and program
+       execution doesn't stop, if input psImage input is null.
+
+    */
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
+    out = psImageSlice( out,
+                        NULL, NULL,
+                        NULL, 0,
+                        c/10, r/10,
+                        c/10 + 1, r/10 + 1,
+                        PS_CUT_X_POS,
+                        stat );
+    if ( out != NULL ) {
+        psError( PS_ERR_UNKNOWN,true, "Giving a NULL image, psImageSlice didn't return NULL as expected" );
+        return 101;
+    }
+
+
+    /*
+       Verify the returned psVector structure pointer is null and program
+       execution doesn't stop, if input psStats stats is null.
+    */
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
+    out = psImageSlice( out,
+                        NULL, image,
+                        mask, 1,
+                        c/10, r/10,
+                        c/10 + 1,
+                        r/10 + 1,
+                        PS_CUT_X_POS,
+                        NULL );
+    if ( out != NULL ) {
+        psError( PS_ERR_UNKNOWN,true, "Giving a NULL stat struct, psImageSlice didn't return NULL as expected" );
+        return 102;
+    }
+    /*
+
+       Verify the returned psVector structure pointer is null and program
+       executions doesn't stop, if the input direction is not set to one of
+       the two valid values.
+    */
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
+    out = psImageSlice( out, NULL,
+                        image,
+                        mask, 1,
+                        c/10, r/10,
+                        c/10+1, r/10+1,
+                        5,
+                        stat);
+    if ( out != NULL ) {
+        psError( PS_ERR_UNKNOWN,true, "Giving a bogus direction flag, psImageSlice didn't return NULL as expected" );
+        return 103;
+    }
+
+    /*
+       Verify the returned psVector structure pointer is null and program
+       execution doesn't stop, if the input nrow and/or ncol are zero.
+    */
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
+    out = psImageSlice( out,
+                        NULL,
+                        image,
+                        mask, 1,
+                        c/10, r/10,
+                        c/10, r/10,
+                        PS_CUT_X_POS,
+                        stat );
+    if ( out != NULL ) {
+        psError( PS_ERR_UNKNOWN,true, "Giving a 0x0 region, psImageSlice didn't return NULL as expected" );
+        return 104;
+    }
+
+    /*
+       Verify the returned psVector structure pointer is null and program
+       execution doesn't stop, if the inputs row, col, nrow, ncol specify a
+       regions of data that is not within the input psImage structure.
+    */
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
+    out = psImageSlice( out, NULL,
+                        image,
+                        mask, 1,
+                        c+1, r/10,
+                        c+2, r/10+10,
+                        PS_CUT_X_POS,
+                        stat );
+    if ( out != NULL ) {
+        psError( PS_ERR_UNKNOWN,true, "Giving an invalid x position, psImageSlice didn't return NULL as expected" );
+        return 105;
+    }
+
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
+    out = psImageSlice( out, NULL,
+                        image,
+                        mask, 1,
+                        c/10, r+1,
+                        c/10+1,r+5,
+                        PS_CUT_X_POS,
+                        stat );
+    if ( out != NULL ) {
+        psError( PS_ERR_UNKNOWN,true, "Giving an invalid y position, psImageSlice didn't return NULL as expected" );
+        return 106;
+    }
+
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
+    out = psImageSlice( out, NULL,
+                        image,
+                        mask, 1,
+                        c/10, r/10,
+                        c+1, r/10+1,
+                        PS_CUT_X_POS,
+                        stat);
+    if ( out != NULL ) {
+        psError( PS_ERR_UNKNOWN,true, "Giving an invalid numCols, psImageSlice didn't return NULL as expected" );
+        return 107;
+    }
+
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
+    out = psImageSlice( out, NULL,
+                        image,
+                        mask, 1,
+                        c/10, r/10,
+                        c/10+1, r + 1,
+                        PS_CUT_X_POS,
+                        stat);
+    if ( out != NULL ) {
+        psError( PS_ERR_UNKNOWN,true, "Giving an invalid numRows, psImageSlice didn't return NULL as expected" );
+        return 108;
+    }
+
+    /*
+       Verify the returned psVector structure pointer is null and program
+       execution doesn't stop, if the input psStat structure member options is
+       zero which indicates no statistic method specified.
+    */
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
+    stat->options = 0;
+    out = psImageSlice( out, NULL,
+                        image,
+                        mask, 1,
+                        c/10, r/10,
+                        c/10+1, r/10+1,
+                        PS_CUT_X_POS,
+                        stat);
+    if ( out != NULL ) {
+        psError( PS_ERR_UNKNOWN,true, "Giving an invalid numRows, psImageSlice didn't return NULL as expected" );
+        return 109;
+    }
+
+    /* Verify that a mask of different size than the input image returns null and program
+       execution doesn't stop.
+    */
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error mask size != image size.");
+    stat->options = PS_STAT_SAMPLE_MEDIAN;
+    psImage* maskSz = psImageAlloc( r, c, PS_TYPE_MASK );
+    out = psImageSlice( out, NULL,
+                        image,
+                        maskSz, 1,
+                        c/10, r/10,
+                        c/10+1, r/10+1,
+                        PS_CUT_X_POS,
+                        stat);
+    if ( out != NULL ) {
+        psError( PS_ERR_UNKNOWN,true, "Mask size different than image size didn't return NULL as expected" );
+        return 110;
+    }
+
+    /* Verify the a invalid type mask returns null and program execution doesn't stop.
+    */
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error invalid mask type.");
+    psImage* maskS8 = psImageAlloc( c, r, PS_TYPE_S8 );
+    out =  psImageSlice( out, NULL,
+                         image,
+                         maskS8, 1,
+                         c/10, r/10,
+                         c/10+1, r/10+1,
+                         PS_CUT_X_POS,
+                         stat);
+    if ( out != NULL ) {
+        psError( PS_ERR_UNKNOWN,true, "Mask invalid type didn't return NULL as expected.");
+        return 111;
+    }
+
+    psFree( image );
+    psFree( positions );
+    psFree( mask );
+    psFree( out );
+    psFree( stat );
+    psFree( maskS8 );
+    psFree( maskSz );
+
+    return 0;
+
+}
+
+static psS32 testImageCut(void)
+{
+    psS32 c = 300;
+    psS32 r = 200;
+    psS32 numPoints = 15;
+    float startCol[] = { 40,150, 40,  0,280, 40,280, -1,300, 20, 20, 20, 20, 20, 20};
+    float endCol[] =   {240,150,240,299, 40,240, 40,240,240, -1,300,240,240,240,240};
+    float startRow[] = { 20, 10,100,  0, 20,180,180, 10, 10, 10, 10, -1,200, 10, 10};
+    float endRow[] =   {160,180,100,199,160, 10, 10,180,180,180,180,180,180, -1,200};
+    psBool success[] = {true,true,true,true,true,true,true,false,false,false,false,false,false,false,false};
+    psU32 length = 100;
+
+    psImage* image = psImageAlloc(c,r,PS_TYPE_F32);
+    psImage* mask = psImageAlloc(c,r,PS_TYPE_MASK);
+    for (psS32 row = 0; row < image->numRows; row++) {
+        for (psS32 col = 0; col < image->numCols; col++) {
+            image->data.F32[row][col] = (psF32)col + (psF32)row/1000.0f;
+            if ((row & 0x0F) == 0) {
+                mask->data.PS_TYPE_MASK_DATA[row][col] = 1;
+            } else {
+                mask->data.PS_TYPE_MASK_DATA[row][col] = 0;
+            }
+        }
+    }
+    psVector* rows = psVectorAlloc(length,PS_TYPE_F32);
+    psVector* cols = psVectorAlloc(length,PS_TYPE_F32);
+
+    psVector* result = NULL;
+    for (psS32 n = 0; n < numPoints; n++) {
+        psVector* orig = result;
+        if (! success[n]) {
+            psLogMsg(__func__,PS_LOG_INFO,"The following should be an error.");
+        }
+        if (n == 1) {
+            result = psImageCut(result,
+                                cols,rows,
+                                image,
+                                NULL,0,
+                                startCol[n], startRow[n],
+                                endCol[n], endRow[n],
+                                length,
+                                PS_INTERPOLATE_FLAT);
+        } else {
+            result = psImageCut(result,
+                                cols,rows,
+                                image,
+                                mask,1,
+                                startCol[n], startRow[n],
+                                endCol[n], endRow[n],
+                                length,
+                                PS_INTERPOLATE_FLAT);
+        }
+
+        if (success[n]) {
+            if (result == NULL) {
+                psLogMsg(__func__,PS_LOG_ERROR,
+                         "psImageCut returned NULL instead of a valid result.");
+                return n*10+1;
+            }
+
+            if (orig != NULL && orig != result) {
+                psLogMsg(__func__,PS_LOG_ERROR,
+                         "psImageCut didn't recycle the out parameter properly.");
+                return n*10+2;
+            }
+
+            float deltaRow = (endRow[n]-startRow[n])/(length-1);
+            float deltaCol = (endCol[n]-startCol[n])/(length-1);
+            psF32 truth;
+            for (psS32 i = 0; i < length; i++) {
+                float x = (float)startCol[n]+(float)i*deltaCol;
+                float y = (float)startRow[n]+(float)i*deltaRow;
+                if (n == 1) {
+                    truth = psImagePixelInterpolate( image, x, y,
+                                                     NULL,0,0,PS_INTERPOLATE_FLAT);
+                } else {
+                    truth = psImagePixelInterpolate( image, x, y,
+                                                     mask,1,0,PS_INTERPOLATE_FLAT);
+                }
+                if (fabs(result->data.F32[i]-truth) > FLT_EPSILON) {
+                    psLogMsg(__func__,PS_LOG_ERROR,
+                             "Bad result in position %d; Found %g but expected %g.",
+                             i, result->data.F32[i], truth);
+                    return n*10+5;
+                }
+                if (fabsf(x - cols->data.F32[i]) > FLT_EPSILON ||
+                        fabsf(y - rows->data.F32[i]) > FLT_EPSILON) {
+                    psLogMsg(__func__,PS_LOG_ERROR,
+                             "Bad resulting col/row at index %d; Found (%g,%g) but expected (%g,%g).",
+                             i, cols->data.F32[i], rows->data.F32[i], x, y);
+                    return n*10+6;
+                }
+            }
+        } else {
+            if (result != NULL) {
+                psLogMsg(__func__,PS_LOG_ERROR,
+                         "psImageCut did not return NULL with a cut of (%g,%g)->(%g,%g).",
+                         startCol[n],startRow[n],endCol[n],endRow[n]);
+                return n*10+7;
+            }
+            psErr* err = psErrorLast();
+            if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+                psLogMsg(__func__,PS_LOG_ERROR,
+                         "psImageCut did not generate proper error message.");
+                return 105;
+            }
+            psFree(err);
+        }
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error (NULL image).");
+    result = psImageCut(result,
+                        cols,rows,
+                        NULL,
+                        mask,1,
+                        startCol[0], startRow[0],
+                        endCol[0], endRow[0],
+                        length,
+                        PS_INTERPOLATE_FLAT);
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageCut did not return NULL given NULL image.");
+        return 100;
+    }
+    psErr* err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageCut did not generate proper error message given NULL image.");
+        return 101;
+    }
+    psFree(err);
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error (length=0).");
+    result = psImageCut(result,
+                        cols,rows,
+                        image,
+                        mask,1,
+                        startCol[0], startRow[0],
+                        endCol[0], endRow[0],
+                        0,
+                        PS_INTERPOLATE_FLAT);
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageCut did not return NULL given length=0.");
+        return 102;
+    }
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageCut did not generate proper error message given length=0.");
+        return 103;
+    }
+    psFree(err);
+
+    psFree(result);
+    psFree(image);
+    psFree(mask);
+    psFree(rows);
+    psFree(cols);
+
+    return 0;
+}
+
+static psS32 testImageRadialCut(void)
+{
+    psS32 c = 300;
+    psS32 r = 200;
+    psS32 centerX = c/2;
+    psS32 centerY = r/2;
+    psErr* err = NULL;
+
+    psImage* image = psImageAlloc(c,r,PS_TYPE_F32);
+    psImage* mask = psImageAlloc(c,r,PS_TYPE_MASK);
+    for (psS32 row = 0; row < image->numRows; row++) {
+        for (psS32 col = 0; col < image->numCols; col++) {
+            image->data.F32[row][col] = sqrtf((col-centerX)*(col-centerX)+(row-centerY)*(row-centerY));
+            if ((row & 0x0F) == 0) {
+                mask->data.PS_TYPE_MASK_DATA[row][col] = 1;
+            } else {
+                mask->data.PS_TYPE_MASK_DATA[row][col] = 0;
+            }
+        }
+    }
+
+    psStats* stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    psVector* radii = psVectorAlloc(10,PS_TYPE_F32);
+    for (psS32 i=0; i < 10; i++) {
+        radii->data.F32[i] = 10+i*10;
+    }
+
+    psVector* result = NULL;
+
+    result = psImageRadialCut(result,image,mask,1,centerX,centerY,radii,stat);
+
+    if (result == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value of NULL unexpected.");
+        return 1;
+    }
+
+    if (result->type.type != PS_TYPE_F64) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return type not psF64, as expected.");
+        return 2;
+    }
+
+    for (psS32 i=0; i < 9; i++) {
+        if (fabs(result->data.F64[i] - (15.0+i*10)) > 1) {
+            psLogMsg(__func__,PS_LOG_ERROR,
+                     "Result was not as expected for radii #%d (%g, expected %d +/- 1)",
+                     result->data.F64[i], (15.0+i*10) );
+            return 3+i;
+        }
+    }
+
+    // again, but without mask
+    psVector* orig = result;
+    result = psImageRadialCut(result,image,NULL,1,centerX,centerY,radii,stat);
+
+    if (result == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value of NULL unexpected.");
+        return 12;
+    }
+
+    if (result != orig) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value of is not same as input parameter 'out'.");
+        return 13;
+    }
+
+    for (psS32 i=0; i < 9; i++) {
+        if (fabs(result->data.F64[i] - (15.0+i*10)) > 1) {
+            psLogMsg(__func__,PS_LOG_ERROR,
+                     "Result was not as expected for radii #%d (%g, expected %d +/- 1)",
+                     result->data.F64[i], (15.0+i*10) );
+            return 14+i;
+        }
+    }
+
+    // NULL input image...
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+    result = psImageRadialCut(result,NULL,NULL,1,centerX,centerY,radii,stat);
+
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not NULL as expected.");
+        return 23;
+    }
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageRadialCut did not generate proper error message.");
+        return 24;
+    }
+    psFree(err);
+
+    // NULL input radii...
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+    result = psImageRadialCut(result,image,mask,1,centerX,centerY,NULL,stat);
+
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not NULL as expected.");
+        return 23;
+    }
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageRadialCut did not generate proper error message.");
+        return 24;
+    }
+    psFree(err);
+
+    // NULL input stat...
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+    result = psImageRadialCut(result,image,mask,1,centerX,centerY,radii,NULL);
+
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not NULL as expected.");
+        return 23;
+    }
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageRadialCut did not generate proper error message.");
+        return 24;
+    }
+    psFree(err);
+
+    // Bad center X
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+    result = psImageRadialCut(result,image,mask,1,
+                              c+1,centerY,radii,stat);
+
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not NULL as expected.");
+        return 25;
+    }
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageRadialCut did not generate proper error message.");
+        return 26;
+    }
+    psFree(err);
+
+    // Bad center Y
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+    result = psImageRadialCut(result,image,mask,1,
+                              centerX,r+1,radii,stat);
+
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not NULL as expected.");
+        return 27;
+    }
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageRadialCut did not generate proper error message.");
+        return 28;
+    }
+    psFree(err);
+
+    // Bad mask type (N.B., swapped image/mask to do this)
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+    result = psImageRadialCut(result,mask,image,1,
+                              centerX,r+1,radii,stat);
+
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not NULL as expected.");
+        return 29;
+    }
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_TYPE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageRadialCut did not generate proper error message.");
+        return 30;
+    }
+    psFree(err);
+
+    // Bad mask size
+    psImage* mask2 = psImageAlloc(c/2,r/2,PS_TYPE_MASK);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+    result = psImageRadialCut(result,image, mask2, 1,
+                              centerX,centerY,radii,stat);
+    psFree(mask2);
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not NULL as expected.");
+        return 31;
+    }
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_SIZE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageRadialCut did not generate proper error message.");
+        return 32;
+    }
+    psFree(err);
+
+    // Bad radii size
+    psVector* radii2 = psVectorAlloc(1,PS_TYPE_MASK);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+    result = psImageRadialCut(result,image, mask, 1,
+                              centerX,centerY,radii2,stat);
+    psFree(radii2);
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not NULL as expected.");
+        return 33;
+    }
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_SIZE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageRadialCut did not generate proper error message.");
+        return 34;
+    }
+    psFree(err);
+
+    // bad input stat option...
+    stat->options = 0;
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+    result = psImageRadialCut(result,image,mask,1,centerX,centerY,radii,stat);
+    stat->options = PS_STAT_SAMPLE_MEAN;
+
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not NULL as expected.");
+        return 35;
+    }
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageRadialCut did not generate proper error message.");
+        return 36;
+    }
+    psFree(err);
+
+    psFree(image);
+    psFree(mask);
+    psFree(radii);
+    psFree(stat);
+    psFree(result);
+
+    return 0;
+}
Index: trunk/psLib/test/image/tst_psImagePixelManip.c
===================================================================
--- trunk/psLib/test/image/tst_psImagePixelManip.c	(revision 3973)
+++ trunk/psLib/test/image/tst_psImagePixelManip.c	(revision 3973)
@@ -0,0 +1,797 @@
+/** @file  tst_psImageManip.c
+ *
+ *  @brief Contains the tests for psImageManip.[ch]
+ *
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-05-19 02:49:40 $
+ *
+ *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <complex.h>
+#include <math.h>
+#include <float.h>
+#include <string.h>
+#include <stdlib.h>
+#include <string.h>                    // for memset
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "psTest.h"
+#include "pslib_strict.h"
+#include "psType.h"
+
+static psS32 testImageClip(void);
+static psS32 testImageClipNAN(void);
+static psS32 testImageClipComplexRegion(void);
+static psS32 testImageOverlay(void);
+
+testDescription tests[] = {
+                              {testImageClip,571,"psImageClip",0,false},
+                              {testImageClipNAN,572,"psImageClipNAN",0,false},
+                              {testImageClipComplexRegion,673,"psImageClipComplexRegion",0,false},
+                              {testImageOverlay,573,"psImageOverlay",0,false},
+                              {NULL}
+                          };
+
+psS32 main(psS32 argc, char* argv[])
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    return ! runTestSuite(stderr,"psImage",tests,argc,argv);
+}
+
+
+psS32 testImageClip(void)
+{
+    psImage* img = NULL;
+    psU32 c = 128;
+    psU32 r = 256;
+    psF64 min;
+    psF64 max;
+    psS32 numClipped = 0;
+    psS32 retVal;
+
+    psLogMsg(__func__,PS_LOG_INFO,
+             "psImageClip shall limit the minimum and maximum data value within a psImage structure");
+
+    /*
+
+        psImageClip shall limit the minimum and maximum data value within a
+        psImage structure to a specified min and max value.
+
+        Verify the returned integer is equal to the number of pixels clipped,
+        if the input psImage structure contains known values and input parameters
+        min and max have know values.
+
+        Verify the psImage structure specified by the input parameter input is
+        modified to contain the expected values, if the input psImage structure
+        contains known values, min and max are specified and vmin and vmax
+        parameters are known.
+
+        Verify the retuned integer is zero, psImage structure input is unmodified
+        and program executions doesn't stop, if input parameter psImage structure
+        pointer is null.
+
+        Verify the retuned integer is zero, psImage structure input is unmodified
+        and program executions doesn't stop, if input parameter min is larger than max.
+    */
+
+    // create image
+    #define testImageClipByType(datatype) \
+    img = psImageAlloc(c,r,PS_TYPE_##datatype); \
+    for (psU32 row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (psU32 col=0;col<c;col++) { \
+            imgRow[col] = (ps##datatype)(row+col); \
+        } \
+    } \
+    min = (psF64)r/2.0; \
+    max = (psF64)r; \
+    \
+    retVal = psImageClip(img,min,(double)PS_MIN_##datatype,max,(double)PS_MAX_##datatype); \
+    \
+    numClipped = 0; \
+    for (psU32 row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (psU32 col=0;col<c;col++) { \
+            ps##datatype value = (ps##datatype)(row+col); \
+            if (value < min) { \
+                numClipped++; \
+                value = PS_MIN_##datatype; \
+            } else if (value > max) { \
+                numClipped++; \
+                value = PS_MAX_##datatype; \
+            } \
+            if (fabsf(imgRow[col]-value) > FLT_EPSILON) { \
+                psError(PS_ERR_UNKNOWN, true,"Pixel value is not as expected (%g vs %g) at %u,%u", \
+                        (psF64)imgRow[col],(psF64)value,col,row); \
+                return 1; \
+            } \
+        } \
+    } \
+    if (retVal != numClipped) { \
+        psError(PS_ERR_UNKNOWN, true,"Expected %d clips, but got %d", \
+                numClipped,retVal); \
+        return 2; \
+    } \
+    psFree(img);
+
+    #define testImageClipByComplexType(datatype) \
+    img = psImageAlloc(c,r,PS_TYPE_##datatype); \
+    for (psU32 row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (psU32 col=0;col<c;col++) { \
+            imgRow[col] = (ps##datatype)(row+I*col); \
+        } \
+    } \
+    min = (float)r/2.0f; \
+    max = (float)r; \
+    \
+    retVal = psImageClip(img,min,-1.0f,max,-2.0f); \
+    \
+    numClipped = 0; \
+    for (psU32 row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (psU32 col=0;col<c;col++) { \
+            ps##datatype value = row+I*col; \
+            if (cabs(value) < min) { \
+                numClipped++; \
+                value = -1.0f; \
+            } else if (cabs(value) > max) { \
+                numClipped++; \
+                value = -2.0f; \
+            } \
+            if (fabsf(creal(imgRow[col])-creal(value)) > FLT_EPSILON || \
+                    fabsf(cimag(imgRow[col])-cimag(value)) > FLT_EPSILON) { \
+                psError(PS_ERR_UNKNOWN, true,"Pixel value is not as expected (%.2f+%.2fi vs %.2f+%.2fi) at %u,%u", \
+                        creal(imgRow[col]),cimag(imgRow[col]),creal(value),cimag(value),col,row); \
+                return 1; \
+            } \
+        } \
+    } \
+    if (retVal != numClipped) { \
+        psError(PS_ERR_UNKNOWN, true,"Expected %d clips, but got %d", \
+                numClipped,retVal); \
+        return 2; \
+    } \
+    psFree(img);
+
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of F64 imagery");
+    testImageClipByType(F64);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of F32 imagery");
+    testImageClipByType(F32);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of S32 imagery");
+    testImageClipByType(S32);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of S16 imagery");
+    testImageClipByType(S16);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of S8 imagery");
+    testImageClipByType(S8);
+    //    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of U32 imagery");
+    //    testImageClipByType(U32);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of U16 imagery");
+    testImageClipByType(U16);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of U8 imagery");
+    testImageClipByType(U8);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of C32 imagery");
+    testImageClipByComplexType(C32);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of C64 imagery");
+    testImageClipByComplexType(C64);
+
+    // Verify the retuned integer is zero, psImage structure input is unmodified
+    // and program executions doesn't stop, if input parameter psImage structure
+    // pointer is null.
+    retVal = psImageClip(NULL,min,-1.0f,max,-2.0f);
+    if (retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"Expected zero return for clips of a NULL image.");
+        return 3;
+    }
+
+    // Verify the retuned integer is zero, psImage structure input is unmodified
+    // and program executions doesn't stop, if input parameter min is larger than max.
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error (max<min)");
+    retVal = psImageClip(img,max,-1.0f,min,-2.0f);
+    if (retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"Expected zero return for clips when max < min.");
+        return 4;
+    }
+
+    return 0;
+}
+
+psS32 testImageClipNAN(void)
+{
+    psImage* img = NULL;
+    psU32 c = 128;
+    psU32 r = 256;
+    psS32 numClipped = 0;
+    psS32 retVal;
+
+    psLogMsg(__func__,PS_LOG_INFO,
+             "psImageClipNaN shall modified pixel values of NaN with a specified value");
+
+    /*
+        psImageClipNaN shall modify a psImage structure with pixel values set
+        to NaN to a value specified as an input parameter.
+
+        Verify the returned integer is equal to the number of pixels modified
+        and the psImage is modified at locations where NaN pixels where
+        located to the value specified in the input parameter value.
+
+        Verify the returned integer is zero and program execution doesn't stop,
+        if the input parameter psImage structure pointer is null.
+    */
+
+    // create image
+    #define testImageClipNaNByType(datatype) \
+    img = psImageAlloc(c,r,PS_TYPE_##datatype); \
+    for (unsigned row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (unsigned col=0;col<c;col++) { \
+            if (row == col) { \
+                imgRow[col] = NAN; \
+            } else if (row+1 == col) { \
+                imgRow[col] = INFINITY; \
+            } else { \
+                imgRow[col] = (ps##datatype)(row+col); \
+            } \
+        } \
+    } \
+    \
+    retVal = psImageClipNaN(img,-1.0f); \
+    \
+    numClipped = 0; \
+    for (unsigned row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (unsigned col=0;col<c;col++) { \
+            ps##datatype value = (ps##datatype)(row+col); \
+            if ( (row == col) || (row+1 == col) ) { \
+                numClipped++; \
+                value = -1.0; \
+            } \
+            if (fabsf(imgRow[col]-value) > FLT_EPSILON) { \
+                psError(PS_ERR_UNKNOWN, true,"Pixel value is not as expected (%f vs %f) at %d,%d", \
+                        imgRow[col],value,col,row); \
+                return 1; \
+            } \
+        } \
+    } \
+    if (retVal != numClipped) { \
+        psError(PS_ERR_UNKNOWN, true,"Expected %d clips, but got %d", \
+                numClipped,retVal); \
+        return 2; \
+    } \
+    psFree(img);
+
+    testImageClipNaNByType(F32);
+    testImageClipNaNByType(F64);
+    testImageClipNaNByType(C32);
+    testImageClipNaNByType(C64);
+
+    // Verify the retuned integer is zero, psImage structure input is unmodified
+    // and program executions doesn't stop, if input parameter psImage structure
+    // pointer is null.
+    retVal = psImageClipNaN(NULL,-1.0f);
+    if (retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"Expected zero return for clips of a NULL image.");
+        return 3;
+    }
+
+    // Verify program execution doesn't stop if the input image type is something
+    // other than F32, F64, C32, C64.
+    img = psImageAlloc(c,r,PS_TYPE_S32);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error (invalid type)");
+    retVal = psImageClipNaN(img,2.0f);
+    if (retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"Expected zero return for clip of invalid image type.");
+        return 4;
+    }
+    psFree(img);
+
+    return 0;
+}
+
+psS32 testImageClipComplexRegion(void)
+{
+    psImage* img = NULL;
+    psU32 c = 1024;
+    psU32 r = 2048;
+    psS32 numClipped = 0;
+    psS32 retVal;
+
+    psLogMsg(__func__,PS_LOG_INFO,
+             "psImageClipNaN shall modified pixel values of NaN with a specified value");
+
+    /*
+    1. Create a complex image with a wide range of complex values
+
+    2. call psImageClipComplexRegion with min and max where there is at least
+       2 pixels in the image above) that is:
+        a) real(p) < real(min) && complex(p) < complex(min),
+        b) real(p) < real(min) && complex(min) < complex(p) < complex(max)
+        c) real(min) < real(p) < real(max) && complex(p) < complex(min)
+        d) real(min) < real(p) < real(max) && complex(min) < complex(p) < complex(max)
+        e) real(p) > real(max) && complex(min) < complex(p) < complex(max)
+        f) real(pmin) < real(p) < real(max) && complex(p) > complex(max)
+        g) real(p) > real(max) && complex(p) > complex(max)
+        h) real(p) < real(min) && complex(p) > complex(max)
+        i) real(p) > real(max) && complex(p) < complex(min)
+
+    3. verify that All pixels in case (a), (b), and (c) have the value vmin
+
+    4. verify that all pixels in case (d) are unchanged from input
+
+    5. verify that all pixels in case (e), (f), (g), (h), and (i) have the
+       value vmax
+
+    */
+
+    #define testImageClipComplexByType(datatype,MIN,MAX) /* datatype must be complex */ \
+    /* create image */ \
+    img = psImageAlloc(c,r,PS_TYPE_##datatype); \
+    for (unsigned row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (unsigned col=0;col<c;col++) { \
+            imgRow[col] = row+I*col; \
+        } \
+    } \
+    \
+    retVal = psImageClipComplexRegion(img,MIN,-1.0-1.0*I,MAX,-2.0-2.0*I); \
+    \
+    numClipped = 0; \
+    for (unsigned row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (unsigned col=0;col<c;col++) { \
+            ps##datatype value = (ps##datatype)(row+I*col); \
+            if ( (row > creal(MAX)) || (col > cimag(MAX)) ) { \
+                numClipped++; \
+                value = -2.0-2.0*I; \
+            } else if ((row < creal(MIN)) || (col < cimag(MIN)) ) { \
+                numClipped++; \
+                value = -1.0-1.0*I; \
+            } \
+            if (cabs(imgRow[col]-value) > FLT_EPSILON) { \
+                psError(PS_ERR_UNKNOWN, true,"Pixel value is not as expected (%g%+gi vs %g%+gi) at %d,%d", \
+                        creal(imgRow[col]),cimag(imgRow[col]),creal(value),cimag(value),col,row); \
+                return 1; \
+            } \
+        } \
+    } \
+    if (retVal != numClipped) { \
+        psError(PS_ERR_UNKNOWN, true,"Expected %d clips, but got %d", \
+                numClipped,retVal); \
+        return 2; \
+    } \
+    psFree(img);
+
+    complex double min = ((double)r)/5.0+I*((double)c)/4.0;
+    complex double max = ((double)r)/3.0+I*((double)c)/2.0;
+
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping at %g%+gi to %g%+gi for psC32",
+             creal(min),cimag(min),creal(max),cimag(max));
+
+    testImageClipComplexByType(C32,min,max);
+
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping at %g%+gi to %g%+gi for psC64",
+             creal(min),cimag(min),creal(max),cimag(max));
+    testImageClipComplexByType(C64,min,max);
+
+    //  6. Call psImageClipComplexRegion with NULL input parameter; should error
+    //     but not stop execution.
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(NULL,0,0,0,0);
+    if (retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"Expected zero return for clips of a NULL image.");
+        return 3;
+    }
+
+
+    img = psImageAlloc(c,r,PS_TYPE_C32);
+    for (unsigned row=0;row<r;row++) {
+        psC32* imgRow = img->data.C32[row];
+        for (unsigned col=0;col<c;col++) {
+            imgRow[col] = row+I*col;
+        }
+    }
+
+    //  7. Call psImageClipComplexRegion with min > max; should error and return 0,
+    //     but not stop execution
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(img,10.0+I*1.0,-1.0,5.0+5.0*I,-2.0);
+    if (retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"Expected zero return for creal(min)>creal(max).");
+        return 3;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(img,1.0+I*10.0,-1.0,5.0+5.0*I,-2.0);
+    if (retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"Expected zero return for cimag(min)>cimag(max).");
+        return 3;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(img,10.0+I*10.0,-1.0,5.0+5.0*I,-2.0);
+    if (retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"Expected zero return for min>max.");
+        return 3;
+    }
+
+    //  8. Call psImageClipComplexRegion with the follow vmin/vmax values; each
+    //     should error and return 0, but not stop execution
+    //      a) vmin < datatype region's minimum
+    //      b) vmax < datatype region's minimum
+    //      c) vmin > datatype region's maximum
+    //      d) vmax > datatype region's maximum
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(img,
+                                      1.0+I*1.0,
+                                      -2.0*(double)FLT_MAX,
+                                      5.0+5.0*I,
+                                      0.0);
+    if (retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"Expected zero return for vmin not in datatype range.");
+        return 80;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(img,
+                                      1.0+I*1.0,
+                                      2.0*(double)FLT_MAX,
+                                      5.0+5.0*I,
+                                      0.0);
+    if (retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"Expected zero return for vmin not in datatype range.");
+        return 81;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(img,
+                                      1.0+I*1.0,
+                                      -2.0*(double)FLT_MAX*I,
+                                      5.0+5.0*I,
+                                      0.0);
+    if (retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"Expected zero return for vmin not in datatype range.");
+        return 82;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(img,
+                                      1.0+I*1.0,
+                                      2.0*(double)FLT_MAX*I,
+                                      5.0+5.0*I,
+                                      0.0);
+    if (retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"Expected zero return for vmin not in datatype range.");
+        return 83;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(img,
+                                      1.0+I*1.0,
+                                      0.0,
+                                      5.0+5.0*I,
+                                      -2.0*(double)FLT_MAX);
+    if (retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"Expected zero return for vmax not in datatype range.");
+        return 84;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(img,
+                                      1.0+I*1.0,
+                                      0.0,
+                                      5.0+5.0*I,
+                                      2.0*(double)FLT_MAX);
+    if (retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"Expected zero return for vmax not in datatype range.");
+        return 85;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(img,
+                                      1.0+I*1.0,
+                                      0.0,
+                                      5.0+5.0*I,
+                                      -2.0*(double)FLT_MAX*I);
+    if (retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"Expected zero return for vmax not in datatype range.");
+        return 87;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(img,
+                                      1.0+I*1.0,
+                                      0.0,
+                                      5.0+5.0*I,
+                                      2.0*(double)FLT_MAX*I);
+    if (retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"Expected zero return for vmax not in datatype range.");
+        return 88;
+    }
+
+
+    // now check if vmin > vmax is OK
+    for (unsigned row=0;row<r;row++) {
+        psC32* imgRow = img->data.C32[row];
+        for (unsigned col=0;col<c;col++) {
+            imgRow[col] = row+I*col;
+        }
+    }
+    retVal = psImageClipComplexRegion(img,
+                                      1.0+I*1.0,
+                                      10.0,
+                                      5.0+5.0*I,
+                                      0.0);
+    if (retVal == 0) {
+        psError(PS_ERR_UNKNOWN, true,"Didn't expect zero return for vmin > vmax.");
+        return 83;
+    }
+
+
+    psFree(img);
+    img = NULL;
+
+    //  9. Call psImageClipComplexRegion with the max value out of datatype's
+    //     range; should clip as expected (see step 1-5). Repeat with min value
+    //     out of datatype's range.
+
+    testImageClipComplexByType(C32,-(double)FLT_MAX*2.0-I*(double)FLT_MAX*2.0,10.0+I*10.0);
+    testImageClipComplexByType(C32,10.0+I*10.0,(double)FLT_MAX*2.0+I*(double)FLT_MAX*2.0);
+
+    // Verify program execution doesn't stop if the input image type is something
+    // other than C32, C64.
+    img = psImageAlloc(c,r,PS_TYPE_S32);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error (invalid type)");
+    retVal = psImageClipComplexRegion(img,2.0,10.0,5.0,0.0);
+    if (retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"Expected zero return for clip of invalid image type.");
+        return 84;
+    }
+    psFree(img);
+
+    return 0;
+}
+
+psS32 testImageOverlay(void)
+{
+
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    psImage* img3 = NULL;
+    psImage* img4 = NULL;
+    psU32 c = 128;
+    psU32 r = 256;
+    psS32 retVal;
+
+    /*
+    psImageSectionOverlay shall modified pixel values in a psImage structure to
+    be equal to the value of the originaldata and an overlay image with a
+    specified operation. Valid operations include =, +, -, *, /.
+
+    Verify the returned integer is zero
+    and the input parameter psImage structure is modified at the specified
+    location and range with the given overlay image and the specified
+    function. Cases should include all the valid operations. Comparison of
+    expected values should include a delta to allow for testing on
+    different platforms.
+
+    */
+
+    #define testOverlayTypeOP(DATATYPE,OP,OPSTRING) \
+    img = psImageAlloc(c,r,PS_TYPE_##DATATYPE); \
+    for (unsigned row=0;row<r;row++) { \
+        ps##DATATYPE* imgRow = img->data.DATATYPE[row]; \
+        for (unsigned col=0;col<c;col++) { \
+            imgRow[col] = 6.0; \
+        } \
+    } \
+    img2 = psImageAlloc(c/2,r/2,PS_TYPE_##DATATYPE); \
+    for (unsigned row=0;row<r/2;row++) { \
+        ps##DATATYPE* img2Row = img2->data.DATATYPE[row]; \
+        for (unsigned col=0;col<c/2;col++) { \
+            img2Row[col] = 2.0; \
+        } \
+    } \
+    retVal = psImageOverlaySection(img,img2,c/4,r/4,OPSTRING); \
+    if (retVal == 0) { \
+        psError(PS_ERR_UNKNOWN, true,"psImageOverlaySection returned zero with %s op", \
+                OPSTRING); \
+        return 1; \
+    } \
+    for (unsigned row=0;row<r;row++) { \
+        ps##DATATYPE* imgRow = img->data.DATATYPE[row]; \
+        ps##DATATYPE* img2Row = img2->data.DATATYPE[row]; \
+        for (unsigned col=0;col<c;col++) { \
+            ps##DATATYPE val = 6.0; \
+            if ( ! (row < r/4 || row >= r/2+r/4 || col < c/4 || col >= c/2+c/4)) { \
+                val OP 2.0; \
+            } \
+            if (fabsf(imgRow[col] - val) > FLT_EPSILON) { \
+                psError(PS_ERR_UNKNOWN, true,"Value incorrect at %d,%d (%.2f vs %.2f for %s)", \
+                        col,row,imgRow[col],val,OPSTRING); \
+                return 2; \
+            } \
+            if (row < r/2 && col < c/2 && fabsf(img2Row[col] - 2.0) > FLT_EPSILON) { \
+                psError(PS_ERR_UNKNOWN, true,"Overlay modified at %d,%d (%.2f for %s)", \
+                        col,row,img2Row[col],OPSTRING); \
+                return 2; \
+            } \
+        } \
+    } \
+    psFree(img); \
+    psFree(img2);
+
+    #define testOverlayType(DATATYPE) \
+    testOverlayTypeOP(DATATYPE,+=,"+"); \
+    testOverlayTypeOP(DATATYPE,-=,"-"); \
+    testOverlayTypeOP(DATATYPE,*=,"*");\
+    testOverlayTypeOP(DATATYPE,/=,"/");\
+    testOverlayTypeOP(DATATYPE,=,"=");
+
+    testOverlayType(C64);
+    testOverlayType(C32);
+    testOverlayType(F64);
+    testOverlayType(F32);
+    testOverlayType(S16);
+    testOverlayType(S8);
+    testOverlayType(U16);
+    testOverlayType(U8);
+
+    /*
+    Verify the returned integer is equal to non-zero and the input psImage structure
+    is unmodified, if the overlay specified is not within the data range of the
+    input psImage structure.
+    */
+
+    img = psImageAlloc(c,r,PS_TYPE_F32);
+    for (unsigned row=0;row<r;row++) {
+        psF32* imgRow = img->data.F32[row];
+        for (unsigned col=0;col<c;col++) {
+            imgRow[col] = 6.0f;
+        }
+    }
+    img2 = psImageAlloc(c,r,PS_TYPE_F32);
+    for (unsigned row=0;row<r;row++) {
+        psF32* img2Row = img2->data.F32[row];
+        for (unsigned col=0;col<c;col++) {
+            img2Row[col] = 2.0f;
+        }
+    }
+    img3 = psImageAlloc(c,r,PS_TYPE_S64);
+    for (unsigned row=0;row<r;row++) {
+        psS64* img3Row = img3->data.S64[row];
+        for (unsigned col=0;col<c;col++) {
+            img3Row[col] = 6.0f;
+        }
+    }
+    img4 = psImageAlloc(c,r,PS_TYPE_S64);
+    for (unsigned row=0;row<r;row++) {
+        psS64* img4Row = img4->data.S64[row];
+        for (unsigned col=0;col<c;col++) {
+            img4Row[col] = 2.0f;
+        }
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error as overlay isn't "
+             "within image boundaries");
+    retVal = psImageOverlaySection(img,img2,c/4,r/4,"+");
+    if (retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"psImageOverlaySection did not return "
+                "zero even though overlay too big");
+        return 3;
+    }
+    for (unsigned row=0;row<r;row++) {
+        psF32* imgRow = img->data.F32[row];
+        for (unsigned col=0;col<c;col++) {
+            if (imgRow[col] != 6.0f) {
+                psError(PS_ERR_UNKNOWN, true,"Input image modified when overlay size too big");
+                return 4;
+            }
+        }
+    }
+
+    /*
+    Verify the returned integer is equal to non-zero, the input psImage
+    structure is unmodified and program execution doesn't stop, if the
+    overlay specified is null.
+    */
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error as overlay is NULL");
+    retVal = psImageOverlaySection(img,NULL,c/4,r/4,"+");
+    if (retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"psImageOverlaySection did not return "
+                "zero even though overlay too big");
+        return 5;
+    }
+    for (unsigned row=0;row<r;row++) {
+        psF32* imgRow = img->data.F32[row];
+        for (unsigned col=0;col<c;col++) {
+            if (imgRow[col] != 6.0f) {
+                psError(PS_ERR_UNKNOWN, true,"Input image modified when overlay NULL");
+                return 6;
+            }
+        }
+    }
+
+    /*
+    Verify the returned integer is equal to non-zero and program execution
+    doesn't stop, if the input parameter image is null.
+    */
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error as image input is NULL");
+    retVal = psImageOverlaySection(NULL,img2,c/4,r/4,"+");
+    if (retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"psImageOverlaySection returned non-zero even though "
+                "overlay too big");
+        return 7;
+    }
+
+    /*
+    Verify the return integer is equal to non-zero and program execution
+    doesn't stop, if the specified operator is not =,+,-,*,/
+    */
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error as operator is invalid");
+    retVal = psImageOverlaySection(img,img2,0,0,"$");
+    if (retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"psImageOverlaySection returned non-zero even though "
+                "overlay operator is invalid");
+        return 8;
+    }
+
+    /*
+    Verify the return integer is equal to non-zero and program execution
+    doesn't stop, if the specified operator is NULL
+    */
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error as operator is invalid");
+    retVal = psImageOverlaySection(img,img2,0,0,NULL);
+    if(retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"psImageOverlaySection returned non-zero even though "
+                "overlay operator is NULL");
+        return 9;
+    }
+
+    /*
+    Verify the return integer is equal to non-zero and program execution
+    doesn't stop, if overlay image is a different type than the input image
+    */
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error as overlay is "
+             "a different type");
+    retVal = psImageOverlaySection(img,img3,0,0,"+");
+    if(retVal != 0) {
+        psError(PS_ERR_UNKNOWN, true,"psImageOverlaySection returned nonzero eventhough "
+                " overlay image type is different than input image.");
+        return 10;
+    }
+
+    /*
+    Verify program execution doen't stop, if the overly image contains
+    zero values with division operation is specified.
+    */
+    for (unsigned row=0;row<r;row++) {
+        psF32* img2Row = img2->data.F32[row];
+        for (unsigned col=0;col<c;col++) {
+            img2Row[col] = 0.0f;
+        }
+    }
+    retVal = psImageOverlaySection(img,img2,0,0,"/");
+    if (retVal == 0) {
+        psError(PS_ERR_UNKNOWN, true,"psImageOverlaySection returned zero when "
+                "checking divide-by-zero.");
+        return 12;
+    }
+
+    psFree(img);
+    psFree(img2);
+    psFree(img3);
+    psFree(img4);
+
+    return 0;
+}
Index: trunk/psLib/test/image/tst_psImageStats.c
===================================================================
--- trunk/psLib/test/image/tst_psImageStats.c	(revision 3941)
+++ trunk/psLib/test/image/tst_psImageStats.c	(revision 3973)
@@ -2,5 +2,5 @@
 *  C Implementation: %{MODULE}
 *
-* Description: 
+* Description:
 *
 *
@@ -113,10 +113,14 @@
             tmpImage2 = psImageAlloc( IMAGE_X_SIZE*2, IMAGE_Y_SIZE*2, PS_TYPE_F32 );
             tmpMask2 = psImageAlloc( IMAGE_X_SIZE*2, IMAGE_Y_SIZE*2, PS_TYPE_U8 );
-            tmpImage = psImageSubset(tmpImage2,
-                                     IMAGE_X_SIZE/4, IMAGE_Y_SIZE/4,
-                                     IMAGE_X_SIZE/4+IMAGE_X_SIZE, IMAGE_Y_SIZE/4+IMAGE_Y_SIZE);
-            tmpMask= psImageSubset(tmpMask2,
-                                   IMAGE_X_SIZE/4, IMAGE_Y_SIZE/4,
-                                   IMAGE_X_SIZE/4+IMAGE_X_SIZE, IMAGE_Y_SIZE/4+IMAGE_Y_SIZE);
+            tmpImage = psImageSubset(tmpImage2, (psRegion) {
+                                         IMAGE_X_SIZE/4, IMAGE_Y_SIZE/4,
+                                         IMAGE_X_SIZE/4+IMAGE_X_SIZE, IMAGE_Y_SIZE/4+IMAGE_Y_SIZE
+                                     }
+                                    );
+            tmpMask= psImageSubset(tmpMask2,(psRegion) {
+                                       IMAGE_X_SIZE/4, IMAGE_Y_SIZE/4,
+                                       IMAGE_X_SIZE/4+IMAGE_X_SIZE, IMAGE_Y_SIZE/4+IMAGE_Y_SIZE
+                                   }
+                                  );
         }
 
@@ -287,10 +291,14 @@
             tmpImage2 = psImageAlloc( IMAGE_X_SIZE*2, IMAGE_Y_SIZE*2, PS_TYPE_F32 );
             tmpMask2 = psImageAlloc( IMAGE_X_SIZE*2, IMAGE_Y_SIZE*2, PS_TYPE_U8 );
-            tmpImage = psImageSubset(tmpImage2,
-                                     IMAGE_X_SIZE/4, IMAGE_Y_SIZE/4,
-                                     IMAGE_X_SIZE/4+IMAGE_X_SIZE, IMAGE_Y_SIZE/4+IMAGE_Y_SIZE);
-            tmpMask = psImageSubset(tmpMask2,
-                                    IMAGE_X_SIZE/4, IMAGE_Y_SIZE/4,
-                                    IMAGE_X_SIZE/4+IMAGE_X_SIZE, IMAGE_Y_SIZE/4+IMAGE_Y_SIZE);
+            tmpImage = psImageSubset(tmpImage2,(psRegion) {
+                                         IMAGE_X_SIZE/4, IMAGE_Y_SIZE/4,
+                                         IMAGE_X_SIZE/4+IMAGE_X_SIZE, IMAGE_Y_SIZE/4+IMAGE_Y_SIZE
+                                     }
+                                    );
+            tmpMask = psImageSubset(tmpMask2,(psRegion) {
+                                        IMAGE_X_SIZE/4, IMAGE_Y_SIZE/4,
+                                        IMAGE_X_SIZE/4+IMAGE_X_SIZE, IMAGE_Y_SIZE/4+IMAGE_Y_SIZE
+                                    }
+                                   );
         }
 
Index: trunk/psLib/test/image/tst_psImageStructManip.c
===================================================================
--- trunk/psLib/test/image/tst_psImageStructManip.c	(revision 3973)
+++ trunk/psLib/test/image/tst_psImageStructManip.c	(revision 3973)
@@ -0,0 +1,745 @@
+/** @file  tst_psImageExtraction.c
+*
+*  @brief Contains the tests for psImageExtraction.[ch]
+*
+*
+*  @author Robert DeSonia, MHPCC
+*
+*  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-05-19 02:49:40 $
+*
+*  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
+*/
+#include<stdlib.h>
+#include<string.h>
+
+#include "psTest.h"
+#include "pslib_strict.h"
+#include "psType.h"
+
+static psS32 testImageSubset(void);
+static psS32 testImageSubsection(void);
+static psS32 testImageTrim(void);
+
+
+testDescription tests[] = {
+                              {testImageSubset,547,"psImageSubset",0,false},
+                              {testImageSubset,550,"psImageSubset",0,true},
+                              {testImageSubsection,730,"psImageSubsection",0,false},
+                              {testImageTrim, 744, "psImageTrim", 0, false},
+                              {NULL}
+                          };
+
+psS32 main( psS32 argc, char* argv[] )
+{
+    return ! runTestSuite( stderr, "psImage", tests, argc, argv );
+}
+
+// #547: psImageSubset shall create child image of a specified size from a parent psImage structure
+psS32 testImageSubset(void)
+{
+    psImage preSubsetStruct;
+    psImage* original;
+    psImage* subset1 = NULL;
+    psImage* subset2 = NULL;
+    psImage* subset3 = NULL;
+    psS32 c = 128;
+    psS32 r = 256;
+    psRegion region1 = {0,0,c/2,r/2};
+    psRegion region2 = {c/4,r/4,c/4+c/2,r/4+r/2};
+
+    original = psImageAlloc(c,r,PS_TYPE_U32);
+    for (psS32 row=0;row<r;row++) {
+        for (psS32 col=0;col<c;col++) {
+            original->data.F32[row][col] = row*1000+col;
+        }
+    }
+
+    memcpy(&preSubsetStruct,original,sizeof(psImage));
+
+    subset2 = psImageSubset(original,region2);
+
+    subset3 = psImageSubset(original,region1);
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure members nrow and ncol are equal to "
+             "the input parameter nrow and ncol respectively.");
+
+    if (subset2->numCols != c/2 || subset2->numRows != r/2) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubset output size was not proper(%dx%d, should be %dx%d).",
+                subset2->numCols, subset2->numRows, c/2,r/2);
+        return 1;
+    }
+
+    if (subset3->numCols != c/2 || subset3->numRows != r/2) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubset output size was not proper(%dx%d, should be %dx%d).",
+                subset3->numCols, subset3->numRows, c/2,r/2);
+        return 2;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure contains expected values in the "
+             "row member, if the input psImage structure image contains known values.");
+
+    for (psS32 row=0;row<r/2;row++) {
+        for (psS32 col=0;col<c/2;col++) {
+            if (subset2->data.U32[row][col] != original->data.U32[row+r/4][col+c/4]) {
+                psError(PS_ERR_UNKNOWN,true,"psImageSubset output #1 was wrong at %dx%d (%d vs %d).",
+                        row,col,subset2->data.U32[row][col], original->data.U32[row+r/4][col+c/4]);
+                return 3;
+            }
+            if (subset3->data.U32[row][col] != original->data.U32[row][col]) {
+                psError(PS_ERR_UNKNOWN,true,"psImageSubset output #1 was wrong at %dx%d (%d vs %d).",
+                        row,col,subset2->data.U32[row][col], original->data.U32[row][col]);
+                return 4;
+            }
+        }
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure member type is equal to the input "
+             "psImage structure member type.");
+
+    if (subset2->type.type != PS_TYPE_U32) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubset output type was not proper(%d, should be %d).",
+                subset2->type.type, PS_TYPE_U32);
+        return 6;
+    }
+    if (subset3->type.type != PS_TYPE_U32) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubset output type was not proper(%d, should be %d).",
+                subset3->type.type, PS_TYPE_U32);
+        return 7;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure members row0 and col0 are equal to "
+             "the input parameters row0 and col0 respectively.");
+
+    if (subset2->col0 != c/4 || subset2->row0 != r/4) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't set col0/row0 for subset2 (%d/%d, should be %d/%d).",
+                subset2->col0,subset2->row0,c/4,r/4);
+        return 8;
+    }
+    if (subset3->col0 != 0 || subset3->row0 != 0) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't set col0/row0 for subset3 (%d/%d, should be %d/%d).",
+                subset3->col0,subset3->row0,0,0);
+        return 9;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure member parent is equal to the "
+             "input psImage structure pointer image.");
+
+    if (subset2->parent != original || subset3->parent != original) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't set parent.");
+        return 10;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure member children is null.");
+
+    if (subset2->children != NULL || subset3->children != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't set children to NULL.");
+        return 11;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the input psImage structure image only has the following members "
+             "changed: 1) Nchildren is increased by one. 2) parent contains pointer psImage structure "
+             "out at parent[Nchildren-1].");
+
+    if (original->children == NULL || original->children->n != 2) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't increment number of children by one per subset.");
+        return 12;
+    }
+    if (original->children->data[0] != subset2 || original->children->data[1] != subset3) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't properly store the children pointers.");
+        return 13;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure pointer is null and program "
+             "execution doesn't stop, if the input parameter image is null. Also verified the input "
+             "psImage structure is not modified.");
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(NULL,region1);
+    if (subset1 != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't return NULL when input image was NULL.");
+        return 14;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure pointer is null and program "
+             " execution doesn't stop, if the input parameters nrow and/or ncol are zero. Also verify "
+             "input psImage structure is not modified.");
+
+    memcpy(&preSubsetStruct,original,sizeof(psImage));
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(original,(psRegion) {
+                                0,r/2,c/2,r/2
+                            }
+                           );
+    if (subset1 != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't return NULL when numRows=0.");
+        return 15;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(original,(psRegion) {
+                                c/2,0,c/2,r/2
+                            }
+                           );
+    if (subset1 != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't return NULL when numCols=0.");
+        return 16;
+    }
+    if (memcmp(original,&preSubsetStruct,sizeof(psImage)) != 0) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubset changed the original struct though it failed to subset.");
+        return 17;
+    }
+
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure pointer is null and program "
+             "execution doesn't stop, if the input parameters row0 and col0 are not within the range of "
+             "values of psImage structure image.");
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(original,(psRegion) {
+                                0,0,c/2,r*2
+                            }
+                           );
+    if (subset1 != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't return NULL when subset origin was outside of "
+                "image (via cols).");
+        return 18;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(original,(psRegion) {
+                                0,0,c*2,r/2
+                            }
+                           );
+    if (subset1 != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't return NULL when subset origin was outside of "
+                "image (via rows).");
+        return 19;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(original,(psRegion) {
+                                -1,0,c/2,r/2
+                            }
+                           );
+    if (subset1 != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't return NULL when subset origin was outside of "
+                "image (col0=-1).");
+        return 20;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(original,(psRegion) {
+                                0,-1,c/2,r/2
+                            }
+                           );
+    if (subset1 != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't return NULL when subset origin was outside of "
+                "image (row0=-1).");
+        return 21;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure pointer is null and program "
+             "execution doesn't stop if the input parameters nrow, ncol, row0 and col0 specify a range of "
+             "data not within the input psImage structure image.  Also verify the input psImage structure "
+             "is not modified.");
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(original,(psRegion) {
+                                0,0,c/2,r+1
+                            }
+                           );
+    if (subset1 != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't return NULL when subset was outside of image (via rows).");
+        return 22;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(original,(psRegion) {
+                                0,0,c+1,r/2
+                            }
+                           );
+    if (subset1 != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't return NULL when subset was outside of image (via cols).");
+        return 23;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(original,(psRegion) {
+                                0,0,c+1,r+1
+                            }
+                           );
+    if (subset1 != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubset didn't return NULL when subset was outside of image (via row+cols).");
+        return 24;
+    }
+
+    psLogMsg(__func__, PS_LOG_INFO, "psImageFreeChildren shall deallocate any children images of a "
+             "psImage structure");
+
+    memcpy(&preSubsetStruct,original,sizeof(psImage));
+
+    psImageFreeChildren(original);
+
+    // Verify the returned psImage structure member Nchildren is set to zero.
+    if (original->children != NULL && original->children->n > 0) {
+        psError(PS_ERR_UNKNOWN,true,"psImageFreeChildren didn't set number of children to zero.");
+        return 25;
+    }
+
+    //Verify the returned psImage structure members type, nrow, ncol, row0, col0, rows and parent are not
+    // modified.
+    if (preSubsetStruct.numRows != original->numRows ||
+            preSubsetStruct.numCols != original->numCols ||
+            preSubsetStruct.row0 != original->row0 ||
+            preSubsetStruct.col0 != original->col0) {
+
+        psError(PS_ERR_UNKNOWN,true,"psImageFreeChildren modified parent's non-children elements.");
+        return 27;
+    }
+
+    psFree(original);
+
+    return 0;
+}
+
+// #730: psImageSubsection shall create child image of a specified size from a parent psImage structure
+psS32 testImageSubsection(void)
+{
+    psImage* original;
+    psImage* subset;
+    psS32 c = 128;
+    psS32 r = 256;
+    psS32 i;
+    psS32 numRegions = 4;
+    psS32 x1[] = {  0, 32, 64, 32};
+    psS32 x2[] = { 32, 64,127, 64};
+    psS32 y1[] = {  0, 32, 32,128};
+    psS32 y2[] = { 32, 64, 64,255};
+
+    original = psImageAlloc(c,r,PS_TYPE_U32);
+    for (psS32 row=0;row<r;row++) {
+        for (psS32 col=0;col<c;col++) {
+            original->data.F32[row][col] = row*1000+col;
+        }
+    }
+
+    for (i=0; i<numRegions; i++) {
+        char sectionStr[64];
+        sprintf(sectionStr,"[%d:%d,%d:%d]",x1[i],x2[i],y1[i],y2[i]);
+
+        psLogMsg(__func__,PS_LOG_INFO,"Testing subsection %s.",
+                 sectionStr);
+
+        subset = psImageSubsection(original,sectionStr);
+
+        if (subset == NULL) {
+            psError(PS_ERR_UNKNOWN,true,"psImageSubsection returned a NULL with a subset of %s.",
+                    sectionStr);
+            return 10*i+1;
+        }
+
+        if (subset->type.type != PS_TYPE_U32) {
+            psError(PS_ERR_UNKNOWN,true,"psImageSubsection output type was not proper(%d, should be %d).",
+                    subset->type.type, PS_TYPE_U32);
+            return 10*i+2;
+        }
+
+        if (subset->col0 != x1[i] || subset->row0 != y1[i]) {
+            psError(PS_ERR_UNKNOWN,true,"psImageSubsection didn't set properly col0/row0 (%d/%d, should be %d/%d).",
+                    subset->col0,subset->row0,x1[i],y1[i]);
+            return 10*i+3;
+        }
+
+        if (subset->parent != original) {
+            psError(PS_ERR_UNKNOWN,true,"psImageSubsection didn't set parent.");
+            return 10*i+4;
+        }
+
+        if (subset->children != NULL) {
+            psError(PS_ERR_UNKNOWN,true,"psImageSubsection didn't set children to NULL.");
+            return 10*i+5;
+        }
+
+        if (original->children == NULL || original->children->n != i+1) {
+            psError(PS_ERR_UNKNOWN,true,"psImageSubsection didn't increment number of children by one per subset.");
+            return 10*i+6;
+        }
+
+
+        if (original->children->data[i] != subset) {
+            psError(PS_ERR_UNKNOWN,true,"psImageSubsection didn't properly store the children pointer.");
+            return 10*i+7;
+        }
+
+        psS32 numCols = x2[i]-x1[i]+1;
+        psS32 numRows = y2[i]-y1[i]+1;
+        if (subset->numCols != numCols || subset->numRows != numRows) {
+            psError(PS_ERR_UNKNOWN,true,"psImageSubsection output size was not proper(%dx%d, should be %dx%d).",
+                    subset->numCols, subset->numRows, numCols, numRows);
+            return 10*i+8;
+        }
+
+        for (psS32 row=0;row<numRows;row++) {
+            for (psS32 col=0;col<numCols;col++) {
+                if (subset->data.U32[row][col] != original->data.U32[row+y1[i]][col+x1[i]]) {
+                    psError(PS_ERR_UNKNOWN,true,"psImageSubset output #1 was wrong at %dx%d (%d vs %d).",
+                            row,col,subset->data.U32[row][col], original->data.U32[row+y1[i]][col+x1[i]]);
+                    return 10*i+9;
+                }
+            }
+        }
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (x1>x2)");
+    subset = psImageSubsection(original,"[64:32,32:64]");
+    if (subset != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubsection didn't return NULL when x1 > x2.");
+        return 10*i+10;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (y1>y2)");
+    subset = psImageSubsection(original,"[32:64,64:32]");
+    if (subset != NULL) {
+        psError(PS_ERR_UNKNOWN,true,"psImageSubsection didn't return NULL when y1 > y2.");
+        return 10*i+11;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (x2>nCols)");
+    subset = psImageSubsection(original,"[64:256,32:64]"); // assumes c<256
+    if (subset != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psImageSubsection didn't return NULL when x2 > c.");
+        return 10*i+12;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (y2>=nRows)");
+    subset = psImageSubsection(original,"[32:64,64:256]"); // assumes r==256
+    if (subset != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psImageSubsection didn't return NULL when y2 > r.");
+        return 10*i+13;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (malformed string - no brackets)");
+    subset = psImageSubsection(original,"32:64,32:64");
+    if (subset != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psImageSubsection didn't return NULL when subsection was '32:64,32:64'.");
+        return 10*i+14;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (malformed string - no colons)");
+    subset = psImageSubsection(original,"[32-64,32-64]");
+    if (subset != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psImageSubsection didn't return NULL when subsection was '[32-64,32-64]'.");
+        return 10*i+15;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (malformed string - not four numbers)");
+    subset = psImageSubsection(original,"[32:64,32]");
+    if (subset != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psImageSubsection didn't return NULL when subsection was '[32:64,32]'.");
+        return 10*i+16;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (image is NULL)");
+    subset = psImageSubsection(NULL,"[32:64,32:64]");
+    if (subset != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psImageSubsection didn't return NULL when image was NULL.");
+        return 10*i+17;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (subsection string is NULL)");
+    subset = psImageSubsection(original,NULL);
+    if (subset != NULL) {
+        psError(PS_ERR_UNKNOWN, true,"psImageSubsection didn't return NULL when subsection was NULL.");
+        return 10*i+18;
+    }
+
+    psFree(original);
+
+    return 0;
+}
+
+static psS32 testImageTrim(void)
+{
+    psS32 r = 200;
+    psS32 c = 300;
+    psS32 qtrR = r/4;
+    psS32 qtrC = c/4;
+    psS32 halfR = r/2;
+    psS32 halfC = c/2;
+    psRegion centerHalf = {qtrC,qtrR,qtrC+halfC,qtrR+halfR};
+
+    psImage* image = psImageAlloc(c,r,PS_TYPE_F32);
+    for (psS32 row = 0; row < image->numRows; row++) {
+        for (psS32 col = 0; col < image->numCols; col++) {
+            image->data.F32[row][col] = (psF32)col + (psF32)row/1000.0f;
+        }
+    }
+
+    /*
+        1. invoke psImageTrim with non-NULL image, and a valid region
+           x0,y0->x1,y1 (using only positive values). Verify that:
+            a. the return psImage is the same as the input psImage.
+            b. the size of the psImage is x1-x0 by y1-y0.
+            c. the pixel values coorespond to the region [x0:x1-1,y0:y1-1].
+    */
+    psImage* image1 = psImageCopy(NULL,image,PS_TYPE_F32);
+    psImage* image2 = psImageTrim(image1,centerHalf);
+
+    if (image1 != image2) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not same as input value.  Not done in-place?");
+        return 1;
+    }
+
+    if (image2->numCols != halfC ||
+            image2->numRows != halfR) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "The resulting image size was %dx%d, but should be %dx%d.",
+                 image2->numCols, image2->numRows,
+                 halfC, halfR);
+        return 2;
+    }
+
+    for (psS32 row = 0; row < image2->numRows; row++) {
+        for (psS32 col = 0; col < image2->numCols; col++) {
+            if (fabsf(image2->data.F32[row][col] - image->data.F32[row+qtrR][col+qtrC]) > FLT_EPSILON) {
+                psLogMsg(__func__,PS_LOG_ERROR,
+                         "The value at (%d,%d) was %g, but should be %g.",
+                         col,row,
+                         image2->data.F32[row][col],
+                         image->data.F32[row+qtrR][col+qtrC]);
+                return 3;
+            }
+        }
+    }
+
+    /*
+        2. invoke psImageTrim with non-NULL image and valid region where x1=0,
+           y1=0. Verify that:
+            a. the return psImage size is numCols-x0 by numRows-y0
+            b. the pixel values coorespond to the region
+               [x0:numCols-1,y0:numRows-1].
+    */
+    image1 = psImageCopy(image1,image,PS_TYPE_F32);
+    image2 = psImageTrim(image1,(psRegion) {
+                             qtrC,qtrR,0,0
+                         }
+                        );
+
+    if (image1 != image2) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not same as input value.  Not done in-place?");
+        return 11;
+    }
+
+    if (image2->numCols != image->numCols-qtrC ||
+            image2->numRows != image->numRows-qtrR) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "The resulting image size was %dx%d, but should be %dx%d.",
+                 image2->numCols, image2->numRows,
+                 image->numCols-qtrC, image->numRows-qtrR);
+        return 12;
+    }
+
+    for (psS32 row = 0; row < image2->numRows; row++) {
+        for (psS32 col = 0; col < image2->numCols; col++) {
+            if (fabsf(image2->data.F32[row][col] -
+                      image->data.F32[row+qtrR][col+qtrC]) > FLT_EPSILON) {
+                psLogMsg(__func__,PS_LOG_ERROR,
+                         "The value at (%d,%d) was %g, but should be %g.",
+                         col,row,
+                         image2->data.F32[row][col],
+                         image->data.F32[row+qtrR][col+qtrC]);
+                return 13;
+            }
+        }
+    }
+
+    /*
+        4. invoke psImageTrim with x1<0, y1<0. Verify:
+            a. the psImage size is (numCols+x1)-x0 by (numRows+y1)-y0.
+            b. the pixel values coorespond to the region
+               [x0:numCols+x1-1,y0:numRows+y1-1].
+
+    */
+    image1 = psImageCopy(image1,image,PS_TYPE_F32);
+    image2 = psImageTrim(image1,(psRegion) {
+                             qtrC,qtrR,-qtrC,-qtrR
+                         }
+                        );
+
+    if (image1 != image2) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not same as input value.  Not done in-place?");
+        return 21;
+    }
+
+    if (image2->numCols != image->numCols-qtrC-qtrC ||
+            image2->numRows != image->numRows-qtrR-qtrR) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "The resulting image size was %dx%d, but should be %dx%d.",
+                 image2->numCols, image2->numRows,
+                 image->numCols-qtrC, image->numRows-qtrR);
+        return 22;
+    }
+
+    for (psS32 row = 0; row < image2->numRows; row++) {
+        for (psS32 col = 0; col < image2->numCols; col++) {
+            if (fabsf(image2->data.F32[row][col] -
+                      image->data.F32[row+qtrR][col+qtrC]) > FLT_EPSILON) {
+                psLogMsg(__func__,PS_LOG_ERROR,
+                         "The value at (%d,%d) was %g, but should be %g.",
+                         col,row,
+                         image2->data.F32[row][col],
+                         image->data.F32[row+qtrR][col+qtrC]);
+                return 23;
+            }
+        }
+    }
+
+    psFree(image2);
+
+    /*
+        6. invoke psImageTrim with image=NULL Verify:
+            a. execution does not cease.
+            b. return value is NULL
+            c. appropriate error is generated.
+    */
+
+    image2 = psImageTrim(NULL,(psRegion) {
+                             qtrC,qtrR,0,0
+                         }
+                        );
+
+    if (image2 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not return NULL given a NULL input image.");
+        return 31;
+    }
+    psErr* err = psErrorLast();
+    if (err == NULL || err->code != PS_ERR_BAD_PARAMETER_NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not generate an appropriate error for NULL input image.");
+        psErrorStackPrint(stderr,"Error Stack:");
+        return 32;
+    }
+    psFree(err);
+
+    image1 = psImageCopy(NULL,image,PS_TYPE_F32);
+    image2 = psImageTrim(image1,(psRegion) {
+                             -1,0,0,0
+                         }
+                        );
+
+    if (image2 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not return NULL given x0=-1.");
+        return 33;
+    }
+    err = psErrorLast();
+    if (err == NULL || err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not generate an appropriate error for x0=-1.");
+        psErrorStackPrint(stderr,"Error Stack:");
+        return 34;
+    }
+    psFree(err);
+
+    image1 = psImageCopy(NULL,image,PS_TYPE_F32);
+    image2 = psImageTrim(image1,(psRegion) {
+                             0,-1,0,0
+                         }
+                        );
+
+    if (image2 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not return NULL given y0=-1.");
+        return 35;
+    }
+    err = psErrorLast();
+    if (err == NULL || err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not generate an appropriate error for y0=-1.");
+        psErrorStackPrint(stderr,"Error Stack:");
+        return 36;
+    }
+    psFree(err);
+
+    image1 = psImageCopy(NULL,image,PS_TYPE_F32);
+    image2 = psImageTrim(image1,(psRegion) {
+                             0,0,image->numCols+1,0
+                         }
+                        );
+
+    if (image2 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not return NULL given x1=numCols+1.");
+        return 37;
+    }
+    err = psErrorLast();
+    if (err == NULL || err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not generate an appropriate error for x1=numCols+1.");
+        psErrorStackPrint(stderr,"Error Stack:");
+        return 38;
+    }
+    psFree(err);
+
+    image1 = psImageCopy(NULL,image,PS_TYPE_F32);
+    image2 = psImageTrim(image1,(psRegion) {
+                             0,0,0,image->numRows+1
+                         }
+                        );
+
+    if (image2 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not return NULL given y1=numRows+1.");
+        return 39;
+    }
+    err = psErrorLast();
+    if (err == NULL || err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not generate an appropriate error for y1=numRows+1.");
+        psErrorStackPrint(stderr,"Error Stack:");
+        return 40;
+    }
+    psFree(err);
+
+    image1 = psImageCopy(NULL,image,PS_TYPE_F32);
+    image2 = psImageTrim(image1,(psRegion) {
+                             0,0,-image->numCols,0
+                         }
+                        );
+
+    if (image2 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not return NULL given x1=-numCols.");
+        return 41;
+    }
+    err = psErrorLast();
+    if (err == NULL || err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not generate an appropriate error for x1=-numCols.");
+        psErrorStackPrint(stderr,"Error Stack:");
+        return 42;
+    }
+    psFree(err);
+
+    image1 = psImageCopy(NULL,image,PS_TYPE_F32);
+    image2 = psImageTrim(image1,(psRegion) {
+                             0,0,0,-image->numRows
+                         }
+                        );
+
+    if (image2 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not return NULL given y1=-numRows.");
+        return 41;
+    }
+    err = psErrorLast();
+    if (err == NULL || err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not generate an appropriate error for y1=-numRows.");
+        psErrorStackPrint(stderr,"Error Stack:");
+        return 42;
+    }
+    psFree(err);
+
+    psFree(image);
+    return 0;
+}
