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

« back to all changes in this revision

Viewing changes to cextern/cfitsio/getcolui.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, getcolui.c, contains routines that read data elements from   */
 
2
/*  a FITS image or table, with unsigned short 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 <math.h>
 
9
#include <stdlib.h>
 
10
#include <limits.h>
 
11
#include <string.h>
 
12
#include "fitsio2.h"
 
13
 
 
14
/*--------------------------------------------------------------------------*/
 
15
int ffgpvui( fitsfile *fptr,   /* I - FITS file pointer                       */
 
16
            long  group,      /* I - group to read (1 = 1st group)           */
 
17
            LONGLONG  firstelem,  /* I - first vector element to read (1 = 1st)  */
 
18
            LONGLONG  nelem,      /* I - number of values to read                */
 
19
   unsigned short nulval,     /* I - value for undefined pixels              */
 
20
   unsigned short *array,     /* O - array of values that are returned       */
 
21
            int  *anynul,     /* O - set to 1 if any values are null; else 0 */
 
22
            int  *status)     /* IO - error status                           */
 
23
/*
 
24
  Read an array of values from the primary array. Data conversion
 
25
  and scaling will be performed if necessary (e.g, if the datatype of
 
26
  the FITS array is not the same as the array being read).
 
27
  Undefined elements will be set equal to NULVAL, unless NULVAL=0
 
28
  in which case no checking for undefined values will be performed.
 
29
  ANYNUL is returned with a value of .true. if any pixels are undefined.
 
30
*/
 
31
{
 
32
    long row;
 
33
    char cdummy;
 
34
    int nullcheck = 1;
 
35
    unsigned short nullvalue;
 
36
 
 
37
    if (fits_is_compressed_image(fptr, status))
 
38
    {
 
39
        /* this is a compressed image in a binary table */
 
40
         nullvalue = nulval;  /* set local variable */
 
41
 
 
42
        fits_read_compressed_pixels(fptr, TUSHORT, firstelem, nelem,
 
43
            nullcheck, &nullvalue, array, NULL, anynul, status);
 
44
        return(*status);
 
45
    }
 
46
 
 
47
    /*
 
48
      the primary array is represented as a binary table:
 
49
      each group of the primary array is a row in the table,
 
50
      where the first column contains the group parameters
 
51
      and the second column contains the image itself.
 
52
    */
 
53
 
 
54
    row=maxvalue(1,group);
 
55
 
 
56
    ffgclui(fptr, 2, row, firstelem, nelem, 1, 1, nulval,
 
57
               array, &cdummy, anynul, status);
 
58
    return(*status);
 
59
}
 
60
/*--------------------------------------------------------------------------*/
 
61
int ffgpfui( fitsfile *fptr,   /* I - FITS file pointer                       */
 
62
            long  group,      /* I - group to read (1 = 1st group)           */
 
63
            LONGLONG  firstelem,  /* I - first vector element to read (1 = 1st)  */
 
64
            LONGLONG  nelem,      /* I - number of values to read                */
 
65
   unsigned short *array,     /* O - array of values that are returned       */
 
66
            char *nularray,   /* O - array of null pixel flags               */
 
67
            int  *anynul,     /* O - set to 1 if any values are null; else 0 */
 
68
            int  *status)     /* IO - error status                           */
 
69
/*
 
70
  Read an array of values from the primary array. Data conversion
 
71
  and scaling will be performed if necessary (e.g, if the datatype of
 
72
  the FITS array is not the same as the array being read).
 
73
  Any undefined pixels in the returned array will be set = 0 and the 
 
74
  corresponding nularray value will be set = 1.
 
75
  ANYNUL is returned with a value of .true. if any pixels are undefined.
 
76
*/
 
77
{
 
78
    long row;
 
79
    int nullcheck = 2;
 
80
 
 
81
    if (fits_is_compressed_image(fptr, status))
 
82
    {
 
83
        /* this is a compressed image in a binary table */
 
84
 
 
85
        fits_read_compressed_pixels(fptr, TUSHORT, firstelem, nelem,
 
86
            nullcheck, NULL, array, nularray, anynul, status);
 
87
        return(*status);
 
88
    }
 
89
 
 
90
    /*
 
91
      the primary array is represented as a binary table:
 
92
      each group of the primary array is a row in the table,
 
93
      where the first column contains the group parameters
 
94
      and the second column contains the image itself.
 
95
    */
 
96
 
 
97
    row=maxvalue(1,group);
 
98
 
 
99
    ffgclui(fptr, 2, row, firstelem, nelem, 1, 2, 0,
 
100
               array, nularray, anynul, status);
 
101
    return(*status);
 
102
}
 
103
/*--------------------------------------------------------------------------*/
 
104
int ffg2dui(fitsfile *fptr,  /* I - FITS file pointer                       */
 
105
           long  group,     /* I - group to read (1 = 1st group)           */
 
106
  unsigned short nulval,    /* set undefined pixels equal to this          */
 
107
           LONGLONG  ncols,     /* I - number of pixels in each row of array   */
 
108
           LONGLONG  naxis1,    /* I - FITS image NAXIS1 value                 */
 
109
           LONGLONG  naxis2,    /* I - FITS image NAXIS2 value                 */
 
110
  unsigned short *array,    /* O - array to be filled and returned         */
 
111
           int  *anynul,    /* O - set to 1 if any values are null; else 0 */
 
112
           int  *status)    /* IO - error status                           */
 
113
/*
 
114
  Read an entire 2-D array of values to the primary array. Data conversion
 
115
  and scaling will be performed if necessary (e.g, if the datatype of the
 
116
  FITS array is not the same as the array being read).  Any null
 
117
  values in the array will be set equal to the value of nulval, unless
 
118
  nulval = 0 in which case no null checking will be performed.
 
119
*/
 
120
{
 
121
    /* call the 3D reading routine, with the 3rd dimension = 1 */
 
122
 
 
123
    ffg3dui(fptr, group, nulval, ncols, naxis2, naxis1, naxis2, 1, array, 
 
124
           anynul, status);
 
125
 
 
126
    return(*status);
 
127
}
 
128
/*--------------------------------------------------------------------------*/
 
129
int ffg3dui(fitsfile *fptr,  /* I - FITS file pointer                       */
 
130
           long  group,     /* I - group to read (1 = 1st group)           */
 
131
  unsigned short nulval,    /* set undefined pixels equal to this          */
 
132
           LONGLONG  ncols,     /* I - number of pixels in each row of array   */
 
133
           LONGLONG  nrows,     /* I - number of rows in each plane of array   */
 
134
           LONGLONG  naxis1,    /* I - FITS image NAXIS1 value                 */
 
135
           LONGLONG  naxis2,    /* I - FITS image NAXIS2 value                 */
 
136
           LONGLONG  naxis3,    /* I - FITS image NAXIS3 value                 */
 
137
  unsigned short *array,    /* O - array to be filled and returned         */
 
138
           int  *anynul,    /* O - set to 1 if any values are null; else 0 */
 
139
           int  *status)    /* IO - error status                           */
 
140
/*
 
141
  Read an entire 3-D array of values to the primary array. Data conversion
 
142
  and scaling will be performed if necessary (e.g, if the datatype of the
 
143
  FITS array is not the same as the array being read).  Any null
 
144
  values in the array will be set equal to the value of nulval, unless
 
145
  nulval = 0 in which case no null checking will be performed.
 
146
*/
 
147
{
 
148
    long tablerow, ii, jj;
 
149
    char cdummy;
 
150
    int nullcheck = 1;
 
151
    long inc[] = {1,1,1};
 
152
    LONGLONG fpixel[] = {1,1,1}, nfits, narray;
 
153
    LONGLONG lpixel[3];
 
154
    unsigned short nullvalue;
 
155
 
 
156
    if (fits_is_compressed_image(fptr, status))
 
157
    {
 
158
        /* this is a compressed image in a binary table */
 
159
 
 
160
        lpixel[0] = ncols;
 
161
        lpixel[1] = nrows;
 
162
        lpixel[2] = naxis3;
 
163
        nullvalue = nulval;  /* set local variable */
 
164
 
 
165
        fits_read_compressed_img(fptr, TUSHORT, fpixel, lpixel, inc,
 
166
            nullcheck, &nullvalue, array, NULL, anynul, status);
 
167
        return(*status);
 
168
    }
 
169
 
 
170
    /*
 
171
      the primary array is represented as a binary table:
 
172
      each group of the primary array is a row in the table,
 
173
      where the first column contains the group parameters
 
174
      and the second column contains the image itself.
 
175
    */
 
176
    tablerow=maxvalue(1,group);
 
177
 
 
178
    if (ncols == naxis1 && nrows == naxis2)  /* arrays have same size? */
 
179
    {
 
180
       /* all the image pixels are contiguous, so read all at once */
 
181
       ffgclui(fptr, 2, tablerow, 1, naxis1 * naxis2 * naxis3, 1, 1, nulval,
 
182
               array, &cdummy, anynul, status);
 
183
       return(*status);
 
184
    }
 
185
 
 
186
    if (ncols < naxis1 || nrows < naxis2)
 
187
       return(*status = BAD_DIMEN);
 
188
 
 
189
    nfits = 1;   /* next pixel in FITS image to read */
 
190
    narray = 0;  /* next pixel in output array to be filled */
 
191
 
 
192
    /* loop over naxis3 planes in the data cube */
 
193
    for (jj = 0; jj < naxis3; jj++)
 
194
    {
 
195
      /* loop over the naxis2 rows in the FITS image, */
 
196
      /* reading naxis1 pixels to each row            */
 
197
 
 
198
      for (ii = 0; ii < naxis2; ii++)
 
199
      {
 
200
       if (ffgclui(fptr, 2, tablerow, nfits, naxis1, 1, 1, nulval,
 
201
          &array[narray], &cdummy, anynul, status) > 0)
 
202
          return(*status);
 
203
 
 
204
       nfits += naxis1;
 
205
       narray += ncols;
 
206
      }
 
207
      narray += (nrows - naxis2) * ncols;
 
208
    }
 
209
 
 
210
    return(*status);
 
211
}
 
212
/*--------------------------------------------------------------------------*/
 
213
int ffgsvui(fitsfile *fptr, /* I - FITS file pointer                         */
 
214
           int  colnum,    /* I - number of the column to read (1 = 1st)    */
 
215
           int naxis,      /* I - number of dimensions in the FITS array    */
 
216
           long  *naxes,   /* I - size of each dimension                    */
 
217
           long  *blc,     /* I - 'bottom left corner' of the subsection    */
 
218
           long  *trc,     /* I - 'top right corner' of the subsection      */
 
219
           long  *inc,     /* I - increment to be applied in each dimension */
 
220
  unsigned short nulval,   /* I - value to set undefined pixels             */
 
221
  unsigned short *array,   /* O - array to be filled and returned           */
 
222
           int  *anynul,   /* O - set to 1 if any values are null; else 0   */
 
223
           int  *status)   /* IO - error status                             */
 
