Index: trunk/psLib/src/astronomy/psMetadata.c
===================================================================
--- trunk/psLib/src/astronomy/psMetadata.c	(revision 3009)
+++ trunk/psLib/src/astronomy/psMetadata.c	(revision 3025)
@@ -12,6 +12,6 @@
 *  @author Ross Harman, MHPCC
 *
-*  @version $Revision: 1.48 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2005-01-13 23:27:06 $
+*  @version $Revision: 1.49 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-17 20:58:20 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -495,4 +495,5 @@
 psMetadataLookupNumTYPE(F64)
 psMetadataLookupNumTYPE(S32)
+psMetadataLookupNumTYPE(Bool)
 
 psMetadataItem* psMetadataGet(psMetadata *md, psS32 where)
Index: trunk/psLib/src/astronomy/psMetadata.h
===================================================================
--- trunk/psLib/src/astronomy/psMetadata.h	(revision 3009)
+++ trunk/psLib/src/astronomy/psMetadata.h	(revision 3025)
@@ -11,6 +11,6 @@
 *  @author Ross Harman, MHPCC
 *
-*  @version $Revision: 1.33 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2005-01-13 21:09:39 $
+*  @version $Revision: 1.34 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-17 20:58:20 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -240,4 +240,18 @@
 );
 
