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

« back to all changes in this revision

Viewing changes to putcole.c

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

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  This file, putcole.c, contains routines that write data elements to    */
 
2
/*  a FITS image or table, with float 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 <limits.h>
 
9
#include <string.h>
 
10
#include <stdlib.h>
 
11
#include "fitsio2.h"
 
12
 
 
13
/* declare variable for passing large firstelem values between routines */
 
14
extern OFF_T large_first_elem_val;
 
15
 
 
16
/*--------------------------------------------------------------------------*/
 
17
int ffppre( fitsfile *fptr,  /* I - FITS file pointer                       */
 
18
            long  group,     /* I - group to write(1 = 1st group)           */
 
19
            long  firstelem, /* I - first vector element to write(1 = 1st)  */
 
20
            long  nelem,     /* I - number of values to write               */
 
21
            float *array,    /* I - array of values that are written        */
 
22
            int  *status)    /* IO - error status                           */
 
23
/*
 
24
  Write an array of values to 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 written).
 
27
*/
 
28
{
 
29
    long row;
 
30
    float nullvalue;
 
31
 
 
32
    /*
 
33
      the primary array is represented as a binary table:
 
34
      each group of the primary array is a row in the table,
 
35
      where the first column contains the group parameters
 
36
      and the second column contains the image itself.
 
37
    */
 
38
 
 
39
    if (fits_is_compressed_image(fptr, status))
 
40
    {
 
41
        /* this is a compressed image in a binary table */
 
42
 
 
43
        /* use the OFF_T variable to pass the first element value */
 
44
        if (firstelem != USE_LARGE_VALUE)
 
45
            large_first_elem_val = firstelem;
 
46
 
 
47
        fits_write_compressed_pixels(fptr, TFLOAT, large_first_elem_val, nelem,
 
48
            0, array, &nullvalue, status);
 
49
        return(*status);
 
50
    }
 
51
 
 
52
    row=maxvalue(1,group);
 
53
 
 
54
    ffpcle(fptr, 2, row, firstelem, nelem, array, status);
 
55
    return(*status);
 
56
}
 
57
/*--------------------------------------------------------------------------*/
 
58
int ffppne( fitsfile *fptr,  /* I - FITS file pointer                       */
 
59
            long  group,     /* I - group to write(1 = 1st group)           */
 
60
            long  firstelem, /* I - first vector element to write(1 = 1st)  */
 
61
            long  nelem,     /* I - number of values to write               */
 
62
            float *array,    /* I - array of values that are written        */
 
63
            float nulval,    /* I - undefined pixel value                   */
 
64
            int  *status)    /* IO - error status                           */
 
65
/*
 
66
  Write an array of values to the primary array. Data conversion
 
67
  and scaling will be performed if necessary (e.g, if the datatype of the
 
68
  FITS array is not the same as the array being written).  Any array values
 
69
  that are equal to the value of nulval will be replaced with the null
 
70
  pixel value that is appropriate for this column.
 
71
*/
 
72
{
 
73
    long row;
 
74
    float nullvalue;
 
75
 
 
76
    /*
 
77
      the primary array is represented as a binary table:
 
78
      each group of the primary array is a row in the table,
 
79
      where the first column contains the group parameters
 
80
      and the second column contains the image itself.
 
81
    */
 
82
 
 
83
    if (fits_is_compressed_image(fptr, status))
 
84
    {
 
85
        /* this is a compressed image in a binary table */
 
86
 
 
87
        /* use the OFF_T variable to pass the first element value */
 
88
        if (firstelem != USE_LARGE_VALUE)
 
89
            large_first_elem_val = firstelem;
 
90
 
 
91
        nullvalue = nulval;  /* set local variable */
 
92
        fits_write_compressed_pixels(fptr, TFLOAT, large_first_elem_val, nelem,
 
93
            1, array, &nullvalue, status);
 
94
        return(*status);
 
95
    }
 
96
 
 
97
    row=maxvalue(1,group);
 
98
 
 
99
    ffpcne(fptr, 2, row, firstelem, nelem, array, nulval, status);
 
100
    return(*status);
 
101
}
 
102
/*--------------------------------------------------------------------------*/
 
103
int ffp2de(fitsfile *fptr,   /* I - FITS file pointer                     */
 
104
           long  group,      /* I - group to write(1 = 1st group)         */
 
105
           long  ncols,      /* I - number of pixels in each row of array */
 
106
           long  naxis1,     /* I - FITS image NAXIS1 value               */
 
107
           long  naxis2,     /* I - FITS image NAXIS2 value               */
 
108
           float *array,     /* I - array to be written                   */
 
109
           int  *status)     /* IO - error status                         */
 
110
/*
 
111
  Write an entire 2-D array of values to the primary array. Data conversion
 
112
  and scaling will be performed if necessary (e.g, if the datatype of the
 
113
  FITS array is not the same as the array being written).
 
114
*/
 
115
{
 
116
    /* call the 3D writing routine, with the 3rd dimension = 1 */
 
117
 
 
118
    ffp3de(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status);
 
119
 
 
120
    return(*status);
 
121
}
 
122
/*--------------------------------------------------------------------------*/
 
123
int ffp3de(fitsfile *fptr,   /* I - FITS file pointer                     */
 
124
           long  group,      /* I - group to write(1 = 1st group)         */
 
125
           long  ncols,      /* I - number of pixels in each row of array */
 
126
           long  nrows,      /* I - number of rows in each plane of array */
 
127
           long  naxis1,     /* I - FITS image NAXIS1 value               */
 
128
           long  naxis2,     /* I - FITS image NAXIS2 value               */
 
129
           long  naxis3,     /* I - FITS image NAXIS3 value               */
 
130
           float *array,     /* I - array to be written                   */
 
131
           int  *status)     /* IO - error status                         */
 
132
/*
 
133
  Write an entire 3-D cube of values to the primary array. Data conversion
 
134
  and scaling will be performed if necessary (e.g, if the datatype of the
 
135
  FITS array is not the same as the array being written).
 
136
*/
 
