Index: trunk/psModules/src/detrend/pmMaskBadPixels.c
===================================================================
--- trunk/psModules/src/detrend/pmMaskBadPixels.c	(revision 5170)
+++ trunk/psModules/src/detrend/pmMaskBadPixels.c	(revision 5516)
@@ -19,6 +19,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-09-28 20:43:52 $
+ *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-11-15 20:09:03 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -35,8 +35,88 @@
 #include "pmMaskBadPixels.h"
 #include "pmMaskBadPixelsErrors.h"
+#include "pmSubtractBias.h"
+
+/******************************************************************************
+GrowPixel(inMask, row, col, radius, maskVal): This private routine takes an
+input image mask and a pixel location, then sets (logical or) all pixels with
+parameter radius if that pixel to maskVal parameter.
+ *****************************************************************************/
+psBool GrowPixel(
+    psImage *inMask,
+    psS32 col,
+    psS32 row,
+    psS32 radius,
+    psU32 maskVal)
+{
+    psS32 rowMin = PS_MAX(row-radius, 0);
+    psS32 rowMax = PS_MIN(row+radius+1, inMask->numRows);
+    psS32 colMin = PS_MAX(col-radius, 0);
+    psS32 colMax = PS_MIN(col+radius+1, inMask->numCols);
+    psF32 squareRadius = PS_SQR(radius);
+
+
+    for(psS32 i=rowMin; i<rowMax; i++) {
+        for(psS32 j=colMin; j<colMax; j++) {
+            // Old code:
+            //            psF32 rRound = 0.5 + sqrtf((psF32) (((col-j)*(col-j)) + ((row-i)*(row-i))));
+            //            if(rRound <= radius) {
+            psF32 squareDis = (psF32) (((col-j)*(col-j)) + ((row-i)*(row-i)));
+            if (squareDis <= squareRadius) {
+                inMask->data.U8[i][j] |= maskVal;
+            }
+        }
+    }
+    return(true);
+}
+
+/******************************************************************************
+GetRadius(inImg, col, row, sat, growVal, grow): This private routine takes an
+input image and pixel location and determines what radius that pixel must grow
+by.
+ 
+//XXX: Inline this or macro it for speed.
+ *****************************************************************************/
+static psS32 GetRadius(
+    psImage *inImg,
+    psS32 col,
+    psS32 row,
+    psF32 sat,
+    psU32 growVal,
+    psS32 grow)
+{
+    psS32 growRadius = 0;
+    if (inImg->type.type == PS_TYPE_F32) {
+        if(inImg->data.F32[row][col] == growVal) {
+            growRadius = grow;
+        }
+        if (inImg->data.F32[row][col] > sat) {
+            growRadius = PS_MAX(growRadius+1, 2);
+        }
+    } else if (inImg->type.type == PS_TYPE_S32) {
+        if(inImg->data.S32[row][col] == growVal) {
+            growRadius = grow;
+        }
+        if (inImg->data.S32[row][col] > sat) {
+            growRadius = PS_MAX(growRadius+1, 2);
+        }
+    } else if (inImg->type.type == PS_TYPE_U16) {
+        if(inImg->data.U16[row][col] == growVal) {
+            growRadius = grow;
+        }
+        if (inImg->data.U16[row][col] > sat) {
+            growRadius = PS_MAX(growRadius+1, 2);
+        }
+    } else {
+        psError( PS_ERR_BAD_PARAMETER_TYPE, true,
+                 PS_ERRORTEXT_pmMaskBadPixels_TYPE_MASK_IMAGE,
+                 inImg->type.type);
+    }
+    return(growRadius);
+}
+
 
 bool pmMaskBadPixels(
     pmReadout *in,
-    const psImage *mask,
+    const pmReadout *mask,
     unsigned int maskVal,
     float sat,
@@ -44,69 +124,57 @@
     int grow)
 {
+    // XXX: Review this code then put all asserts at the top.
+    PS_ASSERT_PTR_NON_NULL(in, true);
+    PS_ASSERT_PTR_NON_NULL(in->image, false);
+    PS_WARN_PTR_NON_NULL(in->parent);
+    if (in->parent != NULL) {
+        PS_WARN_PTR_NON_NULL(in->parent->concepts);
+    }
+    PS_ASSERT_PTR_NON_NULL(mask, false);
     int i = 0;
     int j = 0;
-    int jj = 0;
-    int ii = 0;
-    int rRound = 0;
-    int rowMin = 0;
-    int rowMax = 0;
-    int colMin = 0;
-    int colMax = 0;
     int totOffCol = 0;
     int totOffRow = 0;
-    float r = 0.0f;
     psElemType inType;
     psElemType maskType;
-    psImage *inImage = NULL;
     psImage *inMask = NULL;
 
-
-    // Check for nulls
-    if (in == NULL) {
-        return true;   // Readout may not have data in it
-    } else if(mask==NULL) {
-        psError( PS_ERR_BAD_PARAMETER_NULL, true,
-                 PS_ERRORTEXT_pmMaskBadPixels_NULL_MASK_IMAGE);
-        return false;
-    }
-
-    inImage = in->image;
-    if (inImage == NULL) {
-        psError( PS_ERR_BAD_PARAMETER_NULL, true,
-                 PS_ERRORTEXT_pmMaskBadPixels_NULL_INPUT_IMAGE);
-        return false;
-    } else if(in->mask == NULL) {
-        in->mask = psImageAlloc(inImage->numCols, inImage->numRows, PS_TYPE_MASK);
-        memset(in->mask->data.V[0], 0, inImage->numCols*inImage->numRows*PSELEMTYPE_SIZEOF(PS_TYPE_MASK));
+    //
+    // Determine trimmed image from metadata.
+    //
+    psImage *trimmedImg = p_psDetermineTrimmedImage(in);
+    if(in->mask == NULL) {
+        in->mask = psImageAlloc(trimmedImg->numCols, trimmedImg->numRows, PS_TYPE_MASK);
+        PS_IMAGE_SET_U8(in->mask, 0);
     }
     inMask = in->mask;
 
     // Check input image and its mask are not larger than mask
-    if(inImage->numRows > mask->numRows || inImage->numCols > mask->numCols) {
+    if(trimmedImg->numRows > mask->image->numRows || trimmedImg->numCols > mask->image->numCols) {
         psError( PS_ERR_BAD_PARAMETER_SIZE, true,
                  PS_ERRORTEXT_pmMaskBadPixels_SIZE_INPUT_IMAGE,
-                 inImage->numRows, inImage->numCols, mask->numRows, mask->numCols);
-        return false;
-    } else if(inMask->numRows>mask->numRows || inMask->numCols>mask->numCols) {
+                 trimmedImg->numRows, trimmedImg->numCols, mask->image->numRows, mask->image->numCols);
+        return false;
+    } else if(inMask->numRows > mask->image->numRows || inMask->numCols > mask->image->numCols) {
         psError( PS_ERR_BAD_PARAMETER_SIZE, true,
                  PS_ERRORTEXT_pmMaskBadPixels_SIZE_MASK_IMAGE,
-                 inMask->numRows, inMask->numCols, mask->numRows, mask->numCols);
+                 inMask->numRows, inMask->numCols, mask->image->numRows, mask->image->numCols);
         return false;
     }
 
     // Determine total offset based on image offset with chip offset
-    totOffCol = inImage->col0 + in->col0;
-    totOffRow = inImage->row0 + in->row0;
+    totOffCol = trimmedImg->col0 + in->col0;
+    totOffRow = trimmedImg->row0 + in->row0;
 
     // Check that offsets are within image limits
-    if(totOffRow>=mask->numRows || totOffCol>=mask->numCols) {
+    if(totOffRow>=mask->image->numRows || totOffCol>=mask->image->numCols) {
         psError( PS_ERR_BAD_PARAMETER_SIZE, true,
                  PS_ERRORTEXT_pmMaskBadPixels_OFFSET_MASK_IMAGE,
-                 totOffRow, totOffCol, mask->numRows, mask->numCols);
-        return false;
-    } else if(totOffRow>=inImage->numRows || totOffCol>=inImage->numCols) {
+                 totOffRow, totOffCol, mask->image->numRows, mask->image->numCols);
+        return false;
+    } else if(totOffRow>=trimmedImg->numRows || totOffCol>=trimmedImg->numCols) {
         psError( PS_ERR_BAD_PARAMETER_SIZE, true,
                  PS_ERRORTEXT_pmMaskBadPixels_OFFSET_INPUT_IMAGE,
-                 totOffRow, totOffCol, inImage->numRows, inImage->numCols);
+                 totOffRow, totOffCol, trimmedImg->numRows, trimmedImg->numCols);
         return false;
     } else if(totOffRow>=inMask->numRows || totOffCol>=inMask->numCols) {
@@ -118,6 +186,6 @@
 
     // Check for incorrect types
-    inType = inImage->type.type;
-    maskType = mask->type.type;
+    inType = trimmedImg->type.type;
+    maskType = mask->image->type.type;
     if(PS_IS_PSELEMTYPE_COMPLEX(inType)) {
         psError( PS_ERR_BAD_PARAMETER_TYPE, true,
@@ -132,57 +200,34 @@
     }
 
-    // Macro for all PS types
-    #define PM_BAD_PIXELS(TYPE)                                                                              \
-case PS_TYPE_##TYPE:                                                                                         \
-    for(j=totOffRow; j<inImage->numRows; j++) {                                                              \
-        for(i=totOffCol; i<inImage->numCols; i++) {                                                          \
-            \
-            /* Pixels with flux greater than sat shall be masked */                                          \
-            if(inImage->data.TYPE[j][i] > sat) {                                                             \
-                inMask->data.PS_TYPE_MASK_DATA[j][i] |= PM_MASK_SAT;                                         \
-            }                                                                                                \
-            \
-            /* Pixels which satisfy maskVal shall be masked */                                               \
-            inMask->data.PS_TYPE_MASK_DATA[j][i] |= (mask->data.PS_TYPE_MASK_DATA[j][i]&maskVal);            \
-            \
-            /* Pixels which satisfy growVal and within the grow radius shall be masked */                    \
-            if(mask->data.PS_TYPE_MASK_DATA[j][i] & growVal) {                                               \
-                rowMin = MAX(j-grow, 0);                                                                     \
-                rowMax = MIN(j+grow+1, inImage->numRows);                                                    \
-                colMin = MAX(i-grow, 0);                                                                     \
-                colMax = MIN(i+grow+1, inImage->numCols);                                                    \
-                for(jj=rowMin; jj<rowMax; jj++) {                                                            \
-                    for(ii=colMin; ii<colMax; ii++) {                                                        \
-                        r = sqrtf((ii-i)*(ii-i)+(jj-j)*(jj-j));                                              \
-                        rRound = r + 0.5;                                                                    \
-                        if(rRound <= grow) {                                                                 \
-                            inMask->data.PS_TYPE_MASK_DATA[jj][ii] |=                                        \
-                                    (mask->data.PS_TYPE_MASK_DATA[j][i]&growVal);                            \
-                        }                                                                                    \
-                    }                                                                                        \
-                }                                                                                            \
-            }                                                                                                \
-        }                                                                                                    \
-    }                                                                                                        \
-    break;
-
-    // Switch to call bad pixel masking macro defined above
-    switch(inType) {
-        PM_BAD_PIXELS(U8);
-        PM_BAD_PIXELS(U16);
-        PM_BAD_PIXELS(U32);
-        PM_BAD_PIXELS(U64);
-        PM_BAD_PIXELS(S8);
-        PM_BAD_PIXELS(S16);
-        PM_BAD_PIXELS(S32);
-        PM_BAD_PIXELS(S64);
-        PM_BAD_PIXELS(F32);
-        PM_BAD_PIXELS(F64);
-    default:
-        psError( PS_ERR_BAD_PARAMETER_TYPE, true,
-                 PS_ERRORTEXT_pmMaskBadPixels_TYPE_UNSUPPORTED,
-                 inType);
-    }
-
-    return false;
+    //
+    // This is the main loop which examines each pixel and masks pixels if
+    //    A: The mask matches the maskValue
+    //    B: The pixel is larger than the saturation value
+    //    C: The pixel equals the grow value (in which case a circle is masked)
+    //
+    for(i=totOffRow; i<trimmedImg->numRows; i++) {
+        for(j=totOffCol; j<trimmedImg->numCols; j++) {
+            //
+            // A: Pixels which satisfy maskVal shall be masked
+            //
+            if (mask->image->data.U8[i][j] == maskVal) {
+                in->mask->data.U8[i][j] |= maskVal;
+            }
+
+            //
+            // We first determine how much we need to grow by and store this in
+            // growRadius.
+            //
+            psS32 growRadius = GetRadius(trimmedImg, j, i, sat, growVal, grow);
+
+            //
+            // Grow the pixel mask if necessary.
+            //
+            if (growRadius != 0) {
+                GrowPixel(in->mask, j, i, growRadius, maskVal);
+            }
+        }
+    }
+
+    return true;
 }
