Index: trunk/Ohana/src/libfits/header/F_read_H.c
===================================================================
--- trunk/Ohana/src/libfits/header/F_read_H.c	(revision 15657)
+++ trunk/Ohana/src/libfits/header/F_read_H.c	(revision 15743)
@@ -34,4 +34,8 @@
     Nbytes = fread (&header[0].buffer[i*FT_RECORD_SIZE], 
 		    sizeof(char), FT_RECORD_SIZE, f);
+    if (Nbytes != FT_RECORD_SIZE) {
+      perror ("fits read error");
+    }
+    
     header[0].size += Nbytes;
     if (Nbytes != FT_RECORD_SIZE) {
Index: trunk/Ohana/src/libfits/include/gfitsio.h
===================================================================
--- trunk/Ohana/src/libfits/include/gfitsio.h	(revision 15657)
+++ trunk/Ohana/src/libfits/include/gfitsio.h	(revision 15743)
@@ -2,4 +2,5 @@
 
 # include <assert.h>
+# include <errno.h>
 
 # ifndef GFITSIO
@@ -172,4 +173,5 @@
 int   	gfits_fread_ftable             PROTO((FILE *f, FTable *ftable, char *extname)); 
 int   	gfits_fread_ftable_data        PROTO((FILE *f, FTable *ftable));
+int   	gfits_fread_ftable_range       PROTO((FILE *f, FTable *ftable, int start, int Nrows));
 int   	gfits_fread_vtable             PROTO((FILE *f, VTable *vtable, char *extname, int Nrow, int *row));
 int   	gfits_fread_vtable_range       PROTO((FILE *f, VTable *vtable, int start, int Nrows));
@@ -178,4 +180,5 @@
 int     gfits_fwrite_table             PROTO((FILE *f, FTable *table));
 int     gfits_fwrite_vtable            PROTO((FILE *f, VTable *table));
+int     gfits_fwrite_ftable_range      PROTO((FILE *f, FTable *table, int start, int Nrows, int Ndisk, int Ntotal));
 int     gfits_get_bintable_column      PROTO((Header *header, FTable *table, char *label, void **data));
 int     gfits_get_bintable_column_type PROTO((Header *header, char *label, char *type, int *Nval));
Index: trunk/Ohana/src/libfits/matrix/F_load_M.c
===================================================================
--- trunk/Ohana/src/libfits/matrix/F_load_M.c	(revision 15657)
+++ trunk/Ohana/src/libfits/matrix/F_load_M.c	(revision 15743)
@@ -30,4 +30,7 @@
 
   nbytes = fread (matrix[0].buffer, sizeof(char), Nbytes, f);
+  if (nbytes != Nbytes) {
+    perror ("fits matrix read error");
+  }
 
 # ifdef BYTE_SWAP  
Index: trunk/Ohana/src/libfits/matrix/F_read_portion.c
===================================================================
--- trunk/Ohana/src/libfits/matrix/F_read_portion.c	(revision 15657)
+++ trunk/Ohana/src/libfits/matrix/F_read_portion.c	(revision 15743)
@@ -47,4 +47,8 @@
   fseek (f, header.size + Nskip, SEEK_SET);
   nbytes = fread (matrix[0].buffer, sizeof(char), Nbytes, f);
+  if (nbytes != Nbytes) {
+    perror ("fits matrix read error");
+  }
+
   fclose (f);
 
Index: trunk/Ohana/src/libfits/matrix/F_read_segment.c
===================================================================
--- trunk/Ohana/src/libfits/matrix/F_read_segment.c	(revision 15657)
+++ trunk/Ohana/src/libfits/matrix/F_read_segment.c	(revision 15743)
@@ -90,4 +90,8 @@
   fseek (f, Nskip, SEEK_CUR);
   nbytes = fread (matrix[0].buffer, sizeof(char), Nbytes, f);
+  if (nbytes != Nbytes) {
+    perror ("fits matrix read error");
+  }
+
   matrix[0].size = Nbytes;
 
Index: trunk/Ohana/src/libfits/table/F_read_T.c
===================================================================
--- trunk/Ohana/src/libfits/table/F_read_T.c	(revision 15657)
+++ trunk/Ohana/src/libfits/table/F_read_T.c	(revision 15743)
@@ -59,8 +59,50 @@
   Nread = fread (table[0].buffer, sizeof (char), Nbytes, f);
   if (Nread != Nbytes) {
+    perror ("fits read error");
     gfits_free_table  (table);
     return (FALSE);
   }
   table[0].size = Nbytes;
+  return (TRUE);
+}	
+
+/*********************** fits read ftable data ***********************************/
+int gfits_fread_ftable_range (FILE *f, FTable *table, int start, int Nrows) {
+
+  int Nbytes, Nread, Nskip, Nx, Ny;
+
+  /* find disk table size */
+  Nx = table[0].header[0].Naxis[0];
+  Ny = table[0].header[0].Naxis[1];
+
+  // it is an error to ask for data starting out-of-bounds
+  if (start < 0) return (FALSE);
+  if (start >= Ny) return (FALSE);
+  
+  // if we request more data than is available, we will stop at the table end.
+  Nrows = MIN (Nrows, Ny - start);
+
+  Nskip = start * Nx;
+  Nbytes = Nrows * Nx;
+  ALLOCATE (table[0].buffer, char, MAX (Nbytes, 1));
+
+  fseek (f, Nskip, SEEK_CUR);
+
+  Nread = fread (table[0].buffer, sizeof (char), Nbytes, f);
+  if (Nread != Nbytes) {
+    if (ferror (f)) {
+      perror ("fits read error");
+    } else {
+      fprintf (stderr, "unexpected eof\n");
+    }      
+    free (table[0].buffer);
+    return (FALSE);
+  }
+
+  /* modify structure and header to match actual read rows Ny */
+  table[0].header[0].Naxis[1] = Nrows;
+  gfits_modify (table[0].header, "NAXIS2",  "%d", 1, Nrows);
+  table[0].size = gfits_data_size (table[0].header);
+
   return (TRUE);
 }	