137
{
 
138
    long tablerow, nfits, narray, ii, jj;
 
139
    long fpixel[3]= {1,1,1}, lpixel[3];
 
140
    /*
 
141
      the primary array is represented as a binary table:
 
142
      each group of the primary array is a row in the table,
 
143
      where the first column contains the group parameters
 
144
      and the second column contains the image itself.
 
145
    */
 
146
           
 
147
    if (fits_is_compressed_image(fptr, status))
 
148
    {
 
149
        /* this is a compressed image in a binary table */
 
150
        lpixel[0] = ncols;
 
151
        lpixel[1] = nrows;
 
152
        lpixel[2] = naxis3;
 
153
       
 
154
        fits_write_compressed_img(fptr, TFLOAT, fpixel, lpixel,
 
155
            0,  array, NULL, status);
 
156
    
 
157
        return(*status);
 
158
    }
 
159
 
 
160
    tablerow=maxvalue(1,group);
 
161
 
 
162
    if (ncols == naxis1 && nrows == naxis2)  /* arrays have same size? */
 
163
    {
 
164
      /* all the image pixels are contiguous, so write all at once */
 
165
      ffpcle(fptr, 2, tablerow, 1L, naxis1 * naxis2 * naxis3, array, status);
 
166
      return(*status);
 
167
    }
 
168
 
 
169
    if (ncols < naxis1 || nrows < naxis2)
 
170
       return(*status = BAD_DIMEN);
 
171
 
 
172
    nfits = 1;   /* next pixel in FITS image to write to */
 
173
    narray = 0;  /* next pixel in input array to be written */
 
174
 
 
175
    /* loop over naxis3 planes in the data cube */
 
176
    for (jj = 0; jj < naxis3; jj++)
 
177
    {
 
178
      /* loop over the naxis2 rows in the FITS image, */
 
179
      /* writing naxis1 pixels to each row            */
 
180
 
 
181
      for (ii = 0; ii < naxis2; ii++)
 
182
      {
 
183
       if (ffpcle(fptr, 2, tablerow, nfits, naxis1,&array[narray],status) > 0)
 
184
         return(*status);
 
185
 
 
186
       nfits += naxis1;
 
187
       narray += ncols;
 
188
      }
 
189
      narray += (nrows - naxis2) * ncols;
 
190
    }
 
191
    return(*status);
 
192
}
 
193
/*--------------------------------------------------------------------------*/
 
194
int ffpsse(fitsfile *fptr,   /* I - FITS file pointer                       */
 
195
           long  group,      /* I - group to write(1 = 1st group)           */
 
196
           long  naxis,      /* I - number of data axes in array            */
 
197
           long  *naxes,     /* I - size of each FITS axis                  */
 
198
           long  *fpixel,    /* I - 1st pixel in each axis to write (1=1st) */
 
199
           long  *lpixel,    /* I - last pixel in each axis to write        */
 
200
           float *array,     /* I - array to be written                     */
 
201
           int  *status)     /* IO - error status                           */
 
202
/*
 
203
  Write a subsection of pixels to the primary array or image.
 
204
  A subsection is defined to be any contiguous rectangular
 
205
  array of pixels within the n-dimensional FITS data file.
 
206
  Data conversion and scaling will be performed if necessary 
 
207
  (e.g, if the datatype of the FITS array is not the same as
 
208
  the array being written).
 
209
*/
 
210
{
 
211
    long tablerow;
 
212
    long fpix[7], irange[7], dimen[7], astart, pstart;
 
213
    long off2, off3, off4, off5, off6, off7;
 
214
    long st10, st20, st30, st40, st50, st60, st70;
 
215
    long st1, st2, st3, st4, st5, st6, st7;
 
216
    long ii, i1, i2, i3, i4, i5, i6, i7;
 
217
 
 
218
    if (*status > 0)
 
219
        return(*status);
 
220
 
 
221
    if (fits_is_compressed_image(fptr, status))
 
222
    {
 
223
        /* this is a compressed image in a binary table */
 
224
 
 
225
        fits_write_compressed_img(fptr, TFLOAT, fpixel, lpixel,
 
226
            0,  array, NULL, status);
 
227
    
 
228
        return(*status);
 
229
    }
 
230
 
 
231
    if (naxis < 1 || naxis > 7)
 
232
      return(*status = BAD_DIMEN);
 
233
 
 
234
    tablerow=maxvalue(1,group);
 
235
 
 
236
     /* calculate the size and number of loops to perform in each dimension */
 
237
    for (ii = 0; ii < 7; ii++)
 
238
    {
 
239
      fpix[ii]=1;
 
240
      irange[ii]=1;
 
241
      dimen[ii]=1;
 
242
    }
 
243
 
 
244
    for (ii = 0; ii < naxis; ii++)
 
245
    {    
 
246
      fpix[ii]=fpixel[ii];
 
247
      irange[ii]=lpixel[ii]-fpixel[ii]+1;
 
248
      dimen[ii]=naxes[ii];
 
249
    }
 
250
 
 
251
    i1=irange[0];
 
252
 
 
253
    /* compute the pixel offset between each dimension */
 
254
    off2 =     dimen[0];
 
255
    off3 = off2 * dimen[1];
 
256
    off4 = off3 * dimen[2];
 
257
    off5 = off4 * dimen[3];
 
258
    off6 = off5 * dimen[4];
 
259
    off7 = off6 * dimen[5];
 
260
 
 
261
    st10 = fpix[0];
 
262
    st20 = (fpix[1] - 1) * off2;
 
263
    st30 = (fpix[2] - 1) * off3;
 
264
    st40 = (fpix[3] - 1) * off4;
 
265
    st50 = (fpix[4] - 1) * off5;
 
266
    st60 = (fpix[5] - 1) * off6;
 
267
    st70 = (fpix[6] - 1) * off7;
 
268
 
 
269
    /* store the initial offset in each dimension */
 
270
    st1 = st10;
 
271
    st2 = st20;
 
272
    st3 = st30;
 
273
    st4 = st40;
 
274
    st5 = st50;
 
275
    st6 = st60;
 
276
    st7 = st70;
 
277
 
 
278
    astart = 0;
 
279
 
 
280
    for (i7 = 0; i7 < irange[6]; i7++)
 
281
    {
 
282
     for (i6 = 0; i6 < irange[5]; i6++)
 
283
     {
 
284
      for (i5 = 0; i5 < irange[4]; i5++)
 
285
      {
 
286
       for (i4 = 0; i4 < irange[3]; i4++)
 
287
       {
 
288
        for (i3 = 0; i3 < irange[2]; i3++)
 
289
        {
 
290
         pstart = st1 + st2 + st3 + st4 + st5 + st6 + st7;
 
291
         for (i2 = 0; i2 < irange[1]; i2++)
 
292
         {
 
293
           if (ffpcle(fptr, 2, tablerow, pstart, i1, &array[astart],
 
294
              status) > 0)
 
295
              return(*status);
 
296
 
 
297
           astart += i1;
 
298
           pstart += off2;
 
299
         }
 
300
         st2 = st20;
 
301
         st3 = st3+off3;    
 
302
        }
 
303
        st3 = st30;
 
304
        st4 = st4+off4;
 
305
       }
 
306
       st4 = st40;
 
307
       st5 = st5+off5;
 
308
      }
 
309
      st5 = st50;
 
310
      st6 = st6+off6;
 
311
     }
 
312
     st6 = st60;
 
313
     st7 = st7+off7;
 
314
    }
 
315
    return(*status);
 
316
}
 
