gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master e5b862a 2/2: Naming of datasets in Arithmetic


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master e5b862a 2/2: Naming of datasets in Arithmetic
Date: Thu, 19 Jul 2018 13:18:36 -0400 (EDT)

branch: master
commit e5b862a7d9a3e9c2045811d6a645d4289761523e
Author: Mohammad Akhlaghi <address@hidden>
Commit: Mohammad Akhlaghi <address@hidden>

    Naming of datasets in Arithmetic
    
    It often happens that a dataset (in a file) is needed more than once during
    an Arithmetic process (for example with the `where' operator). But until
    now, it was necessary to give the filename and extension containing the
    dataset everytime it was needed. This would cause Arithmetic to read the
    same dataset into memory multiple times while also making the command-line
    very complex and hard to read.
    
    With this commit a new `set-' operator has been defined that will give a
    name to the popped dataset which can then be used multiple times in the
    arguments to Arithmetic.
    
    Also, since TIFF files can also have multiple extensions and Arithmetic can
    now read them, the part where we check for the number of HDUs now checks
    for all files with multiple extensions. To make this possible, the new
    `gal_array_name_recognized_multiext' library function was defined.
---
 NEWS                        |   4 +
 bin/arithmetic/arithmetic.c |  19 ++-
 bin/arithmetic/main.h       |   5 +-
 bin/arithmetic/operands.c   | 302 +++++++++++++++++++++++++++++++++++---------
 bin/arithmetic/operands.h   |   5 +
 bin/arithmetic/ui.c         |  40 +++---
 doc/gnuastro.texi           |  52 ++++++++
 lib/array.c                 |  20 ++-
 lib/gnuastro/array.h        |   3 +
 9 files changed, 368 insertions(+), 82 deletions(-)

diff --git a/NEWS b/NEWS
index 07b2347..f443168 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,9 @@ GNU Astronomy Utilities NEWS                          -*- 
outline -*-
     --enable-check-with-valgrind: Run `make check' tests within Valgrind.
 
   Arithmetic:
+    - `set-A': Set a name (`A' in this case) for the popped dataset. This
+               allows only reading the dataset it into memory once and
+               possibly using it many times.
     - `collapse-sum': collapse/remove a dimension by summing over it.
     - `collapse-mean': collapse/remove a dimension by averaging over it.
     - `collapse-number': Number of elements included in the collapse.
@@ -17,6 +20,7 @@ GNU Astronomy Utilities NEWS                          -*- 
outline -*-
     --colinfoinstdout: column information when writing to standard output.
 
   Library:
+    - gal_array_name_recognized_multiext: If format contains multiple datasets.
     - gal_dimension_collapse_sum: collapse/remove a dimension by summing.
     - gal_dimension_collapse_mean: collapse/remove a dimension by averaging.
     - gal_dimension_collapse_number: collapse/remove a dimension by number.
diff --git a/bin/arithmetic/arithmetic.c b/bin/arithmetic/arithmetic.c
index f83e461..ba8ef38 100644
--- a/bin/arithmetic/arithmetic.c
+++ b/bin/arithmetic/arithmetic.c
@@ -817,10 +817,14 @@ reversepolish(struct arithmeticparams *p)
       /* If we have a name or number, then add it to the operands linked
          list. Otherwise, pull out two members and do the specified
          operation on them. */
-      if(gal_array_name_recognized(token->v))
+      if( gal_array_name_recognized(token->v)
+          || operands_is_name(p, token->v) )
         operands_add(p, token->v, NULL);
       else if( (d1=gal_data_copy_string_to_number(token->v)) )
         operands_add(p, NULL, d1);
+      else if( !strncmp(token->v, SET_OPERATOR_PREFIX,
+                        SET_OPERATOR_PREFIX_LENGTH) )
+        operands_set_name(p, token->v);
       else
         {
 
@@ -969,7 +973,7 @@ reversepolish(struct arithmeticparams *p)
           /* Finished checks with known operators */
           else
             error(EXIT_FAILURE, 0, "the argument \"%s\" could not be "
-                  "interpretted as a recognized input file name, number, or "
+                  "interpretted as a file name, named dataset, number, or "
                   "operator", token->v);
 
 
@@ -1069,8 +1073,18 @@ reversepolish(struct arithmeticparams *p)
                 }
             }
         }
+
+      /* Increment the token counter. */
+      ++p->tokencounter;
     }
 
+
+  /* If there aren't any more operands (a variable has been set but not
+     used), then there is nothing to create. */
+  if(p->operands==NULL)
+    error(EXIT_FAILURE, 0, "no operands on the stack to write (as output)");
+
+
   /* If there is more than one node in the operands stack then the user has
      given too many operands which is an error. */
   if(p->operands->next!=NULL)
@@ -1130,6 +1144,7 @@ reversepolish(struct arithmeticparams *p)
      into `d1', so it is freed when freeing d1. */
   gal_data_free(d1);
   free(p->refdata.dsize);
+  gal_list_data_free(p->named);
 
   /* Clean up. Note that the tokens were taken from the command-line
      arguments, so the string within each token linked list must not be
diff --git a/bin/arithmetic/main.h b/bin/arithmetic/main.h
index c0c2a1d..652f7e8 100644
--- a/bin/arithmetic/main.h
+++ b/bin/arithmetic/main.h
@@ -38,9 +38,10 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
-
 /* Constants: */
 #define NEG_DASH_REPLACE 11 /* Vertical tab (ASCII=11) for negative dash */
+#define SET_OPERATOR_PREFIX        "set-"
+#define SET_OPERATOR_PREFIX_LENGTH strlen(SET_OPERATOR_PREFIX)
 
 
 
@@ -73,6 +74,8 @@ struct arithmeticparams
   size_t        popcounter;  /* The number of FITS images popped.       */
   gal_data_t       refdata;  /* Container for information of the data.  */
   char          *globalhdu;  /* Single HDU for all inputs.              */
+  gal_data_t        *named;  /* List containing variables.              */
+  size_t      tokencounter;  /* Counter for finding place in tokens.    */
 
   /* Operating mode: */
 
diff --git a/bin/arithmetic/operands.c b/bin/arithmetic/operands.c
index 8329b5e..55eb1ab 100644
--- a/bin/arithmetic/operands.c
+++ b/bin/arithmetic/operands.c
@@ -58,6 +58,162 @@ operands_num(struct arithmeticparams *p)
 
 
 
+static int
+operands_name_is_used_later(struct arithmeticparams *p, char *name)
+{
+  size_t counter=0;
+  gal_list_str_t *token;
+
+  /* If the name indeed exists afterwards, then just return 1. */
+  for(token=p->tokens;token!=NULL;token=token->next)
+    if( counter++ > p->tokencounter && !strcmp(token->v, name) )
+      return 1;
+
+  /* If we get to this point, it means that the name doesn't exist. */
+  return 0;
+}
+
+
+
+
+
+/* Pop a dataset and keep it in the `named' list for later use. */
+void
+operands_set_name(struct arithmeticparams *p, char *token)
+{
+  gal_data_t *tmp;
+  char *varname=&token[ SET_OPERATOR_PREFIX_LENGTH ];
+
+  /* Make sure the variable name hasn't been set before. */
+  for(tmp=p->named; tmp!=NULL; tmp=tmp->next)
+    if( !strcmp(varname, tmp->name) )
+      error(EXIT_FAILURE, 0, "`%s' was previously set as a name",
+            varname);
+
+  /* Pop the top operand, then add it to the list of named datasets, but
+     only if it is used in later tokens. If it isn't, free the popped
+     dataset. The latter case (to define a name, but not use it), is
+     obviously a redundant operation, but that is upto the user, we
+     shouldn't worry about it here. We should just have everything in
+     place, so no crashes occur or no extra memory is consumed. */
+  if( operands_name_is_used_later(p, varname) )
+    {
+      /* Add the top popped operand to the list of names. */
+      gal_list_data_add(&p->named, operands_pop(p, "set"));
+
+      /* Write the requested name into this dataset. But note that `name'
+         MUST be already empty. So to be safe, we'll do a sanity check. */
+      if(p->named->name)
+        error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to fix "
+              "the problem. The `name' element should be NULL at this "
+              "point, but it isn't", __func__, PACKAGE_BUGREPORT);
+      gal_checkset_allocate_copy(varname, &p->named->name);
+    }
+  else
+    {
+      /* Pop the top operand, then free it. */
+      tmp=operands_pop(p, "set");
+      gal_data_free(tmp);
+    }
+}
+
+
+
+
+
+/* See if a given token is the name of a variable. */
+int
+operands_is_name(struct arithmeticparams *p, char *token)
+{
+  gal_data_t *tmp;
+
+  /* Make sure the variable name hasn't been set before. */
+  for(tmp=p->named; tmp!=NULL; tmp=tmp->next)
+    if( !strcmp(token, tmp->name) )
+      return 1;
+
+  /* If control reaches here, then there was no match*/
+  return 0;
+}
+
+
+
+
+
+/* Remove a name from the list of names and retrun the dataset it points
+   to. */
+static gal_data_t *
+operands_remove_name(struct arithmeticparams *p, char *name)
+{
+  gal_data_t *tmp, *removed=NULL, *prev=NULL;
+
+  /* Go over all the given names. */
+  for(tmp=p->named;tmp!=NULL;tmp=tmp->next)
+    {
+      if( !strcmp(tmp->name, name) )
+        {
+          removed=tmp;
+          if(prev) prev->next = tmp->next;
+          else     p->named   = tmp->next;
+        }
+
+      /* Set this node as the `prev' pointer. */
+      prev=tmp;
+    }
+
+  /* A small sanity check. */
+  if(removed==NULL)
+    error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to fix the "
+          "problem. `removed' must not be NULL at this point", __func__,
+          PACKAGE_BUGREPORT);
+
+  /* Nothing in the list points to it now. So we can safely modify and
+     return it. */
+  free(removed->name);
+  removed->name=NULL;
+  return removed;
+}
+
+
+
+
+
+/* Return a copy of the named dataset. */
+static gal_data_t *
+operands_copy_named(struct arithmeticparams *p, char *name)
+{
+  gal_data_t *out=NULL, *tmp;
+
+  /* Find the proper named element to use. */
+  for(tmp=p->named;tmp!=NULL;tmp=tmp->next)
+    if( !strcmp(tmp->name, name) )
+      {
+        /* If the named operand is used later, then copy it into the
+           output. */
+        if( operands_name_is_used_later(p, name) )
+          {
+            out=gal_data_copy(tmp);
+            free(out->name);
+            out->name=NULL;
+          }
+        /* The named operand is not used any more. Remove it from the list
+           of named datasets and continue. */
+        else out=operands_remove_name(p, name);
+      }
+
+  /* A small sanity check. */
+  if(out==NULL)
+    error(EXIT_FAILURE, 0, "%s: a bug! please contact us at %s to fix the "
+          "problem. The requested name `%s' couldn't be found in the list",
+          __func__, PACKAGE_BUGREPORT, name);
+
+  /* Return. */
+  return out;
+}
+
+
+
+
 void
 operands_add(struct arithmeticparams *p, char *filename, gal_data_t *data)
 {
@@ -75,22 +231,32 @@ operands_add(struct arithmeticparams *p, char *filename, 
gal_data_t *data)
         error(EXIT_FAILURE, errno, "%s: allocating %zu bytes for `newnode'",
               __func__, sizeof *newnode);
 
-      /* Fill in the values. */
-      newnode->data=data;
-      newnode->filename=filename;
-
-      /* See if a HDU must be read or not. */
-      if(filename != NULL
-         && ( gal_fits_name_is_fits(filename)
-              || gal_tiff_name_is_tiff(filename) ) )
+      /* If the `filename' is an already set name, then put a copy,
+         otherwise, do the basic analysis. */
+      if( operands_is_name(p, filename) )
         {
-          /* Set the HDU for this filename. */
-          if(p->globalhdu)
-            gal_checkset_allocate_copy(p->globalhdu, &newnode->hdu);
-          else
-            newnode->hdu=gal_list_str_pop(&p->hdus);
+          newnode->filename=NULL;
+          newnode->data=operands_copy_named(p, filename);
+        }
+      else
+        {
+          /* Set the basic parameters. */
+          newnode->data=data;
+          newnode->filename=filename;
+
+          /* See if a HDU must be read or not. */
+          if(filename != NULL
+             && ( gal_fits_name_is_fits(filename)
+                  || gal_tiff_name_is_tiff(filename) ) )
+            {
+              /* Set the HDU for this filename. */
+              if(p->globalhdu)
+                gal_checkset_allocate_copy(p->globalhdu, &newnode->hdu);
+              else
+                newnode->hdu=gal_list_str_pop(&p->hdus);
+            }
+          else newnode->hdu=NULL;
         }
-      else newnode->hdu=NULL;
 
       /* Make the link to the previous list. */
       newnode->next=p->operands;
@@ -116,64 +282,78 @@ operands_pop(struct arithmeticparams *p, char *operator)
     error(EXIT_FAILURE, 0, "not enough operands for the \"%s\" operator",
           operator);
 
-
   /* Set the dataset. If filename is present then read the file
      and fill in the array, if not then just set the array. */
   if(operands->filename)
     {
-      hdu=operands->hdu;
-      filename=operands->filename;
-
-      /* Read the dataset. */
-      data=gal_array_read_one_ch(filename, hdu, p->cp.minmapsize);
-
-      /* In case this is the first image that is read, then keep the WCS
-         information in the `refdata' structure.  */
-      if(p->popcounter==0)
-        p->refdata.wcs=gal_wcs_read(filename, hdu, 0, 0, &p->refdata.nwcs);
-
-      /* When the reference data structure's dimensionality is non-zero, it
-         means that this is not the first image read. So, write its basic
-         information into the reference data structure for future
-         checks. */
-      if(p->refdata.ndim)
-        {
-          if( gal_dimension_is_different(&p->refdata, data) )
-            error(EXIT_FAILURE, 0, "%s (hdu=%s): has a different size "
-                  "compared to previous images. All the images must be "
-                  "the same size in order for Arithmetic to work",
-                  filename, hdu);
-        }
+      if( operands_is_name(p, operands->filename) )
+        data=operands_copy_named(p, operands->filename);
       else
         {
-          /* Set the dimensionality. */
-          p->refdata.ndim=(data)->ndim;
-
-          /* Allocate the dsize array. */
-          errno=0;
-          p->refdata.dsize=malloc(p->refdata.ndim * sizeof *p->refdata.dsize);
-          if(p->refdata.dsize==NULL)
-            error(EXIT_FAILURE, errno, "%s: allocating %zu bytes for "
-                  "p->refdata.dsize", __func__,
-                  p->refdata.ndim * sizeof *p->refdata.dsize);
-
-          /* Write the values into it. */
-          for(i=0;i<p->refdata.ndim;++i)
-            p->refdata.dsize[i]=data->dsize[i];
+          /* Set the HDU and filename */
+          hdu=operands->hdu;
+          filename=operands->filename;
+
+          /* Read the dataset. */
+          data=gal_array_read_one_ch(filename, hdu, p->cp.minmapsize);
+
+          /* Arithmetic changes the contents of a dataset, so the existing
+             name (in the FITS `EXTNAME' keyword) should not be passed on
+             beyond this point. Also, in Arithmetic, the `name' element is
+             used to identify variables. */
+          if(data->name) { free(data->name); data->name=NULL; }
+
+          /* In case this is the first image that is read, then keep the
+             WCS information in the `refdata' structure.  */
+          if(p->popcounter==0)
+            p->refdata.wcs=gal_wcs_read(filename, hdu, 0, 0,
+                                        &p->refdata.nwcs);
+
+          /* When the reference data structure's dimensionality is
+             non-zero, it means that this is not the first image read. So,
+             write its basic information into the reference data structure
+             for future checks. */
+          if(p->refdata.ndim)
+            {
+              if( gal_dimension_is_different(&p->refdata, data) )
+                error(EXIT_FAILURE, 0, "%s (hdu=%s): has a different size "
+                      "compared to previous images. All the images must be "
+                      "the same size in order for Arithmetic to work",
+                      filename, hdu);
+            }
+          else
+            {
+              /* Set the dimensionality. */
+              p->refdata.ndim=(data)->ndim;
+
+              /* Allocate the dsize array. */
+              errno=0;
+              p->refdata.dsize=malloc(p->refdata.ndim
+                                      * sizeof *p->refdata.dsize);
+              if(p->refdata.dsize==NULL)
+                error(EXIT_FAILURE, errno, "%s: allocating %zu bytes for "
+                      "p->refdata.dsize", __func__,
+                      p->refdata.ndim * sizeof *p->refdata.dsize);
+
+              /* Write the values into it. */
+              for(i=0;i<p->refdata.ndim;++i)
+                p->refdata.dsize[i]=data->dsize[i];
+            }
+
+          /* Report the read image if desired: */
+          if(!p->cp.quiet) printf(" - %s (hdu %s) is read.\n", filename, hdu);
+
+          /* Free the HDU string: */
+          if(hdu) free(hdu);
+
+          /* Add to the number of popped FITS images: */
+          ++p->popcounter;
         }
-
-      /* Report the read image if desired: */
-      if(!p->cp.quiet) printf(" - %s (hdu %s) is read.\n", filename, hdu);
-
-      /* Free the HDU string: */
-      free(hdu);
-
-      /* Add to the number of popped FITS images: */
-      ++p->popcounter;
     }
   else
     data=operands->data;
 
+
   /* Remove this node from the queue, return the data structure. */
   p->operands=operands->next;
   free(operands);
diff --git a/bin/arithmetic/operands.h b/bin/arithmetic/operands.h
index ae487f5..e784f6d 100644
--- a/bin/arithmetic/operands.h
+++ b/bin/arithmetic/operands.h
@@ -32,5 +32,10 @@ operands_add(struct arithmeticparams *p, char *filename, 
gal_data_t *data);
 gal_data_t *
 operands_pop(struct arithmeticparams *p, char *operator);
 
+void
+operands_set_name(struct arithmeticparams *p, char *token);
+
+int
+operands_is_name(struct arithmeticparams *p, char *token);
 
 #endif
diff --git a/bin/arithmetic/ui.c b/bin/arithmetic/ui.c
index 8c57feb..3824f3b 100644
--- a/bin/arithmetic/ui.c
+++ b/bin/arithmetic/ui.c
@@ -26,10 +26,12 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <errno.h>
 #include <error.h>
 #include <stdio.h>
+#include <string.h>
 
 #include <gnuastro/list.h>
 #include <gnuastro/fits.h>
 #include <gnuastro/table.h>
+#include <gnuastro/array.h>
 
 #include <gnuastro-internal/timing.h>
 #include <gnuastro-internal/options.h>
@@ -229,7 +231,7 @@ static void
 ui_check_options_and_arguments(struct arithmeticparams *p)
 {
   int output_checked=0;
-  size_t numfits=0, numhdus=0;
+  size_t nummultiext=0, numhdus=0;
   gal_list_str_t *token, *hdu;
 
   /* First, make sure that any tokens are actually given. */
@@ -247,19 +249,21 @@ ui_check_options_and_arguments(struct arithmeticparams *p)
      was done in `gal_options_read_config_set'. */
   gal_list_str_reverse(&p->tokens);
 
-  /* Set the output file name (if any is needed). Note that since the
-     lists are already reversed, the first FITS file encountered, is
-     the first FITS file given by teh user. Also, notet that these
-     file name operations are only necessary for the first FITS file
-     in the token list. */
+  /* Set the output file name (if any is needed). Note that since the lists
+     are already reversed, the first FITS file encountered, is the first
+     FITS file given by the user. Also, note that these file name
+     operations are only necessary for the first FITS file in the token
+     list. */
   for(token=p->tokens; token!=NULL; token=token->next)
     {
-      /* This token is a FITS file, count them and use it to set the output
-         filename if it has not been set. */
-      if(gal_fits_name_is_fits(token->v))
+      /* This token is a file, count how many mult-extension files we haev
+         and use the first to set the output filename (if it has not been
+         set). */
+      if( gal_array_name_recognized(token->v) )
         {
           /* Increment the counter for FITS files. */
-          ++numfits;
+          if( gal_array_name_recognized_multiext(token->v) )
+            ++nummultiext;
 
           /* If the output filename isn't set yet, then set it. */
           if(output_checked==0)
@@ -288,13 +292,15 @@ ui_check_options_and_arguments(struct arithmeticparams *p)
   else
     {
       for(hdu=p->hdus; hdu!=NULL; hdu=hdu->next) ++numhdus;
-      if(numhdus<numfits)
-        error(EXIT_FAILURE, 0, "not enough HDUs. There are %zu input FITS "
-              "files, so the `--hdu' (`-h') option must be called %zu "
-              "times (once for each FITS file). If the HDU value is the "
-              "same for all the files, you may use `--globalhdu' (`-g') to "
-              "specify a single HDU to be used for any number of input "
-              "files", numfits, numfits);
+      if(numhdus<nummultiext)
+        error(EXIT_FAILURE, 0, "not enough HDUs. There are %zu input "
+              "files in formats that may contain multiple extensions (for "
+              "example FITS or TIFF). Therefore, the `--hdu' (`-h') option "
+              "must be called atleaset %zu times (once for each "
+              "multi-extension file). If the HDU value is the same for all "
+              "the files, you may use `--globalhdu' (`-g') to specify a "
+              "single HDU to be used for any number of input files",
+              nummultiext, nummultiext);
     }
 }
 
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 4aa14c7..5a67e31 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -11813,6 +11813,52 @@ Convert the type of the popped operand to 64-bit 
(double precision)
 floating point (see @ref{Numeric data types}). The internal conversion of C
 will be used.
 
