colourpicker

Simple Colour Picker written in C
git clone anongit@rnpnr.xyz:colourpicker.git
Log | Files | Refs | Feed | Submodules | README | LICENSE

Commit: a3bc85c284d6f114aa54eb16bc32cc5a37c95a19
Parent: 2474058570b92f13747294e04fbb851ab5b2ab6a
Author: Randy Palamar
Date:   Wed, 24 Jul 2024 21:23:32 -0600

allow colours to be specified via commandline

Diffstat:
Mmain.c | 68+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Mutil.c | 14++++++++++++++
2 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/main.c b/main.c @@ -3,6 +3,7 @@ #include <fcntl.h> #include <raylib.h> #include <stdio.h> +#include <stdlib.h> #include <sys/stat.h> #include <unistd.h> @@ -68,8 +69,45 @@ static void do_debug(void) { } #endif /* _DEBUG */ +static void __attribute__((noreturn)) +usage(char *argv0) +{ + exit(1); +} + +static f32 +parse_f32(char *s) +{ + return atof(s); +} + +static u32 +parse_u32(char *s) +{ + u32 res = 0; + + /* NOTE: skip over '0x' or '0X' */ + if (*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X')) + s += 2; + + for (; *s; s++) { + res <<= 4; + if (ISDIGIT(*s)) { + res |= *s - '0'; + } else if (ISHEX(*s)) { + /* NOTE: convert to lowercase first then convert to value */ + *s |= 0x20; + res |= *s - 0x57; + } else { + /* TODO: invalid input */ + ASSERT(0); + } + } + return res; +} + int -main(void) +main(i32 argc, char *argv[]) { ColourPickerCtx ctx = { .window_size = { .w = 720, .h = 960 }, @@ -91,10 +129,38 @@ main(void) { .r = 0.59, .g = 0.11, .b = 0.25, .a = 1.00 }, { .r = 0.11, .g = 0.59, .b = 0.36, .a = 1.00 }, { .r = 0.14, .g = 0.29, .b = 0.72, .a = 1.00 }, + /* TODO: add 3 more defaults */ }, }, }; + { + v4 rgb = hsv_to_rgb(ctx.colour); + for (i32 i = 1; i < argc; i++) { + if (argv[i][0] == '-') { + if (!argv[i + 1] || !ISDIGIT(argv[i + 1][0]) || + (argv[i][1] == 'h' && !ISHEX(argv[i + 1][0]))) + usage(argv[0]); + + switch (argv[i][1]) { + case 'h': + rgb = normalize_colour(parse_u32(argv[i + 1])); + ctx.colour = rgb_to_hsv(rgb); + break; + case 'r': rgb.r = parse_f32(argv[i + 1]); break; + case 'g': rgb.g = parse_f32(argv[i + 1]); break; + case 'b': rgb.b = parse_f32(argv[i + 1]); break; + case 'a': rgb.a = parse_f32(argv[i + 1]); break; + default: usage(argv[0]); break; + } + i++; + } else { + usage(argv[0]); + } + } + ctx.colour = rgb_to_hsv(rgb); + } + #ifndef _DEBUG SetTraceLogLevel(LOG_NONE); #endif diff --git a/util.c b/util.c @@ -87,6 +87,9 @@ typedef struct { #define ABS(x) ((x) < 0 ? (-x) : (x)) #define CLAMP(x, a, b) ((x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x)) +#define ISDIGIT(a) ((a) >= '0' && (a) <= '9') +#define ISHEX(a) (ISDIGIT(a) || ((a) >= 'a' && (a) <= 'f') || ((a) >= 'A' && (a) <= 'F')) + static Color colour_from_normalized(v4 colour) { @@ -99,6 +102,17 @@ colour_from_normalized(v4 colour) } static v4 +normalize_colour(u32 rgba) +{ + return (v4){ + .r = ((rgba >> 24) & 0xFF) / 255.0f, + .g = ((rgba >> 16) & 0xFF) / 255.0f, + .b = ((rgba >> 8) & 0xFF) / 255.0f, + .a = ((rgba >> 0) & 0xFF) / 255.0f, + }; +} + +static v4 rgb_to_hsv(v4 rgb) { __m128 rgba = _mm_loadu_ps(rgb.E);