317
/*--------------------------------------------------------------------------*/
 
318
int ffpgpe( fitsfile *fptr,   /* I - FITS file pointer                      */
 
319
            long  group,      /* I - group to write(1 = 1st group)          */
 
320
            long  firstelem,  /* I - first vector element to write(1 = 1st) */
 
321
            long  nelem,      /* I - number of values to write              */
 
322
            float *array,     /* I - array of values that are written       */
 
323
            int  *status)     /* IO - error status                          */
 
324
/*
 
325
  Write an array of group parameters to the primary array. Data conversion
 
326
  and scaling will be performed if necessary (e.g, if the datatype of
 
327
  the FITS array is not the same as the array being written).
 
328
*/
 
329
{
 
330
    long row;
 
331
 
 
332
    /*
 
333
      the primary array is represented as a binary table:
 
334
      each group of the primary array is a row in the table,
 
335
      where the first column contains the group parameters
 
336
      and the second column contains the image itself.
 
337
    */
 
338
 
 
339
    row=maxvalue(1,group);
 
340
 
 
341
    ffpcle(fptr, 1L, row, firstelem, nelem, array, status);
 
342
    return(*status);
 
343
}
 
344
/*--------------------------------------------------------------------------*/
 
345
int ffpcle( fitsfile *fptr,  /* I - FITS file pointer                       */
 
346
            int  colnum,     /* I - number of column to write (1 = 1st col) */
 
347
            long  firstrow,  /* I - first row to write (1 = 1st row)        */
 
348
            long  firstelem, /* I - first vector element to write (1 = 1st) */
 
349
            long  nelem,     /* I - number of values to write               */
 
350
            float *array,    /* I - array of values to write                */
 
351
            int  *status)    /* IO - error status                           */
 
352
/*
 
353
  Write an array of values to a column in the current FITS HDU.
 
354
  The column number may refer to a real column in an ASCII or binary table, 
 
355
  or it may refer to a virtual column in a 1 or more grouped FITS primary
 
356
  array.  FITSIO treats a primary array as a binary table
 
357
  with 2 vector columns: the first column contains the group parameters (often
 
358
  with length = 0) and the second column contains the array of image pixels.
 
359
  Each row of the table represents a group in the case of multigroup FITS
 
360
  images.
 
361
 
 
362
  The input array of values will be converted to the datatype of the column 
 
363
  and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary.
 
364
*/
 
