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