Index: trunk/psLib/src/imageops/psImageGeomManip.c
===================================================================
--- trunk/psLib/src/imageops/psImageGeomManip.c	(revision 6631)
+++ trunk/psLib/src/imageops/psImageGeomManip.c	(revision 6750)
@@ -10,6 +10,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.20 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-02-24 23:43:15 $
+ *  @version $Revision: 1.21 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-04-01 02:43:57 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -749,10 +749,17 @@
         col0 = region.x0;
         col1 = region.x1;
+        //If [0,0,0,0] specified, the whole image is to be included
+        if (row0 == 0 && col0 == 0 && row1 == 0 && col1 == 0) {
+            row0 = input->row0;
+            col0 = input->col0;
+            row1 = input->row0 + input->numRows;
+            col1 = input->col0 + input->numCols;
+        }
         if (col1 < 1) {
-            col1 += input->numCols;
+            col1 += input->col0 + input->numCols;
         }
 
         if (row1 < 1) {
-            row1 += input->numRows;
+            row1 += input->row0 + input->numRows;
         }
 
Index: trunk/psLib/src/imageops/psImageGeomManip.h
===================================================================
--- trunk/psLib/src/imageops/psImageGeomManip.h	(revision 6631)
+++ trunk/psLib/src/imageops/psImageGeomManip.h	(revision 6750)
@@ -8,6 +8,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-02-08 01:03:35 $
+ *  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-04-01 02:43:57 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -150,8 +150,9 @@
     const psPlaneTransform *outToIn,   ///< the transform to apply
     psRegion region,                   ///< the size of the transformed image
-    const psPixels* pixels,            /**< if not NULL, consists of psPixelCoords and specifies which pixels in
-                                                                                 *  output image shall be transformed; otherwise, entire image generated*/
+    const psPixels* pixels,            /**< if not NULL, consists of psPixelCoords and specifies
+                                            * which pixels in output image shall be transformed;
+                                            * otherwise, entire image generated*/
     psImageInterpolateMode mode,       ///< the interpolation scheme to be used
-    double exposedValue                   ///< Exposed value to which non-corresponding pixels are set
+    double exposedValue                ///< Exposed value to which non-corresponding pixels are set
 );
 
Index: trunk/psLib/src/imageops/psImagePixelExtract.c
===================================================================
--- trunk/psLib/src/imageops/psImagePixelExtract.c	(revision 6631)
+++ trunk/psLib/src/imageops/psImagePixelExtract.c	(revision 6750)
@@ -8,6 +8,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.13 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-03-17 20:38:19 $
+ *  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-04-01 02:43:57 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -57,15 +57,37 @@
         return NULL;
     }
-    PS_ASSERT_INT_NONNEGATIVE(input->col0, NULL);
-    PS_ASSERT_INT_NONNEGATIVE(input->row0, NULL);
-    PS_ASSERT_INT_POSITIVE(input->numCols, NULL);
-    PS_ASSERT_INT_POSITIVE(input->numRows, NULL);
+    if (input->col0 < 0) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "psImage input is invalid.  col0 cannot be negative.\n");
+        psFree(out);
+        return NULL;
+    }
+    if (input->row0 < 0) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "psImage input is invalid.  row0 cannot be negative.\n");
+        psFree(out);
+        return NULL;
+    }
+    if (input->numCols < 1) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "psImage input is invalid.  numCols must be greater than 0.\n");
+        psFree(out);
+        return NULL;
+    }
+    if (input->numRows < 1) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "psImage input is invalid.  numRows must be greater than 0.\n");
+        psFree(out);
+        return NULL;
+    }
     if (row >= (input->numRows + input->row0) ) {
         psError(PS_ERR_BAD_PARAMETER_NULL, true,
                 "Specified row number is out of range for specified image.\n");
+        psFree(out);
         return NULL;
     } else if ( row < input->row0 && row >= 0 ) {
         psError(PS_ERR_BAD_PARAMETER_VALUE, true,
                 "Specified row number is out of range for specified image.\n");
+        psFree(out);
         return NULL;
     } else if ( row < 0 ) {
@@ -74,4 +96,5 @@
             psError(PS_ERR_BAD_PARAMETER_VALUE, true,
                     "Specified row number is out of range for specified image.\n");
+            psFree(out);
             return NULL;
         }
@@ -164,15 +187,37 @@
         return NULL;
     }