365
{
 
366
    int tcode, maxelem, hdutype, writeraw;
 
367
    long twidth, incre, rownum, remain, next, ntodo;
 
368
    long tnull;
 
369
    OFF_T repeat, startpos, elemnum, large_elem, wrtptr, rowlen;
 
370
    double scale, zero;
 
371
    char tform[20], cform[20];
 
372
    char message[FLEN_ERRMSG];
 
373
 
 
374
    char snull[20];   /*  the FITS null value  */
 
375
 
 
376
    double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */
 
377
    void *buffer;
 
378
 
 
379
    if (*status > 0)           /* inherit input status value if > 0 */
 
380
        return(*status);
 
381
 
 
382
    buffer = cbuff;
 
383
 
 
384
    if (firstelem == USE_LARGE_VALUE)
 
385
        large_elem = large_first_elem_val;
 
386
    else
 
387
        large_elem = firstelem;
 
388
 
 
389
    /*---------------------------------------------------*/
 
390
    /*  Check input and get parameters about the column: */
 
391
    /*---------------------------------------------------*/
 
392
    if (ffgcpr( fptr, colnum, firstrow, large_elem, nelem, 1, &scale, &zero,
 
393
        tform, &twidth, &tcode, &maxelem, &startpos,  &elemnum, &incre,
 
394
        &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0)
 
395
        return(*status);
 
396
 
 
397
 
 
398
    if (tcode == TSTRING)   
 
399
         ffcfmt(tform, cform);     /* derive C format for writing strings */
 
400
 
 
401
    /*
 
402
       if there is no scaling and the native machine format is not byteswapped
 
403
       then we can simply write the raw data bytes into the FITS file if the
 
404
       datatype of the FITS column is the same as the input values.  Otherwise,
 
405
       we must convert the raw values into the scaled and/or machine dependent
 
406
       format in a temporary buffer that has been allocated for this purpose.
 
407
    */
 
408
    if (scale == 1. && zero == 0. && 
 
409
       MACHINE == NATIVE && tcode == TFLOAT)
 
410
    {
 
411
        writeraw = 1;
 
412
        maxelem = nelem;  /* we can write the entire array at one time */
 
413
    }
 
414
    else
 
415
        writeraw = 0;
 
416
 
 
417
    /*---------------------------------------------------------------------*/
 
418
    /*  Now write the pixels to the FITS column.                           */
 
419
    /*  First call the ffXXfYY routine to  (1) convert the datatype        */
 
420
    /*  if necessary, and (2) scale the values by the FITS TSCALn and      */
 
421
    /*  TZEROn linear scaling parameters into a temporary buffer.          */
 
422
    /*---------------------------------------------------------------------*/
 
423
    remain = nelem;           /* remaining number of values to write  */
 
424
    next = 0;                 /* next element in array to be written  */
 
425
    rownum = 0;               /* row number, relative to firstrow     */
 
426
 
 
427
    while (remain)
 
428
    {
 
429
        /* limit the number of pixels to process a one time to the number that
 
430
           will fit in the buffer space or to the number of pixels that remain
 
431
           in the current vector, which ever is smaller.
 
432
        */
 
433
        ntodo = minvalue(remain, maxelem);      
 
434
        ntodo = minvalue(ntodo, (repeat - elemnum));
 
435
 
 
436
        wrtptr = startpos + ((OFF_T)rownum * rowlen) + (elemnum * incre);
 
437
 
 
438
        ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */
 
439
 
 
440
        switch (tcode) 
 
441
        {
 
442
            case (TFLOAT):
 
443
              if (writeraw)
 
444
              {
 
445
                /* write raw input bytes without conversion */
 
446
                ffpr4b(fptr, ntodo, incre, &array[next], status);
 
447
              }
 
448
              else
 
449
              {
 
450
                /* convert the raw data before writing to FITS file */
 
451
                ffr4fr4(&array[next], ntodo, scale, zero,
 
452
                        (float *) buffer, status);
 
453
                ffpr4b(fptr, ntodo, incre, (float *) buffer, status);
 
454
              }
 
455
 
 
456
              break;
 
457
 
 
458
            case (TLONGLONG):
 
459
 
 
460
                ffr4fi8(&array[next], ntodo, scale, zero,
 
461
                        (LONGLONG *) buffer, status);
 
462
                ffpi8b(fptr, ntodo, incre, (long *) buffer, status);
 
463
                break;
 
464
 
 
465
            case (TBYTE):
 
466
 
 
467
                ffr4fi1(&array[next], ntodo, scale, zero, 
 
468
                        (unsigned char *) buffer, status);
 
469
                ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status);
 
470
                break;
 
471
 
 
472
            case (TSHORT):
 
473
 
 
474
                ffr4fi2(&array[next], ntodo, scale, zero,
 
475
                        (short *) buffer, status);
 
476
                ffpi2b(fptr, ntodo, incre, (short *) buffer, status);
 
477
                break;
 
478
 
 
479
            case (TLONG):
 
480
 
 
481
                ffr4fi4(&array[next], ntodo, scale, zero,
 
482
                        (INT32BIT *) buffer, status);
 
483
                ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status);
 
484
                break;
 
485
 
 
486
            case (TDOUBLE):
 
487
                ffr4fr8(&array[next], ntodo, scale, zero,
 
488
                       (double *) buffer, status);
 
489
                ffpr8b(fptr, ntodo, incre, (double *) buffer, status);
 
490
                break;
 
491
 
 
492
            case (TSTRING):  /* numerical column in an ASCII table */
 
493
 
 
494
                if (cform[1] != 's')  /*  "%s" format is a string */
 
495
                {
 
496
                  ffr4fstr(&array[next], ntodo, scale, zero, cform,
 
497
                          twidth, (char *) buffer, status);
 
498
 
 
499
                  if (incre == twidth)    /* contiguous bytes */
 
500
                     ffpbyt(fptr, ntodo * twidth, buffer, status);
 
501
                  else
 
502
                     ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer,
 
503
                            status);
 
504
 
 
505
                  break;
 
506
                }
 
507
                /* can't write to string column, so fall thru to default: */
 
508
 
 
509
            default:  /*  error trap  */
 
510
                sprintf(message, 
 
511
                       "Cannot write numbers to column %d which has format %s",
 
512
                        colnum,tform);
 
513
                ffpmsg(message);
 
514
                if (hdutype == ASCII_TBL)
 
515
                    return(*status = BAD_ATABLE_FORMAT);
 
516
                else
 
517
                    return(*status = BAD_BTABLE_FORMAT);
 
518
 
 
519
        } /* End of switch block */
 
520
 
 
521
        /*-------------------------*/
 
522
        /*  Check for fatal error  */
 
523
        /*-------------------------*/
 
524
        if (*status > 0)  /* test for error during previous write operation */
 
525
        {
 
526
         sprintf(message,
 
527
          "Error writing elements %ld thru %ld of input data array (ffpcle).",
 
528
             next+1, next+ntodo);
 
529
         ffpmsg(message);
 
530
         return(*status);
 
531
        }
 
532
 
 
533
        /*--------------------------------------------*/
 
534
        /*  increment the counters for the next loop  */
 
535
        /*--------------------------------------------*/
 
536
        remain -= ntodo;
 
537
        if (remain)
 
538
        {
 
539
            next += ntodo;
 
540
            elemnum += ntodo;
 
541
            if (elemnum == repeat)  /* completed a row; start on next row */
 
542
            {
 
543
                elemnum = 0;
 
544
                rownum++;
 
545
            }
 
546
        }
 
547
    }  /*  End of main while Loop  */
 
548
 
 
549
 
 
550
    /*--------------------------------*/
 
551
    /*  check for numerical overflow  */
 
