IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ticket #1289: fpackutil.c

File fpackutil.c, 48.6 KB (added by Michael Wood-Vasey, 17 years ago)

fpackutil.c

Line 
1/* FPACK utility routines
2 * R. Seaman, NOAO & W. Pence, NASA/GSFC
3 */
4
5#include <time.h>
6#include <float.h>
7#include <signal.h>
8#include "fitsio.h"
9#include "fpack.h"
10#include <sys/time.h>
11#include <time.h>
12#include <stdlib.h>
13
14/* nearest integer function */
15# define NINT(x) ((x >= 0.) ? (int) (x + 0.5) : (int) (x - 0.5))
16# define NSHRT(x) ((x >= 0.) ? (short) (x + 0.5) : (short) (x - 0.5))
17
18/* define variables for measuring elapsed time */
19clock_t scpu, ecpu;
20long startsec; /* start of elapsed time interval */
21int startmilli; /* start of elapsed time interval */
22
23/* CLOCKS_PER_SEC should be defined by most compilers */
24#if defined(CLOCKS_PER_SEC)
25#define CLOCKTICKS CLOCKS_PER_SEC
26#else
27/* on SUN OS machine, CLOCKS_PER_SEC is not defined, so set its value */
28#define CLOCKTICKS 1000000
29#endif
30
31/* structure to hold image statistics (defined in fpack.h) */
32imgstats imagestats;
33FILE *outreport;
34
35/* dimension of central image area to be sampled for test statistics */
36int XSAMPLE = 4100;
37int YSAMPLE = 4100;
38
39int fp_msg (char *msg) { printf ("%s", msg); }
40int fp_version (void) { fp_msg (FPACK_VERSION); fp_msg ("\n"); }
41int fp_noop (void) { fp_msg ("Input and output files are unchanged.\n"); }
42
43/*--------------------------------------------------------------------------*/
44int fp_init (fpstate *fpptr)
45{
46 int ii;
47
48 fpptr->comptype = RICE_1;
49 fpptr->quantize_level = DEF_QLEVEL;
50 fpptr->scale = DEF_HCOMP_SCALE;
51 fpptr->smooth = DEF_HCOMP_SMOOTH;
52 fpptr->rescale_noise = DEF_RESCALE_NOISE;
53 fpptr->ntile[0] = (long) 0; /* 0 means extent of axis */
54
55 for (ii=1; ii < MAX_COMPRESS_DIM; ii++)
56 fpptr->ntile[ii] = (long) 1;
57
58 fpptr->to_stdout = 0;
59 fpptr->listonly = 0;
60 fpptr->clobber = 0;
61 fpptr->delete_input = 0;
62 fpptr->do_not_prompt = 0;
63 fpptr->do_checksums = 1;
64 fpptr->do_gzip_file = 0;
65 fpptr->test_all = 0;
66 fpptr->verbose = 0;
67
68 fpptr->prefix[0] = (char) NULL;
69 fpptr->delete_suffix = 0;
70 fpptr->outfile[0] = (char) NULL;
71
72 fpptr->firstfile = 1;
73
74 /* magic number for initialization check, boolean for preflight
75 */
76 fpptr->initialized = FP_INIT_MAGIC;
77 fpptr->preflight_checked = 0;
78 return(0);
79}
80
81/*--------------------------------------------------------------------------*/
82int fp_list (int argc, char *argv[], fpstate fpvar)
83{
84 fitsfile *infptr;
85 char infits[SZ_STR];
86 int hdunum, iarg, stat=0;
87
88 if (fpvar.initialized != FP_INIT_MAGIC) {
89 fp_msg ("Error: internal initialization error\n"); exit (-1);
90 }
91
92 for (iarg=fpvar.firstfile; iarg < argc; iarg++) {
93 strncpy (infits, argv[iarg], SZ_STR);
94
95 if (strchr (infits, '[') || strchr (infits, ']')) {
96 fp_msg ("Error: section/extension notation not supported: ");
97 fp_msg (infits); fp_msg ("\n"); exit (-1);
98 }
99
100 if (access (infits, R_OK) != 0) {
101 fp_msg ("Error: can't find or open input file ");
102 fp_msg (infits); fp_msg ("\n"); exit (-1);
103 }
104
105 fits_open_file (&infptr, infits, READONLY, &stat);
106 if (stat) { fits_report_error (stderr, stat); exit (stat); }
107
108 fp_info (infits);
109
110 fits_get_num_hdus (infptr, &hdunum, &stat);
111 if (stat) { fits_report_error (stderr, stat); exit (stat); }
112
113 fp_info_hdu (infptr);
114
115 fits_close_file (infptr, &stat);
116 if (stat) { fits_report_error (stderr, stat); exit (stat); }
117 }
118 return(0);
119}
120
121/*--------------------------------------------------------------------------*/
122int fp_info (char *infits)
123{
124 struct stat sbuf;
125 char msg[SZ_STR];
126 int mtime, size, uid, gid, nlink;
127 unsigned mode;
128
129 if (stat (infits, &sbuf) != 0) {
130 fp_msg ("Error: can't stat "); fp_msg (infits); fp_msg ("\n");
131
132 } else {
133 size = (int) sbuf.st_size;
134 mtime = (int) sbuf.st_mtime;
135 uid = (int) sbuf.st_uid;
136 gid = (int) sbuf.st_gid;
137 mode = (unsigned) sbuf.st_mode;
138 nlink = (int) sbuf.st_nlink;
139
140 sprintf (msg, "%s: %d bytes\n", infits, size); fp_msg (msg);
141 }
142 return(0);
143}
144
145/*--------------------------------------------------------------------------*/
146int fp_info_hdu (fitsfile *infptr)
147{
148 long naxes[9] = {1, 1, 1, 1, 1, 1, 1, 1, 1};
149 char msg[SZ_STR], val[SZ_CARD], com[SZ_CARD];
150 int naxis=0, hdutype, bitpix, hdupos, stat=0, ii;
151
152 fits_movabs_hdu (infptr, 1, NULL, &stat);
153 if (stat) { fits_report_error (stderr, stat); exit (stat); }
154
155 for (hdupos=1; ! stat; hdupos++) {
156 fits_get_hdu_type (infptr, &hdutype, &stat);
157/* fits_read_keyword (infptr, FILE_KEY, val, com, &stat);
158 */
159 if (stat) { fits_report_error (stderr, stat); exit (stat); }
160
161 if (hdutype == IMAGE_HDU) {
162 sprintf (msg, " %d IMAGE", hdupos); fp_msg (msg);
163
164/* sprintf (msg, " %d IMAGE %s", hdupos, val); fp_msg (msg);
165 */
166 fits_get_img_param (infptr, 9, &bitpix, &naxis, naxes, &stat);
167
168 if (naxis == 0) {
169 sprintf (msg, " [no pixels]"); fp_msg (msg);
170 } else if (naxis == 1) {
171 sprintf (msg, " [%d]", naxes[1]); fp_msg (msg);
172 } else {
173 sprintf (msg, " [%d", naxes[0]); fp_msg (msg);
174 for (ii=1; ii < naxis; ii++) {
175 sprintf (msg, "x%d", naxes[ii]); fp_msg (msg);
176 }
177 fp_msg ("]");
178 }
179
180 if (fits_is_compressed_image (infptr, &stat))
181 fp_msg (" (compressed)\n");
182 else
183 fp_msg ("\n");
184
185 } else if (hdutype == ASCII_TBL) {
186 sprintf (msg, " %d ASCII TABLE\n", hdupos); fp_msg (msg);
187
188 } else if (hdutype == BINARY_TBL) {
189 sprintf (msg, " %d BINARY TABLE\n", hdupos); fp_msg (msg);
190
191 } else {
192 sprintf (msg, " %d UNKNOWN EXTENSION\n", hdupos); fp_msg (msg);
193 }
194
195 fits_movrel_hdu (infptr, 1, NULL, &stat);
196 }
197 return(0);
198}
199
200/*--------------------------------------------------------------------------*/
201int fp_preflight (int argc, char *argv[], int unpack, fpstate *fpptr)
202{
203 char infits[SZ_STR], outfits[SZ_STR], temp[SZ_STR], *cptr;
204 int iarg, suflen, namelen, nfiles = 0;
205
206 if (fpptr->initialized != FP_INIT_MAGIC) {
207 fp_msg ("Error: internal initialization error\n"); exit (-1);
208 }
209
210 for (iarg=fpptr->firstfile; iarg < argc; iarg++) {
211
212 outfits[0] = '\0';
213
214 if (strlen(argv[iarg]) > SZ_STR - 4) { /* allow for .fz or .gz suffix */
215 fp_msg ("Error: input file name\n "); fp_msg (argv[iarg]);
216 fp_msg ("\n is too long\n"); fp_noop (); exit (-1);
217 }
218
219 strncpy (infits, argv[iarg], SZ_STR);
220
221 if (strchr (infits, '[') || strchr (infits, ']')) {
222 fp_msg ("Error: section/extension notation not supported: ");
223 fp_msg (infits); fp_msg ("\n"); fp_noop (); exit (-1);
224 }
225
226 if (unpack) {
227 /* ********** This section applies to funpack ************ */
228
229 /* check that input file exists */
230 if (access (infits, R_OK) != 0) { /* if not, then check if */
231 strcat(infits, ".fz"); /* a .fz version exsits */
232 if (access (infits, R_OK) != 0) {
233 namelen = strlen(infits);
234 infits[namelen - 3] = '\0'; /* remove the .fz suffix */
235 fp_msg ("Error: can't find or read input file "); fp_msg (infits);
236 fp_msg ("\n"); fp_noop (); exit (-1);
237 }
238 } else { /* make sure a .fz version of the same file doesn't exist */
239 namelen = strlen(infits);
240 strcat(infits, ".fz");
241 if (access (infits, R_OK) == 0) {
242 infits[namelen] = '\0'; /* remove the .fz suffix */
243 fp_msg ("Error: ambiguous input file name. Which file should be unpacked?:\n ");
244 fp_msg (infits); fp_msg ("\n ");
245 fp_msg (infits); fp_msg (".fz\n");
246 fp_noop (); exit (-1);
247 } else {
248 infits[namelen] = '\0'; /* remove the .fz suffix */
249 }
250 }
251
252 /* if writing to stdout or just testing, then we are all done */
253 if (fpptr->to_stdout || fpptr->test_all) {
254 continue;
255 }
256
257 if (fpptr->outfile[0]) { /* user specified output file name */
258 nfiles++;
259 if (nfiles > 1) {
260 fp_msg ("Error: cannot use same output file name for multiple files:\n ");
261 fp_msg (fpptr->outfile);
262 fp_msg ("\n"); fp_noop (); exit (-1);
263 }
264
265 /* check that output file doesn't exist */
266 if (access (fpptr->outfile, F_OK) == 0) {
267 fp_msg ("Error: output file already exists:\n ");
268 fp_msg (fpptr->outfile);
269 fp_msg ("\n "); fp_noop (); exit (-1);
270 }
271 continue;
272 }
273
274 /* construct output file name to test */
275 if (fpptr->prefix[0]) {
276 if (strlen(fpptr->prefix) + strlen(infits) > SZ_STR - 1) {
277 fp_msg ("Error: output file name for\n "); fp_msg (infits);
278 fp_msg ("\n is too long with the prefix\n"); fp_noop (); exit (-1);
279 }
280 strcat(outfits,fpptr->prefix);
281 }
282
283 strcat(outfits, infits);
284
285 /* remove .gz suffix, if present (output is not gzipped) */
286 namelen = strlen(outfits);
287 if ( !strcmp(".gz", outfits + namelen - 3) ) {
288 outfits[namelen - 3] = '\0';
289 }
290
291 /* check for .fz suffix that is sometimes required */
292 /* and remove it if present */
293 namelen = strlen(outfits);
294 if ( !strcmp(".fz", outfits + namelen - 3) ) { /* suffix is present */
295 outfits[namelen - 3] = '\0';
296 } else if (fpptr->delete_suffix) { /* required suffix is missing */
297 fp_msg ("Error: input compressed file "); fp_msg (infits);
298 fp_msg ("\n does not have the default .fz suffix.\n");
299 fp_noop (); exit (-1);
300 }
301
302 /* if infits != outfits, make sure outfits doesn't already exist */
303 if (strcmp(infits, outfits)) {
304 if (access (outfits, F_OK) == 0) {
305 fp_msg ("Error: output file already exists:\n "); fp_msg (outfits);
306 fp_msg ("\n "); fp_noop (); exit (-1);
307 }
308 }
309
310 /* if gzipping the output, make sure .gz file doesn't exist */
311 if (fpptr->do_gzip_file) {
312 strcat(outfits, ".gz");
313 if (access (outfits, F_OK) == 0) {
314 fp_msg ("Error: output file already exists:\n "); fp_msg (outfits);
315 fp_msg ("\n "); fp_noop (); exit (-1);
316 }
317 namelen = strlen(outfits);
318 outfits[namelen - 3] = '\0'; /* remove the .gz suffix again */
319 }
320 } else {
321 /* ********** This section applies to fpack ************ */
322
323 /* check that input file exists */
324 if (access (infits, R_OK) != 0) { /* if not, then check if */
325 strcat(infits, ".gz"); /* a gzipped version exsits */
326 if (access (infits, R_OK) != 0) {
327 namelen = strlen(infits);
328 infits[namelen - 3] = '\0'; /* remove the .gz suffix */
329 fp_msg ("Error: can't find or read input file "); fp_msg (infits);
330 fp_msg ("\n"); fp_noop (); exit (-1);
331 }
332 }
333
334 /* make sure the file to pack does not already have a .fz suffix */
335 namelen = strlen(infits);
336 if ( !strcmp(".fz", infits + namelen - 3) ) {
337 fp_msg ("Error: fpack input file already has '.fz' suffix\n" ); fp_msg (infits);
338 fp_msg ("\n"); fp_noop (); exit (-1);
339 }
340
341 /* if writing to stdout, or just testing the files, then we are all done */
342 if (fpptr->to_stdout || fpptr->test_all) {
343 continue;
344 }
345
346 /* construct output file name */
347 strcpy(outfits, infits);
348
349 /* remove .gz suffix, if present (output is not gzipped) */
350 namelen = strlen(outfits);
351 if ( !strcmp(".gz", outfits + namelen - 3) ) {
352 outfits[namelen - 3] = '\0';
353 }
354
355 /* If not clobbering the input file, add .fz suffix to output name */
356 if (! fpptr->clobber)
357 strcat(outfits, ".fz");
358
359 /* if infits != outfits, make sure outfits doesn't already exist */
360 if (strcmp(infits, outfits)) {
361 if (access (outfits, F_OK) == 0) {
362 fp_msg ("Error: output file already exists:\n "); fp_msg (outfits);
363 fp_msg ("\n "); fp_noop (); exit (-1);
364 }
365 }
366 } /* end of fpack section */
367 }
368
369 fpptr->preflight_checked++;
370 return(0);
371}
372
373/*--------------------------------------------------------------------------*/
374/* must run fp_preflight() before fp_loop()
375 */
376int fp_loop (int argc, char *argv[], int unpack, fpstate fpvar)
377{
378 char infits[SZ_STR], outfits[SZ_STR], outfits2[SZ_STR];
379 char temp[SZ_STR], answer[30], *cptr;
380 int iarg, islossless, namelen;
381
382 if (fpvar.initialized != FP_INIT_MAGIC) {
383 fp_msg ("Error: internal initialization error\n"); exit (-1);
384 } else if (! fpvar.preflight_checked) {
385 fp_msg ("Error: internal preflight error\n"); exit (-1);
386 }
387
388
389 if (fpvar.test_all && fpvar.outfile[0]) {
390 outreport = fopen(fpvar.outfile, "w");
391 fprintf(outreport," Filename Extension BITPIX NAXIS1 NAXIS2 Size N_nulls Minval Maxval Mean Sigm Noise1 Noise3 T_whole T_rowbyrow ");
392 fprintf(outreport,"[Comp_ratio, Pack_cpu, Unpack_cpu, Lossless readtimes] (repeated for Rice, Hcompress and GZIP)\n");
393 }
394
395/* set up signal handler to delete temporary file on abort */
396#ifdef SIGINT
397 if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
398 (void) signal(SIGINT, abort_fpack);
399 }
400#endif
401
402#ifdef SIGTERM
403 if (signal(SIGTERM, SIG_IGN) != SIG_IGN) {
404 (void) signal(SIGTERM, abort_fpack);
405 }
406#endif
407
408#ifdef SIGHUP
409 if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {
410 (void) signal(SIGHUP, abort_fpack);
411 }
412#endif
413
414 for (iarg=fpvar.firstfile; iarg < argc; iarg++) {
415
416 temp[0] = '\0';
417 outfits[0] = '\0';
418 islossless = 1;
419
420 strncpy (infits, argv[iarg], SZ_STR - 1);
421
422 if (unpack) {
423 /* ********** This section applies to funpack ************ */
424
425 /* find input file */
426 if (access (infits, R_OK) != 0) { /* if not, then */
427 strcat(infits, ".fz"); /* a .fz version must exsit */
428 }
429
430 if (fpvar.to_stdout) {
431 strcpy(outfits, "-");
432
433 } else if (fpvar.outfile[0]) { /* user specified output file name */
434 strcpy(outfits, fpvar.outfile);
435
436 } else if (! fpvar.test_all) {
437 /* construct output file name */
438 if (fpvar.prefix[0]) {
439 strcat(outfits,fpvar.prefix);
440 }
441
442 strcat(outfits, infits);
443
444 /* remove .gz suffix, if present (output is not gzipped) */
445 namelen = strlen(outfits);
446 if ( !strcmp(".gz", outfits + namelen - 3) ) {
447 outfits[namelen - 3] = '\0';
448 }
449
450 /* check for .fz suffix that is sometimes required */
451 /* and remove it if present */
452 namelen = strlen(outfits);
453 if ( !strcmp(".fz", outfits + namelen - 3) ) { /* suffix is present */
454 outfits[namelen - 3] = '\0';
455 }
456 }
457
458 } else {
459 /* ********** This section applies to fpack ************ */
460
461 if (fpvar.to_stdout) {
462 strcpy(outfits, "-");
463 } else if (! fpvar.test_all) {
464 /* construct output file name */
465 strcpy(outfits, infits);
466
467 /* remove .gz suffix, if present (output is not gzipped) */
468 namelen = strlen(outfits);
469 if ( !strcmp(".gz", outfits + namelen - 3) ) {
470 outfits[namelen - 3] = '\0';
471 }
472
473 /* If not clobbering the input file, add .fz suffix to output name */
474 if (! fpvar.clobber)
475 strcat(outfits, ".fz");
476 }
477 }
478
479 strncpy(temp, outfits, SZ_STR-1);
480
481 if (!strcmp(infits, outfits) ) { /* are input and output names the same? */
482
483 /* clobber the input file with the output file with the same name */
484 if (! fpvar.clobber) {
485 fp_msg ("\nError: must use -F flag to clobber input file.\n");
486 exit (-1);
487 }
488
489 /* create temporary output file */
490 strcpy (outfits, "fpack_tmp.XXXXXX"); mktemp (outfits);
491
492 if (access (outfits, F_OK) == 0) {
493 /* unlikely name collision, try again (once) */
494 strcpy (outfits, "fpack_tmp.XXXXXX"); mktemp (outfits);
495
496 if (access (outfits, F_OK) == 0) {
497 fp_msg ("Error: temporary file "); fp_msg (outfits);
498 fp_msg (" already exists\n"); exit (-1);
499 }
500 }
501 }
502
503
504 /* *************** now do the real work ********************* */
505
506 if (fpvar.verbose && ! fpvar.to_stdout)
507 printf("%s ", infits);
508
509 if (fpvar.test_all) { /* compare all the algorithms */
510
511 strcpy (outfits, "fpack_tmp.XXXXXX"); mktemp (outfits);
512 strcpy (outfits2, "fpack_tmp.XXXXXX"); mktemp (outfits2);
513
514 fp_test (infits, outfits, outfits2, fpvar);
515
516 remove(outfits);
517 remove(outfits2);
518 return(0);
519
520 } else if (unpack) {
521 fp_unpack (infits, outfits, fpvar);
522
523 } else {
524 fp_pack (infits, outfits, fpvar, &islossless);
525 }
526
527 if (fpvar.to_stdout) {
528 return(0);
529 }
530
531 /* ********** clobber and/or delete files, if needed ************** */
532
533 if (!strcmp(infits, temp) && fpvar.clobber ) {
534
535 if (!islossless && ! fpvar.do_not_prompt) {
536 fp_msg ("\nFile ");
537 fp_msg (infits);
538 fp_msg ("\nwas compressed with a LOSSY method. Overwrite the\n");
539 fp_msg ("original file with the compressed version? (Y/N) ");
540 fgets(answer, 29, stdin);
541 if (answer[0] != 'Y' && answer[0] != 'y') {
542 fp_msg ("\noriginal file NOT overwritten!\n");
543 remove(outfits);
544 break;
545 }
546 }
547
548 /* rename clobbers input, may be unix/shell version dependent */
549 if (rename (outfits, temp) != 0) {
550 fp_msg ("\nError renaming tmp file to ");
551 fp_msg (temp); fp_msg ("\n"); exit (-1);
552 }
553 strcpy(outfits, temp);
554
555 } else if (fpvar.clobber || fpvar.delete_input) { /* delete the input file */
556 if (!islossless && !fpvar.do_not_prompt) {
557 fp_msg ("\nFile ");
558 fp_msg (infits);
559 fp_msg ("\nwas compressed with a LOSSY method. \n");
560 fp_msg ("Delete the original file? (Y/N) ");
561 fgets(answer, 29, stdin);
562 if (answer[0] != 'Y' && answer[0] != 'y') {
563 fp_msg ("\noriginal file NOT deleted!\n");
564 } else if (remove(infits) != 0) {
565 fp_msg ("\nError deleting input file ");
566 fp_msg (infits); fp_msg ("\n"); exit (-1);
567 }
568 } else {
569 if (remove(infits) != 0) {
570 fp_msg ("\nError deleting input file ");
571 fp_msg (infits); fp_msg ("\n"); exit (-1);
572 }
573 }
574 }
575
576 if (fpvar.do_gzip_file) { /* gzip the output file */
577 strcpy(temp, "gzip -1 ");
578 strcat(temp,outfits);
579 system(temp);
580 strcat(outfits, ".gz"); /* only possibible with funpack */
581 }
582
583 if (fpvar.verbose && ! fpvar.to_stdout)
584 printf("-> %s\n", outfits);
585
586 }
587
588 if (fpvar.test_all && fpvar.outfile[0])
589 fclose(outreport);
590 return(0);
591}
592
593/*--------------------------------------------------------------------------*/
594/* fp_pack assumes the output file does not exist (checked by preflight)
595 */
596int fp_pack (char *infits, char *outfits, fpstate fpvar, int *islossless)
597{
598 fitsfile *infptr, *outfptr;
599 int stat=0;
600
601 fits_open_file (&infptr, infits, READONLY, &stat);
602 fits_create_file (&outfptr, outfits, &stat);
603
604 if (stat) { fits_report_error (stderr, stat); exit (stat); }
605
606 fits_set_compression_type (outfptr, fpvar.comptype, &stat);
607 fits_set_quantize_level (outfptr, fpvar.quantize_level, &stat);
608 fits_set_hcomp_scale (outfptr, fpvar.scale, &stat);
609 fits_set_hcomp_smooth (outfptr, fpvar.smooth, &stat);
610 fits_set_tile_dim (outfptr, 6, fpvar.ntile, &stat);
611
612 if (stat) { fits_report_error (stderr, stat); exit (stat); }
613
614 while (! stat) {
615
616 fp_pack_hdu (infptr, outfptr, fpvar, islossless, &stat);
617
618 if (fpvar.do_checksums) {
619 fits_write_chksum (outfptr, &stat);
620 }
621
622 fits_movrel_hdu (infptr, 1, NULL, &stat);
623 }
624
625 if (stat == END_OF_FILE) stat = 0;
626
627 /* set checksum for case of newly created primary HDU
628 */
629 if (fpvar.do_checksums) {
630 fits_movabs_hdu (outfptr, 1, NULL, &stat);
631 fits_write_chksum (outfptr, &stat);
632 }
633
634 fits_close_file (outfptr, &stat);
635 fits_close_file (infptr, &stat);
636
637 if (stat) { fits_report_error (stderr, stat); exit (stat); }
638 return(0);
639}
640
641/*--------------------------------------------------------------------------*/
642/* fp_unpack assumes the output file does not exist
643 */
644int fp_unpack (char *infits, char *outfits, fpstate fpvar)
645{
646 fitsfile *infptr, *outfptr;
647 int stat=0;
648
649 fits_open_file (&infptr, infits, READONLY, &stat);
650 fits_create_file (&outfptr, outfits, &stat);
651
652 if (stat) { fits_report_error (stderr, stat); exit (stat); }
653
654 while (! stat) {
655 fp_unpack_hdu (infptr, outfptr, &stat);
656
657 if (fpvar.do_checksums) {
658 fits_write_chksum (outfptr, &stat);
659 }
660
661 fits_movrel_hdu (infptr, 1, NULL, &stat);
662 }
663
664 if (stat == END_OF_FILE) stat = 0;
665
666 /* set checksum for case of newly created primary HDU
667 */
668 if (fpvar.do_checksums) {
669 fits_movabs_hdu (outfptr, 1, NULL, &stat);
670 fits_write_chksum (outfptr, &stat);
671 }
672
673 fits_close_file (outfptr, &stat);
674 fits_close_file (infptr, &stat);
675
676 if (stat) { fits_report_error (stderr, stat); exit (stat); }
677 return(0);
678}
679
680/*--------------------------------------------------------------------------*/
681/* fp_test assumes the output files do not exist
682 */
683int fp_test (char *infits, char *outfits, char *outfits2, fpstate fpvar)
684{
685 fitsfile *inputfptr, *infptr, *outfptr, *outfptr2, *tempfile;
686
687 long naxes[9] = {1, 1, 1, 1, 1, 1, 1, 1, 1};
688 long tilesize[9] = {0,1,1,1,1,1,1,1,1};
689 int stat=0, totpix=0, naxis=0, ii, hdutype, bitpix, extnum = 0, len;
690 int tstatus = 0, hdunum, rescale_flag;
691 char dtype[8], dimen[100], tempfilename[SZ_STR];
692 double bscale, rescale;
693 long headstart, datastart, dataend;
694 float origdata = 0., whole_cpu, whole_elapse, row_elapse, row_cpu;
695
696 fits_open_file (&inputfptr, infits, READONLY, &stat);
697 fits_create_file (&outfptr, outfits, &stat);
698 fits_create_file (&outfptr2, outfits2, &stat);
699
700 if (stat) { fits_report_error (stderr, stat); exit (stat); }
701
702 fits_set_quantize_level (outfptr, fpvar.quantize_level, &stat);
703 fits_set_hcomp_scale (outfptr, fpvar.scale, &stat);
704 fits_set_hcomp_smooth (outfptr, fpvar.smooth, &stat);
705 fits_set_tile_dim (outfptr, 6, fpvar.ntile, &stat);
706
707 while (! stat) {
708
709 rescale_flag = 0;
710
711 /* LOOP OVER EACH HDU */
712 fits_get_hdu_type (inputfptr, &hdutype, &stat);
713
714 if (hdutype == IMAGE_HDU) {
715 fits_get_img_param (inputfptr, 9, &bitpix, &naxis, naxes, &stat);
716 for (totpix=1, ii=0; ii < 9; ii++) totpix *= naxes[ii];
717 }
718
719 if ( !fits_is_compressed_image (inputfptr, &stat) &&
720 hdutype == IMAGE_HDU && naxis != 0 && totpix != 0) {
721
722 /* rescale a scaled integer image to reduce noise? */
723 if (fpvar.rescale_noise != 0. && bitpix > 0 && bitpix < LONGLONG_IMG) {
724
725 tstatus = 0;
726 fits_read_key(inputfptr, TDOUBLE, "BSCALE", &bscale, 0, &tstatus);
727
728 if (tstatus == 0 && bscale != 1.0) { /* image must be scaled */
729
730 if (bitpix == LONG_IMG)
731 fp_i4stat(inputfptr, naxis, naxes, &stat);
732 else
733 fp_i2stat(inputfptr, naxis, naxes, &stat);
734
735 rescale = imagestats.noise3 / fpvar.rescale_noise;
736 if (rescale > 1.0) {
737
738 /* all the criteria are met, so create a temporary file that */
739 /* contains a rescaled version of the image */
740
741 strcpy (tempfilename, "fptmp.XXXXXX"); mktemp (tempfilename);
742 fits_create_file(&tempfile, tempfilename, &stat);
743
744 fits_get_hdu_num(inputfptr, &hdunum);
745 if (hdunum != 1) {
746
747 /* the input hdu is an image extension, so create dummy primary */
748 fits_create_img(tempfile, 8, 0, naxes, &stat);
749 }
750
751 fits_copy_header(inputfptr, tempfile, &stat); /* copy the header */
752
753 /* rescale the data, so that it will compress more efficiently */
754 if (bitpix == LONG_IMG)
755 fp_i4rescale(inputfptr, naxis, naxes, rescale, tempfile, &stat);
756 else
757 fp_i2rescale(inputfptr, naxis, naxes, rescale, tempfile, &stat);
758
759 /* scale the BSCALE keyword by the inverse factor */
760
761 bscale = bscale * rescale;
762 fits_update_key(tempfile, TDOUBLE, "BSCALE", &bscale, 0, &stat);
763
764 /* rescan the header, to reset the actual scaling parameters */
765 fits_set_hdustruc(tempfile, &stat);
766
767 infptr = tempfile;
768 rescale_flag = 1;
769 }
770 }
771 }
772
773 if (!rescale_flag) /* just compress the input file, without rescaling */
774 infptr = inputfptr;
775
776 /* compute basic statistics about the input image */
777 if (bitpix == BYTE_IMG) {
778 strcpy(dtype, "Int*1");
779 fp_i2stat(infptr, naxis, naxes, &stat);
780 } else if (bitpix == SHORT_IMG) {
781 strcpy(dtype, "Int*2");
782 fp_i2stat(infptr, naxis, naxes, &stat);
783 } else if (bitpix == LONG_IMG) {
784 strcpy(dtype, "Int*4");
785 fp_i4stat(infptr, naxis, naxes, &stat);
786 } else if (bitpix == LONGLONG_IMG) {
787 strcpy(dtype, "Int*8");
788 } else if (bitpix == FLOAT_IMG) {
789 strcpy(dtype, "Real*4");
790 fp_r4stat(infptr, naxis, naxes, &stat);
791 } else if (bitpix == DOUBLE_IMG) {
792 strcpy(dtype, "REAL*8");
793 fp_r4stat(infptr, naxis, naxes, &stat);
794 }
795
796 printf("\n File: %s\n", infits);
797 printf(" Ext BITPIX Dimensions Nulls Min Max Mean Sigma Noise1 Noise3 TElpN TCPUN TElp1 TCPU1\n");
798
799 printf(" %3d %s", extnum, dtype);
800 sprintf(dimen," (%d", naxes[0]);
801 len =strlen(dimen);
802 for (ii = 1; ii < naxis; ii++)
803 sprintf(dimen+len,",%d", naxes[ii]);
804 strcat(dimen, ")");
805 printf("%-12s",dimen);
806
807 fits_get_hduaddr(inputfptr, &headstart, &datastart, &dataend, &stat);
808 origdata = (dataend - datastart)/1000000.;
809
810 /* get elapsed and cpu times need to read the uncompressed image */
811 fits_read_image_speed (infptr, &whole_elapse, &whole_cpu,
812 &row_elapse, &row_cpu, &stat);
813
814 printf(" %5d %6.0f %6.0f %8.1f %#8.2g %#9.3g %#9.3g %5.3f %5.3f %5.3f %5.3f\n",
815 imagestats.n_nulls, imagestats.minval, imagestats.maxval,
816 imagestats.mean, imagestats.sigma, imagestats.noise1,
817 imagestats.noise3, whole_elapse, whole_cpu, row_elapse, row_cpu);
818
819 printf("\n Type Ratio Size (MB) Pk (Sec) UnPk Exact ElpN CPUN Elp1 CPU1\n");
820
821
822 if (fpvar.outfile[0]) {
823 fprintf(outreport,
824 " %s %d %d %d %d %#10.4g %d %#10.4g %#10.4g %#10.4g %#10.4g %#10.4g %#10.4g %#10.4g %#10.4g %#10.4g %#10.4g",
825 infits, extnum, bitpix, naxes[0], naxes[1], origdata, imagestats.n_nulls, imagestats.minval,
826 imagestats.maxval, imagestats.mean, imagestats.sigma,
827 imagestats.noise1, imagestats.noise3, whole_elapse, whole_cpu, row_elapse, row_cpu);
828 }
829
830
831 /* test compression ratio and speed for each algorithm */
832 fits_set_compression_type (outfptr, RICE_1, &stat);
833 fits_set_tile_dim (outfptr, 6, fpvar.ntile, &stat);
834 fp_test_hdu(infptr, outfptr, outfptr2, fpvar, &stat);
835
836 fits_set_compression_type (outfptr, HCOMPRESS_1, &stat);
837 fits_set_tile_dim (outfptr, 6, fpvar.ntile, &stat);
838 fp_test_hdu(infptr, outfptr, outfptr2, fpvar, &stat);
839
840 fits_set_compression_type (outfptr, GZIP_1, &stat);
841 fits_set_tile_dim (outfptr, 6, fpvar.ntile, &stat);
842 fp_test_hdu(infptr, outfptr, outfptr2, fpvar, &stat);
843
844 if (bitpix == SHORT_IMG || bitpix == LONG_IMG) {
845 fits_set_compression_type (outfptr, NOCOMPRESS, &stat);
846 fits_set_tile_dim (outfptr, 6, fpvar.ntile, &stat);
847 fp_test_hdu(infptr, outfptr, outfptr2, fpvar, &stat);
848 }
849
850 if (fpvar.outfile[0])
851 fprintf(outreport,"\n");
852
853 /* delete the temporary file */
854 if (rescale_flag)
855 fits_delete_file (infptr, &stat);
856
857 } else {
858 fits_copy_hdu (inputfptr, outfptr, 0, &stat);
859 fits_copy_hdu (inputfptr, outfptr2, 0, &stat);
860 }
861
862 fits_movrel_hdu (inputfptr, 1, NULL, &stat);
863 extnum++;
864 }
865
866
867 if (stat == END_OF_FILE) stat = 0;
868
869 fits_close_file (outfptr2, &stat);
870 fits_close_file (outfptr, &stat);
871 fits_close_file (inputfptr, &stat);
872
873 if (stat) {
874 fits_report_error (stderr, stat);
875 }
876 return(0);
877}
878/*--------------------------------------------------------------------------*/
879int fp_pack_hdu (fitsfile *infptr, fitsfile *outfptr, fpstate fpvar,
880 int *islossless, int *status)
881{
882 fitsfile *tempfile;
883 long naxes[9] = {1, 1, 1, 1, 1, 1, 1, 1, 1};
884 int stat=0, totpix=0, naxis=0, ii, hdutype, bitpix;
885 int tstatus, hdunum, rescale_flag = 0;
886 double bscale, rescale;
887
888 if (*status) return(0);
889
890 fits_get_hdu_type (infptr, &hdutype, &stat);
891
892 if (hdutype == IMAGE_HDU) {
893 fits_get_img_param (infptr, 9, &bitpix, &naxis, naxes, &stat);
894 for (totpix=1, ii=0; ii < 9; ii++) totpix *= naxes[ii];
895 }
896
897 if (fits_is_compressed_image (infptr, &stat) ||
898 hdutype != IMAGE_HDU || naxis == 0 || totpix == 0) {
899
900 fits_copy_hdu (infptr, outfptr, 0, &stat);
901
902 } else {
903
904 /* rescale a scaled integer image to reduce noise? */
905 if (fpvar.rescale_noise != 0. && bitpix > 0 && bitpix < LONGLONG_IMG) {
906
907 tstatus = 0;
908 fits_read_key(infptr, TDOUBLE, "BSCALE", &bscale, 0, &tstatus);
909 if (tstatus == 0 && bscale != 1.0) { /* image must be scaled */
910
911 if (bitpix == LONG_IMG)
912 fp_i4stat(infptr, naxis, naxes, &stat);
913 else
914 fp_i2stat(infptr, naxis, naxes, &stat);
915
916 rescale = imagestats.noise3 / fpvar.rescale_noise;
917 if (rescale > 1.0) {
918
919 /* all the criteria are met, so create a temporary file that */
920 /* contains a rescaled version of the image */
921
922 fits_create_file(&tempfile, "!fptmpqqqq.qqqr", &stat);
923
924 fits_get_hdu_num(infptr, &hdunum);
925 if (hdunum != 1) {
926
927 /* the input hdu is an image extension, so create dummy primary */
928 fits_create_img(tempfile, 8, 0, naxes, &stat);
929 }
930
931 fits_copy_header(infptr, tempfile, &stat); /* copy the header */
932
933 /* rescale the data, so that it will compress more efficiently */
934 if (bitpix == LONG_IMG)
935 fp_i4rescale(infptr, naxis, naxes, rescale, tempfile, &stat);
936 else
937 fp_i2rescale(infptr, naxis, naxes, rescale, tempfile, &stat);
938
939 /* scale the BSCALE keyword by the inverse factor */
940
941 bscale = bscale * rescale;
942 fits_update_key(tempfile, TDOUBLE, "BSCALE", &bscale, 0, &stat);
943
944 /* rescan the header, to reset the actual scaling parameters */
945 fits_set_hdustruc(tempfile, &stat);
946
947 rescale_flag = 1;
948 }
949 }
950 }
951
952 if (rescale_flag) {
953 fits_img_compress (tempfile, outfptr, &stat);
954 fits_delete_file (tempfile, &stat);
955 } else {
956 fits_img_compress (infptr, outfptr, &stat);
957 }
958
959 if (bitpix < 0 || rescale_flag ||
960 (fpvar.comptype == HCOMPRESS_1 && fpvar.scale != 0.)) {
961
962 /* compressed image is not identical to original */
963 *islossless = 0;
964 }
965 }
966
967 *status = stat;
968 return(0);
969}
970
971/*--------------------------------------------------------------------------*/
972int fp_unpack_hdu (fitsfile *infptr, fitsfile *outfptr, int *status)
973{
974 int stat=0;
975
976 if (*status) return(0);
977
978 if (fits_is_compressed_image (infptr, &stat))
979 fits_img_decompress (infptr, outfptr, &stat);
980 else
981 fits_copy_hdu (infptr, outfptr, 0, &stat);
982
983 *status = stat;
984 return(0);
985}
986/*--------------------------------------------------------------------------*/
987int fits_read_image_speed (fitsfile *infptr, float *whole_elapse,
988 float *whole_cpu, float *row_elapse, float *row_cpu, int *status)
989{
990 unsigned char *carray, cnull = 0;
991 short *sarray, snull=0;
992 int bitpix, naxis, anynull, *iarray, inull = 0;
993 long ii, naxes[9], fpixel[9]={1,1,1,1,1,1,1,1,1}, lpixel[9]={1,1,1,1,1,1,1,1,1};
994 long inc[9]={1,1,1,1,1,1,1,1,1} ;
995 float *earray, enull = 0, filesize;
996 double *darray, dnull = 0;
997 LONGLONG fpixelll[9];
998
999 if (*status) return(*status);
1000
1001 fits_get_img_param (infptr, 9, &bitpix, &naxis, naxes, status);
1002
1003 if (naxis != 2)return(*status);
1004
1005 lpixel[0] = naxes[0];
1006 lpixel[1] = naxes[1];
1007
1008 /* filesize in MB */
1009 filesize = naxes[0] * abs(bitpix) / 8000000. * naxes[1];
1010
1011 /* measure time required to read the raw image */
1012 fits_set_bscale(infptr, 1.0, 0.0, status);
1013 *whole_elapse = 0.;
1014 *whole_cpu = 0;
1015
1016 if (bitpix == BYTE_IMG) {
1017 carray = calloc(naxes[1]*naxes[0], sizeof(char));
1018
1019 marktime(status);
1020 fits_read_subset(infptr, TBYTE, fpixel, lpixel, inc, &cnull,
1021 carray, &anynull, status);
1022
1023 /* get elapsped times */
1024 gettime(whole_elapse, whole_cpu, status);
1025
1026 /* now read the image again, row by row */
1027 if (row_elapse) {
1028 marktime(status);
1029 for (ii = 0; ii < naxes[1]; ii++) {
1030 fpixel[1] = ii+1;
1031 fits_read_pix(infptr, TBYTE, fpixel, naxes[0], &cnull,
1032 carray, &anynull, status);
1033 }
1034 /* get elapsped times */
1035 gettime(row_elapse, row_cpu, status);
1036 }
1037 free(carray);
1038
1039 } else if (bitpix == SHORT_IMG) {
1040 sarray = calloc(naxes[0]*naxes[1], sizeof(short));
1041
1042 marktime(status);
1043
1044 fits_read_subset(infptr, TSHORT, fpixel, lpixel, inc, &snull,
1045 sarray, &anynull, status);
1046
1047 gettime(whole_elapse, whole_cpu, status); /* get elapsped times */
1048
1049 /* now read the image again, row by row */
1050 if (row_elapse) {
1051 marktime(status);
1052 for (ii = 0; ii < naxes[1]; ii++) {
1053 fpixel[1] = ii+1;
1054 fits_read_pix(infptr, TSHORT, fpixel, naxes[0], &snull,
1055 sarray, &anynull, status);
1056 }
1057 /* get elapsped times */
1058 gettime(row_elapse, row_cpu, status);
1059 }
1060
1061 free(sarray);
1062
1063 } else if (bitpix == LONG_IMG) {
1064 iarray = calloc(naxes[0]*naxes[1], sizeof(int));
1065
1066 marktime(status);
1067
1068 fits_read_subset(infptr, TINT, fpixel, lpixel, inc, &inull,
1069 iarray, &anynull, status);
1070
1071 /* get elapsped times */
1072 gettime(whole_elapse, whole_cpu, status);
1073
1074
1075 /* now read the image again, row by row */
1076 if (row_elapse) {
1077 marktime(status);
1078 for (ii = 0; ii < naxes[1]; ii++) {
1079 fpixel[1] = ii+1;
1080 fits_read_pix(infptr, TINT, fpixel, naxes[0], &inull,
1081 iarray, &anynull, status);
1082 }
1083 /* get elapsped times */
1084 gettime(row_elapse, row_cpu, status);
1085 }
1086
1087
1088 free(iarray);
1089
1090 } else if (bitpix == FLOAT_IMG) {
1091 earray = calloc(naxes[1]*naxes[0], sizeof(float));
1092
1093 marktime(status);
1094
1095 fits_read_subset(infptr, TFLOAT, fpixel, lpixel, inc, &enull,
1096 earray, &anynull, status);
1097
1098 /* get elapsped times */
1099 gettime(whole_elapse, whole_cpu, status);
1100
1101 /* now read the image again, row by row */
1102 if (row_elapse) {
1103 marktime(status);
1104 for (ii = 0; ii < naxes[1]; ii++) {
1105 fpixel[1] = ii+1;
1106 fits_read_pix(infptr, TFLOAT, fpixel, naxes[0], &enull,
1107 earray, &anynull, status);
1108 }
1109 /* get elapsped times */
1110 gettime(row_elapse, row_cpu, status);
1111 }
1112
1113 free(earray);
1114
1115 } else if (bitpix == DOUBLE_IMG) {
1116 darray = calloc(naxes[1]*naxes[0], sizeof(double));
1117
1118 marktime(status);
1119
1120 fits_read_subset(infptr, TDOUBLE, fpixel, lpixel, inc, &dnull,
1121 darray, &anynull, status);
1122
1123 /* get elapsped times */
1124 gettime(whole_elapse, whole_cpu, status);
1125
1126 /* now read the image again, row by row */
1127 if (row_elapse) {
1128 marktime(status);
1129 for (ii = 0; ii < naxes[1]; ii++) {
1130 fpixel[1] = ii+1;
1131 fits_read_pix(infptr, TDOUBLE, fpixel, naxes[0], &dnull,
1132 darray, &anynull, status);
1133 }
1134 /* get elapsped times */
1135 gettime(row_elapse, row_cpu, status);
1136 }
1137
1138 free(darray);
1139 }
1140
1141 if (whole_elapse) *whole_elapse = *whole_elapse / filesize;
1142 if (row_elapse) *row_elapse = *row_elapse / filesize;
1143 if (whole_cpu) *whole_cpu = *whole_cpu / filesize;
1144 if (row_cpu) *row_cpu = *row_cpu / filesize;
1145
1146 return(*status);
1147}
1148/*--------------------------------------------------------------------------*/
1149int fp_test_hdu (fitsfile *infptr, fitsfile *outfptr, fitsfile *outfptr2,
1150 fpstate fpvar, int *status)
1151{
1152
1153 int stat = 0, hdutype, comptype, noloss = 0;
1154 char ctype[20], lossless[4];
1155 long headstart, datastart, dataend;
1156 float origdata = 0., compressdata = 0.;
1157 float compratio = 0., packcpu = 0., unpackcpu = 0., readcpu;
1158 float elapse, whole_elapse, row_elapse, whole_cpu, row_cpu;
1159 unsigned long datasum1, datasum2, hdusum;
1160
1161 if (*status) return(0);
1162
1163 origdata = 0;
1164 compressdata = 0;
1165 compratio = 0.;
1166 lossless[0] = '\0';
1167
1168 fits_get_compression_type(outfptr, &comptype, &stat);
1169 if (comptype == RICE_1)
1170 strcpy(ctype, "RICE");
1171 else if (comptype == GZIP_1)
1172 strcpy(ctype, "GZIP");
1173 else if (comptype == PLIO_1)
1174 strcpy(ctype, "PLIO");
1175 else if (comptype == HCOMPRESS_1)
1176 strcpy(ctype, "HCOMP");
1177 else if (comptype == NOCOMPRESS)
1178 strcpy(ctype, "NONE");
1179 /* -------------- COMPRESS the image ------------------ */
1180
1181 marktime(&stat);
1182
1183 fits_img_compress (infptr, outfptr, &stat);
1184
1185 /* get elapsped times */
1186 gettime(&elapse, &packcpu, &stat);
1187
1188 /* get elapsed and cpu times need to read the compressed image */
1189/*
1190 if (comptype == HCOMPRESS_1) {
1191 fits_read_image_speed (outfptr, &whole_elapse, &whole_cpu,
1192 0, 0, &stat);
1193 row_elapse = 0; row_cpu = 0;
1194 } else
1195*/
1196 fits_read_image_speed (outfptr, &whole_elapse, &whole_cpu,
1197 &row_elapse, &row_cpu, &stat);
1198
1199
1200 if (!stat) {
1201
1202 /* -------------- UNCOMPRESS the image ------------------ */
1203 marktime(&stat);
1204
1205 fits_img_decompress (outfptr, outfptr2, &stat);
1206
1207 /* get elapsped times */
1208 gettime(&elapse, &unpackcpu, &stat);
1209
1210 /* ----------------------------------------------------- */
1211
1212 /* get sizes of original and compressed images */
1213
1214 fits_get_hduaddr(infptr, &headstart, &datastart, &dataend, &stat);
1215 origdata = (dataend - datastart)/1000000.;
1216
1217 fits_get_hduaddr(outfptr, &headstart, &datastart, &dataend, &stat);
1218 compressdata = (dataend - datastart)/1000000.;
1219
1220 if (compressdata != 0)
1221 compratio = (float) origdata / (float) compressdata;
1222
1223 /* is this uncompressed image identical to the original? */
1224
1225 fits_get_chksum(infptr, &datasum1, &hdusum, &stat);
1226 fits_get_chksum(outfptr2, &datasum2, &hdusum, &stat);
1227
1228 if ( datasum1 == datasum2) {
1229 strcpy(lossless, "Yes");
1230 noloss = 1;
1231 } else {
1232 strcpy(lossless, "No");
1233 }
1234
1235 printf(" %-5s %6.2f %7.2f ->%7.2f %7.2f %7.2f %s %5.3f %5.3f %5.3f %5.3f\n",
1236 ctype, compratio, origdata, compressdata,
1237 packcpu, unpackcpu, lossless, whole_elapse, whole_cpu,
1238 row_elapse, row_cpu);
1239
1240
1241 if (fpvar.outfile[0]) {
1242 fprintf(outreport," %6.3f %5.2f %5.2f %s %7.3f %7.3f %7.3f %7.3f",
1243 compratio, packcpu, unpackcpu, lossless, whole_elapse, whole_cpu,
1244 row_elapse, row_cpu);
1245 }
1246
1247 /* delete the output HDUs to concerve disk space */
1248
1249 fits_delete_hdu(outfptr, &hdutype, &stat);
1250 fits_delete_hdu(outfptr2, &hdutype, &stat);
1251
1252 } else {
1253 printf(" %-5s (unable to compress image)\n", ctype);
1254 }
1255
1256 /* try to recover from any compression errors */
1257 if (stat == DATA_COMPRESSION_ERR) stat = 0;
1258
1259 *status = stat;
1260 return(0);
1261}
1262
1263/*--------------------------------------------------------------------------*/
1264int marktime(int *status)
1265{
1266 struct timeval tv;
1267/* struct timezone tz; */
1268
1269/* gettimeofday (&tv, &tz); */
1270 gettimeofday (&tv, NULL);
1271
1272 startsec = tv.tv_sec;
1273 startmilli = tv.tv_usec/1000;
1274
1275 scpu = clock();
1276
1277 return( *status );
1278}
1279/*--------------------------------------------------------------------------*/
1280int gettime(float *elapse, float *elapscpu, int *status)
1281{
1282 struct timeval tv;
1283/* struct timezone tz; */
1284 int stopmilli;
1285 long stopsec;
1286
1287/* gettimeofday (&tv, &tz); */
1288 gettimeofday (&tv, NULL);
1289 ecpu = clock();
1290
1291 stopmilli = tv.tv_usec/1000;
1292 stopsec = tv.tv_sec;
1293
1294 *elapse = (stopsec - startsec) + (stopmilli - startmilli)/1000.;
1295 *elapscpu = (ecpu - scpu) * 1.0 / CLOCKTICKS;
1296/*
1297printf(" (start: %ld + %d), stop: (%ld + %d) elapse: %f\n ",
1298startsec,startmilli,stopsec, stopmilli, *elapse);
1299*/
1300 return( *status );
1301}
1302/*--------------------------------------------------------------------------*/
1303int fp_i2stat(fitsfile *infptr, int naxis, long *naxes, int *status)
1304{
1305/*
1306 read the central XSAMPLE by YSAMPLE region of pixels in the int*2 image,
1307 and then compute basic statistics: min, max, mean, sigma, mean diff, etc.
1308*/
1309
1310 long fpixel[9] = {1,1,1,1,1,1,1,1,1};
1311 long lpixel[9] = {1,1,1,1,1,1,1,1,1};
1312 long inc[9] = {1,1,1,1,1,1,1,1,1};
1313 long i1, i2, npix, ii, ngood, nx, ny;
1314 short *intarray, minvalue, maxvalue, nullvalue;
1315 int anynul, tstatus, checknull = 1;
1316 double mean, sigma, noise1, noise3;
1317
1318 /* select the middle XSAMPLE by YSAMPLE area of the image */
1319 i1 = naxes[0]/2 - (XSAMPLE/2 - 1);
1320 i2 = naxes[0]/2 + (XSAMPLE/2);
1321 if (i1 < 1) i1 = 1;
1322 if (i2 > naxes[0]) i2 = naxes[0];
1323 fpixel[0] = i1;
1324 lpixel[0] = i2;
1325 nx = i2 - i1 +1;
1326
1327 if (naxis > 1) {
1328 i1 = naxes[1]/2 - (YSAMPLE/2 - 1);
1329 i2 = naxes[1]/2 + (YSAMPLE/2);
1330 if (i1 < 1) i1 = 1;
1331 if (i2 > naxes[1]) i2 = naxes[1];
1332 fpixel[1] = i1;
1333 lpixel[1] = i2;
1334 }
1335 ny = i2 - i1 +1;
1336
1337 npix = nx * ny;
1338
1339 /* if there are higher dimensions, read the middle plane of the cube */
1340 if (naxis > 2) {
1341 fpixel[2] = naxes[2]/2 + 1;
1342 lpixel[2] = naxes[2]/2 + 1;
1343 }
1344
1345 intarray = calloc(npix, sizeof(short));
1346 if (!intarray) {
1347 *status = MEMORY_ALLOCATION;
1348 return(*status);
1349 }
1350
1351 /* turn off any scaling of the integer pixel values */
1352 fits_set_bscale(infptr, 1.0, 0.0, status);
1353
1354 fits_read_subset_sht(infptr, 0, naxis, naxes, fpixel, lpixel, inc,
1355 0, intarray, &anynul, status);
1356
1357 /* read the null value keyword (BLANK) if present */
1358 tstatus = 0;
1359 fits_read_key(infptr, TSHORT, "BLANK", &nullvalue, 0, &tstatus);
1360 if (tstatus) {
1361 nullvalue = 0;
1362 checknull = 0;
1363 }
1364
1365 /* compute statistics of the image */
1366
1367 fits_img_stats_short(intarray, nx, ny, checknull, nullvalue,
1368 &ngood, &minvalue, &maxvalue, &mean, &sigma, &noise1, &noise3, status);
1369
1370 imagestats.n_nulls = npix - ngood;
1371 imagestats.minval = minvalue;
1372 imagestats.maxval = maxvalue;
1373 imagestats.mean = mean;
1374 imagestats.sigma = sigma;
1375 imagestats.noise1 = noise1;
1376 imagestats.noise3 = noise3;
1377
1378 free(intarray);
1379 return(*status);
1380}
1381/*--------------------------------------------------------------------------*/
1382int fp_i4stat(fitsfile *infptr, int naxis, long *naxes, int *status)
1383{
1384/*
1385 read the central XSAMPLE by YSAMPLE region of pixels in the int*2 image,
1386 and then compute basic statistics: min, max, mean, sigma, mean diff, etc.
1387*/
1388
1389 long fpixel[9] = {1,1,1,1,1,1,1,1,1};
1390 long lpixel[9] = {1,1,1,1,1,1,1,1,1};
1391 long inc[9] = {1,1,1,1,1,1,1,1,1};
1392 long i1, i2, npix, ii, ngood, nx, ny;
1393 int *intarray, minvalue, maxvalue, nullvalue;
1394 int anynul, tstatus, checknull = 1;
1395 double mean, sigma, noise1, noise3;
1396
1397 /* select the middle XSAMPLE by YSAMPLE area of the image */
1398 i1 = naxes[0]/2 - (XSAMPLE/2 - 1);
1399 i2 = naxes[0]/2 + (XSAMPLE/2);
1400 if (i1 < 1) i1 = 1;
1401 if (i2 > naxes[0]) i2 = naxes[0];
1402 fpixel[0] = i1;
1403 lpixel[0] = i2;
1404 nx = i2 - i1 +1;
1405
1406 if (naxis > 1) {
1407 i1 = naxes[1]/2 - (YSAMPLE/2 - 1);
1408 i2 = naxes[1]/2 + (YSAMPLE/2);
1409 if (i1 < 1) i1 = 1;
1410 if (i2 > naxes[1]) i2 = naxes[1];
1411 fpixel[1] = i1;
1412 lpixel[1] = i2;
1413 }
1414 ny = i2 - i1 +1;
1415
1416 npix = nx * ny;
1417
1418 /* if there are higher dimensions, read the middle plane of the cube */
1419 if (naxis > 2) {
1420 fpixel[2] = naxes[2]/2 + 1;
1421 lpixel[2] = naxes[2]/2 + 1;
1422 }
1423
1424 intarray = calloc(npix, sizeof(int));
1425 if (!intarray) {
1426 *status = MEMORY_ALLOCATION;
1427 return(*status);
1428 }
1429
1430 /* turn off any scaling of the integer pixel values */
1431 fits_set_bscale(infptr, 1.0, 0.0, status);
1432
1433 fits_read_subset_int(infptr, 0, naxis, naxes, fpixel, lpixel, inc,
1434 0, intarray, &anynul, status);
1435
1436 /* read the null value keyword (BLANK) if present */
1437 tstatus = 0;
1438 fits_read_key(infptr, TINT, "BLANK", &nullvalue, 0, &tstatus);
1439 if (tstatus) {
1440 nullvalue = 0;
1441 checknull = 0;
1442 }
1443
1444 /* compute statistics of the image */
1445
1446 fits_img_stats_int(intarray, nx, ny, checknull, nullvalue,
1447 &ngood, &minvalue, &maxvalue, &mean, &sigma, &noise1, &noise3, status);
1448
1449 imagestats.n_nulls = npix - ngood;
1450 imagestats.minval = minvalue;
1451 imagestats.maxval = maxvalue;
1452 imagestats.mean = mean;
1453 imagestats.sigma = sigma;
1454 imagestats.noise1 = noise1;
1455 imagestats.noise3 = noise3;
1456
1457 free(intarray);
1458 return(*status);
1459}
1460/*--------------------------------------------------------------------------*/
1461int fp_r4stat(fitsfile *infptr, int naxis, long *naxes, int *status)
1462{
1463/*
1464 read the central XSAMPLE by YSAMPLE region of pixels in the int*2 image,
1465 and then compute basic statistics: min, max, mean, sigma, mean diff, etc.
1466*/
1467
1468 long fpixel[9] = {1,1,1,1,1,1,1,1,1};
1469 long lpixel[9] = {1,1,1,1,1,1,1,1,1};
1470 long inc[9] = {1,1,1,1,1,1,1,1,1};
1471 long i1, i2, npix, ii, ngood, nx, ny;
1472 float *array, minvalue, maxvalue, nullvalue = FLOATNULLVALUE;
1473 int anynul,checknull = 1;
1474 double mean, sigma, noise1, noise3;
1475
1476 /* select the middle XSAMPLE by YSAMPLE area of the image */
1477 i1 = naxes[0]/2 - (XSAMPLE/2 - 1);
1478 i2 = naxes[0]/2 + (XSAMPLE/2);
1479 if (i1 < 1) i1 = 1;
1480 if (i2 > naxes[0]) i2 = naxes[0];
1481 fpixel[0] = i1;
1482 lpixel[0] = i2;
1483 nx = i2 - i1 +1;
1484
1485 if (naxis > 1) {
1486 i1 = naxes[1]/2 - (YSAMPLE/2 - 1);
1487 i2 = naxes[1]/2 + (YSAMPLE/2);
1488 if (i1 < 1) i1 = 1;
1489 if (i2 > naxes[1]) i2 = naxes[1];
1490 fpixel[1] = i1;
1491 lpixel[1] = i2;
1492 }
1493 ny = i2 - i1 +1;
1494
1495 npix = nx * ny;
1496
1497 /* if there are higher dimensions, read the middle plane of the cube */
1498 if (naxis > 2) {
1499 fpixel[2] = naxes[2]/2 + 1;
1500 lpixel[2] = naxes[2]/2 + 1;
1501 }
1502
1503 array = calloc(npix, sizeof(float));
1504 if (!array) {
1505 *status = MEMORY_ALLOCATION;
1506 return(*status);
1507 }
1508
1509 fits_read_subset_flt(infptr, 0, naxis, naxes, fpixel, lpixel, inc,
1510 nullvalue, array, &anynul, status);
1511
1512 /* are there any null values in the array? */
1513 if (!anynul) {
1514 nullvalue = 0.;
1515 checknull = 0;
1516 }
1517
1518 /* compute statistics of the image */
1519
1520 fits_img_stats_float(array, nx, ny, checknull, nullvalue,
1521 &ngood, &minvalue, &maxvalue, &mean, &sigma, &noise1, &noise3, status);
1522
1523 imagestats.n_nulls = npix - ngood;
1524 imagestats.minval = minvalue;
1525 imagestats.maxval = maxvalue;
1526 imagestats.mean = mean;
1527 imagestats.sigma = sigma;
1528 imagestats.noise1 = noise1;
1529 imagestats.noise3 = noise3;
1530
1531 free(array);
1532 return(*status);
1533}
1534/*--------------------------------------------------------------------------*/
1535int fp_i2rescale(fitsfile *infptr, int naxis, long *naxes, double rescale,
1536 fitsfile *outfptr, int *status)
1537{
1538/*
1539 divide the integer pixel values in the input file by rescale,
1540 and write back out to the output file..
1541*/
1542
1543 long ii, jj, nelem = 1, nx, ny;
1544 short *intarray, nullvalue;
1545 int anynul, tstatus, checknull = 1;
1546
1547 nx = naxes[0];
1548 ny = 1;
1549
1550 for (ii = 1; ii < naxis; ii++) {
1551 ny = ny * naxes[ii];
1552 }
1553
1554 intarray = calloc(nx, sizeof(short));
1555 if (!intarray) {
1556 *status = MEMORY_ALLOCATION;
1557 return(*status);
1558 }
1559
1560 /* read the null value keyword (BLANK) if present */
1561 tstatus = 0;
1562 fits_read_key(infptr, TSHORT, "BLANK", &nullvalue, 0, &tstatus);
1563 if (tstatus) {
1564 checknull = 0;
1565 }
1566
1567 /* turn off any scaling of the integer pixel values */
1568 fits_set_bscale(infptr, 1.0, 0.0, status);
1569 fits_set_bscale(outfptr, 1.0, 0.0, status);
1570
1571 for (ii = 0; ii < ny; ii++) {
1572
1573 fits_read_img_sht(infptr, 1, nelem, nx,
1574 0, intarray, &anynul, status);
1575
1576 if (checknull) {
1577 for (jj = 0; jj < nx; jj++) {
1578 if (intarray[jj] != nullvalue)
1579 intarray[jj] = NSHRT( (intarray[jj] / rescale) );
1580 }
1581 } else {
1582 for (jj = 0; jj < nx; jj++)
1583 intarray[jj] = NSHRT( (intarray[jj] / rescale) );
1584 }
1585
1586 fits_write_img_sht(outfptr, 1, nelem, nx, intarray, status);
1587
1588 nelem += nx;
1589 }
1590
1591 free(intarray);
1592 return(*status);
1593}
1594/*--------------------------------------------------------------------------*/
1595int fp_i4rescale(fitsfile *infptr, int naxis, long *naxes, double rescale,
1596 fitsfile *outfptr, int *status)
1597{
1598/*
1599 divide the integer pixel values in the input file by rescale,
1600 and write back out to the output file..
1601*/
1602
1603 long ii, jj, nelem = 1, nx, ny;
1604 int *intarray, nullvalue;
1605 int anynul, tstatus, checknull = 1;
1606
1607 nx = naxes[0];
1608 ny = 1;
1609
1610 for (ii = 1; ii < naxis; ii++) {
1611 ny = ny * naxes[ii];
1612 }
1613
1614 intarray = calloc(nx, sizeof(int));
1615 if (!intarray) {
1616 *status = MEMORY_ALLOCATION;
1617 return(*status);
1618 }
1619
1620 /* read the null value keyword (BLANK) if present */
1621 tstatus = 0;
1622 fits_read_key(infptr, TINT, "BLANK", &nullvalue, 0, &tstatus);
1623 if (tstatus) {
1624 checknull = 0;
1625 }
1626
1627 /* turn off any scaling of the integer pixel values */
1628 fits_set_bscale(infptr, 1.0, 0.0, status);
1629 fits_set_bscale(outfptr, 1.0, 0.0, status);
1630
1631 for (ii = 0; ii < ny; ii++) {
1632
1633 fits_read_img_int(infptr, 1, nelem, nx,
1634 0, intarray, &anynul, status);
1635
1636 if (checknull) {
1637 for (jj = 0; jj < nx; jj++) {
1638 if (intarray[jj] != nullvalue)
1639 intarray[jj] = NINT( (intarray[jj] / rescale) );
1640 }
1641 } else {
1642 for (jj = 0; jj < nx; jj++)
1643 intarray[jj] = NINT( (intarray[jj] / rescale) );
1644 }
1645
1646 fits_write_img_int(outfptr, 1, nelem, nx, intarray, status);
1647
1648 nelem += nx;
1649 }
1650
1651 free(intarray);
1652 return(*status);
1653}
1654/* ========================================================================
1655 * Signal and error handler.
1656 */
1657void abort_fpack(int sig)
1658{
1659 char tempfilename[SZ_STR];
1660 if (tempfilename[0]) {
1661 remove(tempfilename);
1662 }
1663
1664 exit(-1);
1665}