~ubuntu-branches/debian/stretch/cfitsio/stretch

« back to all changes in this revision

Viewing changes to getcols.c

  • Committer: Bazaar Package Importer
  • Author(s): Gopal Narayanan
  • Date: 2002-02-26 11:27:29 UTC
  • Revision ID: james.westby@ubuntu.com-20020226112729-3q2o993rhh81ipp4
Tags: upstream-2.401
ImportĀ upstreamĀ versionĀ 2.401

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  This file, getcols.c, contains routines that read data elements from   */
 
2
/*  a FITS image or table, with a character string datatype.               */
 
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 <stdlib.h>
 
9
#include <string.h>
 
10
/* stddef.h is apparently needed to define size_t */
 
11
#include <stddef.h>
 
12
#include <ctype.h>
 
13
#include "fitsio2.h"
 
14
/*--------------------------------------------------------------------------*/
 
15
int ffgcvs( fitsfile *fptr,   /* I - FITS file pointer                       */
 
16
            int  colnum,      /* I - number of column to read (1 = 1st col)  */
 
17
            long  firstrow,   /* I - first row to read (1 = 1st row)         */
 
18
            long  firstelem,  /* I - first vector element to read (1 = 1st)  */
 
19
            long  nelem,      /* I - number of strings to read               */
 
20
            char *nulval,     /* I - string for null pixels                  */
 
21
            char **array,     /* O - array of values that are read           */
 
22
            int  *anynul,     /* O - set to 1 if any values are null; else 0 */
 
23
            int  *status)     /* IO - error status                           */
 
24
/*
 
25
  Read an array of string values from a column in the current FITS HDU.
 
26
  Any undefined pixels will be set equal to the value of 'nulval' unless
 
27
  nulval = null in which case no checks for undefined pixels will be made.
 
28
*/
 
29
{
 
30
    char cdummy[2];
 
31
 
 
32
    ffgcls(fptr, colnum, firstrow, firstelem, nelem, 1, nulval,
 
33
           array, cdummy, anynul, status);
 
34
    return(*status);
 
35
}
 
36
/*--------------------------------------------------------------------------*/
 
37
int ffgcfs( fitsfile *fptr,   /* I - FITS file pointer                       */
 
38
            int  colnum,      /* I - number of column to read (1 = 1st col) */
 
39
            long  firstrow,   /* I - first row to read (1 = 1st row)        */
 
40
            long  firstelem,  /* I - first vector element to read (1 = 1st) */
 
41
            long  nelem,      /* I - number of strings to read              */
 
42
            char **array,     /* O - array of values that are read           */
 
43
            char *nularray,   /* O - array of flags = 1 if nultyp = 2        */
 
44
            int  *anynul,     /* O - set to 1 if any values are null; else 0 */
 
45
            int  *status)     /* IO - error status                           */
 
46
/*
 
47
  Read an array of string values from a column in the current FITS HDU.
 
48
  Nularray will be set = 1 if the corresponding array pixel is undefined, 
 
49
  otherwise nularray will = 0.
 
50
*/
 
51
{
 
52
    char dummy[2];
 
53
 
 
54
    ffgcls(fptr, colnum, firstrow, firstelem, nelem, 2, dummy,
 
55
           array, nularray, anynul, status);
 
56
    return(*status);
 
57
}
 
58
/*--------------------------------------------------------------------------*/
 
59
int ffgcls( fitsfile *fptr,   /* I - FITS file pointer                       */
 
60
            int  colnum,      /* I - number of column to read (1 = 1st col) */
 
61
            long  firstrow,   /* I - first row to read (1 = 1st row)        */
 
62
            long  firstelem,  /* I - first vector element to read (1 = 1st) */
 
63
            long  nelem,      /* I - number of strings to read              */
 
64
            int   nultyp,     /* I - null value handling code:               */
 
65
                              /*     1: set undefined pixels = nulval        */
 
66
                              /*     2: set nularray=1 for undefined pixels  */
 
67
            char  *nulval,    /* I - value for null pixels if nultyp = 1     */
 
68
            char **array,     /* O - array of values that are read           */
 
69
            char *nularray,   /* O - array of flags = 1 if nultyp = 2        */
 
70
            int  *anynul,     /* O - set to 1 if any values are null; else 0 */
 
71
            int  *status)     /* IO - error status                           */
 
