gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master db4c16d 076/125: Pulled in all the recent work


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master db4c16d 076/125: Pulled in all the recent work in master
Date: Sun, 23 Apr 2017 22:36:41 -0400 (EDT)

branch: master
commit db4c16dea8ad70ea621d8b0112bf9cc3e349605a
Merge: c315491 a5aeb7d
Author: Mohammad Akhlaghi <address@hidden>
Commit: Mohammad Akhlaghi <address@hidden>

    Pulled in all the recent work in master
    
    While work was ongoing on this development branch, several bugs and tasks
    were implemented in the main branch. The work was mainly in ImageCrop,
    which is next in-line to adopt the `gal_data_t' structure. So to make the
    final merging easier, this commits brings in all the work that was done
    there so far, so we can port ImageCrop to the new infra-structure with the
    added features and avoid messy cleaning up later.
---
 README-hacking                 |   2 +-
 THANKS                         |   2 +
 bin/convolve/args.h            |  33 ++-
 bin/convolve/astconvolve.conf  |   1 +
 bin/convolve/convolve.c        |  13 +-
 bin/convolve/main.h            |   3 +-
 bin/convolve/ui.c              |  21 +-
 bin/imgcrop/args.h             |  17 +-
 bin/imgcrop/astimgcrop.conf    |   4 +-
 bin/imgcrop/crop.c             | 172 ++++++------
 bin/imgcrop/crop.h             |   3 +-
 bin/imgcrop/imgcrop.c          |  42 +--
 bin/imgcrop/main.h             |   1 +
 bin/imgcrop/ui.c               |  23 +-
 bin/imgcrop/wcsmode.c          |  44 ++--
 bin/imgwarp/astimgwarp.conf    |   1 -
 bin/imgwarp/imgwarp.c          |   9 +-
 bin/imgwarp/ui.c               | 100 ++++---
 bootstrapped/README            |   6 +-
 doc/gnuastro.texi              | 585 ++++++++++++++++++++++++-----------------
 genauthors                     |   3 +-
 lib/checkset.h                 |   5 +
 lib/fits.c                     |   4 +
 lib/gnuastro/wcs.h             |   9 +-
 lib/wcs.c                      | 191 ++++++++++++--
 tests/imgcrop/imgoutpolygon.sh |   2 +-
 26 files changed, 804 insertions(+), 492 deletions(-)

diff --git a/README-hacking b/README-hacking
index eecc47c..b49b2f4 100644
--- a/README-hacking
+++ b/README-hacking
@@ -86,7 +86,7 @@ you cloned 'gnuastro' directory.
 The recommended way is to clone Gnulib and the Autoconf archives separately
 (see above), then tell the script where to look for them. You will not need
 an internet connection every time you decide to bootstrap, your 'gnuastro'
-directory will be much more cleaner, and if your other packages or projects
+directory will be much cleaner, and if your other packages or projects
 need these tools, you won't need to have multiple copies. Note that during
 development, sometimes it can be convenient to remove all non-version
 controlled files.
diff --git a/THANKS b/THANKS
index ecf94b3..b1d13c7 100644
--- a/THANKS
+++ b/THANKS
@@ -21,6 +21,7 @@ support in Gnuastro. The list is ordered alphabetically.
     Antonio Diaz Diaz                    address@hidden
     Takashi Ichikawa                     address@hidden
     Brandon Invergo                      address@hidden
+    Lee Kelvin                           address@hidden
     Mohammad-Reza Khellat                address@hidden
     Alan Lefor                           address@hidden
     Francesco Montanari                  address@hidden
@@ -29,6 +30,7 @@ support in Gnuastro. The list is ordered alphabetically.
     Richard Stallman                     address@hidden
     Ole Streicher                        address@hidden
     David Valls-Gabaud                   address@hidden
+    Christopher Willmer                  address@hidden
 
 
 Institutions
diff --git a/bin/convolve/args.h b/bin/convolve/args.h
index 6e8f335..53317b5 100644
--- a/bin/convolve/args.h
+++ b/bin/convolve/args.h
@@ -55,7 +55,7 @@ const char doc[] =
 
 /* Free letters for options:
 
-   c d e g i j l n r t u w x y z
+   d e g i j l n r t u w x y z
    A B C E F G H I J O Q R T W X Y Z
 
    Free numbers: >=504
@@ -115,6 +115,15 @@ static struct argp_option options[] =
       "Do not normalize the kernel image.",
       1
     },
+    {
+      "minsharpspec",
+      'c',
+      "FLT",
+      0,
+      "Deconvolution: min spectrum of sharp img.",
+      1
+    },
+
 
 
 
@@ -273,7 +282,8 @@ parse_opt(int key, char *arg, struct argp_state *state)
 
     /* Inputs: */
     case 'M':
-      gal_checkset_allocate_copy_set(arg, &p->up.maskname, &p->up.masknameset);
+      gal_checkset_allocate_copy_set(arg, &p->up.maskname,
+                                     &p->up.masknameset);
       break;
     case 'H':
       gal_checkset_allocate_copy_set(arg, &p->up.mhdu, &p->up.mhduset);
@@ -291,6 +301,11 @@ parse_opt(int key, char *arg, struct argp_state *state)
     case 501:
       p->kernelnorm=0;
       break;
+    case 'c':
+      gal_checkset_double_l_0_s_1(arg, &p->minsharpspec, "minsharpspec",
+                                 key, SPACK, NULL, 0);
+      p->up.minsharpspecset=1;
+      break;
 
 
     /* Output: */
@@ -298,21 +313,23 @@ parse_opt(int key, char *arg, struct argp_state *state)
 
    /* Mesh grid: */
     case 's':
-      gal_checkset_sizet_l_zero(arg, &p->mp.meshsize, "meshsize", key, SPACK,
-                                NULL, 0);
+      gal_checkset_sizet_l_zero(arg, &p->mp.meshsize, "meshsize", key,
+                                SPACK, NULL, 0);
       p->up.meshsizeset=1;
       break;
     case 'a':
-      gal_checkset_sizet_l_zero(arg, &p->mp.nch1, "nch1", key, SPACK, NULL, 0);
+      gal_checkset_sizet_l_zero(arg, &p->mp.nch1, "nch1", key, SPACK,
+                                NULL, 0);
       p->up.nch1set=1;
       break;
     case 'b':
-      gal_checkset_sizet_l_zero(arg, &p->mp.nch2, "nch2", key, SPACK, NULL, 0);
+      gal_checkset_sizet_l_zero(arg, &p->mp.nch2, "nch2", key, SPACK,
+                                NULL, 0);
       p->up.nch2set=1;
       break;
     case 'L':
-      gal_checkset_float_l_0_s_1(arg, &p->mp.lastmeshfrac, "lastmeshfrac", key,
-                                 SPACK, NULL, 0);
+      gal_checkset_float_l_0_s_1(arg, &p->mp.lastmeshfrac, "lastmeshfrac",
+                                 key, SPACK, NULL, 0);
       p->up.lastmeshfracset=1;
       break;
     case 503:
diff --git a/bin/convolve/astconvolve.conf b/bin/convolve/astconvolve.conf
index 79169c9..fb06348 100644
--- a/bin/convolve/astconvolve.conf
+++ b/bin/convolve/astconvolve.conf
@@ -21,6 +21,7 @@
  spatial            0
  frequency          1
  makekernel         0
+ minsharpspec       0.005
 
 # Input:
  hdu                0
diff --git a/bin/convolve/convolve.c b/bin/convolve/convolve.c
index e372239..45284ec 100644
--- a/bin/convolve/convolve.c
+++ b/bin/convolve/convolve.c
@@ -118,9 +118,8 @@ complexarraymultiply(double *a, double *b, size_t size)
 
 
 
-/* Divide the elements of the first array by the elements of the
-   second array and put the result into the elements of the first
-   array.
+/* Divide the elements of the first array by the elements of the second
+   array and put the result into the elements of the first array.
 
    (a+ib)/(c+id)=[(a+ib)*(c-id)]/[(c+id)*(c-id)]
                 =(ac-iad+ibc+bd)/(c^2+d^2)
@@ -130,14 +129,14 @@ complexarraymultiply(double *a, double *b, size_t size)
    on the loop.
  */
 void
-complexarraydivide(double *a, double *b, size_t size)
+complexarraydivide(double *a, double *b, size_t size, double minsharpspec)
 {
   double r, *af;
 
   af=a+2*size;
   do
     {
-      if (sqrt(*b**b + *(b+1)**(b+1))>MINGOODDIVSPEC)
+      if (sqrt(*b**b + *(b+1)**(b+1))>minsharpspec)
         {
           r      = ( ( (*a * *b) + (*(a+1) * *(b+1)) )
                      / ( *b * *b + *(b+1) * *(b+1) ) );
@@ -145,6 +144,8 @@ complexarraydivide(double *a, double *b, size_t size)
                      / ( *b * *b + *(b+1) * *(b+1) ) );
           *a=r;
 
+          /* Just as a sanity check (the result should never be larger than
+             one. */
           if(sqrt(*a**a + *(a+1)**(a+1))>1.00001f)
             *a=*(a+1)=0.0f;
         }
@@ -679,7 +680,7 @@ frequencyconvolve(struct convolveparams *p)
   if(verb) gettimeofday(&t1, NULL);
   if(p->makekernel)
     {
-      complexarraydivide(p->pimg, p->pker, p->ps0*p->ps1);
+      complexarraydivide(p->pimg, p->pker, p->ps0*p->ps1, p->minsharpspec);
       if(verb)
         gal_timing_report(&t1, "Divided in the frequency domain.", 1);
     }
diff --git a/bin/convolve/main.h b/bin/convolve/main.h
index 7cb25d0..d5158e5 100644
--- a/bin/convolve/main.h
+++ b/bin/convolve/main.h
@@ -39,7 +39,6 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
-#define MINGOODDIVSPEC       0.005
 #define CONVFLOATINGPOINTERR 1e-10
 #define COMPLEXTOREALSPEC    1  /* Spectrum of complex number.  */
 #define COMPLEXTOREALPHASE   2  /* Phase of the complex number. */
@@ -63,6 +62,7 @@ struct uiparams
   int            mhduset;
   int      kernelnameset;
   int            khduset;
+  int    minsharpspecset;
   int        meshsizeset;
   int            nch1set;
   int            nch2set;
@@ -90,6 +90,7 @@ struct convolveparams
   size_t             is1;   /* Input image size along C's second axis.  */
   size_t             ks0;   /* Kernel size along C's first axis.        */
   size_t             ks1;   /* Kernel size along C's second axis.       */
+  double    minsharpspec;   /* Deconvolution: min spectrum of sharp img.*/
   int         kernelflip;   /* ==1: Flip the kernel.                    */
   int         kernelnorm;   /* ==1: Normalize the kernel.               */
   int               nwcs;   /* Number of WCS headers.                   */
diff --git a/bin/convolve/ui.c b/bin/convolve/ui.c
index 6b57113..0d65275 100644
--- a/bin/convolve/ui.c
+++ b/bin/convolve/ui.c
@@ -110,7 +110,13 @@ readconfig(char *filename, struct convolveparams *p)
                                        &up->kernelnameset);
       else if (strcmp(name, "khdu")==0)
         gal_checkset_allocate_copy_set(value, &up->khdu, &up->khduset);
-
+      else if(strcmp(name, "minsharpspec")==0)
+        {
+          if(up->minsharpspecset) continue;
+          gal_checkset_double_l_0_s_1(value, &p->minsharpspec, "minsharpspec",
+                                     key, SPACK, filename, lineno);
+          up->minsharpspecset=1;
+        }
 
 
       /* Outputs: */
@@ -243,6 +249,8 @@ printvalues(FILE *fp, struct convolveparams *p)
     GAL_CHECKSET_PRINT_STRING_MAYBE_WITH_SPACE("kernel", up->kernelname);
   if(up->khduset)
     GAL_CHECKSET_PRINT_STRING_MAYBE_WITH_SPACE("khdu", up->khdu);
+  if(up->minsharpspecset)
+    fprintf(fp, CONF_SHOWFMT"%f\n", "minsharpspec", p->minsharpspec);
 
 
 
@@ -298,6 +306,8 @@ checkifset(struct convolveparams *p)
     GAL_CONFIGFILES_REPORT_NOTSET("kernel");
   if(up->khduset==0)
     GAL_CONFIGFILES_REPORT_NOTSET("khdu");
+  if(p->makekernel && up->minsharpspecset==0)
+    GAL_CONFIGFILES_REPORT_NOTSET("minsharpspec");
 
 
   /* Mesh grid: */
@@ -447,14 +457,15 @@ preparearrays(struct convolveparams *p)
             "pixels' section of the Gnuastro manual for more information.");
 
 
-  /* Read the file specified by --kernel. If makekernel is specified,
-     then this is actually the low resolution image. */
+  /* Read the file specified by --kernel. If makekernel is specified, then
+     this is actually the sharper image and the input image (given as an
+     argument) is the blurry image. */
   if(p->makekernel)
     {
       /* Read in the kernel array: */
       gal_fits_file_to_float(up->kernelname, NULL, up->khdu, NULL,
-                                  &p->kernel, &bitpix, &anyblank,
-                                  &p->ks0, &p->ks1);
+                             &p->kernel, &bitpix, &anyblank,
+                             &p->ks0, &p->ks1);
       if(p->ks0!=p->is0 || p->ks1!=p->is1)
         error(EXIT_FAILURE, 0, "with the `--makekernel' (`-m') option, "
               "the input image and the image specified with the kernel "
