Browse Source

Rast_log_colors: Another attempt to address r.colors -g/-a (#1480) (#1937)

* color_xform: Another attempt to address r.colors -g/-a (#1480)

* Fix absolute log

* Add a comment
Huidae Cho 3 years ago
parent
commit
6376395ce8
1 changed files with 39 additions and 16 deletions
  1. 39 16
      lib/raster/color_xform.c

+ 39 - 16
lib/raster/color_xform.c

@@ -3,9 +3,9 @@
  *
  *
  * \brief Raster Library - Colors management
  * \brief Raster Library - Colors management
  *
  *
- * (C) 2001-2009 by the GRASS Development Team
+ * (C) 2001-2021 by the GRASS Development Team
  *
  *
- * This program is free software under the GNU General Public License 
+ * This program is free software under the GNU General Public License
  * (>=v2). Read the file COPYING that comes with GRASS for details.
  * (>=v2). Read the file COPYING that comes with GRASS for details.
  *
  *
  * \author Original author CERL
  * \author Original author CERL
@@ -185,7 +185,7 @@ void Rast_histogram_eq_fp_colors(struct Colors *dst,
 void Rast_log_colors(struct Colors *dst, struct Colors *src, int samples)
 void Rast_log_colors(struct Colors *dst, struct Colors *src, int samples)
 {
 {
     DCELL min, max;
     DCELL min, max;
-    double lmin, lmax;
+    double delta, lmin, lmax;
     int red, grn, blu;
     int red, grn, blu;
     DCELL prev;
     DCELL prev;
     int i;
     int i;
@@ -194,8 +194,17 @@ void Rast_log_colors(struct Colors *dst, struct Colors *src, int samples)
 
 
     Rast_get_d_color_range(&min, &max, src);
     Rast_get_d_color_range(&min, &max, src);
 
 
-    lmin = log(min);
-    lmax = log(max);
+    if (min <= 0.0) {
+	/* shift cell values by 1 - min so that they are in [1, max - min + 1]
+	 */
+	delta = 1 - min;
+	lmin = log(min + delta);
+	lmax = log(max + delta);
+    } else {
+	delta = 0;
+	lmin = log(min);
+	lmax = log(max);
+    }
 
 
     Rast_get_default_color(&red, &grn, &blu, src);
     Rast_get_default_color(&red, &grn, &blu, src);
     Rast_set_default_color(red, grn, blu, dst);
     Rast_set_default_color(red, grn, blu, dst);
@@ -217,7 +226,8 @@ void Rast_log_colors(struct Colors *dst, struct Colors *src, int samples)
 	    x = max;
 	    x = max;
 	else {
 	else {
 	    lx = lmin + (lmax - lmin) * i / samples;
 	    lx = lmin + (lmax - lmin) * i / samples;
-	    x = exp(lx);
+	    /* restore cell values approximately */
+	    x = exp(lx) - delta;
 	}
 	}
 
 
 	if (i > 0)
 	if (i > 0)
@@ -243,8 +253,7 @@ void Rast_log_colors(struct Colors *dst, struct Colors *src, int samples)
 void Rast_abs_log_colors(struct Colors *dst, struct Colors *src, int samples)
 void Rast_abs_log_colors(struct Colors *dst, struct Colors *src, int samples)
 {
 {
     DCELL min, max;
     DCELL min, max;
-    double lmin, lmax;
-    DCELL amax, lamax;
+    double absmin, absmax, amin, amax, delta, lamin, lamax;
     int red, grn, blu;
     int red, grn, blu;
     DCELL prev;
     DCELL prev;
     int i;
     int i;
@@ -253,11 +262,24 @@ void Rast_abs_log_colors(struct Colors *dst, struct Colors *src, int samples)
 
 
     Rast_get_d_color_range(&min, &max, src);
     Rast_get_d_color_range(&min, &max, src);
 
 
-    lmin = log(fabs(min) + 1.0);
-    lmax = log(fabs(max) + 1.0);
-
-    amax = fabs(min) > fabs(max) ? fabs(min) : fabs(max);
-    lamax = lmin > lmax ? lmin : lmax;
+    absmin = fabs(min);
+    absmax = fabs(max);
+    amin = MIN(absmin, absmax);
+    amax = MAX(absmin, absmax);
+
+    if (min * max <= 0.0) {
+	/* 0 <= abs(cell) <= amax */
+	amin = 0;
+	/* use the same shifting for Rast_log_colors */
+	delta = 1 - amin;
+	lamin = log(amin + delta);
+	lamax = log(amax + delta);
+    } else {
+	/* 0 < amin <= abs(cell) <= amax */
+	delta = 0;
+	lamin = log(amin);
+	lamax = log(amax);
+    }
 
 
     Rast_get_default_color(&red, &grn, &blu, src);
     Rast_get_default_color(&red, &grn, &blu, src);
     Rast_set_default_color(red, grn, blu, dst);
     Rast_set_default_color(red, grn, blu, dst);
@@ -274,12 +296,13 @@ void Rast_abs_log_colors(struct Colors *dst, struct Colors *src, int samples)
 	Rast_get_d_color(&y, &red2, &grn2, &blu2, src);
 	Rast_get_d_color(&y, &red2, &grn2, &blu2, src);
 
 
 	if (i == 0)
 	if (i == 0)
-	    x = 1;
+	    x = amin;
 	else if (i == samples)
 	else if (i == samples)
 	    x = amax;
 	    x = amax;
 	else {
 	else {
-	    lx = 0 + lamax * i / samples;
-	    x = exp(lx);
+	    lx = lamin + (lamax - lamin) * i / samples;
+	    /* restore cell values approximately */
+	    x = exp(lx) - delta;
 	}
 	}
 
 
 	if (i > 0) {
 	if (i > 0) {