"Fossies" - the Fresh Open Source Software Archive

Member "cfitsio-4.0.0/putcol.c" (20 May 2021, 67984 Bytes) of package /linux/misc/cfitsio-4.0.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*  This file, putcol.c, contains routines that write data elements to     */
    2 /*  a FITS image or table. These are the generic routines.                 */
    3 
    4 /*  The FITSIO software was written by William Pence at the High Energy    */
    5 /*  Astrophysic Science Archive Research Center (HEASARC) at the NASA      */
    6 /*  Goddard Space Flight Center.                                           */
    7 
    8 #include <string.h>
    9 #include <stdlib.h>
   10 #include <limits.h>
   11 #include "fitsio2.h"
   12 
   13 /*--------------------------------------------------------------------------*/
   14 int ffppx(  fitsfile *fptr,  /* I - FITS file pointer                       */
   15             int  datatype,   /* I - datatype of the value                   */
   16             long  *firstpix, /* I - coord of  first pixel to write(1 based) */
   17             LONGLONG  nelem,     /* I - number of values to write               */
   18             void  *array,    /* I - array of values that are written        */
   19             int  *status)    /* IO - error status                           */
   20 /*
   21   Write an array of pixels to the primary array.  The datatype of the
   22   input array is defined by the 2nd argument. Data conversion
   23   and scaling will be performed if necessary (e.g, if the datatype of
   24   the FITS array is not the same as the array being written). 
   25   
   26   This routine is simillar to ffppr, except it supports writing to 
   27   large images with more than 2**31 pixels.
   28 */
   29 {
   30     int naxis, ii;
   31     long group = 1;
   32     LONGLONG firstelem, dimsize = 1, naxes[9];
   33 
   34     if (*status > 0)           /* inherit input status value if > 0 */
   35         return(*status);
   36 
   37     /* get the size of the image */
   38     ffgidm(fptr, &naxis, status);
   39     ffgiszll(fptr, 9, naxes, status);
   40 
   41     firstelem = 0;
   42     for (ii=0; ii < naxis; ii++)
   43     {
   44         firstelem += ((firstpix[ii] - 1) * dimsize);
   45         dimsize *= naxes[ii];
   46     }
   47     firstelem++;
   48 
   49     if (datatype == TBYTE)
   50     {
   51       ffpprb(fptr, group, firstelem, nelem, (unsigned char *) array, status);
   52     }
   53     else if (datatype == TSBYTE)
   54     {
   55       ffpprsb(fptr, group, firstelem, nelem, (signed char *) array, status);
   56     }
   57     else if (datatype == TUSHORT)
   58     {
   59       ffpprui(fptr, group, firstelem, nelem, (unsigned short *) array,
   60               status);
   61     }
   62     else if (datatype == TSHORT)
   63     {
   64       ffppri(fptr, group, firstelem, nelem, (short *) array, status);
   65     }
   66     else if (datatype == TUINT)
   67     {
   68       ffppruk(fptr, group, firstelem, nelem, (unsigned int *) array, status);
   69     }
   70     else if (datatype == TINT)
   71     {
   72       ffpprk(fptr, group, firstelem, nelem, (int *) array, status);
   73     }
   74     else if (datatype == TULONG)
   75     {
   76       ffppruj(fptr, group, firstelem, nelem, (unsigned long *) array, status);
   77     }
   78     else if (datatype == TLONG)
   79     {
   80       ffpprj(fptr, group, firstelem, nelem, (long *) array, status);
   81     }
   82     else if (datatype == TULONGLONG)
   83     {
   84       ffpprujj(fptr, group, firstelem, nelem, (ULONGLONG *) array, status);
   85     }
   86     else if (datatype == TLONGLONG)
   87     {
   88       ffpprjj(fptr, group, firstelem, nelem, (LONGLONG *) array, status);
   89     }
   90     else if (datatype == TFLOAT)
   91     {
   92       ffppre(fptr, group, firstelem, nelem, (float *) array, status);
   93     }
   94     else if (datatype == TDOUBLE)
   95     {
   96       ffpprd(fptr, group, firstelem, nelem, (double *) array, status);
   97     }
   98     else
   99       *status = BAD_DATATYPE;
  100 
  101     return(*status);
  102 }
  103 /*--------------------------------------------------------------------------*/
  104 int ffppxll(  fitsfile *fptr,  /* I - FITS file pointer                       */
  105             int  datatype,   /* I - datatype of the value                   */
  106             LONGLONG  *firstpix, /* I - coord of  first pixel to write(1 based) */
  107             LONGLONG  nelem,     /* I - number of values to write               */
  108             void  *array,    /* I - array of values that are written        */
  109             int  *status)    /* IO - error status                           */
  110 /*
  111   Write an array of pixels to the primary array.  The datatype of the
  112   input array is defined by the 2nd argument. Data conversion
  113   and scaling will be performed if necessary (e.g, if the datatype of
  114   the FITS array is not the same as the array being written). 
  115   
  116   This routine is simillar to ffppr, except it supports writing to 
  117   large images with more than 2**31 pixels.
  118 */
  119 {
  120     int naxis, ii;
  121     long group = 1;
  122     LONGLONG firstelem, dimsize = 1, naxes[9];
  123 
  124     if (*status > 0)           /* inherit input status value if > 0 */
  125         return(*status);
  126 
  127     /* get the size of the image */
  128     ffgidm(fptr, &naxis, status);
  129     ffgiszll(fptr, 9, naxes, status);
  130 
  131     firstelem = 0;
  132     for (ii=0; ii < naxis; ii++)
  133     {
  134         firstelem += ((firstpix[ii] - 1) * dimsize);
  135         dimsize *= naxes[ii];
  136     }
  137     firstelem++;
  138 
  139     if (datatype == TBYTE)
  140     {
  141       ffpprb(fptr, group, firstelem, nelem, (unsigned char *) array, status);
  142     }
  143     else if (datatype == TSBYTE)
  144     {
  145       ffpprsb(fptr, group, firstelem, nelem, (signed char *) array, status);
  146     }
  147     else if (datatype == TUSHORT)
  148     {
  149       ffpprui(fptr, group, firstelem, nelem, (unsigned short *) array,
  150               status);
  151     }
  152     else if (datatype == TSHORT)
  153     {
  154       ffppri(fptr, group, firstelem, nelem, (short *) array, status);
  155     }
  156     else if (datatype == TUINT)
  157     {
  158       ffppruk(fptr, group, firstelem, nelem, (unsigned int *) array, status);
  159     }
  160     else if (datatype == TINT)
  161     {
  162       ffpprk(fptr, group, firstelem, nelem, (int *) array, status);
  163     }
  164     else if (datatype == TULONG)
  165     {
  166       ffppruj(fptr, group, firstelem, nelem, (unsigned long *) array, status);
  167     }
  168     else if (datatype == TLONG)
  169     {
  170       ffpprj(fptr, group, firstelem, nelem, (long *) array, status);
  171     }
  172     else if (datatype == TULONGLONG)
  173     {
  174       ffpprujj(fptr, group, firstelem, nelem, (ULONGLONG *) array, status);
  175     }
  176     else if (datatype == TLONGLONG)
  177     {
  178       ffpprjj(fptr, group, firstelem, nelem, (LONGLONG *) array, status);
  179     }
  180     else if (datatype == TFLOAT)
  181     {
  182       ffppre(fptr, group, firstelem, nelem, (float *) array, status);
  183     }
  184     else if (datatype == TDOUBLE)
  185     {
  186       ffpprd(fptr, group, firstelem, nelem, (double *) array, status);
  187     }
  188     else
  189       *status = BAD_DATATYPE;
  190 
  191     return(*status);
  192 }
  193 /*--------------------------------------------------------------------------*/
  194 int ffppxn(  fitsfile *fptr,  /* I - FITS file pointer                       */
  195             int  datatype,   /* I - datatype of the value                   */
  196             long  *firstpix, /* I - first vector element to write(1 = 1st)  */
  197             LONGLONG  nelem,     /* I - number of values to write               */
  198             void  *array,    /* I - array of values that are written        */
  199             void  *nulval,   /* I - pointer to the null value               */
  200             int  *status)    /* IO - error status                           */
  201 /*
  202   Write an array of values to the primary array.  The datatype of the
  203   input array is defined by the 2nd argument. Data conversion
  204   and scaling will be performed if necessary (e.g, if the datatype of
  205   the FITS array is not the same as the array being written).
  206 
  207   This routine supports writing to large images with
  208   more than 2**31 pixels.
  209 */
  210 {
  211     int naxis, ii;
  212     long group = 1;
  213     LONGLONG firstelem, dimsize = 1, naxes[9];
  214 
  215     if (*status > 0)           /* inherit input status value if > 0 */
  216         return(*status);
  217 
  218     if (nulval == NULL)  /* null value not defined? */
  219     {
  220         ffppx(fptr, datatype, firstpix, nelem, array, status);
  221         return(*status);
  222     }
  223 
  224     /* get the size of the image */
  225     ffgidm(fptr, &naxis, status);
  226     ffgiszll(fptr, 9, naxes, status);
  227 
  228     firstelem = 0;
  229     for (ii=0; ii < naxis; ii++)
  230     {
  231         firstelem += ((firstpix[ii] - 1) * dimsize);
  232         dimsize *= naxes[ii];
  233     }
  234     firstelem++;
  235 
  236     if (datatype == TBYTE)
  237     {
  238       ffppnb(fptr, group, firstelem, nelem, (unsigned char *) array, 
  239              *(unsigned char *) nulval, status);
  240     }
  241     else if (datatype == TSBYTE)
  242     {
  243       ffppnsb(fptr, group, firstelem, nelem, (signed char *) array, 
  244              *(signed char *) nulval, status);
  245     }
  246     else if (datatype == TUSHORT)
  247     {
  248       ffppnui(fptr, group, firstelem, nelem, (unsigned short *) array,
  249               *(unsigned short *) nulval,status);
  250     }
  251     else if (datatype == TSHORT)
  252     {
  253       ffppni(fptr, group, firstelem, nelem, (short *) array,
  254              *(short *) nulval, status);
  255     }
  256     else if (datatype == TUINT)
  257     {
  258       ffppnuk(fptr, group, firstelem, nelem, (unsigned int *) array,
  259              *(unsigned int *) nulval, status);
  260     }
  261     else if (datatype == TINT)
  262     {
  263       ffppnk(fptr, group, firstelem, nelem, (int *) array,
  264              *(int *) nulval, status);
  265     }
  266     else if (datatype == TULONG)
  267     {
  268       ffppnuj(fptr, group, firstelem, nelem, (unsigned long *) array,
  269               *(unsigned long *) nulval,status);
  270     }
  271     else if (datatype == TLONG)
  272     {
  273       ffppnj(fptr, group, firstelem, nelem, (long *) array,
  274              *(long *) nulval, status);
  275     }
  276     else if (datatype == TULONGLONG)
  277     {
  278       ffppnujj(fptr, group, firstelem, nelem, (ULONGLONG *) array,
  279              *(ULONGLONG *) nulval, status);
  280     }
  281     else if (datatype == TLONGLONG)
  282     {
  283       ffppnjj(fptr, group, firstelem, nelem, (LONGLONG *) array,
  284              *(LONGLONG *) nulval, status);
  285     }
  286     else if (datatype == TFLOAT)
  287     {
  288       ffppne(fptr, group, firstelem, nelem, (float *) array,
  289              *(float *) nulval, status);
  290     }
  291     else if (datatype == TDOUBLE)
  292     {
  293       ffppnd(fptr, group, firstelem, nelem, (double *) array,
  294              *(double *) nulval, status);
  295     }
  296     else
  297       *status = BAD_DATATYPE;
  298 
  299     return(*status);
  300 }
  301 /*--------------------------------------------------------------------------*/
  302 int ffppxnll(  fitsfile *fptr,  /* I - FITS file pointer                       */
  303             int  datatype,   /* I - datatype of the value                   */
  304             LONGLONG  *firstpix, /* I - first vector element to write(1 = 1st)  */
  305             LONGLONG  nelem,     /* I - number of values to write               */
  306             void  *array,    /* I - array of values that are written        */
  307             void  *nulval,   /* I - pointer to the null value               */
  308             int  *status)    /* IO - error status                           */
  309 /*
  310   Write an array of values to the primary array.  The datatype of the
  311   input array is defined by the 2nd argument. Data conversion
  312   and scaling will be performed if necessary (e.g, if the datatype of
  313   the FITS array is not the same as the array being written).
  314 
  315   This routine supports writing to large images with
  316   more than 2**31 pixels.
  317 */
  318 {
  319     int naxis, ii;
  320     long  group = 1;
  321     LONGLONG firstelem, dimsize = 1, naxes[9];
  322 
  323     if (*status > 0)           /* inherit input status value if > 0 */
  324         return(*status);
  325 
  326     if (nulval == NULL)  /* null value not defined? */
  327     {
  328         ffppxll(fptr, datatype, firstpix, nelem, array, status);
  329         return(*status);
  330     }
  331 
  332     /* get the size of the image */
  333     ffgidm(fptr, &naxis, status);
  334     ffgiszll(fptr, 9, naxes, status);
  335 
  336     firstelem = 0;
  337     for (ii=0; ii < naxis; ii++)
  338     {
  339         firstelem += ((firstpix[ii] - 1) * dimsize);
  340         dimsize *= naxes[ii];
  341     }
  342     firstelem++;
  343 
  344     if (datatype == TBYTE)
  345     {
  346       ffppnb(fptr, group, firstelem, nelem, (unsigned char *) array, 
  347              *(unsigned char *) nulval, status);
  348     }
  349     else if (datatype == TSBYTE)
  350     {
  351       ffppnsb(fptr, group, firstelem, nelem, (signed char *) array, 
  352              *(signed char *) nulval, status);
  353     }
  354     else if (datatype == TUSHORT)
  355     {
  356       ffppnui(fptr, group, firstelem, nelem, (unsigned short *) array,
  357               *(unsigned short *) nulval,status);
  358     }
  359     else if (datatype == TSHORT)
  360     {
  361       ffppni(fptr, group, firstelem, nelem, (short *) array,
  362              *(short *) nulval, status);
  363     }
  364     else if (datatype == TUINT)
  365     {
  366       ffppnuk(fptr, group, firstelem, nelem, (unsigned int *) array,
  367              *(unsigned int *) nulval, status);
  368     }
  369     else if (datatype == TINT)
  370     {
  371       ffppnk(fptr, group, firstelem, nelem, (int *) array,
  372              *(int *) nulval, status);
  373     }
  374     else if (datatype == TULONG)
  375     {
  376       ffppnuj(fptr, group, firstelem, nelem, (unsigned long *) array,
  377               *(unsigned long *) nulval,status);
  378     }
  379     else if (datatype == TLONG)
  380     {
  381       ffppnj(fptr, group, firstelem, nelem, (long *) array,
  382              *(long *) nulval, status);
  383     }
  384     else if (datatype == TULONGLONG)
  385     {
  386       ffppnujj(fptr, group, firstelem, nelem, (ULONGLONG *) array,
  387              *(ULONGLONG *) nulval, status);
  388     }
  389     else if (datatype == TLONGLONG)
  390     {
  391       ffppnjj(fptr, group, firstelem, nelem, (LONGLONG *) array,
  392              *(LONGLONG *) nulval, status);
  393     }
  394     else if (datatype == TFLOAT)
  395     {
  396       ffppne(fptr, group, firstelem, nelem, (float *) array,
  397              *(float *) nulval, status);
  398     }
  399     else if (datatype == TDOUBLE)
  400     {
  401       ffppnd(fptr, group, firstelem, nelem, (double *) array,
  402              *(double *) nulval, status);
  403     }
  404     else
  405       *status = BAD_DATATYPE;
  406 
  407     return(*status);
  408 }
  409 /*--------------------------------------------------------------------------*/
  410 int ffppr(  fitsfile *fptr,  /* I - FITS file pointer                       */
  411             int  datatype,   /* I - datatype of the value                   */
  412             LONGLONG  firstelem, /* I - first vector element to write(1 = 1st)  */
  413             LONGLONG  nelem,     /* I - number of values to write               */
  414             void  *array,    /* I - array of values that are written        */
  415             int  *status)    /* IO - error status                           */
  416 /*
  417   Write an array of values to the primary array.  The datatype of the
  418   input array is defined by the 2nd argument. Data conversion
  419   and scaling will be performed if necessary (e.g, if the datatype of
  420   the FITS array is not the same as the array being written).
  421 
  422 */
  423 {
  424     long group = 1;
  425 
  426     if (*status > 0)           /* inherit input status value if > 0 */
  427         return(*status);
  428 
  429     if (datatype == TBYTE)
  430     {
  431       ffpprb(fptr, group, firstelem, nelem, (unsigned char *) array, status);
  432     }
  433     else if (datatype == TSBYTE)
  434     {
  435       ffpprsb(fptr, group, firstelem, nelem, (signed char *) array, status);
  436     }
  437     else if (datatype == TUSHORT)
  438     {
  439       ffpprui(fptr, group, firstelem, nelem, (unsigned short *) array,
  440               status);
  441     }
  442     else if (datatype == TSHORT)
  443     {
  444       ffppri(fptr, group, firstelem, nelem, (short *) array, status);
  445     }
  446     else if (datatype == TUINT)
  447     {
  448       ffppruk(fptr, group, firstelem, nelem, (unsigned int *) array, status);
  449     }
  450     else if (datatype == TINT)
  451     {
  452       ffpprk(fptr, group, firstelem, nelem, (int *) array, status);
  453     }
  454     else if (datatype == TULONG)
  455     {
  456       ffppruj(fptr, group, firstelem, nelem, (unsigned long *) array, status);
  457     }
  458     else if (datatype == TLONG)
  459     {
  460       ffpprj(fptr, group, firstelem, nelem, (long *) array, status);
  461     }
  462     else if (datatype == TULONGLONG)
  463     {
  464       ffpprujj(fptr, group, firstelem, nelem, (ULONGLONG *) array, status);
  465     }
  466     else if (datatype == TLONGLONG)
  467     {
  468       ffpprjj(fptr, group, firstelem, nelem, (LONGLONG *) array, status);
  469     }
  470     else if (datatype == TFLOAT)
  471     {
  472       ffppre(fptr, group, firstelem, nelem, (float *) array, status);
  473     }
  474     else if (datatype == TDOUBLE)
  475     {
  476       ffpprd(fptr, group, firstelem, nelem, (double *) array, status);
  477     }
  478     else
  479       *status = BAD_DATATYPE;
  480 
  481     return(*status);
  482 }
  483 /*--------------------------------------------------------------------------*/
  484 int ffppn(  fitsfile *fptr,  /* I - FITS file pointer                       */
  485             int  datatype,   /* I - datatype of the value                   */
  486             LONGLONG  firstelem, /* I - first vector element to write(1 = 1st)  */
  487             LONGLONG  nelem,     /* I - number of values to write               */
  488             void  *array,    /* I - array of values that are written        */
  489             void  *nulval,   /* I - pointer to the null value               */
  490             int  *status)    /* IO - error status                           */
  491 /*
  492   Write an array of values to the primary array.  The datatype of the
  493   input array is defined by the 2nd argument. Data conversion
  494   and scaling will be performed if necessary (e.g, if the datatype of
  495   the FITS array is not the same as the array being written).
  496 
  497 */
  498 {
  499     long group = 1;
  500 
  501     if (*status > 0)           /* inherit input status value if > 0 */
  502         return(*status);
  503 
  504     if (nulval == NULL)  /* null value not defined? */
  505     {
  506         ffppr(fptr, datatype, firstelem, nelem, array, status);
  507         return(*status);
  508     }
  509 
  510     if (datatype == TBYTE)
  511     {
  512       ffppnb(fptr, group, firstelem, nelem, (unsigned char *) array, 
  513              *(unsigned char *) nulval, status);
  514     }
  515     else if (datatype == TSBYTE)
  516     {
  517       ffppnsb(fptr, group, firstelem, nelem, (signed char *) array, 
  518              *(signed char *) nulval, status);
  519     }
  520     else if (datatype == TUSHORT)
  521     {
  522       ffppnui(fptr, group, firstelem, nelem, (unsigned short *) array,
  523               *(unsigned short *) nulval,status);
  524     }
  525     else if (datatype == TSHORT)
  526     {
  527       ffppni(fptr, group, firstelem, nelem, (short *) array,
  528              *(short *) nulval, status);
  529     }
  530     else if (datatype == TUINT)
  531     {
  532       ffppnuk(fptr, group, firstelem, nelem, (unsigned int *) array,
  533              *(unsigned int *) nulval, status);
  534     }
  535     else if (datatype == TINT)
  536     {
  537       ffppnk(fptr, group, firstelem, nelem, (int *) array,
  538              *(int *) nulval, status);
  539     }
  540     else if (datatype == TULONG)
  541     {
  542       ffppnuj(fptr, group, firstelem, nelem, (unsigned long *) array,
  543               *(unsigned long *) nulval,status);
  544     }
  545     else if (datatype == TLONG)
  546     {
  547       ffppnj(fptr, group, firstelem, nelem, (long *) array,
  548              *(long *) nulval, status);
  549     }
  550     else if (datatype == TULONGLONG)
  551     {
  552       ffppnujj(fptr, group, firstelem, nelem, (ULONGLONG *) array,
  553              *(ULONGLONG *) nulval, status);
  554     }
  555     else if (datatype == TLONGLONG)
  556     {
  557       ffppnjj(fptr, group, firstelem, nelem, (LONGLONG *) array,
  558              *(LONGLONG *) nulval, status);
  559     }
  560     else if (datatype == TFLOAT)
  561     {
  562       ffppne(fptr, group, firstelem, nelem, (float *) array,
  563              *(float *) nulval, status);
  564     }
  565     else if (datatype == TDOUBLE)
  566     {
  567       ffppnd(fptr, group, firstelem, nelem, (double *) array,
  568              *(double *) nulval, status);
  569     }
  570     else
  571       *status = BAD_DATATYPE;
  572 
  573     return(*status);
  574 }
  575 /*--------------------------------------------------------------------------*/
  576 int ffpss(  fitsfile *fptr,   /* I - FITS file pointer                       */
  577             int  datatype,    /* I - datatype of the value                   */
  578             long *blc,        /* I - 'bottom left corner' of the subsection  */
  579             long *trc ,       /* I - 'top right corner' of the subsection    */
  580             void *array,      /* I - array of values that are written        */
  581             int  *status)     /* IO - error status                           */
  582 /*
  583   Write a section of values to the primary array. The datatype of the
  584   input array is defined by the 2nd argument.  Data conversion
  585   and scaling will be performed if necessary (e.g, if the datatype of
  586   the FITS array is not the same as the array being written).
  587 
  588   This routine supports writing to large images with
  589   more than 2**31 pixels.
  590 */
  591 {
  592     int naxis;
  593     long naxes[9];
  594 
  595     if (*status > 0)   /* inherit input status value if > 0 */
  596         return(*status);
  597 
  598     /* get the size of the image */
  599     ffgidm(fptr, &naxis, status);
  600     ffgisz(fptr, 9, naxes, status);
  601 
  602     if (datatype == TBYTE)
  603     {
  604         ffpssb(fptr, 1, naxis, naxes, blc, trc,
  605                (unsigned char *) array, status);
  606     }
  607     else if (datatype == TSBYTE)
  608     {
  609         ffpsssb(fptr, 1, naxis, naxes, blc, trc,
  610                (signed char *) array, status);
  611     }
  612     else if (datatype == TUSHORT)
  613     {
  614         ffpssui(fptr, 1, naxis, naxes, blc, trc,
  615                (unsigned short *) array, status);
  616     }
  617     else if (datatype == TSHORT)
  618     {
  619         ffpssi(fptr, 1, naxis, naxes, blc, trc,
  620                (short *) array, status);
  621     }
  622     else if (datatype == TUINT)
  623     {
  624         ffpssuk(fptr, 1, naxis, naxes, blc, trc,
  625                (unsigned int *) array, status);
  626     }
  627     else if (datatype == TINT)
  628     {
  629         ffpssk(fptr, 1, naxis, naxes, blc, trc,
  630                (int *) array, status);
  631     }
  632     else if (datatype == TULONG)
  633     {
  634         ffpssuj(fptr, 1, naxis, naxes, blc, trc,
  635                (unsigned long *) array, status);
  636     }
  637     else if (datatype == TLONG)
  638     {
  639         ffpssj(fptr, 1, naxis, naxes, blc, trc,
  640                (long *) array, status);
  641     }
  642     else if (datatype == TULONGLONG)
  643     {
  644         ffpssujj(fptr, 1, naxis, naxes, blc, trc,
  645                (ULONGLONG *) array, status);
  646     }
  647     else if (datatype == TLONGLONG)
  648     {
  649         ffpssjj(fptr, 1, naxis, naxes, blc, trc,
  650                (LONGLONG *) array, status);
  651     }    
  652     else if (datatype == TFLOAT)
  653     {
  654         ffpsse(fptr, 1, naxis, naxes, blc, trc,
  655                (float *) array, status);
  656     }
  657     else if (datatype == TDOUBLE)
  658     {
  659         ffpssd(fptr, 1, naxis, naxes, blc, trc,
  660                (double *) array, status);
  661     }
  662     else
  663       *status = BAD_DATATYPE;
  664 
  665     return(*status);
  666 }
  667 /*--------------------------------------------------------------------------*/
  668 int ffpcl(  fitsfile *fptr,  /* I - FITS file pointer                       */
  669             int  datatype,   /* I - datatype of the value                   */
  670             int  colnum,     /* I - number of column to write (1 = 1st col) */
  671             LONGLONG  firstrow,  /* I - first row to write (1 = 1st row)        */
  672             LONGLONG  firstelem, /* I - first vector element to write (1 = 1st) */
  673             LONGLONG  nelem,     /* I - number of elements to write             */
  674             void  *array,    /* I - array of values that are written        */
  675             int  *status)    /* IO - error status                           */
  676 /*
  677   Write an array of values to a table column.  The datatype of the
  678   input array is defined by the 2nd argument. Data conversion
  679   and scaling will be performed if necessary (e.g, if the datatype of
  680   the FITS column is not the same as the array being written).
  681 
  682 */
  683 {
  684     if (*status > 0)           /* inherit input status value if > 0 */
  685         return(*status);
  686 
  687     if (datatype == TBIT)
  688     {
  689       ffpclx(fptr, colnum, firstrow, (long) firstelem, (long) nelem, (char *) array, 
  690              status);
  691     }
  692     else if (datatype == TBYTE)
  693     {
  694       ffpclb(fptr, colnum, firstrow, firstelem, nelem, (unsigned char *) array,
  695              status);
  696     }
  697     else if (datatype == TSBYTE)
  698     {
  699       ffpclsb(fptr, colnum, firstrow, firstelem, nelem, (signed char *) array,
  700              status);
  701     }
  702     else if (datatype == TUSHORT)
  703     {
  704       ffpclui(fptr, colnum, firstrow, firstelem, nelem, 
  705              (unsigned short *) array, status);
  706     }
  707     else if (datatype == TSHORT)
  708     {
  709       ffpcli(fptr, colnum, firstrow, firstelem, nelem, (short *) array,
  710              status);
  711     }
  712     else if (datatype == TUINT)
  713     {
  714       ffpcluk(fptr, colnum, firstrow, firstelem, nelem, (unsigned int *) array,
  715                status);
  716     }
  717     else if (datatype == TINT)
  718     {
  719       ffpclk(fptr, colnum, firstrow, firstelem, nelem, (int *) array,
  720                status);
  721     }
  722     else if (datatype == TULONG)
  723     {
  724       ffpcluj(fptr, colnum, firstrow, firstelem, nelem, (unsigned long *) array,
  725               status);
  726     }
  727     else if (datatype == TLONG)
  728     {
  729       ffpclj(fptr, colnum, firstrow, firstelem, nelem, (long *) array,
  730              status);
  731     }
  732     else if (datatype == TULONGLONG)
  733     {
  734       ffpclujj(fptr, colnum, firstrow, firstelem, nelem, (ULONGLONG *) array,
  735              status);
  736     }
  737     else if (datatype == TLONGLONG)
  738     {
  739       ffpcljj(fptr, colnum, firstrow, firstelem, nelem, (LONGLONG *) array,
  740              status);
  741     }
  742     else if (datatype == TFLOAT)
  743     {
  744       ffpcle(fptr, colnum, firstrow, firstelem, nelem, (float *) array,
  745              status);
  746     }
  747     else if (datatype == TDOUBLE)
  748     {
  749       ffpcld(fptr, colnum, firstrow, firstelem, nelem, (double *) array,
  750              status);
  751     }
  752     else if (datatype == TCOMPLEX)
  753     {
  754       ffpcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2,
  755              (float *) array, status);
  756     }
  757     else if (datatype == TDBLCOMPLEX)
  758     {
  759       ffpcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2,
  760              (double *) array, status);
  761     }
  762     else if (datatype == TLOGICAL)
  763     {
  764       ffpcll(fptr, colnum, firstrow, firstelem, nelem, (char *) array,
  765              status);
  766     }
  767     else if (datatype == TSTRING)
  768     {
  769       ffpcls(fptr, colnum, firstrow, firstelem, nelem, (char **) array,
  770              status);
  771     }
  772     else
  773       *status = BAD_DATATYPE;
  774 
  775     return(*status);
  776 }
  777 /*--------------------------------------------------------------------------*/
  778 int ffpcn(  fitsfile *fptr,  /* I - FITS file pointer                       */
  779             int  datatype,   /* I - datatype of the value                   */
  780             int  colnum,     /* I - number of column to write (1 = 1st col) */
  781             LONGLONG  firstrow,  /* I - first row to write (1 = 1st row)        */
  782             LONGLONG  firstelem, /* I - first vector element to write (1 = 1st) */
  783             LONGLONG  nelem,     /* I - number of elements to write             */
  784             void  *array,    /* I - array of values that are written        */
  785             void  *nulval,   /* I - pointer to the null value               */
  786             int  *status)    /* IO - error status                           */
  787 /*
  788   Write an array of values to a table column.  The datatype of the
  789   input array is defined by the 2nd argument. Data conversion
  790   and scaling will be performed if necessary (e.g, if the datatype of
  791   the FITS column is not the same as the array being written).
  792 
  793 */
  794 {
  795     if (*status > 0)           /* inherit input status value if > 0 */
  796         return(*status);
  797 
  798     if (nulval == NULL)  /* null value not defined? */
  799     {
  800         ffpcl(fptr, datatype, colnum, firstrow, firstelem, nelem, array,
  801               status);
  802         return(*status);
  803     }
  804 
  805     if (datatype == TBYTE)
  806     {
  807       ffpcnb(fptr, colnum, firstrow, firstelem, nelem, (unsigned char *) array,
  808             *(unsigned char *) nulval, status);
  809     }
  810     else if (datatype == TSBYTE)
  811     {
  812       ffpcnsb(fptr, colnum, firstrow, firstelem, nelem, (signed char *) array,
  813             *(signed char *) nulval, status);
  814     }
  815     else if (datatype == TUSHORT)
  816     {
  817      ffpcnui(fptr, colnum, firstrow, firstelem, nelem, (unsigned short *) array,
  818              *(unsigned short *) nulval, status);
  819     }
  820     else if (datatype == TSHORT)
  821     {
  822       ffpcni(fptr, colnum, firstrow, firstelem, nelem, (short *) array,
  823              *(unsigned short *) nulval, status);
  824     }
  825     else if (datatype == TUINT)
  826     {
  827       ffpcnuk(fptr, colnum, firstrow, firstelem, nelem, (unsigned int *) array,
  828              *(unsigned int *) nulval, status);
  829     }
  830     else if (datatype == TINT)
  831     {
  832       ffpcnk(fptr, colnum, firstrow, firstelem, nelem, (int *) array,
  833              *(int *) nulval, status);
  834     }
  835     else if (datatype == TULONG)
  836     {
  837       ffpcnuj(fptr, colnum, firstrow, firstelem, nelem, (unsigned long *) array,
  838               *(unsigned long *) nulval, status);
  839     }
  840     else if (datatype == TLONG)
  841     {
  842       ffpcnj(fptr, colnum, firstrow, firstelem, nelem, (long *) array,
  843              *(long *) nulval, status);
  844     }
  845     else if (datatype == TULONGLONG)
  846     {
  847       ffpcnujj(fptr, colnum, firstrow, firstelem, nelem, (ULONGLONG *) array,
  848              *(ULONGLONG *) nulval, status);
  849     }
  850     else if (datatype == TLONGLONG)
  851     {
  852       ffpcnjj(fptr, colnum, firstrow, firstelem, nelem, (LONGLONG *) array,
  853              *(LONGLONG *) nulval, status);
  854     }
  855     else if (datatype == TFLOAT)
  856     {
  857       ffpcne(fptr, colnum, firstrow, firstelem, nelem, (float *) array,
  858              *(float *) nulval, status);
  859     }
  860     else if (datatype == TDOUBLE)
  861     {
  862       ffpcnd(fptr, colnum, firstrow, firstelem, nelem, (double *) array,
  863              *(double *) nulval, status);
  864     }
  865     else if (datatype == TCOMPLEX)
  866     {
  867       ffpcne(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2,
  868              (float *) array, *(float *) nulval, status);
  869     }
  870     else if (datatype == TDBLCOMPLEX)
  871     {
  872       ffpcnd(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2,
  873              (double *) array, *(double *) nulval, status);
  874     }
  875     else if (datatype == TLOGICAL)
  876     {
  877       ffpcnl(fptr, colnum, firstrow, firstelem, nelem, (char *) array,
  878              *(char *) nulval, status);
  879     }
  880     else if (datatype == TSTRING)
  881     {
  882       ffpcns(fptr, colnum, firstrow, firstelem, nelem, (char **) array,
  883              (char *) nulval, status);
  884     }
  885     else
  886       *status = BAD_DATATYPE;
  887 
  888     return(*status);
  889 }
  890 /*--------------------------------------------------------------------------*/
  891 int fits_iter_set_by_name(iteratorCol *col, /* I - iterator col structure */
  892            fitsfile *fptr,  /* I - FITS file pointer                      */
  893            char *colname,   /* I - column name                            */
  894            int datatype,    /* I - column datatype                        */
  895            int iotype)      /* I - InputCol, InputOutputCol, or OutputCol */
  896 /*
  897   set all the parameters for an iterator column, by column name
  898 */
  899 {
  900     col->fptr = fptr;
  901     strncpy(col->colname, colname,69);
  902     col->colname[69]=0;
  903     col->colnum = 0;  /* set column number undefined since name is given */
  904     col->datatype = datatype;
  905     col->iotype = iotype;
  906     return(0);
  907 }
  908 /*--------------------------------------------------------------------------*/
  909 int fits_iter_set_by_num(iteratorCol *col, /* I - iterator column structure */
  910            fitsfile *fptr,  /* I - FITS file pointer                      */
  911            int colnum,      /* I - column number                          */
  912            int datatype,    /* I - column datatype                        */
  913            int iotype)      /* I - InputCol, InputOutputCol, or OutputCol */
  914 /*
  915   set all the parameters for an iterator column, by column number
  916 */
  917 {
  918     col->fptr = fptr;
  919     col->colnum = colnum; 
  920     col->datatype = datatype;
  921     col->iotype = iotype;
  922     return(0);
  923 }
  924 /*--------------------------------------------------------------------------*/
  925 int fits_iter_set_file(iteratorCol *col, /* I - iterator column structure   */
  926            fitsfile *fptr)   /* I - FITS file pointer                      */
  927 /*
  928   set iterator column parameter
  929 */
  930 {
  931     col->fptr = fptr;
  932     return(0);
  933 }
  934 /*--------------------------------------------------------------------------*/
  935 int fits_iter_set_colname(iteratorCol *col, /* I - iterator col structure  */
  936            char *colname)    /* I - column name                            */
  937 /*
  938   set iterator column parameter
  939 */
  940 {
  941     strncpy(col->colname, colname,69);
  942     col->colname[69]=0;
  943     col->colnum = 0;  /* set column number undefined since name is given */
  944     return(0);
  945 }
  946 /*--------------------------------------------------------------------------*/
  947 int fits_iter_set_colnum(iteratorCol *col, /* I - iterator column structure */
  948            int colnum)       /* I - column number                          */
  949 /*
  950   set iterator column parameter
  951 */
  952 {
  953     col->colnum = colnum; 
  954     return(0);
  955 }
  956 /*--------------------------------------------------------------------------*/
  957 int fits_iter_set_datatype(iteratorCol *col, /* I - iterator col structure */
  958            int datatype)    /* I - column datatype                        */
  959 /*
  960   set iterator column parameter
  961 */
  962 {
  963     col->datatype = datatype;
  964     return(0);
  965 }
  966 /*--------------------------------------------------------------------------*/
  967 int fits_iter_set_iotype(iteratorCol *col, /* I - iterator column structure */
  968            int iotype)       /* I - InputCol, InputOutputCol, or OutputCol */
  969 /*
  970   set iterator column parameter
  971 */
  972 {
  973     col->iotype = iotype;
  974     return(0);
  975 }
  976 /*--------------------------------------------------------------------------*/
  977 fitsfile * fits_iter_get_file(iteratorCol *col) /* I -iterator col structure */
  978 /*
  979   get iterator column parameter
  980 */
  981 {
  982      return(col->fptr);
  983 }
  984 /*--------------------------------------------------------------------------*/
  985 char * fits_iter_get_colname(iteratorCol *col) /* I -iterator col structure */
  986 /*
  987   get iterator column parameter
  988 */
  989 {
  990     return(col->colname);
  991 }
  992 /*--------------------------------------------------------------------------*/
  993 int fits_iter_get_colnum(iteratorCol *col) /* I - iterator column structure */
  994 /*
  995   get iterator column parameter
  996 */
  997 {
  998     return(col->colnum);
  999 }
 1000 /*--------------------------------------------------------------------------*/
 1001 int fits_iter_get_datatype(iteratorCol *col) /* I - iterator col structure */
 1002 /*
 1003   get iterator column parameter
 1004 */
 1005 {
 1006     return(col->datatype);
 1007 }
 1008 /*--------------------------------------------------------------------------*/
 1009 int fits_iter_get_iotype(iteratorCol *col) /* I - iterator column structure */
 1010 /*
 1011   get iterator column parameter
 1012 */
 1013 {
 1014      return(col->iotype);
 1015 }
 1016 /*--------------------------------------------------------------------------*/
 1017 void * fits_iter_get_array(iteratorCol *col) /* I - iterator col structure */
 1018 /*
 1019   get iterator column parameter
 1020 */
 1021 {
 1022      return(col->array);
 1023 }
 1024 /*--------------------------------------------------------------------------*/
 1025 long fits_iter_get_tlmin(iteratorCol *col) /* I - iterator column structure */
 1026 /*
 1027   get iterator column parameter
 1028 */
 1029 {
 1030      return(col->tlmin);
 1031 }
 1032 /*--------------------------------------------------------------------------*/
 1033 long fits_iter_get_tlmax(iteratorCol *col) /* I - iterator column structure */
 1034 /*
 1035   get iterator column parameter
 1036 */
 1037 {
 1038      return(col->tlmax);
 1039 }
 1040 /*--------------------------------------------------------------------------*/
 1041 long fits_iter_get_repeat(iteratorCol *col) /* I - iterator col structure */
 1042 /*
 1043   get iterator column parameter
 1044 */
 1045 {
 1046      return(col->repeat);
 1047 }
 1048 /*--------------------------------------------------------------------------*/
 1049 char * fits_iter_get_tunit(iteratorCol *col) /* I - iterator col structure */
 1050 /*
 1051   get iterator column parameter
 1052 */
 1053 {
 1054     return(col->tunit);
 1055 }
 1056 /*--------------------------------------------------------------------------*/
 1057 char * fits_iter_get_tdisp(iteratorCol *col) /* I -iterator col structure   */
 1058 /*
 1059   get iterator column parameter
 1060 */
 1061 {
 1062     return(col->tdisp);
 1063 }
 1064 /*--------------------------------------------------------------------------*/
 1065 int ffiter(int n_cols,
 1066            iteratorCol *cols,
 1067            long offset,
 1068            long n_per_loop,
 1069            int (*work_fn)(long total_n,
 1070                           long offset,
 1071                           long first_n,
 1072                           long n_values,
 1073                           int n_cols,
 1074                           iteratorCol *cols,
 1075                           void *userPointer),
 1076            void *userPointer,
 1077            int *status)
 1078 /*
 1079    The iterator function.  This function will pass the specified
 1080    columns from a FITS table or pixels from a FITS image to the 
 1081    user-supplied function.  Depending on the size of the table
 1082    or image, only a subset of the rows or pixels may be passed to the
 1083    function on each call, in which case the function will be called
 1084    multiple times until all the rows or pixels have been processed.
 1085 */
 1086 {
 1087     typedef struct  /* structure to store the column null value */
 1088     {  
 1089         int      nullsize;    /* length of the null value, in bytes */
 1090         union {   /*  default null value for the column */
 1091             char   *stringnull;
 1092             unsigned char   charnull;
 1093             signed char scharnull;
 1094             int    intnull;
 1095             short  shortnull;
 1096             long   longnull;
 1097             unsigned int   uintnull;
 1098             unsigned short ushortnull;
 1099             unsigned long  ulongnull;
 1100             float  floatnull;
 1101             double doublenull;
 1102         LONGLONG longlongnull;
 1103         } null;
 1104     } colNulls;
 1105 
 1106     void *dataptr, *defaultnull;
 1107     colNulls *col;
 1108     int ii, jj, tstatus, naxis, bitpix;
 1109     int typecode, hdutype, jtype, type, anynul=0, nfiles, nbytes;
 1110     long totaln, nleft, frow, felement, n_optimum, i_optimum, ntodo;
 1111     long rept, rowrept, width, tnull, naxes[9] = {1,1,1,1,1,1,1,1,1}, groups;
 1112     double zeros = 0.;
 1113     char message[FLEN_ERRMSG], keyname[FLEN_KEYWORD], nullstr[FLEN_VALUE];
 1114     char **stringptr, *nullptr, *cptr;
 1115 
 1116     if (*status > 0)
 1117         return(*status);
 1118 
 1119     if (n_cols  < 0 || n_cols > 999 )
 1120     {
 1121         ffpmsg("Illegal number of columms (ffiter)");
 1122         return(*status = BAD_COL_NUM);  /* negative number of columns */
 1123     }
 1124 
 1125     /*------------------------------------------------------------*/
 1126     /* Make sure column numbers and datatypes are in legal range  */
 1127     /* and column numbers and datatypes are legal.                */ 
 1128     /* Also fill in other parameters in the column structure.     */
 1129     /*------------------------------------------------------------*/
 1130 
 1131     ffghdt(cols[0].fptr, &hdutype, status);  /* type of first HDU */
 1132 
 1133     for (jj = 0; jj < n_cols; jj++)
 1134     {
 1135         /* check that output datatype code value is legal */
 1136         type = cols[jj].datatype;  
 1137 
 1138         /* Allow variable length arrays for InputCol and InputOutputCol columns,
 1139        but not for OutputCol columns.  Variable length arrays have a
 1140        negative type code value. */
 1141 
 1142         if ((cols[jj].iotype != OutputCol) && (type<0)) {
 1143             type*=-1;
 1144         }
 1145 
 1146         if (type != 0      && type != TBYTE  &&
 1147             type != TSBYTE && type != TLOGICAL && type != TSTRING &&
 1148             type != TSHORT && type != TINT     && type != TLONG && 
 1149             type != TFLOAT && type != TDOUBLE  && type != TCOMPLEX &&
 1150             type != TULONG && type != TUSHORT  && type != TDBLCOMPLEX &&
 1151         type != TLONGLONG )
 1152         {
 1153         if (type < 0) {
 1154           snprintf(message,FLEN_ERRMSG,
 1155               "Variable length array not allowed for output column number %d (ffiter)",
 1156                     jj + 1);
 1157         } else {
 1158             snprintf(message,FLEN_ERRMSG,
 1159                    "Illegal datatype for column number %d: %d  (ffiter)",
 1160                     jj + 1, cols[jj].datatype);
 1161         }
 1162         
 1163             ffpmsg(message);
 1164             return(*status = BAD_DATATYPE);
 1165         }
 1166 
 1167         /* initialize TLMINn, TLMAXn, column name, and display format */
 1168         cols[jj].tlmin = 0;
 1169         cols[jj].tlmax = 0;
 1170         cols[jj].tunit[0] = '\0';
 1171         cols[jj].tdisp[0] = '\0';
 1172 
 1173         ffghdt(cols[jj].fptr, &jtype, status);  /* get HDU type */
 1174 
 1175         if (hdutype == IMAGE_HDU) /* operating on FITS images */
 1176         {
 1177             if (jtype != IMAGE_HDU)
 1178             {
 1179                 snprintf(message,FLEN_ERRMSG,
 1180                 "File %d not positioned to an image extension (ffiter)",
 1181                     jj + 1);
 1182                 return(*status = NOT_IMAGE);
 1183             }
 1184 
 1185             /* since this is an image, set a dummy column number = 0 */
 1186             cols[jj].colnum = 0;
 1187             strcpy(cols[jj].colname, "IMAGE");  /* dummy name for images */
 1188 
 1189             tstatus = 0;
 1190             ffgkys(cols[jj].fptr, "BUNIT", cols[jj].tunit, 0, &tstatus);
 1191         }
 1192         else  /* operating on FITS tables */
 1193         {
 1194             if (jtype == IMAGE_HDU)
 1195             {
 1196                 snprintf(message,FLEN_ERRMSG,
 1197                 "File %d not positioned to a table extension (ffiter)",
 1198                     jj + 1);
 1199                 return(*status = NOT_TABLE);
 1200             }
 1201 
 1202             if (cols[jj].colnum < 1)
 1203             {
 1204                 /* find the column number for the named column */
 1205                 if (ffgcno(cols[jj].fptr, CASEINSEN, cols[jj].colname,
 1206                            &cols[jj].colnum, status) )
 1207                 {
 1208                     snprintf(message,FLEN_ERRMSG,
 1209                       "Column '%s' not found for column number %d  (ffiter)",
 1210                        cols[jj].colname, jj + 1);
 1211                     ffpmsg(message);
 1212                     return(*status);
 1213                 }
 1214             }
 1215 
 1216             /* check that the column number is valid */
 1217             if (cols[jj].colnum < 1 || 
 1218                 cols[jj].colnum > ((cols[jj].fptr)->Fptr)->tfield)
 1219             {
 1220                 snprintf(message,FLEN_ERRMSG,
 1221                   "Column %d has illegal table position number: %d  (ffiter)",
 1222                     jj + 1, cols[jj].colnum);
 1223                 ffpmsg(message);
 1224                 return(*status = BAD_COL_NUM);
 1225             }
 1226 
 1227             /* look for column description keywords and update structure */
 1228             tstatus = 0;
 1229             ffkeyn("TLMIN", cols[jj].colnum, keyname, &tstatus);
 1230             ffgkyj(cols[jj].fptr, keyname, &cols[jj].tlmin, 0, &tstatus);
 1231 
 1232             tstatus = 0;
 1233             ffkeyn("TLMAX", cols[jj].colnum, keyname, &tstatus);
 1234             ffgkyj(cols[jj].fptr, keyname, &cols[jj].tlmax, 0, &tstatus);
 1235 
 1236             tstatus = 0;
 1237             ffkeyn("TTYPE", cols[jj].colnum, keyname, &tstatus);
 1238             ffgkys(cols[jj].fptr, keyname, cols[jj].colname, 0, &tstatus);
 1239             if (tstatus)
 1240                 cols[jj].colname[0] = '\0';
 1241 
 1242             tstatus = 0;
 1243             ffkeyn("TUNIT", cols[jj].colnum, keyname, &tstatus);
 1244             ffgkys(cols[jj].fptr, keyname, cols[jj].tunit, 0, &tstatus);
 1245 
 1246             tstatus = 0;
 1247             ffkeyn("TDISP", cols[jj].colnum, keyname, &tstatus);
 1248             ffgkys(cols[jj].fptr, keyname, cols[jj].tdisp, 0, &tstatus);
 1249         }
 1250     }  /* end of loop over all columns */
 1251 
 1252     /*-----------------------------------------------------------------*/
 1253     /* use the first file to set the total number of values to process */
 1254     /*-----------------------------------------------------------------*/
 1255 
 1256     offset = maxvalue(offset, 0L);  /* make sure offset is legal */
 1257 
 1258     if (hdutype == IMAGE_HDU)   /* get total number of pixels in the image */
 1259     {
 1260       fits_get_img_dim(cols[0].fptr, &naxis, status);
 1261       fits_get_img_size(cols[0].fptr, 9, naxes, status);
 1262 
 1263       tstatus = 0;
 1264       ffgkyj(cols[0].fptr, "GROUPS", &groups, NULL, &tstatus);
 1265       if (!tstatus && groups && (naxis > 1) && (naxes[0] == 0) )
 1266       {
 1267          /* this is a random groups file, with NAXIS1 = 0 */
 1268          /* Use GCOUNT, the number of groups, as the first multiplier  */
 1269          /* to calculate the total number of pixels in all the groups. */
 1270          ffgkyj(cols[0].fptr, "GCOUNT", &totaln, NULL, status);
 1271 
 1272       }  else {
 1273          totaln = naxes[0];
 1274       }
 1275 
 1276       for (ii = 1; ii < naxis; ii++)
 1277           totaln *= naxes[ii];
 1278 
 1279       frow = 1;
 1280       felement = 1 + offset;
 1281     }
 1282     else   /* get total number or rows in the table */
 1283     {
 1284       ffgkyj(cols[0].fptr, "NAXIS2", &totaln, 0, status);
 1285       frow = 1 + offset;
 1286       felement = 1;
 1287     }
 1288 
 1289     /*  adjust total by the input starting offset value */
 1290     totaln -= offset;
 1291     totaln = maxvalue(totaln, 0L);   /* don't allow negative number */
 1292 
 1293     /*------------------------------------------------------------------*/
 1294     /* Determine number of values to pass to work function on each loop */
 1295     /*------------------------------------------------------------------*/
 1296 
 1297     if (n_per_loop == 0)
 1298     {
 1299         /* Determine optimum number of values for each iteration.    */
 1300         /* Look at all the fitsfile pointers to determine the number */
 1301         /* of unique files.                                          */
 1302 
 1303         nfiles = 1;
 1304         ffgrsz(cols[0].fptr, &n_optimum, status);
 1305 
 1306         for (jj = 1; jj < n_cols; jj++)
 1307         {
 1308             for (ii = 0; ii < jj; ii++)
 1309             {
 1310                 if (cols[ii].fptr == cols[jj].fptr)
 1311                    break;
 1312             }
 1313 
 1314             if (ii == jj)  /* this is a new file */
 1315             {
 1316                 nfiles++;
 1317                 ffgrsz(cols[jj].fptr, &i_optimum, status);
 1318                 n_optimum = minvalue(n_optimum, i_optimum);
 1319             }
 1320         }
 1321 
 1322         /* divid n_optimum by the number of files that will be processed */
 1323         n_optimum = n_optimum / nfiles;
 1324         n_optimum = maxvalue(n_optimum, 1);
 1325     }
 1326     else if (n_per_loop < 0)  /* must pass all the values at one time */
 1327     {
 1328         n_optimum = totaln;
 1329     }
 1330     else /* calling routine specified how many values to pass at a time */
 1331     {
 1332         n_optimum = minvalue(n_per_loop, totaln);
 1333     }
 1334 
 1335     /*--------------------------------------*/
 1336     /* allocate work arrays for each column */
 1337     /* and determine the null pixel value   */
 1338     /*--------------------------------------*/
 1339 
 1340     col = calloc(n_cols, sizeof(colNulls) ); /* memory for the null values */
 1341     if (!col)
 1342     {
 1343         ffpmsg("ffiter failed to allocate memory for null values");
 1344         *status = MEMORY_ALLOCATION;  /* memory allocation failed */
 1345         return(*status);
 1346     }
 1347 
 1348     for (jj = 0; jj < n_cols; jj++)
 1349     {
 1350         /* get image or column datatype and vector length */
 1351         if (hdutype == IMAGE_HDU)   /* get total number of pixels in the image */
 1352         {
 1353            fits_get_img_type(cols[jj].fptr, &bitpix, status);
 1354            switch(bitpix) {
 1355              case BYTE_IMG:
 1356                  typecode = TBYTE;
 1357                  break;
 1358              case SHORT_IMG:
 1359                  typecode = TSHORT;
 1360                  break;
 1361              case LONG_IMG:
 1362                  typecode = TLONG;
 1363                  break;
 1364              case FLOAT_IMG:
 1365                  typecode = TFLOAT;
 1366                  break;
 1367              case DOUBLE_IMG:
 1368                  typecode = TDOUBLE;
 1369                  break;
 1370              case LONGLONG_IMG:
 1371                  typecode = TLONGLONG;
 1372                  break;
 1373             }
 1374         }
 1375         else
 1376         {
 1377             if (ffgtcl(cols[jj].fptr, cols[jj].colnum, &typecode, &rept,
 1378                   &width, status) > 0)
 1379                 goto cleanup;
 1380         
 1381         if (typecode < 0) {  /* if any variable length arrays, then the */ 
 1382             n_optimum = 1;   /* must process the table 1 row at a time */
 1383         
 1384               /* Allow variable length arrays for InputCol and InputOutputCol columns,
 1385            but not for OutputCol columns.  Variable length arrays have a
 1386            negative type code value. */
 1387 
 1388               if (cols[jj].iotype == OutputCol) {
 1389             snprintf(message,FLEN_ERRMSG,
 1390                 "Variable length array not allowed for output column number %d (ffiter)",
 1391                     jj + 1);
 1392                 ffpmsg(message);
 1393                 return(*status = BAD_DATATYPE);
 1394               }
 1395        }
 1396         }
 1397 
 1398         /* special case where sizeof(long) = 8: use TINT instead of TLONG */
 1399         if (abs(typecode) == TLONG && sizeof(long) == 8 && sizeof(int) == 4) {
 1400         if(typecode<0) {
 1401             typecode = -TINT;
 1402         } else {
 1403             typecode = TINT;
 1404         }
 1405         }
 1406 
 1407         /* Special case: interprete 'X' column as 'B' */
 1408         if (abs(typecode) == TBIT)
 1409         {
 1410             typecode  = typecode / TBIT * TBYTE;
 1411             rept = (rept + 7) / 8;
 1412         }
 1413 
 1414         if (cols[jj].datatype == 0)    /* output datatype not specified? */
 1415         {
 1416             /* special case if sizeof(long) = 8: use TINT instead of TLONG */
 1417             if (abs(typecode) == TLONG && sizeof(long) == 8 && sizeof(int) == 4)
 1418                 cols[jj].datatype = TINT;
 1419             else
 1420                 cols[jj].datatype = abs(typecode);
 1421         }
 1422 
 1423         /* calc total number of elements to do on each iteration */
 1424         if (hdutype == IMAGE_HDU || cols[jj].datatype == TSTRING)
 1425         {
 1426             ntodo = n_optimum;
 1427             cols[jj].repeat = 1;
 1428             /* handle special case of a 0-width string column */
 1429             if (hdutype == BINARY_TBL && rept == 0)
 1430                cols[jj].repeat = 0;
 1431 
 1432             /* get the BLANK keyword value, if it exists */
 1433             if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG
 1434                 || abs(typecode) == TINT || abs(typecode) == TLONGLONG)
 1435             {
 1436                 tstatus = 0;
 1437                 ffgkyj(cols[jj].fptr, "BLANK", &tnull, 0, &tstatus);
 1438                 if (tstatus)
 1439                 {
 1440                     tnull = 0L;  /* no null values */
 1441                 }
 1442             }
 1443         }
 1444         else
 1445         {
 1446         if (typecode < 0) 
 1447         {
 1448               /* get max size of the variable length vector; dont't trust the value
 1449              given by the TFORM keyword  */
 1450           rept = 1;
 1451           for (ii = 0; ii < totaln; ii++) {
 1452         ffgdes(cols[jj].fptr, cols[jj].colnum, frow + ii, &rowrept, NULL, status);
 1453         
 1454         rept = maxvalue(rept, rowrept);
 1455           }
 1456             }
 1457         
 1458             ntodo = n_optimum * rept;   /* vector columns */
 1459             cols[jj].repeat = rept;
 1460 
 1461             /* get the TNULL keyword value, if it exists */
 1462             if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG
 1463                 || abs(typecode) == TINT || abs(typecode) == TLONGLONG)
 1464             {
 1465                 tstatus = 0;
 1466                 if (hdutype == ASCII_TBL) /* TNULLn value is a string */
 1467                 {
 1468                     ffkeyn("TNULL", cols[jj].colnum, keyname, &tstatus);
 1469                     ffgkys(cols[jj].fptr, keyname, nullstr, 0, &tstatus);
 1470                     if (tstatus)
 1471                     {
 1472                         tnull = 0L; /* keyword doesn't exist; no null values */
 1473                     }
 1474                     else
 1475                     {
 1476                         cptr = nullstr;
 1477                         while (*cptr == ' ')  /* skip over leading blanks */
 1478                            cptr++;
 1479 
 1480                         if (*cptr == '\0')  /* TNULLn is all blanks? */
 1481                             tnull = LONG_MIN;
 1482                         else
 1483                         {                                                
 1484                             /* attempt to read TNULLn string as an integer */
 1485                             ffc2ii(nullstr, &tnull, &tstatus);
 1486 
 1487                             if (tstatus)
 1488                                 tnull = LONG_MIN;  /* choose smallest value */
 1489                         }                          /* to represent nulls */
 1490                     }
 1491                 }
 1492                 else  /* Binary table; TNULLn value is an integer */
 1493                 {
 1494                     ffkeyn("TNULL", cols[jj].colnum, keyname, &tstatus);
 1495                     ffgkyj(cols[jj].fptr, keyname, &tnull, 0, &tstatus);
 1496                     if (tstatus)
 1497                     {
 1498                         tnull = 0L; /* keyword doesn't exist; no null values */
 1499                     }
 1500                     else if (tnull == 0)
 1501                     {
 1502                         /* worst possible case: a value of 0 is used to   */
 1503                         /* represent nulls in the FITS file.  We have to  */
 1504                         /* use a non-zero null value here (zero is used to */
 1505                         /* mean there are no null values in the array) so we */
 1506                         /* will use the smallest possible integer instead. */
 1507 
 1508                         tnull = LONG_MIN;  /* choose smallest possible value */
 1509                     }
 1510                 }
 1511             }
 1512         }
 1513 
 1514         /* Note that the data array starts with 2nd element;  */
 1515         /* 1st element of the array gives the null data value */
 1516 
 1517         switch (cols[jj].datatype)
 1518         {
 1519          case TBYTE:
 1520           cols[jj].array = calloc(ntodo + 1, sizeof(char));
 1521           col[jj].nullsize  = sizeof(char);  /* number of bytes per value */
 1522 
 1523           if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG
 1524               || abs(typecode) == TINT || abs(typecode) == TLONGLONG)
 1525           {
 1526               tnull = minvalue(tnull, 255);
 1527               tnull = maxvalue(tnull, 0);
 1528               col[jj].null.charnull = (unsigned char) tnull;
 1529           }
 1530           else
 1531           {
 1532               col[jj].null.charnull = (unsigned char) 255; /* use 255 as null */
 1533           }
 1534           break;
 1535 
 1536          case TSBYTE:
 1537           cols[jj].array = calloc(ntodo + 1, sizeof(char));
 1538           col[jj].nullsize  = sizeof(char);  /* number of bytes per value */
 1539 
 1540           if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG
 1541               || abs(typecode) == TINT || abs(typecode) == TLONGLONG)
 1542           {
 1543               tnull = minvalue(tnull, 127);
 1544               tnull = maxvalue(tnull, -128);
 1545               col[jj].null.scharnull = (signed char) tnull;
 1546           }
 1547           else
 1548           {
 1549               col[jj].null.scharnull = (signed char) -128; /* use -128  null */
 1550           }
 1551           break;
 1552 
 1553          case TSHORT:
 1554           cols[jj].array = calloc(ntodo + 1, sizeof(short));
 1555           col[jj].nullsize  = sizeof(short);  /* number of bytes per value */
 1556 
 1557           if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG
 1558               || abs(typecode) == TINT || abs(typecode) == TLONGLONG)
 1559           {
 1560               tnull = minvalue(tnull, SHRT_MAX);
 1561               tnull = maxvalue(tnull, SHRT_MIN);
 1562               col[jj].null.shortnull = (short) tnull;
 1563           }
 1564           else
 1565           {
 1566               col[jj].null.shortnull = SHRT_MIN;  /* use minimum as null */
 1567           }
 1568           break;
 1569 
 1570          case TUSHORT:
 1571           cols[jj].array = calloc(ntodo + 1, sizeof(unsigned short));
 1572           col[jj].nullsize  = sizeof(unsigned short);  /* bytes per value */
 1573 
 1574           if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG
 1575                || abs(typecode) == TINT || abs(typecode) == TLONGLONG)
 1576           {
 1577               tnull = minvalue(tnull, (long) USHRT_MAX);
 1578               tnull = maxvalue(tnull, 0);  /* don't allow negative value */
 1579               col[jj].null.ushortnull = (unsigned short) tnull;
 1580           }
 1581           else
 1582           {
 1583               col[jj].null.ushortnull = USHRT_MAX;   /* use maximum null */
 1584           }
 1585           break;
 1586 
 1587          case TINT:
 1588           cols[jj].array = calloc(sizeof(int), ntodo + 1);
 1589           col[jj].nullsize  = sizeof(int);  /* number of bytes per value */
 1590 
 1591           if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG
 1592                || abs(typecode) == TINT || abs(typecode) == TLONGLONG)
 1593           {
 1594               tnull = minvalue(tnull, INT_MAX);
 1595               tnull = maxvalue(tnull, INT_MIN);
 1596               col[jj].null.intnull = (int) tnull;
 1597           }
 1598           else
 1599           {
 1600               col[jj].null.intnull = INT_MIN;  /* use minimum as null */
 1601           }
 1602           break;
 1603 
 1604          case TUINT:
 1605           cols[jj].array = calloc(ntodo + 1, sizeof(unsigned int));
 1606           col[jj].nullsize  = sizeof(unsigned int);  /* bytes per value */
 1607 
 1608           if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG
 1609                || abs(typecode) == TINT || abs(typecode) == TLONGLONG)
 1610           {
 1611               tnull = minvalue(tnull, INT32_MAX);
 1612               tnull = maxvalue(tnull, 0);
 1613               col[jj].null.uintnull = (unsigned int) tnull;
 1614           }
 1615           else
 1616           {
 1617               col[jj].null.uintnull = UINT_MAX;  /* use maximum as null */
 1618           }
 1619           break;
 1620 
 1621          case TLONG:
 1622           cols[jj].array = calloc(ntodo + 1, sizeof(long));
 1623           col[jj].nullsize  = sizeof(long);  /* number of bytes per value */
 1624 
 1625           if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG
 1626                || abs(typecode) == TINT || abs(typecode) == TLONGLONG)
 1627           {
 1628               col[jj].null.longnull = tnull;
 1629           }
 1630           else
 1631           {
 1632               col[jj].null.longnull = LONG_MIN;   /* use minimum as null */
 1633           }
 1634           break;
 1635 
 1636          case TULONG:
 1637           cols[jj].array = calloc(ntodo + 1, sizeof(unsigned long));
 1638           col[jj].nullsize  = sizeof(unsigned long);  /* bytes per value */
 1639 
 1640           if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG
 1641                || abs(typecode) == TINT || abs(typecode) == TLONGLONG)
 1642           {
 1643               if (tnull < 0)  /* can't use a negative null value */
 1644                   col[jj].null.ulongnull = LONG_MAX;
 1645               else
 1646                   col[jj].null.ulongnull = (unsigned long) tnull;
 1647           }
 1648           else
 1649           {
 1650               col[jj].null.ulongnull = LONG_MAX;   /* use maximum as null */
 1651           }
 1652           break;
 1653 
 1654          case TFLOAT:
 1655           cols[jj].array = calloc(ntodo + 1, sizeof(float));
 1656           col[jj].nullsize  = sizeof(float);  /* number of bytes per value */
 1657 
 1658           if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG
 1659                || abs(typecode) == TINT || abs(typecode) == TLONGLONG)
 1660           {
 1661               col[jj].null.floatnull = (float) tnull;
 1662           }
 1663           else
 1664           {
 1665               col[jj].null.floatnull = FLOATNULLVALUE;  /* special value */
 1666           }
 1667           break;
 1668 
 1669          case TCOMPLEX:
 1670           cols[jj].array = calloc((ntodo * 2) + 1, sizeof(float));
 1671           col[jj].nullsize  = sizeof(float);  /* number of bytes per value */
 1672           col[jj].null.floatnull = FLOATNULLVALUE;  /* special value */
 1673           break;
 1674 
 1675          case TDOUBLE:
 1676           cols[jj].array = calloc(ntodo + 1, sizeof(double));
 1677           col[jj].nullsize  = sizeof(double);  /* number of bytes per value */
 1678 
 1679           if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG
 1680                || abs(typecode) == TINT || abs(typecode) == TLONGLONG)
 1681           {
 1682               col[jj].null.doublenull = (double) tnull;
 1683           }
 1684           else
 1685           {
 1686               col[jj].null.doublenull = DOUBLENULLVALUE;  /* special value */
 1687           }
 1688           break;
 1689 
 1690          case TDBLCOMPLEX:
 1691           cols[jj].array = calloc((ntodo * 2) + 1, sizeof(double));
 1692           col[jj].nullsize  = sizeof(double);  /* number of bytes per value */
 1693           col[jj].null.doublenull = DOUBLENULLVALUE;  /* special value */
 1694           break;
 1695 
 1696          case TSTRING:
 1697           /* allocate array of pointers to all the strings  */
 1698       if( hdutype==ASCII_TBL ) rept = width;
 1699           stringptr = calloc((ntodo + 1) , sizeof(stringptr));
 1700           cols[jj].array = stringptr;
 1701           col[jj].nullsize  = rept + 1;  /* number of bytes per value */
 1702 
 1703           if (stringptr)
 1704           {
 1705             /* allocate string to store the null string value */
 1706             col[jj].null.stringnull = calloc(rept + 1, sizeof(char) );
 1707             if (rept > 0)
 1708                col[jj].null.stringnull[1] = 1; /* to make sure string != 0 */
 1709 
 1710             /* allocate big block for the array of table column strings */
 1711             stringptr[0] = calloc((ntodo + 1) * (rept + 1), sizeof(char) );
 1712 
 1713             if (stringptr[0])
 1714             {
 1715               for (ii = 1; ii <= ntodo; ii++)
 1716               {   /* pointer to each string */
 1717                 stringptr[ii] = stringptr[ii - 1] + (rept + 1);
 1718               }
 1719 
 1720               /* get the TNULL keyword value, if it exists */
 1721               tstatus = 0;
 1722               ffkeyn("TNULL", cols[jj].colnum, keyname, &tstatus);
 1723               ffgkys(cols[jj].fptr, keyname, nullstr, 0, &tstatus);
 1724               if (!tstatus)
 1725                   strncat(col[jj].null.stringnull, nullstr, rept);
 1726             }
 1727             else
 1728             {
 1729               ffpmsg("ffiter failed to allocate memory arrays");
 1730               *status = MEMORY_ALLOCATION;  /* memory allocation failed */
 1731               goto cleanup;
 1732             }
 1733           }
 1734           break;
 1735 
 1736          case TLOGICAL:
 1737 
 1738           cols[jj].array = calloc(ntodo + 1, sizeof(char));
 1739           col[jj].nullsize  = sizeof(char);  /* number of bytes per value */
 1740 
 1741           /* use value = 2 to flag null values in logical columns */
 1742           col[jj].null.charnull = 2;
 1743           break;
 1744 
 1745          case TLONGLONG:
 1746           cols[jj].array = calloc(ntodo + 1, sizeof(LONGLONG));
 1747           col[jj].nullsize  = sizeof(LONGLONG);  /* number of bytes per value */
 1748 
 1749           if (abs(typecode) == TBYTE || abs(typecode) == TSHORT || abs(typecode) == TLONG ||
 1750           abs(typecode) == TLONGLONG || abs(typecode) == TINT)
 1751           {
 1752               col[jj].null.longlongnull = tnull;
 1753           }
 1754           else
 1755           {
 1756               col[jj].null.longlongnull = LONGLONG_MIN;   /* use minimum as null */
 1757           }
 1758           break;
 1759 
 1760          default:
 1761           snprintf(message,FLEN_ERRMSG,
 1762                   "Column %d datatype currently not supported: %d:  (ffiter)",
 1763                    jj + 1, cols[jj].datatype);
 1764           ffpmsg(message);
 1765           *status = BAD_DATATYPE;
 1766           goto cleanup;
 1767 
 1768         }   /* end of switch block */
 1769 
 1770         /* check that all the arrays were allocated successfully */
 1771         if (!cols[jj].array)
 1772         {
 1773             ffpmsg("ffiter failed to allocate memory arrays");
 1774             *status = MEMORY_ALLOCATION;  /* memory allocation failed */
 1775             goto cleanup;
 1776         }
 1777     }
 1778 
 1779     /*--------------------------------------------------*/
 1780     /* main loop while there are values left to process */
 1781     /*--------------------------------------------------*/
 1782 
 1783     nleft = totaln;
 1784 
 1785     while (nleft)
 1786     {
 1787       ntodo = minvalue(nleft, n_optimum); /* no. of values for this loop */
 1788 
 1789       /*  read input columns from FITS file(s)  */
 1790       for (jj = 0; jj < n_cols; jj++)
 1791       {
 1792         if (cols[jj].iotype != OutputCol)
 1793         {
 1794           if (cols[jj].datatype == TSTRING)
 1795           {
 1796             stringptr = cols[jj].array;
 1797             dataptr = stringptr + 1;
 1798             defaultnull = col[jj].null.stringnull; /* ptr to the null value */
 1799           }
 1800           else
 1801           {
 1802             dataptr = (char *) cols[jj].array + col[jj].nullsize;
 1803             defaultnull = &col[jj].null.charnull; /* ptr to the null value */
 1804           }
 1805 
 1806           if (hdutype == IMAGE_HDU)   
 1807           {
 1808               if (ffgpv(cols[jj].fptr, cols[jj].datatype,
 1809                     felement, cols[jj].repeat * ntodo, defaultnull,
 1810                     dataptr,  &anynul, status) > 0)
 1811               {
 1812                  break;
 1813               }
 1814           }
 1815           else
 1816           {
 1817           if (ffgtcl(cols[jj].fptr, cols[jj].colnum, &typecode, &rept,&width, status) > 0)
 1818               goto cleanup;
 1819           
 1820           if (typecode<0)
 1821           {
 1822             /* get size of the variable length vector */
 1823         ffgdes(cols[jj].fptr, cols[jj].colnum, frow,&cols[jj].repeat, NULL,status);
 1824           }
 1825         
 1826               if (ffgcv(cols[jj].fptr, cols[jj].datatype, cols[jj].colnum,
 1827                     frow, felement, cols[jj].repeat * ntodo, defaultnull,
 1828                     dataptr,  &anynul, status) > 0)
 1829               {
 1830                  break;
 1831               }
 1832           }
 1833 
 1834           /* copy the appropriate null value into first array element */
 1835 
 1836           if (anynul)   /* are there any nulls in the data? */
 1837           {   
 1838             if (cols[jj].datatype == TSTRING)
 1839             {
 1840               stringptr = cols[jj].array;
 1841               memcpy(*stringptr, col[jj].null.stringnull, col[jj].nullsize);
 1842             }
 1843             else
 1844             {
 1845               memcpy(cols[jj].array, defaultnull, col[jj].nullsize);
 1846             }
 1847           }
 1848           else /* no null values so copy zero into first element */
 1849           {
 1850             if (cols[jj].datatype == TSTRING)
 1851             {
 1852               stringptr = cols[jj].array;
 1853               memset(*stringptr, 0, col[jj].nullsize);  
 1854             }
 1855             else
 1856             {
 1857               memset(cols[jj].array, 0, col[jj].nullsize);  
 1858             }
 1859           }
 1860         }
 1861       }
 1862 
 1863       if (*status > 0) 
 1864          break;   /* looks like an error occurred; quit immediately */
 1865 
 1866       /* call work function */
 1867 
 1868       if (hdutype == IMAGE_HDU) 
 1869           *status = work_fn(totaln, offset, felement, ntodo, n_cols, cols,
 1870                     userPointer);
 1871       else
 1872           *status = work_fn(totaln, offset, frow, ntodo, n_cols, cols,
 1873                     userPointer);
 1874 
 1875       if (*status > 0 || *status < -1 ) 
 1876          break;   /* looks like an error occurred; quit immediately */
 1877 
 1878       /*  write output columns  before quiting if status = -1 */
 1879       tstatus = 0;
 1880       for (jj = 0; jj < n_cols; jj++)
 1881       {
 1882         if (cols[jj].iotype != InputCol)
 1883         {
 1884           if (cols[jj].datatype == TSTRING)
 1885           {
 1886             stringptr = cols[jj].array;
 1887             dataptr = stringptr + 1;
 1888             nullptr = *stringptr;
 1889             nbytes = 2;
 1890           }
 1891           else
 1892           {
 1893             dataptr = (char *) cols[jj].array + col[jj].nullsize;
 1894             nullptr = (char *) cols[jj].array;
 1895             nbytes = col[jj].nullsize;
 1896           }
 1897 
 1898           if (memcmp(nullptr, &zeros, nbytes) ) 
 1899           {
 1900             /* null value flag not zero; must check for and write nulls */
 1901             if (hdutype == IMAGE_HDU)   
 1902             {
 1903                 if (ffppn(cols[jj].fptr, cols[jj].datatype, 
 1904                       felement, cols[jj].repeat * ntodo, dataptr,
 1905                       nullptr, &tstatus) > 0)
 1906                 break;
 1907             }
 1908             else
 1909             {
 1910             if (ffgtcl(cols[jj].fptr, cols[jj].colnum, &typecode, &rept,&width, status) > 0)
 1911             goto cleanup;
 1912             
 1913         if (typecode<0)  /* variable length array colum */
 1914         {
 1915            ffgdes(cols[jj].fptr, cols[jj].colnum, frow,&cols[jj].repeat, NULL,status);
 1916         }
 1917 
 1918                 if (ffpcn(cols[jj].fptr, cols[jj].datatype, cols[jj].colnum, frow,
 1919                       felement, cols[jj].repeat * ntodo, dataptr,
 1920                       nullptr, &tstatus) > 0)
 1921                 break;
 1922             }
 1923           }
 1924           else
 1925           { 
 1926             /* no null values; just write the array */
 1927             if (hdutype == IMAGE_HDU)   
 1928             {
 1929                 if (ffppr(cols[jj].fptr, cols[jj].datatype,
 1930                       felement, cols[jj].repeat * ntodo, dataptr,
 1931                       &tstatus) > 0)
 1932                 break;
 1933             }
 1934             else
 1935             {
 1936             if (ffgtcl(cols[jj].fptr, cols[jj].colnum, &typecode, &rept,&width, status) > 0)
 1937             goto cleanup;
 1938             
 1939         if (typecode<0)  /* variable length array column */
 1940         {
 1941            ffgdes(cols[jj].fptr, cols[jj].colnum, frow,&cols[jj].repeat, NULL,status);
 1942         }
 1943 
 1944                  if (ffpcl(cols[jj].fptr, cols[jj].datatype, cols[jj].colnum, frow,
 1945                       felement, cols[jj].repeat * ntodo, dataptr,
 1946                       &tstatus) > 0)
 1947                 break;
 1948             }
 1949           }
 1950         }
 1951       }
 1952 
 1953       if (*status == 0)
 1954          *status = tstatus;   /* propagate any error status from the writes */
 1955 
 1956       if (*status) 
 1957          break;   /* exit on any error */
 1958 
 1959       nleft -= ntodo;
 1960 
 1961       if (hdutype == IMAGE_HDU)
 1962           felement += ntodo;
 1963       else
 1964           frow  += ntodo;
 1965     }
 1966 
 1967 cleanup:
 1968 
 1969     /*----------------------------------*/
 1970     /* free work arrays for the columns */
 1971     /*----------------------------------*/
 1972 
 1973     for (jj = 0; jj < n_cols; jj++)
 1974     {
 1975         if (cols[jj].datatype == TSTRING)
 1976         {
 1977             if (cols[jj].array)
 1978             {
 1979                 stringptr = cols[jj].array;
 1980                 free(*stringptr);     /* free the block of strings */
 1981                 free(col[jj].null.stringnull); /* free the null string */
 1982             }
 1983         }
 1984         if (cols[jj].array)
 1985             free(cols[jj].array); /* memory for the array of values from the col */
 1986     }
 1987     free(col);   /* the structure containing the null values */
 1988     return(*status);
 1989 }
 1990