Index: /trunk/psLib/test/dataIO/tst_psFits.c
===================================================================
--- /trunk/psLib/test/dataIO/tst_psFits.c	(revision 2973)
+++ /trunk/psLib/test/dataIO/tst_psFits.c	(revision 2974)
@@ -6,6 +6,6 @@
 *  @author Robert DeSonia, MHPCC
 *
-*  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2005-01-13 02:20:44 $
+*  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-13 21:09:18 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -23,10 +23,15 @@
 static psS32 tst_psFitsAlloc( void );
 static psS32 tst_psFitsMoveExtName( void ); // also tests psFitsGetExtName
-static psS32 tst_psFitsMoveExtNum( void );  // also tests psFitsGetExtNum
+static psS32 tst_psFitsMoveExtNum( void );  // also tests psFitsGetExtNum, psFitsGetSize
+static psS32 tst_psFitsReadHeader( void );
 
 testDescription tests[] = {
                               {tst_psFitsAlloc, 801, "psFitsAlloc", 0, false},
                               {tst_psFitsMoveExtName, 802, "psFitsMoveExtName", 0, false},
+                              {tst_psFitsMoveExtName, 802, "psFitsGetExtName", 0, true},
                               {tst_psFitsMoveExtNum, 803, "psFitsMoveExtNum", 0, false},
+                              {tst_psFitsMoveExtNum, 803, "psFitsGetExtNum", 0, true},
+                              {tst_psFitsMoveExtNum, 803, "psFitsGetSize", 0, true},
+                              {tst_psFitsReadHeader, 0, "psFitsReadHeader", 0, false},
                               {NULL}
                           };
@@ -37,4 +42,68 @@
 
     return ( ! runTestSuite( stderr, "psImage", tests, argc, argv ) );
+}
+
+bool makeMulti(void)
+{
+
+    if (access(multiFilename, F_OK) != 0) {
+        psFits* fitsFile = psFitsAlloc(multiFilename);
+
+        if (fitsFile == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Could not create 'multi' FITS file.");
+            return false;
+        }
+
+        psImage* image = psImageAlloc(16,16,PS_TYPE_F32);
+
+        char extname[80];
+        for (int lcv = 0; lcv < 8; lcv++) {
+            snprintf(extname,80,"ext-%d", lcv);
+
+            psMetadata* header = psMetadataAlloc();
+
+            psMetadataAdd(header,PS_LIST_TAIL, "MYINT",
+                          PS_TYPE_S32, PS_META_PRIMITIVE,
+                          "psS32 Item", (psS32)lcv);
+
+            psMetadataAdd(header,PS_LIST_TAIL, "MYFLT",
+                          PS_TYPE_F32, PS_META_PRIMITIVE,
+                          "psF32 Item", (float)(1.0f/(float)(1+lcv)));
+
+            psMetadataAdd(header,PS_LIST_TAIL, "MYDBL",
+                          PS_TYPE_F64, PS_META_PRIMITIVE,
+                          "psF64 Item", (double)(1.0/(double)(1+lcv)));
+
+            psMetadataAdd(header,PS_LIST_TAIL, "MYBOOL",
+                          PS_TYPE_BOOL, PS_META_PRIMITIVE,
+                          "psBool Item",
+                          (lcv%2 == 0));
+
+            psMetadataAdd(header,PS_LIST_TAIL, "MYSTR",
+                          PS_TYPE_PTR, PS_META_STR,
+                          "String Item",
+                          extname);
+
+            // set the pixels in the image
+            psBinaryOp(image,image,"=",psScalarAlloc(lcv,PS_TYPE_F32));
+            if (! psFitsWriteImage(fitsFile,header,image,1) ) {
+                psError(PS_ERR_UNKNOWN, false,
+                        "Could not write image.");
+                return false;
+            }
+            if (! psFitsSetExtName(fitsFile,extname) ) {
+                psError(PS_ERR_UNKNOWN, false,
+                        "Could not write extension name.");
+                return false;
+            }
+
+            psFree(header);
+        }
+        psFree(image);
+        psFree(fitsFile);
+    }
+
+    return true;
 }
 
