gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master 968ddc4 1/2: Library (fits.h): optionally free


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 968ddc4 1/2: Library (fits.h): optionally free units when writing keywords
Date: Sat, 22 Aug 2020 21:21:54 -0400 (EDT)

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

    Library (fits.h): optionally free units when writing keywords
    
    When the 'gal_fits_key_write_ptr' writes the given keywords into the FITS
    file, it immediately frees all the given components (if
    requested). However, until now it no option on what to do with the 'unit'
    argument. This was not complete and could cause confusion.
    
    With this commit, an extra 'ufree' argument has been added to the
    'gal_fits_key_list_add' and 'gal_fits_key_list_add_end' functions to allow
    freeing the unit string optionally also.
    
    Furthermore, to help in using 'gal_fits_key_write', a fully working example
    has been added to the book.
---
 NEWS                          |  2 ++
 bin/crop/onecrop.c            |  2 +-
 bin/fits/ui.c                 |  2 +-
 bin/mknoise/mknoise.c         | 13 +++++-----
 bin/mkprof/mkprof.c           | 57 +++++++++++++++++++++--------------------
 bin/noisechisel/noisechisel.c | 10 ++++----
 bin/segment/segment.c         | 12 ++++-----
 bin/warp/warp.c               |  2 +-
 doc/gnuastro.texi             | 59 ++++++++++++++++++++++++++++++-------------
 lib/fits.c                    | 21 ++++++++++-----
 lib/gnuastro/fits.h           |  5 ++--
 lib/options.c                 |  4 +--
 12 files changed, 115 insertions(+), 74 deletions(-)

diff --git a/NEWS b/NEWS
index c1608a4..60872c6 100644
--- a/NEWS
+++ b/NEWS
@@ -103,6 +103,8 @@ See the end of the file for license conditions.
      changed).
 
   Library:
+   - gal_fits_key_list_add: new 'ufree' argument to optionally free units.
+   - gal_fits_key_list_add_end: similar to 'gal_fits_key_list_add'.
    - gal_interpolate_neighbors: new name for gal_interpolate_close_neighbors.
    - gal_statistics_outlier_bydistance: new name for the old
      'gal_statistics_outlier_positive'. It can now use the same algorithm
diff --git a/bin/crop/onecrop.c b/bin/crop/onecrop.c
index 589d007..5061b61 100644
--- a/bin/crop/onecrop.c
+++ b/bin/crop/onecrop.c
@@ -755,7 +755,7 @@ onecrop(struct onecropparams *crp)
       sprintf(regionkey, "%sPIX", basekeyname);
       gal_fits_key_list_add_end(&headers, GAL_TYPE_STRING, regionkey,
                                 0, region, 0, "Range of pixels used for "
-                                "this output.", 0, NULL);
+                                "this output.", 0, NULL, 0);
       gal_fits_key_write_in_ptr(&headers, ofp);
 
 
diff --git a/bin/fits/ui.c b/bin/fits/ui.c
index bd8ea0c..c1d3d5b 100644
--- a/bin/fits/ui.c
+++ b/bin/fits/ui.c
@@ -588,7 +588,7 @@ ui_fill_fits_headerll(gal_list_str_t *input, 
gal_fits_list_key_t **output,
 
       /* Add it to the list of keywords. */
       gal_fits_key_list_add(output, type, keyname, 0, fvalue, vfree,
-                            comment, 0, unit);
+                            comment, 0, unit, 0);
       free(original);
     }
 
