Index: /trunk/psLib/src/fits/psFitsImage.c
===================================================================
--- /trunk/psLib/src/fits/psFitsImage.c	(revision 19382)
+++ /trunk/psLib/src/fits/psFitsImage.c	(revision 19383)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.38 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2008-08-29 01:01:39 $
+ *  @version $Revision: 1.39 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2008-09-05 07:51:09 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -28,6 +28,6 @@
 #include "psLogMsg.h"
 #include "psTrace.h"
-#include "psVector.h"
 #include "psRandom.h"
+#include "psImage.h"
 #include "psImageStructManip.h"
 
@@ -249,5 +249,7 @@
                                           psFitsFloat *floatType, // Type of custom floating-point
                                           psFits *fits, // FITS file pointer
-                                          const psImage *image, // Current type
+                                          const psImage *image, // Image to convert
+                                          const psImage *mask, // Mask image, or NULL
+                                          psMaskType maskVal, // Value to mask
                                           psRandom *rng, // Random number generator
                                           bool newScaleZero // Determine a new BSCALE and BZERO?
@@ -285,5 +287,5 @@
         if (newScaleZero) {
             // Choose an appropriate BSCALE and BZERO
-            if (!psFitsScaleDetermine(bscale, bzero, blank, image, fits)) {
+            if (!psFitsScaleDetermine(bscale, bzero, blank, image, mask, maskVal, fits)) {
                 // We can't have the write dying for this reason --- try to save it somehow!
                 psWarning("Unable to determine BSCALE and BZERO for image --- refusing to quantise.");
@@ -404,5 +406,5 @@
 }
 
-psImage* psFitsReadImage(const psFits *fits, // the psFits object
+psImage *psFitsReadImage(const psFits *fits, // the psFits object
                          psRegion region, // the region in the FITS image to read
                          int z          // the z-plane in the FITS image cube to read
@@ -445,5 +447,5 @@
 }
 
-psImage* psFitsReadImageBuffer(psImage *outImage, // Output image buffer
+psImage *psFitsReadImageBuffer(psImage *outImage, // Output image buffer
                                const psFits *fits, // the psFits object
                                psRegion region, // the region in the FITS image to read
@@ -497,9 +499,13 @@
 }
 
-bool psFitsWriteImage(psFits* fits,
-                      psMetadata* header,
-                      const psImage* input,
-                      int numZPlanes,
-                      const char* extname)
+bool psFitsWriteImage(psFits *fits, psMetadata *header, const psImage *input,
+                      int numZPlanes, const char *extname)
+{
+    return psFitsWriteImageWithMask(fits, header, input, NULL, 0, numZPlanes, extname);
+}
+
+bool psFitsWriteImageWithMask(psFits *fits, psMetadata *header, const psImage *input,
+                              const psImage *mask, psMaskType maskVal, int numZPlanes,
+                              const char *extname)
 {
     PS_ASSERT_FITS_NON_NULL(fits, false);
@@ -509,13 +515,24 @@
 
     psFitsMoveLast(fits);
-    return psFitsInsertImage(fits,header,input,numZPlanes,extname,true);
-}
-
-bool psFitsInsertImage(psFits* fits, psMetadata* header, const psImage* image, int numZPlanes,
-                       const char* extname, bool after)
+    return psFitsInsertImageWithMask(fits, header, input, mask, maskVal, numZPlanes, extname, true);
+}
+
+bool psFitsInsertImage(psFits *fits, psMetadata *header, const psImage *image, int numZPlanes,
+                       const char *extname, bool after)
+{
+    return psFitsInsertImageWithMask(fits, header, image, NULL, 0, numZPlanes, extname, after);
+}
+
+bool psFitsInsertImageWithMask(psFits *fits, psMetadata *header, const psImage *image,
+                               const psImage *mask, psMaskType maskVal, int numZPlanes,
+                               const char *extname, bool after)
 {
     PS_ASSERT_FITS_NON_NULL(fits, false);
     PS_ASSERT_FITS_WRITABLE(fits, false);
     PS_ASSERT_IMAGE_NON_NULL(image, false);
+    if (mask) {
+        PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_MASK, false);
+        PS_ASSERT_IMAGES_SIZE_EQUAL(mask, image, false);
+    }
 
     int numCols = image->numCols;       // Number of columns for image
@@ -529,5 +546,5 @@
     psFitsFloat floatType;              // Custom floating-point convention type
     psImage *diskImage = imageToDiskRepresentation(&bscale, &bzero, &blank, &floatType, fits, image,
-                                                   NULL, true); // Image to write out
+                                                   mask, maskVal, NULL, true); // Image to write out
     if (!diskImage) {
         psError(PS_ERR_UNKNOWN, false, "Unable to convert image to desired disk format.");
@@ -557,6 +574,6 @@
     }
     if (cfitsioBzero != 0.0) {
-        // p_psFitsTypeToCfitsio and imageToDiskRepresentation must not clash!
-        psAssert(bzero == 0.0 && bscale == 1.0, "impossible");
+        psAssert(bzero == 0.0 && bscale == 1.0,
+                 "p_psFitsTypeToCfitsio and imageToDiskRepresentation must not clash!");
         bscale = 1.0;
         bzero = cfitsioBzero;
@@ -564,5 +581,6 @@
 
     psFitsOptions *options = fits->options; // FITS I/O options
-    psAssert(!useRequestedScale || !options || bitPix == options->bitpix || options->bitpix == 0, "impossible");
+    psAssert(!useRequestedScale || !options || bitPix == options->bitpix || options->bitpix == 0,
+             "Something's not consistent");
 
     int naxis = 3;                      // Number of axes
@@ -630,4 +648,6 @@
         // own quantisation, the correct keyword is always "BLANK" instead of "ZBLANK".
         fits_write_key_lng(fits->fd, "BLANK", blank, "Value for undefined pixels", &status);
+        // But it seems that cfitsio uses ZBLANK
+        fits_write_key_lng(fits->fd, "ZBLANK", blank, "Value for undefined pixels", &status);
         fits_set_imgnull(fits->fd, blank, &status);
         if (psFitsError(status, true, "Could not write BLANK header to file.")) {
@@ -681,9 +701,19 @@
 }
 
-bool psFitsUpdateImage(psFits* fits, const psImage* input, int x0, int y0, int z)
+bool psFitsUpdateImage(psFits *fits, const psImage *input, int x0, int y0, int z)
+{
+    return psFitsUpdateImageWithMask(fits, input, NULL, 0, x0, y0, z);
+}
+
+bool psFitsUpdateImageWithMask(psFits *fits, const psImage *input, const psImage *mask, psMaskType maskVal,
+                               int x0, int y0, int z)
 {
     PS_ASSERT_FITS_NON_NULL(fits, false);
     PS_ASSERT_FITS_WRITABLE(fits, false);
     PS_ASSERT_IMAGE_NON_NULL(input, false);
+    if (mask) {
+        PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_MASK, false);
+        PS_ASSERT_IMAGES_SIZE_EQUAL(mask, input, false);
+    }
 
     int status = 0;
@@ -709,5 +739,5 @@
     psFitsFloat floatType;              // Custom floating-point convention type
     psImage *diskImage = imageToDiskRepresentation(&bscale, &bzero, &blank, &floatType, fits, input,
-                                                   NULL, false); // Image to write out
+                                                   mask, maskVal, NULL, false); // Image to write out
     if (!diskImage) {
         psError(PS_ERR_UNKNOWN, false, "Unable to convert image to desired disk format.");
@@ -737,11 +767,12 @@
     }
     if (cfitsioBzero != 0.0) {
-        // p_psFitsTypeToCfitsio and imageToDiskRepresentation must not clash!
-        psAssert(bzero == 0.0 && bscale == 1.0, "impossible");
+        psAssert(bzero == 0.0 && bscale == 1.0,
+                 "p_psFitsTypeToCfitsio and imageToDiskRepresentation must not clash!");
         bscale = 1.0;
         bzero = cfitsioBzero;
     }
     psFitsOptions *options = fits->options; // FITS I/O options
-    psAssert(!useRequestedScale || !options || bitPix == options->bitpix || options->bitpix == 0, "impossible");
+    psAssert(!useRequestedScale || !options || bitPix == options->bitpix || options->bitpix == 0,
+             "Something's not consistent");
 
     // Check to see if the HDU has the same datatype
Index: /trunk/psLib/src/fits/psFitsImage.h
===================================================================
--- /trunk/psLib/src/fits/psFitsImage.h	(revision 19382)
+++ /trunk/psLib/src/fits/psFitsImage.h	(revision 19383)
@@ -4,6 +4,6 @@
  * @author Robert DeSonia, MHPCC
  *
- * @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
- * @date $Date: 2007-11-16 01:04:56 $
+ * @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
+ * @date $Date: 2008-09-05 07:51:09 $
  * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
  */
@@ -23,8 +23,9 @@
 
 /// Return the dimensions and type of the FITS image
-bool psFitsImageSize(int *numCols, int *numRows, ///< Size of image
-                     psElemType *type,  ///< Type of image
-                     const psFits *fits, ///< FITS file pointer
-                     psRegion region    ///< Region in the FITS image to read
+bool psFitsImageSize(
+    int *numCols, int *numRows,         ///< Size of image
+    psElemType *type,                   ///< Type of image
+    const psFits *fits,                 ///< FITS file pointer
+    psRegion region                     ///< Region in the FITS image to read
     );
 
@@ -33,59 +34,108 @@
  *  @return psImage*     the read image or NULL if there was an error.
  */
-psImage* psFitsReadImage(
-    const psFits* fits,                ///< the psFits object
-    psRegion region,                   ///< the region in the FITS image to read
-    int z                              ///< the z-plane in the FITS image cube to read
+psImage *psFitsReadImage(
+    const psFits *fits,                 ///< the psFits object
+    psRegion region,                    ///< the region in the FITS image to read
+    int z                               ///< the z-plane in the FITS image cube to read
 );
 
-// Read an image into an extant buffer
-psImage* psFitsReadImageBuffer(psImage *output, // Output image buffer
-                               const psFits *fits,    // the psFits object
-                               psRegion region, // the region in the FITS image to read
-                               int z           // the z-plane in the FITS image cube to read
-                              );
+/** Read an image into an extant buffer
+ */
+psImage *psFitsReadImageBuffer(
+    psImage *output,                    ///< Output image buffer
+    const psFits *fits,                 ///< the psFits object
+    psRegion region,                    ///< the region in the FITS image to read
+    int z                               ///< the z-plane in the FITS image cube to read
+    );
 
-/** Writes an image, given the desired region and z-plane.
+/** Writes an image to a FITS file
+ *
+ * A new IMAGE HDU is appended to the end of the FITS file.
  *
  *  @return bool        TRUE is the write was successful, otherwise FALSE.
  */
 bool psFitsWriteImage(
-    psFits* fits,                      ///< the psFits object
-    psMetadata* header,                 ///< header items for the new HDU.  Can be NULL.
-    const psImage* input,              ///< the image to output
-    int depth,                         ///< the number of z-planes of the FITS image data cube
-    const char* extname                ///< FITS extension name
+    psFits *fits,                       ///< the psFits object
+    psMetadata *header,                 ///< header items for the new HDU.  Can be NULL.
+    const psImage *input,               ///< the image to output
+    int depth,                          ///< the number of z-planes of the FITS image data cube
+    const char *extname                 ///< FITS extension name
 );
 
-/** Writes an image, given the desired region and z-plane.  A new IMAGE HDU is
- *  appended to the end of the FITS file.
+/** Writes an image to a FITS file, optionally using the supplied mask image to do statistics when compressing
+ *
+ * A new IMAGE HDU is appended to the end of the FITS file.
+ *
+ *  @return bool        TRUE is the write was successful, otherwise FALSE.
+ */
+bool psFitsWriteImageWithMask(
+    psFits *fits,                       ///< the psFits object
+    psMetadata *header,                 ///< header items for the new HDU.  Can be NULL.
+    const psImage *input,               ///< the image to output
+    const psImage *mask,                ///< the mask image
+    psMaskType maskVal,                 ///< value to mask
+    int depth,                          ///< the number of z-planes of the FITS image data cube
+    const char *extname                 ///< FITS extension name
+);
+
+/** Insert an image in a FITS file
  *
  *  @return bool        TRUE is the write was successful, otherwise FALSE.
  */
 bool psFitsInsertImage(
-    psFits* fits,                      ///< the psFits object
-    psMetadata* header,                 ///< header items for the new HDU.  Can be NULL.
-    const psImage* input,              ///< the image to output
-    int depth,                         ///< the number of z-planes of the FITS image data cube
-    const char* extname,               ///< FITS extension name
-    bool after                         ///< if TRUE, inserts HDU after current HDU, otherwise before
+    psFits *fits,                       ///< the psFits object
+    psMetadata *header,                 ///< header items for the new HDU.  Can be NULL.
+    const psImage *input,               ///< the image to output
+    int depth,                          ///< the number of z-planes of the FITS image data cube
+    const char *extname,                ///< FITS extension name
+    bool after                          ///< if TRUE, inserts HDU after current HDU, otherwise before
 );
 
-/** Updates the FITS file image, given the desired region and z-plane. a new
- *  IMAGE HDU is inserted before or after, depending on the AFTER parameter,
- *  the current HDU.
+/** Insert an image in a FITS file, optionally using the supplied mask image to do statistics when compressing
+ *
+ *  @return bool        TRUE is the write was successful, otherwise FALSE.
+ */
+bool psFitsInsertImageWithMask(
+    psFits *fits,                       ///< the psFits object
+    psMetadata *header,                 ///< header items for the new HDU.  Can be NULL.
+    const psImage *input,               ///< the image to output
+    const psImage *mask,                ///< the mask image
+    psMaskType maskVal,                 ///< value to mask
+    int depth,                          ///< the number of z-planes of the FITS image data cube
+    const char *extname,                ///< FITS extension name
+    bool after                          ///< if TRUE, inserts HDU after current HDU, otherwise before
+);
+
+/** Updates an existing FITS file image
  *
  *  @return bool        TRUE is the write was successful, otherwise FALSE.
  */
 bool psFitsUpdateImage(
-    psFits* fits,                      ///< the psFits object
-    const psImage* input,              ///< the image to output
-    int x0,                            ///< psImage's x-axis origin in FITS image coordinates
-    int y0,                            ///< psImage's y-axis origin in FITS image coordinates
-    int z                              ///< the z-planes of the FITS image data cube to write
+    psFits *fits,                       ///< the psFits object
+    const psImage *input,               ///< the image to output
+    int x0,                             ///< psImage's x-axis origin in FITS image coordinates
+    int y0,                             ///< psImage's y-axis origin in FITS image coordinates
+    int z                               ///< the z-planes of the FITS image data cube to write
+);
+
+/** Updates an existing FITS file image, optionally using the supplied mask image to do statistics when
+ ** compressing
+ *
+ *  @return bool        TRUE is the write was successful, otherwise FALSE.
+ */
+bool psFitsUpdateImageWithMask(
+    psFits *fits,                       ///< the psFits object
+    const psImage *input,               ///< the image to output
+    const psImage *mask,                ///< the mask image
+    psMaskType maskVal,                 ///< value to mask
+    int x0,                             ///< psImage's x-axis origin in FITS image coordinates
+    int y0,                             ///< psImage's y-axis origin in FITS image coordinates
+    int z                               ///< the z-planes of the FITS image data cube to write
 );
 
 psArray *psFitsReadImageCube(const psFits *fits, psRegion region);
+
 bool psFitsWriteImageCube(psFits *fits, psMetadata *header, const psArray *input, const char *extname);
+
 bool psFitsUpdateImageCube(psFits *fits, const psArray *input, int x0, int y0);
 
Index: /trunk/psLib/src/fits/psFitsScale.c
===================================================================
--- /trunk/psLib/src/fits/psFitsScale.c	(revision 19382)
+++ /trunk/psLib/src/fits/psFitsScale.c	(revision 19383)
@@ -13,4 +13,5 @@
 #include "psTrace.h"
 
+#include "psImage.h"
 #include "psFits.h"
 #include "psImageBackground.h"
@@ -98,4 +99,6 @@
                        double *bzero, // Zero point, to return
                        const psImage *image, // Image to scale
+                       const psImage *mask, // Mask image
+                       psMaskType maskVal, // Value to mask
                        const psFitsOptions *options // FITS options
     )
@@ -112,5 +115,5 @@
     psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS, seed);
     psStats *stats = psStatsAlloc(MEAN_STAT | STDEV_STAT); // Statistics object
-    if (!psImageBackground(stats, NULL, image, NULL, 0, rng)) {
+    if (!psImageBackground(stats, NULL, image, mask, maskVal, rng)) {
         psError(PS_ERR_UNKNOWN, false, "Unable to perform statistics on image");
         psFree(rng);
@@ -163,10 +166,6 @@
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-bool psFitsScaleDetermine(double *bscale, // Scaling, to return
-                          double *bzero, // Zero point, to return
-                          long *blank,  // Blank value, to return
-                          const psImage *image, // Image to scale
-                          const psFits *fits // FITS options
-    )
+bool psFitsScaleDetermine(double *bscale, double *bzero, long *blank, const psImage *image,
+                          const psImage *mask, psMaskType maskVal, const psFits *fits)
 {
     PS_ASSERT_PTR_NON_NULL(bscale, false);
@@ -174,4 +173,8 @@
     PS_ASSERT_PTR_NON_NULL(blank, false);
     PS_ASSERT_IMAGE_NON_NULL(image, false);
+    if (mask) {
+        PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_MASK, false);
+        PS_ASSERT_IMAGES_SIZE_EQUAL(mask, image, false);
+    }
     PS_ASSERT_FITS_NON_NULL(fits, false);
 
@@ -216,5 +219,5 @@
       case PS_FITS_SCALE_STDEV_NEGATIVE:
       case PS_FITS_SCALE_STDEV_BOTH:
-        if (!scaleStdev(bscale, bzero, image, options)) {
+        if (!scaleStdev(bscale, bzero, image, mask, maskVal, options)) {
             psError(PS_ERR_UNKNOWN, false, "Unable to set BSCALE and BZERO from stdev");
             return false;
Index: /trunk/psLib/src/fits/psFitsScale.h
===================================================================
--- /trunk/psLib/src/fits/psFitsScale.h	(revision 19382)
+++ /trunk/psLib/src/fits/psFitsScale.h	(revision 19383)
@@ -12,4 +12,6 @@
                           long *blank,  ///< Blank value, to return
                           const psImage *image, ///< Image to scale
+                          const psImage *mask, ///< Mask image
+                          psMaskType maskVal, ///< Value to mask
                           const psFits *fits ///< FITS options
     );
