gnuastro-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnuastro-commits] master f5a9f21: Library (fits.h): FITS files can be r


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master f5a9f21: Library (fits.h): FITS files can be recognized without suffix
Date: Fri, 23 Apr 2021 11:20:49 -0400 (EDT)

branch: master
commit f5a9f21c7d9cf1424c9785be2824fdd2cfe3a678
Author: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Commit: Mohammad Akhlaghi <mohammad@akhlaghi.org>

    Library (fits.h): FITS files can be recognized without suffix
    
    Until now, Gnuastro identified FITS files based on their recognized suffix
    (for example '.fits', '.fit', or etc). However, in some situations, it may
    happen that the file has no suffix, or a recognized suffix. So until now,
    users would have to find a hack (for example make a symbolic link to the
    file, and set the link name to have a '.fits' suffix). But this was an
    annoying step, therefore having this step helps the usability of Gnuastro.
    
    With this commit, a new 'gal_fits_file_recognized' function has been added
    to Gnuastro's FITS library and used by all the programs when checking their
    inputs. This function will first check the suffix and when the suffix is
    not recognized (or doesn't exist!), it will attempt to open the file with
    CFITSIO to make sure it is a FITS file. Note that it will just "open" the
    file, it won't read anything (beyond checking that it is indeed a FITS
    file) so it shouldn't have too much of a footprint.
    
    Also, a more general 'gal_array_file_recognized' function has been added
    for programs that can theoretically accept other formats (like JPEG or
    TIFF), but this feature is currently only implemented for FITS.
    
    Initially, I also wanted to implement this for similar functions in TIFF
    and JPEG, but ended up not doing so because of the peculiarities of those
    libraries that I have forgot and need more time to remember. But those
    formats are rarely used as input into Gnuastro anyway, and by normal
    convention, they usually do have suffixes.
    
    This feature was implemented while working with Clotilde Laigle and Leigh
    Smith.
---
 NEWS                         |  11 ++++-
 bin/TEMPLATE/ui.c            |   2 +-
 bin/arithmetic/arithmetic.c  |   4 +-
 bin/arithmetic/operands.c    |   2 +-
 bin/arithmetic/ui.c          |   2 +-
 bin/convertt/ui.c            |   2 +-
 bin/convolve/ui.c            |   4 +-
 bin/crop/ui.c                |   2 +-
 bin/fits/ui.c                |   2 +-
 bin/match/ui.c               |   8 ++--
 bin/mkcatalog/ui.c           |   2 +-
 bin/mknoise/ui.c             |   2 +-
 bin/mkprof/ui.c              |   2 +-
 bin/noisechisel/ui.c         |   6 +--
 bin/segment/ui.c             |   4 +-
 bin/statistics/ui.c          |   4 +-
 bin/table/table.c            |   2 +-
 bin/table/ui.c               |   2 +-
 bin/warp/ui.c                |   2 +-
 doc/announce-acknowledge.txt |   2 +
 doc/gnuastro.texi            |  30 +++++++++---
 lib/array.c                  |  15 +++++-
 lib/fits.c                   |  50 +++++++++++++++++++-
 lib/gnuastro/array.h         |   3 ++
 lib/gnuastro/fits.h          |   3 ++
 lib/jpeg.c                   | 108 +++++++++++++++++++++++++++----------------
 lib/table.c                  |   2 +-
 lib/tiff.c                   |  22 +++++++--
 lib/wcs.c                    |   4 +-
 29 files changed, 221 insertions(+), 83 deletions(-)

diff --git a/NEWS b/NEWS
index ec73b6f..2d717c5 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,13 @@ See the end of the file for license conditions.
      the other columns (any MakeCatalog measurement is possible).
 
   All programs:
+   - FITS files that don't have a recognized FITS suffix (e.g., '.fits',
+     '.fit', '.fits.gz', etc) will also be recognized. Generally, it is
+     good practice to keep a suffix to be more human and computer friendly
+     (checking three or four characters is much faster than opening the
+     file and checking the contents to conform with the FITS standard), but
+     when you are given such a file (by someone else), this new feature can
+     be handy. Suggested by Clotilde Laigle and Leigh Smith.
    --wcslinearmatrix: new option in all programs that lets you select the
      output WCS linear matrix format. It takes one of two values: 'pc' (for
      the 'PCi_j' formalism) and 'cd' (for 'CDi_j'). Until now, the outputs
@@ -161,13 +168,15 @@ See the end of the file for license conditions.
    - New arithmetic flag macros:
      - GAL_ARITHMETIC_FLAG_ENVSEED: read random number generator seed from env.
      - GAL_ARITHMETIC_FLAG_QUIET: don't print any warnings by some operators.
-   - WCS coordinate system identifiers:
+   - WCS coordinate system macros:
      - GAL_WCS_COORDSYS_EQB1950: 1950.0 (Besselian-year) equatorial coords.
      - GAL_WCS_COORDSYS_EQJ2000: 2000.0 (Julian-year) equatorial coords.
      - GAL_WCS_COORDSYS_ECB1950: 1950.0 (Besselian-year) ecliptic coords.
      - GAL_WCS_COORDSYS_ECJ2000: 2000.0 (Julian-year) ecliptic coords.
      - GAL_WCS_COORDSYS_GALACTIC: Galactic coordinates.
      - GAL_WCS_COORDSYS_SUPERGALACTIC: Supergalactic coordinates.
