Index: trunk/Ohana/src/libfits/include/gfitsio.h
===================================================================
--- trunk/Ohana/src/libfits/include/gfitsio.h	(revision 15649)
+++ trunk/Ohana/src/libfits/include/gfitsio.h	(revision 15655)
@@ -158,4 +158,6 @@
 int     gfits_extension_is_compressed  PROTO((Header *header));
 int     gfits_tile_size                PROTO((Matrix *matrix, int *otile, int *ztile));
+int     gfits_uncompressed_data_pixsize PROTO((char *cmptype));
+int     gfits_vartable_heap_pixsize    PROTO((char format));
 
 /******************************* Table functions *************/
Index: trunk/Ohana/src/libfits/matrix/F_compress_M.c
===================================================================
--- trunk/Ohana/src/libfits/matrix/F_compress_M.c	(revision 15649)
+++ trunk/Ohana/src/libfits/matrix/F_compress_M.c	(revision 15655)
@@ -37,4 +37,6 @@
   float zscale, zzero;
 
+  int zdata_pixsize, odata_pixsize, idata_pixsize;
+
   int *ztile = NULL;
   int *otile = NULL;
@@ -43,4 +45,5 @@
   char **optvalue = NULL;
   char *out = NULL;
+  char *zdata = NULL;
 
   // is ZIMAGE present?
@@ -161,7 +164,25 @@
   }
 
-  // max_tile_size is in pixels
-  bytes_per_pixel = abs(header[0].bitpix) / 8;
-  ALLOCATE (out, char, bytes_per_pixel*max_tile_size);
+  // this takes place in three major steps:
+  // 1) read the table data : zdef.format tells the size of the varlength heap element
+  // 2) uncompress the data : pixel size depends on compression method
+  // 3) distribute data to the tiles : output pixel size depends on header.bitpix
+
+  // heapdata -> zdata -> odata -> idata
+
+  // heapdata.pixsize : zdef.format
+  // zdata.pixsize : depends on compression
+  // odata.pixsize : depends on compression
+  // idata.pixsize : header.bitpix
+
+  // size of an element in the vartable heap section
+  zdata_pixsize = gfits_vartable_heap_pixsize (zdef.format);
+
+  // size of a pixel in the final image
+  idata_pixsize = abs(header[0].bitpix) / 8;
+
+  // size of a pixel in the output from the decompression routine
+  odata_pixsize = gfits_uncompressed_data_pixsize (cmptype);
+  ALLOCATE (out, char, odata_pixsize*max_tile_size);
 
   // uncompress the data
@@ -172,53 +193,16 @@
     Nout = gfits_tile_size (matrix, otile, ztile);
 
-    switch (zdef.format) {
-      // gfits_varlength returns a pointer to a chunk of Nzdata of data elements starting at zdata.
-      // uncompress_data uncompresses from zdata to the temporary output buffer which must be allocated
-
-      // XXX need to have an API to send the user data
-
-      // XXX need to byte-swap the table column; this needs to be worked out more clearly
-      // in the APIs: do the table read / column extract functions swap or not?.  we have
-      // put the byte-swapping in gifts_varlength_column_pointer, but this is fairly weak.
-
-      // XXX inconsistency between data element size between compressed data, uncompressed data, 
-      // and output pixel data.....
-
-      case 'B': {
-	char *zdata;
-	zdata = gfits_varlength_column_pointer (ftable, &zdef, i, &Nzdata);
-	if (!zdata) return (FALSE);
-	if (!gfits_byteswap_zdata ((char *)zdata, Nzdata, 8)) return (FALSE);
-	if (!gfits_uncompress_data ((char *)zdata, Nzdata, cmptype, optname, optvalue, Noptions, out, &Nout, bytes_per_pixel)) return (FALSE);
-	if (!gfits_distribute_data (matrix, 8, out, Nout, otile, ztile, zscale, zzero)) return (FALSE);
- 	// copy the uncompressed pixels into their correct locations 	    
-	break;
-      }
-
-      case 'I': {
-	short *zdata;
-	zdata = gfits_varlength_column_pointer (ftable, &zdef, i, &Nzdata);
-	if (!zdata) return (FALSE);
-	if (!gfits_byteswap_zdata ((char *)zdata, Nzdata, 16)) return (FALSE);
-	if (!gfits_uncompress_data ((char *)zdata, Nzdata, cmptype, optname, optvalue, Noptions, out, &Nout, bytes_per_pixel)) return (FALSE);
-	if (!gfits_distribute_data (matrix, 16, out, Nout, otile, ztile, zscale, zzero)) return (FALSE);
- 	// copy the uncompressed pixels into their correct locations 	    
-	break;
-      }
-
-      case 'J': {
-	int *zdata;
-	if (!zdata) return (FALSE);
-	if (!gfits_byteswap_zdata ((char *)zdata, Nzdata, 32)) return (FALSE);
-	if (!gfits_uncompress_data ((char *)zdata, Nzdata, cmptype, optname, optvalue, Noptions, out, &Nout, bytes_per_pixel)) return (FALSE);
-	if (!gfits_distribute_data (matrix, 32, out, Nout, otile, ztile, zscale, zzero)) return (FALSE);
- 	// copy the uncompressed pixels into their correct locations 	    
-	break;
-      }
-
-      default:
-	fprintf (stderr, "invalid size for compressed data: %c\n", zdef.format);  
-	return (FALSE);
-    }
+    zdata = gfits_varlength_column_pointer (ftable, &zdef, i, &Nzdata);
+    if (!zdata) return (FALSE);
+
+    // XXX not certain this is the correct place to do the swap (or if zdata_pixsize is
+    // the correct size to guide the swap)
+    if (!gfits_byteswap_zdata (zdata, Nzdata, zdata_pixsize)) return (FALSE);
+
+    // gfits_uncompress_data uncompresses from zdata to the temporary output buffer which must be allocated
+    if (!gfits_uncompress_data ((char *)zdata, Nzdata, cmptype, optname, optvalue, Noptions, out, &Nout, bytes_per_pixel)) return (FALSE);
+
+    // copy the uncompressed pixels into their correct locations 	    
+    if (!gfits_distribute_data (matrix, odata_pixsize, out, Nout, otile, ztile, zscale, zzero)) return (FALSE);
 
     // update the tile counters, carrying to the next dimension if needed
