Index: /branches/eam_branches/ipp-20111122/Ohana/src/libfits/header/F_modify.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/libfits/header/F_modify.c	(revision 33127)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/libfits/header/F_modify.c	(revision 33128)
@@ -70,5 +70,7 @@
   /* string value.  Quotes must be at least 18 chars apart */
   if (!strcmp (mode, "%s")) {
-    strncpy (data, va_arg (argp, char *), 68);
+    char *ptr = va_arg (argp, char *);
+    if (!ptr) goto invalid;
+    strncpy (data, ptr, 68);
     snprintf (string, 81, "%-8s= '%-18s' / %-s ", field, data, comment);
     goto found_it;
@@ -76,4 +78,6 @@
 
   /* failed to find mode */
+invalid:
+  va_end (argp);
   return (FALSE);
 
@@ -82,5 +86,4 @@
   va_end (argp);
   return (TRUE);
-
 }
 
@@ -143,5 +146,7 @@
   /* comment type of value.  */
   if (!strcmp (mode, "%S")) {
-    strncpy (data, va_arg (argp, char *), 71);
+    char *ptr = va_arg (argp, char *);
+    if (!ptr) goto invalid;
+    strncpy (data, ptr, 71);
     snprintf (string, 81, "%-8s %-71s", field, data);
   }  
@@ -157,5 +162,8 @@
 
     strncpy (data, qs, MAX (MIN (qe - qs, 71), 0));
-    strncpy (comment, va_arg (argp, char *), 80);
+
+    char *ptr = va_arg (argp, char *);
+    if (!ptr) goto invalid;
+    strncpy (comment, ptr, 80);
     gfits_pad_ending (comment, ' ', 82);  /* comment must contain spaces to the end */
     snprintf (string, 81, "%-8s= %s / %-s", field, data, comment);
@@ -167,4 +175,7 @@
   return (TRUE);
 
+invalid:
+  va_end (argp);
+  return (FALSE);
 }
 
Index: /branches/eam_branches/ipp-20111122/Ohana/src/libfits/header/F_print.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/libfits/header/F_print.c	(revision 33127)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/libfits/header/F_print.c	(revision 33128)
@@ -65,9 +65,14 @@
   /* string value.  Quotes must be at least 18 chars apart.  Longer lines will this should be fixed to allow arbitrary string lengths, up to 69 chars */
   if (!strcmp (mode, "%s")) {
-    strcpy (line, va_arg (argp, char *));
+    char *ptr = va_arg (argp, char *);
+    if (!ptr) goto invalid;
+    strcpy (line, ptr);
     line[68] = 0;
     snprintf (string, 81, "%-8s= '%-18s' / %46s ", field, line, blank);
     goto found_it;
   }
+
+invalid:
+  va_end (argp);
   return (FALSE);
 
@@ -76,5 +81,4 @@
   va_end (argp);
   return (TRUE);
-
 }
 
@@ -130,6 +134,8 @@
   if (!strcmp (mode, "%S")) {
     /* we are forcing the entry to be <= 69 char long */
-    strcpy (line, va_arg (argp, char *));
-    line[71] = 0;
+    char *ptr = va_arg (argp, char *);
+    if (!ptr) goto invalid;
+    bzero (line, 80);
+    strncpy (line, ptr, 71);
     snprintf (string, 81, "%-8s %-71s", field, line);
   }  
@@ -146,5 +152,5 @@
 
   /* can't write the comment in gfits_print - use gfits_modify */
-  if (!strcmp (mode, "%C")) return (FALSE);
+  if (!strcmp (mode, "%C")) goto invalid;
 
   strncpy (p, string, 80);
@@ -153,3 +159,6 @@
   return (TRUE);
 
+invalid:
+  va_end (argp);
+  return (FALSE);
 }
Index: /branches/eam_branches/ipp-20111122/Ohana/src/libfits/include/gfitsio.h
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/libfits/include/gfitsio.h	(revision 33127)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/libfits/include/gfitsio.h	(revision 33128)
@@ -190,4 +190,5 @@
 int     gfits_read_table               PROTO((char *filename, FTable *ftable)); 
 int     gfits_set_bintable_column      PROTO((Header *header, FTable *table, char *label, void *data, off_t Nrow));
+int     gfits_set_bintable_column_reformat PROTO((Header *header, FTable *table, char *label, char *intype, void *data, off_t Nrow));
 int     gfits_set_table_column         PROTO((Header *header, FTable *table, char *label, void *data, off_t Nrow));
 int     gfits_table_column             PROTO((FTable *ftable, char *field, char *mode,...)) OHANA_FORMAT(printf, 3, 4);
