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