Index: /branches/pap_branch_070920/psLib/src/fits/psFits.c
===================================================================
--- /branches/pap_branch_070920/psLib/src/fits/psFits.c	(revision 15175)
+++ /branches/pap_branch_070920/psLib/src/fits/psFits.c	(revision 15176)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.71.2.3 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2007-10-03 03:01:45 $
+ *  @version $Revision: 1.71.2.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2007-10-03 20:21:45 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -20,4 +20,5 @@
 
 #include "psFits.h"
+#include "psFitsHeader.h"
 #include "string.h"
 #include "psError.h"
@@ -161,5 +162,5 @@
     fits->writable = (iomode == READWRITE);
     fits->extword = NULL;
-    fits->compression = true;
+    fits->compConvention = true;
     psMemSetDeallocator(fits,(psFreeFunc)fitsFree);
 
@@ -232,52 +233,10 @@
 }
 
-// move to the first HDU where extword == extname.  this is equivalent to fits_movnam_hdu() for
-// a user-defined word in place of EXTNAME
-bool p_psFitsMoveExtName_UserKey(const psFits *fits,
-                                 const char *extname,
-                                 const char *extword)
-{
-    PS_ASSERT_FITS_NON_NULL(fits,   false);
-    PS_ASSERT_PTR_NON_NULL(extname, false);
-    PS_ASSERT_PTR_NON_NULL(extword, false);
-
-    int hdutype = 0;
-    char name[MAX_STRING_LENGTH];
-    char extstring[MAX_STRING_LENGTH];
-
-    sprintf (extstring, "'%s'", extname);
-
-    // NOTE: fits_* return 0 for success
-    for (int i = 1; true; i++) {
-        // are we able to read the next HDU?
-
-        int status = 0;
-        if (fits_movabs_hdu(fits->fd, i, &hdutype, &status)) {
-            char fitsErr[MAX_STRING_LENGTH];
-            fits_get_errstatus(status, fitsErr);
-            psError(PS_ERR_LOCATION_INVALID, true,
-                    _("Could not find HDU with %s = '%s'. CFITSIO Error: %s"),
-                    extword, extname, fitsErr);
-            return false;
-        }
-        // is there a keyword called 'extword'? (read as string regardless of type)
-        status = 0;
-        if (fits_read_keyword(fits->fd, (char *)extword, name, NULL, &status)) {
-            continue;
-        }
-        // if this was read as a string, we will have leading and trailing single-quotes
-        // try both for comparison
-
-        // do we have the right hdu (names match)?
-        if (!strcmp (name, extname) || !strcmp (name, extstring)) {
-            return true;
-        }
-    }
-    psAbort("we should not reach here");
-}
-
-// XXX I will need to define a low-level function p_psFitsMoveExtName_UserKey () which
-// uses fits_movabs_hdu() to replicate the functionality of fits_movnam_hdu using an
-// alternate name for EXTNAME
+// Files compressed with cfitsio's "imcopy" program may have multiple EXTNAME keywords, with the first set to
+// COMPRESSED_IMAGE.  However, fits_movnam_hdu won't find the second (proper) value of EXTNAME, and so can
+// fail to find a perfectly legitimate extension, simply because imcopy does something silly.  However, we
+// really want to be able to read these files (MegaCam data are shipped as imcopy-compressed images).
+// Therefore, we implement our own version of moving to an extension specified by name.  The pure cfitsio
+// version is used if "compConvention" handling is turned off in the psFits structure.
 bool psFitsMoveExtName(const psFits* fits,
                        const char* extname)
@@ -288,19 +247,56 @@
     int status = 0;
 
-    if (fits->extword != NULL) {
-        bool result = p_psFitsMoveExtName_UserKey(fits, extname, fits->extword);
-        return (result);
-    }
-
-    if (fits_movnam_hdu(fits->fd, ANY_HDU, (char*)extname, 0, &status) != 0) {
-        char fitsErr[MAX_STRING_LENGTH];
-        fits_get_errstatus(status, fitsErr);
-        psError(PS_ERR_LOCATION_INVALID, true,
-                _("Could not find HDU '%s'. CFITSIO Error: %s"),
-                extname, fitsErr);
-        return false;
-    }
-
-    return true;
+    if (!fits->compConvention && !fits->extword) {
+        // User wants to use cfitsio.  Good luck to them!
+        if (fits_movnam_hdu(fits->fd, ANY_HDU, (char*)extname, 0, &status) != 0) {
+            psFitsError(status, true, _("Could not find HDU '%s'"), extname);
+            return false;
+        }
+        return true;
+    }
+
+    bool ignoreCI = (fits->compConvention &&
+                     (strcmp(extname, "COMPRESSED_IMAGE") != 0)); // Ignore COMPRESSED_IMAGE extension name?
+    char *extword = (fits->extword ? fits->extword : "EXTNAME"); // Word to use as extension name
+
+#if 0
+    // XXX Future optimisation: loop through from the current HDU to the end, then from the start to the
+    // current position.  This will save seeking through the file multiple times.
+    int currentExt = psFitsGetExtNum(fits); // Current extension number
+    int numExt = psFitsGetSize(fits);   // Total number of extensions
+#endif
+
+    for (int i = 1; true; i++) {
+        int hdutype = 0;
+        if (fits_movabs_hdu(fits->fd, i, &hdutype, &status)) {
+            // We've run off the end
+            psFitsError(status, true, _("Could not find HDU with %s = '%s'"), extword, extname);
+            return false;
+        }
+        // Is there a keyword called 'extword'? (read as string regardless of type)
+        char name[MAX_STRING_LENGTH];  // Name of extension
+        if (fits_read_keyword(fits->fd, extword, name, NULL, &status)) {
+            // It doesn't exist in the header.
+            // This isn't the extension you're looking for.  Move along.
+            status = 0;
+            continue;
+        }
+        char *fixed = p_psFitsHeaderParseString(name); // Parsed version (removing quotes and spaces)
+
+        if (ignoreCI && strcmp(fixed, "COMPRESSED_IMAGE") == 0) {
+            // Read it again, Sam
+            if (fits_read_keyword(fits->fd, extword, name, NULL, &status)) {
+                status = 0;
+                continue;
+            }
+            fixed = p_psFitsHeaderParseString(name);
+        }
+
+        if (strcmp(fixed, extname) == 0) {
+            // We've arrived
+            return true;
+        }
+    }
+    psAbort("Should never reach here.");
 }
 
Index: /branches/pap_branch_070920/psLib/src/fits/psFits.h
===================================================================
--- /branches/pap_branch_070920/psLib/src/fits/psFits.h	(revision 15175)
+++ /branches/pap_branch_070920/psLib/src/fits/psFits.h	(revision 15176)
@@ -4,6 +4,6 @@
  * @author Robert DeSonia, MHPCC
  *
- * @version $Revision: 1.31.2.3 $ $Name: not supported by cvs2svn $
- * @date $Date: 2007-10-03 03:01:45 $
+ * @version $Revision: 1.31.2.4 $ $Name: not supported by cvs2svn $
+ * @date $Date: 2007-10-03 20:21:45 $
  * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
  */
@@ -55,5 +55,5 @@
     bool writable;                      ///< Is the file writable?
     char *extword;                      ///< user-specified word to name extensions (NULL implies EXTNAME)
-    bool compression;                   ///< Treat compressed images automatically?
+    bool compConvention;                ///< Honour compression convention, handling compressed images
 } psFits;
 