@@ -409,39 +478,107 @@
 
 
-bool makeMulti(void)
+
+static psS32 tst_psFitsReadHeader( void )
 {
-
-    if (access(multiFilename, F_OK) != 0) {
-        psFits* fitsFile = psFitsAlloc(multiFilename);
-
-        if (fitsFile == NULL) {
-            psError(PS_ERR_UNKNOWN, false,
-                    "Could not create 'multi' FITS file.");
-            return false;
-        }
-
-        psImage* image = psImageAlloc(16,16,PS_TYPE_F32);
-
-        char extname[80];
-        for (int lcv = 0; lcv < 8; lcv++) {
-            // set the pixels in the image
-            psBinaryOp(image,image,"=",psScalarAlloc(lcv,PS_TYPE_F32));
-            if (! psFitsWriteImage(fitsFile,NULL,image,1) ) {
-                psError(PS_ERR_UNKNOWN, false,
-                        "Could not write image.");
-                return false;
-            }
-            snprintf(extname,80,"ext-%d", lcv);
-            if (! psFitsSetExtName(fitsFile,extname) ) {
-                psError(PS_ERR_UNKNOWN, false,
-                        "Could not write extension name.");
-                return false;
-            }
-        }
-        psFree(image);
-        psFree(fitsFile);
-    }
-
-    return true;
+    if (! makeMulti() ) {
+        return 1;
+    }
+
+    psFits* fits = psFitsAlloc(multiFilename);
+
+    int numHDUs = psFitsGetSize(fits);
+
+    if (numHDUs < 8) {
+        psError(PS_ERR_UNKNOWN,true,
+                "The 'multi' FITS file does not have multiple HDUs.");
+        return 2;
+    }
+
+    char extname[80];
+    for (int hdunum = 0; hdunum < numHDUs; hdunum++) {
+        snprintf(extname,80,"ext-%d",hdunum);
+
+        psFitsMoveExtNum(fits,hdunum,false);
+
+        psMetadata* header = psFitsReadHeader(NULL,fits);
+        if (header == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to read header");
+            return 3;
+        }
+
+        psMetadata* header2 = psMetadataAlloc();
+        header2 = psFitsReadHeader(header2,fits);
+        if (header2 == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to read header");
+            return 11;
+        }
+
+        if (header->list->size < 1 || header->list->size != header2->list->size) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Reading the header given a NULL input psMetadata differed "
+                    "from giving an existing psMetadata.");
+            return 12;
+        }
+
+        // check for the extra metadata items
+        psS32 intItem = psMetadataLookupS32(header, "MYINT",NULL);
+        psF32 fltItem = psMetadataLookupF32(header, "MYFLT",NULL);
+        psF64 dblItem = psMetadataLookupF64(header, "MYDBL",NULL);
+        psMetadataItem* boolItem = psMetadataLookup(header, "MYBOOL");
+        char* strItem = psMetadataLookupPtr(header, "MYSTR",NULL);
+
+        if (intItem != hdunum) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psS32 metadata item from file.");
+            return 20;
+        }
+
+        if (fabsf(fltItem - 1.0f/(float)(1+hdunum)) > FLT_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psF32 metadata item from file.  Got %f vs %f",
+                    fltItem,1.0f/(float)(1+hdunum));
+            return 21;
+        }
+
+        if (abs(dblItem - 1.0/(double)(1+hdunum)) > DBL_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psF64 metadata item from file.  Got %g vs %g",
+                    dblItem, 1.0/(double)(1+hdunum));
+            return 22;
+        }
+
+        if (boolItem == NULL ||
+                boolItem->type != PS_META_PRIMITIVE ||
+                boolItem->pType != PS_TYPE_BOOL) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psBool metadata item from file.");
+            return 23;
+        }
+
+        if (strItem == NULL || strncmp(strItem,extname,strlen(extname)) != 0) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve string metadata item from file.  Got '%s' vs '%s' (%d)",
+                    strItem,extname,strlen(extname));
+            return 24;
+        }
+
+        psFree(header);
+        psFree(header2);
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"following should be an error (input psFits = NULL)");
+    psMetadata* header = psFitsReadHeader(NULL,NULL);
+
+    if (header != NULL || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN, true,
+                "psFitsReadHeader didn't error on a NULL psFits.");
+        return 30;
+    }
+
+
+    psFree(fits);
+
+    return 0;
 }