diff --git a/bin/imgcrop/args.h b/bin/imgcrop/args.h
index cb670e3..1f75a1e 100644
--- a/bin/imgcrop/args.h
+++ b/bin/imgcrop/args.h
@@ -73,7 +73,7 @@ const char doc[] =
 
 /* Available letters for short options:
 
-   e m n t u v
+   e k m n t u v
    A B C E F G H J L M O Q R T U X Y Z
 
    Number keys used<=502
@@ -150,14 +150,6 @@ static struct argp_option options[] =
       2
     },
     {
-      "keepblankcenter",
-      'k',
-      0,
-      0,
-      "Keep crop if the central parts are not filled.",
-      2
-    },
-    {
       "checkcenter",
       'c',
       "INT",
@@ -374,12 +366,9 @@ parse_opt(int key, char *arg, struct argp_state *state)
     case 'b':
       p->noblank=1;
       break;
-    case 'k':
-      p->keepblankcenter=1;
-      break;
     case 'c':
-      gal_checkset_sizet_l_zero(arg, &p->checkcenter, "checkcenter",
-                                key, SPACK, NULL, 0);
+      gal_checkset_sizet_el_zero(arg, &p->checkcenter, "checkcenter",
+                                 key, SPACK, NULL, 0);
       p->up.checkcenterset=1;
       break;
     case 'p':
diff --git a/bin/imgcrop/astimgcrop.conf b/bin/imgcrop/astimgcrop.conf
index fcdfbb6..c2fb09b 100644
--- a/bin/imgcrop/astimgcrop.conf
+++ b/bin/imgcrop/astimgcrop.conf
@@ -33,5 +33,5 @@
  hendwcs        0
 
 # Output parameters:
- checkcenter    3
- suffix        _crop.fits
+ checkcenter    0
+ suffix        _cropped.fits
diff --git a/bin/imgcrop/crop.c b/bin/imgcrop/crop.c
index 60f9b53..1f0f5d1 100644
--- a/bin/imgcrop/crop.c
+++ b/bin/imgcrop/crop.c
@@ -71,20 +71,24 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 /* Read the section string and set the starting and ending pixels
    based on that. */
 void
-sectionparser(char *section, long *naxes, long *fpixel, long *lpixel)
+sectionparser(struct imgcropparams *p, long *naxes,
+              long *fpixel, long *lpixel)
 {
   int add;
   long read;
   size_t dim=0;
   char *tailptr;
-  char forl='f', *pt=section;
+  char forl='f', *pt=p->section;
+
+  /* If control reached here, then the cropped region is not defined by its
+     center. So it makes no sense to check if the center is blank. */
+  p->checkcenter=0;
 
   /* Initialize the fpixel and lpixel arrays: */
   lpixel[0]=naxes[0];
   lpixel[1]=naxes[1];
   fpixel[0]=fpixel[1]=1;
 
-
   /* Parse the string. */
   while(*pt!='\0')
     {
@@ -94,7 +98,7 @@ sectionparser(char *section, long *naxes, long *fpixel, long 
*lpixel)
         case ',':
           ++dim;
           if(dim==2)
-            error(EXIT_FAILURE, 0, "Extra `,` in `%s`", section);
+            error(EXIT_FAILURE, 0, "Extra `,` in `%s`", p->section);
           forl='f';
           ++pt;
           break;
@@ -105,8 +109,7 @@ sectionparser(char *section, long *naxes, long *fpixel, 
long *lpixel)
         case '.':
           error(EXIT_FAILURE, 0, "the numbers in the argument to "
                 "`--section` (`-s') have to be integers. You input "
-                "includes a float number: %s",
-                section);
+                "includes a float number: %s", p->section);
           break;
         case ' ': case '\t':
           ++pt;
@@ -127,7 +130,7 @@ sectionparser(char *section, long *naxes, long *fpixel, 
long *lpixel)
       */
 
       /* Make sure if a number was read at all? */
-      if(tailptr==pt)                /* No number was read!             */
+      if(tailptr==pt)           /* No number was read!                 */
         {
           if(add) read=0;       /* We have a * followed by `:' or `,'. */
           else    continue;
@@ -141,7 +144,7 @@ sectionparser(char *section, long *naxes, long *fpixel, 
long *lpixel)
       if(forl=='f')
         fpixel[dim] = add ? naxes[dim]+read : read;
       else
-        lpixel[dim] = add ? naxes[dim]+read-1 : read-1;
+        lpixel[dim] = add ? naxes[dim]+read : read;
       pt=tailptr;
 
       /* For a check:
@@ -151,12 +154,13 @@ sectionparser(char *section, long *naxes, long *fpixel, 
long *lpixel)
       */
     }
 
-  if(fpixel[0]>=lpixel[0] || fpixel[1]>=lpixel[1])
+  /* Make sure the first pixel is located before/below the last pixel. */
+  if(fpixel[0]>lpixel[0] || fpixel[1]>lpixel[1])
     error(EXIT_FAILURE, 0, "the bottom left corner coordinates "
           "cannot be larger or equal to the top right's! Your section "
           "string (%s) has been read as: bottom left coordinate "
           "(%ld, %ld) to top right coordinate (%ld, %ld)",
-          section, fpixel[0], fpixel[1], lpixel[0], lpixel[1]);
+          p->section, fpixel[0], fpixel[1], lpixel[0], lpixel[1]);
 
   /*
   printf("\n%s\nfpixel=(%ld, %ld), lpixel=(%ld, %ld)\n\n", section,
@@ -179,6 +183,10 @@ polygonparser(struct imgcropparams *p)
   struct gal_linkedlist_tdll *gal_linkedlist_tdll=NULL;
   char *pt=p->up.polygon;
 
+  /* If control reached here, then the cropped region is not defined by its
+     center. So it makes no sense to check if the center is blank. */
+  p->checkcenter=0;
+
   /* Parse the string. */
   while(*pt!='\0')
     {
@@ -222,6 +230,18 @@ polygonparser(struct imgcropparams *p)
             error(EXIT_FAILURE, 0, "%s could not be parsed as a floating "
                   "point number", tailptr);
 
+          /* Check if there are no extra characters in the number, for
+             example we don't have a case like `1.00132.17', or
+             1.01i:2.0. Such errors are not uncommon when typing large
+             numbers, and if ignored, they can lead to unpredictable
+             results, so its best to abort and inform the user. */
+          if( *tailptr!='\0'
+              && !isspace(*tailptr)
+              && strchr(":,", *tailptr)==NULL )
+            error(EXIT_FAILURE, 0, "'%s' is an invalid floating point number "
+                  "sequence in the value to the `--polygon' option, error "
+                  "detected at '%s'", pt, tailptr);
+
           /* If this was the second dimension, then put the values
              into the linked list: */
           if(dim==1)
@@ -501,8 +521,8 @@ cropname(struct cropparams *crp)
 void
 cropflpixel(struct cropparams *crp)
 {
-  int ncoord=1, nelem=2, status;
   struct imgcropparams *p=crp->p;
+  int ncoord=1, nelem=2, status[2]={0,0};
   long *naxes=p->imgs[crp->imgindex].naxes;
   double pixcrd[2], imgcrd[2], phi[1], theta[1];
   long *fpixel=crp->fpixel, *lpixel=crp->lpixel;
@@ -516,7 +536,7 @@ cropflpixel(struct cropparams *crp)
       else if(p->up.xcset)
         gal_box_border_from_center(p->xc, p->yc, p->iwidth, fpixel, lpixel);
       else if(p->up.sectionset)
-        sectionparser(p->section, naxes, fpixel, lpixel);
+        sectionparser(p, naxes, fpixel, lpixel);
       else if(p->up.polygonset)
         {
           if(p->outpolygon==0)
@@ -540,11 +560,12 @@ cropflpixel(struct cropparams *crp)
         }
       else
         {
-          status=0;
           if(wcss2p(p->imgs[crp->imgindex].wcs, ncoord, nelem, crp->world,
-                    phi, theta, imgcrd, pixcrd, &status) )
-            error(EXIT_FAILURE, 0, "wcss2p error %d: %s", status,
-                  wcs_errmsg[status]);
+                    phi, theta, imgcrd, pixcrd, status) )
+            if(status[0] || status[1])
+              error(EXIT_FAILURE, 0, "wcss2p error %d: %s",
+                    status[0] ? status[0] : status[1],
+                    wcs_errmsg[status[0] ? status[0] : status[1]]);
           gal_box_border_from_center(pixcrd[0], pixcrd[1], p->iwidth, fpixel,
                                      lpixel);
           /*
@@ -756,8 +777,8 @@ onecrop(struct cropparams *crp)
       sprintf(basename, "ICF%zu", ++p->log[crp->outindex].numimg);
       gal_fits_file_name_in_keywords(basename, img->name, &headers);
       sprintf(regionkey, "%sPIX", basename);
-      sprintf(region, "%ld:%ld,%ld:%ld", fpixel_i[0], lpixel_i[0]+1,
-              fpixel_i[1], lpixel_i[1]+1);
+      sprintf(region, "%ld:%ld,%ld:%ld", fpixel_i[0], lpixel_i[0],
+              fpixel_i[1], lpixel_i[1]);
       gal_fits_add_to_key_ll_end(&headers, TSTRING, regionkey, 0, region, 0,
                                  "Range of pixels used for this output.", 0,
                                  NULL);
@@ -802,88 +823,48 @@ iscenterfilled(struct cropparams *crp)
 {
   struct imgcropparams *p=crp->p;
 
+  size_t size;
   void *array;
-  int bitpix=p->bitpix;
-  size_t size, nulcount;
   fitsfile *ofp=crp->outfits;
-  int status=0, maxdim=10, anynul;
   long checkcenter=p->checkcenter;
+  int status=0, anynul=0, tmp_bitpix;
   long naxes[2], fpixel[2], lpixel[2], inc[2]={1,1};
 
-  uint8_t *b, *fb, *nb;
-  int16_t *s, *fs, *ns;
-  int32_t *l, *fl, *nl;
-  int64_t *L, *fL, *nL;
-  float   *f, *ff; /* isnan will check. */
-  double  *d, *fd; /* isnan will check */
+  /* If checkcenter is zero, then don't check. */
+  if(checkcenter==0) return CENTER_NOT_CHECKED;
 
   /* Get the final size of the output image. */
-  if( fits_get_img_size(ofp, maxdim, naxes, &status) )
-    gal_fits_io_error(status, NULL);
+  gal_fits_img_bitpix_size(ofp, &tmp_bitpix, naxes);
 
   /* Get the size and range of the central region to check. The +1 is
-     because in FITS, counting begins from 1, not zero. */
-  fpixel[0]=(naxes[0]/2+1)-checkcenter/2;
-  fpixel[1]=(naxes[1]/2+1)-checkcenter/2;
-  lpixel[0]=(naxes[0]/2+1)+checkcenter/2;
-  lpixel[1]=(naxes[1]/2+1)+checkcenter/2;
+     because in FITS, counting begins from 1, not zero. It might happen
+     that the image is actually smaller than the width to check the center
+     (for example 1 or 2 pixels wide). In that case, we'll just use the
+     full image to check. */
+  size = ( (naxes[0]>checkcenter ? checkcenter : naxes[0])
+           * (naxes[1]>checkcenter ? checkcenter : naxes[1]) );
+  fpixel[0] = naxes[0]>checkcenter ? (naxes[0]/2+1)-checkcenter/2 : 1;
+  fpixel[1] = naxes[1]>checkcenter ? (naxes[1]/2+1)-checkcenter/2 : 1;
+  lpixel[0] = naxes[0]>checkcenter ? (naxes[0]/2+1)+checkcenter/2 : naxes[0];
+  lpixel[1] = naxes[1]>checkcenter ? (naxes[1]/2+1)+checkcenter/2 : naxes[1];
+
+  /* For a check:
+  printf("naxes: %ld, %ld\nfpixel: (%ld, %ld)\nlpixel: (%ld, %ld)\n"
+         "size: %zu\n", naxes[0], naxes[1], fpixel[0], fpixel[1],
+         lpixel[0], lpixel[1], size);
+  */
 
   /* Allocate the array and read in the pixels. */
-  size=checkcenter*checkcenter;
   array=gal_data_alloc(gal_fits_bitpix_to_type(bitpix), size);
   if( fits_read_subset(ofp, p->datatype, fpixel, lpixel, inc,
                        p->bitnul, array, &anynul, &status) )
     gal_fits_io_error(status, NULL);
-
-  /* Depending on bitpix, check the central pixels of the image. */
-  nulcount=0;
-  switch(bitpix)
-    {
-    case BYTE_IMG:
-      nb=p->bitnul;
-      fb=(b=array)+size;
-      do if(*b==*nb) ++nulcount; while(++b<fb);
-      break;
-
-    case SHORT_IMG:
-      ns=p->bitnul;
-      fs=(s=array)+size;
-      do if(*s==*ns) ++nulcount; while(++s<fs);
-      break;
-
-    case LONG_IMG:
-      nl=p->bitnul;
-      fl=(l=array)+size;
-      do if(*l==*nl) ++nulcount; while(++l<fl);
-      break;
-
-    case LONGLONG_IMG:
-      nL=p->bitnul;
-      fL=(L=array)+size;
-      do if(*L==*nL) ++nulcount; while(++L<fL);
-      break;
-
-    case FLOAT_IMG:
-      ff=(f=array)+size;
-      do if(isnan(*f)) ++nulcount; while(++f<ff);
-      break;
-
-    case DOUBLE_IMG:
-      fd=(d=array)+size;
-      do if(isnan(*d)) ++nulcount; while(++d<fd);
-      break;
-
-    default:
-      error(EXIT_FAILURE, 0, "in iscenterfilled, the bitbix is not "
-            "recognized! This is not possible by the user, so it is a "
-            "a bug. Please contact us so we can correct it");
-    }
   free(array);
 
-  if(nulcount==size)
-    return 0;
-  else
-    return 1;
+  /* CFITSIO already checks if there are any blank pixels. If there are,
+     then `anynul' will be 1, if there aren't it will be 0. So the output
+     of this function is just the inverse of that number. */
+  return !anynul;
 }
 
 
