Index: trunk/psLib/src/fits/psFitsTable.c
===================================================================
--- trunk/psLib/src/fits/psFitsTable.c	(revision 24497)
+++ trunk/psLib/src/fits/psFitsTable.c	(revision 24512)
@@ -390,9 +390,11 @@
 
 
-bool psFitsInsertTable(psFits* fits,
-                       const psMetadata* header,
-                       const psArray* table,
-                       const char *extname,
-                       bool after)
+static bool fitsInsertTable(psFits* fits,             // FITS file
+                            const psMetadata* header, // FITS header to write
+                            const psArray* table,     // Table to write
+                            const char *extname,      // Extension name to give table
+                            bool after,               // Write table after current extension?
+                            bool writeData            // Write data?
+                            )
 {
     PS_ASSERT_FITS_NON_NULL(fits, false);
@@ -403,5 +405,5 @@
 
     long numRows = table->n;
-    if (numRows < 1) {
+    if (writeData && numRows < 1) {
         // no table data, what can I do?
         psError(PS_ERR_BAD_PARAMETER_SIZE, true,
@@ -504,5 +506,5 @@
         fits_create_tbl(fits->fd,
                         BINARY_TBL,
-                        table->n, // number of rows in table
+                        writeData ? numRows : 0, // number of rows in table
                         numColumns, // number of columns in table
                         (char**)columnNames->data, // names of the columns
@@ -524,5 +526,5 @@
         // Insert the table
         fits_insert_btbl(fits->fd,
-                         table->n, // number of rows in table
+                         writeData ? numRows : 0, // number of rows in table
                          numColumns, // number of columns in table
                          (char**)columnNames->data, // names of the columns
@@ -562,76 +564,78 @@
 
     // cfitsio requires that we write the data by columns --- urgh!
-    psMetadataIteratorSet(colSpecsIter, PS_LIST_HEAD);
-    for (long colNum = 1; (colSpecItem = psMetadataGetAndIncrement(colSpecsIter)); colNum++) {
-        // Note: colNum is unit-indexed, because it's for cfitsio
-        colSpec *spec = colSpecItem->data.V; // The specification
-        if (PS_DATA_IS_PRIMITIVE(spec->type)) {
-            size_t dataSize = PSELEMTYPE_SIZEOF(spec->type); // Size (in bytes) of this type
-            psVector *columnData = psVectorAlloc(table->n, spec->type); // The raw row data, to be written
-            psVectorInit(columnData, 0);
-            for (long i = 0; i < table->n; i++) {
-                psMetadata *row = table->data[i]; // The row of interest
-                psMetadataItem *dataItem = psMetadataLookup(row, colSpecItem->name); // The value of interest
-                memcpy(&columnData->data.U8[i * dataSize], &dataItem->data, dataSize);
+    if (writeData) {
+        psMetadataIteratorSet(colSpecsIter, PS_LIST_HEAD);
+        for (long colNum = 1; (colSpecItem = psMetadataGetAndIncrement(colSpecsIter)); colNum++) {
+            // Note: colNum is unit-indexed, because it's for cfitsio
+            colSpec *spec = colSpecItem->data.V; // The specification
+            if (PS_DATA_IS_PRIMITIVE(spec->type)) {
+                size_t dataSize = PSELEMTYPE_SIZEOF(spec->type); // Size (in bytes) of this type
+                psVector *columnData = psVectorAlloc(table->n, spec->type); // The raw row data, to be written
+                psVectorInit(columnData, 0);
+                for (long i = 0; i < table->n; i++) {
+                    psMetadata *row = table->data[i]; // The row of interest
+                    psMetadataItem *dataItem = psMetadataLookup(row, colSpecItem->name); // Value of interest
+                    memcpy(&columnData->data.U8[i * dataSize], &dataItem->data, dataSize);
+                }
+
+                int fitsDataType;           // Data type for cfitsio
+                p_psFitsTypeToCfitsio(spec->type, NULL, NULL, &fitsDataType);
+                fits_write_col(fits->fd,
+                               fitsDataType,
+                               colNum, // column number
+                               1, // first row
+                               1, // first element
+                               table->n, // number of rows
+                               columnData->data.U8, // the data
+                               &status);
+                psFree(columnData);
+            } else {
+                switch (spec->type) {
+                  case PS_DATA_STRING: {
+                      psArray *strings = psArrayAlloc(table->n); // Array of strings
+                      for (long i = 0; i < table->n; i++) {
+                          psMetadata *row = table->data[i]; // The row of interest
+                          strings->data[i] = psMemIncrRefCounter(psMetadataLookupStr(NULL, row,
+                                                                                     colSpecItem->name));
+                      }
+                      fits_write_col_str(fits->fd, colNum, 1, 1, table->n, (char**)strings->data, &status);
+                      psFree(strings);
+                      break;
+                  }
+                  case PS_DATA_VECTOR: {
+                      size_t dataSize = PSELEMTYPE_SIZEOF(spec->vectorType); // Size of data, in bytes
+                      psVector *columnData = psVectorAlloc(spec->size * table->n * dataSize, PS_TYPE_U8);
+                      psVectorInit(columnData, 0);
+                      for (long i = 0; i < table->n; i++) {
+                          psMetadata *row = table->data[i]; // The row of interest
+                          psMetadataItem* dataItem = psMetadataLookup(row, colSpecItem->name);
+                          if (dataItem->type != PS_DATA_VECTOR) {
+                              // Just in case --- get a zero instead of some weird result
+                              continue;
+                          }
+                          psVector *vector = dataItem->data.V;
+                          memcpy(&columnData->data.U8[i * dataSize * spec->size], vector->data.U8,
+                                 vector->n * dataSize);
+                      }
+
+                      int fitsDataType;           // Data type for cfitsio
+                      p_psFitsTypeToCfitsio(spec->vectorType, NULL, NULL, &fitsDataType);
+                      fits_write_col(fits->fd, fitsDataType, colNum, 1, 1, table->n * spec->size,
+                                     columnData->data.U8, &status);
+                      psFree(columnData);
+                      break;
+                  }
+                  default:
+                    psAbort("Should never get here.\n");
+                }
             }
 
-            int fitsDataType;           // Data type for cfitsio
-            p_psFitsTypeToCfitsio(spec->type, NULL, NULL, &fitsDataType);
-            fits_write_col(fits->fd,
-                           fitsDataType,
-                           colNum, // column number
-                           1, // first row
-                           1, // first element
-                           table->n, // number of rows
-                           columnData->data.U8, // the data
-                           &status);
-            psFree(columnData);
-        } else {
-            switch (spec->type) {
-            case PS_DATA_STRING: {
-                    psArray *strings = psArrayAlloc(table->n); // Array of strings
-                    for (long i = 0; i < table->n; i++) {
-                        psMetadata *row = table->data[i]; // The row of interest
-                        strings->data[i] = psMemIncrRefCounter(psMetadataLookupStr(NULL, row,
-                                                               colSpecItem->name));
-                    }
-                    fits_write_col_str(fits->fd, colNum, 1, 1, table->n, (char**)strings->data, &status);
-                    psFree(strings);
-                    break;
-                }
-            case PS_DATA_VECTOR: {
-                    size_t dataSize = PSELEMTYPE_SIZEOF(spec->vectorType); // Size of data, in bytes
-                    psVector *columnData = psVectorAlloc(spec->size * table->n * dataSize, PS_TYPE_U8);
-                    psVectorInit(columnData, 0);
-                    for (long i = 0; i < table->n; i++) {
-                        psMetadata *row = table->data[i]; // The row of interest
-                        psMetadataItem* dataItem = psMetadataLookup(row, colSpecItem->name);
-                        if (dataItem->type != PS_DATA_VECTOR) {
-                            // Just in case --- get a zero instead of some weird result
-                            continue;
-                        }
-                        psVector *vector = dataItem->data.V;
-                        memcpy(&columnData->data.U8[i * dataSize * spec->size], vector->data.U8,
-                               vector->n * dataSize);
-                    }
-
-                    int fitsDataType;           // Data type for cfitsio
-                    p_psFitsTypeToCfitsio(spec->vectorType, NULL, NULL, &fitsDataType);
-                    fits_write_col(fits->fd, fitsDataType, colNum, 1, 1, table->n * spec->size,
-                                   columnData->data.U8, &status);
-                    psFree(columnData);
-                    break;
-                }
-            default:
-                psAbort("Should never get here.\n");
+            // Check error status from writing column
+            if (status != 0) {
+                psFitsError(status, true, "Unable to write column %ld of FITS table", colNum);
+                psFree(colSpecsIter);
+                psFree(colSpecs);
+                return false;
             }
-        }
-
-        // Check error status from writing column
-        if (status != 0) {
-            psFitsError(status, true, "Unable to write column %ld of FITS table", colNum);
-            psFree(colSpecsIter);
-            psFree(colSpecs);
-            return false;
         }
     }
@@ -650,4 +654,42 @@
     return true;
 }
+
+
+bool psFitsInsertTable(psFits* fits, const psMetadata* header, const psArray* table, const char *extname,
+                       bool after)
+{
+    PS_ASSERT_FITS_NON_NULL(fits, false);
+    PS_ASSERT_FITS_WRITABLE(fits, false);
+    return fitsInsertTable(fits, header, table, extname, after, true);
+}
+
+bool psFitsWriteTableEmpty(psFits *fits, const psMetadata *header, const psMetadata *columns,
+                           const char *extname)
+{
+    PS_ASSERT_FITS_NON_NULL(fits, false);
+    PS_ASSERT_FITS_WRITABLE(fits, false);
+    if (!psFitsMoveLast(fits)) {
+        psError(PS_ERR_UNKNOWN, false, "Unable to move to last extension to write table");
+        return false;
+    }
+    psArray *table = psArrayAlloc(1);   // Dummy table carrying column definitions
+    table->data[0] = psMemIncrRefCounter((psPtr)columns); // Casting away const
+    bool status = fitsInsertTable(fits, header, table, extname, true, false); // Status of insertion
+    psFree(table);
+    return status;
+}
+
+bool psFitsInsertTableEmpty(psFits *fits, const psMetadata *header, const psMetadata *columns,
+                            const char *extname, bool after)
+{
+    PS_ASSERT_FITS_NON_NULL(fits, false);
+    PS_ASSERT_FITS_WRITABLE(fits, false);
+    psArray *table = psArrayAlloc(1);   // Dummy table carrying column definitions
+    table->data[0] = psMemIncrRefCounter((psPtr)columns); // Casting away const
+    bool status = fitsInsertTable(fits, header, table, extname, after, false); // Status of insertion
+    psFree(table);
+    return status;
+}
+
 
 bool psFitsUpdateTable(psFits* fits,
Index: trunk/psLib/src/fits/psFitsTable.h
===================================================================
--- trunk/psLib/src/fits/psFitsTable.h	(revision 24497)
+++ trunk/psLib/src/fits/psFitsTable.h	(revision 24512)
@@ -90,4 +90,12 @@
 );
 
+/// Write an empty table
+bool psFitsWriteTableEmpty(
+    psFits *fits,                       ///< FITS file pointer
+    const psMetadata *header,           ///< Header to write
+    const psMetadata *columns,          ///< Column definitions; no data used except name,type
+    const char *extname                 ///< Extension name for table
+    );
+
 /** Inserts a whole FITS table. A new HDU of the type BINTABLE is inserted either
  *  before or after, depending on the AFTER parameter, the current HDU.
@@ -104,4 +112,14 @@
     bool after    ///< TRUE if insert is done after CHDU, otherwise table is inserted before CHDU
 );
+
+/// Insert an empty table
+bool psFitsInsertTableEmpty(
+    psFits *fits,              ///< FITS file pointer
+    const psMetadata *header,  ///< Header to write
+    const psMetadata *columns, ///< Column definitions; no data used except name,type
+    const char *extname,       ///< Extension name for table
+    bool after                 ///< Insert after current HDU?
+    );
+
 
 /** Updates a FITS table.  The current HDU type must be either