224
/*
 
225
  Read a subsection of data values from an image or a table column.
 
226
  This routine is set up to handle a maximum of nine dimensions.
 
227
*/
 
228
{
 
229
    long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc;
 
230
    long str[9],stp[9],incr[9];
 
231
    long nelem, nultyp, ninc, numcol;
 
232
    LONGLONG felem, dsize[10], blcll[9], trcll[9];
 
233
    int hdutype, anyf;
 
234
    char ldummy, msg[FLEN_ERRMSG];
 
235
    int nullcheck = 1;
 
236
    unsigned short nullvalue;
 
237
 
 
238
    if (naxis < 1 || naxis > 9)
 
239
    {
 
240
        sprintf(msg, "NAXIS = %d in call to ffgsvui is out of range", naxis);
 
241
        ffpmsg(msg);
 
242
        return(*status = BAD_DIMEN);
 
243
    }
 
244
 
 
245
    if (fits_is_compressed_image(fptr, status))
 
246
    {
 
247
        /* this is a compressed image in a binary table */
 
248
 
 
249
        for (ii=0; ii < naxis; ii++) {
 
250
            blcll[ii] = blc[ii];
 
251
            trcll[ii] = trc[ii];
 
252
        }
 
253
 
 
254
        nullvalue = nulval;  /* set local variable */
 
255
 
 
256
        fits_read_compressed_img(fptr, TUSHORT, blcll, trcll, inc,
 
257
            nullcheck, &nullvalue, array, NULL, anynul, status);
 
258
        return(*status);
 
259
    }
 
260
 
 
261
/*
 
262
    if this is a primary array, then the input COLNUM parameter should
 
263
    be interpreted as the row number, and we will alway read the image
 
264
    data from column 2 (any group parameters are in column 1).
 
265
*/
 
266
    if (ffghdt(fptr, &hdutype, status) > 0)
 
267
        return(*status);
 
268
 
 
269
    if (hdutype == IMAGE_HDU)
 
270
    {
 
271
        /* this is a primary array, or image extension */
 
272
        if (colnum == 0)
 
273
        {
 
274
            rstr = 1;
 
275
            rstp = 1;
 
276
        }
 
277
        else
 
278
        {
 
279
            rstr = colnum;
 
280
            rstp = colnum;
 
281
        }
 
282
        rinc = 1;
 
283
        numcol = 2;
 
284
    }
 
285
    else
 
286
    {
 
287
        /* this is a table, so the row info is in the (naxis+1) elements */
 
288
        rstr = blc[naxis];
 
289
        rstp = trc[naxis];
 
290
        rinc = inc[naxis];
 
291
        numcol = colnum;
 
292
    }
 
293
 
 
294
    nultyp = 1;
 
295
    if (anynul)
 
296
        *anynul = FALSE;
 
297
 
 
298
    i0 = 0;
 
299
    for (ii = 0; ii < 9; ii++)
 
300
    {
 
301
        str[ii] = 1;
 
302
        stp[ii] = 1;
 
303
        incr[ii] = 1;
 
304
        dsize[ii] = 1;
 
305
    }
 
306
 
 
307
    for (ii = 0; ii < naxis; ii++)
 
308
    {
 
309
      if (trc[ii] < blc[ii])
 
310
      {
 
311
        sprintf(msg, "ffgsvui: illegal range specified for axis %ld", ii + 1);
 
312
        ffpmsg(msg);
 
313
        return(*status = BAD_PIX_NUM);
 
314
      }
 
315
 
 
316
      str[ii] = blc[ii];
 
317
      stp[ii] = trc[ii];
 
318
      incr[ii] = inc[ii];
 
319
      dsize[ii + 1] = dsize[ii] * naxes[ii];
 
320
    }
 
321
 
 
322
    if (naxis == 1 && naxes[0] == 1)
 
323
    {
 
324
      /* This is not a vector column, so read all the rows at once */
 
325
      nelem = (rstp - rstr) / rinc + 1;
 
326
      ninc = rinc;
 
327
      rstp = rstr;
 
328
    }
 
329
    else
 
330
    {
 
331
      /* have to read each row individually, in all dimensions */
 
332
      nelem = (stp[0] - str[0]) / inc[0] + 1;
 
333
      ninc = incr[0];
 
334
    }
 
335
 
 
336
    for (row = rstr; row <= rstp; row += rinc)
 
337
    {
 
338
     for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8])
 
339
     {
 
340
      for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7])
 
341
      {
 
342
       for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6])
 
343
       {
 
344
        for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5])
 
345
        {
 
346
         for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4])
 
347
         {
 
348
          for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3])
 
349
          {
 
350
           for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2])
 
351
           {
 
352
            for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1])
 
353
            {
 
354
              felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + 
 
355
                             (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] +
 
356
                             (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] +
 
357
                             (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8];
 
358
              if ( ffgclui(fptr, numcol, row, felem, nelem, ninc, nultyp,
 
359
                   nulval, &array[i0], &ldummy, &anyf, status) > 0)
 
360
                   return(*status);
 
361
 
 
362
              if (anyf && anynul)
 
363
                  *anynul = TRUE;
 
364
 
 
365
              i0 += nelem;
 
366
            }
 
367
           }
 
368
          }
 
369
         }
 
370
        }
 
371
       }
 
372
      }
 
373
     }
 
374
    }
 
375
    return(*status);
 
376
}
 
377
/*--------------------------------------------------------------------------*/
 
378
int ffgsfui(fitsfile *fptr, /* I - FITS file pointer                         */
 
379
           int  colnum,    /* I - number of the column to read (1 = 1st)    */
 
380
           int naxis,      /* I - number of dimensions in the FITS array    */
 
381
           long  *naxes,   /* I - size of each dimension                    */
 
382
           long  *blc,     /* I - 'bottom left corner' of the subsection    */
 
383
           long  *trc,     /* I - 'top right corner' of the subsection      */
 
384
           long  *inc,     /* I - increment to be applied in each dimension */
 
385
  unsigned short *array,   /* O - array to be filled and returned           */
 
386
           char *flagval,  /* O - set to 1 if corresponding value is null   */
 
387
           int  *anynul,   /* O - set to 1 if any values are null; else 0   */
 
388
           int  *status)   /* IO - error status                             */
 
389
/*
 
390
  Read a subsection of data values from an image or a table column.
 
391
  This routine is set up to handle a maximum of nine dimensions.
 
392
*/
 
393
{
 
394
    long ii,i0, i1,i2,i3,i4,i5,i6,i7,i8,row,rstr,rstp,rinc;
 
395
    long str[9],stp[9],incr[9],dsize[10];
 
396
    LONGLONG blcll[9], trcll[9];
 
397
    long felem, nelem, nultyp, ninc, numcol;
 
398
    int hdutype, anyf;
 
399
    unsigned short nulval = 0;
 
400
    char msg[FLEN_ERRMSG];
 
401
    int nullcheck = 2;
 
402
 
 
403
    if (naxis < 1 || naxis > 9)
 
404
    {
 
405
        sprintf(msg, "NAXIS = %d in call to ffgsvi is out of range", naxis);
 
406
        ffpmsg(msg);
 
407
        return(*status = BAD_DIMEN);
 
408
    }
 
409
 
 
410
    if (fits_is_compressed_image(fptr, status))
 
411
    {
 
412
        /* this is a compressed image in a binary table */
 
413
 
 
414
        for (ii=0; ii < naxis; ii++) {
 
415
            blcll[ii] = blc[ii];
 
416
            trcll[ii] = trc[ii];
 
417
        }
 
418
 
 
419
        fits_read_compressed_img(fptr, TUSHORT, blcll, trcll, inc,
 
420
            nullcheck, NULL, array, flagval, anynul, status);
 
421
        return(*status);
 
422
    }
 
423
 
 
424
/*
 
425
    if this is a primary array, then the input COLNUM parameter should
 
426
    be interpreted as the row number, and we will alway read the image
 
427
    data from column 2 (any group parameters are in column 1).
 
428
*/
 
429
    if (ffghdt(fptr, &hdutype, status) > 0)
 
430
        return(*status);
 
431
 
 
432
    if (hdutype == IMAGE_HDU)
 
433
    {
 
434
        /* this is a primary array, or image extension */
 
435
        if (colnum == 0)
 
436
        {
 
437
            rstr = 1;
 
438
            rstp = 1;
 
439
        }
 
440
        else
 
441
        {
 
442
            rstr = colnum;
 
443
            rstp = colnum;
 
444
        }
 
445
        rinc = 1;
 
446
        numcol = 2;
 
447
    }
 
448
    else
 
449
    {
 
450
        /* this is a table, so the row info is in the (naxis+1) elements */
 
451
        rstr = blc[naxis];
 
452
        rstp = trc[naxis];
 
453
        rinc = inc[naxis];
 
454
        numcol = colnum;
 
455
    }
 
456
 
 
457
    nultyp = 2;
 
458
    if (anynul)
 
459
        *anynul = FALSE;
 
460
 
 
461
    i0 = 0;
 
462
    for (ii = 0; ii < 9; ii++)
 
463
    {
 
464
        str[ii] = 1;
 
465
        stp[ii] = 1;
 
466
        incr[ii] = 1;
 
467
        dsize[ii] = 1;
 
468
    }
 
469
 
 
470
    for (ii = 0; ii < naxis; ii++)
 
471
    {
 
472
      if (trc[ii] < blc[ii])
 
473
      {
 
474
        sprintf(msg, "ffgsvi: illegal range specified for axis %ld", ii + 1);
 
475
        ffpmsg(msg);
 
476
        return(*status = BAD_PIX_NUM);
 
477
      }
 
478
 
 
479
      str[ii] = blc[ii];
 
480
      stp[ii] = trc[ii];
 
481
      incr[ii] = inc[ii];
 
482
      dsize[ii + 1] = dsize[ii] * naxes[ii];
 
483
    }
 
484
 
 
485
    if (naxis == 1 && naxes[0] == 1)
 
486
    {
 
487
      /* This is not a vector column, so read all the rows at once */
 
488
      nelem = (rstp - rstr) / rinc + 1;
 
489
      ninc = rinc;
 
490
      rstp = rstr;
 
491
    }
 
492
    else
 
493
    {
 
494
      /* have to read each row individually, in all dimensions */
 
495
      nelem = (stp[0] - str[0]) / inc[0] + 1;
 
496
      ninc = incr[0];
 
497
    }
 
498
 
 
499
    for (row = rstr; row <= rstp; row += rinc)
 
500
    {
 
501
     for (i8 = str[8]; i8 <= stp[8]; i8 += incr[8])
 
502
     {
 
503
      for (i7 = str[7]; i7 <= stp[7]; i7 += incr[7])
 
504
      {
 
505
       for (i6 = str[6]; i6 <= stp[6]; i6 += incr[6])
 
506
       {
 
507
        for (i5 = str[5]; i5 <= stp[5]; i5 += incr[5])
 
508
        {
 
509
         for (i4 = str[4]; i4 <= stp[4]; i4 += incr[4])
 
510
         {
 
511
          for (i3 = str[3]; i3 <= stp[3]; i3 += incr[3])
 
512
          {
 
513
           for (i2 = str[2]; i2 <= stp[2]; i2 += incr[2])
 
514
           {
 
515
            for (i1 = str[1]; i1 <= stp[1]; i1 += incr[1])
 
516
            {
 
517
              felem=str[0] + (i1 - 1) * dsize[1] + (i2 - 1) * dsize[2] + 
 
518
                             (i3 - 1) * dsize[3] + (i4 - 1) * dsize[4] +
 
519
                             (i5 - 1) * dsize[5] + (i6 - 1) * dsize[6] +
 
520
                             (i7 - 1) * dsize[7] + (i8 - 1) * dsize[8];
 
521
 
 
522
              if ( ffgclui(fptr, numcol, row, felem, nelem, ninc, nultyp,
 
523
                   nulval, &array[i0], &flagval[i0], &anyf, status) > 0)
 
524
                   return(*status);
 
525
 
 
526
              if (anyf && anynul)
 
527
                  *anynul = TRUE;
 
528
 
 
529
              i0 += nelem;
 
530
            }
 
531
           }
 
532
          }
 
533
         }
 
534
        }
 
535
       }
 
536
      }
 
537
     }
 
538
    }
 
539
    return(*status);
 
540
}
 
