~ubuntu-branches/ubuntu/wily/pyfits/wily-proposed

« back to all changes in this revision

Viewing changes to cextern/cfitsio/getcols.c

  • Committer: Package Import Robot
  • Author(s): Aurelien Jarno
  • Date: 2013-12-07 16:18:48 UTC
  • mfrom: (1.1.11)
  • Revision ID: package-import@ubuntu.com-20131207161848-mcw0saz0iprjhbju
Tags: 1:3.2-1
* New upstream version.
* Bump Standards-Version to 3.9.5 (no changes).
* Remove build-depends on zlib1g-dev and remove patches/01-zlib.diff.
* Add build-depends on libcfitsio3-dev and add 
  patches/01-system-cfitsio.diff.
* Update debian/copyright.
* Install upstream changelog now that it is provided in the upstream
  tarball.
* Don't compress the binary packages with xz, it's no the dpkg's default.

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
            LONGLONG  firstrow,   /* I - first row to read (1 = 1st row)         */
 
18
            LONGLONG  firstelem,  /* I - first vector element to read (1 = 1st)  */
 
19
            LONGLONG  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
            LONGLONG  firstrow,   /* I - first row to read (1 = 1st row)        */
 
40
            LONGLONG  firstelem,  /* I - first vector element to read (1 = 1st) */
 
41
            LONGLONG  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
            LONGLONG  firstrow,   /* I - first row to read (1 = 1st row)        */
 
62
            LONGLONG  firstelem,  /* I - first vector element to read (1 = 1st) */
 
63
            LONGLONG  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, nulwidth, ll, dlen;
 
78
    long ii, jj;
 
79
    tcolumn *colptr;
 
80
    char message[FLEN_ERRMSG], *carray, keyname[FLEN_KEYWORD];
 
81
    char cform[20], dispfmt[20], tmpstr[400], *flgarray, tmpnull[80];
 
82
    unsigned char byteval;
 
83
    float *earray;
 
84
    double *darray, tscale = 1.0;
 
85
    LONGLONG *llarray;
 
86
 
 
87
    if (*status > 0 || nelem == 0)  /* inherit input status value if > 0 */
 
88
        return(*status);
 
89
 
 
90
    /* reset position to the correct HDU if necessary */
 
91
    if (fptr->HDUposition != (fptr->Fptr)->curhdu)
 
92
        ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
 
93
 
 
94
    /* rescan header if data structure is undefined */
 
95
    else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
 
96
        if ( ffrdef(fptr, status) > 0)               
 
97
            return(*status);
 
98
 
 
99
    if (colnum < 1 || colnum > (fptr->Fptr)->tfield)
 
100
    {
 
101
        sprintf(message, "Specified column number is out of range: %d",
 
102
                colnum);
 
103
        ffpmsg(message);
 
104
        return(*status = BAD_COL_NUM);
 
105
    }
 
106
 
 
107
    colptr  = (fptr->Fptr)->tableptr;   /* point to first column */
 
108
    colptr += (colnum - 1);     /* offset to correct column structure */
 
109
    tcode = abs(colptr->tdatatype);
 
110
 
 
111
    if (tcode == TSTRING)
 
112
    {
 
113
      /* simply call the string column reading routine */
 
114
      ffgcls2(fptr, colnum, firstrow, firstelem, nelem, nultyp, nulval,
 
115
           array, nularray, anynul, status);
 
116
    }
 
117
    else if (tcode == TLOGICAL)
 
118
    {
 
119
      /* allocate memory for the array of logical values */
 
120
      carray = (char *) malloc((size_t) nelem);
 
121
 
 
122
      /*  call the logical column reading routine */
 
123
      ffgcll(fptr, colnum, firstrow, firstelem, nelem, nultyp, *nulval,
 
124
           carray, nularray, anynul, status); 
 
125
 
 
126
      if (*status <= 0)
 
127
      {
 
128
         /* convert logical values to "T", "F", or "N" (Null) */
 
129
         for (ii = 0; ii < nelem; ii++)
 
130
         {
 
131
           if (carray[ii] == 1)
 
132
              strcpy(array[ii], "T");
 
133
           else if (carray[ii] == 0)
 
134
              strcpy(array[ii], "F");
 
135
           else  /* undefined values = 2 */
 
136
              strcpy(array[ii],"N");
 
137
         }
 
138
      }
 
139
 
 
140
      free(carray);  /* free the memory */
 
141
    }
 
