Index: trunk/psLib/test/image/tst_psImageManip.c
===================================================================
--- trunk/psLib/test/image/tst_psImageManip.c	(revision 1225)
+++ trunk/psLib/test/image/tst_psImageManip.c	(revision 1249)
@@ -6,6 +6,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-07-15 19:58:24 $
+ *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-07-21 23:38:27 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -27,4 +27,5 @@
 static int testImageRebin(void);
 static int testImageRoll(void);
+static int testImageRotate(void);
 
 testDescription tests[] = {
@@ -34,4 +35,5 @@
                               {testImageRebin,559,"psImageRebin",0,false},
                               {testImageRoll,562,"psImageRoll",0,false},
+                              {testImageRotate,560,"psImageRotate",0,false},
                               {NULL}
                           };
@@ -390,5 +392,6 @@
     }
 
-    psLogMsg(__func__,PS_LOG_INFO,"Following should error as overlay isn't within image boundaries");
+    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) {
@@ -470,5 +473,6 @@
 
     /*
-    This function shall generate a rescaled version of a psImage structure derived from a specified statistics method.
+    This function shall generate a rescaled version of a psImage structure 
+    derived from a specified statistics method.
     */
 
@@ -481,5 +485,10 @@
 
     /*
-    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.
+    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.
     */
 
@@ -518,5 +527,6 @@
 
     if (out->numRows != 4 || out->numCols != 4) {
-        psError(__func__,"psImageRebin didn't produce the proper size image (%d x %d).",
+        psError(__func__,"psImageRebin didn't produce the proper size image "
+                "(%d x %d).",
                 out->numCols, out->numRows);
         return 2;
@@ -528,5 +538,6 @@
         for (int col = 0; col<4; col++) {
             if (fabsf(outRow[col]-truthRow[col]) > FLT_EPSILON) {
-                psError(__func__,"psImageRebin didn't produce the proper result at (%d,%d) [%f vs %f].",
+                psError(__func__,"psImageRebin didn't produce the proper "
+                        "result at (%d,%d) [%f vs %f].",
                         col,row,outRow[col],truthRow[col]);
                 return 3;
@@ -538,5 +549,6 @@
     out2 = psImageRebin(out,in,3,&stats);
 
-    // Verify the returned psImage structure is equal to the input parameter out if specified.
+    // Verify the returned psImage structure is equal to the input parameter
+    // out if specified.
     if (out != out2) {
         psError(__func__,"psImageRebin didn't recycle a psImage properly!?");
@@ -550,5 +562,6 @@
 
     if (out->numRows != 6 || out->numCols != 6) {
-        psError(__func__,"psImageRebin didn't produce the proper size image (%d x %d).",
+        psError(__func__,"psImageRebin didn't produce the proper size image "
+                "(%d x %d).",
                 out->numCols, out->numRows);
         return 5;
@@ -560,5 +573,6 @@
         for (int col = 0; col<6; col++) {
             if (fabsf(outRow[col]-truthRow[col]) > FLT_EPSILON) {
-                psError(__func__,"psImageRebin didn't produce the proper result at (%d,%d) [%f vs %f].",
+                psError(__func__,"psImageRebin didn't produce the proper "
+                        "result at (%d,%d) [%f vs %f].",
                         col,row,outRow[col],truthRow[col]);
                 return 6;
@@ -573,5 +587,6 @@
 
     if (out2 != NULL) {
-        psError(__func__,"psImageRebin returned an image though the input was NULL!?");
+        psError(__func__,"psImageRebin returned an image though the input was "
+                "NULL!?");
         return 8;
     }
@@ -583,5 +598,6 @@
 
     if (out2 != NULL) {
-        psError(__func__,"psImageRebin returned an image though the scale was zero!?");
+        psError(__func__,"psImageRebin returned an image though the scale was "
+                "zero!?");
         return 9;
     }
@@ -593,5 +609,6 @@
 
     if (out2 != NULL) {
-        psError(__func__,"psImageRebin returned an image though the stats was NULL!?");
+        psError(__func__,"psImageRebin returned an image though the stats was "
+                "NULL!?");
         return 10;
     }
@@ -606,5 +623,6 @@
 
     if (out2 != NULL) {
-        psError(__func__,"psImageRebin returned an image though the stats options was zero!?");
+        psError(__func__,"psImageRebin returned an image though the stats "
+                "options was zero!?");
         return 11;
     }
@@ -615,5 +633,6 @@
 
     if (out2 != NULL) {
-        psError(__func__,"psImageRebin returned an image though the stats options was PS_STAT_USE_RANGE!?");
+        psError(__func__,"psImageRebin returned an image though the stats "
+                "options was PS_STAT_USE_RANGE!?");
         return 12;
     }
@@ -627,5 +646,6 @@
 
     if (out2 != NULL) {
-        psError(__func__,"psImageRebin returned an image though the stats options was PS_STAT_SAMPLE_MEAN+PS_STAT_MAX!?");
+        psError(__func__,"psImageRebin returned an image though the stats "
+                "options was PS_STAT_SAMPLE_MEAN+PS_STAT_MAX!?");
         return 13;
     }
@@ -792,2 +812,149 @@
     return 0;
 }
+
+int 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, 60, 90, 120, 180, 240, 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 TBD, if
+          the rotation and input psImage to not correspond to the output image.
+
+    */
+
+    psImage* fOut = NULL;
+    psImage* sOut = NULL;
+    psImage* fTruth = NULL;
+    psImage* sTruth = NULL;
+    int rows = 100;
+    int cols = 75;
+    psImage* fImg = psImageAlloc(cols,rows,PS_TYPE_F32);
+    psImage* sImg = psImageAlloc(cols,rows,PS_TYPE_S16);
+
+    for(int row=0;row<rows;row++) {
+        psF32* fRow = fImg->data.F32[row];
+        psS16* sRow = sImg->data.S16[row];
+        for (int 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
+    remove
+        ("temp/fOut.fits");
+    remove
+        ("temp/sOut.fits");
+    int index = 0;
+    bool fail = false;
+    for (int rot=-180;rot<=180;rot+=30) {
+        psImage* oldOut = fOut;
+        fOut = psImageRotate(fOut,fImg,rot,-1.0,PS_INTERPOLATE_FLAT);
+        // Verify the returned psImage structure is equal to the input
+        // parameter out if provided.
+        if (oldOut != NULL && oldOut != fOut) {
+            psError(__func__,"the output recycle functionality failed");
+            return 2;
+        }
+        sOut = psImageRotate(sOut,sImg,rot,-1.0,PS_INTERPOLATE_FLAT);
+        psImageWriteSection(fOut,0,0,0,NULL,index,"temp/fOut.fits");
+        psImageWriteSection(sOut,0,0,0,NULL,index,"temp/sOut.fits");
+
+        // now, let's compare this with the verified file
+        fTruth = psImageReadSection(fTruth,0,0,0,0,0,NULL,index,"verified/fOut.fits");
+        sTruth = psImageReadSection(sTruth,0,0,0,0,0,NULL,index,"verified/sOut.fits");
+
+        if (fTruth == NULL) {
+            psError(__func__,"verified psF32 image failed to be read (%d deg. rotation)",
+                    rot);
+            fail = true;
+        } else {
+            if (fTruth->numRows != fOut->numRows || fTruth->numCols != fOut->numCols) {
+                psError(__func__,"Rotated float image size did not match truth "
+                        "image for %d deg rotation.");
+                fail = true;
+            } else {
+                for (int row=0;row<fTruth->numRows;row++) {
+                    psF32* truthRow = fTruth->data.F32[row];
+                    psF32* outRow = fOut->data.F32[row];
+                    for (int col=0;col<fTruth->numCols;col++) {
+                        if (fabsf(truthRow[col]-outRow[col]) > FLT_EPSILON) {
+                            psError(__func__,"Float Image mismatch (%f vs %f) at %d,%d.",
+                                    outRow[col], truthRow[col],col,row);
+                            fail = true;
+                        }
+                    }
+                }
+            }
+        }
+
+        if (sTruth == NULL) {
+            psError(__func__,"verified psS16 image failed to be read "
+                    "(%d deg. rotation)",rot);
+            fail = true;
+        } else {
+            if (sTruth->numRows != sOut->numRows ||
+                    sTruth->numCols != sOut->numCols) {
+                psError(__func__,"Rotated short image size did not match truth "
+                        "image for %d deg rotation.");
+                fail = true;
+            } else {
+                for (int row=0;row<sTruth->numRows;row++) {
+                    psS16* truthRow = sTruth->data.S16[row];
+                    psS16* outRow = sOut->data.S16[row];
+                    for (int col=0;col<sTruth->numCols;col++) {
+                        if (fabsf(truthRow[col]-outRow[col]) > 1) {
+                            psError(__func__,"Short Image mismatch (%d vs %d) "
+                                    "at %d,%d.",
+                                    outRow[col], truthRow[col],col,row);
+                            fail = true;
+                        }
+                    }
+                }
+            }
+        }
+
+
+        index++;
+    }
+
+    if (fail) {
+        psError(__func__,"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(__func__,"NULL wasn't returned though the input image was NULL.");
+        return 3;
+    }
+
+    psFree(sOut);
+    psFree(fImg);
+    psFree(sImg);
+    psFree(fTruth);
+    psFree(sTruth);
+
+    return 0;
+}