541
/*--------------------------------------------------------------------------*/
 
542
int ffggpui( fitsfile *fptr,   /* I - FITS file pointer                       */
 
543
            long  group,      /* I - group to read (1 = 1st group)           */
 
544
            long  firstelem,  /* I - first vector element to read (1 = 1st)  */
 
545
            long  nelem,      /* I - number of values to read                */
 
546
   unsigned short *array,     /* O - array of values that are returned       */
 
547
            int  *status)     /* IO - error status                           */
 
548
/*
 
549
  Read an array of group parameters from the primary array. Data conversion
 
550
  and scaling will be performed if necessary (e.g, if the datatype of
 
551
  the FITS array is not the same as the array being read).
 
552
*/
 
553
{
 
554
    long row;
 
555
    int idummy;
 
556
    char cdummy;
 
557
    /*
 
558
      the primary array is represented as a binary table:
 
559
      each group of the primary array is a row in the table,
 
560
      where the first column contains the group parameters
 
561
      and the second column contains the image itself.
 
562
    */
 
563
 
 
564
    row=maxvalue(1,group);
 
565
 
 
566
    ffgclui(fptr, 1, row, firstelem, nelem, 1, 1, 0,
 
567
               array, &cdummy, &idummy, status);
 
568
    return(*status);
 
569
}
 
570
/*--------------------------------------------------------------------------*/
 
571
int ffgcvui(fitsfile *fptr,   /* I - FITS file pointer                       */
 
572
           int  colnum,      /* I - number of column to read (1 = 1st col)  */
 
573
           LONGLONG  firstrow,   /* I - first row to read (1 = 1st row)         */
 
574
           LONGLONG  firstelem,  /* I - first vector element to read (1 = 1st)  */
 
575
           LONGLONG  nelem,      /* I - number of values to read                */
 
576
  unsigned short nulval,     /* I - value for null pixels                   */
 
577
  unsigned short *array,     /* O - array of values that are read           */
 
578
           int  *anynul,     /* O - set to 1 if any values are null; else 0 */
 
579
           int  *status)     /* IO - error status                           */
 
580
/*
 
581
  Read an array of values from a column in the current FITS HDU. Automatic
 
582
  datatype conversion will be performed if the datatype of the column does not
 
583
  match the datatype of the array parameter. The output values will be scaled 
 
584
  by the FITS TSCALn and TZEROn values if these values have been defined.
 
585
  Any undefined pixels will be set equal to the value of 'nulval' unless
 
586
  nulval = 0 in which case no checks for undefined pixels will be made.
 
587
*/
 
588
{
 
589
    char cdummy;
 
590
 
 
591
    ffgclui(fptr, colnum, firstrow, firstelem, nelem, 1, 1, nulval,
 
592
           array, &cdummy, anynul, status);
 
593
    return(*status);
 
594
}
 
595
/*--------------------------------------------------------------------------*/
 
596
int ffgcfui(fitsfile *fptr,   /* I - FITS file pointer                       */
 
597
           int  colnum,      /* I - number of column to read (1 = 1st col)  */
 
598
           LONGLONG  firstrow,   /* I - first row to read (1 = 1st row)         */
 
599
           LONGLONG  firstelem,  /* I - first vector element to read (1 = 1st)  */
 
600
           LONGLONG  nelem,      /* I - number of values to read                */
 
601
  unsigned short *array,     /* O - array of values that are read           */
 
602
           char *nularray,   /* O - array of flags: 1 if null pixel; else 0 */
 
603
           int  *anynul,     /* O - set to 1 if any values are null; else 0 */
 
604
           int  *status)     /* IO - error status                           */
 
605
/*
 
606
  Read an array of values from a column in the current FITS HDU. Automatic
 
607
  datatype conversion will be performed if the datatype of the column does not
 
608
  match the datatype of the array parameter. The output values will be scaled 
 
609
  by the FITS TSCALn and TZEROn values if these values have been defined.
 
610
  Nularray will be set = 1 if the corresponding array pixel is undefined, 
 
611
  otherwise nularray will = 0.
 
612
*/
 
613
{
 
614
    unsigned short dummy = 0;
 
615
 
 
616
    ffgclui(fptr, colnum, firstrow, firstelem, nelem, 1, 2, dummy,
 
617
           array, nularray, anynul, status);
 
618
    return(*status);
 
619
}
 
620
/*--------------------------------------------------------------------------*/
 