@@ -88,4 +130,5 @@
   Nread = fread (buffer, sizeof (char), Nbytes, f);
   if (Nread != Nbytes) {
+    perror ("fits read error");
     free (buffer);
     return (FALSE);
@@ -146,5 +189,8 @@
       fseek (f, offset, SEEK_SET);
       Nread = fread (table[0].buffer[i], sizeof (char), Nx, f);
-      if (Nread != Nx) { return (FALSE); }
+      if (Nread != Nx) { 
+	perror ("fits read error");
+	return (FALSE); 
+      }
     }
 
Index: trunk/Ohana/src/libfits/table/F_read_TH.c
===================================================================
--- trunk/Ohana/src/libfits/table/F_read_TH.c	(revision 15657)
+++ trunk/Ohana/src/libfits/table/F_read_TH.c	(revision 15743)
@@ -46,4 +46,8 @@
     Nbytes = fread (&Theader[0].buffer[i*FT_RECORD_SIZE], 
 		    sizeof(char), FT_RECORD_SIZE, f);
+    if (Nbytes != FT_RECORD_SIZE) {
+      perror ("fits matrix read error");
+    }
+
     Theader[0].size += Nbytes;
     if (Nbytes != FT_RECORD_SIZE) 
Index: trunk/Ohana/src/libfits/table/F_write_T.c
===================================================================
--- trunk/Ohana/src/libfits/table/F_write_T.c	(revision 15657)
+++ trunk/Ohana/src/libfits/table/F_write_T.c	(revision 15743)
@@ -69,2 +69,47 @@
 /* this will add data beyond the end of the table in the file if needed,
    filling intervening gap with 0 */
+
+/*********************** fits read ftable data ***********************************/
+int gfits_fwrite_ftable_range (FILE *f, FTable *ftable, int start, int Nrows, int Ndisk, int Ntotal) {
+
+  int Nbytes, Nwrite, Nskip, Nx, Npad;
+  char *pad;
+
+  if (start < 0) return (FALSE);
+  
+  /* modify vtable to represent full disk table */
+  gfits_modify (ftable[0].header, "NAXIS2", "%d", 1, Ntotal);
+  ftable[0].header[0].Naxis[1] = Ntotal;
+
+  Nx = ftable[0].header[0].Naxis[0]; // final output table size on disk 
+  ftable[0].size = gfits_data_size (ftable[0].header);
+
+  Nskip = start * Nx;
+  Nbytes = Nrows * Nx;
+
+  // cursor must be at start of the table header
+  if (!gfits_fwrite_Theader (f, ftable[0].header)) {
+    fprintf (stderr, "can't write table header");
+    return (FALSE);
+  }
+
+  // cursor must be at start of the table (after table header)
+  fseek (f, Nskip, SEEK_CUR);
+  Nwrite = fwrite (ftable[0].buffer, sizeof (char), Nbytes, f);
+  if (Nwrite != Nbytes) {
+    return (FALSE);
+  }
+
+  if (Ntotal >= Ndisk) {
+    Npad = ftable[0].size - Nx*Ntotal;
+    ALLOCATE (pad, char, Npad);
+    bzero (pad, Npad);
+    Nbytes = fwrite (pad, sizeof (char), Npad, f);
+    free (pad);
+
+    if (Nbytes != Npad) return (FALSE); 
+  }
+
+  return (TRUE);
+}	
+