+   - gal_array_file_recognized: For FITS images, check contents also.
+   - gal_fits_file_recognized: Check the file contents when suffix isn't FITS.
    - gal_units_counts_to_mag: Convert counts to magnitudes.
    - gal_units_counts_to_jy: Convert counts to Janskys.
    - gal_wcs_coordsys_from_string: WCS coordinate system from string.
diff --git a/bin/TEMPLATE/ui.c b/bin/TEMPLATE/ui.c
index 6d96430..9117a1e 100644
--- a/bin/TEMPLATE/ui.c
+++ b/bin/TEMPLATE/ui.c
@@ -224,7 +224,7 @@ ui_check_options_and_arguments(struct TEMPLATEparams *p)
       gal_checkset_check_file(p->inputname);
 
       /* If it is FITS, a HDU is also mandatory. */
-      if( gal_fits_name_is_fits(p->inputname) && p->cp.hdu==NULL )
+      if( gal_fits_file_recognized(p->inputname) && p->cp.hdu==NULL )
         error(EXIT_FAILURE, 0, "no HDU specified. When the input is a FITS "
               "file, a HDU must also be specified, you can use the '--hdu' "
               "('-h') option and give it the HDU number (starting from "
diff --git a/bin/arithmetic/arithmetic.c b/bin/arithmetic/arithmetic.c
index 89b6dd4..7892d6b 100644
--- a/bin/arithmetic/arithmetic.c
+++ b/bin/arithmetic/arithmetic.c
@@ -1412,7 +1412,7 @@ reversepolish(struct arithmeticparams *p)
       else if( !strncmp(token->v, GAL_ARITHMETIC_SET_PREFIX,
                         GAL_ARITHMETIC_SET_PREFIX_LENGTH) )
         gal_arithmetic_set_name(&p->setprm, token->v);
-      else if(    gal_array_name_recognized(token->v)
+      else if(    gal_array_file_recognized(token->v)
                || gal_arithmetic_set_is_name(p->setprm.named, token->v) )
         operands_add(p, token->v, NULL);
       else if( (data=gal_data_copy_string_to_number(token->v)) )
@@ -1460,7 +1460,7 @@ reversepolish(struct arithmeticparams *p)
       /* Read the desired image and report it if necessary. */
       hdu=p->operands->hdu;
       filename=p->operands->filename;
-      if( gal_fits_name_is_fits(filename) )
+      if( gal_fits_file_recognized(filename) )
         {
           /* Read the data, note that the WCS has already been set. */
           p->operands->data=gal_array_read_one_ch(filename, hdu, NULL,
diff --git a/bin/arithmetic/operands.c b/bin/arithmetic/operands.c
index cb10d3c..7e29777 100644
--- a/bin/arithmetic/operands.c
+++ b/bin/arithmetic/operands.c
@@ -113,7 +113,7 @@ operands_add(struct arithmeticparams *p, char *filename, 
gal_data_t *data)
 
           /* See if a HDU must be read or not. */
           if(filename != NULL
-             && ( gal_fits_name_is_fits(filename)
+             && ( gal_fits_file_recognized(filename)
                   || gal_tiff_name_is_tiff(filename) ) )
             {
               /* Set the HDU for this filename. */
diff --git a/bin/arithmetic/ui.c b/bin/arithmetic/ui.c
index 5f13635..5722558 100644
--- a/bin/arithmetic/ui.c
+++ b/bin/arithmetic/ui.c
@@ -234,7 +234,7 @@ ui_read_check_only_options(struct arithmeticparams *p)
 {
   if(p->wcsfile && strcmp(p->wcsfile,"none"))
     {
-      if(gal_fits_name_is_fits(p->wcsfile)==0)
+      if(gal_fits_file_recognized(p->wcsfile)==0)
         error(EXIT_FAILURE, 0, "%s: file given to '--wcsfile' must be in "
               "FITS format with a recognizable FITS format suffix.",
               p->wcsfile);
diff --git a/bin/convertt/ui.c b/bin/convertt/ui.c
index 3602ffa..939dd08 100644
--- a/bin/convertt/ui.c
+++ b/bin/convertt/ui.c
@@ -516,7 +516,7 @@ ui_make_channels_ll(struct converttparams *p)
       if(strcmp(name->v, "blank")) gal_checkset_check_file(name->v);
 
       /* FITS: */
-      if( gal_fits_name_is_fits(name->v) )
+      if( gal_fits_file_recognized(name->v) )
         {
           /* Get the HDU value for this channel. */
           if(p->globalhdu)
diff --git a/bin/convolve/ui.c b/bin/convolve/ui.c
index 3fb32db..44e8ed0 100644
--- a/bin/convolve/ui.c
+++ b/bin/convolve/ui.c
@@ -252,7 +252,7 @@ ui_check_options_and_arguments(struct convolveparams *p)
   if(p->filename)
     {
       /* If input is FITS. */
-      if( (p->isfits=gal_fits_name_is_fits(p->filename)) )
+      if( (p->isfits=gal_fits_file_recognized(p->filename)) )
         {
           /* Check if a HDU is given. */
           if( p->cp.hdu==NULL )
@@ -275,7 +275,7 @@ ui_check_options_and_arguments(struct convolveparams *p)
   if(p->kernelname)
     {
       /* If input is FITS. */
-      if( gal_fits_name_is_fits(p->kernelname) )
+      if( gal_fits_file_recognized(p->kernelname) )
         {
           /* Check if a HDU is given. */
           if( p->khdu==NULL )
diff --git a/bin/crop/ui.c b/bin/crop/ui.c
index 8776f15..b95d51f 100644
--- a/bin/crop/ui.c
+++ b/bin/crop/ui.c
@@ -350,7 +350,7 @@ ui_read_check_only_options(struct cropparams *p)
               "best for this option to have a value", p->catname);
 
       /* If it is a FITS file, we need the HDU. */
-      if( gal_fits_name_is_fits(p->catname) && p->cathdu==NULL )
+      if( gal_fits_file_recognized(p->catname) && p->cathdu==NULL )
         error(EXIT_FAILURE, 0, "%s: no hdu given. Please use the '--cathdu' "
               "option to specify which extension contains the table",
               p->catname);
diff --git a/bin/fits/ui.c b/bin/fits/ui.c
index b8e9436..536ecd5 100644
--- a/bin/fits/ui.c
+++ b/bin/fits/ui.c
@@ -176,7 +176,7 @@ parse_opt(int key, char *arg, struct argp_state *state)
     /* Read the non-option tokens (arguments): */
     case ARGP_KEY_ARG:
       /* Only FITS files are acceptable. */
-      if( gal_fits_name_is_fits(arg) )
+      if( gal_fits_file_recognized(arg) )
         gal_list_str_add(&p->input, arg, 1);
       else
         argp_error(state, "%s is not a recognized FITS file", arg);
diff --git a/bin/match/ui.c b/bin/match/ui.c
index 31d1ee2..c0815f1 100644
--- a/bin/match/ui.c
+++ b/bin/match/ui.c
@@ -267,7 +267,7 @@ ui_check_options_and_arguments(struct matchparams *p)
 
   /* If the first input is a FITS file, make sure its HDU is also given. */
   if( p->input1name
-      && gal_fits_name_is_fits(p->input1name)
+      && gal_fits_file_recognized(p->input1name)
       && p->cp.hdu==NULL )
     error(EXIT_FAILURE, 0, "no HDU for first input. When the input is "
           "a FITS file, a HDU must also be specified, you can use the "
@@ -275,7 +275,7 @@ ui_check_options_and_arguments(struct matchparams *p)
           "from zero), extension name, or anything acceptable by "
           "CFITSIO");
   if( p->input2name
-      && gal_fits_name_is_fits(p->input2name)
+      && gal_fits_file_recognized(p->input2name)
       && p->hdu2==NULL )
     error(EXIT_FAILURE, 0, "no HDU for second input. Please use "
           "the '--hdu2' ('-H') option and give it the HDU number "
@@ -316,7 +316,7 @@ ui_set_mode(struct matchparams *p)
      'NULL'), then we go into catalog mode because currently we assume
      standard input is only for plain text and WCS matching is not defined
      on plain text. */
-  if( p->input1name && gal_fits_name_is_fits(p->input1name) )
+  if( p->input1name && gal_fits_file_recognized(p->input1name) )
     {
       tin1=gal_fits_hdu_format(p->input1name, p->cp.hdu);
       p->mode = (tin1 == IMAGE_HDU) ? MATCH_MODE_WCS : MATCH_MODE_CATALOG;
@@ -340,7 +340,7 @@ ui_set_mode(struct matchparams *p)
      file.*/
   if(p->input2name)
     {
-      if(gal_fits_name_is_fits(p->input2name))
+      if(gal_fits_file_recognized(p->input2name))
         {
           tin2=gal_fits_hdu_format(p->input2name, p->hdu2);
           if(tin1==IMAGE_HDU && tin2!=IMAGE_HDU)
diff --git a/bin/mkcatalog/ui.c b/bin/mkcatalog/ui.c
index c111919..c2c753c 100644
--- a/bin/mkcatalog/ui.c
+++ b/bin/mkcatalog/ui.c
@@ -454,7 +454,7 @@ ui_check_options_and_arguments(struct mkcatalogparams *p)
      and if it was a FITS file, that a HDU is also given. */
   if(p->objectsfile)
     {
-      if( gal_fits_name_is_fits(p->objectsfile) && p->cp.hdu==NULL )
+      if( gal_fits_file_recognized(p->objectsfile) && p->cp.hdu==NULL )
         error(EXIT_FAILURE, 0, "no HDU specified. When the input is a FITS "
               "file, a HDU must also be specified, you can use the '--hdu' "
               "('-h') option and give it the HDU number (starting from "
diff --git a/bin/mknoise/ui.c b/bin/mknoise/ui.c
index 4c99355..7a0fc95 100644
--- a/bin/mknoise/ui.c
+++ b/bin/mknoise/ui.c
@@ -271,7 +271,7 @@ ui_check_options_and_arguments(struct mknoiseparams *p)
      a HDU is also given. */
   if(p->inputname)
     {
-      if( gal_fits_name_is_fits(p->inputname) && p->cp.hdu==NULL )
+      if( gal_fits_file_recognized(p->inputname) && p->cp.hdu==NULL )
         error(EXIT_FAILURE, 0, "no HDU specified. When the input is a FITS "
               "file, a HDU must also be specified, you can use the '--hdu' "
               "('-h') option and give it the HDU number (starting from "
diff --git a/bin/mkprof/ui.c b/bin/mkprof/ui.c
index 9b29674..93b04a6 100644
--- a/bin/mkprof/ui.c
+++ b/bin/mkprof/ui.c
@@ -578,7 +578,7 @@ ui_check_options_and_arguments(struct mkprofparams *p)
     {
       if(p->catname)
         {
-          if( gal_fits_name_is_fits(p->catname) && p->cp.hdu==NULL)
+          if( gal_fits_file_recognized(p->catname) && p->cp.hdu==NULL)
             error(EXIT_FAILURE, 0, "no 'hdu' specified for the input FITS "
                   "table '%s', to ", p->catname);
         }
diff --git a/bin/noisechisel/ui.c b/bin/noisechisel/ui.c
index 9d3e2b5..96e1419 100644
--- a/bin/noisechisel/ui.c
+++ b/bin/noisechisel/ui.c
@@ -256,7 +256,7 @@ ui_read_check_only_options(struct noisechiselparams *p)
       gal_checkset_check_file(p->kernelname);
 
       /* If its FITS, see if a HDU has been provided. */
-      if( gal_fits_name_is_fits(p->kernelname) && p->khdu==NULL )
+      if( gal_fits_file_recognized(p->kernelname) && p->khdu==NULL )
         error(EXIT_FAILURE, 0, "no HDU specified for kernel. When the "
               "kernel is a FITS file, a HDU must also be specified. You "
               "can use the '--khdu' option and give it the HDU number "
@@ -271,7 +271,7 @@ ui_read_check_only_options(struct noisechiselparams *p)
       gal_checkset_check_file(p->widekernelname);
 
       /* If its FITS, see if a HDU has been provided. */
-      if( gal_fits_name_is_fits(p->widekernelname) && p->whdu==NULL )
+      if( gal_fits_file_recognized(p->widekernelname) && p->whdu==NULL )
         error(EXIT_FAILURE, 0, "no HDU specified for the given wide kernel "
               "('%s'). When the wide kernel is a FITS file, a HDU must also "
               "be specified. You can use the '--whdu' option and give it the "
@@ -309,7 +309,7 @@ ui_check_options_and_arguments(struct noisechiselparams *p)
       gal_checkset_check_file(p->inputname);
 
       /* If its FITS, see if a HDU has been provided. */
-      if( gal_fits_name_is_fits(p->inputname) && p->cp.hdu==NULL )
+      if( gal_fits_file_recognized(p->inputname) && p->cp.hdu==NULL )
         error(EXIT_FAILURE, 0, "no HDU specified for input. When the input "
               "is a FITS file, a HDU must also be specified, you can use "
               "the '--hdu' ('-h') option and give it the HDU number "
diff --git a/bin/segment/ui.c b/bin/segment/ui.c
index 62f8f0f..b72a15a 100644
--- a/bin/segment/ui.c
+++ b/bin/segment/ui.c
@@ -266,7 +266,7 @@ ui_read_check_only_options(struct segmentparams *p)
       gal_checkset_check_file(p->kernelname);
 
       /* If its FITS, see if a HDU has been provided. */
-      if( gal_fits_name_is_fits(p->kernelname) && p->khdu==NULL )
+      if( gal_fits_file_recognized(p->kernelname) && p->khdu==NULL )
         error(EXIT_FAILURE, 0, "no HDU specified for kernel. When the "
               "kernel is a FITS file, a HDU must also be specified. You "
               "can use the '--khdu' option and give it the HDU number "
@@ -305,7 +305,7 @@ ui_check_options_and_arguments(struct segmentparams *p)
       gal_checkset_check_file(p->inputname);
 
       /* If it is FITS, a HDU is also mandatory. */
-      if( gal_fits_name_is_fits(p->inputname) && p->cp.hdu==NULL )
+      if( gal_fits_file_recognized(p->inputname) && p->cp.hdu==NULL )
         error(EXIT_FAILURE, 0, "no HDU specified. When the input is a FITS "
               "file, a HDU must also be specified, you can use the '--hdu' "
               "('-h') option and give it the HDU number (starting from "
diff --git a/bin/statistics/ui.c b/bin/statistics/ui.c
index 96232c9..38c36a7 100644
--- a/bin/statistics/ui.c
+++ b/bin/statistics/ui.c
@@ -436,7 +436,7 @@ ui_read_check_only_options(struct statisticsparams *p)
               p->meanmedqdiff);
 
       /* If a kernel name has been given, we need the HDU. */
-      if(p->kernelname && gal_fits_name_is_fits(p->kernelname)
+      if(p->kernelname && gal_fits_file_recognized(p->kernelname)
          && p->khdu==NULL )
         error(EXIT_FAILURE, 0, "no HDU specified for the kernel image. When "
               "A HDU is necessary for FITS files. You can use the '--khdu' "
@@ -540,7 +540,7 @@ ui_check_options_and_arguments(struct statisticsparams *p)
   if(p->inputname)
     {
       /* If input is FITS. */
-      if( (p->isfits=gal_fits_name_is_fits(p->inputname)) )
+      if( (p->isfits=gal_fits_file_recognized(p->inputname)) )
         {
           /* Check if a HDU is given. */
           if( p->cp.hdu==NULL )
diff --git a/bin/table/table.c b/bin/table/table.c
index 6e48ab1..4f3e805 100644
--- a/bin/table/table.c
+++ b/bin/table/table.c
@@ -759,7 +759,7 @@ table_catcolumn(struct tableparams *p)
   for(filell=p->catcolumnfile; filell!=NULL; filell=filell->next)
     {
       /* Set the HDU (not necessary for non-FITS tables). */
-      if(gal_fits_name_is_fits(filell->v))
+      if(gal_fits_file_recognized(filell->v))
         {
           if(hdull) { hdu=hdull->v; hdull=hdull->next; }
           else
diff --git a/bin/table/ui.c b/bin/table/ui.c
index ece4e24..483336a 100644
--- a/bin/table/ui.c
+++ b/bin/table/ui.c
@@ -302,7 +302,7 @@ ui_check_options_and_arguments(struct tableparams *p)
      a HDU is also given. */
   if(p->filename)
     {
-      if( gal_fits_name_is_fits(p->filename) && p->cp.hdu==NULL )
+      if( gal_fits_file_recognized(p->filename) && p->cp.hdu==NULL )
         error(EXIT_FAILURE, 0, "no HDU specified. When the input is a FITS "
               "file, a HDU must also be specified, you can use the '--hdu' "
               "('-h') option and give it the HDU number (starting from "
diff --git a/bin/warp/ui.c b/bin/warp/ui.c
index 72659c1..f846516 100644
--- a/bin/warp/ui.c
+++ b/bin/warp/ui.c
@@ -339,7 +339,7 @@ ui_check_options_and_arguments(struct warpparams *p)
   if(p->inputname)
     {
       /* Make sure a HDU is given. */
-      if( gal_fits_name_is_fits(p->inputname) && p->cp.hdu==NULL )
+      if( gal_fits_file_recognized(p->inputname) && p->cp.hdu==NULL )
         error(EXIT_FAILURE, 0, "no HDU specified, you can use the '--hdu' "
               "('-h') option and give it the HDU number (starting from "
               "zero), or extension name (generally, anything acceptable "
diff --git a/doc/announce-acknowledge.txt b/doc/announce-acknowledge.txt
index aabddfd..c2cefc4 100644
--- a/doc/announce-acknowledge.txt
+++ b/doc/announce-acknowledge.txt
@@ -3,6 +3,7 @@ Alphabetically ordered list to acknowledge in the next release.
 Mark Calabretta
 Sepideh Eskandarlou
 Raul Infante-Sainz
+Clotilde Laigle
 Alberto Madrigal
 Juan Miro
 Carlos Morales Socorro
@@ -10,6 +11,7 @@ Sylvain Mottet
 Francois Ochsenbein
 Samane Raji
 Zahra Sharbaf
+Leigh Smith
 Ignacio Trujillo
 
 
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 7a7bf2d..41a73ba 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -6900,13 +6900,19 @@ In Gnuastro, arguments are almost exclusively used as 
the input data file names.
 Please consult the first few paragraph of the ``Invoking ProgramName'' section 
for each program for a description of what it expects as input, how many 
arguments, or input data, it accepts, or in what order.
 Everything particular about how a program treats arguments, is explained under 
the ``Invoking ProgramName'' section for that program.
 
-Generally, if there is a standard file name extension for a particular format, 
that filename extension is used to separate the kinds of arguments.
-The list below shows the data formats that are recognized in Gnuastro's 
programs based on their file name endings.
-Any argument that doesn't end with the specified extensions below is 
considered to be a text file (usually catalogs, see @ref{Tables}).
-In some cases, a program can accept specific formats, for example 
@ref{ConvertType} also accepts @file{.jpg} images.
+@cindex Filename suffix
+@cindex Suffix (filename)
+@cindex FITS filename suffixes
+Generally, if there is a standard file name suffix for a particular format, 
that filename extension is checked to identify their format.
+In astronomy (and thus Gnuastro), FITS is the preferred format for inputs and 
outputs, so the focus here and throughout this book is on FITS.
+However, other formats are also accepted in special cases, for example 
@ref{ConvertType} also accepts JPEG or TIFF inputs, and writes JPEG, EPS or PDF 
files.
+The recognized suffixes for these formats are listed there.
+
+The list below shows the recognized suffixes for FITS data files in Gnuastro's 
programs.
+However, in some scenarios FITS writers may not append a suffix to the file, 
or use a non-recognized suffix (not in the list below).
+Therefore if a FITS file is expected, but it doesn't have any of these 
suffixes, Gnuastro programs will look into the contents of the file and if it 
does conform with the FITS standard, the file will be used.
+Just note that checking about 5 characters at the end of a name string is much 
more efficient than opening and checking the contents of a file, so it is 
generally recommended to have a recognized FITS suffix.
 
-@cindex Astronomical data suffixes
-@cindex Suffixes, astronomical data
 @itemize
 
 @item
@@ -24500,6 +24506,11 @@ types for reading arrays which may contain multiple 
extensions (for example
 FITS or TIFF) formats.
 @end deftypefun
 
+@deftypefun int gal_array_file_recognized (char @code{*filename})
+Similar to @code{gal_array_name_recognized}, but for FITS files, it will also 
check the contents of the file if the recognized file name suffix is not found.
+See the description of @code{gal_fits_file_recognized} for more (@ref{FITS 
macros errors filenames}).
+@end deftypefun
+
 @deftypefun gal_data_t gal_array_read (char @code{*filename}, char 
@code{*extension}, gal_list_str_t @code{*lines}, size_t @code{minmapsize}, int 
@code{quietmmap})
 Read the array within the given extension (@code{extension}) of
 @code{filename}, or the @code{lines} list (see below). If the array is
@@ -24844,6 +24855,13 @@ suffix doesn't have to start with `@key{.}': this 
function will return
 @code{1} (one) for both @code{fits} and @code{.fits}.
 @end deftypefun
 
+@deftypefun in gal_fits_file_recognized (char @code{*name})
+Return @code{1} if the given file name (possibly including its contents) is a 
FITS file.
+This is necessary in when the contents of a FITS file do follow the FITS 
standard, but it the file doesn't have a Gnuastro-recognized FITS suffix.
+Therefore, it will first call @code{gal_fits_name_is_fits}, if the result is 
negative, then this function will attept to open the file with CFITSIO and if 
it works, it will close it again and return 1.
+In the process of opening the file, CFITSIO will just to open the file, no 
reading will take place, so it should have minimal CPU footprint.
+@end deftypefun
+
 @deftypefun {char *} gal_fits_name_save_as_string (char @code{*filename}, char 
@code{*hdu})
 If the name is a FITS name, then put a @code{(hdu: ...)} after it and
 return the string. If it isn't a FITS file, just print the name, if
diff --git a/lib/array.c b/lib/array.c
index 26bd646..8589abd 100644
--- a/lib/array.c
+++ b/lib/array.c
@@ -83,6 +83,19 @@ gal_array_name_recognized_multiext(char *name)
 
 
 
+int
+gal_array_file_recognized(char *name)
+{
+  if(       gal_fits_file_recognized(name) ) return 1;
+  else if ( gal_jpeg_name_is_jpeg(name)    ) return 1;
+  else if ( gal_tiff_name_is_tiff(name)    ) return 1;
+  else                                       return 0;
+}
+
+
+
+
+
 /* Read (all the possibly existing) color channels within each
    extension/dir of the given file. */
 gal_data_t *
@@ -92,7 +105,7 @@ gal_array_read(char *filename, char *extension, 
gal_list_str_t *lines,
   size_t ext;
 
   /* FITS  */
-  if( gal_fits_name_is_fits(filename) )
+  if( gal_fits_file_recognized(filename) )
     return gal_fits_img_read(filename, extension, minmapsize, quietmmap);
 
   /* TIFF */
diff --git a/lib/fits.c b/lib/fits.c
index 0f31ec7..140cf09 100644
--- a/lib/fits.c
+++ b/lib/fits.c
@@ -91,7 +91,7 @@ gal_fits_io_error(int status, char *message)
 
 
 /*************************************************************
- **************           FITS names           ***************
+ ************** FITS name and file identification ************
  *************************************************************/
 /* IMPORTANT NOTE: if other compression suffixes are add to this function,
    include them in 'gal_checkset_automatic_output', so the compression
@@ -178,6 +178,54 @@ gal_fits_name_save_as_string(char *filename, char *hdu)
 
 
 
+int
+gal_fits_file_recognized(char *filename)
+{
+  FILE *tmpfile;
+  fitsfile *fptr;
+  int out=0, status=0;
+
+  /* Opening a FITS file can be CPU intensive (for example when its
+     compressed). So if the name has the correct suffix, we'll trust the
+     suffix. In this way, if the file name is correct, but the contents
+     doesn't follow the FITS standard, the opening function will complain
+     if its not a FITS file when trying to open it for its usage. */
+  if( gal_fits_name_is_fits(filename) ) return 1;
+
+  /* CFITSIO has some special conventions for file names (for example if
+     its '-', which can happen in the Arithmetic program). So before
+     passing to CFITSIO, we'll check if a file is actually associated with
+     the string. */
+  errno=0;
+  tmpfile = fopen(filename, "r");
+  if(tmpfile) /* The file existed and opened. */
+    {
+      /* Close the opened filed. */
+      if(fclose(tmpfile)==EOF)
+        error(EXIT_FAILURE, errno, "%s", filename);
+
+      /* Open the file with CFITSIO to see if its actually a FITS file. */
+      fits_open_file(&fptr, filename, READONLY, &status);
+
+      /* If it opened successfully then status will be zero and we can
+         safely close the file. Otherwise, this is not a recognized FITS
+         file for CFITSIO and we should just return 0. */
+      if(status==0)
+        {
+          if( fits_close_file(fptr, &status) )
+            gal_fits_io_error(status, NULL);
+          out=1;
+        }
+    }
+
+  /* Return the final value. */
+  return out;
+}
+
+
+
+
+
 
 
 
diff --git a/lib/gnuastro/array.h b/lib/gnuastro/array.h
index cd91755..f4231a6 100644
--- a/lib/gnuastro/array.h
+++ b/lib/gnuastro/array.h
@@ -58,6 +58,9 @@ gal_array_name_recognized(char *name);
 int
 gal_array_name_recognized_multiext(char *name);
 
+int
+gal_array_file_recognized(char *name);
+
 gal_data_t *
 gal_array_read(char *filename, char *extension, gal_list_str_t *lines,
                size_t minmapsize, int quietmmap);
diff --git a/lib/gnuastro/fits.h b/lib/gnuastro/fits.h
index aebd667..7827fac 100644
--- a/lib/gnuastro/fits.h
+++ b/lib/gnuastro/fits.h
@@ -121,6 +121,9 @@ gal_fits_name_is_fits(char *name);
 int
 gal_fits_suffix_is_fits(char *suffix);
 
+int
+gal_fits_file_recognized(char *filename);
+
 char *
 gal_fits_name_save_as_string(char *filename, char *hdu);
 
diff --git a/lib/jpeg.c b/lib/jpeg.c
index 99431b7..8dd09c7 100644
--- a/lib/jpeg.c
+++ b/lib/jpeg.c
@@ -42,7 +42,69 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 /*************************************************************
- **************      Acceptable JPEG names      **************
+ **************       Basic access settings       ************
+ *************************************************************/
+#ifdef HAVE_LIBJPEG
+
+/* Read the example.c in libjpeg's source code to understand the
+   details of what is going on here.  */
+struct my_error_mgr
+{
+  struct jpeg_error_mgr pub;        /* "public" fields */
+  jmp_buf setjmp_buffer;            /* for return to caller */
+};
+
+typedef struct my_error_mgr *my_error_ptr;
+
+
+METHODDEF(void)
+jpeg_error_exit(j_common_ptr cinfo)
+{
+  /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
+  my_error_ptr myerr = (my_error_ptr) cinfo->err;
+
+  /* Always display the message. */
+  /* We could postpone this until after returning, if we chose. */
+  (*cinfo->err->output_message) (cinfo);
+
+  /* Return control to the setjmp point */
+  longjmp(myerr->setjmp_buffer, 1);
+}
+
+#else
+
+static void
+jpeg_error_no_libjpeg(char *func)
+{
+  error(EXIT_FAILURE, 0, "%s: libjpeg was not found during the "
+        "configuration of %s on this system. To read from JPEG files, "
+        "libjpeg is required. Please install libjpeg and configure, make "
+        "and install %s again", func, PACKAGE_STRING, PACKAGE_STRING);
+}
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*************************************************************
+ ************** JPEG name and file identification ************
  *************************************************************/
 int
 gal_jpeg_name_is_jpeg(char *name)
@@ -114,37 +176,8 @@ gal_jpeg_suffix_is_jpeg(char *name)
  **************        Read a JPEG image        **************
  *************************************************************/
 #ifdef HAVE_LIBJPEG
-/* Read the example.c in libjpeg's source code to understand the
-   details of what is going on here.  */
-struct my_error_mgr
-{
-  struct jpeg_error_mgr pub;        /* "public" fields */
-  jmp_buf setjmp_buffer;            /* for return to caller */
-};
-
-typedef struct my_error_mgr *my_error_ptr;
-
-
-METHODDEF(void)
-jpeg_error_exit(j_common_ptr cinfo)
-{
-  /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
-  my_error_ptr myerr = (my_error_ptr) cinfo->err;
-
-  /* Always display the message. */
-  /* We could postpone this until after returning, if we chose. */
-  (*cinfo->err->output_message) (cinfo);
-
-  /* Return control to the setjmp point */
-  longjmp(myerr->setjmp_buffer, 1);
-}
-
-
-
-
-
 static void
-makejsample(JSAMPLE **a, size_t size)
+jpeg_jsample_make(JSAMPLE **a, size_t size)
 {
   JSAMPLE *jsarr;
 
@@ -168,9 +201,9 @@ makejsample(JSAMPLE **a, size_t size)
 
 
 static unsigned char **
-readjpg(char *inname, size_t *outs0, size_t *outs1, size_t *numcolors)
+jpeg_read_to_array(char *inname, size_t *outs0, size_t *outs1, size_t 
*numcolors)
 {
-  FILE * infile;
+  FILE *infile;
   JSAMPROW jrow;
   JSAMPLE *jsamp;
   int rowstride, c;
@@ -207,7 +240,7 @@ readjpg(char *inname, size_t *outs0, size_t *outs1, size_t 
*numcolors)
   size=s0*s1;
   nc=*numcolors=cinfo.output_components;
   rowstride=s1*nc;
-  makejsample(&jsamp, size*nc);
+  jpeg_jsample_make(&jsamp, size*nc);
 
   /* Allocate all the arrays for each color: */
   errno=0;
@@ -265,7 +298,7 @@ gal_jpeg_read(char *filename, size_t minmapsize, int 
quietmmap)
   size_t i, s0, s1, numcolors;
 
   /* Read the JPEG image into the all array. */
-  allcolors=readjpg(filename, &s0, &s1, &numcolors);
+  allcolors=jpeg_read_to_array(filename, &s0, &s1, &numcolors);
 
   /* Add the arrays to the linked list. */
   for(i=0;i<numcolors;++i)
@@ -289,10 +322,7 @@ gal_jpeg_read(char *filename, size_t minmapsize, int 
quietmmap)
   /* Return the number of color channels. */
   return out;
 #else
-  error(EXIT_FAILURE, 0, "%s: libjpeg was not found during the "
-        "configuration of %s on this system. To read from JPEG files, "
-        "libjpeg is required. Please install libjpeg and configure, make "
-        "and install %s again", __func__, PACKAGE_STRING, PACKAGE_STRING);
+  jpeg_error_no_libjpeg(__func__);
   return NULL;
 #endif
 }
diff --git a/lib/table.c b/lib/table.c
index eb65630..a9534b7 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -64,7 +64,7 @@ gal_table_info(char *filename, char *hdu, gal_list_str_t 
*lines,
                size_t *numcols, size_t *numrows, int *tableformat)
 {
   /* Get the table format and size (number of columns and rows). */
-  if(filename && gal_fits_name_is_fits(filename))
+  if(filename && gal_fits_file_recognized(filename))
     return gal_fits_tab_info(filename, hdu, numcols, numrows, tableformat);
   else
     {
diff --git a/lib/tiff.c b/lib/tiff.c
index 2ab622f..c651b2f 100644
--- a/lib/tiff.c
+++ b/lib/tiff.c
@@ -46,8 +46,23 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 /*************************************************************
- **************      Acceptable TIFF names      **************
+ ************** TIFF name and file identification ************
  *************************************************************/
+#ifndef HAVE_LIBTIFF
+static void
+tiff_error_no_litiff(char *func)
+{
+  error(EXIT_FAILURE, 0, "%s: libtiff was not found during the "
+        "configuration of %s on this system. To read from TIFF files, "
+        "libtiff is required. Please install libtiff, then configure, make "
+        "and install %s again", func, PACKAGE_STRING, PACKAGE_STRING);
+}
+#endif
+
+
+
+
+
 int
 gal_tiff_name_is_tiff(char *name)
 {
@@ -608,10 +623,7 @@ gal_tiff_read(char *filename, size_t dir, size_t 
minmapsize, int quietmmap)
   TIFFClose(tif);
   return out;
 #else
-  error(EXIT_FAILURE, 0, "%s: libtiff was not found during the "
-        "configuration of %s on this system. To read from TIFF files, "
-        "libtiff is required. Please install libtiff, then configure, make "
-        "and install %s again", __func__, PACKAGE_STRING, PACKAGE_STRING);
+  tiff_error_no_litiff(__func__);
   return NULL;
 #endif  /* HAVE_LIBTIFF */
 }
diff --git a/lib/wcs.c b/lib/wcs.c
index 83f435f..a90d12e 100644
--- a/lib/wcs.c
+++ b/lib/wcs.c
@@ -379,7 +379,7 @@ gal_wcs_read(char *filename, char *hdu, int linearmatrix,
   struct wcsprm *wcs;
 
   /* Make sure we are dealing with a FITS file. */
-  if( gal_fits_name_is_fits(filename) == 0 )
+  if( gal_fits_file_recognized(filename) == 0 )
     return NULL;
 
   /* Check HDU for realistic conditions: */
@@ -579,7 +579,7 @@ gal_wcs_write(struct wcsprm *wcs, char *filename,
   /* Small sanity checks */
   if(wcs==NULL)
     error(EXIT_FAILURE, 0, "%s: input WCS is NULL", __func__);
-  if( gal_fits_name_is_fits(filename)==0 )
+  if( gal_fits_file_recognized(filename)==0 )
     error(EXIT_FAILURE, 0, "%s: not a FITS suffix", filename);
 
   /* Open the file for writing */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]