621
int ffgclui( fitsfile *fptr,   /* I - FITS file pointer                       */
 
622
            int  colnum,      /* I - number of column to read (1 = 1st col)  */
 
623
            LONGLONG  firstrow,   /* I - first row to read (1 = 1st row)         */
 
624
            LONGLONG firstelem,  /* I - first vector element to read (1 = 1st)  */
 
625
            LONGLONG  nelem,      /* I - number of values to read                */
 
626
            long  elemincre,  /* I - pixel increment; e.g., 2 = every other  */
 
627
            int   nultyp,     /* I - null value handling code:               */
 
628
                              /*     1: set undefined pixels = nulval        */
 
629
                              /*     2: set nularray=1 for undefined pixels  */
 
630
   unsigned short nulval,     /* I - value for null pixels if nultyp = 1     */
 
631
   unsigned short *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 values from a column in the current FITS HDU.
 
637
  The column number may refer to a real column in an ASCII or binary table, 
 
638
  or it may refer be a virtual column in a 1 or more grouped FITS primary
 
639
  array or image extension.  FITSIO treats a primary array as a binary table
 
640
  with 2 vector columns: the first column contains the group parameters (often
 
641
  with length = 0) and the second column contains the array of image pixels.
 
642
  Each row of the table represents a group in the case of multigroup FITS
 
643
  images.
 
644
 
 
645
  The output array of values will be converted from the datatype of the column 
 
646
  and will be scaled by the FITS TSCALn and TZEROn values if necessary.
 
647
*/
 
648
{
 
649
    double scale, zero, power = 1., dtemp;
 
650
    int tcode, maxelem2, hdutype, xcode, decimals;
 
651
    long twidth, incre;
 
652
    long ii, xwidth, ntodo;
 
653
    int nulcheck;
 
654
    LONGLONG repeat, startpos, elemnum, readptr, tnull;
 
655
    LONGLONG rowlen, rownum, remain, next, rowincre, maxelem;
 
656
    char tform[20];
 
657
    char message[81];
 
658
    char snull[20];   /*  the FITS null value if reading from ASCII table  */
 
659
 
 
660
    double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */
 
661
    void *buffer;
 
662
 
 
663
    if (*status > 0 || nelem == 0)  /* inherit input status value if > 0 */
 
664
        return(*status);
 
665
 
 
666
    buffer = cbuff;
 
667
 
 
668
    if (anynul)
 
669
        *anynul = 0;
 
670
 
 
671
    if (nultyp == 2)
 
672
        memset(nularray, 0, (size_t) nelem);   /* initialize nullarray */
 
673
 
 
674
    /*---------------------------------------------------*/
 
675
    /*  Check input and get parameters about the column: */
 
676
    /*---------------------------------------------------*/
 
677
    if ( ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 0, &scale, &zero,
 
678
         tform, &twidth, &tcode, &maxelem2, &startpos, &elemnum, &incre,
 
679
         &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0 )
 
680
         return(*status);
 
681
    maxelem = maxelem2;
 
682
 
 
683
    incre *= elemincre;   /* multiply incre to just get every nth pixel */
 
684
 
 
685
    if (tcode == TSTRING)    /* setup for ASCII tables */
 
686
    {
 
687
      /* get the number of implied decimal places if no explicit decmal point */
 
688
      ffasfm(tform, &xcode, &xwidth, &decimals, status); 
 
689
      for(ii = 0; ii < decimals; ii++)
 
690
        power *= 10.;
 
691
    }
 
692
    /*------------------------------------------------------------------*/
 
693
    /*  Decide whether to check for null values in the input FITS file: */
 
694
    /*------------------------------------------------------------------*/
 
695
    nulcheck = nultyp; /* by default check for null values in the FITS file */
 
696
 
 
697
    if (nultyp == 1 && nulval == 0)
 
698
       nulcheck = 0;    /* calling routine does not want to check for nulls */
 
699
 
 
700
    else if (tcode%10 == 1 &&        /* if reading an integer column, and  */ 
 
701
            tnull == NULL_UNDEFINED) /* if a null value is not defined,    */
 
702
            nulcheck = 0;            /* then do not check for null values. */
 
703
 
 
704
    else if (tcode == TSHORT && (tnull > SHRT_MAX || tnull < SHRT_MIN) )
 
705
            nulcheck = 0;            /* Impossible null value */
 
706
 
 
707
    else if (tcode == TBYTE && (tnull > 255 || tnull < 0) )
 
708
            nulcheck = 0;            /* Impossible null value */
 
709
 
 
710
    else if (tcode == TSTRING && snull[0] == ASCII_NULL_UNDEFINED)
 
711
         nulcheck = 0;
 
712
 
 
713
    /*----------------------------------------------------------------------*/
 
714
    /*  If FITS column and output data array have same datatype, then we do */
 
715
    /*  not need to use a temporary buffer to store intermediate datatype.  */
 
716
    /*----------------------------------------------------------------------*/
 
717
    if (tcode == TSHORT) /* Special Case:                        */
 
718
    {                             /* no type convertion required, so read */
 
719
        maxelem = nelem;          /* data directly into output buffer.    */
 
720
    }
 
721
 
 
722
    /*---------------------------------------------------------------------*/
 
723
    /*  Now read the pixels from the FITS column. If the column does not   */
 
724
    /*  have the same datatype as the output array, then we have to read   */
 
725
    /*  the raw values into a temporary buffer (of limited size).  In      */
 
726
    /*  the case of a vector colum read only 1 vector of values at a time  */
 
727
    /*  then skip to the next row if more values need to be read.          */
 
728
    /*  After reading the raw values, then call the fffXXYY routine to (1) */
 
729
    /*  test for undefined values, (2) convert the datatype if necessary,  */
 
730
    /*  and (3) scale the values by the FITS TSCALn and TZEROn linear      */
 
731
    /*  scaling parameters.                                                */
 
732
    /*---------------------------------------------------------------------*/
 
733
    remain = nelem;           /* remaining number of values to read */
 
734
    next = 0;                 /* next element in array to be read   */
 
735
    rownum = 0;               /* row number, relative to firstrow   */
 
736
 
 
737
    while (remain)
 
738
    {
 
739
        /* limit the number of pixels to read at one time to the number that
 
740
           will fit in the buffer or to the number of pixels that remain in
 
741
           the current vector, which ever is smaller.
 
742
        */
 
743
        ntodo = (long) minvalue(remain, maxelem);      
 
744
        ntodo = (long) minvalue(ntodo, ((repeat - elemnum - 1)/elemincre +1));
 
745
 
 
746
        readptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * (incre / elemincre));
 
747
 
 
748
        switch (tcode) 
 
749
        {
 
750
            case (TSHORT):
 
751
                ffgi2b(fptr, readptr, ntodo, incre,
 
752
                       (short *) &array[next], status);
 
753
                fffi2u2((short *) &array[next], ntodo, scale,
 
754
                       zero, nulcheck, (short) tnull, nulval, &nularray[next],
 
755
                       anynul, &array[next], status);
 
756
                break;
 
757
            case (TLONGLONG):
 
758
 
 
759
                ffgi8b(fptr, readptr, ntodo, incre, (long *) buffer, status);
 
760
                fffi8u2( (LONGLONG *) buffer, ntodo, scale, zero, 
 
761
                           nulcheck, tnull, nulval, &nularray[next], 
 
762
                            anynul, &array[next], status);
 
763
                break;
 
764
            case (TBYTE):
 
765
                ffgi1b(fptr, readptr, ntodo, incre, (unsigned char *) buffer,
 
766
                      status);
 
767
                fffi1u2((unsigned char *) buffer, ntodo, scale, zero, nulcheck, 
 
768
                    (unsigned char) tnull, nulval, &nularray[next], anynul, 
 
769
                    &array[next], status);
 
770
                break;
 
771
            case (TLONG):
 
772
                ffgi4b(fptr, readptr, ntodo, incre, (INT32BIT *) buffer,
 
773
                       status);
 
774
                fffi4u2((INT32BIT *) buffer, ntodo, scale, zero, nulcheck, 
 
775
                       (INT32BIT) tnull, nulval, &nularray[next], anynul, 
 
776
                       &array[next], status);
 
777
                break;
 
778
            case (TFLOAT):
 
779
                ffgr4b(fptr, readptr, ntodo, incre, (float  *) buffer, status);
 
780
                fffr4u2((float  *) buffer, ntodo, scale, zero, nulcheck, 
 
781
                       nulval, &nularray[next], anynul, 
 
782
                       &array[next], status);
 
783
                break;
 
784
            case (TDOUBLE):
 
785
                ffgr8b(fptr, readptr, ntodo, incre, (double *) buffer, status);
 
786
                fffr8u2((double *) buffer, ntodo, scale, zero, nulcheck, 
 
787
                          nulval, &nularray[next], anynul, 
 
788
                          &array[next], status);
 
789
                break;
 
790
            case (TSTRING):
 
791
                ffmbyt(fptr, readptr, REPORT_EOF, status);
 
792
       
 
793
                if (incre == twidth)    /* contiguous bytes */
 
794
                     ffgbyt(fptr, ntodo * twidth, buffer, status);
 
795
                else
 
796
                     ffgbytoff(fptr, twidth, ntodo, incre - twidth, buffer,
 
797
                               status);
 
798
 
 
799
                fffstru2((char *) buffer, ntodo, scale, zero, twidth, power,
 
800
                     nulcheck, snull, nulval, &nularray[next], anynul,
 
801
                     &array[next], status);
 
802
                break;
 
803
 
 
804
            default:  /*  error trap for invalid column format */
 
805
                sprintf(message, 
 
806
                   "Cannot read numbers from column %d which has format %s",
 
807
                    colnum, tform);
 
808
                ffpmsg(message);
 
809
                if (hdutype == ASCII_TBL)
 
810
                    return(*status = BAD_ATABLE_FORMAT);
 
811
                else
 
812
                    return(*status = BAD_BTABLE_FORMAT);
 
813
 
 
814
        } /* End of switch block */
 
815
 
 
816
        /*-------------------------*/
 
817
        /*  Check for fatal error  */
 
818
        /*-------------------------*/
 
819
        if (*status > 0)  /* test for error during previous read operation */
 
820
        {
 
821
          dtemp = (double) next;
 
822
          if (hdutype > 0)
 
823
            sprintf(message,
 
824
            "Error reading elements %.0f thru %.0f from column %d (ffgclui).",
 
825
              dtemp+1., dtemp+ntodo, colnum);
 
826
          else
 
827
            sprintf(message,
 
828
            "Error reading elements %.0f thru %.0f from image (ffgclui).",
 
829
              dtemp+1., dtemp+ntodo);
 
830
 
 
831
          ffpmsg(message);
 
832
          return(*status);
 
833
        }
 
834
 
 
835
        /*--------------------------------------------*/
 
836
        /*  increment the counters for the next loop  */
 
837
        /*--------------------------------------------*/
 
838
        remain -= ntodo;
 
839
        if (remain)
 
840
        {
 
841
            next += ntodo;
 
842
            elemnum = elemnum + (ntodo * elemincre);
 
843
 
 
844
            if (elemnum >= repeat)  /* completed a row; start on later row */
 
845
            {
 
846
                rowincre = elemnum / repeat;
 
847
                rownum += rowincre;
 
848
                elemnum = elemnum - (rowincre * repeat);
 
849
            }
 
850
        }
 
851
    }  /*  End of main while Loop  */
 
852
 
 
853
 
 
854
    /*--------------------------------*/
 
855
    /*  check for numerical overflow  */
 
856
    /*--------------------------------*/
 
857
    if (*status == OVERFLOW_ERR)
 
858
    {
 
859
        ffpmsg(
 
860
        "Numerical overflow during type conversion while reading FITS data.");
 
861
        *status = NUM_OVERFLOW;
 
862
    }
 
863
 
 
864
    return(*status);
 
865
}
 
866
/*--------------------------------------------------------------------------*/
 
867
int fffi1u2(unsigned char *input, /* I - array of values to be converted     */
 
868
            long ntodo,           /* I - number of elements in the array     */
 
869
            double scale,         /* I - FITS TSCALn or BSCALE value         */
 
870
            double zero,          /* I - FITS TZEROn or BZERO  value         */
 
871
            int nullcheck,        /* I - null checking code; 0 = don't check */
 
872
                                  /*     1:set null pixels = nullval         */
 
873
                                  /*     2: if null pixel, set nullarray = 1 */
 
874
            unsigned char tnull,  /* I - value of FITS TNULLn keyword if any */
 
875
   unsigned short nullval,        /* I - set null pixels, if nullcheck = 1   */
 
876
            char *nullarray,      /* I - bad pixel array, if nullcheck = 2   */
 
877
            int  *anynull,        /* O - set to 1 if any pixels are null     */
 
878
   unsigned short *output,        /* O - array of converted pixels           */
 
879
            int *status)          /* IO - error status                       */
 
880
/*
 
881
  Copy input to output following reading of the input from a FITS file.
 
882
  Check for null values and do datatype conversion and scaling if required.
 
883
  The nullcheck code value determines how any null values in the input array
 
884
  are treated.  A null value is an input pixel that is equal to tnull.  If 
 
885
  nullcheck = 0, then no checking for nulls is performed and any null values
 
886
  will be transformed just like any other pixel.  If nullcheck = 1, then the
 
887
  output pixel will be set = nullval if the corresponding input pixel is null.
 
888
  If nullcheck = 2, then if the pixel is null then the corresponding value of
 
889
  nullarray will be set to 1; the value of nullarray for non-null pixels 
 
890
  will = 0.  The anynull parameter will be set = 1 if any of the returned
 
891
  pixels are null, otherwise anynull will be returned with a value = 0;
 
892
*/
 