Index: /branches/eam_branches/ipp-20111122/Ohana/src/libfits/table/F_define_column.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/libfits/table/F_define_column.c	(revision 33127)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/libfits/table/F_define_column.c	(revision 33128)
@@ -4,4 +4,7 @@
 /***********************/
 int gfits_define_bintable_column (Header *header, char *format, char *label, char *comment, char *unit, double bscale, double bzero) {
+
+  assert (label);
+  assert (format);
 
   off_t Naxis1;
Index: /branches/eam_branches/ipp-20111122/Ohana/src/libfits/table/F_set_column.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/libfits/table/F_set_column.c	(revision 33127)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/libfits/table/F_set_column.c	(revision 33128)
@@ -40,7 +40,11 @@
   /* interpret format */
   sprintf (field, "TSCAL%d", N);
-  gfits_scan (header, field, "%lf", 1, &Bscale);
+  if (!gfits_scan (header, field, "%lf", 1, &Bscale)) {
+    Bscale = 1.0;
+  }
   sprintf (field, "TZERO%d", N);
-  gfits_scan (header, field, "%lf", 1, &Bzero);
+  if (!gfits_scan (header, field, "%lf", 1, &Bzero)) {
+    Bzero = 0.0;
+  }
   sprintf (field, "TFORM%d", N);
   gfits_scan (header, field, "%s", 1, format);
@@ -126,4 +130,308 @@
   for (i = 0; i < Nrow; i++, Pout += Nx, Pin += Nval*Nbytes) {
     memcpy (Pout, Pin, Nval*Nbytes);
+  }
+
+  free (array);
+  return (TRUE);
+}
+
+/***********************/
+int gfits_set_bintable_column_reformat (Header *header, FTable *table, char *label, char *intype, void *data, off_t Nrow) {
+
+  off_t Nx, Ny, nbytes;
+  int i, N, Nfields;
+  int Nval, NbytesOut, Nstart, Nv, Nb;
+  char tlabel[80], field[80], format[80], outtype[16], tmpline[16];
+  char *Pin, *Pout, *array;
+  double Bscale, Bzero;
+
+  if (label == (char *) NULL) return (FALSE);
+  if (label[0] == 0) return (FALSE);
+
+  /* find label in header */
+  tlabel[0] = 0;
+  gfits_scan (header, "TFIELDS", "%d", 1, &Nfields);
+  for (i = 1; strcasecmp (label, tlabel) && (i < Nfields + 1); i++) {
+    sprintf (field, "TTYPE%d", i);
+    gfits_scan (header, field, "%s", 1, tlabel);
+  }
+  if (strcasecmp (label, tlabel)) return (FALSE);
+  N = i - 1;
+
+  /* interpret format */
+  sprintf (field, "TSCAL%d", N);
+  if (!gfits_scan (header, field, "%lf", 1, &Bscale)) {
+    Bscale = 1.0;
+  }
+  sprintf (field, "TZERO%d", N);
+  if (!gfits_scan (header, field, "%lf", 1, &Bzero)) {
+    Bzero = 0.0;
+  }
+  sprintf (field, "TFORM%d", N);
+  gfits_scan (header, field, "%s", 1, format);
+
+  if (!gfits_bintable_format (format, outtype, &Nval, &NbytesOut)) return (FALSE);
+  
+  /* check existing table dimensions */
+  gfits_scan (header, "NAXIS1", OFF_T_FMT, 1,  &Nx);
+  gfits_scan (header, "NAXIS2", OFF_T_FMT, 1,  &Ny);
+  if (Ny == 0) { 
+    Ny = Nrow;
+    header[0].Naxis[1] = Ny;
+    gfits_modify (header, "NAXIS2", OFF_T_FMT, 1,  Ny);
+
+    nbytes = gfits_data_size (header);
+    REALLOCATE (table[0].buffer, char, MAX (nbytes, 1));
+    bzero (table[0].buffer, nbytes);
+    table[0].datasize = nbytes;
+  }
+  if (Ny != Nrow) return (FALSE);
+
+  /* scan columns to find insert point */
+  Nstart = 0;
+  for (i = 1; i < N; i++) {
+    sprintf (field, "TFORM%d", i);
+    gfits_scan (header, field, "%s", 1, format);
+    gfits_bintable_format (format, tmpline, &Nv, &Nb);
+    Nstart += Nv*Nb;
+  }
+
+  /* make duplicate of data with correct type
+     byte swap and Bzero/Bscale */
+  ALLOCATE (array, char, NbytesOut*Nval*Nrow);
+  Pin = data;
+  Pout = array;
+
+  /** input == char **/
+  if (!strcmp (outtype, "char") && !strcmp (intype, "char")) {
+    int NbytesIn = 1;
+    for (i = 0; i < Nval*Nrow; i++, Pin+=NbytesIn, Pout+=NbytesOut) {
+      *(char *)Pout = (*(char *)Pin - Bzero) / Bscale;
+    }
+  }
+  if (!strcmp (outtype, "short") && !strcmp (intype, "char")) {
+    int NbytesIn = 1;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(short *)Pout = (*(char *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_BYTE;
+# endif
+    }  
+  }
+  if (!strcmp (outtype, "int") && !strcmp (intype, "char")) {
+    int NbytesIn = 1;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(int *)Pout = (*(char *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_WORD;
+# endif
+    }
+  }
+  if (!strcmp (outtype, "float") && !strcmp (intype, "char")) {
+    int NbytesIn = 1;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(float *)Pout = (*(char *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_WORD;
+# endif
+    }
+  }
+  if (!strcmp (outtype, "double") && !strcmp (intype, "char")) {
+    int NbytesIn = 1;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(double *)Pout = (*(char *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_DBLE;
+# endif
+    }
+  }
+
+  /** input == short **/
+  if (!strcmp (outtype, "char") && !strcmp (intype, "short")) {
+    int NbytesIn = 2;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(char *)Pout = (*(short *)Pin - Bzero) / Bscale;
+    }
+  }
+  if (!strcmp (outtype, "short") && !strcmp (intype, "short")) {
+    int NbytesIn = 2;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(short *)Pout = (*(short *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_BYTE;
+# endif
+    }  
+  }
+  if (!strcmp (outtype, "int") && !strcmp (intype, "short")) {
+    int NbytesIn = 2;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(int *)Pout = (*(short *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_WORD;
+# endif
+    }
+  }
+  if (!strcmp (outtype, "float") && !strcmp (intype, "short")) {
+    int NbytesIn = 2;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(float *)Pout = (*(short *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_WORD;
+# endif
+    }
+  }
+  if (!strcmp (outtype, "double") && !strcmp (intype, "short")) {
+    int NbytesIn = 2;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(double *)Pout = (*(short *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_DBLE;
+# endif
+    }
+  }
+
+  /** input == int **/
+  if (!strcmp (outtype, "char") && !strcmp (intype, "int")) {
+    int NbytesIn = 4;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(char *)Pout = (*(int *)Pin - Bzero) / Bscale;
+    }
+  }
+  if (!strcmp (outtype, "short") && !strcmp (intype, "int")) {
+    int NbytesIn = 4;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(short *)Pout = (*(int *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_BYTE;
+# endif
+    }  
+  }
+  if (!strcmp (outtype, "int") && !strcmp (intype, "int")) {
+    int NbytesIn = 4;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(int *)Pout = (*(int *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_WORD;
+# endif
+    }
+  }
+  if (!strcmp (outtype, "float") && !strcmp (intype, "int")) {
+    int NbytesIn = 4;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(float *)Pout = (*(int *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_WORD;
+# endif
+    }
+  }
+  if (!strcmp (outtype, "double") && !strcmp (intype, "int")) {
+    int NbytesIn = 4;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(double *)Pout = (*(int *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_DBLE;
+# endif
+    }
+  }
+
+  /** input == float **/
+  if (!strcmp (outtype, "char") && !strcmp (intype, "float")) {
+    int NbytesIn = 4;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(char *)Pout = (*(float *)Pin - Bzero) / Bscale;
+    }
+  }
+  if (!strcmp (outtype, "short") && !strcmp (intype, "float")) {
+    int NbytesIn = 4;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(short *)Pout = (*(float *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_BYTE;
+# endif
+    }  
+  }
+  if (!strcmp (outtype, "int") && !strcmp (intype, "float")) {
+    int NbytesIn = 4;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(int *)Pout = (*(float *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_WORD;
+# endif
+    }
+  }
+  if (!strcmp (outtype, "float") && !strcmp (intype, "float")) {
+    int NbytesIn = 4;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(float *)Pout = (*(float *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_WORD;
+# endif
+    }
+  }
+  if (!strcmp (outtype, "double") && !strcmp (intype, "float")) {
+    int NbytesIn = 4;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(double *)Pout = (*(float *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_DBLE;
+# endif
+    }
+  }
+
+  /** input == double **/
+  if (!strcmp (outtype, "char") && !strcmp (intype, "double")) {
+    int NbytesIn = 8;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(char *)Pout = (*(double *)Pin - Bzero) / Bscale;
+    }
+  }
+  if (!strcmp (outtype, "short") && !strcmp (intype, "double")) {
+    int NbytesIn = 8;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(short *)Pout = (*(double *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_BYTE;
+# endif
+    }  
+  }
+  if (!strcmp (outtype, "int") && !strcmp (intype, "double")) {
+    int NbytesIn = 8;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(int *)Pout = (*(double *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_WORD;
+# endif
+    }
+  }
+  if (!strcmp (outtype, "float") && !strcmp (intype, "double")) {
+    int NbytesIn = 8;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(float *)Pout = (*(double *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_WORD;
+# endif
+    }
+  }
+  if (!strcmp (outtype, "double") && !strcmp (intype, "double")) {
+    int NbytesIn = 8;
+    for (i = 0; i < Nval*Nrow; i++, Pin += NbytesIn, Pout += NbytesOut) {
+      *(double *)Pout = (*(double *)Pin - Bzero) / Bscale;
+# ifdef BYTE_SWAP
+      SWAP_DBLE;
+# endif
+    }
+  }
+
+  /* check array space */
+  if (Nx*Ny < Nx*(Nrow - 1) + Nstart + Nval*NbytesOut) {
+    fprintf (stderr, "mismatch in array sizes\n");
+    return (FALSE);
+  }
+
+  /* insert bytes from array into appropriate section of buffer */
+  Pout = table[0].buffer + Nstart;
+  Pin  = array;
+  for (i = 0; i < Nrow; i++, Pout += Nx, Pin += Nval*NbytesOut) {
+    memcpy (Pout, Pin, Nval*NbytesOut);
   }
 
