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

« back to all changes in this revision

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