552
    /*--------------------------------*/
 
553
    if (*status == OVERFLOW_ERR)
 
554
    {
 
555
        ffpmsg(
 
556
        "Numerical overflow during type conversion while writing FITS data.");
 
557
        *status = NUM_OVERFLOW;
 
558
    }
 
559
 
 
560
    return(*status);
 
561
}
 
562
/*--------------------------------------------------------------------------*/
 
563
int ffpclc( fitsfile *fptr,  /* I - FITS file pointer                       */
 
564
            int  colnum,     /* I - number of column to write (1 = 1st col) */
 
565
            long  firstrow,  /* I - first row to write (1 = 1st row)        */
 
566
            long  firstelem, /* I - first vector element to write (1 = 1st) */
 
567
            long  nelem,     /* I - number of values to write               */
 
568
            float *array,    /* I - array of values to write                */
 
569
            int  *status)    /* IO - error status                           */
 
570
/*
 
571
  Write an array of complex values to a column in the current FITS HDU.
 
572
  Each complex number if interpreted as a pair of float values.
 
573
  The column number may refer to a real column in an ASCII or binary table, 
 
574
  or it may refer to a virtual column in a 1 or more grouped FITS primary
 
575
  array.  FITSIO treats a primary array as a binary table
 
576
  with 2 vector columns: the first column contains the group parameters (often
 
577
  with length = 0) and the second column contains the array of image pixels.
 
578
  Each row of the table represents a group in the case of multigroup FITS
 
579
  images.
 
580
 
 
581
  The input array of values will be converted to the datatype of the column
 
582
  if necessary, but normally complex values should only be written to a binary
 
583
  table with TFORMn = 'rC' where r is an optional repeat count. The TSCALn and
 
584
  TZERO keywords should not be used with complex numbers because mathmatically
 
585
  the scaling should only be applied to the real (first) component of the
 
586
  complex value.
 
587
*/
 
588
{
 
589
    /* simply multiply the number of elements by 2, and call ffpcle */
 
590
 
 
591
    ffpcle(fptr, colnum, firstrow, (firstelem - 1) * 2 + 1,
 
592
            nelem * 2, array, status);
 
593
    return(*status);
 
594
}
 
595
/*--------------------------------------------------------------------------*/
 
596
int ffpcne( fitsfile *fptr,  /* I - FITS file pointer                       */
 
597
            int  colnum,     /* I - number of column to write (1 = 1st col) */
 
598
            long  firstrow,  /* I - first row to write (1 = 1st row)        */
 
599
            long  firstelem, /* I - first vector element to write (1 = 1st) */
 
600
            long  nelem,     /* I - number of values to write               */
 
601
            float *array,    /* I - array of values to write                */
 
602
            float  nulvalue, /* I - value used to flag undefined pixels     */
 
603
            int  *status)    /* IO - error status                           */
 
604
/*
 
605
  Write an array of elements to the specified column of a table.  Any input
 
606
  pixels equal to the value of nulvalue will be replaced by the appropriate
 
607
  null value in the output FITS file. 
 
608
 
 
609
  The input array of values will be converted to the datatype of the column 
 
610
  and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary
 
611
*/
 
612
{
 
613
    tcolumn *colptr;
 
614
    long  ngood = 0, nbad = 0, ii, fstrow;
 
615
    OFF_T large_elem, repeat, first, fstelm;
 
616
 
 
617
    if (*status > 0)
 
618
        return(*status);
 
619
 
 
620
    /* reset position to the correct HDU if necessary */
 
621
    if (fptr->HDUposition != (fptr->Fptr)->curhdu)
 
622
    {
 
623
        ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
 
624
    }
 
625
    else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
 
626
    {
 
627
        if ( ffrdef(fptr, status) > 0)               /* rescan header */
 
628
            return(*status);
 
629
    }
 
630
 
 
631
    colptr  = (fptr->Fptr)->tableptr;   /* point to first column */
 
632
    colptr += (colnum - 1);     /* offset to correct column structure */
 
633
 
 
634
    repeat = colptr->trepeat;  /* repeat count for this column */
 
635
 
 
636
    if (firstelem == USE_LARGE_VALUE)
 
637
        large_elem = large_first_elem_val;
 
638
    else
 
639
        large_elem = firstelem;
 
640
 
 
641
    /* hereafter, pass first element parameter via global variable */
 
642
    firstelem = USE_LARGE_VALUE;
 
643
 
 
644
    /* absolute element number in the column */
 
645
    first = (firstrow - 1) * repeat + large_elem;
 
646
 
 
647
    for (ii = 0; ii < nelem; ii++)
 
648
    {
 
649
      if (array[ii] != nulvalue)  /* is this a good pixel? */
 
650
      {
 
651
         if (nbad)  /* write previous string of bad pixels */
 
652
         {
 
653
            fstelm = ii - nbad + first;  /* absolute element number */
 
654
            fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
 
655
            fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */
 
656
            large_first_elem_val = fstelm;
 
657
 
 
658
            if (ffpclu(fptr, colnum, fstrow, firstelem, nbad, status) > 0)
 
659
                return(*status);
 
660
 
 
661
            nbad=0;
 
662
         }
 
663
 
 
664
         ngood = ngood +1;  /* the consecutive number of good pixels */
 
665
      }
 
666
      else
 
667
      {
 
668
         if (ngood)  /* write previous string of good pixels */
 
669
         {
 
670
            fstelm = ii - ngood + first;  /* absolute element number */
 
671
            fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
 
672
            fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */
 
673
            large_first_elem_val = fstelm;
 
674
 
 
675
            if (ffpcle(fptr, colnum, fstrow, firstelem, ngood, &array[ii-ngood],
 
676
                status) > 0)
 
677
                return(*status);
 
678
 
 
679
            ngood=0;
 
680
         }
 
681
 
 
682
         nbad = nbad +1;  /* the consecutive number of bad pixels */
 
683
      }
 
684
    }
 
685
 
 
686
    /* finished loop;  now just write the last set of pixels */
 
687
 
 
688
    if (ngood)  /* write last string of good pixels */
 
689
    {
 
690
      fstelm = ii - ngood + first;  /* absolute element number */
 
691
      fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
 
692
      fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */
 
693
      large_first_elem_val = fstelm;
 
694
 
 
695
      ffpcle(fptr, colnum, fstrow, firstelem, ngood, &array[ii-ngood], status);
 
696
    }
 
697
    else if (nbad) /* write last string of bad pixels */
 
698
    {
 
699
      fstelm = ii - nbad + first;  /* absolute element number */
 
700
      fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
 
701
      fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */
 
702
      large_first_elem_val = fstelm;
 
703
      ffpclu(fptr, colnum, fstrow, firstelem, nbad, status);
 
704
    }
 
705
 
 
706
    return(*status);
 
707
}
 