893
{
 
894
    long ii;
 
895
    double dvalue;
 
896
 
 
897
    if (nullcheck == 0)     /* no null checking required */
 
898
    {
 
899
        if (scale == 1. && zero == 0.)      /* no scaling */
 
900
        {       
 
901
            for (ii = 0; ii < ntodo; ii++)
 
902
                output[ii] = (unsigned short) input[ii]; /* copy input */
 
903
        }
 
904
        else             /* must scale the data */
 
905
        {
 
906
            for (ii = 0; ii < ntodo; ii++)
 
907
            {
 
908
                dvalue = input[ii] * scale + zero;
 
909
 
 
910
                if (dvalue < DUSHRT_MIN)
 
911
                {
 
912
                    *status = OVERFLOW_ERR;
 
913
                    output[ii] = 0;
 
914
                }
 
915
                else if (dvalue > DUSHRT_MAX)
 
916
                {
 
917
                    *status = OVERFLOW_ERR;
 
918
                    output[ii] = USHRT_MAX;
 
919
                }
 
920
                else
 
921
                    output[ii] = (unsigned short) dvalue;
 
922
            }
 
923
        }
 
924
    }
 
925
    else        /* must check for null values */
 
926
    {
 
927
        if (scale == 1. && zero == 0.)  /* no scaling */
 
928
        {       
 
929
            for (ii = 0; ii < ntodo; ii++)
 
930
            {
 
931
                if (input[ii] == tnull)
 
932
                {
 
933
                    *anynull = 1;
 
934
                    if (nullcheck == 1)
 
935
                        output[ii] = nullval;
 
936
                    else
 
937
                        nullarray[ii] = 1;
 
938
                }
 
939
                else
 
940
                    output[ii] = (unsigned short) input[ii];
 
941
            }
 
942
        }
 
943
        else                  /* must scale the data */
 
944
        {
 
945
            for (ii = 0; ii < ntodo; ii++)
 
946
            {
 
947
                if (input[ii] == tnull)
 
948
                {
 
949
                    *anynull = 1;
 
950
                    if (nullcheck == 1)
 
951
                        output[ii] = nullval;
 
952
                    else
 
953
                        nullarray[ii] = 1;
 
954
                }
 
955
                else
 
956
                {
 
957
                    dvalue = input[ii] * scale + zero;
 
958
 
 
959
                    if (dvalue < DUSHRT_MIN)
 
960
                    {
 
961
                        *status = OVERFLOW_ERR;
 
962
                        output[ii] = 0;
 
963
                    }
 
964
                    else if (dvalue > DUSHRT_MAX)
 
965
                    {
 
966
                        *status = OVERFLOW_ERR;
 
967
                        output[ii] = USHRT_MAX;
 
968
                    }
 
969
                    else
 
970
                        output[ii] = (unsigned short) dvalue;
 
971
                }
 
972
            }
 
973
        }
 
974
    }
 
975
    return(*status);
 
976
}
 
977
/*--------------------------------------------------------------------------*/
 
978
int fffi2u2(short *input,         /* I - array of values to be converted     */
 
979
            long ntodo,           /* I - number of elements in the array     */
 
980
            double scale,         /* I - FITS TSCALn or BSCALE value         */
 
981
            double zero,          /* I - FITS TZEROn or BZERO  value         */
 
982
            int nullcheck,        /* I - null checking code; 0 = don't check */
 
983
                                  /*     1:set null pixels = nullval         */
 
984
                                  /*     2: if null pixel, set nullarray = 1 */
 
985
            short tnull,          /* I - value of FITS TNULLn keyword if any */
 
986
   unsigned short nullval,        /* I - set null pixels, if nullcheck = 1   */
 
987
            char *nullarray,      /* I - bad pixel array, if nullcheck = 2   */
 
988
            int  *anynull,        /* O - set to 1 if any pixels are null     */
 
989
   unsigned short *output,        /* O - array of converted pixels           */
 
990
            int *status)          /* IO - error status                       */
 
991
/*
 
992
  Copy input to output following reading of the input from a FITS file.
 
993
  Check for null values and do datatype conversion and scaling if required.
 
994
  The nullcheck code value determines how any null values in the input array
 
995
  are treated.  A null value is an input pixel that is equal to tnull.  If 
 
996
  nullcheck = 0, then no checking for nulls is performed and any null values
 
997
  will be transformed just like any other pixel.  If nullcheck = 1, then the
 
998
  output pixel will be set = nullval if the corresponding input pixel is null.
 
999
  If nullcheck = 2, then if the pixel is null then the corresponding value of
 
1000
  nullarray will be set to 1; the value of nullarray for non-null pixels 
 
1001
  will = 0.  The anynull parameter will be set = 1 if any of the returned
 
1002
  pixels are null, otherwise anynull will be returned with a value = 0;
 
1003
*/
 
1004
{
 
1005
    long ii;
 
1006
    double dvalue;
 
1007
 
 
1008
    if (nullcheck == 0)     /* no null checking required */
 
1009
    {
 
1010
        if (scale == 1. && zero == 32768.) 
 
1011
        {       
 
1012
           /* Instead of adding 32768, it is more efficient */
 
1013
           /* to just flip the sign bit with the XOR operator */
 
1014
 
 
1015
           for (ii = 0; ii < ntodo; ii++)
 
1016
              output[ii] =  ( *(unsigned short *) &input[ii] ) ^ 0x8000;
 
1017
        }
 
1018
        else if (scale == 1. && zero == 0.)      /* no scaling */
 
1019
        {       
 
1020
            for (ii = 0; ii < ntodo; ii++)
 
1021
            {
 
1022
                if (input[ii] < 0)
 
1023
                {
 
1024
                    *status = OVERFLOW_ERR;
 
1025
                    output[ii] = 0;
 
1026
                }
 
1027
                else
 
1028
                    output[ii] = (unsigned short) input[ii]; /* copy input */
 
1029
            }
 
1030
        }
 
1031
        else             /* must scale the data */
 
1032
        {
 
1033
            for (ii = 0; ii < ntodo; ii++)
 
1034
            {
 
1035
                dvalue = input[ii] * scale + zero;
 
1036
 
 
1037
                if (dvalue < DUSHRT_MIN)
 
1038
                {
 
1039
                    *status = OVERFLOW_ERR;
 
1040
                    output[ii] = 0;
 
1041
                }
 
1042
                else if (dvalue > DUSHRT_MAX)
 
1043
                {
 
1044
                    *status = OVERFLOW_ERR;
 
1045
                    output[ii] = USHRT_MAX;
 
1046
                }
 
1047
                else
 
1048
                    output[ii] = (unsigned short) dvalue;
 
1049
            }
 
1050
        }
 
1051
    }
 
1052
    else        /* must check for null values */
 
1053
    {
 
1054
        if (scale == 1. && zero == 32768.)  /* no scaling */
 
1055
        {       
 
1056
            for (ii = 0; ii < ntodo; ii++)
 
1057
            {
 
1058
                if (input[ii] == tnull)
 
1059
                {
 
1060
                    *anynull = 1;
 
1061
                    if (nullcheck == 1)
 
1062
                        output[ii] = nullval;
 
1063
                    else
 
1064
                        nullarray[ii] = 1;
 
1065
                }
 
1066
                else
 
1067
                    output[ii] =  ( *(unsigned short *) &input[ii] ) ^ 0x8000;
 
1068
            }
 
1069
        }
 
1070
        else if (scale == 1. && zero == 0.)  /* no scaling */
 
1071
        {       
 
1072
            for (ii = 0; ii < ntodo; ii++)
 
1073
            {
 
1074
                if (input[ii] == tnull)
 
1075
                {
 
1076
                    *anynull = 1;
 
1077
                    if (nullcheck == 1)
 
1078
                        output[ii] = nullval;
 
1079
                    else
 
1080
                        nullarray[ii] = 1;
 
1081
                }
 
1082
                else if (input[ii] < 0)
 
1083
                {
 
1084
                    *status = OVERFLOW_ERR;
 
1085
                    output[ii] = 0;
 
1086
                }
 
1087
                else
 
1088
                    output[ii] = (unsigned short) input[ii]; /* copy input */
 
1089
            }
 
1090
        }
 
1091
        else                  /* must scale the data */
 
1092
        {
 
1093
            for (ii = 0; ii < ntodo; ii++)
 
1094
            {
 
1095
                if (input[ii] == tnull)
 
1096
                {
 
1097
                    *anynull = 1;
 
1098
                    if (nullcheck == 1)
 
1099
                        output[ii] = nullval;
 
1100
                    else
 
1101
                        nullarray[ii] = 1;
 
1102
                }
 
1103
                else
 
1104
                {
 
1105
                    dvalue = input[ii] * scale + zero;
 
1106
 
 
1107
                    if (dvalue < DUSHRT_MIN)
 
1108
                    {
 
1109
                        *status = OVERFLOW_ERR;
 
1110
                        output[ii] = 0;
 
1111
                    }
 
1112
                    else if (dvalue > DUSHRT_MAX)
 
1113
                    {
 
1114
                        *status = OVERFLOW_ERR;
 
1115
                        output[ii] = USHRT_MAX;
 
1116
                    }
 
1117
                    else
 
1118
                        output[ii] = (unsigned short) dvalue;
 
1119
                }
 
1120
            }
 
1121
        }
 
1122
    }
 
1123
    return(*status);
 
1124
}
 
1125
/*--------------------------------------------------------------------------*/
 
1126
int fffi4u2(INT32BIT *input,      /* I - array of values to be converted     */
 
1127
            long ntodo,           /* I - number of elements in the array     */
 
1128
            double scale,         /* I - FITS TSCALn or BSCALE value         */
 
1129
            double zero,          /* I - FITS TZEROn or BZERO  value         */
 
1130
            int nullcheck,        /* I - null checking code; 0 = don't check */
 
1131
                                  /*     1:set null pixels = nullval         */
 
1132
                                  /*     2: if null pixel, set nullarray = 1 */
 
1133
            INT32BIT tnull,       /* I - value of FITS TNULLn keyword if any */
 
1134
   unsigned short nullval,        /* I - set null pixels, if nullcheck = 1   */
 
1135
            char *nullarray,      /* I - bad pixel array, if nullcheck = 2   */
 
1136
            int  *anynull,        /* O - set to 1 if any pixels are null     */
 
1137
   unsigned short *output,        /* O - array of converted pixels           */
 
1138
            int *status)          /* IO - error status                       */
 
1139
/*
 
1140
  Copy input to output following reading of the input from a FITS file.
 
1141
  Check for null values and do datatype conversion and scaling if required.
 
1142
  The nullcheck code value determines how any null values in the input array
 
1143
  are treated.  A null value is an input pixel that is equal to tnull.  If 
 
1144
  nullcheck = 0, then no checking for nulls is performed and any null values
 
1145
  will be transformed just like any other pixel.  If nullcheck = 1, then the
 
1146
  output pixel will be set = nullval if the corresponding input pixel is null.
 
1147
  If nullcheck = 2, then if the pixel is null then the corresponding value of
 
1148
  nullarray will be set to 1; the value of nullarray for non-null pixels 
 
1149
  will = 0.  The anynull parameter will be set = 1 if any of the returned
 
1150
  pixels are null, otherwise anynull will be returned with a value = 0;
 
1151
*/
 