-    PS_ASSERT_INT_NONNEGATIVE(input->col0, NULL);
-    PS_ASSERT_INT_NONNEGATIVE(input->row0, NULL);
-    PS_ASSERT_INT_POSITIVE(input->numCols, NULL);
-    PS_ASSERT_INT_POSITIVE(input->numRows, NULL);
+    if (input->col0 < 0) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "psImage input is invalid.  col0 cannot be negative.\n");
+        psFree(out);
+        return NULL;
+    }
+    if (input->row0 < 0) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "psImage input is invalid.  row0 cannot be negative.\n");
+        psFree(out);
+        return NULL;
+    }
+    if (input->numCols < 1) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "psImage input is invalid.  numCols must be greater than 0.\n");
+        psFree(out);
+        return NULL;
+    }
+    if (input->numRows < 1) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "psImage input is invalid.  numRows must be greater than 0.\n");
+        psFree(out);
+        return NULL;
+    }
     if (column >= (input->numCols + input->col0) ) {
         psError(PS_ERR_BAD_PARAMETER_NULL, true,
                 "Specified column number is out of range for specified image.\n");
+        psFree(out);
         return NULL;
     } else if ( column < input->col0 && column >= 0 ) {
         psError(PS_ERR_BAD_PARAMETER_VALUE, true,
                 "Specified column number is out of range for specified image.\n");
+        psFree(out);
         return NULL;
     } else if ( column < 0 ) {
@@ -181,4 +226,5 @@
             psError(PS_ERR_BAD_PARAMETER_VALUE, true,
                     "Specified column number is out of range for specified image.\n");
+            psFree(out);
             return NULL;
         }
@@ -263,17 +309,37 @@
         return NULL;
     }