-
Index: /trunk/psLib/test/fileUtils/tst_psFits.c
===================================================================
--- /trunk/psLib/test/fileUtils/tst_psFits.c	(revision 2973)
+++ /trunk/psLib/test/fileUtils/tst_psFits.c	(revision 2974)
@@ -6,6 +6,6 @@
 *  @author Robert DeSonia, MHPCC
 *
-*  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2005-01-13 02:20:44 $
+*  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-13 21:09:18 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -23,10 +23,15 @@
 static psS32 tst_psFitsAlloc( void );
 static psS32 tst_psFitsMoveExtName( void ); // also tests psFitsGetExtName
-static psS32 tst_psFitsMoveExtNum( void );  // also tests psFitsGetExtNum
+static psS32 tst_psFitsMoveExtNum( void );  // also tests psFitsGetExtNum, psFitsGetSize
+static psS32 tst_psFitsReadHeader( void );
 
 testDescription tests[] = {
                               {tst_psFitsAlloc, 801, "psFitsAlloc", 0, false},
                               {tst_psFitsMoveExtName, 802, "psFitsMoveExtName", 0, false},
+                              {tst_psFitsMoveExtName, 802, "psFitsGetExtName", 0, true},
                               {tst_psFitsMoveExtNum, 803, "psFitsMoveExtNum", 0, false},
+                              {tst_psFitsMoveExtNum, 803, "psFitsGetExtNum", 0, true},
+                              {tst_psFitsMoveExtNum, 803, "psFitsGetSize", 0, true},
+                              {tst_psFitsReadHeader, 0, "psFitsReadHeader", 0, false},
                               {NULL}
                           };
@@ -37,4 +42,68 @@
 
     return ( ! runTestSuite( stderr, "psImage", tests, argc, argv ) );
+}
+
+bool makeMulti(void)
+{
+
+    if (access(multiFilename, F_OK) != 0) {
+        psFits* fitsFile = psFitsAlloc(multiFilename);
+
+        if (fitsFile == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Could not create 'multi' FITS file.");
+            return false;
+        }
+
+        psImage* image = psImageAlloc(16,16,PS_TYPE_F32);
+
+        char extname[80];
+        for (int lcv = 0; lcv < 8; lcv++) {
+            snprintf(extname,80,"ext-%d", lcv);
+
+            psMetadata* header = psMetadataAlloc();
+
+            psMetadataAdd(header,PS_LIST_TAIL, "MYINT",
+                          PS_TYPE_S32, PS_META_PRIMITIVE,
+                          "psS32 Item", (psS32)lcv);
+
+            psMetadataAdd(header,PS_LIST_TAIL, "MYFLT",
+                          PS_TYPE_F32, PS_META_PRIMITIVE,
+                          "psF32 Item", (float)(1.0f/(float)(1+lcv)));
+
+            psMetadataAdd(header,PS_LIST_TAIL, "MYDBL",
+                          PS_TYPE_F64, PS_META_PRIMITIVE,
+                          "psF64 Item", (double)(1.0/(double)(1+lcv)));
+
+            psMetadataAdd(header,PS_LIST_TAIL, "MYBOOL",
+                          PS_TYPE_BOOL, PS_META_PRIMITIVE,
+                          "psBool Item",
+                          (lcv%2 == 0));
+
+            psMetadataAdd(header,PS_LIST_TAIL, "MYSTR",
+                          PS_TYPE_PTR, PS_META_STR,
+                          "String Item",
+                          extname);
+
+            // set the pixels in the image
+            psBinaryOp(image,image,"=",psScalarAlloc(lcv,PS_TYPE_F32));
+            if (! psFitsWriteImage(fitsFile,header,image,1) ) {
+                psError(PS_ERR_UNKNOWN, false,
+                        "Could not write image.");
+                return false;
+            }
+            if (! psFitsSetExtName(fitsFile,extname) ) {
+                psError(PS_ERR_UNKNOWN, false,
+                        "Could not write extension name.");
+                return false;
+            }
+
+            psFree(header);
+        }
+        psFree(image);
+        psFree(fitsFile);
+    }
+
+    return true;
 }
 