72
/*
 
73
  Read an array of string values from a column in the current FITS HDU.
 
74
  Returns a formated string value, regardless of the datatype of the column
 
75
*/
 
76
{
 
77
    int tcode, hdutype, tstatus, scaled, intcol, dwidth;
 
78
    long ii, jj;
 
79
    tcolumn *colptr;
 
80
    char message[FLEN_ERRMSG], *carray, keyname[FLEN_KEYWORD];
 
81
    char cform[20], dispfmt[20], tmpstr[80];
 
82
    float *earray;
 
83
    double *darray, tscale = 1.0;
 
84
 
 
85
    if (*status > 0 || nelem == 0)  /* inherit input status value if > 0 */
 
86
        return(*status);
 
87
 
 
88
    /* reset position to the correct HDU if necessary */
 
89
    if (fptr->HDUposition != (fptr->Fptr)->curhdu)
 
90
        ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
 
91
 
 
92
    /* rescan header if data structure is undefined */
 
93
    else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
 
94
        if ( ffrdef(fptr, status) > 0)               
 
95
            return(*status);
 
96
 
 
97
    if (colnum < 1 || colnum > (fptr->Fptr)->tfield)
 
98
    {
 
99
        sprintf(message, "Specified column number is out of range: %d",
 
100
                colnum);
 
101
        ffpmsg(message);
 
102
        return(*status = BAD_COL_NUM);
 
103
    }
 
104
 
 
105
    colptr  = (fptr->Fptr)->tableptr;   /* point to first column */
 
106
    colptr += (colnum - 1);     /* offset to correct column structure */
 
107
    tcode = abs(colptr->tdatatype);
 
108
 
 
109
    if (tcode == TSTRING)
 
110
    {
 
111
      /* simply call the string column reading routine */
 
112
      ffgcls2(fptr, colnum, firstrow, firstelem, nelem, nultyp, nulval,
 
113
           array, nularray, anynul, status);
 
114
    }
 
115
    else if (tcode == TLOGICAL)
 
116
    {
 
117
      /* allocate memory for the array of logical values */
 
118
      carray = (char *) malloc(nelem);
 
119
 
 
120
      /*  call the logical column reading routine */
 
121
      ffgcll(fptr, colnum, firstrow, firstelem, nelem, nultyp, *nulval,
 
122
           carray, nularray, anynul, status); 
 
123
 
 
124
      if (*status <= 0)
 
125
      {
 
126
         /* convert logical values to "T", "F", or "N" (Null) */
 
127
         for (ii = 0; ii < nelem; ii++)
 
128
         {
 
129
           if (carray[ii] == 1)
 
130
              strcpy(array[ii], "T");
 
131
           else if (carray[ii] == 0)
 
132
              strcpy(array[ii], "F");
 
133
           else  /* undefined values = 2 */
 
134
              strcpy(array[ii],"N");
 
135
         }
 
136
      }
 
137
 
 
138
      free(carray);  /* free the memory */
 
139
    }
 
140
    else if (tcode == TCOMPLEX)
 
141
    {
 
142
      /* allocate memory for the array of double values */
 
143
      earray = (float *) calloc(nelem * 2, sizeof(float) );
 
144
      
 
145
      ffgcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2,
 
146
        1, 1, FLOATNULLVALUE, earray, nularray, anynul, status);
 
147
 
 
148
      if (*status <= 0)
 
149
      {
 
150
 
 
151
         /* determine the format for the output strings */
 
152
 
 
153
         ffgcdw(fptr, colnum, &dwidth, status);
 
154
         dwidth = (dwidth - 3) / 2;
 
155
 
 
156
         /* use the TDISPn keyword if it exists */
 
157
         ffkeyn("TDISP", colnum, keyname, status);
 
158
         tstatus = 0;
 
159
         cform[0] = '\0';
 
160
 
 
161
         if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0)
 
162
         {
 
163
             /* convert the Fortran style format to a C style format */
 
164
             ffcdsp(dispfmt, cform);
 
165
         }
 
166
 
 
167
         if (!cform[0])
 
168
             strcpy(cform, "%14.6E");
 
169
 
 
170
         /* write the formated string for each value:  "(real,imag)" */
 
171
         jj = 0;
 
172
         for (ii = 0; ii < nelem; ii++)
 
173
         {
 
174
           strcpy(array[ii], "(");
 
175
 
 
176
           /* test for null value */
 
177
           if (earray[jj] == FLOATNULLVALUE)
 
178
           {
 
179
             strcpy(tmpstr, "NULL");
 
180
             if (nultyp == 2)
 
181
                nularray[ii] = 1;
 
182
           }
 
183
           else
 
184
             sprintf(tmpstr, cform, earray[jj]);
 
185
 
 
186
           strncat(array[ii], tmpstr, dwidth);
 
187
           strcat(array[ii], ",");
 
188
           jj++;
 
189
 
 
190
           /* test for null value */
 
191
           if (earray[jj] == FLOATNULLVALUE)
 
192
           {
 
193
             strcpy(tmpstr, "NULL");
 
194
             if (nultyp == 2)
 
195
                nularray[ii] = 1;
 
196
           }
 
197
           else
 
198
             sprintf(tmpstr, cform, earray[jj]);
 
199
 
 
200
           strncat(array[ii], tmpstr, dwidth);
 
201
           strcat(array[ii], ")");
 
202
           jj++;
 
203
         }
 
204
      }
 
