162 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			162 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  *		FloatImg library
 | |
|  *		HUE - SATURATION - VALUE
 | |
| 
 | |
|        +---------------------------------------------+
 | |
|        |    ce code ne fonctionne vraiment PAS !     |
 | |
|        +---------------------------------------------+
 | |
| 
 | |
|  */
 | |
| 
 | |
| #include  <stdio.h>
 | |
| #include  <stdlib.h>
 | |
| #include  <string.h>
 | |
| #include  <math.h>
 | |
| #include  "../floatimg.h"
 | |
| 
 | |
| extern int		verbosity;
 | |
| 
 | |
| /* --------------------------------------------------------------------- */
 | |
| /*	helper functions						 */
 | |
| static float maxi3f(float a, float b, float c)
 | |
| {
 | |
| return ((a > b)? (a > c ? a : c) : (b > c ? b : c));
 | |
| }
 | |
| static float mini3f(float a, float b, float c)
 | |
| {
 | |
| return ((a < b)? (a < c ? a : c) : (b < c ? b : c));
 | |
| }
 | |
| static int pseudoeq(float a, float b)
 | |
| {
 | |
| return (fabsf(a-b)<0.00000000000001);		// UGLY HACK ???
 | |
| }
 | |
| /* --------------------------------------------------------------------- */
 | |
| /*
 | |
|  *		WARNING : ALL THIS CODE IS STRANGE
 | |
|  *
 | |
| 
 | |
| www.tutorialspoint.com/c-program-to-change-rgb-color-model-to-hsv-color-model
 | |
| 
 | |
|  */
 | |
| int fimg_rgb2hsv(float rgb[3], float hsv[3], float scale)
 | |
| {
 | |
| // float		h, s, v;
 | |
| float		cmin, cmax, diff;
 | |
| 
 | |
| // scale input value to [0..1]
 | |
| rgb[0] /= scale; rgb[1] /= scale; rgb[2] /= scale;
 | |
| 
 | |
| hsv[0] =  hsv[1] =  hsv[2] = -12345.6789;
 | |
| 
 | |
| cmin = mini3f(rgb[0], rgb[1], rgb[2]);
 | |
| cmax = maxi3f(rgb[0], rgb[1], rgb[2]);
 | |
| diff = cmax - cmin;
 | |
| 
 | |
| if (pseudoeq(cmax, cmin))		hsv[0] = 0.0;
 | |
| else if (pseudoeq(cmax, rgb[0]))
 | |
| 	hsv[0] = fmod((60 * ((rgb[1] - rgb[2]) / diff) + 360), 360.0);
 | |
| else if (pseudoeq(cmax, rgb[1]))
 | |
| 	hsv[0] = fmod((60 * ((rgb[2] - rgb[0]) / diff) + 120), 360.0);
 | |
| else if (pseudoeq(cmax, rgb[2]))
 | |
| 	hsv[0] = fmod((60 * ((rgb[0] - rgb[1]) / diff) + 240), 360.0);
 | |
| 
 | |
| if (pseudoeq(cmax, 0.0))	hsv[1] = 0.0;
 | |
| else				hsv[1] = (diff / cmax) / 100.0;
 | |
| 
 | |
| hsv[2] = cmax * 100.0;		/* WHAT THE FUCK ? */
 | |
| 
 | |
| #if DEBUG_LEVEL
 | |
| fprintf(stderr, "cmin/cmax   %f   %f\n", cmin, cmax);
 | |
| #endif
 | |
| 
 | |
| return 0;
 | |
| }
 | |
| /* --------------------------------------------------------------------- */
 | |
| int fimg_hsv2rgb(float hsv[3], float rgb[3], float scale)
 | |
| {
 | |
| float		hh, ff, p, q, t;
 | |
| long		i;
 | |
| 
 | |
| if(hsv[1] <= 0.0) {       // < is bogus, just shuts up warnings
 | |
|         rgb[0] = rgb[1] = rgb[2] = hsv[2];
 | |
|         return 0;
 | |
| 	}
 | |
| 
 | |
|     hh = hsv[0];
 | |
|     if(hh >= 360.0) hh = 0.0;
 | |
|     hh /= 60.0;
 | |
|     i = (long)hh;
 | |
|     ff = hh - i;
 | |
|     p = hsv[2] * (1.0 -  hsv[1]);
 | |
|     q = hsv[2] * (1.0 - (hsv[1] * ff));
 | |
|     t = hsv[2] * (1.0 - (hsv[1] * (1.0 - ff)));
 | |
| 
 | |
| switch(i) {
 | |
|     case 0:
 | |
| 	rgb[0] = hsv[2];	rgb[1] = t;		rgb[2] = p;
 | |
| 	break;
 | |
|     case 1:
 | |
| 	rgb[0] = q;		rgb[1] = hsv[2];	rgb[2] = p;
 | |
| 	break;
 | |
|     case 2:
 | |
| 	rgb[0] = p;		rgb[1] = hsv[2];	rgb[2] = t;
 | |
| 	break;
 | |
|     case 3:
 | |
| 	rgb[0] = p;		rgb[1] = q;		rgb[2] = hsv[2];
 | |
| 	break;
 | |
|     case 4:
 | |
| 	rgb[0] = t;		rgb[1] = p;		rgb[2] = hsv[2];
 | |
| 	break;
 | |
|     case 5:
 | |
|     default:
 | |
| 	rgb[0] = hsv[2];	rgb[1] = p; 		rgb[2] = q;
 | |
|         break;
 | |
|     }
 | |
| return 0;
 | |
| }
 | |
| 
 | |
| /* --------------------------------------------------------------------- */
 | |
| /*
 | |
|  *		expect garbage !
 | |
|  */
 | |
| int fimg_essai_hsv(char *fname)
 | |
| {
 | |
| float		colors[3], values[3], newcols[3];
 | |
| int		foo, r, g, b;
 | |
| 
 | |
| #define INC  16
 | |
| for (r=0; r<255; r+=INC) {
 | |
|  for (g=0; g<255; g+=INC) {
 | |
|   for (b=0; b<255; b+=INC) {
 | |
| 
 | |
| 	printf("%4d %4d %4d  ", r, g, b);
 | |
| 
 | |
| 	colors[0] = (float)r;
 | |
| 	colors[1] = (float)g;
 | |
| 	colors[2] = (float)b;
 | |
| 	foo = fimg_rgb2hsv(colors, values, 255.0);
 | |
| 	if (foo) {
 | |
| 		fprintf(stderr, "%s: err %d in rgv->hsv\n", __func__, foo);
 | |
| 		exit(1);
 | |
| 		}
 | |
| 
 | |
| 	printf("   %8.4f %8.4f %8.4f   ",
 | |
| 			values[0], values[1], values[2]);
 | |
| 
 | |
| 	foo = fimg_hsv2rgb(values, newcols, 255.0);
 | |
| 	if (foo) {
 | |
| 		fprintf(stderr, "%s: err %d in hsv->rgb\n", __func__, foo);
 | |
| 		exit(1);
 | |
| 		}
 | |
| 
 | |
| 	printf("   %8.4f %8.4f %8.4f\n",
 | |
| 			newcols[0], newcols[1], newcols[2]);
 | |
| 
 | |
| 	}
 | |
|  }
 | |
| }
 | |
| 
 | |
| return -1;
 | |
| }
 | |
| /* --------------------------------------------------------------------- */
 |