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

« back to all changes in this revision

Viewing changes to putcolb.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, putcolb.c, contains routines that write data elements to    */
 
2
/*  a FITS image or table with char (byte) 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 ffpprb( 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
            unsigned char *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
    unsigned char 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, TBYTE, large_first_elem_val, nelem,
 
48
            0, array, &nullvalue, status);
 
49
        return(*status);
 
50
    }
 
51
 
 
52
    row=maxvalue(1,group);
 
53
 
 
54
    ffpclb(fptr, 2, row, firstelem, nelem, array, status);
 
55
    return(*status);
 
56
}
 
57
/*--------------------------------------------------------------------------*/
 
58
int ffppnb( 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
            unsigned char *array, /* I - array of values that are written   */
 
63
            unsigned char 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
    unsigned char 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, TBYTE, large_first_elem_val, nelem,
 
93
            1, array, &nullvalue, status);
 
94
        return(*status);
 
95
    }
 
96
 
 
97
    row=maxvalue(1,group);
 
98
 
 
99
    ffpcnb(fptr, 2, row, firstelem, nelem, array, nulval, status);
 
100
    return(*status);
 
101
}
 
102
/*--------------------------------------------------------------------------*/
 
103
int ffp2db(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
           unsigned char *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
    ffp3db(fptr, group, ncols, naxis2, naxis1, naxis2, 1, array, status);
 
119
 
 
120
    return(*status);
 
121
}
 
122
/*--------------------------------------------------------------------------*/
 