diff --git a/bin/mknoise/mknoise.c b/bin/mknoise/mknoise.c
index 56ee00a..3ccbba2 100644
--- a/bin/mknoise/mknoise.c
+++ b/bin/mknoise/mknoise.c
@@ -68,33 +68,34 @@ convertsaveoutput(struct mknoiseparams *p)
       gal_fits_key_list_add_end(&headers, GAL_TYPE_FLOAT64, keyname1, 0,
                                 &p->background_mag, 0, "Background "
                                 "value (in magnitude) for noise.",
-                                0, NULL);
+                                0, NULL, 0);
       strcpy(keyname2, "BZRPNT");
       gal_fits_key_list_add_end(&headers, GAL_TYPE_FLOAT64, keyname2, 0,
                                 &p->zeropoint, 0,
-                                "Zeropoint magnitude of image.", 0, NULL);
+                                "Zeropoint magnitude of image.", 0, NULL, 0);
       strcpy(keyname3, "INSTRU");
       gal_fits_key_list_add_end(&headers, GAL_TYPE_FLOAT64, keyname3, 0,
                                 &p->instrumental, 0,
                                 "Instrumental noise in units of flux.",
-                                0, NULL);
+                                0, NULL, 0);
     }
   else
     {
       strcpy(keyname1, "SIGMA");
       gal_fits_key_list_add_end(&headers, GAL_TYPE_FLOAT64, keyname1, 0,
-                                &p->sigma, 0, "Total noise sigma", 0, NULL);
+                                &p->sigma, 0, "Total noise sigma", 0,
+                                NULL, 0);
     }
   strcpy(keyname4, "RNGTYPE");
   gal_fits_key_list_add_end(&headers, GAL_TYPE_STRING, keyname4, 0,
                             (void *)(p->rng_name), 0,
                             "Random number generator (by GSL) type.",
-                            0, NULL);
+                            0, NULL, 0);
   strcpy(keyname5, "RNGSEED");
   gal_fits_key_list_add_end(&headers, GAL_TYPE_ULONG, keyname5, 0,
                             &p->rng_seed, 0,
                             "Random number generator (by GSL) seed.",
-                            0, NULL);
+                            0, NULL, 0);
 
   /* Save the output: */
   p->input=gal_data_copy_to_new_type_free(p->input, p->cp.type);
diff --git a/bin/mkprof/mkprof.c b/bin/mkprof/mkprof.c
index adc249d..40acdf8 100644
--- a/bin/mkprof/mkprof.c
+++ b/bin/mkprof/mkprof.c
@@ -171,95 +171,98 @@ saveindividual(struct mkonthread *mkp)
   /* Write profile settings into the FITS file. */
   gal_fits_key_list_add(&keys, GAL_TYPE_STRING, "PROFILE", 0,
                         ui_profile_name_write(mkp->func), 0,
-                        "Radial function", 0, NULL);
+                        "Radial function", 0, NULL, 0);
   gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT64, "XCENTER", 0,
                         &p->x[id], 0, "Center of profile in catalog "
-                        "(FITS axis 1)", 0, NULL);
+                        "(FITS axis 1)", 0, NULL, 0);
   gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT64, "YCENTER", 0,
                         &p->y[id], 0, "Center of profile in catalog "
-                        "(FITS axis 2)", 0, NULL);
+                        "(FITS axis 2)", 0, NULL, 0);
   if(ndim==3)
     gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT64, "ZCENTER", 0,
                           &p->z[id], 0, "Center of profile in catalog "
-                          "(FITS axis 3)", 0, NULL);
+                          "(FITS axis 3)", 0, NULL, 0);
   gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "RADIUS", 0,
                         &p->r[id], 0, "Radial parameter in catalog",
-                        0, NULL);
+                        0, NULL, 0);
   if( mkp->func==PROFILE_SERSIC || mkp->func==PROFILE_MOFFAT )
     gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "PINDEX", 0,
                           &p->r[id], 0, "Index (Sersic or Moffat) of profile"
-                          "in catalog", 0, NULL);
+                          "in catalog", 0, NULL, 0);
   if(ndim==2)
     {
       gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "PA_DEG", 0,
                             &p->p1[id], 0, "Position angle of profile in "
-                            "catalog", 0, "deg");
+                            "catalog", 0, "deg", 0);
       gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "AXISRATIO", 0,
                             &p->q1[id], 0, "Axis ratio of profile in catalog",
-                            0, NULL);
+                            0, NULL, 0);
     }
   else
     {
       gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "PA1_DEG", 0,
                             &p->p1[id], 0, "First X-Z-X Euler angle in 3D", 0,
-                            "deg");
+                            "deg", 0);
       gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "PA2_DEG", 0,
                             &p->p2[id], 0, "Second X-Z-X Euler angle in 3D", 0,
-                            "deg");
+                            "deg", 0);
       gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "PA3_DEG", 0,
                             &p->p3[id], 0, "Third X-Z-X Euler angle in 3D", 0,
-                            "deg");
+                            "deg", 0);
       gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "AXISRATIO1", 0,
                             &p->q1[id], 0, "Axis ratio along second dim",
