diff options
Diffstat (limited to 'source/blender/blenlib/intern/math_color.c')
-rw-r--r-- | source/blender/blenlib/intern/math_color.c | 853 |
1 files changed, 427 insertions, 426 deletions
diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c index 54698ddf7ca..bc1699451f3 100644 --- a/source/blender/blenlib/intern/math_color.c +++ b/source/blender/blenlib/intern/math_color.c @@ -26,7 +26,6 @@ #include <assert.h> - #include "BLI_math.h" #include "BLI_utildefines.h" @@ -34,95 +33,95 @@ void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b) { - float nr, ng, nb; + float nr, ng, nb; - nr = fabsf(h * 6.0f - 3.0f) - 1.0f; - ng = 2.0f - fabsf(h * 6.0f - 2.0f); - nb = 2.0f - fabsf(h * 6.0f - 4.0f); + nr = fabsf(h * 6.0f - 3.0f) - 1.0f; + ng = 2.0f - fabsf(h * 6.0f - 2.0f); + nb = 2.0f - fabsf(h * 6.0f - 4.0f); - CLAMP(nr, 0.0f, 1.0f); - CLAMP(nb, 0.0f, 1.0f); - CLAMP(ng, 0.0f, 1.0f); + CLAMP(nr, 0.0f, 1.0f); + CLAMP(nb, 0.0f, 1.0f); + CLAMP(ng, 0.0f, 1.0f); - *r = ((nr - 1.0f) * s + 1.0f) * v; - *g = ((ng - 1.0f) * s + 1.0f) * v; - *b = ((nb - 1.0f) * s + 1.0f) * v; + *r = ((nr - 1.0f) * s + 1.0f) * v; + *g = ((ng - 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) { - float nr, ng, nb, chroma; + float nr, ng, nb, chroma; - nr = fabsf(h * 6.0f - 3.0f) - 1.0f; - ng = 2.0f - fabsf(h * 6.0f - 2.0f); - nb = 2.0f - fabsf(h * 6.0f - 4.0f); + nr = fabsf(h * 6.0f - 3.0f) - 1.0f; + ng = 2.0f - fabsf(h * 6.0f - 2.0f); + nb = 2.0f - fabsf(h * 6.0f - 4.0f); - CLAMP(nr, 0.0f, 1.0f); - CLAMP(nb, 0.0f, 1.0f); - CLAMP(ng, 0.0f, 1.0f); + CLAMP(nr, 0.0f, 1.0f); + CLAMP(nb, 0.0f, 1.0f); + CLAMP(ng, 0.0f, 1.0f); - chroma = (1.0f - fabsf(2.0f * l - 1.0f)) * s; + chroma = (1.0f - fabsf(2.0f * l - 1.0f)) * s; - *r = (nr - 0.5f) * chroma + l; - *g = (ng - 0.5f) * chroma + l; - *b = (nb - 0.5f) * chroma + l; + *r = (nr - 0.5f) * chroma + l; + *g = (ng - 0.5f) * chroma + l; + *b = (nb - 0.5f) * chroma + l; } /* convenience function for now */ void hsv_to_rgb_v(const float hsv[3], float r_rgb[3]) { - hsv_to_rgb(hsv[0], hsv[1], hsv[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]); + hsv_to_rgb(hsv[0], hsv[1], hsv[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]); } /* convenience function for now */ void hsl_to_rgb_v(const float hsl[3], float r_rgb[3]) { - 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) { - float y, u, v; + float y, u, v; - switch (colorspace) { - case BLI_YUV_ITU_BT601: - y = 0.299f * r + 0.587f * g + 0.114f * b; - u = -0.147f * r - 0.289f * g + 0.436f * b; - v = 0.615f * r - 0.515f * g - 0.100f * b; - break; - case BLI_YUV_ITU_BT709: - default: - y = 0.2126f * r + 0.7152f * g + 0.0722f * b; - u = -0.09991f * r - 0.33609f * g + 0.436f * b; - v = 0.615f * r - 0.55861f * g - 0.05639f * b; - break; - } + switch (colorspace) { + case BLI_YUV_ITU_BT601: + y = 0.299f * r + 0.587f * g + 0.114f * b; + u = -0.147f * r - 0.289f * g + 0.436f * b; + v = 0.615f * r - 0.515f * g - 0.100f * b; + break; + case BLI_YUV_ITU_BT709: + default: + y = 0.2126f * r + 0.7152f * g + 0.0722f * b; + u = -0.09991f * r - 0.33609f * g + 0.436f * b; + v = 0.615f * r - 0.55861f * g - 0.05639f * b; + break; + } - *ly = y; - *lu = u; - *lv = v; + *ly = y; + *lu = u; + *lv = v; } void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb, int colorspace) { - float r, g, b; + float r, g, b; - switch (colorspace) { - case BLI_YUV_ITU_BT601: - r = y + 1.140f * v; - g = y - 0.394f * u - 0.581f * v; - b = y + 2.032f * u; - break; - case BLI_YUV_ITU_BT709: - r = y + 1.28033f * v; - g = y - 0.21482f * u - 0.38059f * v; - b = y + 2.12798f * u; - break; - } + switch (colorspace) { + case BLI_YUV_ITU_BT601: + r = y + 1.140f * v; + g = y - 0.394f * u - 0.581f * v; + b = y + 2.032f * u; + break; + case BLI_YUV_ITU_BT709: + r = y + 1.28033f * v; + g = y - 0.21482f * u - 0.38059f * v; + b = y + 2.12798f * u; + break; + } - *lr = r; - *lg = g; - *lb = b; + *lr = r; + *lg = g; + *lb = b; } /* The RGB inputs are supposed gamma corrected and in the range 0 - 1.0f @@ -130,231 +129,229 @@ void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb, int * 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) { - float sr, sg, sb; - float y = 128.0f, cr = 128.0f, cb = 128.0f; - - sr = 255.0f * r; - sg = 255.0f * g; - sb = 255.0f * b; - - switch (colorspace) { - case BLI_YCC_ITU_BT601: - y = (0.257f * sr) + (0.504f * sg) + (0.098f * sb) + 16.0f; - cb = (-0.148f * sr) - (0.291f * sg) + (0.439f * sb) + 128.0f; - cr = (0.439f * sr) - (0.368f * sg) - (0.071f * sb) + 128.0f; - break; - case BLI_YCC_ITU_BT709: - y = (0.183f * sr) + (0.614f * sg) + (0.062f * sb) + 16.0f; - cb = (-0.101f * sr) - (0.338f * sg) + (0.439f * sb) + 128.0f; - cr = (0.439f * sr) - (0.399f * sg) - (0.040f * sb) + 128.0f; - break; - case BLI_YCC_JFIF_0_255: - y = (0.299f * sr) + (0.587f * sg) + (0.114f * sb); - cb = (-0.16874f * sr) - (0.33126f * sg) + (0.5f * sb) + 128.0f; - cr = (0.5f * sr) - (0.41869f * sg) - (0.08131f * sb) + 128.0f; - break; - default: - assert(!"invalid colorspace"); - break; - } - - *ly = y; - *lcb = cb; - *lcr = cr; + float sr, sg, sb; + float y = 128.0f, cr = 128.0f, cb = 128.0f; + + sr = 255.0f * r; + sg = 255.0f * g; + sb = 255.0f * b; + + switch (colorspace) { + case BLI_YCC_ITU_BT601: + y = (0.257f * sr) + (0.504f * sg) + (0.098f * sb) + 16.0f; + cb = (-0.148f * sr) - (0.291f * sg) + (0.439f * sb) + 128.0f; + cr = (0.439f * sr) - (0.368f * sg) - (0.071f * sb) + 128.0f; + break; + case BLI_YCC_ITU_BT709: + y = (0.183f * sr) + (0.614f * sg) + (0.062f * sb) + 16.0f; + cb = (-0.101f * sr) - (0.338f * sg) + (0.439f * sb) + 128.0f; + cr = (0.439f * sr) - (0.399f * sg) - (0.040f * sb) + 128.0f; + break; + case BLI_YCC_JFIF_0_255: + y = (0.299f * sr) + (0.587f * sg) + (0.114f * sb); + cb = (-0.16874f * sr) - (0.33126f * sg) + (0.5f * sb) + 128.0f; + cr = (0.5f * sr) - (0.41869f * sg) - (0.08131f * sb) + 128.0f; + break; + default: + assert(!"invalid colorspace"); + break; + } + + *ly = y; + *lcb = cb; + *lcr = cr; } - /* YCC input have a range of 16-235 and 16-240 except with JFIF_0_255 where the range is 0-255 */ /* RGB outputs are in the range 0 - 1.0f */ /* FIXME comment above must be wrong because BLI_YCC_ITU_BT601 y 16.0 cr 16.0 -> r -0.7009 */ void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb, int colorspace) { - float r = 128.0f, g = 128.0f, b = 128.0f; - - switch (colorspace) { - case BLI_YCC_ITU_BT601: - r = 1.164f * (y - 16.0f) + 1.596f * (cr - 128.0f); - g = 1.164f * (y - 16.0f) - 0.813f * (cr - 128.0f) - 0.392f * (cb - 128.0f); - b = 1.164f * (y - 16.0f) + 2.017f * (cb - 128.0f); - break; - case BLI_YCC_ITU_BT709: - r = 1.164f * (y - 16.0f) + 1.793f * (cr - 128.0f); - g = 1.164f * (y - 16.0f) - 0.534f * (cr - 128.0f) - 0.213f * (cb - 128.0f); - b = 1.164f * (y - 16.0f) + 2.115f * (cb - 128.0f); - break; - case BLI_YCC_JFIF_0_255: - r = y + 1.402f * cr - 179.456f; - g = y - 0.34414f * cb - 0.71414f * cr + 135.45984f; - b = y + 1.772f * cb - 226.816f; - break; - default: - BLI_assert(0); - break; - } - *lr = r / 255.0f; - *lg = g / 255.0f; - *lb = b / 255.0f; + float r = 128.0f, g = 128.0f, b = 128.0f; + + switch (colorspace) { + case BLI_YCC_ITU_BT601: + r = 1.164f * (y - 16.0f) + 1.596f * (cr - 128.0f); + g = 1.164f * (y - 16.0f) - 0.813f * (cr - 128.0f) - 0.392f * (cb - 128.0f); + b = 1.164f * (y - 16.0f) + 2.017f * (cb - 128.0f); + break; + case BLI_YCC_ITU_BT709: + r = 1.164f * (y - 16.0f) + 1.793f * (cr - 128.0f); + g = 1.164f * (y - 16.0f) - 0.534f * (cr - 128.0f) - 0.213f * (cb - 128.0f); + b = 1.164f * (y - 16.0f) + 2.115f * (cb - 128.0f); + break; + case BLI_YCC_JFIF_0_255: + r = y + 1.402f * cr - 179.456f; + g = y - 0.34414f * cb - 0.71414f * cr + 135.45984f; + b = y + 1.772f * cb - 226.816f; + break; + default: + BLI_assert(0); + break; + } + *lr = r / 255.0f; + *lg = g / 255.0f; + *lb = b / 255.0f; } void hex_to_rgb(char *hexcol, float *r, float *g, float *b) { - unsigned int ri, gi, bi; - - if (hexcol[0] == '#') { - hexcol++; - } - - if (sscanf(hexcol, "%02x%02x%02x", &ri, &gi, &bi) == 3) { - /* six digit hex colors */ - } - else if (sscanf(hexcol, "%01x%01x%01x", &ri, &gi, &bi) == 3) { - /* three digit hex colors (#123 becomes #112233) */ - ri += ri << 4; - gi += gi << 4; - bi += bi << 4; - } - else { - /* avoid using un-initialized vars */ - *r = *g = *b = 0.0f; - return; - } - - *r = (float)ri * (1.0f / 255.0f); - *g = (float)gi * (1.0f / 255.0f); - *b = (float)bi * (1.0f / 255.0f); - CLAMP(*r, 0.0f, 1.0f); - CLAMP(*g, 0.0f, 1.0f); - CLAMP(*b, 0.0f, 1.0f); + unsigned int ri, gi, bi; + + if (hexcol[0] == '#') { + hexcol++; + } + + if (sscanf(hexcol, "%02x%02x%02x", &ri, &gi, &bi) == 3) { + /* six digit hex colors */ + } + else if (sscanf(hexcol, "%01x%01x%01x", &ri, &gi, &bi) == 3) { + /* three digit hex colors (#123 becomes #112233) */ + ri += ri << 4; + gi += gi << 4; + bi += bi << 4; + } + else { + /* avoid using un-initialized vars */ + *r = *g = *b = 0.0f; + return; + } + + *r = (float)ri * (1.0f / 255.0f); + *g = (float)gi * (1.0f / 255.0f); + *b = (float)bi * (1.0f / 255.0f); + CLAMP(*r, 0.0f, 1.0f); + CLAMP(*g, 0.0f, 1.0f); + CLAMP(*b, 0.0f, 1.0f); } void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv) { - float k = 0.0f; - float chroma; - float min_gb; + float k = 0.0f; + float chroma; + float min_gb; - if (g < b) { - SWAP(float, g, b); - k = -1.0f; - } - min_gb = b; - if (r < g) { - SWAP(float, r, g); - k = -2.0f / 6.0f - k; - min_gb = min_ff(g, b); - } + if (g < b) { + SWAP(float, g, b); + k = -1.0f; + } + min_gb = b; + if (r < g) { + SWAP(float, r, g); + k = -2.0f / 6.0f - k; + min_gb = min_ff(g, b); + } - chroma = r - min_gb; + chroma = r - min_gb; - *lh = fabsf(k + (g - b) / (6.0f * chroma + 1e-20f)); - *ls = chroma / (r + 1e-20f); - *lv = r; + *lh = fabsf(k + (g - b) / (6.0f * chroma + 1e-20f)); + *ls = chroma / (r + 1e-20f); + *lv = r; } /* convenience function for now */ 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) { - const float cmax = max_fff(r, g, b); - const float cmin = min_fff(r, g, b); - float h, s, l = min_ff(1.0, (cmax + cmin) / 2.0f); - - if (cmax == cmin) { - h = s = 0.0f; // achromatic - } - else { - float d = cmax - cmin; - s = l > 0.5f ? d / (2.0f - cmax - cmin) : d / (cmax + cmin); - if (cmax == r) { - h = (g - b) / d + (g < b ? 6.0f : 0.0f); - } - else if (cmax == g) { - h = (b - r) / d + 2.0f; - } - else { - h = (r - g) / d + 4.0f; - } - } - h /= 6.0f; - - *lh = h; - *ls = s; - *ll = l; + const float cmax = max_fff(r, g, b); + const float cmin = min_fff(r, g, b); + float h, s, l = min_ff(1.0, (cmax + cmin) / 2.0f); + + if (cmax == cmin) { + h = s = 0.0f; // achromatic + } + else { + float d = cmax - cmin; + s = l > 0.5f ? d / (2.0f - cmax - cmin) : d / (cmax + cmin); + if (cmax == r) { + h = (g - b) / d + (g < b ? 6.0f : 0.0f); + } + else if (cmax == g) { + h = (b - r) / d + 2.0f; + } + else { + h = (r - g) / d + 4.0f; + } + } + h /= 6.0f; + + *lh = h; + *ls = s; + *ll = l; } void rgb_to_hsl_compat(float r, float g, float b, float *lh, float *ls, float *ll) { - const float orig_s = *ls; - const float orig_h = *lh; + const float orig_s = *ls; + 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) { - *lh = orig_h; - *ls = orig_s; - } - else if (*ls <= 0.0f) { - *lh = orig_h; - *ls = orig_s; - } + if (*ll <= 0.0f) { + *lh = orig_h; + *ls = orig_s; + } + else if (*ls <= 0.0f) { + *lh = orig_h; + *ls = orig_s; + } - if (*lh == 0.0f && orig_h >= 1.0f) { - *lh = 1.0f; - } + if (*lh == 0.0f && orig_h >= 1.0f) { + *lh = 1.0f; + } } void rgb_to_hsl_compat_v(const float rgb[3], float r_hsl[3]) { - rgb_to_hsl_compat(rgb[0], rgb[1], rgb[2], &r_hsl[0], &r_hsl[1], &r_hsl[2]); + rgb_to_hsl_compat(rgb[0], rgb[1], rgb[2], &r_hsl[0], &r_hsl[1], &r_hsl[2]); } - /* convenience function for now */ 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) { - const float orig_h = *lh; - const float orig_s = *ls; + const float orig_h = *lh; + 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) { - /* Very low v values will affect the hs values, correct them in post. */ - *lh = orig_h; - *ls = orig_s; - } - else if (*ls <= 1e-8) { - *lh = orig_h; - } + if (*lv <= 1e-8) { + /* Very low v values will affect the hs values, correct them in post. */ + *lh = orig_h; + *ls = orig_s; + } + else if (*ls <= 1e-8) { + *lh = orig_h; + } - if (*lh == 0.0f && orig_h >= 1.0f) { - *lh = 1.0f; - } + if (*lh == 0.0f && orig_h >= 1.0f) { + *lh = 1.0f; + } } /* convenience function for now */ void rgb_to_hsv_compat_v(const float rgb[3], float r_hsv[3]) { - rgb_to_hsv_compat(rgb[0], rgb[1], rgb[2], &r_hsv[0], &r_hsv[1], &r_hsv[2]); + rgb_to_hsv_compat(rgb[0], rgb[1], rgb[2], &r_hsv[0], &r_hsv[1], &r_hsv[2]); } /* clamp hsv to usable values */ void hsv_clamp_v(float hsv[3], float v_max) { - if (UNLIKELY(hsv[0] < 0.0f || hsv[0] > 1.0f)) { - hsv[0] = hsv[0] - floorf(hsv[0]); - } - CLAMP(hsv[1], 0.0f, 1.0f); - CLAMP(hsv[2], 0.0f, v_max); + if (UNLIKELY(hsv[0] < 0.0f || hsv[0] > 1.0f)) { + hsv[0] = hsv[0] - floorf(hsv[0]); + } + CLAMP(hsv[1], 0.0f, 1.0f); + CLAMP(hsv[2], 0.0f, v_max); } /** @@ -365,112 +362,117 @@ void hsv_clamp_v(float hsv[3], float v_max) unsigned int hsv_to_cpack(float h, float s, float v) { - unsigned int r, g, b; - float rf, gf, bf; - unsigned int col; + unsigned int r, g, b; + float rf, gf, bf; + unsigned int col; - hsv_to_rgb(h, s, v, &rf, &gf, &bf); + hsv_to_rgb(h, s, v, &rf, &gf, &bf); - r = (unsigned int) (rf * 255.0f); - g = (unsigned int) (gf * 255.0f); - b = (unsigned int) (bf * 255.0f); + r = (unsigned int)(rf * 255.0f); + g = (unsigned int)(gf * 255.0f); + b = (unsigned int)(bf * 255.0f); - col = (r + (g * 256) + (b * 256 * 256)); - return col; + col = (r + (g * 256) + (b * 256 * 256)); + return col; } unsigned int rgb_to_cpack(float r, float g, float b) { - unsigned int ir, ig, ib; + unsigned int ir, ig, ib; - ir = (unsigned int)floorf(255.0f * max_ff(r, 0.0f)); - ig = (unsigned int)floorf(255.0f * max_ff(g, 0.0f)); - ib = (unsigned int)floorf(255.0f * max_ff(b, 0.0f)); + ir = (unsigned int)floorf(255.0f * max_ff(r, 0.0f)); + ig = (unsigned int)floorf(255.0f * max_ff(g, 0.0f)); + ib = (unsigned int)floorf(255.0f * max_ff(b, 0.0f)); - if (ir > 255) { ir = 255; } - if (ig > 255) { ig = 255; } - if (ib > 255) { ib = 255; } + if (ir > 255) { + ir = 255; + } + if (ig > 255) { + ig = 255; + } + if (ib > 255) { + ib = 255; + } - return (ir + (ig * 256) + (ib * 256 * 256)); + return (ir + (ig * 256) + (ib * 256 * 256)); } void cpack_to_rgb(unsigned int col, float *r, float *g, float *b) { - *r = ((float)(((col) ) & 0xFF)) * (1.0f / 255.0f); - *g = ((float)(((col) >> 8) & 0xFF)) * (1.0f / 255.0f); - *b = ((float)(((col) >> 16) & 0xFF)) * (1.0f / 255.0f); + *r = ((float)(((col)) & 0xFF)) * (1.0f / 255.0f); + *g = ((float)(((col) >> 8) & 0xFF)) * (1.0f / 255.0f); + *b = ((float)(((col) >> 16) & 0xFF)) * (1.0f / 255.0f); } void rgb_uchar_to_float(float r_col[3], const unsigned char col_ub[3]) { - r_col[0] = ((float)col_ub[0]) * (1.0f / 255.0f); - r_col[1] = ((float)col_ub[1]) * (1.0f / 255.0f); - r_col[2] = ((float)col_ub[2]) * (1.0f / 255.0f); + r_col[0] = ((float)col_ub[0]) * (1.0f / 255.0f); + r_col[1] = ((float)col_ub[1]) * (1.0f / 255.0f); + r_col[2] = ((float)col_ub[2]) * (1.0f / 255.0f); } void rgba_uchar_to_float(float r_col[4], const unsigned char col_ub[4]) { - r_col[0] = ((float)col_ub[0]) * (1.0f / 255.0f); - r_col[1] = ((float)col_ub[1]) * (1.0f / 255.0f); - r_col[2] = ((float)col_ub[2]) * (1.0f / 255.0f); - r_col[3] = ((float)col_ub[3]) * (1.0f / 255.0f); + r_col[0] = ((float)col_ub[0]) * (1.0f / 255.0f); + r_col[1] = ((float)col_ub[1]) * (1.0f / 255.0f); + r_col[2] = ((float)col_ub[2]) * (1.0f / 255.0f); + r_col[3] = ((float)col_ub[3]) * (1.0f / 255.0f); } void rgb_float_to_uchar(unsigned char r_col[3], const float col_f[3]) { - unit_float_to_uchar_clamp_v3(r_col, col_f); + unit_float_to_uchar_clamp_v3(r_col, col_f); } void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4]) { - unit_float_to_uchar_clamp_v4(r_col, col_f); + unit_float_to_uchar_clamp_v4(r_col, col_f); } /* ********************************* color transforms ********************************* */ - float srgb_to_linearrgb(float c) { - if (c < 0.04045f) { - return (c < 0.0f) ? 0.0f : c * (1.0f / 12.92f); - } - else { - return powf((c + 0.055f) * (1.0f / 1.055f), 2.4f); - } + if (c < 0.04045f) { + return (c < 0.0f) ? 0.0f : c * (1.0f / 12.92f); + } + else { + return powf((c + 0.055f) * (1.0f / 1.055f), 2.4f); + } } float linearrgb_to_srgb(float c) { - if (c < 0.0031308f) { - return (c < 0.0f) ? 0.0f : c * 12.92f; - } - else { - return 1.055f * powf(c, 1.0f / 2.4f) - 0.055f; - } + if (c < 0.0031308f) { + return (c < 0.0f) ? 0.0f : c * 12.92f; + } + else { + return 1.055f * powf(c, 1.0f / 2.4f) - 0.055f; + } } void minmax_rgb(short c[3]) { - if (c[0] > 255) { - c[0] = 255; - } - else if (c[0] < 0) { - c[0] = 0; - } + if (c[0] > 255) { + c[0] = 255; + } + else if (c[0] < 0) { + c[0] = 0; + } - if (c[1] > 255) { - c[1] = 255; - } - else if (c[1] < 0) { - c[1] = 0; - } + if (c[1] > 255) { + c[1] = 255; + } + else if (c[1] < 0) { + c[1] = 0; + } - if (c[2] > 255) { - c[2] = 255; - } - else if (c[2] < 0) { - c[2] = 0; - } + if (c[2] > 255) { + c[2] = 255; + } + else if (c[2] < 0) { + c[2] = 0; + } } /* If the requested RGB shade contains a negative weight for @@ -481,36 +483,37 @@ void minmax_rgb(short c[3]) * components were modified, zero otherwise.*/ int constrain_rgb(float *r, float *g, float *b) { - /* Amount of white needed */ - const float w = -min_ffff(0.0f, *r, *g, *b); + /* Amount of white needed */ + const float w = -min_ffff(0.0f, *r, *g, *b); - /* Add just enough white to make r, g, b all positive. */ - if (w > 0.0f) { - *r += w; - *g += w; - *b += w; + /* Add just enough white to make r, g, b all positive. */ + if (w > 0.0f) { + *r += w; + *g += w; + *b += w; - return 1; /* Color modified to fit RGB gamut */ - } + return 1; /* Color modified to fit RGB gamut */ + } - return 0; /* Color within RGB gamut */ + return 0; /* Color within RGB gamut */ } /* ********************** lift/gamma/gain / ASC-CDL conversion ********************************* */ -void lift_gamma_gain_to_asc_cdl(float *lift, float *gamma, float *gain, float *offset, float *slope, float *power) +void lift_gamma_gain_to_asc_cdl( + float *lift, float *gamma, float *gain, float *offset, float *slope, float *power) { - int c; - for (c = 0; c < 3; c++) { - offset[c] = lift[c] * gain[c]; - slope[c] = gain[c] * (1.0f - lift[c]); - if (gamma[c] == 0) { - power[c] = FLT_MAX; - } - else { - power[c] = 1.0f / gamma[c]; - } - } + int c; + for (c = 0; c < 3; c++) { + offset[c] = lift[c] * gain[c]; + slope[c] = gain[c] * (1.0f - lift[c]); + if (gamma[c] == 0) { + power[c] = FLT_MAX; + } + else { + power[c] = 1.0f / gamma[c]; + } + } } /* ************************************* other ************************************************* */ @@ -518,32 +521,31 @@ void lift_gamma_gain_to_asc_cdl(float *lift, float *gamma, float *gain, float *o /* Applies an hue offset to a float rgb color */ void rgb_float_set_hue_float_offset(float rgb[3], float hue_offset) { - float hsv[3]; + float hsv[3]; - rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv + 1, hsv + 2); + rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv + 1, hsv + 2); - hsv[0] += hue_offset; - if (hsv[0] > 1.0f) { - hsv[0] -= 1.0f; - } - else if (hsv[0] < 0.0f) { - hsv[0] += 1.0f; - } + hsv[0] += hue_offset; + if (hsv[0] > 1.0f) { + hsv[0] -= 1.0f; + } + else if (hsv[0] < 0.0f) { + hsv[0] += 1.0f; + } - hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb + 1, rgb + 2); + hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb + 1, rgb + 2); } /* Applies an hue offset to a byte rgb color */ void rgb_byte_set_hue_float_offset(unsigned char rgb[3], float hue_offset) { - float rgb_float[3]; + float rgb_float[3]; - rgb_uchar_to_float(rgb_float, rgb); - rgb_float_set_hue_float_offset(rgb_float, hue_offset); - rgb_float_to_uchar(rgb, rgb_float); + rgb_uchar_to_float(rgb_float, rgb); + rgb_float_set_hue_float_offset(rgb_float, hue_offset); + rgb_float_to_uchar(rgb, rgb_float); } - /* fast sRGB conversion * LUT from linear float to 16-bit short * based on http://mysite.verizon.net/spitzak/conversion/ @@ -554,83 +556,83 @@ unsigned short BLI_color_to_srgb_table[0x10000]; static unsigned short hipart(const float f) { - union { - float f; - unsigned short us[2]; - } tmp; + union { + float f; + unsigned short us[2]; + } tmp; - tmp.f = f; + tmp.f = f; #ifdef __BIG_ENDIAN__ - return tmp.us[0]; + return tmp.us[0]; #else - return tmp.us[1]; + return tmp.us[1]; #endif } static float index_to_float(const unsigned short i) { - union { - float f; - unsigned short us[2]; - } tmp; + union { + float f; + unsigned short us[2]; + } tmp; - /* positive and negative zeros, and all gradual underflow, turn into zero: */ - if (i < 0x80 || (i >= 0x8000 && i < 0x8080)) { - return 0; - } - /* All NaN's and infinity turn into the largest possible legal float: */ - if (i >= 0x7f80 && i < 0x8000) { - return FLT_MAX; - } - if (i >= 0xff80) { - return -FLT_MAX; - } + /* positive and negative zeros, and all gradual underflow, turn into zero: */ + if (i < 0x80 || (i >= 0x8000 && i < 0x8080)) { + return 0; + } + /* All NaN's and infinity turn into the largest possible legal float: */ + if (i >= 0x7f80 && i < 0x8000) { + return FLT_MAX; + } + if (i >= 0xff80) { + return -FLT_MAX; + } #ifdef __BIG_ENDIAN__ - tmp.us[0] = i; - tmp.us[1] = 0x8000; + tmp.us[0] = i; + tmp.us[1] = 0x8000; #else - tmp.us[0] = 0x8000; - tmp.us[1] = i; + tmp.us[0] = 0x8000; + tmp.us[1] = i; #endif - return tmp.f; + return tmp.f; } void BLI_init_srgb_conversion(void) { - static bool initialized = false; - unsigned int i, b; - - if (initialized) { - return; - } - initialized = true; - - /* Fill in the lookup table to convert floats to bytes: */ - for (i = 0; i < 0x10000; i++) { - float f = linearrgb_to_srgb(index_to_float((unsigned short)i)) * 255.0f; - if (f <= 0) { - BLI_color_to_srgb_table[i] = 0; - } - else if (f < 255) { - BLI_color_to_srgb_table[i] = (unsigned short) (f * 0x100 + 0.5f); - } - else { - BLI_color_to_srgb_table[i] = 0xff00; - } - } - - /* Fill in the lookup table to convert bytes to float: */ - for (b = 0; b <= 255; b++) { - float f = srgb_to_linearrgb(((float)b) * (1.0f / 255.0f)); - BLI_color_from_srgb_table[b] = f; - i = hipart(f); - /* replace entries so byte->float->byte does not change the data: */ - BLI_color_to_srgb_table[i] = (unsigned short)(b * 0x100); - } + static bool initialized = false; + unsigned int i, b; + + if (initialized) { + return; + } + initialized = true; + + /* Fill in the lookup table to convert floats to bytes: */ + for (i = 0; i < 0x10000; i++) { + float f = linearrgb_to_srgb(index_to_float((unsigned short)i)) * 255.0f; + if (f <= 0) { + BLI_color_to_srgb_table[i] = 0; + } + else if (f < 255) { + BLI_color_to_srgb_table[i] = (unsigned short)(f * 0x100 + 0.5f); + } + else { + BLI_color_to_srgb_table[i] = 0xff00; + } + } + + /* Fill in the lookup table to convert bytes to float: */ + for (b = 0; b <= 255; b++) { + float f = srgb_to_linearrgb(((float)b) * (1.0f / 255.0f)); + BLI_color_from_srgb_table[b] = f; + i = hipart(f); + /* replace entries so byte->float->byte does not change the data: */ + BLI_color_to_srgb_table[i] = (unsigned short)(b * 0x100); + } } /* ****************************** blackbody ******************************** */ @@ -642,71 +644,70 @@ void BLI_init_srgb_conversion(void) */ static const float blackbody_table_r[6][3] = { - { 2.52432244e+03f, -1.06185848e-03f, 3.11067539e+00f }, - { 3.37763626e+03f, -4.34581697e-04f, 1.64843306e+00f }, - { 4.10671449e+03f, -8.61949938e-05f, 6.41423749e-01f }, - { 4.66849800e+03f, 2.85655028e-05f, 1.29075375e-01f }, - { 4.60124770e+03f, 2.89727618e-05f, 1.48001316e-01f }, - { 3.78765709e+03f, 9.36026367e-06f, 3.98995841e-01f }, + {2.52432244e+03f, -1.06185848e-03f, 3.11067539e+00f}, + {3.37763626e+03f, -4.34581697e-04f, 1.64843306e+00f}, + {4.10671449e+03f, -8.61949938e-05f, 6.41423749e-01f}, + {4.66849800e+03f, 2.85655028e-05f, 1.29075375e-01f}, + {4.60124770e+03f, 2.89727618e-05f, 1.48001316e-01f}, + {3.78765709e+03f, 9.36026367e-06f, 3.98995841e-01f}, }; static const float blackbody_table_g[6][3] = { - { -7.50343014e+02f, 3.15679613e-04f, 4.73464526e-01f }, - { -1.00402363e+03f, 1.29189794e-04f, 9.08181524e-01f }, - { -1.22075471e+03f, 2.56245413e-05f, 1.20753416e+00f }, - { -1.42546105e+03f, -4.01730887e-05f, 1.44002695e+00f }, - { -1.18134453e+03f, -2.18913373e-05f, 1.30656109e+00f }, - { -5.00279505e+02f, -4.59745390e-06f, 1.09090465e+00f }, + {-7.50343014e+02f, 3.15679613e-04f, 4.73464526e-01f}, + {-1.00402363e+03f, 1.29189794e-04f, 9.08181524e-01f}, + {-1.22075471e+03f, 2.56245413e-05f, 1.20753416e+00f}, + {-1.42546105e+03f, -4.01730887e-05f, 1.44002695e+00f}, + {-1.18134453e+03f, -2.18913373e-05f, 1.30656109e+00f}, + {-5.00279505e+02f, -4.59745390e-06f, 1.09090465e+00f}, }; static const float blackbody_table_b[6][4] = { - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { -2.02524603e-11f, 1.79435860e-07f, -2.60561875e-04f, -1.41761141e-02f }, - { -2.22463426e-13f, -1.55078698e-08f, 3.81675160e-04f, -7.30646033e-01f }, - { 6.72595954e-13f, -2.73059993e-08f, 4.24068546e-04f, -7.52204323e-01f }, + {0.0f, 0.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 0.0f, 0.0f}, + {-2.02524603e-11f, 1.79435860e-07f, -2.60561875e-04f, -1.41761141e-02f}, + {-2.22463426e-13f, -1.55078698e-08f, 3.81675160e-04f, -7.30646033e-01f}, + {6.72595954e-13f, -2.73059993e-08f, 4.24068546e-04f, -7.52204323e-01f}, }; static void blackbody_temperature_to_rgb(float rgb[3], float t) { - if (t >= 12000.0f) { - rgb[0] = 0.826270103f; - rgb[1] = 0.994478524f; - rgb[2] = 1.56626022f; - } - else if (t < 965.0f) { - rgb[0] = 4.70366907f; - rgb[1] = 0.0f; - rgb[2] = 0.0f; - } - else { - int i = (t >= 6365.0f) ? 5 : - (t >= 3315.0f) ? 4 : - (t >= 1902.0f) ? 3 : - (t >= 1449.0f) ? 2 : - (t >= 1167.0f) ? 1 : 0; - - const float *r = blackbody_table_r[i]; - const float *g = blackbody_table_g[i]; - const float *b = blackbody_table_b[i]; - - const float t_inv = 1.0f / t; - rgb[0] = r[0] * t_inv + r[1] * t + r[2]; - rgb[1] = g[0] * t_inv + g[1] * t + g[2]; - rgb[2] = ((b[0] * t + b[1]) * t + b[2]) * t + b[3]; - } + if (t >= 12000.0f) { + rgb[0] = 0.826270103f; + rgb[1] = 0.994478524f; + rgb[2] = 1.56626022f; + } + else if (t < 965.0f) { + rgb[0] = 4.70366907f; + rgb[1] = 0.0f; + rgb[2] = 0.0f; + } + else { + int i = (t >= 6365.0f) ? + 5 : + (t >= 3315.0f) ? 4 : + (t >= 1902.0f) ? 3 : (t >= 1449.0f) ? 2 : (t >= 1167.0f) ? 1 : 0; + + const float *r = blackbody_table_r[i]; + const float *g = blackbody_table_g[i]; + const float *b = blackbody_table_b[i]; + + const float t_inv = 1.0f / t; + rgb[0] = r[0] * t_inv + r[1] * t + r[2]; + rgb[1] = g[0] * t_inv + g[1] * t + g[2]; + rgb[2] = ((b[0] * t + b[1]) * t + b[2]) * t + b[3]; + } } void blackbody_temperature_to_rgb_table(float *r_table, int width, float min, float max) { - for (int i = 0; i < width; i++) { - float temperature = min + (max - min) / (float)width * (float)i; + for (int i = 0; i < width; i++) { + float temperature = min + (max - min) / (float)width * (float)i; - float rgb[3]; - blackbody_temperature_to_rgb(rgb, temperature); + float rgb[3]; + blackbody_temperature_to_rgb(rgb, temperature); - copy_v3_v3(&r_table[i * 4], rgb); - r_table[i * 4 + 3] = 0.0f; - } + copy_v3_v3(&r_table[i * 4], rgb); + r_table[i * 4 + 3] = 0.0f; + } } |