gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master 7564d430: Crop: new --append operator to add c


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 7564d430: Crop: new --append operator to add crop as new HDU fo output
Date: Sun, 30 Oct 2022 12:30:33 -0400 (EDT)

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

    Crop: new --append operator to add crop as new HDU fo output
    
    Until now, Crop would always delete the output file if it already
    existed. However, in some scenarios, it is necessary keep existing HDUs and
    just append the new crop to them. To do this, it was necessary to put the
    cropped HDU in a temporary file, then use 'astfits' to copy that HDU into
    the file with existing HDUs. But this is an annoying extra step (given that
    the low-level structure to preserve the HDUs is already present in crop).
    
    With this commit, a new '--append' option has been added for this job. When
    it is called, if the output file already exists, the cropped HDU will be
    written after the last HDU. An example usage of this to crop all image-HDUs
    of a file has been added at the example commands in the "Invoking Crop"
    section of the book.
    
    In the process, I also noticed that Crop's output options weren't listed in
    the "Crop output" sub-section of the "invoking Crop" section. They have
    also been moved there with this commit.
    
    This issue was implemented after a discussion with Michael Stein and Elham
    Saremi.
---
 NEWS                             |   3 +
 bin/crop/args.h                  |  13 ++++
 bin/crop/main.h                  |   1 +
 bin/crop/onecrop.c               |  42 +++++++-----
 bin/crop/ui.c                    |   7 +-
 bin/crop/ui.h                    |   3 +-
 bin/mkprof/ui.c                  |   2 +-
 doc/announce-acknowledge.txt     |   1 +
 doc/gnuastro.texi                | 139 ++++++++++++++++++++-------------------
 lib/checkset.c                   |   4 +-
 lib/gnuastro-internal/checkset.h |   2 +-
 11 files changed, 125 insertions(+), 92 deletions(-)

diff --git a/NEWS b/NEWS
index c2963b45..6c679098 100644
--- a/NEWS
+++ b/NEWS
@@ -22,6 +22,9 @@ See the end of the file for license conditions.
      - counteronly: similar to 'counter', but pops the top stack dataset.
 
    Crop:
+   --append: if the output file already exists, append the cropped image
+     HDU to the already existing HDUs of the file. Without this option, any
+     existing HDUs in the output file will be removed (default behavior).
    --metaname: Specify the name of the cropped output HDU (value to the
      'EXTNAME' keyword in FITS).
 
diff --git a/bin/crop/args.h b/bin/crop/args.h
index 97fcc435..50152a64 100644
--- a/bin/crop/args.h
+++ b/bin/crop/args.h
@@ -154,6 +154,19 @@ struct argp_option program_options[] =
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
     },
+    {
+      "append",
+      UI_KEY_APPEND,
+      0,
+      0,
+      "If output exists, append crop to existing HDUs.",
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->append,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
+    },
 
 
 
diff --git a/bin/crop/main.h b/bin/crop/main.h
index b0ccc505..706d7cdf 100644
--- a/bin/crop/main.h
+++ b/bin/crop/main.h
@@ -86,6 +86,7 @@ struct cropparams
   int                     mode;  /* Image or WCS mode.                    */
   uint8_t       zeroisnotblank;  /* ==1: In float or double, keep 0.0.    */
   uint8_t        primaryimghdu;  /* ==1: write in primary/0-th HDU.       */
+  uint8_t               append;  /* If output exists, append crop.        */
   uint8_t              noblank;  /* ==1: no blank (out of image) pixels.  */
   char                 *suffix;  /* Ending of output file name.           */
   gal_data_t    *incheckcenter;  /* Value given to '--checkcenter'.       */
diff --git a/bin/crop/onecrop.c b/bin/crop/onecrop.c
index de267552..537b1a53 100644
--- a/bin/crop/onecrop.c
+++ b/bin/crop/onecrop.c
@@ -405,7 +405,7 @@ onecrop_name(struct onecropparams *crp)
           error(EXIT_FAILURE, 0, "%s: asprintf allocation", __func__);
 
       /* Make sure the file doesn't exist. */
