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