address@hidden set-AAA
+Set a name (all characters after the dash, @code{AAA} in the case shown
+here) for the first popped operand on the stack. The name can be any
+string, but avoid strings ending with standard filename suffixes (for
+example @file{.fits})@footnote{A dataset name like @file{a.fits} (which can
+be set with @command{set-a.fits}) will cause confusion in the the initial
+parser of Arithmetic. It will assume this name is a FITS file, and if it is
+used multiple times, Arithmetic will abort, complaining that you haven't
+provided enough HDUs.}. The named dataset will be freed from memory as soon
+as it is no longer needed in the rest of the command. This operator thus
+enables re-usability of a dataset without having to re-read it from a file
+everytime its necessary during a process.
+
+The name to give the popped dataset is part of the operator's name. For
+example the @code{set-a} operator of the command below, gives the name of
address@hidden'' to the contents of @file{image.fits}. This name is then used
+instead of the actual filename to multiply the dataset by two.
+
address@hidden
+$ astarithmetic image.fits set-a a 2 x
address@hidden example
+
+This is a unique operator, because it doesn't actually do anything to the
+contents of the popped dataset, it just assigns a name to the dataset. This
+makes it very easy to use a single dataset on the command-line multiple
+times and avoid extra attempts at reading it into memory.
+
+One example of the usefulness of this operator is in the @code{where}
+operator. For example, let's assume you want to mask all pixels larger than
address@hidden in @file{image.fits} (extension number 1) with a NaN
+value. Without using this operator, you have to run
+
address@hidden
+$ astarithmetic image.fits image.fits 5 gt nan where -g1
address@hidden example
+
+But with this operator you can simply give @file{image.fits} the name
address@hidden and simplify the command above:
+
address@hidden
+$ astarithmetic image.fits set-i   i i 5 gt nan where
address@hidden example
+
+This operator can thus help simplify reading/writing on the command-line
+(avoid potential bugs), while also speeding up your processing.
+
 @end table
 
 @cartouche