205
 
 
206
      free(earray);  /* free the memory */
 
207
    }
 
208
    else if (tcode == TDBLCOMPLEX)
 
209
    {
 
210
      /* allocate memory for the array of double values */
 
211
      darray = (double *) calloc(nelem * 2, sizeof(double) );
 
212
      
 
213
      ffgcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2,
 
214
        1, 1, DOUBLENULLVALUE, darray, nularray, anynul, status);
 
215
 
 
216
      if (*status <= 0)
 
217
      {
 
218
         /* determine the format for the output strings */
 
219
 
 
220
         ffgcdw(fptr, colnum, &dwidth, status);
 
221
         dwidth = (dwidth - 3) / 2;
 
222
 
 
223
         /* use the TDISPn keyword if it exists */
 
224
         ffkeyn("TDISP", colnum, keyname, status);
 
225
         tstatus = 0;
 
226
         cform[0] = '\0';
 
227
 
 
228
         if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0)
 
229
         {
 
230
             /* convert the Fortran style format to a C style format */
 
231
             ffcdsp(dispfmt, cform);
 
232
         }
 
233
 
 
234
         if (!cform[0])
 
235
            strcpy(cform, "%23.15E");
 
236
 
 
237
         /* write the formated string for each value:  "(real,imag)" */
 
238
         jj = 0;
 
239
         for (ii = 0; ii < nelem; ii++)
 
240
         {
 
241
           strcpy(array[ii], "(");
 
242
 
 
243
           /* test for null value */
 
244
           if (darray[jj] == DOUBLENULLVALUE)
 
245
           {
 
246
             strcpy(tmpstr, "NULL");
 
247
             if (nultyp == 2)
 
248
                nularray[ii] = 1;
 
249
           }
 
250
           else
 
251
             sprintf(tmpstr, cform, darray[jj]);
 
252
 
 
253
           strncat(array[ii], tmpstr, dwidth);
 
254
           strcat(array[ii], ",");
 
255
           jj++;
 
256
 
 
257
           /* test for null value */
 
258
           if (darray[jj] == DOUBLENULLVALUE)
 
259
           {
 
260
             strcpy(tmpstr, "NULL");
 
261
             if (nultyp == 2)
 
262
                nularray[ii] = 1;
 
263
           }
 
264
           else
 
265
             sprintf(tmpstr, cform, darray[jj]);
 
266
 
 
267
           strncat(array[ii], tmpstr, dwidth);
 
268
           strcat(array[ii], ")");
 
269
           jj++;
 
270
         }
 
