Attached here-in a slightly updated diff (from the last diff attached in
#774) for i.rgb.his.

I need time to learn/understand things (in C). Yet, I tested the "new"
version and it works for me.

I would like to push this version into SVN myself. Thus, I'd like to ask
(in the grass-psc list) for commit access. However, I can just submit
another, updated, diff, in ticket #774 for someone to take over.

Modifying i.his.rgb, accordingly, is halfway done. I mostly learn how to
use pre-existing C functions, and this is a bit time-consuming.

These modifications would free-up also subsequent modules who use
i.[rgb|his].[his|rgb] to compute maps of more than 8-bit. For example,
i.pansharpen [see tickets #774, #2048]

Thanks for any attention.
Nikos
Index: closefiles.c
===================================================================
--- closefiles.c        (revision 69246)
+++ closefiles.c        (working copy)
@@ -1,20 +1,18 @@
 #include <stdlib.h>
-#include <grass/gis.h>
-#include <grass/raster.h>
 #include "globals.h"
 
 /* This routine closes up the cell maps, frees up the row buffers and
-   use a less than perfect way of setting the color maps for the output
+   uses a less than perfect way of setting the color maps for the output
    to grey scale.  */
 
 int closefiles(char *h_name, char *i_name, char *s_name,
-              int fd_output[3], CELL * rowbuf[3])
+              int fd_output[3], FCELL * rowbuf[3])
 {
     int i;
     struct Colors colors;
-    struct Range range;
+    struct FPRange range;
     struct History history;
-    CELL min, max;
+    DCELL min, max;
     const char *mapset;
 
     for (i = 0; i < 3; i++) {
@@ -25,20 +23,19 @@
     mapset = G_mapset();
 
     /* write colors */
-    /*   set to 0,max_level instead of min,max ?? */
-    Rast_read_range(h_name, mapset, &range);
-    Rast_get_range_min_max(&range, &min, &max);
-    Rast_make_grey_scale_colors(&colors, min, max);
+    Rast_read_fp_range(h_name, mapset, &range);
+    Rast_get_fp_range_min_max(&range, &min, &max);
+    Rast_make_grey_scale_fp_colors(&colors, min, max);
     Rast_write_colors(h_name, mapset, &colors);
 
-    Rast_read_range(i_name, mapset, &range);
-    Rast_get_range_min_max(&range, &min, &max);
-    Rast_make_grey_scale_colors(&colors, min, max);
+    Rast_read_fp_range(i_name, mapset, &range);
+    Rast_get_fp_range_min_max(&range, &min, &max);
+    Rast_make_grey_scale_fp_colors(&colors, min, max);
     Rast_write_colors(i_name, mapset, &colors);
 
-    Rast_read_range(s_name, mapset, &range);
-    Rast_get_range_min_max(&range, &min, &max);
-    Rast_make_grey_scale_colors(&colors, min, max);
+    Rast_read_fp_range(s_name, mapset, &range);
+    Rast_get_fp_range_min_max(&range, &min, &max);
+    Rast_make_grey_scale_fp_colors(&colors, min, max);
     Rast_write_colors(s_name, mapset, &colors);
 
     /* write metadata */
@@ -46,6 +43,7 @@
     Rast_command_history(&history);
     Rast_write_history(h_name, &history);
     Rast_put_cell_title(h_name, "Image hue");
+    Rast_write_units(h_name, "degrees");
 
     Rast_short_history(i_name, "raster", &history);
     Rast_command_history(&history);
@@ -59,4 +57,3 @@
 
     return 0;
 }
-
Index: globals.h
===================================================================
--- globals.h   (revision 69246)
+++ globals.h   (working copy)
@@ -4,12 +4,13 @@
 #include <grass/raster.h>
 
 /* closefiles.c */
-int closefiles(char *, char *, char *, int[3], CELL *[3]);
+int closefiles(char *, char *, char *, int[3], FCELL *[3]);
 
 /* openfiles.c */
 void openfiles(char *, char *, char *, char *, char *, char *,
-              int[3], int[3], CELL *[3]);
+              int[3], int[3], DCELL *[3]);
+
 /* rgb2his.c */
-void rgb2his(CELL *[3], int);
+void rgb2his(DCELL *[3], int, double);
 
 #endif /* __GLOBALS_H__ */
Index: main.c
===================================================================
--- main.c      (revision 69246)
+++ main.c      (working copy)
@@ -6,10 +6,10 @@
  * AUTHOR(S):    David Satnik, GIS Laboratory, Central Washington University
  *               with acknowledgements to Ali Vali,
  *               Univ. of Texas Space Research Center, for the core routine. 
- *               
- * PURPOSE:      Red-green-blue (rgb) to hue-intensity-saturation (his) 
- *               raster map color transformation function
  *
+ * PURPOSE:      Previously: Red-green-blue (rgb) to hue-intensity-saturation
+ *               (his) raster map color transformation function
+ *
  * COPYRIGHT:    (C) 2007-2008 by the GRASS Development Team
  *
  *               This program is free software under the GNU General Public
@@ -21,6 +21,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <math.h>
 #include <grass/gis.h>
 #include <grass/raster.h>
 #include <grass/glocale.h>
@@ -30,13 +31,16 @@
 {
     long i;
     int band, rows, cols;
-    CELL *rowbuffer[3];
+    DCELL *rowbuffer[3];
     struct Option *opt_hue, *opt_red;
-    struct Option *opt_inten, *opt_green;
-    struct Option *opt_sat, *opt_blue;
+    struct Option *opt_intensity, *opt_green;
+    struct Option *opt_saturation, *opt_blue;
+    struct Option *opt_bit_depth;
     struct GModule *module;
     int fd_input[3];
     int fd_output[3];
+    int bit_depth;
+    double max_level;   /* expanded bitdepth (eg 255) */
 
     /* Initialize GIS engine */
     G_gisinit(argv[0]);
@@ -46,11 +50,11 @@
     G_add_keyword(_("imagery"));
     G_add_keyword(_("color transformation"));
     G_add_keyword("RGB");
-    G_add_keyword("HIS");
-    G_add_keyword("IHS");
+    G_add_keyword("HSL");
+    G_add_keyword("HSV");
     module->description =
-       _("Transforms raster maps from RGB (Red-Green-Blue) color space to "
-         "HIS (Hue-Intensity-Saturation) color space.");
+       _("Transforms raster maps from Red-Green-Blue (RGB) color space to "
+         "Hue-Saturation-Luminance (HSL) color space.");
 
     /* Define the different options */
     opt_red = G_define_standard_option(G_OPT_R_INPUT);
@@ -69,43 +73,60 @@
     opt_hue->key = "hue";
     opt_hue->description = _("Name for output raster map (hue)");
 
-    opt_inten = G_define_standard_option(G_OPT_R_OUTPUT);
-    opt_inten->key = "intensity";
-    opt_inten->description = _("Name for output raster map (intensity)");
+    opt_intensity = G_define_standard_option(G_OPT_R_OUTPUT);
+    opt_intensity->key = "intensity";
+    opt_intensity->description = _("Name for output raster map (intensity)");
 
-    opt_sat = G_define_standard_option(G_OPT_R_OUTPUT);
-    opt_sat->key = "saturation";
-    opt_sat->description = _("Name for output raster map (saturation)");
+    opt_saturation = G_define_standard_option(G_OPT_R_OUTPUT);
+    opt_saturation->key = "saturation";
+    opt_saturation->description = _("Name for output raster map (saturation)");
 
+    opt_bit_depth = G_define_option();
+    opt_bit_depth->key = "bit_depth";
+    opt_bit_depth->type = TYPE_INTEGER;
+    opt_bit_depth->required = NO;
+    opt_bit_depth->answer = "8";
+    opt_bit_depth->options = "8-16";
+    opt_bit_depth->description = _("Number of bits in a band");
+
     if (G_parser(argc, argv))
        exit(EXIT_FAILURE);
 
 
+    bit_depth = atoi(opt_bit_depth->answer);
+    if (bit_depth <= 0)
+       G_fatal_error(_("Invalid number of levels"));
+    max_level = pow(2, bit_depth) - 1.0;
+    G_debug(1, "%d-bit data has range 0,%.0f", bit_depth, max_level);
+
+
     /* get dimension of the image */
     rows = Rast_window_rows();
     cols = Rast_window_cols();
 
     openfiles(opt_red->answer, opt_green->answer, opt_blue->answer,
-             opt_hue->answer, opt_inten->answer, opt_sat->answer,
+             opt_hue->answer, opt_intensity->answer, opt_saturation->answer,
              fd_input, fd_output, rowbuffer);
 
     for (i = 0; i < rows; i++) {
-       /* read in a row from each cell map */
-       G_percent(i, rows, 2);
+        /* read in a row from each cell map */
+        G_percent(i, rows, 2);
 
        for (band = 0; band < 3; band++)
-           Rast_get_c_row(fd_input[band], rowbuffer[band], i);
+           /* Rast_get_c_row(fd_input[band], rowbuffer[band], i); */
+           Rast_get_d_row(fd_input[band], rowbuffer[band], i);
 
        /* process this row of the map */
-       rgb2his(rowbuffer, cols);
+       rgb2his(rowbuffer, cols, max_level);
 
        /* write out the new row for each cell map */
        for (band = 0; band < 3; band++)
-           Rast_put_row(fd_output[band], rowbuffer[band], CELL_TYPE);
+           /* Rast_put_row(fd_output[band], rowbuffer[band], CELL_TYPE); */
+           Rast_put_row(fd_output[band], rowbuffer[band], DCELL_TYPE);
     }
     G_percent(i, rows, 2);
 
-    closefiles(opt_hue->answer, opt_inten->answer, opt_sat->answer,
+    closefiles(opt_hue->answer, opt_intensity->answer, opt_saturation->answer,
               fd_output, rowbuffer);
 
 
Index: openfiles.c
===================================================================
--- openfiles.c (revision 69246)
+++ openfiles.c (working copy)
@@ -1,13 +1,9 @@
 #include <stdio.h>
-#include <grass/gis.h>
-#include <grass/raster.h>
-#include <grass/glocale.h>
 #include "globals.h"
 
-
 void openfiles(char *r_name, char *g_name, char *b_name,
               char *h_name, char *i_name, char *s_name,
-              int fd_input[3], int fd_output[3], CELL * rowbuf[3])
+              int fd_input[3], int fd_output[3], DCELL * rowbuf[3])
 {
     fd_input[0] = Rast_open_old(r_name, "");
     fd_input[1] = Rast_open_old(g_name, "");
@@ -14,12 +10,12 @@
     fd_input[2] = Rast_open_old(b_name, "");
 
     /* open output files */
-    fd_output[0] = Rast_open_c_new(h_name);
-    fd_output[1] = Rast_open_c_new(i_name);
-    fd_output[2] = Rast_open_c_new(s_name);
+    fd_output[0] = Rast_open_fp_new(h_name);
+    fd_output[1] = Rast_open_fp_new(i_name);
+    fd_output[2] = Rast_open_fp_new(s_name);
 
     /* allocate the cell row buffer */
-    rowbuf[0] = Rast_allocate_c_buf();
-    rowbuf[1] = Rast_allocate_c_buf();
-    rowbuf[2] = Rast_allocate_c_buf();
+    rowbuf[0] = Rast_allocate_d_buf();
+    rowbuf[1] = Rast_allocate_d_buf();
+    rowbuf[2] = Rast_allocate_d_buf();
 }
Index: rgb2his.c
===================================================================
--- rgb2his.c   (revision 69246)
+++ rgb2his.c   (working copy)
@@ -2,9 +2,7 @@
 /******************************************************************************
 NAME:                         RGB2HIS
  
-PURPOSE    To process red,green,blue bands to hue,intensity,saturation.
- 
-ALGORITHM:
+PURPOSE    To process red,green,blue bands to hue
    Get red, green, blue from input buffer
    Create the HIS bands
    Write to output buffer
@@ -17,109 +15,110 @@
    each band is processed and written out.   CWU GIS Lab: DBS 8/90 */
 
 #include <grass/gis.h>
+#include <grass/glocale.h>
 #include "globals.h"
+#include <math.h>
 
-void rgb2his(CELL * rowbuffer[3], int columns)
+
+/* read in RGB as double precision DCELL? */
+/* or get type automatically? Rast_map_type() */
+
+void rgb2his(DCELL *rowbuffer[3], int columns, double max_level)
 {
     int sample;                        /* sample indicator                     
 */
     double red;                        /* the red band output                  
 */
     double green;              /* the green band output                 */
     double blue;               /* the blue band output                  */
-    double scaler;             /* red value                             */
-    double scaleg;             /* green value                           */
-    double scaleb;             /* blue value                            */
-    double high;               /* maximum red, green, blue              */
-    double low;                        /* minimum red, green, blue             
 */
-    double intens;             /* intensity                             */
-    double sat;                        /* saturation                           
 */
-    double hue = 0.0L;         /* hue                                   */
+    double max;                /* maximum red, green, blue              */
+    double min;                        /* minimum red, green, blue             
 */
+    double chroma;
+    double intensity;   /* intensity                             */
+    double saturation; /* saturation                            */
+    double hue = 0.0L; /* hue                                   */
 
-    for (sample = 0; sample < columns; sample++) {
-       if (Rast_is_c_null_value(&rowbuffer[0][sample]) ||
-           Rast_is_c_null_value(&rowbuffer[1][sample]) ||
-           Rast_is_c_null_value(&rowbuffer[2][sample])) {
-           Rast_set_c_null_value(&rowbuffer[0][sample], 1);
-           Rast_set_c_null_value(&rowbuffer[1][sample], 1);
-           Rast_set_c_null_value(&rowbuffer[2][sample], 1);
-           continue;
+for (sample = 0; sample < columns; sample++) {
+
+       if (Rast_is_d_null_value(&rowbuffer[0][sample]) ||
+           Rast_is_d_null_value(&rowbuffer[1][sample]) ||
+           Rast_is_d_null_value(&rowbuffer[2][sample])) {
+            Rast_set_d_null_value(&rowbuffer[0][sample], 1);
+            Rast_set_d_null_value(&rowbuffer[1][sample], 1);
+            Rast_set_d_null_value(&rowbuffer[2][sample], 1);
+            continue;
+        }
+
+    /* scale r, g, b to [0.0,1.0] */
+
+       red = rowbuffer[0][sample];
+       red /= max_level;
+
+       green = rowbuffer[1][sample];
+       green /= max_level;
+
+       blue = rowbuffer[2][sample];
+       blue /= max_level;
+
+    /* max of {r,g,b} */
+
+       max = red;
+       if (green > max)
+           max = green;
+
+       if (blue > max)
+           max = blue;
+
+    /* min of {r,g,b} */
+       
+    min = red;
+       if (green < min)
+           min = green;
+       
+    if (blue < min)
+           min = blue;
+
+    chroma = max - min;
+       intensity = ((max + min) / 2.0);
+
+       /* if min = max, then achromatic -- case R = G = B */
+
+       if (chroma == 0.0) {
+
+           saturation = 0.0;
+
+        /* undefined -- (how to) set to NULL? */
+        hue = 0.0;
+
+           rowbuffer[0][sample] = (FCELL)hue;
+           rowbuffer[1][sample] = (FCELL)intensity;
+           rowbuffer[2][sample] = (FCELL)saturation;
        }
 
-       scaler = (double)rowbuffer[0][sample];
-       scaler /= 255.0;
-       scaleg = (double)rowbuffer[1][sample];
-       scaleg /= 255.0;
-       scaleb = (double)rowbuffer[2][sample];
-       scaleb /= 255.0;
+       /*  else chromatic */
 
-       high = scaler;
-       if (scaleg > high)
-           high = scaleg;
-       if (scaleb > high)
-           high = scaleb;
-       low = scaler;
-       if (scaleg < low)
-           low = scaleg;
-       if (scaleb < low)
-           low = scaleb;
-       /*
-          calculate the lightness (intensity)
-        */
-       intens = ((high + low) / 2.0);
-       /*
-          if min = max the achromatic case R=G=B
-        */
-       if (high == low) {
-           sat = 0.0;
-           /*        hue = -1.0; */
-           hue = 0.0;
-           rowbuffer[0][sample] = (unsigned char)hue;
-           rowbuffer[1][sample] = (unsigned char)(intens * 255.);
-           rowbuffer[2][sample] = (unsigned char)(sat * 255.);
-       }
-       /*
-          else chromatic case
-        */
-       else if (high != low) {
-           if (intens <= 0.5)
-               sat = (high - low) / (high + low);
-           else
-               /*
-                  sat = (high-low)/(2 - (high-low));
-                */
-               sat = (high - low) / (2 - high - low);
-           red = (high - scaler) / (high - low);
-           green = (high - scaleg) / (high - low);
-           blue = (high - scaleb) / (high - low);
-           /*
-              resulting color between yellow and magenta
-            */
-           if (scaler == high)
-               hue = blue - green;
-           /*
-              resulting color between cyan and yellow
-            */
-           else if (scaleg == high)
-               hue = 2 + red - blue;
-           /*
-              resulting color between magenta and cyan
-            */
-           else if (scaleb == high)
-               hue = 4 + green - red;
-           /*
-              convert to degrees
-            */
-           hue *= 60.0;
-           /*
-              make nonnegative
-            */
+       else if (chroma != 0.0) {
+
+        saturation = chroma / (1 - fabs(2.0 * intensity - 1.0));
+
+           if (red == max)
+               hue = fmod(((green - blue) / chroma), 6.0);
+
+           else if (green == max)
+               hue = ((blue - red) / chroma) + 2.0;
+
+           else if (blue == max)
+               hue = ((red - green) / chroma) + 4.0;
+
+           /* convert hue to degrees */
+           hue *= 60.0;
+
+           /* make nonnegative */
            if (hue < 0.0)
-               hue += 360.0;
-           /*
-              set the HIS output values
-            */
-           rowbuffer[0][sample] = (unsigned char)(255.0 * hue / 360.0 + 0.5);
-           rowbuffer[1][sample] = (unsigned char)(intens * 255. + 0.5);
-           rowbuffer[2][sample] = (unsigned char)(sat * 255. + 0.5);
+               hue += 360.0;
+
+           /* HIS output values */
+           rowbuffer[0][sample] = (FCELL)hue;
+           rowbuffer[1][sample] = (FCELL)intensity;
+           rowbuffer[2][sample] = (FCELL)saturation;
        }
-    }
+  }
 }
_______________________________________________
grass-dev mailing list
[email protected]
http://lists.osgeo.org/mailman/listinfo/grass-dev

Reply via email to