1152
{
 
1153
    long ii;
 
1154
    double dvalue;
 
1155
 
 
1156
    if (nullcheck == 0)     /* no null checking required */
 
1157
    {
 
1158
        if (scale == 1. && zero == 0.)      /* no scaling */
 
1159
        {       
 
1160
            for (ii = 0; ii < ntodo; ii++)
 
1161
            {
 
1162
                if (input[ii] < 0)
 
1163
                {
 
1164
                    *status = OVERFLOW_ERR;
 
1165
                    output[ii] = 0;
 
1166
                }
 
1167
                else if (input[ii] > USHRT_MAX)
 
1168
                {
 
1169
                    *status = OVERFLOW_ERR;
 
1170
                    output[ii] = USHRT_MAX;
 
1171
                }
 
1172
                else
 
1173
                    output[ii] = (unsigned short) input[ii];
 
1174
            }
 
1175
        }
 
1176
        else             /* must scale the data */
 
1177
        {
 
1178
            for (ii = 0; ii < ntodo; ii++)
 
1179
            {
 
1180
                dvalue = input[ii] * scale + zero;
 
1181
 
 
1182
                if (dvalue < DUSHRT_MIN)
 
1183
                {
 
1184
                    *status = OVERFLOW_ERR;
 
1185
                    output[ii] = 0;
 
1186
                }
 
1187
                else if (dvalue > DUSHRT_MAX)
 
1188
                {
 
1189
                    *status = OVERFLOW_ERR;
 
1190
                    output[ii] = USHRT_MAX;
 
1191
                }
 
1192
                else
 
1193
                    output[ii] = (unsigned short) dvalue;
 
1194
            }
 
1195
        }
 
1196
    }
 
1197
    else        /* must check for null values */
 
1198
    {
 
1199
        if (scale == 1. && zero == 0.)  /* no scaling */
 
1200
        {       
 
1201
            for (ii = 0; ii < ntodo; ii++)
 
1202
            {
 
1203
                if (input[ii] == tnull)
 
1204
                {
 
1205
                    *anynull = 1;
 
1206
                    if (nullcheck == 1)
 
1207
                        output[ii] = nullval;
 
1208
                    else
 
1209
                        nullarray[ii] = 1;
 
1210
                }
 
1211
                else
 
1212
                {
 
1213
                    if (input[ii] < 0)
 
1214
                    {
 
1215
                        *status = OVERFLOW_ERR;
 
1216
                        output[ii] = 0;
 
1217
                    }
 
1218
                    else if (input[ii] > USHRT_MAX)
 
1219
                    {
 
1220
                        *status = OVERFLOW_ERR;
 
1221
                        output[ii] = USHRT_MAX;
 
1222
                    }
 
1223
                    else
 
1224
                        output[ii] = (unsigned short) input[ii];
 
1225
                }
 
1226
            }
 
1227
        }
 
1228
        else                  /* must scale the data */
 
1229
        {
 
1230
            for (ii = 0; ii < ntodo; ii++)
 
1231
            {
 
1232
                if (input[ii] == tnull)
 
1233
                {
 
1234
                    *anynull = 1;
 
1235
                    if (nullcheck == 1)
 
1236
                        output[ii] = nullval;
 
1237
                    else
 
1238
                        nullarray[ii] = 1;
 
1239
                }
 
1240
                else
 
1241
                {
 
1242
                    dvalue = input[ii] * scale + zero;
 
1243
 
 
1244
                    if (dvalue < DUSHRT_MIN)
 
1245
                    {
 
1246
                        *status = OVERFLOW_ERR;
 
1247
                        output[ii] = 0;
 
1248
                    }
 
1249
                    else if (dvalue > DUSHRT_MAX)
 
1250
                    {
 
1251
                        *status = OVERFLOW_ERR;
 
1252
                        output[ii] = USHRT_MAX;
 
1253
                    }
 
1254
                    else
 
1255
                        output[ii] = (unsigned short) dvalue;
 
1256
                }
 
1257
            }
 
1258
        }
 
1259
    }
 
1260
    return(*status);
 
1261
}
 
1262
/*--------------------------------------------------------------------------*/
 
1263
int fffi8u2(LONGLONG *input,      /* I - array of values to be converted     */
 
1264
            long ntodo,           /* I - number of elements in the array     */
 
1265
            double scale,         /* I - FITS TSCALn or BSCALE value         */
 
1266
            double zero,          /* I - FITS TZEROn or BZERO  value         */
 
1267
            int nullcheck,        /* I - null checking code; 0 = don't check */
 
1268
                                  /*     1:set null pixels = nullval         */
 
1269
                                  /*     2: if null pixel, set nullarray = 1 */
 
1270
            LONGLONG tnull,       /* I - value of FITS TNULLn keyword if any */
 
1271
   unsigned short nullval,        /* I - set null pixels, if nullcheck = 1   */
 
1272
            char *nullarray,      /* I - bad pixel array, if nullcheck = 2   */
 
1273
            int  *anynull,        /* O - set to 1 if any pixels are null     */
 
1274
   unsigned short *output,        /* O - array of converted pixels           */
 
1275
            int *status)          /* IO - error status                       */
 
1276
/*
 
1277
  Copy input to output following reading of the input from a FITS file.
 
1278
  Check for null values and do datatype conversion and scaling if required.
 
1279
  The nullcheck code value determines how any null values in the input array
 
1280
  are treated.  A null value is an input pixel that is equal to tnull.  If 
 
1281
  nullcheck = 0, then no checking for nulls is performed and any null values
 
1282
  will be transformed just like any other pixel.  If nullcheck = 1, then the
 
1283
  output pixel will be set = nullval if the corresponding input pixel is null.
 
1284
  If nullcheck = 2, then if the pixel is null then the corresponding value of
 
1285
  nullarray will be set to 1; the value of nullarray for non-null pixels 
 
1286
  will = 0.  The anynull parameter will be set = 1 if any of the returned
 
1287
  pixels are null, otherwise anynull will be returned with a value = 0;
 
1288
*/
 
1289
{
 
1290
    long ii;
 
1291
    double dvalue;
 
1292
 
 
1293
    if (nullcheck == 0)     /* no null checking required */
 
1294
    {
 
1295
        if (scale == 1. && zero == 0.)      /* no scaling */
 
1296
        {       
 
1297
            for (ii = 0; ii < ntodo; ii++)
 
1298
            {
 
1299
                if (input[ii] < 0)
 
1300
                {
 
1301
                    *status = OVERFLOW_ERR;
 
1302
                    output[ii] = 0;
 
1303
                }
 
1304
                else if (input[ii] > USHRT_MAX)
 
1305
                {
 
1306
                    *status = OVERFLOW_ERR;
 
1307
                    output[ii] = USHRT_MAX;
 
1308
                }
 
1309
                else
 
1310
                    output[ii] = (unsigned short) input[ii];
 
1311
            }
 
1312
        }
 
1313
        else             /* must scale the data */
 
1314
        {
 
1315
            for (ii = 0; ii < ntodo; ii++)
 
1316
            {
 
1317
                dvalue = input[ii] * scale + zero;
 
1318
 
 
1319
                if (dvalue < DUSHRT_MIN)
 
1320
                {
 
1321
                    *status = OVERFLOW_ERR;
 
1322
                    output[ii] = 0;
 
1323
                }
 
1324
                else if (dvalue > DUSHRT_MAX)
 
1325
                {
 
1326
                    *status = OVERFLOW_ERR;
 
1327
                    output[ii] = USHRT_MAX;
 
1328
                }
 
1329
                else
 
1330
                    output[ii] = (unsigned short) dvalue;
 
1331
            }
 
1332
        }
 
1333
    }
 
1334
    else        /* must check for null values */
 
1335
    {
 
1336
        if (scale == 1. && zero == 0.)  /* no scaling */
 
1337
        {       
 
1338
            for (ii = 0; ii < ntodo; ii++)
 
1339
            {
 
1340
                if (input[ii] == tnull)
 
1341
                {
 
1342
                    *anynull = 1;
 
1343
                    if (nullcheck == 1)
 
1344
                        output[ii] = nullval;
 
1345
                    else
 
1346
                        nullarray[ii] = 1;
 
1347
                }
 
1348
                else
 
1349
                {
 
1350
                    if (input[ii] < 0)
 
1351
                    {
 
1352
                        *status = OVERFLOW_ERR;
 
1353
                        output[ii] = 0;
 
1354
                    }
 
1355
                    else if (input[ii] > USHRT_MAX)
 
1356
                    {
 
1357
                        *status = OVERFLOW_ERR;
 
1358
                        output[ii] = USHRT_MAX;
 
1359
                    }
 
1360
                    else
 
1361
                        output[ii] = (unsigned short) input[ii];
 
1362
                }
 
1363
            }
 
1364
        }
 
1365
        else                  /* must scale the data */
 
1366
        {
 
1367
            for (ii = 0; ii < ntodo; ii++)
 
1368
            {
 
1369
                if (input[ii] == tnull)
 
1370
                {
 
1371
                    *anynull = 1;
 
1372
                    if (nullcheck == 1)
 
1373
                        output[ii] = nullval;
 
1374
                    else
 
1375
                        nullarray[ii] = 1;
 
1376
                }
 
1377
                else
 
1378
                {
 
1379
                    dvalue = input[ii] * scale + zero;
 
1380
 
 
1381
                    if (dvalue < DUSHRT_MIN)
 
1382
                    {
 
1383
                        *status = OVERFLOW_ERR;
 
1384
                        output[ii] = 0;
 
1385
                    }
 
1386
                    else if (dvalue > DUSHRT_MAX)
 
1387
                    {
 
1388
                        *status = OVERFLOW_ERR;
 
1389
                        output[ii] = USHRT_MAX;
 
1390
                    }
 
1391
                    else
 
1392
                        output[ii] = (unsigned short) dvalue;
 
1393
                }
 
1394
            }
 
1395
        }
 
1396
    }
 
1397
    return(*status);
 
1398
}
 
1399
/*--------------------------------------------------------------------------*/
 
1400
int fffr4u2(float *input,         /* I - array of values to be converted     */
 
1401
            long ntodo,           /* I - number of elements in the array     */
 
1402
            double scale,         /* I - FITS TSCALn or BSCALE value         */
 
1403
            double zero,          /* I - FITS TZEROn or BZERO  value         */
 
1404
            int nullcheck,        /* I - null checking code; 0 = don't check */
 
1405
                                  /*     1:set null pixels = nullval         */
 
1406
                                  /*     2: if null pixel, set nullarray = 1 */
 
1407
   unsigned short nullval,        /* I - set null pixels, if nullcheck = 1   */
 
1408
            char *nullarray,      /* I - bad pixel array, if nullcheck = 2   */
 
1409
            int  *anynull,        /* O - set to 1 if any pixels are null     */
 
1410
   unsigned short *output,        /* O - array of converted pixels           */
 
1411
            int *status)          /* IO - error status                       */
 