271
      }
 
272
 
 
273
      free(darray);  /* free the memory */
 
274
    }
 
275
    else
 
276
    {
 
277
      /* allocate memory for the array of double values */
 
278
      darray = (double *) calloc(nelem, sizeof(double) );
 
279
      
 
280
      /* read all other numeric type columns as doubles */
 
281
      if (ffgcld(fptr, colnum, firstrow, firstelem, nelem, 1, nultyp, 
 
282
           DOUBLENULLVALUE, darray, nularray, anynul, status) > 0)
 
283
      {
 
284
         free(darray);
 
285
         return(*status);
 
286
      }
 
287
 
 
288
      /* determine the format for the output strings */
 
289
 
 
290
      ffgcdw(fptr, colnum, &dwidth, status);
 
291
 
 
292
      /* check if  column is scaled */
 
293
      ffkeyn("TSCAL", colnum, keyname, status);
 
294
      tstatus = 0;
 
295
      scaled = 0;
 
296
      if (ffgkyd(fptr, keyname, &tscale, NULL, &tstatus) == 0)
 
297
      {
 
298
            if (tscale != 1.0)
 
299
                scaled = 1;    /* yes, this is a scaled column */
 
300
      }
 
301
 
 
302
      intcol = 0;
 
303
      if (tcode <= TLONG && !scaled)
 
304
             intcol = 1;   /* this is an unscaled integer column */
 
305
 
 
306
      /* use the TDISPn keyword if it exists */
 
307
      ffkeyn("TDISP", colnum, keyname, status);
 
308
      tstatus = 0;
 
309
      cform[0] = '\0';
 
310
 
 
311
      if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0)
 
312
      {
 
313
           /* convert the Fortran style TDISPn to a C style format */
 
314
           ffcdsp(dispfmt, cform);
 
315
      }
 
316
 
 
317
      if (!cform[0])
 
318
      {
 
319
            /* no TDISPn keyword; use TFORMn instead */
 
320
 
 
321
            ffkeyn("TFORM", colnum, keyname, status);
 
322
            ffgkys(fptr, keyname, dispfmt, NULL, status);
 
323
 
 
324
            if (scaled && tcode <= TSHORT)
 
325
            {
 
326
                  /* scaled short integer column == float */
 
327
                  strcpy(cform, "%14.6G");
 
328
            }
 
329
            else if (scaled && tcode == TLONG)
 
330
            {
 
331
                  /* scaled long integer column == double */
 
332
                  strcpy(cform, "%23.15G");
 
333
            }
 
334
            else
 
335
            {
 
336
               ffghdt(fptr, &hdutype, status);
 
337
               if (hdutype == ASCII_TBL)
 
338
               {
 
339
                  /* convert the Fortran style TFORMn to a C style format */
 
340
                  ffcdsp(dispfmt, cform);
 
341
               }
 
342
               else
 
343
               {
 
344
                 /* this is a binary table, need to convert the format */
 
345
                  if (tcode <= TBYTE)          /* 'X' and 'B' */
 
346
                     strcpy(cform, "%4d");
 
347
                  else if (tcode == TSHORT)    /* 'I' */
 
348
                     strcpy(cform, "%6d");
 
349
                  else if (tcode == TLONG)     /* 'J' */
 
350
                     strcpy(cform, "%11d");
 
351
                  else if (tcode == TFLOAT)    /* 'E' */
 
352
                     strcpy(cform, "%14.6E");
 
353
                  else if (tcode == TDOUBLE)   /* 'D' */
 
354
                     strcpy(cform, "%23.15E");
 
355
               }
 
356
            }
 
357
      } 
 
