Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenlib/intern/math_color.c
| Show All 25 Lines | |||||
| #include <assert.h> | #include <assert.h> | ||||
| #include "BLI_math.h" | #include "BLI_math.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BLI_strict_flags.h" | #include "BLI_strict_flags.h" | ||||
| #define CLAMP3_VARS(a, b, c, min, max) \ | |||||
| { \ | |||||
| CLAMP(a, min, max); \ | |||||
| CLAMP(b, min, max); \ | |||||
| CLAMP(c, min, max); \ | |||||
| } \ | |||||
| (void)0 | |||||
| void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b) | void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b) | ||||
| { | { | ||||
| float nr, ng, nb; | float nr, ng, nb; | ||||
| CLAMP3_VARS(h, s, v, 0.0f, 1.0f); | |||||
| nr = fabsf(h * 6.0f - 3.0f) - 1.0f; | nr = fabsf(h * 6.0f - 3.0f) - 1.0f; | ||||
| ng = 2.0f - fabsf(h * 6.0f - 2.0f); | ng = 2.0f - fabsf(h * 6.0f - 2.0f); | ||||
| nb = 2.0f - fabsf(h * 6.0f - 4.0f); | nb = 2.0f - fabsf(h * 6.0f - 4.0f); | ||||
| CLAMP(nr, 0.0f, 1.0f); | CLAMP(nr, 0.0f, 1.0f); | ||||
| CLAMP(nb, 0.0f, 1.0f); | CLAMP(nb, 0.0f, 1.0f); | ||||
| CLAMP(ng, 0.0f, 1.0f); | CLAMP(ng, 0.0f, 1.0f); | ||||
| *r = ((nr - 1.0f) * s + 1.0f) * v; | *r = ((nr - 1.0f) * s + 1.0f) * v; | ||||
| *g = ((ng - 1.0f) * s + 1.0f) * v; | *g = ((ng - 1.0f) * s + 1.0f) * v; | ||||
| *b = ((nb - 1.0f) * s + 1.0f) * v; | *b = ((nb - 1.0f) * s + 1.0f) * v; | ||||
| } | } | ||||
| void hsl_to_rgb(float h, float s, float l, float *r, float *g, float *b) | void hsl_to_rgb(float h, float s, float l, float *r, float *g, float *b) | ||||
| { | { | ||||
| float nr, ng, nb, chroma; | float nr, ng, nb, chroma; | ||||
| CLAMP3_VARS(h, s, l, 0.0f, 1.0f); | |||||
| nr = fabsf(h * 6.0f - 3.0f) - 1.0f; | nr = fabsf(h * 6.0f - 3.0f) - 1.0f; | ||||
| ng = 2.0f - fabsf(h * 6.0f - 2.0f); | ng = 2.0f - fabsf(h * 6.0f - 2.0f); | ||||
| nb = 2.0f - fabsf(h * 6.0f - 4.0f); | nb = 2.0f - fabsf(h * 6.0f - 4.0f); | ||||
| CLAMP(nr, 0.0f, 1.0f); | CLAMP(nr, 0.0f, 1.0f); | ||||
| CLAMP(nb, 0.0f, 1.0f); | CLAMP(nb, 0.0f, 1.0f); | ||||
| CLAMP(ng, 0.0f, 1.0f); | CLAMP(ng, 0.0f, 1.0f); | ||||
| Show All 16 Lines | |||||
| { | { | ||||
| hsl_to_rgb(hsl[0], hsl[1], hsl[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]); | hsl_to_rgb(hsl[0], hsl[1], hsl[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]); | ||||
| } | } | ||||
| void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv, int colorspace) | void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv, int colorspace) | ||||
| { | { | ||||
| float y, u, v; | float y, u, v; | ||||
| CLAMP3_VARS(r, g, b, 0.0f, 1.0f); | |||||
| switch (colorspace) { | switch (colorspace) { | ||||
| case BLI_YUV_ITU_BT601: | case BLI_YUV_ITU_BT601: | ||||
| y = 0.299f * r + 0.587f * g + 0.114f * b; | y = 0.299f * r + 0.587f * g + 0.114f * b; | ||||
| u = -0.147f * r - 0.289f * g + 0.436f * b; | u = -0.147f * r - 0.289f * g + 0.436f * b; | ||||
| v = 0.615f * r - 0.515f * g - 0.100f * b; | v = 0.615f * r - 0.515f * g - 0.100f * b; | ||||
| break; | break; | ||||
| case BLI_YUV_ITU_BT709: | case BLI_YUV_ITU_BT709: | ||||
| default: | default: | ||||
| Show All 33 Lines | |||||
| /* The RGB inputs are supposed gamma corrected and in the range 0 - 1.0f | /* The RGB inputs are supposed gamma corrected and in the range 0 - 1.0f | ||||
| * | * | ||||
| * Output YCC have a range of 16-235 and 16-240 except with JFIF_0_255 where the range is 0-255 */ | * Output YCC have a range of 16-235 and 16-240 except with JFIF_0_255 where the range is 0-255 */ | ||||
| void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr, int colorspace) | void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr, int colorspace) | ||||
| { | { | ||||
| float sr, sg, sb; | float sr, sg, sb; | ||||
| float y = 128.0f, cr = 128.0f, cb = 128.0f; | float y = 128.0f, cr = 128.0f, cb = 128.0f; | ||||
| CLAMP3_VARS(r, g, b, 0.0f, 1.0f); | |||||
| sr = 255.0f * r; | sr = 255.0f * r; | ||||
| sg = 255.0f * g; | sg = 255.0f * g; | ||||
| sb = 255.0f * b; | sb = 255.0f * b; | ||||
| switch (colorspace) { | switch (colorspace) { | ||||
| case BLI_YCC_ITU_BT601: | case BLI_YCC_ITU_BT601: | ||||
| y = (0.257f * sr) + (0.504f * sg) + (0.098f * sb) + 16.0f; | y = (0.257f * sr) + (0.504f * sg) + (0.098f * sb) + 16.0f; | ||||
| cb = (-0.148f * sr) - (0.291f * sg) + (0.439f * sb) + 128.0f; | cb = (-0.148f * sr) - (0.291f * sg) + (0.439f * sb) + 128.0f; | ||||
| ▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv) | void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv) | ||||
| { | { | ||||
| float k = 0.0f; | float k = 0.0f; | ||||
| float chroma; | float chroma; | ||||
| float min_gb; | float min_gb; | ||||
| CLAMP3_VARS(r, g, b, 0.0f, 1.0f); | |||||
| if (g < b) { | if (g < b) { | ||||
| SWAP(float, g, b); | SWAP(float, g, b); | ||||
| k = -1.0f; | k = -1.0f; | ||||
| } | } | ||||
| min_gb = b; | min_gb = b; | ||||
| if (r < g) { | if (r < g) { | ||||
| SWAP(float, r, g); | SWAP(float, r, g); | ||||
| k = -2.0f / 6.0f - k; | k = -2.0f / 6.0f - k; | ||||
| Show All 10 Lines | |||||
| /* convenience function for now */ | /* convenience function for now */ | ||||
| void rgb_to_hsv_v(const float rgb[3], float r_hsv[3]) | void rgb_to_hsv_v(const float rgb[3], float r_hsv[3]) | ||||
| { | { | ||||
| rgb_to_hsv(rgb[0], rgb[1], rgb[2], &r_hsv[0], &r_hsv[1], &r_hsv[2]); | rgb_to_hsv(rgb[0], rgb[1], rgb[2], &r_hsv[0], &r_hsv[1], &r_hsv[2]); | ||||
| } | } | ||||
| void rgb_to_hsl(float r, float g, float b, float *lh, float *ls, float *ll) | void rgb_to_hsl(float r, float g, float b, float *lh, float *ls, float *ll) | ||||
| { | { | ||||
| CLAMP3_VARS(r, g, b, 0.0f, 1.0f); | |||||
| const float cmax = max_fff(r, g, b); | const float cmax = max_fff(r, g, b); | ||||
| const float cmin = min_fff(r, g, b); | const float cmin = min_fff(r, g, b); | ||||
| float h, s, l = min_ff(1.0, (cmax + cmin) / 2.0f); | float h, s, l = min_ff(1.0, (cmax + cmin) / 2.0f); | ||||
| if (cmax == cmin) { | if (cmax == cmin) { | ||||
| h = s = 0.0f; // achromatic | h = s = 0.0f; // achromatic | ||||
| } | } | ||||
| else { | else { | ||||
| Show All 13 Lines | void rgb_to_hsl(float r, float g, float b, float *lh, float *ls, float *ll) | ||||
| *lh = h; | *lh = h; | ||||
| *ls = s; | *ls = s; | ||||
| *ll = l; | *ll = l; | ||||
| } | } | ||||
| void rgb_to_hsl_compat(float r, float g, float b, float *lh, float *ls, float *ll) | void rgb_to_hsl_compat(float r, float g, float b, float *lh, float *ls, float *ll) | ||||
| { | { | ||||
| CLAMP3_VARS(r, g, b, 0.0f, 1.0f); | |||||
| const float orig_s = *ls; | const float orig_s = *ls; | ||||
| const float orig_h = *lh; | const float orig_h = *lh; | ||||
| rgb_to_hsl(r, g, b, lh, ls, ll); | rgb_to_hsl(r, g, b, lh, ls, ll); | ||||
| if (*ll <= 0.0f) { | if (*ll <= 0.0f) { | ||||
| *lh = orig_h; | *lh = orig_h; | ||||
| *ls = orig_s; | *ls = orig_s; | ||||
| Show All 16 Lines | |||||
| /* convenience function for now */ | /* convenience function for now */ | ||||
| void rgb_to_hsl_v(const float rgb[3], float r_hsl[3]) | void rgb_to_hsl_v(const float rgb[3], float r_hsl[3]) | ||||
| { | { | ||||
| rgb_to_hsl(rgb[0], rgb[1], rgb[2], &r_hsl[0], &r_hsl[1], &r_hsl[2]); | rgb_to_hsl(rgb[0], rgb[1], rgb[2], &r_hsl[0], &r_hsl[1], &r_hsl[2]); | ||||
| } | } | ||||
| void rgb_to_hsv_compat(float r, float g, float b, float *lh, float *ls, float *lv) | void rgb_to_hsv_compat(float r, float g, float b, float *lh, float *ls, float *lv) | ||||
| { | { | ||||
| CLAMP3_VARS(r, g, b, 0.0f, 1.0f); | |||||
| const float orig_h = *lh; | const float orig_h = *lh; | ||||
| const float orig_s = *ls; | const float orig_s = *ls; | ||||
| rgb_to_hsv(r, g, b, lh, ls, lv); | rgb_to_hsv(r, g, b, lh, ls, lv); | ||||
| if (*lv <= 1e-8) { | if (*lv <= 1e-8) { | ||||
| /* Very low v values will affect the hs values, correct them in post. */ | /* Very low v values will affect the hs values, correct them in post. */ | ||||
| *lh = orig_h; | *lh = orig_h; | ||||
| ▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | unsigned int hsv_to_cpack(float h, float s, float v) | ||||
| col = (r + (g * 256) + (b * 256 * 256)); | col = (r + (g * 256) + (b * 256 * 256)); | ||||
| return col; | return col; | ||||
| } | } | ||||
| unsigned int rgb_to_cpack(float r, float g, float b) | unsigned int rgb_to_cpack(float r, float g, float b) | ||||
| { | { | ||||
| unsigned int ir, ig, ib; | unsigned int ir, ig, ib; | ||||
| CLAMP3_VARS(r, g, b, 0.0f, 1.0f); | |||||
| ir = (unsigned int)floorf(255.0f * max_ff(r, 0.0f)); | ir = (unsigned int)floorf(255.0f * max_ff(r, 0.0f)); | ||||
| ig = (unsigned int)floorf(255.0f * max_ff(g, 0.0f)); | ig = (unsigned int)floorf(255.0f * max_ff(g, 0.0f)); | ||||
| ib = (unsigned int)floorf(255.0f * max_ff(b, 0.0f)); | ib = (unsigned int)floorf(255.0f * max_ff(b, 0.0f)); | ||||
| if (ir > 255) { | if (ir > 255) { | ||||
| ir = 255; | ir = 255; | ||||
| } | } | ||||
| if (ig > 255) { | if (ig > 255) { | ||||
| ▲ Show 20 Lines • Show All 323 Lines • Show Last 20 Lines | |||||