@@ -234,4 +218,15 @@
   return (TRUE);
 }
+
+// gfits_varlength returns a pointer to a chunk of Nzdata of data elements starting at zdata.
+
+// XXX need to have an API to send the user data
+
+// XXX need to byte-swap the table column; this needs to be worked out more clearly
+// in the APIs: do the table read / column extract functions swap or not?.  we have
+// put the byte-swapping in gifts_varlength_column_pointer, but this is fairly weak.
+
+// XXX inconsistency between data element size between compressed data, uncompressed data, 
+// and output pixel data.....
 
 int gfits_tile_size (Matrix *matrix, int *otile, int *ztile) {
@@ -321,11 +316,11 @@
   for (i = 0; i < Nline; i++) {
     switch (bitpix) {
-      case 8:
+      case 1:
 	SETUP_INSIZE (char, 1);
 	break;
-      case 16: 
+      case 2: 
 	SETUP_INSIZE (short, 2);
 	break; 
-      case 32:
+      case 4:
 	SETUP_INSIZE (int, 4);
 	break;
@@ -361,5 +356,5 @@
 }
 
-int gfits_byteswap_zdata (char *zdata, int Nzdata, int bitpix) {
+int gfits_byteswap_zdata (char *zdata, int Nzdata, int pixsize) {
 
 # ifdef BYTE_SWAP
@@ -368,11 +363,9 @@
   char tmp;
 
-  switch (bitpix) {
-    case +8:
-    case -8:
+  switch (pixsize) {
+    case 1:
       break;
 
-    case +16:
-    case -16:
+    case 2:
       for (i = 0; i < Nzdata; i+=2) {
 	tmp = zdata[i];
@@ -382,6 +375,5 @@
       break;
 
-    case +32:
-    case -32:
+    case 4:
       for (i = 0; i < Nzdata; i+=4) {
 	tmp = zdata[i+1];
@@ -394,6 +386,5 @@
       break;
 
-    case +64:
-    case -64:
+    case 8:
       for (i = 0; i < Nzdata; i+=8) {
 	tmp = zdata[i+0];
@@ -444,2 +435,34 @@
     return (FALSE);
 }
+
+int gfits_uncompressed_data_pixsize (char *cmptype) {
+
+  if (!strcasecmp(cmptype, "GZIP")) {
+    return (0);
+  }
+  if (!strcasecmp(cmptype, "RICE") || !strcasecmp(cmptype, "RICE_1")) {
+    return (4);
+  }
+  if (!strcasecmp(cmptype, "PLIO")) {
+    return (1);
+  }
+  if (!strcasecmp(cmptype, "HCOMPRESS")) {
+    return (4);
+  }
+  return (0);
+}
+
+int gfits_vartable_heap_pixsize (char format) {
+
+  if (format == 'B') {
+      return (1);
+  }
+  if (format == 'I') {
+      return (2);
+  }
+  if (format == 'J') {
+      return (4);
+  }
+  fprintf (stderr, "invalid size for compressed data: %c\n", format);  
+  abort ();
+}