142
    else if (tcode == TCOMPLEX)
 
143
    {
 
144
      /* allocate memory for the array of double values */
 
145
      earray = (float *) calloc((size_t) (nelem * 2), sizeof(float) );
 
146
      
 
147
      ffgcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2,
 
148
        1, 1, FLOATNULLVALUE, earray, nularray, anynul, status);
 
149
 
 
150
      if (*status <= 0)
 
151
      {
 
152
 
 
153
         /* determine the format for the output strings */
 
154
 
 
155
         ffgcdw(fptr, colnum, &dwidth, status);
 
156
         dwidth = (dwidth - 3) / 2;
 
157
 
 
158
         /* use the TDISPn keyword if it exists */
 
159
         ffkeyn("TDISP", colnum, keyname, status);
 
160
         tstatus = 0;
 
161
         cform[0] = '\0';
 
162
 
 
163
         if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0)
 
164
         {
 
165
             /* convert the Fortran style format to a C style format */
 
166
             ffcdsp(dispfmt, cform);
 
167
         }
 
168
 
 
169
         if (!cform[0])
 
170
             strcpy(cform, "%14.6E");
 
171
 
 
172
         /* write the formated string for each value:  "(real,imag)" */
 
173
         jj = 0;
 
174
         for (ii = 0; ii < nelem; ii++)
 
175
         {
 
176
           strcpy(array[ii], "(");
 
177
 
 
178
           /* test for null value */
 
179
           if (earray[jj] == FLOATNULLVALUE)
 
180
           {
 
181
             strcpy(tmpstr, "NULL");
 
182
             if (nultyp == 2)
 
183
                nularray[ii] = 1;
 
184
           }
 
185
           else
 
186
             sprintf(tmpstr, cform, earray[jj]);
 
187
 
 
188
           strncat(array[ii], tmpstr, dwidth);
 
189
           strcat(array[ii], ",");
 
190
           jj++;
 
191
 
 
192
           /* test for null value */
 
193
           if (earray[jj] == FLOATNULLVALUE)
 
194
           {
 
195
             strcpy(tmpstr, "NULL");
 
196
             if (nultyp == 2)
 
197
                nularray[ii] = 1;
 
198
           }
 
199
           else
 
200
             sprintf(tmpstr, cform, earray[jj]);
 
201
 
 
202
           strncat(array[ii], tmpstr, dwidth);
 
203
           strcat(array[ii], ")");
 
204
           jj++;
 
205
         }
 
206
      }
 
207
 
 
208
      free(earray);  /* free the memory */
 
209
    }
 
210
    else if (tcode == TDBLCOMPLEX)
 
211
    {
 
212
      /* allocate memory for the array of double values */
 
213
      darray = (double *) calloc((size_t) (nelem * 2), sizeof(double) );
 
214
      
 
215
      ffgcld(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1, nelem * 2,
 
216
        1, 1, DOUBLENULLVALUE, darray, nularray, anynul, status);
 
217
 
 
218
      if (*status <= 0)
 
219
      {
 
220
         /* determine the format for the output strings */
 
221
 
 
222
         ffgcdw(fptr, colnum, &dwidth, status);
 
223
         dwidth = (dwidth - 3) / 2;
 
224
 
 
225
         /* use the TDISPn keyword if it exists */
 
226
         ffkeyn("TDISP", colnum, keyname, status);
 
227
         tstatus = 0;
 
228
         cform[0] = '\0';
 
229
 
 
230
         if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0)
 
231
         {
 
232
             /* convert the Fortran style format to a C style format */
 
233
             ffcdsp(dispfmt, cform);
 
234
         }
 
235
 
 
236
         if (!cform[0])
 
237
            strcpy(cform, "%23.15E");
 
238
 
 
239
         /* write the formated string for each value:  "(real,imag)" */
 
240
         jj = 0;
 
241
         for (ii = 0; ii < nelem; ii++)
 
242
         {
 
243
           strcpy(array[ii], "(");
 
244
 
 
245
           /* test for null value */
 
246
           if (darray[jj] == DOUBLENULLVALUE)
 
247
           {
 
248
             strcpy(tmpstr, "NULL");
 
249
             if (nultyp == 2)
 
250
                nularray[ii] = 1;
 
251
           }
 
252
           else
 
253
             sprintf(tmpstr, cform, darray[jj]);
 
254
 
 
255
           strncat(array[ii], tmpstr, dwidth);
 
256
           strcat(array[ii], ",");
 
257
           jj++;
 
258
 
 
259
           /* test for null value */
 
260
           if (darray[jj] == DOUBLENULLVALUE)
 
261
           {
 
262
             strcpy(tmpstr, "NULL");
 
263
             if (nultyp == 2)
 
264
                nularray[ii] = 1;
 
265
           }
 
266
           else
 
267
             sprintf(tmpstr, cform, darray[jj]);
 
268
 
 
269
           strncat(array[ii], tmpstr, dwidth);
 
270
           strcat(array[ii], ")");
 
271
           jj++;
 
272
         }
 
273
      }
 