708
/*--------------------------------------------------------------------------*/
 
709
int ffr4fi1(float *input,          /* I - array of values to be converted  */
 
710
            long ntodo,            /* I - number of elements in the array  */
 
711
            double scale,          /* I - FITS TSCALn or BSCALE value      */
 
712
            double zero,           /* I - FITS TZEROn or BZERO  value      */
 
713
            unsigned char *output, /* O - output array of converted values */
 
714
            int *status)           /* IO - error status                    */
 
715
/*
 
716
  Copy input to output prior to writing output to a FITS file.
 
717
  Do datatype conversion and scaling if required.
 
718
*/
 
719
{
 
720
    long ii;
 
721
    double dvalue;
 
722
 
 
723
    if (scale == 1. && zero == 0.)
 
724
    {       
 
725
        for (ii = 0; ii < ntodo; ii++)
 
726
        {
 
727
            if (input[ii] < DUCHAR_MIN)
 
728
            {
 
729
                *status = OVERFLOW_ERR;
 
730
                output[ii] = 0;
 
731
            }
 
732
            else if (input[ii] > DUCHAR_MAX)
 
733
            {
 
734
                *status = OVERFLOW_ERR;
 
735
                output[ii] = UCHAR_MAX;
 
736
            }
 
737
            else
 
738
                output[ii] = (unsigned char) input[ii];
 
739
        }
 
740
    }
 
741
    else
 
742
    {
 
743
        for (ii = 0; ii < ntodo; ii++)
 
744
        {
 
745
            dvalue = (input[ii] - zero) / scale;
 
746
 
 
747
            if (dvalue < DUCHAR_MIN)
 
748
            {
 
749
                *status = OVERFLOW_ERR;
 
750
                output[ii] = 0;
 
751
            }
 
752
            else if (dvalue > DUCHAR_MAX)
 
753
            {
 
754
                *status = OVERFLOW_ERR;
 
755
                output[ii] = UCHAR_MAX;
 
756
            }
 
757
            else
 
758
                output[ii] = (unsigned char) (dvalue + .5);
 
759
        }
 
760
    }
 
761
    return(*status);
 
762
}
 
763
/*--------------------------------------------------------------------------*/
 
764
int ffr4fi2(float *input,      /* I - array of values to be converted  */
 
765
            long ntodo,        /* I - number of elements in the array  */
 
766
            double scale,      /* I - FITS TSCALn or BSCALE value      */
 
767
            double zero,       /* I - FITS TZEROn or BZERO  value      */
 
768
            short *output,     /* O - output array of converted values */
 
769
            int *status)       /* IO - error status                    */
 
770
/*
 
771
  Copy input to output prior to writing output to a FITS file.
 
772
  Do datatype conversion and scaling if required.
 
773
*/
 
774
{
 
775
    long ii;
 
776
    double dvalue;
 
777
 
 
778
    if (scale == 1. && zero == 0.)
 
779
    {       
 
780
        for (ii = 0; ii < ntodo; ii++)
 
781
        {
 
782
            if (input[ii] < DSHRT_MIN)
 
783
            {
 
784
                *status = OVERFLOW_ERR;
 
785
                output[ii] = SHRT_MIN;
 
786
            }
 
787
            else if (input[ii] > DSHRT_MAX)
 
788
            {
 
789
                *status = OVERFLOW_ERR;
 
790
                output[ii] = SHRT_MAX;
 
791
            }
 
792
            else
 
793
                output[ii] = (short) input[ii];
 
794
        }
 
795
    }
 
796
    else
 
797
    {
 
798
        for (ii = 0; ii < ntodo; ii++)
 
799
        {
 
800
            dvalue = (input[ii] - zero) / scale;
 
801
 
 
802
            if (dvalue < DSHRT_MIN)
 
803
            {
 
804
                *status = OVERFLOW_ERR;
 
805
                output[ii] = SHRT_MIN;
 
806
            }
 
807
            else if (dvalue > DSHRT_MAX)
 
808
            {
 
809
                *status = OVERFLOW_ERR;
 
810
                output[ii] = SHRT_MAX;
 
811
            }
 
812
            else
 
813
            {
 
814
                if (dvalue >= 0)
 
815
                    output[ii] = (short) (dvalue + .5);
 
816
                else
 
817
                    output[ii] = (short) (dvalue - .5);
 
818
            }
 
819
        }
 
820
    }
 
821
    return(*status);
 
822
}
 
823
/*--------------------------------------------------------------------------*/
 
824
int ffr4fi4(float *input,      /* I - array of values to be converted  */
 
825
            long ntodo,        /* I - number of elements in the array  */
 
826
            double scale,      /* I - FITS TSCALn or BSCALE value      */
 
827
            double zero,       /* I - FITS TZEROn or BZERO  value      */
 
828
            INT32BIT *output,  /* O - output array of converted values */
 
829
            int *status)       /* IO - error status                    */
 
830
/*
 
831
  Copy input to output prior to writing output to a FITS file.
 
832
  Do datatype conversion and scaling if required.
 
833
*/
 