@@ -912,8 +893,8 @@ printlog(struct imgcropparams *p)
 {
   size_t i;
   FILE *logfile;
-  char msg[GAL_TIMING_VERB_MSG_LENGTH_V];
   struct imgcroplog *log=p->log;
+  char msg[GAL_TIMING_VERB_MSG_LENGTH_V];
   size_t numfiles=0, numcentfilled=0, numstitched=0;
 
   /* Only for a catalog are these statistics worth it! */
@@ -921,7 +902,7 @@ printlog(struct imgcropparams *p)
     for(i=0;log[i].name;++i)
       if(log[i].numimg)
         {
-          if(log[i].centerfilled || p->keepblankcenter)
+          if(log[i].centerfilled)
             {
               ++numfiles;
               if(log[i].numimg>1)
@@ -947,16 +928,19 @@ printlog(struct imgcropparams *p)
               "# "SPACK_STRING" log file.\n"
               "# "SPACK_NAME" was run on %s#\n",
               ctime(&p->rawtime));
-      if(p->keepblankcenter==0)
-        fprintf(logfile, "# NOTE: by default images with a blank "
-                "center are deleted.\n# To keep such images, run again "
-                "with `--keepblankcenter`.\n#\n");
+      if(p->checkcenter)
+        fprintf(logfile,
+                "# The central %zu pixels were checked for blank values.\n"
+                "# NOTE: by default when the crops are defined by "
+                "their center,\n"
+                "# crops with a blank center are deleted.\n"
+                "# To keep such images, run again with `--checkcenter=0`.\n"
+                "#\n", p->checkcenter);
       fprintf(logfile,
-              "# Column numbers below start from zero.\n"
-              "# 0: Output file name.\n"
-              "# 1: Number of images used in this cropped image.\n"
-              "# 2: Are the central %zu pixels filled? (1: yes, 0: no)\n",
-              p->checkcenter);
+              "# Column 1: Output file name.\n"
+              "# Column 2: Number of images used in this cropped image.\n"
+              "# Column 3: Are the central pixels filled? (1: yes, 0: no, "
+              "%d: not checked)\n", CENTER_NOT_CHECKED);
 
       /* Then print each output's information. */
       for(i=0;log[i].name;++i)
diff --git a/bin/imgcrop/crop.h b/bin/imgcrop/crop.h
index 29c3fb6..908e87c 100644
--- a/bin/imgcrop/crop.h
+++ b/bin/imgcrop/crop.h
@@ -59,7 +59,8 @@ void
 polygonparser(struct imgcropparams *p);
 
 void
-sectionparser(char *section, long *naxes, long *fpixel, long *lpixel);
+sectionparser(struct imgcropparams *p, long *naxes,
+              long *fpixel, long *lpixel);
 
 void
 cropname(struct cropparams *crp);
diff --git a/bin/imgcrop/imgcrop.c b/bin/imgcrop/imgcrop.c
index ea358a8..61055d3 100644
--- a/bin/imgcrop/imgcrop.c
+++ b/bin/imgcrop/imgcrop.c
@@ -55,18 +55,26 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 void
 reportcrop(struct imgcroplog *log)
 {
+  char *filestatus, *msg;
   size_t outnamelen=strlen(log->name);;
-  char msg[GAL_TIMING_VERB_MSG_LENGTH_V];
+
+  /* Human readable values. */
+  filestatus = ( log->centerfilled==0
+                 ? "not created (blank center)" : "created");
 
   /* Define the output string based on the length of the output file. */
   if ( outnamelen > FILENAME_BUFFER_IN_VERB )
-    sprintf(msg, "...%s %zu %d",
+    asprintf(&msg, "...%s %s from %zu input%s.",
             &log->name[ outnamelen - FILENAME_BUFFER_IN_VERB + 3 ],
-            log->numimg, log->centerfilled);
+            filestatus, log->numimg, log->numimg > 1 ? "s" : "");
   else
-    sprintf(msg, "%-" MACROSTR(FILENAME_BUFFER_IN_VERB) "s %zu %d",
-            log->name, log->numimg, log->centerfilled);
+    asprintf(&msg, "%-" MACROSTR(FILENAME_BUFFER_IN_VERB) "s %s from %zu "
+             "input%s.", log->name, filestatus, log->numimg,
+             log->numimg > 1 ? "s" : "");
+
+  /* Print the results. */
   gal_timing_report(NULL, msg, 2);
+  free(msg);
 }
 
 
@@ -120,7 +128,7 @@ imgmodecrop(void *inparam)
                                    "the opened file");
 
           /* Remove the output image if its center was not filled. */
-          if(log->centerfilled==0 && p->keepblankcenter==0)
+          if(log->centerfilled==0)
             {
               errno=0;
               if(unlink(log->name))
@@ -207,7 +215,7 @@ wcsmodecrop(void *inparam)
             gal_fits_io_error(status, "CFITSIO could not close the "
                                      "opened file");
 
-          if(log->centerfilled==0 && p->keepblankcenter==0)
+          if(log->centerfilled==0)
             {
               errno=0;
               if(unlink(log->name))
@@ -230,11 +238,9 @@ wcsmodecrop(void *inparam)
       if(p->cp.verb) reportcrop(log);
     }
 
-  /* Wait until all other threads finish. */
+  /* Wait until all other threads finish, then return. */
   if(p->cp.numthreads>1)
     pthread_barrier_wait(crp->b);
-
-
   return NULL;
 }
 
@@ -286,8 +292,8 @@ imgcrop(struct imgcropparams *p)
           "neither the imgmode is on or the wcsmode! Please contact us "
           "so we can fix it, thanks");
 
-  /* Allocate the arrays to keep the thread and parameters for each
-     thread. */
+  /* Allocate the array of structures to keep the thread and parameters for
+     each thread. */
   errno=0;
   crp=malloc(nt*sizeof *crp);
   if(crp==NULL)
@@ -303,10 +309,9 @@ imgcrop(struct imgcropparams *p)
 
   /* Distribute the indexs into the threads (this is needed even if we
      only have one object where p->cs0 is not defined): */
-  if(p->up.catset)
-    gal_threads_dist_in_threads(p->cs0, nt, &indexs, &thrdcols);
-  else
-    gal_threads_dist_in_threads(1, nt, &indexs, &thrdcols);
+  gal_threads_dist_in_threads(p->up.catset ? p->cs0 : 1, nt,
+                              &indexs, &thrdcols);
+
 
   /* Run the job, if there is only one thread, don't go through the
      trouble of spinning off a thread! */
@@ -345,10 +350,13 @@ imgcrop(struct imgcropparams *p)
       pthread_barrier_destroy(&b);
     }
 
+
   /* Print the log file: */
-  if(p->cp.nolog==0)
+  if(!p->cp.nolog)
     printlog(p);
 
+
+  /* Clean up. */
   free(crp);
   free(indexs);
 }
diff --git a/bin/imgcrop/main.h b/bin/imgcrop/main.h
index 1096bbd..8e92004 100644
--- a/bin/imgcrop/main.h
+++ b/bin/imgcrop/main.h
@@ -51,6 +51,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #define STRINGIFY(x) #x
 #define MACROSTR(x) STRINGIFY(x)
 #define FILENAME_BUFFER_IN_VERB 30
+#define CENTER_NOT_CHECKED      -1
 
 
 
diff --git a/bin/imgcrop/ui.c b/bin/imgcrop/ui.c
index 8346167..818449e 100644
--- a/bin/imgcrop/ui.c
+++ b/bin/imgcrop/ui.c
@@ -29,6 +29,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <string.h>
 #include <fitsio.h>
 
+#include <gnuastro/wcs.h>
 #include <gnuastro/fits.h>
 #include <gnuastro/txtarray.h>
 
@@ -362,23 +363,17 @@ sanitycheck(struct imgcropparams *p)
   struct gal_commonparams *cp=&p->cp;
 
 
-
-  /* checkcenter is odd: */
-  if(p->checkcenter%2==0)
-    p->checkcenter+=1;
-
-
-
   /* Width and checkcenter are odd */
   if(p->iwidth[0]<3)
     error(EXIT_FAILURE, 0, "--iwidth has to be 3 or more pixels");
   else if(p->iwidth[0]%2==0)
-      p->iwidth[0]+=1;
+    error(EXIT_FAILURE, 0, "the given value to `iwidth' (%ld) has to "
+          "be an odd number (the pixel corresponding to the desired "
+          "coordinate to be in the center)", p->iwidth[0]);
   p->iwidth[1]=p->iwidth[0];
-  if(p->checkcenter<3)
-    error(EXIT_FAILURE, 0, "--checkcenter has to be 3 or more pixels");
-  else if(p->checkcenter%2==0)
-    p->checkcenter+=1;
+  if(p->checkcenter && p->checkcenter%2==0)
+    error(EXIT_FAILURE, 0, "`checkcenter' has to be an odd number. The "
+          "current value is %zu", p->checkcenter);
 
 
 
