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
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <unistd.h>
/* Convert sRGB to Linear RGB */
double srgb_to_linear(double value) {
if (value <= 0.04045) {
return value / 12.92;
} else {
return pow((value + 0.055) / 1.055, 2.4);
}
}
/* Convert Linear RGB to sRGB */
double linear_to_srgb(double value) {
if (value <= 0.0031308) {
return value * 12.92;
} else {
return 1.055 * pow(value, 1.0 / 2.4) - 0.055;
}
}
/* Interpolate between two colors in Linear RGB space */
void interpolate_color_linear(const char *color1, const char *color2, double t, char *output) {
unsigned int r1, g1, b1, r2, g2, b2;
sscanf(color1, "#%02x%02x%02x", &r1, &g1, &b1);
sscanf(color2, "#%02x%02x%02x", &r2, &g2, &b2);
// Convert sRGB to linear RGB
double lr1 = srgb_to_linear(r1 / 255.0);
double lg1 = srgb_to_linear(g1 / 255.0);
double lb1 = srgb_to_linear(b1 / 255.0);
double lr2 = srgb_to_linear(r2 / 255.0);
double lg2 = srgb_to_linear(g2 / 255.0);
double lb2 = srgb_to_linear(b2 / 255.0);
// Interpolate in linear RGB space
double lr = lr1 + t * (lr2 - lr1);
double lg = lg1 + t * (lg2 - lg1);
double lb = lb1 + t * (lb2 - lb1);
// Convert back to sRGB
unsigned int r = (unsigned int)(linear_to_srgb(lr) * 255.0);
unsigned int g = (unsigned int)(linear_to_srgb(lg) * 255.0);
unsigned int b = (unsigned int)(linear_to_srgb(lb) * 255.0);
// Format as hex output
snprintf(output, 8, "#%02x%02x%02x", r, g, b);
}
int main() {
/* Define the colors to cycle through */
const char *breathing_colors[] = {
"#ffe667", // Yellow
"#f27049", // Orange
"#3dd762", // Green
};
int color_count = sizeof(breathing_colors) / sizeof(breathing_colors[0]);
int current_index = 0;
double t = 0.0; // Interpolation factor
char current_color[8];
struct timespec ts = { 0, 5000000 }; // 5ms sleep
while (1) {
/* Interpolate the current color */
interpolate_color_linear(
breathing_colors[current_index],
breathing_colors[(current_index + 1) % color_count],
t,
current_color
);
/* Write the current color to a file */
FILE *f = fopen("/tmp/breathing_color", "w");
if (f) {
fprintf(f, "%s\n", current_color);
fclose(f);
}
/* Increment interpolation factor */
t += 0.005; // Adjust the speed of transition (smaller value = slower transition)
if (t >= 1.0) {
t = 0.0; // Reset interpolation
current_index = (current_index + 1) % color_count; // Move to the next color
}
/* Sleep for 5ms */
nanosleep(&ts, NULL);
}
return 0;
}
|