123
int ffp3db(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
           unsigned char *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, TBYTE, 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
      ffpclb(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 (ffpclb(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 ffpssb(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
           unsigned char *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, TBYTE, 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 (ffpclb(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 ffpgpb( 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
            unsigned char *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
    ffpclb(fptr, 1L, row, firstelem, nelem, array, status);
 
342
    return(*status);
 
343
}
 
344
/*--------------------------------------------------------------------------*/
 
345
int ffpclb( 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
            unsigned char *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 with
 
357
  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
    if (tcode == TSTRING)   
 
398
         ffcfmt(tform, cform);     /* derive C format for writing strings */
 
399
 
 
400
    /*
 
401
      if there is no scaling 
 
402
      then we can simply write the raw data bytes into the FITS file if the
 
403
      datatype of the FITS column is the same as the input values.  Otherwise,
 
404
      we must convert the raw values into the scaled and/or machine dependent
 
405
      format in a temporary buffer that has been allocated for this purpose.
 
406
    */
 
407
    if (scale == 1. && zero == 0. && tcode == TBYTE)
 
408
    {
 
409
        writeraw = 1;
 
410
        maxelem = nelem;  /* we can write the entire array at one time */
 
411
    }
 
412
    else
 
413
        writeraw = 0;
 
414
 
 
415
    /*---------------------------------------------------------------------*/
 
416
    /*  Now write the pixels to the FITS column.                           */
 
417
    /*  First call the ffXXfYY routine to  (1) convert the datatype        */
 
418
    /*  if necessary, and (2) scale the values by the FITS TSCALn and      */
 
419
    /*  TZEROn linear scaling parameters into a temporary buffer.          */
 
420
    /*---------------------------------------------------------------------*/
 
421
    remain = nelem;           /* remaining number of values to write  */
 
422
    next = 0;                 /* next element in array to be written  */
 
423
    rownum = 0;               /* row number, relative to firstrow     */
 
424
 
 
425
    while (remain)
 
426
    {
 
427
        /* limit the number of pixels to process a one time to the number that
 
428
           will fit in the buffer space or to the number of pixels that remain
 
429
           in the current vector, which ever is smaller.
 
430
        */
 
431
        ntodo = minvalue(remain, maxelem);      
 
432
        ntodo = minvalue(ntodo, (repeat - elemnum));
 
433
 
 
434
        wrtptr = startpos + ((OFF_T)rownum * rowlen) + (elemnum * incre);
 
435
        ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */
 
436
 
 
437
        switch (tcode) 
 
438
        {
 
439
            case (TBYTE):
 
440
              if (writeraw)
 
441
              {
 
442
                /* write raw input bytes without conversion */
 
443
                ffpi1b(fptr, ntodo, incre, &array[next], status);
 
444
              }
 
445
              else
 
446
              {
 
447
                /* convert the raw data before writing to FITS file */
 
448
                ffi1fi1(&array[next], ntodo, scale, zero,
 
449
                        (unsigned char *) buffer, status);
 
450
                ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status);
 
451
              }
 
452
 
 
453
              break;
 
454
 
 
455
            case (TLONGLONG):
 
456
 
 
457
                ffi1fi8(&array[next], ntodo, scale, zero,
 
458
                        (LONGLONG *) buffer, status);
 
459
                ffpi8b(fptr, ntodo, incre, (long *) buffer, status);
 
460
                break;
 
461
 
 
462
            case (TSHORT):
 
463
 
 
464
                ffi1fi2(&array[next], ntodo, scale, zero,
 
465
                        (short *) buffer, status);
 
466
                ffpi2b(fptr, ntodo, incre, (short *) buffer, status);
 
467
                break;
 
468
 
 
469
            case (TLONG):
 
470
 
 
471
                ffi1fi4(&array[next], ntodo, scale, zero,
 
472
                        (INT32BIT *) buffer, status);
 
473
                ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status);
 
474
                break;
 
475
 
 
476
            case (TFLOAT):
 
477
 
 
478
                ffi1fr4(&array[next], ntodo, scale, zero,
 
479
                        (float *)  buffer, status);
 
480
                ffpr4b(fptr, ntodo, incre, (float *) buffer, status);
 
481
                break;
 
482
 
 
483
            case (TDOUBLE):
 
484
                ffi1fr8(&array[next], ntodo, scale, zero,
 
485
                        (double *) buffer, status);
 
486
                ffpr8b(fptr, ntodo, incre, (double *) buffer, status);
 
487
                break;
 
488
 
 
489
            case (TSTRING):  /* numerical column in an ASCII table */
 
490
 
 
491
                if (strchr(tform,'A'))
 
492
                {
 
493
                    /* write raw input bytes without conversion        */
 
494
                    /* This case is a hack to let users write a stream */
 
495
                    /* of bytes directly to the 'A' format column      */
 
496
 
 
497
                    if (incre == twidth)
 
498
                        ffpbyt(fptr, ntodo, &array[next], status);
 
499
                    else
 
500
                        ffpbytoff(fptr, twidth, ntodo/twidth, incre - twidth, 
 
501
                                &array[next], status);
 
502
                    break;
 
503
                }
 
504
                else if (cform[1] != 's')  /*  "%s" format is a string */
 
505
                {
 
506
                  ffi1fstr(&array[next], ntodo, scale, zero, cform,
 
507
                          twidth, (char *) buffer, status);
 
508
 
 
509
                  if (incre == twidth)    /* contiguous bytes */
 
510
                     ffpbyt(fptr, ntodo * twidth, buffer, status);
 
511
                  else
 
512
                     ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer,
 
513
                            status);
 
514
                  break;
 
515
                }
 
516
                /* can't write to string column, so fall thru to default: */
 
517
 
 
518
            default:  /*  error trap  */
 
519
                sprintf(message, 
 
520
                       "Cannot write numbers to column %d which has format %s",
 
521
                        colnum,tform);
 
522
                ffpmsg(message);
 
523
                if (hdutype == ASCII_TBL)
 
524
                    return(*status = BAD_ATABLE_FORMAT);
 
525
                else
 
526
                    return(*status = BAD_BTABLE_FORMAT);
 
527
 
 
528
        } /* End of switch block */
 
529
 
 
530
        /*-------------------------*/
 
531
        /*  Check for fatal error  */
 
532
        /*-------------------------*/
 
533
        if (*status > 0)  /* test for error during previous write operation */
 
534
        {
 
535
          sprintf(message,
 
536
          "Error writing elements %ld thru %ld of input data array (ffpclb).",
 
537
              next+1, next+ntodo);
 
538
          ffpmsg(message);
 
539
          return(*status);
 
540
        }
 
541
 
 
542
        /*--------------------------------------------*/
 
543
        /*  increment the counters for the next loop  */
 
544
        /*--------------------------------------------*/
 
545
        remain -= ntodo;
 
546
        if (remain)
 
547
        {
 
548
            next += ntodo;
 
549
            elemnum += ntodo;
 
550
            if (elemnum == repeat)  /* completed a row; start on next row */
 
551
            {
 
552
                elemnum = 0;
 
553
                rownum++;
 
554
            }
 
555
        }
 
556
    }  /*  End of main while Loop  */
 
557
 
 
558
 
 
559
    /*--------------------------------*/
 
560
    /*  check for numerical overflow  */
 
561
    /*--------------------------------*/
 
562
    if (*status == OVERFLOW_ERR)
 
563
    {
 
564
      ffpmsg(
 
565
      "Numerical overflow during type conversion while writing FITS data.");
 
566
      *status = NUM_OVERFLOW;
 
567
    }
 
568
 
 
569
    return(*status);
 
570
}
 
571
/*--------------------------------------------------------------------------*/
 
572
int ffpcnb( fitsfile *fptr,  /* I - FITS file pointer                       */
 
573
            int  colnum,     /* I - number of column to write (1 = 1st col) */
 
574
            long  firstrow,  /* I - first row to write (1 = 1st row)        */
 
575
            long  firstelem, /* I - first vector element to write (1 = 1st) */
 
576
            long  nelem,     /* I - number of values to write               */
 
577
            unsigned char *array,   /* I - array of values to write         */
 
578
            unsigned char nulvalue, /* I - flag for undefined pixels        */
 
579
            int  *status)    /* IO - error status                           */
 
580
/*
 
581
  Write an array of elements to the specified column of a table.  Any input
 
582
  pixels equal to the value of nulvalue will be replaced by the appropriate
 
583
  null value in the output FITS file. 
 
584
 
 
585
  The input array of values will be converted to the datatype of the column 
 
586
  and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary
 
587
*/
 
588
{
 
589
    tcolumn *colptr;
 
590
    long  ngood = 0, nbad = 0, ii, fstrow;
 
591
    OFF_T large_elem, repeat, first, fstelm;
 
592
 
 
593
    if (*status > 0)
 
594
        return(*status);
 
595
 
 
596
    /* reset position to the correct HDU if necessary */
 
597
    if (fptr->HDUposition != (fptr->Fptr)->curhdu)
 
598
    {
 
599
        ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
 
600
    }
 
601
    else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
 
602
    {
 
603
        if ( ffrdef(fptr, status) > 0)               /* rescan header */
 
604
            return(*status);
 
605
    }
 
606
 
 
607
    colptr  = (fptr->Fptr)->tableptr;   /* point to first column */
 
608
    colptr += (colnum - 1);     /* offset to correct column structure */
 
609
 
 
610
    repeat = colptr->trepeat;  /* repeat count for this column */
 
611
 
 
612
    if (firstelem == USE_LARGE_VALUE)
 
613
        large_elem = large_first_elem_val;
 
614
    else
 
615
        large_elem = firstelem;
 
616
 
 
617
    /* hereafter, pass first element parameter via global variable */
 
618
    firstelem = USE_LARGE_VALUE;
 
619
 
 
620
    /* absolute element number in the column */
 
621
    first = (firstrow - 1) * repeat + large_elem;
 
622
 
 
623
    for (ii = 0; ii < nelem; ii++)
 
624
    {
 
625
      if (array[ii] != nulvalue)  /* is this a good pixel? */
 
626
      {
 
627
         if (nbad)  /* write previous string of bad pixels */
 
628
         {
 
629
            fstelm = ii - nbad + first;  /* absolute element number */
 
630
            fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
 
631
            fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */
 
632
            large_first_elem_val = fstelm;
 
633
 
 
634
            if (ffpclu(fptr, colnum, fstrow, firstelem, nbad, status) > 0)
 
635
                return(*status);
 
636
 
 
637
            nbad=0;
 
638
         }
 
639
 
 
640
         ngood = ngood + 1;  /* the consecutive number of good pixels */
 
641
      }
 
642
      else
 
643
      {
 
644
         if (ngood)  /* write previous string of good pixels */
 
645
         {
 
646
            fstelm = ii - ngood + first;  /* absolute element number */
 
647
            fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
 
648
            fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */
 
649
            large_first_elem_val = fstelm;
 
650
 
 
651
            if (ffpclb(fptr, colnum, fstrow, firstelem, ngood, &array[ii-ngood],
 
652
                status) > 0)
 
653
                return(*status);
 
654
 
 
655
            ngood=0;
 
656
         }
 
657
 
 
658
         nbad = nbad + 1;  /* the consecutive number of bad pixels */
 
659
      }
 
660
    }
 
661
 
 
662
    /* finished loop;  now just write the last set of pixels */
 
663
 
 
664
    if (ngood)  /* write last string of good pixels */
 
665
    {
 
666
      fstelm = ii - ngood + first;  /* absolute element number */
 
667
      fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
 
668
      fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */
 
669
      large_first_elem_val = fstelm;
 
670
 
 
671
      ffpclb(fptr, colnum, fstrow, firstelem, ngood, &array[ii-ngood], status);
 
672
    }
 
673
    else if (nbad) /* write last string of bad pixels */
 
674
    {
 
675
      fstelm = ii - nbad + first;  /* absolute element number */
 
676
      fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
 
677
      fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */
 
678
      large_first_elem_val = fstelm;
 
679
 
 
680
      ffpclu(fptr, colnum, fstrow, firstelem, nbad, status);
 
681
    }
 
682
 
 
683
    return(*status);
 
684
}
 
685
/*--------------------------------------------------------------------------*/
 
686
int ffi1fi1(unsigned char *input,  /* I - array of values to be converted  */
 
687
            long ntodo,            /* I - number of elements in the array  */
 
688
            double scale,          /* I - FITS TSCALn or BSCALE value      */
 
689
            double zero,           /* I - FITS TZEROn or BZERO  value      */
 
690
            unsigned char *output, /* O - output array of converted values */
 
691
            int *status)           /* IO - error status                    */
 
692
/*
 
693
  Copy input to output prior to writing output to a FITS file.
 
694
  Do datatype conversion and scaling if required
 
695
*/
 
696
{
 
697
    long ii;
 
698
    double dvalue;
 
699
 
 
700
    if (scale == 1. && zero == 0.)
 
701
    {       
 
702
        memcpy(output, input, ntodo); /* just copy input to output */
 
703
    }
 
704
    else
 
705
    {
 
706
        for (ii = 0; ii < ntodo; ii++)
 
707
        {
 
708
            dvalue = ( ((double) input[ii]) - zero) / scale;
 
709
 
 
710
            if (dvalue < DUCHAR_MIN)
 
711
            {
 
712
                *status = OVERFLOW_ERR;
 
713
                output[ii] = 0;
 
714
            }
 
715
            else if (dvalue > DUCHAR_MAX)
 
716
            {
 
717
                *status = OVERFLOW_ERR;
 
718
                output[ii] = UCHAR_MAX;
 
719
            }
 
720
            else
 
721
                output[ii] = (unsigned char) (dvalue + .5);
 
722
        }
 
723
    }
 
724
    return(*status);
 
725
}
 
726
/*--------------------------------------------------------------------------*/
 
727
int ffi1fi2(unsigned char *input,  /* I - array of values to be converted  */
 
728
            long ntodo,            /* I - number of elements in the array  */
 
729
            double scale,          /* I - FITS TSCALn or BSCALE value      */
 
730
            double zero,           /* I - FITS TZEROn or BZERO  value      */
 
731
            short *output,         /* O - output array of converted values */
 
732
            int *status)           /* IO - error status                    */
 
733
/*
 
734
  Copy input to output prior to writing output to a FITS file.
 
735
  Do datatype conversion and scaling if required
 
736
*/
 
737
{
 
738
    long ii;
 
739
    double dvalue;
 
740
 
 
741
    if (scale == 1. && zero == 0.)
 
742
    {       
 
743
        for (ii = 0; ii < ntodo; ii++)
 
744
            output[ii] = input[ii];   /* just copy input to output */
 
745
    }
 
746
    else
 
747
    {
 
748
        for (ii = 0; ii < ntodo; ii++)
 
749
        {
 
750
            dvalue = (((double) input[ii]) - zero) / scale;
 
751
 
 
752
            if (dvalue < DSHRT_MIN)
 
753
            {
 
754
                *status = OVERFLOW_ERR;
 
755
                output[ii] = SHRT_MIN;
 
756
            }
 
757
            else if (dvalue > DSHRT_MAX)
 
758
            {
 
759
                *status = OVERFLOW_ERR;
 
760
                output[ii] = SHRT_MAX;
 
761
            }
 
762
            else
 
763
            {
 
764
                if (dvalue >= 0)
 
765
                    output[ii] = (short) (dvalue + .5);
 
766
                else
 
767
                    output[ii] = (short) (dvalue - .5);
 
768
            }
 
769
        }
 
770
    }
 
771
    return(*status);
 
772
}
 
773
/*--------------------------------------------------------------------------*/
 
774
int ffi1fi4(unsigned char *input,  /* I - array of values to be converted  */
 
775
            long ntodo,            /* I - number of elements in the array  */
 
776
            double scale,          /* I - FITS TSCALn or BSCALE value      */
 
777
            double zero,           /* I - FITS TZEROn or BZERO  value      */
 
778
            INT32BIT *output,      /* O - output array of converted values */
 
779
            int *status)           /* IO - error status                    */
 
780
/*
 
781
  Copy input to output prior to writing output to a FITS file.
 
782
  Do datatype conversion and scaling if required
 
783
*/
 
784
{
 
785
    long ii;
 
786
    double dvalue;
 
787
 
 
788
    if (scale == 1. && zero == 0.)
 
789
    {       
 
790
        for (ii = 0; ii < ntodo; ii++)
 
791
            output[ii] = (INT32BIT) input[ii];   /* copy input to output */
 
792
    }
 
793
    else
 
794
    {
 
795
        for (ii = 0; ii < ntodo; ii++)
 
796
        {
 
797
            dvalue = (((double) input[ii]) - zero) / scale;
 
798
 
 
799
            if (dvalue < DINT_MIN)
 
800
            {
 
801
                *status = OVERFLOW_ERR;
 
802
                output[ii] = INT32_MIN;
 
803
            }
 
804
            else if (dvalue > DINT_MAX)
 
805
            {
 
806
                *status = OVERFLOW_ERR;
 
807
                output[ii] = INT32_MAX;
 
808
            }
 
809
            else
 
810
            {
 
811
                if (dvalue >= 0)
 
812
                    output[ii] = (INT32BIT) (dvalue + .5);
 
813
                else
 
814
                    output[ii] = (INT32BIT) (dvalue - .5);
 
815
            }
 
816
        }
 
817
    }
 
818
    return(*status);
 
819
}
 
820
/*--------------------------------------------------------------------------*/
 
821
int ffi1fi8(unsigned char *input, /* I - array of values to be converted  */
 
822
            long ntodo,           /* I - number of elements in the array  */
 
823
            double scale,         /* I - FITS TSCALn or BSCALE value      */
 
824
            double zero,          /* I - FITS TZEROn or BZERO  value      */
 
825
            LONGLONG *output,     /* O - output array of converted values */
 
826
            int *status)          /* IO - error status                    */
 
827
/*
 
828
  Copy input to output prior to writing output to a FITS file.
 
829
  Do datatype conversion and scaling if required
 
830
*/
 
831
{
 
832
#if (LONGSIZE == 32) && (! defined HAVE_LONGLONG)
 
833
 
 
834
/* don't have a native 8-byte integer, so have to construct the */
 
835
/* 2 equivalent 4-byte integers have the same bit pattern */
 
836
 
 
837
    unsigned long *uoutput;
 
838
    long ii, jj, kk, temp;
 
839
    double dvalue;
 
840
 
 
841
    uoutput = (unsigned long *) output;
 
842
 
 
843
#if BYTESWAPPED  /* jj points to the most significant part of the 8-byte int */
 
844
    jj = 1;
 
845
    kk = 0;
 
846
#else
 
847
    jj = 0;
 
848
    kk = 1;
 
849
#endif
 
850
 
 
851
    if (scale == 1. && zero == 0.)
 
852
    {       
 
853
        for (ii = 0; ii < ntodo; ii++, jj += 2, kk += 2)
 
854
        {
 
855
                output[jj] = 0;
 
856
                output[kk] = input[ii];
 
857
        }
 
858
    }
 
859
    else
 
860
    {
 
861
        for (ii = 0; ii < ntodo; ii++, jj += 2, kk += 2)
 
862
        {
 
863
            dvalue = (input[ii] - zero) / scale;
 
864
 
 
865
            if (dvalue < DLONGLONG_MIN)
 
866
            {
 
867
                *status = OVERFLOW_ERR;
 
868
                output[jj] = LONG_MIN;
 
869
                output[kk] = 0;
 
870
            }
 
871
            else if (dvalue > DLONGLONG_MAX)
 
872
            {
 
873
                *status = OVERFLOW_ERR;
 
874
                output[jj] = LONG_MAX;
 
875
                output[kk] = -1;
 
876
            }
 
877
            else
 
878
            {
 
879
                if (dvalue < 0)
 
880
                {
 
881
                   temp = (dvalue + 1.) / 4294967296. - 1.;
 
882
                   output[jj] = temp;
 
883
                   uoutput[kk] = 4294967296.  + 
 
884
                      (dvalue - (double) (temp + 1) * 4294967296.);
 
885
                }
 
886
                else
 
887
                {
 
888
                   temp = dvalue / 4294967296.;
 
889
                   output[jj] = temp;
 
890
                   uoutput[kk] = dvalue - (double) temp * 4294967296.;
 
891
                }
 
892
            }
 
893
        }
 
894
    }
 
895
 
 
896
#else
 
897
 
 
898
/* this is the much simpler case where the native 8-byte integer exists */
 
899
 
 
900
    long ii;
 
901
    double dvalue;
 
902
 
 
903
    if (scale == 1. && zero == 0.)
 
904
    {       
 
905
        for (ii = 0; ii < ntodo; ii++)
 
906
                output[ii] = input[ii];
 
907
    }
 
908
    else
 
909
    {
 
910
        for (ii = 0; ii < ntodo; ii++)
 
911
        {
 
912
            dvalue = (input[ii] - zero) / scale;
 
913
 
 
914
            if (dvalue < DLONGLONG_MIN)
 
915
            {
 
916
                *status = OVERFLOW_ERR;
 
917
                output[ii] = LONGLONG_MIN;
 
918
            }
 
919
            else if (dvalue > DLONGLONG_MAX)
 
920
            {
 
921
                *status = OVERFLOW_ERR;
 
922
                output[ii] = LONGLONG_MAX;
 
923
            }
 
924
            else
 
925
            {
 
926
                if (dvalue >= 0)
 
927
                    output[ii] = (LONGLONG) (dvalue + .5);
 
928
                else
 
929
                    output[ii] = (LONGLONG) (dvalue - .5);
 
930
            }
 
931
        }
 
932
    }
 
933
 
 
934
#endif
 
935
 
 
936
    return(*status);
 
937
}
 
938
/*--------------------------------------------------------------------------*/
 
939
int ffi1fr4(unsigned char *input,  /* I - array of values to be converted  */
 
940
            long ntodo,            /* I - number of elements in the array  */
 
941
            double scale,          /* I - FITS TSCALn or BSCALE value      */
 
942
            double zero,           /* I - FITS TZEROn or BZERO  value      */
 
943
            float *output,         /* O - output array of converted values */
 
944
            int *status)           /* IO - error status                    */
 
945
/*
 
946
  Copy input to output prior to writing output to a FITS file.
 
947
  Do datatype conversion and scaling if required.
 
948
*/
 
949
{
 
950
    long ii;
 
951
 
 
952
    if (scale == 1. && zero == 0.)
 
953
    {       
 
954
        for (ii = 0; ii < ntodo; ii++)
 
955
                output[ii] = (float) input[ii];
 
956
    }
 
957
    else
 
958
    {
 
959
        for (ii = 0; ii < ntodo; ii++)
 
960
            output[ii] = ( ( (double) input[ii] ) - zero) / scale;
 
961
    }
 
962
    return(*status);
 
963
}
 
964
/*--------------------------------------------------------------------------*/
 
965
int ffi1fr8(unsigned char *input,  /* I - array of values to be converted  */
 
966
            long ntodo,            /* I - number of elements in the array  */
 
967
            double scale,          /* I - FITS TSCALn or BSCALE value      */
 
968
            double zero,           /* I - FITS TZEROn or BZERO  value      */
 
969
            double *output,        /* O - output array of converted values */
 
970
            int *status)           /* IO - error status                    */
 
971
/*
 
972
  Copy input to output prior to writing output to a FITS file.
 
973
  Do datatype conversion and scaling if required.
 
974
*/
 
975
{
 
976
    long ii;
 
977
 
 
978
    if (scale == 1. && zero == 0.)
 
979
    {       
 
980
        for (ii = 0; ii < ntodo; ii++)
 
981
                output[ii] = (double) input[ii];
 
982
    }
 
983
    else
 
984
    {
 
985
        for (ii = 0; ii < ntodo; ii++)
 
986
            output[ii] = ( ( (double) input[ii] ) - zero) / scale;
 
987
    }
 
988
    return(*status);
 
989
}
 
990
/*--------------------------------------------------------------------------*/
 
991
int ffi1fstr(unsigned char *input, /* I - array of values to be converted  */
 
992
            long ntodo,        /* I - number of elements in the array  */
 
993
            double scale,      /* I - FITS TSCALn or BSCALE value      */
 
994
            double zero,       /* I - FITS TZEROn or BZERO  value      */
 
995
            char *cform,       /* I - format for output string values  */
 
996
            long twidth,       /* I - width of each field, in chars    */
 
997
            char *output,      /* O - output array of converted values */
 
998
            int *status)       /* IO - error status                    */
 
999
/*
 
1000
  Copy input to output prior to writing output to a FITS file.
 
1001
  Do scaling if required.
 
1002
*/
 
1003
{
 
1004
    long ii;
 
1005
    double dvalue;
 
1006
 
 
1007
    if (scale == 1. && zero == 0.)
 
1008
    {       
 
1009
        for (ii = 0; ii < ntodo; ii++)
 
1010
        {
 
1011
           sprintf(output, cform, (double) input[ii]);
 
1012
           output += twidth;
 
1013
 
 
1014
           if (*output)  /* if this char != \0, then overflow occurred */
 
1015
              *status = OVERFLOW_ERR;
 
1016
        }
 
1017
    }
 
1018
    else
 
1019
    {
 
1020
        for (ii = 0; ii < ntodo; ii++)
 
1021
        {
 
1022
          dvalue = ((double) input[ii] - zero) / scale;
 
1023
          sprintf(output, cform, dvalue);
 
1024
          output += twidth;
 
1025
 
 
1026
          if (*output)  /* if this char != \0, then overflow occurred */
 
1027
            *status = OVERFLOW_ERR;
 
1028
        }
 
1029
    }
 
1030
    return(*status);
 
1031
}