358
 
 
359
      /* write the formated string for each value */
 
360
      for (ii = 0; ii < nelem; ii++)
 
361
      {
 
362
           /* test for null value */
 
363
           if ( (nultyp == 1 && darray[ii] == DOUBLENULLVALUE) ||
 
364
                (nultyp == 2 && nularray[ii]) )
 
365
           {
 
366
              *array[ii] = '\0';
 
367
              strncat(array[ii], "NULL", dwidth);
 
368
           }
 
369
           else
 
370
           {
 
371
              if (intcol)    
 
372
                sprintf(tmpstr, cform, (int) darray[ii]);
 
373
              else
 
374
                sprintf(tmpstr, cform, darray[ii]);
 
375
 
 
376
              *array[ii] = '\0';
 
377
              strncat(array[ii], tmpstr, dwidth);
 
378
           }
 
379
      }
 
380
 
 
381
      free(darray);  /* free the memory */
 
382
    }
 
383
    return(*status);
 
384
}
 
385
/*--------------------------------------------------------------------------*/
 
386
int ffgcdw( fitsfile *fptr,   /* I - FITS file pointer                       */
 
387
            int  colnum,      /* I - number of column (1 = 1st col)      */
 
388
            int  *width,      /* O - display width                       */
 
389
            int  *status)     /* IO - error status                           */
 
390
/*
 
391
  Get Column Display Width.
 
392
*/
 
393
{
 
394
    tcolumn *colptr;
 
395
    char *cptr;
 
396
    char message[FLEN_ERRMSG], keyname[FLEN_KEYWORD], dispfmt[20];
 
397
    int tcode, hdutype, tstatus, scaled;
 
398
    double tscale;
 
399
 
 
400
    if (*status > 0)  /* inherit input status value if > 0 */
 
401
        return(*status);
 
402
 
 
403
    if (fptr->HDUposition != (fptr->Fptr)->curhdu)
 
404
        ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
 
405
 
 
406
    if (colnum < 1 || colnum > (fptr->Fptr)->tfield)
 
407
    {
 
408
        sprintf(message, "Specified column number is out of range: %d",
 
409
                colnum);
 
410
        ffpmsg(message);
 
411
        return(*status = BAD_COL_NUM);
 
412
    }
 
413
 
 
414
    colptr  = (fptr->Fptr)->tableptr;   /* point to first column */
 
415
    colptr += (colnum - 1);     /* offset to correct column structure */
 
416
    tcode = abs(colptr->tdatatype);
 
417
 
 
418
    /* use the TDISPn keyword if it exists */
 
419
    ffkeyn("TDISP", colnum, keyname, status);
 
420
 
 
421
    *width = 0;
 
422
    tstatus = 0;
 
423
    if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0)
 
424
    {
 
425
          /* parse TDISPn get the display width */
 
426
          cptr = dispfmt;
 
427
          while(*cptr == ' ') /* skip leading blanks */
 
428
              cptr++;
 
429
 
 
430
          if (*cptr == 'A' || *cptr == 'a' ||
 
431
              *cptr == 'I' || *cptr == 'i' ||
 
432
              *cptr == 'O' || *cptr == 'o' ||
 
433
              *cptr == 'Z' || *cptr == 'z' ||
 
434
              *cptr == 'F' || *cptr == 'f' ||
 
435
              *cptr == 'E' || *cptr == 'e' ||
 
436
              *cptr == 'D' || *cptr == 'd' ||
 
437
              *cptr == 'G' || *cptr == 'g')
 
438
          {
 
439
 
 
440
            while(!isdigit((int) *cptr) && *cptr != '\0') /* find 1st digit */
 
441
              cptr++;
 
442
 
 
443
            *width = atoi(cptr);
 
444
            if (tcode >= TCOMPLEX)
 
445
              *width = (2 * (*width)) + 3;
 
446
          }
 
447
    }
 