-                            0, NULL);
+                            0, NULL, 0);
       gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "AXISRATIO2", 0,
                             &p->q2[id], 0, "Axis ratio along third dim",
-                            0, NULL);
+                            0, NULL, 0);
     }
   gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "MAGNITUDE", 0,
                         &p->m[id], 0, "Magnitude of profile in catalog",
-                        0, NULL);
+                        0, NULL, 0);
   gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "TRUNCATION", 0,
                         &p->t[id], 0, "Truncation of profile in catalog",
-                        0, NULL);
+                        0, NULL, 0);
   gal_fits_key_list_add(&keys, GAL_TYPE_STRING, "RNGNAME", 0,
                         (void *)(p->rng_name), 0,
-                        "Name of random number generator", 0, NULL);
+                        "Name of random number generator", 0, NULL, 0);
   gal_fits_key_list_add(&keys, GAL_TYPE_ULONG, "RNGSEED", 0,
                         &mkp->rng_seed, 0, "Seed of random number generator",
-                        0, NULL);
+                        0, NULL, 0);
   gal_fits_key_list_add(&keys, GAL_TYPE_SIZE_T, "NUMRANDOM", 0,
                         &p->numrandom, 0,
-                        "Number of random points in central pixels", 0, NULL);
+                        "Number of random points in central pixels", 0,
+                        NULL, 0);
   gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "TOLERANCE", 0,
                         &p->tolerance, 0,
                         "Tolerance level to stop random integration",
-                        0, NULL);
+                        0, NULL, 0);
   gal_fits_key_list_add(&keys, GAL_TYPE_STRING, "MODE", 0,
                         p->mode==MKPROF_MODE_IMG?"img":"wcs", 0,
-                        "Coordinates in image or WCS units", 0, NULL);
+                        "Coordinates in image or WCS units", 0, NULL, 0);
   gal_fits_key_list_add(&keys, GAL_TYPE_UINT8, "OVERSAMPLE", 0,
-                        &p->oversample, 0, "Oversampling factor", 0, NULL);
+                        &p->oversample, 0, "Oversampling factor", 0,
+                        NULL, 0);
   gal_fits_key_list_add(&keys, GAL_TYPE_UINT8, "TUNITINP", 0,
                         &p->tunitinp, 0, "Truncation is in units of pixels, "
-                        "not radius", 0, NULL);
+                        "not radius", 0, NULL, 0);
   if( !isnan(p->zeropoint) )
       gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "ZEROPOINT", 0,
-                            &p->zeropoint, 0, "Zeropoint magnitude", 0, NULL);
+                            &p->zeropoint, 0, "Zeropoint magnitude", 0,
+                            NULL, 0);
   if( mkp->func==PROFILE_CIRCUMFERENCE )
       gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "CIRCUMWIDTH", 0,
                             &p->circumwidth, 0, "Width of circumference "
-                            "(inward) profiles", 0, NULL);
+                            "(inward) profiles", 0, NULL, 0);
   if( mkp->func==PROFILE_FLAT || mkp->func==PROFILE_CIRCUMFERENCE )
       gal_fits_key_list_add(&keys, GAL_TYPE_UINT8, "MFORFLATPIX", 0,
                             &p->mforflatpix, 0, "Magnitude is flat pixel "
-                            "value", 0, NULL);
+                            "value", 0, NULL, 0);
   gal_fits_key_list_add(&keys, GAL_TYPE_UINT8, "MCOLISBRIGHTNESS", 0,
                         &p->mcolisbrightness, 0, "Catalog's magnitude is "
-                        "actually brightness", 0, NULL);
+                        "actually brightness", 0, NULL, 0);
   gal_fits_key_list_add(&keys, GAL_TYPE_UINT8, "MAGATPEAK", 0,
                         &p->magatpeak, 0, "Magnitude is for peak pixel, "
-                        "not full profile", 0, NULL);
+                        "not full profile", 0, NULL, 0);
 
   gal_fits_key_list_reverse(&keys);
   gal_fits_key_write_config(&keys, "Profile configuration", "PROFILE-CONFIG",
diff --git a/bin/noisechisel/noisechisel.c b/bin/noisechisel/noisechisel.c
index 16b859f..8e90639 100644
--- a/bin/noisechisel/noisechisel.c
+++ b/bin/noisechisel/noisechisel.c
@@ -160,11 +160,11 @@ noisechisel_output(struct noisechiselparams *p)
   /* Write the detected pixels and useful information into it's header. */
   gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "DETSN", 0, &p->detsnthresh,
                         0, "Minimum S/N of true pseudo-detections", 0,
-                        "ratio");
+                        "ratio", 0);
   if(p->label)
     gal_fits_key_list_add(&keys, GAL_TYPE_SIZE_T, "NUMLABS", 0,
                           &p->numdetections, 0, "Total number of labels "
-                          "(inclusive)", 0, "counter");
+                          "(inclusive)", 0, "counter", 0);
   gal_fits_key_list_reverse(&keys);
   if(p->label)
     {
@@ -193,13 +193,13 @@ noisechisel_output(struct noisechiselparams *p)
   p->std->name="SKY_STD";
   gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "MAXSTD", 0, &p->maxstd, 0,
                         "Maximum raw tile standard deviation", 0,
-                        p->input->unit);
+                        p->input->unit, 0);
   gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "MINSTD", 0, &p->minstd, 0,
                         "Minimum raw tile standard deviation", 0,
