1
1
use cgmath:: Vector4 ;
2
2
3
+ pub fn ftoi ( v : f32 ) -> u8 {
4
+ ( v * 255. ) . round ( ) as u8
5
+ }
6
+
7
+ pub fn itof ( v : u8 ) -> f32 {
8
+ ( v as f32 ) / 255.
9
+ }
10
+
3
11
pub fn modulus ( a : f32 , b : f32 ) -> f32 {
4
12
( ( a % b) + b) % b
5
13
}
@@ -10,50 +18,36 @@ pub fn float_equals(a: f32, b: f32) -> bool {
10
18
}
11
19
12
20
pub fn rgb2hsv ( rgb : Vector4 < u8 > ) -> Vector4 < f32 > {
13
- let r = ( rgb[ 0 ] as f32 ) / 255f32 ;
14
- let g = ( rgb[ 1 ] as f32 ) / 255f32 ;
15
- let b = ( rgb[ 2 ] as f32 ) / 255f32 ;
16
- let a = ( rgb[ 3 ] as f32 ) / 255f32 ;
21
+ let ( r, g, b, a) =
22
+ ( itof ( rgb[ 0 ] ) , itof ( rgb[ 1 ] ) , itof ( rgb[ 2 ] ) , itof ( rgb[ 3 ] ) ) ;
17
23
18
24
// max of rgb is equivalent to V in HSV
19
- let mut max = r;
20
- if g > max {
21
- max = g
22
- }
23
- if b > max {
24
- max = b
25
- }
25
+ let max = r. max ( g) . max ( b) ;
26
26
27
27
// min of rgb is V - C where C is chroma (range)
28
- let mut min = r;
29
- if g < min {
30
- min = g
31
- }
32
- if b < min {
33
- min = b
34
- }
28
+ let min = r. min ( g) . min ( b) ;
35
29
36
30
let mid = max - min;
37
31
38
- let mut hue = if float_equals ( mid, 0f32 ) {
39
- 0f32
32
+ let mut hue = if float_equals ( mid, 0. ) {
33
+ 0.
40
34
} else if float_equals ( max, r) {
41
- modulus ( ( g - b) / mid, 6f32 )
35
+ modulus ( ( g - b) / mid, 6. )
42
36
} else if float_equals ( max, g) {
43
- ( b - r) / mid + 2f32
37
+ ( b - r) / mid + 2.
44
38
} else if float_equals ( max, b) {
45
- ( r - g) / mid + 4f32
39
+ ( r - g) / mid + 4.
46
40
} else {
47
- 0f32
41
+ 0.
48
42
} ;
49
43
50
44
hue *= std:: f32:: consts:: PI / 3f32 ;
51
- if hue < 0f32 {
52
- hue += 2f32 * std:: f32:: consts:: PI
45
+ if hue < 0. {
46
+ hue += 2. * std:: f32:: consts:: PI
53
47
}
54
48
55
- let saturation = if float_equals ( max, 0f32 ) {
56
- 0f32
49
+ let saturation = if float_equals ( max, 0. ) {
50
+ 0.
57
51
} else {
58
52
mid / max
59
53
} ;
@@ -62,11 +56,13 @@ pub fn rgb2hsv(rgb: Vector4<u8>) -> Vector4<f32> {
62
56
}
63
57
64
58
fn color_conversion ( color : u8 ) -> u8 {
65
- if ( color as f64 / 255.0 ) > 0.04045 {
66
- ( ( ( ( color as f64 / 255.0 ) / 1.055 ) + 0.052_132_7 ) . powf ( 2.4 ) * 255.0 ) as u8
59
+ let color = itof ( color) ;
60
+ let c = if color > 0.04045 {
61
+ ( ( color / 1.055 ) + 0.052_132_7 ) . powf ( 2.4 )
67
62
} else {
68
- ( ( color as f64 / 255.0 ) / 12.92 * 255.0 ) as u8
69
- }
63
+ color / 12.92
64
+ } ;
65
+ ftoi ( c)
70
66
}
71
67
72
68
pub fn gamma_correct ( rgb : Vector4 < u8 > ) -> Vector4 < u8 > {
@@ -79,69 +75,60 @@ pub fn gamma_correct(rgb: Vector4<u8>) -> Vector4<u8> {
79
75
}
80
76
81
77
pub fn hsv2rgb ( hsv : Vector4 < f32 > ) -> Vector4 < u8 > {
82
- let hue = hsv[ 0 ] * 180f32 / std:: f32:: consts:: PI ;
78
+ let hue = hsv[ 0 ] * 180. / std:: f32:: consts:: PI ;
83
79
let saturation = hsv[ 1 ] ;
84
80
let value = hsv[ 2 ] ;
85
81
86
82
let chroma = value * saturation;
87
- let x = chroma * ( 1f32 - ( modulus ( hue / 60f32 , 2f32 ) - 1f32 ) . abs ( ) ) ;
83
+ let x = chroma * ( 1f32 - ( modulus ( hue / 60. , 2f32 ) - 1f32 ) . abs ( ) ) ;
88
84
let match_value = value - chroma;
89
85
90
86
let ( r, g, b) = match hue {
91
- hh if hh < 60f32 => ( chroma, x, 0f32 ) ,
92
- hh if hh < 120f32 => ( x, chroma, 0f32 ) ,
93
- hh if hh < 180f32 => ( 0f32 , chroma, x) ,
94
- hh if hh < 240f32 => ( 0f32 , x, chroma) ,
95
- hh if hh < 300f32 => ( x, 0f32 , chroma) ,
96
- hh if hh < 360f32 => ( chroma, 0f32 , x) ,
97
- _ => ( 0f32 , 0f32 , 0f32 ) ,
87
+ hh if hh < 60. => ( chroma, x, 0. ) ,
88
+ hh if hh < 120. => ( x, chroma, 0. ) ,
89
+ hh if hh < 180. => ( 0. , chroma, x) ,
90
+ hh if hh < 240. => ( 0. , x, chroma) ,
91
+ hh if hh < 300. => ( x, 0. , chroma) ,
92
+ hh if hh < 360. => ( chroma, 0. , x) ,
93
+ _ => ( 0. , 0. , 0. ) ,
98
94
} ;
99
95
100
96
Vector4 :: new (
101
- ( ( r + match_value) * 255f32 ) as u8 ,
102
- ( ( g + match_value) * 255f32 ) as u8 ,
103
- ( ( b + match_value) * 255f32 ) as u8 ,
104
- ( hsv[ 3 ] * 255f32 ) as u8 ,
97
+ ( ( r + match_value) * 255. ) as u8 ,
98
+ ( ( g + match_value) * 255. ) as u8 ,
99
+ ( ( b + match_value) * 255. ) as u8 ,
100
+ ( hsv[ 3 ] * 255. ) as u8 ,
105
101
)
106
102
}
107
103
108
104
pub fn hsv_distance ( a : & Vector4 < f32 > , b : & Vector4 < f32 > ) -> f32 {
109
- // (a.x - b.x).powf(2.0) * 8./21.
110
- // + (a.y - b.y).powf(2.0) * 5./21.
111
- // + (a.z - b.z).powf(2.0) * 4./21.
112
- // + (a.w - b.w).powf(2.0) * 4./21.
113
-
114
105
( a. x . sin ( ) * a. y - b. x . sin ( ) * b. y ) . powf ( 2.0 )
115
106
+ ( a. x . cos ( ) * a. y - b. x . cos ( ) * b. y ) . powf ( 2.0 )
116
107
+ ( a. z - b. z ) . powf ( 2.0 )
117
108
+ ( a. w - b. w ) . powf ( 2.0 )
118
109
}
119
110
120
111
pub fn hsv_average ( colors : & [ Vector4 < u8 > ] ) -> Vector4 < f32 > {
121
- let n = colors. len ( ) as f32 ;
122
- let mut h_avg = 0f32 ;
123
- let mut s_avg = 0f32 ;
124
- let mut v_avg = 0f32 ;
125
- let mut a_avg = 0f32 ;
126
-
112
+ let ( mut h_sum, mut s_sum, mut v_sum, mut a_sum) = ( 0. , 0. , 0. , 0. ) ;
127
113
for c in colors {
128
114
let color = rgb2hsv ( * c) ;
129
- h_avg += color. x ;
130
- s_avg += color. y ;
131
- v_avg += color. z ;
132
- a_avg += color. w ;
115
+ h_sum += color. x ;
116
+ s_sum += color. y ;
117
+ v_sum += color. z ;
118
+ a_sum += color. w ;
133
119
}
134
120
135
- Vector4 :: < f32 > :: new ( h_avg / n, s_avg / n, v_avg / n, a_avg / n)
121
+ let n = colors. len ( ) as f32 ;
122
+ Vector4 :: < f32 > :: new ( h_sum / n, s_sum / n, v_sum / n, a_sum / n)
136
123
}
137
124
138
125
pub fn convert_colorset_to_hsv ( colorset : & [ brickadia:: save:: Color ] ) -> Vec < Vector4 < f32 > > {
139
- let mut new = Vec :: < Vector4 < f32 > > :: with_capacity ( colorset. len ( ) ) ;
126
+ let mut converted_colorset = Vec :: < Vector4 < f32 > > :: with_capacity ( colorset. len ( ) ) ;
140
127
for c in colorset {
141
- new . push ( rgb2hsv ( Vector4 :: new ( c. r , c. g , c. b , c. a ) ) ) ;
128
+ converted_colorset . push ( rgb2hsv ( Vector4 :: new ( c. r , c. g , c. b , c. a ) ) ) ;
142
129
}
143
130
144
- new
131
+ converted_colorset
145
132
}
146
133
147
134
pub fn match_hsv_to_colorset ( colorset : & [ Vector4 < f32 > ] , color : & Vector4 < f32 > ) -> usize {
0 commit comments