448
 
 
449
    if (*width == 0)
 
450
    {
 
451
        /* no valid TDISPn keyword; use TFORMn instead */
 
452
 
 
453
        ffkeyn("TFORM", colnum, keyname, status);
 
454
        ffgkys(fptr, keyname, dispfmt, NULL, status);
 
455
 
 
456
        /* check if  column is scaled */
 
457
        ffkeyn("TSCAL", colnum, keyname, status);
 
458
        tstatus = 0;
 
459
        scaled = 0;
 
460
 
 
461
        if (ffgkyd(fptr, keyname, &tscale, NULL, &tstatus) == 0)
 
462
        {
 
463
            if (tscale != 1.0)
 
464
                scaled = 1;    /* yes, this is a scaled column */
 
465
        }
 
466
 
 
467
        if (scaled && tcode <= TSHORT)
 
468
        {
 
469
            /* scaled short integer col == float; default format is 14.6E */
 
470
            *width = 14;
 
471
        }
 
472
        else if (scaled && tcode == TLONG)
 
473
        {
 
474
            /* scaled long integer col == double; default format is 23.15E */
 
475
            *width = 23;
 
476
        }
 
477
        else
 
478
        {
 
479
           ffghdt(fptr, &hdutype, status);  /* get type of table */
 
480
           if (hdutype == ASCII_TBL)
 
481
           {
 
482
              /* parse TFORMn get the display width */
 
483
              cptr = dispfmt;
 
484
              while(!isdigit((int) *cptr) && *cptr != '\0') /* find 1st digit */
 
485
                 cptr++;
 
486
 
 
487
              *width = atoi(cptr);
 
488
           }
 
489
           else
 
490
           {
 
491
                 /* this is a binary table */
 
492
                  if (tcode <= TBYTE)          /* 'X' and 'B' */
 
493
                     *width = 4;
 
494
                  else if (tcode == TSHORT)    /* 'I' */
 
495
                     *width = 6;
 
496
                  else if (tcode == TLONG)     /* 'J' */
 
497
                     *width = 11;
 
498
                  else if (tcode == TFLOAT)    /* 'E' */
 
499
                     *width = 14;
 
500
                  else if (tcode == TDOUBLE)   /* 'D' */
 
501
                     *width = 23;
 
502
                  else if (tcode == TCOMPLEX)  /* 'C' */
 
503
                     *width = 31;
 
504
                  else if (tcode == TDBLCOMPLEX)  /* 'M' */
 
505
                     *width = 49;
 
506
                  else if (tcode == TLOGICAL)  /* 'L' */
 
507
                     *width = 1;
 
508
                  else if (tcode == TSTRING)   /* 'A' */
 
509
                  {
 
510
                     cptr = dispfmt;
 
511
                     while(!isdigit((int) *cptr) && *cptr != '\0') 
 
512
                         cptr++;
 
513
 
 
514
                     *width = atoi(cptr);
 
515
                  }
 
516
            }
 
517
        }
 
518
    } 
 
519
    return(*status);
 
520
}
 
521
/*--------------------------------------------------------------------------*/
 
522
int ffgcls2 ( fitsfile *fptr,   /* I - FITS file pointer                       */
 
523
            int  colnum,      /* I - number of column to read (1 = 1st col) */
 
524
            long  firstrow,   /* I - first row to read (1 = 1st row)        */
 
525
            long  firstelem,  /* I - first vector element to read (1 = 1st) */
 
526
            long  nelem,      /* I - number of strings to read              */
 
527
            int   nultyp,     /* I - null value handling code:               */
 
528
                              /*     1: set undefined pixels = nulval        */
 
529
                              /*     2: set nularray=1 for undefined pixels  */
 
530
            char  *nulval,    /* I - value for null pixels if nultyp = 1     */
 
531
            char **array,     /* O - array of values that are read           */
 
532
            char *nularray,   /* O - array of flags = 1 if nultyp = 2        */
 
533
            int  *anynul,     /* O - set to 1 if any values are null; else 0 */
 
534
            int  *status)     /* IO - error status                           */
 