274
 
 
275
      free(darray);  /* free the memory */
 
276
    }
 
277
    else if (tcode == TLONGLONG)
 
278
    {
 
279
      /* allocate memory for the array of LONGLONG values */
 
280
      llarray = (LONGLONG *) calloc((size_t) nelem, sizeof(LONGLONG) );
 
281
      flgarray = (char *) calloc((size_t) nelem, sizeof(char) );
 
282
      dwidth = 20;  /* max width of displayed long long integer value */
 
283
 
 
284
      if (ffgcfjj(fptr, colnum, firstrow, firstelem, nelem,
 
285
            llarray, flgarray, anynul, status) > 0)
 
286
      {
 
287
         free(flgarray);
 
288
         free(llarray);
 
289
         return(*status);
 
290
      }
 
291
 
 
292
      /* write the formated string for each value */
 
293
      if (nulval) {
 
294
          strcpy(tmpnull, nulval);
 
295
          nulwidth = strlen(nulval);
 
296
      } else {
 
297
          strcpy(tmpnull, " ");
 
298
          nulwidth = 1;
 
299
      }
 
300
 
 
301
      for (ii = 0; ii < nelem; ii++)
 
302
      {
 
303
           if ( flgarray[ii] )
 
304
           {
 
305
              *array[ii] = '\0';
 
306
              if (dwidth < nulwidth)
 
307
                  strncat(array[ii], tmpnull, dwidth);
 
308
              else
 
309
                  sprintf(array[ii],"%*s",dwidth,tmpnull);
 
310
                  
 
311
              if (nultyp == 2)
 
312
                  nularray[ii] = 1;
 
313
           }
 
314
           else
 
315
           {       
 
316
 
 
317
#if defined(_MSC_VER)
 
318
    /* Microsoft Visual C++ 6.0 uses '%I64d' syntax  for 8-byte integers */
 
319
        sprintf(tmpstr, "%20I64d", llarray[ii]);
 
320
#elif (USE_LL_SUFFIX == 1)
 
321
        sprintf(tmpstr, "%20lld", llarray[ii]);
 
322
#else
 
323
        sprintf(tmpstr, "%20ld", llarray[ii]);
 
324
#endif
 
325
              *array[ii] = '\0';
 
326
              strncat(array[ii], tmpstr, 20);
 
327
           }
 
328
      }
 
329
 
 
330
      free(flgarray);
 
331
      free(llarray);  /* free the memory */
 
332
 
 
333
    }
 
334
    else
 