-                        p->input->unit);
+                        p->input->unit, 0);
   gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "MEDSTD", 0, &p->medstd, 0,
                         "Median raw tile standard deviation", 0,
-                        p->input->unit);
+                        p->input->unit, 0);
   gal_tile_full_values_write(p->std, &p->cp.tl, !p->ignoreblankintiles,
                              p->cp.output, keys, PROGRAM_NAME);
   p->std->name=NULL;
diff --git a/bin/segment/segment.c b/bin/segment/segment.c
index 0f8a5bd..8767c42 100644
--- a/bin/segment/segment.c
+++ b/bin/segment/segment.c
@@ -1070,10 +1070,10 @@ segment_output(struct segmentparams *p)
   /* The clump labels. */
   gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "CLUMPSN", 0,
                         &p->clumpsnthresh, 0, "Minimum S/N of true clumps",
-                        0, "ratio");
+                        0, "ratio", 0);
   gal_fits_key_list_add(&keys, GAL_TYPE_SIZE_T, "NUMLABS", 0,
                         &p->numclumps, 0, "Total number of clumps", 0,
-                        "counter");
+                        "counter", 0);
   p->clabel->name="CLUMPS";
   gal_fits_img_write(p->clabel, p->cp.output, keys, PROGRAM_NAME);
   p->clabel->name=NULL;
@@ -1085,7 +1085,7 @@ segment_output(struct segmentparams *p)
     {
       gal_fits_key_list_add(&keys, GAL_TYPE_SIZE_T, "NUMLABS", 0,
                             &p->numobjects, 0, "Total number of objects", 0,
-                            "counter");
+                            "counter", 0);
       p->olabel->name="OBJECTS";
       gal_fits_img_write(p->olabel, p->cp.output, keys, PROGRAM_NAME);
       p->olabel->name=NULL;
@@ -1101,17 +1101,17 @@ segment_output(struct segmentparams *p)
         gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "MAXSTD", 0,
                               &p->maxstd, 0,
                               "Maximum raw tile standard deviation", 0,
-                              p->input->unit);
+                              p->input->unit, 0);
       if( !isnan(p->minstd) )
         gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "MINSTD", 0,
                               &p->minstd, 0,
                               "Minimum raw tile standard deviation", 0,
-                              p->input->unit);
+                              p->input->unit, 0);
       if( !isnan(p->medstd) )
         gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "MEDSTD", 0,
                               &p->medstd, 0,
                               "Median raw tile standard deviation", 0,
-                              p->input->unit);
+                              p->input->unit, 0);
 
       /* If the input was actually a variance dataset, we'll need to take
          its square root before writing it. We want this output to be a
diff --git a/bin/warp/warp.c b/bin/warp/warp.c
index f5f113c..13cd919 100644
--- a/bin/warp/warp.c
+++ b/bin/warp/warp.c
@@ -479,7 +479,7 @@ correct_wcs_save_output(struct warpparams *p)
       sprintf(&keyword[i*FLEN_KEYWORD], "WMTX%zu_%zu", i/3+1, i%3+1);
       gal_fits_key_list_add_end(&headers, GAL_TYPE_FLOAT64,
                                 &keyword[i*FLEN_KEYWORD], 0, &m[i], 0,
-                                "Warp matrix element value", 0, NULL);
+                                "Warp matrix element value", 0, NULL, 0);
     }
 
   /* Save the output into the proper type and write it. */
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index b443683..b5ba0ce 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -21983,22 +21983,23 @@ filename and HDU as input instead of an already 
opened CFITSIO
 @end deftypefun
 
 