+/** Find an item in the metadata collection based on key name and return its boolean value.
+ *
+ *  Items may be found in the metadata by providing a key. If the key is
+ *  non-unique, the value of the first item is returned. If the item is not found, zero is
+ *  returned.
+ *
+ * @return psBool : Value of metadata item.
+ */
+psBool psMetadataLookupBool(
+    psMetadata *md,            ///< Metadata collection to lookup metadata item.
+    const char *key,           ///< Name of metadata key.
+    psBool *status              ///< Status of lookup.
+);
+
 /** Find an item in the metadata collection based on key name and return its integer value.
  *
Index: trunk/psLib/src/collections/psMetadata.c
===================================================================
--- trunk/psLib/src/collections/psMetadata.c	(revision 3009)
+++ trunk/psLib/src/collections/psMetadata.c	(revision 3025)
@@ -12,6 +12,6 @@
 *  @author Ross Harman, MHPCC
 *
-*  @version $Revision: 1.48 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2005-01-13 23:27:06 $
+*  @version $Revision: 1.49 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-17 20:58:20 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -495,4 +495,5 @@
 psMetadataLookupNumTYPE(F64)
 psMetadataLookupNumTYPE(S32)
+psMetadataLookupNumTYPE(Bool)
 
 psMetadataItem* psMetadataGet(psMetadata *md, psS32 where)
Index: trunk/psLib/src/collections/psMetadata.h
===================================================================
--- trunk/psLib/src/collections/psMetadata.h	(revision 3009)
+++ trunk/psLib/src/collections/psMetadata.h	(revision 3025)
@@ -11,6 +11,6 @@
 *  @author Ross Harman, MHPCC
 *
-*  @version $Revision: 1.33 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2005-01-13 21:09:39 $
+*  @version $Revision: 1.34 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-17 20:58:20 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -240,4 +240,18 @@
 );
 
+/** Find an item in the metadata collection based on key name and return its boolean value.
+ *
+ *  Items may be found in the metadata by providing a key. If the key is
+ *  non-unique, the value of the first item is returned. If the item is not found, zero is
+ *  returned.
+ *
+ * @return psBool : Value of metadata item.
+ */
+psBool psMetadataLookupBool(
+    psMetadata *md,            ///< Metadata collection to lookup metadata item.
+    const char *key,           ///< Name of metadata key.
+    psBool *status              ///< Status of lookup.
+);
+
 /** Find an item in the metadata collection based on key name and return its integer value.
  *
Index: trunk/psLib/src/collections/psVector.h
===================================================================
--- trunk/psLib/src/collections/psVector.h	(revision 3009)
+++ trunk/psLib/src/collections/psVector.h	(revision 3025)
@@ -11,6 +11,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.25 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-10-27 00:57:31 $
+ *  @version $Revision: 1.26 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 20:58:21 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -37,4 +37,5 @@
 
     union {
+        psBool B;               ///< Boolean data.
         psU8* U8;               ///< Unsigned 8-bit integer data.
         psU16* U16;             ///< Unsigned 16-bit integer data.
@@ -63,5 +64,5 @@
 /** Allocate a vector.
  *
- *  Uses psLib memory allocation functions to create a vector collection of 
+ *  Uses psLib memory allocation functions to create a vector collection of
  *  data as defined by the psType type.
  *
@@ -75,6 +76,6 @@
 /** Reallocate a vector.
  *
- *  Uses psLib memory allocation functions to reallocate a vector collection 
- *  of data. The vector is reallocated according to the psType type member 
+ *  Uses psLib memory allocation functions to reallocate a vector collection
+ *  of data. The vector is reallocated according to the psType type member
  *  contained within the vector.
  *
@@ -89,6 +90,6 @@
 /** Recycle a vector.
  *
- *  Uses psLib memory allocation functions to reallocate a vector collection 
- *  of data. The vector is reallocated according to the psElemType type 
+ *  Uses psLib memory allocation functions to reallocate a vector collection
+ *  of data. The vector is reallocated according to the psElemType type
  *  parameter.
  *
@@ -107,5 +108,5 @@
 /** Copy a vector, converting types.
  *
- *  Performs a deep copy of the elements of one psVector to a new psVector, 
+ *  Performs a deep copy of the elements of one psVector to a new psVector,
  *  converting numeric types to a specified type.
  *
@@ -133,6 +134,6 @@
 /** Creates an array of indices based on sort ordered of array.
  *
- *  Sorts a vector and creates an integer array holding indices of 
- *  sorted float values based on pre-sort index positions.  
+ *  Sorts a vector and creates an integer array holding indices of
+ *  sorted float values based on pre-sort index positions.
  *
  *  @return  psVector*     vector of the indices of sort.
Index: trunk/psLib/src/dataIO/psFileUtilsErrors.dat
===================================================================
--- trunk/psLib/src/dataIO/psFileUtilsErrors.dat	(revision 3009)
+++ trunk/psLib/src/dataIO/psFileUtilsErrors.dat	(revision 3025)
@@ -34,5 +34,5 @@
 psFits_NOT_IMAGE_TYPE                  Current FITS HDU type must be an image.
 psFits_NOT_TABLE_TYPE                  Current FITS HDU type must be a table.
-psFits_TABLE_FIRSTROW_NULL             Can't create a table without the first row, where table column information is derived.
+psFits_TABLE_EMPTY                     Can't create a table without any rows.
 psFits_CFITSIO_ERROR                   CFITSIO error: %s
 psFits_METATYPE_INVALID                Specified FITS metadata type, %c, is not supported.
Index: trunk/psLib/src/dataIO/psFileUtilsErrors.h
===================================================================
--- trunk/psLib/src/dataIO/psFileUtilsErrors.h	(revision 3009)
+++ trunk/psLib/src/dataIO/psFileUtilsErrors.h	(revision 3025)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.7 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-01-13 01:54:25 $
+ *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 20:58:21 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -56,5 +56,5 @@
 #define PS_ERRORTEXT_psFits_NOT_IMAGE_TYPE "Current FITS HDU type must be an image."
 #define PS_ERRORTEXT_psFits_NOT_TABLE_TYPE "Current FITS HDU type must be a table."
-#define PS_ERRORTEXT_psFits_TABLE_FIRSTROW_NULL "Can't create a table without the first row, where table column information is derived."
+#define PS_ERRORTEXT_psFits_TABLE_EMPTY "Can't create a table without any rows."
 #define PS_ERRORTEXT_psFits_CFITSIO_ERROR "CFITSIO error: %s"
 #define PS_ERRORTEXT_psFits_METATYPE_INVALID "Specified FITS metadata type, %c, is not supported."
Index: trunk/psLib/src/dataIO/psFits.c
===================================================================
--- trunk/psLib/src/dataIO/psFits.c	(revision 3009)
+++ trunk/psLib/src/dataIO/psFits.c	(revision 3025)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-01-14 19:40:33 $
+ *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 20:58:21 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -165,14 +165,14 @@
     switch (type) {
     case PS_TYPE_BOOL:
-        *fitsType = "1L";
+        *fitsType = psStringCopy("1L");
         break;
     case PS_TYPE_S32:
-        *fitsType = "1J";
+        *fitsType = psStringCopy("1J");
         break;
     case PS_TYPE_F32:
-        *fitsType = "1E";
+        *fitsType = psStringCopy("1E");
         break;
     case PS_TYPE_F64:
-        *fitsType = "1D";
+        *fitsType = psStringCopy("1D");
         break;
         // XXX: Handle other types, e.g., Vectors, etc.
@@ -1028,5 +1028,5 @@
 
     // the row parameter in the proper range?
-    if (row < 1 || row > numRows) {
+    if (row < 0 || row >= numRows) {
         psError(PS_ERR_BAD_PARAMETER_VALUE, true,
                 PS_ERRORTEXT_psFits_ROW_INVALID,
@@ -1056,7 +1056,7 @@
         if (status == 0) {
 
-            #define READ_TABLE_ROW_CASE(FITSTYPE, TYPE) \
+            #define READ_TABLE_ROW_CASE(FITSTYPE, NATIVETYPE, TYPE) \
         case FITSTYPE: { \
-                ps##TYPE value; \
+                NATIVETYPE value; \
                 int anynul = 0; \
                 fits_read_col(fits->p_fd, FITSTYPE, col,row+1, \
@@ -1064,16 +1064,30 @@
                 if (anynul == 0) { \
                     psMetadataAdd(data,PS_LIST_TAIL, name, \
-                                  PS_TYPE_S32, PS_META_PRIMITIVE, \
-                                  "", value); \
+                                  PS_TYPE_##TYPE, PS_META_PRIMITIVE, \
+                                  "", (ps##TYPE)value); \
                 } \
-            } \
-            break;
+                break; \
+            }
 
             switch (typecode) {
             case TBYTE:
             case TSHORT:
-                READ_TABLE_ROW_CASE(TLONG, S32)
-                READ_TABLE_ROW_CASE(TFLOAT, F32)
-                READ_TABLE_ROW_CASE(TDOUBLE, F64)
+            case TLONGLONG:
+                READ_TABLE_ROW_CASE(TLONG, long, S32)
+                READ_TABLE_ROW_CASE(TFLOAT, float, F32)
+                READ_TABLE_ROW_CASE(TDOUBLE, double, F64)
+                READ_TABLE_ROW_CASE(TLOGICAL, bool, BOOL);
+            case TSTRING: {
+                    char* value;
+                    int anynul = 0;
+                    fits_read_col(fits->p_fd, TSTRING, col,row+1,
+                                  1, 1, NULL, &value, &anynul, &status);
+                    if (anynul == 0) {
+                        psMetadataAdd(data,PS_LIST_TAIL, name,
+                                      PS_TYPE_PTR, PS_META_STR,
+                                      "", value);
+                    }
+                    break;
+                }
             default:
                 psTrace("psFits.psFitsReadTableRow", 2,
@@ -1266,7 +1280,5 @@
     // get the size of the FITS table
     long numRows = 0;
-    int numCols = 0;
     fits_get_num_rows(fits->p_fd, &numRows, &status);
-    fits_get_num_cols(fits->p_fd, &numCols, &status);
     if ( status != 0) {
         char fitsErr[MAX_STRING_LENGTH];
@@ -1278,5 +1290,5 @@
     }
 
-    psArray* table = psArrayAlloc(numCols);
+    psArray* table = psArrayAlloc(numRows);
 
     for (int row = 0; row < numRows; row++) {
@@ -1293,4 +1305,5 @@
 {
     int status = 0;
+    psMetadataItem* item;
 
     if (fits == NULL) {
@@ -1307,11 +1320,16 @@
 
     int rows = table->n;
+    if (rows < 1) {
+        // no table data, what can I do?
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                PS_ERRORTEXT_psFits_TABLE_EMPTY);
+        return false;
+    }
 
     // find all the columns needed
-    psArray* columns = psArrayAlloc(16);
+    psArray* columns = psArrayAlloc(((psMetadata*)table->data[0])->list->size);
     columns->n=0;
 
     // find the unique items in the array of metadata 'rows'
-    psMetadataItem* item;
     for (int row=0; row < rows; row++) {
         psMetadata* rowMeta = table->data[row];
@@ -1329,5 +1347,5 @@
                     }
                     if (! found) {
-                        psArrayAdd(columns, columns->nalloc, item);
+                        psArrayAdd(columns, columns->nalloc, psMemIncrRefCounter(item));
                     }
                 }
@@ -1347,5 +1365,5 @@
     for (int n=0; n < columns->n; n++) {
         char* fitsType;
-        columnNames->data[n] = ((psMetadataItem*)columns->data[n])->name;
+        columnNames->data[n] = psMemIncrRefCounter(((psMetadataItem*)columns->data[n])->name);
         if ( ! convertPsTypeToBinaryTForm(((psMetadataItem*)columns->data[n])->pType,
                                           &fitsType)) {
@@ -1366,12 +1384,11 @@
                     &status);
 
+    psFree(columnNames);
+    psFree(columnTypes);
+
     // fill in the table elements with data
     for (int n = 0; n < columns->n; n++) {
         int row;
         item = columns->data[n];
-        psArray* columnItems = psArrayAlloc(table->n);
-        for (row = 0; row < table->n; row++) {
-            columnItems->data[row] = psMetadataLookup(table->data[row],item->name);
-        }
 
         if (item->type == PS_META_PRIMITIVE) {
@@ -1380,8 +1397,9 @@
             case PS_TYPE_S32:
                 for (row = 0; row < table->n; row++) {
-                    col->data.S32[row] = item->data.S32;
+                    col->data.S32[row] = psMetadataLookupS32(
+                                             table->data[row],item->name,NULL);
                 }
                 fits_write_col_int(fits->p_fd,
-                                   n, // column number
+                                   n+1, // column number
                                    1, // firstrow
                                    1, // firstelem
@@ -1392,8 +1410,9 @@
             case PS_TYPE_F32:
                 for (row = 0; row < table->n; row++) {
-                    col->data.F32[row] = item->data.F32;
+                    col->data.F32[row] = psMetadataLookupF32(
+                                             table->data[row],item->name,NULL);
                 }
                 fits_write_col_flt(fits->p_fd,
-                                   n, // column number
+                                   n+1, // column number
                                    1, // firstrow
                                    1, // firstelem
@@ -1402,10 +1421,11 @@
                                    &status);
                 break;
-            case PS_TYPE_S64:
+            case PS_TYPE_F64:
                 for (row = 0; row < table->n; row++) {
-                    col->data.F64[row] = item->data.F64;
+                    col->data.F64[row] = psMetadataLookupF64(
+                                             table->data[row],item->name,NULL);
                 }
                 fits_write_col_dbl(fits->p_fd,
-                                   n, // column number
+                                   n+1, // column number
                                    1, // firstrow
                                    1, // firstelem
@@ -1414,14 +1434,22 @@
                                    &status);
                 break;
+            case PS_TYPE_BOOL:
+                for (row = 0; row < table->n; row++) {
+                    col->data.S8[row] = psMetadataLookupBool(
+                                            table->data[row],item->name,NULL);
+                }
+                fits_write_col_log(fits->p_fd,
+                                   n+1, // column number
+                                   1, // firstrow
+                                   1, // firstelem
+                                   table->n, // nelements
+                                   col->data.S8,
+                                   &status);
+                break;
             default:
                 // XXX: error message
-                psFree(col);
-                psFree(columnItems);
-                psFree(columnNames);
-                psFree(columnTypes);
-                psFree(columns);
-                return false;
+                break;
             }
-
+            psFree(col);
         } else if (item->type == PS_META_STR) {
             psArray* col = psArrayAlloc(table->n);
@@ -1436,6 +1464,9 @@
                                (char**)col->data,
                                &status);
-        }
-    }
+            psFree(col);
+        }
+    }
+
+    psFree(columns);
 
     return true;
Index: trunk/psLib/src/fileUtils/psFileUtilsErrors.dat
===================================================================
--- trunk/psLib/src/fileUtils/psFileUtilsErrors.dat	(revision 3009)
+++ trunk/psLib/src/fileUtils/psFileUtilsErrors.dat	(revision 3025)
@@ -34,5 +34,5 @@
 psFits_NOT_IMAGE_TYPE                  Current FITS HDU type must be an image.
 psFits_NOT_TABLE_TYPE                  Current FITS HDU type must be a table.
-psFits_TABLE_FIRSTROW_NULL             Can't create a table without the first row, where table column information is derived.
+psFits_TABLE_EMPTY                     Can't create a table without any rows.
 psFits_CFITSIO_ERROR                   CFITSIO error: %s
 psFits_METATYPE_INVALID                Specified FITS metadata type, %c, is not supported.
Index: trunk/psLib/src/fileUtils/psFileUtilsErrors.h
===================================================================
--- trunk/psLib/src/fileUtils/psFileUtilsErrors.h	(revision 3009)
+++ trunk/psLib/src/fileUtils/psFileUtilsErrors.h	(revision 3025)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.7 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-01-13 01:54:25 $
+ *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 20:58:21 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -56,5 +56,5 @@
 #define PS_ERRORTEXT_psFits_NOT_IMAGE_TYPE "Current FITS HDU type must be an image."
 #define PS_ERRORTEXT_psFits_NOT_TABLE_TYPE "Current FITS HDU type must be a table."
-#define PS_ERRORTEXT_psFits_TABLE_FIRSTROW_NULL "Can't create a table without the first row, where table column information is derived."
+#define PS_ERRORTEXT_psFits_TABLE_EMPTY "Can't create a table without any rows."
 #define PS_ERRORTEXT_psFits_CFITSIO_ERROR "CFITSIO error: %s"
 #define PS_ERRORTEXT_psFits_METATYPE_INVALID "Specified FITS metadata type, %c, is not supported."
Index: trunk/psLib/src/fileUtils/psFits.c
===================================================================
--- trunk/psLib/src/fileUtils/psFits.c	(revision 3009)
+++ trunk/psLib/src/fileUtils/psFits.c	(revision 3025)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-01-14 19:40:33 $
+ *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 20:58:21 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -165,14 +165,14 @@
     switch (type) {
     case PS_TYPE_BOOL:
-        *fitsType = "1L";
+        *fitsType = psStringCopy("1L");
         break;
     case PS_TYPE_S32:
-        *fitsType = "1J";
+        *fitsType = psStringCopy("1J");
         break;
     case PS_TYPE_F32:
-        *fitsType = "1E";
+        *fitsType = psStringCopy("1E");
         break;
     case PS_TYPE_F64:
-        *fitsType = "1D";
+        *fitsType = psStringCopy("1D");
         break;
         // XXX: Handle other types, e.g., Vectors, etc.
@@ -1028,5 +1028,5 @@
 
     // the row parameter in the proper range?
-    if (row < 1 || row > numRows) {
+    if (row < 0 || row >= numRows) {
         psError(PS_ERR_BAD_PARAMETER_VALUE, true,
                 PS_ERRORTEXT_psFits_ROW_INVALID,
@@ -1056,7 +1056,7 @@
         if (status == 0) {
 
-            #define READ_TABLE_ROW_CASE(FITSTYPE, TYPE) \
+            #define READ_TABLE_ROW_CASE(FITSTYPE, NATIVETYPE, TYPE) \
         case FITSTYPE: { \
-                ps##TYPE value; \
+                NATIVETYPE value; \
                 int anynul = 0; \
                 fits_read_col(fits->p_fd, FITSTYPE, col,row+1, \
@@ -1064,16 +1064,30 @@
                 if (anynul == 0) { \
                     psMetadataAdd(data,PS_LIST_TAIL, name, \
-                                  PS_TYPE_S32, PS_META_PRIMITIVE, \
-                                  "", value); \
+                                  PS_TYPE_##TYPE, PS_META_PRIMITIVE, \
+                                  "", (ps##TYPE)value); \
                 } \
-            } \
-            break;
+                break; \
+            }
 
             switch (typecode) {
             case TBYTE:
             case TSHORT:
-                READ_TABLE_ROW_CASE(TLONG, S32)
-                READ_TABLE_ROW_CASE(TFLOAT, F32)
-                READ_TABLE_ROW_CASE(TDOUBLE, F64)
+            case TLONGLONG:
+                READ_TABLE_ROW_CASE(TLONG, long, S32)
+                READ_TABLE_ROW_CASE(TFLOAT, float, F32)
+                READ_TABLE_ROW_CASE(TDOUBLE, double, F64)
+                READ_TABLE_ROW_CASE(TLOGICAL, bool, BOOL);
+            case TSTRING: {
+                    char* value;
+                    int anynul = 0;
+                    fits_read_col(fits->p_fd, TSTRING, col,row+1,
+                                  1, 1, NULL, &value, &anynul, &status);
+                    if (anynul == 0) {
+                        psMetadataAdd(data,PS_LIST_TAIL, name,
+                                      PS_TYPE_PTR, PS_META_STR,
+                                      "", value);
+                    }
+                    break;
+                }
             default:
                 psTrace("psFits.psFitsReadTableRow", 2,
@@ -1266,7 +1280,5 @@
     // get the size of the FITS table
     long numRows = 0;
-    int numCols = 0;
     fits_get_num_rows(fits->p_fd, &numRows, &status);
-    fits_get_num_cols(fits->p_fd, &numCols, &status);
     if ( status != 0) {
         char fitsErr[MAX_STRING_LENGTH];
@@ -1278,5 +1290,5 @@
     }
 
-    psArray* table = psArrayAlloc(numCols);
+    psArray* table = psArrayAlloc(numRows);
 
     for (int row = 0; row < numRows; row++) {
@@ -1293,4 +1305,5 @@
 {
     int status = 0;
+    psMetadataItem* item;
 
     if (fits == NULL) {
@@ -1307,11 +1320,16 @@
 
     int rows = table->n;
+    if (rows < 1) {
+        // no table data, what can I do?
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                PS_ERRORTEXT_psFits_TABLE_EMPTY);
+        return false;
+    }
 
     // find all the columns needed
-    psArray* columns = psArrayAlloc(16);
+    psArray* columns = psArrayAlloc(((psMetadata*)table->data[0])->list->size);
     columns->n=0;
 
     // find the unique items in the array of metadata 'rows'
-    psMetadataItem* item;
     for (int row=0; row < rows; row++) {
         psMetadata* rowMeta = table->data[row];
@@ -1329,5 +1347,5 @@
                     }
                     if (! found) {
-                        psArrayAdd(columns, columns->nalloc, item);
+                        psArrayAdd(columns, columns->nalloc, psMemIncrRefCounter(item));
                     }
                 }
@@ -1347,5 +1365,5 @@
     for (int n=0; n < columns->n; n++) {
         char* fitsType;
-        columnNames->data[n] = ((psMetadataItem*)columns->data[n])->name;
+        columnNames->data[n] = psMemIncrRefCounter(((psMetadataItem*)columns->data[n])->name);
         if ( ! convertPsTypeToBinaryTForm(((psMetadataItem*)columns->data[n])->pType,
                                           &fitsType)) {
@@ -1366,12 +1384,11 @@
                     &status);
 
+    psFree(columnNames);
+    psFree(columnTypes);
+
     // fill in the table elements with data
     for (int n = 0; n < columns->n; n++) {
         int row;
         item = columns->data[n];
-        psArray* columnItems = psArrayAlloc(table->n);
-        for (row = 0; row < table->n; row++) {
-            columnItems->data[row] = psMetadataLookup(table->data[row],item->name);
-        }
 
         if (item->type == PS_META_PRIMITIVE) {
@@ -1380,8 +1397,9 @@
             case PS_TYPE_S32:
                 for (row = 0; row < table->n; row++) {
-                    col->data.S32[row] = item->data.S32;
+                    col->data.S32[row] = psMetadataLookupS32(
+                                             table->data[row],item->name,NULL);
                 }
                 fits_write_col_int(fits->p_fd,
-                                   n, // column number
+                                   n+1, // column number
                                    1, // firstrow
                                    1, // firstelem
@@ -1392,8 +1410,9 @@
             case PS_TYPE_F32:
                 for (row = 0; row < table->n; row++) {
-                    col->data.F32[row] = item->data.F32;
+                    col->data.F32[row] = psMetadataLookupF32(
+                                             table->data[row],item->name,NULL);
                 }
                 fits_write_col_flt(fits->p_fd,
-                                   n, // column number
+                                   n+1, // column number
                                    1, // firstrow
                                    1, // firstelem
@@ -1402,10 +1421,11 @@
                                    &status);
                 break;
-            case PS_TYPE_S64:
+            case PS_TYPE_F64:
                 for (row = 0; row < table->n; row++) {
-                    col->data.F64[row] = item->data.F64;
+                    col->data.F64[row] = psMetadataLookupF64(
+                                             table->data[row],item->name,NULL);
                 }
                 fits_write_col_dbl(fits->p_fd,
-                                   n, // column number
+                                   n+1, // column number
                                    1, // firstrow
                                    1, // firstelem
@@ -1414,14 +1434,22 @@
                                    &status);
                 break;
+            case PS_TYPE_BOOL:
+                for (row = 0; row < table->n; row++) {
+                    col->data.S8[row] = psMetadataLookupBool(
+                                            table->data[row],item->name,NULL);
+                }
+                fits_write_col_log(fits->p_fd,
+                                   n+1, // column number
+                                   1, // firstrow
+                                   1, // firstelem
+                                   table->n, // nelements
+                                   col->data.S8,
+                                   &status);
+                break;
             default:
                 // XXX: error message
-                psFree(col);
-                psFree(columnItems);
-                psFree(columnNames);
-                psFree(columnTypes);
-                psFree(columns);
-                return false;
+                break;
             }
-
+            psFree(col);
         } else if (item->type == PS_META_STR) {
             psArray* col = psArrayAlloc(table->n);
@@ -1436,6 +1464,9 @@
                                (char**)col->data,
                                &status);
-        }
-    }
+            psFree(col);
+        }
+    }
+
+    psFree(columns);
 
     return true;
Index: trunk/psLib/src/fits/psFits.c
===================================================================
--- trunk/psLib/src/fits/psFits.c	(revision 3009)
+++ trunk/psLib/src/fits/psFits.c	(revision 3025)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-01-14 19:40:33 $
+ *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 20:58:21 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -165,14 +165,14 @@
     switch (type) {
     case PS_TYPE_BOOL:
-        *fitsType = "1L";
+        *fitsType = psStringCopy("1L");
         break;
     case PS_TYPE_S32:
-        *fitsType = "1J";
+        *fitsType = psStringCopy("1J");
         break;
     case PS_TYPE_F32:
-        *fitsType = "1E";
+        *fitsType = psStringCopy("1E");
         break;
     case PS_TYPE_F64:
-        *fitsType = "1D";
+        *fitsType = psStringCopy("1D");
         break;
         // XXX: Handle other types, e.g., Vectors, etc.
@@ -1028,5 +1028,5 @@
 
     // the row parameter in the proper range?
-    if (row < 1 || row > numRows) {
+    if (row < 0 || row >= numRows) {
         psError(PS_ERR_BAD_PARAMETER_VALUE, true,
                 PS_ERRORTEXT_psFits_ROW_INVALID,
@@ -1056,7 +1056,7 @@
         if (status == 0) {
 
-            #define READ_TABLE_ROW_CASE(FITSTYPE, TYPE) \
+            #define READ_TABLE_ROW_CASE(FITSTYPE, NATIVETYPE, TYPE) \
         case FITSTYPE: { \
-                ps##TYPE value; \
+                NATIVETYPE value; \
                 int anynul = 0; \
                 fits_read_col(fits->p_fd, FITSTYPE, col,row+1, \
@@ -1064,16 +1064,30 @@
                 if (anynul == 0) { \
                     psMetadataAdd(data,PS_LIST_TAIL, name, \
-                                  PS_TYPE_S32, PS_META_PRIMITIVE, \
-                                  "", value); \
+                                  PS_TYPE_##TYPE, PS_META_PRIMITIVE, \
+                                  "", (ps##TYPE)value); \
                 } \
-            } \
-            break;
+                break; \
+            }
 
             switch (typecode) {
             case TBYTE:
             case TSHORT:
-                READ_TABLE_ROW_CASE(TLONG, S32)
-                READ_TABLE_ROW_CASE(TFLOAT, F32)
-                READ_TABLE_ROW_CASE(TDOUBLE, F64)
+            case TLONGLONG:
+                READ_TABLE_ROW_CASE(TLONG, long, S32)
+                READ_TABLE_ROW_CASE(TFLOAT, float, F32)
+                READ_TABLE_ROW_CASE(TDOUBLE, double, F64)
+                READ_TABLE_ROW_CASE(TLOGICAL, bool, BOOL);
+            case TSTRING: {
+                    char* value;
+                    int anynul = 0;
+                    fits_read_col(fits->p_fd, TSTRING, col,row+1,
+                                  1, 1, NULL, &value, &anynul, &status);
+                    if (anynul == 0) {
+                        psMetadataAdd(data,PS_LIST_TAIL, name,
+                                      PS_TYPE_PTR, PS_META_STR,
+                                      "", value);
+                    }
+                    break;
+                }
             default:
                 psTrace("psFits.psFitsReadTableRow", 2,
@@ -1266,7 +1280,5 @@
     // get the size of the FITS table
     long numRows = 0;
-    int numCols = 0;
     fits_get_num_rows(fits->p_fd, &numRows, &status);
-    fits_get_num_cols(fits->p_fd, &numCols, &status);
     if ( status != 0) {
         char fitsErr[MAX_STRING_LENGTH];
@@ -1278,5 +1290,5 @@
     }
 
-    psArray* table = psArrayAlloc(numCols);
+    psArray* table = psArrayAlloc(numRows);
 
     for (int row = 0; row < numRows; row++) {
@@ -1293,4 +1305,5 @@
 {
     int status = 0;
+    psMetadataItem* item;
 
     if (fits == NULL) {
@@ -1307,11 +1320,16 @@
 
     int rows = table->n;
+    if (rows < 1) {
+        // no table data, what can I do?
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                PS_ERRORTEXT_psFits_TABLE_EMPTY);
+        return false;
+    }
 
     // find all the columns needed
-    psArray* columns = psArrayAlloc(16);
+    psArray* columns = psArrayAlloc(((psMetadata*)table->data[0])->list->size);
     columns->n=0;
 
     // find the unique items in the array of metadata 'rows'
-    psMetadataItem* item;
     for (int row=0; row < rows; row++) {
         psMetadata* rowMeta = table->data[row];
@@ -1329,5 +1347,5 @@
                     }
                     if (! found) {
-                        psArrayAdd(columns, columns->nalloc, item);
+                        psArrayAdd(columns, columns->nalloc, psMemIncrRefCounter(item));
                     }
                 }
@@ -1347,5 +1365,5 @@
     for (int n=0; n < columns->n; n++) {
         char* fitsType;
-        columnNames->data[n] = ((psMetadataItem*)columns->data[n])->name;
+        columnNames->data[n] = psMemIncrRefCounter(((psMetadataItem*)columns->data[n])->name);
         if ( ! convertPsTypeToBinaryTForm(((psMetadataItem*)columns->data[n])->pType,
                                           &fitsType)) {
@@ -1366,12 +1384,11 @@
                     &status);
 
+    psFree(columnNames);
+    psFree(columnTypes);
+
     // fill in the table elements with data
     for (int n = 0; n < columns->n; n++) {
         int row;
         item = columns->data[n];
-        psArray* columnItems = psArrayAlloc(table->n);
-        for (row = 0; row < table->n; row++) {
-            columnItems->data[row] = psMetadataLookup(table->data[row],item->name);
-        }
 
         if (item->type == PS_META_PRIMITIVE) {
@@ -1380,8 +1397,9 @@
             case PS_TYPE_S32:
                 for (row = 0; row < table->n; row++) {
-                    col->data.S32[row] = item->data.S32;
+                    col->data.S32[row] = psMetadataLookupS32(
+                                             table->data[row],item->name,NULL);
                 }
                 fits_write_col_int(fits->p_fd,
-                                   n, // column number
+                                   n+1, // column number
                                    1, // firstrow
                                    1, // firstelem
@@ -1392,8 +1410,9 @@
             case PS_TYPE_F32:
                 for (row = 0; row < table->n; row++) {
-                    col->data.F32[row] = item->data.F32;
+                    col->data.F32[row] = psMetadataLookupF32(
+                                             table->data[row],item->name,NULL);
                 }
                 fits_write_col_flt(fits->p_fd,
-                                   n, // column number
+                                   n+1, // column number
                                    1, // firstrow
                                    1, // firstelem
@@ -1402,10 +1421,11 @@
                                    &status);
                 break;
-            case PS_TYPE_S64:
+            case PS_TYPE_F64:
                 for (row = 0; row < table->n; row++) {
-                    col->data.F64[row] = item->data.F64;
+                    col->data.F64[row] = psMetadataLookupF64(
+                                             table->data[row],item->name,NULL);
                 }
                 fits_write_col_dbl(fits->p_fd,
-                                   n, // column number
+                                   n+1, // column number
                                    1, // firstrow
                                    1, // firstelem
@@ -1414,14 +1434,22 @@
                                    &status);
                 break;
+            case PS_TYPE_BOOL:
+                for (row = 0; row < table->n; row++) {
+                    col->data.S8[row] = psMetadataLookupBool(
+                                            table->data[row],item->name,NULL);
+                }
+                fits_write_col_log(fits->p_fd,
+                                   n+1, // column number
+                                   1, // firstrow
+                                   1, // firstelem
+                                   table->n, // nelements
+                                   col->data.S8,
+                                   &status);
+                break;
             default:
                 // XXX: error message
-                psFree(col);
-                psFree(columnItems);
-                psFree(columnNames);
-                psFree(columnTypes);
-                psFree(columns);
-                return false;
+                break;
             }
-
+            psFree(col);
         } else if (item->type == PS_META_STR) {
             psArray* col = psArrayAlloc(table->n);
@@ -1436,6 +1464,9 @@
                                (char**)col->data,
                                &status);
-        }
-    }
+            psFree(col);
+        }
+    }
+
+    psFree(columns);
 
     return true;
Index: trunk/psLib/src/mathtypes/psVector.h
===================================================================
--- trunk/psLib/src/mathtypes/psVector.h	(revision 3009)
+++ trunk/psLib/src/mathtypes/psVector.h	(revision 3025)
@@ -11,6 +11,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.25 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-10-27 00:57:31 $
+ *  @version $Revision: 1.26 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-17 20:58:21 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -37,4 +37,5 @@
 
     union {
+        psBool B;               ///< Boolean data.
         psU8* U8;               ///< Unsigned 8-bit integer data.
         psU16* U16;             ///< Unsigned 16-bit integer data.
@@ -63,5 +64,5 @@
 /** Allocate a vector.
  *
- *  Uses psLib memory allocation functions to create a vector collection of 
+ *  Uses psLib memory allocation functions to create a vector collection of
  *  data as defined by the psType type.
  *
@@ -75,6 +76,6 @@
 /** Reallocate a vector.
  *
- *  Uses psLib memory allocation functions to reallocate a vector collection 
- *  of data. The vector is reallocated according to the psType type member 
+ *  Uses psLib memory allocation functions to reallocate a vector collection
+ *  of data. The vector is reallocated according to the psType type member
  *  contained within the vector.
  *
@@ -89,6 +90,6 @@
 /** Recycle a vector.
  *
- *  Uses psLib memory allocation functions to reallocate a vector collection 
- *  of data. The vector is reallocated according to the psElemType type 
+ *  Uses psLib memory allocation functions to reallocate a vector collection
+ *  of data. The vector is reallocated according to the psElemType type
  *  parameter.
  *
@@ -107,5 +108,5 @@
 /** Copy a vector, converting types.
  *
- *  Performs a deep copy of the elements of one psVector to a new psVector, 
+ *  Performs a deep copy of the elements of one psVector to a new psVector,
  *  converting numeric types to a specified type.
  *
@@ -133,6 +134,6 @@
 /** Creates an array of indices based on sort ordered of array.
  *
- *  Sorts a vector and creates an integer array holding indices of 
- *  sorted float values based on pre-sort index positions.  
+ *  Sorts a vector and creates an integer array holding indices of
+ *  sorted float values based on pre-sort index positions.
  *
  *  @return  psVector*     vector of the indices of sort.
Index: trunk/psLib/src/sys/psType.h
===================================================================
--- trunk/psLib/src/sys/psType.h	(revision 3009)
+++ trunk/psLib/src/sys/psType.h	(revision 3025)
@@ -11,6 +11,6 @@
 *  @author Ross Harman, MHPCC
 *
-*  @version $Revision: 1.26 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2004-12-21 00:37:51 $
+*  @version $Revision: 1.27 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-17 20:58:21 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -78,5 +78,5 @@
 
 typedef psU8 psMaskType;               ///< the C datatype for a mask image
-
+typedef psBool psBOOL;                 ///< allow psBOOL to be used instead of psBool (for macros)
 
 #define PS_MIN_S8        INT8_MIN      /**< minimum valid psS8 value */
