"SfR Fresh" - the SfR Freeware/Shareware Archive 
Member "cfitsio/cfileio.c" of archive cfitsio3100.tar.gz:
As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers.
Alternatively you can here view or download the uninterpreted source code file.
That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
1 /* This file, cfileio.c, contains the low-level file access routines. */
2
3 /* The FITSIO software was written by William Pence at the High Energy */
4 /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */
5 /* Goddard Space Flight Center. */
6
7 #include <string.h>
8 #include <stdlib.h>
9 #include <math.h>
10 #include <ctype.h>
11 #include <errno.h>
12 #include <stddef.h> /* apparently needed to define size_t */
13 #include "fitsio2.h"
14 #include "group.h"
15
16 #define MAX_PREFIX_LEN 20 /* max length of file type prefix (e.g. 'http://') */
17 #define MAX_DRIVERS 23 /* max number of file I/O drivers */
18
19 typedef struct /* structure containing pointers to I/O driver functions */
20 { char prefix[MAX_PREFIX_LEN];
21 int (*init)(void);
22 int (*shutdown)(void);
23 int (*setoptions)(int option);
24 int (*getoptions)(int *options);
25 int (*getversion)(int *version);
26 int (*checkfile)(char *urltype, char *infile, char *outfile);
27 int (*open)(char *filename, int rwmode, int *driverhandle);
28 int (*create)(char *filename, int *drivehandle);
29 int (*truncate)(int drivehandle, LONGLONG size);
30 int (*close)(int drivehandle);
31 int (*remove)(char *filename);
32 int (*size)(int drivehandle, LONGLONG *size);
33 int (*flush)(int drivehandle);
34 int (*seek)(int drivehandle, LONGLONG offset);
35 int (*read)(int drivehandle, void *buffer, long nbytes);
36 int (*write)(int drivehandle, void *buffer, long nbytes);
37 } fitsdriver;
38
39 fitsdriver driverTable[MAX_DRIVERS]; /* allocate driver tables */
40
41 FITSfile *FptrTable[NMAXFILES]; /* this table of Fptr pointers is */
42 /* used by fits_already_open */
43
44 int need_to_initialize = 1; /* true if CFITSIO has not been initialized */
45 int no_of_drivers = 0; /* number of currently defined I/O drivers */
46
47 static int pixel_filter_helper(fitsfile **fptr, char *outfile,
48 char *expr, int *status);
49
50
51 /*--------------------------------------------------------------------------*/
52 int ffomem(fitsfile **fptr, /* O - FITS file pointer */
53 const char *name, /* I - name of file to open */
54 int mode, /* I - 0 = open readonly; 1 = read/write */
55 void **buffptr, /* I - address of memory pointer */
56 size_t *buffsize, /* I - size of buffer, in bytes */
57 size_t deltasize, /* I - increment for future realloc's */
58 void *(*mem_realloc)(void *p, size_t newsize), /* function */
59 int *status) /* IO - error status */
60 /*
61 Open an existing FITS file in core memory. This is a specialized version
62 of ffopen.
63 */
64 {
65 int driver, handle, hdutyp, slen, movetotype, extvers, extnum;
66 char extname[FLEN_VALUE];
67 LONGLONG filesize;
68 char urltype[MAX_PREFIX_LEN], infile[FLEN_FILENAME], outfile[FLEN_FILENAME];
69 char extspec[FLEN_FILENAME], rowfilter[FLEN_FILENAME];
70 char binspec[FLEN_FILENAME], colspec[FLEN_FILENAME];
71 char imagecolname[FLEN_VALUE], rowexpress[FLEN_FILENAME];
72 char *url, errmsg[FLEN_ERRMSG];
73 char *hdtype[3] = {"IMAGE", "TABLE", "BINTABLE"};
74
75 if (*status > 0)
76 return(*status);
77
78 *fptr = 0; /* initialize null file pointer */
79
80 if (need_to_initialize) /* this is called only once */
81 {
82 if (need_to_initialize != 1) {
83 /* This is bad. looks like memory has been corrupted. */
84 ffpmsg("Vital CFITSIO parameters held in memory have been corrupted!!");
85 ffpmsg("Fatal condition detected in ffomem.");
86 *status = FILE_NOT_OPENED;
87 return(*status);
88 }
89
90 *status = fits_init_cfitsio();
91
92 if (*status > 0)
93 return(*status);
94 }
95
96 url = (char *) name;
97 while (*url == ' ') /* ignore leading spaces in the file spec */
98 url++;
99
100 /* parse the input file specification */
101 ffiurl(url, urltype, infile, outfile, extspec,
102 rowfilter, binspec, colspec, status);
103
104 strcpy(urltype, "memkeep://"); /* URL type for pre-existing memory file */
105
106 *status = urltype2driver(urltype, &driver);
107
108 if (*status > 0)
109 {
110 ffpmsg("could not find driver for pre-existing memory file: (ffomem)");
111 return(*status);
112 }
113
114 /* call driver routine to open the memory file */
115 *status = mem_openmem( buffptr, buffsize,deltasize,
116 mem_realloc, &handle);
117
118 if (*status > 0)
119 {
120 ffpmsg("failed to open pre-existing memory file: (ffomem)");
121 return(*status);
122 }
123
124 /* get initial file size */
125 *status = (*driverTable[driver].size)(handle, &filesize);
126
127 if (*status > 0)
128 {
129 (*driverTable[driver].close)(handle); /* close the file */
130 ffpmsg("failed get the size of the memory file: (ffomem)");
131 return(*status);
132 }
133
134 /* allocate fitsfile structure and initialize = 0 */
135 *fptr = (fitsfile *) calloc(1, sizeof(fitsfile));
136
137 if (!(*fptr))
138 {
139 (*driverTable[driver].close)(handle); /* close the file */
140 ffpmsg("failed to allocate structure for following file: (ffomem)");
141 ffpmsg(url);
142 return(*status = MEMORY_ALLOCATION);
143 }
144
145 /* allocate FITSfile structure and initialize = 0 */
146 (*fptr)->Fptr = (FITSfile *) calloc(1, sizeof(FITSfile));
147
148 if (!((*fptr)->Fptr))
149 {
150 (*driverTable[driver].close)(handle); /* close the file */
151 ffpmsg("failed to allocate structure for following file: (ffomem)");
152 ffpmsg(url);
153 free(*fptr);
154 *fptr = 0;
155 return(*status = MEMORY_ALLOCATION);
156 }
157
158 slen = strlen(url) + 1;
159 slen = maxvalue(slen, 32); /* reserve at least 32 chars */
160 ((*fptr)->Fptr)->filename = (char *) malloc(slen); /* mem for file name */
161
162 if ( !(((*fptr)->Fptr)->filename) )
163 {
164 (*driverTable[driver].close)(handle); /* close the file */
165 ffpmsg("failed to allocate memory for filename: (ffomem)");
166 ffpmsg(url);
167 free((*fptr)->Fptr);
168 free(*fptr);
169 *fptr = 0; /* return null file pointer */
170 return(*status = MEMORY_ALLOCATION);
171 }
172
173 /* mem for headstart array */
174 ((*fptr)->Fptr)->headstart = (LONGLONG *) calloc(1001, sizeof(LONGLONG));
175
176 if ( !(((*fptr)->Fptr)->headstart) )
177 {
178 (*driverTable[driver].close)(handle); /* close the file */
179 ffpmsg("failed to allocate memory for headstart array: (ffomem)");
180 ffpmsg(url);
181 free( ((*fptr)->Fptr)->filename);
182 free((*fptr)->Fptr);
183 free(*fptr);
184 *fptr = 0; /* return null file pointer */
185 return(*status = MEMORY_ALLOCATION);
186 }
187
188 /* store the parameters describing the file */
189 ((*fptr)->Fptr)->MAXHDU = 1000; /* initial size of headstart */
190 ((*fptr)->Fptr)->filehandle = handle; /* file handle */
191 ((*fptr)->Fptr)->driver = driver; /* driver number */
192 strcpy(((*fptr)->Fptr)->filename, url); /* full input filename */
193 ((*fptr)->Fptr)->filesize = filesize; /* physical file size */
194 ((*fptr)->Fptr)->logfilesize = filesize; /* logical file size */
195 ((*fptr)->Fptr)->writemode = mode; /* read-write mode */
196 ((*fptr)->Fptr)->datastart = DATA_UNDEFINED; /* unknown start of data */
197 ((*fptr)->Fptr)->curbuf = -1; /* undefined current IO buffer */
198 ((*fptr)->Fptr)->open_count = 1; /* structure is currently used once */
199 ((*fptr)->Fptr)->validcode = VALIDSTRUC; /* flag denoting valid structure */
200
201 ffldrc(*fptr, 0, REPORT_EOF, status); /* load first record */
202
203 fits_store_Fptr( (*fptr)->Fptr, status); /* store Fptr address */
204
205 if (ffrhdu(*fptr, &hdutyp, status) > 0) /* determine HDU structure */
206 {
207 ffpmsg(
208 "ffomem could not interpret primary array header of file: (ffomem)");
209 ffpmsg(url);
210
211 if (*status == UNKNOWN_REC)
212 ffpmsg("This does not look like a FITS file.");
213
214 ffclos(*fptr, status);
215 *fptr = 0; /* return null file pointer */
216 }
217
218 /* ---------------------------------------------------------- */
219 /* move to desired extension, if specified as part of the URL */
220 /* ---------------------------------------------------------- */
221
222 imagecolname[0] = '\0';
223 rowexpress[0] = '\0';
224
225 if (*extspec)
226 {
227 /* parse the extension specifier into individual parameters */
228 ffexts(extspec, &extnum,
229 extname, &extvers, &movetotype, imagecolname, rowexpress, status);
230
231
232 if (*status > 0)
233 return(*status);
234
235 if (extnum)
236 {
237 ffmahd(*fptr, extnum + 1, &hdutyp, status);
238 }
239 else if (*extname) /* move to named extension, if specified */
240 {
241 ffmnhd(*fptr, movetotype, extname, extvers, status);
242 }
243
244 if (*status > 0)
245 {
246 ffpmsg("ffomem could not move to the specified extension:");
247 if (extnum > 0)
248 {
249 sprintf(errmsg,
250 " extension number %d doesn't exist or couldn't be opened.",extnum);
251 ffpmsg(errmsg);
252 }
253 else
254 {
255 sprintf(errmsg,
256 " extension with EXTNAME = %s,", extname);
257 ffpmsg(errmsg);
258
259 if (extvers)
260 {
261 sprintf(errmsg,
262 " and with EXTVERS = %d,", extvers);
263 ffpmsg(errmsg);
264 }
265
266 if (movetotype != ANY_HDU)
267 {
268 sprintf(errmsg,
269 " and with XTENSION = %s,", hdtype[movetotype]);
270 ffpmsg(errmsg);
271 }
272
273 ffpmsg(" doesn't exist or couldn't be opened.");
274 }
275 return(*status);
276 }
277 }
278
279 return(*status);
280 }
281 /*--------------------------------------------------------------------------*/
282 int ffdkopn(fitsfile **fptr, /* O - FITS file pointer */
283 const char *name, /* I - full name of file to open */
284 int mode, /* I - 0 = open readonly; 1 = read/write */
285 int *status) /* IO - error status */
286 /*
287 Open an existing FITS file on magnetic disk with either readonly or
288 read/write access. The routine does not support CFITSIO's extended
289 filename syntax and simply uses the entire input 'name' string as
290 the name of the file.
291 */
292 {
293 if (*status > 0)
294 return(*status);
295
296 *status = OPEN_DISK_FILE;
297
298 ffopen(fptr, name, mode, status);
299
300 return(*status);
301 }
302 /*--------------------------------------------------------------------------*/
303 int ffdopn(fitsfile **fptr, /* O - FITS file pointer */
304 const char *name, /* I - full name of file to open */
305 int mode, /* I - 0 = open readonly; 1 = read/write */
306 int *status) /* IO - error status */
307 /*
308 Open an existing FITS file with either readonly or read/write access. and
309 move to the first HDU that contains 'interesting' data, if the primary
310 array contains a null image (i.e., NAXIS = 0).
311 */
312 {
313 if (*status > 0)
314 return(*status);
315
316 *status = SKIP_NULL_PRIMARY;
317
318 ffopen(fptr, name, mode, status);
319
320 return(*status);
321 }
322 /*--------------------------------------------------------------------------*/
323 int fftopn(fitsfile **fptr, /* O - FITS file pointer */
324 const char *name, /* I - full name of file to open */
325 int mode, /* I - 0 = open readonly; 1 = read/write */
326 int *status) /* IO - error status */
327 /*
328 Open an existing FITS file with either readonly or read/write access. and
329 move to the first HDU that contains 'interesting' table (not an image).
330 */
331 {
332 int hdutype;
333
334 if (*status > 0)
335 return(*status);
336
337 *status = SKIP_IMAGE;
338
339 ffopen(fptr, name, mode, status);
340
341 if (ffghdt(*fptr, &hdutype, status) <= 0) {
342 if (hdutype == IMAGE_HDU)
343 *status = NOT_TABLE;
344 }
345
346 return(*status);
347 }
348 /*--------------------------------------------------------------------------*/
349 int ffiopn(fitsfile **fptr, /* O - FITS file pointer */
350 const char *name, /* I - full name of file to open */
351 int mode, /* I - 0 = open readonly; 1 = read/write */
352 int *status) /* IO - error status */
353 /*
354 Open an existing FITS file with either readonly or read/write access. and
355 move to the first HDU that contains 'interesting' image (not an table).
356 */
357 {
358 int hdutype;
359
360 if (*status > 0)
361 return(*status);
362
363 *status = SKIP_TABLE;
364
365 ffopen(fptr, name, mode, status);
366
367 if (ffghdt(*fptr, &hdutype, status) <= 0) {
368 if (hdutype != IMAGE_HDU)
369 *status = NOT_IMAGE;
370 }
371
372 return(*status);
373 }
374 /*--------------------------------------------------------------------------*/
375 int ffopentest(double version, /* I - CFITSIO version number, from the */
376 /* application program (fitsio.h file) */
377 fitsfile **fptr, /* O - FITS file pointer */
378 const char *name, /* I - full name of file to open */
379 int mode, /* I - 0 = open readonly; 1 = read/write */
380 int *status) /* IO - error status */
381 /*
382 Open an existing FITS file with either readonly or read/write access.
383 First test that the version of fitsio.h used to build the CFITSIO library
384 is the same as the version used in building the application program that
385 links to the library.
386 */
387 {
388 if (version != CFITSIO_VERSION)
389 {
390 printf("ERROR: Mismatch in the version of the fitsio.h include file used to build\n");
391 printf("the CFITSIO library, and the version included by the application program:\n");
392 printf(" Version used to build the CFITSIO library = %f\n",CFITSIO_VERSION);
393 printf(" Version included by the application program = %f\n",version);
394
395 *status = FILE_NOT_OPENED;
396 return(*status);
397 }
398
399 /* now call the normal file open routine */
400 ffopen(fptr, name, mode, status);
401 return(*status);
402 }
403 /*--------------------------------------------------------------------------*/
404 int ffopen(fitsfile **fptr, /* O - FITS file pointer */
405 const char *name, /* I - full name of file to open */
406 int mode, /* I - 0 = open readonly; 1 = read/write */
407 int *status) /* IO - error status */
408 /*
409 Open an existing FITS file with either readonly or read/write access.
410 */
411 {
412 fitsfile *newptr;
413 int driver, hdutyp, hdunum, slen, writecopy, isopen;
414 LONGLONG filesize;
415 long rownum, nrows, goodrows;
416 int extnum, extvers, handle, movetotype, tstatus = 0;
417 char urltype[MAX_PREFIX_LEN], infile[FLEN_FILENAME], outfile[FLEN_FILENAME];
418 char origurltype[MAX_PREFIX_LEN], extspec[FLEN_FILENAME];
419 char extname[FLEN_VALUE], rowfilter[FLEN_FILENAME], tblname[FLEN_VALUE];
420 char imagecolname[FLEN_VALUE], rowexpress[FLEN_FILENAME];
421 char binspec[FLEN_FILENAME], colspec[FLEN_FILENAME], pixfilter[FLEN_FILENAME];
422 char histfilename[FLEN_FILENAME];
423 char filtfilename[FLEN_FILENAME];
424 char wtcol[FLEN_VALUE];
425 char minname[4][FLEN_VALUE], maxname[4][FLEN_VALUE];
426 char binname[4][FLEN_VALUE];
427
428 char *url;
429 double minin[4], maxin[4], binsizein[4], weight;
430 int imagetype, naxis = 1, haxis, recip;
431 int skip_null = 0, skip_image = 0, skip_table = 0, open_disk_file = 0;
432 char colname[4][FLEN_VALUE];
433 char errmsg[FLEN_ERRMSG];
434 char *hdtype[3] = {"IMAGE", "TABLE", "BINTABLE"};
435 char *rowselect = 0;
436
437 if (*status > 0)
438 return(*status);
439
440 if (*status == SKIP_NULL_PRIMARY)
441 {
442 /* this special status value is used as a flag by ffdopn to tell */
443 /* ffopen to skip over a null primary array when opening the file. */
444
445 skip_null = 1;
446 *status = 0;
447 }
448 else if (*status == SKIP_IMAGE)
449 {
450 /* this special status value is used as a flag by fftopn to tell */
451 /* ffopen to move to 1st significant table when opening the file. */
452
453 skip_image = 1;
454 *status = 0;
455 }
456 else if (*status == SKIP_TABLE)
457 {
458 /* this special status value is used as a flag by ffiopn to tell */
459 /* ffopen to move to 1st significant image when opening the file. */
460
461 skip_table = 1;
462 *status = 0;
463 }
464 else if (*status == OPEN_DISK_FILE)
465 {
466 /* this special status value is used as a flag by ffdkopn to tell */
467 /* ffopen to not interpret the input filename using CFITSIO's */
468 /* extended filename syntax, and simply open the specified disk file */
469
470 open_disk_file = 1;
471 *status = 0;
472 }
473
474 *fptr = 0; /* initialize null file pointer */
475 writecopy = 0; /* have we made a write-able copy of the input file? */
476
477 if (need_to_initialize) { /* this is called only once */
478
479 if (need_to_initialize != 1) {
480 /* This is bad. looks like memory has been corrupted. */
481 ffpmsg("Vital CFITSIO parameters held in memory have been corrupted!!");
482 ffpmsg("Fatal condition detected in ffopen.");
483 *status = FILE_NOT_OPENED;
484 return(*status);
485 }
486
487 *status = fits_init_cfitsio();
488 }
489
490 if (*status > 0)
491 return(*status);
492
493 url = (char *) name;
494 while (*url == ' ') /* ignore leading spaces in the filename */
495 url++;
496
497 if (*url == '\0')
498 {
499 ffpmsg("Name of file to open is blank. (ffopen)");
500 return(*status = FILE_NOT_OPENED);
501 }
502
503 if (open_disk_file)
504 {
505 /* treat the input URL literally as the name of the file to open */
506 /* and don't try to parse the URL using the extended filename syntax */
507
508 if (strlen(url) > FLEN_FILENAME - 1) {
509 ffpmsg("Name of file to open is too long. (ffopen)");
510 return(*status = FILE_NOT_OPENED);
511 }
512
513 strcpy(infile,url);
514 strcpy(urltype, "file://");
515 outfile[0] = '\0';
516 extspec[0] = '\0';
517 binspec[0] = '\0';
518 colspec[0] = '\0';
519 rowfilter[0] = '\0';
520 pixfilter[0] = '\0';
521 }
522 else
523 {
524 /* parse the input file specification */
525
526 /* NOTE: This routine tests that all the strings do not */
527 /* overflow the standard buffer sizes (FLEN_FILENAME, etc.) */
528 /* therefore in general we do not have to worry about buffer */
529 /* overflow of any of the returned strings. */
530
531 fits_parse_input_filename(url, urltype, infile, outfile, extspec,
532 rowfilter, binspec, colspec, pixfilter, status);
533 }
534
535 if (*status > 0)
536 {
537 ffpmsg("could not parse the input filename: (ffopen)");
538 ffpmsg(url);
539 return(*status);
540 }
541
542 imagecolname[0] = '\0';
543 rowexpress[0] = '\0';
544
545 if (*extspec)
546 {
547 /* parse the extension specifier into individual parameters */
548 ffexts(extspec, &extnum,
549 extname, &extvers, &movetotype, imagecolname, rowexpress, status);
550
551 if (*status > 0)
552 return(*status);
553 }
554
555 /*-------------------------------------------------------------------*/
556 /* special cases: */
557 /*-------------------------------------------------------------------*/
558
559 histfilename[0] = '\0';
560 filtfilename[0] = '\0';
561 if (*outfile && (*binspec || *imagecolname || *pixfilter))
562 {
563 /* if binspec or imagecolumn are specified, then the */
564 /* output file name is intended for the final image, */
565 /* and not a copy of the input file. */
566
567 strcpy(histfilename, outfile);
568 outfile[0] = '\0';
569 }
570 else if (*outfile && (*rowfilter || *colspec))
571 {
572 /* if rowfilter or colspece are specified, then the */
573 /* output file name is intended for the filtered file */
574 /* and not a copy of the input file. */
575
576 strcpy(filtfilename, outfile);
577 outfile[0] = '\0';
578 }
579
580 /*-------------------------------------------------------------------*/
581 /* check if this same file is already open, and if so, attach to it */
582 /*-------------------------------------------------------------------*/
583
584 if (fits_already_open(fptr, url, urltype, infile, extspec, rowfilter,
585 binspec, colspec, mode, &isopen, status) > 0)
586 {
587 return(*status);
588 }
589
590 if (isopen)
591 goto move2hdu;
592
593 /* get the driver number corresponding to this urltype */
594 *status = urltype2driver(urltype, &driver);
595
596 if (*status > 0)
597 {
598 ffpmsg("could not find driver for this file: (ffopen)");
599 ffpmsg(urltype);
600 ffpmsg(url);
601 return(*status);
602 }
603
604 /*-------------------------------------------------------------------
605 deal with all those messy special cases which may require that
606 a different driver be used:
607 - is disk file compressed?
608 - are ftp:, gsiftp:, or http: files compressed?
609 - has user requested that a local copy be made of
610 the ftp or http file?
611 -------------------------------------------------------------------*/
612
613 if (driverTable[driver].checkfile)
614 {
615 strcpy(origurltype,urltype); /* Save the urltype */
616
617 /* 'checkfile' may modify the urltype, infile and outfile strings */
618 *status = (*driverTable[driver].checkfile)(urltype, infile, outfile);
619
620 if (*status)
621 {
622 ffpmsg("checkfile failed for this file: (ffopen)");
623 ffpmsg(url);
624 return(*status);
625 }
626
627 if (strcmp(origurltype, urltype)) /* did driver changed on us? */
628 {
629 *status = urltype2driver(urltype, &driver);
630 if (*status > 0)
631 {
632 ffpmsg("could not change driver for this file: (ffopen)");
633 ffpmsg(url);
634 ffpmsg(urltype);
635 return(*status);
636 }
637 }
638 }
639
640 /* call appropriate driver to open the file */
641 if (driverTable[driver].open)
642 {
643 *status = (*driverTable[driver].open)(infile, mode, &handle);
644 if (*status > 0)
645 {
646 ffpmsg("failed to find or open the following file: (ffopen)");
647 ffpmsg(url);
648 return(*status);
649 }
650 }
651 else
652 {
653 ffpmsg("cannot open an existing file of this type: (ffopen)");
654 ffpmsg(url);
655 return(*status = FILE_NOT_OPENED);
656 }
657
658 /* get initial file size */
659 *status = (*driverTable[driver].size)(handle, &filesize);
660 if (*status > 0)
661 {
662 (*driverTable[driver].close)(handle); /* close the file */
663 ffpmsg("failed get the size of the following file: (ffopen)");
664 ffpmsg(url);
665 return(*status);
666 }
667
668 /* allocate fitsfile structure and initialize = 0 */
669 *fptr = (fitsfile *) calloc(1, sizeof(fitsfile));
670
671 if (!(*fptr))
672 {
673 (*driverTable[driver].close)(handle); /* close the file */
674 ffpmsg("failed to allocate structure for following file: (ffopen)");
675 ffpmsg(url);
676 return(*status = MEMORY_ALLOCATION);
677 }
678
679 /* allocate FITSfile structure and initialize = 0 */
680 (*fptr)->Fptr = (FITSfile *) calloc(1, sizeof(FITSfile));
681
682 if (!((*fptr)->Fptr))
683 {
684 (*driverTable[driver].close)(handle); /* close the file */
685 ffpmsg("failed to allocate structure for following file: (ffopen)");
686 ffpmsg(url);
687 free(*fptr);
688 *fptr = 0;
689 return(*status = MEMORY_ALLOCATION);
690 }
691
692 slen = strlen(url) + 1;
693 slen = maxvalue(slen, 32); /* reserve at least 32 chars */
694 ((*fptr)->Fptr)->filename = (char *) malloc(slen); /* mem for file name */
695
696 if ( !(((*fptr)->Fptr)->filename) )
697 {
698 (*driverTable[driver].close)(handle); /* close the file */
699 ffpmsg("failed to allocate memory for filename: (ffopen)");
700 ffpmsg(url);
701 free((*fptr)->Fptr);
702 free(*fptr);
703 *fptr = 0; /* return null file pointer */
704 return(*status = MEMORY_ALLOCATION);
705 }
706
707 /* mem for headstart array */
708 ((*fptr)->Fptr)->headstart = (LONGLONG *) calloc(1001, sizeof(LONGLONG));
709
710 if ( !(((*fptr)->Fptr)->headstart) )
711 {
712 (*driverTable[driver].close)(handle); /* close the file */
713 ffpmsg("failed to allocate memory for headstart array: (ffopen)");
714 ffpmsg(url);
715 free( ((*fptr)->Fptr)->filename);
716 free((*fptr)->Fptr);
717 free(*fptr);
718 *fptr = 0; /* return null file pointer */
719 return(*status = MEMORY_ALLOCATION);
720 }
721 /* store the parameters describing the file */
722 ((*fptr)->Fptr)->MAXHDU = 1000; /* initial size of headstart */
723 ((*fptr)->Fptr)->filehandle = handle; /* file handle */
724 ((*fptr)->Fptr)->driver = driver; /* driver number */
725 strcpy(((*fptr)->Fptr)->filename, url); /* full input filename */
726 ((*fptr)->Fptr)->filesize = filesize; /* physical file size */
727 ((*fptr)->Fptr)->logfilesize = filesize; /* logical file size */
728 ((*fptr)->Fptr)->writemode = mode; /* read-write mode */
729 ((*fptr)->Fptr)->datastart = DATA_UNDEFINED; /* unknown start of data */
730 ((*fptr)->Fptr)->curbuf = -1; /* undefined current IO buffer */
731 ((*fptr)->Fptr)->open_count = 1; /* structure is currently used once */
732 ((*fptr)->Fptr)->validcode = VALIDSTRUC; /* flag denoting valid structure */
733
734 ffldrc(*fptr, 0, REPORT_EOF, status); /* load first record */
735
736 fits_store_Fptr( (*fptr)->Fptr, status); /* store Fptr address */
737
738 if (ffrhdu(*fptr, &hdutyp, status) > 0) /* determine HDU structure */
739 {
740 ffpmsg(
741 "ffopen could not interpret primary array header of file: ");
742 ffpmsg(url);
743
744 if (*status == UNKNOWN_REC)
745 ffpmsg("This does not look like a FITS file.");
746
747 ffclos(*fptr, status);
748 *fptr = 0; /* return null file pointer */
749 return(*status);
750 }
751
752 /* ------------------------------------------------------------- */
753 /* At this point, the input file has been opened. If outfile was */
754 /* specified, then we have opened a copy of the file, not the */
755 /* original file so it is safe to modify it if necessary */
756 /* ------------------------------------------------------------- */
757
758 if (*outfile)
759 writecopy = 1;
760
761 move2hdu:
762
763 /* ---------------------------------------------------------- */
764 /* move to desired extension, if specified as part of the URL */
765 /* ---------------------------------------------------------- */
766
767 if (*extspec)
768 {
769 if (extnum) /* extension number was specified */
770 {
771 ffmahd(*fptr, extnum + 1, &hdutyp, status);
772 }
773 else if (*extname) /* move to named extension, if specified */
774 {
775 ffmnhd(*fptr, movetotype, extname, extvers, status);
776 }
777
778 if (*status > 0) /* clean up after error */
779 {
780 ffpmsg("ffopen could not move to the specified extension:");
781 if (extnum > 0)
782 {
783 sprintf(errmsg,
784 " extension number %d doesn't exist or couldn't be opened.",extnum);
785 ffpmsg(errmsg);
786 }
787 else
788 {
789 sprintf(errmsg,
790 " extension with EXTNAME = %s,", extname);
791 ffpmsg(errmsg);
792
793 if (extvers)
794 {
795 sprintf(errmsg,
796 " and with EXTVERS = %d,", extvers);
797 ffpmsg(errmsg);
798 }
799
800 if (movetotype != ANY_HDU)
801 {
802 sprintf(errmsg,
803 " and with XTENSION = %s,", hdtype[movetotype]);
804 ffpmsg(errmsg);
805 }
806
807 ffpmsg(" doesn't exist or couldn't be opened.");
808 }
809
810 ffclos(*fptr, status);
811 *fptr = 0; /* return null file pointer */
812 return(*status);
813 }
814 }
815 else if (skip_null || skip_image || skip_table ||
816 (*imagecolname || *colspec || *rowfilter || *binspec))
817 {
818 /* ------------------------------------------------------------------
819
820 If no explicit extension specifier is given as part of the file
821 name, and, if a) skip_null is true (set if ffopen is called by
822 ffdopn) or b) skip_image or skip_table is true (set if ffopen is
823 called by fftopn or ffdopn) or c) other file filters are
824 specified, then CFITSIO will attempt to move to the first
825 'interesting' HDU after opening an existing FITS file (or to
826 first interesting table HDU if skip_image is true);
827
828 An 'interesting' HDU is defined to be either an image with NAXIS
829 > 0 (i.e., not a null array) or a table which has an EXTNAME
830 value which does not contain any of the following strings:
831 'GTI' - Good Time Interval extension
832 'OBSTABLE' - used in Beppo SAX data files
833
834 The main purpose for this is to allow CFITSIO to skip over a null
835 primary and other non-interesting HDUs when opening an existing
836 file, and move directly to the first extension that contains
837 significant data.
838 ------------------------------------------------------------------ */
839
840 fits_get_hdu_num(*fptr, &hdunum);
841 if (hdunum == 1) {
842
843 fits_get_img_dim(*fptr, &naxis, status);
844
845 if (naxis == 0 || skip_image) /* skip primary array */
846 {
847 while(1)
848 {
849 /* see if the next HDU is 'interesting' */
850 if (fits_movrel_hdu(*fptr, 1, &hdutyp, status))
851 {
852 if (*status == END_OF_FILE)
853 *status = 0; /* reset expected error */
854
855 /* didn't find an interesting HDU so move back to beginning */
856 fits_movabs_hdu(*fptr, 1, &hdutyp, status);
857 break;
858 }
859
860 if (hdutyp == IMAGE_HDU && skip_image) {
861
862 continue; /* skip images */
863
864 } else if (hdutyp != IMAGE_HDU && skip_table) {
865
866 continue; /* skip tables */
867
868