335
    {
 
336
      /* allocate memory for the array of double values */
 
337
      darray = (double *) calloc((size_t) nelem, sizeof(double) );
 
338
      
 
339
      /* read all other numeric type columns as doubles */
 
340
      if (ffgcld(fptr, colnum, firstrow, firstelem, nelem, 1, nultyp, 
 
341
           DOUBLENULLVALUE, darray, nularray, anynul, status) > 0)
 
342
      {
 
343
         free(darray);
 
344
         return(*status);
 
345
      }
 
346
 
 
347
      /* determine the format for the output strings */
 
348
 
 
349
      ffgcdw(fptr, colnum, &dwidth, status);
 
350
 
 
351
      /* check if  column is scaled */
 
352
      ffkeyn("TSCAL", colnum, keyname, status);
 
353
      tstatus = 0;
 
354
      scaled = 0;
 
355
      if (ffgkyd(fptr, keyname, &tscale, NULL, &tstatus) == 0)
 
356
      {
 
357
            if (tscale != 1.0)
 
358
                scaled = 1;    /* yes, this is a scaled column */
 
359
      }
 
360
 
 
361
      intcol = 0;
 
362
      if (tcode <= TLONG && !scaled)
 
363
             intcol = 1;   /* this is an unscaled integer column */
 
364
 
 
365
      /* use the TDISPn keyword if it exists */
 
366
      ffkeyn("TDISP", colnum, keyname, status);
 
367
      tstatus = 0;
 
368
      cform[0] = '\0';
 
369
 
 
370
      if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0)
 
371
      {
 
372
           /* convert the Fortran style TDISPn to a C style format */
 
373
           ffcdsp(dispfmt, cform);
 
374
      }
 
375
 
 
376
      if (!cform[0])
 
377
      {
 
378
            /* no TDISPn keyword; use TFORMn instead */
 
379
 
 
380
            ffkeyn("TFORM", colnum, keyname, status);
 
381
            ffgkys(fptr, keyname, dispfmt, NULL, status);
 
382
 
 
383
            if (scaled && tcode <= TSHORT)
 
384
            {
 
385
                  /* scaled short integer column == float */
 
386
                  strcpy(cform, "%#14.6G");
 
387
            }
 
388
            else if (scaled && tcode == TLONG)
 
389
            {
 
390
                  /* scaled long integer column == double */
 
391
                  strcpy(cform, "%#23.15G");
 
392
            }
 
393
            else
 
394
            {
 
395
               ffghdt(fptr, &hdutype, status);
 
396
               if (hdutype == ASCII_TBL)
 
397
               {
 
398
                  /* convert the Fortran style TFORMn to a C style format */
 
399
                  ffcdsp(dispfmt, cform);
 
400
               }
 
401
               else
 
402
               {
 
403
                 /* this is a binary table, need to convert the format */
 
404
                  if (tcode == TBIT) {            /* 'X' */
 
405
                     strcpy(cform, "%4d");
 
406
                  } else if (tcode == TBYTE) {    /* 'B' */
 
407
                     strcpy(cform, "%4d");
 
408
                  } else if (tcode == TSHORT) {   /* 'I' */
 
409
                     strcpy(cform, "%6d");
 
410
                  } else if (tcode == TLONG) {    /* 'J' */
 
411
                     strcpy(cform, "%11.0f");
 
412
                     intcol = 0;  /* needed to support unsigned int */
 
413
                  } else if (tcode == TFLOAT) {   /* 'E' */
 
414
                     strcpy(cform, "%#14.6G");
 
415
                  } else if (tcode == TDOUBLE) {  /* 'D' */
 
416
                     strcpy(cform, "%#23.15G");
 
417
                  }
 
418
               }
 
419
            }
 
420
      } 
 
421
 
 
422
      if (nulval) {
 
423
          strcpy(tmpnull, nulval);
 
424
          nulwidth = strlen(nulval);
 
425
      } else {
 
426
          strcpy(tmpnull, " ");
 
427
          nulwidth = 1;
 
428
      }
 
429
 
 
430
      /* write the formated string for each value */
 
431
      for (ii = 0; ii < nelem; ii++)
 
