[elinks-dev] [Patch] rgb and hsl color converters

Jonas Fonseca fonseca at diku.dk
Mon Oct 6 03:34:56 PDT 2003


Stolen from gimp, elinksified by Zas and minor cleanup by me.

-- 
Jonas Fonseca
-------------- next part --------------
Index: util/color.c
===================================================================
RCS file: /home/cvs/elinks/elinks/src/util/color.c,v
retrieving revision 1.2
diff -u -d -r1.2 color.c
--- util/color.c	29 Aug 2003 17:28:46 -0000	1.2
+++ util/color.c	6 Oct 2003 10:29:30 -0000
@@ -269,3 +269,104 @@
 {
 	snprintf(str, 8, "#%06x", color);
 }
+
+#define ROUND(x)	((int) ((x) + 0.5))
+
+/* Converters borrowed from gimp sources, slightly modified by me (Zas). */
+void
+rgb_to_hsl(struct rgb *rgb, struct hsl *hsl)
+{
+	int min = int_min(rgb->r, int_min(rgb->g, rgb->b));
+	int max = int_max(rgb->r, int_max(rgb->g, rgb->b));
+	int sum = max + min;
+	double lightness = sum / 2.0;
+
+	if (max == min) {
+		hsl->saturation = 0;
+		hsl->hue = 0;
+	} else {
+		int delta = max - min;
+		double hue, saturation;
+
+		if (lightness < 128) {
+			saturation = 255 * (double) delta / (double) sum;
+		} else {
+			saturation = 255 * (double) delta / (double) (511 - sum);
+		}
+
+		if (rgb->r == max) {
+			hue = (rgb->g - rgb->b) / (double) delta;
+		} else if (rgb->g == max) {
+			hue = 2 + (rgb->b - rgb->r) / (double) delta;
+		} else {
+			hue = 4 + (rgb->r- rgb->g) / (double) delta;
+		}
+
+		hue *= 42.5;
+
+		if (hue < 0) {
+			hue += 255;
+		} else if (hue > 255) {
+			hue -= 255;
+		}
+
+		hsl->hue = ROUND(hue);
+		hsl->saturation = ROUND(saturation);
+	}
+
+	hsl->lightness = ROUND(lightness);
+}
+
+static int
+hsl_value(double n1, double n2, double hue)
+{
+	double value;
+
+	if (hue > 255) {
+		hue -= 255;
+	} else if (hue < 0) {
+		hue += 255;
+	}
+
+	if (hue < 42.5) {
+		value = n1 + (n2 - n1) * (hue / 42.5);
+	} else if (hue < 127.5) {
+		value = n2;
+	} else if (hue < 170) {
+		value = n1 + (n2 - n1) * ((170 - hue) / 42.5);
+	} else {
+		value = n1;
+	}
+
+	return ROUND(value * 255.0);
+}
+
+void
+hsl_to_rgb(struct hsl *hsl, struct rgb *rgb)
+{
+	if (hsl->saturation == 0) {
+		/*  achromatic case  */
+		rgb->r = hsl->lightness;
+		rgb->g = hsl->lightness;
+		rgb->b = hsl->lightness;
+	} else {
+		double hue = hsl->hue;
+		double saturation = hsl->saturation;
+		double lightness = hsl->lightness;
+		double m1, m2;
+
+		if (lightness < 128) {
+			m2 = (lightness * (255 + saturation)) / 65025.0;
+		} else {
+			m2 = lightness + saturation;
+			m2 -= ((lightness * saturation) / 255.0) / 255.0;
+		}
+
+		m1 = (lightness / 127.5) - m2;
+
+		/*  chromatic case  */
+		rgb->r = hsl_value(m1, m2, hue + 85);
+		rgb->g = hsl_value(m1, m2, hue);
+		rgb->b = hsl_value(m1, m2, hue - 85);
+	}
+}
Index: util/color.h
===================================================================
RCS file: /home/cvs/elinks/elinks/src/util/color.h,v
retrieving revision 1.3
diff -u -d -r1.3 color.h
--- util/color.h	31 Aug 2003 12:48:36 -0000	1.3
+++ util/color.h	6 Oct 2003 10:29:30 -0000
@@ -21,6 +21,11 @@
 	unsigned char pad;
 };
 
+struct hsl {
+	unsigned char hue, saturation, lightness;
+	unsigned char pad;
+};
+
 /* Initialize a rgb strubt from a color_t */
 #define INIT_RGB(color) \
 	{ RED_COLOR(color), GREEN_COLOR(color), BLUE_COLOR(color) }


More information about the elinks-dev mailing list