834
{
 
835
    long ii;
 
836
    double dvalue;
 
837
 
 
838
    if (scale == 1. && zero == 0.)
 
839
    {       
 
840
        for (ii = 0; ii < ntodo; ii++)
 
841
        {
 
842
            if (input[ii] < DINT_MIN)
 
843
            {
 
844
                *status = OVERFLOW_ERR;
 
845
                output[ii] = INT32_MIN;
 
846
            }
 
847
            else if (input[ii] > DINT_MAX)
 
848
            {
 
849
                *status = OVERFLOW_ERR;
 
850
                output[ii] = INT32_MAX;
 
851
            }
 
852
            else
 
853
                output[ii] = (INT32BIT) input[ii];
 
854
        }
 
855
    }
 
856
    else
 
857
    {
 
858
        for (ii = 0; ii < ntodo; ii++)
 
859
        {
 
860
            dvalue = (input[ii] - zero) / scale;
 
861
 
 
862
            if (dvalue < DINT_MIN)
 
863
            {
 
864
                *status = OVERFLOW_ERR;
 
865
                output[ii] = INT32_MIN;
 
866
            }
 
867
            else if (dvalue > DINT_MAX)
 
868
            {
 
869
                *status = OVERFLOW_ERR;
 
870
                output[ii] = INT32_MAX;
 
871
            }
 
872
            else
 
873
            {
 
874
                if (dvalue >= 0)
 
875
                    output[ii] = (INT32BIT) (dvalue + .5);
 
876
                else
 
877
                    output[ii] = (INT32BIT) (dvalue - .5);
 
878
            }
 
879
        }
 
880
    }
 
881
    return(*status);
 
882
}
 
883
/*--------------------------------------------------------------------------*/
 
884
int ffr4fi8(float *input,      /* I - array of values to be converted  */
 
885
            long ntodo,        /* I - number of elements in the array  */
 
886
            double scale,      /* I - FITS TSCALn or BSCALE value      */
 
887
            double zero,       /* I - FITS TZEROn or BZERO  value      */
 
888
            LONGLONG *output,  /* O - output array of converted values */
 
889
            int *status)       /* IO - error status                    */
 
890
/*
 
891
  Copy input to output prior to writing output to a FITS file.
 
892
  Do datatype conversion and scaling if required.
 
893
*/
 
894
{
 
895
#if (LONGSIZE == 32) && (! defined HAVE_LONGLONG)
 
896
 
 
897
/* don't have a native 8-byte integer, so have to construct the */
 
898
/* 2 equivalent 4-byte integers have the same bit pattern */
 
899
 
 
900
    unsigned long *uoutput;
 
901
    long ii, jj, kk, temp;
 
902
    double dvalue;
 
903
 
 
904
    uoutput = (unsigned long *) output;
 
905
 
 
906
#if BYTESWAPPED  /* jj points to the most significant part of the 8-byte int */
 
907
    jj = 1;
 
908
    kk = 0;
 
909
#else
 
910
    jj = 0;
 
911
    kk = 1;
 
912
#endif
 
913
 
 
914
    if (scale == 1. && zero == 0.)
 
915
    {       
 
916
        for (ii = 0; ii < ntodo; ii++, jj += 2, kk += 2)
 
917
        {
 
918
            if (input[ii] < DLONGLONG_MIN)
 
919
            {
 
920
                *status = OVERFLOW_ERR;
 
921
                output[jj] = LONG_MIN;
 
922
                output[kk] = 0;
 
923
            }
 
924
            else if (input[ii] > DLONGLONG_MAX)
 
925
            {
 
926
                *status = OVERFLOW_ERR;
 
927
                output[jj] = LONG_MAX;
 
928
                output[kk] = -1;
 
929
            }
 
930
            else
 
931
            {
 
932
               if (input[ii] < 0)
 
933
                {
 
934
                   temp = (input[ii] + 1.) / 4294967296. - 1.;
 
935
                   output[jj] = temp;
 
936
                   uoutput[kk] = 4294967296.  + 
 
937
                      (input[ii] - (double) (temp + 1) * 4294967296.);
 
938
                }
 
939
                else
 
940
                {
 
941
                   temp = input[ii] / 4294967296.;
 
942
                   output[jj] = temp;
 
943
                   uoutput[kk] = input[ii] - (double) temp * 4294967296.;
 
944
                }
 
945
            }
 
946
        }
 
947
    }
 
948
    else
 
949
    {
 
950
        for (ii = 0; ii < ntodo; ii++, jj += 2, kk += 2)
 
951
        {
 
952
            dvalue = (input[ii] - zero) / scale;
 
953
 
 
954
            if (dvalue < DLONGLONG_MIN)
 
955
            {
 
956
                *status = OVERFLOW_ERR;
 
957
                output[jj] = LONG_MIN;
 
958
                output[kk] = 0;
 
959
            }
 
960
            else if (dvalue > DLONGLONG_MAX)
 
961
            {
 
962
                *status = OVERFLOW_ERR;
 
963
                output[jj] = LONG_MAX;
 
964
                output[kk] = -1;
 
965
            }
 
966
            else
 
967
            {
 
968
               if (dvalue < 0)
 
969
                {
 
970
                   temp = (dvalue + 1.) / 4294967296. - 1.;
 
971
                   output[jj] = temp;
 
972
                   uoutput[kk] = 4294967296.  + 
 
973
                      (dvalue - (double) (temp + 1) * 4294967296.);
 
974
                }
 
975
                else
 
976
                {
 
977
                   temp = dvalue / 4294967296.;
 
978
                   output[jj] = temp;
 
979
                   uoutput[kk] = dvalue - (double) temp * 4294967296.;
 
980
                }
 
981
            }
 
982
        }
 
983
    }
 
984
 
 
985
#else
 
986
 
 
987
/* this is the much simpler case where the native 8-byte integer exists */
 
988
 
 
989
    long ii;
 
990
    double dvalue;
 
991
 
 
992
    if (scale == 1. && zero == 0.)
 
993
    {       
 
994
        for (ii = 0; ii < ntodo; ii++)
 
995
        {
 
996
            if (input[ii] < DLONGLONG_MIN)
 
997
            {
 
998
                *status = OVERFLOW_ERR;
 
999
                output[ii] = LONGLONG_MIN;
 
1000
            }
 
1001
            else if (input[ii] > DLONGLONG_MAX)
 
1002
            {
 
1003
                *status = OVERFLOW_ERR;
 
1004
                output[ii] = LONGLONG_MAX;
 
1005
            }
 
1006
            else
 
1007
                output[ii] = (long) input[ii];
 
1008
        }
 
1009
    }
 
1010
    else
 
1011
    {
 
1012
        for (ii = 0; ii < ntodo; ii++)
 
1013
        {
 
1014
            dvalue = (input[ii] - zero) / scale;
 
1015
 
 
1016
            if (dvalue < DLONGLONG_MIN)
 
1017
            {
 
1018
                *status = OVERFLOW_ERR;
 
1019
                output[ii] = LONGLONG_MIN;
 
1020
            }
 
1021
            else if (dvalue > DINT_MAX)
 
1022
            {
 
1023
                *status = OVERFLOW_ERR;
 
1024
                output[ii] = LONGLONG_MAX;
 
1025
            }
 
1026
            else
 
1027
            {
 
1028
                if (dvalue >= 0)
 
1029
                    output[ii] = (LONGLONG) (dvalue + .5);
 
1030
                else
 
1031
                    output[ii] = (LONGLONG) (dvalue - .5);
 
1032
            }
 
1033
        }
 
1034
    }
 
1035
 
 
1036
#endif
 
1037
 
 
1038
    return(*status);
 
1039
}
 