432
      {
 
433
           if (tcode == TBIT)
 
434
           {
 
435
               byteval = (char) darray[ii];
 
436
 
 
437
               for (ll=0; ll < 8; ll++)
 
438
               {
 
439
                   if ( ((unsigned char) (byteval << ll)) >> 7 )
 
440
                       *(array[ii] + ll) = '1';
 
441
                   else
 
442
                       *(array[ii] + ll) = '0';
 
443
               }
 
444
               *(array[ii] + 8) = '\0';
 
445
           }
 
446
           /* test for null value */
 
447
           else if ( (nultyp == 1 && darray[ii] == DOUBLENULLVALUE) ||
 
448
                (nultyp == 2 && nularray[ii]) )
 
449
           {
 
450
              *array[ii] = '\0';
 
451
              if (dwidth < nulwidth)
 
452
                  strncat(array[ii], tmpnull, dwidth);
 
453
              else
 
454
                  sprintf(array[ii],"%*s",dwidth,tmpnull);
 
455
           }
 
456
           else
 
457
           {       
 
458
              if (intcol)
 
459
                sprintf(tmpstr, cform, (int) darray[ii]);
 
460
              else
 
461
                sprintf(tmpstr, cform, darray[ii]);
 
462
 
 
463
              /* fill field with '*' if number is too wide */
 
464
              dlen = strlen(tmpstr);
 
465
              if (dlen > dwidth) {
 
466
                 memset(tmpstr, '*', dwidth);
 
467
              }
 
468
 
 
469
              *array[ii] = '\0';
 
470
              strncat(array[ii], tmpstr, dwidth);
 
471
           }
 
472
      }
 
473
 
 
474
      free(darray);  /* free the memory */
 
475
    }
 
476
    return(*status);
 
477
}
 
478
/*--------------------------------------------------------------------------*/
 
479
int ffgcdw( fitsfile *fptr,   /* I - FITS file pointer                       */
 
480
            int  colnum,      /* I - number of column (1 = 1st col)      */
 
481
            int  *width,      /* O - display width                       */
 
482
            int  *status)     /* IO - error status                           */
 
483
/*
 
484
  Get Column Display Width.
 
485
*/
 