-      gal_checkset_writable_remove(crp->name, 0, cp->dontdelete);
+      gal_checkset_writable_remove(crp->name, cp->keep, cp->dontdelete);
     }
   else
     {
@@ -413,12 +413,14 @@ onecrop_name(struct onecropparams *crp)
       if(p->outnameisfile)            /* An output file was specified. */
         {
           crp->name=cp->output;
-          gal_checkset_writable_remove(crp->name, 0, cp->dontdelete);
+          gal_checkset_writable_remove(crp->name, cp->keep, cp->dontdelete);
         }
       else          /* The output was a directory, use automatic output. */
+        {
         crp->name=gal_checkset_automatic_output(cp,
                                                 p->imgs[crp->in_ind].name,
                                                 p->suffix);
+        }
     }
 }
 
@@ -516,19 +518,21 @@ static void
 onecrop_make_array(struct onecropparams *crp, long *fpixel_i,
                    long *lpixel_i, long *fpixel_c, long *lpixel_c)
 {
+  struct cropparams *p=crp->p;
+
   double crpix;
   fitsfile *ofp;
   long naxes[MAXDIM];
   char *outname=crp->name;
-  int status=0, type=crp->p->type;
+  int status=0, type=p->type;
   char **strarr, cpname[FLEN_KEYWORD];
+  size_t i, ndim=p->imgs->ndim, totsize;
   gal_data_t *rkey=gal_data_array_calloc(1);
-  size_t i, ndim=crp->p->imgs->ndim, totsize;
-  struct inputimgs *img=&crp->p->imgs[crp->in_ind];
+  struct inputimgs *img=&p->imgs[crp->in_ind];
 
 
   /* Set the size of the output, in WCS mode, noblank==0. */
-  if(crp->p->noblank && crp->p->mode==IMGCROP_MODE_IMG)
+  if(p->noblank && p->mode==IMGCROP_MODE_IMG)
     for(i=0;i<ndim;++i)
       {
         fpixel_c[i] = 1;
@@ -541,15 +545,19 @@ onecrop_make_array(struct onecropparams *crp, long 
*fpixel_i,
 
   /* Create the FITS file with a blank first extension, then close it, so
      with the next 'fits_open_file', we build the image in the second
-     extension. This way, atleast for Gnuastro's outputs, we can
-     consistently use '-h1' (something like how you count columns, or
-     generally everything from 1). */
-  if(fits_create_file(&ofp, outname, &status))
-    gal_fits_io_error(status, "creating file");
-  if(crp->p->primaryimghdu==0)
+     extension. But only if the user didn't want the append the crop to an
+     existing file or if the file doesn't exist at all. This way, at least
+     for Gnuastro's outputs, we can consistently use '-h1' (something like
+     how you count columns, or generally everything from 1). */
+  if(p->append==0 || gal_checkset_check_file_return(outname)==0)
     {
-      fits_create_img(ofp, SHORT_IMG, 0, naxes, &status);
-      fits_close_file(ofp, &status);
+      if(fits_create_file(&ofp, outname, &status))
+        gal_fits_io_error(status, "creating file");
+      if(p->primaryimghdu==0)
+        {
+          fits_create_img(ofp, SHORT_IMG, 0, naxes, &status);
+          fits_close_file(ofp, &status);
+        }
     }
 
 
@@ -574,7 +582,7 @@ onecrop_make_array(struct onecropparams *crp, long 
*fpixel_i,
 
 
   /* Name of extension. */
-  fits_update_key(ofp, TSTRING, "EXTNAME", crp->p->metaname,
+  fits_update_key(ofp, TSTRING, "EXTNAME", p->metaname,
                   "Name of HDU (extension).", &status);
   gal_fits_io_error(status, "writing EXTNAME");
 
@@ -597,8 +605,8 @@ onecrop_make_array(struct onecropparams *crp, long 
*fpixel_i,
 
   /* Write the blank value as a FITS keyword if necessary. */
   if( type!=GAL_TYPE_FLOAT32 && type!=GAL_TYPE_FLOAT64 )
-    if(fits_write_key(ofp, gal_fits_type_to_datatype(crp->p->type), "BLANK",
-                      crp->p->blankptrwrite, "Pixels with no data.",
+    if(fits_write_key(ofp, gal_fits_type_to_datatype(type), "BLANK",
+                      p->blankptrwrite, "Pixels with no data.",
                       &status) )
       gal_fits_io_error(status, "adding Blank");
   totsize = naxes[0]*naxes[1] * (ndim==3?naxes[2]:1);
diff --git a/bin/crop/ui.c b/bin/crop/ui.c
index 30b775f8..d5da5507 100644
--- a/bin/crop/ui.c
+++ b/bin/crop/ui.c
@@ -433,6 +433,10 @@ ui_read_check_only_options(struct cropparams *p)
   if(p->mode==IMGCROP_MODE_WCS && p->noblank)
     error(EXIT_FAILURE, 0, "'--noblanks' ('-b') is only for image mode. "
           "You have called it with WCS mode");
+
+  /* If '--apend' has been called, set 'cp.keep' to 1 (since we don't want
+     to delete the output file). */
+  if(p->append) p->cp.keep=1;
 }
 
 
@@ -501,8 +505,7 @@ ui_check_options_and_arguments(struct cropparams *p)
   else
     {
       p->cp.numthreads=1;
-      p->outnameisfile=gal_checkset_dir_0_file_1(p->cp.output,
-                                                 p->cp.dontdelete);
+      p->outnameisfile=gal_checkset_dir_0_file_1(&p->cp, p->cp.output);
     }
 }
 
diff --git a/bin/crop/ui.h b/bin/crop/ui.h
index d5068e5d..056c76d5 100644
--- a/bin/crop/ui.h
+++ b/bin/crop/ui.h
@@ -46,7 +46,7 @@ enum program_args_groups
 /* Available letters for short options:
 
    d e f g i j k m r u v y
-   A B E G H J L Q R W Y
+   B E G H J L Q R W Y
 */
 enum option_keys_enum
 {
@@ -65,6 +65,7 @@ enum option_keys_enum
   UI_KEY_COORDCOL       = 'x',
   UI_KEY_ONEELEMSTDOUT  = 't',
   UI_KEY_METANAME       = 'a',
+  UI_KEY_APPEND         = 'A',
 
   /* Only with long version (start with a value 1000, the rest will be set
      automatically). */
diff --git a/bin/mkprof/ui.c b/bin/mkprof/ui.c
index 0aebbc88..3ac0f5e9 100644
--- a/bin/mkprof/ui.c
+++ b/bin/mkprof/ui.c
@@ -636,7 +636,7 @@ ui_check_options_and_arguments(struct mkprofparams *p)
 
 
   /* Set the necessary output names. */
-  d0f1=gal_checkset_dir_0_file_1(p->cp.output, p->cp.dontdelete);
+  d0f1=gal_checkset_dir_0_file_1(&p->cp, p->cp.output);
   if(d0f1)                        /* --output is a file name. */
     {
       p->mergedimgname=p->cp.output;
diff --git a/doc/announce-acknowledge.txt b/doc/announce-acknowledge.txt
index 991973ad..654805b2 100644
--- a/doc/announce-acknowledge.txt
+++ b/doc/announce-acknowledge.txt
@@ -2,6 +2,7 @@ Alphabetically ordered list to acknowledge in the next release.
 
 Sepideh Eskandarlou
 Giulia Golini
+Elham Saremi
 Michael Stein
 
 
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index c82eccc3..0bb1d33c 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -15654,6 +15654,13 @@ $ astcrop --mode=wcs --center=12h36m40.08,62d13m5.53 
goodsnorth.fits
 
 ## Crop region around pixel coordinate (568.342, 2091.719):
 $ astcrop --mode=img --center=568.342,2091.719 --width=201 image.fits
+
+## Crop all HDUs within a FITS file at a certain coordinate, while
+## preserving the names of the HDUs in the output.
+$ for hdu in $(astfits input.fits --listimagehdus); do \
+    astcrop input.fits --hdu=$$hdu --append --output=crop.fits \
+            --metaname=$$hdu --mode=wcs --center=189.16704,62.218203
+  done
 @end example
 
 @noindent
@@ -15743,6 +15750,11 @@ The number of values given to this option must be the 
same as the dimensions of
 The width of the crop should be set with @code{--width}.
 The units of the coordinates are read based on the value to the 
@option{--mode} option, see below.
 
+@item -O STR
+@itemx --mode=STR
+Mode to interpret the crop's coordinates (for example with @option{--center}, 
@option{--catalog} or @option{--polygon}).
+The value must either be @option{img} (to assume image/pixel coordinates) or 
@option{wcs} (to assume WCS, usually RA/Dec, coordinates), see @ref{Crop modes} 
for a full description.
+
 @item -w FLT[,FLT[,...]]
 @itemx --width=FLT[,FLT[,...]]
 Width of the cropped region about coordinate given to @option{--center}.
@@ -15891,72 +15903,6 @@ When this column is not given, the row number will be 
used instead.
 
 @end table
 
-@noindent
-Output options:
-@table @option
-
-@item -a STR
-@itemx --metaname=STR
-Name of cropped HDU (value to the @code{EXTNAME} keyword of FITS).
-If not given, a default @code{CROP} will be placed there (so the 
@code{EXTNAME} keyword will always be present in the output).
-If crop produces many outputs from a catalog, they will be given the same 
string as @code{EXTNAME} (the file names containing the cropped HDU will be 
different).
-
-@item -c FLT/INT
-@itemx --checkcenter=FLT/INT
-@cindex Check center of crop
-Square box width of region in the center of the image to check for blank 
values.
-If any of the pixels in this central region of a crop (defined by its center) 
are blank, then it will not be stored in an output file.
-If the value to this option is zero, no checking is done.
-This check is only applied when the cropped region(s) are defined by their 
center (not by the vertices, see @ref{Crop modes}).
-
-The units of the value are interpreted based on the @option{--mode} value (in 
WCS or pixel units).
-The ultimate checked region size (in pixels) will be an odd integer around the 
center (converted from WCS, or when an even number of pixels are given to this 
option).
-In WCS mode, the value can be given as fractions, for example, if the WCS 
units are in degrees, @code{0.1/3600} will correspond to a check size of 0.1 
arcseconds.
-
-Because survey regions do not often have a clean square or rectangle shape, 
some of the pixels on the sides of the survey FITS image do not commonly have 
any data and are blank (see @ref{Blank pixels}).
-So when the catalog was not generated from the input image, it often happens 
that the image does not have data over some of the points.
-
-When the given center of a crop falls in such regions or outside the dataset, 
and this option has a non-zero value, no crop will be created.
-Therefore with this option, you can specify a width of a small box (3 pixels 
is often good enough) around the central pixel of the cropped image.
-You can check which crops were created and which were not from the 
command-line (if @option{--quiet} was not called, see @ref{Operating mode 
options}), or in Crop's log file (see @ref{Crop output}).
-
-@item -p STR
-@itemx --suffix=STR
-The suffix (or post-fix) of the output files for when you want all the cropped 
images to have a special ending.
-One case where this might be helpful is when besides the science images, you 
want the weight images (or exposure maps, which are also distributed with 
survey images) of the cropped regions too.
-So in one run, you can set the input images to the science images and 
@option{--suffix=_s.fits}.
-In the next run you can set the weight images as input and 
@option{--suffix=_w.fits}.
-
-@item --primaryimghdu
-Write the output into the primary (0-th) HDU/extension of the output.
-By default, like all Gnuastro's default outputs, no data is written in the 
primary extension because the FITS standard suggests keeping that extension 
free of data and only for meta data.
-
-@item -b
-@itemx --noblank
-Pixels outside of the input image that are in the crop box will not be used.
-By default they are filled with blank values (depending on type), see 
@ref{Blank pixels}.
-This option only applies only in Image mode, see @ref{Crop modes}.
-
-@item -z
-@itemx --zeroisnotblank
-In float or double images, it is common to give the value of zero to blank 
pixels.
-If the input image type is one of these two types, such pixels will also be 
considered as blank.
-You can disable this behavior with this option, see @ref{Blank pixels}.
-
-@end table
-
-@noindent
-Operating mode options:
-@table @option
-
-@item -O STR
-@itemx --mode=STR
-Operate in Image mode or WCS mode when the input coordinates can be both image 
or WCS.
-The value must either be @option{img} or @option{wcs}, see @ref{Crop modes} 
for a full description.
-
-@end table
-
-
 
 
 
@@ -15982,6 +15928,9 @@ By default, as suggested by the FITS standard and 
implemented in all Gnuastro pr
 The cropped images/cubes will be written into the 2nd HDU of their respective 
FITS file (which is actually counted as @code{1} because HDU counting starts 
from @code{0}).
 However, if you want the cropped data to be written into the primary (0-th) 
HDU, run Crop with the @option{--primaryimghdu} option.
 
+If the output file already exists by default Crop will re-write it (so that 
all existing HDUs in it will be deleted).
+If you want the cropped HDU to be appended to existing HDUs, use 
@option{--append} described below.
+
 The header of each output cropped image will contain the names of the input 
image(s) it was cut from.
 If a name is longer than the 70 character space that the FITS standard allows 
for header keyword values, the name will be cut into several keywords from the 
nearest slash (@key{/}).
 The keywords have the following format: @command{ICFn_m} (for Crop File).
@@ -16009,6 +15958,29 @@ Instead, the single element's value is printed on the 
standard output.
 See the description of @option{--oneelemstdout} below for more:
 
 @table @option
+@item -p STR
+@itemx --suffix=STR
+The suffix (or post-fix) of the output files for when you want all the cropped 
images to have a special ending.
+One case where this might be helpful is when besides the science images, you 
want the weight images (or exposure maps, which are also distributed with 
survey images) of the cropped regions too.
+So in one run, you can set the input images to the science images and 
@option{--suffix=_s.fits}.
+In the next run you can set the weight images as input and 
@option{--suffix=_w.fits}.
+
+@item -a STR
+@itemx --metaname=STR
+Name of cropped HDU (value to the @code{EXTNAME} keyword of FITS).
+If not given, a default @code{CROP} will be placed there (so the 
@code{EXTNAME} keyword will always be present in the output).
+If crop produces many outputs from a catalog, they will be given the same 
string as @code{EXTNAME} (the file names containing the cropped HDU will be 
different).
+
+@item -A
+@itemx --append
+If the output file already exists, append the cropped image HDU to the end of 
any existing HDUs.
+By default (when this option isn't given), if an output file already exists, 
any exisitng HDU in it will be deleted.
+If the output file doesn't exist, this option is redundant.
+
+@item --primaryimghdu
+Write the output into the primary (0-th) HDU/extension of the output.
+By default, like all Gnuastro's default outputs, no data is written in the 
primary extension because the FITS standard suggests keeping that extension 
free of data and only for meta data.
+
 @item -t
 @itemx --oneelemstdout
 When a crop only has a single element (a single pixel), print it to the 
standard output instead of making a file.
@@ -16028,6 +16000,37 @@ Recall that Crop will do the crops in parallel, 
therefore each time you run it,
 
 To allow identification of each value (which row of the input catalog it 
corresponds to), Crop will first print the name of the would-be created file 
name, and print the value after it (separated by an empty SPACE character).
 In other words, the file in the first column will not actually be created, but 
the value of the pixel it would have contained (if this option was not called) 
is printed after it.
+
+@item -c FLT/INT
+@itemx --checkcenter=FLT/INT
+@cindex Check center of crop
+Square box width of region in the center of the image to check for blank 
values.
+If any of the pixels in this central region of a crop (defined by its center) 
are blank, then it will not be stored in an output file.
+If the value to this option is zero, no checking is done.
+This check is only applied when the cropped region(s) are defined by their 
center (not by the vertices, see @ref{Crop modes}).
+
+The units of the value are interpreted based on the @option{--mode} value (in 
WCS or pixel units).
+The ultimate checked region size (in pixels) will be an odd integer around the 
center (converted from WCS, or when an even number of pixels are given to this 
option).
+In WCS mode, the value can be given as fractions, for example, if the WCS 
units are in degrees, @code{0.1/3600} will correspond to a check size of 0.1 
arcseconds.
+
+Because survey regions do not often have a clean square or rectangle shape, 
some of the pixels on the sides of the survey FITS image do not commonly have 
any data and are blank (see @ref{Blank pixels}).
+So when the catalog was not generated from the input image, it often happens 
that the image does not have data over some of the points.
+
+When the given center of a crop falls in such regions or outside the dataset, 
and this option has a non-zero value, no crop will be created.
+Therefore with this option, you can specify a width of a small box (3 pixels 
is often good enough) around the central pixel of the cropped image.
+You can check which crops were created and which were not from the 
command-line (if @option{--quiet} was not called, see @ref{Operating mode 
options}), or in Crop's log file (see @ref{Crop output}).
+
+@item -b
+@itemx --noblank
+Pixels outside of the input image that are in the crop box will not be used.
+By default they are filled with blank values (depending on type), see 
@ref{Blank pixels}.
+This option only applies only in Image mode, see @ref{Crop modes}.
+
+@item -z
+@itemx --zeroisnotblank
+In float or double images, it is common to give the value of zero to blank 
pixels.
+If the input image type is one of these two types, such pixels will also be 
considered as blank.
+You can disable this behavior with this option, see @ref{Blank pixels}.
 @end table
 
 
@@ -18053,8 +18056,8 @@ With the command below, we will be masking all pixels 
that are 20 pixels away fr
 Here is a description of the command below (for the basics of Arithmetic's 
notation, see @ref{Reverse polish notation}):
 @itemize
 @item
-The @code{index} operator just adds a new dataset on the stack: unlike almost 
all other operators in Arithmetic, @code{index} doesn't remove the dataset 
within @file{image.fits} from the stack (use @code{indexonly} for the 
``normal'' behavior).
-This is because @code{index} is returns the pixel metadata not data.
+The @code{index} operator just adds a new dataset on the stack: unlike almost 
all other operators in Arithmetic, @code{index} doesn't remove its input 
dataset from the stack (use @code{indexonly} for the ``normal'' behavior).
+This is because @code{index} returns the pixel metadata not data.
 As a result, after @code{index}, we have two operands on the stack: the input 
image and the index image.
 @item
 With the @code{set-i} operator, the top operand (the image containing the 
index of each pixel) is popped from the stack and associated to the name 
@code{i}.
diff --git a/lib/checkset.c b/lib/checkset.c
index bf2948a1..04a8f940 100644
--- a/lib/checkset.c
+++ b/lib/checkset.c
@@ -774,7 +774,7 @@ gal_checkset_writable_remove(char *filename, int keep, int 
dontdelete)
    a directory) it will return 0. Finally, if it exists but cannot be
    deleted, report an error and abort. */
 int
-gal_checkset_dir_0_file_1(char *name, int dontdelete)
+gal_checkset_dir_0_file_1(struct gal_options_common_params *cp, char *name)
 {
   FILE *tmpfile;
   struct stat nameinfo;
@@ -813,7 +813,7 @@ gal_checkset_dir_0_file_1(char *name, int dontdelete)
     return 0;
   else if (S_ISREG(nameinfo.st_mode))  /* It is a file, GOOD. */
     {
-      gal_checkset_writable_remove(name, 0, dontdelete);
+      gal_checkset_writable_remove(name, cp->keep, cp->dontdelete);
       return 1;
     }
   else                                 /* Not a file or a dir, ABORT */
diff --git a/lib/gnuastro-internal/checkset.h b/lib/gnuastro-internal/checkset.h
index d3628e21..9093f7ca 100644
--- a/lib/gnuastro-internal/checkset.h
+++ b/lib/gnuastro-internal/checkset.h
@@ -127,7 +127,7 @@ void    /* keep==0 && dontdelete==0: file will be deleted 
if exists.*/
 gal_checkset_writable_remove(char *filename, int keep, int dontdelete);
 
 int
-gal_checkset_dir_0_file_1(char *name, int dontdelete);
+gal_checkset_dir_0_file_1(struct gal_options_common_params *cp, char *name);
 
 char *
 gal_checkset_automatic_output(struct gal_options_common_params *cp,



reply via email to

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