@@ -614,6 +609,7 @@ preparearrays(struct imgcropparams *p)
                                      p->hstartwcs, p->hendwcs);
       if(img->wcs)
         {
+          gal_wcs_decompose_pc_cdelt(img->wcs);
           status=wcshdo(0, img->wcs, &img->nwcskeys, &img->wcstxt);
           if(status)
             error(EXIT_FAILURE, 0, "wcshdo ERROR %d: %s", status,
@@ -666,7 +662,8 @@ preparearrays(struct imgcropparams *p)
   /* Report timing: */
   if(p->cp.verb)
     {
-      sprintf(msg, "Read metadata of %zu images.", p->numimg);
+      sprintf(msg, "Read metadata of %zu image%s.", p->numimg,
+              p->numimg>1 ? "s" : "");
       gal_timing_report(&t1, msg, 1);
     }
 }
diff --git a/bin/imgcrop/wcsmode.c b/bin/imgcrop/wcsmode.c
index 6d91135..d572e2a 100644
--- a/bin/imgcrop/wcsmode.c
+++ b/bin/imgcrop/wcsmode.c
@@ -50,9 +50,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 void
 wcscheckprepare(struct imgcropparams *p, struct inputimgs *img)
 {
-  double twidth;
+  double twidth, *pixscale;
   struct wcsprm *wcs=img->wcs;
-  int status, ncoord=4, nelem=2;
+  int i, status[4]={0,0,0,0}, ncoord=4, nelem=2;
   double imgcrd[8], phi[4], theta[4], pixcrd[8];
 
 
@@ -88,7 +88,9 @@ wcscheckprepare(struct imgcropparams *p, struct inputimgs 
*img)
   if(p->res==0.0f)
     {
       /* Set the resolution of the image. */
-      p->res=wcs->pc[3];
+      pixscale=gal_wcs_pixel_scale_deg(wcs);
+      p->res=pixscale[0];
+      free(pixscale);
 
       /* Set the widths such that iwidth and wwidth are exactly the same
          (within their different units ofcourse). Also make sure that the
@@ -109,12 +111,16 @@ wcscheckprepare(struct imgcropparams *p, struct inputimgs 
*img)
       p->iwidth[1]=p->iwidth[0];
     }
   else
-    if(p->res!=wcs->pc[3])
-      error(EXIT_FAILURE, 0, "%s: HDU %s: The resolution of "
-            "this image is %f arcseconds/pixel while the "
-            "previously checked input image(s) had a resolution "
-            "of %f", img->name, p->cp.hdu, 3600*wcs->pc[3],
-            3600*p->res);
+    {
+      pixscale=gal_wcs_pixel_scale_deg(wcs);
+      if(p->res!=pixscale[0])
+        error(EXIT_FAILURE, 0, "%s: HDU %s: The resolution of "
+              "this image is %f arcseconds/pixel while the "
+              "previously checked input image(s) had a resolution "
+              "of %f", img->name, p->cp.hdu, 3600*wcs->pc[3],
+              3600*p->res);
+      free(pixscale);
+    }
 
 
   /* Get the coordinates of the first pixel in the image. */
@@ -123,10 +129,13 @@ wcscheckprepare(struct imgcropparams *p, struct inputimgs 
*img)
   pixcrd[4]=1;               pixcrd[5]=img->naxes[1];
   pixcrd[6]=img->naxes[0];   pixcrd[7]=img->naxes[1];
   wcsp2s(wcs, ncoord, nelem, pixcrd, imgcrd, phi, theta,
-         img->corners, &status);
-  if(status)
-    error(EXIT_FAILURE, 0, "wcsp2s ERROR %d: %s", status,
-          wcs_errmsg[status]);
+         img->corners, status);
+
+  /* Check if there was no error in the conversion. */
+  for(i=0;i<4;++i)
+    if(status[i])
+      error(EXIT_FAILURE, 0, "wcsp2s ERROR %d in row %d of pixcrd: %s",
+            i, status[i], wcs_errmsg[status[i]]);
 
 
   /* Fill in the size of the image in celestial degrees from the first
@@ -456,12 +465,13 @@ radecoverlap(struct cropparams *crp)
 {
   double *d, *fd;
   double *i, *s, *c;                /* for clear viewing. */
+  struct imgcropparams *p=crp->p;
 
   /* First check if the four sides of the crop box are in the image.*/
   fd=(d=crp->corners)+8;
-  s=crp->p->imgs[crp->imgindex].sized;
-  i=crp->p->imgs[crp->imgindex].corners;
-  c=crp->p->imgs[crp->imgindex].equatorcorr;
+  s=p->imgs[crp->imgindex].sized;
+  i=p->imgs[crp->imgindex].corners;
+  c=p->imgs[crp->imgindex].equatorcorr;
   do
     {
       if( radecinimg(d, i, s, c) ) return 1;
@@ -474,7 +484,7 @@ radecoverlap(struct cropparams *crp)
   s=crp->sized;
   i=crp->corners;
   c=crp->equatorcorr;
-  fd=(d=crp->p->imgs[crp->imgindex].corners)+8;
+  fd=(d=p->imgs[crp->imgindex].corners)+8;
   do
     {
       if( radecinimg(d, i, s, c) ) return 1;
diff --git a/bin/imgwarp/astimgwarp.conf b/bin/imgwarp/astimgwarp.conf
index 1017118..dd5a1d0 100644
--- a/bin/imgwarp/astimgwarp.conf
+++ b/bin/imgwarp/astimgwarp.conf
@@ -21,5 +21,4 @@
  hdu           0
 
 # Output:
- scale         1.0
  maxblankfrac  0.8
\ No newline at end of file
diff --git a/bin/imgwarp/imgwarp.c b/bin/imgwarp/imgwarp.c
index 1207f58..27c9533 100644
--- a/bin/imgwarp/imgwarp.c
+++ b/bin/imgwarp/imgwarp.c
@@ -430,8 +430,9 @@ correctwcssaveoutput(struct imgwarpparams *p)
 {
   size_t i;
   void *array;
+  double *pixelscale;
+  double *m=p->matrix, diff;
   char keyword[9*FLEN_KEYWORD];
-  double *m=p->matrix, diff, dx, dy;
   struct gal_fits_key_ll *headers=NULL;
   double tpc[4], tcrpix[3], *crpix=p->wcs->crpix, *pc=p->wcs->pc;
   double tinv[4]={p->inverse[0]/p->inverse[8], p->inverse[1]/p->inverse[8],
@@ -484,9 +485,9 @@ correctwcssaveoutput(struct imgwarpparams *p)
      signs are usually different.*/
   if( p->wcs->pc[1]<ABSOLUTEFLTERROR ) p->wcs->pc[1]=0.0f;
   if( p->wcs->pc[2]<ABSOLUTEFLTERROR ) p->wcs->pc[2]=0.0f;
-  gal_wcs_pixel_scale_deg(p->wcs, &dx, &dy);
+  pixelscale=gal_wcs_pixel_scale_deg(p->wcs);
   diff=fabs(p->wcs->pc[0])-fabs(p->wcs->pc[3]);
-  if( fabs(diff/dx)<RELATIVEFLTERROR )
+  if( fabs(diff/pixelscale[0])<RELATIVEFLTERROR )
     p->wcs->pc[3] =  ( (p->wcs->pc[3] < 0.0f ? -1.0f : 1.0f)
                        * fabs(p->wcs->pc[0]) );
 
@@ -495,6 +496,8 @@ correctwcssaveoutput(struct imgwarpparams *p)
                          p->onaxes[1], p->onaxes[0], p->numnul, p->wcs,
                          headers, SPACK_STRING);
 
+  /* Clean up. */
+  free(pixelscale);
   if(array!=p->output)
     free(array);
 }
diff --git a/bin/imgwarp/ui.c b/bin/imgwarp/ui.c
index f8ba672..95a053c 100644
--- a/bin/imgwarp/ui.c
+++ b/bin/imgwarp/ui.c
@@ -541,9 +541,7 @@ read_matrix(struct imgwarpparams *p)
 void
 makealignmatrix(struct imgwarpparams *p, double *tmatrix)
 {
-  double A, dx, dy;
-  double amatrix[4];
-  double w[4]={0,0,0,0};
+  double A, *w, *ps, amatrix[4];
 
   /* Check if there is only two WCS axises: */
   if(p->wcs->naxis!=2)
@@ -551,30 +549,12 @@ makealignmatrix(struct imgwarpparams *p, double *tmatrix)
           "axises. For the `--align' option to operate it must be 2",
           p->up.inputname, p->cp.hdu, p->wcs->naxis);
 
-  /* Depending on the type of data, make the input matrix. Note that
-     wcs->altlin is actually bit flags, not integers, so we have to compare
-     with powers of two. */
-  if(p->wcs->altlin |= 1)
-    {
-      w[0]=p->wcs->cdelt[0]*p->wcs->pc[0];
-      w[1]=p->wcs->cdelt[0]*p->wcs->pc[1];
-      w[2]=p->wcs->cdelt[1]*p->wcs->pc[2];
-      w[3]=p->wcs->cdelt[1]*p->wcs->pc[3];
-    }
-  if(p->wcs->altlin |= 2)
-    {
-      w[0]=p->wcs->cd[0];
-      w[1]=p->wcs->cd[1];
-      w[2]=p->wcs->cd[2];
-      w[3]=p->wcs->cd[3];
-    }
-  else
-    error(EXIT_FAILURE, 0, "currently the `--align' option only recognizes "
-          "PCi_ja and CDi_ja keywords, not any others");
 
   /* Find the pixel scale along the two dimensions. Note that we will be
      using the scale along the image X axis for both values. */
-  gal_wcs_pixel_scale_deg(p->wcs, &dx, &dy);
+  w=gal_wcs_array_from_wcsprm(p->wcs);
+  ps=gal_wcs_pixel_scale_deg(p->wcs);
+
 
   /* Lets call the given WCS orientation `W', the rotation matrix we want
      to find as `X' and the final (aligned matrix) to have just one useful
@@ -626,28 +606,32 @@ makealignmatrix(struct imgwarpparams *p, double *tmatrix)
   else
     {
       A = (w[3]/w[1]) - (w[2]/w[0]);
-      amatrix[1] = dx / w[0] / A;
-      amatrix[3] = dx / w[1] / A;
+      amatrix[1] = ps[0] / w[0] / A;
+      amatrix[3] = ps[0] / w[1] / A;
       amatrix[0] = -1 * amatrix[1] * w[3] / w[1];
       amatrix[2] = -1 * amatrix[3] * w[2] / w[0];
     }
 
 
   /* For a check:
-  printf("dx: %e\n", dx);
+  printf("ps: %e\n", ps);
   printf("w:\n");
   printf("  %.8e    %.8e\n", w[0], w[1]);
   printf("  %.8e    %.8e\n", w[2], w[3]);
   printf("x:\n");
   printf("  %.8e    %.8e\n", amatrix[0], amatrix[1]);
   printf("  %.8e    %.8e\n", amatrix[2], amatrix[3]);
+  exit(0);
   */
 
-
   /* Put the matrix elements into the output array: */
   tmatrix[0]=amatrix[0];  tmatrix[1]=amatrix[1]; tmatrix[2]=0.0f;
   tmatrix[3]=amatrix[2];  tmatrix[4]=amatrix[3]; tmatrix[5]=0.0f;
   tmatrix[6]=0.0f;        tmatrix[7]=0.0f;       tmatrix[8]=1.0f;
+
+  /* Clean up. */
+  free(w);
+  free(ps);
 }
 
 
@@ -854,21 +838,69 @@ prepare_modular_matrix(struct imgwarpparams *p)
 /**************************************************************/
 /***************       Sanity Check         *******************/
 /**************************************************************/
+/* When only one transformation is required, set the suffix for automatic
+   output to more meaningful string. */
+char *
+ui_set_suffix(struct optionwarpsll *owll)
+{
+  /* We only want the more meaningful suffix when the list is defined AND
+     when its only has one node (the `next' element is NULL). */
+  if(owll && owll->next==NULL)
+    switch(owll->type)
+      {
+      case ALIGN_WARP:
+        return "_aligned.fits";
+
+      case ROTATE_WARP:
+        return "_rotated.fits";
+
+      case SCALE_WARP:
+        return "_scaled.fits";
+
+      case FLIP_WARP:
+        return "_flipped.fits";
+
+      case SHEAR_WARP:
+        return "_sheared.fits";
+
+      case TRANSLATE_WARP:
+        return "_translated.fits";
+
+      case PROJECT_WARP:
+        return "_projected.fits";
+
+      default:
+        return "_warped.fits";
+      }
+  else
+    return "_warped.fits";
+}
+
+
+
+
+
 void
 sanitycheck(struct imgwarpparams *p)
 {
+  char *suffix;
   double *d, *df, *m=p->matrix;
 
   /* Make sure the input file exists. */
   gal_checkset_check_file(p->up.inputname);
 
-  /* Set the output name: */
+  /* Set the output name. This needs to be done before
+     `prepare_modular_matrix' because that function will free the linked
+     list of modular warpings (`p->up.owll'). */
   if(p->cp.output)
     gal_checkset_check_remove_file(p->cp.output, p->cp.dontdelete);
   else
-    gal_checkset_automatic_output(p->up.inputname, "_warped.fits",
-                                  p->cp.removedirinfo, p->cp.dontdelete,
-                                  &p->cp.output);
+    {
+      suffix=ui_set_suffix(p->up.owll);
+      gal_checkset_automatic_output(p->up.inputname, suffix,
+                                    p->cp.removedirinfo, p->cp.dontdelete,
+                                    &p->cp.output);
+    }
 
   /* If an actual matrix is given, then it will be used and all modular
      warpings will be ignored. */
@@ -938,8 +970,8 @@ preparearrays(struct imgwarpparams *p)
 
   /* Read in the input image: */
   numnul=gal_fits_hdu_to_array(p->up.inputname, p->cp.hdu,
-                                     &p->inputbitpix, &array, &p->is0,
-                                     &p->is1);
+                               &p->inputbitpix, &array, &p->is0,
+                               &p->is1);
   if(p->inputbitpix==DOUBLE_IMG)
     p->input=array;
   else
diff --git a/bootstrapped/README b/bootstrapped/README
index 2b568d3..b9b5dfa 100644
--- a/bootstrapped/README
+++ b/bootstrapped/README
@@ -3,14 +3,14 @@ Imported files to GNU Astronomy Utilities
 
 The contents of this directory (except this README file!) are imported
 to GNU Astronomy Utilities (Gnuastro) from other projects. Therefore
-they are not maintained by Gnuastro developers and separately kept in
-this directory for clarity and easy maintainence.
+they are not maintained by Gnuastro developers and are kept separately
+in this directory for clarity and easy maintenance.
 
 In the version controlled repository this directory only contains this
 single README file. It is populated during the bootstrapping process
 (see ../README-hacking for more on bootstrapping, or the
 "Bootstrapping" section in the manual). In the distribution tar-ball
-this directory is populated with the relevant necessary files.
+this directory is populated with the necessary files.
 
 The projects that were used are:
 
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index acaa76b..5be7673 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -367,8 +367,8 @@ ImageCrop
 
 Invoking ImageCrop
 
-* astimgcrop options::          A list of all the options with explanation.
-* astimgcrop output::           The outputs of ImageCrop.
+* ImageCrop options::          A list of all the options with explanation.
+* ImageCrop output::           The outputs of ImageCrop.
 
 Arithmetic
 
@@ -2879,7 +2879,7 @@ of your projects also needs Gnulib, and you insist on 
running bootstrap
 like this, you will have two copies. In case you regularly backup your
 important files, Gnulib will also slow down the backup process. Therefore
 while the simple invocation above can be used with no problem, it is not
-recommended, see the next paragraph.
+recommended. To do better, see the next paragraph.
 
 The recommended way to get these two packages is thoroughly discussed in
 @ref{Bootstrapping dependencies} (in short: clone them in the separate
@@ -6937,104 +6937,133 @@ image, see @ref{Crop section syntax}.
 
 @node ImageCrop modes, Crop section syntax, ImageCrop, ImageCrop
 @subsection ImageCrop modes
-In order to be as comprehensive as possible, ImageCrop has two major
address@hidden and @emph{WCS} modes as described below.
+In order to be comprehensive, intuitive, and easy to use, ImageCrop has two
+ways to define crop region: 1) From its center and (square) side length,
+for example to generate postage stamps of a given catalog. 2) The vertices
+of the crop region, this can be useful for larger crops over many targets,
+for example to crop out a uniformly deep, or contiguous, region of a large
+survey. Irrespective of how the crop region is defined, both Image/pixel,
+and World coordinate system (WCS) coordinates are acceptable and all
+coordinates are read as floating point numbers (not integers, except for
+the @option{--section} option, see below). The coordinate standards used
+are the main modes of ImageCrop. Here, the different ways to specify the
+crop region are discussed within each standard. For the full list options,
+please see @ref{Invoking astimgcrop}.
+
+When the crop is defined by its center, the respective (integer) central
+pixel position will be found internally according to the FITS standard. To
+have this pixel positioned in the center of the cropped region, the final
+cropped region must have (in Image mode), or will have (in WCS mode) an add
+number of pixels. Furthermore, when the crop is defined as by its center,
+ImageCrop allows you to only keep crops what don't have any blank pixels in
+the vicinity of their center (your primary target). This can be very
+convenient when your input catalog/coordinates originated from another
+survey/filter which is not fully covered by your input image, to learn more
+about this feature, please see the description of the
address@hidden option in @ref{Invoking astimgcrop}.
 
 @table @asis
address@hidden Image
-The image mode uses the pixel coordinates. Depending on your command
-line options, this mode consists of three sub-modes. In image mode,
-only one image may be input.
address@hidden
-
address@hidden
-Catalog (multiple crops). Coordinates are read from a text file. The
address@hidden and @option{--ycol} columns in the catalog are
-interpreted as the center of a square crop box whose width is
-specified with the @option{--iwidth} option in pixels. Since the given
-pixel has to be on the center, the width has to be an odd number, so
-if you give an even number for the width, it will be added by one. If
-a catalog file name is provided (with @option{--imagemode} activated
-of course) this mode will be used.
-
address@hidden
-Center (one crop). The box center is given on the command-line with
-the @option{--xc} and @option{--yc} parameters. The image width is
-similar to above.
-
address@hidden
-Section (one crop). You can specify the section of pixels along each
-axis in the image which you want to be cropped with the
address@hidden option. See @ref{Crop section syntax} for a full
-explanation on the syntax of specifying the desired region.
address@hidden itemize
address@hidden Image coordinates
+In image mode, ImageCrop uses the pixel coordinates/positions (instead of
+world coordinates). In image mode, only one image may be input. The crop(s)
+can be defined in multiple ways as listed below.
 
-The latter two cases will only have one crop box. In both cases,
-ImageCrop will go into the image mode, irrespective of calling
address@hidden or the default mode. In the first two cases, since
-you specify a central pixel, the crop box will be a square with an odd
-number of pixels on the side, so your desired pixel sits right in the
-center, see @ref{Blank pixels} on how to disable this for cases when
-the box exceeds the image size.
-
address@hidden WCS
-The Right ascension (RA) and Declination (Dec) of the objects in a
-catalog is used to define the central position of each postage
-stamp. In this mode, the width (@option{--wwidth}) is read in units of
-arc seconds and multiple images (tiles in a survey) can be input. If
-the objects are closer to the edge of the image than half the required
-width, other tiles (if they are present in the input files) are used
-to fill the empty space. The square output cropped box will have an
-odd number of pixels on the side.
-
-In this mode, the input images do not necessarily have to be the same
-size, each individual tile can even be smaller than the final crop. In
-any case, any part of any of the input images which overlaps with the
-desired region will be used in the crop. Note that if there is an over
-lap, the pixels from the last input image read are going to be
-used. The input images all just have to be aligned with the celestial
-coordinates, see the caution note below.
-
-Similar to the image mode, there are two sub-modes:
-
address@hidden
address@hidden @asis
address@hidden Center of multiple crops (in a catalog)
+The center of (possibly multiple) crops are read from a text file. A
+catalog can also contain WCS coordinates, so @option{--imgmode} has to be
+called/activated. The @option{--xcol} and @option{--ycol} columns in the
+catalog are interpreted as the center of a square crop with a width of
address@hidden pixels (an odd number). The columns can contain any
+floating point value. The value to @option{--output} option is seen as a
+directory which will host (the possibly multiple) separate crop files, see
address@hidden output} for more. For a tutorial using this feature, please
+see @ref{Hubble visually checks and classifies his catalog}.
+
address@hidden Center of a single crop (on the command-line)
+The center of the crop is given on the command-line with the @option{--xc}
+and @option{--yc} options. The crop width is specified by the
address@hidden option. The given coordinates can be any floating point
+and the width has to be an odd integer, see the explanations above.
+
address@hidden Vertices of a single crop
+In Image mode there are two options to define the vertices of a region to
+crop: @option{--section} and @option{--polygon}. The former is lower-level
+(doesn't accept floating point vertices, and only a rectangular region can
+be defined), it is also only available in Image mode. Please see @ref{Crop
+section syntax} for a full description of this method.
+
+The latter option (@option{--polygon}) is a higher-level method to define
+any convex polygon (with any number of vertices) with floating point
+values. Please see the description of this option in @ref{Invoking
+astimgcrop} for its syntax. It is available in both Image and WCS modes,
+hence, to read the vertices as pixel coordinates, @option{--imgmode} has to
+be called/activated.
address@hidden table
 
address@hidden
-Catalog (multiple crops). Similar to catalog mode in image mode. The
-RA and Dec column should be specified in the catalog (@option{--racol}
-and @option{--deccol}).
address@hidden WCS coordinates
+Use the World Coordinate System (WCS) information to define the crop, not
+pixel coordinates. In this mode, the width (@option{--wwidth}) is read in
+units of arc-seconds and multiple images (tiles in a survey) can be
+input. When the cropped region (defined by center or vertices) overlaps
+with multiple of the input images/tiles, the overlapping regions will be
+taken from the respective input (they will be stitched in the crop).
+
+In this mode, the input images do not necessarily have to be the same size,
+they just need to have the same orientation and pixel resolution. Currently
+only orientation along the celestial coordinates is accepted, if your input
+has a different orientation you can use ImageWarp's @option{--align} option
+to align the image before cropping it (see @ref{ImageWarp}).
+
+Each individual input image/tile can even be smaller than the final
+crop. In any case, any part of any of the input images which overlaps with
+the desired region will be used in the crop. Note that if there is an
+overlap in the input images/tiles, the pixels from the last input image
+read are going to be used for the overlap. ImageCrop will not change pixel
+values, so it assumes your overlapping tiles were cutout from the same
+original image. There are multiple ways to define your cropped region as
+listed below.
 
address@hidden
-Center (one crop). You can specify the center of only one crop box (no
-matter how many input images there are) with the options @option{--ra}
-and @option{--dec}. If it exists in the input images, it will be
-cropped similar to the catalog mode. If automatic output is triggered
-(you don't specify a file name for @option{--output}) and several of
-the input images are used to stitch and crop the region around the
-central point, the name of the first input will be used in automatic
-output, see @ref{Automatic output}.
address@hidden @asis
 
address@hidden itemize
address@hidden Center of multiple crops (in a catalog)
+Similar to catalog inputs in Image mode (above), but @option{--wcsmode} has
+to be activated. The central RA and Dec value for each crop will be read
+from the @option{--racol} and @option{--deccol} columns of the input
+catalog. The square cropped box will have an odd number of pixels.
+
address@hidden Center of a single crop (on the command-line)
+You can specify the center of only one crop box with the @option{--ra} and
address@hidden options. If it exists in the input images, it will be
+cropped similar to the catalog mode.
+
address@hidden Vertices of a single crop
+The @option{--polygon} option is a high-level method to define any convex
+polygon (with any number of vertices). Please see the description of this
+option in @ref{Invoking astimgcrop} for its syntax. It is available in both
+Image and WCS modes, hence, to read the vertices as RA and Dec coordinates,
address@hidden has to be called/activated.
address@hidden table
 
 @cartouche
 @noindent
 @strong{CAUTION:} In WCS mode, the image has to be aligned with the
-celestial coordinates, such that the first FITS axis is parallel
-(opposite direction) to the Right Ascension (RA) while the second FITS
-axis is parallel to the declination. If these conditions aren't met
-for an image, ImageCrop will warn you and abort. You have to use other
-tools to transform the image to the correct directions.
+celestial coordinates, such that the first FITS axis is parallel (opposite
+direction) to the Right Ascension (RA) and the second FITS axis is parallel
+to the declination. If these conditions aren't met for an image, ImageCrop
+will warn you and abort. You can use ImageWarp's @option{--align} option to
+align the input image with these coordinates, see @ref{ImageWarp}.
 @end cartouche
 
 @end table
 
-In short, if you don't specify a catalog, you have to specify box
-coordinates manually on the command-line. When you do specify a
-catalog, ImageCrop has to be in one of the two major modes
-(@option{--imgmode} or @option{--wcsmode}). Note that the single crop
-box parameters specified in the sub-modes will not be written to or
-read from the configuration file, they have to be specified on each
-execution.
+As a summary, if you don't specify a catalog, you have to define the
+cropped region manually on the command-line. Other than the
address@hidden option, the other methods to define a single crop are
+uniqe to each mode, so the mode options (@option{--imgmode} or
address@hidden) will be ignored. When using a catalog, or
address@hidden, the modes have to be specified to correctly interpret
+the values.
 
 
 @node Crop section syntax, Blank pixels, ImageCrop modes, ImageCrop
@@ -7050,18 +7079,18 @@ sizes.
 
 @cindex Define section to crop
 To define a box, you need the coordinates of two points: the first
-pixel in the box at (@code{X1}, @code{Y1}) and the pixel which is
-immediately outside of the box (@code{X2, @code{Y2}}), four
-coordinates in total. The four coordinates can be specified with one
-string in this format: @command{X1:X2,Y1:Y2}. It is given to the
address@hidden option. Therefore, the pixels along the first axis
-that are @address@hidden and <@command{X2} will be included in
+(@code{X1}, @code{Y1}) and the last pixel (@code{X2}, @code{Y2}) pixel
+positions in the image, or four integer numbers in total. The four
+coordinates can be specified with one string in this format:
address@hidden:X2,Y1:Y2}'. This string is given to the @option{--section}
+option. Therefore, the pixels along the first axis that are
address@hidden@command{X1} and @address@hidden will be included in
 the cropped image. The same goes for the second axis. Note that each
-different term will be read as an integer, not a float (there are no
-sub-pixels in ImageCrop, you can use ImageWarp to shift the matrix
-with any sub-pixel distance, then crop the warped image, see
address@hidden). Also, following the FITS standard, pixel indexes
-along each axis start from unity(1) not zero(0).
+different term will be read as an integer, not a float. This is a low-level
+option, for a higher-level way to specify region (any polygon, not just a
+box), please see the @option{--polygon} option in @ref{ImageCrop
+options}. Also note that in the FITS standard, pixel indexes along each
+axis start from unity(1) not zero(0).
 
 @cindex Crop section format
 You can omit any of the values and they will be filled automatically.
@@ -7085,13 +7114,14 @@ replace it with the maximum length of the image in that 
dimension. So
 the input image with 3/4 of the image being covered by blank pixels,
 see @ref{Blank pixels}.
 
-If you feel more comfortable with space characters between the values,
-you can use as many space characters as you wish, just be careful to
-put your value in double quotes, for example
address@hidden"5:200, 123:854"}. If you forget, anything after
-the first space will not be seen by @option{--section}, because the
-unquoted space character is one of the characters that separates
-options on the command-line.
+If you feel more comfortable with space characters between the values, you
+can use as many space characters as you wish, just be careful to put your
+value in double quotes, for example @command{--section="5:200,
+123:854"}. If you forget the quotes, anything after the first space will
+not be seen by @option{--section} and you will most probably get an error
+because the rest of your string will be read as a filename (which most
+probably doesn't exist). See @ref{Command-line} for a description of how
+the command-line works.
 
 
 @node Blank pixels, Invoking astimgcrop, Crop section syntax, ImageCrop
@@ -7151,16 +7181,40 @@ $ astimgcrop -I catalog.txt image.fits
 $ astimgcrop -W catalog.txt /mnt/data/COSMOS/*_drz.fits
 $ astimgcrop --section=10:*-10,10:*-10 --hdu=2 image.fits
 $ astimgcrop --ra=189.16704 --dec=62.218203 goodsnorth.fits
-$ astimgcrop --xc=568.342 --yc=2091.719 --iwidth=200 image.fits
+$ astimgcrop --xc=568.342 --yc=2091.719 --iwidth=201 image.fits
 @end example
 
 @noindent
 ImageCrop has one mandatory argument which is the input image name(s),
-shown above with @file{ASTRdata ...}. You can use shell expansions,
-for example @command{*} for this if you have lots of images in WCS
-mode. If the crop box centers are in a catalog, you also have to
-provide the catalog name as an argument. Alternatively, you have to
-provide the crop box parameters with command-line options.
+shown above with @file{ASTRdata ...}. You can use shell expansions, for
+example @command{*} for this if you have lots of images in WCS mode. If the
+crop box centers are in a catalog, you also have to provide the catalog
+name as an argument. Alternatively, you have to provide the crop box
+parameters with command-line options. See @ref{ImageCrop output} for how
+the output file name(s) can be specified. For the full list of general
+options to all Gnuastro programs (including ImageCrop), please see
address@hidden options}.
+
+Floating point numbers can be used to specify the crop region (except the
address@hidden option, see @ref{Crop section syntax}). In such cases,
+the floating point values will be used to find the desired integer pixel
+indices based on the FITS standard. Hence, ImageCrop ultimately doesn't do
+any sub-pixel cropping (in other words, it doesn't change pixel values). If
+you need such crops, you can use @ref{ImageWarp} to first warp the image to
+the a new pixel grid where your initial floating points can be seen as
+integers, then crop from that with ImageCrop. For example, let's say you
+want a crop from pixels 12.982 to 80.982 along the first dimension. You
+should first translate the image by @mymath{-0.482} (note that the edge of
+a pixel is at integer multiples of @mymath{0.5}). So you should run
+ImageWarp with @option{--translate=-0.482,0} and then crop the warped image
+with @option{--section=13:81}.
+
+There are two ways to define the cropped region: with its center or its
+vertices. See @ref{ImageCrop modes} for a full description. In the former
+case, ImageCrop can check if the central region of the cropped image is
+indeed filled with data or is blank (see @ref{Blank pixels}), and not
+produce any output when the center is blank, see the description under
address@hidden for more.
 
 @cindex Asynchronous thread allocation
 When in catalog mode, ImageCrop will run in parallel unless you set
@@ -7172,11 +7226,11 @@ and classifies his catalog} for a tutorial on 
effectively using this
 feature.
 
 @menu
-* astimgcrop options::          A list of all the options with explanation.
-* astimgcrop output::           The outputs of ImageCrop.
+* ImageCrop options::          A list of all the options with explanation.
+* ImageCrop output::           The outputs of ImageCrop.
 @end menu
 
address@hidden astimgcrop options, astimgcrop output, Invoking astimgcrop, 
Invoking astimgcrop
address@hidden ImageCrop options, ImageCrop output, Invoking astimgcrop, 
Invoking astimgcrop
 @subsubsection ImageCrop options
 
 The options can be classified into the following contexts: Input,
@@ -7238,19 +7292,39 @@ Crop box parameters:
 
 @item -x FLT
 @itemx --xc=FLT
-The first FITS axis value of central position of the crop box in single
-image mode.
+X axis (first image axis, horizontal when viewed in SAO DS9) position of
+crop box center. Along with @option{--yc}, this only produces one crop in
+each run. The width of the square crop (in pixels) is the value to
address@hidden
 
 @item -y FLT
 @itemx --yc=FLT
-The second FITS axis value of the central position of the crop box in
-single image mode.
+Y axis (second image axis, vertical when viewed in SAO DS9) position of
+crop box center. See @option{--xc}.
 
address@hidden -s STR
address@hidden --section=STR
-Section of the input image which you want to be cropped. See @ref{Crop
-section syntax} for a complete explanation on the syntax required for this
-input.
address@hidden -r FLT
address@hidden --ra=FLT
+Right Ascension of crop box center. Along with @option{--dec}, this only
+produces one crop in each run. The width of the square crop (in arcseconds)
+is the value to @option{--wwidth}.
+
address@hidden -d FLT
address@hidden --dec=FLT
+Declination of crop box center. see @option{--ra}.
+
address@hidden -a INT
address@hidden --iwidth=INT
+Width of the cropped region in units of pixels when the crop is defined by
+its center in Image mode (see @ref{ImageCrop modes}). In order for the
+chosen central pixel to be in the center of the cropped image, this option
+only accepts an odd number (an error will be given if its even). If you
+want an even sided crop, you can run ImageCrop afterwards with
address@hidden":*-1,:*-1"} or @option{--section=2:,2:} (depending on
+which side you don't need), see @ref{Crop section syntax}.
+
address@hidden -w FLT
address@hidden --wwidth=FLT
+The width of the crop box in WCS mode in units of arc-seconds.
 
 @item -l STR
 @itemx --polygon=STR
@@ -7258,22 +7332,25 @@ String of crop polygon vertices. Note that currently 
only convex polygons
 should be used. In the future we will make it work for all kinds of
 polygons. Convex polygons are polygons that do not have an internal angle
 more than 180 degrees. This option can be used both in the image and WCS
-modes. The rectangular region that completely encompasses the polygon will
-be kept and all the pixels that are outside of it will be removed.
-
-The syntax for the polygon vertices is similar to and simpler than
-that for @option{--section}. In short, the dimensions of each
-coordinate are separated by a comma (@key{,}) and each vertice is
-separated by a colon (@key{:}). You can define as many vertices as you
-like. If you would like to use space characters between the dimensions
-and vertices to make them more human-readable, then you have to put
-the value to this option in double quotation marks.
-
-For example let's assume you want to work on the deepest part of the
+modes, see @ref{ImageCrop modes}. The cropped image will be the size of the
+rectangular region that completely encompasses the polygon. By default all
+the pixels that are outside of the polygon will be set as blank values (see
address@hidden pixels}). However, if @option{--outpolygon} is called all pixels
+interal to the vertices will be set to blank.
+
+The syntax for the polygon vertices is similar to, and simpler than, that
+for @option{--section}. In short, the dimensions of each coordinate are
+separated by a comma (@key{,}) and each vertice is separated by a colon
+(@key{:}). You can define as many vertices as you like. If you would like
+to use space characters between the dimensions and vertices to make them
+more human-readable, then you have to put the value to this option in
+double quotation marks.
+
+For example, let's assume you want to work on the deepest part of the
 WFC3/IR images of Hubble Space Telescope eXtreme Deep Field
-(HST-XDF). @url{https://archive.stsci.edu/prepds/xdf/, According to
-the address@hidden@url{https://archive.stsci.edu/prepds/xdf/}} the
-deepest part is contained within the coordinates:
+(HST-XDF). @url{https://archive.stsci.edu/prepds/xdf/, According to the
address@hidden@url{https://archive.stsci.edu/prepds/xdf/}} the deepest
+part is contained within the coordinates:
 
 @example
 [ (53.187414,-27.779152), (53.159507,-27.759633),
@@ -7281,14 +7358,14 @@ deepest part is contained within the coordinates:
 @end example
 
 They have provided mask images with only these pixels in the WFC3/IR
-images, but what if you also need to work on the same region in the
-full resolution ACS images? Also what if you want to use the CANDELS
-data for the shallow region? Running ImageCrop with @option{--polygon}
-will easily pull out this region of the image for you irrespective of
-the resolution (if you have set the operating mode to WCS mode in your
-nearest configuration file, there is no need for @option{--wcsmode},
-you may also provide many FITS image or tiles and ImageCrop will
-stitch them all):
+images, but what if you also need to work on the same region in the full
+resolution ACS images? Also what if you want to use the CANDELS data for
+the shallow region? Running ImageCrop with @option{--polygon} will easily
+pull out this region of the image for you irrespective of the
+resolution. If you have set the operating mode to WCS mode in your nearest
+configuration file (see @ref{Configuration files}), there is no need to
+call @option{--wcsmode} on the command line. You may also provide many FITS
+images/tiles and ImageCrop will stitch them to produce this cropped region:
 
 @example
 $ astimgcrop --wcsmode desired-filter-image(s).fits        \
@@ -7307,35 +7384,23 @@ large area if large surveys like COSMOS are used. So 
ImageCrop will
 abort and notify you. In such cases, it is best to crop out the larger
 region you want, then mask the smaller region with this option.
 
address@hidden -r FLT
address@hidden --ra=FLT
-The first FITS axis value of central position of the crop box in single
-image mode.
-
address@hidden -d FLT
address@hidden --dec=flt
-The second FITS axis value of the central position of the crop box in
-single image mode.
address@hidden -s STR
address@hidden --section=STR
+Section of the input image which you want to be cropped. See @ref{Crop
+section syntax} for a complete explanation on the syntax required for this
+input.
 
 @item -i INT
 @itemx --xcol=INT
-Column number of the first FITS axis position of the box center, starting
-from zero. In SAO ds9, the first FITS axis is the horizontal axis.
+Column number of the first FITS axis position of the box center in a
+catalog, starting from zero. In SAO ds9, the first FITS axis is the
+horizontal axis.
 
 @item -j INT
 @itemx --ycol=INT
 Column number of the second FITS axis position of the box center, starting
 from zero. In SAO ds9, the second FITS axis is the vertical axis.
 
address@hidden -a INT
address@hidden --iwidth=INT
-Width the square box to crop in image mode in units of pixels. In order for
-the chosen central pixel to be in the center of the cropped image, the
-final width has to be an odd number, therefore if the value to this option
-is an even number, the final crop width will be one pixel larger in each
-dimension. If you want an even sided crop box, use the @option{--section}
-option to specify the boundaries of the box, see @ref{Crop section syntax}.
-
 @item -f INT
 @itemx --racol=INT
 Column number of Right Ascension (RA) in the input catalog, starting from
@@ -7345,10 +7410,6 @@ zero.
 @itemx --deccol=INT
 Column number of declination in the input catalog, starting from zero.
 
address@hidden -w FLT
address@hidden --wwidth=FLT
-The width of the crop box in WCS mode in units of arc-seconds.
-
 @end table
 
 @noindent
@@ -7358,18 +7419,26 @@ Output options:
 @item -c INT
 @itemx --checkcenter=INT
 @cindex Check center of crop
-Box size of region in the center of the image to check in units of
-pixels. This is only used in WCS mode. Because surveys don't often have a
-clean square or rectangle shape, some of the pixels on the sides of the
-surveys don't have any data and are commonly filled with zero valued
-pixels.
-
-If the RA and Dec of any of the targets specified in the catalog fall
-in such regions, that cropped image will be useless! 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. If all the
-pixels in this small box have the value of zero, no cropped image will
-be created and this object will be flagged in the final log file.
+Box width (odd number of pixels) of region in the center of the image to
+check for blank values. If the value to this option is zero, no checking is
+done. This option is only relevant when the cropped region(s) are defined
+by their center (not by the vertices, see @ref{ImageCrop modes}). If any of
+the pixels in this central region of a crop (defined by its center) are
+blank, then it will not be created.
+
+Because survey regions don't often have a clean square or rectangle shape,
+some of the pixels on the sides of the survey FITS image don't 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 and this option has a
+non-zero, odd 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 weren't from the command-line (if @option{--quiet}
+was not called, see @ref{Operating mode options}), or in ImageCrop's log
+file (see @ref{ImageCrop output}).
 
 @item -p STR
 @itemx --suffix=STR
@@ -7416,34 +7485,45 @@ Operate in WCS mode. See explanations for 
@option{--imgmode}.
 
 
 
address@hidden astimgcrop output,  , astimgcrop options, Invoking astimgcrop
address@hidden ImageCrop output,  , ImageCrop options, Invoking astimgcrop
 @subsubsection ImageCrop output
-When a catalog is given, the value of @option{--output} (see
address@hidden options}) will be seen as the directory to store the
-output cropped images. In such cases, the outputs will consist of two
-parts: a variable part (the row number of each target starting from 1)
-along with a fixed string which you can set with the @option{--suffix}
-option. Note that in catalog mode, only one image can be input.
-
-When the crop box is specified on the command-line, the value to
address@hidden will be used as a file name. If no output is
-specified or if it is a directory, the output file name will follow
-the automatic output names of Gnuastro, see @ref{Automatic output}
-for the input image.
-
-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:
address@hidden Where @command{n} is the number of the image used in
-this crop and @command{m} is the part of the name. Following the name
-is another keyword named @command{ICFnPIX} which shows the pixel range
-from that input image in the same syntax as @ref{Crop section syntax}.
+
+The value given to @option{--output} option will depend on how many crops
+were created, see @ref{ImageCrop modes}:
+
address@hidden
address@hidden
+When a catalog is given, the value of the @option{--output} (see
address@hidden options}) will be read as the directory to store the output
+cropped images. Hence if it doesn't alread exist, ImageCrop will abort with
+an error of a ``No such file or directory'' error. The crop file names will
+consist of two parts: a variable part (the row number of each target
+starting from 1) along with a fixed string which you can set with the
address@hidden option.
+
address@hidden
+When only one crop is desired, the value to @option{--output} will be read
+as a file name. If no output is specified or if it is a directory, the
+output file name will follow the automatic output names of Gnuastro, see
address@hidden output}: The string given to @option{--suffix} will be
+replaced with the @file{.fits} suffix of the input.
address@hidden itemize
+
+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 ImageCrop File). Where
address@hidden is the number of the image used in this crop and @command{m} is
+the part of the name (it can be broken into multiple keywords). Following
+the name is another keyword named @command{ICFnPIX} which shows the pixel
+range from that input image in the same syntax as @ref{Crop section
+syntax}. So this string can be directly given to the @option{--section}
+option later.
 
 Once done, a log file will be created in the current directory named
address@hidden For each input row, this file will have three
-columns:
address@hidden This file will have three columns and the same
+number of rows as the number of cropped images.
 
 @enumerate
 @item
@@ -7451,17 +7531,20 @@ The cropped image file name for that row.
 @item
 The number of input images that were used to create that image.
 @item
-A @code{0} if the central few pixels (value to the
address@hidden option) are blank and @code{1} otherwise.
+A @code{0} if the central few pixels (value to the @option{--checkcenter}
+option) are blank and @code{1} if they aren't. When the crop was not
+defined by its center (see @ref{ImageCrop modes}), or
address@hidden was given a value of 0 (see @ref{Invoking
+astimgcrop}), the center will not be checked and this column will be given
+a value of @code{-1}.
 @end enumerate
 
-There are also comments on the top explaining basic information about
-the run. If the log file cannot be created (for example you don't have
-write permission in the directory you are running ImageCrop in) or you
-have specifically asked for no log file (with the @option{--nolog}
-option), then a log file will not be created (unless
address@hidden is called). The same columns will be printed in
-verbose mode on the command-line for each row.
+There are also comments on the top of the log file explaining basic
+information about the run and descriptions for the columns. If the log file
+cannot be created (for example you don't have write permission in the
+directory you are running ImageCrop in) or you have specifically asked for
+no log file (with the @option{--nolog} option), then a log file will not be
+created (unless @option{--individual} is called).
 
 
 
@@ -9389,7 +9472,7 @@ One line examples:
 
 @example
 $ astconvolve --kernel=psf.fits mockimg.fits
-$ astconvolve --kernel=sharperimage.fits --makekernel\
+$ astconvolve --kernel=sharperimage.fits --makekernel=10 \
               blurryimage.fits
 @end example
 
@@ -9490,22 +9573,23 @@ of the image), we also remove any pixel with a value 
less than
 
 @end enumerate
 
address@hidden -m=INT
address@hidden -m INT
 @itemx --makekernel=INT
-If this option is called, Convolve will do de-convolution (see
address@hidden theorem}). The image specified by the @option{--kernel}
-option is assumed to be the sharper (less blurry) image and the input image
-is assumed to be the more blurry image. The two images have to be the same
-size. Some notes to take into account for a good result:
-
-Noise has large frequencies which can make the result less reliable
-for the higher frequencies of the kernel. So all the frequencies which
-have a spectrum smaller than 0.005 in the frequency domain are set to
-zero and not divided. This will cause the wings of the final kernel to
-be flatter than they would ideally be which will make the convolved
-image result unreliable. The value given to this option will be used
-as the maximum radius of the kernel. Any pixel in the final kernel
-that is larger than this distance from the center will be set to zero.
+(@option{=INT}) If this option is called, Convolve will do de-convolution
+(see @ref{Convolution theorem}). The image specified by the
address@hidden option is assumed to be the sharper (less blurry) image
+and the input image is assumed to be the more blurry image. The value given
+to this option will be used as the maximum radius of the kernel. Any pixel
+in the final kernel that is larger than this distance from the center will
+be set to zero. The two images must have the same size.
+
+Noise has large frequencies which can make the result less reliable for the
+higher frequencies of the final result. So all the frequencies which have a
+spectrum smaller than the value given to the @option{minsharpspec} option
+in the sharper input image are set to zero and not divided. This will cause
+the wings of the final kernel to be flatter than they would ideally be
+which will make the convolved image result unreliable if it is too
+high. Some notes to take into account for a good result:
 @itemize
 
 @item
@@ -9525,8 +9609,13 @@ pixels is one) and then take their average to decrease 
this effect.
 The shifting might move the center of the star by one pixel in any
 direction, so crop the central pixel of the warped image to have a
 clean image for the de-convolution.
-
 @end itemize
+
address@hidden -c
address@hidden --minsharpspec
+(@option{=FLT}) The minimum frequency spectrum (or coefficient, or pixel
+value in the frequency domain image) to use in deconvolution, see the
+explanations under the @option{--makekernel} option for more information.
 @end table
 
 
@@ -9928,9 +10017,9 @@ One line examples:
 
 @example
 $ astimgwarp matrix.txt image.fits
-$ astimgwarp --align rawimage.fits
-$ astimgwarp --scale 1.82 --translate 2.1 image.fits
 $ astimgwarp --rotate=37.92 --scale=0.8 image.fits
+$ astimgwarp --scale 1.82 --translate 2.1 image.fits
+$ astimgwarp --align rawimage.fits --output=aligned.fits
 $ astimgwarp --matrix=0.2,0,0.4,0,0.2,0.4,0,0,1 image.fits
 $ astimgwarp --matrix="0.7071,-0.7071  0.7071,0.7071" image.fits
 @end example
@@ -9939,8 +10028,11 @@ ImageWarp can accept two arguments, one (an image) is 
mandatory if any
 processing is to be done. An optional argument is a plain text file, which
 must contain the warp/transform matrix, see @ref{Warping basics}. When this
 text file is specified, then all options related to the matrix will be
-ignored (see below for the options). The general options to all Gnuastro
-programs (including ImageWarp) can be seen in @ref{Common options}.
+ignored (see below for the options). As in all Gnuastro programs, when an
+output is not explicitly set with the @option{--output} option, the output
+filename will be set automatically based on the operation, see
address@hidden output}. For the full list of general options to all
+Gnuastro programs (including ImageWarp), please see @ref{Common options}.
 
 To be the most accurate the input image will be converted to double
 precision floating points and all the processing will be done in this
@@ -18240,13 +18332,12 @@ features/capabilities) that are to be added to 
Gnuastro.
 @noindent
 All the trackers can be browsed by a (possibly anonymous) visitor, but to
 edit and comment on the Bugs and Tasks trackers, you have to be a
-registered Gnuastro developer. When posting an issue to a tracker, it is
-very important to choose the `Category' and `Item Group' options
-accurately. The first contains a list of all Gnuastro's programs along
-with `Installation', `New program' and `Webpage'. The ``Item Group''
-contains the nature of the issue, for example if it is a `Crash' in the
-software (a bug), or a problem in the documentation (also a bug) or a
-feature request or an enhancement.
+registered on Savannah. When posting an issue to a tracker, it is very
+important to choose the `Category' and `Item Group' options accurately. The
+first contains a list of all Gnuastro's programs along with `Installation',
+`New program' and `Webpage'. The ``Item Group'' contains the nature of the
+issue, for example if it is a `Crash' in the software (a bug), or a problem
+in the documentation (also a bug) or a feature request or an enhancement.
 
 The set of horizontal links on the top of the page (Starting with
 `Main' and `Homepage' and finishing with `News') are the easiest way
@@ -19325,7 +19416,7 @@ Workflow:
 You can send commit patches by email as fully explained in `Pro Git'. This
 is good for your first few contributions. Just note that raw patches
 (containing only the diff) do not have any meta-data (author name, date and
-etc). Therefore will not allow us to fully acknowledge your contributions
+etc). Therefore they will not allow us to fully acknowledge your contributions
 as an author in Gnuastro: in the @file{AUTHORS} file and at the start of
 the PDF book. These author lists are created automatically from the version
 controlled source.
@@ -19356,8 +19447,8 @@ else is already working on. In that case, you can get 
in touch with them
 and help the job go on faster, see @ref{Gnuastro project webpage}. This
 workflow is currently mostly borrowed from the general recommendations of
 
address@hidden@url{https://github.com/git/git/blob/master/Documentation/SubmittingPatches}}
-and GitHub. But since Gnuastro is under heavy development currently, these
-might change and evolve to better suite our needs.
+and GitHub. But since Gnuastro is currently under heavy development, these
+might change and evolve to better suit our needs.
 
 
 
diff --git a/genauthors b/genauthors
index 8809396..fff6538 100755
--- a/genauthors
+++ b/genauthors
@@ -100,4 +100,5 @@ Ordered by number of commits in the Git project history.
 " > $1/AUTHORS
 
 # Generate the aggregate list
-git --git-dir=$1/.git shortlog --summary --email --no-merges >> $1/AUTHORS
+git --git-dir=$1/.git shortlog --summary --email --no-merges \
+    --numbered >> $1/AUTHORS
diff --git a/lib/checkset.h b/lib/checkset.h
index aaa24d4..b5a208d 100644
--- a/lib/checkset.h
+++ b/lib/checkset.h
@@ -50,6 +50,11 @@ __BEGIN_C_DECLS  /* From C++ preparations */
 
 
 
+
+
+
+
+
 /**************************************************************/
 /**********          Check fixed strings           ************/
 /**************************************************************/
diff --git a/lib/fits.c b/lib/fits.c
index ff9f9f1..80235bc 100644
--- a/lib/fits.c
+++ b/lib/fits.c
@@ -32,6 +32,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <unistd.h>
 
 #include <gnuastro/git.h>
+#include <gnuastro/wcs.h>
 #include <gnuastro/fits.h>
 
 #include "checkset.h"
@@ -1476,6 +1477,9 @@ gal_fits_write_img_fitsptr(gal_data_t *data, char 
*filename)
   /* If a WCS structure is present, write it in */
   if(data->wcs)
     {
+      /* Decompose the `PCi_j' matrix and `CDELTi' vector. */
+      gal_wcs_decompose_pc_cdelt(data->wcs);
+
       /* Convert the WCS information to text. */
       status=wcshdo(WCSHDO_safe, data->wcs, &nkeyrec, &wcsheader);
       if(status)
diff --git a/lib/gnuastro/wcs.h b/lib/gnuastro/wcs.h
index b2f4b11..9c8f6de 100644
--- a/lib/gnuastro/wcs.h
+++ b/lib/gnuastro/wcs.h
@@ -47,6 +47,11 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 __BEGIN_C_DECLS  /* From C++ preparations */
 
 
+double *
+gal_wcs_array_from_wcsprm(struct wcsprm *wcs);
+
+void
+gal_wcs_decompose_pc_cdelt(struct wcsprm *wcs);
 
 void
 gal_wcs_xy_array_to_radec(struct wcsprm *wcs, double *xy, double *radec,
@@ -59,8 +64,8 @@ gal_wcs_world_to_img(struct wcsprm *wcs, double *ra, double 
*dec,
 double
 gal_wcs_angular_distance_deg(double r1, double d1, double r2, double d2);
 
-void
-gal_wcs_pixel_scale_deg(struct wcsprm *wcs, double *dx, double *dy);
+double *
+gal_wcs_pixel_scale_deg(struct wcsprm *wcs);
 
 double
 gal_wcs_pixel_area_arcsec2(struct wcsprm *wcs);
diff --git a/lib/wcs.c b/lib/wcs.c
index e4cdd02..bf899bf 100644
--- a/lib/wcs.c
+++ b/lib/wcs.c
@@ -31,11 +31,126 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <unistd.h>
 #include <assert.h>
 
+#include <gsl/gsl_linalg.h>
+
 #include <gnuastro/wcs.h>
 #include <gnuastro/fits.h>
 
 
 
+/**************************************************************/
+/**********              Utilities                 ************/
+/**************************************************************/
+double *
+gal_wcs_array_from_wcsprm(struct wcsprm *wcs)
+{
+  double *out;
+  size_t i, j, size=wcs->naxis*wcs->naxis;
+
+  /* Allocate the necessary array. */
+  errno=0;
+  out=malloc(size*sizeof *out);
+  if(out==NULL)
+    error(EXIT_FAILURE, errno, "%zu bytes for `out' in "
+          "`gal_wcs_array_from_wcsprm'", size*sizeof *out);
+
+  /* Fill in the array. */
+  if(wcs->altlin |= 1)          /* Has a PCi_j array. */
+    {
+      for(i=0;i<wcs->naxis;++i)
+        for(j=0;j<wcs->naxis;++j)
+          out[i*wcs->naxis+j] = wcs->cdelt[i] * wcs->pc[i*wcs->naxis+j];
+    }
+  else if(wcs->altlin |= 2)     /* Has CDi_j array */
+    {
+      for(i=0;i<size;++i)
+        out[i]=wcs->cd[i];
+    }
+  else
+    error(EXIT_FAILURE, 0, "currently, `gal_wcs_pixel_scale_deg' only "
+          "recognizes PCi_ja and CDi_ja keywords");
+
+  /* Return the result */
+  return out;
+}
+
+
+
+
+
+/* According to the FITS standard, in the `PCi_j' WCS formalism, the matrix
+   elements m_{ij} are encoded in the `PCi_j' keywords and the scale
+   factors are encoded in the `CDELTi' keywords. There is also another
+   formalism (the `CDi_j' formalism) which merges the two into one
+   matrix.
+
+   However, WCSLIB's internal operations are apparently done in the `PCi_j'
+   formalism. So its outputs are also all in that format by default. When
+   the input is a `CDi_j', WCSLIB will still read the image into the
+   `PCi_j' formalism and the `CDELTi's are set to 1. This function will
+   decompose the two matrices to give a reasonable `CDELTi' and `PCi_j' in
+   such cases. */
+void
+gal_wcs_decompose_pc_cdelt(struct wcsprm *wcs)
+{
+  double *ps;
+  size_t i, j;
+
+  /* The correction is only needed when the matrix is internally stored
+     as PCi_j. */
+  if(wcs->altlin |= 1)
+    {
+      /* Get the pixel scale. */
+      ps=gal_wcs_pixel_scale_deg(wcs);
+
+      /* The PC matrix and the CDELT elements might both contain scale
+         elements (during processing the scalings might be added only to PC
+         elements for example). So to be safe, we first multiply them into
+         one matrix. */
+      for(i=0;i<wcs->naxis;++i)
+        for(j=0;j<wcs->naxis;++j)
+          wcs->pc[i*wcs->naxis+j] *= wcs->cdelt[i];
+
+      /* Set the CDELTs. */
+      for(i=0; i<wcs->naxis; ++i)
+        wcs->cdelt[i] = ps[i];
+
+      /* Correct the PCi_js */
+      for(i=0;i<wcs->naxis;++i)
+        for(j=0;j<wcs->naxis;++j)
+          wcs->pc[i*wcs->naxis+j] /= ps[i];
+
+      /* Clean up. */
+      free(ps);
+
+      /* According to the `wcslib/wcs.h' header: "In particular, wcsset()
+         resets wcsprm::cdelt to unity if CDi_ja is present (and no
+         PCi_ja).". So apparently, when the input is a `CDi_j', it might
+         expect the `CDELTi' elements to be 1.0. But we have changed that
+         here, so we will correct the `altlin' element of the WCS structure
+         to make sure that WCSLIB only looks into the `PCi_j' and `CDELTi'
+         and makes no assumptioins about `CDELTi'. */
+      wcs->altlin=1;
+    }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 
 /**************************************************************/
@@ -57,7 +172,7 @@ gal_wcs_xy_array_to_radec(struct wcsprm *wcs, double *xy, 
double *radec,
 {
   size_t i;
   double imgcrd[2], phi, theta;
-  int stat, status=0, ncoord=1, nelem=2;
+  int status=0, ncoord=1, nelem=2;
 
   for(i=0;i<number;++i)
     {
@@ -65,8 +180,8 @@ gal_wcs_xy_array_to_radec(struct wcsprm *wcs, double *xy, 
double *radec,
         radec[i*stride]=radec[i*stride+1]=NAN;
       else
         {
-          status=wcsp2s(wcs, ncoord, nelem, xy+i*stride, imgcrd, &phi,
-                        &theta, radec+i*stride, &stat);
+          wcsp2s(wcs, ncoord, nelem, xy+i*stride, imgcrd, &phi,
+                 &theta, radec+i*stride, &status);
           if(status)
             error(EXIT_FAILURE, 0, "wcsp2s ERROR %d: %s", status,
                   wcs_errmsg[status]);
@@ -176,18 +291,42 @@ gal_wcs_angular_distance_deg(double r1, double d1, double 
r2, double d2)
 
 
 /* Return the pixel scale of the image in both dimentions in degrees. */
-void
-gal_wcs_pixel_scale_deg(struct wcsprm *wcs, double *dx, double *dy)
+double *
+gal_wcs_pixel_scale_deg(struct wcsprm *wcs)
 {
-  double radec[6], xy[]={0,0,1,0,0,1};
-
-  /* Get the RA and Dec of the bottom left, bottom right and top left
-     sides of the first pixel in the image. */
-  gal_wcs_xy_array_to_radec(wcs, xy, radec, 3, 2);
-
-  /* Calculate the distances and convert back to degrees: */
-  *dx = gal_wcs_angular_distance_deg(radec[0], radec[1], radec[2], radec[3]);
-  *dy = gal_wcs_angular_distance_deg(radec[0], radec[1], radec[4], radec[5]);
+  gsl_vector S;
+  gsl_matrix A, V;
+  size_t n=wcs->naxis;
+  double *a, *v, *pixscale;
+
+  /* Allocate space for the `v' and `pixscale' arrays. */
+  errno=0; v=malloc(n*n*sizeof *v);
+  if(v==NULL)
+    error(EXIT_FAILURE, errno, "%zu bytes for `v' in "
+          "`gal_wcs_pixel_scale_deg'", n*n*sizeof *v);
+  errno=0; pixscale=malloc(n*sizeof *pixscale);
+  if(pixscale==NULL)
+    error(EXIT_FAILURE, errno, "%zu bytes for `pixscale' in "
+          "`gal_wcs_pixel_scale_deg'", n*sizeof *pixscale);
+
+  /* Write the full matrix into an array, irrespective of what type it was
+     stored in the wcsprm structure (`PCi_j' style or `CDi_j' style). */
+  a=gal_wcs_array_from_wcsprm(wcs);
+
+  /* Fill in the necessary GSL vector and Matrix structures. */
+  S.size=n;     S.stride=1;                S.data=pixscale;
+  V.size1=n;    V.size2=n;    V.tda=n;     V.data=v;
+  A.size1=n;    A.size2=n;    A.tda=n;     A.data=a;
+
+  /* Run GSL's Singular Value Decomposition, using one-sided Jacobi
+     orthogonalization which computes the singular (scale) values to a
+     higher relative accuracy.*/
+  gsl_linalg_SV_decomp_jacobi(&A, &V, &S);
+
+  /* Clean up and return. */
+  free(a);
+  free(v);
+  return pixscale;
 }
 
 
@@ -202,11 +341,21 @@ gal_wcs_pixel_scale_deg(struct wcsprm *wcs, double *dx, 
double *dy)
 double
 gal_wcs_pixel_area_arcsec2(struct wcsprm *wcs)
 {
-  double dx, dy;
-
-  /* Get the pixel scales along each axis in degrees. */
-  gal_wcs_pixel_scale_deg(wcs, &dx, &dy);
-
-  /* Return the result */
-  return dx * dy * 3600.0f * 3600.0f;
+  double out;
+  double *pixscale;
+
+  /* A small sanity check. Later, when higher dimensions are necessary, we
+     can find which ones correlate to RA and Dec and use them to find the
+     pixel area in arcsec^2. */
+  if(wcs->naxis!=2)
+    error(EXIT_FAILURE, 0, "`gal_wcs_pixel_area_arcsec2' can currently "
+          "calculate the area only when the image has 2 dimensions.");
+
+  /* Get the pixel scales along each axis in degrees, then multiply. */
+  pixscale=gal_wcs_pixel_scale_deg(wcs);
+
+  /* Clean up and return the result. */
+  out = pixscale[0] * pixscale[1] * 3600.0f * 3600.0f;
+  free(pixscale);
+  return out;
 }
diff --git a/tests/imgcrop/imgoutpolygon.sh b/tests/imgcrop/imgoutpolygon.sh
index edda747..a0e3668 100755
--- a/tests/imgcrop/imgoutpolygon.sh
+++ b/tests/imgcrop/imgoutpolygon.sh
@@ -52,6 +52,6 @@ if [ ! -f $execname ] || [ ! -f $img ]; then exit 77; fi
 # The number of threads is one so if CFITSIO does is not configured to
 # enable multithreaded access to files, the tests pass. It is the
 # users choice to enable this feature.
-$execname $img $cat --imgmode --zeroisnotblank --outpolygon --keepblankcenter \
+$execname $img $cat --imgmode --zeroisnotblank --outpolygon                   \
           --polygon=209,50:436.76,151:475.64,438.2:210.6,454.04:121.4,289.88  \
           --output=imgoutpolygon.fits



reply via email to

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