/*********************************************************/ /* program 3: convert RGB from/to HSV */ /* */ /* note: no main program is supplied for this example, */ /* only the routines to perform the conversions. */ /*********************************************************/ #define UNDEFINED 999.0 void rgb2hsv(); void hsv2rgb(); /***********************************************/ /* rgb2hsv: RGB-to-HSV conversion */ /***********************************************/ void rgb2hsv(r,g,b,h,s,v) int r,g,b; float *h,*s,*v; { float min,max; float rc,gc,bc; /* determine maximum of R,G,B */ if ((r >= g) && (r >= b)) max = (float)r; if ((g >= r) && (g >= b)) max = (float)g; if ((b >= r) && (b >= g)) max = (float)b; /* determine minimum of R,G,B */ if ((r <= g) && (r <= b)) min = (float)r; if ((g <= r) && (g <= b)) min = (float)g; if ((b <= r) && (b <= g)) min = (float)b; /* calculate V (simply maximum of R,G,B) */ *v = max; /* calculate S (if RGB is black, saturation is 0) */ if (max != 0) *s = (max-min) / max; else *s = 0.0; /* calculate H (if no saturation, hue is undefined) */ if (*s == 0) { *h = UNDEFINED; } else { rc = (max - ((float)r / 255.0)) / (max - min); gc = (max - ((float)g / 255.0)) / (max - min); bc = (max - ((float)b / 255.0)) / (max - min); if (r == (unsigned char)max) *h = bc - gc; /* hue between yellow and magenta */ else if (g == (unsigned char)max) *h = 2.0 + rc - bc; /* hue between cyan and yellow */ else *h = 4.0 + gc - rc; /* hue between magenta and cyan */ *h = *h * 60.0; /* convert to degrees */ if (*h < 0.0) *h = *h + 360.0; /* make non-negative */ } return; } /***********************************************/ /* hsv2rgb: HSV-to-RGB conversion */ /***********************************************/ void hsv2rgb(h,s,v,r,g,b) float h,s,v; int *r,*g,*b; { long int i; float hh; float f,p,q,t; if (s == 0) { if (h == UNDEFINED) { *r = (unsigned char)v; /* achromatic, RGB is grey scale */ *g = (unsigned char)v; *b = (unsigned char)v; } else { *r = 0; /* ERROR! this should never occur */ *g = 0; *b = 0; } } else { hh = h; if (hh == 360) hh = 0; hh = hh / 60.0; i = (long)hh; f = hh - (float)i; p = v * (1.0 - s); q = v * (1.0 - (s * f)); t = v * (1.0 - (s * (1.0 - f))); switch(i) { case 0: *r = (unsigned char) (v * 255.0); *g = (unsigned char) (t * 255.0); *b = (unsigned char) (p * 255.0); break; case 1: *r = (unsigned char) (q * 255.0); *g = (unsigned char) (v * 255.0); *b = (unsigned char) (p * 255.0); break; case 2: *r = (unsigned char) (p * 255.0); *g = (unsigned char) (v * 255.0); *b = (unsigned char) (t * 255.0); break; case 3: *r = (unsigned char) (p * 255.0); *g = (unsigned char) (q * 255.0); *b = (unsigned char) (v * 255.0); break; case 4: *r = (unsigned char) (t * 255.0); *g = (unsigned char) (p * 255.0); *b = (unsigned char) (v * 255.0); break; case 5: *r = (unsigned char) (v * 255.0); *g = (unsigned char) (p * 255.0); *b = (unsigned char) (q * 255.0); break; default: break; } } return; }