486
{
 
487
    tcolumn *colptr;
 
488
    char *cptr;
 
489
    char message[FLEN_ERRMSG], keyname[FLEN_KEYWORD], dispfmt[20];
 
490
    int tcode, hdutype, tstatus, scaled;
 
491
    double tscale;
 
492
 
 
493
    if (*status > 0)  /* inherit input status value if > 0 */
 
494
        return(*status);
 
495
 
 
496
    if (fptr->HDUposition != (fptr->Fptr)->curhdu)
 
497
        ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
 
498
 
 
499
    if (colnum < 1 || colnum > (fptr->Fptr)->tfield)
 
500
    {
 
501
        sprintf(message, "Specified column number is out of range: %d",
 
502
                colnum);
 
503
        ffpmsg(message);
 
504
        return(*status = BAD_COL_NUM);
 
505
    }
 
506
 
 
507
    colptr  = (fptr->Fptr)->tableptr;   /* point to first column */
 
508
    colptr += (colnum - 1);     /* offset to correct column structure */
 
509
    tcode = abs(colptr->tdatatype);
 
510
 
 
511
    /* use the TDISPn keyword if it exists */
 
512
    ffkeyn("TDISP", colnum, keyname, status);
 
513
 
 
514
    *width = 0;
 
515
    tstatus = 0;
 
516
    if (ffgkys(fptr, keyname, dispfmt, NULL, &tstatus) == 0)
 
517
    {
 
518
          /* parse TDISPn get the display width */
 
519
          cptr = dispfmt;
 
520
          while(*cptr == ' ') /* skip leading blanks */
 
521
              cptr++;
 
522
 
 
523
          if (*cptr == 'A' || *cptr == 'a' ||
 
524
              *cptr == 'I' || *cptr == 'i' ||
 
525
              *cptr == 'O' || *cptr == 'o' ||
 
526
              *cptr == 'Z' || *cptr == 'z' ||
 
527
              *cptr == 'F' || *cptr == 'f' ||
 
528
              *cptr == 'E' || *cptr == 'e' ||
 
529
              *cptr == 'D' || *cptr == 'd' ||
 
530
              *cptr == 'G' || *cptr == 'g')
 
531
          {
 
532
 
 
533
            while(!isdigit((int) *cptr) && *cptr != '\0') /* find 1st digit */
 
534
              cptr++;
 
535
 
 
536
            *width = atoi(cptr);
 
537
            if (tcode >= TCOMPLEX)
 
538
              *width = (2 * (*width)) + 3;
 
539
          }
 
540
    }
 
541
 
 
542
    if (*width == 0)
 
543
    {
 
544
        /* no valid TDISPn keyword; use TFORMn instead */
 
545
 
 
546
        ffkeyn("TFORM", colnum, keyname, status);
 
547
        ffgkys(fptr, keyname, dispfmt, NULL, status);
 
548
 
 
549
        /* check if  column is scaled */
 
550
        ffkeyn("TSCAL", colnum, keyname, status);
 
551
        tstatus = 0;
 
552
        scaled = 0;
 
553
 
 
554
        if (ffgkyd(fptr, keyname, &tscale, NULL, &tstatus) == 0)
 
555
        {
 
556
            if (tscale != 1.0)
 
557
                scaled = 1;    /* yes, this is a scaled column */
 
558
        }
 
559
 
 
560
        if (scaled && tcode <= TSHORT)
 
561
        {
 
562
            /* scaled short integer col == float; default format is 14.6G */
 
563
            *width = 14;
 
564
        }
 
565
        else if (scaled && tcode == TLONG)
 
566
        {
 
567
            /* scaled long integer col == double; default format is 23.15G */
 
568
            *width = 23;
 
569
        }
 
570
        else
 
571
        {
 
572
           ffghdt(fptr, &hdutype, status);  /* get type of table */
 
573
           if (hdutype == ASCII_TBL)
 
574
           {
 
575
              /* parse TFORMn get the display width */
 
576
              cptr = dispfmt;
 
577
              while(!isdigit((int) *cptr) && *cptr != '\0') /* find 1st digit */
 
578
                 cptr++;
 
579
 
 
580
              *width = atoi(cptr);
 
581
           }
 
582
           else
 
583
           {
 
584
                 /* this is a binary table */
 
585
                  if (tcode == TBIT)           /* 'X' */
 
586
                     *width = 8;
 
587
                  else if (tcode == TBYTE)     /* 'B' */
 
588
                     *width = 4;
 
589
                  else if (tcode == TSHORT)    /* 'I' */
 
590
                     *width = 6;
 
591
                  else if (tcode == TLONG)     /* 'J' */
 
592
                     *width = 11;
 
593
                  else if (tcode == TLONGLONG) /* 'K' */
 
594
                     *width = 20;
 
595
                  else if (tcode == TFLOAT)    /* 'E' */
 
596
                     *width = 14;
 
597
                  else if (tcode == TDOUBLE)   /* 'D' */
 
598
                     *width = 23;
 
599
                  else if (tcode == TCOMPLEX)  /* 'C' */
 
600
                     *width = 31;
 
601
                  else if (tcode == TDBLCOMPLEX)  /* 'M' */
 
602
                     *width = 49;
 
603
                  else if (tcode == TLOGICAL)  /* 'L' */
 
604
                     *width = 1;
 
605
                  else if (tcode == TSTRING)   /* 'A' */
 
606
                  {
 
607
                     cptr = dispfmt;
 
608
                     while(!isdigit((int) *cptr) && *cptr != '\0') 
 
609
                         cptr++;
 
610
 
 
611
                     *width = atoi(cptr);
 
612
 
 
613
                     if (*width < 1)
 
614
                         *width = 1;  /* default is at least 1 column */
 
615
                  }
 
616
            }
 
617
        }
 
618
    } 
 
619
    return(*status);
 
620
}
 
621
/*--------------------------------------------------------------------------*/
 
622
int ffgcls2 ( fitsfile *fptr,   /* I - FITS file pointer                       */
 
623
            int  colnum,      /* I - number of column to read (1 = 1st col) */
 
624
            LONGLONG  firstrow,   /* I - first row to read (1 = 1st row)        */
 
625
            LONGLONG  firstelem,  /* I - first vector element to read (1 = 1st) */
 
626
            LONGLONG  nelem,      /* I - number of strings to read              */
 
627
            int   nultyp,     /* I - null value handling code:               */
 
628
                              /*     1: set undefined pixels = nulval        */
 
629
                              /*     2: set nularray=1 for undefined pixels  */
 
630
            char  *nulval,    /* I - value for null pixels if nultyp = 1     */
 
631
            char **array,     /* O - array of values that are read           */
 
632
            char *nularray,   /* O - array of flags = 1 if nultyp = 2        */
 
633
            int  *anynul,     /* O - set to 1 if any values are null; else 0 */
 
634
            int  *status)     /* IO - error status                           */
 