1412
/*
 
1413
  Copy input to output following reading of the input from a FITS file.
 
1414
  Check for null values and do datatype conversion and scaling if required.
 
1415
  The nullcheck code value determines how any null values in the input array
 
1416
  are treated.  A null value is an input pixel that is equal to NaN.  If 
 
1417
  nullcheck = 0, then no checking for nulls is performed and any null values
 
1418
  will be transformed just like any other pixel.  If nullcheck = 1, then the
 
1419
  output pixel will be set = nullval if the corresponding input pixel is null.
 
1420
  If nullcheck = 2, then if the pixel is null then the corresponding value of
 
1421
  nullarray will be set to 1; the value of nullarray for non-null pixels 
 
1422
  will = 0.  The anynull parameter will be set = 1 if any of the returned
 
1423
  pixels are null, otherwise anynull will be returned with a value = 0;
 
1424
*/
 
1425
{
 
1426
    long ii;
 
1427
    double dvalue;
 
1428
    short *sptr, iret;
 
1429
 
 
1430
    if (nullcheck == 0)     /* no null checking required */
 
1431
    {
 
1432
        if (scale == 1. && zero == 0.)      /* no scaling */
 
1433
        {       
 
1434
            for (ii = 0; ii < ntodo; ii++)
 
1435
            {
 
1436
                if (input[ii] < DUSHRT_MIN)
 
1437
                {
 
1438
                    *status = OVERFLOW_ERR;
 
1439
                    output[ii] = 0;
 
1440
                }
 
1441
                else if (input[ii] > DUSHRT_MAX)
 
1442
                {
 
1443
                    *status = OVERFLOW_ERR;
 
1444
                    output[ii] = USHRT_MAX;
 
1445
                }
 
1446
                else
 
1447
                    output[ii] = (unsigned short) input[ii];
 
1448
            }
 
1449
        }
 
1450
        else             /* must scale the data */
 
1451
        {
 
1452
            for (ii = 0; ii < ntodo; ii++)
 
1453
            {
 
1454
                dvalue = input[ii] * scale + zero;
 
1455
 
 
1456
                if (dvalue < DUSHRT_MIN)
 
1457
                {
 
1458
                    *status = OVERFLOW_ERR;
 
1459
                    output[ii] = 0;
 
1460
                }
 
1461
                else if (dvalue > DUSHRT_MAX)
 
1462
                {
 
1463
                    *status = OVERFLOW_ERR;
 
1464
                    output[ii] = USHRT_MAX;
 
1465
                }
 
1466
                else
 
1467
                    output[ii] = (unsigned short) dvalue;
 
1468
            }
 
1469
        }
 
1470
    }
 
1471
    else        /* must check for null values */
 
1472
    {
 
1473
        sptr = (short *) input;
 
1474
 
 
1475
#if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS
 
1476
        sptr++;       /* point to MSBs */
 
1477
#endif
 
1478
 
 
1479
        if (scale == 1. && zero == 0.)  /* no scaling */
 
1480
        {       
 
1481
            for (ii = 0; ii < ntodo; ii++, sptr += 2)
 
1482
            {
 
1483
              if (0 != (iret = fnan(*sptr) ) )   /* test for NaN or underflow */
 
1484
              {
 
1485
                  if (iret == 1)  /* is it a NaN? */
 
1486
                  {
 
1487
                    *anynull = 1;
 
1488
                    if (nullcheck == 1)
 
1489
                        output[ii] = nullval;
 
1490
                    else
 
1491
                        nullarray[ii] = 1;
 
1492
                  }
 
1493
                  else            /* it's an underflow */
 
1494
                     output[ii] = 0;
 
1495
              }
 
1496
              else
 
1497
                {
 
1498
                    if (input[ii] < DUSHRT_MIN)
 
1499
                    {
 
1500
                        *status = OVERFLOW_ERR;
 
1501
                        output[ii] = 0;
 
1502
                    }
 
1503
                    else if (input[ii] > DUSHRT_MAX)
 
1504
                    {
 
1505
                        *status = OVERFLOW_ERR;
 
1506
                        output[ii] = USHRT_MAX;
 
1507
                    }
 
1508
                    else
 
1509
                        output[ii] = (unsigned short) input[ii];
 
1510
                }
 
1511
            }
 
1512
        }
 
1513
        else                  /* must scale the data */
 
1514
        {
 
1515
            for (ii = 0; ii < ntodo; ii++, sptr += 2)
 
1516
            {
 
1517
              if (0 != (iret = fnan(*sptr) ) )  /* test for NaN or underflow */
 
1518
              {
 
1519
                  if (iret == 1)  /* is it a NaN? */
 
1520
                  {  
 
1521
                    *anynull = 1;
 
1522
                    if (nullcheck == 1)
 
1523
                        output[ii] = nullval;
 
1524
                    else
 
1525
                        nullarray[ii] = 1;
 
1526
                  }
 
1527
                  else            /* it's an underflow */
 
1528
                  { 
 
1529
                    if (zero < DUSHRT_MIN)
 
1530
                    {
 
1531
                        *status = OVERFLOW_ERR;
 
1532
                        output[ii] = 0;
 
1533
                    }
 
1534
                    else if (zero > DUSHRT_MAX)
 
1535
                    {
 
1536
                        *status = OVERFLOW_ERR;
 
1537
                        output[ii] = USHRT_MAX;
 
1538
                    }
 
1539
                    else
 
1540
                      output[ii] = (unsigned short) zero;
 
1541
                  }
 
1542
              }
 
1543
              else
 
1544
              {
 
1545
                    dvalue = input[ii] * scale + zero;
 
1546
 
 
1547
                    if (dvalue < DUSHRT_MIN)
 
1548
                    {
 
1549
                        *status = OVERFLOW_ERR;
 
1550
                        output[ii] = 0;
 
1551
                    }
 
1552
                    else if (dvalue > DUSHRT_MAX)
 
1553
                    {
 
1554
                        *status = OVERFLOW_ERR;
 
1555
                        output[ii] = USHRT_MAX;
 
1556
                    }
 
1557
                    else
 
1558
                        output[ii] = (unsigned short) dvalue;
 
1559
              }
 
1560
            }
 
1561
        }
 
1562
    }
 
1563
    return(*status);
 
1564
}
 
1565
/*--------------------------------------------------------------------------*/
 
1566
int fffr8u2(double *input,        /* I - array of values to be converted     */
 
1567
            long ntodo,           /* I - number of elements in the array     */
 
1568
            double scale,         /* I - FITS TSCALn or BSCALE value         */
 
1569
            double zero,          /* I - FITS TZEROn or BZERO  value         */
 
1570
            int nullcheck,        /* I - null checking code; 0 = don't check */
 
1571
                                  /*     1:set null pixels = nullval         */
 
1572
                                  /*     2: if null pixel, set nullarray = 1 */
 
1573
   unsigned short nullval,        /* I - set null pixels, if nullcheck = 1   */
 
1574
            char *nullarray,      /* I - bad pixel array, if nullcheck = 2   */
 
1575
            int  *anynull,        /* O - set to 1 if any pixels are null     */
 
1576
   unsigned short *output,        /* O - array of converted pixels           */
 
1577
            int *status)          /* IO - error status                       */
 
1578
/*
 
1579
  Copy input to output following reading of the input from a FITS file.
 
1580
  Check for null values and do datatype conversion and scaling if required.
 
1581
  The nullcheck code value determines how any null values in the input array
 
1582
  are treated.  A null value is an input pixel that is equal to NaN.  If 
 
1583
  nullcheck = 0, then no checking for nulls is performed and any null values
 
1584
  will be transformed just like any other pixel.  If nullcheck = 1, then the
 
1585
  output pixel will be set = nullval if the corresponding input pixel is null.
 
1586
  If nullcheck = 2, then if the pixel is null then the corresponding value of
 
1587
  nullarray will be set to 1; the value of nullarray for non-null pixels 
 
1588
  will = 0.  The anynull parameter will be set = 1 if any of the returned
 
1589
  pixels are null, otherwise anynull will be returned with a value = 0;
 
1590
*/
 
