/* $Id$ */ /* * Copyright (c) 2014 Dimitri Sokolyuk * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * input: H 0..360, S 0..100, V 0..100 * output: R, G, B 0..65535 */ #include #include #include #include #include "cms.h" #if 0 static void hsv2rgb(unsigned short *r, unsigned short *g, unsigned short *b, double h, double s, double v) { double F, M, N, K; int i; /* normalize */ h /= 360.0; s /= 100.0; v /= 100.0; if (s > 0.0) { if (h >= 1.0) h -= 1.0; h *= 6.0; i = (int)h; F = h - i; M = v * (1 - s); N = v * (1 - s * F); K = v * (1 - s * (1 - F)); /* scale up */ v *= UINT16_MAX; M *= UINT16_MAX; K *= UINT16_MAX; N *= UINT16_MAX; switch (i) { case 0: *r = v; *g = K; *b = M; break; case 1: *r = N; *g = v; *b = M; break; case 2: *r = M; *g = v; *b = K; break; case 3: *r = M; *g = N; *b = v; break; case 4: *r = K; *g = M; *b = v; break; case 5: *r = v; *g = M; *b = N; break; } } else { *r = *g = *b = UINT16_MAX * v; } } #endif /* * input: H 0..360, S 0..100, L 0..100 * output: R, G, B 0..65535 */ static void hsl2rgb(unsigned short *r, unsigned short *g, unsigned short *b, double h, double s, double l) { double v, F, M, K, N; int i; /* normalize */ h /= 360.0; s /= 100.0; l /= 100.0; v = (l <= 0.5) ? (l + l * s) : (l - l * s + s); if (v > 0.0) { if (h >= 1.0) h -= 1.0; h *= 6.0; i = (int)h; F = h - i; M = l + l - v; K = M + F * (v - M); N = v - F * (v - M); /* scale up */ v *= UINT16_MAX; M *= UINT16_MAX; K *= UINT16_MAX; N *= UINT16_MAX; switch (i) { case 0: *r = v; *g = K; *b = M; break; case 1: *r = N; *g = v; *b = M; break; case 2: *r = M; *g = v; *b = K; break; case 3: *r = M; *g = N; *b = v; break; case 4: *r = K; *g = M; *b = v; break; case 5: *r = v; *g = M; *b = N; break; } } else { *r = *g = *b = UINT16_MAX * l; } } unsigned long hslcolor(Display *d, double h, double s, double l) { int scr = DefaultScreen(d); Colormap cmap = DefaultColormap(d, scr); XColor c; hsl2rgb(&c.red, &c.green, &c.blue, h, s, l); c.flags = DoRed|DoGreen|DoBlue; XAllocColor(d, cmap, &c); return c.pixel; } unsigned long * init_palette(Display *d, struct palette pal, int n) { unsigned long *p; float hstep, sstep, lstep; int i; p = calloc(n, sizeof(unsigned long)); assert(p); hstep = (pal.to.h - pal.from.h) / (n - 1); sstep = (pal.to.s - pal.from.s) / (n - 1); lstep = (pal.to.l - pal.from.l) / (n - 1); for (i = 0; i < n; i++) { p[i] = hslcolor(d, pal.from.h, pal.from.s, pal.from.l); pal.from.h += hstep; pal.from.s += sstep; pal.from.l += lstep; } return p; }