635
/*
 
636
  Read an array of string values from a column in the current FITS HDU.
 
637
*/
 
638
{
 
639
    double dtemp;
 
640
    long nullen; 
 
641
    int tcode, maxelem, hdutype, nulcheck;
 
642
    long twidth, incre;
 
643
    long ii, jj, ntodo;
 
644
    LONGLONG repeat, startpos, elemnum, readptr, tnull, rowlen, rownum, remain, next;
 
645
    double scale, zero;
 
646
    char tform[20];
 
647
    char message[FLEN_ERRMSG];
 
648
    char snull[20];   /*  the FITS null value  */
 
649
    tcolumn *colptr;
 
650
 
 
651
    double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */
 
652
    char *buffer, *arrayptr;
 
653
 
 
654
    if (*status > 0 || nelem == 0)  /* inherit input status value if > 0 */
 
655
        return(*status);
 
656
 
 
657
    if (fptr->HDUposition != (fptr->Fptr)->curhdu)
 
658
        ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
 
659
 
 
660
    if (anynul)
 
661
        *anynul = 0;
 
662
 
 
663
    if (nultyp == 2)
 
664
        memset(nularray, 0, (size_t) nelem);   /* initialize nullarray */
 
665
 
 
666
    /*---------------------------------------------------*/
 
667
    /*  Check input and get parameters about the column: */
 
668
    /*---------------------------------------------------*/
 
669
    if (colnum < 1 || colnum > (fptr->Fptr)->tfield)
 
670
    {
 
671
        sprintf(message, "Specified column number is out of range: %d",
 
672
                colnum);
 
673
        ffpmsg(message);
 
674
        return(*status = BAD_COL_NUM);
 
675
    }
 
676
 
 
677
    colptr  = (fptr->Fptr)->tableptr;   /* point to first column */
 
678
    colptr += (colnum - 1);     /* offset to correct column structure */
 
679
    tcode = colptr->tdatatype;
 
680
 
 
681
    if (tcode == -TSTRING) /* variable length column in a binary table? */
 
682
    {
 
683
      /* only read a single string; ignore value of firstelem */
 
684
 
 
685
      if (ffgcprll( fptr, colnum, firstrow, 1, 1, 0, &scale, &zero,
 
686
        tform, &twidth, &tcode, &maxelem, &startpos,  &elemnum, &incre,
 
687
        &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0)
 
688
        return(*status);
 
689
 
 
690
      remain = 1;
 
691
      twidth = (long) repeat;  
 
692
    }
 
693
    else if (tcode == TSTRING)
 
694
    {
 
695
      if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 0, &scale, &zero,
 
696
        tform, &twidth, &tcode, &maxelem, &startpos,  &elemnum, &incre,
 
697
        &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0)
 
698
        return(*status);
 
699
 
 
700
      /* if string length is greater than a FITS block (2880 char) then must */
 
701
      /* only read 1 string at a time, to force reading by ffgbyt instead of */
 
702
      /* ffgbytoff (ffgbytoff can't handle this case) */
 
703
      if (twidth > IOBUFLEN) {
 
704
        maxelem = 1;
 
705
        incre = twidth;
 
706
        repeat = 1;
 
707
      }   
 
708
 
 
709
      remain = nelem;
 
710
    }
 
711
    else
 
712
        return(*status = NOT_ASCII_COL);
 
713
 
 
714
    nullen = strlen(snull);   /* length of the undefined pixel string */
 
715
    if (nullen == 0)
 
716
        nullen = 1;
 
717
 
 
718
    /*------------------------------------------------------------------*/
 
719
    /*  Decide whether to check for null values in the input FITS file: */
 
720
    /*------------------------------------------------------------------*/
 
721
    nulcheck = nultyp; /* by default check for null values in the FITS file */
 
722
 
 
723
    if (nultyp == 1 && nulval == 0)
 
724
       nulcheck = 0;    /* calling routine does not want to check for nulls */
 
725
 
 
726
    else if (nultyp == 1 && nulval && nulval[0] == 0)
 
727
       nulcheck = 0;    /* calling routine does not want to check for nulls */
 
728
 
 
729
    else if (snull[0] == ASCII_NULL_UNDEFINED)
 
730
       nulcheck = 0;   /* null value string in ASCII table not defined */
 
731
 
 
732
    else if (nullen > twidth)
 
733
       nulcheck = 0;   /* null value string is longer than width of column  */
 
734
                       /* thus impossible for any column elements to = null */
 
735
 
 
736
    /*---------------------------------------------------------------------*/
 
737
    /*  Now read the strings one at a time from the FITS column.           */
 
738
    /*---------------------------------------------------------------------*/
 
739
    next = 0;                 /* next element in array to be read  */
 
740
    rownum = 0;               /* row number, relative to firstrow     */
 
741
 
 
742
    while (remain)
 
743
    {
 
744
      /* limit the number of pixels to process at one time to the number that
 
745
         will fit in the buffer space or to the number of pixels that remain
 
746
         in the current vector, which ever is smaller.
 
747
      */
 
748
      ntodo = (long) minvalue(remain, maxelem);      
 
749
      ntodo = (long) minvalue(ntodo, (repeat - elemnum));
 
750
 
 
751
      readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre);
 
752
      ffmbyt(fptr, readptr, REPORT_EOF, status);  /* move to read position */
 
753
 
 
754
      /* read the array of strings from the FITS file into the buffer */
 
755
 
 
756
      if (incre == twidth)
 
757
         ffgbyt(fptr, ntodo * twidth, cbuff, status);
 
758
      else
 
759
         ffgbytoff(fptr, twidth, ntodo, incre - twidth, cbuff, status);
 
760
 
 
761
      /* copy from the buffer into the user's array of strings */
 
762
      /* work backwards from last char of last string to 1st char of 1st */
 
763
 
 
764
      buffer = ((char *) cbuff) + (ntodo * twidth) - 1;
 
765
 
 
766
      for (ii = (long) (next + ntodo - 1); ii >= next; ii--)
 
767
      {
 
768
         arrayptr = array[ii] + twidth - 1;
 
769
 
 
770
         for (jj = twidth - 1; jj > 0; jj--)  /* ignore trailing blanks */
 
771
         {
 
772
            if (*buffer == ' ')
 
773
            {
 
774
              buffer--;
 
775
              arrayptr--;
 
776
            }
 
777
            else
 
778
              break;
 
779
         }
 
780
         *(arrayptr + 1) = 0;  /* write the string terminator */
 
781
         
 
782
         for (; jj >= 0; jj--)    /* copy the string itself */
 
783
         {
 
784
           *arrayptr = *buffer;
 
785
           buffer--;
 
786
           arrayptr--;
 
787
         }
 
788
 
 
789
         /* check if null value is defined, and if the   */
 
790
         /* column string is identical to the null string */
 
791
         if (nulcheck && !strncmp(snull, array[ii], nullen) )
 
792
         {
 
793
           *anynul = 1;   /* this is a null value */
 
794
           if (nultyp == 1) {
 
795
           
 
796
             if (nulval)
 
797
                strcpy(array[ii], nulval);
 
798
             else
 
799
                strcpy(array[ii], " ");
 
800
             
 
801
           } else
 
802
             nularray[ii] = 1;
 
803
         }
 
804
      }
 
805
    
 
806
      if (*status > 0)  /* test for error during previous read operation */
 
807
      {
 
808
         dtemp = (double) next;
 
809
         sprintf(message,
 
810
          "Error reading elements %.0f thru %.0f of data array (ffpcls).",
 
811
             dtemp+1., dtemp+ntodo);
 
812
 
 
813
         ffpmsg(message);
 
814
         return(*status);
 
815
      }
 
816
 
 
817
      /*--------------------------------------------*/
 
818
      /*  increment the counters for the next loop  */
 
819
      /*--------------------------------------------*/
 
820
      next += ntodo;
 
821
      remain -= ntodo;
 
822
      if (remain)
 
823
      {
 
824
          elemnum += ntodo;
 
825
          if (elemnum == repeat)  /* completed a row; start on next row */
 
826
          {
 
827
              elemnum = 0;
 
828
              rownum++;
 
829
          }
 
830
      }
 
831
    }  /*  End of main while Loop  */
 
832
 
 
833
    return(*status);
 
834
}
 
835