1591
{
 
1592
    long ii;
 
1593
    double dvalue;
 
1594
    short *sptr, iret;
 
1595
 
 
1596
    if (nullcheck == 0)     /* no null checking required */
 
1597
    {
 
1598
        if (scale == 1. && zero == 0.)      /* no scaling */
 
1599
        {       
 
1600
            for (ii = 0; ii < ntodo; ii++)
 
1601
            {
 
1602
                if (input[ii] < DUSHRT_MIN)
 
1603
                {
 
1604
                    *status = OVERFLOW_ERR;
 
1605
                    output[ii] = 0;
 
1606
                }
 
1607
                else if (input[ii] > DUSHRT_MAX)
 
1608
                {
 
1609
                    *status = OVERFLOW_ERR;
 
1610
                    output[ii] = USHRT_MAX;
 
1611
                }
 
1612
                else
 
1613
                    output[ii] = (unsigned short) input[ii];
 
1614
            }
 
1615
        }
 
1616
        else             /* must scale the data */
 
1617
        {
 
1618
            for (ii = 0; ii < ntodo; ii++)
 
1619
            {
 
1620
                dvalue = input[ii] * scale + zero;
 
1621
 
 
1622
                if (dvalue < DUSHRT_MIN)
 
1623
                {
 
1624
                    *status = OVERFLOW_ERR;
 
1625
                    output[ii] = 0;
 
1626
                }
 
1627
                else if (dvalue > DUSHRT_MAX)
 
1628
                {
 
1629
                    *status = OVERFLOW_ERR;
 
1630
                    output[ii] = USHRT_MAX;
 
1631
                }
 
1632
                else
 
1633
                    output[ii] = (unsigned short) dvalue;
 
1634
            }
 
1635
        }
 
1636
    }
 
1637
    else        /* must check for null values */
 
1638
    {
 
1639
        sptr = (short *) input;
 
1640
 
 
1641
#if BYTESWAPPED && MACHINE != VAXVMS && MACHINE != ALPHAVMS
 
1642
        sptr += 3;       /* point to MSBs */
 
1643
#endif
 
1644
        if (scale == 1. && zero == 0.)  /* no scaling */
 
1645
        {       
 
1646
            for (ii = 0; ii < ntodo; ii++, sptr += 4)
 
1647
            {
 
1648
              if (0 != (iret = dnan(*sptr)) )  /* test for NaN or underflow */
 
1649
              {
 
1650
                  if (iret == 1)  /* is it a NaN? */
 
1651
                  {
 
1652
                    *anynull = 1;
 
1653
                    if (nullcheck == 1)
 
1654
                        output[ii] = nullval;
 
1655
                    else
 
1656
                        nullarray[ii] = 1;
 
1657
                  }
 
1658
                  else            /* it's an underflow */
 
1659
                     output[ii] = 0;
 
1660
              }
 
1661
              else
 
1662
                {
 
1663
                    if (input[ii] < DUSHRT_MIN)
 
1664
                    {
 
1665
                        *status = OVERFLOW_ERR;
 
1666
                        output[ii] = 0;
 
1667
                    }
 
1668
                    else if (input[ii] > DUSHRT_MAX)
 
1669
                    {
 
1670
                        *status = OVERFLOW_ERR;
 
1671
                        output[ii] = USHRT_MAX;
 
1672
                    }
 
1673
                    else
 
1674
                        output[ii] = (unsigned short) input[ii];
 
1675
                }
 
1676
            }
 
1677
        }
 
1678
        else                  /* must scale the data */
 
1679
        {
 
1680
            for (ii = 0; ii < ntodo; ii++, sptr += 4)
 
1681
            {
 
1682
              if (0 != (iret = dnan(*sptr)) )  /* test for NaN or underflow */
 
1683
              {
 
1684
                  if (iret == 1)  /* is it a NaN? */
 
1685
                  {  
 
1686
                    *anynull = 1;
 
1687
                    if (nullcheck == 1)
 
1688
                        output[ii] = nullval;
 
1689
                    else
 
1690
                        nullarray[ii] = 1;
 
1691
                  }
 
1692
                  else            /* it's an underflow */
 
1693
                  { 
 
1694
                    if (zero < DUSHRT_MIN)
 
1695
                    {
 
1696
                        *status = OVERFLOW_ERR;
 
1697
                        output[ii] = 0;
 
1698
                    }
 
1699
                    else if (zero > DUSHRT_MAX)
 
1700
                    {
 
1701
                        *status = OVERFLOW_ERR;
 
1702
                        output[ii] = USHRT_MAX;
 
1703
                    }
 
1704
                    else
 
1705
                      output[ii] = (unsigned short) zero;
 
1706
                  }
 
1707
              }
 
1708
              else
 
1709
                {
 
1710
                    dvalue = input[ii] * scale + zero;
 
1711
 
 
1712
                    if (dvalue < DUSHRT_MIN)
 
1713
                    {
 
1714
                        *status = OVERFLOW_ERR;
 
1715
                        output[ii] = 0;
 
1716
                    }
 
1717
                    else if (dvalue > DUSHRT_MAX)
 
1718
                    {
 
1719
                        *status = OVERFLOW_ERR;
 
1720
                        output[ii] = USHRT_MAX;
 
1721
                    }
 
1722
                    else
 
1723
                        output[ii] = (unsigned short) dvalue;
 
1724
                }
 
1725
            }
 
1726
        }
 
1727
    }
 
1728
    return(*status);
 
1729
}
 
1730
/*--------------------------------------------------------------------------*/
 
1731
int fffstru2(char *input,         /* I - array of values to be converted     */
 
1732
            long ntodo,           /* I - number of elements in the array     */
 
1733
            double scale,         /* I - FITS TSCALn or BSCALE value         */
 
1734
            double zero,          /* I - FITS TZEROn or BZERO  value         */
 
1735
            long twidth,          /* I - width of each substring of chars    */
 
1736
            double implipower,    /* I - power of 10 of implied decimal      */
 
1737
            int nullcheck,        /* I - null checking code; 0 = don't check */
 
1738
                                  /*     1:set null pixels = nullval         */
 
1739
                                  /*     2: if null pixel, set nullarray = 1 */
 
1740
            char  *snull,         /* I - value of FITS null string, if any   */
 
1741
   unsigned short nullval,        /* I - set null pixels, if nullcheck = 1   */
 
1742
            char *nullarray,      /* I - bad pixel array, if nullcheck = 2   */
 
1743
            int  *anynull,        /* O - set to 1 if any pixels are null     */
 
1744
   unsigned short *output,        /* O - array of converted pixels           */
 
1745
            int *status)          /* IO - error status                       */
 
1746
/*
 
1747
  Copy input to output following reading of the input from a FITS file. Check
 
1748
  for null values and do scaling if required. The nullcheck code value
 
1749
  determines how any null values in the input array are treated. A null
 
1750
  value is an input pixel that is equal to snull.  If nullcheck= 0, then
 
1751
  no special checking for nulls is performed.  If nullcheck = 1, then the
 
1752
  output pixel will be set = nullval if the corresponding input pixel is null.
 
1753
  If nullcheck = 2, then if the pixel is null then the corresponding value of
 
1754
  nullarray will be set to 1; the value of nullarray for non-null pixels 
 
1755
  will = 0.  The anynull parameter will be set = 1 if any of the returned
 
1756
  pixels are null, otherwise anynull will be returned with a value = 0;
 
1757
*/
 
1758
{
 
1759
    int nullen;
 
1760
    long ii;
 
1761
    double dvalue;
 
1762
    char *cstring, message[81];
 
1763
    char *cptr, *tpos;
 
1764
    char tempstore, chrzero = '0';
 
1765
    double val, power;
 
1766
    int exponent, sign, esign, decpt;
 
1767
 
 
1768
    nullen = strlen(snull);
 
1769
    cptr = input;  /* pointer to start of input string */
 
1770
    for (ii = 0; ii < ntodo; ii++)
 
1771
    {
 
1772
      cstring = cptr;
 
1773
      /* temporarily insert a null terminator at end of the string */
 
1774
      tpos = cptr + twidth;
 
1775
      tempstore = *tpos;
 
1776
      *tpos = 0;
 
1777
 
 
1778
      /* check if null value is defined, and if the    */
 
1779
      /* column string is identical to the null string */
 
1780
      if (snull[0] != ASCII_NULL_UNDEFINED && 
 
1781
         !strncmp(snull, cptr, nullen) )
 
1782
      {
 
1783
        if (nullcheck)  
 
1784
        {
 
1785
          *anynull = 1;    
 
1786
          if (nullcheck == 1)
 
1787
            output[ii] = nullval;
 
1788
          else
 
1789
            nullarray[ii] = 1;
 
1790
        }
 
1791
        cptr += twidth;
 
1792
      }
 
1793
      else
 
1794
      {
 
1795
        /* value is not the null value, so decode it */
 
1796
        /* remove any embedded blank characters from the string */
 
1797
 
 
1798
        decpt = 0;
 
1799
        sign = 1;
 
1800
        val  = 0.;
 
1801
        power = 1.;
 
1802
        exponent = 0;
 
1803
        esign = 1;
 
1804
 
 
1805
        while (*cptr == ' ')               /* skip leading blanks */
 
1806
           cptr++;
 
1807
 
 
1808
        if (*cptr == '-' || *cptr == '+')  /* check for leading sign */
 
1809
        {
 
1810
          if (*cptr == '-')
 
1811
             sign = -1;
 
1812
 
 
1813
          cptr++;
 
1814
 
 
1815
          while (*cptr == ' ')         /* skip blanks between sign and value */
 
1816
            cptr++;
 
1817
        }
 
1818
 
 
1819
        while (*cptr >= '0' && *cptr <= '9')
 
1820
        {
 
1821
          val = val * 10. + *cptr - chrzero;  /* accumulate the value */
 
1822
          cptr++;
 
1823
 
 
1824
          while (*cptr == ' ')         /* skip embedded blanks in the value */
 
1825
            cptr++;
 
1826
        }
 
1827
 
 
1828
        if (*cptr == '.' || *cptr == ',')       /* check for decimal point */
 
1829
        {
 
1830
          decpt = 1;       /* set flag to show there was a decimal point */
 
1831
          cptr++;
 
1832
          while (*cptr == ' ')         /* skip any blanks */
 
1833
            cptr++;
 
1834
 
 
1835
          while (*cptr >= '0' && *cptr <= '9')
 
1836
          {
 
1837
            val = val * 10. + *cptr - chrzero;  /* accumulate the value */
 
1838
            power = power * 10.;
 
1839
            cptr++;
 
1840
 
 
1841
            while (*cptr == ' ')         /* skip embedded blanks in the value */
 
1842
              cptr++;
 
1843
          }
 
1844
        }
 
1845
 
 
1846
        if (*cptr == 'E' || *cptr == 'D')  /* check for exponent */
 
1847
        {
 
1848
          cptr++;
 
1849
          while (*cptr == ' ')         /* skip blanks */
 
1850
              cptr++;
 
1851
  
 
1852
          if (*cptr == '-' || *cptr == '+')  /* check for exponent sign */
 
1853
          {
 
1854
            if (*cptr == '-')
 
1855
               esign = -1;
 
1856
 
 
1857
            cptr++;
 
1858
 
 
1859
            while (*cptr == ' ')        /* skip blanks between sign and exp */
 
1860
              cptr++;
 
1861
          }
 
1862
 
 
1863
          while (*cptr >= '0' && *cptr <= '9')
 
1864
          {
 
1865
            exponent = exponent * 10 + *cptr - chrzero;  /* accumulate exp */
 
1866
            cptr++;
 
1867
 
 
1868
            while (*cptr == ' ')         /* skip embedded blanks */
 
1869
              cptr++;
 
1870
          }
 
1871
        }
 
1872
 
 
1873
        if (*cptr  != 0)  /* should end up at the null terminator */
 
1874
        {
 
1875
          sprintf(message, "Cannot read number from ASCII table");
 
1876
          ffpmsg(message);
 
1877
          sprintf(message, "Column field = %s.", cstring);
 
1878
          ffpmsg(message);
 
1879
          /* restore the char that was overwritten by the null */
 
1880
          *tpos = tempstore;
 
1881
          return(*status = BAD_C2D);
 
1882
        }
 
1883
 
 
1884
        if (!decpt)  /* if no explicit decimal, use implied */
 
1885
           power = implipower;
 
1886
 
 
1887
        dvalue = (sign * val / power) * pow(10., (double) (esign * exponent));
 
1888
 
 
1889
        dvalue = dvalue * scale + zero;   /* apply the scaling */
 
1890
 
 
1891
        if (dvalue < DUSHRT_MIN)
 
1892
        {
 
1893
            *status = OVERFLOW_ERR;
 
1894
            output[ii] = 0;
 
1895
        }
 
1896
        else if (dvalue > DUSHRT_MAX)
 
1897
        {
 
1898
            *status = OVERFLOW_ERR;
 
1899
            output[ii] = USHRT_MAX;
 
1900
        }
 
1901
        else
 
1902
            output[ii] = (unsigned short) dvalue;
 
1903
      }
 
1904
      /* restore the char that was overwritten by the null */
 
1905
      *tpos = tempstore;
 
1906
    }
 
1907
    return(*status);
 
1908
}