gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master 99ac7dc 083/125: Gnuastro now uses fixed width


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 99ac7dc 083/125: Gnuastro now uses fixed width (from stdint.h) types
Date: Sun, 23 Apr 2017 22:36:43 -0400 (EDT)

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

    Gnuastro now uses fixed width (from stdint.h) types
    
    Until now the different types of `gal_data_t' were defined based on the
    standard C types like `int', `short' and `long'. This was initially
    modelled on CFITSIO's `TTYPE' macros like `TINT', or `TLONG'. But this
    model is very hard to maintain for a portable system because on different
    systems, `int' or `long' can have different widths. This would make the
    code very hard to maintain. So following the types defined in `stdint.h',
    the type constant names were changed and also, `stdint.h' types were used
    to make sure we get a consistent result on all systems.
    
    As a result of this clear definition of types based on widths, the
    conversions from CFITSIO types (which are relative) to the `stdint.h' types
    which are absolute is now much more clear.
    
    In the process, a new `func' element was added to the `argp_option'
    structure that will link to a function to parse the user given string and
    put it in the given variable. `gal_options_read_type' is one function that
    was defined for this job to read the string types given by the user and
    convert them to internal integer codes. This was primarily done as part of
    using the fruits of `gal_data_t' in ImageWarp, where multiple options (like
    `--scale', `--rotate', and all other modular warpings) should be used to
    update one linked list, but was then first tested on the `--type' option.
---
 bin/arithmetic/arithmetic.c |   90 +--
 bin/arithmetic/main.h       |    4 +-
 bin/arithmetic/ui.c         |    9 +-
 bin/convertt/args.h         |    8 +-
 bin/convertt/convertt.c     |   12 +-
 bin/convertt/eps.c          |    2 +-
 bin/convertt/jpeg.c         |    2 +-
 bin/convertt/main.h         |   16 +-
 bin/convertt/ui.c           |    5 +-
 bin/convolve/args.h         |    6 +-
 bin/convolve/convolve.c     |    8 +-
 bin/convolve/main.h         |   14 +-
 bin/convolve/ui.c           |   15 +-
 bin/cosmiccal/args.h        |   10 +-
 bin/cosmiccal/main.h        |    8 +-
 bin/header/main.h           |    8 +-
 bin/header/ui.c             |    4 +-
 bin/imgcrop/args.h          |   10 +-
 bin/imgcrop/crop.c          |  121 ++--
 bin/imgcrop/main.h          |   10 +-
 bin/imgcrop/ui.c            |   10 +-
 bin/imgcrop/wcsmode.c       |   10 +-
 bin/imgwarp/args.h          |  407 +++----------
 bin/imgwarp/main.c          |    4 +-
 bin/imgwarp/main.h          |   74 +--
 bin/imgwarp/ui.c            | 1126 ++++++++---------------------------
 bin/imgwarp/ui.h            |   29 +-
 bin/mkprof/args.h           |   39 +-
 bin/mkprof/astmkprof.conf   |    2 +-
 bin/mkprof/main.h           |   26 +-
 bin/mkprof/mkprof.c         |    2 +-
 bin/mkprof/ui.c             |   42 +-
 bin/table/main.h            |    6 +-
 bootstrap.conf              |   11 +
 configure.ac                |  227 ++++----
 doc/gnuastro.texi           |  423 ++++++++------
 lib/Makefile.am             |   21 +-
 lib/arithmetic-binary.c     |  252 ++++----
 lib/arithmetic-binary.h     |    2 +-
 lib/arithmetic-onlyint.c    |  265 ++++-----
 lib/arithmetic.c            |  534 ++++++++---------
 lib/checkset.c              |   50 --
 lib/commonopts.h            |   14 +
 lib/config.h.in             |   21 +-
 lib/data.c                  | 1357 +++++++++++++------------------------------
 lib/fits.c                  |  396 +++++++------
 lib/gnuastro/arithmetic.h   |   21 +-
 lib/gnuastro/data.h         |   76 +--
 lib/gnuastro/fits.h         |    6 +-
 lib/mesh.c                  |    2 +-
 lib/options.c               |  135 +++--
 lib/options.h               |   10 +-
 lib/table.c                 |   27 +-
 lib/txt.c                   |  116 ++--
 lib/wcs.c                   |   16 +-
 tests/imgcrop/cat.txt       |    8 +-
 tests/imgcrop/imgcat.sh     |    2 +-
 tests/mkprof/mkprofcat1.txt |   20 +-
 tests/mkprof/mkprofcat2.txt |   20 +-
 tests/mkprof/mkprofcat3.txt |   20 +-
 tests/mkprof/mkprofcat4.txt |   20 +-
 tests/mkprof/radeccat.txt   |   20 +-
 tests/table/table.txt       |   18 +-
 63 files changed, 2323 insertions(+), 3926 deletions(-)

diff --git a/bin/arithmetic/arithmetic.c b/bin/arithmetic/arithmetic.c
index 44370c0..7ff824d 100644
--- a/bin/arithmetic/arithmetic.c
+++ b/bin/arithmetic/arithmetic.c
@@ -56,20 +56,13 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 /***************************************************************/
 /*************          Internal functions         *************/
 /***************************************************************/
-size_t
+#define SET_NUM_OP(CTYPE) {                                \
+    CTYPE a=*(CTYPE *)(data->array); if(a>0) return a;    }
+
+static size_t
 set_number_of_operands(struct imgarithparams *p, gal_data_t *data,
                        char *token_string)
 {
-  unsigned char  *uc;
-  char            *c;
-  unsigned short *us;
-  short           *s;
-  unsigned int   *ui;
-  int             *i;
-  unsigned long  *ul;
-  long            *l;
-  LONGLONG        *L;
-
   /* Check if its a number. */
   if(data->size>1)
     error(EXIT_FAILURE, 0, "the first popped operand to the \"%s\" "
@@ -82,37 +75,18 @@ set_number_of_operands(struct imgarithparams *p, gal_data_t 
*data,
     /* For the integer types, if they are unsigned, then just pass their
        value, if they are signed, you have to make sure they are zero or
        positive. */
-    case GAL_DATA_TYPE_UCHAR:
-      uc=data->array; if(*uc>0) return *uc;
-      break;
-    case GAL_DATA_TYPE_CHAR:
-      c=data->array; if(*c>0) return *c;
-      break;
-    case GAL_DATA_TYPE_USHORT:
-      us=data->array; if(*us>0) return *us;
-      break;
-    case GAL_DATA_TYPE_SHORT:
-      s=data->array; if(*s>0) return *s;
-      break;
-    case GAL_DATA_TYPE_UINT:
-      ui=data->array; if(*ui>0) return *ui;
-      break;
-    case GAL_DATA_TYPE_INT:
-      i=data->array; if(*i>0) return *i;
-      break;
-    case GAL_DATA_TYPE_ULONG:
-      ul=data->array; if(*ul>0) return *ul;
-      break;
-    case GAL_DATA_TYPE_LONG:
-      l=data->array; if(*l>0) return *l;
-      break;
-    case GAL_DATA_TYPE_LONGLONG:
-      L=data->array; if(*L>0) return *L;
-      break;
+    case GAL_DATA_TYPE_UINT8:   SET_NUM_OP(uint8_t);     break;
+    case GAL_DATA_TYPE_INT8:    SET_NUM_OP(int8_t);      break;
+    case GAL_DATA_TYPE_UINT16:  SET_NUM_OP(uint16_t);    break;
+    case GAL_DATA_TYPE_INT16:   SET_NUM_OP(int16_t);     break;
+    case GAL_DATA_TYPE_UINT32:  SET_NUM_OP(uint32_t);    break;
+    case GAL_DATA_TYPE_INT32:   SET_NUM_OP(int32_t);     break;
+    case GAL_DATA_TYPE_UINT64:  SET_NUM_OP(uint64_t);    break;
+    case GAL_DATA_TYPE_INT64:   SET_NUM_OP(int64_t);     break;
 
     /* Floating point numbers are not acceptable in this context. */
-    case GAL_DATA_TYPE_FLOAT:
-    case GAL_DATA_TYPE_DOUBLE:
+    case GAL_DATA_TYPE_FLOAT32:
+    case GAL_DATA_TYPE_FLOAT64:
       error(EXIT_FAILURE, 0, "the first popped operand to the \"%s\" "
             "operator must be an integer type", token_string);
 
@@ -264,24 +238,22 @@ reversepolish(struct imgarithparams *p)
             { op=GAL_ARITHMETIC_OP_BITNOT;        nop=1;  }
 
           /* Type conversion. */
-          else if (!strcmp(token->v, "uchar"))
-            { op=GAL_ARITHMETIC_OP_TO_UCHAR;      nop=1;  }
-          else if (!strcmp(token->v, "char"))
-            { op=GAL_ARITHMETIC_OP_TO_CHAR;       nop=1;  }
-          else if (!strcmp(token->v, "ushort"))
-            { op=GAL_ARITHMETIC_OP_TO_USHORT;     nop=1;  }
-          else if (!strcmp(token->v, "short"))
-            { op=GAL_ARITHMETIC_OP_TO_SHORT;      nop=1;  }
-          else if (!strcmp(token->v, "ulong"))
-            { op=GAL_ARITHMETIC_OP_TO_ULONG;      nop=1;  }
-          else if (!strcmp(token->v, "long"))
-            { op=GAL_ARITHMETIC_OP_TO_LONG;       nop=1;  }
-          else if (!strcmp(token->v, "longlong"))
-            { op=GAL_ARITHMETIC_OP_TO_LONGLONG;   nop=1;  }
-          else if (!strcmp(token->v, "float"))
-            { op=GAL_ARITHMETIC_OP_TO_FLOAT;      nop=1;  }
-          else if (!strcmp(token->v, "double"))
-            { op=GAL_ARITHMETIC_OP_TO_DOUBLE;     nop=1;  }
+          else if (!strcmp(token->v, "uint8"))
+            { op=GAL_ARITHMETIC_OP_TO_UINT8;      nop=1;  }
+          else if (!strcmp(token->v, "int8"))
+            { op=GAL_ARITHMETIC_OP_TO_INT8;       nop=1;  }
+          else if (!strcmp(token->v, "uint16"))
+            { op=GAL_ARITHMETIC_OP_TO_UINT16;     nop=1;  }
+          else if (!strcmp(token->v, "int16"))
+            { op=GAL_ARITHMETIC_OP_TO_INT16;      nop=1;  }
+          else if (!strcmp(token->v, "uint64"))
+            { op=GAL_ARITHMETIC_OP_TO_UINT64;     nop=1;  }
+          else if (!strcmp(token->v, "int64"))
+            { op=GAL_ARITHMETIC_OP_TO_INT64;      nop=1;  }
+          else if (!strcmp(token->v, "float32"))
+            { op=GAL_ARITHMETIC_OP_TO_FLOAT32;    nop=1;  }
+          else if (!strcmp(token->v, "float64"))
+            { op=GAL_ARITHMETIC_OP_TO_FLOAT64;    nop=1;  }
 
           /* Finished checks with known operators */
           else
@@ -355,7 +327,7 @@ reversepolish(struct imgarithparams *p)
       /* To simplify the printing process, we will first change it to
          double, then use printf's `%g' to print it, so integers will be
          printed as an integer.  */
-      d2=gal_data_copy_to_new_type(d1, GAL_DATA_TYPE_DOUBLE);
+      d2=gal_data_copy_to_new_type(d1, GAL_DATA_TYPE_FLOAT32);
       printf("%g\n", *(double *)d2->array);
       gal_data_free(d2);
     }
diff --git a/bin/arithmetic/main.h b/bin/arithmetic/main.h
index 6a2620a..660ea80 100644
--- a/bin/arithmetic/main.h
+++ b/bin/arithmetic/main.h
@@ -30,8 +30,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 /* Progarm name macros: */
-#define PROGRAM_NAME "Arithmetic"      /* Program full name.       */
-#define PROGRAM_EXEC "astarithmetic"   /* Program executable name. */
+#define PROGRAM_NAME   "Arithmetic"     /* Program full name.       */
+#define PROGRAM_EXEC   "astarithmetic"  /* Program executable name. */
 #define PROGRAM_STRING PROGRAM_NAME" (" PACKAGE_NAME ") " PACKAGE_VERSION
 
 
diff --git a/bin/arithmetic/ui.c b/bin/arithmetic/ui.c
index 65e8246..cbe233c 100644
--- a/bin/arithmetic/ui.c
+++ b/bin/arithmetic/ui.c
@@ -74,10 +74,10 @@ doc[] = GAL_STRINGS_TOP_HELP_INFO PROGRAM_NAME" will do 
arithmetic "
   "\n\nThe operators/functions recognized by "PROGRAM_NAME" are: +, -, *, "
   "/, abs, pow, sqrt, log, log10, minvalue, maxvalue, min, max, average, "
   "median, lt, le, gt, ge, eq, ne, and, or, not, isblank, and the full set "
-  "of bitwise operators. Please run `info gnuastro \"Arithmetic "
-  "operators\"' for detailed information on each operator. Note that "
-  "multiplication should be quoted (like \"*\", or '*') to avoid shell "
-  "expansion.\n"
+  "of bitwise operators, and numeric type conversion operators to all known "
+  "types. Please run `info gnuastro \"Arithmetic operators\"' for detailed "
+  "information on each operator. Note that multiplication should be quoted "
+  "(like \"*\", or '*') to avoid shell expansion.\n"
   GAL_STRINGS_MORE_HELP_INFO
   /* After the list of options: */
   "\v"
@@ -131,6 +131,7 @@ ui_initialize_options(struct imgarithparams *p,
         cp->coptions[i].doc="Nth call, used for HDU of Nth input FITS.";
         break;
 
+      case GAL_OPTIONS_KEY_TYPE:
       case GAL_OPTIONS_KEY_SEARCHIN:
       case GAL_OPTIONS_KEY_IGNORECASE:
       case GAL_OPTIONS_KEY_TABLEFORMAT:
diff --git a/bin/convertt/args.h b/bin/convertt/args.h
index 42a80ad..9314fdb 100644
--- a/bin/convertt/args.h
+++ b/bin/convertt/args.h
@@ -39,7 +39,7 @@ struct argp_option program_options[] =
       "Quality of output JPEG image (1 to 100).",
       GAL_OPTIONS_GROUP_OUTPUT,
       &p->quality,
-      GAL_DATA_TYPE_UCHAR,
+      GAL_DATA_TYPE_UINT8,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -52,7 +52,7 @@ struct argp_option program_options[] =
       "Width in units of centimeters.",
       GAL_OPTIONS_GROUP_OUTPUT,
       &p->widthincm,
-      GAL_DATA_TYPE_FLOAT,
+      GAL_DATA_TYPE_FLOAT32,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -65,7 +65,7 @@ struct argp_option program_options[] =
       "EPS/PDF border width in units of 1/72 inch.",
       GAL_OPTIONS_GROUP_OUTPUT,
       &p->borderwidth,
-      GAL_DATA_TYPE_UINT,
+      GAL_DATA_TYPE_UINT32,
       GAL_OPTIONS_RANGE_GE_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -127,7 +127,7 @@ struct argp_option program_options[] =
       "Maximum byte value for all color channels.",
       ARGS_GROUP_FLUX,
       &p->maxbyte,
-      GAL_DATA_TYPE_UCHAR,
+      GAL_DATA_TYPE_UINT8,
       GAL_OPTIONS_RANGE_GE_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
diff --git a/bin/convertt/convertt.c b/bin/convertt/convertt.c
index cfacc79..93a755e 100644
--- a/bin/convertt/convertt.c
+++ b/bin/convertt/convertt.c
@@ -236,10 +236,11 @@ convertt_scale_to_uchar(struct converttparams *p)
       if(channel->status==0)
         {
           /* If the type isn't float, then convert it to float. */
-          if(channel->type!=GAL_DATA_TYPE_FLOAT)
+          if(channel->type!=GAL_DATA_TYPE_FLOAT32)
             {
               /* Change the type to float. */
-              copied=gal_data_copy_to_new_type(channel, GAL_DATA_TYPE_FLOAT);
+              copied=gal_data_copy_to_new_type(channel,
+                                               GAL_DATA_TYPE_FLOAT32);
 
               /* Correct the pointers. */
               copied->next=channel->next;
@@ -276,14 +277,15 @@ convertt_scale_to_uchar(struct converttparams *p)
       if(p->flminbyte)
         {
           /* Convert the fluxlow value to float and put it in min. */
-          copied=gal_data_copy_to_new_type(p->fluxlow, GAL_DATA_TYPE_FLOAT);
+          copied=gal_data_copy_to_new_type(p->fluxlow, GAL_DATA_TYPE_FLOAT32);
           min = *((float *)(copied->array));
           gal_data_free(copied);
         }
       if(p->fhmaxbyte)
         {
           /* Convert the fluxhigh value to float and put it in min. */
-          copied=gal_data_copy_to_new_type(p->fluxhigh, GAL_DATA_TYPE_FLOAT);
+          copied=gal_data_copy_to_new_type(p->fluxhigh,
+                                           GAL_DATA_TYPE_FLOAT32);
           max = *((float *)(copied->array));
           gal_data_free(copied);
         }
@@ -314,7 +316,7 @@ convertt_scale_to_uchar(struct converttparams *p)
             }
 
           /* Change the type to unsigned char. */
-          copied=gal_data_copy_to_new_type(channel, GAL_DATA_TYPE_UCHAR);
+          copied=gal_data_copy_to_new_type(channel, GAL_DATA_TYPE_UINT8);
 
           /* Correct the pointers. */
           copied->next=channel->next;
diff --git a/bin/convertt/eps.c b/bin/convertt/eps.c
index 3eebfcf..292e022 100644
--- a/bin/convertt/eps.c
+++ b/bin/convertt/eps.c
@@ -198,7 +198,7 @@ eps_convert_to_bitstream(struct converttparams *p)
   for(channel=p->chll; channel!=NULL; channel=channel->next)
     {
       /* Allocate the array. */
-      bits=gal_data_malloc_array(GAL_DATA_TYPE_UCHAR, bytesinimg);
+      bits=gal_data_malloc_array(GAL_DATA_TYPE_UINT8, bytesinimg);
 
       /* Put the values in. */
       in=channel->array;
diff --git a/bin/convertt/jpeg.c b/bin/convertt/jpeg.c
index ec20d62..a79d8f4 100644
--- a/bin/convertt/jpeg.c
+++ b/bin/convertt/jpeg.c
@@ -259,7 +259,7 @@ jpeg_read_to_ll(char *filename, gal_data_t **list, size_t 
minmapsize)
       dsize[0]=s0;
       dsize[1]=s1;
       asprintf(&name, "JPEG_CH_%zu", i+1);
-      gal_data_add_to_ll(list, allcolors[i], GAL_DATA_TYPE_UCHAR, ndim,
+      gal_data_add_to_ll(list, allcolors[i], GAL_DATA_TYPE_UINT8, ndim,
                          dsize, NULL, 0, minmapsize, name, NULL, NULL);
       free(name);
     }
diff --git a/bin/convertt/main.h b/bin/convertt/main.h
index 549b37f..37d0c78 100644
--- a/bin/convertt/main.h
+++ b/bin/convertt/main.h
@@ -70,18 +70,18 @@ struct converttparams
   struct gal_options_common_params cp;    /* Common parameters.        */
   struct gal_linkedlist_stll *inputnames; /* The names of input files. */
   struct gal_linkedlist_stll *hdus;       /* The names of input hdus.  */
-  unsigned char     quality;  /* Quality of JPEG image.                */
+  uint8_t           quality;  /* Quality of JPEG image.                */
   float           widthincm;  /* Width in centimeters.                 */
-  unsigned int  borderwidth;  /* Width of border in PostScript points. */
-  unsigned char         hex;  /* Use hexadecimal not ASCII85 encoding. */
+  uint32_t      borderwidth;  /* Width of border in PostScript points. */
+  uint8_t               hex;  /* Use hexadecimal not ASCII85 encoding. */
   char          *fluxlowstr;  /* Lower flux truncation value.          */
   char         *fluxhighstr;  /* Higher flux truncation value.         */
-  unsigned char     maxbyte;  /* Maximum byte value.                   */
-  unsigned char   flminbyte;  /* fluxlow is minimum byte.              */
-  unsigned char   fhmaxbyte;  /* fluxhigh is maximum byte.             */
+  uint8_t           maxbyte;  /* Maximum byte value.                   */
+  uint8_t         flminbyte;  /* fluxlow is minimum byte.              */
+  uint8_t         fhmaxbyte;  /* fluxhigh is maximum byte.             */
   char           *changestr;  /* String of change values.              */
-  unsigned char changeaftertrunc;  /* First convert, then truncate.    */
-  unsigned char      invert;  /* ==1: invert the output image.         */
+  uint8_t  changeaftertrunc;  /* First convert, then truncate.         */
+  uint8_t            invert;  /* ==1: invert the output image.         */
 
   /* Internal */
   struct change     *change;  /* The value conversion string.          */
diff --git a/bin/convertt/ui.c b/bin/convertt/ui.c
index c22613d..9d6ec6a 100644
--- a/bin/convertt/ui.c
+++ b/bin/convertt/ui.c
@@ -106,7 +106,7 @@ enum option_keys_enum
   ARGS_OPTION_KEY_FHMAXBYTE           = 'b',
   ARGS_OPTION_KEY_CHANGE              = 'c',
   ARGS_OPTION_KEY_CHANGEAFTERTRUNC    = 'C',
-  ARGS_OPTION_KEY_INVERT            = 'i',
+  ARGS_OPTION_KEY_INVERT              = 'i',
 
   /* Only with long version (start with a value 1000, the rest will be set
      automatically). */
@@ -172,6 +172,7 @@ ui_initialize_options(struct converttparams *p,
         cp->coptions[i].mandatory=GAL_OPTIONS_MANDATORY;
         break;
 
+      case GAL_OPTIONS_KEY_TYPE:
       case GAL_OPTIONS_KEY_SEARCHIN:
       case GAL_OPTIONS_KEY_IGNORECASE:
       case GAL_OPTIONS_KEY_TABLEFORMAT:
@@ -593,7 +594,7 @@ ui_prepare_input_channels(struct converttparams *p)
       if(tmp->ndim==0)
         {
           /* Make the blank data structure. */
-          blank=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, ndim, dsize,
+          blank=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, ndim, dsize,
                                wcs, 1, p->cp.minmapsize, "blank channel",
                                NULL, NULL);
 
diff --git a/bin/convolve/args.h b/bin/convolve/args.h
index f662d63..5a1796d 100644
--- a/bin/convolve/args.h
+++ b/bin/convolve/args.h
@@ -92,7 +92,7 @@ struct argp_option program_options[] =
       "Deconvolution: min spectrum of sharp img.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->minsharpspec,
-      GAL_DATA_TYPE_DOUBLE,
+      GAL_DATA_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_GE_0_LE_1,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -172,7 +172,7 @@ struct argp_option program_options[] =
       "Fraction of last mesh area to add new.",
       ARGS_GROUP_MESH_GRID,
       &p->mp.lastmeshfrac,
-      GAL_DATA_TYPE_FLOAT,
+      GAL_DATA_TYPE_FLOAT32,
       GAL_OPTIONS_RANGE_GE_0_LE_1,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -185,7 +185,7 @@ struct argp_option program_options[] =
       "Fraction of last mesh area to add new.",
       ARGS_GROUP_MESH_GRID,
       &p->mp.lastmeshfrac,
-      GAL_DATA_TYPE_FLOAT,
+      GAL_DATA_TYPE_FLOAT32,
       GAL_OPTIONS_RANGE_GE_0_LE_1,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
diff --git a/bin/convolve/convolve.c b/bin/convolve/convolve.c
index 19039c1..27bf71f 100644
--- a/bin/convolve/convolve.c
+++ b/bin/convolve/convolve.c
@@ -645,7 +645,7 @@ frequencyconvolve(struct convolveparams *p)
       /* Prepare the data structure for viewing the steps, note that we
          don't need the array that is initially made. */
       dsize[0]=p->ps0; dsize[1]=p->ps1;
-      data=gal_data_alloc(NULL, GAL_DATA_TYPE_DOUBLE, 2, dsize, NULL, 0,
+      data=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT64, 2, dsize, NULL, 0,
                           p->cp.minmapsize, NULL, NULL, NULL);
       free(data->array);
 
@@ -783,14 +783,14 @@ convolve(struct convolveparams *p)
         {
           /* Allocate the `gal_data_t' with the input imag. */
           gal_mesh_check_mesh_id(mp, &meshindexs);
-          data=gal_data_alloc(p->mp.img, GAL_DATA_TYPE_FLOAT, ndim, dsize,
+          data=gal_data_alloc(p->mp.img, GAL_DATA_TYPE_FLOAT32, ndim, dsize,
                               p->wcs, 0, p->cp.minmapsize, NULL, NULL, NULL);
           data->name="Input";
           gal_fits_img_write(data, p->meshname, NULL, PROGRAM_STRING);
 
           /* Change the array, type, and name. */
           data->array=meshindexs;
-          data->type=GAL_DATA_TYPE_LONG;
+          data->type=GAL_DATA_TYPE_INT64;
           data->name="Mesh indexs";
           gal_fits_img_write(data, p->meshname, NULL, PROGRAM_STRING);
 
@@ -813,7 +813,7 @@ convolve(struct convolveparams *p)
   /* Save the output (which is in p->input) array and clean up. Note that
      we will rely on `gal_data_free' to free some of the things that we
      don't need any more. */
-  data=gal_data_alloc(p->input, GAL_DATA_TYPE_FLOAT, ndim, dsize,
+  data=gal_data_alloc(p->input, GAL_DATA_TYPE_FLOAT32, ndim, dsize,
                       NULL, 0, p->cp.minmapsize, NULL, NULL, NULL);
   data->wcs=p->wcs;
   data->unit=p->unit;
diff --git a/bin/convolve/main.h b/bin/convolve/main.h
index 10fa237..5f3ccbd 100644
--- a/bin/convolve/main.h
+++ b/bin/convolve/main.h
@@ -30,8 +30,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <options.h>
 
 /* Program names.  */
-#define PROGRAM_NAME "Convolve"      /* Program full name.       */
-#define PROGRAM_EXEC "astconvolve"   /* Program executable name. */
+#define PROGRAM_NAME   "Convolve"      /* Program full name.       */
+#define PROGRAM_EXEC   "astconvolve"   /* Program executable name. */
 #define PROGRAM_STRING PROGRAM_NAME" (" PACKAGE_NAME ") " PACKAGE_VERSION
 
 
@@ -77,13 +77,13 @@ struct convolveparams
   char             *filename;  /* Name of input file.                    */
   char           *kernelname;  /* File name of kernel.                   */
   char                 *khdu;  /* HDU of kernel.                         */
-  unsigned char nokernelflip;  /* Do not flip the kernel.                */
-  unsigned char nokernelnorm;  /* Do not normalize the kernel.           */
+  uint8_t       nokernelflip;  /* Do not flip the kernel.                */
+  uint8_t       nokernelnorm;  /* Do not normalize the kernel.           */
   double        minsharpspec;  /* Deconvolution: min spect. of sharp img.*/
-  unsigned char checkfreqsteps; /* View the frequency domain steps.      */
-  unsigned char    checkmesh;  /* View the mesh structure.               */
+  uint8_t     checkfreqsteps;  /* View the frequency domain steps.       */
+  uint8_t          checkmesh;  /* View the mesh structure.               */
   char            *domainstr;  /* String value specifying domain.        */
-  unsigned char   makekernel;  /* ==1: Make a kernel to create input.    */
+  uint8_t         makekernel;  /* ==1: Make a kernel to create input.    */
 
   /* Internal */
   int                 domain;  /* Frequency or spatial domain conv.      */
diff --git a/bin/convolve/ui.c b/bin/convolve/ui.c
index fa671f6..3f8dc34 100644
--- a/bin/convolve/ui.c
+++ b/bin/convolve/ui.c
@@ -283,12 +283,12 @@ ui_read_domain(struct convolveparams *p)
 static void
 ui_read_kernel(struct convolveparams *p)
 {
-  double zero=0.0f;
+  float *f, *ff;
   gal_data_t *data;
 
   /* Read the image into file. */
-  data=gal_fits_img_read_to_type(p->kernelname, p->khdu, GAL_DATA_TYPE_FLOAT,
-                                 p->cp.minmapsize);
+  data=gal_fits_img_read_to_type(p->kernelname, p->khdu,
+                                 GAL_DATA_TYPE_FLOAT32, p->cp.minmapsize);
 
   /* Put its values into the main program structure. */
   p->ks0=data->dsize[0];
@@ -298,7 +298,10 @@ ui_read_kernel(struct convolveparams *p)
   /* Convert all the NaN pixels to zero if the kernel contains blank
      pixels. */
   if(gal_data_has_blank(data))
-    gal_data_blank_to_value(data, &zero);
+    {
+      ff=(f=data->array)+data->size;
+      do *f = isnan(*f) ? 0.0f : *f; while(++f<ff);
+    }
 
   /* Clean up. Note that we need the array, so it must be set to NULL. */
   data->array=NULL;
@@ -336,8 +339,8 @@ ui_preparations(struct convolveparams *p)
 
 
   /* Read the input image as a float array and its WCS info. */
-  data=gal_fits_img_read_to_type(p->filename, p->cp.hdu, GAL_DATA_TYPE_FLOAT,
-                                 p->cp.minmapsize);
+  data=gal_fits_img_read_to_type(p->filename, p->cp.hdu,
+                                 GAL_DATA_TYPE_FLOAT32, p->cp.minmapsize);
   gal_wcs_read(p->filename, p->cp.hdu, 0, 0, &p->nwcs, &p->wcs);
   p->unit=data->unit;
   data->unit=NULL;
diff --git a/bin/cosmiccal/args.h b/bin/cosmiccal/args.h
index 0a3e69a..b9ab2b1 100644
--- a/bin/cosmiccal/args.h
+++ b/bin/cosmiccal/args.h
@@ -39,7 +39,7 @@ struct argp_option program_options[] =
       "Redshift of interest.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->redshift,
-      GAL_DATA_TYPE_DOUBLE,
+      GAL_DATA_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_GE_0,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -52,7 +52,7 @@ struct argp_option program_options[] =
       "Current expansion rate (Hubble constant).",
       GAL_OPTIONS_GROUP_INPUT,
       &p->H0,
-      GAL_DATA_TYPE_DOUBLE,
+      GAL_DATA_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_GE_0,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -65,7 +65,7 @@ struct argp_option program_options[] =
       "Current cosmological cst. dens. per crit. dens.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->olambda,
-      GAL_DATA_TYPE_DOUBLE,
+      GAL_DATA_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_GE_0_LE_1,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -78,7 +78,7 @@ struct argp_option program_options[] =
       "Current matter density per critical density.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->omatter,
-      GAL_DATA_TYPE_DOUBLE,
+      GAL_DATA_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_GE_0_LE_1,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -91,7 +91,7 @@ struct argp_option program_options[] =
       "Current radiation density per critical density.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->oradiation,
-      GAL_DATA_TYPE_DOUBLE,
+      GAL_DATA_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_GE_0_LE_1,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
diff --git a/bin/cosmiccal/main.h b/bin/cosmiccal/main.h
index 644999d..acdae15 100644
--- a/bin/cosmiccal/main.h
+++ b/bin/cosmiccal/main.h
@@ -29,8 +29,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <options.h>
 
 /* Progarm names.  */
-#define PROGRAM_NAME "CosmicCalculator" /* Program full name.       */
-#define PROGRAM_EXEC "astcosmiccal"     /* Program executable name. */
+#define PROGRAM_NAME   "CosmicCalculator" /* Program full name.       */
+#define PROGRAM_EXEC   "astcosmiccal"     /* Program executable name. */
 #define PROGRAM_STRING PROGRAM_NAME" (" PACKAGE_NAME ") " PACKAGE_VERSION
 
 
@@ -54,8 +54,8 @@ struct cosmiccalparams
   double            solidangle; /* Solid angle for volume (in stradian).*/
 
   /* Output: */
-  unsigned char     onlyvolume; /* Only print the volume in Mpc^3.      */
-  unsigned char onlyabsmagconv; /* Only print conversion to abs. mag.   */
+  uint8_t           onlyvolume; /* Only print the volume in Mpc^3.      */
+  uint8_t       onlyabsmagconv; /* Only print conversion to abs. mag.   */
 
   /* Internal: */
   double                     K; /* Curvature constant.                  */
diff --git a/bin/header/main.h b/bin/header/main.h
index 12e1099..2450637 100644
--- a/bin/header/main.h
+++ b/bin/header/main.h
@@ -28,8 +28,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <options.h>
 
 /* Progarm name macros: */
-#define PROGRAM_NAME "Header"        /* Program full name.       */
-#define PROGRAM_EXEC "astheader"     /* Program executable name. */
+#define PROGRAM_NAME  "Header"        /* Program full name.       */
+#define PROGRAM_EXEC  "astheader"     /* Program executable name. */
 #define PROGRAM_STRING PROGRAM_NAME" (" PACKAGE_NAME ") " PACKAGE_VERSION
 
 
@@ -49,7 +49,7 @@ struct headerparams
   struct wcsprm                  *wcs;  /* Pointer to WCS structures.      */
 
   /* Output: */
-  unsigned char                  date;  /* Set DATE to current time.       */
+  uint8_t                        date;  /* Set DATE to current time.       */
   char                       *comment;  /* COMMENT value.                  */
   char                       *history;  /* HISTORY value.                  */
   struct gal_linkedlist_stll    *asis;  /* Strings to write asis.          */
@@ -60,7 +60,7 @@ struct headerparams
   struct gal_fits_key_ll       *write;  /* Keywords to add.                */
 
   /* Operating mode: */
-  unsigned char           quitonerror;  /* Quit if an error occurs.        */
+  uint8_t                 quitonerror;  /* Quit if an error occurs.        */
 
   /* Internal: */
   int                        onlyview;
diff --git a/bin/header/ui.c b/bin/header/ui.c
index 93ada8b..eaf5dce 100644
--- a/bin/header/ui.c
+++ b/bin/header/ui.c
@@ -389,7 +389,7 @@ ui_fill_fits_headerll(struct gal_linkedlist_stll *input,
       if(*tailptr=='\0' && errno==0)
         {
           vfree=1;
-          type=GAL_DATA_TYPE_LONG;
+          type=GAL_DATA_TYPE_INT64;
           errno=0;
           fvalue=lp=malloc(sizeof *lp);
           if(lp==NULL)
@@ -404,7 +404,7 @@ ui_fill_fits_headerll(struct gal_linkedlist_stll *input,
           if(*tailptr=='\0' && errno==0)
             {
               vfree=1;
-              type=GAL_DATA_TYPE_DOUBLE;
+              type=GAL_DATA_TYPE_FLOAT64;
               errno=0;
               fvalue=dp=malloc(sizeof *dp);
               if(dp==NULL)
diff --git a/bin/imgcrop/args.h b/bin/imgcrop/args.h
index 00cfda2..d877736 100644
--- a/bin/imgcrop/args.h
+++ b/bin/imgcrop/args.h
@@ -145,7 +145,7 @@ struct argp_option program_options[] =
       "Width (arcseconds) for crops defined by RA,Dec.",
       ARGS_GROUP_CENTER_GENERAL,
       &p->wwidth,
-      GAL_DATA_TYPE_DOUBLE,
+      GAL_DATA_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -168,7 +168,7 @@ struct argp_option program_options[] =
       "Right ascension of one crop box center.",
       ARGS_GROUP_CENTER_SINGLE,
       &p->ra,
-      GAL_DATA_TYPE_DOUBLE,
+      GAL_DATA_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -181,7 +181,7 @@ struct argp_option program_options[] =
       "Declination of one crop box center.",
       ARGS_GROUP_CENTER_SINGLE,
       &p->dec,
-      GAL_DATA_TYPE_DOUBLE,
+      GAL_DATA_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -194,7 +194,7 @@ struct argp_option program_options[] =
       "First axis position of one crop box center.",
       ARGS_GROUP_CENTER_SINGLE,
       &p->xc,
-      GAL_DATA_TYPE_DOUBLE,
+      GAL_DATA_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -207,7 +207,7 @@ struct argp_option program_options[] =
       "Second axis position of one crop box center.",
       ARGS_GROUP_CENTER_SINGLE,
       &p->yc,
-      GAL_DATA_TYPE_DOUBLE,
+      GAL_DATA_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
diff --git a/bin/imgcrop/crop.c b/bin/imgcrop/crop.c
index bda80de..2603f46 100644
--- a/bin/imgcrop/crop.c
+++ b/bin/imgcrop/crop.c
@@ -307,18 +307,25 @@ imgpolygonflpixel(double *ipolygon, size_t nvertices, 
long *fpixel,
 
 
 
+#define POLYGON_MASK(CTYPE) {                                           \
+    CTYPE *ba=array, *bb=gal_data_alloc_blank(type);                    \
+    for(i=0;i<size;++i)                                                 \
+      {                                                                 \
+        point[0]=i%s1+1; point[1]=i/s1+1;                               \
+        if(gal_polygon_pin(ipolygon, point, nvertices)==outpolygon)     \
+          ba[i]=*bb;                                                    \
+      }                                                                 \
+    free(bb);                                                           \
+  }
+
+
 void
 polygonmask(struct cropparams *crp, void *array, long *fpixel_i,
             size_t s0, size_t s1)
 {
-  long *lb, *la=array;
-  short *sb, *sa=array;
-  float *fb, *fa=array;
   int type=crp->p->type;
-  LONGLONG *Lb, *La=array;
-  unsigned char *bb, *ba=array;
+  double *ipolygon, point[2];
   int outpolygon=crp->p->outpolygon;
-  double *db, *ipolygon, point[2], *da=array;
   size_t i, *ordinds, size=s0*s1, nvertices=crp->p->nvertices;
 
 
@@ -350,66 +357,15 @@ polygonmask(struct cropparams *crp, void *array, long 
*fpixel_i,
      polygon keep them if the user has asked for it.*/
   switch(type)
     {
-    case GAL_DATA_TYPE_UCHAR:
-      bb=gal_data_alloc_blank(type);
-      for(i=0;i<size;++i)
-        {
-          point[0]=i%s1+1; point[1]=i/s1+1;
-          if(gal_polygon_pin(ipolygon, point, nvertices)==outpolygon)
-            ba[i]=*bb;
-        }
-      free(bb);
-      break;
-    case GAL_DATA_TYPE_SHORT:
-      sb=gal_data_alloc_blank(type);
-      for(i=0;i<size;++i)
-        {
-          point[0]=i%s1+1; point[1]=i/s1+1;
-          if(gal_polygon_pin(ipolygon, point, nvertices)==outpolygon)
-            sa[i]=*sb;
-        }
-      free(sb);
-      break;
-    case GAL_DATA_TYPE_LONG:
-      lb=gal_data_alloc_blank(type);
-      for(i=0;i<size;++i)
-        {
-          point[0]=i%s1+1; point[1]=i/s1+1;
-          if(gal_polygon_pin(ipolygon, point, nvertices)==outpolygon)
-            la[i]=*lb;
-        }
-      free(lb);
-      break;
-    case GAL_DATA_TYPE_LONGLONG:
-      Lb=gal_data_alloc_blank(type);
-      for(i=0;i<size;++i)
-        {
-          point[0]=i%s1+1; point[1]=i/s1+1;
-          if(gal_polygon_pin(ipolygon, point, nvertices)==outpolygon)
-            La[i]=*Lb;
-        }
-      free(Lb);
-      break;
-    case GAL_DATA_TYPE_FLOAT:
-      fb=gal_data_alloc_blank(type);
-      for(i=0;i<size;++i)
-        {
-          point[0]=i%s1+1; point[1]=i/s1+1;
-          if(gal_polygon_pin(ipolygon, point, nvertices)==outpolygon)
-            fa[i]=*fb;
-        }
-      free(fb);
-      break;
-    case GAL_DATA_TYPE_DOUBLE:
-      db=gal_data_alloc_blank(type);
-      for(i=0;i<size;++i)
-        {
-          point[0]=i%s1+1; point[1]=i/s1+1;
-          if(gal_polygon_pin(ipolygon, point, nvertices)==outpolygon)
-            da[i]=*db;
-        }
-      free(db);
-      break;
+    case GAL_DATA_TYPE_UINT8:    POLYGON_MASK(uint8_t);  break;
+    case GAL_DATA_TYPE_INT8:     POLYGON_MASK(int8_t);   break;
+    case GAL_DATA_TYPE_UINT16:   POLYGON_MASK(uint16_t); break;
+    case GAL_DATA_TYPE_INT16:    POLYGON_MASK(int16_t);  break;
+    case GAL_DATA_TYPE_UINT32:   POLYGON_MASK(uint32_t); break;
+    case GAL_DATA_TYPE_INT32:    POLYGON_MASK(int32_t);  break;
+    case GAL_DATA_TYPE_INT64:    POLYGON_MASK(int64_t);  break;
+    case GAL_DATA_TYPE_FLOAT32:  POLYGON_MASK(float);    break;
+    case GAL_DATA_TYPE_FLOAT64:  POLYGON_MASK(double);   break;
     default:
       error(EXIT_FAILURE, 0, "a bug! Please contact us at %s, so we "
             "can fix the problem. For some reason, an unrecognized "
@@ -451,14 +407,14 @@ changezerotonan(void *array, size_t size, int type)
 
   switch(type)
     {
-    case GAL_DATA_TYPE_FLOAT:
+    case GAL_DATA_TYPE_FLOAT32:
       ffp=(fp=array)+size;
       do
         if(*fp==0.0f) *fp=NAN;
       while(++fp<ffp);
       break;
 
-    case GAL_DATA_TYPE_DOUBLE:
+    case GAL_DATA_TYPE_FLOAT64:
       fdp=(dp=array)+size;
       do
         if(*dp==0.0f) *dp=NAN;
@@ -650,14 +606,23 @@ firstcropmakearray(struct cropparams *crp, long *fpixel_i,
 
 
   /* Create the FITS image extension and array and fill it with null
-     values. */
+     values. About the COMMENTs: when CFITSIO creates a FITS extension it
+     adds two comments linking to the FITS paper. Since we are mentioning
+     the version of CFITSIO and only use its ruitines to read/write from/to
+     FITS files, this is redundant. If `status!=0', then
+     `gal_fits_io_error' will abort, but in case CFITSIO doesn't write the
+     comments, status will become non-zero. So we are resetting it to zero
+     after these (because not being able to delete them isn't an error).*/
   if(fits_create_file(&crp->outfits, outname, &status))
     gal_fits_io_error(status, "creating file");
   ofp=crp->outfits;
-  if( fits_create_img(ofp, gal_fits_type_to_bitpix(type),
-                      naxis, naxes, &status) )
-    gal_fits_io_error(status, "creating image");
-  if( type!=GAL_DATA_TYPE_FLOAT && type!=GAL_DATA_TYPE_DOUBLE )
+  fits_create_img(ofp, gal_fits_type_to_bitpix(type),
+                  naxis, naxes, &status);
+  gal_fits_io_error(status, "creating image");
+  fits_delete_key(ofp, "COMMENT", &status);
+  fits_delete_key(ofp, "COMMENT", &status);
+  status=0;
+  if( type!=GAL_DATA_TYPE_FLOAT32 && type!=GAL_DATA_TYPE_FLOAT64 )
     if(fits_write_key(ofp, gal_fits_type_to_datatype(crp->p->type), "BLANK",
                       crp->p->bitnul, "pixels with no data", &status) )
       gal_fits_io_error(status, "adding Blank");
@@ -752,12 +717,12 @@ onecrop(struct cropparams *crp)
                           &anynul, &status))
         gal_fits_io_error(status, NULL);
 
-
       /* If we have a floating point or double image, pixels with zero
          value should actually be a NaN. Unless the user specificly
          asks for it, make the conversion.*/
       if(p->zeroisnotblank==0
-         && (p->type==GAL_DATA_TYPE_FLOAT || p->type==GAL_DATA_TYPE_DOUBLE) )
+         && (p->type==GAL_DATA_TYPE_FLOAT32
+             || p->type==GAL_DATA_TYPE_FLOAT64) )
         changezerotonan(array, cropsize, p->type);
 
 
@@ -789,12 +754,12 @@ onecrop(struct cropparams *crp)
       sprintf(regionkey, "%sPIX", basename);
       sprintf(region, "%ld:%ld,%ld:%ld", fpixel_i[0], lpixel_i[0],
               fpixel_i[1], lpixel_i[1]);
-      gal_fits_key_add_to_ll_end(&headers, TSTRING, regionkey, 0, region, 0,
+      gal_fits_key_add_to_ll_end(&headers, GAL_DATA_TYPE_STRING, regionkey,
+                                 0, region, 0,
                                  "Range of pixels used for this output.", 0,
                                  NULL);
       gal_fits_key_write(ofp, &headers);
 
-
       /* Free the allocated array. */
       free(array);
     }
@@ -841,7 +806,7 @@ iscenterfilled(struct cropparams *crp)
   long naxes[2], fpixel[2], lpixel[2], inc[2]={1,1};
 
   /* If checkcenter is zero, then don't check. */
-  if(checkcenter==0) return GAL_DATA_BLANK_UCHAR;
+  if(checkcenter==0) return GAL_DATA_BLANK_UINT8;
 
   /* Get the final size of the output image. */
   gal_fits_img_info(ofp, &type, &ndim, &dsize);
diff --git a/bin/imgcrop/main.h b/bin/imgcrop/main.h
index 9e1a921..c90324f 100644
--- a/bin/imgcrop/main.h
+++ b/bin/imgcrop/main.h
@@ -29,8 +29,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <options.h>
 
 /* Progarm names.  */
-#define PROGRAM_NAME "ImageCrop"     /* Program full name.       */
-#define PROGRAM_EXEC "astimgcrop"    /* Program executable name. */
+#define PROGRAM_NAME   "ImageCrop"     /* Program full name.       */
+#define PROGRAM_EXEC   "astimgcrop"    /* Program executable name. */
 #define PROGRAM_STRING PROGRAM_NAME" (" PACKAGE_NAME ") " PACKAGE_VERSION
 
 
@@ -84,8 +84,8 @@ struct imgcropparams
   struct gal_linkedlist_stll  *inputs;  /* All input FITS files.          */
   size_t             hstartwcs;  /* Header keyword No. to start read WCS. */
   size_t               hendwcs;  /* Header keyword No. to end read WCS.   */
-  unsigned char zeroisnotblank;  /* ==1: In float or double, keep 0.0.    */
-  unsigned char        noblank;  /* ==1: no blank (out of image) pixels.  */
+  uint8_t       zeroisnotblank;  /* ==1: In float or double, keep 0.0.    */
+  uint8_t              noblank;  /* ==1: no blank (out of image) pixels.  */
   char                 *suffix;  /* Ending of output file name.           */
   size_t           checkcenter;  /* width of a box to check for zeros     */
   size_t              iwidthin;  /* Image mode width (in pixels).         */
@@ -103,7 +103,7 @@ struct imgcropparams
   char                   *ycol;  /* Catalog Y column                      */
   char                *section;  /* Section string.                       */
   char                *polygon;  /* Input string of polygon vertices.     */
-  unsigned char     outpolygon;  /* ==1: Keep the inner polygon region.   */
+  uint8_t           outpolygon;  /* ==1: Keep the inner polygon region.   */
   char                *modestr;  /* ==1: will use X and Y coordiates.     */
 
   /* Internal */
diff --git a/bin/imgcrop/ui.c b/bin/imgcrop/ui.c
index 23f530f..c48a671 100644
--- a/bin/imgcrop/ui.c
+++ b/bin/imgcrop/ui.c
@@ -568,13 +568,13 @@ ui_read_cols(struct imgcropparams *p)
 
         case 2:
           colname="first axis position";
-          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_DOUBLE);
+          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT64);
           p->c1=corrtype->array;
           break;
 
         case 1:
           colname="second axis position";
-          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_DOUBLE);
+          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT64);
           p->c2=corrtype->array;
           break;
 
@@ -626,14 +626,14 @@ ui_make_log(struct imgcropparams *p)
 
   /* If central pixels are filled. */
   asprintf(&comment, "Are the central pixels filled? (1: yes, 0: no, "
-           "%u: not checked)", GAL_DATA_BLANK_UCHAR);
-  gal_data_add_to_ll(&p->log, NULL, GAL_DATA_TYPE_UCHAR, 1, &p->numout,
+           "%u: not checked)", GAL_DATA_BLANK_UINT8);
+  gal_data_add_to_ll(&p->log, NULL, GAL_DATA_TYPE_UINT8, 1, &p->numout,
                      NULL, 1, p->cp.minmapsize, "CENTER_FILLED", "bool",
                      comment);
   free(comment);
 
   /* Number of images used. */
-  gal_data_add_to_ll(&p->log, NULL, GAL_DATA_TYPE_USHORT, 1, &p->numout,
+  gal_data_add_to_ll(&p->log, NULL, GAL_DATA_TYPE_UINT16, 1, &p->numout,
                      NULL, 1, p->cp.minmapsize, "NUM_INPUTS", "count",
                      "Number of input images used to make this crop.");
 
diff --git a/bin/imgcrop/wcsmode.c b/bin/imgcrop/wcsmode.c
index 9d99c17..62efe24 100644
--- a/bin/imgcrop/wcsmode.c
+++ b/bin/imgcrop/wcsmode.c
@@ -300,11 +300,11 @@ fillcrpipolygon(struct cropparams *crp)
   struct imgcropparams *p=crp->p;
 
   /* Allocate the necessary arrays. */
-  x=gal_data_calloc_array(GAL_DATA_TYPE_DOUBLE, p->nvertices);
-  y=gal_data_calloc_array(GAL_DATA_TYPE_DOUBLE, p->nvertices);
-  ra=gal_data_calloc_array(GAL_DATA_TYPE_DOUBLE, p->nvertices);
-  dec=gal_data_calloc_array(GAL_DATA_TYPE_DOUBLE, p->nvertices);
-  crp->ipolygon=gal_data_malloc_array(GAL_DATA_TYPE_DOUBLE, 2*p->nvertices);
+  x=gal_data_calloc_array(GAL_DATA_TYPE_FLOAT64, p->nvertices);
+  y=gal_data_calloc_array(GAL_DATA_TYPE_FLOAT64, p->nvertices);
+  ra=gal_data_calloc_array(GAL_DATA_TYPE_FLOAT64, p->nvertices);
+  dec=gal_data_calloc_array(GAL_DATA_TYPE_FLOAT64, p->nvertices);
+  crp->ipolygon=gal_data_malloc_array(GAL_DATA_TYPE_FLOAT64, 2*p->nvertices);
 
   /* Fill in the RA and Dec columns. */
   for(i=0;i<p->nvertices;++i)
diff --git a/bin/imgwarp/args.h b/bin/imgwarp/args.h
index 1322c8b..9fc421a 100644
--- a/bin/imgwarp/args.h
+++ b/bin/imgwarp/args.h
@@ -5,7 +5,7 @@ ImageWarp is part of GNU Astronomy Utilities (Gnuastro) package.
 Original author:
      Mohammad Akhlaghi <address@hidden>
 Contributing author(s):
-Copyright (C) 2015, Free Software Foundation, Inc.
+Copyright (C) 2016, Free Software Foundation, Inc.
 
 Gnuastro is free software: you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
@@ -23,220 +23,122 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #ifndef ARGS_H
 #define ARGS_H
 
-#include <argp.h>
 
-#include <commonargs.h>
-#include <fixedstringmacros.h>
 
 
 
 
-
-
-
-
-
-
-/**************************************************************/
-/**************        argp.h definitions       ***************/
-/**************************************************************/
-
-
-
-
-/* Definition parameters for the argp: */
-const char *argp_program_version=SPACK_STRING"\n"GAL_STRINGS_COPYRIGHT
-  "\n\nWritten by Mohammad Akhlaghi";
-const char *argp_program_bug_address=PACKAGE_BUGREPORT;
-static char args_doc[] = "[matrix.txt] ASTRdata ...";
-
-
-
-
-
-const char doc[] =
-  /* Before the list of options: */
-  GAL_STRINGS_TOP_HELP_INFO
-  SPACK_NAME" will warp/transform the input image using an input coordinate "
-  "matrix. Currently it accepts any general projective mapping (which "
-  "includes affine mappings as a subset). \n"
-  GAL_STRINGS_MORE_HELP_INFO
-  /* After the list of options: */
-  "\v"
-  PACKAGE_NAME" home page: "PACKAGE_URL;
-
-
-
-
-
-/* Available letters for short options:
-
-   c g i j k l u v w x y
-   A B C E F G H I J L M O Q R T U W X Y Z
-
-   Number keys used: <=503
-
-   Options with keys (second structure element) larger than 500 do not
-   have a short version.
- */
-static struct argp_option options[] =
+/* Array of acceptable options. */
+struct argp_option program_options[] =
   {
-    {
-      0, 0, 0, 0,
-      "Input:",
-      1
-    },
-    {
-      "matrix",
-      'm',
-      "STR",
-      0,
-      "Warp/Transform matrix elements.",
-      1
-    },
+
+    /* Input. */
     {
       "hstartwcs",
-      501,
+      ARGS_OPTION_KEY_HSTARTWCS,
       "INT",
       0,
       "Header keyword number to start reading WCS.",
-      1
+      GAL_OPTIONS_GROUP_INPUT,
+      &p->hstartwcs,
+      GAL_DATA_TYPE_SIZE_T,
+      GAL_OPTIONS_RANGE_GT_0,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "hendwcs",
-      502,
+      ARGS_OPTION_KEY_HENDWCS,
       "INT",
       0,
-      "Header keyword number to stop reading WCS.",
-      1
+      "Header keyword number to end reading WCS.",
+      GAL_OPTIONS_GROUP_INPUT,
+      &p->hendwcs,
+      GAL_DATA_TYPE_SIZE_T,
+      GAL_OPTIONS_RANGE_GT_0,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
-    {
-      "nofitscorrect",
-      503,
-      0,
-      0,
-      "Do not shift to correct for FITS positioning.",
-      1
-    },
-
 
 
 
-
-
-    {
-      0, 0, 0, 0,
-      "Output:",
-      2
-    },
-    {
-      "nowcscorrection",
-      'n',
-      0,
-      0,
-      "Do not correct input image WCS.",
-      2
-    },
+    /* Output. */
     {
-      "zerofornoinput",
-      'z',
+      "keepinputwcs",
+      ARGS_OPTION_KEY_KEEPINPUTWCS,
       0,
       0,
-      "Set pixels with no input to zero not blank.",
-      2
-    },
-    {
-      "doubletype",
-      'd',
-      0,
-      0,
-      "Do not convert output to input image type.",
-      2
+      "Do not apply warp to input's WCS",
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->keepinputwcs,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "maxblankfrac",
-      'b',
+      ARGS_OPTION_KEY_MAXBLANKFRAC,
       "FLT",
       0,
       "Maximum fraction of area covered by blank.",
-      2
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->maxblankfrac,
+      GAL_DATA_TYPE_FLOAT,
+      GAL_OPTIONS_RANGE_GE_0_LE_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
+    },
+    {
+      "type",
+      ARGS_OPTION_KEY_TYPE,
+      "STR",
+      0,
+      "uchar, short, long, longlong, float, double."
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->typestr,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
-
-
 
 
     {
       0, 0, 0, 0,
-      "Modular warpings:",
-      3
+      "Warps:",
+      ARGS_GROUP_WARPS
     },
     {
       "align",
-      'a',
-      0,
-      0,
-      "Align the image and celestial axes.",
-      3
-    },
-    {
-      "rotate",
-      'r',
-      "FLT",
-      0,
-      "Rotate by the given angle in degrees.",
-      3
-    },
-    {
-      "scale",
-      's',
-      "FLT[,FLT]",
+      ARGS_OPTION_KEY_ALIGN,
       0,
-      "Scale along the given axis(es).",
-      3
-    },
-    {
-      "flip",
-      'f',
-      "FLT[,FLT]",
       0,
-      "Flip along the given axis(es).",
-      3
+      "Align the image and celestial axes."
+      ARGS_GROUP_WARPS,
+      &p->align,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
-      "shear",
-      'e',
-      "FLT[,FLT]",
-      0,
-      "Shear along the given axis(es).",
-      3
-    },
-    {
-      "translate",
-      't',
-      "FLT[,FLT]",
-      0,
-      "Translate along the given axis(es).",
-      3
-    },
-    {
-      "project",
-      'p',
-      "FLT[,FLT]",
+      "type",
+      ARGS_OPTION_KEY_TYPE,
+      "STR",
       0,
-      "Project along the given axis(es).",
-      3
+      "uchar, short, long, longlong, float, double."
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->typestr,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
 
 
 
-    {
-      0, 0, 0, 0,
-      "Operating modes:",
-      -1
-    },
-
-
     {0}
   };
 
@@ -244,160 +146,21 @@ static struct argp_option options[] =
 
 
 
-/* Parse a single option: */
-static error_t
-parse_opt(int key, char *arg, struct argp_state *state)
-{
-  /* Save the arguments structure: */
-  struct imgwarpparams *p = state->input;
-
-  /* Set the pointer to the common parameters for all programs
-     here: */
-  state->child_inputs[0]=&p->cp;
-
-  /* In case the user incorrectly uses the equal sign (for example
-     with a short format or with space in the long format, then `arg`
-     start with (if the short version was called) or be (if the long
-     version was called with a space) the equal sign. So, here we
-     check if the first character of arg is the equal sign, then the
-     user is warned and the program is stopped: */
-  if(arg && arg[0]=='=')
-    argp_error(state, "incorrect use of the equal sign (`=`). For short "
-               "options, `=` should not be used and for long options, "
-               "there should be no space between the option, equal sign "
-               "and value");
-
-  switch(key)
-    {
-
-
-    /* Input: */
-    case 'm':
-      p->up.matrixstring=arg;
-      p->up.matrixstringset=1;
-      break;
-    case 501:
-      gal_checkset_sizet_el_zero(arg, &p->hstartwcs, "hstartwcs", key, SPACK,
-                                 NULL, 0);
-      p->up.hstartwcsset=1;
-      break;
-    case 502:
-      gal_checkset_sizet_el_zero(arg, &p->hendwcs, "hendwcs", key, SPACK,
-                                 NULL, 0);
-      p->up.hendwcsset=1;
-      break;
-
-
-    /* Output: */
-    case 'n':
-      p->correctwcs=0;
-      break;
-    case 'z':
-      p->zerofornoinput=1;
-      break;
-    case 'd':
-      p->doubletype=1;
-      break;
-    case 'b':
-      gal_checkset_float_l_0_s_1(arg, &p->maxblankfrac, "maxblankfrac", key,
-                                 SPACK, NULL, 0);
-      p->up.maxblankfracset=1;
-      break;
-    case 503:
-      p->up.nofitscorrect=1;
-      p->up.nofitscorrectset=1;
-      break;
+/* Define the child argp structure. */
+struct argp
+gal_options_common_child = {gal_commonopts_options,
+                            gal_options_common_argp_parse,
+                            NULL, NULL, NULL, NULL, NULL};
 
+/* Use the child argp structure in list of children (only one for now). */
+struct argp_child
+children[]=
+{
+  {&gal_options_common_child, 0, NULL, 0},
+  {0, 0, 0, 0}
+};
 
-    /* Modular warpings */
-    case 'a':
-      add_to_optionwapsll(&p->up.owll, ALIGN_WARP, NULL);
-      break;
-    case 'r':
-      add_to_optionwapsll(&p->up.owll, ROTATE_WARP, arg);
-      break;
-    case 's':
-      add_to_optionwapsll(&p->up.owll, SCALE_WARP, arg);
-      break;
-    case 'f':
-      add_to_optionwapsll(&p->up.owll, FLIP_WARP, arg);
-      break;
-    case 'e':
-      add_to_optionwapsll(&p->up.owll, SHEAR_WARP, arg);
-      break;
-    case 't':
-      add_to_optionwapsll(&p->up.owll, TRANSLATE_WARP, arg);
-      break;
-    case 'p':
-      add_to_optionwapsll(&p->up.owll, PROJECT_WARP, arg);
-      break;
-
-
-
-    /* Read the non-option arguments: */
-    case ARGP_KEY_ARG:
-
-      /* See what type of input value it is and put it in. */
-      if( gal_fits_name_is_fits(arg) )
-        {
-          if(p->up.inputname)
-            argp_error(state, "only one input image should be given");
-          else
-            p->up.inputname=arg;
-        }
-      else
-        {
-          if(p->up.matrixname)
-            argp_error(state, "only one warp/transformation matrix "
-                       "should be given");
-          else
-            p->up.matrixname=arg;
-        }
-      break;
-
-
-
-
-
-    /* The command line options and arguments are finished. */
-    case ARGP_KEY_END:
-      if(p->cp.setdirconf==0 && p->cp.setusrconf==0
-         && p->cp.printparams==0)
-        {
-          if(state->arg_num==0)
-            argp_error(state, "no argument given");
-          if(p->up.inputname==NULL)
-            argp_error(state, "no input FITS image(s) provided");
-        }
-      break;
-
-
-
-
-
-    default:
-      return ARGP_ERR_UNKNOWN;
-    }
-  return 0;
-}
-
-
-
-
-
-/* Specify the children parsers: */
-struct argp_child children[]=
-  {
-    {&commonargp, 0, NULL, 0},
-    {0, 0, 0, 0}
-  };
-
-
-
-
-
-/* Basic structure defining the whole argument reading process. */
-static struct argp thisargp = {options, parse_opt, args_doc,
-                               doc, children, NULL, NULL};
-
+/* Set all the necessary argp parameters. */
+struct argp
+thisargp = {program_options, parse_opt, args_doc, doc, children, NULL, NULL};
 #endif
diff --git a/bin/imgwarp/main.c b/bin/imgwarp/main.c
index be186da..86a21d9 100644
--- a/bin/imgwarp/main.c
+++ b/bin/imgwarp/main.c
@@ -42,13 +42,13 @@ main (int argc, char *argv[])
   gettimeofday(&t1, NULL);
 
   /* Read the input parameters. */
-  setparams(argc, argv, &p);
+  ui_read_check_inputs_setup(argc, argv, &p);
 
   /* Run ImageWarp */
   imgwarp(&p);
 
   /* Free all non-freed allocations. */
-  freeandreport(&p, &t1);
+  ui_free_report(&p, &t1);
 
   /* Return successfully.*/
   return EXIT_SUCCESS;
diff --git a/bin/imgwarp/main.h b/bin/imgwarp/main.h
index 79233d7..4b65e8b 100644
--- a/bin/imgwarp/main.h
+++ b/bin/imgwarp/main.h
@@ -5,7 +5,7 @@ ImageWarp is part of GNU Astronomy Utilities (Gnuastro) package.
 Original author:
      Mohammad Akhlaghi <address@hidden>
 Contributing author(s):
-Copyright (C) 2015, Free Software Foundation, Inc.
+Copyright (C) 2016, Free Software Foundation, Inc.
 
 Gnuastro is free software: you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
@@ -23,22 +23,19 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #ifndef MAIN_H
 #define MAIN_H
 
-#include <pthread.h>
+/* Include necessary headers */
+#include <gnuastro/data.h>
 
-#include <commonparams.h>
+#include <options.h>
 
+/* Progarm names.  */
+#define PROGRAM_NAME   "ImageWarp"      /* Program full name.       */
+#define PROGRAM_EXEC   "astimgwarp"     /* Program executable name. */
+#define PROGRAM_STRING PROGRAM_NAME" (" PACKAGE_NAME ") " PACKAGE_VERSION
 
 
 
 
-/* Progarm name macros: */
-#define SPACK           "astimgwarp" /* Subpackage executable name. */
-#define SPACK_NAME      "ImageWarp"  /* Subpackage full name.       */
-#define SPACK_STRING    SPACK_NAME" ("PACKAGE_NAME") "PACKAGE_VERSION
-#define LOGFILENAME     SPACK".log"
-
-
-
 
 
 struct optionwarpsll
@@ -53,51 +50,30 @@ struct optionwarpsll
 
 
 
-struct uiparams
-{
-  char        *inputname;  /* Name of input file.                      */
-  char       *matrixname;  /* Name of transform file.                  */
-  char     *matrixstring;  /* String containing transform elements.    */
-
-  struct optionwarpsll *owll;    /* List of 2D rotations.              */
-  int      nofitscorrect;  /* No corr the 0.5 pixel necessary in FITS. */
-  int   nofitscorrectset;
-
-  int    matrixstringset;
-  int    maxblankfracset;
-  int       hstartwcsset;
-  int         hendwcsset;
-};
-
-
-
-
-
 struct imgwarpparams
 {
-  /* Other structures: */
-  struct uiparams      up;  /* User interface parameters.                */
-  struct gal_commonparams cp; /* Common parameters.                      */
-
-  /* Input: */
-  double           *input;  /* Name of input FITS file.                  */
-  double        matrix[9];  /* Warp/Transformation matrix.               */
-  size_t              is0;  /* Number of rows in input image.            */
-  size_t              is1;  /* Number of columns in input image.         */
-  int         inputbitpix;  /* The type of the input array.              */
-  int                nwcs;  /* Number of WCS structures.                 */
-  struct wcsprm      *wcs;  /* Pointer to WCS structures.                */
+  /* From command-line */
+  struct gal_options_common_params cp; /* Common parameters.             */
+  struct optionwarpsll *owll;    /* List of 2D rotations.                */
+  char         *inputname;  /* Name of input file.                       */
   size_t        hstartwcs;  /* Header keyword No. to start reading WCS.  */
   size_t          hendwcs;  /* Header keyword No. to end reading WCS.    */
-
-  /* Output: */
-  size_t           numnul;  /* Number of blank pixels in output.         */
-  int          correctwcs;  /* Wrap the warped/transfomed pixels.        */
-  int          doubletype;  /* Save output in double not in input type.  */
-  int      zerofornoinput;  /* Set the pixels with no input to zero.     */
+  unsigned char keepinputwcs;  /* Wrap the warped/transfomed pixels.     */
   float      maxblankfrac;  /* Maximum fraction of blank pixel in out.   */
+  char           *typestr;  /* Type of output image.                     */
+  unsigned char     align;  /* Align the image with celestial coord.     */
+  char         *rotatestr;  /* String given for rotation.                */
+  char          *scalestr;  /* String given for scaling.                 */
+  char           *flipstr;  /* String given for flipping.                */
+  char          *shearstr;  /* String given for shearing.                */
+  char      *translatestr;  /* String given for translation.             */
+  char        *projectstr;  /* String given for projection.              */
+  char         *matrixstr;  /* String containing transform elements.     */
 
   /* Internal parameters: */
+  gal_data_t       *input;  /* Name of input FITS file.                  */
+  int             outtype;  /* Output type.                              */
+  double        matrix[9];  /* Warp/Transformation matrix.               */
   double          *output;  /* Warped image array.                       */
   size_t        onaxes[2];  /* Output image size                         */
   size_t        knaxes[2];  /* Output image size                         */
diff --git a/bin/imgwarp/ui.c b/bin/imgwarp/ui.c
index 95a053c..20daafe 100644
--- a/bin/imgwarp/ui.c
+++ b/bin/imgwarp/ui.c
@@ -5,7 +5,7 @@ ImageWarp is part of GNU Astronomy Utilities (Gnuastro) package.
 Original author:
      Mohammad Akhlaghi <address@hidden>
 Contributing author(s):
-Copyright (C) 2015, Free Software Foundation, Inc.
+Copyright (C) 2016, Free Software Foundation, Inc.
 
 Gnuastro is free software: you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
@@ -22,238 +22,91 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 **********************************************************************/
 #include <config.h>
 
-#include <stdio.h>
+#include <argp.h>
 #include <errno.h>
 #include <error.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fitsio.h>
-
-#include <nproc.h>               /* From Gnulib.                   */
+#include <stdio.h>
 
-#include <gnuastro/wcs.h>
 #include <gnuastro/fits.h>
-#include <gnuastro/txtarray.h>
+#include <gnuastro/table.h>
+#include <gnuastro/linkedlist.h>
 
-#include <timing.h>              /* Includes time.h and sys/time.h */
+#include <timing.h>
+#include <options.h>
 #include <checkset.h>
-#include <commonargs.h>
-#include <configfiles.h>
+#include <fixedstringmacros.h>
 
 #include "main.h"
 
-#include "ui.h"                  /* Needs main.h                   */
-#include "args.h"                /* Needs main.h, includes argp.h. */
-
-
-/* Set the file names of the places where the default parameters are
-   put. */
-#define CONFIG_FILE SPACK CONF_POSTFIX
-#define SYSCONFIG_FILE SYSCONFIG_DIR "/" CONFIG_FILE
-#define USERCONFIG_FILEEND USERCONFIG_DIR CONFIG_FILE
-#define CURDIRCONFIG_FILE CURDIRCONFIG_DIR CONFIG_FILE
-
-
-
-
-
+#include "ui.h"
+#include "authors-cite.h"
 
 
 
 
 
 /**************************************************************/
-/**************       Options and parameters    ***************/
+/*********      Argp necessary global entities     ************/
 /**************************************************************/
-void
-readconfig(char *filename, struct imgwarpparams *p)
-{
-  FILE *fp;
-  size_t lineno=0, len=200;
-  char *line, *name, *value;
-  struct uiparams *up=&p->up;
-  struct gal_commonparams *cp=&p->cp;
-  char key='a';        /* Not used, just a place holder. */
-
-  /* When the file doesn't exist or can't be opened, it is ignored. It
-     might be intentional, so there is no error. If a parameter is
-     missing, it will be reported after all defaults are read. */
-  fp=fopen(filename, "r");
-  if (fp==NULL) return;
-
-
-  /* Allocate some space for `line` with `len` elements so it can
-     easily be freed later on. The value of `len` is arbitarary at
-     this point, during the run, getline will change it along with the
-     pointer to line. */
-  errno=0;
-  line=malloc(len*sizeof *line);
-  if(line==NULL)
-    error(EXIT_FAILURE, errno, "ui.c: %zu bytes in readdefaults",
-          len * sizeof *line);
-
-  /* Read the tokens in the file:  */
-  while(getline(&line, &len, fp) != -1)
-    {
-      /* Prepare the "name" and "value" strings, also set lineno. */
-      GAL_CONFIGFILES_START_READING_LINE;
-
+/* Definition parameters for the Argp: */
+const char *
+argp_program_version = PROGRAM_STRING "\n"
+                       GAL_STRINGS_COPYRIGHT
+                       "\n\nWritten/developed by "PROGRAM_AUTHORS;
 
+const char *
+argp_program_bug_address = PACKAGE_BUGREPORT;
 
+static char
+args_doc[] = "ASTRdata";
 
-      /* Inputs: */
-      if(strcmp(name, "hdu")==0)
-        gal_checkset_allocate_copy_set(value, &cp->hdu, &cp->hduset);
-      else if(strcmp(name, "hstartwcs")==0)
-        {
-          if(up->hstartwcsset) continue;
-          gal_checkset_sizet_el_zero(value, &p->hstartwcs, name, key,
-                                     SPACK, filename, lineno);
-          up->hstartwcsset=1;
-        }
-      else if(strcmp(name, "hendwcs")==0)
-        {
-          if(up->hendwcsset) continue;
-          gal_checkset_sizet_el_zero(value, &p->hendwcs, name, key, SPACK,
-                                     filename, lineno);
-          up->hendwcsset=1;
-        }
-
-
-
-
-
-      /* Outputs */
-      else if(strcmp(name, "matrix")==0)
-        gal_checkset_allocate_copy_set(value, &up->matrixstring,
-                                       &up->matrixstringset);
-
-      else if(strcmp(name, "output")==0)
-        gal_checkset_allocate_copy_set(value, &cp->output, &cp->outputset);
-
-      else if(strcmp(name, "maxblankfrac")==0)
-        {
-          if(up->maxblankfracset) continue;
-          gal_checkset_float_l_0_s_1(value, &p->maxblankfrac, name, key,
-                                     SPACK, filename, lineno);
-          up->maxblankfracset=1;
-        }
-      else if(strcmp(name, "nofitscorrect")==0)
-        {
-          if(up->nofitscorrectset) continue;
-          gal_checkset_int_zero_or_one(value, &up->nofitscorrect, name,
-                                       key, SPACK, filename, lineno);
-          up->nofitscorrectset=1;
-        }
-
+const char
+doc[] = GAL_STRINGS_TOP_HELP_INFO PROGRAM_NAME" will warp/transform the "
+  "input image using an input coordinate matrix. Currently it accepts any "
+  "general projective mapping (which includes affine mappings as a "
+  "subset). \n"
+  GAL_STRINGS_MORE_HELP_INFO
+  /* After the list of options: */
+  "\v"
+  PACKAGE_NAME" home page: "PACKAGE_URL;
 
 
 
 
-      /* Modular warpings */
-      else if(strcmp(name, "align")==0)
-        add_to_optionwapsll(&p->up.owll, ALIGN_WARP, NULL);
-
-      else if(strcmp(name, "rotate")==0)
-        add_to_optionwapsll(&p->up.owll, ROTATE_WARP, value);
-
-      else if(strcmp(name, "scale")==0)
-        add_to_optionwapsll(&p->up.owll, SCALE_WARP, value);
-
-      else if(strcmp(name, "flip")==0)
-        add_to_optionwapsll(&p->up.owll, FLIP_WARP, value);
-
-      else if(strcmp(name, "shear")==0)
-        add_to_optionwapsll(&p->up.owll, SHEAR_WARP, value);
-
-      else if(strcmp(name, "translate")==0)
-        add_to_optionwapsll(&p->up.owll, TRANSLATE_WARP, value);
-
-      else if(strcmp(name, "project")==0)
-        add_to_optionwapsll(&p->up.owll, PROJECT_WARP, value);
-
-
-
-      /* Operating modes: */
-      /* Read options common to all programs */
-      GAL_CONFIGFILES_READ_COMMONOPTIONS_FROM_CONF
-
-
-      else
-        error_at_line(EXIT_FAILURE, 0, filename, lineno,
-                      "`%s` not recognized.\n", name);
-    }
-
-  free(line);
-  fclose(fp);
-}
-
-
-
-
-
-void
-printvalues(FILE *fp, struct imgwarpparams *p)
+/* Option groups particular to this program. */
+enum program_args_groups
 {
-  struct uiparams *up=&p->up;
-  struct gal_commonparams *cp=&p->cp;
-
-  /* Print all the options that are set. Separate each group with a
-     commented line explaining the options in that group. */
-  fprintf(fp, "\n# Input image:\n");
-  if(cp->hduset)
-    GAL_CHECKSET_PRINT_STRING_MAYBE_WITH_SPACE("hdu", cp->hdu);
-  if(up->hstartwcsset)
-    fprintf(fp, CONF_SHOWFMT"%zu\n", "hstartwcs", p->hstartwcs);
-  if(up->hendwcsset)
-    fprintf(fp, CONF_SHOWFMT"%zu\n", "hendwcs", p->hendwcs);
-
-  fprintf(fp, "\n# Output parameters:\n");
-  if(up->matrixstringset)
-    GAL_CHECKSET_PRINT_STRING_MAYBE_WITH_SPACE("matrix", up->matrixstring);
-
-  if(cp->outputset)
-    GAL_CHECKSET_PRINT_STRING_MAYBE_WITH_SPACE("output", cp->output);
+  ARGS_GROUP_WARPS = GAL_OPTIONS_GROUP_AFTER_COMMON,
+};
 
-  if(up->maxblankfracset)
-    fprintf(fp, CONF_SHOWFMT"%.3f\n", "maxblankfrac", p->maxblankfrac);
-
-
-
-  fprintf(fp, "\n# Modular transformations:\n");
-  if(up->nofitscorrectset)
-    fprintf(fp, CONF_SHOWFMT"%d\n", "nofitscorrect", up->nofitscorrect);
-
-
-
-  /* For the operating mode, first put the macro to print the common
-     options, then the (possible options particular to this
-     program). */
-  fprintf(fp, "\n# Operating mode:\n");
-  GAL_CONFIGFILES_PRINT_COMMONOPTIONS;
-}
 
 
 
 
+/* Available letters for short options:
 
-
-/* Note that numthreads will be used automatically based on the
-   configure time. */
-void
-checkifset(struct imgwarpparams *p)
+   c g i j k l u v w x y
+   A B C E F G H I J L M O Q R T U W X Y Z  */
+enum option_keys_enum
 {
-  struct uiparams *up=&p->up;
-  struct gal_commonparams *cp=&p->cp;
+  /* With short-option version. */
+  ARGS_OPTION_KEY_KEEPINPUTWCS    = 'n',
+  ARGS_OPTION_KEY_MAXBLANKFRAC    = 'b',
+  ARGS_OPTION_KEY_TYPE            = 'T',
+  ARGS_OPTION_KEY_ALIGN           = 'a',
+  ARGS_OPTION_KEY_ROTATE          = 'r',
+  ARGS_OPTION_KEY_SCALE           = 's',
+  ARGS_OPTION_KEY_FLIP            = 'f',
+  ARGS_OPTION_KEY_SHEAR           = 'e',
+  ARGS_OPTION_KEY_TRANSLATE       = 't',
+  ARGS_OPTION_KEY_PROJECT         = 'p',
+  ARGS_OPTION_KEY_MATRIX          = 'm',
 
-  int intro=0;
-  if(cp->hduset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("hdu");
-  if(up->maxblankfracset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("maxblankfrac");
-
-  GAL_CONFIGFILES_END_OF_NOTSET_REPORT;
-}
+  /* Only with long version (start with a value 1000, the rest will be set
+     automatically). */
+  ARGS_OPTION_KEY_HSTARTWCS   = 1000,
+  ARGS_OPTION_KEY_HENDWCS,
+};
 
 
 
@@ -274,154 +127,82 @@ checkifset(struct imgwarpparams *p)
 
 
 /**************************************************************/
-/**********      Modular matrix linked list       *************/
+/*********    Initialize & Parse command-line    **************/
 /**************************************************************/
-void
-add_to_optionwapsll(struct optionwarpsll **list, int type, char *value)
+static void
+ui_initialize_options(struct tableparams *p,
+                      struct argp_option *program_options,
+                      struct argp_option *gal_commonopts_options)
 {
-  double v1=NAN, v2=NAN;
-  char *tailptr, *secondstr;
-  struct optionwarpsll *newnode;
-
-  /* Allocate the necessary space. */
-  errno=0;
-  newnode=malloc(sizeof *newnode);
-  if(newnode==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for newnode in "
-          "add_to_optionwarpsll", sizeof *newnode);
-
-  /* Read the numbers when necessary. */
-  if(value)
-    {
-      /* Parse the first number */
-      v1=strtod(value, &tailptr);
-      if(tailptr==value)
-        error(EXIT_FAILURE, 0, "The start of the string `%s' could not be "
-              "read as a number", value);
-
-      /* If there is any white space characters, ignore them and make sure
-         that the first character is a coma (`,'). */
-      secondstr=tailptr;
-      while(isspace(*secondstr)) ++secondstr;
-      if(*secondstr==',')
-        {
-          /* If the type is rotate, then print an error since rotate only
-             needs one input, not two. */
-          if(type==ROTATE_WARP)
-            error(EXIT_FAILURE, 0, "The `--rotate' (`-r') option only needs "
-                  "one input number, not more. It was given `%s'", value);
-
-          /* Ignore the coma. */
-          ++secondstr;
-
-          /* Read the second number: */
-          v2=strtod(secondstr, &tailptr);
-          if(tailptr==secondstr)
-            error(EXIT_FAILURE, 0, "The second part (after the coma) of "
-                  "`%s' (`%s') could not be read as a number", value,
-                  secondstr);
-        }
-
-      /* If there was only one number given, secondstr will be '\0' when
-         control reaches here. */
-      else if(*secondstr!='\0')
-        error(EXIT_FAILURE, 0, "the character between the two numbers (`%s') "
-              "must be a coma (`,')\n", value);
-    }
-
-  /* Put in the values. Note that both v1 and v2 were initialized to NaN,
-     so if v2 is not given, it will be NaN and the later function can
-     decide what it wants to replace it with.*/
-  newnode->v1=v1;
-  newnode->v2=v2;
-  newnode->type=type;
-  newnode->next=*list;
-
-  /* Set list to point to the new node. */
-  *list=newnode;
-}
+  size_t i;
+  struct gal_options_common_params *cp=&p->cp;
 
 
+  /* Set the necessary common parameters structure. */
+  cp->poptions           = program_options;
+  cp->program_name       = PROGRAM_NAME;
+  cp->program_exec       = PROGRAM_EXEC;
+  cp->program_bibtex     = PROGRAM_BIBTEX;
+  cp->program_authors    = PROGRAM_AUTHORS;
+  cp->coptions           = gal_commonopts_options;
 
 
-
-/* Allocate space for a new node: */
-struct optionwarpsll *
-alloc_owll_node(void)
-{
-  struct optionwarpsll *newnode;
-
-  errno=0;
-  newnode=malloc(sizeof *newnode);
-  if(newnode==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for newnode in "
-          "add_to_optionwarpsll", sizeof *newnode);
-
-  return newnode;
+  /* Set the mandatory common options. */
+  for(i=0; !gal_options_is_last(&cp->coptions[i]); ++i)
+    switch(cp->coptions[i].key)
+      {
+      case GAL_OPTIONS_KEY_SEARCHIN:
+      case GAL_OPTIONS_KEY_MINMAPSIZE:
+      case GAL_OPTIONS_KEY_TABLEFORMAT:
+        cp->coptions[i].mandatory=GAL_OPTIONS_MANDATORY;
+        break;
+      }
 }
 
 
 
 
 
-/* The input list of warpings are recorded in a last-in-first-out order. So
-   we reverse the order and also add the transformations necessary for the
-   FITS definition (where the center of the pixel has a value of 1, not its
-   corner. */
-void
-prepare_optionwapsll(struct imgwarpparams *p)
+/* Parse a single option: */
+error_t
+parse_opt(int key, char *arg, struct argp_state *state)
 {
-  struct optionwarpsll *tmp, *next, *newnode, *prepared=NULL;
-
-  /* Add the FITS correction for the first warp (before everything else).
-
-     IMPORTANT: This is the last transform that will be done, so we have to
-     translate the image by -0.5.*/
-  if(!p->up.nofitscorrect)
+  struct tableparams *p = state->input;
+
+  /* Pass `gal_options_common_params' into the child parser.  */
+  state->child_inputs[0] = &p->cp;
+
+  /* In case the user incorrectly uses the equal sign (for example
+     with a short format or with space in the long format, then `arg`
+     start with (if the short version was called) or be (if the long
+     version was called with a space) the equal sign. So, here we
+     check if the first character of arg is the equal sign, then the
+     user is warned and the program is stopped: */
+  if(arg && arg[0]=='=')
+    argp_error(state, "incorrect use of the equal sign (`=`). For short "
+               "options, `=` should not be used and for long options, "
+               "there should be no space between the option, equal sign "
+               "and value");
+
+  /* Set the key to this option. */
+  switch(key)
     {
-      newnode = alloc_owll_node();
-      newnode->v1 = newnode->v2 = -0.5f;
-      newnode->type = TRANSLATE_WARP;
-      newnode->next = prepared;
-      prepared = newnode;
-    }
 
-  /* Put in the rest of the warpings */
-  tmp=p->up.owll;
-  while(tmp!=NULL)
-    {
-      /* Allocate space for the new element, and put the values in. */
-      newnode = alloc_owll_node();
-      newnode->v1 = tmp->v1;
-      newnode->v2 = tmp->v2;
-      newnode->type = tmp->type;
-      newnode->next = prepared;
-
-      /* Now that previous nodes have been linked to next, set the
-         reversed to the new node. */
-      prepared = newnode;
-
-      /* Now keep the next element and free the old allocated space. */
-      next = tmp->next;
-      free(tmp);
-      tmp = next;
-    }
+    /* Read the non-option tokens (arguments): */
+    case ARGP_KEY_ARG:
+      if(p->filename)
+        argp_error(state, "only one argument (input file) should be given");
+      else
+        p->filename=arg;
+      break;
 
-  /* Add the FITS correction for the last warp (after everything else).
 
-     IMPORTANT: This is the first transform that will be done, so we have
-     to translate the image by +0.5.*/
-  if(!p->up.nofitscorrect)
-    {
-      newnode = alloc_owll_node();
-      newnode->v1 = newnode->v2 = 0.5f;
-      newnode->type = TRANSLATE_WARP;
-      newnode->next = prepared;
-      prepared = newnode;
+    /* This is an option, set its value. */
+    default:
+      return gal_options_set_from_key(key, arg, p->cp.poptions, &p->cp);
     }
 
-  /* Put the pointer in the output */
-  p->up.owll=prepared;
+  return 0;
 }
 
 
@@ -444,194 +225,40 @@ prepare_optionwapsll(struct imgwarpparams *p)
 
 
 /**************************************************************/
-/*************      Fill temporary matrix     *****************/
+/***************       Sanity Check         *******************/
 /**************************************************************/
-void
-read_matrix(struct imgwarpparams *p)
+/* Read and check ONLY the options. When arguments are involved, do the
+   check in `ui_check_options_and_arguments'. */
+static void
+ui_read_check_only_options(struct tableparams *p)
 {
-  char *t, *tailptr;
-  size_t i, counter=0, m0, m1;
-  double *matrix=p->matrix, rmatrix[9], *fmatrix;
 
-  /* Read the matrix either as a file or from the command-line. */
-  if(p->up.matrixname)
-    {
-      gal_txtarray_txt_to_array(p->up.matrixname, &fmatrix, &m0, &m1);
-      counter=m0*m1;
-      for(i=0;i<(counter<9 ? counter : 9);++i)
-        rmatrix[i]=fmatrix[i];
-      free(fmatrix);
-    }
-  else
-    {
-      t=p->up.matrixstring;
-      while(*t!='\0')
-        {
-          switch(*t)
-            {
-            case ' ': case '\t': case ',':
-              ++t;
-              break;
-            default:
-              errno=0;
-              rmatrix[counter++]=strtod(t, &tailptr);
-              if(errno) error(EXIT_FAILURE, errno, "reading `%s`", t);
-              if(tailptr==t)
-                error(EXIT_FAILURE, 0, "the provided string `%s' for "
-                      "matrix could not be read as a number", t);
-              t=tailptr;
-              if(counter>9)       /* Note that it was incremented! */
-                error(EXIT_FAILURE, 0, "there are %zu elements in `%s', "
-                      "there should be 4 or 9", counter, p->up.matrixstring);
-              /*printf("%f, %s\n", p->matrix[counter-1], t);*/
-            }
-        }
-    }
+  /* Check if the format of the output table is valid, given the type of
+     the output. */
+  gal_table_check_fits_format(p->cp.output, p->cp.tableformat);
 
-  /* If there was 4 elements (a 2 by 2 matrix), put them into a 3 by 3
-     matrix. */
-  if(counter==4)
-    {
-      /* Fill in the easy 3 by 3 matrix: */
-      matrix[0]=rmatrix[0];   matrix[1]=rmatrix[1];
-      matrix[3]=rmatrix[2];   matrix[4]=rmatrix[3];
-      matrix[6]=0.0f;         matrix[7]=0.0f;         matrix[8]=1.0f;
-
-      /* If we need to correct for the FITS standard, then correc the last
-         two elements. Recall that the coordinates of the center of the
-         first pixel in the FITS standard are 1. We want 0 to be the
-         coordinates of the bottom corner of the image.
-
-         1  0  0.5      a  b  0      a  b  0.5
-         0  1  0.5   *  c  d  0   =  c  d  0.5
-         0  0   1       0  0  1      0  0   1
-
-         and
-
-         a  b  0.5     1  0  -0.5     a  b  (a*-0.5)+(b*-0.5)+0.5
-         c  d  0.5  *  0  1  -0.5  =  c  d  (c*-0.5)+(d*-0.5)+0.5
-         0  0   1      0  0   1       0  0           1
-      */
-      if(p->up.nofitscorrect)
-        matrix[2] = matrix[5] = 0.0f;
-      else
-        {
-          matrix[2] = ((rmatrix[0] + rmatrix[1]) * -0.5f) + 0.5f;
-          matrix[5] = ((rmatrix[2] + rmatrix[3]) * -0.5f) + 0.5f;
-        }
-    }
-  else if (counter==9)
-    {
-      matrix[0]=rmatrix[0];   matrix[1]=rmatrix[1];   matrix[2]=rmatrix[2];
-      matrix[3]=rmatrix[3];   matrix[4]=rmatrix[4];   matrix[5]=rmatrix[5];
-      matrix[6]=rmatrix[6];   matrix[7]=rmatrix[7];   matrix[8]=rmatrix[8];
-    }
-  else
-    error(EXIT_FAILURE, 0, "there are %zu numbers in the string `%s'! "
-          "It should contain 4 or 9 numbers (for a 2 by 2 or 3 by 3 "
-          "matrix)", counter, p->up.matrixstring);
 }
 
 
 
 
 
-/* Set the matrix so the image is aligned with the axises. Note that
-   WCSLIB automatically fills the CRPI */
-void
-makealignmatrix(struct imgwarpparams *p, double *tmatrix)
+static void
+ui_check_options_and_arguments(struct tableparams *p)
 {
-  double A, *w, *ps, amatrix[4];
-
-  /* Check if there is only two WCS axises: */
-  if(p->wcs->naxis!=2)
-    error(EXIT_FAILURE, 0, "the WCS structure of %s (hdu: %s) has %d "
-          "axises. For the `--align' option to operate it must be 2",
-          p->up.inputname, p->cp.hdu, p->wcs->naxis);
-
-
-  /* Find the pixel scale along the two dimensions. Note that we will be
-     using the scale along the image X axis for both values. */
-  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
-     value: `a' (which is the pixel scale):
-
-        x0  x1       w0  w1      -a  0
-        x2  x3   *   w2  w3   =   0  a
-
-     Let's open up the matrix multiplication, so we can find the `X'
-     elements as function of the `W' elements and `a'.
-
-        x0*w0 + x1*w2 = -a                                         (1)
-        x0*w1 + x1*w3 =  0                                         (2)
-        x2*w0 + x3*w2 =  0                                         (3)
-        x2*w1 + x3*w3 =  a                                         (4)
-
-     Let's bring the X with the smaller index in each equation to the left
-     side:
-
-        x0 = (-w2/w0)*x1 - a/w0                                    (5)
-        x0 = (-w3/w1)*x1                                           (6)
-        x2 = (-w2/w0)*x3                                           (7)
-        x2 = (-w3/w1)*x3 + a/w1                                    (8)
-
-    Using (5) and (6) we can find x0 and x1, by first eliminating x0:
-
-       (-w2/w0)*x1 - a/w0 = (-w3/w1)*x1 -> (w3/w1 - w2/w0) * x1 = a/w0
-
-    For easy reading/writing, let's define: A = (w3/w1 - w2/w0)
-
-       --> x1 = a / w0 / A
-       --> x0 = -1 * x1 * w3 / w1
-
-    Similar to the above, we can find x2 and x3 from (7) and (8):
-
-       (-w2/w0)*x3 = (-w3/w1)*x3 + a/w1 -> (w3/w1 - w2/w0) * x3 = a/w1
-
-       --> x3 = a / w1 / A
-       --> x2 = -1 * x3 * w2 / w0
-
-    Note that when the image is already aligned, a unity matrix should be
-    output.
-   */
-  if( w[1]==0.0f && w[2]==0.0f )
+  /* Make sure an input file name was given and if it was a FITS file, that
+     a HDU is also given. */
+  if(p->filename)
     {
-      amatrix[0]=1.0f;   amatrix[1]=0.0f;
-      amatrix[2]=0.0f;   amatrix[3]=1.0f;
+      if( gal_fits_name_is_fits(p->filename) && p->cp.hdu==NULL )
+        error(EXIT_FAILURE, 0, "no HDU specified. When the input is a FITS "
+              "file, a HDU must also be specified, you can use the `--hdu' "
+              "(`-h') option and give it the HDU number (starting from "
+              "zero), extension name, or anything acceptable by CFITSIO");
+
     }
   else
-    {
-      A = (w[3]/w[1]) - (w[2]/w[0]);
-      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("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);
+    error(EXIT_FAILURE, 0, "no input file is specified");
 }
 
 
@@ -652,170 +279,89 @@ makealignmatrix(struct imgwarpparams *p, double *tmatrix)
 
 
 
+
 /**************************************************************/
-/***************       Prepare Matrix       *******************/
+/***************       Preparations         *******************/
 /**************************************************************/
-/* This function is mainly for easy checking/debugging. */
-void
-printmatrix(double *matrix)
-{
-  printf("%-10.3f%-10.3f%-10.3f\n", matrix[0], matrix[1], matrix[2]);
-  printf("%-10.3f%-10.3f%-10.3f\n", matrix[3], matrix[4], matrix[5]);
-  printf("%-10.3f%-10.3f%-10.3f\n", matrix[6], matrix[7], matrix[8]);
-}
-
-
-
-
-
 void
-inplace_matrix_multiply(double *in, double *with)
+ui_preparations(struct tableparams *p)
 {
-  /* `tin' will keep the values of the input array because we want to
-     write the multiplication result in the input array. */
-  double tin[9]={in[0],in[1],in[2],in[3],in[4],in[5],in[6],in[7],in[8]};
-
-  /* For easy checking, here are the matrix/memory layouts:
-          tin[0] tin[1] tin[2]     with[0] with[1] with[2]
-          tin[3] tin[4] tin[5]  *  with[3] with[4] with[5]
-          tin[6] tin[7] tin[8]     with[6] with[7] with[8]   */
-  in[0] = tin[0]*with[0] + tin[1]*with[3] + tin[2]*with[6];
-  in[1] = tin[0]*with[1] + tin[1]*with[4] + tin[2]*with[7];
-  in[2] = tin[0]*with[2] + tin[1]*with[5] + tin[2]*with[8];
-
-  in[3] = tin[3]*with[0] + tin[4]*with[3] + tin[5]*with[6];
-  in[4] = tin[3]*with[1] + tin[4]*with[4] + tin[5]*with[7];
-  in[5] = tin[3]*with[2] + tin[4]*with[5] + tin[5]*with[8];
-
-  in[6] = tin[6]*with[0] + tin[7]*with[3] + tin[8]*with[6];
-  in[7] = tin[6]*with[1] + tin[7]*with[4] + tin[8]*with[7];
-  in[8] = tin[6]*with[2] + tin[7]*with[5] + tin[8]*with[8];
-}
-
-
-
+  char *numstr;
+  int tableformat;
+  gal_data_t *allcols;
+  size_t i, numcols, numrows;
+  struct gal_options_common_params *cp=&p->cp;
+
+  /* If there were no columns specified, we want the full set of
+     columns. */
+  if(p->columns==NULL)
+    {
+      /* Read the table information for the number of columns and rows. */
+      allcols=gal_table_info(p->filename, cp->hdu, &numcols,
+                             &numrows, &tableformat);
 
+      /* If there was no actual data in the file, then inform the user */
+      if(allcols==NULL)
+        error(EXIT_FAILURE, 0, "%s: no usable data rows", p->filename);
 
-/* Fill in the warping matrix elements based on the options/arguments */
-void
-prepare_modular_matrix(struct imgwarpparams *p)
-{
-  int f1, f2;                   /* For flipping. */
-  double s, c, tmatrix[9];
-  struct uiparams *up=&p->up;
-  struct optionwarpsll *tmp, *next;
 
+      /* If the user just wanted information, then print it. */
+      if(p->information)
+        {
+          /* Print the file information. */
+          printf("--------\n");
+          printf("%s", p->filename);
+          if(gal_fits_name_is_fits(p->filename))
+            printf(" (hdu: %s)\n", cp->hdu);
+          else
+            printf("\n");
 
-  /* Allocate space for the matrix, then initialize it. */
-  p->matrix[0]=1.0f;     p->matrix[1]=0.0f;     p->matrix[2]=0.0f;
-  p->matrix[3]=0.0f;     p->matrix[4]=1.0f;     p->matrix[5]=0.0f;
-  p->matrix[6]=0.0f;     p->matrix[7]=0.0f;     p->matrix[8]=1.0f;
+          /* Print each column's information. */
+          gal_table_print_info(allcols, numcols, numrows);
+        }
 
 
-  /* The linked list is last-in-first-out, so we need to reverse it to
-     easily apply the changes in the same order that was read in. */
-  prepare_optionwapsll(p);
+      /* Free the information from all the columns. */
+      for(i=0;i<numcols;++i)
+        gal_data_free_contents(&allcols[i]);
+      free(allcols);
 
 
-  /* Do all the operations */
-  tmp=up->owll;
-  while(tmp!=NULL)
-    {
-      /* Fill `tmatrix' depending on the type of the warp. */
-      switch(tmp->type)
+      /* If the user just wanted information, then free the allocated
+         spaces and exit. Otherwise, add the number of columns to the list
+         if the user wanted to print the columns (didn't just want their
+         information. */
+      if(p->information)
         {
-        case ALIGN_WARP:
-          makealignmatrix(p, tmatrix);
-          break;
-
-        case ROTATE_WARP:
-          s = sin( tmp->v1*M_PI/180 );
-          c = cos( tmp->v1*M_PI/180 );
-          tmatrix[0]=c;        tmatrix[1]=s;     tmatrix[2]=0.0f;
-          tmatrix[3]=-1.0f*s;  tmatrix[4]=c;     tmatrix[5]=0.0f;
-          tmatrix[6]=0.0f;     tmatrix[7]=0.0f;  tmatrix[8]=1.0f;
-          break;
-
-        case SCALE_WARP:
-          if( isnan(tmp->v2) ) tmp->v2=tmp->v1;
-          tmatrix[0]=tmp->v1;  tmatrix[1]=0.0f;     tmatrix[2]=0.0f;
-          tmatrix[3]=0.0f;     tmatrix[4]=tmp->v2;  tmatrix[5]=0.0f;
-          tmatrix[6]=0.0f;     tmatrix[7]=0.0f;     tmatrix[8]=1.0f;
-          break;
-
-        case FLIP_WARP:
-          /* For the flip, the values dont really matter! As long as the
-             value is non-zero, the flip in the respective axis will be
-             made. Note that the second axis is optional (can be NaN), but
-             the first axis is required.*/
-          f1 = tmp->v1==0.0f ? 0 : 1;
-          f2 = isnan(tmp->v2) ? 0 : ( tmp->v2==0.0f ? 0 : 1);
-          if( f1 && !f2  )
-            {
-              tmatrix[0]=1.0f;   tmatrix[1]=0.0f;
-              tmatrix[3]=0.0f;   tmatrix[4]=-1.0f;
-            }
-          else if ( !f1 && f2 )
-            {
-              tmatrix[0]=-1.0f;  tmatrix[1]=0.0f;
-              tmatrix[3]=0.0f;   tmatrix[4]=1.0f;
-            }
-          else
-            {
-              tmatrix[0]=-1.0f;  tmatrix[1]=0.0f;
-              tmatrix[3]=0.0f;   tmatrix[4]=-1.0f;
-            }
-                                                      tmatrix[2]=0.0f;
-                                                      tmatrix[5]=0.0f;
-          tmatrix[6]=0.0f;       tmatrix[7]=0.0f;     tmatrix[8]=1.0f;
-          break;
-
-        case SHEAR_WARP:
-          if( isnan(tmp->v2) ) tmp->v2=tmp->v1;
-          tmatrix[0]=1.0f;     tmatrix[1]=tmp->v1;    tmatrix[2]=0.0f;
-          tmatrix[3]=tmp->v2;  tmatrix[4]=1.0f;       tmatrix[5]=0.0f;
-          tmatrix[6]=0.0f;     tmatrix[7]=0.0f;       tmatrix[8]=1.0f;
-          break;
-
-        case TRANSLATE_WARP:
-          if( isnan(tmp->v2) ) tmp->v2=tmp->v1;
-          tmatrix[0]=1.0f;     tmatrix[1]=0.0f;       tmatrix[2]=tmp->v1;
-          tmatrix[3]=0.0f;     tmatrix[4]=1.0f;       tmatrix[5]=tmp->v2;
-          tmatrix[6]=0.0f;     tmatrix[7]=0.0f;       tmatrix[8]=1.0f;
-          break;
-
-        case PROJECT_WARP:
-          if( isnan(tmp->v2) ) tmp->v2=tmp->v1;
-          tmatrix[0]=1.0f;     tmatrix[1]=0.0f;       tmatrix[2]=0.0f;
-          tmatrix[3]=0.0f;     tmatrix[4]=1.0f;       tmatrix[5]=0.0f;
-          tmatrix[6]=tmp->v1;  tmatrix[7]=tmp->v2;    tmatrix[8]=1.0f;
-          break;
-
-        default:
-          error(EXIT_FAILURE, 0, "a bug! Please contact us at %s so we can "
-                "address the problem. For some reason the value of tmp->type "
-                "in `prepare_modular_matrix' of ui.c is not recognized. "
-                "This is an internal, not a user issue. So please let us "
-                "know.", PACKAGE_BUGREPORT);
+          ui_free_report(p);
+          exit(EXIT_SUCCESS);
         }
-
-      /* Multiply this matrix with the main matrix in-place. */
-      inplace_matrix_multiply(p->matrix, tmatrix);
-
-      /* Keep the next element and free the node's allocated space. */
-      next = tmp->next;
-      free(tmp);
-      tmp = next;
-
-      /* For a check:
-      printf("tmatrix:\n");
-      printmatrix(tmatrix);
-      printf("out:\n");
-      printmatrix(p->matrix);
-      */
+      else
+        for(i=1;i<=numcols;++i)
+          {
+            asprintf(&numstr, "%zu", i);
+            gal_linkedlist_add_to_stll(&p->columns, numstr, 0);
+          }
     }
-}
 
+  /* Reverse the list of column search criteria that we are looking for
+     (since this is a last-in-first-out linked list, the order that
+     elements were added to the list is the reverse of the order that they
+     will be popped). */
+  gal_linkedlist_reverse_stll(&p->columns);
+  p->table=gal_table_read(p->filename, cp->hdu, p->columns, cp->searchin,
+                          cp->ignorecase, cp->minmapsize);
+
+  /* If there was no actual data in the file, then inform the user and
+     abort. */
+  if(p->table==NULL)
+    error(EXIT_FAILURE, 0, "%s: no usable data rows (non-commented and "
+          "non-blank lines)", p->filename);
+
+  /* Now that the data columns are ready, we can free the string linked
+     list. */
+  gal_linkedlist_free_stll(p->columns, 1);
+}
 
 
 
@@ -836,257 +382,59 @@ prepare_modular_matrix(struct imgwarpparams *p)
 
 
 /**************************************************************/
-/***************       Sanity Check         *******************/
+/************         Set the parameters          *************/
 /**************************************************************/
-/* 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)
+ui_read_check_inputs_setup(int argc, char *argv[], struct tableparams *p)
 {
-  char *suffix;
-  double *d, *df, *m=p->matrix;
+  struct gal_options_common_params *cp=&p->cp;
 
-  /* Make sure the input file exists. */
-  gal_checkset_check_file(p->up.inputname);
 
-  /* 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
-    {
-      suffix=ui_set_suffix(p->up.owll);
-      gal_checkset_automatic_output(p->up.inputname, suffix,
-                                    p->cp.removedirinfo, p->cp.dontdelete,
-                                    &p->cp.output);
-    }
+  /* Include the parameters necessary for argp from this program (`args.h')
+     and for the common options to all Gnuastro (`commonopts.h'). We want
+     to directly put the pointers to the fields in `p' and `cp', so we are
+     simply including the header here to not have to use long macros in
+     those headers which make them hard to read and modify. This also helps
+     in having a clean environment: everything in those headers is only
+     available within the scope of this function. */
+#include <commonopts.h>
+#include "args.h"
 
-  /* If an actual matrix is given, then it will be used and all modular
-     warpings will be ignored. */
-  if(p->up.matrixstring || p->up.matrixname)
-    read_matrix(p);
-  else if (p->up.owll)
-    prepare_modular_matrix(p);
-  else
-    error(EXIT_FAILURE, 0, "No input matrix specified.\n\nPlease either "
-          "use the modular warp options like `--rotate' or `--scale', "
-          "or directly specify the matrix on the command-line, or in the "
-          "configuration files.\n\nRun with `--help' for the full list of "
-          "modular warpings (among other options), or see the manual's "
-          "`Warping basics' section for more on the matrix.");
-
-
-  /* Check if there are any non-normal numbers in the matrix: */
-  df=(d=p->matrix)+9;
-  do
-    if(!isfinite(*d++))
-      {
-        printmatrix(p->matrix);
-        error(EXIT_FAILURE, 0, "%f is not a `normal' number in the "
-              "input matrix shown above", *(d-1));
-      }
-  while(d<df);
 
-  /* Check if the determinant is not zero: */
-  if( m[0]*m[4]*m[8] + m[1]*m[5]*m[6] + m[2]*m[3]*m[7]
-      - m[2]*m[4]*m[6] - m[1]*m[3]*m[8] - m[0]*m[5]*m[7] == 0 )
-    error(EXIT_FAILURE, 0, "the determinant of the given matrix "
-          "is zero");
+  /* Initialize the options and necessary information.  */
+  ui_initialize_options(p, program_options, gal_commonopts_options);
 
-  /* Check if the transformation is spatially invariant */
-}
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/**************************************************************/
-/***************       Preparations         *******************/
-/**************************************************************/
-/* It is important that the image names are stored in an array (for
-   WCS mode in particular). We do that here. */
-void
-preparearrays(struct imgwarpparams *p)
-{
-  void *array;
-  size_t numnul;
-  double *inv, *m=p->matrix;
-
-  /* Read in the input image: */
-  numnul=gal_fits_hdu_to_array(p->up.inputname, p->cp.hdu,
-                               &p->inputbitpix, &array, &p->is0,
-                               &p->is1);
-  if(p->inputbitpix==DOUBLE_IMG)
-    p->input=array;
-  else
-    {
-      gal_fits_change_type(array, p->inputbitpix, p->is0*p->is1, numnul,
-                                (void **)&p->input, DOUBLE_IMG);
-      free(array);
-    }
-
-  /* Make the inverse matrix: */
+  /* Read the command-line options and arguments. */
   errno=0;
-  p->inverse=inv=malloc(9*sizeof *inv);
-  if(inv==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for the inverse array",
-          9*sizeof *inv);
-  inv[0]=m[4]*m[8]-m[5]*m[7];
-  inv[1]=m[2]*m[7]-m[1]*m[8];
-  inv[2]=m[1]*m[5]-m[2]*m[4];
-  inv[3]=m[5]*m[6]-m[3]*m[8];
-  inv[4]=m[0]*m[8]-m[2]*m[6];
-  inv[5]=m[2]*m[3]-m[0]*m[5];
-  inv[6]=m[3]*m[7]-m[4]*m[6];
-  inv[7]=m[1]*m[6]-m[0]*m[7];
-  inv[8]=m[0]*m[4]-m[1]*m[3];
-  /* Just for a test:
-  {
-    size_t i;
-    printf("\nInput matrix:");
-    for(i=0;i<9;++i) { if(i%3==0) printf("\n"); printf("%-10.5f", m[i]); }
-    printf("\n-----------\n");
-    printf("Inverse matrix:");
-    for(i=0;i<9;++i) { if(i%3==0) printf("\n"); printf("%-10.5f", inv[i]); }
-    printf("\n\n");
-  }
-  */
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+  if(argp_parse(&thisargp, argc, argv, 0, 0, p))
+    error(EXIT_FAILURE, errno, "parsing arguments");
 
-/**************************************************************/
-/************         Set the parameters          *************/
-/**************************************************************/
-void
-setparams(int argc, char *argv[], struct imgwarpparams *p)
-{
-  struct gal_commonparams *cp=&p->cp;
 
-  /* Set the non-zero initial values, the structure was initialized to
-     have a zero value for all elements. */
-  cp->spack         = SPACK;
-  cp->verb          = 1;
-  cp->numthreads    = num_processors(NPROC_CURRENT);
-  cp->removedirinfo = 1;
+  /* Read the configuration files and set the common values. */
+  gal_options_read_config_set(&p->cp);
 
-  p->correctwcs     = 1;
-  p->up.owll        = NULL;
 
-  /* Read the arguments. */
-  errno=0;
-  if(argp_parse(&thisargp, argc, argv, 0, 0, p))
-    error(EXIT_FAILURE, errno, "parsing arguments");
+  /* Read the options into the program's structure, and check them and
+     their relations prior to printing. */
+  ui_read_check_only_options(p);
 
-  /* Add the user default values and save them if asked. */
-  GAL_CONFIGFILES_CHECK_SET_CONFIG;
 
-  /* Check if all the required parameters are set. */
-  checkifset(p);
+  /* Print the option values if asked. Note that this needs to be done
+     after the option checks so un-sane values are not printed in the
+     output state. */
+  gal_options_print_state(&p->cp);
 
-  /* Print the values for each parameter. */
-  if(cp->printparams)
-    GAL_CONFIGFILES_REPORT_PARAMETERS_SET;
 
-  /* Read the input image WCS structure. We are doing this here because
-     some of the matrix operations might need it. */
-  gal_fits_read_wcs(p->up.inputname, p->cp.hdu, p->hstartwcs,
-                    p->hendwcs, &p->nwcs, &p->wcs);
+  /* Check that the options and arguments fit well with each other. Note
+     that arguments don't go in a configuration file. So this test should
+     be done after (possibly) printing the option values. */
+  ui_check_options_and_arguments(p);
 
-  /* Do a sanity check. */
-  sanitycheck(p);
-  gal_checkset_check_remove_file(GAL_TXTARRAY_LOG, 0);
 
-  /* Everything is ready, notify the user of the program starting. */
-  if(cp->verb)
-    {
-      printf(SPACK_NAME" started on %s", ctime(&p->rawtime));
-      printf(" Using %zu CPU thread%s\n", p->cp.numthreads,
-             p->cp.numthreads==1 ? "." : "s.");
-      printf(" Input image: %s\n", p->up.inputname);
-      printf(" matrix:"
-             "\n\t%.4f   %.4f   %.4f"
-             "\n\t%.4f   %.4f   %.4f"
-             "\n\t%.4f   %.4f   %.4f\n",
-             p->matrix[0], p->matrix[1], p->matrix[2],
-             p->matrix[3], p->matrix[4], p->matrix[5],
-             p->matrix[6], p->matrix[7], p->matrix[8]);
-    }
-
-  /* Make the array of input images. */
-  preparearrays(p);
+  /* Read/allocate all the necessary starting arrays. */
+  ui_preparations(p);
 }
 
 
@@ -1112,18 +460,12 @@ setparams(int argc, char *argv[], struct imgwarpparams 
*p)
 /************      Free allocated, report         *************/
 /**************************************************************/
 void
-freeandreport(struct imgwarpparams *p, struct timeval *t1)
+ui_free_report(struct tableparams *p)
 {
   /* Free the allocated arrays: */
-  free(p->input);
   free(p->cp.hdu);
-  free(p->inverse);
   free(p->cp.output);
-
-  if(p->wcs)
-    wcsvfree(&p->nwcs, &p->wcs);
-
-  /* Print the final message. */
-  if(p->cp.verb)
-    gal_timing_report(t1, SPACK_NAME" finished in: ", 0);
+  free(p->cp.searchinstr);
+  free(p->cp.tableformatstr);
+  gal_data_free_ll(p->table);
 }
diff --git a/bin/imgwarp/ui.h b/bin/imgwarp/ui.h
index 3c6aaa1..ab02660 100644
--- a/bin/imgwarp/ui.h
+++ b/bin/imgwarp/ui.h
@@ -5,7 +5,7 @@ ImageWarp is part of GNU Astronomy Utilities (Gnuastro) package.
 Original author:
      Mohammad Akhlaghi <address@hidden>
 Contributing author(s):
-Copyright (C) 2015, Free Software Foundation, Inc.
+Copyright (C) 2016, Free Software Foundation, Inc.
 
 Gnuastro is free software: you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
@@ -23,33 +23,10 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #ifndef UI_H
 #define UI_H
 
-
-/* Macros for various types of standard transformation.*/
-enum standard_warps
-{
-  UI_WARP_INVALID,
-
-  UI_WARP_ALIGN,
-  UI_WARP_ROTATE,
-  UI_WARP_SCALE,
-  UI_WARP_FLIP,
-  UI_WARP_SHEAR,
-  UI_WARP_TRANSLATE,
-  UI_WARP_PROJECT,
-};
-
-
-/* Functions */
-void
-add_to_optionwapsll(struct optionwarpsll **list, int type, char *value);
-
-void
-parse_two_values(char *str, double *v1, double *v2);
-
 void
-setparams(int argc, char *argv[], struct imgwarpparams *p);
+ui_read_check_inputs_setup(int argc, char *argv[], struct imgwaprparams *p);
 
 void
-freeandreport(struct imgwarpparams *p, struct timeval *t1);
+ui_free_report(struct imgwarpparams *p, struct timeval *t1);
 
 #endif
diff --git a/bin/mkprof/args.h b/bin/mkprof/args.h
index c37f8d1..7060c57 100644
--- a/bin/mkprof/args.h
+++ b/bin/mkprof/args.h
@@ -69,7 +69,7 @@ struct argp_option program_options[] =
       "Number of pixels along first FITS axis.",
       GAL_OPTIONS_GROUP_OUTPUT,
       &p->naxes[0],
-      GAL_DATA_TYPE_LONG,
+      GAL_DATA_TYPE_UINT64,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -82,7 +82,7 @@ struct argp_option program_options[] =
       "Number of pixels along second FITS axis.",
       GAL_OPTIONS_GROUP_OUTPUT,
       &p->naxes[1],
-      GAL_DATA_TYPE_LONG,
+      GAL_DATA_TYPE_INT64,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -95,7 +95,7 @@ struct argp_option program_options[] =
       "Scale of oversampling (>0 and odd).",
       GAL_OPTIONS_GROUP_OUTPUT,
       &p->oversample,
-      GAL_DATA_TYPE_UCHAR,
+      GAL_DATA_TYPE_UINT8,
       GAL_OPTIONS_RANGE_GT_0_ODD,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -139,19 +139,6 @@ struct argp_option program_options[] =
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
     },
-    {
-      "type",
-      ARGS_OPTION_KEY_TYPE,
-      "STR",
-      0,
-      "uchar, short, long, longlong, float, double.",
-      GAL_OPTIONS_GROUP_OUTPUT,
-      &p->typestr,
-      GAL_DATA_TYPE_STRING,
-      GAL_OPTIONS_RANGE_ANY,
-      GAL_OPTIONS_NOT_MANDATORY,
-      GAL_OPTIONS_NOT_SET
-    },
 
 
 
@@ -183,7 +170,7 @@ struct argp_option program_options[] =
       "Tolerance to switch to less accurate method.",
       ARGS_GROUP_PROFILES,
       &p->tolerance,
-      GAL_DATA_TYPE_FLOAT,
+      GAL_DATA_TYPE_FLOAT32,
       GAL_OPTIONS_RANGE_GE_0_LE_1,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -209,7 +196,7 @@ struct argp_option program_options[] =
       "Shift profile centers and enlarge image, X axis.",
       ARGS_GROUP_PROFILES,
       &p->shift[0],
-      GAL_DATA_TYPE_LONG,
+      GAL_DATA_TYPE_INT64,
       GAL_OPTIONS_RANGE_GE_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -222,7 +209,7 @@ struct argp_option program_options[] =
       "Shift profile centers and enlarge image, Y axis.",
       ARGS_GROUP_PROFILES,
       &p->shift[1],
-      GAL_DATA_TYPE_LONG,
+      GAL_DATA_TYPE_INT64,
       GAL_OPTIONS_RANGE_GE_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -248,7 +235,7 @@ struct argp_option program_options[] =
       "Magnitude zero point.",
       ARGS_GROUP_PROFILES,
       &p->zeropoint,
-      GAL_DATA_TYPE_FLOAT,
+      GAL_DATA_TYPE_FLOAT32,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -261,7 +248,7 @@ struct argp_option program_options[] =
       "Width of circumference (inward) profiles",
       ARGS_GROUP_PROFILES,
       &p->circumwidth,
-      GAL_DATA_TYPE_FLOAT,
+      GAL_DATA_TYPE_FLOAT32,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -490,7 +477,7 @@ struct argp_option program_options[] =
       "Pixel coordinate of reference point (axis 1).",
       ARGS_GROUP_WCS,
       &p->crpix[0],
-      GAL_DATA_TYPE_DOUBLE,
+      GAL_DATA_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -503,7 +490,7 @@ struct argp_option program_options[] =
       "Pixel coordinate of reference point (axis 2).",
       ARGS_GROUP_WCS,
       &p->crpix[1],
-      GAL_DATA_TYPE_DOUBLE,
+      GAL_DATA_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -516,7 +503,7 @@ struct argp_option program_options[] =
       "Right ascension at reference point (degrees).",
       ARGS_GROUP_WCS,
       &p->crval[0],
-      GAL_DATA_TYPE_DOUBLE,
+      GAL_DATA_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -529,7 +516,7 @@ struct argp_option program_options[] =
       "Declination at reference point (degrees).",
       ARGS_GROUP_WCS,
       &p->crval[1],
-      GAL_DATA_TYPE_DOUBLE,
+      GAL_DATA_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -542,7 +529,7 @@ struct argp_option program_options[] =
       "Resolution of image (arcseconds/pixel).",
       ARGS_GROUP_WCS,
       &p->resolution,
-      GAL_DATA_TYPE_DOUBLE,
+      GAL_DATA_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
diff --git a/bin/mkprof/astmkprof.conf b/bin/mkprof/astmkprof.conf
index 37a2930..386c0a5 100644
--- a/bin/mkprof/astmkprof.conf
+++ b/bin/mkprof/astmkprof.conf
@@ -27,7 +27,7 @@
  naxis2             1000
  oversample            5
  circumwidth           2
- type              float
+ type            float32
 
 # Profiles:
  tunitinp              0
diff --git a/bin/mkprof/main.h b/bin/mkprof/main.h
index 4114ff8..0635c40 100644
--- a/bin/mkprof/main.h
+++ b/bin/mkprof/main.h
@@ -32,8 +32,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 /* Progarm name macros: */
-#define PROGRAM_NAME "MakeProfiles"      /* Program full name.       */
-#define PROGRAM_EXEC "astmkprof"         /* Program executable name. */
+#define PROGRAM_NAME   "MakeProfiles"      /* Program full name.       */
+#define PROGRAM_EXEC   "astmkprof"         /* Program executable name. */
 #define PROGRAM_STRING PROGRAM_NAME" (" PACKAGE_NAME ") " PACKAGE_VERSION
 
 
@@ -107,22 +107,22 @@ struct mkprofparams
   char             *catname;  /* Name of catalog of parameters.           */
   char             *backhdu;  /* HDU of background image.                 */
   long             naxes[2];  /* Size of the output image.                */
-  unsigned char inputascanvas;/* Input image's header for size and WCS.   */
-  unsigned char  oversample;  /* Oversampling scale.                      */
-  unsigned char    psfinimg;  /* ==1: Build PSF profiles in image.        */
-  unsigned char  individual;  /* ==1: Build all catalog separately.       */
-  unsigned char    nomerged;  /* ==1: Don't make a merged image of all.   */
+  uint8_t     inputascanvas;  /* Input image's header for size and WCS.   */
+  uint8_t        oversample;  /* Oversampling scale.                      */
+  uint8_t          psfinimg;  /* ==1: Build PSF profiles in image.        */
+  uint8_t        individual;  /* ==1: Build all catalog separately.       */
+  uint8_t          nomerged;  /* ==1: Don't make a merged image of all.   */
   char             *typestr;  /* Type of finally merged output image.     */
   size_t          numrandom;  /* Number of radom points for integration.  */
   float           tolerance;  /* Accuracy to stop integration.            */
-  unsigned char    tunitinp;  /* ==1: Truncation is in pixels, not radial.*/
+  uint8_t          tunitinp;  /* ==1: Truncation is in pixels, not radial.*/
   long             shift[2];  /* Shift along axeses position of profiles. */
-  unsigned char prepforconv;  /* Shift and expand by size of first psf.   */
+  uint8_t       prepforconv;  /* Shift and expand by size of first psf.   */
   float           zeropoint;  /* Magnitude of zero point flux.            */
   double        circumwidth;  /* Width of circumference (inward).         */
-  unsigned char     replace;  /* Replace overlaping profile pixel values. */
-  unsigned char   magatpeak;  /* Mag only for peak pixel, not all profile.*/
-  unsigned char     envseed;  /* Use GSL_RNG_SEED for random seed.        */
+  uint8_t           replace;  /* Replace overlaping profile pixel values. */
+  uint8_t         magatpeak;  /* Mag only for peak pixel, not all profile.*/
+  uint8_t           envseed;  /* Use GSL_RNG_SEED for random seed.        */
   char                *xcol;  /* X column of profile center.              */
   char                *ycol;  /* Y column of profile center.              */
   char               *racol;  /* RA column of profile center.             */
@@ -134,7 +134,7 @@ struct mkprofparams
   char                *qcol;  /* Axis ratio column of profile.            */
   char                *mcol;  /* Magnitude column.                        */
   char                *tcol;  /* Truncation of the profiles.              */
-  unsigned char mforflatpix;  /* mcol is flat pixel value (f is 4 or 5).  */
+  uint8_t       mforflatpix;  /* mcol is flat pixel value (f is 4 or 5).  */
   double           crpix[2];  /* CRPIX FITS header keywords.              */
   double           crval[2];  /* CRVAL FITS header keywords.              */
   double         resolution;  /* For CDELTi FITS header keywords.         */
diff --git a/bin/mkprof/mkprof.c b/bin/mkprof/mkprof.c
index 2f4e0a1..ecdaf44 100644
--- a/bin/mkprof/mkprof.c
+++ b/bin/mkprof/mkprof.c
@@ -133,7 +133,7 @@ saveindividual(struct mkonthread *mkp)
   gal_checkset_check_remove_file(filename, p->cp.dontdelete);
 
   /* Put the array into a data structure */
-  data=gal_data_alloc(ibq->img, GAL_DATA_TYPE_FLOAT, 2, dsize, NULL, 0,
+  data=gal_data_alloc(ibq->img, GAL_DATA_TYPE_FLOAT32, 2, dsize, NULL, 0,
                       p->cp.minmapsize, "MockImage", "Brightness", NULL);
 
   /* Write the array to file (a separately built PSF doesn't need WCS
diff --git a/bin/mkprof/ui.c b/bin/mkprof/ui.c
index 31542f7..85b851c 100644
--- a/bin/mkprof/ui.c
+++ b/bin/mkprof/ui.c
@@ -107,7 +107,6 @@ enum option_keys_enum
   ARGS_OPTION_KEY_OVERSAMPLE      = 's',
   ARGS_OPTION_KEY_INDIVIDUAL      = 'i',
   ARGS_OPTION_KEY_NOMERGED        = 'm',
-  ARGS_OPTION_KEY_TYPE            = 'T',
   ARGS_OPTION_KEY_NUMRANDOM       = 'r',
   ARGS_OPTION_KEY_TOLERANCE       = 't',
   ARGS_OPTION_KEY_TUNITINP        = 'p',
@@ -180,7 +179,7 @@ ui_initialize_options(struct mkprofparams *p,
   cp->coptions           = gal_commonopts_options;
 
   /* Default program parameters. */
-  p->type=GAL_DATA_TYPE_FLOAT;
+  p->type=GAL_DATA_TYPE_FLOAT32;
 
 
   /* Modify the common options for this program. */
@@ -384,7 +383,7 @@ ui_read_profile_function(struct mkprofparams *p, char 
**strarr)
 {
   size_t i;
 
-  p->f=gal_data_malloc_array(GAL_DATA_TYPE_INT, p->num);
+  p->f=gal_data_malloc_array(GAL_DATA_TYPE_INT32, p->num);
   for(i=0;i<p->num;++i)
     {
       if( !strcmp("sersic", strarr[i]) )
@@ -461,13 +460,13 @@ ui_read_cols(struct mkprofparams *p)
         {
         case 9:
           colname="first axis position";
-          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_DOUBLE);
+          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT64);
           p->x=corrtype->array;
           break;
 
         case 8:
           colname="second axis position";
-          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_DOUBLE);
+          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT64);
           p->y=corrtype->array;
           break;
 
@@ -482,7 +481,8 @@ ui_read_cols(struct mkprofparams *p)
             {
               /* Read the user's profile codes. */
               colname="profile function code (`fcol')";
-              corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_INT);
+              corrtype=gal_data_copy_to_new_type_free(tmp,
+                                                      GAL_DATA_TYPE_INT32);
               p->f=corrtype->array;
 
               /* Check if they are in the correct range. */
@@ -503,37 +503,37 @@ ui_read_cols(struct mkprofparams *p)
 
         case 6:
           colname="radius (`rcol')";
-          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT);
+          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT32);
           p->r=corrtype->array;
           break;
 
         case 5:
           colname="index (`ncol')";
-          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT);
+          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT32);
           p->n=corrtype->array;
           break;
 
         case 4:
           colname="position angle (`pcol')";
-          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT);
+          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT32);
           p->p=corrtype->array;
           break;
 
         case 3:
           colname="axis ratio (`qcol')";
-          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT);
+          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT32);
           p->q=corrtype->array;
           break;
 
         case 2:
           colname="magnitude (`mcol')";
-          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT);
+          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT32);
           p->m=corrtype->array;
           break;
 
         case 1:
           colname="truncation (`tcol')";
-          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT);
+          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT32);
           p->t=corrtype->array;
           break;
 
@@ -641,12 +641,12 @@ ui_prepare_canvas(struct mkprofparams *p)
          no merged image is desired, we just need the WCS information of
          the background image. */
       if(p->nomerged)
-        p->out=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT, 0, dsize, NULL, 1,
-                              p->cp.minmapsize, NULL, NULL, NULL);
+        p->out=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT32, 0, dsize, NULL,
+                              1, p->cp.minmapsize, NULL, NULL, NULL);
       else
         {
           p->out=gal_fits_img_read_to_type(p->backname, p->backhdu,
-                                           GAL_DATA_TYPE_FLOAT,
+                                           GAL_DATA_TYPE_FLOAT32,
                                            p->cp.minmapsize);
           p->naxes[0]=p->out->dsize[1];
           p->naxes[1]=p->out->dsize[0];
@@ -737,7 +737,7 @@ ui_prepare_canvas(struct mkprofparams *p)
         }
 
       /* Make the output structure. */
-      p->out=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT, ndim, dsize, NULL, 1,
+      p->out=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT32, ndim, dsize, NULL, 1,
                             p->cp.minmapsize, NULL, NULL, NULL);
     }
 
@@ -839,23 +839,23 @@ ui_make_log(struct mkprofparams *p)
   if(p->cp.log==0) return;
 
   /* Individual created. */
-  gal_data_add_to_ll(&p->log, NULL, GAL_DATA_TYPE_UCHAR, 1, &p->num, NULL,
+  gal_data_add_to_ll(&p->log, NULL, GAL_DATA_TYPE_UINT8, 1, &p->num, NULL,
                      1, p->cp.minmapsize, "INDIV_CREATED", "bool",
                      "If an individual image was made (1) or not (0).");
 
   /* Fraction of monte-carlo. */
-  gal_data_add_to_ll(&p->log, NULL, GAL_DATA_TYPE_FLOAT, 1, &p->num, NULL,
+  gal_data_add_to_ll(&p->log, NULL, GAL_DATA_TYPE_FLOAT32, 1, &p->num, NULL,
                      1, p->cp.minmapsize, "FRAC_MONTECARLO", "frac",
                      "Fraction of brightness in Monte-carlo integrated "
                      "pixels.");
 
   /* Number of monte-carlo. */
-  gal_data_add_to_ll(&p->log, NULL, GAL_DATA_TYPE_ULONG, 1, &p->num, NULL,
+  gal_data_add_to_ll(&p->log, NULL, GAL_DATA_TYPE_UINT64, 1, &p->num, NULL,
                      1, p->cp.minmapsize, "NUM_MONTECARLO", "count",
                      "Number of Monte Carlo integrated pixels.");
 
   /* Magnitude of profile overlap. */
-  gal_data_add_to_ll(&p->log, NULL, GAL_DATA_TYPE_FLOAT, 1, &p->num, NULL,
+  gal_data_add_to_ll(&p->log, NULL, GAL_DATA_TYPE_FLOAT32, 1, &p->num, NULL,
                      1, p->cp.minmapsize, "MAG_OVERLAP", "mag",
                      "Magnitude of profile's overlap with merged image.");
 
@@ -865,7 +865,7 @@ ui_make_log(struct mkprofparams *p)
              p->catname, p->cp.hdu);
   else
     asprintf(&comment, "Row number of profile in %s.", p->catname);
-  gal_data_add_to_ll(&p->log, NULL, GAL_DATA_TYPE_ULONG, 1, &p->num, NULL,
+  gal_data_add_to_ll(&p->log, NULL, GAL_DATA_TYPE_UINT64, 1, &p->num, NULL,
                      1, p->cp.minmapsize, "INPUT_ROW_NO", "count",
                      "Row number of profile in ");
   free(comment);
diff --git a/bin/table/main.h b/bin/table/main.h
index df9d193..b46c09d 100644
--- a/bin/table/main.h
+++ b/bin/table/main.h
@@ -29,8 +29,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <options.h>
 
 /* Progarm names.  */
-#define PROGRAM_NAME "Table"         /* Program full name.       */
-#define PROGRAM_EXEC "asttable"      /* Program executable name. */
+#define PROGRAM_NAME   "Table"         /* Program full name.       */
+#define PROGRAM_EXEC   "asttable"      /* Program executable name. */
 #define PROGRAM_STRING PROGRAM_NAME" (" PACKAGE_NAME ") " PACKAGE_VERSION
 
 
@@ -46,7 +46,7 @@ struct tableparams
   struct gal_options_common_params cp; /* Common parameters.            */
   char              *filename;  /* Input filename.                      */
   struct gal_linkedlist_stll *columns; /* List of given columns.        */
-  unsigned char   information;  /* ==1, only print FITS information.    */
+  uint8_t         information;  /* ==1, only print FITS information.    */
 
   /* Output: */
   gal_data_t           *table;  /* Linked list of output table columns. */
diff --git a/bootstrap.conf b/bootstrap.conf
index 3de3888..b4b0587 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -160,6 +160,17 @@ bootstrap_post_import_hook()
              print "     IMPORTANT: A Gnuastro addition. */";               \
              print "  unsigned char set;";                                  \
                                                                             \
+             printf "\n";                                                   \
+             print "  /* Function to process the given value.";             \
+             print "     Arguments to the function:";                       \
+             print "       struct argp_option *option: This structure.";    \
+             print "       char      *arg: String given by the user.";      \
+             print "       void *filename: Filename option was read from."; \
+             print "       size_t  lineno: Line number of option in file."; \
+             print "";                                                      \
+             print "     IMPORTANT: A Gnuastro addition. */";               \
+             print "  void (*func)(struct argp_option *, char *, char *, 
size_t);";  \
+                                                                            \
              print;                                                         \
              inargp=0;                                                      \
           }                                                                 \
diff --git a/configure.ac b/configure.ac
index 266955d..06cdb94 100644
--- a/configure.ac
+++ b/configure.ac
@@ -287,148 +287,135 @@ AC_DEFINE_UNQUOTED([CONF_SHOWFMT], [" %-20s"],
 # default list of types. If they have a value of 1, they will be
 # compiled. unless the user configures with `--disable-bin-op-TYPENAME', or
 # `--enable-bin-op-TYPENAME=no'.
-binop_uchar=1
-binop_char=0
-binop_ushort=0
-binop_short=0
-binop_uint=0
-binop_int=0
-binop_ulong=1
-binop_long=1
-binop_longlong=0
-binop_float=1
-binop_double=1
-
-AC_MSG_CHECKING(whether to compile unsigned char binary data operators)
-AC_ARG_ENABLE([bin-op-uchar],
-              [AS_HELP_STRING([--enable-bin-op-uchar],
-                    [Native binary operators on unsigned char data.])],
-             [AS_IF([test "x$enable_bin_op_uchar" != xno],
-                     [binop_uchar=1], [binop_uchar=0])], [])
-AS_IF([test "x$binop_uchar" != x0], [binoptprint=yes], [binoptprint=no])
-AC_DEFINE_UNQUOTED([GAL_CONFIG_BIN_OP_UCHAR], [$binop_uchar],
-                   [Native binary operations on unsigned char data.])
-AC_SUBST(HAVE_BIN_OP_UCHAR, [$binop_uchar])
+binop_uint8=1
+binop_int8=0
+binop_uint16=0
+binop_int16=0
+binop_uint32=0
+binop_int32=0
+binop_uint64=1
+binop_int64=1
+binop_float32=1
+binop_float64=1
+
+AC_MSG_CHECKING(compilation of 8-bit unsigned int binary operators)
+AC_ARG_ENABLE([bin-op-uint8],
+              [AS_HELP_STRING([--enable-bin-op-uint8],
+                    [Native binary operators on unsigned 8-bit int.])],
+             [AS_IF([test "x$enable_bin_op_uint8" != xno],
+                     [binop_uint8=1], [binop_uint8=0])], [])
+AS_IF([test "x$binop_uint8" != x0], [binoptprint=yes], [binoptprint=no])
+AC_DEFINE_UNQUOTED([GAL_CONFIG_BIN_OP_UINT8], [$binop_uint8],
+                   [Native binary operations on unsigned 8-bit int.])
+AC_SUBST(HAVE_BIN_OP_UINT8, [$binop_uint8])
 AC_MSG_RESULT($binoptprint)
 
-AC_MSG_CHECKING(whether to compile char binary data operators)
-AC_ARG_ENABLE([bin-op-char],
-              [AS_HELP_STRING([--enable-bin-op-char],
-                    [Native binary operations on char data.])],
-             [AS_IF([test "x$enable_bin_op_char" != xno],
-                     [binop_char=1], [binop_char=0])], [])
-AS_IF([test "x$binop_char" != x0], [binoptprint=yes], [binoptprint=no])
-AC_DEFINE_UNQUOTED([GAL_CONFIG_BIN_OP_CHAR], [$binop_char],
-                   [Native binary operations on char data.])
-AC_SUBST(HAVE_BIN_OP_CHAR, [$binop_char])
+AC_MSG_CHECKING(compilation of 8-bit signed int binary operators)
+AC_ARG_ENABLE([bin-op-int8],
+              [AS_HELP_STRING([--enable-bin-op-int8],
+                    [Native binary operations on int8 data.])],
+             [AS_IF([test "x$enable_bin_op_int8" != xno],
+                     [binop_int8=1], [binop_int8=0])], [])
+AS_IF([test "x$binop_int8" != x0], [binoptprint=yes], [binoptprint=no])
+AC_DEFINE_UNQUOTED([GAL_CONFIG_BIN_OP_INT8], [$binop_int8],
+                   [Native binary operations on int8 data.])
+AC_SUBST(HAVE_BIN_OP_INT8, [$binop_int8])
 AC_MSG_RESULT($binoptprint)
 
-AC_MSG_CHECKING(whether to compile unsigned short binary data operators)
-AC_ARG_ENABLE([bin-op-ushort],
-              [AS_HELP_STRING([--enable-bin-op-ushort],
+AC_MSG_CHECKING(compilation of 16-bit unsigned int binary operators)
+AC_ARG_ENABLE([bin-op-uint16],
+              [AS_HELP_STRING([--enable-bin-op-uint16],
                     [Native binary operators on unsigned short data.])],
-             [AS_IF([test "x$enable_bin_op_ushort" != xno],
-                     [binop_ushort=1], [binop_ushort=0])], [])
-AS_IF([test "x$binop_ushort" != x0], [binoptprint=yes], [binoptprint=no])
-AC_DEFINE_UNQUOTED([GAL_CONFIG_BIN_OP_USHORT], [$binop_ushort],
+             [AS_IF([test "x$enable_bin_op_uint16" != xno],
+                     [binop_uint16=1], [binop_uint16=0])], [])
+AS_IF([test "x$binop_uint16" != x0], [binoptprint=yes], [binoptprint=no])
+AC_DEFINE_UNQUOTED([GAL_CONFIG_BIN_OP_UINT16], [$binop_uint16],
                    [Native binary operations on unsigned short data.])
-AC_SUBST(HAVE_BIN_OP_USHORT, [$binop_ushort])
+AC_SUBST(HAVE_BIN_OP_UINT16, [$binop_uint16])
 AC_MSG_RESULT($binoptprint)
 
-AC_MSG_CHECKING(whether to compile short binary data operators)
-AC_ARG_ENABLE([bin-op-short],
-              [AS_HELP_STRING([--enable-bin-op-short],
-                    [Native binary operations on short data.])],
-             [AS_IF([test "x$enable_bin_op_short" != xno],
-                     [binop_short=1], [binop_short=0])], [])
-AS_IF([test "x$binop_short" != x0], [binoptprint=yes], [binoptprint=no])
-AC_DEFINE_UNQUOTED([GAL_CONFIG_BIN_OP_SHORT], [$binop_short],
-                   [Native binary operations on short data.])
-AC_SUBST(HAVE_BIN_OP_SHORT, [$binop_short])
+AC_MSG_CHECKING(compilation of 16-bit signed int binary operators)
+AC_ARG_ENABLE([bin-op-int16],
+              [AS_HELP_STRING([--enable-bin-op-int16],
+                    [Native binary operations on int16 data.])],
+             [AS_IF([test "x$enable_bin_op_int16" != xno],
+                     [binop_int16=1], [binop_int16=0])], [])
+AS_IF([test "x$binop_int16" != x0], [binoptprint=yes], [binoptprint=no])
+AC_DEFINE_UNQUOTED([GAL_CONFIG_BIN_OP_INT16], [$binop_int16],
+                   [Native binary operations on int16 data.])
+AC_SUBST(HAVE_BIN_OP_INT16, [$binop_int16])
 AC_MSG_RESULT($binoptprint)
 
-AC_MSG_CHECKING(whether to compile unsigned int binary data operators)
-AC_ARG_ENABLE([bin-op-uint],
-              [AS_HELP_STRING([--enable-bin-op-uint],
-                    [Native binary operators on unsigned int data.])],
-             [AS_IF([test "x$enable_bin_op_uint" != xno],
-                     [binop_uint=1], [binop_uint=0])], [])
-AS_IF([test "x$binop_uint" != x0], [binoptprint=yes], [binoptprint=no])
-AC_DEFINE_UNQUOTED([GAL_CONFIG_BIN_OP_UINT], [$binop_uint],
-                   [Native binary operations on unsigned int data.])
-AC_SUBST(HAVE_BIN_OP_UINT, [$binop_uint])
+AC_MSG_CHECKING(compilation of 32-bit unsigned int binary operators)
+AC_ARG_ENABLE([bin-op-uint32],
+              [AS_HELP_STRING([--enable-bin-op-uint32],
+                    [Native binary operators on unsigned int32 data.])],
+             [AS_IF([test "x$enable_bin_op_uint32" != xno],
+                     [binop_uint32=1], [binop_uint32=0])], [])
+AS_IF([test "x$binop_uint32" != x0], [binoptprint=yes], [binoptprint=no])
+AC_DEFINE_UNQUOTED([GAL_CONFIG_BIN_OP_UINT32], [$binop_uint32],
+                   [Native binary operations on unsigned int32 data.])
+AC_SUBST(HAVE_BIN_OP_UINT32, [$binop_uint32])
 AC_MSG_RESULT($binoptprint)
 
-AC_MSG_CHECKING(whether to compile int binary data operators)
-AC_ARG_ENABLE([bin-op-int],
-              [AS_HELP_STRING([--enable-bin-op-int],
-                    [Native binary operations on int data.])],
-             [AS_IF([test "x$enable_bin_op_int" != xno],
-                     [binop_int=1], [binop_int=0])], [])
-AS_IF([test "x$binop_int" != x0], [binoptprint=yes], [binoptprint=no])
-AC_DEFINE_UNQUOTED([GAL_CONFIG_BIN_OP_INT], [$binop_int],
-                   [Native binary operations on int data.])
-AC_SUBST(HAVE_BIN_OP_INT, [$binop_int])
+AC_MSG_CHECKING(compilation of 32-bit signed int binary operators)
+AC_ARG_ENABLE([bin-op-int32],
+              [AS_HELP_STRING([--enable-bin-op-int32],
+                    [Native binary operations on int32 data.])],
+             [AS_IF([test "x$enable_bin_op_int32" != xno],
+                     [binop_int32=1], [binop_int32=0])], [])
+AS_IF([test "x$binop_int32" != x0], [binoptprint=yes], [binoptprint=no])
+AC_DEFINE_UNQUOTED([GAL_CONFIG_BIN_OP_INT32], [$binop_int32],
+                   [Native binary operations on int32 data.])
+AC_SUBST(HAVE_BIN_OP_INT32, [$binop_int32])
 AC_MSG_RESULT($binoptprint)
 
-AC_MSG_CHECKING(whether to compile unsigned long binary data operators)
-AC_ARG_ENABLE([bin-op-ulong],
-              [AS_HELP_STRING([--enable-bin-op-ulong],
+AC_MSG_CHECKING(compilation of 64-bit unsigned int binary operators)
+AC_ARG_ENABLE([bin-op-uint64],
+              [AS_HELP_STRING([--enable-bin-op-uint64],
                     [Native binary operators on unsigned long data.])],
-             [AS_IF([test "x$enable_bin_op_ulong" != xno],
-                     [binop_ulong=1], [binop_ulong=0])], [])
-AS_IF([test "x$binop_ulong" != x0], [binoptprint=yes], [binoptprint=no])
-AC_DEFINE_UNQUOTED([GAL_CONFIG_BIN_OP_ULONG], [$binop_ulong],
+             [AS_IF([test "x$enable_bin_op_uint64" != xno],
+                     [binop_uint64=1], [binop_uint64=0])], [])
+AS_IF([test "x$binop_uint64" != x0], [binoptprint=yes], [binoptprint=no])
+AC_DEFINE_UNQUOTED([GAL_CONFIG_BIN_OP_UINT64], [$binop_uint64],
                    [Native binary operations on unsigned long data.])
-AC_SUBST(HAVE_BIN_OP_ULONG, [$binop_ulong])
+AC_SUBST(HAVE_BIN_OP_UINT64, [$binop_uint64])
 AC_MSG_RESULT($binoptprint)
 
-AC_MSG_CHECKING(whether to compile long native binary data operators)
-AC_ARG_ENABLE([bin-op-long],
-              [AS_HELP_STRING([--enable-bin-op-long],
-                    [Native binary operations on long data.])],
-             [AS_IF([test "x$enable_bin_op_long" != xno],
-                     [binop_long=1], [binop_long=0])], [])
-AS_IF([test "x$binop_long" != x0], [binoptprint=yes], [binoptprint=no])
-AC_DEFINE_UNQUOTED([GAL_CONFIG_BIN_OP_LONG], [$binop_long],
-                   [Native binary operations on long data.])
-AC_SUBST(HAVE_BIN_OP_LONG, [$binop_long])
+AC_MSG_CHECKING(compilation of 64-bit signed int binary operators)
+AC_ARG_ENABLE([bin-op-int64],
+              [AS_HELP_STRING([--enable-bin-op-int64],
+                    [Native binary operations on int64 data.])],
+             [AS_IF([test "x$enable_bin_op_int64" != xno],
+                     [binop_int64=1], [binop_int64=0])], [])
+AS_IF([test "x$binop_int64" != x0], [binoptprint=yes], [binoptprint=no])
+AC_DEFINE_UNQUOTED([GAL_CONFIG_BIN_OP_INT64], [$binop_int64],
+                   [Native binary operations on long64 data.])
+AC_SUBST(HAVE_BIN_OP_INT64, [$binop_int64])
 AC_MSG_RESULT($binoptprint)
 
-AC_MSG_CHECKING(whether to compile LONGLONG native binary data operators)
-AC_ARG_ENABLE([bin-op-longlong],
-              [AS_HELP_STRING([--enable-bin-op-longlong],
-                    [Native binary operations on LONGLONG data.])],
-             [AS_IF([test "x$enable_bin_op_longlong" != xno],
-                     [binop_longlong=1], [binop_longlong=0])], [])
-AS_IF([test "x$binop_longlong" != x0], [binoptprint=yes], [binoptprint=no])
-AC_DEFINE_UNQUOTED([GAL_CONFIG_BIN_OP_LONGLONG], [$binop_longlong],
-                   [Native binary operations on LONGLONG data.])
-AC_SUBST(HAVE_BIN_OP_LONGLONG, [$binop_longlong])
+AC_MSG_CHECKING(compilation of 32-bit floating point binary operators)
+AC_ARG_ENABLE([bin-op-float32],
+              [AS_HELP_STRING([--enable-bin-op-float32],
+                    [Native binary operations on float32 data.])],
+             [AS_IF([test "x$enable_bin_op_float32" != xno],
+                     [binop_float32=1], [binop_float32=0])], [])
+AS_IF([test "x$binop_float32" != x0], [binoptprint=yes], [binoptprint=no])
+AC_DEFINE_UNQUOTED([GAL_CONFIG_BIN_OP_FLOAT32], [$binop_float32],
+                   [Native binary operations on float32 data.])
+AC_SUBST(HAVE_BIN_OP_FLOAT32, [$binop_float32])
 AC_MSG_RESULT($binoptprint)
 
-AC_MSG_CHECKING(whether to compile float native binary data operators)
-AC_ARG_ENABLE([bin-op-float],
-              [AS_HELP_STRING([--enable-bin-op-float],
-                    [Native binary operations on float data.])],
-             [AS_IF([test "x$enable_bin_op_float" != xno],
-                     [binop_float=1], [binop_float=0])], [])
-AS_IF([test "x$binop_float" != x0], [binoptprint=yes], [binoptprint=no])
-AC_DEFINE_UNQUOTED([GAL_CONFIG_BIN_OP_FLOAT], [$binop_float],
-                   [Native binary operations on float data.])
-AC_SUBST(HAVE_BIN_OP_FLOAT, [$binop_float])
-AC_MSG_RESULT($binoptprint)
-
-AC_MSG_CHECKING(whether to compile double native binary data operators)
-AC_ARG_ENABLE([bin-op-double],
-              [AS_HELP_STRING([--enable-bin-op-double],
-                    [Native binary operations on double data.])],
-             [AS_IF([test "x$enable_bin_op_double" != xno],
-                     [binop_double=1], [binop_double=0])], [])
-AS_IF([test "x$binop_double" != x0], [binoptprint=yes], [binoptprint=no])
-AC_DEFINE_UNQUOTED([GAL_CONFIG_BIN_OP_DOUBLE], [$binop_double],
-                   [Native binary operations on double data.])
-AC_SUBST(HAVE_BIN_OP_DOUBLE, [$binop_double])
+AC_MSG_CHECKING(compilation of 64-bit floating point binary operators)
+AC_ARG_ENABLE([bin-op-float64],
+              [AS_HELP_STRING([--enable-bin-op-float64],
+                    [Native binary operations on float64 data.])],
+             [AS_IF([test "x$enable_bin_op_float64" != xno],
+                     [binop_float64=1], [binop_float64=0])], [])
+AS_IF([test "x$binop_float64" != x0], [binoptprint=yes], [binoptprint=no])
+AC_DEFINE_UNQUOTED([GAL_CONFIG_BIN_OP_FLOAT64], [$binop_float64],
+                   [Native binary operations on float64 data.])
+AC_SUBST(HAVE_BIN_OP_FLOAT64, [$binop_float64])
 AC_MSG_RESULT($binoptprint)
 
 
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 73e9568..bb17b44 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -281,6 +281,7 @@ Common program behavior
 * Configuration files::         Values for unspecified variables.
 * Threads in Gnuastro::         How threads are managed in Gnuastro.
 * Automatic output::            About automatic output names.
+* Numeric data types::          Different types and how to specify them.
 * Tables in Gnuastro::          Recognized table formats.
 * Getting help::                Getting more information on the go.
 * Output headers::              Common headers to all FITS outputs.
@@ -373,7 +374,6 @@ Invoking ImageCrop
 Arithmetic
 
 * Reverse polish notation::     The current notation style for Arithmetic
-* Data types::                  How bits are read as numbers
 * Arithmetic operators::        List of operators known to Arithmetic
 * Invoking astarithmetic::      How to run Arithmetic: options and output
 
@@ -3138,24 +3138,23 @@ Do not build or install the program named 
@file{progname}. This is
 very similar to the @option{--enable-progname}, but will build and
 install all the other programs except this one.
 
address@hidden --enable-bin-op-uchar
address@hidden --enable-bin-op-char
address@hidden --enable-bin-op-ushort
address@hidden --enable-bin-op-short
address@hidden --enable-bin-op-uint
address@hidden --enable-bin-op-int
address@hidden --enable-bin-op-ulong
address@hidden --enable-bin-op-long
address@hidden --enable-bin-op-longlong
address@hidden --enable-bin-op-float
address@hidden --enable-bin-op-double
address@hidden --enable-bin-op-uint8
address@hidden --enable-bin-op-int8
address@hidden --enable-bin-op-uint16
address@hidden --enable-bin-op-int16
address@hidden --enable-bin-op-uint32
address@hidden --enable-bin-op-int32
address@hidden --enable-bin-op-uint64
address@hidden --enable-bin-op-int64
address@hidden --enable-bin-op-float32
address@hidden --enable-bin-op-float64
 Enable the binary data-structure operators to work natively on the
 respective type of data (@option{u} stands for unsigned types, see
address@hidden types}). Some are compiled by default, to disable them (or
-disable any other type), either run @option{enable-bin-op-TYPE=no}, or run
address@hidden The final list of enabled/disabled types
-can be inspected in the outputs of @command{./configure} (close to the
-end).
address@hidden data types}). Some are compiled by default, to disable them
+(or disable any other type), either run @option{enable-bin-op-TYPE=no}, or
+run @option{--disable-bin-op-TYPE}. The final list of enabled/disabled
+types can be inspected in the outputs of @command{./configure} (close to
+the end).
 
 Binary operators, for example @code{+} or @code{>} (greater than), are some
 of the most common operators to the @ref{Arithmetic} program or the
@@ -3188,9 +3187,9 @@ libraries and optimizations (as in @ref{Building and 
debugging}) is the
 first step to take. If you commonly work with very specific data-types, you
 can enable them (and disable the default types that you don't need) with
 these configuration options. Since the outputs of comparison operators are
address@hidden char} type and most astronomical datasets are in
address@hidden, the recommended minimum enabled types are @code{unsigned
-char} and @code{float}.
address@hidden char} (or @code{uint8_t}) type and most astronomical
+datasets are in single precision (32-bit) floating point (@code{float}),
+the recommended minimum enabled types are @code{uint8} and @code{float32}.
 
 GNU/Linux distribution package managers who compile once, for a large
 audience of users who just download the compiled programs and executables,
@@ -3975,6 +3974,7 @@ command-line.
 * Configuration files::         Values for unspecified variables.
 * Threads in Gnuastro::         How threads are managed in Gnuastro.
 * Automatic output::            About automatic output names.
+* Numeric data types::          Different types and how to specify them.
 * Tables in Gnuastro::          Recognized table formats.
 * Getting help::                Getting more information on the go.
 * Output headers::              Common headers to all FITS outputs.
@@ -4354,6 +4354,13 @@ take table columns as input.
 The name of the output file or directory. With this option the automatic
 output names explained in @ref{Automatic output} are ignored.
 
address@hidden -T STR
address@hidden --type=STR
+The data type of the output depending on the program context. This option
+isn't applicable to some programs like @ref{Header} and will be ignored by
+them. The different acceptable values to this option are fully described in
address@hidden data types}.
+
 @item -D
 @itemx --dontdelete
 By default, if the output file already exists, Gnuastro's programs will
@@ -5058,7 +5065,7 @@ your exciting science.} are very important.
 
 
 
address@hidden Automatic output, Tables in Gnuastro, Threads in Gnuastro, 
Common program behavior
address@hidden Automatic output, Numeric data types, Threads in Gnuastro, 
Common program behavior
 @section Automatic output
 
 @cindex Automatic output file names
@@ -5112,8 +5119,140 @@ ABC01.jpg ABC02.jpg DEF01_labeled.fits
 
 
 
address@hidden Numeric data types, Tables in Gnuastro, Automatic output, Common 
program behavior
address@hidden Numeric data types
+
address@hidden Bit
address@hidden Type
+At the lowest level, the computer stores everything in terms of @code{1} or
address@hidden For example, each program in Gnuastro, or each astronomical image
+you take with the telescope is actually a string of millions of these zeros
+and ones. The space required to keep a zero or one is the smallest unit of
+storage, and is known as a @emph{bit}. Understanding and manipulating this
+string of bits is extremely hard for most people, therefore, we define
+packages of these bits along with a standard on how to interpret the bits
+in each package as @emph{type}s.
 
address@hidden Tables in Gnuastro, Getting help, Automatic output, Common 
program behavior
+The most basic standard for reading the bits is integer numbers. Since we
+use CFITSIO, we define the @code{char}, @code{short}, or @code{long}
+integer types. These types can store an integer number (@mymath{..., -2,
+-1, 0, 1, 2, ...}), with an increasing number of bytes/bits (and thus
+larger limits). The range of integers each can represent is: @mymath{(-2^7,
+..., 2^7-1)}, @mymath{(-2^{15}, ..., 2^{15}-1}), and @mymath{(-2^{32}, ...,
+2^{31}-1)} respectively. One bit in the above types is dedicated to the
+number's sign (positive or negative). So, there is also an @code{unsigned}
+version where all the bits are counted in calculating the number. The
address@hidden types thus have larger positive limits, but no negative
+value with ranges @mymath{(0, ..., 2^8-1)}, @mymath{(0, ..., 2^{16}-1}),
+and @mymath{(0, ..., 2^{32}-1)} respectively. When the context of your work
+doesn't involve negative numbers (for example labeled images, where pixels
+can only have zero or positive integer values), it is best to use the
address@hidden types.
+
+Another standard of converting a given number of bits to numbers is the
+floating point standard, this standard can approximately store any real
+number with a given precision. There are two floating point types in
+CFITSIO: @code{float} and @code{double}, for single and double precision
+floating point numbers respectively. The former is sufficient for data with
+less than 8 significant decimal digits (most astronomical data), while the
+latter is good for less than 16 significant decimal digits. The
+representation of real numbers as bits is much more complex than integers,
+so we won't explain any further, if you are interested have a look in the
address@hidden://en.wikipedia.org/wiki/Floating_point, Wikipedia article}.
+
+With the conversion operators in Gnuastro's Arithmetic, you can change the
+types of data to each other, which is necessary in some contexts. For
+example the program/library, that you intend to feed the data into, only
+accepts floating point values, but you have an integer image. Another
+example can be that you know that your data only has values that fit within
address@hidden or @code{short} types, however it is currently formatted in the
address@hidden type. Operations involving floating point or larger integer
+types are significantly slower than integer or smaller types
+respectively. In the latter case, it also requires much more (by 8 or 4
+times in the example above) storage space. So when you confront such
+situations and want to store/archive/transfter/process the data, it is best
+convert them to the most efficient type.
+
+The short and long names for the recognized numeric data types in Gnuastro
+are listed below. Both short and long names can be used when you want to
+speicy a type. For example, as a value to the common option @option{--type}
+(see @ref{Input output}), or in the information comment lines of
address@hidden text table format}. The ranges listed below are inclusive.
+
address@hidden @code
address@hidden u8
address@hidden uint8
+8-bit un-signed integers, range:@*
address@hidden to\ }2^8-1]} or @mymath{[0\rm{\ to\ }255]}.
+
address@hidden i8
address@hidden int8
+8-bit signed integers, range:@*
address@hidden to\ }2^7-1]} or @mymath{[-127\rm{\ to\ }127]}.
+
address@hidden u16
address@hidden uint16
+16-bit un-signed integers, range:@*
address@hidden to\ }2^{16}-1]} or @mymath{[0\rm{\ to\ }65535]}.
+
address@hidden i16
address@hidden int16
+16-bit signed integers, range:@* @mymath{[-2^{15}\rm{\ to\ }2^{15}-1]} or
address@hidden to\ }32768]}.
+
address@hidden u32
address@hidden uint32
+32-bit un-signed integers, range:@* @mymath{[0\rm{\ to\ }2^{32}-1]} or
address@hidden to\ }4294967295]}.
+
address@hidden i32
address@hidden int32
+32-bit signed integers, range:@* @mymath{[-2^{32}\rm{\ to\ }2^{32}-1]} or
address@hidden to\ }2147483647]}.
+
address@hidden u64
address@hidden uint64
+64-bit un-signed integers, address@hidden @mymath{[0\rm{\ to\ }2^{64}-1]} or
address@hidden to\ }18446744073709551615]}.
+
address@hidden i64
address@hidden int64
+64-bit signed integers, range:@* @mymath{[-2^{64}\rm{\ to\ }2^{64}-1]} or
address@hidden to\ }9223372036854775807]}.
+
address@hidden f32
address@hidden float32
+32-bit (single-precision) floating point types. The maximum (minimum is its
+negative) possible value is
address@hidden Single-precision floating points can
+accurately represent a floating point number @mymath{\sim7.2} significant
+decimals. Given the heavy noise in astronomical data, this is usually more
+than sufficient for storing results.
+
address@hidden f64
address@hidden float64
+64-bit (double-precision) floating point types. The maximum (minimum is its
+negative) possible value is @mymath{\sim10^{308}}. Double-precision
+floating points can accurately represent a floating point number
address@hidden significant decimals. This is usually good for processing
+(mixing) the data internally, for example a sum of single precision data
+(and later storing the result as @code{float32}).
address@hidden table
+
address@hidden
address@hidden
address@hidden file formats don't recognize all types.} Some file formats
+don't recognize all the types, for example the FITS binary table standard
+does not define the @code{unsigned int} and @code{unsigned long} types. The
+FITS standard also only defines the following types for images:
address@hidden char}, @code{short}, @code{int}, @code{long}, @code{float},
+and @code{double}. Although CFITSIO allows writing/reading to/from a wider
+range of types.
address@hidden cartouche
+
+
+
address@hidden Tables in Gnuastro, Getting help, Numeric data types, Common 
program behavior
 @section Tables in Gnuastro
 
 ``A table is a collection of related data held in a structured format
@@ -5204,15 +5343,15 @@ have a fixed width (number of characters).
 Numbers in a FITS ASCII table are printed into ASCII format, they are not
 in binary (that the CPU uses). Hence, they can take a larger space in
 memory, loose their precision, and take longer to read into memory. If you
-are dealing with integer type columns (see @ref{Data types}), another issue
-with FITS ASCII tables is that the type information for the column will be
-lost (there is only one integer type in FITS ASCII tables). One problem
-with the binary format on the other hand is that it isn't portable
-(different CPUs/compilers) have different standards for translating the
-zeros and ones. But since ASCII characters are defined on a byte and are
-well recognized, they are better for portability on those various
-systems. Gnuastro's plain text table format described below is much more
-portable and easier to read/write/interpret by humans manually.
+are dealing with integer type columns (see @ref{Numeric data types}),
+another issue with FITS ASCII tables is that the type information for the
+column will be lost (there is only one integer type in FITS ASCII
+tables). One problem with the binary format on the other hand is that it
+isn't portable (different CPUs/compilers) have different standards for
+translating the zeros and ones. But since ASCII characters are defined on a
+byte and are well recognized, they are better for portability on those
+various systems. Gnuastro's plain text table format described below is much
+more portable and easier to read/write/interpret by humans manually.
 
 Generally, as the name implies, this format is useful for when your table
 mainly contains ASCII columns (for example file names, or
@@ -5280,7 +5419,8 @@ of columns.
 The columns don't have to be exactly under each other and the rows can be
 arbitrarily long with different lengths. For example the following contents
 in a file would be interpretted as a table with 4 columns and 2 rows, with
-each element interpretted as a @code{double} type (see @ref{Data types}).
+each element interpretted as a @code{double} type (see @ref{Numeric data
+types}).
 
 @example
 1     2.234948   128   39.8923e8
@@ -5343,8 +5483,8 @@ interpretted as the column name (so it can contain 
anything except the
 line is defined as a comment. Within the brackets, anything before the
 first address@hidden,}' is the units (physical units, for example km/s, or 
erg/s),
 anything before the second address@hidden,}' is the short type identifier (see
-below, and @ref{Data types}). Finally (still within the brackets), any
-non-white characters after the second address@hidden,}' are interpretted as the
+below, and @ref{Numeric data types}). Finally (still within the brackets),
+any non-white characters after the second address@hidden,}' are interpretted 
as the
 blank value for that column (see @ref{Blank pixels}). Note that blank
 values will be stored in the same type as the column, not as a
 address@hidden floating point types, the @code{nan}, or @code{inf}
@@ -5388,32 +5528,14 @@ with nothing but the column number is redundant):
 # Column 3: mag_f160w [AB mag, f] Magnitude from the F160W filter
 @end example
 
-The data type of the column (see @ref{Data types}) should be specified with
-one of the following values:
address@hidden
+The data type of the column should be specified with one of the following
+values:
 
 @itemize
 @item
address@hidden': for @code{unsigned char}.
address@hidden
address@hidden': for (signed) @code{char}.
address@hidden
address@hidden': for @code{unsigned short}.
address@hidden
address@hidden': for (signed) @code{short}.
address@hidden
address@hidden': for @code{unsigned int} (see note below).
address@hidden
address@hidden': for (signed) @code{int}.
address@hidden
address@hidden': for @code{unsigned long} (see note below).
address@hidden
address@hidden': for (signed) @code{long}.
address@hidden
address@hidden': for @code{long long}.
address@hidden
address@hidden': for @code{float}.
address@hidden
address@hidden': for @code{double}.
+For a numeric column, you can use any of the numeric types (and their
+recognized identifiers) described in @ref{Numeric data types}.
 @item
 address@hidden': for strings. The @code{N} value identifies the length of the
 string (how many characters it has). The start of the string on each row is
@@ -5917,6 +6039,10 @@ The version of WCSLIB used (see @ref{WCSLIB}). Note that 
older versions of
 WCSLIB do not report the version internally. So this is only available if
 you are using more recent WCSLIB versions.
 
address@hidden GSL
+The version of GNU Scientific Library that was used, see @ref{GNU
+Scientific Library}.
+
 @item GNUASTRO
 The version of Gnuastro used (see @ref{Version numbering}).
 @end table
@@ -5927,8 +6053,9 @@ Here is one example of the last few lines of an example 
output.
               / Versions and date
 DATE    = '...'                / file creation date
 COMMIT  = 'v0-8-g547f6eb'      / Commit description in running dir.
-CFITSIO = '3.39    '           / CFITSIO version.
-WCSLIB  = '5.15    '           / WCSLIB version.
+CFITSIO = '3.41    '           / CFITSIO version.
+WCSLIB  = '5.16    '           / WCSLIB version.
+GSL     = '2.3     '           / GNU Scientific Library version.
 GNUASTRO= '0.3'                / GNU Astronomy Utilities version.
 END
 @end example
@@ -6396,14 +6523,15 @@ will not be preformed.
 The basic input/output on plain text images is very similar to how tables
 are read/written as discribed in @ref{Gnuastro text table format}. Simply
 put, the restrictions are very loose, and there is a convention to define a
-name, units, data type (see @ref{Data types}), and comments for the data in
-a commented line. The only difference is that as a table, a text file can
-contain many datasets (columns), but as a 2D image, it can only contain one
-dataset. As a result, only one information comment line is necessary for a
-2D image, and instead of the starting address@hidden Column N}' (@code{N} is 
the
-column number), the information line for a 2D image must start with
address@hidden Image 1}'. When ConvertType is asked to output to plain text 
file,
-this information comment line is written before the image pixel values.
+name, units, data type (see @ref{Numeric data types}), and comments for the
+data in a commented line. The only difference is that as a table, a text
+file can contain many datasets (columns), but as a 2D image, it can only
+contain one dataset. As a result, only one information comment line is
+necessary for a 2D image, and instead of the starting address@hidden Column N}'
+(@code{N} is the column number), the information line for a 2D image must
+start with address@hidden Image 1}'. When ConvertType is asked to output to 
plain
+text file, this information comment line is written before the image pixel
+values.
 
 When converting an image to plain text, consider the fact that if the image
 is large, the number of columns in each line will become very large,
@@ -6834,12 +6962,12 @@ tools like AWK or sort, similar to the examples above.
 Only print the column information in the specified table on the
 command-line and exit. Each columns information (number, name, units, data
 type, and comments) will be printed as a row on the command-line. Note that
-the FITS standard only requires the data type (see @ref{Data types}) and in
-plain text tables, no meta-data/information is mandatory. Gnuastro has its
-own convention in the comments of a plain text table to store and transfer
-this information as described in @ref{Gnuastro text table format}. Note
-that if columns have been requested with the @option{--column} option
-(below), this option will be ignored if given.
+the FITS standard only requires the data type (see @ref{Numeric data
+types}) and in plain text tables, no meta-data/information is
+mandatory. Gnuastro has its own convention in the comments of a plain text
+table to store and transfer this information as described in @ref{Gnuastro
+text table format}. Note that if columns have been requested with the
address@hidden option (below), this option will be ignored if given.
 
 @cindex AWK
 @cindex GNU AWK
@@ -7607,18 +7735,17 @@ images). Arithmetic is Gnuastro's program for such 
operations on your
 datasets directly from the command-line. It currently uses the reverse
 polish or postfix notation, see @ref{Reverse polish notation} and will work
 on the native data types of the input images/data to reduce CPU and RAM
-resources, see @ref{Data types}. For more information on how to run
+resources, see @ref{Numeric data types}. For more information on how to run
 Arithmetic, please see @ref{Invoking astarithmetic}.
 
 
 @menu
 * Reverse polish notation::     The current notation style for Arithmetic
-* Data types::                  How bits are read as numbers
 * Arithmetic operators::        List of operators known to Arithmetic
 * Invoking astarithmetic::      How to run Arithmetic: options and output
 @end menu
 
address@hidden Reverse polish notation, Data types, Arithmetic, Arithmetic
address@hidden Reverse polish notation, Arithmetic operators, Arithmetic, 
Arithmetic
 @subsection Reverse polish notation
 
 @cindex Postfix notation
@@ -7679,65 +7806,7 @@ Postscript and compiled into PDF files) uses this 
notation.
 
 
 
address@hidden Data types, Arithmetic operators, Reverse polish notation, 
Arithmetic
address@hidden Data types
-
address@hidden Bit
address@hidden Type
-At the lowest level, the computer stores everything in terms of @code{1} or
address@hidden For example, each program in Gnuastro, or each astronomical image
-you take with the telescope is actually a string of millions of these zeros
-and ones. The space required to keep a zero or one is the smallest unit of
-storage, and is known as a @emph{bit}. Understanding and manipulating this
-string of bits is extremely hard for most people, therefore, we define
-packages of these bits along with a standard on how to interpret the bits
-in each package as @emph{type}s.
-
-The most basic standard for reading the bits is integer numbers. Since we
-use CFITSIO, we define the @code{char}, @code{short}, or @code{long}
-integer types. These types can store an integer number (@mymath{..., -2,
--1, 0, 1, 2, ...}), with an increasing number of bytes/bits (and thus
-larger limits). The range of integers each can represent is: @mymath{(-2^7,
-..., 2^7-1)}, @mymath{(-2^{15}, ..., 2^{15}-1}), and @mymath{(-2^{32}, ...,
-2^{31}-1)} respectively. One bit in the above types is dedicated to the
-number's sign (positive or negative). So, there is also an @code{unsigned}
-version where all the bits are counted in calculating the number. The
address@hidden types thus have larger positive limits, but no negative
-value with ranges @mymath{(0, ..., 2^8-1)}, @mymath{(0, ..., 2^{16}-1}),
-and @mymath{(0, ..., 2^{32}-1)} respectively. When the context of your work
-doesn't involve negative numbers (for example labeled images, where pixels
-can only have zero or positive integer values), it is best to use the
address@hidden types.
-
-Another standard of converting a given number of bits to numbers is the
-floating point standard, this standard can approximately store any real
-number with a given precision. There are two floating point types in
-CFITSIO: @code{float} and @code{double}, for single and double precision
-floating point numbers respectively. The former is sufficient for data with
-less than 8 significant decimal digits (most astronomical data), while the
-latter is good for less than 16 significant decimal digits. The
-representation of real numbers as bits is much more complex than integers,
-so we won't explain any further, if you are interested have a look in the
address@hidden://en.wikipedia.org/wiki/Floating_point, Wikipedia article}.
-
-With the conversion operators in Gnuastro's Arithmetic, you can change the
-types of data to each other, which is necessary in some contexts. For
-example the program/library, that you intend to feed the data into, only
-accepts floating point values, but you have an integer image. Another
-example can be that you know that your data only has values that fit within
address@hidden or @code{short} types, however it is currently formatted in the
address@hidden type. Operations involving floating point or larger integer
-types are significantly slower than integer or smaller types
-respectively. In the latter case, it also requires much more (by 8 or 4
-times in the example above) storage space. So when you confront such
-situations and want to store/archive/transfter/process the data, it is best
-convert them to the most efficient type.
-
-
-
-
-
address@hidden Arithmetic operators, Invoking astarithmetic, Data types, 
Arithmetic
address@hidden Arithmetic operators, Invoking astarithmetic, Reverse polish 
notation, Arithmetic
 @subsection Arithmetic operators
 
 The recognized operators in Arithmetic are listed below. See @ref{Reverse
@@ -7747,7 +7816,7 @@ array (for example a FITS image) or a number, the output 
will be an array
 or number according to the inputs. For example a number multiplied by an
 array will produce an array. The conditional operators will return pixel,
 or numerical values of 0 (false) or 1 (true) and stored in an
address@hidden char} data type (see @ref{Data types}).
address@hidden char} data type (see @ref{Numeric data types}).
 
 @table @command
 
@@ -8009,44 +8078,43 @@ numbers can be written as bit strings on the 
command-line): @code{00101000
 bitnot} will give @code{11010111}. Note that the bitwise operators only
 work on integer type datasets/numbers.
 
address@hidden uchar
-Convert the type of the popped operand to @code{unsigned char}. See
address@hidden types} for a short review of the different data types.
address@hidden uint8
+Convert the type of the popped operand to 8-bit un-signed integer type (see
address@hidden data types}). The internal conversion of C will be used.
 
address@hidden char
-Convert the type of the popped operand to @code{char}. See @ref{Data types}
-for a short review of the different data types.
address@hidden int8
+Convert the type of the popped operand to 8-bit signed integer type (see
address@hidden data types}). The internal conversion of C will be used.
 
address@hidden ushort
-Convert the type of the popped operand to @code{unsigned short}. See
address@hidden types} for a short review of the different data types.
address@hidden uint16
+Convert the type of the popped operand to 16-bit un-signed integer type
+(see @ref{Numeric data types}). The internal conversion of C will be used.
 
address@hidden short
-Convert the type of the popped operand to @code{short}. See @ref{Data
-types} for a short review of the different data types.
address@hidden int16
+Convert the type of the popped operand to 16-bit signed integer (see
address@hidden data types}). The internal conversion of C will be used.
 
address@hidden ulong
-Convert the type of the popped operand to @code{unsigned long}. See
address@hidden types} for a short review of the different data types.
address@hidden uint32
+Convert the type of the popped operand to 32-bit un-signed integer type
+(see @ref{Numeric data types}). The internal conversion of C will be used.
 
address@hidden long
-Convert the type of the popped operand to @code{long}. See @ref{Data types}
-for a short review of the different data types.
address@hidden int32
+Convert the type of the popped operand to 32-bit signed integer type (see
address@hidden data types}). The internal conversion of C will be used.
 
address@hidden longlong
-Convert the type of the popped operand to @code{long long} (64-bit
-integer). See @ref{Data types} for a short review of the different data
-types.
address@hidden uint64
+Convert the type of the popped operand to 64-bit un-signed integer (see
address@hidden data types}). The internal conversion of C will be used.
 
address@hidden float
-Convert the type of the popped operand to @code{float} (single precision
-floating point). See @ref{Data types} for a short review of the different
-data types.
address@hidden float32
+Convert the type of the popped operand to 32-bit (single precision)
+floating point (see @ref{Numeric data types}). The internal conversion of C
+will be used.
 
address@hidden double
-Convert the type of the popped operand to @code{double} (double precision
-floating point). See @ref{Data types} for a short review of the different
-data types.
address@hidden float64
+Convert the type of the popped operand to 64-bit (double precision)
+floating point (see @ref{Numeric data types}). The internal conversion of C
+will be used.
 
 @end table
 
@@ -8151,9 +8219,9 @@ when you install Gnuastro.
 Arithmetic accepts two kinds of input: images and numbers. Images are
 considered to be any of the inputs that is a file name of a recognized type
 (see @ref{Arguments}) and has more than one element/pixel. Numbers on the
-command-line will be read into the smallest type (see @ref{Data types})
-that can store them, so @command{-2} will be read as a @code{char} type
-(which is signed on most systems and can thus keep negative values),
+command-line will be read into the smallest type (see @ref{Numeric data
+types}) that can store them, so @command{-2} will be read as a @code{char}
+type (which is signed on most systems and can thus keep negative values),
 @command{2500} will be read as an @code{unsigned short} (all positive
 numbers will be read as unsigned), while @code{3.1415926535897} will be
 read as a @code{double} and @code{3.14} will be read as a @code{float}. To
@@ -13947,7 +14015,8 @@ see below. When a background image is specified, it 
will be used to derive
 all the information about the output image. Hence, the following options
 will be ignored: @option{--naxis1}, @option{--naxis2}, @option{--crpix1},
 @option{--crpix2}, @option{--crval1}, @option{--crval2},
address@hidden, @option{--oversample}, and @option{--type}.
address@hidden, @option{--oversample}, and data type (see
address@hidden in @ref{Input output}).
 
 The profiles will be built on the image (profile pixel values will be
 summed with the background image pixel values). If you want to use all the
@@ -13990,20 +14059,6 @@ The number of pixels in the output image along the 
second FITS axis
 (vertical when viewed in SAO ds9), see the explanation for
 @option{--naxis1}.
 
address@hidden -T STR
address@hidden --type=STR
-Data type of the output image pixels (specified by @code{BITPIX} in the
-FITS standard, see @ref{Data types}). It can have any one of the following
-values: @option{byte}, @option{short}, @option{long}, @option{longlong},
address@hidden, @option{double}. Internally, the images are made in the
-float type, but upon writing of the single output (not individual
-profiles), the image will be converted to the type specified by this
-option.
-
-When a background image is given without the @option{--backascanvas}
-option, it is assumed that you want the output with the same data type as
-the background, therefore the value to this option is ignored.
-
 @item -s INT
 @itemx --oversample=INT
 The scale to over-sample the profiles and final image. If not an odd
diff --git a/lib/Makefile.am b/lib/Makefile.am
index c198e9f..b4dce9f 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -106,17 +106,16 @@ gnuastro/config.h: Makefile config.h.in
               -e 's|@address@hidden|$(HAVE_LIBGIT2)|g'                  \
               -e 's|@address@hidden|$(HAVE_WCSLIB_VERSION)|g'    \
               -e 's|@address@hidden|$(HAVE_PTHREAD_BARRIER)|g'  \
-              -e 's|@address@hidden|$(HAVE_BIN_OP_UCHAR)|g'        \
-              -e 's|@address@hidden|$(HAVE_BIN_OP_CHAR)|g'          \
-              -e 's|@address@hidden|$(HAVE_BIN_OP_USHORT)|g'      \
-              -e 's|@address@hidden|$(HAVE_BIN_OP_SHORT)|g'        \
-              -e 's|@address@hidden|$(HAVE_BIN_OP_UINT)|g'          \
-              -e 's|@address@hidden|$(HAVE_BIN_OP_INT)|g'            \
-              -e 's|@address@hidden|$(HAVE_BIN_OP_ULONG)|g'        \
-              -e 's|@address@hidden|$(HAVE_BIN_OP_LONG)|g'          \
-              -e 's|@address@hidden|$(HAVE_BIN_OP_LONGLONG)|g'  \
-              -e 's|@address@hidden|$(HAVE_BIN_OP_FLOAT)|g'        \
-              -e 's|@address@hidden|$(HAVE_BIN_OP_DOUBLE)|g'      \
+              -e 's|@address@hidden|$(HAVE_BIN_OP_UINT8)|g'        \
+              -e 's|@address@hidden|$(HAVE_BIN_OP_INT8)|g'          \
+              -e 's|@address@hidden|$(HAVE_BIN_OP_UINT16)|g'      \
+              -e 's|@address@hidden|$(HAVE_BIN_OP_INT16)|g'        \
+              -e 's|@address@hidden|$(HAVE_BIN_OP_UINT32)|g'      \
+              -e 's|@address@hidden|$(HAVE_BIN_OP_INT32)|g'        \
+              -e 's|@address@hidden|$(HAVE_BIN_OP_UINT64)|g'      \
+              -e 's|@address@hidden|$(HAVE_BIN_OP_INT64)|g'        \
+              -e 's|@address@hidden|$(HAVE_BIN_OP_FLOAT32)|g'    \
+              -e 's|@address@hidden|$(HAVE_BIN_OP_FLOAT64)|g'    \
               -e 's|@address@hidden|$(SIZEOF_SIZE_T)|g'                \
                $(srcdir)/config.h.in >> address@hidden
        chmod a-w address@hidden
diff --git a/lib/arithmetic-binary.c b/lib/arithmetic-binary.c
index 654d723..a4b6b79 100644
--- a/lib/arithmetic-binary.c
+++ b/lib/arithmetic-binary.c
@@ -37,198 +37,180 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 /************************************************************************/
 /*************            Native type macros            *****************/
 /************************************************************************/
-#if GAL_CONFIG_BIN_OP_UCHAR == 1
-#define BINARY_LT_IS_UCHAR                                         \
-  case GAL_DATA_TYPE_UCHAR:                                        \
-    BINARY_LT_SET(unsigned char);                                  \
+#if GAL_CONFIG_BIN_OP_UINT8 == 1
+#define BINARY_LT_IS_UINT8                                         \
+  case GAL_DATA_TYPE_UINT8:                                        \
+    BINARY_LT_SET(uint8_t);                                        \
     break;
-#define BINARY_LT_SET_RT_IS_UCHAR(LT)                              \
-  case GAL_DATA_TYPE_UCHAR:                                        \
-    BINARY_RT_LT_SET(unsigned char, LT);                           \
+#define BINARY_LT_SET_RT_IS_UINT8(LT)                              \
+  case GAL_DATA_TYPE_UINT8:                                        \
+    BINARY_RT_LT_SET(uint8_t, LT);                                 \
     break;
 #else
-#define BINARY_LT_IS_UCHAR
-#define BINARY_LT_SET_RT_IS_UCHAR(LT)
+#define BINARY_LT_IS_UINT8
+#define BINARY_LT_SET_RT_IS_UINT8(LT)
 #endif
 
 
 
 
 
-#if GAL_CONFIG_BIN_OP_CHAR == 1
-#define BINARY_LT_IS_CHAR                                          \
-  case GAL_DATA_TYPE_CHAR:                                         \
-    BINARY_LT_SET(char);                                           \
+#if GAL_CONFIG_BIN_OP_INT8 == 1
+#define BINARY_LT_IS_INT8                                          \
+  case GAL_DATA_TYPE_INT8:                                         \
+    BINARY_LT_SET(int8_t);                                         \
     break;
-#define BINARY_LT_SET_RT_IS_CHAR(LT)                               \
-  case GAL_DATA_TYPE_CHAR:                                         \
-    BINARY_RT_LT_SET(char, LT);                                    \
+#define BINARY_LT_SET_RT_IS_INT8(LT)                               \
+  case GAL_DATA_TYPE_INT8:                                         \
+    BINARY_RT_LT_SET(int8_t, LT);                                  \
     break;
 #else
-#define BINARY_LT_IS_CHAR
-#define BINARY_LT_SET_RT_IS_CHAR(LT)
+#define BINARY_LT_IS_INT8
+#define BINARY_LT_SET_RT_IS_INT8(LT)
 #endif
 
 
 
 
 
-#if GAL_CONFIG_BIN_OP_USHORT == 1
-#define BINARY_LT_IS_USHORT                                        \
-  case GAL_DATA_TYPE_USHORT:                                       \
-    BINARY_LT_SET(unsigned short);                                 \
+#if GAL_CONFIG_BIN_OP_UINT16 == 1
+#define BINARY_LT_IS_UINT16                                        \
+  case GAL_DATA_TYPE_UINT16:                                       \
+    BINARY_LT_SET(uint16_t);                                       \
     break;
-#define BINARY_LT_SET_RT_IS_USHORT(LT)                             \
-  case GAL_DATA_TYPE_USHORT:                                       \
-    BINARY_RT_LT_SET(unsigned short, LT);                          \
+#define BINARY_LT_SET_RT_IS_UINT16(LT)                             \
+  case GAL_DATA_TYPE_UINT16:                                       \
+    BINARY_RT_LT_SET(uint16_t, LT);                                \
     break;
 #else
-#define BINARY_LT_IS_USHORT
-#define BINARY_LT_SET_RT_IS_USHORT(LT)
+#define BINARY_LT_IS_UINT16
+#define BINARY_LT_SET_RT_IS_UINT16(LT)
 #endif
 
 
 
 
 
-#if GAL_CONFIG_BIN_OP_SHORT == 1
-#define BINARY_LT_IS_SHORT                                         \
-  case GAL_DATA_TYPE_SHORT:                                        \
-    BINARY_LT_SET(short);                                          \
+#if GAL_CONFIG_BIN_OP_INT16 == 1
+#define BINARY_LT_IS_INT16                                         \
+  case GAL_DATA_TYPE_INT16:                                        \
+    BINARY_LT_SET(int16_t);                                        \
     break;
-#define BINARY_LT_SET_RT_IS_SHORT(LT)                              \
-  case GAL_DATA_TYPE_SHORT:                                        \
-    BINARY_RT_LT_SET(short, LT);                                   \
+#define BINARY_LT_SET_RT_IS_INT16(LT)                              \
+  case GAL_DATA_TYPE_INT16:                                        \
+    BINARY_RT_LT_SET(int16_t, LT);                                 \
     break;
 #else
-#define BINARY_LT_IS_SHORT
-#define BINARY_LT_SET_RT_IS_SHORT(LT)
+#define BINARY_LT_IS_INT16
+#define BINARY_LT_SET_RT_IS_INT16(LT)
 #endif
 
 
 
 
 
-#if GAL_CONFIG_BIN_OP_UINT == 1
-#define BINARY_LT_IS_UINT                                          \
-  case GAL_DATA_TYPE_UINT:                                         \
-    BINARY_LT_SET(unsigned int);                                   \
+#if GAL_CONFIG_BIN_OP_UINT32 == 1
+#define BINARY_LT_IS_UINT32                                        \
+  case GAL_DATA_TYPE_UINT32:                                       \
+    BINARY_LT_SET(uint32_t);                                       \
     break;
-#define BINARY_LT_SET_RT_IS_UINT(LT)                               \
-  case GAL_DATA_TYPE_UINT:                                         \
-    BINARY_RT_LT_SET(unsigned int, LT);                            \
+#define BINARY_LT_SET_RT_IS_UINT32(LT)                             \
+  case GAL_DATA_TYPE_UINT32:                                       \
+    BINARY_RT_LT_SET(uint32_t, LT);                                \
     break;
 #else
-#define BINARY_LT_IS_UINT
-#define BINARY_LT_SET_RT_IS_UINT(LT)
+#define BINARY_LT_IS_UINT32
+#define BINARY_LT_SET_RT_IS_UINT32(LT)
 #endif
 
 
 
 
 
-#if GAL_CONFIG_BIN_OP_INT == 1
-#define BINARY_LT_IS_INT                                           \
-  case GAL_DATA_TYPE_INT:                                          \
-    BINARY_LT_SET(int);                                            \
+#if GAL_CONFIG_BIN_OP_INT32 == 1
+#define BINARY_LT_IS_INT32                                         \
+  case GAL_DATA_TYPE_INT32:                                        \
+    BINARY_LT_SET(int32_t);                                        \
     break;
-#define BINARY_LT_SET_RT_IS_INT(LT)                                \
-  case GAL_DATA_TYPE_INT:                                          \
-    BINARY_RT_LT_SET(int, LT);                                     \
+#define BINARY_LT_SET_RT_IS_INT32(LT)                              \
+  case GAL_DATA_TYPE_INT32:                                        \
+    BINARY_RT_LT_SET(int32_t, LT);                                 \
     break;
 #else
-#define BINARY_LT_IS_INT
-#define BINARY_LT_SET_RT_IS_INT(LT)
+#define BINARY_LT_IS_INT32
+#define BINARY_LT_SET_RT_IS_INT32(LT)
 #endif
 
 
 
 
 
-#if GAL_CONFIG_BIN_OP_ULONG == 1
-#define BINARY_LT_IS_ULONG                                         \
-  case GAL_DATA_TYPE_ULONG:                                        \
-    BINARY_LT_SET(unsigned long);                                  \
+#if GAL_CONFIG_BIN_OP_UINT64 == 1
+#define BINARY_LT_IS_UINT64                                        \
+  case GAL_DATA_TYPE_UINT64:                                       \
+    BINARY_LT_SET(uint64_t);                                       \
     break;
-#define BINARY_LT_SET_RT_IS_ULONG(LT)                              \
-  case GAL_DATA_TYPE_ULONG:                                        \
-    BINARY_RT_LT_SET(unsigned long, LT);                           \
+#define BINARY_LT_SET_RT_IS_UINT64(LT)                             \
+  case GAL_DATA_TYPE_UINT64:                                       \
+    BINARY_RT_LT_SET(uint64_t, LT);                                \
     break;
 #else
-#define BINARY_LT_IS_ULONG
-#define BINARY_LT_SET_RT_IS_ULONG(LT)
+#define BINARY_LT_IS_UINT64
+#define BINARY_LT_SET_RT_IS_UINT64(LT)
 #endif
 
 
 
 
 
-#if GAL_CONFIG_BIN_OP_LONG == 1
-#define BINARY_LT_IS_LONG                                          \
-  case GAL_DATA_TYPE_LONG:                                         \
-    BINARY_LT_SET(long);                                           \
+#if GAL_CONFIG_BIN_OP_INT64 == 1
+#define BINARY_LT_IS_INT64                                         \
+  case GAL_DATA_TYPE_INT64:                                        \
+    BINARY_LT_SET(int64_t);                                        \
     break;
-#define BINARY_LT_SET_RT_IS_LONG(LT)                               \
-  case GAL_DATA_TYPE_LONG:                                         \
-    BINARY_RT_LT_SET(long, LT);                                    \
+#define BINARY_LT_SET_RT_IS_INT64(LT)                              \
+  case GAL_DATA_TYPE_INT64:                                        \
+    BINARY_RT_LT_SET(int64_t, LT);                                 \
     break;
 #else
-#define BINARY_LT_IS_LONG
-#define BINARY_LT_SET_RT_IS_LONG(LT)
+#define BINARY_LT_IS_INT64
+#define BINARY_LT_SET_RT_IS_INT64(LT)
 #endif
 
 
 
 
 
-#if GAL_CONFIG_BIN_OP_LONGLONG == 1
-#define BINARY_LT_IS_LONGLONG                                      \
-  case GAL_DATA_TYPE_LONGLONG:                                     \
-    BINARY_LT_SET(LONGLONG);                                       \
-    break;
-#define BINARY_LT_SET_RT_IS_LONGLONG(LT)                           \
-  case GAL_DATA_TYPE_LONGLONG:                                     \
-    BINARY_RT_LT_SET(LONGLONG, LT);                                \
-    break;
-#else
-#define BINARY_LT_IS_LONGLONG
-#define BINARY_LT_SET_RT_IS_LONGLONG(LT)
-#endif
-
-
-
-
-
-#if GAL_CONFIG_BIN_OP_FLOAT == 1
-#define BINARY_LT_IS_FLOAT                                         \
-  case GAL_DATA_TYPE_FLOAT:                                        \
+#if GAL_CONFIG_BIN_OP_FLOAT32 == 1
+#define BINARY_LT_IS_FLOAT32                                       \
+  case GAL_DATA_TYPE_FLOAT32:                                      \
     BINARY_LT_SET(float);                                          \
     break;
-#define BINARY_LT_SET_RT_IS_FLOAT(LT)                              \
-  case GAL_DATA_TYPE_FLOAT:                                        \
+#define BINARY_LT_SET_RT_IS_FLOAT32(LT)                            \
+  case GAL_DATA_TYPE_FLOAT32:                                      \
     BINARY_RT_LT_SET(float, LT);                                   \
     break;
 #else
-#define BINARY_LT_IS_FLOAT
-#define BINARY_LT_SET_RT_IS_FLOAT(LT)
+#define BINARY_LT_IS_FLOAT32
+#define BINARY_LT_SET_RT_IS_FLOAT32(LT)
 #endif
 
 
 
 
 
-#if GAL_CONFIG_BIN_OP_DOUBLE == 1
-#define BINARY_LT_IS_DOUBLE                                        \
-  case GAL_DATA_TYPE_DOUBLE:                                       \
+#if GAL_CONFIG_BIN_OP_FLOAT64 == 1
+#define BINARY_LT_IS_FLOAT64                                       \
+  case GAL_DATA_TYPE_FLOAT64:                                      \
     BINARY_LT_SET(double);                                         \
     break;
-#define BINARY_LT_SET_RT_IS_DOUBLE(LT)                             \
-  case GAL_DATA_TYPE_DOUBLE:                                       \
+#define BINARY_LT_SET_RT_IS_FLOAT64(LT)                            \
+  case GAL_DATA_TYPE_FLOAT64:                                      \
     BINARY_RT_LT_SET(double, LT);                                  \
     break;
 #else
-#define BINARY_LT_IS_DOUBLE
-#define BINARY_LT_SET_RT_IS_DOUBLE(LT)
+#define BINARY_LT_IS_FLOAT64
+#define BINARY_LT_SET_RT_IS_FLOAT64(LT)
 #endif
 
 
@@ -308,28 +290,28 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
       BINARY_OP_RT_LT_SET(/, RT, LT);                              \
       break;                                                       \
     case GAL_ARITHMETIC_OP_LT:                                     \
-      BINARY_OP_OT_RT_LT_SET(<, unsigned char, RT, LT);            \
+      BINARY_OP_OT_RT_LT_SET(<, uint8_t, RT, LT);                  \
       break;                                                       \
     case GAL_ARITHMETIC_OP_LE:                                     \
-      BINARY_OP_OT_RT_LT_SET(<=, unsigned char, RT, LT);           \
+      BINARY_OP_OT_RT_LT_SET(<=, uint8_t, RT, LT);                 \
       break;                                                       \
     case GAL_ARITHMETIC_OP_GT:                                     \
-      BINARY_OP_OT_RT_LT_SET(>, unsigned char, RT, LT);            \
+      BINARY_OP_OT_RT_LT_SET(>, uint8_t, RT, LT);                  \
       break;                                                       \
     case GAL_ARITHMETIC_OP_GE:                                     \
-      BINARY_OP_OT_RT_LT_SET(>=, unsigned char, RT, LT);           \
+      BINARY_OP_OT_RT_LT_SET(>=, uint8_t, RT, LT);                 \
       break;                                                       \
     case GAL_ARITHMETIC_OP_EQ:                                     \
-      BINARY_OP_OT_RT_LT_SET(==, unsigned char, RT, LT);           \
+      BINARY_OP_OT_RT_LT_SET(==, uint8_t, RT, LT);                 \
       break;                                                       \
     case GAL_ARITHMETIC_OP_NE:                                     \
-      BINARY_OP_OT_RT_LT_SET(!=, unsigned char, RT, LT);           \
+      BINARY_OP_OT_RT_LT_SET(!=, uint8_t, RT, LT);                 \
       break;                                                       \
     case GAL_ARITHMETIC_OP_AND:                                    \
-      BINARY_OP_INCR_OT_RT_LT_SET(&&, unsigned char, RT, LT);      \
+      BINARY_OP_INCR_OT_RT_LT_SET(&&, uint8_t, RT, LT);            \
       break;                                                       \
     case GAL_ARITHMETIC_OP_OR:                                     \
-      BINARY_OP_INCR_OT_RT_LT_SET(||, unsigned char, RT, LT);      \
+      BINARY_OP_INCR_OT_RT_LT_SET(||, uint8_t, RT, LT);            \
       break;                                                       \
     default:                                                       \
       error(EXIT_FAILURE, 0, "operator code %d not recognized in " \
@@ -345,17 +327,16 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #define BINARY_LT_SET(LT)                                          \
   switch(r->type)                                                  \
     {                                                              \
-      BINARY_LT_SET_RT_IS_UCHAR(LT);                               \
-      BINARY_LT_SET_RT_IS_CHAR(LT);                                \
-      BINARY_LT_SET_RT_IS_USHORT(LT);                              \
-      BINARY_LT_SET_RT_IS_SHORT(LT);                               \
-      BINARY_LT_SET_RT_IS_UINT(LT);                                \
-      BINARY_LT_SET_RT_IS_INT(LT);                                 \
-      BINARY_LT_SET_RT_IS_ULONG(LT);                               \
-      BINARY_LT_SET_RT_IS_LONG(LT);                                \
-      BINARY_LT_SET_RT_IS_LONGLONG(LT);                            \
-      BINARY_LT_SET_RT_IS_FLOAT(LT);                               \
-      BINARY_LT_SET_RT_IS_DOUBLE(LT);                              \
+      BINARY_LT_SET_RT_IS_UINT8(LT);                               \
+      BINARY_LT_SET_RT_IS_INT8(LT);                                \
+      BINARY_LT_SET_RT_IS_UINT16(LT);                              \
+      BINARY_LT_SET_RT_IS_INT16(LT);                               \
+      BINARY_LT_SET_RT_IS_UINT32(LT);                              \
+      BINARY_LT_SET_RT_IS_INT32(LT);                               \
+      BINARY_LT_SET_RT_IS_UINT64(LT);                              \
+      BINARY_LT_SET_RT_IS_INT64(LT);                               \
+      BINARY_LT_SET_RT_IS_FLOAT32(LT);                             \
+      BINARY_LT_SET_RT_IS_FLOAT64(LT);                             \
     default:                                                       \
       error(EXIT_FAILURE, 0, "type code %d not recognized in "     \
             "`BINARY_LT_SET'", r->type);                           \
@@ -384,13 +365,13 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 /*************              Top level function          *****************/
 /************************************************************************/
 gal_data_t *
-arithmetic_binary(int operator, unsigned char flags, gal_data_t *lo,
+arithmetic_binary(int operator, uint8_t flags, gal_data_t *lo,
                   gal_data_t *ro)
 {
   /* Read the variable arguments. `lo' and `ro' keep the original data, in
      case their type isn't built (based on configure options are configure
      time). */
-  int otype, final_otype;
+  int32_t otype, final_otype;
   size_t out_size, minmapsize;
   gal_data_t *l, *r, *o=NULL, *tmp_o;
 
@@ -456,17 +437,16 @@ arithmetic_binary(int operator, unsigned char flags, 
gal_data_t *lo,
   /* Start setting the operator and operands. */
   switch(l->type)
     {
-      BINARY_LT_IS_UCHAR;
-      BINARY_LT_IS_CHAR;
-      BINARY_LT_IS_USHORT;
-      BINARY_LT_IS_SHORT;
-      BINARY_LT_IS_UINT;
-      BINARY_LT_IS_INT;
-      BINARY_LT_IS_ULONG;
-      BINARY_LT_IS_LONG;
-      BINARY_LT_IS_LONGLONG;
-      BINARY_LT_IS_FLOAT;
-      BINARY_LT_IS_DOUBLE;
+      BINARY_LT_IS_UINT8;
+      BINARY_LT_IS_INT8;
+      BINARY_LT_IS_UINT16;
+      BINARY_LT_IS_INT16;
+      BINARY_LT_IS_UINT32;
+      BINARY_LT_IS_INT32;
+      BINARY_LT_IS_UINT64;
+      BINARY_LT_IS_INT64;
+      BINARY_LT_IS_FLOAT32;
+      BINARY_LT_IS_FLOAT64;
     default:
       error(EXIT_FAILURE, 0, "type code %d not recognized in "
             "`arithmetic_binary'", l->type);
diff --git a/lib/arithmetic-binary.h b/lib/arithmetic-binary.h
index bd498ef..496cb9f 100644
--- a/lib/arithmetic-binary.h
+++ b/lib/arithmetic-binary.h
@@ -25,7 +25,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 gal_data_t *
-arithmetic_binary(int operator, unsigned char flags, gal_data_t *lo,
+arithmetic_binary(int operator, uint8_t flags, gal_data_t *lo,
                   gal_data_t *ro);
 
 
diff --git a/lib/arithmetic-onlyint.c b/lib/arithmetic-onlyint.c
index 831bb65..6073c32 100644
--- a/lib/arithmetic-onlyint.c
+++ b/lib/arithmetic-onlyint.c
@@ -38,162 +38,144 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 /************************************************************************/
 /*************            Native type macros            *****************/
 /************************************************************************/
-#if GAL_CONFIG_BIN_OP_UCHAR == 1
-#define BINOIN_LT_IS_UCHAR                                         \
-  case GAL_DATA_TYPE_UCHAR:                                        \
-    BINOIN_LT_SET(unsigned char);                                  \
+#if GAL_CONFIG_BIN_OP_UINT8 == 1
+#define BINOIN_LT_IS_UINT8                                         \
+  case GAL_DATA_TYPE_UINT8:                                        \
+    BINOIN_LT_SET(uint8_t);                                        \
     break;
-#define BINOIN_LT_SET_RT_IS_UCHAR(LT)                              \
-  case GAL_DATA_TYPE_UCHAR:                                        \
-    BINOIN_RT_LT_SET(unsigned char, LT);                           \
+#define BINOIN_LT_SET_RT_IS_UINT8(LT)                              \
+  case GAL_DATA_TYPE_UINT8:                                        \
+    BINOIN_RT_LT_SET(uint8_t, LT);                                 \
     break;
 #else
-#define BINOIN_LT_IS_UCHAR
-#define BINOIN_LT_SET_RT_IS_UCHAR(LT)
+#define BINOIN_LT_IS_UINT8
+#define BINOIN_LT_SET_RT_IS_UINT8(LT)
 #endif
 
 
 
 
 
-#if GAL_CONFIG_BIN_OP_CHAR == 1
-#define BINOIN_LT_IS_CHAR                                          \
-  case GAL_DATA_TYPE_CHAR:                                         \
-    BINOIN_LT_SET(char);                                           \
+#if GAL_CONFIG_BIN_OP_INT8 == 1
+#define BINOIN_LT_IS_INT8                                          \
+  case GAL_DATA_TYPE_INT8:                                         \
+    BINOIN_LT_SET(int8_t);                                         \
     break;
-#define BINOIN_LT_SET_RT_IS_CHAR(LT)                               \
-  case GAL_DATA_TYPE_CHAR:                                         \
-    BINOIN_RT_LT_SET(char, LT);                                    \
+#define BINOIN_LT_SET_RT_IS_INT8(LT)                               \
+  case GAL_DATA_TYPE_INT8:                                         \
+    BINOIN_RT_LT_SET(int8_t, LT);                                  \
     break;
 #else
-#define BINOIN_LT_IS_CHAR
-#define BINOIN_LT_SET_RT_IS_CHAR(LT)
+#define BINOIN_LT_IS_INT8
+#define BINOIN_LT_SET_RT_IS_INT8(LT)
 #endif
 
 
 
 
 
-#if GAL_CONFIG_BIN_OP_USHORT == 1
-#define BINOIN_LT_IS_USHORT                                        \
-  case GAL_DATA_TYPE_USHORT:                                       \
-    BINOIN_LT_SET(unsigned short);                                 \
+#if GAL_CONFIG_BIN_OP_UINT16 == 1
+#define BINOIN_LT_IS_UINT16                                        \
+  case GAL_DATA_TYPE_UINT16:                                       \
+    BINOIN_LT_SET(uint16_t);                                       \
     break;
-#define BINOIN_LT_SET_RT_IS_USHORT(LT)                             \
-  case GAL_DATA_TYPE_USHORT:                                       \
-    BINOIN_RT_LT_SET(unsigned short, LT);                          \
+#define BINOIN_LT_SET_RT_IS_UINT16(LT)                             \
+  case GAL_DATA_TYPE_UINT16:                                       \
+    BINOIN_RT_LT_SET(uint16_t, LT);                                \
     break;
 #else
-#define BINOIN_LT_IS_USHORT
-#define BINOIN_LT_SET_RT_IS_USHORT(LT)
+#define BINOIN_LT_IS_UINT16
+#define BINOIN_LT_SET_RT_IS_UINT16(LT)
 #endif
 
 
 
 
 
-#if GAL_CONFIG_BIN_OP_SHORT == 1
-#define BINOIN_LT_IS_SHORT                                         \
-  case GAL_DATA_TYPE_SHORT:                                        \
-    BINOIN_LT_SET(short);                                          \
+#if GAL_CONFIG_BIN_OP_INT16 == 1
+#define BINOIN_LT_IS_INT16                                         \
+  case GAL_DATA_TYPE_INT16:                                        \
+    BINOIN_LT_SET(int16_t);                                        \
     break;
-#define BINOIN_LT_SET_RT_IS_SHORT(LT)                              \
-  case GAL_DATA_TYPE_SHORT:                                        \
-    BINOIN_RT_LT_SET(short, LT);                                   \
+#define BINOIN_LT_SET_RT_IS_INT16(LT)                              \
+  case GAL_DATA_TYPE_INT16:                                        \
+    BINOIN_RT_LT_SET(int16_t, LT);                                 \
     break;
 #else
-#define BINOIN_LT_IS_SHORT
-#define BINOIN_LT_SET_RT_IS_SHORT(LT)
+#define BINOIN_LT_IS_INT16
+#define BINOIN_LT_SET_RT_IS_INT16(LT)
 #endif
 
 
 
 
 
-#if GAL_CONFIG_BIN_OP_UINT == 1
-#define BINOIN_LT_IS_UINT                                          \
-  case GAL_DATA_TYPE_UINT:                                         \
-    BINOIN_LT_SET(unsigned int);                                   \
+#if GAL_CONFIG_BIN_OP_UINT32 == 1
+#define BINOIN_LT_IS_UINT32                                        \
+  case GAL_DATA_TYPE_UINT32:                                       \
+    BINOIN_LT_SET(uint32_t);                                       \
     break;
-#define BINOIN_LT_SET_RT_IS_UINT(LT)                               \
-  case GAL_DATA_TYPE_UINT:                                         \
-    BINOIN_RT_LT_SET(unsigned int, LT);                            \
+#define BINOIN_LT_SET_RT_IS_UINT32(LT)                             \
+  case GAL_DATA_TYPE_UINT32:                                       \
+    BINOIN_RT_LT_SET(uint32_t, LT);                                \
     break;
 #else
-#define BINOIN_LT_IS_UINT
-#define BINOIN_LT_SET_RT_IS_UINT(LT)
+#define BINOIN_LT_IS_UINT32
+#define BINOIN_LT_SET_RT_IS_UINT32(LT)
 #endif
 
 
 
 
 
-#if GAL_CONFIG_BIN_OP_INT == 1
-#define BINOIN_LT_IS_INT                                           \
-  case GAL_DATA_TYPE_INT:                                          \
-    BINOIN_LT_SET(int);                                            \
+#if GAL_CONFIG_BIN_OP_INT32 == 1
+#define BINOIN_LT_IS_INT32                                         \
+  case GAL_DATA_TYPE_INT32:                                        \
+    BINOIN_LT_SET(int32_t);                                        \
     break;
-#define BINOIN_LT_SET_RT_IS_INT(LT)                                \
-  case GAL_DATA_TYPE_INT:                                          \
-    BINOIN_RT_LT_SET(int, LT);                                     \
+#define BINOIN_LT_SET_RT_IS_INT32(LT)                              \
+  case GAL_DATA_TYPE_INT32:                                        \
+    BINOIN_RT_LT_SET(int32_t, LT);                                 \
     break;
 #else
-#define BINOIN_LT_IS_INT
-#define BINOIN_LT_SET_RT_IS_INT(LT)
+#define BINOIN_LT_IS_INT32
+#define BINOIN_LT_SET_RT_IS_INT32(LT)
 #endif
 
 
 
 
 
-#if GAL_CONFIG_BIN_OP_ULONG == 1
-#define BINOIN_LT_IS_ULONG                                         \
-  case GAL_DATA_TYPE_ULONG:                                        \
-    BINOIN_LT_SET(unsigned long);                                  \
+#if GAL_CONFIG_BIN_OP_UINT64 == 1
+#define BINOIN_LT_IS_UINT64                                        \
+  case GAL_DATA_TYPE_UINT64:                                       \
+    BINOIN_LT_SET(uint64_t);                                       \
     break;
-#define BINOIN_LT_SET_RT_IS_ULONG(LT)                              \
-  case GAL_DATA_TYPE_ULONG:                                        \
-    BINOIN_RT_LT_SET(unsigned long, LT);                           \
+#define BINOIN_LT_SET_RT_IS_UINT64(LT)                             \
+  case GAL_DATA_TYPE_UINT64:                                       \
+    BINOIN_RT_LT_SET(uint64_t, LT);                                \
     break;
 #else
-#define BINOIN_LT_IS_ULONG
-#define BINOIN_LT_SET_RT_IS_ULONG(LT)
+#define BINOIN_LT_IS_UINT64
+#define BINOIN_LT_SET_RT_IS_UINT64(LT)
 #endif
 
 
 
 
 
-#if GAL_CONFIG_BIN_OP_LONG == 1
-#define BINOIN_LT_IS_LONG                                          \
-  case GAL_DATA_TYPE_LONG:                                         \
-    BINOIN_LT_SET(long);                                           \
+#if GAL_CONFIG_BIN_OP_INT64 == 1
+#define BINOIN_LT_IS_INT64                                         \
+  case GAL_DATA_TYPE_INT64:                                        \
+    BINOIN_LT_SET(int64_t);                                        \
     break;
-#define BINOIN_LT_SET_RT_IS_LONG(LT)                               \
-  case GAL_DATA_TYPE_LONG:                                         \
-    BINOIN_RT_LT_SET(long, LT);                                    \
+#define BINOIN_LT_SET_RT_IS_INT64(LT)                              \
+  case GAL_DATA_TYPE_INT64:                                        \
+    BINOIN_RT_LT_SET(int64_t, LT);                                 \
     break;
 #else
-#define BINOIN_LT_IS_LONG
-#define BINOIN_LT_SET_RT_IS_LONG(LT)
-#endif
-
-
-
-
-
-#if GAL_CONFIG_BIN_OP_LONGLONG == 1
-#define BINOIN_LT_IS_LONGLONG                                      \
-  case GAL_DATA_TYPE_LONGLONG:                                     \
-    BINOIN_LT_SET(LONGLONG);                                       \
-    break;
-#define BINOIN_LT_SET_RT_IS_LONGLONG(LT)                           \
-  case GAL_DATA_TYPE_LONGLONG:                                     \
-    BINOIN_RT_LT_SET(LONGLONG, LT);                                \
-    break;
-#else
-#define BINOIN_LT_IS_LONGLONG
-#define BINOIN_LT_SET_RT_IS_LONGLONG(LT)
+#define BINOIN_LT_IS_INT64
+#define BINOIN_LT_SET_RT_IS_INT64(LT)
 #endif
 
 
@@ -278,15 +260,14 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #define BINOIN_LT_SET(LT)                                          \
   switch(r->type)                                                  \
     {                                                              \
-      BINOIN_LT_SET_RT_IS_UCHAR(LT);                               \
-      BINOIN_LT_SET_RT_IS_CHAR(LT);                                \
-      BINOIN_LT_SET_RT_IS_USHORT(LT);                              \
-      BINOIN_LT_SET_RT_IS_SHORT(LT);                               \
-      BINOIN_LT_SET_RT_IS_UINT(LT);                                \
-      BINOIN_LT_SET_RT_IS_INT(LT);                                 \
-      BINOIN_LT_SET_RT_IS_ULONG(LT);                               \
-      BINOIN_LT_SET_RT_IS_LONG(LT);                                \
-      BINOIN_LT_SET_RT_IS_LONGLONG(LT);                            \
+      BINOIN_LT_SET_RT_IS_UINT8(LT);                               \
+      BINOIN_LT_SET_RT_IS_INT8(LT);                                \
+      BINOIN_LT_SET_RT_IS_UINT16(LT);                              \
+      BINOIN_LT_SET_RT_IS_INT16(LT);                               \
+      BINOIN_LT_SET_RT_IS_UINT32(LT);                              \
+      BINOIN_LT_SET_RT_IS_INT32(LT);                               \
+      BINOIN_LT_SET_RT_IS_UINT64(LT);                              \
+      BINOIN_LT_SET_RT_IS_INT64(LT);                               \
     default:                                                       \
       error(EXIT_FAILURE, 0, "type code %d not recognized in "     \
             "`BINOIN_LT_SET'", r->type);                           \
@@ -333,8 +314,8 @@ arithmetic_onlyint_binary(int operator, unsigned char flags,
     error(EXIT_FAILURE, 0, "the non-number inputs to %s don't have the "
           "same dimension/size", opstring);
 
-  if( lo->type==GAL_DATA_TYPE_FLOAT || lo->type==GAL_DATA_TYPE_DOUBLE
-      || ro->type==GAL_DATA_TYPE_FLOAT || ro->type==GAL_DATA_TYPE_DOUBLE )
+  if( lo->type==GAL_DATA_TYPE_FLOAT32 || lo->type==GAL_DATA_TYPE_FLOAT64
+      || ro->type==GAL_DATA_TYPE_FLOAT32 || ro->type==GAL_DATA_TYPE_FLOAT64 )
       error(EXIT_FAILURE, 0, "the %s operator can only work on integer "
             "type operands", opstring);
 
@@ -355,7 +336,7 @@ arithmetic_onlyint_binary(int operator, unsigned char flags,
 
 
   /* Sanity check: see if the compiled type is actually an integer. */
-  if( l->type>=GAL_DATA_TYPE_FLOAT || r->type>=GAL_DATA_TYPE_FLOAT )
+  if( l->type>=GAL_DATA_TYPE_FLOAT32 || r->type>=GAL_DATA_TYPE_FLOAT32 )
     error(EXIT_FAILURE, 0, "no larger integer compiled type. The `%s' "
           "operator can only work on integer types. The left and right "
           "operands had types `%s' and `%s'.\n\nYou can use the "
@@ -405,15 +386,14 @@ arithmetic_onlyint_binary(int operator, unsigned char 
flags,
   /* Start setting the operator and operands. */
   switch(l->type)
     {
-      BINOIN_LT_IS_UCHAR;
-      BINOIN_LT_IS_CHAR;
-      BINOIN_LT_IS_USHORT;
-      BINOIN_LT_IS_SHORT;
-      BINOIN_LT_IS_UINT;
-      BINOIN_LT_IS_INT;
-      BINOIN_LT_IS_ULONG;
-      BINOIN_LT_IS_LONG;
-      BINOIN_LT_IS_LONGLONG;
+      BINOIN_LT_IS_UINT8;
+      BINOIN_LT_IS_INT8;
+      BINOIN_LT_IS_UINT16;
+      BINOIN_LT_IS_INT16;
+      BINOIN_LT_IS_UINT32;
+      BINOIN_LT_IS_INT32;
+      BINOIN_LT_IS_UINT64;
+      BINOIN_LT_IS_INT64;
     default:
       error(EXIT_FAILURE, 0, "type code %d not recognized in "
             "`arithmetic_onlyint_binary'", l->type);
@@ -464,21 +444,20 @@ gal_data_t *
 arithmetic_onlyint_bitwise_not(unsigned char flags, gal_data_t *in)
 {
   gal_data_t *o;
-  unsigned char    *iuc=in->array, *iucf=in->array+in->size, *ouc;
-  char              *ic=in->array,  *icf=in->array+in->size,  *oc;
-  unsigned short   *ius=in->array, *iusf=in->array+in->size, *ous;
-  short             *is=in->array,  *isf=in->array+in->size,  *os;
-  unsigned int     *iui=in->array, *iuif=in->array+in->size, *oui;
-  int               *ii=in->array,  *iif=in->array+in->size,  *oi;
-  unsigned long    *iul=in->array, *iulf=in->array+in->size, *oul;
-  long              *il=in->array,  *ilf=in->array+in->size,  *ol;
-  LONGLONG          *iL=in->array,  *iLf=in->array+in->size,  *oL;
+  uint8_t    *iu8  = in->array,  *iu8f  = iu8  + in->size,   *ou8;
+  int8_t     *ii8  = in->array,  *ii8f  = ii8  + in->size,   *oi8;
+  uint16_t   *iu16 = in->array,  *iu16f = iu16 + in->size,   *ou16;
+  int16_t    *ii16 = in->array,  *ii16f = ii16 + in->size,   *oi16;
+  uint32_t   *iu32 = in->array,  *iu32f = iu32 + in->size,   *ou32;
+  int32_t    *ii32 = in->array,  *ii32f = ii32 + in->size,   *oi32;
+  uint64_t   *iu64 = in->array,  *iu64f = iu64 + in->size,   *ou64;
+  int64_t    *ii64 = in->array,  *ii64f = ii64 + in->size,   *oi64;
 
   /* Check the type */
   switch(in->type)
     {
-    case GAL_DATA_TYPE_FLOAT:
-    case GAL_DATA_TYPE_DOUBLE:
+    case GAL_DATA_TYPE_FLOAT32:
+    case GAL_DATA_TYPE_FLOAT64:
       error(EXIT_FAILURE, 0, "the bitwise not (one's complement) "
             "operator can only work on integer types");
     }
@@ -494,24 +473,30 @@ arithmetic_onlyint_bitwise_not(unsigned char flags, 
gal_data_t *in)
   /* Start setting the types. */
   switch(in->type)
     {
-    case GAL_DATA_TYPE_UCHAR:
-      ouc=o->array;   do *ouc++ = ~(*iuc++);  while(iuc<iucf);
-    case GAL_DATA_TYPE_CHAR:
-      oc=o->array;    do  *oc++ = ~(*ic++);   while(ic<icf);
-    case GAL_DATA_TYPE_USHORT:
-      ous=o->array;   do *ous++ = ~(*ius++);  while(ius<iusf);
-    case GAL_DATA_TYPE_SHORT:
-      os=o->array;    do  *os++ = ~(*is++);   while(is<isf);
-    case GAL_DATA_TYPE_UINT:
-      oui=o->array;   do *oui++ = ~(*iui++);  while(iui<iuif);
-    case GAL_DATA_TYPE_INT:
-      oi=o->array;    do  *oi++ = ~(*ii++);   while(ii<iif);
-    case GAL_DATA_TYPE_ULONG:
-      oul=o->array;   do *oul++ = ~(*iul++);  while(iul<iulf);
-    case GAL_DATA_TYPE_LONG:
-      ol=o->array;    do  *ol++ = ~(*il++);   while(il<ilf);
-    case GAL_DATA_TYPE_LONGLONG:
-      oL=o->array;    do  *oL++ = ~(*iL++);   while(iL<iLf);
+    case GAL_DATA_TYPE_UINT8:
+      ou8=o->array;   do  *ou8++ = ~(*iu8++);    while(iu8<iu8f);
+
+    case GAL_DATA_TYPE_INT8:
+      oi8=o->array;   do  *oi8++ = ~(*ii8++);    while(ii8<ii8f);
+
+    case GAL_DATA_TYPE_UINT16:
+      ou16=o->array;  do *ou16++ = ~(*iu16++);   while(iu16<iu16f);
+
+    case GAL_DATA_TYPE_INT16:
+      oi16=o->array;  do *oi16++ = ~(*ii16++);   while(ii16<ii16f);
+
+    case GAL_DATA_TYPE_UINT32:
+      ou32=o->array;  do *ou32++ = ~(*iu32++);   while(iu32<iu32f);
+
+    case GAL_DATA_TYPE_INT32:
+      oi32=o->array;  do *oi32++ = ~(*ii32++);   while(ii32<ii32f);
+
+    case GAL_DATA_TYPE_UINT64:
+      ou64=o->array;  do *ou64++ = ~(*iu64++);   while(iu64<iu64f);
+
+    case GAL_DATA_TYPE_INT64:
+      oi64=o->array;  do *oi64++ = ~(*ii64++);   while(ii64<ii64f);
+
     default:
       error(EXIT_FAILURE, 0, "type code %d not recognized in "
             "data_arithmetic_bitwise_not", in->type);
diff --git a/lib/arithmetic.c b/lib/arithmetic.c
index f56decb..531db06 100644
--- a/lib/arithmetic.c
+++ b/lib/arithmetic.c
@@ -24,6 +24,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #include <errno.h>
 #include <error.h>
+#include <stdlib.h>
 #include <stdarg.h>
 
 #include <gnuastro/qsort.h>
@@ -50,17 +51,16 @@ arithmetic_change_type(gal_data_t *data, int operator, 
unsigned char flags)
   /* Set the output type. */
   switch(operator)
     {
-    case GAL_ARITHMETIC_OP_TO_UCHAR:    type=GAL_DATA_TYPE_UCHAR;    break;
-    case GAL_ARITHMETIC_OP_TO_CHAR:     type=GAL_DATA_TYPE_UCHAR;    break;
-    case GAL_ARITHMETIC_OP_TO_USHORT:   type=GAL_DATA_TYPE_USHORT;   break;
-    case GAL_ARITHMETIC_OP_TO_SHORT:    type=GAL_DATA_TYPE_SHORT;    break;
-    case GAL_ARITHMETIC_OP_TO_UINT:     type=GAL_DATA_TYPE_UINT;     break;
-    case GAL_ARITHMETIC_OP_TO_INT:      type=GAL_DATA_TYPE_INT;      break;
-    case GAL_ARITHMETIC_OP_TO_ULONG:    type=GAL_DATA_TYPE_ULONG;    break;
-    case GAL_ARITHMETIC_OP_TO_LONG:     type=GAL_DATA_TYPE_LONG;     break;
-    case GAL_ARITHMETIC_OP_TO_LONGLONG: type=GAL_DATA_TYPE_LONGLONG; break;
-    case GAL_ARITHMETIC_OP_TO_FLOAT:    type=GAL_DATA_TYPE_FLOAT;    break;
-    case GAL_ARITHMETIC_OP_TO_DOUBLE:   type=GAL_DATA_TYPE_DOUBLE;   break;
+    case GAL_ARITHMETIC_OP_TO_UINT8:    type=GAL_DATA_TYPE_UINT8;    break;
+    case GAL_ARITHMETIC_OP_TO_INT8:     type=GAL_DATA_TYPE_INT8;     break;
+    case GAL_ARITHMETIC_OP_TO_UINT16:   type=GAL_DATA_TYPE_UINT16;   break;
+    case GAL_ARITHMETIC_OP_TO_INT16:    type=GAL_DATA_TYPE_INT16;    break;
+    case GAL_ARITHMETIC_OP_TO_UINT32:   type=GAL_DATA_TYPE_UINT32;   break;
+    case GAL_ARITHMETIC_OP_TO_INT32:    type=GAL_DATA_TYPE_INT32;    break;
+    case GAL_ARITHMETIC_OP_TO_UINT64:   type=GAL_DATA_TYPE_UINT64;   break;
+    case GAL_ARITHMETIC_OP_TO_INT64:    type=GAL_DATA_TYPE_INT64;    break;
+    case GAL_ARITHMETIC_OP_TO_FLOAT32:  type=GAL_DATA_TYPE_FLOAT32;  break;
+    case GAL_ARITHMETIC_OP_TO_FLOAT64:  type=GAL_DATA_TYPE_FLOAT64;  break;
     default:
       error(EXIT_FAILURE, 0, "operator value of %d not recognized in "
             "`arithmetic_change_type'", operator);
@@ -83,35 +83,19 @@ arithmetic_change_type(gal_data_t *data, int operator, 
unsigned char flags)
 
 /* Return an array of value 1 for any zero valued element and zero for any
    non-zero valued element. */
-#define TYPE_CASE_FOR_NOT(TYPE, IN, IN_FINISH) {                        \
-    case TYPE:                                                          \
-      do *o++ = !*IN; while(++IN<IN_FINISH);                            \
-      break;                                                            \
+#define TYPE_CASE_FOR_NOT(CTYPE) {                                      \
+    CTYPE *a=data->array, *af=a+data->size;                             \
+    do *o++ = !(*a); while(++a<af);                                     \
   }
 
 static gal_data_t *
 arithmetic_not(gal_data_t *data, unsigned char flags)
 {
+  uint8_t *o;
   gal_data_t *out;
 
-  /* 'value' will only be read from one of these based on the
-     datatype. Which the caller assigned. If there is any problem, it is
-     their responsability, not this function's.*/
-  unsigned char     *uc = data->array,   *ucf = uc + data->size, *o;
-  char               *c = data->array,    *cf = c  + data->size;
-  unsigned short    *us = data->array,   *usf = us + data->size;
-  short              *s = data->array,    *sf = s  + data->size;
-  unsigned int      *ui = data->array,   *uif = ui + data->size;
-  int               *in = data->array,   *inf = in + data->size;
-  unsigned long     *ul = data->array,   *ulf = ul + data->size;
-  long               *l = data->array,    *lf = l  + data->size;
-  LONGLONG           *L = data->array,    *Lf = L  + data->size;
-  float              *f = data->array,    *ff = f  + data->size;
-  double             *d = data->array,    *df = d  + data->size;
-
-
   /* Allocate the output array. */
-  out=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, data->ndim, data->dsize,
+  out=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, data->ndim, data->dsize,
                      data->wcs, 0, data->minmapsize, data->name, data->unit,
                      data->comment);
   o=out->array;
@@ -120,19 +104,16 @@ arithmetic_not(gal_data_t *data, unsigned char flags)
   /* Go over the pixels and set the output values. */
   switch(data->type)
     {
-
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_UCHAR,    uc,  ucf)
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_CHAR,     c,   cf)
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_LOGICAL,  c,   cf)
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_USHORT,   us,  usf)
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_SHORT,    s,   sf)
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_UINT,     ui,  uif)
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_INT,      in,  inf)
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_ULONG,    ul,  ulf)
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_LONG,     l,   lf)
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_LONGLONG, L,   Lf)
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_FLOAT,    f,   ff)
-    TYPE_CASE_FOR_NOT(GAL_DATA_TYPE_DOUBLE,   d,   df)
+    case GAL_DATA_TYPE_UINT8:   TYPE_CASE_FOR_NOT(uint8_t);   break;
+    case GAL_DATA_TYPE_INT8:    TYPE_CASE_FOR_NOT(int8_t);    break;
+    case GAL_DATA_TYPE_UINT16:  TYPE_CASE_FOR_NOT(uint16_t);  break;
+    case GAL_DATA_TYPE_INT16:   TYPE_CASE_FOR_NOT(int16_t);   break;
+    case GAL_DATA_TYPE_UINT32:  TYPE_CASE_FOR_NOT(uint32_t);  break;
+    case GAL_DATA_TYPE_INT32:   TYPE_CASE_FOR_NOT(int32_t);   break;
+    case GAL_DATA_TYPE_UINT64:  TYPE_CASE_FOR_NOT(uint64_t);  break;
+    case GAL_DATA_TYPE_INT64:   TYPE_CASE_FOR_NOT(int64_t);   break;
+    case GAL_DATA_TYPE_FLOAT32: TYPE_CASE_FOR_NOT(float);     break;
+    case GAL_DATA_TYPE_FLOAT64: TYPE_CASE_FOR_NOT(double);    break;
 
     case GAL_DATA_TYPE_BIT:
       error(EXIT_FAILURE, 0, "Currently Gnuastro doesn't support bit "
@@ -155,6 +136,13 @@ arithmetic_not(gal_data_t *data, unsigned char flags)
 
 
 
+#define ARITHMETIC_ABS_SGN(CTYPE, U0_S1) {                        \
+    CTYPE *o=out->array, *a=in->array, *af=a+in->size;            \
+    if(U0_S1)          do *o++ = abs(*a); while(++a<af);          \
+    else if(out!=in) { do *o++ = *a; while(++a<af); }             \
+  }
+
+
 /* We don't want to use the standard function for unary functions in the
    case of the absolute operator. This is because there are multiple
    versions of this function in the C library for different types, which
@@ -164,18 +152,6 @@ arithmetic_abs(unsigned char flags, gal_data_t *in)
 {
   gal_data_t *out;
 
-  unsigned char  *ouc,  *uc = in->array,   *ucf = uc + in->size;
-  char            *oc,   *c = in->array,    *cf = c  + in->size;
-  unsigned short *ous,  *us = in->array,   *usf = us + in->size;
-  short           *os,   *s = in->array,    *sf = s  + in->size;
-  unsigned int   *oui,  *ui = in->array,   *uif = ui + in->size;
-  int             *oi,  *ii = in->array,   *iif = ii + in->size;
-  unsigned long  *oul,  *ul = in->array,   *ulf = ul + in->size;
-  long            *ol,   *l = in->array,    *lf = l  + in->size;
-  LONGLONG        *oL,   *L = in->array,    *Lf = L  + in->size;
-  float           *of,   *f = in->array,    *ff = f  + in->size;
-  double          *od,   *d = in->array,    *df = d  + in->size;
-
   /* Set the output array. */
   if(flags & GAL_ARITHMETIC_INPLACE)
     out=in;
@@ -189,39 +165,16 @@ arithmetic_abs(unsigned char flags, gal_data_t *in)
      output must be a separate array), just copy the values.*/
   switch(in->type)
     {
-    case GAL_DATA_TYPE_UCHAR:
-      if(out!=in) { ouc=out->array; do *ouc++ = *uc++; while(uc<ucf); }
-      break;
-    case GAL_DATA_TYPE_CHAR:
-      oc=out->array; do *oc++ = abs(*c++); while(c<cf);
-      break;
-    case GAL_DATA_TYPE_USHORT:
-      if(out!=in) { ous=out->array; do *ous++ = *us++; while(us<usf); }
-      break;
-    case GAL_DATA_TYPE_SHORT:
-      os=out->array; do *os++ = abs(*s++); while(s<sf);
-      break;
-    case GAL_DATA_TYPE_UINT:
-      if(out!=in) { oui=out->array; do *oui++ = *ui++; while(ui<uif); }
-      break;
-    case GAL_DATA_TYPE_INT:
-      oi=out->array; do *oi++ = abs(*ii++); while(ii<iif);
-      break;
-    case GAL_DATA_TYPE_ULONG:
-      if(out!=in) { oul=out->array; do *oul++ = *ul++; while(ul<ulf); }
-      break;
-    case GAL_DATA_TYPE_LONG:
-      ol=out->array; do *ol++ = labs(*l++); while(l<lf);
-      break;
-    case GAL_DATA_TYPE_LONGLONG:
-      oL=out->array; do *oL++ = llabs(*L++); while(L<Lf);
-      break;
-    case GAL_DATA_TYPE_FLOAT:
-      of=out->array; do *of++ = fabsf(*f++); while(f<ff);
-      break;
-    case GAL_DATA_TYPE_DOUBLE:
-      od=out->array; do *od++ = fabs(*d++); while(d<df);
-      break;
+    case GAL_DATA_TYPE_UINT8:   ARITHMETIC_ABS_SGN(uint8_t, 0);   break;
+    case GAL_DATA_TYPE_INT8:    ARITHMETIC_ABS_SGN(int8_t, 1);    break;
+    case GAL_DATA_TYPE_UINT16:  ARITHMETIC_ABS_SGN(uint16_t, 0);  break;
+    case GAL_DATA_TYPE_INT16:   ARITHMETIC_ABS_SGN(int16_t, 1);   break;
+    case GAL_DATA_TYPE_UINT32:  ARITHMETIC_ABS_SGN(uint32_t, 0);  break;
+    case GAL_DATA_TYPE_INT32:   ARITHMETIC_ABS_SGN(int32_t, 1);   break;
+    case GAL_DATA_TYPE_UINT64:  ARITHMETIC_ABS_SGN(uint64_t, 0);  break;
+    case GAL_DATA_TYPE_INT64:   ARITHMETIC_ABS_SGN(int64_t, 1);   break;
+    case GAL_DATA_TYPE_FLOAT32: ARITHMETIC_ABS_SGN(float, 1);     break;
+    case GAL_DATA_TYPE_FLOAT64: ARITHMETIC_ABS_SGN(double, 1);    break;
     default:
       error(EXIT_FAILURE, 0, "type code %d not recognized in "
             "`arithmetic_abs'", in->type);
@@ -264,8 +217,8 @@ arithmetic_check_float_input(gal_data_t *in, int operator, 
char *numstr)
 {
   switch(in->type)
     {
-    case GAL_DATA_TYPE_FLOAT:
-    case GAL_DATA_TYPE_DOUBLE:
+    case GAL_DATA_TYPE_FLOAT32:
+    case GAL_DATA_TYPE_FLOAT64:
       break;
     default:
       error(EXIT_FAILURE, 0, "the %s operator can only accept single or "
@@ -358,37 +311,34 @@ arithmetic_check_float_input(gal_data_t *in, int 
operator, char *numstr)
 #define UNIARY_FUNCTION_ON_ELEMENT(OP)                                  \
   switch(in->type)                                                      \
     {                                                                   \
-    case GAL_DATA_TYPE_UCHAR:                                           \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(unsigned char, OP)                \
+    case GAL_DATA_TYPE_UINT8:                                           \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint8_t, OP)                      \
       break;                                                            \
-    case GAL_DATA_TYPE_CHAR:                                            \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(char, OP)                         \
+    case GAL_DATA_TYPE_INT8:                                            \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int8_t, OP)                       \
       break;                                                            \
-    case GAL_DATA_TYPE_USHORT:                                          \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(unsigned short, OP)               \
+    case GAL_DATA_TYPE_UINT16:                                          \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint16_t, OP)                     \
       break;                                                            \
-    case GAL_DATA_TYPE_SHORT:                                           \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(short, OP)                        \
+    case GAL_DATA_TYPE_INT16:                                           \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int16_t, OP)                      \
       break;                                                            \
-    case GAL_DATA_TYPE_UINT:                                            \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(unsigned int, OP)                 \
+    case GAL_DATA_TYPE_UINT32:                                          \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint32_t, OP)                     \
       break;                                                            \
-    case GAL_DATA_TYPE_INT:                                             \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int, OP)                          \
+    case GAL_DATA_TYPE_INT32:                                           \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int32_t, OP)                      \
       break;                                                            \
-    case GAL_DATA_TYPE_ULONG:                                           \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(unsigned long, OP)                \
+    case GAL_DATA_TYPE_UINT64:                                          \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint64_t, OP)                     \
       break;                                                            \
-    case GAL_DATA_TYPE_LONG:                                            \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(long, OP)                         \
+    case GAL_DATA_TYPE_INT64:                                           \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int64_t, OP)                      \
       break;                                                            \
-    case GAL_DATA_TYPE_LONGLONG:                                        \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(LONGLONG, OP)                     \
-      break;                                                            \
-    case GAL_DATA_TYPE_FLOAT:                                           \
+    case GAL_DATA_TYPE_FLOAT32:                                         \
       UNIFUNC_RUN_FUNCTION_ON_ELEMENT(float, OP)                        \
       break;                                                            \
-    case GAL_DATA_TYPE_DOUBLE:                                          \
+    case GAL_DATA_TYPE_FLOAT64:                                         \
       UNIFUNC_RUN_FUNCTION_ON_ELEMENT(double, OP)                       \
       break;                                                            \
     default:                                                            \
@@ -403,37 +353,34 @@ arithmetic_check_float_input(gal_data_t *in, int 
operator, char *numstr)
 #define UNIARY_FUNCTION_ON_ARRAY                                        \
   switch(in->type)                                                      \
     {                                                                   \
-    case GAL_DATA_TYPE_UCHAR:                                           \
-      UNIFUNC_RUN_FUNCTION_ON_ARRAY(unsigned char)                      \
+    case GAL_DATA_TYPE_UINT8:                                           \
+      UNIFUNC_RUN_FUNCTION_ON_ARRAY(uint8_t)                            \
       break;                                                            \
-    case GAL_DATA_TYPE_CHAR:                                            \
-      UNIFUNC_RUN_FUNCTION_ON_ARRAY(char)                               \
+    case GAL_DATA_TYPE_INT8:                                            \
+      UNIFUNC_RUN_FUNCTION_ON_ARRAY(int16_t)                            \
       break;                                                            \
-    case GAL_DATA_TYPE_USHORT:                                          \
-      UNIFUNC_RUN_FUNCTION_ON_ARRAY(unsigned short)                     \
+    case GAL_DATA_TYPE_UINT16:                                          \
+      UNIFUNC_RUN_FUNCTION_ON_ARRAY(uint16_t)                           \
       break;                                                            \
-    case GAL_DATA_TYPE_SHORT:                                           \
-      UNIFUNC_RUN_FUNCTION_ON_ARRAY(short)                              \
+    case GAL_DATA_TYPE_INT16:                                           \
+      UNIFUNC_RUN_FUNCTION_ON_ARRAY(int16_t)                            \
         break;                                                          \
-    case GAL_DATA_TYPE_UINT:                                            \
-      UNIFUNC_RUN_FUNCTION_ON_ARRAY(unsigned int)                       \
+    case GAL_DATA_TYPE_UINT32:                                          \
+      UNIFUNC_RUN_FUNCTION_ON_ARRAY(uint32_t)                           \
         break;                                                          \
-    case GAL_DATA_TYPE_INT:                                             \
-      UNIFUNC_RUN_FUNCTION_ON_ARRAY(int)                                \
+    case GAL_DATA_TYPE_INT32:                                           \
+      UNIFUNC_RUN_FUNCTION_ON_ARRAY(int32_t)                            \
         break;                                                          \
-    case GAL_DATA_TYPE_ULONG:                                           \
-      UNIFUNC_RUN_FUNCTION_ON_ARRAY(unsigned long)                      \
+    case GAL_DATA_TYPE_UINT64:                                          \
+      UNIFUNC_RUN_FUNCTION_ON_ARRAY(uint64_t)                           \
         break;                                                          \
-    case GAL_DATA_TYPE_LONG:                                            \
-      UNIFUNC_RUN_FUNCTION_ON_ARRAY(long)                               \
+    case GAL_DATA_TYPE_INT64:                                           \
+      UNIFUNC_RUN_FUNCTION_ON_ARRAY(int64_t)                            \
         break;                                                          \
-    case GAL_DATA_TYPE_LONGLONG:                                        \
-      UNIFUNC_RUN_FUNCTION_ON_ARRAY(LONGLONG)                           \
-      break;                                                            \
-    case GAL_DATA_TYPE_FLOAT:                                           \
+    case GAL_DATA_TYPE_FLOAT32:                                         \
       UNIFUNC_RUN_FUNCTION_ON_ARRAY(float)                              \
       break;                                                            \
-    case GAL_DATA_TYPE_DOUBLE:                                          \
+    case GAL_DATA_TYPE_FLOAT64:                                         \
       UNIFUNC_RUN_FUNCTION_ON_ARRAY(double)                             \
         break;                                                          \
     default:                                                            \
@@ -558,10 +505,10 @@ arithmetic_unary_function(int operator, unsigned char 
flags, gal_data_t *in)
 #define BINFUNC_F_OPERATOR_LEFT_RIGHT_SET(RT, LT, OP)                   \
   switch(o->type)                                                       \
     {                                                                   \
-    case GAL_DATA_TYPE_FLOAT:                                           \
+    case GAL_DATA_TYPE_FLOAT32:                                         \
       BINFUNC_RUN_FUNCTION(float, RT, LT, OP);                          \
       break;                                                            \
-    case GAL_DATA_TYPE_DOUBLE:                                          \
+    case GAL_DATA_TYPE_FLOAT64:                                         \
       BINFUNC_RUN_FUNCTION(double, RT, LT, OP);                         \
       break;                                                            \
     default:                                                            \
@@ -577,10 +524,10 @@ arithmetic_unary_function(int operator, unsigned char 
flags, gal_data_t *in)
 #define BINFUNC_F_OPERATOR_LEFT_SET(LT, OP)                             \
   switch(r->type)                                                       \
     {                                                                   \
-    case GAL_DATA_TYPE_FLOAT:                                           \
+    case GAL_DATA_TYPE_FLOAT32:                                         \
       BINFUNC_F_OPERATOR_LEFT_RIGHT_SET(float, LT, OP);                 \
       break;                                                            \
-    case GAL_DATA_TYPE_DOUBLE:                                          \
+    case GAL_DATA_TYPE_FLOAT64:                                         \
       BINFUNC_F_OPERATOR_LEFT_RIGHT_SET(double, LT, OP);                \
       break;                                                            \
     default:                                                            \
@@ -595,10 +542,10 @@ arithmetic_unary_function(int operator, unsigned char 
flags, gal_data_t *in)
 #define BINFUNC_F_OPERATOR_SET(OP)                                      \
   switch(l->type)                                                       \
     {                                                                   \
-    case GAL_DATA_TYPE_FLOAT:                                           \
+    case GAL_DATA_TYPE_FLOAT32:                                         \
       BINFUNC_F_OPERATOR_LEFT_SET(float, OP);                           \
       break;                                                            \
-    case GAL_DATA_TYPE_DOUBLE:                                          \
+    case GAL_DATA_TYPE_FLOAT64:                                         \
       BINFUNC_F_OPERATOR_LEFT_SET(double, OP);                          \
       break;                                                            \
     default:                                                            \
@@ -728,37 +675,34 @@ arithmetic_binary_function_flt(int operator, unsigned 
char flags,
 #define WHERE_OUT_SET(OT)                                            \
   switch(iftrue->type)                                               \
     {                                                                \
-    case GAL_DATA_TYPE_UCHAR:                                        \
-      DO_WHERE_OPERATION(unsigned char, OT);                         \
-      break;                                                         \
-    case GAL_DATA_TYPE_CHAR:                                         \
-      DO_WHERE_OPERATION(char, OT);                                  \
+    case GAL_DATA_TYPE_UINT8:                                        \
+      DO_WHERE_OPERATION(uint8_t, OT);                               \
       break;                                                         \
-    case GAL_DATA_TYPE_USHORT:                                       \
-      DO_WHERE_OPERATION(unsigned short, OT);                        \
+    case GAL_DATA_TYPE_INT8:                                         \
+      DO_WHERE_OPERATION(int8_t, OT);                                \
       break;                                                         \
-    case GAL_DATA_TYPE_SHORT:                                        \
-      DO_WHERE_OPERATION(short, OT);                                 \
+    case GAL_DATA_TYPE_UINT16:                                       \
+      DO_WHERE_OPERATION(uint16_t, OT);                              \
       break;                                                         \
-    case GAL_DATA_TYPE_UINT:                                         \
-      DO_WHERE_OPERATION(unsigned int, OT);                          \
+    case GAL_DATA_TYPE_INT16:                                        \
+      DO_WHERE_OPERATION(int16_t, OT);                               \
       break;                                                         \
-    case GAL_DATA_TYPE_INT:                                          \
-      DO_WHERE_OPERATION(int, OT);                                   \
+    case GAL_DATA_TYPE_UINT32:                                       \
+      DO_WHERE_OPERATION(uint32_t, OT);                              \
       break;                                                         \
-    case GAL_DATA_TYPE_ULONG:                                        \
-      DO_WHERE_OPERATION(unsigned long, OT);                         \
+    case GAL_DATA_TYPE_INT32:                                        \
+      DO_WHERE_OPERATION(int32_t, OT);                               \
       break;                                                         \
-    case GAL_DATA_TYPE_LONG:                                         \
-      DO_WHERE_OPERATION(long, OT);                                  \
+    case GAL_DATA_TYPE_UINT64:                                       \
+      DO_WHERE_OPERATION(uint64_t, OT);                              \
       break;                                                         \
-    case GAL_DATA_TYPE_LONGLONG:                                     \
-      DO_WHERE_OPERATION(LONGLONG, OT);                              \
+    case GAL_DATA_TYPE_INT64:                                        \
+      DO_WHERE_OPERATION(int64_t, OT);                               \
       break;                                                         \
-    case GAL_DATA_TYPE_FLOAT:                                        \
+    case GAL_DATA_TYPE_FLOAT32:                                      \
       DO_WHERE_OPERATION(float, OT);                                 \
       break;                                                         \
-    case GAL_DATA_TYPE_DOUBLE:                                       \
+    case GAL_DATA_TYPE_FLOAT64:                                      \
       DO_WHERE_OPERATION(double, OT);                                \
       break;                                                         \
     default:                                                         \
@@ -777,7 +721,7 @@ arithmetic_where(unsigned char flags, gal_data_t *out, 
gal_data_t *cond,
   unsigned char *c=cond->array;
 
   /* The condition operator has to be unsigned char. */
-  if(cond->type!=GAL_DATA_TYPE_UCHAR)
+  if(cond->type!=GAL_DATA_TYPE_UINT8)
     error(EXIT_FAILURE, 0, "the condition operand to `arithmetic_where' "
           "must be an `unsigned char' type, but the given condition "
           "operator has a `%s' type", gal_data_type_as_string(cond->type, 1));
@@ -791,37 +735,34 @@ arithmetic_where(unsigned char flags, gal_data_t *out, 
gal_data_t *cond,
   /* Do the operation. */
   switch(out->type)
     {
-    case GAL_DATA_TYPE_UCHAR:
-      WHERE_OUT_SET(unsigned char);
+    case GAL_DATA_TYPE_UINT8:
+      WHERE_OUT_SET(uint8_t);
       break;
-    case GAL_DATA_TYPE_CHAR:
-      WHERE_OUT_SET(char);
+    case GAL_DATA_TYPE_INT8:
+      WHERE_OUT_SET(uint8_t);
       break;
-    case GAL_DATA_TYPE_USHORT:
-      WHERE_OUT_SET(unsigned short);
+    case GAL_DATA_TYPE_UINT16:
+      WHERE_OUT_SET(uint16_t);
       break;
-    case GAL_DATA_TYPE_SHORT:
-      WHERE_OUT_SET(short);
+    case GAL_DATA_TYPE_INT16:
+      WHERE_OUT_SET(int16_t);
       break;
-    case GAL_DATA_TYPE_UINT:
-      WHERE_OUT_SET(unsigned int);
+    case GAL_DATA_TYPE_UINT32:
+      WHERE_OUT_SET(uint32_t);
       break;
-    case GAL_DATA_TYPE_INT:
-      WHERE_OUT_SET(int);
+    case GAL_DATA_TYPE_INT32:
+      WHERE_OUT_SET(int32_t);
       break;
-    case GAL_DATA_TYPE_ULONG:
-      WHERE_OUT_SET(unsigned long);
+    case GAL_DATA_TYPE_UINT64:
+      WHERE_OUT_SET(uint64_t);
       break;
-    case GAL_DATA_TYPE_LONG:
-      WHERE_OUT_SET(long);
+    case GAL_DATA_TYPE_INT64:
+      WHERE_OUT_SET(int64_t);
       break;
-    case GAL_DATA_TYPE_LONGLONG:
-      WHERE_OUT_SET(LONGLONG);
-      break;
-    case GAL_DATA_TYPE_FLOAT:
+    case GAL_DATA_TYPE_FLOAT32:
       WHERE_OUT_SET(float);
       break;
-    case GAL_DATA_TYPE_DOUBLE:
+    case GAL_DATA_TYPE_FLOAT64:
       WHERE_OUT_SET(double);
       break;
     default:
@@ -866,7 +807,7 @@ arithmetic_where(unsigned char flags, gal_data_t *out, 
gal_data_t *cond,
       {                                                                 \
         p=max;                                                          \
         for(i=0;i<dnum;++i)  /* Loop over each array. */                \
-          {  /* Only for integer types, does *b==*b. */                 \
+          {   /* Only for integer types, does *b==*b. */                \
             if(hasblank[i] && *b==*b)                                   \
               { if( *a[i] != *b ) p = *a[i] < p ? *a[i] : p;            \
                 else              p = *a[i] < p ? *a[i] : p; }          \
@@ -888,7 +829,7 @@ arithmetic_where(unsigned char flags, gal_data_t *out, 
gal_data_t *cond,
       {                                                                 \
         p=min;                                                          \
         for(i=0;i<dnum;++i)  /* Loop over each array. */                \
-          {  /* Only for integer types, does *b==*b. */                 \
+          {   /* Only for integer types, does *b==*b. */                \
             if(hasblank[i] && *b==*b)                                   \
               { if( *a[i] != *b ) p = *a[i] > p ? *a[i] : p;            \
                 else              p = *a[i] > p ? *a[i] : p; }          \
@@ -1116,28 +1057,36 @@ arithmetic_multioperand(int operator, unsigned char 
flags, gal_data_t *list)
   /* Start the operation. */
   switch(list->type)
     {
-    case GAL_DATA_TYPE_UCHAR:
-      MULTIOPERAND_TYPE_SET(unsigned char,  gal_qsort_uchar_increasing);
-    case GAL_DATA_TYPE_CHAR:
-      MULTIOPERAND_TYPE_SET(char,           gal_qsort_char_increasing);
-    case GAL_DATA_TYPE_USHORT:
-      MULTIOPERAND_TYPE_SET(unsigned short, gal_qsort_ushort_increasing);
-    case GAL_DATA_TYPE_SHORT:
-      MULTIOPERAND_TYPE_SET(short,          gal_qsort_short_increasing);
-    case GAL_DATA_TYPE_UINT:
-      MULTIOPERAND_TYPE_SET(unsigned int,   gal_qsort_uint_increasing);
-    case GAL_DATA_TYPE_INT:
-      MULTIOPERAND_TYPE_SET(int,            gal_qsort_int_increasing);
-    case GAL_DATA_TYPE_ULONG:
-      MULTIOPERAND_TYPE_SET(unsigned long,  gal_qsort_ulong_increasing);
-    case GAL_DATA_TYPE_LONG:
-      MULTIOPERAND_TYPE_SET(long,           gal_qsort_long_increasing);
-    case GAL_DATA_TYPE_LONGLONG:
-      MULTIOPERAND_TYPE_SET(LONGLONG,       gal_qsort_longlong_increasing);
-    case GAL_DATA_TYPE_FLOAT:
-      MULTIOPERAND_TYPE_SET(float,          gal_qsort_float_increasing);
-    case GAL_DATA_TYPE_DOUBLE:
-      MULTIOPERAND_TYPE_SET(double,         gal_qsort_double_increasing);
+    case GAL_DATA_TYPE_UINT8:
+      MULTIOPERAND_TYPE_SET(uint8_t,   gal_qsort_uchar_increasing);
+      break;
+    case GAL_DATA_TYPE_INT8:
+      MULTIOPERAND_TYPE_SET(int8_t,    gal_qsort_char_increasing);
+      break;
+    case GAL_DATA_TYPE_UINT16:
+      MULTIOPERAND_TYPE_SET(uint16_t,  gal_qsort_ushort_increasing);
+      break;
+    case GAL_DATA_TYPE_INT16:
+      MULTIOPERAND_TYPE_SET(int16_t,   gal_qsort_short_increasing);
+      break;
+    case GAL_DATA_TYPE_UINT32:
+      MULTIOPERAND_TYPE_SET(uint32_t,  gal_qsort_uint_increasing);
+      break;
+    case GAL_DATA_TYPE_INT32:
+      MULTIOPERAND_TYPE_SET(int32_t,   gal_qsort_int_increasing);
+      break;
+    case GAL_DATA_TYPE_UINT64:
+      MULTIOPERAND_TYPE_SET(uint64_t,  gal_qsort_ulong_increasing);
+      break;
+    case GAL_DATA_TYPE_INT64:
+      MULTIOPERAND_TYPE_SET(int64_t,   gal_qsort_long_increasing);
+      break;
+    case GAL_DATA_TYPE_FLOAT32:
+      MULTIOPERAND_TYPE_SET(float,     gal_qsort_float_increasing);
+      break;
+    case GAL_DATA_TYPE_FLOAT64:
+      MULTIOPERAND_TYPE_SET(double,    gal_qsort_double_increasing);
+      break;
     default:
       error(EXIT_FAILURE, 0, "type code %d not recognized in "
             "`arithmetic_multioperand'", list->type);
@@ -1195,7 +1144,7 @@ gal_arithmetic_binary_out_type(int operator, gal_data_t 
*l, gal_data_t *r)
       return gal_data_out_type(l, r);
 
     default:
-      return GAL_DATA_TYPE_UCHAR;
+      return GAL_DATA_TYPE_UINT8;
     }
   return -1;
 }
@@ -1209,123 +1158,106 @@ arithmetic_nearest_compiled_type(int intype)
 {
   switch(intype)
     {
-    case GAL_DATA_TYPE_UCHAR:
-      if(GAL_CONFIG_BIN_OP_UCHAR) return GAL_DATA_TYPE_UCHAR;
-      else
-        {
-          if     (GAL_CONFIG_BIN_OP_USHORT)   return GAL_DATA_TYPE_USHORT;
-          else if(GAL_CONFIG_BIN_OP_SHORT)    return GAL_DATA_TYPE_SHORT;
-          else if(GAL_CONFIG_BIN_OP_UINT)     return GAL_DATA_TYPE_UINT;
-          else if(GAL_CONFIG_BIN_OP_INT)      return GAL_DATA_TYPE_INT;
-          else if(GAL_CONFIG_BIN_OP_ULONG)    return GAL_DATA_TYPE_ULONG;
-          else if(GAL_CONFIG_BIN_OP_LONG)     return GAL_DATA_TYPE_LONG;
-          else if(GAL_CONFIG_BIN_OP_LONGLONG) return GAL_DATA_TYPE_LONGLONG;
-          else if(GAL_CONFIG_BIN_OP_FLOAT)    return GAL_DATA_TYPE_FLOAT;
-          else if(GAL_CONFIG_BIN_OP_DOUBLE)   return GAL_DATA_TYPE_DOUBLE;
-        }
-      break;
-
-    case GAL_DATA_TYPE_CHAR:
-      if(GAL_CONFIG_BIN_OP_CHAR) return GAL_DATA_TYPE_CHAR;
+    case GAL_DATA_TYPE_UINT8:
+      if(GAL_CONFIG_BIN_OP_UINT8) return GAL_DATA_TYPE_UINT8;
       else
         {
-          if     (GAL_CONFIG_BIN_OP_SHORT)    return GAL_DATA_TYPE_SHORT;
-          else if(GAL_CONFIG_BIN_OP_INT)      return GAL_DATA_TYPE_INT;
-          else if(GAL_CONFIG_BIN_OP_LONG)     return GAL_DATA_TYPE_LONG;
-          else if(GAL_CONFIG_BIN_OP_LONGLONG) return GAL_DATA_TYPE_LONGLONG;
-          else if(GAL_CONFIG_BIN_OP_FLOAT)    return GAL_DATA_TYPE_FLOAT;
-          else if(GAL_CONFIG_BIN_OP_DOUBLE)   return GAL_DATA_TYPE_DOUBLE;
+          if     (GAL_CONFIG_BIN_OP_UINT16)   return GAL_DATA_TYPE_UINT16;
+          else if(GAL_CONFIG_BIN_OP_INT16)    return GAL_DATA_TYPE_INT16;
+          else if(GAL_CONFIG_BIN_OP_UINT32)   return GAL_DATA_TYPE_UINT32;
+          else if(GAL_CONFIG_BIN_OP_INT32)    return GAL_DATA_TYPE_INT32;
+          else if(GAL_CONFIG_BIN_OP_UINT64)   return GAL_DATA_TYPE_UINT64;
+          else if(GAL_CONFIG_BIN_OP_INT64)    return GAL_DATA_TYPE_INT64;
+          else if(GAL_CONFIG_BIN_OP_FLOAT32)  return GAL_DATA_TYPE_FLOAT32;
+          else if(GAL_CONFIG_BIN_OP_FLOAT64)  return GAL_DATA_TYPE_FLOAT64;
         }
       break;
 
-    case GAL_DATA_TYPE_USHORT:
-      if(GAL_CONFIG_BIN_OP_USHORT) return GAL_DATA_TYPE_USHORT;
+    case GAL_DATA_TYPE_INT8:
+      if(GAL_CONFIG_BIN_OP_INT8) return GAL_DATA_TYPE_INT8;
       else
         {
-          if     (GAL_CONFIG_BIN_OP_UINT)     return GAL_DATA_TYPE_UINT;
-          else if(GAL_CONFIG_BIN_OP_INT)      return GAL_DATA_TYPE_INT;
-          else if(GAL_CONFIG_BIN_OP_ULONG)    return GAL_DATA_TYPE_ULONG;
-          else if(GAL_CONFIG_BIN_OP_LONG)     return GAL_DATA_TYPE_LONG;
-          else if(GAL_CONFIG_BIN_OP_LONGLONG) return GAL_DATA_TYPE_LONGLONG;
-          else if(GAL_CONFIG_BIN_OP_FLOAT)    return GAL_DATA_TYPE_FLOAT;
-          else if(GAL_CONFIG_BIN_OP_DOUBLE)   return GAL_DATA_TYPE_DOUBLE;
+          if     (GAL_CONFIG_BIN_OP_INT16)    return GAL_DATA_TYPE_INT16;
+          else if(GAL_CONFIG_BIN_OP_INT32)    return GAL_DATA_TYPE_INT32;
+          else if(GAL_CONFIG_BIN_OP_INT64)    return GAL_DATA_TYPE_INT64;
+          else if(GAL_CONFIG_BIN_OP_FLOAT32)  return GAL_DATA_TYPE_FLOAT32;
+          else if(GAL_CONFIG_BIN_OP_FLOAT64)  return GAL_DATA_TYPE_FLOAT64;
         }
       break;
 
-    case GAL_DATA_TYPE_SHORT:
-      if(GAL_CONFIG_BIN_OP_SHORT) return GAL_DATA_TYPE_SHORT;
+    case GAL_DATA_TYPE_UINT16:
+      if(GAL_CONFIG_BIN_OP_UINT16) return GAL_DATA_TYPE_UINT16;
       else
         {
-          if     (GAL_CONFIG_BIN_OP_INT)      return GAL_DATA_TYPE_INT;
-          else if(GAL_CONFIG_BIN_OP_LONG)     return GAL_DATA_TYPE_LONG;
-          else if(GAL_CONFIG_BIN_OP_LONGLONG) return GAL_DATA_TYPE_LONGLONG;
-          else if(GAL_CONFIG_BIN_OP_FLOAT)    return GAL_DATA_TYPE_FLOAT;
-          else if(GAL_CONFIG_BIN_OP_DOUBLE)   return GAL_DATA_TYPE_DOUBLE;
+          if     (GAL_CONFIG_BIN_OP_UINT32)   return GAL_DATA_TYPE_UINT32;
+          else if(GAL_CONFIG_BIN_OP_INT32)    return GAL_DATA_TYPE_INT32;
+          else if(GAL_CONFIG_BIN_OP_UINT64)   return GAL_DATA_TYPE_UINT64;
+          else if(GAL_CONFIG_BIN_OP_INT64)    return GAL_DATA_TYPE_INT64;
+          else if(GAL_CONFIG_BIN_OP_FLOAT32)  return GAL_DATA_TYPE_FLOAT32;
+          else if(GAL_CONFIG_BIN_OP_FLOAT64)  return GAL_DATA_TYPE_FLOAT64;
         }
       break;
 
-    case GAL_DATA_TYPE_UINT:
-      if(GAL_CONFIG_BIN_OP_UINT) return GAL_DATA_TYPE_UINT;
+    case GAL_DATA_TYPE_INT16:
+      if(GAL_CONFIG_BIN_OP_INT16) return GAL_DATA_TYPE_INT16;
       else
         {
-          if     (GAL_CONFIG_BIN_OP_ULONG)    return GAL_DATA_TYPE_ULONG;
-          else if(GAL_CONFIG_BIN_OP_LONG)     return GAL_DATA_TYPE_LONG;
-          else if(GAL_CONFIG_BIN_OP_LONGLONG) return GAL_DATA_TYPE_LONGLONG;
-          else if(GAL_CONFIG_BIN_OP_FLOAT)    return GAL_DATA_TYPE_FLOAT;
-          else if(GAL_CONFIG_BIN_OP_DOUBLE)   return GAL_DATA_TYPE_DOUBLE;
+          if     (GAL_CONFIG_BIN_OP_INT32)    return GAL_DATA_TYPE_INT32;
+          else if(GAL_CONFIG_BIN_OP_INT64)    return GAL_DATA_TYPE_INT64;
+          else if(GAL_CONFIG_BIN_OP_FLOAT32)  return GAL_DATA_TYPE_FLOAT32;
+          else if(GAL_CONFIG_BIN_OP_FLOAT64)  return GAL_DATA_TYPE_FLOAT64;
         }
       break;
 
-    case GAL_DATA_TYPE_INT:
-      if(GAL_CONFIG_BIN_OP_INT) return GAL_DATA_TYPE_INT;
+    case GAL_DATA_TYPE_UINT32:
+      if(GAL_CONFIG_BIN_OP_UINT32) return GAL_DATA_TYPE_UINT32;
       else
         {
-          if     (GAL_CONFIG_BIN_OP_LONG)     return GAL_DATA_TYPE_LONG;
-          else if(GAL_CONFIG_BIN_OP_LONGLONG) return GAL_DATA_TYPE_LONGLONG;
-          else if(GAL_CONFIG_BIN_OP_FLOAT)    return GAL_DATA_TYPE_FLOAT;
-          else if(GAL_CONFIG_BIN_OP_DOUBLE)   return GAL_DATA_TYPE_DOUBLE;
+          if     (GAL_CONFIG_BIN_OP_UINT64)   return GAL_DATA_TYPE_UINT64;
+          else if(GAL_CONFIG_BIN_OP_INT64)    return GAL_DATA_TYPE_INT64;
+          else if(GAL_CONFIG_BIN_OP_FLOAT32)  return GAL_DATA_TYPE_FLOAT32;
+          else if(GAL_CONFIG_BIN_OP_FLOAT64)  return GAL_DATA_TYPE_FLOAT64;
         }
       break;
 
-    case GAL_DATA_TYPE_ULONG:
-      if(GAL_CONFIG_BIN_OP_ULONG) return GAL_DATA_TYPE_ULONG;
+    case GAL_DATA_TYPE_INT32:
+      if(GAL_CONFIG_BIN_OP_INT32) return GAL_DATA_TYPE_INT32;
       else
         {
-          if     (GAL_CONFIG_BIN_OP_LONGLONG) return GAL_DATA_TYPE_LONGLONG;
-          else if(GAL_CONFIG_BIN_OP_FLOAT)    return GAL_DATA_TYPE_FLOAT;
-          else if(GAL_CONFIG_BIN_OP_DOUBLE)   return GAL_DATA_TYPE_DOUBLE;
+          if     (GAL_CONFIG_BIN_OP_INT64)     return GAL_DATA_TYPE_INT64;
+          else if(GAL_CONFIG_BIN_OP_FLOAT32)   return GAL_DATA_TYPE_FLOAT32;
+          else if(GAL_CONFIG_BIN_OP_FLOAT64)   return GAL_DATA_TYPE_FLOAT64;
         }
       break;
 
-    case GAL_DATA_TYPE_LONG:
-      if(GAL_CONFIG_BIN_OP_LONG) return GAL_DATA_TYPE_LONG;
+    case GAL_DATA_TYPE_UINT64:
+      if(GAL_CONFIG_BIN_OP_UINT64) return GAL_DATA_TYPE_UINT64;
       else
         {
-          if     (GAL_CONFIG_BIN_OP_LONGLONG) return GAL_DATA_TYPE_LONGLONG;
-          else if(GAL_CONFIG_BIN_OP_FLOAT)    return GAL_DATA_TYPE_FLOAT;
-          else if(GAL_CONFIG_BIN_OP_DOUBLE)   return GAL_DATA_TYPE_DOUBLE;
+          if     (GAL_CONFIG_BIN_OP_FLOAT32)   return GAL_DATA_TYPE_FLOAT32;
+          else if(GAL_CONFIG_BIN_OP_FLOAT64)   return GAL_DATA_TYPE_FLOAT64;
         }
       break;
 
-    case GAL_DATA_TYPE_LONGLONG:
-      if(GAL_CONFIG_BIN_OP_LONGLONG) return GAL_DATA_TYPE_LONGLONG;
+    case GAL_DATA_TYPE_INT64:
+      if(GAL_CONFIG_BIN_OP_INT64) return GAL_DATA_TYPE_INT64;
       else
         {
-          if     (GAL_CONFIG_BIN_OP_FLOAT)    return GAL_DATA_TYPE_FLOAT;
-          else if(GAL_CONFIG_BIN_OP_DOUBLE)   return GAL_DATA_TYPE_DOUBLE;
+          if     (GAL_CONFIG_BIN_OP_FLOAT32)   return GAL_DATA_TYPE_FLOAT32;
+          else if(GAL_CONFIG_BIN_OP_FLOAT64)   return GAL_DATA_TYPE_FLOAT64;
         }
       break;
 
-    case GAL_DATA_TYPE_FLOAT:
-      if(GAL_CONFIG_BIN_OP_FLOAT) return GAL_DATA_TYPE_FLOAT;
+    case GAL_DATA_TYPE_FLOAT32:
+      if(GAL_CONFIG_BIN_OP_FLOAT32) return GAL_DATA_TYPE_FLOAT32;
       else
         {
-          if     (GAL_CONFIG_BIN_OP_DOUBLE)   return GAL_DATA_TYPE_DOUBLE;
+          if     (GAL_CONFIG_BIN_OP_FLOAT64)   return GAL_DATA_TYPE_FLOAT64;
         }
       break;
 
-    case GAL_DATA_TYPE_DOUBLE:
-      if         (GAL_CONFIG_BIN_OP_DOUBLE)   return GAL_DATA_TYPE_DOUBLE;
+    case GAL_DATA_TYPE_FLOAT64:
+      if         (GAL_CONFIG_BIN_OP_FLOAT64)   return GAL_DATA_TYPE_FLOAT64;
       break;
 
     default:
@@ -1401,17 +1333,16 @@ gal_arithmetic_operator_string(int operator)
     case GAL_ARITHMETIC_OP_AVERAGE:      return "average";
     case GAL_ARITHMETIC_OP_MEDIAN:       return "median";
 
-    case GAL_ARITHMETIC_OP_TO_UCHAR:     return "uchar";
-    case GAL_ARITHMETIC_OP_TO_CHAR:      return "char";
-    case GAL_ARITHMETIC_OP_TO_USHORT:    return "ushort";
-    case GAL_ARITHMETIC_OP_TO_SHORT:     return "short";
-    case GAL_ARITHMETIC_OP_TO_UINT:      return "uint";
-    case GAL_ARITHMETIC_OP_TO_INT:       return "int";
-    case GAL_ARITHMETIC_OP_TO_ULONG:     return "ulong";
-    case GAL_ARITHMETIC_OP_TO_LONG:      return "long";
-    case GAL_ARITHMETIC_OP_TO_LONGLONG:  return "longlong";
-    case GAL_ARITHMETIC_OP_TO_FLOAT:     return "float";
-    case GAL_ARITHMETIC_OP_TO_DOUBLE:    return "double";
+    case GAL_ARITHMETIC_OP_TO_UINT8:     return "uchar";
+    case GAL_ARITHMETIC_OP_TO_INT8:      return "char";
+    case GAL_ARITHMETIC_OP_TO_UINT16:    return "ushort";
+    case GAL_ARITHMETIC_OP_TO_INT16:     return "short";
+    case GAL_ARITHMETIC_OP_TO_UINT32:    return "uint";
+    case GAL_ARITHMETIC_OP_TO_INT32:     return "int";
+    case GAL_ARITHMETIC_OP_TO_UINT64:    return "ulong";
+    case GAL_ARITHMETIC_OP_TO_INT64:     return "long";
+    case GAL_ARITHMETIC_OP_TO_FLOAT32:   return "float32";
+    case GAL_ARITHMETIC_OP_TO_FLOAT64:   return "float64";
 
     default:
       error(EXIT_FAILURE, 0, "Operator code %d not recognized in "
@@ -1586,17 +1517,16 @@ gal_arithmetic(int operator, unsigned char flags, ...)
 
 
     /* Conversion operators. */
-    case GAL_ARITHMETIC_OP_TO_UCHAR:
-    case GAL_ARITHMETIC_OP_TO_CHAR:
-    case GAL_ARITHMETIC_OP_TO_USHORT:
-    case GAL_ARITHMETIC_OP_TO_SHORT:
-    case GAL_ARITHMETIC_OP_TO_UINT:
-    case GAL_ARITHMETIC_OP_TO_INT:
-    case GAL_ARITHMETIC_OP_TO_ULONG:
-    case GAL_ARITHMETIC_OP_TO_LONG:
-    case GAL_ARITHMETIC_OP_TO_LONGLONG:
-    case GAL_ARITHMETIC_OP_TO_FLOAT:
-    case GAL_ARITHMETIC_OP_TO_DOUBLE:
+    case GAL_ARITHMETIC_OP_TO_UINT8:
+    case GAL_ARITHMETIC_OP_TO_INT8:
+    case GAL_ARITHMETIC_OP_TO_UINT16:
+    case GAL_ARITHMETIC_OP_TO_INT16:
+    case GAL_ARITHMETIC_OP_TO_UINT32:
+    case GAL_ARITHMETIC_OP_TO_INT32:
+    case GAL_ARITHMETIC_OP_TO_UINT64:
+    case GAL_ARITHMETIC_OP_TO_INT64:
+    case GAL_ARITHMETIC_OP_TO_FLOAT32:
+    case GAL_ARITHMETIC_OP_TO_FLOAT64:
       d1 = va_arg(va, gal_data_t *);
       out=arithmetic_change_type(d1, operator, flags);
       break;
diff --git a/lib/checkset.c b/lib/checkset.c
index 75367ae..1475f67 100644
--- a/lib/checkset.c
+++ b/lib/checkset.c
@@ -46,56 +46,6 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 /**************************************************************/
-/**********          Check fixed strings           ************/
-/**************************************************************/
-/* Check if the value to the `--type' option is recognized, if so set the
-   integer value. */
-void
-gal_checkset_known_types(char *optarg, int *type, char *filename,
-                         size_t lineno)
-{
-  /* First check if the value is one of the accepted types. */
-  if     (strcmp(optarg, "uchar")==0)    *type = GAL_DATA_TYPE_UCHAR;
-  else if(strcmp(optarg, "short")==0)    *type = GAL_DATA_TYPE_SHORT;
-  else if(strcmp(optarg, "long")==0)     *type = GAL_DATA_TYPE_LONG;
-  else if(strcmp(optarg, "longlong")==0) *type = GAL_DATA_TYPE_LONGLONG;
-  else if(strcmp(optarg, "float")==0)    *type = GAL_DATA_TYPE_FLOAT;
-  else if(strcmp(optarg, "double")==0)   *type = GAL_DATA_TYPE_DOUBLE;
-  else
-    {
-      if(filename)
-        error_at_line(EXIT_FAILURE, 0, filename, lineno, "given value of "
-                      "the `type' option (`%s') is not recognized. It must "
-                      "be `uchar', `short', `long', `longlong', `float', or "
-                      "`double'. The FITS standard only defines these types "
-                      "for image arrays", optarg);
-      else
-        error(EXIT_FAILURE, 0, "given value of the `--type' (`-T') option "
-              "(`%s') is not recognized. It must be `byte', `short', `long' "
-              "`longlong', `float', or `double'. The FITS standard only "
-              "defines these types for image arrays", optarg);
-    }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/**************************************************************/
 /**********          My String functions:          ************/
 /**************************************************************/
 int
diff --git a/lib/commonopts.h b/lib/commonopts.h
index 6012fa8..5eedf46 100644
--- a/lib/commonopts.h
+++ b/lib/commonopts.h
@@ -104,6 +104,20 @@ struct argp_option gal_commonopts_options[] =
       GAL_OPTIONS_NOT_SET
     },
     {
+      "type",
+      GAL_OPTIONS_KEY_TYPE,
+      "STR",  /* Will be converted to `int' code by `gal_options_read_type'.*/
+      0,
+      "Numerical datatype of output",
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &cp->type,
+      GAL_DATA_TYPE_INT32,
+      GAL_OPTIONS_RANGE_GT_0,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET,
+      gal_options_read_type
+    },
+    {
       "tableformat",
       GAL_OPTIONS_KEY_TABLEFORMAT,
       "STR",
diff --git a/lib/config.h.in b/lib/config.h.in
index 8071c55..0a094c9 100644
--- a/lib/config.h.in
+++ b/lib/config.h.in
@@ -37,17 +37,16 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #define GAL_CONFIG_HAVE_PTHREAD_BARRIER @HAVE_PTHREAD_BARRIER@
 
-#define GAL_CONFIG_BIN_OP_UCHAR         @HAVE_BIN_OP_UCHAR@
-#define GAL_CONFIG_BIN_OP_CHAR          @HAVE_BIN_OP_CHAR@
-#define GAL_CONFIG_BIN_OP_USHORT        @HAVE_BIN_OP_USHORT@
-#define GAL_CONFIG_BIN_OP_SHORT         @HAVE_BIN_OP_SHORT@
-#define GAL_CONFIG_BIN_OP_UINT          @HAVE_BIN_OP_UINT@
-#define GAL_CONFIG_BIN_OP_INT           @HAVE_BIN_OP_INT@
-#define GAL_CONFIG_BIN_OP_ULONG         @HAVE_BIN_OP_ULONG@
-#define GAL_CONFIG_BIN_OP_LONG          @HAVE_BIN_OP_LONG@
-#define GAL_CONFIG_BIN_OP_LONGLONG      @HAVE_BIN_OP_LONGLONG@
-#define GAL_CONFIG_BIN_OP_FLOAT         @HAVE_BIN_OP_FLOAT@
-#define GAL_CONFIG_BIN_OP_DOUBLE        @HAVE_BIN_OP_DOUBLE@
+#define GAL_CONFIG_BIN_OP_UINT8         @HAVE_BIN_OP_UINT8@
+#define GAL_CONFIG_BIN_OP_INT8          @HAVE_BIN_OP_INT8@
+#define GAL_CONFIG_BIN_OP_UINT16        @HAVE_BIN_OP_UINT16@
+#define GAL_CONFIG_BIN_OP_INT16         @HAVE_BIN_OP_INT16@
+#define GAL_CONFIG_BIN_OP_UINT32        @HAVE_BIN_OP_UINT32@
+#define GAL_CONFIG_BIN_OP_INT32         @HAVE_BIN_OP_INT32@
+#define GAL_CONFIG_BIN_OP_UINT64        @HAVE_BIN_OP_UINT64@
+#define GAL_CONFIG_BIN_OP_INT64         @HAVE_BIN_OP_INT64@
+#define GAL_CONFIG_BIN_OP_FLOAT32       @HAVE_BIN_OP_FLOAT32@
+#define GAL_CONFIG_BIN_OP_FLOAT64       @HAVE_BIN_OP_FLOAT64@
 
 #define GAL_CONFIG_SIZEOF_SIZE_T        @SIZEOF_SIZE_T@
 
diff --git a/lib/data.c b/lib/data.c
index 17157c9..b41d169 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -58,52 +58,46 @@ gal_data_type_as_string(int type, int long_name)
   switch(type)
     {
     case GAL_DATA_TYPE_BIT:
-      if(long_name) return "bit";             else return "b";
+      if(long_name) return "bit";                 else return "b";
 
-    case GAL_DATA_TYPE_UCHAR:
-      if(long_name) return "unsigned char";   else return "uc";
+    case GAL_DATA_TYPE_UINT8:
+      if(long_name) return "uint8";               else return "u8";
 
-      /* CFITSIO says "int for keywords, char for table columns". Here we
-         are only assuming table columns. So in practice this also applies
-         to TSBYTE.*/
-    case GAL_DATA_TYPE_CHAR: case GAL_DATA_TYPE_LOGICAL:
-      if(long_name) return "char";            else return "c";
+    case GAL_DATA_TYPE_INT8:
+      if(long_name) return "int8";                else return "i8";
 
-    case GAL_DATA_TYPE_STRING:
-      if(long_name) return "string";          else return "str";
-
-    case GAL_DATA_TYPE_USHORT:
-      if(long_name) return "unsigned short";  else return "us";
+    case GAL_DATA_TYPE_UINT16:
+      if(long_name) return "uint16";              else return "u16";
 
-    case GAL_DATA_TYPE_SHORT:
-      if(long_name) return "short";           else return "s";
+    case GAL_DATA_TYPE_INT16:
+      if(long_name) return "int16";               else return "i16";
 
-    case GAL_DATA_TYPE_UINT:
-      if(long_name) return "unsigned int";    else return "ui";
+    case GAL_DATA_TYPE_UINT32:
+      if(long_name) return "uint32";              else return "u32";
 
-    case GAL_DATA_TYPE_INT:
-      if(long_name) return "int";             else return "i";
+    case GAL_DATA_TYPE_INT32:
+      if(long_name) return "int32";               else return "i32";
 
-    case GAL_DATA_TYPE_ULONG:
-      if(long_name) return "unsigned long";   else return "ul";
+    case GAL_DATA_TYPE_UINT64:
+      if(long_name) return "uint64";              else return "u64";
 
-    case GAL_DATA_TYPE_LONG:
-      if(long_name) return "long";            else return "l";
+    case GAL_DATA_TYPE_INT64:
+      if(long_name) return "int64";               else return "i64";
 
-    case GAL_DATA_TYPE_LONGLONG:
-      if(long_name) return "LONGLONG";        else return "L";
+    case GAL_DATA_TYPE_FLOAT32:
+      if(long_name) return "float32";             else return "f32";
 
-    case GAL_DATA_TYPE_FLOAT:
-      if(long_name) return "float";           else return "f";
+    case GAL_DATA_TYPE_FLOAT64:
+      if(long_name) return "float64";             else return "f64";
 
-    case GAL_DATA_TYPE_DOUBLE:
-      if(long_name) return "double";          else return "d";
+    case GAL_DATA_TYPE_COMPLEX32:
+      if(long_name) return "complex32";           else return "c32";
 
-    case GAL_DATA_TYPE_COMPLEX:
-      if(long_name) return "complex float";   else return "cf";
+    case GAL_DATA_TYPE_COMPLEX64:
+      if(long_name) return "complex64";           else return "c64";
 
-    case GAL_DATA_TYPE_DCOMPLEX:
-      if(long_name) return "complex double";  else return "cd";
+    case GAL_DATA_TYPE_STRING:
+      if(long_name) return "string";              else return "str";
 
     case GAL_DATA_TYPE_STRLL:
       if(long_name) return "string linked list";  else return "strll";
@@ -129,50 +123,47 @@ gal_data_type_as_string(int type, int long_name)
 int
 gal_data_string_as_type(char *str)
 {
-  if(      !strcmp(str, "b")   || !strcmp(str, "bit") )
+  if(      !strcmp(str, "b")     || !strcmp(str, "bit") )
     return GAL_DATA_TYPE_BIT;
 
-  else if( !strcmp(str, "uc")  || !strcmp(str, "unsigned char") )
-    return GAL_DATA_TYPE_UCHAR;
+  else if( !strcmp(str, "u8")    || !strcmp(str, "uint8") )
+    return GAL_DATA_TYPE_UINT8;
 
-  else if( !strcmp(str, "c")   || !strcmp(str, "char") )
-    return GAL_DATA_TYPE_CHAR;
-
-  else if( !strcmp(str, "str") || !strcmp(str, "string") )
-    return GAL_DATA_TYPE_STRING;
+  else if( !strcmp(str, "i8")    || !strcmp(str, "int8") )
+    return GAL_DATA_TYPE_INT8;
 
-  else if( !strcmp(str, "us")  || !strcmp(str, "unsigned short") )
-    return GAL_DATA_TYPE_USHORT;
+  else if( !strcmp(str, "u16")   || !strcmp(str, "uint16") )
+    return GAL_DATA_TYPE_UINT16;
 
-  else if( !strcmp(str, "s")   || !strcmp(str, "short") )
-    return GAL_DATA_TYPE_SHORT;
+  else if( !strcmp(str, "i16")   || !strcmp(str, "int16") )
+    return GAL_DATA_TYPE_INT16;
 
-  else if( !strcmp(str, "ui")  || !strcmp(str, "unsigned int") )
-    return GAL_DATA_TYPE_UINT;
+  else if( !strcmp(str, "u32")   || !strcmp(str, "uint32") )
+    return GAL_DATA_TYPE_UINT32;
 
-  else if( !strcmp(str, "i")   || !strcmp(str, "int") )
-    return GAL_DATA_TYPE_INT;
+  else if( !strcmp(str, "i32")   || !strcmp(str, "int32") )
+    return GAL_DATA_TYPE_INT32;
 
-  else if( !strcmp(str, "ul")  || !strcmp(str, "unsigned long") )
-    return GAL_DATA_TYPE_ULONG;
+  else if( !strcmp(str, "u64")   || !strcmp(str, "uint64") )
+    return GAL_DATA_TYPE_UINT64;
 
-  else if( !strcmp(str, "l")   || !strcmp(str, "long") )
-    return GAL_DATA_TYPE_LONG;
+  else if( !strcmp(str, "i64")   || !strcmp(str, "int64") )
+    return GAL_DATA_TYPE_INT64;
 
-  else if( !strcmp(str, "L")   || !strcmp(str, "LONGLONG") )
-    return GAL_DATA_TYPE_LONGLONG;
+  else if( !strcmp(str, "f32")   || !strcmp(str, "float32") )
+    return GAL_DATA_TYPE_FLOAT32;
 
-  else if( !strcmp(str, "f")   || !strcmp(str, "float") )
-    return GAL_DATA_TYPE_FLOAT;
+  else if( !strcmp(str, "f64")   || !strcmp(str, "float64") )
+    return GAL_DATA_TYPE_FLOAT64;
 
-  else if( !strcmp(str, "d")   || !strcmp(str, "double") )
-    return GAL_DATA_TYPE_DOUBLE;
+  else if( !strcmp(str, "c32")   || !strcmp(str, "complex32") )
+    return GAL_DATA_TYPE_COMPLEX32;
 
-  else if( !strcmp(str, "cf")  || !strcmp(str, "complex float") )
-    return GAL_DATA_TYPE_COMPLEX;
+  else if( !strcmp(str, "c64")   || !strcmp(str, "complex64") )
+    return GAL_DATA_TYPE_COMPLEX64;
 
-  else if( !strcmp(str, "cd")  || !strcmp(str, "complex double") )
-    return GAL_DATA_TYPE_DCOMPLEX;
+  else if( !strcmp(str, "str")   || !strcmp(str, "string") )
+    return GAL_DATA_TYPE_STRING;
 
   else
     return GAL_DATA_TYPE_INVALID;
@@ -198,17 +189,16 @@ gal_data_type_min(int type, void *in)
 {
   switch(type)
     {
-    case GAL_DATA_TYPE_UCHAR:    *(unsigned char *)in  = 0;            break;
-    case GAL_DATA_TYPE_CHAR:     *(char *)in           = CHAR_MIN;     break;
-    case GAL_DATA_TYPE_USHORT:   *(unsigned short *)in = 0;            break;
-    case GAL_DATA_TYPE_SHORT:    *(short *)in          = SHRT_MIN;     break;
-    case GAL_DATA_TYPE_UINT:     *(unsigned int *)in   = 0;            break;
-    case GAL_DATA_TYPE_INT:      *(int *)in            = INT_MIN;      break;
-    case GAL_DATA_TYPE_ULONG:    *(unsigned long *)in  = 0;            break;
-    case GAL_DATA_TYPE_LONG:     *(long *)in           = LONG_MIN;     break;
-    case GAL_DATA_TYPE_LONGLONG: *(LONGLONG *)in       = LONGLONG_MIN; break;
-    case GAL_DATA_TYPE_FLOAT:    *(float *)in          = -FLT_MAX;     break;
-    case GAL_DATA_TYPE_DOUBLE:   *(double *)in         = -DBL_MAX;     break;
+    case GAL_DATA_TYPE_UINT8:    *(uint8_t *)  in = 0;            break;
+    case GAL_DATA_TYPE_INT8:     *(int8_t *)   in = INT8_MIN;     break;
+    case GAL_DATA_TYPE_UINT16:   *(uint16_t *) in = 0;            break;
+    case GAL_DATA_TYPE_INT16:    *(int16_t *)  in = INT16_MIN;    break;
+    case GAL_DATA_TYPE_UINT32:   *(uint32_t *) in = 0;            break;
+    case GAL_DATA_TYPE_INT32:    *(int32_t *)  in = INT32_MIN;    break;
+    case GAL_DATA_TYPE_UINT64:   *(uint64_t *) in = 0;            break;
+    case GAL_DATA_TYPE_INT64:    *(int64_t *)  in = INT64_MIN;    break;
+    case GAL_DATA_TYPE_FLOAT32:  *(float *)    in = -FLT_MAX;     break;
+    case GAL_DATA_TYPE_FLOAT64:  *(double *)   in = -DBL_MAX;     break;
     default:
       error(EXIT_FAILURE, 0, "type code %d not recognized in "
             "`gal_data_type_min'", type);
@@ -224,17 +214,16 @@ gal_data_type_max(int type, void *in)
 {
   switch(type)
     {
-    case GAL_DATA_TYPE_UCHAR:    *(unsigned char *)in  = UCHAR_MAX;    break;
-    case GAL_DATA_TYPE_CHAR:     *(char *)in           = CHAR_MAX;     break;
-    case GAL_DATA_TYPE_USHORT:   *(unsigned short *)in = USHRT_MAX;    break;
-    case GAL_DATA_TYPE_SHORT:    *(short *)in          = SHRT_MAX;     break;
-    case GAL_DATA_TYPE_UINT:     *(unsigned int *)in   = UINT_MAX;     break;
-    case GAL_DATA_TYPE_INT:      *(int *)in            = INT_MAX;      break;
-    case GAL_DATA_TYPE_ULONG:    *(unsigned long *)in  = ULONG_MAX;    break;
-    case GAL_DATA_TYPE_LONG:     *(long *)in           = LONG_MAX;     break;
-    case GAL_DATA_TYPE_LONGLONG: *(LONGLONG *)in       = LONGLONG_MAX; break;
-    case GAL_DATA_TYPE_FLOAT:    *(float *)in          = FLT_MAX;      break;
-    case GAL_DATA_TYPE_DOUBLE:   *(double *)in         = DBL_MAX;      break;
+    case GAL_DATA_TYPE_UINT8:    *(uint8_t *)  in = UINT8_MAX;    break;
+    case GAL_DATA_TYPE_INT8:     *(int8_t *)   in = INT8_MAX;     break;
+    case GAL_DATA_TYPE_UINT16:   *(uint16_t *) in = UINT16_MAX;   break;
+    case GAL_DATA_TYPE_INT16:    *(int16_t *)  in = INT16_MAX;    break;
+    case GAL_DATA_TYPE_UINT32:   *(uint32_t *) in = UINT32_MAX;   break;
+    case GAL_DATA_TYPE_INT32:    *(int32_t *)  in = INT32_MAX;    break;
+    case GAL_DATA_TYPE_UINT64:   *(uint64_t *) in = UINT64_MAX;   break;
+    case GAL_DATA_TYPE_INT64:    *(int64_t *)  in = INT64_MAX;    break;
+    case GAL_DATA_TYPE_FLOAT32:  *(float *)    in = FLT_MAX;      break;
+    case GAL_DATA_TYPE_FLOAT64:  *(double *)   in = DBL_MAX;      break;
     default:
       error(EXIT_FAILURE, 0, "type code %d not recognized in "
             "`gal_data_type_min'", type);
@@ -312,56 +301,53 @@ gal_data_sizeof(int type)
          type cast, so we have put a space between size of and the
          parenthesis to highlight this. In C, `sizeof' is an operator, not
          a function.*/
-    case GAL_DATA_TYPE_UCHAR:
-      return sizeof (unsigned char);
-
-    case GAL_DATA_TYPE_LOGICAL: case GAL_DATA_TYPE_CHAR:
-      return sizeof (char);
-
-    case GAL_DATA_TYPE_STRING:
-      return sizeof (char *);
+    case GAL_DATA_TYPE_UINT8:
+      return sizeof (uint8_t);
 
-    case GAL_DATA_TYPE_USHORT:
-      return sizeof (unsigned short);
+    case GAL_DATA_TYPE_INT8:
+      return sizeof (int8_t);
 
-    case GAL_DATA_TYPE_SHORT:
-      return sizeof (short);
+    case GAL_DATA_TYPE_UINT16:
+      return sizeof (uint16_t);
 
-    case GAL_DATA_TYPE_UINT:
-      return sizeof (unsigned int);
+    case GAL_DATA_TYPE_INT16:
+      return sizeof (int16_t);
 
-    case GAL_DATA_TYPE_INT:
-      return sizeof (int);
+    case GAL_DATA_TYPE_UINT32:
+      return sizeof (uint32_t);
 
-    case GAL_DATA_TYPE_ULONG:
-      return sizeof (unsigned long);
+    case GAL_DATA_TYPE_INT32:
+      return sizeof (int32_t);
 
-    case GAL_DATA_TYPE_LONG:
-      return sizeof (long);
+    case GAL_DATA_TYPE_UINT64:
+      return sizeof (uint64_t);
 
-    case GAL_DATA_TYPE_LONGLONG:
-      return sizeof (LONGLONG);
+    case GAL_DATA_TYPE_INT64:
+      return sizeof (int64_t);
 
-    case GAL_DATA_TYPE_FLOAT:
+    case GAL_DATA_TYPE_FLOAT32:
       if( sizeof (float) != 4 )
         error(EXIT_FAILURE, 0, "`float` is not 32 bits on this machine");
       return sizeof (float);
 
-    case GAL_DATA_TYPE_DOUBLE:
+    case GAL_DATA_TYPE_FLOAT64:
       if( sizeof (double) != 8 )
         error(EXIT_FAILURE, 0, "`double` is not 64 bits on this machine");
       return sizeof (double);
 
-    case GAL_DATA_TYPE_COMPLEX:
+    case GAL_DATA_TYPE_COMPLEX32:
       if( sizeof (float) != 4 )
         error(EXIT_FAILURE, 0, "`float` is not 32 bits on this machine");
       return sizeof (gsl_complex_float);
 
-    case GAL_DATA_TYPE_DCOMPLEX:
+    case GAL_DATA_TYPE_COMPLEX64:
       if( sizeof (double) != 8 )
         error(EXIT_FAILURE, 0, "`double` is not 64 bits on this machine");
       return sizeof (gsl_complex);
 
+    case GAL_DATA_TYPE_STRING:
+      return sizeof (char *);
+
     default:
       error(EXIT_FAILURE, 0, "type value of %d not recognized in "
             "gal_data_sizeof", type);
@@ -466,61 +452,54 @@ gal_data_alloc_number(int type, void *number)
             "values for `GAL_DATA_TYPE_BIT', please get in touch with "
             "us to see how we can implement it.");
 
-    case GAL_DATA_TYPE_UCHAR:
-      *(unsigned char *)allocated=*(unsigned char *)number;
-      break;
-
-      /* CFITSIO says "int for keywords, char for table columns". Here we
-         are only assuming table columns. So in practice this also applies
-         to TSBYTE.*/
-    case GAL_DATA_TYPE_CHAR: case GAL_DATA_TYPE_LOGICAL:
-      *(char *)allocated=*(char *)number;
+    case GAL_DATA_TYPE_UINT8:
+      *(uint8_t *)allocated=*(uint8_t *)number;
       break;
 
-    case GAL_DATA_TYPE_USHORT:
-      *(unsigned short *)allocated=*(unsigned short *)number;
+    case GAL_DATA_TYPE_INT8:
+      *(int8_t *)allocated=*(int8_t *)number;
       break;
 
-    case GAL_DATA_TYPE_SHORT:
-      *(short *)allocated=*(short *)number;
+    case GAL_DATA_TYPE_UINT16:
+      *(uint16_t *)allocated=*(uint16_t *)number;
       break;
 
-    case GAL_DATA_TYPE_UINT:
-      *(unsigned int *)allocated=*(unsigned int *)number;
+    case GAL_DATA_TYPE_INT16:
+      *(int16_t *)allocated=*(int16_t *)number;
       break;
 
-    case GAL_DATA_TYPE_INT:
-      *(int *)allocated=*(int *)number;
+    case GAL_DATA_TYPE_UINT32:
+      *(uint32_t *)allocated=*(uint32_t *)number;
       break;
 
-    case GAL_DATA_TYPE_ULONG:
-      *(unsigned long *)allocated=*(unsigned long *)number;
+    case GAL_DATA_TYPE_INT32:
+      *(int32_t *)allocated=*(int32_t *)number;
       break;
 
-    case GAL_DATA_TYPE_LONG:
-      *(long *)allocated=*(long *)number;
+    case GAL_DATA_TYPE_UINT64:
+      *(uint64_t *)allocated=*(uint64_t *)number;
       break;
 
-    case GAL_DATA_TYPE_LONGLONG:
-      *(LONGLONG *)allocated=*(LONGLONG *)number;
+    case GAL_DATA_TYPE_INT64:
+      *(int64_t *)allocated=*(int64_t *)number;
       break;
 
-    case GAL_DATA_TYPE_FLOAT:
+    case GAL_DATA_TYPE_FLOAT32:
       *(float *)allocated=*(float *)number;
       break;
 
-    case GAL_DATA_TYPE_DOUBLE:
+    case GAL_DATA_TYPE_FLOAT64:
       *(double *)allocated=*(double *)number;
       break;
 
-    case GAL_DATA_TYPE_COMPLEX:
+    case GAL_DATA_TYPE_COMPLEX32:
       GSL_COMPLEX_P_REAL(((gsl_complex_float *)allocated)) =
         GSL_COMPLEX_P_REAL(((gsl_complex_float *)number));
       GSL_COMPLEX_P_IMAG(((gsl_complex_float *)allocated)) =
         GSL_COMPLEX_P_IMAG(((gsl_complex_float *)number));
       break;
 
-    case GAL_DATA_TYPE_DCOMPLEX:
+    case GAL_DATA_TYPE_COMPLEX64:
       GSL_COMPLEX_P_REAL(((gsl_complex *)allocated)) =
         GSL_COMPLEX_P_REAL(((gsl_complex *)number));
       GSL_COMPLEX_P_IMAG(((gsl_complex *)allocated)) =
@@ -1087,48 +1066,44 @@ gal_data_set_blank(void *pointer, int type)
       gal_checkset_allocate_copy(GAL_DATA_BLANK_STRING, pointer);
       break;
 
-    case GAL_DATA_TYPE_UCHAR:
-      *(unsigned char *)pointer  = GAL_DATA_BLANK_UCHAR;
+    case GAL_DATA_TYPE_UINT8:
+      *(uint8_t *)pointer       = GAL_DATA_BLANK_UINT8;
       break;
 
-    case GAL_DATA_TYPE_CHAR:
-      *(char *)pointer           = GAL_DATA_BLANK_CHAR;
+    case GAL_DATA_TYPE_INT8:
+      *(int8_t *)pointer        = GAL_DATA_BLANK_INT8;
       break;
 
-    case GAL_DATA_TYPE_USHORT:
-      *(unsigned short *)pointer = GAL_DATA_BLANK_USHORT;
+    case GAL_DATA_TYPE_UINT16:
+      *(uint16_t *)pointer      = GAL_DATA_BLANK_UINT16;
       break;
 
-    case GAL_DATA_TYPE_SHORT:
-      *(short *)pointer          = GAL_DATA_BLANK_SHORT;
+    case GAL_DATA_TYPE_INT16:
+      *(int16_t *)pointer       = GAL_DATA_BLANK_INT16;
       break;
 
-    case GAL_DATA_TYPE_UINT:
-      *(unsigned int *)pointer   = GAL_DATA_BLANK_UINT;
+    case GAL_DATA_TYPE_UINT32:
+      *(uint32_t *)pointer      = GAL_DATA_BLANK_UINT32;
       break;
 
-    case GAL_DATA_TYPE_INT:
-      *(int *)pointer            = GAL_DATA_BLANK_INT;
+    case GAL_DATA_TYPE_INT32:
+      *(int32_t *)pointer       = GAL_DATA_BLANK_INT32;
       break;
 
-    case GAL_DATA_TYPE_ULONG:
-      *(unsigned long *)pointer  = GAL_DATA_BLANK_ULONG;
+    case GAL_DATA_TYPE_UINT64:
+      *(uint64_t *)pointer      = GAL_DATA_BLANK_UINT64;
       break;
 
-    case GAL_DATA_TYPE_LONG:
-      *(long *)pointer           = GAL_DATA_BLANK_LONG;
+    case GAL_DATA_TYPE_INT64:
+      *(int64_t *)pointer       = GAL_DATA_BLANK_INT64;
       break;
 
-    case GAL_DATA_TYPE_LONGLONG:
-      *(LONGLONG *)pointer       = GAL_DATA_BLANK_LONGLONG;
+    case GAL_DATA_TYPE_FLOAT32:
+      *(float *)pointer         = GAL_DATA_BLANK_FLOAT32;
       break;
 
-    case GAL_DATA_TYPE_FLOAT:
-      *(float *)pointer          = GAL_DATA_BLANK_FLOAT;
-      break;
-
-    case GAL_DATA_TYPE_DOUBLE:
-      *(double *)pointer         = GAL_DATA_BLANK_DOUBLE;
+    case GAL_DATA_TYPE_FLOAT64:
+      *(double *)pointer        = GAL_DATA_BLANK_FLOAT64;
       break;
 
     default:
@@ -1181,81 +1156,74 @@ gal_data_blank_as_string(int type, int width)
         asprintf(&blank, "%s", GAL_DATA_BLANK_STRING);
       break;
 
-    case GAL_DATA_TYPE_UCHAR:
-      if(width)
-        asprintf(&blank, "%*u", width, (unsigned char)GAL_DATA_BLANK_UCHAR);
-      else
-        asprintf(&blank, "%u",         (unsigned char)GAL_DATA_BLANK_UCHAR);
-      break;
-
-    case GAL_DATA_TYPE_CHAR:
+    case GAL_DATA_TYPE_UINT8:
       if(width)
-        asprintf(&blank, "%*d", width, (char)GAL_DATA_BLANK_CHAR);
+        asprintf(&blank, "%*u", width, (uint8_t)GAL_DATA_BLANK_UINT8);
       else
-        asprintf(&blank, "%d",         (char)GAL_DATA_BLANK_CHAR);
+        asprintf(&blank, "%u",         (uint8_t)GAL_DATA_BLANK_UINT8);
       break;
 
-    case GAL_DATA_TYPE_USHORT:
+    case GAL_DATA_TYPE_INT8:
       if(width)
-        asprintf(&blank, "%*u", width, (unsigned short)GAL_DATA_BLANK_USHORT);
+        asprintf(&blank, "%*d", width, (int8_t)GAL_DATA_BLANK_INT8);
       else
-        asprintf(&blank, "%u",         (unsigned short)GAL_DATA_BLANK_USHORT);
+        asprintf(&blank, "%d",         (int8_t)GAL_DATA_BLANK_INT8);
       break;
 
-    case GAL_DATA_TYPE_SHORT:
+    case GAL_DATA_TYPE_UINT16:
       if(width)
-        asprintf(&blank, "%*d", width, (short)GAL_DATA_BLANK_SHORT);
+        asprintf(&blank, "%*u", width, (uint16_t)GAL_DATA_BLANK_UINT16);
       else
-        asprintf(&blank, "%d",         (short)GAL_DATA_BLANK_SHORT);
+        asprintf(&blank, "%u",         (uint16_t)GAL_DATA_BLANK_UINT16);
       break;
 
-    case GAL_DATA_TYPE_UINT:
+    case GAL_DATA_TYPE_INT16:
       if(width)
-        asprintf(&blank, "%*u", width, (unsigned int)GAL_DATA_BLANK_UINT);
+        asprintf(&blank, "%*d", width, (int16_t)GAL_DATA_BLANK_INT16);
       else
-        asprintf(&blank, "%u",         (unsigned int)GAL_DATA_BLANK_UINT);
+        asprintf(&blank, "%d",         (int16_t)GAL_DATA_BLANK_INT16);
       break;
 
-    case GAL_DATA_TYPE_INT:
+    case GAL_DATA_TYPE_UINT32:
       if(width)
-        asprintf(&blank, "%*d", width, (int)GAL_DATA_BLANK_INT);
+        asprintf(&blank, "%*u", width, (uint32_t)GAL_DATA_BLANK_UINT32);
       else
-        asprintf(&blank, "%d",         (int)GAL_DATA_BLANK_INT);
+        asprintf(&blank, "%u",         (uint32_t)GAL_DATA_BLANK_UINT32);
       break;
 
-    case GAL_DATA_TYPE_ULONG:
+    case GAL_DATA_TYPE_INT32:
       if(width)
-        asprintf(&blank, "%*lu", width, (unsigned long)GAL_DATA_BLANK_ULONG);
+        asprintf(&blank, "%*d", width, (int32_t)GAL_DATA_BLANK_INT32);
       else
-        asprintf(&blank, "%lu",         (unsigned long)GAL_DATA_BLANK_ULONG);
+        asprintf(&blank, "%d",         (int32_t)GAL_DATA_BLANK_INT32);
       break;
 
-    case GAL_DATA_TYPE_LONG:
+    case GAL_DATA_TYPE_UINT64:
       if(width)
-        asprintf(&blank, "%*ld", width, (long)GAL_DATA_BLANK_LONG);
+        asprintf(&blank, "%*lu", width, (uint64_t)GAL_DATA_BLANK_UINT64);
       else
-        asprintf(&blank, "%ld",         (long)GAL_DATA_BLANK_LONG);
+        asprintf(&blank, "%lu",         (uint64_t)GAL_DATA_BLANK_UINT64);
       break;
 
-    case GAL_DATA_TYPE_LONGLONG:
+    case GAL_DATA_TYPE_INT64:
       if(width)
-        asprintf(&blank, "%*lld", width, (LONGLONG)GAL_DATA_BLANK_LONGLONG);
+        asprintf(&blank, "%*ld", width, (int64_t)GAL_DATA_BLANK_INT64);
       else
-        asprintf(&blank, "%lld",         (LONGLONG)GAL_DATA_BLANK_LONGLONG);
+        asprintf(&blank, "%ld",         (int64_t)GAL_DATA_BLANK_INT64);
       break;
 
-    case GAL_DATA_TYPE_FLOAT:
+    case GAL_DATA_TYPE_FLOAT32:
       if(width)
-        asprintf(&blank, "%*f", width, (float)GAL_DATA_BLANK_FLOAT);
+        asprintf(&blank, "%*f", width, (float)GAL_DATA_BLANK_FLOAT32);
       else
-        asprintf(&blank, "%f",         (float)GAL_DATA_BLANK_FLOAT);
+        asprintf(&blank, "%f",         (float)GAL_DATA_BLANK_FLOAT32);
       break;
 
-    case GAL_DATA_TYPE_DOUBLE:
+    case GAL_DATA_TYPE_FLOAT64:
       if(width)
-        asprintf(&blank, "%*f", width, (double)GAL_DATA_BLANK_DOUBLE);
+        asprintf(&blank, "%*f", width, (double)GAL_DATA_BLANK_FLOAT64);
       else
-        asprintf(&blank, "%f",         (double)GAL_DATA_BLANK_DOUBLE);
+        asprintf(&blank, "%f",         (double)GAL_DATA_BLANK_FLOAT64);
       break;
 
     default:
@@ -1269,326 +1237,28 @@ gal_data_blank_as_string(int type, int width)
 
 
 
-/* Any non-zero pixel in the `mask' array is set as blank in the `in'
-   array. */
-void
-gal_data_apply_mask(gal_data_t *in, gal_data_t *mask)
-{
-  int hasblank=0;
-  float *mpt, *m, *mf;
-  gal_data_t *converted;
-
-  unsigned char     *uc   = in->array, *ucf   = uc  + in->size;
-  char              *c    = in->array, *cf    = c   + in->size;
-  char              **str = in->array, **strf = str + in->size;
-  unsigned short    *us   = in->array, *usf   = us  + in->size;
-  short             *s    = in->array, *sf    = s   + in->size;
-  unsigned int      *ui   = in->array, *uif   = ui  + in->size;
-  int               *ii   = in->array, *iif   = ii  + in->size;
-  unsigned long     *ul   = in->array, *ulf   = ul  + in->size;
-  long              *l    = in->array, *lf    = l   + in->size;
-  LONGLONG          *L    = in->array, *Lf    = L   + in->size;
-  float             *f    = in->array, *ff    = f   + in->size;
-  double            *d    = in->array, *df    = d   + in->size;
-  gsl_complex_float *cx   = in->array, *cxf   = cx  + in->size;
-  gsl_complex       *dcx  = in->array, *dcxf  = dcx + in->size;
-
-
-  /* Make sure the mask and input image have the same dimentionality: */
-  if(in->ndim!=mask->ndim)
-    error(EXIT_FAILURE, 0, "the `in' and `mask' data structures given "
-          "to `gal_data_apply_mask' do not have the same dimensionality: "
-          "%zu and %zu respectively", in->ndim, mask->ndim);
-
-
-  /* Make sure the mask and input image have the same size along each
-     dimension: */
-  if(gal_data_dsize_is_different(in, mask))
-    error(EXIT_FAILURE, 0, "the `in' and `mask' data structures given "
-          "to `gal_data_apply_mask' do not have the same size along each "
-          "dimension");
-
-
-  /* First convert the mask to floating point. Note that although the
-     standard definition of a mask is for it to be an integer, in some
-     situations, the users might want to specify a floating point image as
-     a mask. Such a mask might have values between 0 and 1 (for example
-     they have made a mock profiles and want to mask all pixels covered by
-     a profile). If we simply convert the mask image to an integer, all
-     pixels with values between zero and one will be set to 0. So we need
-     to internally convert the mask image to float to preserve this. */
-  if(mask->type==GAL_DATA_TYPE_FLOAT)
-    converted=mask;
-  else
-    converted=gal_data_copy_to_new_type(mask, GAL_DATA_TYPE_FLOAT);
-  mpt=converted->array;
-
-
-  /* Go over all the pixels and apply the mask. But first check if there
-     actually are any blank values, it might be the case that there isn't
-     any and in that case we can ignore the checks: */
-  mf=(m=mpt)+in->size; do if(*m++ != 0.0f) hasblank=1; while(m<mf);
-  if(hasblank)
-    {
-      switch(in->type)
-        {
-        case GAL_DATA_TYPE_BIT:
-          error(EXIT_FAILURE, 0, "Currently Gnuastro doesn't support blank "
-                "values for `GAL_DATA_TYPE_BIT', please get in touch with "
-                "us to see how we can implement it.");
-
-        case GAL_DATA_TYPE_UCHAR:
-          do *uc = *mpt++==0.0f ? *uc : GAL_DATA_BLANK_UCHAR; while(++uc<ucf);
-          break;
-
-          /* CFITSIO says "int for keywords, char for table columns". Here we
-             are only assuming table columns. So in practice this also applies
-             to TSBYTE.*/
-        case GAL_DATA_TYPE_CHAR: case GAL_DATA_TYPE_LOGICAL:
-          do *c = *mpt++==0.0f ? *c : GAL_DATA_BLANK_CHAR; while(++c<cf);
-          break;
-
-        case GAL_DATA_TYPE_STRING:
-          do *str = *mpt++==0.0f ? *str : GAL_DATA_BLANK_STRING;
-          while(++str<strf);
-          break;
-
-        case GAL_DATA_TYPE_USHORT:
-          do *us = *mpt++==0.0f ? *us : GAL_DATA_BLANK_USHORT;
-          while(++us<usf);
-          break;
-
-        case GAL_DATA_TYPE_SHORT:
-          do *s = *mpt++==0.0f ? *s : GAL_DATA_BLANK_SHORT; while(++s<sf);
-          break;
-
-        case GAL_DATA_TYPE_UINT:
-          do *ui = *mpt++==0.0f ? *ui : GAL_DATA_BLANK_UINT; while(++ui<uif);
-          break;
-
-        case GAL_DATA_TYPE_INT:
-          do *ii = *mpt++==0.0f ? *ii : GAL_DATA_BLANK_INT; while(++ii<iif);
-          break;
-
-        case GAL_DATA_TYPE_ULONG:
-          do *ul = *mpt++==0.0f ? *ul : GAL_DATA_BLANK_ULONG; while(++ul<ulf);
-          break;
-
-        case GAL_DATA_TYPE_LONG:
-          do *l = *mpt++==0.0f ? *l : GAL_DATA_BLANK_LONG; while(++l<lf);
-          break;
-
-        case GAL_DATA_TYPE_LONGLONG:
-          do *L = *mpt++==0.0f ? *L : GAL_DATA_BLANK_LONGLONG; while(++L<Lf);
-          break;
-
-        case GAL_DATA_TYPE_FLOAT:
-          do *f = *mpt++==0.0f ? *f : GAL_DATA_BLANK_FLOAT; while(++f<ff);
-          break;
-
-        case GAL_DATA_TYPE_DOUBLE:
-          do *d = *mpt++==0.0f ? *d : GAL_DATA_BLANK_DOUBLE; while(++d<df);
-          break;
-
-        case GAL_DATA_TYPE_COMPLEX:
-          do
-            if(*mpt++ == 0.0f)
-              GSL_SET_COMPLEX(cx, GAL_DATA_BLANK_FLOAT, GAL_DATA_BLANK_FLOAT);
-          while(++cx<cxf);
-          break;
-
-        case GAL_DATA_TYPE_DCOMPLEX:
-          do
-            if(*mpt++==0.0f)
-              GSL_SET_COMPLEX(dcx, GAL_DATA_BLANK_DOUBLE,
-                              GAL_DATA_BLANK_DOUBLE);
-          while(++dcx<dcxf);
-          break;
-
-        default:
-          error(EXIT_FAILURE, 0, "type value of %d not recognized in "
-                "`gal_data_alloc_blank'", in->type);
-        }
-    }
-
-  /* Free the converted mask data if it was allocated: */
-  if(converted!=mask)
-    free(converted);
-}
-
-
-
-
-
-/* Change all blank values in `data' to the value pointed to by `value'. */
-void
-gal_data_blank_to_value(gal_data_t *data, void *value)
-{
-  /* 'value' will only be read from one of these based on the
-     datatype. Which the caller assigned. If there is any problem, it is
-     their responsability, not this function's.*/
-  void *A=data->array;
-  size_t S=data->size;
-  unsigned char     *uc = A,   *ucf = A+S,   ucv = *(unsigned char *) value;
-  char               *c = A,    *cf = A+S,    cv = *(char *) value;
-  char            **str = A, **strf = A+S, *strv = *(char **) value;
-  unsigned short    *us = A,   *usf = A+S,   usv = *(unsigned short *) value;
-  short              *s = A,    *sf = A+S,    sv = *(short *) value;
-  unsigned int      *ui = A,   *uif = A+S,   uiv = *(unsigned int *) value;
-  int               *in = A,   *inf = A+S,   inv = *(int *) value;
-  unsigned long     *ul = A,   *ulf = A+S,   ulv = *(unsigned long *) value;
-  long               *l = A,    *lf = A+S,    lv = *(int32_t *) value;
-  LONGLONG           *L = A,    *Lf = A+S,    Lv = *(int64_t *) value;
-  float              *f = A,    *ff = A+S,    fv = *(float *) value;
-  double             *d = A,    *df = A+S,    dv = *(double *) value;
-  gsl_complex_float *cx = A,   *cxf = A+S,   cxv = *(gsl_complex_float *) 
value;
-  gsl_complex      *dcx = A,  *dcxf = A+S,  dcxv = *(gsl_complex *) value;
-
-  switch(data->type)
-    {
-    case GAL_DATA_TYPE_BIT:
-      error(EXIT_FAILURE, 0, "Currently Gnuastro doesn't support bit "
-            "datatype, please get in touch with us to implement it.");
-
-    case GAL_DATA_TYPE_UCHAR:
-      do if(*uc==GAL_DATA_BLANK_UCHAR) *uc=ucv; while(++uc<ucf);
-      break;
-
-
-    case GAL_DATA_TYPE_CHAR: case GAL_DATA_TYPE_LOGICAL:
-      do if(*c==GAL_DATA_BLANK_CHAR) *c=cv; while(++c<cf);
-      break;
-
-
-    case GAL_DATA_TYPE_STRING:
-      do
-        if(!strcmp(*str, GAL_DATA_BLANK_STRING))
-          gal_checkset_allocate_copy(strv, str);
-      while(++str<strf);
-      break;
-
-
-    case GAL_DATA_TYPE_USHORT:
-      do if(*us==GAL_DATA_BLANK_USHORT) *us=usv; while(++us<usf);
-      break;
-
-
-    case GAL_DATA_TYPE_SHORT:
-      do if(*s==GAL_DATA_BLANK_SHORT) *s=sv; while(++s<sf);
-      break;
-
-
-    case GAL_DATA_TYPE_UINT:
-      do if(*ui==GAL_DATA_BLANK_UINT) *ui=uiv; while(++ui<uif);
-      break;
-
-
-    case GAL_DATA_TYPE_INT:
-      do if(*in==GAL_DATA_BLANK_INT) *in=inv; while(++in<inf);
-      break;
-
-
-    case GAL_DATA_TYPE_ULONG:
-      do if(*ul==GAL_DATA_BLANK_ULONG) *ul=ulv; while(++ul<ulf);
-      break;
-
-
-    case GAL_DATA_TYPE_LONG:
-      do if(*l==GAL_DATA_BLANK_LONG) *l=lv; while(++l<lf);
-      break;
-
-
-    case GAL_DATA_TYPE_LONGLONG:
-      do if(*L==GAL_DATA_BLANK_LONGLONG) *L=Lv; while(++L<Lf);
-      break;
-
-
-      /* Note that a NaN value is not equal to another NaN value, so we
-         can't use the easy check for cases were the blank value is
-         NaN. Also note that `isnan' is actually a macro, so it works for
-         both float and double types.*/
-    case GAL_DATA_TYPE_FLOAT:
-      if(isnan(GAL_DATA_BLANK_FLOAT))
-        do if(isnan(*f)) *f++=fv; while(f<ff);
-      else
-        do if(*f==GAL_DATA_BLANK_FLOAT) *f++=fv; while(f<ff);
-      break;
-
-
-    case GAL_DATA_TYPE_DOUBLE:
-      if(isnan(GAL_DATA_BLANK_DOUBLE))
-        do if(isnan(*d)) *d++=dv; while(d<df);
-      else
-        do if(*d==GAL_DATA_BLANK_FLOAT) *d++=dv; while(d<df);
-      break;
-
-
-    case GAL_DATA_TYPE_COMPLEX:
-      if(isnan(GAL_DATA_BLANK_FLOAT))
-          do
-            if(isnan(GSL_COMPLEX_P_REAL(cx))
-               && isnan(GSL_COMPLEX_P_IMAG(cx)) )
-              GSL_SET_COMPLEX(cx, GSL_COMPLEX_P_REAL(&cxv),
-                              GSL_COMPLEX_P_IMAG(&cxv));
-          while(++cx<cxf);
-      else
-        do
-          if( GSL_COMPLEX_P_REAL(cx) == GAL_DATA_BLANK_FLOAT
-              && GSL_COMPLEX_P_IMAG(cx) == GAL_DATA_BLANK_FLOAT)
-            GSL_SET_COMPLEX(cx, GSL_COMPLEX_P_REAL(&cxv),
-                            GSL_COMPLEX_P_IMAG(&cxv));
-        while(++cx<cxf);
-      break;
-
-
-    case GAL_DATA_TYPE_DCOMPLEX:
-      if(isnan(GAL_DATA_BLANK_DOUBLE))
-          do
-            if(isnan(GSL_COMPLEX_P_REAL(dcx))
-               && isnan(GSL_COMPLEX_P_IMAG(dcx)) )
-              GSL_SET_COMPLEX(dcx, GSL_COMPLEX_P_REAL(&dcxv),
-                              GSL_COMPLEX_P_IMAG(&dcxv));
-          while(++dcx<dcxf);
-      else
-        do
-          if( GSL_COMPLEX_P_REAL(dcx) == GAL_DATA_BLANK_FLOAT
-              && GSL_COMPLEX_P_IMAG(dcx) == GAL_DATA_BLANK_FLOAT)
-            GSL_SET_COMPLEX(dcx, GSL_COMPLEX_P_REAL(&dcxv),
-                            GSL_COMPLEX_P_IMAG(&dcxv));
-        while(++dcx<dcxf);
-      break;
-
-
-    default:
-      error(EXIT_FAILURE, 0, "a bug! type value (%d) not recognized "
-            "in `gal_data_blank_to_value'", data->type);
-    }
-}
-
 
+/* For integers a simple equality is enough. */
+#define HAS_BLANK_INT(CTYPE, BLANK) {                                   \
+    CTYPE *a=data->array, *af=a+data->size;                             \
+    do if(*a++ == BLANK) return 1; while(a<af);                         \
+  }
 
+/* Note that a NaN value is not equal to another NaN value, so we can't use
+   the easy check for cases were the blank value is NaN. Also note that
+   `isnan' is actually a macro, so it works for both float and double
+   types.*/
+#define HAS_BLANK_FLT(CTYPE, BLANK, MULTIP) {                           \
+    CTYPE *a=data->array, *af=a+(MULTIP*data->size);                    \
+    if(isnan(BLANK)) do if(isnan(*a++)) return 1; while(a<af);          \
+    else             do if(*a++==BLANK) return 1; while(a<af);          \
+  }
 
 /* Return 1 if the dataset has a blank value and zero if it doesn't. */
 int
 gal_data_has_blank(gal_data_t *data)
 {
-  /* 'value' will only be read from one of these based on the
-     datatype. Which the caller assigned. If there is any problem, it is
-     their responsability, not this function's.*/
-  unsigned char     *uc = data->array,   *ucf = uc  + data->size;
-  char               *c = data->array,    *cf = c   + data->size;
-  char            **str = data->array, **strf = str + data->size;
-  unsigned short    *us = data->array,   *usf = us  + data->size;
-  short              *s = data->array,    *sf = s   + data->size;
-  unsigned int      *ui = data->array,   *uif = ui  + data->size;
-  int               *in = data->array,   *inf = in  + data->size;
-  unsigned long     *ul = data->array,   *ulf = ul  + data->size;
-  long               *l = data->array,    *lf = l   + data->size;
-  LONGLONG           *L = data->array,    *Lf = L   + data->size;
-  float              *f = data->array,    *ff = f   + data->size;
-  double             *d = data->array,    *df = d   + data->size;
-  gsl_complex_float *cx = data->array,   *cxf = cx  + data->size;
-  gsl_complex      *dcx = data->array,  *dcxf = dcx + data->size;
+  char **str=data->array, **strf=str+data->size;
 
   /* Go over the pixels and check: */
   switch(data->type)
@@ -1597,108 +1267,46 @@ gal_data_has_blank(gal_data_t *data)
       error(EXIT_FAILURE, 0, "Currently Gnuastro doesn't support bit "
             "datatype, please get in touch with us to implement it.");
 
-    case GAL_DATA_TYPE_UCHAR:
-      do if(*uc++==GAL_DATA_BLANK_UCHAR) return 1; while(uc<ucf);
-      break;
-
-
-    case GAL_DATA_TYPE_CHAR: case GAL_DATA_TYPE_LOGICAL:
-      do if(*c++==GAL_DATA_BLANK_CHAR) return 1; while(c<cf);
-      break;
-
-
-    case GAL_DATA_TYPE_STRING:
-      do if(!strcmp(*str++,GAL_DATA_BLANK_STRING)) return 1; while(str<strf);
-      break;
-
-
-    case GAL_DATA_TYPE_USHORT:
-      do if(*us++==GAL_DATA_BLANK_USHORT) return 1; while(us<usf);
-      break;
-
-
-    case GAL_DATA_TYPE_SHORT:
-      do if(*s++==GAL_DATA_BLANK_SHORT) return 1; while(s<sf);
-      break;
-
-
-    case GAL_DATA_TYPE_UINT:
-      do if(*ui++==GAL_DATA_BLANK_UINT) return 1; while(ui<uif);
-      break;
-
+    case GAL_DATA_TYPE_UINT8:
+      HAS_BLANK_INT(uint8_t, GAL_DATA_BLANK_UINT8);     break;
 
-    case GAL_DATA_TYPE_INT:
-      do if(*in++==GAL_DATA_BLANK_INT) return 1; while(in<inf);
-      break;
+    case GAL_DATA_TYPE_INT8:
+      HAS_BLANK_INT(int8_t, GAL_DATA_BLANK_INT8);       break;
 
+    case GAL_DATA_TYPE_UINT16:
+      HAS_BLANK_INT(uint16_t, GAL_DATA_BLANK_UINT16);   break;
 
-    case GAL_DATA_TYPE_ULONG:
-      do if(*ul++==GAL_DATA_BLANK_ULONG) return 1; while(ul<ulf);
-      break;
+    case GAL_DATA_TYPE_INT16:
+      HAS_BLANK_INT(int16_t, GAL_DATA_BLANK_INT16);     break;
 
+    case GAL_DATA_TYPE_UINT32:
+      HAS_BLANK_INT(uint32_t, GAL_DATA_BLANK_UINT32);   break;
 
-    case GAL_DATA_TYPE_LONG:
-      do if(*l++==GAL_DATA_BLANK_LONG) return 1; while(l<lf);
-      break;
-
+    case GAL_DATA_TYPE_INT32:
+      HAS_BLANK_INT(int32_t, GAL_DATA_BLANK_INT32);     break;
 
-    case GAL_DATA_TYPE_LONGLONG:
-      do if(*L++==GAL_DATA_BLANK_LONGLONG) return 1; while(L<Lf);
-      break;
+    case GAL_DATA_TYPE_UINT64:
+      HAS_BLANK_INT(uint64_t, GAL_DATA_BLANK_UINT64);   break;
 
+    case GAL_DATA_TYPE_INT64:
+      HAS_BLANK_INT(int64_t, GAL_DATA_BLANK_INT64);     break;
 
-      /* Note that a NaN value is not equal to another NaN value, so we
-         can't use the easy check for cases were the blank value is
-         NaN. Also note that `isnan' is actually a macro, so it works for
-         both float and double types.*/
-    case GAL_DATA_TYPE_FLOAT:
-      if(isnan(GAL_DATA_BLANK_FLOAT))
-        do if(isnan(*f++)) return 1; while(f<ff);
-      else
-        do if(*f++==GAL_DATA_BLANK_FLOAT) return 1; while(f<ff);
-      break;
+    case GAL_DATA_TYPE_FLOAT32:
+      HAS_BLANK_FLT(float, GAL_DATA_BLANK_FLOAT32, 1);  break;
 
+    case GAL_DATA_TYPE_FLOAT64:
+      HAS_BLANK_FLT(double, GAL_DATA_BLANK_FLOAT64, 1); break;
 
-    case GAL_DATA_TYPE_DOUBLE:
-      if(isnan(GAL_DATA_BLANK_DOUBLE))
-        do if(isnan(*d++)) return 1; while(d<df);
-      else
-        do if(*d++==GAL_DATA_BLANK_FLOAT) return 1; while(d<df);
-      break;
+    case GAL_DATA_TYPE_COMPLEX32:
+      HAS_BLANK_FLT(float, GAL_DATA_BLANK_FLOAT32, 2);  break;
 
+    case GAL_DATA_TYPE_COMPLEX64:
+      HAS_BLANK_FLT(double, GAL_DATA_BLANK_FLOAT64, 2); break;
 
-    case GAL_DATA_TYPE_COMPLEX:
-      if(isnan(GAL_DATA_BLANK_FLOAT))
-          do
-            if(isnan(GSL_COMPLEX_P_REAL(cx))
-               && isnan(GSL_COMPLEX_P_IMAG(cx)) )
-              return 1;
-          while(++cx<cxf);
-      else
-        do
-          if( GSL_COMPLEX_P_REAL(cx) == GAL_DATA_BLANK_FLOAT
-              && GSL_COMPLEX_P_IMAG(cx) == GAL_DATA_BLANK_FLOAT)
-            return 1;
-        while(++cx<cxf);
-      break;
-
-
-    case GAL_DATA_TYPE_DCOMPLEX:
-      if(isnan(GAL_DATA_BLANK_DOUBLE))
-          do
-            if(isnan(GSL_COMPLEX_P_REAL(dcx))
-               && isnan(GSL_COMPLEX_P_IMAG(dcx)) )
-              return 1;
-          while(++dcx<dcxf);
-      else
-        do
-          if( GSL_COMPLEX_P_REAL(dcx) == GAL_DATA_BLANK_FLOAT
-              && GSL_COMPLEX_P_IMAG(dcx) == GAL_DATA_BLANK_FLOAT)
-            return 1;
-        while(++dcx<dcxf);
+    case GAL_DATA_TYPE_STRING:
+      do if(!strcmp(*str++,GAL_DATA_BLANK_STRING)) return 1; while(str<strf);
       break;
 
-
     default:
       error(EXIT_FAILURE, 0, "a bug! type value (%d) not recognized "
             "in `gal_data_blank_to_value'", data->type);
@@ -1714,41 +1322,46 @@ gal_data_has_blank(gal_data_t *data)
 
 
 
-/* Output a data-set of the the same size as the input, but with an
-   unsigned character type that has a value of 1 for data that are blank
-   and 0 for those that aren't. */
+/* For integers a simple equality is enough. */
+#define FLAG_BLANK_INT(CTYPE, BLANK) {                                  \
+    CTYPE *a=data->array; do *o = (*a==BLANK); while(++o<of);           \
+  }
+
+/* Note that a NaN value is not equal to another NaN value, so we can't use
+   the easy check for cases were the blank value is NaN. Also note that
+   `isnan' is actually a macro, so it works for both float and double
+   types.*/
+#define FLAG_BLANK_FLT(CTYPE, BLANK) {                                  \
+    CTYPE *a=data->array;                                               \
+    if(isnan(BLANK)) do *o = isnan(*a++);   while(++o<of);              \
+    else             do *o = (*a++==BLANK); while(++o<of);              \
+  }
+
+#define FLAG_BLANK_COMPLEX(CTYPE, BLANK) {                              \
+    CTYPE *a=data->array;                                               \
+    if(isnan(BLANK))                                                    \
+      do { *o=(isnan(*a) || isnan(*(a+1))); a+=2; } while(++o<of);      \
+    else                                                                \
+      do { *o=(*a==BLANK || *(a+1)==BLANK); a+=2; } while(++o<of);      \
+  }
+
+/* Output a data-set of the the same size as the input, but with an uint8_t
+   type that has a value of 1 for data that are blank and 0 for those that
+   aren't. */
 gal_data_t *
 gal_data_flag_blank(gal_data_t *data)
 {
+  uint8_t *o, *of;
   gal_data_t *out;
-
-  /* 'value' will only be read from one of these based on the
-     datatype. Which the caller assigned. If there is any problem, it is
-     their responsability, not this function's.*/
-  void *A=data->array;
-  size_t S=data->size;
-  unsigned char     *uc = A,   *ucf = A+S, *o;
-  char               *c = A,    *cf = A+S;
-  char            **str = A, **strf = A+S;
-  unsigned short    *us = A,   *usf = A+S;
-  short              *s = A,    *sf = A+S;
-  unsigned int      *ui = A,   *uif = A+S;
-  int               *in = A,   *inf = A+S;
-  unsigned long     *ul = A,   *ulf = A+S;
-  long               *l = A,    *lf = A+S;
-  LONGLONG           *L = A,    *Lf = A+S;
-  float              *f = A,    *ff = A+S;
-  double             *d = A,    *df = A+S;
-  gsl_complex_float *cx = A,   *cxf = A+S;
-  gsl_complex      *dcx = A,  *dcxf = A+S;
-
+  char **str=data->array, **strf=str+data->size;
 
   /* Allocate the output array. */
-  out=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, data->ndim, data->dsize,
+  out=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, data->ndim, data->dsize,
                      data->wcs, 0, data->minmapsize, data->name, data->unit,
                      data->comment);
-  o=out->array;
 
+  /* Set the pointers for easy looping. */
+  of=(o=out->array)+data->size;
 
   /* Go over the pixels and set the output values. */
   switch(data->type)
@@ -1757,104 +1370,46 @@ gal_data_flag_blank(gal_data_t *data)
       error(EXIT_FAILURE, 0, "Currently Gnuastro doesn't support bit "
             "datatype, please get in touch with us to implement it.");
 
-    case GAL_DATA_TYPE_UCHAR:
-      do *o++ = *uc==GAL_DATA_BLANK_UCHAR; while(++uc<ucf);
-      break;
+    case GAL_DATA_TYPE_UINT8:
+      FLAG_BLANK_INT(uint8_t, GAL_DATA_BLANK_UINT8);      break;
 
+    case GAL_DATA_TYPE_INT8:
+      FLAG_BLANK_INT(int8_t, GAL_DATA_BLANK_INT8);        break;
 
-    case GAL_DATA_TYPE_CHAR: case GAL_DATA_TYPE_LOGICAL:
-      do *o++ = *c==GAL_DATA_BLANK_CHAR; while(++c<cf);
-      break;
+    case GAL_DATA_TYPE_UINT16:
+      FLAG_BLANK_INT(uint16_t, GAL_DATA_BLANK_UINT16);    break;
 
+    case GAL_DATA_TYPE_INT16:
+      FLAG_BLANK_INT(int16_t, GAL_DATA_BLANK_INT16);      break;
 
-    case GAL_DATA_TYPE_STRING:
-      do *o++ = !strcmp(*str,GAL_DATA_BLANK_STRING); while(++str<strf);
-      break;
+    case GAL_DATA_TYPE_UINT32:
+      FLAG_BLANK_INT(uint32_t, GAL_DATA_BLANK_UINT32);    break;
 
+    case GAL_DATA_TYPE_INT32:
+      FLAG_BLANK_INT(int32_t, GAL_DATA_BLANK_INT32);      break;
 
-    case GAL_DATA_TYPE_USHORT:
-      do *o++ = *us==GAL_DATA_BLANK_USHORT; while(++us<usf);
-      break;
+    case GAL_DATA_TYPE_UINT64:
+      FLAG_BLANK_INT(uint64_t, GAL_DATA_BLANK_UINT64);    break;
 
+    case GAL_DATA_TYPE_INT64:
+      FLAG_BLANK_INT(int64_t, GAL_DATA_BLANK_INT64);      break;
 
-    case GAL_DATA_TYPE_SHORT:
-      do *o++ = *s==GAL_DATA_BLANK_SHORT; while(++s<sf);
-      break;
+    case GAL_DATA_TYPE_FLOAT32:
+      FLAG_BLANK_FLT(float, GAL_DATA_BLANK_FLOAT32);      break;
 
+    case GAL_DATA_TYPE_FLOAT64:
+      FLAG_BLANK_FLT(double, GAL_DATA_BLANK_FLOAT64);     break;
 
-    case GAL_DATA_TYPE_UINT:
-      do *o++ = *ui==GAL_DATA_BLANK_UINT; while(++ui<uif);
-      break;
-
-
-    case GAL_DATA_TYPE_INT:
-      do *o++ = *in==GAL_DATA_BLANK_INT; while(++in<inf);
-      break;
+    case GAL_DATA_TYPE_COMPLEX32:
+      FLAG_BLANK_COMPLEX(float, GAL_DATA_BLANK_FLOAT32);  break;
 
+    case GAL_DATA_TYPE_COMPLEX64:
+      FLAG_BLANK_COMPLEX(double, GAL_DATA_BLANK_FLOAT64); break;
 
-    case GAL_DATA_TYPE_ULONG:
-      do *o++ = *ul==GAL_DATA_BLANK_ULONG; while(++ul<ulf);
-      break;
-
-
-    case GAL_DATA_TYPE_LONG:
-      do *o++ = *l==GAL_DATA_BLANK_LONG; while(++l<lf);
-      break;
-
-
-    case GAL_DATA_TYPE_LONGLONG:
-      do *o++ = *L==GAL_DATA_BLANK_LONGLONG; while(++L<Lf);
-      break;
-
-
-      /* Note that a NaN value is not equal to another NaN value, so we
-         can't use the easy check for cases were the blank value is
-         NaN. Also note that `isnan' is actually a macro, so it works for
-         both float and double types.*/
-    case GAL_DATA_TYPE_FLOAT:
-      if(isnan(GAL_DATA_BLANK_FLOAT))
-        do *o++ = isnan(*f); while(++f<ff);
-      else
-        do *o++ = *f==GAL_DATA_BLANK_FLOAT; while(++f<ff);
-      break;
-
-
-    case GAL_DATA_TYPE_DOUBLE:
-      if(isnan(GAL_DATA_BLANK_DOUBLE))
-        do *o++ = isnan(*d); while(++d<df);
-      else
-        do *o++ = *d==GAL_DATA_BLANK_DOUBLE; while(++d<df);
-      break;
-
-
-    case GAL_DATA_TYPE_COMPLEX:
-      if(isnan(GAL_DATA_BLANK_FLOAT))
-          do
-            *o++ = ( isnan(GSL_COMPLEX_P_REAL(cx))
-                     && isnan(GSL_COMPLEX_P_IMAG(cx)) );
-          while(++cx<cxf);
-      else
-        do
-          *o++ = ( GSL_COMPLEX_P_REAL(cx) == GAL_DATA_BLANK_FLOAT
-                   && GSL_COMPLEX_P_IMAG(cx) == GAL_DATA_BLANK_FLOAT );
-        while(++cx<cxf);
-      break;
-
-
-    case GAL_DATA_TYPE_DCOMPLEX:
-      if(isnan(GAL_DATA_BLANK_DOUBLE))
-          do
-            *o++ = ( isnan(GSL_COMPLEX_P_REAL(dcx))
-                     && isnan(GSL_COMPLEX_P_IMAG(dcx)) );
-          while(++dcx<dcxf);
-      else
-        do
-          *o++ = ( GSL_COMPLEX_P_REAL(dcx) == GAL_DATA_BLANK_FLOAT
-                   && GSL_COMPLEX_P_IMAG(dcx) == GAL_DATA_BLANK_FLOAT );
-        while(++dcx<dcxf);
+    case GAL_DATA_TYPE_STRING:
+      do *o++ = !strcmp(*str,GAL_DATA_BLANK_STRING); while(++str<strf);
       break;
 
-
     default:
       error(EXIT_FAILURE, 0, "type value (%d) not recognized "
             "in `gal_data_flag_blank'", data->type);
@@ -1924,33 +1479,31 @@ data_copy_from_string(gal_data_t *from, gal_data_t *to)
       /* Set the pointer. */
       switch(to->type)
         {
-        case GAL_DATA_TYPE_UCHAR:    ptr = (unsigned char *)(to->array) + i;
-          break;
-        case GAL_DATA_TYPE_CHAR:     ptr = (char *)(to->array) + i;
+        case GAL_DATA_TYPE_UINT8:    ptr = (uint8_t *)(to->array) + i;
           break;
-        case GAL_DATA_TYPE_USHORT:   ptr = (unsigned short *)(to->array) + i;
+        case GAL_DATA_TYPE_INT8:     ptr = (int8_t *)(to->array) + i;
           break;
-        case GAL_DATA_TYPE_SHORT:    ptr = (short *)(to->array) + i;
+        case GAL_DATA_TYPE_UINT16:   ptr = (uint16_t *)(to->array) + i;
           break;
-        case GAL_DATA_TYPE_UINT:     ptr = (unsigned int *)(to->array) + i;
+        case GAL_DATA_TYPE_INT16:    ptr = (int16_t *)(to->array) + i;
           break;
-        case GAL_DATA_TYPE_INT:      ptr = (int *)(to->array) + i;
+        case GAL_DATA_TYPE_UINT32:   ptr = (uint32_t *)(to->array) + i;
           break;
-        case GAL_DATA_TYPE_ULONG:    ptr = (unsigned long *)(to->array) + i;
+        case GAL_DATA_TYPE_INT32:    ptr = (int32_t *)(to->array) + i;
           break;
-        case GAL_DATA_TYPE_LONG:     ptr = (long *)(to->array) + i;
+        case GAL_DATA_TYPE_UINT64:   ptr = (uint64_t *)(to->array) + i;
           break;
-        case GAL_DATA_TYPE_LONGLONG: ptr = (LONGLONG *)(to->array) + i;
+        case GAL_DATA_TYPE_INT64:    ptr = (int64_t *)(to->array) + i;
           break;
-        case GAL_DATA_TYPE_FLOAT:    ptr = (float *)(to->array) + i;
+        case GAL_DATA_TYPE_FLOAT32:  ptr = (float *)(to->array) + i;
           break;
-        case GAL_DATA_TYPE_DOUBLE:   ptr = (double *)(to->array) + i;
+        case GAL_DATA_TYPE_FLOAT64:  ptr = (double *)(to->array) + i;
           break;
 
         case GAL_DATA_TYPE_BIT:
         case GAL_DATA_TYPE_STRLL:
-        case GAL_DATA_TYPE_COMPLEX:
-        case GAL_DATA_TYPE_DCOMPLEX:
+        case GAL_DATA_TYPE_COMPLEX32:
+        case GAL_DATA_TYPE_COMPLEX64:
           error(EXIT_FAILURE, 0, "`data_copy_from_string' currently doesn't "
                 "support copying to %s type",
                 gal_data_type_as_string(to->type, 1));
@@ -1976,6 +1529,28 @@ data_copy_from_string(gal_data_t *from, gal_data_t *to)
 
 
 
+/* Macros for copying to a string. */
+#define COPY_TO_STR_INT(CTYPE, BLANK, FMT) {                            \
+    CTYPE *a=from->array;                                               \
+    for(i=0;i<from->size;++i)                                           \
+      {                                                                 \
+        if(a[i]!=BLANK) asprintf(&strarr[i], FMT, a[i]);                \
+        else                                                            \
+          gal_checkset_allocate_copy(GAL_DATA_BLANK_STRING, &strarr[i]); \
+      }                                                                 \
+  }
+
+#define COPY_TO_STR_FLT(CTYPE, BLANK) {                                 \
+    CTYPE *a=from->array;                                               \
+    for(i=0;i<from->size;++i)                                           \
+      {                                                                 \
+        if(isnan(BLANK)) isblank = isnan(a[i]) ? 1 : 0;                 \
+        else             isblank = a[i]==BLANK ? 1 : 0;                 \
+        if(isblank==0) asprintf(&strarr[i], "%f", a[i]);                \
+        else gal_checkset_allocate_copy(GAL_DATA_BLANK_STRING, &strarr[i]); \
+      }                                                                 \
+  }
+
 /* Convert any given type into a string by printing it into the elements of
    the already allocated `to->array'. */
 static void
@@ -1985,18 +1560,6 @@ data_copy_to_string(gal_data_t *from, gal_data_t *to)
   int isblank;
   char **strarr=to->array, **instrarr=from->array;
 
-  unsigned char  *uc=from->array;
-  char            *c=from->array;
-  unsigned short *us=from->array;
-  short           *s=from->array;
-  unsigned int   *ui=from->array;
-  int            *ii=from->array;
-  unsigned long  *ul=from->array;
-  long            *l=from->array;
-  LONGLONG        *L=from->array;
-  float           *f=from->array;
-  double          *d=from->array;
-
   /* Sanity check */
   if(to->type!=GAL_DATA_TYPE_STRING)
     error(EXIT_FAILURE, 0, "`to' in `data_copy_to_string' must have a "
@@ -2005,79 +1568,35 @@ data_copy_to_string(gal_data_t *from, gal_data_t *to)
   /* Do the copying */
   switch(from->type)
     {
-    case GAL_DATA_TYPE_UCHAR:
-      for(i=0;i<from->size;++i)
-        {if(uc[i]!=GAL_DATA_BLANK_UCHAR) asprintf(&strarr[i], "%u", uc[i]);
-         else gal_checkset_allocate_copy(GAL_DATA_BLANK_STRING, &strarr[i]);}
-      break;
+    case GAL_DATA_TYPE_UINT8:
+      COPY_TO_STR_INT(uint8_t,  GAL_DATA_BLANK_UINT8, "%u");    break;
 
-    case GAL_DATA_TYPE_CHAR:
-      for(i=0;i<from->size;++i)
-        {if(c[i]!=GAL_DATA_BLANK_CHAR) asprintf(&strarr[i], "%d", c[i]);
-         else gal_checkset_allocate_copy(GAL_DATA_BLANK_STRING, &strarr[i]);}
-      break;
+    case GAL_DATA_TYPE_INT8:
+      COPY_TO_STR_INT(int8_t,   GAL_DATA_BLANK_INT8, "%d");     break;
 
-    case GAL_DATA_TYPE_USHORT:
-      for(i=0;i<from->size;++i)
-        {if(us[i]!=GAL_DATA_BLANK_USHORT) asprintf(&strarr[i], "%u", us[i]);
-         else gal_checkset_allocate_copy(GAL_DATA_BLANK_STRING, &strarr[i]);}
-      break;
+    case GAL_DATA_TYPE_UINT16:
+      COPY_TO_STR_INT(uint16_t, GAL_DATA_BLANK_UINT16, "%u");   break;
 
-    case GAL_DATA_TYPE_SHORT:
-      for(i=0;i<from->size;++i)
-        {if(s[i]!=GAL_DATA_BLANK_SHORT) asprintf(&strarr[i], "%d", s[i]);
-         else gal_checkset_allocate_copy(GAL_DATA_BLANK_STRING, &strarr[i]);}
-      break;
+    case GAL_DATA_TYPE_INT16:
+      COPY_TO_STR_INT(int16_t,  GAL_DATA_BLANK_INT16, "%d");    break;
 
-    case GAL_DATA_TYPE_UINT:
-      for(i=0;i<from->size;++i)
-        {if(ui[i]!=GAL_DATA_BLANK_UINT) asprintf(&strarr[i], "%u", ui[i]);
-         else gal_checkset_allocate_copy(GAL_DATA_BLANK_STRING, &strarr[i]);}
-      break;
+    case GAL_DATA_TYPE_UINT32:
+      COPY_TO_STR_INT(uint32_t, GAL_DATA_BLANK_UINT32, "%u");   break;
 
-    case GAL_DATA_TYPE_INT:
-      for(i=0;i<from->size;++i)
-        {if(ii[i]!=GAL_DATA_BLANK_INT) asprintf(&strarr[i], "%d", ii[i]);
-         else gal_checkset_allocate_copy(GAL_DATA_BLANK_STRING, &strarr[i]);}
-      break;
+    case GAL_DATA_TYPE_INT32:
+      COPY_TO_STR_INT(int32_t,  GAL_DATA_BLANK_INT32, "%d");    break;
 
-    case GAL_DATA_TYPE_ULONG:
-      for(i=0;i<from->size;++i)
-        {if(ul[i]!=GAL_DATA_BLANK_ULONG) asprintf(&strarr[i], "%lu", ul[i]);
-         else gal_checkset_allocate_copy(GAL_DATA_BLANK_STRING, &strarr[i]);}
-      break;
+    case GAL_DATA_TYPE_UINT64:
+      COPY_TO_STR_INT(uint64_t, GAL_DATA_BLANK_UINT64, "%lu");  break;
 
-    case GAL_DATA_TYPE_LONG:
-      for(i=0;i<from->size;++i)
-        {if(l[i]!=GAL_DATA_BLANK_LONG) asprintf(&strarr[i], "%ld", l[i]);
-         else gal_checkset_allocate_copy(GAL_DATA_BLANK_STRING, &strarr[i]);}
-      break;
+    case GAL_DATA_TYPE_INT64:
+      COPY_TO_STR_INT(int64_t,  GAL_DATA_BLANK_INT64, "%ld");   break;
 
-    case GAL_DATA_TYPE_LONGLONG:
-      for(i=0;i<from->size;++i)
-        {if(L[i]!=GAL_DATA_BLANK_LONGLONG) asprintf(&strarr[i], "%lld", L[i]);
-         else gal_checkset_allocate_copy(GAL_DATA_BLANK_STRING, &strarr[i]);}
-      break;
-
-    case GAL_DATA_TYPE_FLOAT:
-      for(i=0;i<from->size;++i)
-        {
-          if(isnan(GAL_DATA_BLANK_FLOAT)) isblank = isnan(f[i]) ? 1 : 0;
-          else isblank = GAL_DATA_BLANK_FLOAT==f[i] ? 1 : 0;
-          if(isblank==0) asprintf(&strarr[i], "%f", f[i]);
-          else gal_checkset_allocate_copy(GAL_DATA_BLANK_STRING, &strarr[i]);
-        }
-      break;
+    case GAL_DATA_TYPE_FLOAT32:
+      COPY_TO_STR_FLT(float, GAL_DATA_BLANK_FLOAT32);           break;
 
-    case GAL_DATA_TYPE_DOUBLE:
-      for(i=0;i<from->size;++i)
-        {
-          if(isnan(GAL_DATA_BLANK_FLOAT)) isblank = isnan(d[i]) ? 1 : 0;
-          else isblank = GAL_DATA_BLANK_FLOAT==d[i] ? 1 : 0;
-          if(isblank==0) asprintf(&strarr[i], "%f", d[i]);
-          else gal_checkset_allocate_copy(GAL_DATA_BLANK_STRING, &strarr[i]);
-        }
-      break;
+    case GAL_DATA_TYPE_FLOAT64:
+      COPY_TO_STR_FLT(double, GAL_DATA_BLANK_FLOAT32);          break;
 
     case GAL_DATA_TYPE_STRING:
       for(i=0;i<from->size;++i)
@@ -2086,8 +1605,8 @@ data_copy_to_string(gal_data_t *from, gal_data_t *to)
 
     case GAL_DATA_TYPE_BIT:
     case GAL_DATA_TYPE_STRLL:
-    case GAL_DATA_TYPE_COMPLEX:
-    case GAL_DATA_TYPE_DCOMPLEX:
+    case GAL_DATA_TYPE_COMPLEX32:
+    case GAL_DATA_TYPE_COMPLEX64:
       error(EXIT_FAILURE, 0, "`data_copy_to_string' currently doesn't "
             "support copying to %s type",
             gal_data_type_as_string(from->type, 1));
@@ -2172,47 +1691,43 @@ data_copy_to_string(gal_data_t *from, gal_data_t *to)
 #define COPY_OTYPE_SET(otype)                                           \
   switch(in->type)                                                      \
     {                                                                   \
-    case GAL_DATA_TYPE_UCHAR:                                           \
-      COPY_OTYPE_ITYPE_SET_INT(otype, unsigned char);                   \
+    case GAL_DATA_TYPE_UINT8:                                           \
+      COPY_OTYPE_ITYPE_SET_INT(otype, uint8_t);                         \
       break;                                                            \
                                                                         \
-    case GAL_DATA_TYPE_CHAR:                                            \
-      COPY_OTYPE_ITYPE_SET_INT(otype, char);                            \
+    case GAL_DATA_TYPE_INT8:                                            \
+      COPY_OTYPE_ITYPE_SET_INT(otype, int8_t);                          \
       break;                                                            \
                                                                         \
-    case GAL_DATA_TYPE_USHORT:                                          \
-      COPY_OTYPE_ITYPE_SET_INT(otype, unsigned short);                  \
+    case GAL_DATA_TYPE_UINT16:                                          \
+      COPY_OTYPE_ITYPE_SET_INT(otype, uint16_t);                        \
       break;                                                            \
                                                                         \
-    case GAL_DATA_TYPE_SHORT:                                           \
-      COPY_OTYPE_ITYPE_SET_INT(otype, short);                           \
+    case GAL_DATA_TYPE_INT16:                                           \
+      COPY_OTYPE_ITYPE_SET_INT(otype, int16_t);                         \
       break;                                                            \
                                                                         \
-    case GAL_DATA_TYPE_UINT:                                            \
-      COPY_OTYPE_ITYPE_SET_INT(otype, unsigned int);                    \
+    case GAL_DATA_TYPE_UINT32:                                          \
+      COPY_OTYPE_ITYPE_SET_INT(otype, uint32_t);                        \
       break;                                                            \
                                                                         \
-    case GAL_DATA_TYPE_INT:                                             \
-      COPY_OTYPE_ITYPE_SET_INT(otype, int);                             \
+    case GAL_DATA_TYPE_INT32:                                           \
+      COPY_OTYPE_ITYPE_SET_INT(otype, int32_t);                         \
       break;                                                            \
                                                                         \
-    case GAL_DATA_TYPE_ULONG:                                           \
-      COPY_OTYPE_ITYPE_SET_INT(otype, unsigned long);                   \
+    case GAL_DATA_TYPE_UINT64:                                          \
+      COPY_OTYPE_ITYPE_SET_INT(otype, uint64_t);                        \
       break;                                                            \
                                                                         \
-    case GAL_DATA_TYPE_LONG:                                            \
-      COPY_OTYPE_ITYPE_SET_INT(otype, long);                            \
+    case GAL_DATA_TYPE_INT64:                                           \
+      COPY_OTYPE_ITYPE_SET_INT(otype, int64_t);                         \
       break;                                                            \
                                                                         \
-    case GAL_DATA_TYPE_LONGLONG:                                        \
-      COPY_OTYPE_ITYPE_SET_INT(otype, LONGLONG);                        \
-      break;                                                            \
-                                                                        \
-    case GAL_DATA_TYPE_FLOAT:                                           \
+    case GAL_DATA_TYPE_FLOAT32:                                         \
       COPY_OTYPE_ITYPE_SET_FLT(otype, float);                           \
       break;                                                            \
                                                                         \
-    case GAL_DATA_TYPE_DOUBLE:                                          \
+    case GAL_DATA_TYPE_FLOAT64:                                         \
       COPY_OTYPE_ITYPE_SET_FLT(otype, double);                          \
       break;                                                            \
                                                                         \
@@ -2222,8 +1737,8 @@ data_copy_to_string(gal_data_t *from, gal_data_t *to)
                                                                         \
     case GAL_DATA_TYPE_BIT:                                             \
     case GAL_DATA_TYPE_STRLL:                                           \
-    case GAL_DATA_TYPE_COMPLEX:                                         \
-    case GAL_DATA_TYPE_DCOMPLEX:                                        \
+    case GAL_DATA_TYPE_COMPLEX32:                                       \
+    case GAL_DATA_TYPE_COMPLEX64:                                       \
       error(EXIT_FAILURE, 0, "`gal_data_copy_to_new_type' currently "   \
             "doesn't support copying from %s type to a numeric (real) " \
             "type", gal_data_type_as_string(in->type, 1));              \
@@ -2257,58 +1772,22 @@ gal_data_copy_to_new_type(gal_data_t *in, int newtype)
   /* Fill in the output array: */
   switch(newtype)
     {
-    case GAL_DATA_TYPE_UCHAR:
-      COPY_OTYPE_SET(unsigned char);
-      break;
-
-    case GAL_DATA_TYPE_CHAR:
-      COPY_OTYPE_SET(char);
-      break;
-
-    case GAL_DATA_TYPE_USHORT:
-      COPY_OTYPE_SET(unsigned short);
-      break;
-
-    case GAL_DATA_TYPE_SHORT:
-      COPY_OTYPE_SET(short);
-      break;
-
-    case GAL_DATA_TYPE_UINT:
-      COPY_OTYPE_SET(unsigned int);
-      break;
-
-    case GAL_DATA_TYPE_INT:
-      COPY_OTYPE_SET(int);
-      break;
-
-    case GAL_DATA_TYPE_ULONG:
-      COPY_OTYPE_SET(unsigned long);
-      break;
-
-    case GAL_DATA_TYPE_LONG:
-      COPY_OTYPE_SET(long);
-      break;
-
-    case GAL_DATA_TYPE_LONGLONG:
-      COPY_OTYPE_SET(LONGLONG);
-      break;
-
-    case GAL_DATA_TYPE_FLOAT:
-      COPY_OTYPE_SET(float);
-      break;
-
-    case GAL_DATA_TYPE_DOUBLE:
-      COPY_OTYPE_SET(double);
-      break;
-
-    case GAL_DATA_TYPE_STRING:
-      data_copy_to_string(in, out);
-      break;
+    case GAL_DATA_TYPE_UINT8:   COPY_OTYPE_SET(uint8_t);         break;
+    case GAL_DATA_TYPE_INT8:    COPY_OTYPE_SET(int8_t);          break;
+    case GAL_DATA_TYPE_UINT16:  COPY_OTYPE_SET(uint16_t);        break;
+    case GAL_DATA_TYPE_INT16:   COPY_OTYPE_SET(int16_t);         break;
+    case GAL_DATA_TYPE_UINT32:  COPY_OTYPE_SET(uint32_t);        break;
+    case GAL_DATA_TYPE_INT32:   COPY_OTYPE_SET(int32_t);         break;
+    case GAL_DATA_TYPE_UINT64:  COPY_OTYPE_SET(uint64_t);        break;
+    case GAL_DATA_TYPE_INT64:   COPY_OTYPE_SET(int64_t);         break;
+    case GAL_DATA_TYPE_FLOAT32: COPY_OTYPE_SET(float);           break;
+    case GAL_DATA_TYPE_FLOAT64: COPY_OTYPE_SET(double);          break;
+    case GAL_DATA_TYPE_STRING:  data_copy_to_string(in, out);    break;
 
     case GAL_DATA_TYPE_BIT:
     case GAL_DATA_TYPE_STRLL:
-    case GAL_DATA_TYPE_COMPLEX:
-    case GAL_DATA_TYPE_DCOMPLEX:
+    case GAL_DATA_TYPE_COMPLEX32:
+    case GAL_DATA_TYPE_COMPLEX64:
       error(EXIT_FAILURE, 0, "`gal_data_copy_to_new_type' currently doesn't "
             "support copying to %s type",
             gal_data_type_as_string(newtype, 1));
@@ -2411,6 +1890,8 @@ gal_data_to_same_type(gal_data_t *f,   gal_data_t *s,
 /*************************************************************
  **************              Write             ***************
  *************************************************************/
+#define WRITE_TO_STRING(CTYPE, FMT) asprintf(&str, FMT, *(CTYPE *)ptr);
+
 char *
 gal_data_write_to_string(void *ptr, int type, int quote_if_str_has_space)
 {
@@ -2431,49 +1912,16 @@ gal_data_write_to_string(void *ptr, int type, int 
quote_if_str_has_space)
         asprintf(&str, "%s", *(char **)ptr);
       break;
 
-    case GAL_DATA_TYPE_UCHAR:
-      asprintf(&str, "%u", *(unsigned char *)ptr);
-      break;
-
-    case GAL_DATA_TYPE_CHAR:
-      asprintf(&str, "%d", *(char *)ptr);
-      break;
-
-    case GAL_DATA_TYPE_USHORT:
-      asprintf(&str, "%u", *(unsigned short *)ptr);
-      break;
-
-    case GAL_DATA_TYPE_SHORT:
-      asprintf(&str, "%d", *(short *)ptr);
-      break;
-
-    case GAL_DATA_TYPE_UINT:
-      asprintf(&str, "%u", *(unsigned int *)ptr);
-      break;
-
-    case GAL_DATA_TYPE_INT:
-      asprintf(&str, "%d", *(int *)ptr);
-      break;
-
-    case GAL_DATA_TYPE_ULONG:
-      asprintf(&str, "%lu", *(unsigned long *)ptr);
-      break;
-
-    case GAL_DATA_TYPE_LONG:
-      asprintf(&str, "%ld", *(long *)ptr);
-      break;
-
-    case GAL_DATA_TYPE_LONGLONG:
-      asprintf(&str, "%lld", *(LONGLONG *)ptr);
-      break;
-
-    case GAL_DATA_TYPE_FLOAT:
-      asprintf(&str, "%.6f", *(float *)ptr);
-      break;
-
-    case GAL_DATA_TYPE_DOUBLE:
-      asprintf(&str, "%.10f", *(double *)ptr);
-      break;
+    case GAL_DATA_TYPE_UINT8:   WRITE_TO_STRING(uint8_t,   "%u");  break;
+    case GAL_DATA_TYPE_INT8:    WRITE_TO_STRING(int8_t,    "%d");  break;
+    case GAL_DATA_TYPE_UINT16:  WRITE_TO_STRING(uint16_t,  "%u");  break;
+    case GAL_DATA_TYPE_INT16:   WRITE_TO_STRING(int16_t,   "%d");  break;
+    case GAL_DATA_TYPE_UINT32:  WRITE_TO_STRING(uint32_t,  "%u");  break;
+    case GAL_DATA_TYPE_INT32:   WRITE_TO_STRING(int32_t,   "%d");  break;
+    case GAL_DATA_TYPE_UINT64:  WRITE_TO_STRING(uint64_t, "%lu");  break;
+    case GAL_DATA_TYPE_INT64:   WRITE_TO_STRING(int64_t,  "%ld");  break;
+    case GAL_DATA_TYPE_FLOAT32: WRITE_TO_STRING(float,   "%.6f");  break;
+    case GAL_DATA_TYPE_FLOAT64: WRITE_TO_STRING(double, "%.10f");  break;
 
     default:
       error(EXIT_FAILURE, 0, "type code %d not recognized in "
@@ -2515,20 +1963,12 @@ gal_data_string_to_number(char *string)
   char *tailptr, *cp;
   int type, forcedfloat=0;
 
-  /* Define the pointers. */
-  unsigned char     uc;
-  char               c;
-  unsigned short    us;
-  short              s;
-  unsigned int      ui;
-  int                i;
-  unsigned long     ul;
-  long               l;
-  LONGLONG           L;
-  float              f;
-  double             d;
-
-  /* First see if the number is a double. */
+  /* Define initial spaces to keep the value. */
+  uint8_t   u8;   int8_t   i8;      uint16_t u16;   int16_t i16;
+  uint32_t u32;   int32_t i32;      uint64_t u64;   int64_t i64;
+  float      f;   double    d;
+
+  /* First see if the number is a double (the most generic). */
   d=strtod(string, &tailptr);
   if(*tailptr=='f') { if(tailptr[1]=='\0') forcedfloat=1; else return NULL; }
   else if (*tailptr!='\0')  return NULL;
@@ -2541,19 +1981,17 @@ gal_data_string_to_number(char *string)
          types. */
       if( d < 0 )
         {
-          if     (d>CHAR_MIN)   {c=d; ptr=&c; type=GAL_DATA_TYPE_CHAR;}
-          else if(d>SHRT_MIN)   {s=d; ptr=&s; type=GAL_DATA_TYPE_SHORT;}
-          else if(d>INT_MIN)    {i=d; ptr=&i; type=GAL_DATA_TYPE_INT;}
-          else if(d>LONG_MIN)   {l=d; ptr=&l; type=GAL_DATA_TYPE_LONG;}
-          else                  {L=d; ptr=&L; type=GAL_DATA_TYPE_LONGLONG;}
+          if     (d>INT8_MIN)    {i8=d;  ptr=&i8;  type=GAL_DATA_TYPE_INT8;}
+          else if(d>INT16_MIN)   {i16=d; ptr=&i16; type=GAL_DATA_TYPE_INT16;}
+          else if(d>INT32_MIN)   {i32=d; ptr=&i32; type=GAL_DATA_TYPE_INT32;}
+          else                   {i64=d; ptr=&i64; type=GAL_DATA_TYPE_INT64;}
         }
       else
         {
-          if     (d<=UCHAR_MAX) {uc=d; ptr=&uc; type=GAL_DATA_TYPE_UCHAR;}
-          else if(d<=USHRT_MAX) {us=d; ptr=&us; type=GAL_DATA_TYPE_USHORT;}
-          else if(d<=UINT_MAX)  {ui=d; ptr=&ui; type=GAL_DATA_TYPE_UINT;}
-          else if(d<=ULONG_MAX) {ul=d; ptr=&ul; type=GAL_DATA_TYPE_ULONG;}
-          else                  {L=d;  ptr=&L;  type=GAL_DATA_TYPE_LONGLONG;}
+          if     (d<=UINT8_MAX)  {u8=d;  ptr=&u8;  type=GAL_DATA_TYPE_UINT8;}
+          else if(d<=UINT16_MAX) {u16=d; ptr=&u16; type=GAL_DATA_TYPE_UINT16;}
+          else if(d<=UINT32_MAX) {u32=d; ptr=&u32; type=GAL_DATA_TYPE_UINT32;}
+          else                   {u64=d; ptr=&u64; type=GAL_DATA_TYPE_UINT64;}
         }
     }
   else
@@ -2587,9 +2025,9 @@ gal_data_string_to_number(char *string)
       /* Calculate the number of decimal digits and decide if it the number
          should be a float or a double. */
       if( lnz-fnz < FLT_DIG || ( d<FLT_MAX && d>FLT_MIN ) )
-        { f=d; ptr=&f; type=GAL_DATA_TYPE_FLOAT; }
+        { f=d; ptr=&f; type=GAL_DATA_TYPE_FLOAT32; }
       else
-        {      ptr=&d; type=GAL_DATA_TYPE_DOUBLE; }
+        {      ptr=&d; type=GAL_DATA_TYPE_FLOAT64; }
     }
 
   /* Return the pointer to the data structure. */
@@ -2622,8 +2060,8 @@ gal_data_string_to_number(char *string)
 int
 gal_data_string_to_type(void **out, char *string, int type)
 {
+  long l;
   double d;
-  LONGLONG L;
   void *value;
   char *tailptr;
   int status=0, allocated=0;
@@ -2657,46 +2095,45 @@ gal_data_string_to_type(void **out, char *string, int 
type)
     /* Floating point: Read it as a double or long, then put it in the
        array. When the conversion can't be done (the string isn't a number
        for example), then just assume no blank value was given. */
-    case GAL_DATA_TYPE_FLOAT:
-    case GAL_DATA_TYPE_DOUBLE:
+    case GAL_DATA_TYPE_FLOAT32:
+    case GAL_DATA_TYPE_FLOAT64:
       d=strtod(string, &tailptr);
       if(*tailptr!='\0')
         status=1;
       else
         {
-          if(type==GAL_DATA_TYPE_FLOAT) *(float *) value=d;
-          else                          *(double *) value=d;
+          if(type==GAL_DATA_TYPE_FLOAT32) *(float *) value=d;
+          else                            *(double *) value=d;
         }
       break;
 
     /* Integers. */
     default:
-      L=strtoll(string, &tailptr, 0);
+      l=strtol(string, &tailptr, 0);
       if(*tailptr!='\0')
         status=1;
       else
         switch(type)
           {
           /* The signed values can easily be put in. */
-          case GAL_DATA_TYPE_CHAR:             *(char *) value = L; break;
-          case GAL_DATA_TYPE_SHORT:           *(short *) value = L; break;
-          case GAL_DATA_TYPE_INT:               *(int *) value = L; break;
-          case GAL_DATA_TYPE_LONG:             *(long *) value = L; break;
-          case GAL_DATA_TYPE_LONGLONG:     *(LONGLONG *) value = L; break;
+          case GAL_DATA_TYPE_INT8:         *(int8_t *)    value = l; break;
+          case GAL_DATA_TYPE_INT16:        *(int16_t *)   value = l; break;
+          case GAL_DATA_TYPE_INT32:        *(int32_t *)   value = l; break;
+          case GAL_DATA_TYPE_INT64:        *(int64_t *)   value = l; break;
 
           /* For the unsigned types, the value has to be positive, so if
              the input was negative, then just return a status of one and
              don't store the value. */
           default:
-            if(L<0)
+            if(l<0)
               status=1;
             else
               switch(type)
                 {
-                case GAL_DATA_TYPE_UCHAR:  *(unsigned char *)  value=L; break;
-                case GAL_DATA_TYPE_USHORT: *(unsigned short *) value=L; break;
-                case GAL_DATA_TYPE_UINT:   *(unsigned int *)   value=L; break;
-                case GAL_DATA_TYPE_ULONG:  *(unsigned long *)  value=L; break;
+                case GAL_DATA_TYPE_UINT8:  *(uint8_t *)   value=l; break;
+                case GAL_DATA_TYPE_UINT16: *(uint16_t *)  value=l; break;
+                case GAL_DATA_TYPE_UINT32: *(uint32_t *)  value=l; break;
+                case GAL_DATA_TYPE_UINT64: *(uint64_t *)  value=l; break;
                 default:
                   error(EXIT_FAILURE, 0, "type code %d not recognized in "
                         "`gal_data_string_to_type'", type);
diff --git a/lib/fits.c b/lib/fits.c
index 1b4ea9d..ed99382 100644
--- a/lib/fits.c
+++ b/lib/fits.c
@@ -198,24 +198,15 @@ gal_fits_bitpix_to_type(int bitpix)
 {
   switch(bitpix)
     {
-    case BYTE_IMG:
-      return GAL_DATA_TYPE_UCHAR;
-    case SBYTE_IMG:
-      return GAL_DATA_TYPE_CHAR;
-    case USHORT_IMG:
-      return GAL_DATA_TYPE_USHORT;
-    case SHORT_IMG:
-      return GAL_DATA_TYPE_SHORT;
-    case ULONG_IMG:
-      return GAL_DATA_TYPE_ULONG;
-    case LONG_IMG:
-      return GAL_DATA_TYPE_LONG;
-    case LONGLONG_IMG:
-      return GAL_DATA_TYPE_LONGLONG;
-    case FLOAT_IMG:
-      return GAL_DATA_TYPE_FLOAT;
-    case DOUBLE_IMG:
-      return GAL_DATA_TYPE_DOUBLE;
+    case BYTE_IMG:                  return GAL_DATA_TYPE_UINT8;
+    case SBYTE_IMG:                 return GAL_DATA_TYPE_INT8;
+    case USHORT_IMG:                return GAL_DATA_TYPE_UINT16;
+    case SHORT_IMG:                 return GAL_DATA_TYPE_INT16;
+    case ULONG_IMG:                 return GAL_DATA_TYPE_UINT32;
+    case LONG_IMG:                  return GAL_DATA_TYPE_INT32;
+    case LONGLONG_IMG:              return GAL_DATA_TYPE_INT64;
+    case FLOAT_IMG:                 return GAL_DATA_TYPE_FLOAT32;
+    case DOUBLE_IMG:                return GAL_DATA_TYPE_FLOAT64;
     default:
       error(EXIT_FAILURE, 0, "bitpix value of %d not recognized in "
             "gal_fits_bitpix_to_type", bitpix);
@@ -232,24 +223,25 @@ gal_fits_type_to_bitpix(int type)
 {
   switch(type)
     {
-    case GAL_DATA_TYPE_UCHAR:
-      return BYTE_IMG;
-    case GAL_DATA_TYPE_CHAR:
-      return SBYTE_IMG;
-    case GAL_DATA_TYPE_USHORT:
-      return USHORT_IMG;
-    case GAL_DATA_TYPE_SHORT:
-      return SHORT_IMG;
-    case GAL_DATA_TYPE_ULONG:
-      return ULONG_IMG;
-    case GAL_DATA_TYPE_LONG:
-      return LONG_IMG;
-    case GAL_DATA_TYPE_LONGLONG:
-      return LONGLONG_IMG;
-    case GAL_DATA_TYPE_FLOAT:
-      return FLOAT_IMG;
-    case GAL_DATA_TYPE_DOUBLE:
-      return DOUBLE_IMG;
+    case GAL_DATA_TYPE_UINT8:       return BYTE_IMG;
+    case GAL_DATA_TYPE_INT8:        return SBYTE_IMG;
+    case GAL_DATA_TYPE_UINT16:      return USHORT_IMG;
+    case GAL_DATA_TYPE_INT16:       return SHORT_IMG;
+    case GAL_DATA_TYPE_UINT32:      return ULONG_IMG;
+    case GAL_DATA_TYPE_INT32:       return LONG_IMG;
+    case GAL_DATA_TYPE_INT64:       return LONGLONG_IMG;
+    case GAL_DATA_TYPE_FLOAT32:     return FLOAT_IMG;
+    case GAL_DATA_TYPE_FLOAT64:     return DOUBLE_IMG;
+
+    case GAL_DATA_TYPE_BIT:
+    case GAL_DATA_TYPE_STRLL:
+    case GAL_DATA_TYPE_STRING:
+    case GAL_DATA_TYPE_UINT64:
+    case GAL_DATA_TYPE_COMPLEX32:
+    case GAL_DATA_TYPE_COMPLEX64:
+      error(EXIT_FAILURE, 0, "type %s not recognized for FITS image BITPIX",
+            gal_data_type_as_string(type, 1));
+
     default:
       error(EXIT_FAILURE, 0, "type value of %d not recognized in "
             "gal_fits_type_to_bitpix", type);
@@ -270,41 +262,28 @@ gal_fits_type_to_bin_tform(int type)
 {
   switch(type)
     {
-    case GAL_DATA_TYPE_STRING:
-      return 'A';
-
-    case GAL_DATA_TYPE_BIT:
-      return 'X';
-    case GAL_DATA_TYPE_UCHAR:
-      return 'B';
-    case GAL_DATA_TYPE_CHAR: case GAL_DATA_TYPE_LOGICAL:
-      return 'S';
-    case GAL_DATA_TYPE_USHORT:
-      return 'U';
-    case GAL_DATA_TYPE_SHORT:
-      return 'I';
-    case GAL_DATA_TYPE_UINT:
-      return 'V';
-    case GAL_DATA_TYPE_INT:
-      error(EXIT_FAILURE, 0, "CFITSIO doesn't support integer table "
-            "columns");
+    /* Recognized by CFITSIO. */
+    case GAL_DATA_TYPE_STRING:      return 'A';
+    case GAL_DATA_TYPE_BIT:         return 'X';
+    case GAL_DATA_TYPE_UINT8:       return 'B';
+    case GAL_DATA_TYPE_INT8:        return 'S';
+    case GAL_DATA_TYPE_UINT16:      return 'U';
+    case GAL_DATA_TYPE_INT16:       return 'I';
+    case GAL_DATA_TYPE_UINT32:      return 'V';
+    case GAL_DATA_TYPE_INT32:       return 'J';
+    case GAL_DATA_TYPE_INT64:       return 'K';
+    case GAL_DATA_TYPE_FLOAT32:     return 'E';
+    case GAL_DATA_TYPE_FLOAT64:     return 'D';
+    case GAL_DATA_TYPE_COMPLEX32:   return 'C';
+    case GAL_DATA_TYPE_COMPLEX64:   return 'M';
+
+    /* Not recognized by CFITSIO. */
+    case GAL_DATA_TYPE_UINT64:
+      error(EXIT_FAILURE, 0, "type %s not recognized for FITS binary "
+            "table TFORM", gal_data_type_as_string(type, 1));
       break;
-    case GAL_DATA_TYPE_ULONG:
-      error(EXIT_FAILURE, 0, "CFITSIO doesn't support unsigned long table "
-            "columns");
-      break;
-    case GAL_DATA_TYPE_LONG:
-      return 'J';
-    case GAL_DATA_TYPE_LONGLONG:
-      return 'K';
-    case GAL_DATA_TYPE_FLOAT:
-      return 'E';
-    case GAL_DATA_TYPE_DOUBLE:
-      return 'D';
-    case GAL_DATA_TYPE_COMPLEX:
-      return 'C';
-    case GAL_DATA_TYPE_DCOMPLEX:
-      return 'M';
+
+    /* Wrong type code. */
     default:
       error(EXIT_FAILURE, 0, "type code %d not recognized in "
             "`gal_fits_type_to_bin_tform'", type);
@@ -323,61 +302,76 @@ gal_fits_type_to_bin_tform(int type)
 int
 gal_fits_type_to_datatype(int type)
 {
+  int w=0;
+
   switch(type)
     {
-    case GAL_DATA_TYPE_BIT:
-      return TBIT;
-
-    case GAL_DATA_TYPE_UCHAR:
-      return TBYTE;
-
-    case GAL_DATA_TYPE_CHAR:
-      return TSBYTE;
-
-    case GAL_DATA_TYPE_STRING:
-      return TSTRING;
-
-    case GAL_DATA_TYPE_USHORT:
-      return TUSHORT;
-
-    case GAL_DATA_TYPE_SHORT:
-      return TSHORT;
-
-    case GAL_DATA_TYPE_UINT:
-      return TUINT;
-
-    case GAL_DATA_TYPE_INT:
-      return TINT;
-
-    case GAL_DATA_TYPE_ULONG:
-      return TULONG;
-
-    case GAL_DATA_TYPE_LONG:
-      return TLONG;
+    /* Recognized CFITSIO types. */
+    case GAL_DATA_TYPE_BIT:              return TBIT;
+    case GAL_DATA_TYPE_UINT8:            return TBYTE;
+    case GAL_DATA_TYPE_INT8:             return TSBYTE;
+    case GAL_DATA_TYPE_FLOAT32:          return TFLOAT;
+    case GAL_DATA_TYPE_FLOAT64:          return TDOUBLE;
+    case GAL_DATA_TYPE_COMPLEX32:        return TCOMPLEX;
+    case GAL_DATA_TYPE_COMPLEX64:        return TDBLCOMPLEX;
+    case GAL_DATA_TYPE_STRING:           return TSTRING;
+
+    /* Types that depend on the host system. The C standard says that the
+       `short', `int' and `long' types are ATLEAST 2, 2, 4 bytes, so be
+       safe, we will checking all of them for the 32-bit types.*/
+    case GAL_DATA_TYPE_UINT16:
+      w=2;
+      if     ( sizeof(short)    == w )   return TUSHORT;
+      else if( sizeof(int)      == w )   return TUINT;
+      break;
 
-    case GAL_DATA_TYPE_LONGLONG:
-      return TLONGLONG;
+    case GAL_DATA_TYPE_INT16:
+      w=2;
+      if     ( sizeof(short)    == w )   return TSHORT;
+      else if( sizeof(int)      == w )   return TINT;
+      break;
 
-    case GAL_DATA_TYPE_FLOAT:
-      return TFLOAT;
+    case GAL_DATA_TYPE_UINT32:
+      w=4;
+      if     ( sizeof(int)      == w )   return TUINT;
+      else if( sizeof(long)     == w )   return TULONG;
+      else if( sizeof(short)    == w )   return TUSHORT;
+      break;
 
-    case GAL_DATA_TYPE_DOUBLE:
-      return TDOUBLE;
+    case GAL_DATA_TYPE_INT32:
+      w=4;
+      if     ( sizeof(int)      == w )   return TINT;
+      else if( sizeof(long)     == w )   return TLONG;
+      else if( sizeof(short)    == w )   return TSHORT;
+      break;
 
-    case GAL_DATA_TYPE_COMPLEX:
-      return TCOMPLEX;
+    case GAL_DATA_TYPE_UINT64:
+      w=8;
+      if     ( sizeof(long)     == w )   return TULONG;
+      break;
 
-    case GAL_DATA_TYPE_DCOMPLEX:
-      return TDBLCOMPLEX;
+    case GAL_DATA_TYPE_INT64:
+      w=8;
+      if     ( sizeof(long)     == w )   return TLONG;
+      else if( sizeof(LONGLONG) == w )   return TLONGLONG;
+      break;
 
+    /* Wrong type. */
     default:
       error(EXIT_FAILURE, 0, "'%d' is not a recognized Gnuastro type. "
             "It was given to `gal_fits_type_to_datatype'.", type);
     }
 
-  error(EXIT_FAILURE, 0, "A bug! Please contact us so we can fix this. "
-        "For some reason, control has reached to the end of the "
-        "gal_fits_type_to_datatype function in fits.c.");
+  /* If control reaches, here, there was a problem with the host types. */
+  if(w)
+    error(EXIT_FAILURE, 0, "this system doesn't have a %d byte integer "
+          "type, so type `%s' cannot be written to FITS", w,
+          gal_data_type_as_string(type, 1));
+  else
+    error(EXIT_FAILURE, 0, "a bug! please contact us at %s so we can "
+          "fix theh problem. Control must not have reached the end of "
+          "`gal_fits_type_to_datatype', for the given type `%s'",
+          PACKAGE_BUGREPORT, gal_data_type_as_string(type, 1));
   return -1;
 }
 
@@ -386,55 +380,93 @@ gal_fits_type_to_datatype(int type)
 
 
 int
-gal_fits_datatype_to_type(int datatype)
+gal_fits_datatype_to_type(int datatype, int is_table_column)
 {
+  int inttype;
+
   switch(datatype)
     {
-    case TBIT:
-      return GAL_DATA_TYPE_BIT;
-
-    case TBYTE:
-      return GAL_DATA_TYPE_UCHAR;
-
-    case TSBYTE:
-      return GAL_DATA_TYPE_CHAR;
-
-    case TSTRING:
-      return GAL_DATA_TYPE_STRING;
-
+    case TBIT:            return GAL_DATA_TYPE_BIT;
+    case TBYTE:           return GAL_DATA_TYPE_UINT8;
+    case TSBYTE:          return GAL_DATA_TYPE_INT8;
+    case TFLOAT:          return GAL_DATA_TYPE_FLOAT32;
+    case TDOUBLE:         return GAL_DATA_TYPE_FLOAT64;
+    case TCOMPLEX:        return GAL_DATA_TYPE_COMPLEX32;
+    case TDBLCOMPLEX:     return GAL_DATA_TYPE_COMPLEX64;
+    case TSTRING:         return GAL_DATA_TYPE_STRING;
+
+    /* Sizes that depend on the host system. */
     case TUSHORT:
-      return GAL_DATA_TYPE_USHORT;
+      switch( sizeof(short) )
+        {
+        case 2:           return GAL_DATA_TYPE_UINT16; break;
+        case 4:           return GAL_DATA_TYPE_UINT32; break;
+        case 8:           return GAL_DATA_TYPE_UINT64; break;
+        }
+      break;
 
     case TSHORT:
-      return GAL_DATA_TYPE_SHORT;
+      switch( sizeof(short) )
+        {
+        case 2:           return GAL_DATA_TYPE_INT16;  break;
+        case 4:           return GAL_DATA_TYPE_INT32;  break;
+        case 8:           return GAL_DATA_TYPE_INT64;  break;
+        }
+      break;
 
     case TUINT:
-      return GAL_DATA_TYPE_UINT;
+      switch( sizeof(int) )
+        {
+        case 2:           return GAL_DATA_TYPE_UINT16; break;
+        case 4:           return GAL_DATA_TYPE_UINT32; break;
+        case 8:           return GAL_DATA_TYPE_UINT64; break;
+        }
+      break;
 
     case TINT:
-      return GAL_DATA_TYPE_INT;
+      switch( sizeof(int) )
+        {
+        case 2:           return GAL_DATA_TYPE_INT16;  break;
+        case 4:           return GAL_DATA_TYPE_INT32;  break;
+        case 8:           return GAL_DATA_TYPE_INT64;  break;
+        }
+      break;
 
     case TULONG:
-      return GAL_DATA_TYPE_ULONG;
+      switch( sizeof(long) )
+        {
+        case 4:           return GAL_DATA_TYPE_UINT32; break;
+        case 8:           return GAL_DATA_TYPE_UINT64; break;
+        }
+      break;
 
-    case TLONG:
-      return GAL_DATA_TYPE_LONG;
+    case TLONG: /* ==TINT32BIT when in a table column. */
+      if(is_table_column) return GAL_DATA_TYPE_INT32;
+      else
+        switch( sizeof(long) )
+          {
+          case 4:         return GAL_DATA_TYPE_INT32;  break;
+          case 8:         return GAL_DATA_TYPE_INT64;  break;
+          }
+      break;
 
     case TLONGLONG:
-      return GAL_DATA_TYPE_LONGLONG;
-
-    case TFLOAT:
-      return GAL_DATA_TYPE_FLOAT;
-
-    case TDOUBLE:
-      return GAL_DATA_TYPE_DOUBLE;
-
-    case TCOMPLEX:
-      return GAL_DATA_TYPE_COMPLEX;
+      return GAL_DATA_TYPE_INT64;
+      break;
 
-    case TDBLCOMPLEX:
-      return GAL_DATA_TYPE_DCOMPLEX;
+    /* The TLOGICAL depends on the context: for keywords, it is int32, for
+       table columns, it is int8. */
+    case TLOGICAL:
+      switch( sizeof(int) )
+        {
+        case 2: inttype=GAL_DATA_TYPE_INT16;  break;
+        case 4: inttype=GAL_DATA_TYPE_INT32;  break;
+        case 8: inttype=GAL_DATA_TYPE_INT64;  break;
+        }
+      return is_table_column ? GAL_DATA_TYPE_INT8 : inttype;
+      break;
 
+    /* A bug! */
     default:
       error(EXIT_FAILURE, 0, "'%d' is not a recognized CFITSIO datatype. "
             "It was given to `gal_fits_datatype_to_type'.", datatype);
@@ -442,7 +474,7 @@ gal_fits_datatype_to_type(int datatype)
 
   error(EXIT_FAILURE, 0, "A bug! Please contact us at %s so we can fix "
         "this. For some reason, control has reached to the end of the "
-        "gal_fits_datatype_to_type function in fits.c.", PACKAGE_BUGREPORT);
+        "`gal_fits_datatype_to_type' function in fits.c.", PACKAGE_BUGREPORT);
   return -1;
 }
 
@@ -865,7 +897,7 @@ gal_fits_key_write_filename(char *keynamebase, char 
*filename,
          length was copied. */
       if(value[maxlength-1]=='\0')
         {
-          gal_fits_key_add_to_ll_end(list, TSTRING, keyname, 1,
+          gal_fits_key_add_to_ll_end(list, GAL_DATA_TYPE_STRING, keyname, 1,
                                      value, 1, NULL, 0, NULL);
           break;
         }
@@ -972,6 +1004,7 @@ gal_fits_key_write(fitsfile *fptr, struct gal_fits_key_ll 
**keylist)
       free(tmp);
       tmp=ttmp;
     }
+
   *keylist=NULL;
 }
 
@@ -1098,10 +1131,10 @@ gal_fits_img_info(fitsfile *fptr, int *type, size_t 
*ndim, size_t **dsize)
 {
   size_t i;
   int bitpix, status=0, naxis;
-  long naxes[GAL_DATA_MAXDIM];
+  long naxes[GAL_FITS_MAX_NDIM];
 
   /* Get the BITPIX, number of dimensions and size of each dimension. */
-  if( fits_get_img_param(fptr, GAL_DATA_MAXDIM, &bitpix, &naxis,
+  if( fits_get_img_param(fptr, GAL_FITS_MAX_NDIM, &bitpix, &naxis,
                          naxes, &status) )
     gal_fits_io_error(status, NULL);
   *ndim=naxis;
@@ -1111,7 +1144,7 @@ gal_fits_img_info(fitsfile *fptr, int *type, size_t 
*ndim, size_t **dsize)
 
   /* Allocate the array to keep the dimension size and fill it in, note
      that its order is the opposite of naxes. */
-  *dsize=gal_data_malloc_array(GAL_DATA_TYPE_LONG, *ndim);
+  *dsize=gal_data_malloc_array(GAL_DATA_TYPE_INT64, *ndim);
   for(i=0; i<*ndim; ++i)
     (*dsize)[i]=naxes[*ndim-1-i];
 }
@@ -1153,7 +1186,7 @@ gal_fits_img_read(char *filename, char *hdu, size_t 
minmapsize)
 
 
   /* Set the fpixel array (first pixel in all dimensions): */
-  fpixel=gal_data_malloc_array(GAL_DATA_TYPE_LONG, ndim);
+  fpixel=gal_data_malloc_array(GAL_DATA_TYPE_INT64, ndim);
   for(i=0;i<ndim;++i) fpixel[i]=1;
 
 
@@ -1238,7 +1271,7 @@ gal_fits_img_read_kernel(char *filename, char *hdu, 
size_t minmapsize)
   float *f, *fp, tmp;
 
   /* Read the image as a float */
-  kernel=gal_fits_img_read_to_type(filename, hdu, GAL_DATA_TYPE_FLOAT,
+  kernel=gal_fits_img_read_to_type(filename, hdu, GAL_DATA_TYPE_FLOAT32,
                                    minmapsize);
 
   /* Check if the size along each dimension of the kernel is an odd
@@ -1295,7 +1328,7 @@ gal_fits_img_write_to_ptr(gal_data_t *data, char 
*filename)
   int nkeyrec, status=0, datatype=gal_fits_type_to_datatype(data->type);
 
   /* Fill the `naxes' array (in opposite order, and `long' type): */
-  naxes=gal_data_malloc_array(GAL_DATA_TYPE_LONG, data->ndim);
+  naxes=gal_data_malloc_array(GAL_DATA_TYPE_INT64, data->ndim);
   for(i=0;i<data->ndim;++i)
     naxes[data->ndim-1-i]=data->dsize[i];
 
@@ -1327,8 +1360,8 @@ gal_fits_img_write_to_ptr(gal_data_t *data, char 
*filename)
   if(gal_data_has_blank(data))
     switch(data->type)
       {
-      case GAL_DATA_TYPE_FLOAT:
-      case GAL_DATA_TYPE_DOUBLE:
+      case GAL_DATA_TYPE_FLOAT32:
+      case GAL_DATA_TYPE_FLOAT64:
         /* Do nothing! Since there are much fewer floating point types
            (that don't need any BLANK keyword), we are checking them.*/
         break;
@@ -1667,16 +1700,16 @@ fits_correct_bin_table_int_types(gal_data_t *allcols, 
int tfields,
       /* Correct the type based on the initial read type and the value to
          tzero. If tzero is any other value, then again, its not a type
          conversion, so just ignore it. */
-      if(allcols[i].type==GAL_DATA_TYPE_UCHAR && tzero[i]==SCHAR_MIN)
-        allcols[i].type = GAL_DATA_TYPE_CHAR;
+      if(allcols[i].type==GAL_DATA_TYPE_UINT8 && tzero[i]==INT8_MIN)
+        allcols[i].type = GAL_DATA_TYPE_INT8;
 
-      else if ( allcols[i].type==GAL_DATA_TYPE_SHORT
-                && tzero[i] == -(long long)SHRT_MIN )
-        allcols[i].type = GAL_DATA_TYPE_USHORT;
+      else if ( allcols[i].type==GAL_DATA_TYPE_INT16
+                && tzero[i] == -(long long)INT16_MIN )
+        allcols[i].type = GAL_DATA_TYPE_UINT16;
 
-      else if (allcols[i].type==GAL_DATA_TYPE_LONG
-               && tzero[i] ==  -(long long)INT_MIN)
-        allcols[i].type = GAL_DATA_TYPE_UINT;
+      else if (allcols[i].type==GAL_DATA_TYPE_INT32
+               && tzero[i] ==  -(long long)INT32_MIN)
+        allcols[i].type = GAL_DATA_TYPE_UINT32;
 
       /* For a check
       printf("Column %zu corrected type: %s\n", i+1,
@@ -1704,11 +1737,13 @@ gal_fits_tab_info(char *filename, char *hdu, size_t 
*numcols,
   int status=0, datatype, *tscal;
   char keyname[FLEN_KEYWORD]="XXXXXXXXXXXXX", value[FLEN_VALUE], *val;
 
+
   /* Open the FITS file and get the basic information. */
   fptr=gal_fits_hdu_open(filename, hdu, 1);
   *tabletype=gal_fits_tab_type(fptr);
   gal_fits_tab_size(fptr, numrows, numcols);
 
+
   /* Read the total number of fields, then allocate space for the data
      structure array and store the information within it. */
   fits_read_key(fptr, TINT, "TFIELDS", &tfields, NULL, &status);
@@ -1775,7 +1810,11 @@ gal_fits_tab_info(char *filename, char *hdu, size_t 
*numcols,
                 fits_binary_tform(val, &datatype, &repeat, NULL, &status);
 
               /* Write the type into the data structure. */
-              allcols[index].type=gal_fits_datatype_to_type(datatype);
+              allcols[index].type=gal_fits_datatype_to_type(datatype, 1);
+
+              printf("%zu: %s (%d)\n", index,
+                     gal_data_type_as_string(allcols[index].type, 1),
+                     datatype);
 
               /* If we are dealing with a string type, we need to know the
                  number of bytes in both cases for printing later. */
@@ -1914,8 +1953,8 @@ gal_fits_tab_read(char *filename, char *hdu, size_t 
numrows,
   size_t dsize;
   char **strarr;
   fitsfile *fptr;
-  int status=0, anynul;
   gal_data_t *out=NULL;
+  int status=0, anynul=0;
   struct gal_linkedlist_sll *ind;
 
   /* Open the FITS file */
@@ -1940,11 +1979,11 @@ gal_fits_tab_read(char *filename, char *hdu, size_t 
numrows,
           {
             strarr=out->array;
             errno=0;
-            strarr[i]=calloc(allcols[ind->v].disp_width, sizeof *strarr[i]);
+            strarr[i]=calloc(allcols[ind->v].disp_width+1, sizeof *strarr[i]);
             if(strarr[i]==NULL)
               error(EXIT_FAILURE, errno, "%zu bytes for strarr[%zu] in "
                     "`gal_fits_table_read'",
-                    allcols[ind->v].disp_width * sizeof *strarr[i], i);
+                    (allcols[ind->v].disp_width+1) * sizeof *strarr[i], i);
           }
 
       /* Allocate a blank value for the given type and read/store the
@@ -2033,20 +2072,19 @@ fits_table_prepare_arrays(gal_data_t *cols, size_t 
numcols, int tabletype,
             switch(col->type)
               {
               case GAL_DATA_TYPE_STRING:
-              case GAL_DATA_TYPE_UCHAR:
-              case GAL_DATA_TYPE_CHAR:
-              case GAL_DATA_TYPE_USHORT:
-              case GAL_DATA_TYPE_SHORT:
-              case GAL_DATA_TYPE_UINT:
-              case GAL_DATA_TYPE_INT:
-              case GAL_DATA_TYPE_ULONG:
-              case GAL_DATA_TYPE_LONG:
-              case GAL_DATA_TYPE_LONGLONG:
+              case GAL_DATA_TYPE_UINT8:
+              case GAL_DATA_TYPE_INT8:
+              case GAL_DATA_TYPE_UINT16:
+              case GAL_DATA_TYPE_INT16:
+              case GAL_DATA_TYPE_UINT32:
+              case GAL_DATA_TYPE_INT32:
+              case GAL_DATA_TYPE_UINT64:
+              case GAL_DATA_TYPE_INT64:
                 asprintf(&tform[i], "%c%d", fmt[0], col->disp_width);
                 break;
 
-              case GAL_DATA_TYPE_FLOAT:
-              case GAL_DATA_TYPE_DOUBLE:
+              case GAL_DATA_TYPE_FLOAT32:
+              case GAL_DATA_TYPE_FLOAT64:
                 asprintf(&tform[i], "%c%d.%d", fmt[0], col->disp_width,
                          col->disp_precision);
                 break;
@@ -2127,8 +2165,8 @@ fits_write_tnull_tcomm(fitsfile *fptr, gal_data_t *col, 
int tabletype,
       /* FITS binary tables don't accept NULL values for floating point or
          string columns. For floating point is must be NaN and for strings
          it is a blank string. */
-      if( col->type!=GAL_DATA_TYPE_FLOAT
-          && col->type!=GAL_DATA_TYPE_DOUBLE
+      if( col->type!=GAL_DATA_TYPE_FLOAT32
+          && col->type!=GAL_DATA_TYPE_FLOAT64
           && col->type!=GAL_DATA_TYPE_STRING )
         {
           blank=gal_data_alloc_blank(col->type);
diff --git a/lib/gnuastro/arithmetic.h b/lib/gnuastro/arithmetic.h
index 0f39bf3..ec2ab40 100644
--- a/lib/gnuastro/arithmetic.h
+++ b/lib/gnuastro/arithmetic.h
@@ -112,17 +112,16 @@ enum gal_arithmetic_operators
   GAL_ARITHMETIC_OP_AVERAGE,      /* Average per pixel of multiple arrays. */
   GAL_ARITHMETIC_OP_MEDIAN,       /* Median per pixel of multiple arrays.  */
 
-  GAL_ARITHMETIC_OP_TO_UCHAR,     /* Convert to unsigned char.             */
-  GAL_ARITHMETIC_OP_TO_CHAR,      /* Convert to char.                      */
-  GAL_ARITHMETIC_OP_TO_USHORT,    /* Convert to unsigned short.            */
-  GAL_ARITHMETIC_OP_TO_SHORT,     /* Convert to short.                     */
-  GAL_ARITHMETIC_OP_TO_UINT,      /* Convert to unsigned int.              */
-  GAL_ARITHMETIC_OP_TO_INT,       /* Convert to int.                       */
-  GAL_ARITHMETIC_OP_TO_ULONG,     /* Convert to unsigned long.             */
-  GAL_ARITHMETIC_OP_TO_LONG,      /* Convert to long.                      */
-  GAL_ARITHMETIC_OP_TO_LONGLONG,  /* Convert to LONGLONG.                  */
-  GAL_ARITHMETIC_OP_TO_FLOAT,     /* Convert to float.                     */
-  GAL_ARITHMETIC_OP_TO_DOUBLE,    /* Convert to double.                    */
+  GAL_ARITHMETIC_OP_TO_UINT8,     /* Convert to unsigned char.             */
+  GAL_ARITHMETIC_OP_TO_INT8,      /* Convert to char.                      */
+  GAL_ARITHMETIC_OP_TO_UINT16,    /* Convert to unsigned short.            */
+  GAL_ARITHMETIC_OP_TO_INT16,     /* Convert to short.                     */
+  GAL_ARITHMETIC_OP_TO_UINT32,    /* Convert to unsigned int.              */
+  GAL_ARITHMETIC_OP_TO_INT32,     /* Convert to int.                       */
+  GAL_ARITHMETIC_OP_TO_UINT64,    /* Convert to unsigned long.             */
+  GAL_ARITHMETIC_OP_TO_INT64,     /* Convert to long.                      */
+  GAL_ARITHMETIC_OP_TO_FLOAT32,   /* Convert to float.                     */
+  GAL_ARITHMETIC_OP_TO_FLOAT64,   /* Convert to double.                    */
 };
 
 
diff --git a/lib/gnuastro/data.h b/lib/gnuastro/data.h
index 2334b6a..e47b59a 100644
--- a/lib/gnuastro/data.h
+++ b/lib/gnuastro/data.h
@@ -29,7 +29,6 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <limits.h>
 #include <stdint.h>
 
-#include <fitsio.h>             /* Only for the LONGLONG type */
 #include <wcslib/wcs.h>
 #include <gsl/gsl_complex.h>
 
@@ -70,61 +69,46 @@ __BEGIN_C_DECLS  /* From C++ preparations */
 
 /* Macros: */
 
-/* The maximum dimensionality of datasets. */
-#define GAL_DATA_MAXDIM    999
-
 /* Blank values: Note that for the unsigned types or small types (like
    char), the maximum value is considered as a blank value, since the
    minimum value of an unsigned type is zero and zero is often meaningful
    in contexts were unsigned values are used. */
-#define GAL_DATA_BLANK_UCHAR      UCHAR_MAX
-#define GAL_DATA_BLANK_CHAR       SCHAR_MAX
-#define GAL_DATA_BLANK_LOGICAL    SCHAR_MAX
+#define GAL_DATA_BLANK_UINT8      UINT8_MAX
+#define GAL_DATA_BLANK_INT8       INT8_MIN
+#define GAL_DATA_BLANK_UINT16     UINT16_MAX
+#define GAL_DATA_BLANK_INT16      INT16_MIN
+#define GAL_DATA_BLANK_UINT32     UINT32_MAX
+#define GAL_DATA_BLANK_INT32      INT32_MIN
+#define GAL_DATA_BLANK_UINT64     UINT64_MAX
+#define GAL_DATA_BLANK_INT64      INT64_MIN
+#define GAL_DATA_BLANK_FLOAT32    NAN
+#define GAL_DATA_BLANK_FLOAT64    NAN
 #define GAL_DATA_BLANK_STRING     "n/a"
-#define GAL_DATA_BLANK_USHORT     USHRT_MAX
-#define GAL_DATA_BLANK_SHORT      INT16_MIN
-#define GAL_DATA_BLANK_UINT       UINT_MAX
-#define GAL_DATA_BLANK_INT        INT_MIN
-#define GAL_DATA_BLANK_ULONG      ULONG_MAX
-#define GAL_DATA_BLANK_LONG       INT32_MIN
-#define GAL_DATA_BLANK_LONGLONG   INT64_MIN
-#define GAL_DATA_BLANK_FLOAT      NAN
-#define GAL_DATA_BLANK_DOUBLE     NAN
-
 
 
 
 
-/* Macros to identify the type of data. The macros in the comment
-   parenthesis is the equivalent macro in CFITSIO.
 
-   IMPORTANT: the integer types must have a smaller value than the floating
-              point types.
-*/
+/* Macros to identify the type of data. */
 enum gal_data_types
 {
-  GAL_DATA_TYPE_INVALID,   /* Invalid (=0 by C standard).    */
-
-  GAL_DATA_TYPE_BIT,       /* Bit              (TBIT).        */
-  GAL_DATA_TYPE_UCHAR,     /* unsigned char    (TBYTE).       */
-  GAL_DATA_TYPE_CHAR,      /* char             (TSBYTE).      */
-  GAL_DATA_TYPE_LOGICAL,   /* char             (TLOGICAL).    */
-  GAL_DATA_TYPE_USHORT,    /* unsigned short   (TUSHORT).     */
-  GAL_DATA_TYPE_SHORT,     /* short            (TSHORT).      */
-  GAL_DATA_TYPE_UINT,      /* unsigned int     (TUINT).       */
-  GAL_DATA_TYPE_INT,       /* int              (TINT).        */
-  GAL_DATA_TYPE_ULONG,     /* unsigned long    (TLONG).       */
-  GAL_DATA_TYPE_LONG,      /* long             (TLONG).       */
-  GAL_DATA_TYPE_LONGLONG,  /* long long        (TLONGLONG).   */
-
-  GAL_DATA_TYPE_FLOAT,     /* float            (TFLOAT).      */
-  GAL_DATA_TYPE_DOUBLE,    /* double           (TDOUBLE).     */
-  GAL_DATA_TYPE_COMPLEX,   /* Complex float    (TCOMPLEX).    */
-  GAL_DATA_TYPE_DCOMPLEX,  /* Complex double   (TDBLCOMPLEX). */
-
-  GAL_DATA_TYPE_STRING,    /* string           (TSTRING).     */
-
-  GAL_DATA_TYPE_STRLL,     /* String linked list.             */
+  GAL_DATA_TYPE_INVALID,     /* Invalid (=0 by C standard).             */
+
+  GAL_DATA_TYPE_BIT,         /* 1 bit                                   */
+  GAL_DATA_TYPE_UINT8,       /* 8-bit  unsigned integer.                */
+  GAL_DATA_TYPE_INT8,        /* 8-bit  signed   integer.                */
+  GAL_DATA_TYPE_UINT16,      /* 16-bit unsigned integer.                */
+  GAL_DATA_TYPE_INT16,       /* 16-bit signed   integer.                */
+  GAL_DATA_TYPE_UINT32,      /* 32-bit unsigned integer.                */
+  GAL_DATA_TYPE_INT32,       /* 32-bit signed   integer.                */
+  GAL_DATA_TYPE_UINT64,      /* 64-bit unsigned integer.                */
+  GAL_DATA_TYPE_INT64,       /* 64-bit signed   integer.                */
+  GAL_DATA_TYPE_FLOAT32,     /* 32-bit single precision floating point. */
+  GAL_DATA_TYPE_FLOAT64,     /* 64-bit double precision floating point. */
+  GAL_DATA_TYPE_COMPLEX32,   /* Complex 32-bit floating point.          */
+  GAL_DATA_TYPE_COMPLEX64,   /* Complex 64-bit floating point.          */
+  GAL_DATA_TYPE_STRING,      /* String of characters.                   */
+  GAL_DATA_TYPE_STRLL,       /* Linked list of strings.                 */
 };
 
 /* `size_t' is 4 and 8 bytes on 32 and 64 bit systems respectively. In both
@@ -132,9 +116,9 @@ enum gal_data_types
    `./configure' the sizeof size_t was found and is stored in
    `GAL_CONFIG_SIZEOF_SIZE_T'. */
 #if GAL_CONFIG_SIZEOF_SIZE_T == 4
-#define GAL_DATA_TYPE_SIZE_T GAL_DATA_TYPE_UINT
+#define GAL_DATA_TYPE_SIZE_T GAL_DATA_TYPE_UINT32
 #else
-#define GAL_DATA_TYPE_SIZE_T GAL_DATA_TYPE_ULONG
+#define GAL_DATA_TYPE_SIZE_T GAL_DATA_TYPE_UINT64
 #endif
 
 
diff --git a/lib/gnuastro/fits.h b/lib/gnuastro/fits.h
index 7efb132..ba7efd8 100644
--- a/lib/gnuastro/fits.h
+++ b/lib/gnuastro/fits.h
@@ -67,6 +67,10 @@ __BEGIN_C_DECLS  /* From C++ preparations */
 
 
 
+/* Macros. */
+#define GAL_FITS_MAX_NDIM 999
+
+
 
 
 /* To create a linked list of headers. */
@@ -129,7 +133,7 @@ int
 gal_fits_type_to_datatype(int type);
 
 int
-gal_fits_datatype_to_type(int type);
+gal_fits_datatype_to_type(int datatype, int is_table_column);
 
 
 
diff --git a/lib/mesh.c b/lib/mesh.c
index 2fdf5b4..4bed78f 100644
--- a/lib/mesh.c
+++ b/lib/mesh.c
@@ -462,7 +462,7 @@ gal_mesh_value_file(struct gal_mesh_params *mp, char 
*filename,
      is `size'.*/
   data.ndim=2;
   data.dsize=dsize;
-  data.type=GAL_DATA_TYPE_FLOAT;
+  data.type=GAL_DATA_TYPE_FLOAT32;
 
   if(mp->meshbasedcheck)
     {
diff --git a/lib/options.c b/lib/options.c
index 9c036b1..051ed47 100644
--- a/lib/options.c
+++ b/lib/options.c
@@ -47,6 +47,36 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
+
+/**********************************************************************/
+/************                Declarations               ***************/
+/**********************************************************************/
+/* Declaration of `option_parse_file' that is defined below, since it is
+   also needed in `options_immediate', but it fits into context below
+   better. */
+static void
+options_parse_file(char *filename,  struct gal_options_common_params *cp,
+                   int enoent_abort);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 /**********************************************************************/
 /************             Option utilities              ***************/
 /**********************************************************************/
@@ -144,6 +174,26 @@ options_get_home()
 
 
 
+void
+gal_options_read_type(struct argp_option *option, char *arg,
+                      char *filename, size_t lineno)
+{
+  int type=gal_data_string_as_type(arg);
+  if(type==GAL_DATA_TYPE_INVALID)
+    error_at_line(EXIT_FAILURE, 0, filename, lineno, "`%s' (value to "
+                  "`%s' option) couldn't be recognized as a known type."
+                  "For the full list of known types, please run the "
+                  "following command:\n\n"
+                  "    $ info gnuastro \"Numeric data types\"\n",
+                  arg, option->name);
+  else
+    *(int *)(option->value)=type;
+}
+
+
+
+
+
 
 
 
@@ -248,17 +298,6 @@ options_print_citation_exit(struct 
gal_options_common_params *cp)
 
 
 
-/* Declaration of `option_parse_file' that is defined below, since it is
-   also needed in `options_immediate', but it fits into context below
-   better. */
-static void
-options_parse_file(char *filename,  struct gal_options_common_params *cp,
-                   int enoent_abort);
-
-
-
-
-
 /* Some options need immediate attention/action before continuing to read
    the rest of the options. In these cases we need to (maybe) check and
    (possibly) abort immediately. */
@@ -327,7 +366,7 @@ options_sanity_check(struct argp_option *option, char *arg,
 
     case GAL_OPTIONS_RANGE_GT_0:
       message="greater than zero";
-      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, 1, &dsize, NULL,
+      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, 1, &dsize, NULL,
                           0, -1, NULL, NULL, NULL);
       *(unsigned char *)(ref1->array)=0;
       operator1=GAL_ARITHMETIC_OP_GT;
@@ -337,7 +376,7 @@ options_sanity_check(struct argp_option *option, char *arg,
 
     case GAL_OPTIONS_RANGE_GE_0:
       message="greater or equal to zero";
-      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, 1, &dsize, NULL,
+      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, 1, &dsize, NULL,
                           0, -1, NULL, NULL, NULL);
       *(unsigned char *)(ref1->array)=0;
       operator1=GAL_ARITHMETIC_OP_GE;
@@ -347,9 +386,9 @@ options_sanity_check(struct argp_option *option, char *arg,
 
     case GAL_OPTIONS_RANGE_0_OR_1:
       message="either 0 or 1";
-      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, 1, &dsize, NULL,
+      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, 1, &dsize, NULL,
                           0, -1, NULL, NULL, NULL);
-      ref2=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, 1, &dsize, NULL,
+      ref2=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, 1, &dsize, NULL,
                           0, -1, NULL, NULL, NULL);
       *(unsigned char *)(ref1->array)=0;
       *(unsigned char *)(ref2->array)=1;
@@ -362,9 +401,9 @@ options_sanity_check(struct argp_option *option, char *arg,
 
     case GAL_OPTIONS_RANGE_GE_0_LE_1:
       message="between zero and one";
-      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, 1, &dsize, NULL,
+      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, 1, &dsize, NULL,
                           0, -1, NULL, NULL, NULL);
-      ref2=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, 1, &dsize, NULL,
+      ref2=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, 1, &dsize, NULL,
                           0, -1, NULL, NULL, NULL);
       *(unsigned char *)(ref1->array)=0;
       *(unsigned char *)(ref2->array)=1;
@@ -377,9 +416,9 @@ options_sanity_check(struct argp_option *option, char *arg,
 
     case GAL_OPTIONS_RANGE_GT_0_ODD:
       message="greater than zero and odd";
-      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, 1, &dsize, NULL,
+      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, 1, &dsize, NULL,
                           0, -1, NULL, NULL, NULL);
-      ref2=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, 1, &dsize, NULL,
+      ref2=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, 1, &dsize, NULL,
                           0, -1, NULL, NULL, NULL);
       *(unsigned char *)(ref1->array)=0;
       *(unsigned char *)(ref2->array)=2;
@@ -391,9 +430,9 @@ options_sanity_check(struct argp_option *option, char *arg,
 
     case GAL_OPTIONS_RANGE_0_OR_ODD:
       message="greater than, or equal to, zero and odd";
-      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, 1, &dsize, NULL,
+      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, 1, &dsize, NULL,
                           0, -1, NULL, NULL, NULL);
-      ref2=gal_data_alloc(NULL, GAL_DATA_TYPE_UCHAR, 1, &dsize, NULL,
+      ref2=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, 1, &dsize, NULL,
                           0, -1, NULL, NULL, NULL);
       *(unsigned char *)(ref1->array)=0;
       *(unsigned char *)(ref2->array)=2;
@@ -450,32 +489,38 @@ static void
 gal_options_read_check(struct argp_option *option, char *arg, char *filename,
                        size_t lineno)
 {
-  if(option->type==GAL_DATA_TYPE_STRLL)
-    gal_linkedlist_add_to_stll(option->value, arg, 1);
+  /* If a function is defined to process the value, then use it. */
+  if(option->func)
+    option->func(option, arg, filename, lineno);
   else
     {
-      /* Read the string argument into the value. */
-      if( gal_data_string_to_type(&option->value, arg, option->type) )
-        /* Fortunately `error_at_line' will behave like `error' when the
-           filename is NULL (the option was read from a command-line). */
-        error_at_line(EXIT_FAILURE, 0, filename, lineno,
-                      "`%s' (value to option `--%s') couldn't be read into "
-                      "the proper numerical type. Common causes for this "
-                      "error are:\n"
-                      "  - It contains non-numerical characters.\n"
-                      "  - It is negative, but the expected value is "
-                      "positive.\n"
-                      "  - It is floating point, but the expected value "
-                      "is an integer.\n"
-                      "  - The previous option required a value, but you "
-                      "forgot to give it one, so the next option's "
-                      "name(+value, if there are no spaces between them) "
-                      "is read as the value of the previous option.", arg,
-                      option->name);
-    }
+      if(option->type==GAL_DATA_TYPE_STRLL)
+        gal_linkedlist_add_to_stll(option->value, arg, 1);
+      else
+        {
+          /* Read the string argument into the value. */
+          if( gal_data_string_to_type(&option->value, arg, option->type) )
+            /* Fortunately `error_at_line' will behave like `error' when the
+               filename is NULL (the option was read from a command-line). */
+            error_at_line(EXIT_FAILURE, 0, filename, lineno,
+                          "`%s' (value to option `--%s') couldn't be read "
+                          "into the proper numerical type. Common causes "
+                          "for this error are:\n"
+                          "  - It contains non-numerical characters.\n"
+                          "  - It is negative, but the expected value is "
+                          "positive.\n"
+                          "  - It is floating point, but the expected value "
+                          "is an integer.\n"
+                          "  - The previous option required a value, but you "
+                          "forgot to give it one, so the next option's "
+                          "name(+value, if there are no spaces between them) "
+                          "is read as the value of the previous option.", arg,
+                          option->name);
+        }
 
-  /* Do a sanity check. */
-  options_sanity_check(option, arg, filename, lineno);
+      /* Do a sanity check. */
+      options_sanity_check(option, arg, filename, lineno);
+    }
 
 
   /* Flip the `set' flag to `GAL_OPTIONS_SET'. */
@@ -869,7 +914,7 @@ gal_options_parse_config_files(struct 
gal_options_common_params *cp)
 
   /* A small sanity check because in multiple places, we have assumed the
      on/off options have a type of `unsigned char'. */
-  if(GAL_OPTIONS_NO_ARG_TYPE != GAL_DATA_TYPE_UCHAR)
+  if(GAL_OPTIONS_NO_ARG_TYPE != GAL_DATA_TYPE_UINT8)
     error(EXIT_FAILURE, 0, "A bug! Please contact us at %s so we can fix the "
           "problem. The `GAL_OPTIONS_NO_ARG_TYPE' must have the "
           "`unsigned char' type. But",
diff --git a/lib/options.h b/lib/options.h
index db9f03f..3b376a2 100644
--- a/lib/options.h
+++ b/lib/options.h
@@ -38,7 +38,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 /* Type for options that don't accept an argument/value. This macro is
    defined to help make the definition and processing of these options
    easier and less buggy. Please use this macro for such options. */
-#define GAL_OPTIONS_NO_ARG_TYPE GAL_DATA_TYPE_UCHAR
+#define GAL_OPTIONS_NO_ARG_TYPE GAL_DATA_TYPE_UINT8
 
 
 
@@ -73,13 +73,14 @@ enum options_standard_groups
    is also removed.
 
    a b c d e f g i j k l m n p r s t u v w x y z
-   A B C E F G H J L M O Q R T W X Y Z
+   A B C E F G H J L M O Q R W X Y Z
 */
 enum options_common_keys
 {
   /* With short-option version */
   GAL_OPTIONS_KEY_HDU          = 'h',
   GAL_OPTIONS_KEY_OUTPUT       = 'o',
+  GAL_OPTIONS_KEY_TYPE         = 'T',
   GAL_OPTIONS_KEY_DONTDELETE   = 'D',
   GAL_OPTIONS_KEY_KEEPINPUTDIR = 'K',
   GAL_OPTIONS_KEY_QUIET        = 'q',
@@ -157,6 +158,7 @@ struct gal_options_common_params
 
   /* Output. */
   char                 *output; /* Directory containg output.            */
+  int                     type; /* Data type of output.                  */
   unsigned char     dontdelete; /* ==1: Don't delete existing file.      */
   unsigned char   keepinputdir; /* Keep input directory for auto output. */
   char         *tableformatstr; /* Format of output table (as a string). */
@@ -208,6 +210,10 @@ void
 gal_options_abort_if_mandatory_missing(struct gal_options_common_params *cp);
 
 void
+gal_options_read_type(struct argp_option *option, char *arg,
+                      char *filename, size_t lineno);
+
+void
 gal_options_free(struct argp_option *options);
 
 
diff --git a/lib/table.c b/lib/table.c
index c81fff8..79cad70 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -302,10 +302,10 @@ gal_table_col_print_info(gal_data_t *col, int 
tableformat, char *fmt,
 
 
 
-    case GAL_DATA_TYPE_UCHAR:
-    case GAL_DATA_TYPE_USHORT:
-    case GAL_DATA_TYPE_UINT:
-    case GAL_DATA_TYPE_ULONG:
+    case GAL_DATA_TYPE_UINT8:
+    case GAL_DATA_TYPE_UINT16:
+    case GAL_DATA_TYPE_UINT32:
+    case GAL_DATA_TYPE_UINT64:
 
       /* For the FITS ASCII table, there is only one format for all
          integers.  */
@@ -321,7 +321,7 @@ gal_table_col_print_info(gal_data_t *col, int tableformat, 
char *fmt,
           }
 
       /* If we have a long type, then make changes. */
-      if(col->type==GAL_DATA_TYPE_ULONG)
+      if(col->type==GAL_DATA_TYPE_UINT64)
         {
           lng[0]='l';
           width=( col->disp_width<=0 ? GAL_TABLE_DEF_LINT_WIDTH
@@ -336,10 +336,9 @@ gal_table_col_print_info(gal_data_t *col, int tableformat, 
char *fmt,
 
 
 
-    case GAL_DATA_TYPE_CHAR:
-    case GAL_DATA_TYPE_LOGICAL:
-    case GAL_DATA_TYPE_SHORT:
-    case GAL_DATA_TYPE_INT:
+    case GAL_DATA_TYPE_INT8:
+    case GAL_DATA_TYPE_INT16:
+    case GAL_DATA_TYPE_INT32:
       fmt[0] = tableformat==GAL_TABLE_FORMAT_TXT ? 'd' : 'I';
       width = ( col->disp_width<=0 ? GAL_TABLE_DEF_INT_WIDTH
                 : col->disp_width );
@@ -350,11 +349,9 @@ gal_table_col_print_info(gal_data_t *col, int tableformat, 
char *fmt,
 
 
 
-    case GAL_DATA_TYPE_LONG:
-    case GAL_DATA_TYPE_LONGLONG:
+    case GAL_DATA_TYPE_INT64:
       lng[0] = 'l';
       fmt[0] = tableformat==GAL_TABLE_FORMAT_TXT ? 'd' : 'I';
-      lng[1] = col->type==GAL_DATA_TYPE_LONGLONG ? 'l' : '\0';
       width=( col->disp_width<=0 ? GAL_TABLE_DEF_LINT_WIDTH
               : col->disp_width );
       precision=( col->disp_precision<=0 ? GAL_TABLE_DEF_INT_PRECISION
@@ -364,8 +361,8 @@ gal_table_col_print_info(gal_data_t *col, int tableformat, 
char *fmt,
 
 
     /* We need a default value (because in most cases, it won't be set. */
-    case GAL_DATA_TYPE_FLOAT:
-    case GAL_DATA_TYPE_DOUBLE:
+    case GAL_DATA_TYPE_FLOAT32:
+    case GAL_DATA_TYPE_FLOAT64:
       switch(col->disp_fmt)
         {
         case GAL_TABLE_DISPLAY_FMT_FLOAT:
@@ -378,7 +375,7 @@ gal_table_col_print_info(gal_data_t *col, int tableformat, 
char *fmt,
           fmt[0] = tableformat==GAL_TABLE_FORMAT_TXT ? 'g' : 'E'; break;
         }
       width = ( col->disp_width<=0
-                ? ( col->type==GAL_DATA_TYPE_FLOAT
+                ? ( col->type==GAL_DATA_TYPE_FLOAT32
                     ? GAL_TABLE_DEF_FLT_WIDTH
                     : GAL_TABLE_DEF_DBL_WIDTH )
                 : col->disp_width );
diff --git a/lib/txt.c b/lib/txt.c
index cb63681..8c93cb4 100644
--- a/lib/txt.c
+++ b/lib/txt.c
@@ -156,7 +156,7 @@ txt_info_from_comment(char *line, gal_data_t **datall, char 
*comm_start)
   gal_data_t *tmp;
   int index, strw=0;
   size_t len=strlen(comm_start);
-  int type=GAL_DATA_TYPE_DOUBLE;                     /* Default type. */
+  int type=GAL_DATA_TYPE_FLOAT64;                     /* Default type. */
   char *number=NULL, *name=NULL, *comment=NULL;
   char *inbrackets=NULL, *unit=NULL, *typestr=NULL, *blank=NULL;
 
@@ -362,7 +362,7 @@ txt_info_from_first_row(char *line, gal_data_t **datall, 
int format)
              information). */
           if( *datall==NULL || format==TXT_FORMAT_TABLE )
             {
-              gal_data_add_to_ll(datall, NULL, GAL_DATA_TYPE_DOUBLE, 0,
+              gal_data_add_to_ll(datall, NULL, GAL_DATA_TYPE_FLOAT64, 0,
                                  NULL, NULL, 0, -1, NULL, NULL, NULL);
               (*datall)->status=n;
             }
@@ -644,19 +644,18 @@ static void
 txt_read_token(gal_data_t *data, gal_data_t *info, char *token,
                size_t i, char *filename, size_t lineno, size_t colnum)
 {
-  char *tailptr;
-  char         **str=data->array, **strb;
-  unsigned char  *uc=data->array,   *ucb;
-  char            *c=data->array,    *cb;
-  unsigned short *us=data->array,   *usb;
-  short           *s=data->array,    *sb;
-  unsigned int   *ui=data->array,   *uib;
-  int            *ii=data->array,    *ib;
-  unsigned long  *ul=data->array,   *ulb;
-  long            *l=data->array,    *lb;
-  LONGLONG        *L=data->array,    *Lb;
-  float           *f=data->array,    *fb;
-  double          *d=data->array,    *db;
+  char   *tailptr;
+  char     **str = data->array, **strb;
+  uint8_t    *uc = data->array,   *ucb;
+  int8_t      *c = data->array,    *cb;
+  uint16_t   *us = data->array,   *usb;
+  int16_t     *s = data->array,    *sb;
+  uint32_t   *ui = data->array,   *uib;
+  int32_t    *ii = data->array,    *ib;
+  uint64_t   *ul = data->array,   *ulb;
+  int64_t     *l = data->array,    *lb;
+  float       *f = data->array,    *fb;
+  double      *d = data->array,    *db;
 
   /* Read the proper token into the column. */
   switch(data->type)
@@ -670,76 +669,70 @@ txt_read_token(gal_data_t *data, gal_data_t *info, char 
*token,
         }
       break;
 
-    case GAL_DATA_TYPE_UCHAR:
+    case GAL_DATA_TYPE_UINT8:
       uc[i]=strtol(token, &tailptr, 0);
       if( (ucb=info->array) && *ucb==uc[i] )
-        uc[i]=GAL_DATA_BLANK_UCHAR;
+        uc[i]=GAL_DATA_BLANK_UINT8;
       break;
 
-    case GAL_DATA_TYPE_CHAR:
+    case GAL_DATA_TYPE_INT8:
       c[i]=strtol(token, &tailptr, 0);
       if( (cb=info->array) && *cb==c[i] )
-        c[i]=GAL_DATA_BLANK_CHAR;
+        c[i]=GAL_DATA_BLANK_INT8;
       break;
 
-    case GAL_DATA_TYPE_USHORT:
+    case GAL_DATA_TYPE_UINT16:
       us[i]=strtol(token, &tailptr, 0);
       if( (usb=info->array) && *usb==us[i] )
-        us[i]=GAL_DATA_BLANK_USHORT;
+        us[i]=GAL_DATA_BLANK_UINT16;
       break;
 
-    case GAL_DATA_TYPE_SHORT:
+    case GAL_DATA_TYPE_INT16:
       s[i]=strtol(token, &tailptr, 0);
       if( (sb=info->array) && *sb==s[i] )
-        s[i]=GAL_DATA_BLANK_SHORT;
+        s[i]=GAL_DATA_BLANK_INT16;
       break;
 
-    case GAL_DATA_TYPE_UINT:
+    case GAL_DATA_TYPE_UINT32:
       ui[i]=strtol(token, &tailptr, 0);
       if( (uib=info->array) && *uib==ui[i] )
-        ui[i]=GAL_DATA_BLANK_UINT;
+        ui[i]=GAL_DATA_BLANK_UINT32;
       break;
 
-    case GAL_DATA_TYPE_INT:
+    case GAL_DATA_TYPE_INT32:
       ii[i]=strtol(token, &tailptr, 0);
       if( (ib=info->array) && *ib==ii[i] )
-        ii[i]=GAL_DATA_BLANK_INT;
+        ii[i]=GAL_DATA_BLANK_INT32;
       break;
 
-    case GAL_DATA_TYPE_ULONG:
+    case GAL_DATA_TYPE_UINT64:
       ul[i]=strtoul(token, &tailptr, 0);
       if( (ulb=info->array) && *ulb==ul[i] )
-        ul[i]=GAL_DATA_BLANK_ULONG;
+        ul[i]=GAL_DATA_BLANK_UINT64;
       break;
 
-    case GAL_DATA_TYPE_LONG:
+    case GAL_DATA_TYPE_INT64:
       l[i]=strtol(token, &tailptr, 0);
       if( (lb=info->array) && *lb==l[i] )
-        l[i]=GAL_DATA_BLANK_LONG;
-      break;
-
-    case GAL_DATA_TYPE_LONGLONG:
-      L[i]=strtoll(token, &tailptr, 0);
-      if( (Lb=info->array) && *Lb==L[i] )
-        L[i]=GAL_DATA_BLANK_LONGLONG;
+        l[i]=GAL_DATA_BLANK_INT64;
       break;
 
       /* For the blank value of floating point types, we need to make
          sure it isn't a NaN, because a NaN value will fail on any
          condition check (even `=='). If it isn't NaN, then we can
          compare the values. */
-    case GAL_DATA_TYPE_FLOAT:
+    case GAL_DATA_TYPE_FLOAT32:
       f[i]=strtod(token, &tailptr);
       if( (fb=info->array)
           && ( (isnan(*fb) && isnan(f[i])) || *fb==f[i] ) )
-        f[i]=GAL_DATA_BLANK_FLOAT;
+        f[i]=GAL_DATA_BLANK_FLOAT64;
       break;
 
-    case GAL_DATA_TYPE_DOUBLE:
+    case GAL_DATA_TYPE_FLOAT64:
       d[i]=strtod(token, &tailptr);
       if( (db=info->array)
           && ( (isnan(*db) && isnan(d[i])) || *db==d[i] ) )
-        d[i]=GAL_DATA_BLANK_DOUBLE;
+        d[i]=GAL_DATA_BLANK_FLOAT64;
       break;
 
     default:
@@ -1111,48 +1104,43 @@ txt_print_value(FILE *fp, void *array, int type, size_t 
ind, char *fmt)
   switch(type)
     {
       /* Numerical types. */
-    case GAL_DATA_TYPE_UCHAR:
-      fprintf(fp, fmt, ((unsigned char *)array)[ind]);
-      break;
-
-    case GAL_DATA_TYPE_CHAR:
-    case GAL_DATA_TYPE_LOGICAL:
-      fprintf(fp, fmt, ((char *)array)[ind]);
+    case GAL_DATA_TYPE_UINT8:
+      fprintf(fp, fmt, ((uint8_t *)array)[ind]);
       break;
 
-    case GAL_DATA_TYPE_USHORT:
-      fprintf(fp, fmt, ((unsigned short *)array)[ind]);
+    case GAL_DATA_TYPE_INT8:
+      fprintf(fp, fmt, ((int8_t *)array)[ind]);
       break;
 
-    case GAL_DATA_TYPE_SHORT:
-      fprintf(fp, fmt, ((short *)array)[ind]);
+    case GAL_DATA_TYPE_UINT16:
+      fprintf(fp, fmt, ((uint16_t *)array)[ind]);
       break;
 
-    case GAL_DATA_TYPE_UINT:
-      fprintf(fp, fmt, ((unsigned int *)array)[ind]);
+    case GAL_DATA_TYPE_INT16:
+      fprintf(fp, fmt, ((int16_t *)array)[ind]);
       break;
 
-    case GAL_DATA_TYPE_INT:
-      fprintf(fp, fmt, ((int *)array)[ind]);
+    case GAL_DATA_TYPE_UINT32:
+      fprintf(fp, fmt, ((uint32_t *)array)[ind]);
       break;
 
-    case GAL_DATA_TYPE_ULONG:
-      fprintf(fp, fmt, ((unsigned long *)array)[ind]);
+    case GAL_DATA_TYPE_INT32:
+      fprintf(fp, fmt, ((int32_t *)array)[ind]);
       break;
 
-    case GAL_DATA_TYPE_LONG:
-      fprintf(fp, fmt, ((long *)array)[ind]);
+    case GAL_DATA_TYPE_UINT64:
+      fprintf(fp, fmt, ((uint64_t *)array)[ind]);
       break;
 
-    case GAL_DATA_TYPE_LONGLONG:
-      fprintf(fp, fmt, ((LONGLONG *)array)[ind]);
+    case GAL_DATA_TYPE_INT64:
+      fprintf(fp, fmt, ((int64_t *)array)[ind]);
       break;
 
-    case GAL_DATA_TYPE_FLOAT:
+    case GAL_DATA_TYPE_FLOAT32:
       fprintf(fp, fmt, ((float *)array)[ind]);
       break;
 
-    case GAL_DATA_TYPE_DOUBLE:
+    case GAL_DATA_TYPE_FLOAT64:
       fprintf(fp, fmt, ((double *)array)[ind]);
       break;
 
diff --git a/lib/wcs.c b/lib/wcs.c
index cf8f615..8c6b816 100644
--- a/lib/wcs.c
+++ b/lib/wcs.c
@@ -460,12 +460,12 @@ gal_wcs_world_to_img(struct wcsprm *wcs, double *ra, 
double *dec,
   double *phi, *theta, *world, *pixcrd, *imgcrd;
 
   /* Allocate all the necessary arrays. */
-  stat=gal_data_calloc_array(GAL_DATA_TYPE_INT, size);
-  phi=gal_data_malloc_array(GAL_DATA_TYPE_DOUBLE, size);
-  theta=gal_data_malloc_array(GAL_DATA_TYPE_DOUBLE, size);
-  world=gal_data_malloc_array(GAL_DATA_TYPE_DOUBLE, 2*size);
-  imgcrd=gal_data_malloc_array(GAL_DATA_TYPE_DOUBLE, 2*size);
-  pixcrd=gal_data_malloc_array(GAL_DATA_TYPE_DOUBLE, 2*size);
+  stat=gal_data_calloc_array(GAL_DATA_TYPE_INT32, size);
+  phi=gal_data_malloc_array(GAL_DATA_TYPE_FLOAT64, size);
+  theta=gal_data_malloc_array(GAL_DATA_TYPE_FLOAT64, size);
+  world=gal_data_malloc_array(GAL_DATA_TYPE_FLOAT64, 2*size);
+  imgcrd=gal_data_malloc_array(GAL_DATA_TYPE_FLOAT64, 2*size);
+  pixcrd=gal_data_malloc_array(GAL_DATA_TYPE_FLOAT64, 2*size);
 
   /* Put in the values. */
   for(i=0;i<size;++i) { world[i*2]=ra[i]; world[i*2+1]=dec[i]; }
@@ -484,8 +484,8 @@ gal_wcs_world_to_img(struct wcsprm *wcs, double *ra, double 
*dec,
   */
 
   /* Allocate the output arrays if they were not already allocated. */
-  if(*x==NULL) *x=gal_data_calloc_array(GAL_DATA_TYPE_DOUBLE, size);
-  if(*y==NULL) *y=gal_data_calloc_array(GAL_DATA_TYPE_DOUBLE, size);
+  if(*x==NULL) *x=gal_data_calloc_array(GAL_DATA_TYPE_FLOAT64, size);
+  if(*y==NULL) *y=gal_data_calloc_array(GAL_DATA_TYPE_FLOAT64, size);
 
   /* Put the values into the output arrays. */
   for(i=0;i<size;++i)
diff --git a/tests/imgcrop/cat.txt b/tests/imgcrop/cat.txt
index 652ebab..d791342 100644
--- a/tests/imgcrop/cat.txt
+++ b/tests/imgcrop/cat.txt
@@ -1,7 +1,7 @@
 # Column 1: NAME       [name,str4]  Name of object.
-# Column 2: X_CENTER   [pixels,d]   Image X axis position.
-# Column 3: Y_CENTER   [pixels,d]   Image Y axis position.
-# Column 4: RA_CENTER  [deg,d]      Right Ascension.
-# Column 5: DEC_CENTER [deg,d]      Declination.
+# Column 2: X_CENTER   [pixels,f64] Image X axis position.
+# Column 3: Y_CENTER   [pixels,f64] Image Y axis position.
+# Column 4: RA_CENTER  [deg,f64]    Right Ascension.
+# Column 5: DEC_CENTER [deg,f64]    Declination.
 A0B1  500.00  500.00   0.99917157   1.0008283
 c2d3  251.00  251.00   0.99958658   1.0004150
diff --git a/tests/imgcrop/imgcat.sh b/tests/imgcrop/imgcat.sh
index 9b6db5e..fa28d77 100755
--- a/tests/imgcrop/imgcat.sh
+++ b/tests/imgcrop/imgcat.sh
@@ -53,5 +53,5 @@ if [ ! -f $execname ] || [ ! -f $img ]; then exit 77; fi
 # enable multithreaded access to files, the tests pass. It is the
 # users choice to enable this feature.
 cat=$topsrc/tests/$prog/cat.txt
-$execname $img --catalog=$cat --mode=img --suffix=_imgcat.fits    \
+$execname $img --catalog=$cat --mode=img --suffix=_imgcat.fits --numthreads=1 \
           --zeroisnotblank --xcol=X_CENTER --ycol=Y_CENTER --namecol=NAME
diff --git a/tests/mkprof/mkprofcat1.txt b/tests/mkprof/mkprofcat1.txt
index 92cdfa6..bf82212 100644
--- a/tests/mkprof/mkprofcat1.txt
+++ b/tests/mkprof/mkprofcat1.txt
@@ -1,13 +1,13 @@
-# Column 1:  ID                [count, uc]  Object ID
-# Column 2:  X                 [pixel, d]   X axis position of profile center
-# Column 3:  Y                 [pixel, d]   Y axis position of profile center
-# Column 4:  Function          [name, str7] Profile's radial function
-# Column 5:  Width             [pixel, d]   For Sersic: effective radius, for 
Moffat, FWHM
-# Column 6:  Sersic index      [none, d]    Sersic index, or Moffat beta
-# Column 7:  Position angle    [deg, d]     Position angle of profile
-# Column 8:  Axis ratio        [frac, d]    Axis ratio of profile
-# Column 9:  Magnitude         [ABmag, d]   Magnitude of profile within 
truncation radius
-# Column 10: Truncation radius [dist, d]    Truncation radius to stop building 
profile
+# Column 1:  ID                [count, u8]   Object ID
+# Column 2:  X                 [pixel, f64]  X axis position of profile center
+# Column 3:  Y                 [pixel, f64]  Y axis position of profile center
+# Column 4:  Function          [name, str7]  Profile's radial function
+# Column 5:  Width             [pixel, f64]  For Sersic: effective radius, for 
Moffat, FWHM
+# Column 6:  Sersic index      [none, f64]   Sersic index, or Moffat beta
+# Column 7:  Position angle    [deg, f64]    Position angle of profile
+# Column 8:  Axis ratio        [frac, f64]   Axis ratio of profile
+# Column 9:  Magnitude         [ABmag, f64]  Magnitude of profile within 
truncation radius
+# Column 10: Truncation radius [dist, f64]   Truncation radius to stop 
building profile
 1     0.0000     0.0000     moffat     3.000     4.765      0.0000     1.000   
   0.000     5.000
 2     100.40     100.40     sersic     20.00     2.500      45.000     1.000   
   -18.0     5.000
 3     50.321     50.827     sersic     5.978     1.320      77.650     0.801   
   -15.0     5.000
diff --git a/tests/mkprof/mkprofcat2.txt b/tests/mkprof/mkprofcat2.txt
index aac3cff..16e3da1 100644
--- a/tests/mkprof/mkprofcat2.txt
+++ b/tests/mkprof/mkprofcat2.txt
@@ -1,11 +1,11 @@
-# Column 1:  ID                [count, uc]  Object ID
-# Column 2:  X                 [pixel, d]   X axis position of profile center
-# Column 3:  Y                 [pixel, d]   Y axis position of profile center
-# Column 4:  Function          [code, i]    Profile's radial function code
-# Column 5:  Width             [pixel, d]   For Sersic: effective radius, for 
Moffat, FWHM
-# Column 6:  Sersic index      [none, d]    Sersic index, or Moffat beta
-# Column 7:  Position angle    [deg, d]     Position angle of profile
-# Column 8:  Axis ratio        [frac, d]    Axis ratio of profile
-# Column 9:  Magnitude         [ABmag, d]   Magnitude of profile within 
truncation radius
-# Column 10: Truncation radius [dist, d]    Truncation radius to stop building 
profile
+# Column 1:  ID                [count, u8]   Object ID
+# Column 2:  X                 [pixel, f64]  X axis position of profile center
+# Column 3:  Y                 [pixel, f64]  Y axis position of profile center
+# Column 4:  Function          [code, i32]   Profile's radial function code
+# Column 5:  Width             [pixel, f64]  For Sersic: effective radius, for 
Moffat, FWHM
+# Column 6:  Sersic index      [none, f64]   Sersic index, or Moffat beta
+# Column 7:  Position angle    [deg, f64]    Position angle of profile
+# Column 8:  Axis ratio        [frac, f64]   Axis ratio of profile
+# Column 9:  Magnitude         [ABmag, f64]  Magnitude of profile within 
truncation radius
+# Column 10: Truncation radius [dist, f64]   Truncation radius to stop 
building profile
 1     0.400    100.40     1     20.00     2.500      45.000     1.00       
-18.0     5.000
diff --git a/tests/mkprof/mkprofcat3.txt b/tests/mkprof/mkprofcat3.txt
index a6b05d6..6005f95 100644
--- a/tests/mkprof/mkprofcat3.txt
+++ b/tests/mkprof/mkprofcat3.txt
@@ -1,11 +1,11 @@
-# Column 1:  ID                [count, uc]  Object ID
-# Column 2:  X                 [pixel, d]   X axis position of profile center
-# Column 3:  Y                 [pixel, d]   Y axis position of profile center
-# Column 4:  Function          [code, i]    Profile's radial function code
-# Column 5:  Width             [pixel, d]   For Sersic: effective radius, for 
Moffat, FWHM
-# Column 6:  Sersic index      [none, d]    Sersic index, or Moffat beta
-# Column 7:  Position angle    [deg, d]     Position angle of profile
-# Column 8:  Axis ratio        [frac, d]    Axis ratio of profile
-# Column 9:  Magnitude         [ABmag, d]   Magnitude of profile within 
truncation radius
-# Column 10: Truncation radius [dist, d]    Truncation radius to stop building 
profile
+# Column 1:  ID                [count, u8]   Object ID
+# Column 2:  X                 [pixel, f64]  X axis position of profile center
+# Column 3:  Y                 [pixel, f64]  Y axis position of profile center
+# Column 4:  Function          [code, i32]   Profile's radial function code
+# Column 5:  Width             [pixel, f64]  For Sersic: effective radius, for 
Moffat, FWHM
+# Column 6:  Sersic index      [none, f64]   Sersic index, or Moffat beta
+# Column 7:  Position angle    [deg, f64]    Position angle of profile
+# Column 8:  Axis ratio        [frac, f64]   Axis ratio of profile
+# Column 9:  Magnitude         [ABmag, f64]  Magnitude of profile within 
truncation radius
+# Column 10: Truncation radius [dist, f64]   Truncation radius to stop 
building profile
 1     100.40    0.40     1     20.00     2.500      45.000     1.00       
-18.0     5.000
diff --git a/tests/mkprof/mkprofcat4.txt b/tests/mkprof/mkprofcat4.txt
index 2f2b221..5305532 100644
--- a/tests/mkprof/mkprofcat4.txt
+++ b/tests/mkprof/mkprofcat4.txt
@@ -1,11 +1,11 @@
-# Column 1:  ID                [count, uc]  Object ID
-# Column 2:  X                 [pixel, d]   X axis position of profile center
-# Column 3:  Y                 [pixel, d]   Y axis position of profile center
-# Column 4:  Function          [name, str7] Profile's radial function
-# Column 5:  Width             [pixel, d]   For Sersic: effective radius, for 
Moffat, FWHM
-# Column 6:  Sersic index      [none, d]    Sersic index, or Moffat beta
-# Column 7:  Position angle    [deg, d]     Position angle of profile
-# Column 8:  Axis ratio        [frac, d]    Axis ratio of profile
-# Column 9:  Magnitude         [ABmag, d]   Magnitude of profile within 
truncation radius
-# Column 10: Truncation radius [dist, d]    Truncation radius to stop building 
profile
+# Column 1:  ID                [count, u8]   Object ID
+# Column 2:  X                 [pixel, f64]  X axis position of profile center
+# Column 3:  Y                 [pixel, f64]  Y axis position of profile center
+# Column 4:  Function          [name, str7]  Profile's radial function
+# Column 5:  Width             [pixel, f64]  For Sersic: effective radius, for 
Moffat, FWHM
+# Column 6:  Sersic index      [none, f64]   Sersic index, or Moffat beta
+# Column 7:  Position angle    [deg, f64]    Position angle of profile
+# Column 8:  Axis ratio        [frac, f64]   Axis ratio of profile
+# Column 9:  Magnitude         [ABmag, f64]  Magnitude of profile within 
truncation radius
+# Column 10: Truncation radius [dist, f64]   Truncation radius to stop 
building profile
 1     0.40    0.40     sersic     20.00     2.500      45.000     1.00       
-18.0     5.000
diff --git a/tests/mkprof/radeccat.txt b/tests/mkprof/radeccat.txt
index 7fc7b42..8340859 100644
--- a/tests/mkprof/radeccat.txt
+++ b/tests/mkprof/radeccat.txt
@@ -1,12 +1,12 @@
-# Column 1:  ID                [count, uc]  Object ID
-# Column 2:  RA                [deg, d]     Right Ascension of profile center
-# Column 3:  Dec               [deg, d]     Declination of profile center
-# Column 4:  Function          [name, str7] Profile's radial function
-# Column 5:  Width             [pixel, d]   For Sersic: effective radius, for 
Moffat, FWHM
-# Column 6:  Sersic index      [none, d]    Sersic index, or Moffat beta
-# Column 7:  Position angle    [deg, d]     Position angle of profile
-# Column 8:  Axis ratio        [frac, d]    Axis ratio of profile
-# Column 9:  Magnitude         [ABmag, d]   Magnitude of profile within 
truncation radius
-# Column 10: Truncation radius [dist, d]    Truncation radius to stop building 
profile
+# Column 1:  ID                [count,  u8]    Object ID
+# Column 2:  RA                [deg,   f64]     Right Ascension of profile 
center
+# Column 3:  Dec               [deg,   f64]     Declination of profile center
+# Column 4:  Function          [name, str7]   Profile's radial function
+# Column 5:  Width             [pixel, f64]   For Sersic: effective radius, 
for Moffat, FWHM
+# Column 6:  Sersic index      [none,  f64]    Sersic index, or Moffat beta
+# Column 7:  Position angle    [deg,   f64]     Position angle of profile
+# Column 8:  Axis ratio        [frac,  f64]    Axis ratio of profile
+# Column 9:  Magnitude         [ABmag, f64]   Magnitude of profile within 
truncation radius
+# Column 10: Truncation radius [dist,  f64]    Truncation radius to stop 
building profile
 1     0.99987331  1.0001617     sersic     10.00     2.500      45.000     0.3 
     -6.0     2.000
 2     0.99929656  1.0006917     sersic     10.00     2.500      135.00     0.3 
     -6.0     2.000
diff --git a/tests/table/table.txt b/tests/table/table.txt
index a2ad869..7efb24a 100644
--- a/tests/table/table.txt
+++ b/tests/table/table.txt
@@ -9,18 +9,18 @@
 #  - Columns with missing information
 #  - Some blank values different from the internal blank values.
 
-# Column 10: DOUBLE      [no units, d, 255]  Column with double values
+# Column 10: DOUBLE      [no units, f64, 255]  Column with double values
 
-# Column 1:  UCHAR_DATA  [no units, uc, 5]  Column with unsigned char values
-# Column 2:  CHAR        [no-units, c] Column with char values
+# Column 1:  UINT8_DATA  [no units, u8, 5]  Column with unsigned char values
+# Column 2:  INT8        [no-units, i8] Column with char values
 # Column 3:  STRING data [, str21, no data]          Column with string values
-# Column 4:  USHORT data [,us] Column with unsigned short values
-# Column 5:  SHORT       [no units, s]  Column with short values
-# Column 7:  LONG        [no units, l]  Column with long values
-# Column 8: LONGLONG    [no units, L]  Column with LONGLONG values
-# Column 9: FLOAT       [no units, f,-99]  Column with float values
+# Column 4:  UINT16 data [,u16] Column with unsigned short values
+# Column 5:  INT16       [no units, i16]  Column with short values
+# Column 7:  INT32        [no units, i32]  Column with long values
+# Column 8: INT64  [no units, i64]  Another column of long values
+# Column 9: FLOAT32       [no units, f32,-99]  Column with float values
 
-# Column 6:  UINT [,ui]
+# Column 6:  UINT32 [,u32]
 
 
 # IMPORTANT NOTE FOR FITS ASCII tables: CFITSIO will give its error



reply via email to

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