1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
////////////////////////////////////////////////////////
//
// GEM - Graphics Environment for Multimedia
//
// mark@danks.org
//
// Copyright (c) 1997-1999 Mark Danks.
// For information on usage and redistribution, and for a DISCLAIMER OF ALL
// WARRANTIES, see the file, "LICENSE.txt" in this distribution.
//
/////////////////////////////////////////////////////////
#include "m_pd.h"
#include <math.h>
static inline float FLOAT_CLAMP(float x) { return((x > 1.f) ? 1.f : ( (x < 0.f) ? 0.f : x)); }
/////////////////////////////////////////////////////////
//
// hsv2rgb
//
/////////////////////////////////////////////////////////
// instance structure
static t_class *hsv2rgb_class;
typedef struct _hsv2rgb
{
t_object x_obj; // obligatory object header
t_outlet *t_out1; // the outlet
}t_hsv2rgb;
static void hsv2rgb_float(t_hsv2rgb *x, t_floatarg h, t_floatarg s, t_floatarg v)
{
t_atom argv[3];
float r=0, g=0, b=0;
h = FLOAT_CLAMP(h);
s = FLOAT_CLAMP(s);
v = FLOAT_CLAMP(v);
// convert hue to degrees
h *= 360.f;
if (s == 0.0) // black and white
{
r = g = b = v;
}
else
{
if (h == 360.0) // 360 == 0 degrees
h = 0.0f;
h /= 60.0f; // hue is now [0, 6]
{
int i = (int)floor(h);
float f = h - i; // f is the fractional part of h
float p = v * (1 - s);
float q = v * (1 - s * f);
float t = v * (1 - s * (1 - f));
switch (i)
{
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
case 5:
r = v;
g = p;
b = q;
break;
}
}
}
SETFLOAT(&argv[0], r);
SETFLOAT(&argv[1], g);
SETFLOAT(&argv[2], b);
outlet_list(x->t_out1, &s_list, 3, argv);
}
static void hsv2rgb_list(t_hsv2rgb *x, t_symbol *sym, int argc, t_atom *argv)
{
if (argc >= 3)
{
float h = atom_getfloat(&argv[0]);
float s = atom_getfloat(&argv[1]);
float v = atom_getfloat(&argv[2]);
hsv2rgb_float(x, h, s, v);
}
}
static void *hsv2rgb_new(void) // init vals in struct
{
t_hsv2rgb *x = (t_hsv2rgb *)pd_new(hsv2rgb_class);
x->t_out1 = outlet_new(&x->x_obj, 0);
return (x);
}
void hsv2rgb_setup(void)
{
hsv2rgb_class = class_new(gensym("hsv2rgb"), (t_newmethod)hsv2rgb_new, 0,
sizeof(t_hsv2rgb), CLASS_DEFAULT, A_NULL);
class_addlist(hsv2rgb_class, (t_method)hsv2rgb_list);
}
|