Index: trunk/psLib/src/sysUtils/psType.h
===================================================================
--- trunk/psLib/src/sysUtils/psType.h	(revision 3009)
+++ trunk/psLib/src/sysUtils/psType.h	(revision 3025)
@@ -11,6 +11,6 @@
 *  @author Ross Harman, MHPCC
 *
-*  @version $Revision: 1.26 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2004-12-21 00:37:51 $
+*  @version $Revision: 1.27 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-17 20:58:21 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -78,5 +78,5 @@
 
 typedef psU8 psMaskType;               ///< the C datatype for a mask image
-
+typedef psBool psBOOL;                 ///< allow psBOOL to be used instead of psBool (for macros)
 
 #define PS_MIN_S8        INT8_MIN      /**< minimum valid psS8 value */
Index: trunk/psLib/src/types/psMetadata.c
===================================================================
--- trunk/psLib/src/types/psMetadata.c	(revision 3009)
+++ trunk/psLib/src/types/psMetadata.c	(revision 3025)
@@ -12,6 +12,6 @@
 *  @author Ross Harman, MHPCC
 *
-*  @version $Revision: 1.48 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2005-01-13 23:27:06 $
+*  @version $Revision: 1.49 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-17 20:58:20 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -495,4 +495,5 @@
 psMetadataLookupNumTYPE(F64)
 psMetadataLookupNumTYPE(S32)
+psMetadataLookupNumTYPE(Bool)
 
 psMetadataItem* psMetadataGet(psMetadata *md, psS32 where)
Index: trunk/psLib/src/types/psMetadata.h
===================================================================
--- trunk/psLib/src/types/psMetadata.h	(revision 3009)
+++ trunk/psLib/src/types/psMetadata.h	(revision 3025)
@@ -11,6 +11,6 @@
 *  @author Ross Harman, MHPCC
 *
-*  @version $Revision: 1.33 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2005-01-13 21:09:39 $
+*  @version $Revision: 1.34 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2005-01-17 20:58:20 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -240,4 +240,18 @@
 );
 
+/** Find an item in the metadata collection based on key name and return its boolean value.
+ *
+ *  Items may be found in the metadata by providing a key. If the key is
+ *  non-unique, the value of the first item is returned. If the item is not found, zero is
+ *  returned.
+ *
+ * @return psBool : Value of metadata item.
+ */
+psBool psMetadataLookupBool(
+    psMetadata *md,            ///< Metadata collection to lookup metadata item.
+    const char *key,           ///< Name of metadata key.
+    psBool *status              ///< Status of lookup.
+);
+
 /** Find an item in the metadata collection based on key name and return its integer value.
  *