1040
/*--------------------------------------------------------------------------*/
 
1041
int ffr4fr4(float *input,      /* I - array of values to be converted  */
 
1042
            long ntodo,        /* I - number of elements in the array  */
 
1043
            double scale,      /* I - FITS TSCALn or BSCALE value      */
 
1044
            double zero,       /* I - FITS TZEROn or BZERO  value      */
 
1045
            float *output,     /* O - output array of converted values */
 
1046
            int *status)       /* IO - error status                    */
 
1047
/*
 
1048
  Copy input to output prior to writing output to a FITS file.
 
1049
  Do datatype conversion and scaling if required.
 
1050
*/
 
1051
{
 
1052
    long ii;
 
1053
 
 
1054
    if (scale == 1. && zero == 0.)
 
1055
    {       
 
1056
      memcpy(output, input, ntodo * sizeof(float) ); /* copy input to output */
 
1057
    }
 
1058
    else
 
1059
    {
 
1060
        for (ii = 0; ii < ntodo; ii++)
 
1061
            output[ii] = (input[ii] - zero) / scale;
 
1062
    }
 
1063
    return(*status);
 
1064
}
 
1065
/*--------------------------------------------------------------------------*/
 
1066
int ffr4fr8(float *input,      /* I - array of values to be converted  */
 
1067
            long ntodo,        /* I - number of elements in the array  */
 
1068
            double scale,      /* I - FITS TSCALn or BSCALE value      */
 
1069
            double zero,       /* I - FITS TZEROn or BZERO  value      */
 
1070
            double *output,    /* O - output array of converted values */
 
1071
            int *status)       /* IO - error status                    */
 
1072
/*
 
1073
  Copy input to output prior to writing output to a FITS file.
 
1074
  Do datatype conversion and scaling if required.
 
1075
*/
 
1076
{
 
1077
    long ii;
 
1078
 
 
1079
    if (scale == 1. && zero == 0.)
 
1080
    {       
 
1081
        for (ii = 0; ii < ntodo; ii++)
 
1082
                output[ii] = (double) input[ii];
 
1083
    }
 
1084
    else
 
1085
    {
 
1086
        for (ii = 0; ii < ntodo; ii++)
 
1087
            output[ii] = (input[ii] - zero) / scale;
 
1088
    }
 
1089
    return(*status);
 
1090
}
 
1091
/*--------------------------------------------------------------------------*/
 
1092
int ffr4fstr(float *input,     /* I - array of values to be converted  */
 
1093
            long ntodo,        /* I - number of elements in the array  */
 
1094
            double scale,      /* I - FITS TSCALn or BSCALE value      */
 
1095
            double zero,       /* I - FITS TZEROn or BZERO  value      */
 
1096
            char *cform,       /* I - format for output string values  */
 
1097
            long twidth,       /* I - width of each field, in chars    */
 
1098
            char *output,      /* O - output array of converted values */
 
1099
            int *status)       /* IO - error status                    */
 
1100
/*
 
1101
  Copy input to output prior to writing output to a FITS file.
 
1102
  Do scaling if required.
 
1103
*/
 
1104
{
 
1105
    long ii;
 
1106
    double dvalue;
 
1107
 
 
1108
    if (scale == 1. && zero == 0.)
 
1109
    {       
 
1110
        for (ii = 0; ii < ntodo; ii++)
 
1111
        {
 
1112
           sprintf(output, cform, (double) input[ii]);
 
1113
           output += twidth;
 
1114
 
 
1115
           if (*output)  /* if this char != \0, then overflow occurred */
 
1116
              *status = OVERFLOW_ERR;
 
1117
        }
 
1118
    }
 
1119
    else
 
1120
    {
 
1121
        for (ii = 0; ii < ntodo; ii++)
 
1122
        {
 
1123
          dvalue = (input[ii] - zero) / scale;
 
1124
          sprintf(output, cform, dvalue);
 
1125
          output += twidth;
 
1126
 
 
1127
          if (*output)  /* if this char != \0, then overflow occurred */
 
1128
            *status = OVERFLOW_ERR;
 
1129
        }
 
1130
    }
 
1131
    return(*status);
 
1132
}