535
/*
 
536
  Read an array of string values from a column in the current FITS HDU.
 
537
*/
 
538
{
 
539
    long nullen; 
 
540
    int tcode, maxelem, hdutype, nulcheck;
 
541
    long twidth, incre, rownum;
 
542
    long ii, jj, ntodo, tnull, remain, next;
 
543
    OFF_T repeat, startpos, elemnum, readptr, rowlen;
 
544
    double scale, zero;
 
545
    char tform[20];
 
546
    char message[FLEN_ERRMSG];
 
547
    char snull[20];   /*  the FITS null value  */
 
548
    tcolumn *colptr;
 
549
 
 
550
    double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */
 
551
    char *buffer, *arrayptr;
 
552
 
 
553
    if (*status > 0 || nelem == 0)  /* inherit input status value if > 0 */
 
554
        return(*status);
 
555
 
 
556
    if (fptr->HDUposition != (fptr->Fptr)->curhdu)
 
557
        ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
 
558
 
 
559
    if (anynul)
 
560
        *anynul = 0;
 
561
 
 
562
    if (nultyp == 2)
 
563
        memset(nularray, 0, nelem);   /* initialize nullarray */
 
564
 
 
565
    /*---------------------------------------------------*/
 
566
    /*  Check input and get parameters about the column: */
 
567
    /*---------------------------------------------------*/
 
568
    if (colnum < 1 || colnum > (fptr->Fptr)->tfield)
 
569
    {
 
570
        sprintf(message, "Specified column number is out of range: %d",
 
571
                colnum);
 
572
        ffpmsg(message);
 
573
        return(*status = BAD_COL_NUM);
 
574
    }
 
575
 
 
576
    colptr  = (fptr->Fptr)->tableptr;   /* point to first column */
 
577
    colptr += (colnum - 1);     /* offset to correct column structure */
 
578
    tcode = colptr->tdatatype;
 
579
 
 
580
    if (tcode == -TSTRING) /* variable length column in a binary table? */
 
581
    {
 
582
      /* only read a single string; ignore value of firstelem */
 
583
 
 
584
      if (ffgcpr( fptr, colnum, firstrow, 1, 1, 0, &scale, &zero,
 
585
        tform, &twidth, &tcode, &maxelem, &startpos,  &elemnum, &incre,
 
586
        &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0)
 
587
        return(*status);
 
588
 
 
589
      remain = 1;
 
590
      twidth = repeat;  
 
591
    }
 
592
    else if (tcode == TSTRING)
 
593
    {
 
594
      if (ffgcpr( fptr, colnum, firstrow, firstelem, nelem, 0, &scale, &zero,
 
595
        tform, &twidth, &tcode, &maxelem, &startpos,  &elemnum, &incre,
 
596
        &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0)
 
597
        return(*status);
 
598
 
 
599
      remain = nelem;
 
600
    }
 
601
    else
 
602
        return(*status = NOT_ASCII_COL);
 
603
 
 
604
    nullen = strlen(snull);   /* length of the undefined pixel string */
 
605
    if (nullen == 0)
 
606
        nullen = 1;
 
607
 
 
608
    /*------------------------------------------------------------------*/
 
609
    /*  Decide whether to check for null values in the input FITS file: */
 
610
    /*------------------------------------------------------------------*/
 
611
    nulcheck = nultyp; /* by default check for null values in the FITS file */
 
612
 
 
613
    if (nultyp == 1 && nulval[0] == 0)
 
614
       nulcheck = 0;    /* calling routine does not want to check for nulls */
 
615
 
 
616
    else if (snull[0] == ASCII_NULL_UNDEFINED)
 
617
       nulcheck = 0;   /* null value string in ASCII table not defined */
 
618
 
 
619
    else if (nullen > twidth)
 
620
       nulcheck = 0;   /* null value string is longer than width of column  */
 
621
                       /* thus impossible for any column elements to = null */
 
622
 
 
623
    /*---------------------------------------------------------------------*/
 
624
    /*  Now read the strings one at a time from the FITS column.           */
 
625
    /*---------------------------------------------------------------------*/
 
626
    next = 0;                 /* next element in array to be read  */
 
627
    rownum = 0;               /* row number, relative to firstrow     */
 
628
 
 
629
    while (remain)
 
630
    {
 
631
      /* limit the number of pixels to process a one time to the number that
 
632
         will fit in the buffer space or to the number of pixels that remain
 
633
         in the current vector, which ever is smaller.
 
634
      */
 
635
      ntodo = minvalue(remain, maxelem);      
 
636
      ntodo = minvalue(ntodo, (repeat - elemnum));
 
637
 
 
638
      readptr = startpos + ((OFF_T)rownum * rowlen) + (elemnum * incre);
 
639
      ffmbyt(fptr, readptr, REPORT_EOF, status);  /* move to read position */
 
640
 
 
641
      /* read the array of strings from the FITS file into the buffer */
 
642
 
 
643
      if (incre == twidth)
 
644
         ffgbyt(fptr, ntodo * twidth, cbuff, status);
 
645
      else
 
646
         ffgbytoff(fptr, twidth, ntodo, incre - twidth, cbuff, status);
 
647
 
 
648
      /* copy from the buffer into the user's array of strings */
 
649
      /* work backwards from last char of last string to 1st char of 1st */
 
650
 
 
651
      buffer = ((char *) cbuff) + (ntodo * twidth) - 1;
 
652
 
 
653
      for (ii = next + ntodo - 1; ii >= next; ii--)
 
654
      {
 
655
         arrayptr = array[ii] + twidth - 1;
 
656
 
 
657
         for (jj = twidth - 1; jj > 0; jj--)  /* ignore trailing blanks */
 
658
         {
 
659
            if (*buffer == ' ')
 
660
            {
 
661
              buffer--;
 
662
              arrayptr--;
 
663
            }
 
664
            else
 
665
              break;
 
666
         }
 
667
         *(arrayptr + 1) = 0;  /* write the string terminator */
 
668
         
 
669
         for (; jj >= 0; jj--)    /* copy the string itself */
 
670
         {
 
671
           *arrayptr = *buffer;
 
672
           buffer--;
 
673
           arrayptr--;
 
674
         }
 
675
 
 
676
         /* check if null value is defined, and if the   */
 
677
         /* column string is identical to the null string */
 
678
         if (nulcheck && !strncmp(snull, array[ii], nullen) )
 
679
         {
 
680
           *anynul = 1;   /* this is a null value */
 
681
           if (nultyp == 1)
 
682
             strcpy(array[ii], nulval);
 
683
           else
 
684
             nularray[ii] = 1;
 
685
         }
 
686
      }
 
687
    
 
688
      if (*status > 0)  /* test for error during previous read operation */
 
689
      {
 
690
         sprintf(message,
 
691
          "Error reading elements %ld thru %ld of data array (ffpcls).",
 
692
             next+1, next+ntodo);
 
693
 
 
694
         ffpmsg(message);
 
695
         return(*status);
 
696
      }
 
697
 
 
698
      /*--------------------------------------------*/
 
699
      /*  increment the counters for the next loop  */
 
700
      /*--------------------------------------------*/
 
701
      next += ntodo;
 
702
      remain -= ntodo;
 
703
      if (remain)
 
704
      {
 
705
          elemnum += ntodo;
 
706
          if (elemnum == repeat)  /* completed a row; start on next row */
 
707
          {
 
708
              elemnum = 0;
 
709
              rownum++;
 
710
          }
 
711
      }
 
712
    }  /*  End of main while Loop  */
 
713
 
 
714
    return(*status);
 
715
}
 
716