-@deftypefun void gal_fits_key_list_add (gal_fits_list_key_t @code{**list}, 
uint8_t @code{type}, char @code{*keyname}, int @code{kfree}, void 
@code{*value}, int @code{vfree}, char @code{*comment}, int @code{cfree}, char 
@code{*unit})
-Add a keyword to the top of list of header keywords that need to be
-written into a FITS file. In the end, the keywords will have to be freed,
-so it is important to know before hand if they were allocated or not (hence
-the presence of the arguments ending in @code{free}). If the space for the
-respective element is not allocated, set these arguments to @code{0}
-(zero).
+@deftypefun void gal_fits_key_list_add (gal_fits_list_key_t @code{**list}, 
uint8_t @code{type}, char @code{*keyname}, int @code{kfree}, void 
@code{*value}, int @code{vfree}, char @code{*comment}, int @code{cfree}, char 
@code{*unit}, int @code{ufree})
+Add a keyword to the top of list of header keywords that need to be written 
into a FITS file.
+In the end, the keywords will have to be freed, so it is important to know 
before hand if they were allocated or not (hence the presence of the arguments 
ending in @code{free}).
+If the space for the respective element is not allocated, set these arguments 
to @code{0} (zero).
 
-@strong{Important note for strings}: the value should be the pointer to the
-string its-self (@code{char *}), not a pointer to a pointer (@code{char **}).
+You can call this function multiple times on a single list add several keys 
that will be written in one call to @code{gal_fits_key_write} or 
@code{gal_fits_key_write_in_ptr}.
+However, the resulting list will be a last-in-first-out list (for more on 
lists, see @ref{Linked lists}).
+Hence, the written keys will have the inverse order of your calls to this 
function.
+To avoid this problem, you can either use @code{gal_fits_key_list_add_end} 
instead (which will add each key to the end of the list, not to the top like 
this function).
+Alternatively, you can use @code{gal_fits_key_list_reverse} after adding all 
the keys with this function.
+
+@strong{Important note for strings}: the value should be the pointer to the 
string its-self (@code{char *}), not a pointer to a pointer (@code{char **}).
 @end deftypefun
 
-@deftypefun void gal_fits_key_list_add_end (gal_fits_list_key_t @code{**list}, 
uint8_t @code{type}, char @code{*keyname}, int @code{kfree}, void 
@code{*value}, int @code{vfree}, char @code{*comment}, int @code{cfree}, char 
@code{*unit})
-Similar to @code{gal_fits_key_list_add} (see above) but add the keyword to
-the end of the list. Use this function if you want the keywords to be
-written in the same order that you add nodes to the list of keywords.
+@deftypefun void gal_fits_key_list_add_end (gal_fits_list_key_t @code{**list}, 
uint8_t @code{type}, char @code{*keyname}, int @code{kfree}, void 
@code{*value}, int @code{vfree}, char @code{*comment}, int @code{cfree}, char 
@code{*unit}, int @code{ufree})
+Similar to @code{gal_fits_key_list_add}, but add the given keyword to the end 
of the list, see the description of @code{gal_fits_key_list_add} for more.
+Use this function if you want the keywords to be written in the same order 
that you add nodes to the list of keywords.
 @end deftypefun
 
 @deftypefun void gal_fits_key_list_reverse (gal_fits_list_key_t @code{**list})