@@ -409,39 +478,107 @@
 
 
-bool makeMulti(void)
+
+static psS32 tst_psFitsReadHeader( void )
 {
-
-    if (access(multiFilename, F_OK) != 0) {
-        psFits* fitsFile = psFitsAlloc(multiFilename);
-
-        if (fitsFile == NULL) {
-            psError(PS_ERR_UNKNOWN, false,
-                    "Could not create 'multi' FITS file.");
-            return false;
-        }
-
-        psImage* image = psImageAlloc(16,16,PS_TYPE_F32);
-
-        char extname[80];
-        for (int lcv = 0; lcv < 8; lcv++) {
-            // set the pixels in the image
-            psBinaryOp(image,image,"=",psScalarAlloc(lcv,PS_TYPE_F32));
-            if (! psFitsWriteImage(fitsFile,NULL,image,1) ) {
-                psError(PS_ERR_UNKNOWN, false,
-                        "Could not write image.");
-                return false;
-            }
-            snprintf(extname,80,"ext-%d", lcv);
-            if (! psFitsSetExtName(fitsFile,extname) ) {
-                psError(PS_ERR_UNKNOWN, false,
-                        "Could not write extension name.");
-                return false;
-            }
-        }
-        psFree(image);
-        psFree(fitsFile);
-    }
-
-    return true;
+    if (! makeMulti() ) {
+        return 1;
+    }
+
+    psFits* fits = psFitsAlloc(multiFilename);
+
+    int numHDUs = psFitsGetSize(fits);
+
+    if (numHDUs < 8) {
+        psError(PS_ERR_UNKNOWN,true,
+                "The 'multi' FITS file does not have multiple HDUs.");
+        return 2;
+    }
+
+    char extname[80];
+    for (int hdunum = 0; hdunum < numHDUs; hdunum++) {
+        snprintf(extname,80,"ext-%d",hdunum);
+
+        psFitsMoveExtNum(fits,hdunum,false);
+
+        psMetadata* header = psFitsReadHeader(NULL,fits);
+        if (header == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to read header");
+            return 3;
+        }
+
+        psMetadata* header2 = psMetadataAlloc();
+        header2 = psFitsReadHeader(header2,fits);
+        if (header2 == NULL) {
+            psError(PS_ERR_UNKNOWN, false,
+                    "Failed to read header");
+            return 11;
+        }
+
+        if (header->list->size < 1 || header->list->size != header2->list->size) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Reading the header given a NULL input psMetadata differed "
+                    "from giving an existing psMetadata.");
+            return 12;
+        }
+
+        // check for the extra metadata items
+        psS32 intItem = psMetadataLookupS32(header, "MYINT",NULL);
+        psF32 fltItem = psMetadataLookupF32(header, "MYFLT",NULL);
+        psF64 dblItem = psMetadataLookupF64(header, "MYDBL",NULL);
+        psMetadataItem* boolItem = psMetadataLookup(header, "MYBOOL");
+        char* strItem = psMetadataLookupPtr(header, "MYSTR",NULL);
+
+        if (intItem != hdunum) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psS32 metadata item from file.");
+            return 20;
+        }
+
+        if (fabsf(fltItem - 1.0f/(float)(1+hdunum)) > FLT_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psF32 metadata item from file.  Got %f vs %f",
+                    fltItem,1.0f/(float)(1+hdunum));
+            return 21;
+        }
+
+        if (abs(dblItem - 1.0/(double)(1+hdunum)) > DBL_EPSILON) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psF64 metadata item from file.  Got %g vs %g",
+                    dblItem, 1.0/(double)(1+hdunum));
+            return 22;
+        }
+
+        if (boolItem == NULL ||
+                boolItem->type != PS_META_PRIMITIVE ||
+                boolItem->pType != PS_TYPE_BOOL) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve psBool metadata item from file.");
+            return 23;
+        }
+
+        if (strItem == NULL || strncmp(strItem,extname,strlen(extname)) != 0) {
+            psError(PS_ERR_UNKNOWN, true,
+                    "Failed to retrieve string metadata item from file.  Got '%s' vs '%s' (%d)",
+                    strItem,extname,strlen(extname));
+            return 24;
+        }
+
+        psFree(header);
+        psFree(header2);
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"following should be an error (input psFits = NULL)");
+    psMetadata* header = psFitsReadHeader(NULL,NULL);
+
+    if (header != NULL || psErrorGetStackSize() != 1) {
+        psError(PS_ERR_UNKNOWN, true,
+                "psFitsReadHeader didn't error on a NULL psFits.");
+        return 30;
+    }
+
+
+    psFree(fits);
+
+    return 0;
 }
-