@@ -24026,6 +24072,12 @@ Return 1 if the given file name corresponds to one of 
the recognized file
 types for reading arrays.
 @end deftypefun
 
address@hidden int gal_array_name_recognized_multiext (char @code{*filename})
+Return 1 if the given file name corresponds to one of the recognized file
+types for reading arrays which may contain multiple extesions (for example
+FITS or TIFF) formats.
address@hidden deftypefun
+
 @deftypefun gal_data_t gal_array_read (char @code{*filename}, char 
@code{*extension}, size_t @code{minmapsize})
 Read the array within the given extension (@code{extension}) of
 @code{filename}. If the array is larger than @code{minmapsize} bytes, then
diff --git a/lib/array.c b/lib/array.c
index 0aa708e..6c63afc 100644
--- a/lib/array.c
+++ b/lib/array.c
@@ -48,9 +48,27 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 int
 gal_array_name_recognized(char *name)
 {
+  if( gal_array_name_recognized_multiext(name) ) return 1;
+  else if ( gal_jpeg_name_is_jpeg(name)        ) return 1;
+  else                                           return 0;
+
+  /* Control should not get to here, but just to avoid compiler warnings,
+     we'll return a NULL. */
+  error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to solve the "
+        "problem. Control must not reach the end of this function", __func__,
+        PACKAGE_BUGREPORT);
+  return 0;
+}
+
+
+
+
+
+int
+gal_array_name_recognized_multiext(char *name)
+{
   if(       gal_fits_name_is_fits(name) ) return 1;
   else if ( gal_tiff_name_is_tiff(name) ) return 1;
-  else if ( gal_jpeg_name_is_jpeg(name) ) return 1;
   else                                    return 0;
 
   /* Control should not get to here, but just to avoid compiler warnings,
diff --git a/lib/gnuastro/array.h b/lib/gnuastro/array.h
index aaff1fd..faff5f2 100644
--- a/lib/gnuastro/array.h
+++ b/lib/gnuastro/array.h
@@ -55,6 +55,9 @@ __BEGIN_C_DECLS  /* From C++ preparations */
 int
 gal_array_name_recognized(char *name);
 
+int
+gal_array_name_recognized_multiext(char *name);
+
 gal_data_t *
 gal_array_read(char *filename, char *extension, size_t minmapsize);
 



reply via email to

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