@@ -22038,13 +22039,37 @@ each keyword record.
 @end deftypefun
 
 @deftypefun void gal_fits_key_write (gal_fits_list_key_t @code{**keylist}, 
char @code{*title}, char @code{*filename}, char @code{*hdu})
-Write the list of keywords in @code{keylist} into the @code{hdu} extension
-of the file called @code{filename} (it must already exist).
+Write the list of keywords in @code{keylist} into the @code{hdu} extension of 
the file called @code{filename} (the file must already exist) and free the list.
+
+The list nodes are meant to be dynamically allocated (because they will be 
freed after being written).
+We thus recommend using the @code{gal_fits_key_list_add} or 
@code{gal_fits_key_list_add_end} to create and fill the list.
+Below is one fully working example of using this function to write a keyword 
into an existing FITS file.
+
+@example
+#include <stdio.h>
+#include <stdlib.h>
+#include <gnuastro/fits.h>
+
+int main()
+@{
+  char *filename="test.fits";
+  gal_fits_list_key_t *keylist=NULL;
+
+  char *unit="unit";
+  float value=123.456;
+  char *keyname="MYKEY";
+  char *comment="A good description of the key";
+  gal_fits_key_list_add_end(&keylist, GAL_TYPE_FLOAT32, keyname, 0,
+                            &value, 0, comment, 0, unit, 0);
+  gal_fits_key_write(&keylist, "Matching metadata", filename, "1");
+  return EXIT_SUCCESS;
+@}
+@end example
 @end deftypefun
 
 @deftypefun void gal_fits_key_write_in_ptr (gal_fits_list_key_t 
@code{**keylist}, fitsfile @code{*fptr})
-Write the list of keywords in @code{keylist} into the given CFITSIO
-@code{fitsfile} pointer.
+Write the list of keywords in @code{keylist} into the given CFITSIO 
@code{fitsfile} pointer and free keylist.
+For more on the input @code{keylist}, see the description and example for 
@code{gal_fits_key_write}, above.
 @end deftypefun
 
 @deftypefun void gal_fits_key_write_version (gal_fits_list_key_t 
@code{**keylist}, char @code{*title}, char @code{*filename}, char @code{*hdu})
diff --git a/lib/fits.c b/lib/fits.c
index 046d536..4b8ebdd 100644
--- a/lib/fits.c
+++ b/lib/fits.c
@@ -1268,7 +1268,7 @@ gal_fits_key_read(char *filename, char *hdu, gal_data_t 
*keysll,
 void
 gal_fits_key_list_add(gal_fits_list_key_t **list, uint8_t type,
                       char *keyname, int kfree, void *value, int vfree,
-                      char *comment, int cfree, char *unit)
+                      char *comment, int cfree, char *unit, int ufree)
 {
   gal_fits_list_key_t *newnode;
 
@@ -1277,6 +1277,8 @@ gal_fits_key_list_add(gal_fits_list_key_t **list, uint8_t 
type,
   newnode=malloc(sizeof *newnode);
   if(newnode==NULL)
     error(EXIT_FAILURE, errno, "%s: allocating new node", __func__);
+
+  /* Write the given values into the key structure. */
   newnode->type=type;
   newnode->keyname=keyname;
   newnode->value=value;
@@ -1285,7 +1287,9 @@ gal_fits_key_list_add(gal_fits_list_key_t **list, uint8_t 
type,
   newnode->kfree=kfree;                /* Free pointers after using them. */
   newnode->vfree=vfree;
   newnode->cfree=cfree;
+  newnode->ufree=ufree;
 
+  /* Set the next pointer. */
   newnode->next=*list;
   *list=newnode;
 }
@@ -1297,7 +1301,7 @@ gal_fits_key_list_add(gal_fits_list_key_t **list, uint8_t 
type,
 void
 gal_fits_key_list_add_end(gal_fits_list_key_t **list, uint8_t type,
                           char *keyname, int kfree, void *value, int vfree,
-                          char *comment, int cfree, char *unit)
+                          char *comment, int cfree, char *unit, int ufree)
 {
   gal_fits_list_key_t *newnode, *tmp;
 
@@ -1306,6 +1310,8 @@ gal_fits_key_list_add_end(gal_fits_list_key_t **list, 
uint8_t type,
   newnode=malloc(sizeof *newnode);
   if(newnode==NULL)
     error(EXIT_FAILURE, errno, "%s: allocation of new node", __func__);
+
+  /* Write the given values into the key structure. */
   newnode->type=type;
   newnode->keyname=keyname;
   newnode->value=value;
@@ -1314,7 +1320,9 @@ gal_fits_key_list_add_end(gal_fits_list_key_t **list, 
uint8_t type,
   newnode->kfree=kfree;            /* Free pointers after using them. */
   newnode->vfree=vfree;
   newnode->cfree=cfree;
+  newnode->ufree=ufree;
 
+  /* Set the next pointer. */
   if(*list)         /* List is already full, add this node to the end */
     {
       /* After this line, tmp points to the last node. */
@@ -1448,10 +1456,10 @@ gal_fits_key_write_filename(char *keynamebase, char 
*filename,
         {
           if(top1end0)
             gal_fits_key_list_add(list, GAL_TYPE_STRING, keyname, 1,
-                                  value, 1, NULL, 0, NULL);
+                                  value, 1, NULL, 0, NULL, 0);
           else
             gal_fits_key_list_add_end(list, GAL_TYPE_STRING, keyname, 1,
-                                      value, 1, NULL, 0, NULL);
+                                      value, 1, NULL, 0, NULL, 0);
           break;
         }
       else
@@ -1484,10 +1492,10 @@ gal_fits_key_write_filename(char *keynamebase, char 
*filename,
           /* Convert the last useful character and save the file name.*/
           if(top1end0)
             gal_fits_key_list_add(list, GAL_TYPE_STRING, keyname, 1,
-                                  value, 1, NULL, 0, NULL);
+                                  value, 1, NULL, 0, NULL, 0);
           else
             gal_fits_key_list_add_end(list, GAL_TYPE_STRING, keyname, 1,
-                                      value, 1, NULL, 0, NULL);
+                                      value, 1, NULL, 0, NULL, 0);
           i+=j+1;
         }
     }
@@ -1589,6 +1597,7 @@ gal_fits_key_write_in_ptr(gal_fits_list_key_t **keylist, 
fitsfile *fptr)
       if(tmp->kfree) free(tmp->keyname);
       if(tmp->vfree) free(tmp->value);
       if(tmp->cfree) free(tmp->comment);
+      if(tmp->ufree) free(tmp->unit);
 
       /* Keep the pointer to the next keyword and free the allocated
          space for this keyword.*/
diff --git a/lib/gnuastro/fits.h b/lib/gnuastro/fits.h
index df4d192..468587a 100644
--- a/lib/gnuastro/fits.h
+++ b/lib/gnuastro/fits.h
@@ -80,6 +80,7 @@ typedef struct gal_fits_list_key_t
   int                        kfree;   /* ==1, free keyword name.   */
   int                        vfree;   /* ==1, free keyword value.  */
   int                        cfree;   /* ==1, free comment.        */
+  int                        ufree;   /* ==1, free unit.           */
   uint8_t                     type;   /* Keyword value type.       */
   char                    *keyname;   /* Keyword Name.             */
   void                      *value;   /* Keyword value.            */
@@ -185,12 +186,12 @@ gal_fits_key_read(char *filename, char *hdu, gal_data_t 
*keysll,
 void
 gal_fits_key_list_add(gal_fits_list_key_t **list, uint8_t type,
                       char *keyname, int kfree, void *value, int vfree,
-                      char *comment, int cfree, char *unit);
+                      char *comment, int cfree, char *unit, int ufree);
 
 void
 gal_fits_key_list_add_end(gal_fits_list_key_t **list, uint8_t type,
                           char *keyname, int kfree, void *value, int vfree,
-                          char *comment, int cfree, char *unit);
+                          char *comment, int cfree, char *unit, int ufree);
 
 void
 gal_fits_key_list_reverse(gal_fits_list_key_t **list);
diff --git a/lib/options.c b/lib/options.c
index a22a5ec..8159420 100644
--- a/lib/options.c
+++ b/lib/options.c
@@ -2804,7 +2804,7 @@ options_as_fits_keywords_write(gal_fits_list_key_t **keys,
               gal_checkset_allocate_copy(options[i].name, &name);
               gal_checkset_allocate_copy(options[i].doc,  &doc);
               gal_fits_key_list_add(keys, GAL_TYPE_STRING, name, 1, tmp->v,
-                                    0, doc, 1, NULL);
+                                    0, doc, 1, NULL, 0);
             }
         /* Normal types. */
         else
@@ -2835,7 +2835,7 @@ options_as_fits_keywords_write(gal_fits_list_key_t **keys,
               {
                 gal_checkset_allocate_copy(options[i].doc,  &doc);
                 gal_fits_key_list_add(keys, vtype, name, 1, vptr, 0, doc, 1,
-                                      NULL);
+                                      NULL, 0);
               }
           }
       }



reply via email to

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