-    PS_ASSERT_INT_NONNEGATIVE(input->col0, NULL);
-    PS_ASSERT_INT_NONNEGATIVE(input->row0, NULL);
-    PS_ASSERT_INT_POSITIVE(input->numCols, NULL);
-    PS_ASSERT_INT_POSITIVE(input->numRows, NULL);
+    if (input->col0 < 0) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "psImage input is invalid.  col0 cannot be negative.\n");
+        psFree(out);
+        return NULL;
+    }
+    if (input->row0 < 0) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "psImage input is invalid.  row0 cannot be negative.\n");
+        psFree(out);
+        return NULL;
+    }
+    if (input->numCols < 1) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "psImage input is invalid.  numCols must be greater than 0.\n");
+        psFree(out);
+        return NULL;
+    }
+    if (input->numRows < 1) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "psImage input is invalid.  numRows must be greater than 0.\n");
+        psFree(out);
+        return NULL;
+    }
     /*
         if (col1 < 1) {
             col1 += input->numCols;
         }
-     
+
         if (row1 < 1) {
             row1 += input->numRows;
         }
-     
+
         if (    col0 < 0 ||
                 row0 < 0 ||
@@ -296,5 +362,5 @@
         psError(PS_ERR_BAD_PARAMETER_VALUE, true,
                 "Specified psRegion parameter, x0=%f, is out of range [%d,%d].\n",
-                region.x0, input->col0, input->col0+input->numCols);
+                region.x0, input->col0, input->col0+input->numCols-1);
         return NULL;
     }
@@ -305,5 +371,5 @@
         psError(PS_ERR_BAD_PARAMETER_VALUE, true,
                 "Specified psRegion parameter, y0=%f, is out of range [%d,%d].\n",
-                region.y0, input->row0, input->row0+input->numRows);
+                region.y0, input->row0, input->row0+input->numRows-1);
         return NULL;
     }
@@ -315,5 +381,5 @@
             psError(PS_ERR_BAD_PARAMETER_VALUE, true,
                     "Specified psRegion parameter, x1=%f=%d, is out of range [%d,%d].\n",
-                    region.x1, col1+input->col0, input->col0, input->col0+input->numCols);
+                    region.x1, col1+input->col0, input->col0, input->col0+input->numCols-1);
             return NULL;
         }
@@ -323,5 +389,5 @@
         psError(PS_ERR_BAD_PARAMETER_VALUE, true,
                 "Specified psRegion parameter, x1=%f=%d, is out of range [%d,%d].\n",
-                region.x1, col1, input->col0, input->col0+input->numCols);
+                region.x1, col1, input->col0, input->col0+input->numCols-1);
         return NULL;
     }
@@ -332,5 +398,5 @@
             psError(PS_ERR_BAD_PARAMETER_VALUE, true,
                     "Specified psRegion parameter, y1=%f=%d, is out of range [%d,%d].\n",
-                    region.y1, row1+input->row0, input->row0, input->row0+input->numRows);
+                    region.y1, row1+input->row0, input->row0, input->row0+input->numRows-1);
             return NULL;
         }
@@ -340,5 +406,5 @@
         psError(PS_ERR_BAD_PARAMETER_VALUE, true,
                 "Specified psRegion parameter, y1=%f=%d, is out of range [%d,%d].\n",
-                region.y1, row1, input->row0, input->row0+input->numRows);
+                region.y1, row1, input->row0, input->row0+input->numRows-1);
         return NULL;
     }
@@ -583,8 +649,28 @@
         return NULL;
     }
-    //    PS_ASSERT_INT_NONNEGATIVE(input->col0, NULL);
-    //    PS_ASSERT_INT_NONNEGATIVE(input->row0, NULL);
-    //    PS_ASSERT_INT_POSITIVE(input->numCols, NULL);
-    //    PS_ASSERT_INT_POSITIVE(input->numRows, NULL);
+    if (input->col0 < 0) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "psImage input is invalid.  col0 cannot be negative.\n");
+        psFree(out);
+        return NULL;
+    }
+    if (input->row0 < 0) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "psImage input is invalid.  row0 cannot be negative.\n");
+        psFree(out);
+        return NULL;
+    }
+    if (input->numCols < 1) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "psImage input is invalid.  numCols must be greater than 0.\n");
+        psFree(out);
+        return NULL;
+    }
+    if (input->numRows < 1) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "psImage input is invalid.  numRows must be greater than 0.\n");
+        psFree(out);
+        return NULL;
+    }
     psS32 numCols = input->numCols;
     psS32 numRows = input->numRows;
@@ -598,20 +684,115 @@
     }
 
-
-    float startCol = region.x0;
-    float startRow = region.y0;
-    float endCol = region.x1;
-    float endRow = region.y1;
-    if (startCol < 0 || startCol >= numCols ||
-            startRow < 0 || startRow >= numRows ||
-            endCol < 0 || endCol >= numCols ||
-            endRow < 0 || endRow >= numRows) {
-        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
-                PS_ERRORTEXT_psImage_LINE_NOT_IN_IMAGE,
-                startCol,startRow,endCol,endRow,
-                numCols-1,numRows-1);
-        psFree(out);
-        return NULL;
-    }
+    float col0 = region.x0;
+    float row0 = region.y0;
+    float col1 = region.x1;
+    float row1 = region.y1;
+
+    //Make sure x0 of region is inside image.  If so, set col0 to corresponding index number.
+    if (col0 >= input->col0 && col0 < (input->col0 + input->numCols) ) {
+        col0 -= input->col0;
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "Specified psRegion parameter, x0=%f, is out of range [%d,%d].\n",
+                region.x0, input->col0, input->col0+input->numCols);
+        psFree(out);
+        return NULL;
+    }
+    //Make sure y0 of region is inside image.  If so, set row0 to corresponding index number.
+    if (row0 >= input->row0 && row0 < (input->row0 + input->numRows) ) {
+        row0 -= input->row0;
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "Specified psRegion parameter, y0=%f, is out of range [%d,%d].\n",
+                region.y0, input->row0, input->row0+input->numRows);
+        psFree(out);
+        return NULL;
+    }
+    /*
+        //Make sure x1 of region is valid.  If negative, index from tail (if valid).
+        if (col1 < 0) {
+            col1 += input->numCols;
+            if (col1 < 0) {
+                psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                        "Specified psRegion parameter, x1=%f=%f, is out of range [%d,%d].\n",
+                        region.x1, col1+input->col0, input->col0, input->col0+input->numCols);
+                psFree(out);
+                return NULL;
+            }
+        } else if (col1 >= input->col0 && col1 < (input->col0 + input->numCols) ) {
+            col1 -= input->col0;
+        } else {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    "Specified psRegion parameter, x1=%f=%f, is out of range [%d,%d].\n",
+                    region.x1, col1, input->col0, input->col0+input->numCols);
+            psFree(out);
+            return NULL;
+        }
+        //Make sure y1 of region is valid.  If negative, index from tail (if valid).
+        if (row1 < 0) {
+            row1 += input->numRows;
+            if (row1 < 0) {
+                psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                        "Specified psRegion parameter, y1=%f=%f, is out of range [%d,%d].\n",
+                        region.y1, row1+input->row0, input->row0, input->row0+input->numRows);
+                psFree(out);
+                return NULL;
+            }
+        } else if (row1 >= input->row0 && row1 < (input->row0 + input->numRows) ) {
+            row1 -= input->row0;
+        } else {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    "Specified psRegion parameter, y1=%f=%f, is out of range [%d,%d].\n",
+                    region.y1, row1, input->row0, input->row0+input->numRows);
+            psFree(out);
+            return NULL;
+        }
+    */
+    /*    //Now make sure that the region makes sense.
+        if (col0 > col1 || row0 > row1) {
+            if (col0 > col1) {
+                psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                        "Invalid psRegion specified.  x0=%f=%f is greater than x1=%f=%f.\n",
+                        region.x0, col0, region.x1, col1);
+            } else {
+                psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                        "Invalid psRegion specified.  y0=%f=%f is greater than y1=%f=%f.\n",
+                        region.y0, row0, region.y1, row1);
+            }
+            psFree(out);
+            return NULL;
+        } else if (col0 == col1 && row0 == row1) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    "Invalid psRegion specified.  Region contains only 1 pixel.\n");
+            psFree(out);
+            return NULL;
+        }
+    */
+    if (col1 < 0 || row1 < 0 || col0 < 0 || row0 < 0 || col0 >= numCols || col1 >= numCols ||
+            row0 >= numRows || row1 >= numRows) {
+        psFree(out);
+        return NULL;
+    }
+    float startCol = col0;
+    float startRow = row0;
+    float endCol = col1;
+    float endRow = row1;
+    /*
+        float startCol = region.x0;
+        float startRow = region.y0;
+        float endCol = region.x1;
+        float endRow = region.y1;
+        if (startCol < 0 || startCol >= numCols ||
+                startRow < 0 || startRow >= numRows ||
+                endCol < 0 || endCol >= numCols ||
+                endRow < 0 || endRow >= numRows) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    PS_ERRORTEXT_psImage_LINE_NOT_IN_IMAGE,
+                    startCol,startRow,endCol,endRow,
+                    numCols-1,numRows-1);
+            psFree(out);
+            return NULL;
+        }
+    */
 
     if (mode < PS_INTERPOLATE_FLAT ) {
Index: trunk/psLib/src/imageops/psImageStats.c
===================================================================
--- trunk/psLib/src/imageops/psImageStats.c	(revision 6631)
+++ trunk/psLib/src/imageops/psImageStats.c	(revision 6750)
@@ -9,6 +9,6 @@
  *  @author GLG, MHPCC
  *
- *  @version $Revision: 1.90 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-02-07 23:14:21 $
+ *  @version $Revision: 1.91 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-04-01 02:43:57 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -267,6 +267,8 @@
     // We scale the pixel positions to values
     // between -1.0 and 1.0
-    rScalingFactors = calcScaleFactors(input->numRows);
-    cScalingFactors = calcScaleFactors(input->numCols);
+    //    rScalingFactors = calcScaleFactors(input->numRows);
+    //    cScalingFactors = calcScaleFactors(input->numCols);
+    rScalingFactors = calcScaleFactors(input->row0 + input->numRows);
+    cScalingFactors = calcScaleFactors(input->col0 + input->numCols);
 
     // Determine how many Chebyshev polynomials
@@ -283,6 +285,8 @@
         for (j = 0; j < (1 + coeffs->nY); j++) {
             sums[i][j] = 0.0;
-            for (x = 0; x < input->numRows; x++) {
-                for (y = 0; y < input->numCols; y++) {
+            //            for (x = 0; x < input->numRows; x++) {
+            //                for (y = 0; y < input->numCols; y++) {
+            for (x = input->row0; x < (input->row0 + input->numRows); x++) {
+                for (y = input->col0; y < (input->col0 + input->numCols); y++) {
                     double pixel = 0.0;
                     if (input->type.type == PS_TYPE_S8) {
@@ -399,5 +403,6 @@
             //            nodes->data.F64[x][y] = psImagePixelInterpolate(input, yNode, xNode, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
             //            nodes->data.F64[x][y] = psImagePixelInterpolate(input, yTmp, xTmp, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
-            nodes->data.F64[x][y] = psImagePixelInterpolate(input, yOrig, xOrig, NULL, 0, 0.0, PS_INTERPOLATE_BILINEAR);
+            nodes->data.F64[x][y] = psImagePixelInterpolate(input, yOrig, xOrig, NULL,
+                                    0, 0.0, PS_INTERPOLATE_BILINEAR);
         }
     }
@@ -505,6 +510,8 @@
     // We scale the pixel positions to values between -1.0 and 1.0
     // Use static data structures here.
-    rScalingFactors = calcScaleFactors(input->numRows);
-    cScalingFactors = calcScaleFactors(input->numCols);
+    //    rScalingFactors = calcScaleFactors(input->numRows);
+    //    cScalingFactors = calcScaleFactors(input->numCols);
+    rScalingFactors = calcScaleFactors(input->numRows+input->row0);
+    cScalingFactors = calcScaleFactors(input->numCols+input->col0);
 
     // Determine how many Chebyshev polynomials
@@ -517,6 +524,8 @@
     chebPolys = p_psCreateChebyshevPolys(maxChebyPoly + 1);
 
-    for (x = 0; x < input->numRows; x++) {
-        for (y = 0; y < input->numCols; y++) {
+    //    for (x = 0; x < input->numRows; x++) {
+    //        for (y = 0; y < input->numCols; y++) {
+    for (x = input->row0; x < (input->row0 + input->numRows); x++) {
+        for (y = input->col0; y < (input->col0 + input->numCols); y++) {
             polySum = 0.0;
             for (i = 0; i < (1 + coeffs->nX); i++) {
@@ -563,11 +572,15 @@
         for (int col = 0; col < input->numCols ; col++) {
             if (input->type.type == PS_TYPE_S8) {
-                input->data.S8[row][col] = (psS8) psPolynomial2DEval(coeffs, (psF32) row, (psF32) col);
+                input->data.S8[row][col] = (psS8) psPolynomial2DEval(coeffs,
+                                           (psF32) (row + input->row0), (psF32) (col + input->col0));
             } else if (input->type.type == PS_TYPE_U16) {
-                input->data.U16[row][col] = (psS16) psPolynomial2DEval(coeffs, (psF32) row, (psF32) col);
+                input->data.U16[row][col] = (psS16) psPolynomial2DEval(coeffs,
+                                            (psF32) (row + input->row0), (psF32) (col + input->col0));
             } else if (input->type.type == PS_TYPE_F32) {
-                input->data.F32[row][col] = psPolynomial2DEval(coeffs, (psF32) row, (psF32) col);
+                input->data.F32[row][col] = psPolynomial2DEval(coeffs,
+                                            (psF32) (row + input->row0), (psF32) (col + input->col0));
             } else if (input->type.type == PS_TYPE_F64) {
-                input->data.F64[row][col] = (psF64) psPolynomial2DEval(coeffs, (psF32) row, (psF32) col);
+                input->data.F64[row][col] = (psF64) psPolynomial2DEval(coeffs,
+                                            (psF32) (row + input->row0), (psF32) (col + input->col0));
             }
         }
@@ -617,9 +630,4 @@
     int y1 = 0;
     psElemType type;
-    if (mask == NULL) {
-        psError(PS_ERR_BAD_PARAMETER_NULL, true,
-                PS_ERRORTEXT_psImage_IMAGE_NULL);
-        return -1;
-    }
 
     // this is not a valid error: a psRegion with ranges outside the valid pixels
@@ -641,16 +649,117 @@
 
     // rationalize the region
-    region = psRegionForImage(mask, region);
-
-    if (region.x0 == region.x1 || region.y0 == region.y1) {
-        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
-                "psRegion input contains 0 pixels\n");
+
+    /*
+        if (mask == NULL) {
+            psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                    PS_ERRORTEXT_psImage_IMAGE_NULL);
+            return -1;
+        }
+        region = psRegionForImage(mask, region);
+     
+        if (region.x0 == region.x1 || region.y0 == region.y1) {
+            psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                    "psRegion input contains 0 pixels\n");
+            return -1;
+        }
+    */
+    PS_ASSERT_IMAGE_NON_NULL(mask, -1);
+    PS_ASSERT_INT_NONNEGATIVE(mask->col0, -1);
+    PS_ASSERT_INT_NONNEGATIVE(mask->row0, -1);
+    PS_ASSERT_INT_POSITIVE(mask->numCols, -1);
+    PS_ASSERT_INT_POSITIVE(mask->numRows, -1);
+
+    /*    x0 = (int)(roundf(region.x0));
+        x1 = (int)(roundf(region.x1));
+        y0 = (int)(roundf(region.y0));
+        y1 = (int)(roundf(region.y1));
+    */
+    int col0 = (int)(roundf(region.x0));
+    int col1 = (int)(roundf(region.x1));
+    int row0 = (int)(roundf(region.y0));
+    int row1 = (int)(roundf(region.y1));
+    //If (0,0,0,0) specified, the whole image is to be used.
+    if (col0 == 0 && col1 == 0 && row0 == 0 && row1 == 0) {
+        col0 = mask->col0;
+        col1 = mask->col0 + mask->numCols - 1;
+        row0 = mask->row0;
+        row1 = mask->row0 + mask->numRows - 1;
+    }
+
+    //Make sure x0 of region is inside image.  If so, set col0 to corresponding index number.
+    if (col0 >= mask->col0 && col0 < (mask->col0 + mask->numCols) ) {
+        col0 -= mask->col0;
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "Specified psRegion parameter, x0=%f, is out of range [%d,%d].\n",
+                region.x0, mask->col0, mask->col0+mask->numCols-1);
         return -1;
     }
-
-    x0 = (int)(roundf(region.x0));
-    x1 = (int)(roundf(region.x1));
-    y0 = (int)(roundf(region.y0));
-    y1 = (int)(roundf(region.y1));
+    //Make sure y0 of region is inside image.  If so, set row0 to corresponding index number.
+    if (row0 >= mask->row0 && row0 < (mask->row0 + mask->numRows) ) {
+        row0 -= mask->row0;
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "Specified psRegion parameter, y0=%f, is out of range [%d,%d].\n",
+                region.y0, mask->row0, mask->row0+mask->numRows-1);
+        return -1;
+    }
+
+    //Make sure x1 of region is valid.  If negative, index from tail (if valid).
+    if (col1 < 0) {
+        col1 += mask->numCols;
+        if (col1 < 0) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    "Specified psRegion parameter, x1=%f=%d, is out of range [%d,%d].\n",
+                    region.x1, col1+mask->col0, mask->col0, mask->col0+mask->numCols-1);
+            return -1;
+        }
+    } else if (col1 >= mask->col0 && col1 < (mask->col0 + mask->numCols) ) {
+        col1 -= mask->col0;
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "Specified psRegion parameter, x1=%f=%d, is out of range [%d,%d].\n",
+                region.x1, col1, mask->col0, mask->col0+mask->numCols-1);
+        return -1;
+    }
+    //Make sure y1 of region is valid.  If negative, index from tail (if valid).
+    if (row1 < 0) {
+        row1 += mask->numRows;
+        if (row1 < 0) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    "Specified psRegion parameter, y1=%f=%d, is out of range [%d,%d].\n",
+                    region.y1, row1+mask->row0, mask->row0, mask->row0+mask->numRows-1);
+            return -1;
+        }
+    } else if (row1 >= mask->row0 && row1 < (mask->row0 + mask->numRows) ) {
+        row1 -= mask->row0;
+    } else {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "Specified psRegion parameter, y1=%f=%d, is out of range [%d,%d].\n",
+                region.y1, row1, mask->row0, mask->row0+mask->numRows-1);
+        return -1;
+    }
+    //Now make sure that the region makes sense.
+    if (col0 > col1 || row0 > row1) {
+        if (col0 > col1) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    "Invalid psRegion specified.  x0=%f=%d is greater than x1=%f=%d.\n",
+                    region.x0, col0, region.x1, col1);
+        } else {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    "Invalid psRegion specified.  y0=%f=%d is greater than y1=%f=%d.\n",
+                    region.y0, row0, region.y1, row1);
+        }
+        return -1;
+    }/* else if (col0 == col1 && row0 == row1) {
+            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                    "Invalid psRegion specified.  Region contains only 1 pixel.\n");
+            return -1;
+        }
+    */
+    x0 = col0;
+    x1 = col1;
+    y0 = row0;
+    y1 = row1;
 
     type = mask->type.type;
@@ -664,6 +773,6 @@
     case PS_TYPE_U8:
     case PS_TYPE_U16:
-        for (long j = y0; j < y1; j++) {
-            for (long i = x0; i < x1; i++) {
+        for (long j = y0; j <= y1; j++) {
+            for (long i = x0; i <= x1; i++) {
                 if (mask->data.PS_TYPE_MASK_DATA[j][i] & value) {
                     Npixels ++;
