"Fossies" - the Fresh Open Source Software Archive

Member "gnuastro-0.8/bin/convertt/color.c" (26 Dec 2018, 23489 Bytes) of package /linux/privat/gnuastro-0.8.tar.lz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "color.c" see the Fossies "Dox" file reference documentation.

    1 /*********************************************************************
    2 ConvertType - Convert between various types of files.
    3 ConvertType is part of GNU Astronomy Utilities (Gnuastro) package.
    4 
    5 Original author:
    6      Mohammad Akhlaghi <mohammad@akhlaghi.org>
    7 Contributing author(s):
    8 Copyright (C) 2015-2018, Free Software Foundation, Inc.
    9 
   10 Gnuastro is free software: you can redistribute it and/or modify it
   11 under the terms of the GNU General Public License as published by the
   12 Free Software Foundation, either version 3 of the License, or (at your
   13 option) any later version.
   14 
   15 Gnuastro is distributed in the hope that it will be useful, but
   16 WITHOUT ANY WARRANTY; without even the implied warranty of
   17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   18 General Public License for more details.
   19 
   20 You should have received a copy of the GNU General Public License
   21 along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
   22 **********************************************************************/
   23 #include <config.h>
   24 
   25 #include <stdio.h>
   26 #include <errno.h>
   27 #include <error.h>
   28 #include <stdlib.h>
   29 
   30 #include <gnuastro/data.h>
   31 
   32 #include "main.h"
   33 
   34 
   35 
   36 
   37 
   38 
   39 
   40 /***********************************************************************/
   41 /**************            From mono-channel           *****************/
   42 /***********************************************************************/
   43 /* This algorithm is a translation of the primary algorithm in this page:
   44 https://stackoverflow.com/questions/3018313/algorithm-to-convert-rgb-to-hsv-and-hsv-to-rgb-in-range-0-255-for-both */
   45 void
   46 color_from_mono_hsv(struct converttparams *p)
   47 {
   48   int i;
   49   gal_data_t *R, *G, *B, *channel;
   50   float *r, *g, *b, *f, *fp, min, max;
   51   float *params=p->colormap->next->array;
   52   float h, s=1, v, hh, ff, P, q, t, h_min, h_max;
   53 
   54   /* Set the input values. */
   55   h_min = params[0];
   56   h_max = params[1];
   57 
   58   /* Sanity checks. */
   59   if(h_min>h_max)
   60     error(EXIT_FAILURE, 0, "the minimum angle value (%g) is not smaller "
   61           "than the maximum (%f)", h_min, h_max);
   62   if(h_min<0)
   63     error(EXIT_FAILURE, 0, "the minimum angle (%g) must be larger than 0",
   64           h_min);
   65   if(h_max>360)
   66     error(EXIT_FAILURE, 0, "the maximum angle (%g) must be smaller than "
   67           "360", h_max);
   68 
   69   /* Convert the dataset to floating point, then change its range to the
   70      given angle values. */
   71   gal_type_min(GAL_TYPE_FLOAT32, &max);
   72   gal_type_max(GAL_TYPE_FLOAT32, &min);
   73   channel=gal_data_copy_to_new_type_free(p->chll, GAL_TYPE_FLOAT32);
   74   fp=(f=channel->array)+channel->size;
   75   do {if(*f<min) min=*f; if(*f>max) max=*f;} while(++f<fp);
   76 
   77   /* Allocate the three datasets to keep the RGB colors. */
   78   R=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, channel->ndim,
   79                    channel->dsize, channel->wcs, 0, p->cp.minmapsize,
   80                    "RED", NULL, "Red color channel.");
   81   G=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, channel->ndim,
   82                    channel->dsize, channel->wcs, 0, p->cp.minmapsize,
   83                    "GREEN", NULL, "Green color channel.");
   84   B=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, channel->ndim,
   85                    channel->dsize, channel->wcs, 0, p->cp.minmapsize,
   86                    "BLUE", NULL, "Blue color channel.");
   87 
   88   /* Start the conversion. Note that the "Choroma" (`C') is fixed by our
   89      definition. */
   90   r=R->array;
   91   g=G->array;
   92   b=B->array;
   93   fp=(f=channel->array)+channel->size;
   94   do
   95     {
   96       if(isnan(*f))
   97         *r=*g=*b=0.0;
   98       else
   99         {
  100           /* Shift all the values to start from the desired angle. We'll
  101              set the "value" (brightness: 0: dark, 1: bright) using the
  102              pixel value, then scale it to fix the color. */
  103           v=(*f-min) / (max-min);
  104           h = v * (h_max-h_min) + h_min;
  105           if(h==360) h=0;
  106 
  107           /* Prepare the intermediate values. */
  108           hh=h/60;
  109           i  = (int)hh;
  110           ff = hh - i;
  111           P  = v * ( 1.0 -  s );
  112           q  = v * ( 1.0 - (s * ff) );
  113           t  = v * ( 1.0 - (s * (1.0 - ff) ));
  114 
  115           /* Based on the integer phase, set the r,g,b values. */
  116           switch(i)
  117             {
  118             case 0:          *r=v; *g=t; *b=P; break;
  119             case 1:          *r=q; *g=v; *b=P; break;
  120             case 2:          *r=P; *g=v; *b=t; break;
  121             case 3:          *r=P; *g=q; *b=v; break;
  122             case 4:          *r=t; *g=P; *b=v; break;
  123             case 5: default: *r=v; *g=P; *b=q; break;
  124             }
  125         }
  126 
  127       /* Convert the RGB values to 0 and 255.  With the steps above, they
  128          are between 0 and 1. */
  129       *r++ *= 255;
  130       *g++ *= 255;
  131       *b++ *= 255;
  132     }
  133   while(++f<fp);
  134 
  135   /* Convert the type to unsigned char. */
  136   R=gal_data_copy_to_new_type_free(R, GAL_TYPE_UINT8);
  137   G=gal_data_copy_to_new_type_free(G, GAL_TYPE_UINT8);
  138   B=gal_data_copy_to_new_type_free(B, GAL_TYPE_UINT8);
  139   p->chll=R;
  140   p->chll->next=G;
  141   p->chll->next->next=B;
  142 
  143   /* Clean up. */
  144   gal_data_free(channel);
  145 }
  146 
  147 
  148 
  149 
  150 
  151 /* From SAO DS9: */
  152 void
  153 color_from_mono_sls(struct converttparams *p)
  154 {
  155   gal_data_t *R, *G, *B, *channel;
  156   float *r, *g, *b, *f, *fp, min, max;
  157 
  158   /* Convert the dataset to floating point, then find its minimum and
  159      maximum values. */
  160   gal_type_min(GAL_TYPE_FLOAT32, &max);
  161   gal_type_max(GAL_TYPE_FLOAT32, &min);
  162   channel=gal_data_copy_to_new_type_free(p->chll, GAL_TYPE_FLOAT32);
  163   fp=(f=channel->array)+channel->size;
  164   do {if(*f<min) min=*f; if(*f>max) max=*f;} while(++f<fp);
  165 
  166   /* Allocate the three datasets to keep the RGB colors. */
  167   R=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, channel->ndim,
  168                    channel->dsize, channel->wcs, 0, p->cp.minmapsize,
  169                    "RED", NULL, "Red color channel.");
  170   G=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, channel->ndim,
  171                    channel->dsize, channel->wcs, 0, p->cp.minmapsize,
  172                    "GREEN", NULL, "Green color channel.");
  173   B=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, channel->ndim,
  174                    channel->dsize, channel->wcs, 0, p->cp.minmapsize,
  175                    "BLUE", NULL, "Blue color channel.");
  176 
  177   /* Start the conversion. Note that the "Choroma" (`C') is fixed by our
  178      definition. */
  179   r=R->array;
  180   g=G->array;
  181   b=B->array;
  182   fp=(f=channel->array)+channel->size;
  183   do
  184     {
  185       if(isnan(*f))
  186         *r=*g=*b=0.0;
  187       else
  188         switch( (int)((*f-min)/(max-min)*200) )
  189           {
  190           case 0:   *r=0.000000; *g=0.000000; *b=0.000000; break;
  191           case 1:   *r=0.043442; *g=0.000000; *b=0.052883; break;
  192           case 2:   *r=0.086883; *g=0.000000; *b=0.105767; break;
  193           case 3:   *r=0.130325; *g=0.000000; *b=0.158650; break;
  194           case 4:   *r=0.173767; *g=0.000000; *b=0.211533; break;
  195           case 5:   *r=0.217208; *g=0.000000; *b=0.264417; break;
  196           case 6:   *r=0.260650; *g=0.000000; *b=0.317300; break;
  197           case 7:   *r=0.304092; *g=0.000000; *b=0.370183; break;
  198           case 8:   *r=0.347533; *g=0.000000; *b=0.423067; break;
  199           case 9:   *r=0.390975; *g=0.000000; *b=0.475950; break;
  200           case 10:  *r=0.434417; *g=0.000000; *b=0.528833; break;
  201           case 11:  *r=0.477858; *g=0.000000; *b=0.581717; break;
  202           case 12:  *r=0.521300; *g=0.000000; *b=0.634600; break;
  203           case 13:  *r=0.506742; *g=0.000000; *b=0.640217; break;
  204           case 14:  *r=0.492183; *g=0.000000; *b=0.645833; break;
  205           case 15:  *r=0.477625; *g=0.000000; *b=0.651450; break;
  206           case 16:  *r=0.463067; *g=0.000000; *b=0.657067; break;
  207           case 17:  *r=0.448508; *g=0.000000; *b=0.662683; break;
  208           case 18:  *r=0.433950; *g=0.000000; *b=0.668300; break;
  209           case 19:  *r=0.419392; *g=0.000000; *b=0.673917; break;
  210           case 20:  *r=0.404833; *g=0.000000; *b=0.679533; break;
  211           case 21:  *r=0.390275; *g=0.000000; *b=0.685150; break;
  212           case 22:  *r=0.375717; *g=0.000000; *b=0.690767; break;
  213           case 23:  *r=0.361158; *g=0.000000; *b=0.696383; break;
  214           case 24:  *r=0.346600; *g=0.000000; *b=0.702000; break;
  215           case 25:  *r=0.317717; *g=0.000000; *b=0.712192; break;
  216           case 26:  *r=0.288833; *g=0.000000; *b=0.722383; break;
  217           case 27:  *r=0.259950; *g=0.000000; *b=0.732575; break;
  218           case 28:  *r=0.231067; *g=0.000000; *b=0.742767; break;
  219           case 29:  *r=0.202183; *g=0.000000; *b=0.752958; break;
  220           case 30:  *r=0.173300; *g=0.000000; *b=0.763150; break;
  221           case 31:  *r=0.144417; *g=0.000000; *b=0.773342; break;
  222           case 32:  *r=0.115533; *g=0.000000; *b=0.783533; break;
  223           case 33:  *r=0.086650; *g=0.000000; *b=0.793725; break;
  224           case 34:  *r=0.057767; *g=0.000000; *b=0.803917; break;
  225           case 35:  *r=0.028883; *g=0.000000; *b=0.814108; break;
  226           case 36:  *r=0.000000; *g=0.000000; *b=0.824300; break;
  227           case 37:  *r=0.000000; *g=0.019817; *b=0.838942; break;
  228           case 38:  *r=0.000000; *g=0.039633; *b=0.853583; break;
  229           case 39:  *r=0.000000; *g=0.059450; *b=0.868225; break;
  230           case 40:  *r=0.000000; *g=0.079267; *b=0.882867; break;
  231           case 41:  *r=0.000000; *g=0.099083; *b=0.897508; break;
  232           case 42:  *r=0.000000; *g=0.118900; *b=0.912150; break;
  233           case 43:  *r=0.000000; *g=0.138717; *b=0.926792; break;
  234           case 44:  *r=0.000000; *g=0.158533; *b=0.941433; break;
  235           case 45:  *r=0.000000; *g=0.178350; *b=0.956075; break;
  236           case 46:  *r=0.000000; *g=0.198167; *b=0.970717; break;
  237           case 47:  *r=0.000000; *g=0.217983; *b=0.985358; break;
  238           case 48:  *r=0.000000; *g=0.237800; *b=1.000000; break;
  239           case 49:  *r=0.000000; *g=0.268533; *b=1.000000; break;
  240           case 50:  *r=0.000000; *g=0.299267; *b=1.000000; break;
  241           case 51:  *r=0.000000; *g=0.330000; *b=1.000000; break;
  242           case 52:  *r=0.000000; *g=0.360733; *b=1.000000; break;
  243           case 53:  *r=0.000000; *g=0.391467; *b=1.000000; break;
  244           case 54:  *r=0.000000; *g=0.422200; *b=1.000000; break;
  245           case 55:  *r=0.000000; *g=0.452933; *b=1.000000; break;
  246           case 56:  *r=0.000000; *g=0.483667; *b=1.000000; break;
  247           case 57:  *r=0.000000; *g=0.514400; *b=1.000000; break;
  248           case 58:  *r=0.000000; *g=0.545133; *b=1.000000; break;
  249           case 59:  *r=0.000000; *g=0.575867; *b=1.000000; break;
  250           case 60:  *r=0.000000; *g=0.606600; *b=1.000000; break;
  251           case 61:  *r=0.000000; *g=0.631733; *b=0.975300; break;
  252           case 62:  *r=0.000000; *g=0.656867; *b=0.950600; break;
  253           case 63:  *r=0.000000; *g=0.682000; *b=0.925900; break;
  254           case 64:  *r=0.000000; *g=0.707133; *b=0.901200; break;
  255           case 65:  *r=0.000000; *g=0.732267; *b=0.876500; break;
  256           case 66:  *r=0.000000; *g=0.757400; *b=0.851800; break;
  257           case 67:  *r=0.000000; *g=0.782533; *b=0.827100; break;
  258           case 68:  *r=0.000000; *g=0.807667; *b=0.802400; break;
  259           case 69:  *r=0.000000; *g=0.832800; *b=0.777700; break;
  260           case 70:  *r=0.000000; *g=0.857933; *b=0.753000; break;
  261           case 71:  *r=0.000000; *g=0.883067; *b=0.728300; break;
  262           case 72:  *r=0.000000; *g=0.908200; *b=0.703600; break;
  263           case 73:  *r=0.000000; *g=0.901908; *b=0.676675; break;
  264           case 74:  *r=0.000000; *g=0.895617; *b=0.649750; break;
  265           case 75:  *r=0.000000; *g=0.889325; *b=0.622825; break;
  266           case 76:  *r=0.000000; *g=0.883033; *b=0.595900; break;
  267           case 77:  *r=0.000000; *g=0.876742; *b=0.568975; break;
  268           case 78:  *r=0.000000; *g=0.870450; *b=0.542050; break;
  269           case 79:  *r=0.000000; *g=0.864158; *b=0.515125; break;
  270           case 80:  *r=0.000000; *g=0.857867; *b=0.488200; break;
  271           case 81:  *r=0.000000; *g=0.851575; *b=0.461275; break;
  272           case 82:  *r=0.000000; *g=0.845283; *b=0.434350; break;
  273           case 83:  *r=0.000000; *g=0.838992; *b=0.407425; break;
  274           case 84:  *r=0.000000; *g=0.832700; *b=0.380500; break;
  275           case 85:  *r=0.000000; *g=0.832308; *b=0.354858; break;
  276           case 86:  *r=0.000000; *g=0.831917; *b=0.329217; break;
  277           case 87:  *r=0.000000; *g=0.831525; *b=0.303575; break;
  278           case 88:  *r=0.000000; *g=0.831133; *b=0.277933; break;
  279           case 89:  *r=0.000000; *g=0.830742; *b=0.252292; break;
  280           case 90:  *r=0.000000; *g=0.830350; *b=0.226650; break;
  281           case 91:  *r=0.000000; *g=0.829958; *b=0.201008; break;
  282           case 92:  *r=0.000000; *g=0.829567; *b=0.175367; break;
  283           case 93:  *r=0.000000; *g=0.829175; *b=0.149725; break;
  284           case 94:  *r=0.000000; *g=0.828783; *b=0.124083; break;
  285           case 95:  *r=0.000000; *g=0.828392; *b=0.098442; break;
  286           case 96:  *r=0.000000; *g=0.828000; *b=0.072800; break;
  287           case 97:  *r=0.033167; *g=0.834167; *b=0.066733; break;
  288           case 98:  *r=0.066333; *g=0.840333; *b=0.060667; break;
  289           case 99:  *r=0.099500; *g=0.846500; *b=0.054600; break;
  290           case 100: *r=0.132667; *g=0.852667; *b=0.048533; break;
  291           case 101: *r=0.165833; *g=0.858833; *b=0.042467; break;
  292           case 102: *r=0.199000; *g=0.865000; *b=0.036400; break;
  293           case 103: *r=0.232167; *g=0.871167; *b=0.030333; break;
  294           case 104: *r=0.265333; *g=0.877333; *b=0.024267; break;
  295           case 105: *r=0.298500; *g=0.883500; *b=0.018200; break;
  296           case 106: *r=0.331667; *g=0.889667; *b=0.012133; break;
  297           case 107: *r=0.364833; *g=0.895833; *b=0.006067; break;
  298           case 108: *r=0.398000; *g=0.902000; *b=0.000000; break;
  299           case 109: *r=0.430950; *g=0.902000; *b=0.000000; break;
  300           case 110: *r=0.463900; *g=0.902000; *b=0.000000; break;
  301           case 111: *r=0.496850; *g=0.902000; *b=0.000000; break;
  302           case 112: *r=0.529800; *g=0.902000; *b=0.000000; break;
  303           case 113: *r=0.562750; *g=0.902000; *b=0.000000; break;
  304           case 114: *r=0.595700; *g=0.902000; *b=0.000000; break;
  305           case 115: *r=0.628650; *g=0.902000; *b=0.000000; break;
  306           case 116: *r=0.661600; *g=0.902000; *b=0.000000; break;
  307           case 117: *r=0.694550; *g=0.902000; *b=0.000000; break;
  308           case 118: *r=0.727500; *g=0.902000; *b=0.000000; break;
  309           case 119: *r=0.760450; *g=0.902000; *b=0.000000; break;
  310           case 120: *r=0.793400; *g=0.902000; *b=0.000000; break;
  311           case 121: *r=0.810617; *g=0.897133; *b=0.003983; break;
  312           case 122: *r=0.827833; *g=0.892267; *b=0.007967; break;
  313           case 123: *r=0.845050; *g=0.887400; *b=0.011950; break;
  314           case 124: *r=0.862267; *g=0.882533; *b=0.015933; break;
  315           case 125: *r=0.879483; *g=0.877667; *b=0.019917; break;
  316           case 126: *r=0.896700; *g=0.872800; *b=0.023900; break;
  317           case 127: *r=0.913917; *g=0.867933; *b=0.027883; break;
  318           case 128: *r=0.931133; *g=0.863067; *b=0.031867; break;
  319           case 129: *r=0.948350; *g=0.858200; *b=0.035850; break;
  320           case 130: *r=0.965567; *g=0.853333; *b=0.039833; break;
  321           case 131: *r=0.982783; *g=0.848467; *b=0.043817; break;
  322           case 132: *r=1.000000; *g=0.843600; *b=0.047800; break;
  323           case 133: *r=0.995725; *g=0.824892; *b=0.051600; break;
  324           case 134: *r=0.991450; *g=0.806183; *b=0.055400; break;
  325           case 135: *r=0.987175; *g=0.787475; *b=0.059200; break;
  326           case 136: *r=0.982900; *g=0.768767; *b=0.063000; break;
  327           case 137: *r=0.978625; *g=0.750058; *b=0.066800; break;
  328           case 138: *r=0.974350; *g=0.731350; *b=0.070600; break;
  329           case 139: *r=0.970075; *g=0.712642; *b=0.074400; break;
  330           case 140: *r=0.965800; *g=0.693933; *b=0.078200; break;
  331           case 141: *r=0.961525; *g=0.675225; *b=0.082000; break;
  332           case 142: *r=0.957250; *g=0.656517; *b=0.085800; break;
  333           case 143: *r=0.952975; *g=0.637808; *b=0.089600; break;
  334           case 144: *r=0.948700; *g=0.619100; *b=0.093400; break;
  335           case 145: *r=0.952975; *g=0.600408; *b=0.085617; break;
  336           case 146: *r=0.957250; *g=0.581717; *b=0.077833; break;
  337           case 147: *r=0.961525; *g=0.563025; *b=0.070050; break;
  338           case 148: *r=0.965800; *g=0.544333; *b=0.062267; break;
  339           case 149: *r=0.970075; *g=0.525642; *b=0.054483; break;
  340           case 150: *r=0.974350; *g=0.506950; *b=0.046700; break;
  341           case 151: *r=0.978625; *g=0.488258; *b=0.038917; break;
  342           case 152: *r=0.982900; *g=0.469567; *b=0.031133; break;
  343           case 153: *r=0.987175; *g=0.450875; *b=0.023350; break;
  344           case 154: *r=0.991450; *g=0.432183; *b=0.015567; break;
  345           case 155: *r=0.995725; *g=0.413492; *b=0.007783; break;
  346           case 156: *r=1.000000; *g=0.394800; *b=0.000000; break;
  347           case 157: *r=0.998342; *g=0.361900; *b=0.000000; break;
  348           case 158: *r=0.996683; *g=0.329000; *b=0.000000; break;
  349           case 160: *r=0.995025; *g=0.296100; *b=0.000000; break;
  350           case 161: *r=0.993367; *g=0.263200; *b=0.000000; break;
  351           case 162: *r=0.991708; *g=0.230300; *b=0.000000; break;
  352           case 163: *r=0.990050; *g=0.197400; *b=0.000000; break;
  353           case 164: *r=0.988392; *g=0.164500; *b=0.000000; break;
  354           case 165: *r=0.986733; *g=0.131600; *b=0.000000; break;
  355           case 166: *r=0.985075; *g=0.098700; *b=0.000000; break;
  356           case 167: *r=0.983417; *g=0.065800; *b=0.000000; break;
  357           case 168: *r=0.981758; *g=0.032900; *b=0.000000; break;
  358           case 169: *r=0.980100; *g=0.000000; *b=0.000000; break;
  359           case 170: *r=0.955925; *g=0.000000; *b=0.000000; break;
  360           case 171: *r=0.931750; *g=0.000000; *b=0.000000; break;
  361           case 172: *r=0.907575; *g=0.000000; *b=0.000000; break;
  362           case 173: *r=0.883400; *g=0.000000; *b=0.000000; break;
  363           case 174: *r=0.859225; *g=0.000000; *b=0.000000; break;
  364           case 175: *r=0.835050; *g=0.000000; *b=0.000000; break;
  365           case 176: *r=0.810875; *g=0.000000; *b=0.000000; break;
  366           case 177: *r=0.786700; *g=0.000000; *b=0.000000; break;
  367           case 178: *r=0.762525; *g=0.000000; *b=0.000000; break;
  368           case 179: *r=0.738350; *g=0.000000; *b=0.000000; break;
  369           case 180: *r=0.714175; *g=0.000000; *b=0.000000; break;
  370           case 181: *r=0.690000; *g=0.000000; *b=0.000000; break;
  371           case 182: *r=0.715833; *g=0.083333; *b=0.083333; break;
  372           case 183: *r=0.741667; *g=0.166667; *b=0.166667; break;
  373           case 184: *r=0.767500; *g=0.250000; *b=0.250000; break;
  374           case 185: *r=0.793333; *g=0.333333; *b=0.333333; break;
  375           case 186: *r=0.819167; *g=0.416667; *b=0.416667; break;
  376           case 187: *r=0.845000; *g=0.500000; *b=0.500000; break;
  377           case 188: *r=0.870833; *g=0.583333; *b=0.583333; break;
  378           case 189: *r=0.896667; *g=0.666667; *b=0.666667; break;
  379           case 190: *r=0.922500; *g=0.750000; *b=0.750000; break;
  380           case 191: *r=0.948333; *g=0.833333; *b=0.833333; break;
  381           case 192: *r=0.974167; *g=0.916667; *b=0.916667; break;
  382           case 193: *r=1.000000; *g=1.000000; *b=1.000000; break;
  383           case 194: *r=1.000000; *g=1.000000; *b=1.000000; break;
  384           case 195: *r=1.000000; *g=1.000000; *b=1.000000; break;
  385           case 196: *r=1.000000; *g=1.000000; *b=1.000000; break;
  386           case 197: *r=1.000000; *g=1.000000; *b=1.000000; break;
  387           case 198: *r=1.000000; *g=1.000000; *b=1.000000; break;
  388           case 199: *r=1.000000; *g=1.000000; *b=1.000000; break;
  389           case 200: *r=1.000000; *g=1.000000; *b=1.000000; break;
  390           }
  391 
  392       /* Convert the RGB values to 0 and 255.  With the steps above, they
  393          are between 0 and 1. */
  394       *r++ *= 255;
  395       *g++ *= 255;
  396       *b++ *= 255;
  397     }
  398   while(++f<fp);
  399 
  400   /* Convert the type to unsigned char. */
  401   R=gal_data_copy_to_new_type_free(R, GAL_TYPE_UINT8);
  402   G=gal_data_copy_to_new_type_free(G, GAL_TYPE_UINT8);
  403   B=gal_data_copy_to_new_type_free(B, GAL_TYPE_UINT8);
  404   p->chll=R;
  405   p->chll->next=G;
  406   p->chll->next->next=B;
  407 
  408   /* Clean up. */
  409   gal_data_free(channel);
  410 }
  411 
  412 
  413 
  414 
  415 
  416 
  417 
  418 
  419 
  420 
  421 
  422 
  423 
  424 
  425 
  426 
  427 
  428 
  429 
  430 
  431 /***********************************************************************/
  432 /**************            From mono-channel           *****************/
  433 /***********************************************************************/
  434 /* This algorithm is a translation of the primary algorithm in this page:
  435 https://stackoverflow.com/questions/3018313/algorithm-to-convert-rgb-to-hsv-and-hsv-to-rgb-in-range-0-255-for-both */
  436 void
  437 color_rgb_to_hsv(struct converttparams *p)
  438 {
  439   float *h, *s, *v;
  440   gal_data_t *H, *S, *V;
  441   uint8_t *r, *g, *b, *rr, min, max, delta;
  442 
  443   /* Basic sanity checks. */
  444   if(gal_list_data_number(p->chll)!=3)
  445     error(EXIT_FAILURE, 0, "%s: three color channels must be input",
  446           __func__);
  447   if( p->chll->type!=GAL_TYPE_UINT8
  448       || p->chll->next->type!=GAL_TYPE_UINT8
  449       || p->chll->next->next->type!=GAL_TYPE_UINT8 )
  450     error(EXIT_FAILURE, 0, "when converting RGB to HSV, all three input "
  451           "color channels must have an 8-bit unsigned integer type");
  452 
  453   /* Allocate the three datasets to keep the RGB colors. */
  454   H=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, p->chll->ndim,
  455                    p->chll->dsize, p->chll->wcs, 0, p->cp.minmapsize,
  456                    "HUE", NULL, NULL);
  457   S=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, p->chll->ndim,
  458                    p->chll->dsize, p->chll->wcs, 0, p->cp.minmapsize,
  459                    "SATURATION", NULL, NULL);
  460   V=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, p->chll->ndim,
  461                    p->chll->dsize, p->chll->wcs, 0, p->cp.minmapsize,
  462                    "VALUE", NULL, NULL);
  463 
  464   /* Initiate the pointer arrays. */
  465   h=H->array;
  466   s=S->array;
  467   v=V->array;
  468   r=p->chll->array;
  469   g=p->chll->next->array;
  470   b=p->chll->next->next->array;
  471 
  472   /* Parse the dataset and do the conversion. */
  473   rr=r+p->chll->size;
  474   do
  475     {
  476       /* Get the minimum and maximum RGB values. */
  477       min = *r  < *g ? *r  : *g;
  478       min = min < *b ? min : *b;
  479       max = *r  > *g ? *r  : *g;
  480       max = max > *b ? max : *b;
  481 
  482       /* The "value" is the maximum. */
  483       *v = (float)(max)/255.0;
  484 
  485       /* See what the difference between the minimum and maximum are. */
  486       delta=max-min;
  487       if(delta)
  488         {
  489           if(max)
  490             {
  491               /* Set the Saturation and hue. */
  492               *s = (float)(delta)/(float)(max);
  493               *h = ( *r==max
  494                      /* Between yellow and magenta. */
  495                      ? ((float)(*g-*b)/(float)(delta))
  496                      : ( *g==max
  497                          /* Between cyan & yellow. */
  498                          ? (2.0+(float)(*b-*r)/(float)(delta))
  499                          /* Between magenta & cyan. */
  500                          : (4.0+(float)(*r-*g)/(float)(delta)) ) );
  501 
  502               /* Correct the hue: */
  503               *h *= 60.0;
  504               if( *h<0.0 ) *h += 360.0;
  505             }
  506           else
  507             /* When `max==0', then *r=*g=*b=0, so s=h=0. */
  508             *s=*h=0.0;
  509         }
  510       else
  511         /* When there is no difference, then its actually a grayscale
  512            dataset, so `*v' is the only parameter that matters. */
  513         *s=*h=0.0;
  514 
  515 
  516       /* Increment all the pointers. */
  517       ++g; ++b; ++h; ++s; ++v;
  518     }
  519   while(++r<rr);
  520 
  521   /* Free the old channels linked list and replace it with the new ones. */
  522   gal_list_data_free(p->chll);
  523   p->chll=H;
  524   p->chll->next=S;
  525   p->chll->next->next=V;
  526 }