aboutsummaryrefslogtreecommitdiff
path: root/pkg/tbtables/cfitsio/putcol.c
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
commitfa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch)
treebdda434976bc09c864f2e4fa6f16ba1952b1e555 /pkg/tbtables/cfitsio/putcol.c
downloadiraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz
Initial commit
Diffstat (limited to 'pkg/tbtables/cfitsio/putcol.c')
-rw-r--r--pkg/tbtables/cfitsio/putcol.c1714
1 files changed, 1714 insertions, 0 deletions
diff --git a/pkg/tbtables/cfitsio/putcol.c b/pkg/tbtables/cfitsio/putcol.c
new file mode 100644
index 00000000..348d0930
--- /dev/null
+++ b/pkg/tbtables/cfitsio/putcol.c
@@ -0,0 +1,1714 @@
+/* This file, putcol.c, contains routines that write data elements to */
+/* a FITS image or table. These are the generic routines. */
+
+/* The FITSIO software was written by William Pence at the High Energy */
+/* Astrophysic Science Archive Research Center (HEASARC) at the NASA */
+/* Goddard Space Flight Center. */
+
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#include "fitsio2.h"
+
+OFF_T large_first_elem_val = 0; /* used to pass large firstelem values */
+
+/*--------------------------------------------------------------------------*/
+int ffppx( fitsfile *fptr, /* I - FITS file pointer */
+ int datatype, /* I - datatype of the value */
+ long *firstpix, /* I - coord of first pixel to write(1 based) */
+ long nelem, /* I - number of values to write */
+ void *array, /* I - array of values that are written */
+ int *status) /* IO - error status */
+/*
+ Write an array of pixels to the primary array. The datatype of the
+ input array is defined by the 2nd argument. Data conversion
+ and scaling will be performed if necessary (e.g, if the datatype of
+ the FITS array is not the same as the array being written). This routine
+ is simillar to ffppr, except it supports writing large images with
+ more than 2.1E9 pixels.
+*/
+{
+ int naxis, ii;
+ long naxes[9], firstelem, group = 1;
+ OFF_T dimsize = 1;
+
+ if (*status > 0) /* inherit input status value if > 0 */
+ return(*status);
+
+ /* get the size of the image */
+ ffgidm(fptr, &naxis, status);
+ ffgisz(fptr, 9, naxes, status);
+
+ /* store the actual first element value in a external variable */
+ /* because we can't pass the value directly to the lower routine */
+ /* because the parameter is declared as 'long' instead of 'off_t'. */
+
+ large_first_elem_val = 0;
+ for (ii=0; ii < naxis; ii++)
+ {
+ large_first_elem_val += ((firstpix[ii] - 1) * dimsize);
+ dimsize *= naxes[ii];
+ }
+ large_first_elem_val++;
+
+ firstelem = USE_LARGE_VALUE; /* special flag value */
+
+ if (datatype == TBYTE)
+ {
+ ffpprb(fptr, group, firstelem, nelem, (unsigned char *) array, status);
+ }
+ else if (datatype == TSBYTE)
+ {
+ ffpprsb(fptr, group, firstelem, nelem, (signed char *) array, status);
+ }
+ else if (datatype == TUSHORT)
+ {
+ ffpprui(fptr, group, firstelem, nelem, (unsigned short *) array,
+ status);
+ }
+ else if (datatype == TSHORT)
+ {
+ ffppri(fptr, group, firstelem, nelem, (short *) array, status);
+ }
+ else if (datatype == TUINT)
+ {
+ ffppruk(fptr, group, firstelem, nelem, (unsigned int *) array, status);
+ }
+ else if (datatype == TINT)
+ {
+ ffpprk(fptr, group, firstelem, nelem, (int *) array, status);
+ }
+ else if (datatype == TULONG)
+ {
+ ffppruj(fptr, group, firstelem, nelem, (unsigned long *) array, status);
+ }
+ else if (datatype == TLONG)
+ {
+ ffpprj(fptr, group, firstelem, nelem, (long *) array, status);
+ }
+ else if (datatype == TLONGLONG)
+ {
+ ffpprjj(fptr, group, firstelem, nelem, (LONGLONG *) array, status);
+ }
+ else if (datatype == TFLOAT)
+ {
+ ffppre(fptr, group, firstelem, nelem, (float *) array, status);
+ }
+ else if (datatype == TDOUBLE)
+ {
+ ffpprd(fptr, group, firstelem, nelem, (double *) array, status);
+ }
+ else
+ *status = BAD_DATATYPE;
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffppxn( fitsfile *fptr, /* I - FITS file pointer */
+ int datatype, /* I - datatype of the value */
+ long *firstpix, /* I - first vector element to write(1 = 1st) */
+ long nelem, /* I - number of values to write */
+ void *array, /* I - array of values that are written */
+ void *nulval, /* I - pointer to the null value */
+ int *status) /* IO - error status */
+/*
+ Write an array of values to the primary array. The datatype of the
+ input array is defined by the 2nd argument. Data conversion
+ and scaling will be performed if necessary (e.g, if the datatype of
+ the FITS array is not the same as the array being written).
+*/
+{
+ int naxis, ii;
+ long naxes[9], firstelem, group = 1;
+ OFF_T dimsize = 1;
+
+ if (*status > 0) /* inherit input status value if > 0 */
+ return(*status);
+
+ if (nulval == NULL) /* null value not defined? */
+ {
+ ffppx(fptr, datatype, firstpix, nelem, array, status);
+ return(*status);
+ }
+
+ /* get the size of the image */
+ ffgidm(fptr, &naxis, status);
+ ffgisz(fptr, 9, naxes, status);
+
+ /* store the actual first element value in a external variable */
+ /* because we can't pass the value directly to the lower routine */
+ /* because the parameter is declared as 'long' instead of 'off_t'. */
+
+ large_first_elem_val = 0;
+ for (ii=0; ii < naxis; ii++)
+ {
+ large_first_elem_val += ((firstpix[ii] - 1) * dimsize);
+ dimsize *= naxes[ii];
+ }
+ large_first_elem_val++;
+
+ firstelem = USE_LARGE_VALUE; /* special flag value */
+
+ if (datatype == TBYTE)
+ {
+ ffppnb(fptr, group, firstelem, nelem, (unsigned char *) array,
+ *(unsigned char *) nulval, status);
+ }
+ else if (datatype == TSBYTE)
+ {
+ ffppnsb(fptr, group, firstelem, nelem, (signed char *) array,
+ *(signed char *) nulval, status);
+ }
+ else if (datatype == TUSHORT)
+ {
+ ffppnui(fptr, group, firstelem, nelem, (unsigned short *) array,
+ *(unsigned short *) nulval,status);
+ }
+ else if (datatype == TSHORT)
+ {
+ ffppni(fptr, group, firstelem, nelem, (short *) array,
+ *(short *) nulval, status);
+ }
+ else if (datatype == TUINT)
+ {
+ ffppnuk(fptr, group, firstelem, nelem, (unsigned int *) array,
+ *(unsigned int *) nulval, status);
+ }
+ else if (datatype == TINT)
+ {
+ ffppnk(fptr, group, firstelem, nelem, (int *) array,
+ *(int *) nulval, status);
+ }
+ else if (datatype == TULONG)
+ {
+ ffppnuj(fptr, group, firstelem, nelem, (unsigned long *) array,
+ *(unsigned long *) nulval,status);
+ }
+ else if (datatype == TLONG)
+ {
+ ffppnj(fptr, group, firstelem, nelem, (long *) array,
+ *(long *) nulval, status);
+ }
+ else if (datatype == TLONGLONG)
+ {
+ ffppnjj(fptr, group, firstelem, nelem, (LONGLONG *) array,
+ *(LONGLONG *) nulval, status);
+ }
+ else if (datatype == TFLOAT)
+ {
+ ffppne(fptr, group, firstelem, nelem, (float *) array,
+ *(float *) nulval, status);
+ }
+ else if (datatype == TDOUBLE)
+ {
+ ffppnd(fptr, group, firstelem, nelem, (double *) array,
+ *(double *) nulval, status);
+ }
+ else
+ *status = BAD_DATATYPE;
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffppr( fitsfile *fptr, /* I - FITS file pointer */
+ int datatype, /* I - datatype of the value */
+ long firstelem, /* I - first vector element to write(1 = 1st) */
+ long nelem, /* I - number of values to write */
+ void *array, /* I - array of values that are written */
+ int *status) /* IO - error status */
+/*
+ Write an array of values to the primary array. The datatype of the
+ input array is defined by the 2nd argument. Data conversion
+ and scaling will be performed if necessary (e.g, if the datatype of
+ the FITS array is not the same as the array being written).
+*/
+{
+ long group = 1;
+
+ if (*status > 0) /* inherit input status value if > 0 */
+ return(*status);
+
+ if (datatype == TBYTE)
+ {
+ ffpprb(fptr, group, firstelem, nelem, (unsigned char *) array, status);
+ }
+ else if (datatype == TSBYTE)
+ {
+ ffpprsb(fptr, group, firstelem, nelem, (signed char *) array, status);
+ }
+ else if (datatype == TUSHORT)
+ {
+ ffpprui(fptr, group, firstelem, nelem, (unsigned short *) array,
+ status);
+ }
+ else if (datatype == TSHORT)
+ {
+ ffppri(fptr, group, firstelem, nelem, (short *) array, status);
+ }
+ else if (datatype == TUINT)
+ {
+ ffppruk(fptr, group, firstelem, nelem, (unsigned int *) array, status);
+ }
+ else if (datatype == TINT)
+ {
+ ffpprk(fptr, group, firstelem, nelem, (int *) array, status);
+ }
+ else if (datatype == TULONG)
+ {
+ ffppruj(fptr, group, firstelem, nelem, (unsigned long *) array, status);
+ }
+ else if (datatype == TLONG)
+ {
+ ffpprj(fptr, group, firstelem, nelem, (long *) array, status);
+ }
+ else if (datatype == TLONGLONG)
+ {
+ ffpprjj(fptr, group, firstelem, nelem, (LONGLONG *) array, status);
+ }
+ else if (datatype == TFLOAT)
+ {
+ ffppre(fptr, group, firstelem, nelem, (float *) array, status);
+ }
+ else if (datatype == TDOUBLE)
+ {
+ ffpprd(fptr, group, firstelem, nelem, (double *) array, status);
+ }
+ else
+ *status = BAD_DATATYPE;
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffppn( fitsfile *fptr, /* I - FITS file pointer */
+ int datatype, /* I - datatype of the value */
+ long firstelem, /* I - first vector element to write(1 = 1st) */
+ long nelem, /* I - number of values to write */
+ void *array, /* I - array of values that are written */
+ void *nulval, /* I - pointer to the null value */
+ int *status) /* IO - error status */
+/*
+ Write an array of values to the primary array. The datatype of the
+ input array is defined by the 2nd argument. Data conversion
+ and scaling will be performed if necessary (e.g, if the datatype of
+ the FITS array is not the same as the array being written).
+*/
+{
+ long group = 1;
+
+ if (*status > 0) /* inherit input status value if > 0 */
+ return(*status);
+
+ if (nulval == NULL) /* null value not defined? */
+ {
+ ffppr(fptr, datatype, firstelem, nelem, array, status);
+ return(*status);
+ }
+
+ if (datatype == TBYTE)
+ {
+ ffppnb(fptr, group, firstelem, nelem, (unsigned char *) array,
+ *(unsigned char *) nulval, status);
+ }
+ else if (datatype == TSBYTE)
+ {
+ ffppnsb(fptr, group, firstelem, nelem, (signed char *) array,
+ *(signed char *) nulval, status);
+ }
+ else if (datatype == TUSHORT)
+ {
+ ffppnui(fptr, group, firstelem, nelem, (unsigned short *) array,
+ *(unsigned short *) nulval,status);
+ }
+ else if (datatype == TSHORT)
+ {
+ ffppni(fptr, group, firstelem, nelem, (short *) array,
+ *(short *) nulval, status);
+ }
+ else if (datatype == TUINT)
+ {
+ ffppnuk(fptr, group, firstelem, nelem, (unsigned int *) array,
+ *(unsigned int *) nulval, status);
+ }
+ else if (datatype == TINT)
+ {
+ ffppnk(fptr, group, firstelem, nelem, (int *) array,
+ *(int *) nulval, status);
+ }
+ else if (datatype == TULONG)
+ {
+ ffppnuj(fptr, group, firstelem, nelem, (unsigned long *) array,
+ *(unsigned long *) nulval,status);
+ }
+ else if (datatype == TLONG)
+ {
+ ffppnj(fptr, group, firstelem, nelem, (long *) array,
+ *(long *) nulval, status);
+ }
+ else if (datatype == TLONGLONG)
+ {
+ ffppnjj(fptr, group, firstelem, nelem, (LONGLONG *) array,
+ *(LONGLONG *) nulval, status);
+ }
+ else if (datatype == TFLOAT)
+ {
+ ffppne(fptr, group, firstelem, nelem, (float *) array,
+ *(float *) nulval, status);
+ }
+ else if (datatype == TDOUBLE)
+ {
+ ffppnd(fptr, group, firstelem, nelem, (double *) array,
+ *(double *) nulval, status);
+ }
+ else
+ *status = BAD_DATATYPE;
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffpss( fitsfile *fptr, /* I - FITS file pointer */
+ int datatype, /* I - datatype of the value */
+ long *blc, /* I - 'bottom left corner' of the subsection */
+ long *trc , /* I - 'top right corner' of the subsection */
+ void *array, /* I - array of values that are written */
+ int *status) /* IO - error status */
+/*
+ Write a section of values to the primary array. The datatype of the
+ input array is defined by the 2nd argument. Data conversion
+ and scaling will be performed if necessary (e.g, if the datatype of
+ the FITS array is not the same as the array being written).
+*/
+{
+ int naxis;
+ long naxes[9];
+
+ if (*status > 0) /* inherit input status value if > 0 */
+ return(*status);
+
+ /* get the size of the image */
+ ffgidm(fptr, &naxis, status);
+ ffgisz(fptr, 9, naxes, status);
+
+ if (datatype == TBYTE)
+ {
+ ffpssb(fptr, 1, naxis, naxes, blc, trc,
+ (unsigned char *) array, status);
+ }
+ else if (datatype == TSBYTE)
+ {
+ ffpsssb(fptr, 1, naxis, naxes, blc, trc,
+ (signed char *) array, status);
+ }
+ else if (datatype == TUSHORT)
+ {
+ ffpssui(fptr, 1, naxis, naxes, blc, trc,
+ (unsigned short *) array, status);
+ }
+ else if (datatype == TSHORT)
+ {
+ ffpssi(fptr, 1, naxis, naxes, blc, trc,
+ (short *) array, status);
+ }
+ else if (datatype == TUINT)
+ {
+ ffpssuk(fptr, 1, naxis, naxes, blc, trc,
+ (unsigned int *) array, status);
+ }
+ else if (datatype == TINT)
+ {
+ ffpssk(fptr, 1, naxis, naxes, blc, trc,
+ (int *) array, status);
+ }
+ else if (datatype == TULONG)
+ {
+ ffpssuj(fptr, 1, naxis, naxes, blc, trc,
+ (unsigned long *) array, status);
+ }
+ else if (datatype == TLONG)
+ {
+ ffpssj(fptr, 1, naxis, naxes, blc, trc,
+ (long *) array, status);
+ }
+ else if (datatype == TLONGLONG)
+ {
+ ffpssjj(fptr, 1, naxis, naxes, blc, trc,
+ (LONGLONG *) array, status);
+ } else if (datatype == TFLOAT)
+ {
+ ffpsse(fptr, 1, naxis, naxes, blc, trc,
+ (float *) array, status);
+ }
+ else if (datatype == TDOUBLE)
+ {
+ ffpssd(fptr, 1, naxis, naxes, blc, trc,
+ (double *) array, status);
+ }
+ else
+ *status = BAD_DATATYPE;
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffpcl( fitsfile *fptr, /* I - FITS file pointer */
+ int datatype, /* I - datatype of the value */
+ int colnum, /* I - number of column to write (1 = 1st col) */
+ long firstrow, /* I - first row to write (1 = 1st row) */
+ long firstelem, /* I - first vector element to write (1 = 1st) */
+ long nelem, /* I - number of elements to write */
+ void *array, /* I - array of values that are written */
+ int *status) /* IO - error status */
+/*
+ Write an array of values to a table column. The datatype of the
+ input array is defined by the 2nd argument. Data conversion
+ and scaling will be performed if necessary (e.g, if the datatype of
+ the FITS column is not the same as the array being written).
+*/
+{
+ if (*status > 0) /* inherit input status value if > 0 */
+ return(*status);
+
+ if (datatype == TBIT)
+ {
+ ffpclx(fptr, colnum, firstrow, firstelem, nelem, (char *) array,
+ status);
+ }
+ else if (datatype == TBYTE)
+ {
+ ffpclb(fptr, colnum, firstrow, firstelem, nelem, (unsigned char *) array,
+ status);
+ }
+ else if (datatype == TSBYTE)
+ {
+ ffpclsb(fptr, colnum, firstrow, firstelem, nelem, (signed char *) array,
+ status);
+ }
+ else if (datatype == TUSHORT)
+ {
+ ffpclui(fptr, colnum, firstrow, firstelem, nelem,
+ (unsigned short *) array, status);
+ }
+ else if (datatype == TSHORT)
+ {
+ ffpcli(fptr, colnum, firstrow, firstelem, nelem, (short *) array,
+ status);
+ }
+ else if (datatype == TUINT)
+ {
+ ffpcluk(fptr, colnum, firstrow, firstelem, nelem, (unsigned int *) array,
+ status);
+ }
+ else if (datatype == TINT)
+ {
+ ffpclk(fptr, colnum, firstrow, firstelem, nelem, (int *) array,
+ status);
+ }
+ else if (datatype == TULONG)
+ {
+ ffpcluj(fptr, colnum, firstrow, firstelem, nelem, (unsigned long *) array,
+ status);
+ }
+ else if (datatype == TLONG)
+ {
+ ffpclj(fptr, colnum, firstrow, firstelem, nelem, (long *) array,
+ status);
+ }
+ else if (datatype == TLONGLONG)
+ {
+ ffpcljj(fptr, colnum, firstrow, firstelem, nelem, (LONGLONG *) array,
+ status);
+ }
+ else if (datatype == TFLOAT)
+ {
+ ffpcle(fptr, colnum, firstrow, firstelem, nelem, (float *) array,
+ status);
+ }
+ else if (datatype == TDOUBLE)
+ {
+ ffpcld(fptr, colnum, firstrow, firstelem, nelem, (double *) array,
+ status);
+ }
+ else if (datatype == TCOMPLEX)
+ {
+ ffpcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2,
+ (float *) array, status);
+ }
+ else if (datatype == TDBLCOMPLEX)
+ {
+ ffpcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2,
+ (double *) array, status);
+ }
+ else if (datatype == TLOGICAL)
+ {
+ ffpcll(fptr, colnum, firstrow, firstelem, nelem, (char *) array,
+ status);
+ }
+ else if (datatype == TSTRING)
+ {
+ ffpcls(fptr, colnum, firstrow, firstelem, nelem, (char **) array,
+ status);
+ }
+ else
+ *status = BAD_DATATYPE;
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int ffpcn( fitsfile *fptr, /* I - FITS file pointer */
+ int datatype, /* I - datatype of the value */
+ int colnum, /* I - number of column to write (1 = 1st col) */
+ long firstrow, /* I - first row to write (1 = 1st row) */
+ long firstelem, /* I - first vector element to write (1 = 1st) */
+ long nelem, /* I - number of elements to write */
+ void *array, /* I - array of values that are written */
+ void *nulval, /* I - pointer to the null value */
+ int *status) /* IO - error status */
+/*
+ Write an array of values to a table column. The datatype of the
+ input array is defined by the 2nd argument. Data conversion
+ and scaling will be performed if necessary (e.g, if the datatype of
+ the FITS column is not the same as the array being written).
+*/
+{
+ if (*status > 0) /* inherit input status value if > 0 */
+ return(*status);
+
+ if (nulval == NULL) /* null value not defined? */
+ {
+ ffpcl(fptr, datatype, colnum, firstrow, firstelem, nelem, array,
+ status);
+ return(*status);
+ }
+
+ if (datatype == TBYTE)
+ {
+ ffpcnb(fptr, colnum, firstrow, firstelem, nelem, (unsigned char *) array,
+ *(unsigned char *) nulval, status);
+ }
+ else if (datatype == TSBYTE)
+ {
+ ffpcnsb(fptr, colnum, firstrow, firstelem, nelem, (signed char *) array,
+ *(signed char *) nulval, status);
+ }
+ else if (datatype == TUSHORT)
+ {
+ ffpcnui(fptr, colnum, firstrow, firstelem, nelem, (unsigned short *) array,
+ *(unsigned short *) nulval, status);
+ }
+ else if (datatype == TSHORT)
+ {
+ ffpcni(fptr, colnum, firstrow, firstelem, nelem, (short *) array,
+ *(unsigned short *) nulval, status);
+ }
+ else if (datatype == TUINT)
+ {
+ ffpcnuk(fptr, colnum, firstrow, firstelem, nelem, (unsigned int *) array,
+ *(unsigned int *) nulval, status);
+ }
+ else if (datatype == TINT)
+ {
+ ffpcnk(fptr, colnum, firstrow, firstelem, nelem, (int *) array,
+ *(int *) nulval, status);
+ }
+ else if (datatype == TULONG)
+ {
+ ffpcnuj(fptr, colnum, firstrow, firstelem, nelem, (unsigned long *) array,
+ *(unsigned long *) nulval, status);
+ }
+ else if (datatype == TLONG)
+ {
+ ffpcnj(fptr, colnum, firstrow, firstelem, nelem, (long *) array,
+ *(long *) nulval, status);
+ }
+ else if (datatype == TLONGLONG)
+ {
+ ffpcnjj(fptr, colnum, firstrow, firstelem, nelem, (LONGLONG *) array,
+ *(LONGLONG *) nulval, status);
+ }
+ else if (datatype == TFLOAT)
+ {
+ ffpcne(fptr, colnum, firstrow, firstelem, nelem, (float *) array,
+ *(float *) nulval, status);
+ }
+ else if (datatype == TDOUBLE)
+ {
+ ffpcnd(fptr, colnum, firstrow, firstelem, nelem, (double *) array,
+ *(double *) nulval, status);
+ }
+ else if (datatype == TCOMPLEX)
+ {
+ ffpcne(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2,
+ (float *) array, *(float *) nulval, status);
+ }
+ else if (datatype == TDBLCOMPLEX)
+ {
+ ffpcnd(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2,
+ (double *) array, *(double *) nulval, status);
+ }
+ else if (datatype == TLOGICAL)
+ {
+ ffpcnl(fptr, colnum, firstrow, firstelem, nelem, (char *) array,
+ *(char *) nulval, status);
+ }
+ else if (datatype == TSTRING)
+ {
+ ffpcns(fptr, colnum, firstrow, firstelem, nelem, (char **) array,
+ (char *) nulval, status);
+ }
+ else
+ *status = BAD_DATATYPE;
+
+ return(*status);
+}
+/*--------------------------------------------------------------------------*/
+int fits_iter_set_by_name(iteratorCol *col, /* I - iterator col structure */
+ fitsfile *fptr, /* I - FITS file pointer */
+ char *colname, /* I - column name */
+ int datatype, /* I - column datatype */
+ int iotype) /* I - InputCol, InputOutputCol, or OutputCol */
+/*
+ set all the parameters for an iterator column, by column name
+*/
+{
+ col->fptr = fptr;
+ strcpy(col->colname, colname);
+ col->colnum = 0; /* set column number undefined since name is given */
+ col->datatype = datatype;
+ col->iotype = iotype;
+ return(0);
+}
+/*--------------------------------------------------------------------------*/
+int fits_iter_set_by_num(iteratorCol *col, /* I - iterator column structure */
+ fitsfile *fptr, /* I - FITS file pointer */
+ int colnum, /* I - column number */
+ int datatype, /* I - column datatype */
+ int iotype) /* I - InputCol, InputOutputCol, or OutputCol */
+/*
+ set all the parameters for an iterator column, by column number
+*/
+{
+ col->fptr = fptr;
+ col->colnum = colnum;
+ col->datatype = datatype;
+ col->iotype = iotype;
+ return(0);
+}
+/*--------------------------------------------------------------------------*/
+int fits_iter_set_file(iteratorCol *col, /* I - iterator column structure */
+ fitsfile *fptr) /* I - FITS file pointer */
+/*
+ set iterator column parameter
+*/
+{
+ col->fptr = fptr;
+ return(0);
+}
+/*--------------------------------------------------------------------------*/
+int fits_iter_set_colname(iteratorCol *col, /* I - iterator col structure */
+ char *colname) /* I - column name */
+/*
+ set iterator column parameter
+*/
+{
+ strcpy(col->colname, colname);
+ col->colnum = 0; /* set column number undefined since name is given */
+ return(0);
+}
+/*--------------------------------------------------------------------------*/
+int fits_iter_set_colnum(iteratorCol *col, /* I - iterator column structure */
+ int colnum) /* I - column number */
+/*
+ set iterator column parameter
+*/
+{
+ col->colnum = colnum;
+ return(0);
+}
+/*--------------------------------------------------------------------------*/
+int fits_iter_set_datatype(iteratorCol *col, /* I - iterator col structure */
+ int datatype) /* I - column datatype */
+/*
+ set iterator column parameter
+*/
+{
+ col->datatype = datatype;
+ return(0);
+}
+/*--------------------------------------------------------------------------*/
+int fits_iter_set_iotype(iteratorCol *col, /* I - iterator column structure */
+ int iotype) /* I - InputCol, InputOutputCol, or OutputCol */
+/*
+ set iterator column parameter
+*/
+{
+ col->iotype = iotype;
+ return(0);
+}
+/*--------------------------------------------------------------------------*/
+fitsfile * fits_iter_get_file(iteratorCol *col) /* I -iterator col structure */
+/*
+ get iterator column parameter
+*/
+{
+ return(col->fptr);
+}
+/*--------------------------------------------------------------------------*/
+char * fits_iter_get_colname(iteratorCol *col) /* I -iterator col structure */
+/*
+ get iterator column parameter
+*/
+{
+ return(col->colname);
+}
+/*--------------------------------------------------------------------------*/
+int fits_iter_get_colnum(iteratorCol *col) /* I - iterator column structure */
+/*
+ get iterator column parameter
+*/
+{
+ return(col->colnum);
+}
+/*--------------------------------------------------------------------------*/
+int fits_iter_get_datatype(iteratorCol *col) /* I - iterator col structure */
+/*
+ get iterator column parameter
+*/
+{
+ return(col->datatype);
+}
+/*--------------------------------------------------------------------------*/
+int fits_iter_get_iotype(iteratorCol *col) /* I - iterator column structure */
+/*
+ get iterator column parameter
+*/
+{
+ return(col->iotype);
+}
+/*--------------------------------------------------------------------------*/
+void * fits_iter_get_array(iteratorCol *col) /* I - iterator col structure */
+/*
+ get iterator column parameter
+*/
+{
+ return(col->array);
+}
+/*--------------------------------------------------------------------------*/
+long fits_iter_get_tlmin(iteratorCol *col) /* I - iterator column structure */
+/*
+ get iterator column parameter
+*/
+{
+ return(col->tlmin);
+}
+/*--------------------------------------------------------------------------*/
+long fits_iter_get_tlmax(iteratorCol *col) /* I - iterator column structure */
+/*
+ get iterator column parameter
+*/
+{
+ return(col->tlmax);
+}
+/*--------------------------------------------------------------------------*/
+long fits_iter_get_repeat(iteratorCol *col) /* I - iterator col structure */
+/*
+ get iterator column parameter
+*/
+{
+ return(col->repeat);
+}
+/*--------------------------------------------------------------------------*/
+char * fits_iter_get_tunit(iteratorCol *col) /* I - iterator col structure */
+/*
+ get iterator column parameter
+*/
+{
+ return(col->tunit);
+}
+/*--------------------------------------------------------------------------*/
+char * fits_iter_get_tdisp(iteratorCol *col) /* I -iterator col structure */
+/*
+ get iterator column parameter
+*/
+{
+ return(col->tdisp);
+}
+/*--------------------------------------------------------------------------*/
+int ffiter(int n_cols,
+ iteratorCol *cols,
+ long offset,
+ long n_per_loop,
+ int (*work_fn)(long total_n,
+ long offset,
+ long first_n,
+ long n_values,
+ int n_cols,
+ iteratorCol *cols,
+ void *userPointer),
+ void *userPointer,
+ int *status)
+/*
+ The iterator function. This function will pass the specified
+ columns from a FITS table or pixels from a FITS image to the
+ user-supplied function. Depending on the size of the table
+ or image, only a subset of the rows or pixels may be passed to the
+ function on each call, in which case the function will be called
+ multiple times until all the rows or pixels have been processed.
+*/
+{
+ typedef struct /* structure to store the column null value */
+ {
+ int nullsize; /* length of the null value, in bytes */
+ union { /* default null value for the column */
+ char *stringnull;
+ unsigned char charnull;
+ signed char scharnull;
+ int intnull;
+ short shortnull;
+ long longnull;
+ unsigned int uintnull;
+ unsigned short ushortnull;
+ unsigned long ulongnull;
+ float floatnull;
+ double doublenull;
+ } null;
+ } colNulls;
+
+ void *dataptr, *defaultnull;
+ colNulls *col;
+ int ii, jj, tstatus, naxis, bitpix;
+ int typecode, hdutype, jtype, type, anynul, nfiles, nbytes;
+ long totaln, nleft, frow, felement, n_optimum, i_optimum, ntodo;
+ long rept, rowrept, width, tnull, naxes[9] = {1,1,1,1,1,1,1,1,1}, groups;
+ double zeros = 0.;
+ char message[FLEN_ERRMSG], keyname[FLEN_KEYWORD], nullstr[FLEN_VALUE];
+ char **stringptr, *nullptr, *cptr;
+
+ if (*status > 0)
+ return(*status);
+
+ if (n_cols < 0 || n_cols > 999 )
+ {
+ ffpmsg("Illegal number of columms (ffiter)");
+ return(*status = BAD_COL_NUM); /* negative number of columns */
+ }
+
+ col = calloc(n_cols, sizeof(colNulls) ); /* memory for the null values */
+
+ /*------------------------------------------------------------*/
+ /* Make sure column numbers and datatypes are in legal range */
+ /* and column numbers and datatypes are legal. */
+ /* Also fill in other parameters in the column structure. */
+ /*------------------------------------------------------------*/
+
+ ffghdt(cols[0].fptr, &hdutype, status); /* type of first HDU */
+
+ for (jj = 0; jj < n_cols; jj++)
+ {
+ /* check that output datatype code value is legal */
+ type = cols[jj].datatype;
+
+ /* Allow variable length arrays for InputCol and InputOutputCol columns,
+ but not for OutputCol columns. Variable length arrays have a
+ negative type code value. */
+
+ if ((cols[jj].iotype != OutputCol) && (type<0)) {
+ type*=-1;
+ }
+
+ if (type != 0 && type != TBYTE &&
+ type != TSBYTE && type != TLOGICAL && type != TSTRING &&
+ type != TSHORT && type != TINT && type != TLONG &&
+ type != TFLOAT && type != TDOUBLE && type != TCOMPLEX &&
+ type != TULONG && type != TUSHORT && type != TDBLCOMPLEX)
+ {
+ if (type < 0) {
+ sprintf(message,
+ "Variable length array not allowed for output column number %d (ffiter)",
+ jj + 1);
+ } else {
+ sprintf(message,
+ "Illegal datatype for column number %d: %d (ffiter)",
+ jj + 1, cols[jj].datatype);
+ }
+
+ ffpmsg(message);
+ return(*status = BAD_DATATYPE);
+ }
+
+ /* initialize TLMINn, TLMAXn, column name, and display format */
+ cols[jj].tlmin = 0;
+ cols[jj].tlmax = 0;
+ cols[jj].tunit[0] = '\0';
+ cols[jj].tdisp[0] = '\0';
+
+ ffghdt(cols[jj].fptr, &jtype, status); /* get HDU type */
+
+ if (hdutype == IMAGE_HDU)
+ {
+ if (jtype != IMAGE_HDU)
+ {
+ sprintf(message,
+ "File %d not positioned to an image extension (ffiter)",
+ jj + 1);
+ return(*status = NOT_IMAGE);
+ }
+
+ /* since this is an image, set a dummy column number = 0 */
+ cols[jj].colnum = 0;
+ strcpy(cols[jj].colname, "IMAGE"); /* dummy name for images */
+
+ tstatus = 0;
+ ffgkys(cols[jj].fptr, "BUNIT", cols[jj].tunit, 0, &tstatus);
+ }
+ else
+ {
+ if (jtype == IMAGE_HDU)
+ {
+ sprintf(message,
+ "File %d not positioned to a table extension (ffiter)",
+ jj + 1);
+ return(*status = NOT_TABLE);
+ }
+
+ if (cols[jj].colnum < 1)
+ {
+ /* find the column number for the named column */
+ if (ffgcno(cols[jj].fptr, CASEINSEN, cols[jj].colname,
+ &cols[jj].colnum, status) )
+ {
+ sprintf(message,
+ "Column '%s' not found for column number %d (ffiter)",
+ cols[jj].colname, jj + 1);
+ ffpmsg(message);
+ return(*status);
+ }
+ }
+
+ if (cols[jj].colnum < 1 ||
+ cols[jj].colnum > ((cols[jj].fptr)->Fptr)->tfield)
+ {
+ sprintf(message,
+ "Column %d has illegal table position number: %d (ffiter)",
+ jj + 1, cols[jj].colnum);
+ ffpmsg(message);
+ return(*status = BAD_COL_NUM);
+ }
+
+ /* look for column description keywords and update structure */
+ tstatus = 0;
+ ffkeyn("TLMIN", cols[jj].colnum, keyname, &tstatus);
+ ffgkyj(cols[jj].fptr, keyname, &cols[jj].tlmin, 0, &tstatus);
+
+ tstatus = 0;
+ ffkeyn("TLMAX", cols[jj].colnum, keyname, &tstatus);
+ ffgkyj(cols[jj].fptr, keyname, &cols[jj].tlmax, 0, &tstatus);
+
+ tstatus = 0;
+ ffkeyn("TTYPE", cols[jj].colnum, keyname, &tstatus);
+ ffgkys(cols[jj].fptr, keyname, cols[jj].colname, 0, &tstatus);
+ if (tstatus)
+ cols[jj].colname[0] = '\0';
+
+ tstatus = 0;
+ ffkeyn("TUNIT", cols[jj].colnum, keyname, &tstatus);
+ ffgkys(cols[jj].fptr, keyname, cols[jj].tunit, 0, &tstatus);
+
+ tstatus = 0;
+ ffkeyn("TDISP", cols[jj].colnum, keyname, &tstatus);
+ ffgkys(cols[jj].fptr, keyname, cols[jj].tdisp, 0, &tstatus);
+ }
+ }
+
+ /*-----------------------------------------------------------------*/
+ /* use the first file to set the total number of values to process */
+ /*-----------------------------------------------------------------*/
+
+ offset = maxvalue(offset, 0L); /* make sure offset is legal */
+
+ if (hdutype == IMAGE_HDU) /* get total number of pixels in the image */
+ {
+ fits_get_img_dim(cols[0].fptr, &naxis, status);
+ fits_get_img_size(cols[0].fptr, 9, naxes, status);
+
+ tstatus = 0;
+ ffgkyj(cols[0].fptr, "GROUPS", &groups, NULL, &tstatus);
+ if (!tstatus && groups && (naxis > 1) && (naxes[0] == 0) )
+ {
+ /* this is a random groups file, with NAXIS1 = 0 */
+ /* Use GCOUNT, the number of groups, as the first multiplier */
+ /* to calculate the total number of pixels in all the groups. */
+ ffgkyj(cols[0].fptr, "GCOUNT", &totaln, NULL, status);
+
+ } else {
+ totaln = naxes[0];
+ }
+
+ for (ii = 1; ii < naxis; ii++)
+ totaln *= naxes[ii];
+
+ frow = 1;
+ felement = 1 + offset;
+ }
+ else /* get total number or rows in the table */
+ {
+ ffgkyj(cols[0].fptr, "NAXIS2", &totaln, 0, status);
+ frow = 1 + offset;
+ felement = 1;
+ }
+
+ /* adjust total by the input starting offset value */
+ totaln -= offset;
+ totaln = maxvalue(totaln, 0L); /* don't allow negative number */
+
+ /*------------------------------------------------------------------*/
+ /* Determine number of values to pass to work function on each loop */
+ /*------------------------------------------------------------------*/
+
+ if (n_per_loop == 0)
+ {
+ /* Determine optimum number of values for each iteration. */
+ /* Look at all the fitsfile pointers to determine the number */
+ /* of unique files. */
+
+ nfiles = 1;
+ ffgrsz(cols[0].fptr, &n_optimum, status);
+
+ for (jj = 1; jj < n_cols; jj++)
+ {
+ for (ii = 0; ii < jj; ii++)
+ {
+ if (cols[ii].fptr == cols[jj].fptr)
+ break;
+ }
+
+ if (ii == jj) /* this is a new file */
+ {
+ nfiles++;
+ ffgrsz(cols[jj].fptr, &i_optimum, status);
+ n_optimum = minvalue(n_optimum, i_optimum);
+ }
+ }
+
+ n_optimum = n_optimum / nfiles;
+ n_optimum = maxvalue(n_optimum, 1);
+ }
+ else if (n_per_loop < 0) /* must pass all the values at one time */
+ {
+ n_optimum = totaln;
+ }
+ else /* calling routine specified how many values to pass at a time */
+ {
+ n_optimum = minvalue(n_per_loop, totaln);
+ }
+
+ /*--------------------------------------*/
+ /* allocate work arrays for each column */
+ /* and determine the null pixel value */
+ /*--------------------------------------*/
+
+ for (jj = 0; jj < n_cols; jj++)
+ {
+ /* get image or column datatype and vector length */
+ if (hdutype == IMAGE_HDU) /* get total number of pixels in the image */
+ {
+ fits_get_img_type(cols[jj].fptr, &bitpix, status);
+ switch(bitpix) {
+ case BYTE_IMG:
+ typecode = TBYTE;
+ break;
+ case SHORT_IMG:
+ typecode = TSHORT;
+ break;
+ case LONG_IMG:
+ typecode = TLONG;
+ break;
+ case FLOAT_IMG:
+ typecode = TFLOAT;
+ break;
+ case DOUBLE_IMG:
+ typecode = TDOUBLE;
+ break;
+ }
+ }
+ else
+ {
+ if (ffgtcl(cols[jj].fptr, cols[jj].colnum, &typecode, &rept,
+ &width, status) > 0)
+ goto cleanup;
+
+ if (typecode < 0) { /* if any variable length arrays, then the */
+ n_optimum = 1; /* must process the table 1 row at a time */
+
+ /* Allow variable length arrays for InputCol and InputOutputCol columns,
+ but not for OutputCol columns. Variable length arrays have a
+ negative type code value. */
+
+ if (cols[jj].iotype == OutputCol) {
+ sprintf(message,
+ "Variable length array not allowed for output column number %d (ffiter)",
+ jj + 1);
+ ffpmsg(message);
+ return(*status = BAD_DATATYPE);
+ }
+ }
+ }
+
+ /* special case where sizeof(long) = 8: use TINT instead of TLONG */
+ if (abs(typecode) == TLONG && sizeof(long) == 8 && sizeof(int) == 4) {
+ if(typecode<0) {
+ typecode = -TINT;
+ } else {
+ typecode = TINT;
+ }
+ }
+
+ /* Special case: interprete 'X' column as 'B' */
+ if (abs(typecode) == TBIT)
+ {
+ typecode = typecode / TBIT * TBYTE;
+ rept = (rept + 7) / 8;
+ }
+
+ if (cols[jj].datatype == 0) /* output datatype not specified? */
+ {
+ /* special case if sizeof(long) = 8: use TINT instead of TLONG */
+ if (abs(typecode) == TLONG && sizeof(long) == 8 && sizeof(int) == 4)
+ cols[jj].datatype = TINT;
+ else
+ cols[jj].datatype = abs(typecode);
+ }
+
+ /* calc total number of elements to do on each iteration */
+ if (hdutype == IMAGE_HDU || cols[jj].datatype == TSTRING)
+ {
+ ntodo = n_optimum;
+ cols[jj].repeat = 1;
+
+ /* get the BLANK keyword value, if it exists */
+ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG)
+ {
+ tstatus = 0;
+ ffgkyj(cols[jj].fptr, "BLANK", &tnull, 0, &tstatus);
+ if (tstatus)
+ {
+ tnull = 0L; /* no null values */
+ }
+ }
+ }
+ else
+ {
+ if (typecode < 0)
+ {
+ /* get max size of the variable length vector; dont't trust the value
+ given by the TFORM keyword */
+ rept = 1;
+ for (ii = 0; ii < totaln; ii++) {
+ ffgdes(cols[jj].fptr, cols[jj].colnum, frow + ii, &rowrept, NULL, status);
+
+ rept = maxvalue(rept, rowrept);
+ }
+ }
+
+ ntodo = n_optimum * rept; /* vector columns */
+ cols[jj].repeat = rept;
+
+ /* get the TNULL keyword value, if it exists */
+ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG)
+ {
+ tstatus = 0;
+ if (hdutype == ASCII_TBL) /* TNULLn value is a string */
+ {
+ ffkeyn("TNULL", cols[jj].colnum, keyname, &tstatus);
+ ffgkys(cols[jj].fptr, keyname, nullstr, 0, &tstatus);
+ if (tstatus)
+ {
+ tnull = 0L; /* keyword doesn't exist; no null values */
+ }
+ else
+ {
+ cptr = nullstr;
+ while (*cptr == ' ') /* skip over leading blanks */
+ cptr++;
+
+ if (*cptr == '\0') /* TNULLn is all blanks? */
+ tnull = LONG_MIN;
+ else
+ {
+ /* attempt to read TNULLn string as an integer */
+ ffc2ii(nullstr, &tnull, &tstatus);
+
+ if (tstatus)
+ tnull = LONG_MIN; /* choose smallest value */
+ } /* to represent nulls */
+ }
+ }
+ else /* Binary table; TNULLn value is an integer */
+ {
+ ffkeyn("TNULL", cols[jj].colnum, keyname, &tstatus);
+ ffgkyj(cols[jj].fptr, keyname, &tnull, 0, &tstatus);
+ if (tstatus)
+ {
+ tnull = 0L; /* keyword doesn't exist; no null values */
+ }
+ else if (tnull == 0)
+ {
+ /* worst possible case: a value of 0 is used to */
+ /* represent nulls in the FITS file. We have to */
+ /* use a non-zero null value here (zero is used to */
+ /* mean there are no null values in the array) so we */
+ /* will use the smallest possible integer instead. */
+
+ tnull = LONG_MIN; /* choose smallest possible value */
+ }
+ }
+ }
+ }
+
+ /* Note that the data array starts with 2nd element; */
+ /* 1st element of the array gives the null data value */
+
+ switch (cols[jj].datatype)
+ {
+ case TBYTE:
+ cols[jj].array = calloc(ntodo + 1, sizeof(char));
+ col[jj].nullsize = sizeof(char); /* number of bytes per value */
+
+ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG)
+ {
+ tnull = minvalue(tnull, 255);
+ tnull = maxvalue(tnull, 0);
+ col[jj].null.charnull = (unsigned char) tnull;
+ }
+ else
+ {
+ col[jj].null.charnull = (unsigned char) 255; /* use 255 as null */
+ }
+ break;
+
+ case TSBYTE:
+ cols[jj].array = calloc(ntodo + 1, sizeof(char));
+ col[jj].nullsize = sizeof(char); /* number of bytes per value */
+
+ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG)
+ {
+ tnull = minvalue(tnull, 127);
+ tnull = maxvalue(tnull, -128);
+ col[jj].null.scharnull = (signed char) tnull;
+ }
+ else
+ {
+ col[jj].null.scharnull = (signed char) -128; /* use -128 null */
+ }
+ break;
+
+ case TSHORT:
+ cols[jj].array = calloc(ntodo + 1, sizeof(short));
+ col[jj].nullsize = sizeof(short); /* number of bytes per value */
+
+ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG)
+ {
+ tnull = minvalue(tnull, SHRT_MAX);
+ tnull = maxvalue(tnull, SHRT_MIN);
+ col[jj].null.shortnull = (short) tnull;
+ }
+ else
+ {
+ col[jj].null.shortnull = SHRT_MIN; /* use minimum as null */
+ }
+ break;
+
+ case TUSHORT:
+ cols[jj].array = calloc(ntodo + 1, sizeof(unsigned short));
+ col[jj].nullsize = sizeof(unsigned short); /* bytes per value */
+
+ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG)
+ {
+ tnull = minvalue(tnull, USHRT_MAX);
+ tnull = maxvalue(tnull, 0); /* don't allow negative value */
+ col[jj].null.ushortnull = (unsigned short) tnull;
+ }
+ else
+ {
+ col[jj].null.ushortnull = USHRT_MAX; /* use maximum null */
+ }
+ break;
+
+ case TINT:
+ cols[jj].array = calloc(sizeof(int), ntodo + 1);
+ col[jj].nullsize = sizeof(int); /* number of bytes per value */
+
+ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG)
+ {
+ tnull = minvalue(tnull, INT_MAX);
+ tnull = maxvalue(tnull, INT_MIN);
+ col[jj].null.intnull = (int) tnull;
+ }
+ else
+ {
+ col[jj].null.intnull = INT_MIN; /* use minimum as null */
+ }
+ break;
+
+ case TUINT:
+ cols[jj].array = calloc(ntodo + 1, sizeof(unsigned int));
+ col[jj].nullsize = sizeof(unsigned int); /* bytes per value */
+
+ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG)
+ {
+ tnull = minvalue(tnull, INT32_MAX);
+ tnull = maxvalue(tnull, 0);
+ col[jj].null.uintnull = (unsigned int) tnull;
+ }
+ else
+ {
+ col[jj].null.intnull = UINT_MAX; /* use maximum as null */
+ }
+ break;
+
+ case TLONG:
+ cols[jj].array = calloc(ntodo + 1, sizeof(long));
+ col[jj].nullsize = sizeof(long); /* number of bytes per value */
+
+ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG)
+ {
+ col[jj].null.longnull = tnull;
+ }
+ else
+ {
+ col[jj].null.longnull = LONG_MIN; /* use minimum as null */
+ }
+ break;
+
+ case TULONG:
+ cols[jj].array = calloc(ntodo + 1, sizeof(unsigned long));
+ col[jj].nullsize = sizeof(unsigned long); /* bytes per value */
+
+ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG)
+ {
+ if (tnull < 0) /* can't use a negative null value */
+ col[jj].null.ulongnull = LONG_MAX;
+ else
+ col[jj].null.ulongnull = (unsigned long) tnull;
+ }
+ else
+ {
+ col[jj].null.ulongnull = LONG_MAX; /* use maximum as null */
+ }
+ break;
+
+ case TFLOAT:
+ cols[jj].array = calloc(ntodo + 1, sizeof(float));
+ col[jj].nullsize = sizeof(float); /* number of bytes per value */
+
+ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG)
+ {
+ col[jj].null.floatnull = (float) tnull;
+ }
+ else
+ {
+ col[jj].null.floatnull = FLOATNULLVALUE; /* special value */
+ }
+ break;
+
+ case TCOMPLEX:
+ cols[jj].array = calloc((ntodo * 2) + 1, sizeof(float));
+ col[jj].nullsize = sizeof(float); /* number of bytes per value */
+ col[jj].null.floatnull = FLOATNULLVALUE; /* special value */
+ break;
+
+ case TDOUBLE:
+ cols[jj].array = calloc(ntodo + 1, sizeof(double));
+ col[jj].nullsize = sizeof(double); /* number of bytes per value */
+
+ if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG)
+ {
+ col[jj].null.doublenull = (double) tnull;
+ }
+ else
+ {
+ col[jj].null.doublenull = DOUBLENULLVALUE; /* special value */
+ }
+ break;
+
+ case TDBLCOMPLEX:
+ cols[jj].array = calloc((ntodo * 2) + 1, sizeof(double));
+ col[jj].nullsize = sizeof(double); /* number of bytes per value */
+ col[jj].null.doublenull = DOUBLENULLVALUE; /* special value */
+ break;
+
+ case TSTRING:
+ /* allocate array of pointers to all the strings */
+ if( hdutype==ASCII_TBL ) rept = width;
+ stringptr = calloc((ntodo + 1) , sizeof(stringptr));
+ cols[jj].array = stringptr;
+ col[jj].nullsize = rept + 1; /* number of bytes per value */
+
+ if (stringptr)
+ {
+ /* allocate string to store the null string value */
+ col[jj].null.stringnull = calloc(rept + 1, sizeof(char) );
+ col[jj].null.stringnull[1] = 1; /* to make sure string != 0 */
+
+ /* allocate big block for the array of table column strings */
+ stringptr[0] = calloc((ntodo + 1) * (rept + 1), sizeof(char) );
+
+ if (stringptr[0])
+ {
+ for (ii = 1; ii <= ntodo; ii++)
+ { /* pointer to each string */
+ stringptr[ii] = stringptr[ii - 1] + (rept + 1);
+ }
+
+ /* get the TNULL keyword value, if it exists */
+ tstatus = 0;
+ ffkeyn("TNULL", cols[jj].colnum, keyname, &tstatus);
+ ffgkys(cols[jj].fptr, keyname, nullstr, 0, &tstatus);
+ if (!tstatus)
+ strncat(col[jj].null.stringnull, nullstr, rept);
+ }
+ else
+ {
+ ffpmsg("ffiter failed to allocate memory arrays");
+ *status = MEMORY_ALLOCATION; /* memory allocation failed */
+ goto cleanup;
+ }
+ }
+ break;
+
+ case TLOGICAL:
+
+ cols[jj].array = calloc(ntodo + 1, sizeof(char));
+ col[jj].nullsize = sizeof(char); /* number of bytes per value */
+
+ /* use value = 2 to flag null values in logical columns */
+ col[jj].null.charnull = 2;
+ break;
+
+ default:
+ sprintf(message,
+ "Column %d datatype currently not supported: %d: (ffiter)",
+ jj + 1, cols[jj].datatype);
+ ffpmsg(message);
+ *status = BAD_DATATYPE;
+ goto cleanup;
+
+ } /* end of switch block */
+
+ /* check that all the arrays were allocated successfully */
+ if (!cols[jj].array)
+ {
+ ffpmsg("ffiter failed to allocate memory arrays");
+ *status = MEMORY_ALLOCATION; /* memory allocation failed */
+ goto cleanup;
+ }
+ }
+
+ /*--------------------------------------------------*/
+ /* main loop while there are values left to process */
+ /*--------------------------------------------------*/
+
+ nleft = totaln;
+
+ while (nleft)
+ {
+ ntodo = minvalue(nleft, n_optimum); /* no. of values for this loop */
+
+ /* read input columns from FITS file(s) */
+ for (jj = 0; jj < n_cols; jj++)
+ {
+ if (cols[jj].iotype != OutputCol)
+ {
+ if (cols[jj].datatype == TSTRING)
+ {
+ stringptr = cols[jj].array;
+ dataptr = stringptr + 1;
+ defaultnull = col[jj].null.stringnull; /* ptr to the null value */
+ }
+ else
+ {
+ dataptr = (char *) cols[jj].array + col[jj].nullsize;
+ defaultnull = &col[jj].null.charnull; /* ptr to the null value */
+ }
+
+ if (hdutype == IMAGE_HDU)
+ {
+ if (ffgpv(cols[jj].fptr, cols[jj].datatype,
+ felement, cols[jj].repeat * ntodo, defaultnull,
+ dataptr, &anynul, status) > 0)
+ {
+ break;
+ }
+ }
+ else
+ {
+ if (ffgtcl(cols[jj].fptr, cols[jj].colnum, &typecode, &rept,&width, status) > 0)
+ goto cleanup;
+
+ if (typecode<0)
+ {
+ /* get size of the variable length vector */
+ ffgdes(cols[jj].fptr, cols[jj].colnum, frow,&cols[jj].repeat, NULL,status);
+ }
+
+ if (ffgcv(cols[jj].fptr, cols[jj].datatype, cols[jj].colnum,
+ frow, felement, cols[jj].repeat * ntodo, defaultnull,
+ dataptr, &anynul, status) > 0)
+ {
+ break;
+ }
+ }
+
+ /* copy the appropriate null value into first array element */
+
+ if (anynul) /* are there any nulls in the data? */
+ {
+ if (cols[jj].datatype == TSTRING)
+ {
+ stringptr = cols[jj].array;
+ memcpy(*stringptr, col[jj].null.stringnull, col[jj].nullsize);
+ }
+ else
+ {
+ memcpy(cols[jj].array, defaultnull, col[jj].nullsize);
+ }
+ }
+ else /* no null values so copy zero into first element */
+ {
+ if (cols[jj].datatype == TSTRING)
+ {
+ stringptr = cols[jj].array;
+ memset(*stringptr, 0, col[jj].nullsize);
+ }
+ else
+ {
+ memset(cols[jj].array, 0, col[jj].nullsize);
+ }
+ }
+ }
+ }
+
+ if (*status > 0)
+ break; /* looks like an error occurred; quit immediately */
+
+ /* call work function */
+
+ if (hdutype == IMAGE_HDU)
+ *status = work_fn(totaln, offset, felement, ntodo, n_cols, cols,
+ userPointer);
+ else
+ *status = work_fn(totaln, offset, frow, ntodo, n_cols, cols,
+ userPointer);
+
+ if (*status > 0 || *status < -1 )
+ break; /* looks like an error occurred; quit immediately */
+
+ /* write output columns before quiting if status = -1 */
+ tstatus = 0;
+ for (jj = 0; jj < n_cols; jj++)
+ {
+ if (cols[jj].iotype != InputCol)
+ {
+ if (cols[jj].datatype == TSTRING)
+ {
+ stringptr = cols[jj].array;
+ dataptr = stringptr + 1;
+ nullptr = *stringptr;
+ nbytes = 2;
+ }
+ else
+ {
+ dataptr = (char *) cols[jj].array + col[jj].nullsize;
+ nullptr = (char *) cols[jj].array;
+ nbytes = col[jj].nullsize;
+ }
+
+ if (memcmp(nullptr, &zeros, nbytes) )
+ {
+ /* null value flag not zero; must check for and write nulls */
+ if (hdutype == IMAGE_HDU)
+ {
+ if (ffppn(cols[jj].fptr, cols[jj].datatype,
+ felement, cols[jj].repeat * ntodo, dataptr,
+ nullptr, &tstatus) > 0)
+ break;
+ }
+ else
+ {
+ if (ffgtcl(cols[jj].fptr, cols[jj].colnum, &typecode, &rept,&width, status) > 0)
+ goto cleanup;
+
+ if (typecode<0) /* variable length array colum */
+ {
+ ffgdes(cols[jj].fptr, cols[jj].colnum, frow,&cols[jj].repeat, NULL,status);
+ }
+
+ if (ffpcn(cols[jj].fptr, cols[jj].datatype, cols[jj].colnum, frow,
+ felement, cols[jj].repeat * ntodo, dataptr,
+ nullptr, &tstatus) > 0)
+ break;
+ }
+ }
+ else
+ {
+ /* no null values; just write the array */
+ if (hdutype == IMAGE_HDU)
+ {
+ if (ffppr(cols[jj].fptr, cols[jj].datatype,
+ felement, cols[jj].repeat * ntodo, dataptr,
+ &tstatus) > 0)
+ break;
+ }
+ else
+ {
+ if (ffgtcl(cols[jj].fptr, cols[jj].colnum, &typecode, &rept,&width, status) > 0)
+ goto cleanup;
+
+ if (typecode<0) /* variable length array column */
+ {
+ ffgdes(cols[jj].fptr, cols[jj].colnum, frow,&cols[jj].repeat, NULL,status);
+ }
+
+ if (ffpcl(cols[jj].fptr, cols[jj].datatype, cols[jj].colnum, frow,
+ felement, cols[jj].repeat * ntodo, dataptr,
+ &tstatus) > 0)
+ break;
+ }
+ }
+ }
+ }
+
+ if (*status == 0)
+ *status = tstatus; /* propagate any error status from the writes */
+
+ if (*status)
+ break; /* exit on any error */
+
+ nleft -= ntodo;
+
+ if (hdutype == IMAGE_HDU)
+ felement += ntodo;
+ else
+ frow += ntodo;
+ }
+
+cleanup:
+
+ /*----------------------------------*/
+ /* free work arrays for the columns */
+ /*----------------------------------*/
+
+ for (jj = 0; jj < n_cols; jj++)
+ {
+ if (cols[jj].datatype == TSTRING)
+ {
+ if (cols[jj].array)
+ {
+ stringptr = cols[jj].array;
+ free(*stringptr); /* free the block of strings */
+ free(col[jj].null.stringnull); /* free the null string */
+ }
+ }
+ free(cols[jj].array); /* memory for the array of values from the col */
+ }
+ free(col); /* the structure containing the null values */
+ return(*status);
+}
+