From e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 17 Apr 2019 06:17:24 +0200 Subject: ClangFormat: apply to source, most of intern Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat --- source/blender/blenkernel/intern/colortools.c | 2738 +++++++++++++------------ 1 file changed, 1408 insertions(+), 1330 deletions(-) (limited to 'source/blender/blenkernel/intern/colortools.c') diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 8b92c42a286..96c098b37e9 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -21,7 +21,6 @@ * \ingroup bke */ - #include #include #include @@ -42,7 +41,6 @@ #include "BKE_curve.h" #include "BKE_fcurve.h" - #include "IMB_colormanagement.h" #include "IMB_imbuf_types.h" @@ -50,125 +48,127 @@ /* ***************** operations on full struct ************* */ -void curvemapping_set_defaults(CurveMapping *cumap, int tot, float minx, float miny, float maxx, float maxy) +void curvemapping_set_defaults( + CurveMapping *cumap, int tot, float minx, float miny, float maxx, float maxy) { - int a; - float clipminx, clipminy, clipmaxx, clipmaxy; + int a; + float clipminx, clipminy, clipmaxx, clipmaxy; - cumap->flag = CUMA_DO_CLIP; - if (tot == 4) cumap->cur = 3; /* rhms, hack for 'col' curve? */ + cumap->flag = CUMA_DO_CLIP; + if (tot == 4) + cumap->cur = 3; /* rhms, hack for 'col' curve? */ - clipminx = min_ff(minx, maxx); - clipminy = min_ff(miny, maxy); - clipmaxx = max_ff(minx, maxx); - clipmaxy = max_ff(miny, maxy); + clipminx = min_ff(minx, maxx); + clipminy = min_ff(miny, maxy); + clipmaxx = max_ff(minx, maxx); + clipmaxy = max_ff(miny, maxy); - BLI_rctf_init(&cumap->curr, clipminx, clipmaxx, clipminy, clipmaxy); - cumap->clipr = cumap->curr; + BLI_rctf_init(&cumap->curr, clipminx, clipmaxx, clipminy, clipmaxy); + cumap->clipr = cumap->curr; - cumap->white[0] = cumap->white[1] = cumap->white[2] = 1.0f; - cumap->bwmul[0] = cumap->bwmul[1] = cumap->bwmul[2] = 1.0f; + cumap->white[0] = cumap->white[1] = cumap->white[2] = 1.0f; + cumap->bwmul[0] = cumap->bwmul[1] = cumap->bwmul[2] = 1.0f; - for (a = 0; a < tot; a++) { - cumap->cm[a].flag = CUMA_EXTEND_EXTRAPOLATE; - cumap->cm[a].totpoint = 2; - cumap->cm[a].curve = MEM_callocN(2 * sizeof(CurveMapPoint), "curve points"); + for (a = 0; a < tot; a++) { + cumap->cm[a].flag = CUMA_EXTEND_EXTRAPOLATE; + cumap->cm[a].totpoint = 2; + cumap->cm[a].curve = MEM_callocN(2 * sizeof(CurveMapPoint), "curve points"); - cumap->cm[a].curve[0].x = minx; - cumap->cm[a].curve[0].y = miny; - cumap->cm[a].curve[1].x = maxx; - cumap->cm[a].curve[1].y = maxy; - } + cumap->cm[a].curve[0].x = minx; + cumap->cm[a].curve[0].y = miny; + cumap->cm[a].curve[1].x = maxx; + cumap->cm[a].curve[1].y = maxy; + } - cumap->changed_timestamp = 0; + cumap->changed_timestamp = 0; } CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, float maxy) { - CurveMapping *cumap; + CurveMapping *cumap; - cumap = MEM_callocN(sizeof(CurveMapping), "new curvemap"); + cumap = MEM_callocN(sizeof(CurveMapping), "new curvemap"); - curvemapping_set_defaults(cumap, tot, minx, miny, maxx, maxy); + curvemapping_set_defaults(cumap, tot, minx, miny, maxx, maxy); - return cumap; + return cumap; } void curvemapping_free_data(CurveMapping *cumap) { - int a; - - for (a = 0; a < CM_TOT; a++) { - if (cumap->cm[a].curve) { - MEM_freeN(cumap->cm[a].curve); - cumap->cm[a].curve = NULL; - } - if (cumap->cm[a].table) { - MEM_freeN(cumap->cm[a].table); - cumap->cm[a].table = NULL; - } - if (cumap->cm[a].premultable) { - MEM_freeN(cumap->cm[a].premultable); - cumap->cm[a].premultable = NULL; - } - } + int a; + + for (a = 0; a < CM_TOT; a++) { + if (cumap->cm[a].curve) { + MEM_freeN(cumap->cm[a].curve); + cumap->cm[a].curve = NULL; + } + if (cumap->cm[a].table) { + MEM_freeN(cumap->cm[a].table); + cumap->cm[a].table = NULL; + } + if (cumap->cm[a].premultable) { + MEM_freeN(cumap->cm[a].premultable); + cumap->cm[a].premultable = NULL; + } + } } void curvemapping_free(CurveMapping *cumap) { - if (cumap) { - curvemapping_free_data(cumap); - MEM_freeN(cumap); - } + if (cumap) { + curvemapping_free_data(cumap); + MEM_freeN(cumap); + } } void curvemapping_copy_data(CurveMapping *target, const CurveMapping *cumap) { - int a; - - *target = *cumap; - - for (a = 0; a < CM_TOT; a++) { - if (cumap->cm[a].curve) - target->cm[a].curve = MEM_dupallocN(cumap->cm[a].curve); - if (cumap->cm[a].table) - target->cm[a].table = MEM_dupallocN(cumap->cm[a].table); - if (cumap->cm[a].premultable) - target->cm[a].premultable = MEM_dupallocN(cumap->cm[a].premultable); - } + int a; + + *target = *cumap; + + for (a = 0; a < CM_TOT; a++) { + if (cumap->cm[a].curve) + target->cm[a].curve = MEM_dupallocN(cumap->cm[a].curve); + if (cumap->cm[a].table) + target->cm[a].table = MEM_dupallocN(cumap->cm[a].table); + if (cumap->cm[a].premultable) + target->cm[a].premultable = MEM_dupallocN(cumap->cm[a].premultable); + } } CurveMapping *curvemapping_copy(const CurveMapping *cumap) { - if (cumap) { - CurveMapping *cumapn = MEM_dupallocN(cumap); - curvemapping_copy_data(cumapn, cumap); - return cumapn; - } - return NULL; + if (cumap) { + CurveMapping *cumapn = MEM_dupallocN(cumap); + curvemapping_copy_data(cumapn, cumap); + return cumapn; + } + return NULL; } void curvemapping_set_black_white_ex(const float black[3], const float white[3], float r_bwmul[3]) { - int a; + int a; - for (a = 0; a < 3; a++) { - const float delta = max_ff(white[a] - black[a], 1e-5f); - r_bwmul[a] = 1.0f / delta; - } + for (a = 0; a < 3; a++) { + const float delta = max_ff(white[a] - black[a], 1e-5f); + r_bwmul[a] = 1.0f / delta; + } } void curvemapping_set_black_white(CurveMapping *cumap, const float black[3], const float white[3]) { - if (white) { - copy_v3_v3(cumap->white, white); - } - if (black) { - copy_v3_v3(cumap->black, black); - } - - curvemapping_set_black_white_ex(cumap->black, cumap->white, cumap->bwmul); - cumap->changed_timestamp++; + if (white) { + copy_v3_v3(cumap->white, white); + } + if (black) { + copy_v3_v3(cumap->black, black); + } + + curvemapping_set_black_white_ex(cumap->black, cumap->white, cumap->bwmul); + cumap->changed_timestamp++; } /* ***************** operations on single curve ************* */ @@ -177,240 +177,257 @@ void curvemapping_set_black_white(CurveMapping *cumap, const float black[3], con /* remove specified point */ bool curvemap_remove_point(CurveMap *cuma, CurveMapPoint *point) { - CurveMapPoint *cmp; - int a, b, removed = 0; - - /* must have 2 points minimum */ - if (cuma->totpoint <= 2) - return false; - - cmp = MEM_mallocN((cuma->totpoint) * sizeof(CurveMapPoint), "curve points"); - - /* well, lets keep the two outer points! */ - for (a = 0, b = 0; a < cuma->totpoint; a++) { - if (&cuma->curve[a] != point) { - cmp[b] = cuma->curve[a]; - b++; - } - else { - removed++; - } - } - - MEM_freeN(cuma->curve); - cuma->curve = cmp; - cuma->totpoint -= removed; - return (removed != 0); + CurveMapPoint *cmp; + int a, b, removed = 0; + + /* must have 2 points minimum */ + if (cuma->totpoint <= 2) + return false; + + cmp = MEM_mallocN((cuma->totpoint) * sizeof(CurveMapPoint), "curve points"); + + /* well, lets keep the two outer points! */ + for (a = 0, b = 0; a < cuma->totpoint; a++) { + if (&cuma->curve[a] != point) { + cmp[b] = cuma->curve[a]; + b++; + } + else { + removed++; + } + } + + MEM_freeN(cuma->curve); + cuma->curve = cmp; + cuma->totpoint -= removed; + return (removed != 0); } /* removes with flag set */ void curvemap_remove(CurveMap *cuma, const short flag) { - CurveMapPoint *cmp = MEM_mallocN((cuma->totpoint) * sizeof(CurveMapPoint), "curve points"); - int a, b, removed = 0; - - /* well, lets keep the two outer points! */ - cmp[0] = cuma->curve[0]; - for (a = 1, b = 1; a < cuma->totpoint - 1; a++) { - if (!(cuma->curve[a].flag & flag)) { - cmp[b] = cuma->curve[a]; - b++; - } - else { - removed++; - } - } - cmp[b] = cuma->curve[a]; - - MEM_freeN(cuma->curve); - cuma->curve = cmp; - cuma->totpoint -= removed; + CurveMapPoint *cmp = MEM_mallocN((cuma->totpoint) * sizeof(CurveMapPoint), "curve points"); + int a, b, removed = 0; + + /* well, lets keep the two outer points! */ + cmp[0] = cuma->curve[0]; + for (a = 1, b = 1; a < cuma->totpoint - 1; a++) { + if (!(cuma->curve[a].flag & flag)) { + cmp[b] = cuma->curve[a]; + b++; + } + else { + removed++; + } + } + cmp[b] = cuma->curve[a]; + + MEM_freeN(cuma->curve); + cuma->curve = cmp; + cuma->totpoint -= removed; } CurveMapPoint *curvemap_insert(CurveMap *cuma, float x, float y) { - CurveMapPoint *cmp = MEM_callocN((cuma->totpoint + 1) * sizeof(CurveMapPoint), "curve points"); - CurveMapPoint *newcmp = NULL; - int a, b; - bool foundloc = false; - - /* insert fragments of the old one and the new point to the new curve */ - cuma->totpoint++; - for (a = 0, b = 0; a < cuma->totpoint; a++) { - if ((foundloc == false) && ((a + 1 == cuma->totpoint) || (x < cuma->curve[a].x))) { - cmp[a].x = x; - cmp[a].y = y; - cmp[a].flag = CUMA_SELECT; - foundloc = true; - newcmp = &cmp[a]; - } - else { - cmp[a].x = cuma->curve[b].x; - cmp[a].y = cuma->curve[b].y; - /* make sure old points don't remain selected */ - cmp[a].flag = cuma->curve[b].flag & ~CUMA_SELECT; - cmp[a].shorty = cuma->curve[b].shorty; - b++; - } - } - - /* free old curve and replace it with new one */ - MEM_freeN(cuma->curve); - cuma->curve = cmp; - - return newcmp; + CurveMapPoint *cmp = MEM_callocN((cuma->totpoint + 1) * sizeof(CurveMapPoint), "curve points"); + CurveMapPoint *newcmp = NULL; + int a, b; + bool foundloc = false; + + /* insert fragments of the old one and the new point to the new curve */ + cuma->totpoint++; + for (a = 0, b = 0; a < cuma->totpoint; a++) { + if ((foundloc == false) && ((a + 1 == cuma->totpoint) || (x < cuma->curve[a].x))) { + cmp[a].x = x; + cmp[a].y = y; + cmp[a].flag = CUMA_SELECT; + foundloc = true; + newcmp = &cmp[a]; + } + else { + cmp[a].x = cuma->curve[b].x; + cmp[a].y = cuma->curve[b].y; + /* make sure old points don't remain selected */ + cmp[a].flag = cuma->curve[b].flag & ~CUMA_SELECT; + cmp[a].shorty = cuma->curve[b].shorty; + b++; + } + } + + /* free old curve and replace it with new one */ + MEM_freeN(cuma->curve); + cuma->curve = cmp; + + return newcmp; } void curvemap_reset(CurveMap *cuma, const rctf *clipr, int preset, int slope) { - if (cuma->curve) - MEM_freeN(cuma->curve); - - switch (preset) { - case CURVE_PRESET_LINE: cuma->totpoint = 2; break; - case CURVE_PRESET_SHARP: cuma->totpoint = 4; break; - case CURVE_PRESET_SMOOTH: cuma->totpoint = 4; break; - case CURVE_PRESET_MAX: cuma->totpoint = 2; break; - case CURVE_PRESET_MID9: cuma->totpoint = 9; break; - case CURVE_PRESET_ROUND: cuma->totpoint = 4; break; - case CURVE_PRESET_ROOT: cuma->totpoint = 4; break; - case CURVE_PRESET_GAUSS: cuma->totpoint = 7; break; - case CURVE_PRESET_BELL: cuma->totpoint = 3; break; - } - - cuma->curve = MEM_callocN(cuma->totpoint * sizeof(CurveMapPoint), "curve points"); - - switch (preset) { - case CURVE_PRESET_LINE: - cuma->curve[0].x = clipr->xmin; - cuma->curve[0].y = clipr->ymax; - cuma->curve[1].x = clipr->xmax; - cuma->curve[1].y = clipr->ymin; - if (slope == CURVEMAP_SLOPE_POS_NEG) { - cuma->curve[0].flag |= CUMA_HANDLE_VECTOR; - cuma->curve[1].flag |= CUMA_HANDLE_VECTOR; - } - break; - case CURVE_PRESET_SHARP: - cuma->curve[0].x = 0; - cuma->curve[0].y = 1; - cuma->curve[1].x = 0.25; - cuma->curve[1].y = 0.50; - cuma->curve[2].x = 0.75; - cuma->curve[2].y = 0.04; - cuma->curve[3].x = 1; - cuma->curve[3].y = 0; - break; - case CURVE_PRESET_SMOOTH: - cuma->curve[0].x = 0; - cuma->curve[0].y = 1; - cuma->curve[1].x = 0.25; - cuma->curve[1].y = 0.94; - cuma->curve[2].x = 0.75; - cuma->curve[2].y = 0.06; - cuma->curve[3].x = 1; - cuma->curve[3].y = 0; - break; - case CURVE_PRESET_MAX: - cuma->curve[0].x = 0; - cuma->curve[0].y = 1; - cuma->curve[1].x = 1; - cuma->curve[1].y = 1; - break; - case CURVE_PRESET_MID9: - { - int i; - for (i = 0; i < cuma->totpoint; i++) { - cuma->curve[i].x = i / ((float)cuma->totpoint - 1); - cuma->curve[i].y = 0.5; - } - break; - } - case CURVE_PRESET_ROUND: - cuma->curve[0].x = 0; - cuma->curve[0].y = 1; - cuma->curve[1].x = 0.5; - cuma->curve[1].y = 0.90; - cuma->curve[2].x = 0.86; - cuma->curve[2].y = 0.5; - cuma->curve[3].x = 1; - cuma->curve[3].y = 0; - break; - case CURVE_PRESET_ROOT: - cuma->curve[0].x = 0; - cuma->curve[0].y = 1; - cuma->curve[1].x = 0.25; - cuma->curve[1].y = 0.95; - cuma->curve[2].x = 0.75; - cuma->curve[2].y = 0.44; - cuma->curve[3].x = 1; - cuma->curve[3].y = 0; - break; - case CURVE_PRESET_GAUSS: - cuma->curve[0].x = 0; - cuma->curve[0].y = 0.025f; - cuma->curve[1].x = 0.16f; - cuma->curve[1].y = 0.135f; - cuma->curve[2].x = 0.298f; - cuma->curve[2].y = 0.36f; - - cuma->curve[3].x = 0.50f; - cuma->curve[3].y = 1.0f; - - cuma->curve[4].x = 0.70f; - cuma->curve[4].y = 0.36f; - cuma->curve[5].x = 0.84f; - cuma->curve[5].y = 0.135f; - cuma->curve[6].x = 1.0f; - cuma->curve[6].y = 0.025f; - break; - case CURVE_PRESET_BELL: - cuma->curve[0].x = 0; - cuma->curve[0].y = 0.025f; - - cuma->curve[1].x = 0.50f; - cuma->curve[1].y = 1.0f; - - cuma->curve[2].x = 1.0f; - cuma->curve[2].y = 0.025f; - break; - } - - /* mirror curve in x direction to have positive slope - * rather than default negative slope */ - if (slope == CURVEMAP_SLOPE_POSITIVE) { - int i, last = cuma->totpoint - 1; - CurveMapPoint *newpoints = MEM_dupallocN(cuma->curve); - - for (i = 0; i < cuma->totpoint; i++) { - newpoints[i].y = cuma->curve[last - i].y; - } - - MEM_freeN(cuma->curve); - cuma->curve = newpoints; - } - else if (slope == CURVEMAP_SLOPE_POS_NEG) { - const int num_points = cuma->totpoint * 2 - 1; - CurveMapPoint *new_points = MEM_mallocN(num_points * sizeof(CurveMapPoint), - "curve symmetric points"); - int i; - for (i = 0; i < cuma->totpoint; i++) { - const int src_last_point = cuma->totpoint - i - 1; - const int dst_last_point = num_points - i - 1; - new_points[i] = cuma->curve[src_last_point]; - new_points[i].x = (1.0f - cuma->curve[src_last_point].x) * 0.5f; - new_points[dst_last_point] = new_points[i]; - new_points[dst_last_point].x = 0.5f + cuma->curve[src_last_point].x * 0.5f; - } - cuma->totpoint = num_points; - MEM_freeN(cuma->curve); - cuma->curve = new_points; - } - - if (cuma->table) { - MEM_freeN(cuma->table); - cuma->table = NULL; - } + if (cuma->curve) + MEM_freeN(cuma->curve); + + switch (preset) { + case CURVE_PRESET_LINE: + cuma->totpoint = 2; + break; + case CURVE_PRESET_SHARP: + cuma->totpoint = 4; + break; + case CURVE_PRESET_SMOOTH: + cuma->totpoint = 4; + break; + case CURVE_PRESET_MAX: + cuma->totpoint = 2; + break; + case CURVE_PRESET_MID9: + cuma->totpoint = 9; + break; + case CURVE_PRESET_ROUND: + cuma->totpoint = 4; + break; + case CURVE_PRESET_ROOT: + cuma->totpoint = 4; + break; + case CURVE_PRESET_GAUSS: + cuma->totpoint = 7; + break; + case CURVE_PRESET_BELL: + cuma->totpoint = 3; + break; + } + + cuma->curve = MEM_callocN(cuma->totpoint * sizeof(CurveMapPoint), "curve points"); + + switch (preset) { + case CURVE_PRESET_LINE: + cuma->curve[0].x = clipr->xmin; + cuma->curve[0].y = clipr->ymax; + cuma->curve[1].x = clipr->xmax; + cuma->curve[1].y = clipr->ymin; + if (slope == CURVEMAP_SLOPE_POS_NEG) { + cuma->curve[0].flag |= CUMA_HANDLE_VECTOR; + cuma->curve[1].flag |= CUMA_HANDLE_VECTOR; + } + break; + case CURVE_PRESET_SHARP: + cuma->curve[0].x = 0; + cuma->curve[0].y = 1; + cuma->curve[1].x = 0.25; + cuma->curve[1].y = 0.50; + cuma->curve[2].x = 0.75; + cuma->curve[2].y = 0.04; + cuma->curve[3].x = 1; + cuma->curve[3].y = 0; + break; + case CURVE_PRESET_SMOOTH: + cuma->curve[0].x = 0; + cuma->curve[0].y = 1; + cuma->curve[1].x = 0.25; + cuma->curve[1].y = 0.94; + cuma->curve[2].x = 0.75; + cuma->curve[2].y = 0.06; + cuma->curve[3].x = 1; + cuma->curve[3].y = 0; + break; + case CURVE_PRESET_MAX: + cuma->curve[0].x = 0; + cuma->curve[0].y = 1; + cuma->curve[1].x = 1; + cuma->curve[1].y = 1; + break; + case CURVE_PRESET_MID9: { + int i; + for (i = 0; i < cuma->totpoint; i++) { + cuma->curve[i].x = i / ((float)cuma->totpoint - 1); + cuma->curve[i].y = 0.5; + } + break; + } + case CURVE_PRESET_ROUND: + cuma->curve[0].x = 0; + cuma->curve[0].y = 1; + cuma->curve[1].x = 0.5; + cuma->curve[1].y = 0.90; + cuma->curve[2].x = 0.86; + cuma->curve[2].y = 0.5; + cuma->curve[3].x = 1; + cuma->curve[3].y = 0; + break; + case CURVE_PRESET_ROOT: + cuma->curve[0].x = 0; + cuma->curve[0].y = 1; + cuma->curve[1].x = 0.25; + cuma->curve[1].y = 0.95; + cuma->curve[2].x = 0.75; + cuma->curve[2].y = 0.44; + cuma->curve[3].x = 1; + cuma->curve[3].y = 0; + break; + case CURVE_PRESET_GAUSS: + cuma->curve[0].x = 0; + cuma->curve[0].y = 0.025f; + cuma->curve[1].x = 0.16f; + cuma->curve[1].y = 0.135f; + cuma->curve[2].x = 0.298f; + cuma->curve[2].y = 0.36f; + + cuma->curve[3].x = 0.50f; + cuma->curve[3].y = 1.0f; + + cuma->curve[4].x = 0.70f; + cuma->curve[4].y = 0.36f; + cuma->curve[5].x = 0.84f; + cuma->curve[5].y = 0.135f; + cuma->curve[6].x = 1.0f; + cuma->curve[6].y = 0.025f; + break; + case CURVE_PRESET_BELL: + cuma->curve[0].x = 0; + cuma->curve[0].y = 0.025f; + + cuma->curve[1].x = 0.50f; + cuma->curve[1].y = 1.0f; + + cuma->curve[2].x = 1.0f; + cuma->curve[2].y = 0.025f; + break; + } + + /* mirror curve in x direction to have positive slope + * rather than default negative slope */ + if (slope == CURVEMAP_SLOPE_POSITIVE) { + int i, last = cuma->totpoint - 1; + CurveMapPoint *newpoints = MEM_dupallocN(cuma->curve); + + for (i = 0; i < cuma->totpoint; i++) { + newpoints[i].y = cuma->curve[last - i].y; + } + + MEM_freeN(cuma->curve); + cuma->curve = newpoints; + } + else if (slope == CURVEMAP_SLOPE_POS_NEG) { + const int num_points = cuma->totpoint * 2 - 1; + CurveMapPoint *new_points = MEM_mallocN(num_points * sizeof(CurveMapPoint), + "curve symmetric points"); + int i; + for (i = 0; i < cuma->totpoint; i++) { + const int src_last_point = cuma->totpoint - i - 1; + const int dst_last_point = num_points - i - 1; + new_points[i] = cuma->curve[src_last_point]; + new_points[i].x = (1.0f - cuma->curve[src_last_point].x) * 0.5f; + new_points[dst_last_point] = new_points[i]; + new_points[dst_last_point].x = 0.5f + cuma->curve[src_last_point].x * 0.5f; + } + cuma->totpoint = num_points; + MEM_freeN(cuma->curve); + cuma->curve = new_points; + } + + if (cuma->table) { + MEM_freeN(cuma->table); + cuma->table = NULL; + } } /** @@ -418,22 +435,22 @@ void curvemap_reset(CurveMap *cuma, const rctf *clipr, int preset, int slope) */ void curvemap_handle_set(CurveMap *cuma, int type) { - int a; - - for (a = 0; a < cuma->totpoint; a++) { - if (cuma->curve[a].flag & CUMA_SELECT) { - cuma->curve[a].flag &= ~(CUMA_HANDLE_VECTOR | CUMA_HANDLE_AUTO_ANIM); - if (type == HD_VECT) { - cuma->curve[a].flag |= CUMA_HANDLE_VECTOR; - } - else if (type == HD_AUTO_ANIM) { - cuma->curve[a].flag |= CUMA_HANDLE_AUTO_ANIM; - } - else { - /* pass */ - } - } - } + int a; + + for (a = 0; a < cuma->totpoint; a++) { + if (cuma->curve[a].flag & CUMA_SELECT) { + cuma->curve[a].flag &= ~(CUMA_HANDLE_VECTOR | CUMA_HANDLE_AUTO_ANIM); + if (type == HD_VECT) { + cuma->curve[a].flag |= CUMA_HANDLE_VECTOR; + } + else if (type == HD_AUTO_ANIM) { + cuma->curve[a].flag |= CUMA_HANDLE_AUTO_ANIM; + } + else { + /* pass */ + } + } + } } /* *********************** Making the tables and display ************** */ @@ -441,123 +458,120 @@ void curvemap_handle_set(CurveMap *cuma, int type) /** * reduced copy of #calchandleNurb_intern code in curve.c */ -static void calchandle_curvemap( - BezTriple *bezt, const BezTriple *prev, const BezTriple *next) +static void calchandle_curvemap(BezTriple *bezt, const BezTriple *prev, const BezTriple *next) { - /* defines to avoid confusion */ -#define p2_h1 ((p2) - 3) + /* defines to avoid confusion */ +#define p2_h1 ((p2)-3) #define p2_h2 ((p2) + 3) - const float *p1, *p3; - float *p2; - float pt[3]; - float len, len_a, len_b; - float dvec_a[2], dvec_b[2]; - - if (bezt->h1 == 0 && bezt->h2 == 0) { - return; - } - - p2 = bezt->vec[1]; - - if (prev == NULL) { - p3 = next->vec[1]; - pt[0] = 2.0f * p2[0] - p3[0]; - pt[1] = 2.0f * p2[1] - p3[1]; - p1 = pt; - } - else { - p1 = prev->vec[1]; - } - - if (next == NULL) { - p1 = prev->vec[1]; - pt[0] = 2.0f * p2[0] - p1[0]; - pt[1] = 2.0f * p2[1] - p1[1]; - p3 = pt; - } - else { - p3 = next->vec[1]; - } - - sub_v2_v2v2(dvec_a, p2, p1); - sub_v2_v2v2(dvec_b, p3, p2); - - len_a = len_v2(dvec_a); - len_b = len_v2(dvec_b); - - if (len_a == 0.0f) len_a = 1.0f; - if (len_b == 0.0f) len_b = 1.0f; - - if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) || ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) { /* auto */ - float tvec[2]; - tvec[0] = dvec_b[0] / len_b + dvec_a[0] / len_a; - tvec[1] = dvec_b[1] / len_b + dvec_a[1] / len_a; - - len = len_v2(tvec) * 2.5614f; - if (len != 0.0f) { - - if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM)) { - len_a /= len; - madd_v2_v2v2fl(p2_h1, p2, tvec, -len_a); - - if ((bezt->h1 == HD_AUTO_ANIM) && next && prev) { /* keep horizontal if extrema */ - const float ydiff1 = prev->vec[1][1] - bezt->vec[1][1]; - const float ydiff2 = next->vec[1][1] - bezt->vec[1][1]; - if ((ydiff1 <= 0.0f && ydiff2 <= 0.0f) || - (ydiff1 >= 0.0f && ydiff2 >= 0.0f)) - { - bezt->vec[0][1] = bezt->vec[1][1]; - } - else { /* handles should not be beyond y coord of two others */ - if (ydiff1 <= 0.0f) { - if (prev->vec[1][1] > bezt->vec[0][1]) { - bezt->vec[0][1] = prev->vec[1][1]; - } - } - else { - if (prev->vec[1][1] < bezt->vec[0][1]) { - bezt->vec[0][1] = prev->vec[1][1]; - } - } - } - } - } - if (ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) { - len_b /= len; - madd_v2_v2v2fl(p2_h2, p2, tvec, len_b); - - if ((bezt->h2 == HD_AUTO_ANIM) && next && prev) { /* keep horizontal if extrema */ - const float ydiff1 = prev->vec[1][1] - bezt->vec[1][1]; - const float ydiff2 = next->vec[1][1] - bezt->vec[1][1]; - if ((ydiff1 <= 0.0f && ydiff2 <= 0.0f) || - (ydiff1 >= 0.0f && ydiff2 >= 0.0f)) - { - bezt->vec[2][1] = bezt->vec[1][1]; - } - else { /* handles should not be beyond y coord of two others */ - if (ydiff1 <= 0.0f) { - if (next->vec[1][1] < bezt->vec[2][1]) { - bezt->vec[2][1] = next->vec[1][1]; - } - } - else { - if (next->vec[1][1] > bezt->vec[2][1]) { - bezt->vec[2][1] = next->vec[1][1]; - } - } - } - } - } - } - } - - if (bezt->h1 == HD_VECT) { /* vector */ - madd_v2_v2v2fl(p2_h1, p2, dvec_a, -1.0f / 3.0f); - } - if (bezt->h2 == HD_VECT) { - madd_v2_v2v2fl(p2_h2, p2, dvec_b, 1.0f / 3.0f); - } + const float *p1, *p3; + float *p2; + float pt[3]; + float len, len_a, len_b; + float dvec_a[2], dvec_b[2]; + + if (bezt->h1 == 0 && bezt->h2 == 0) { + return; + } + + p2 = bezt->vec[1]; + + if (prev == NULL) { + p3 = next->vec[1]; + pt[0] = 2.0f * p2[0] - p3[0]; + pt[1] = 2.0f * p2[1] - p3[1]; + p1 = pt; + } + else { + p1 = prev->vec[1]; + } + + if (next == NULL) { + p1 = prev->vec[1]; + pt[0] = 2.0f * p2[0] - p1[0]; + pt[1] = 2.0f * p2[1] - p1[1]; + p3 = pt; + } + else { + p3 = next->vec[1]; + } + + sub_v2_v2v2(dvec_a, p2, p1); + sub_v2_v2v2(dvec_b, p3, p2); + + len_a = len_v2(dvec_a); + len_b = len_v2(dvec_b); + + if (len_a == 0.0f) + len_a = 1.0f; + if (len_b == 0.0f) + len_b = 1.0f; + + if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) || ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) { /* auto */ + float tvec[2]; + tvec[0] = dvec_b[0] / len_b + dvec_a[0] / len_a; + tvec[1] = dvec_b[1] / len_b + dvec_a[1] / len_a; + + len = len_v2(tvec) * 2.5614f; + if (len != 0.0f) { + + if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM)) { + len_a /= len; + madd_v2_v2v2fl(p2_h1, p2, tvec, -len_a); + + if ((bezt->h1 == HD_AUTO_ANIM) && next && prev) { /* keep horizontal if extrema */ + const float ydiff1 = prev->vec[1][1] - bezt->vec[1][1]; + const float ydiff2 = next->vec[1][1] - bezt->vec[1][1]; + if ((ydiff1 <= 0.0f && ydiff2 <= 0.0f) || (ydiff1 >= 0.0f && ydiff2 >= 0.0f)) { + bezt->vec[0][1] = bezt->vec[1][1]; + } + else { /* handles should not be beyond y coord of two others */ + if (ydiff1 <= 0.0f) { + if (prev->vec[1][1] > bezt->vec[0][1]) { + bezt->vec[0][1] = prev->vec[1][1]; + } + } + else { + if (prev->vec[1][1] < bezt->vec[0][1]) { + bezt->vec[0][1] = prev->vec[1][1]; + } + } + } + } + } + if (ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) { + len_b /= len; + madd_v2_v2v2fl(p2_h2, p2, tvec, len_b); + + if ((bezt->h2 == HD_AUTO_ANIM) && next && prev) { /* keep horizontal if extrema */ + const float ydiff1 = prev->vec[1][1] - bezt->vec[1][1]; + const float ydiff2 = next->vec[1][1] - bezt->vec[1][1]; + if ((ydiff1 <= 0.0f && ydiff2 <= 0.0f) || (ydiff1 >= 0.0f && ydiff2 >= 0.0f)) { + bezt->vec[2][1] = bezt->vec[1][1]; + } + else { /* handles should not be beyond y coord of two others */ + if (ydiff1 <= 0.0f) { + if (next->vec[1][1] < bezt->vec[2][1]) { + bezt->vec[2][1] = next->vec[1][1]; + } + } + else { + if (next->vec[1][1] > bezt->vec[2][1]) { + bezt->vec[2][1] = next->vec[1][1]; + } + } + } + } + } + } + } + + if (bezt->h1 == HD_VECT) { /* vector */ + madd_v2_v2v2fl(p2_h1, p2, dvec_a, -1.0f / 3.0f); + } + if (bezt->h2 == HD_VECT) { + madd_v2_v2v2fl(p2_h2, p2, dvec_b, 1.0f / 3.0f); + } #undef p2_h1 #undef p2_h2 @@ -565,237 +579,256 @@ static void calchandle_curvemap( /* in X, out Y. * X is presumed to be outside first or last */ -static float curvemap_calc_extend(const CurveMap *cuma, float x, const float first[2], const float last[2]) +static float curvemap_calc_extend(const CurveMap *cuma, + float x, + const float first[2], + const float last[2]) { - if (x <= first[0]) { - if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) { - /* no extrapolate */ - return first[1]; - } - else { - if (cuma->ext_in[0] == 0.0f) - return first[1] + cuma->ext_in[1] * 10000.0f; - else - return first[1] + cuma->ext_in[1] * (x - first[0]) / cuma->ext_in[0]; - } - } - else if (x >= last[0]) { - if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) { - /* no extrapolate */ - return last[1]; - } - else { - if (cuma->ext_out[0] == 0.0f) - return last[1] - cuma->ext_out[1] * 10000.0f; - else - return last[1] + cuma->ext_out[1] * (x - last[0]) / cuma->ext_out[0]; - } - } - return 0.0f; + if (x <= first[0]) { + if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) { + /* no extrapolate */ + return first[1]; + } + else { + if (cuma->ext_in[0] == 0.0f) + return first[1] + cuma->ext_in[1] * 10000.0f; + else + return first[1] + cuma->ext_in[1] * (x - first[0]) / cuma->ext_in[0]; + } + } + else if (x >= last[0]) { + if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) { + /* no extrapolate */ + return last[1]; + } + else { + if (cuma->ext_out[0] == 0.0f) + return last[1] - cuma->ext_out[1] * 10000.0f; + else + return last[1] + cuma->ext_out[1] * (x - last[0]) / cuma->ext_out[0]; + } + } + return 0.0f; } /* only creates a table for a single channel in CurveMapping */ static void curvemap_make_table(CurveMap *cuma, const rctf *clipr) { - CurveMapPoint *cmp = cuma->curve; - BezTriple *bezt; - float *fp, *allpoints, *lastpoint, curf, range; - int a, totpoint; - - if (cuma->curve == NULL) return; - - /* default rect also is table range */ - cuma->mintable = clipr->xmin; - cuma->maxtable = clipr->xmax; - - /* hrmf... we now rely on blender ipo beziers, these are more advanced */ - bezt = MEM_callocN(cuma->totpoint * sizeof(BezTriple), "beztarr"); - - for (a = 0; a < cuma->totpoint; a++) { - cuma->mintable = min_ff(cuma->mintable, cmp[a].x); - cuma->maxtable = max_ff(cuma->maxtable, cmp[a].x); - bezt[a].vec[1][0] = cmp[a].x; - bezt[a].vec[1][1] = cmp[a].y; - if (cmp[a].flag & CUMA_HANDLE_VECTOR) { - bezt[a].h1 = bezt[a].h2 = HD_VECT; - } - else if (cmp[a].flag & CUMA_HANDLE_AUTO_ANIM) { - bezt[a].h1 = bezt[a].h2 = HD_AUTO_ANIM; - } - else { - bezt[a].h1 = bezt[a].h2 = HD_AUTO; - } - } - - const BezTriple *bezt_prev = NULL; - for (a = 0; a < cuma->totpoint; a++) { - const BezTriple *bezt_next = (a != cuma->totpoint - 1) ? &bezt[a + 1] : NULL; - calchandle_curvemap(&bezt[a], bezt_prev, bezt_next); - bezt_prev = &bezt[a]; - } - - /* first and last handle need correction, instead of pointing to center of next/prev, - * we let it point to the closest handle */ - if (cuma->totpoint > 2) { - float hlen, nlen, vec[3]; - - if (bezt[0].h2 == HD_AUTO) { - - hlen = len_v3v3(bezt[0].vec[1], bezt[0].vec[2]); /* original handle length */ - /* clip handle point */ - copy_v3_v3(vec, bezt[1].vec[0]); - if (vec[0] < bezt[0].vec[1][0]) - vec[0] = bezt[0].vec[1][0]; - - sub_v3_v3(vec, bezt[0].vec[1]); - nlen = len_v3(vec); - if (nlen > FLT_EPSILON) { - mul_v3_fl(vec, hlen / nlen); - add_v3_v3v3(bezt[0].vec[2], vec, bezt[0].vec[1]); - sub_v3_v3v3(bezt[0].vec[0], bezt[0].vec[1], vec); - } - } - a = cuma->totpoint - 1; - if (bezt[a].h2 == HD_AUTO) { - - hlen = len_v3v3(bezt[a].vec[1], bezt[a].vec[0]); /* original handle length */ - /* clip handle point */ - copy_v3_v3(vec, bezt[a - 1].vec[2]); - if (vec[0] > bezt[a].vec[1][0]) - vec[0] = bezt[a].vec[1][0]; - - sub_v3_v3(vec, bezt[a].vec[1]); - nlen = len_v3(vec); - if (nlen > FLT_EPSILON) { - mul_v3_fl(vec, hlen / nlen); - add_v3_v3v3(bezt[a].vec[0], vec, bezt[a].vec[1]); - sub_v3_v3v3(bezt[a].vec[2], bezt[a].vec[1], vec); - } - } - } - /* make the bezier curve */ - if (cuma->table) - MEM_freeN(cuma->table); - totpoint = (cuma->totpoint - 1) * CM_RESOL; - fp = allpoints = MEM_callocN(totpoint * 2 * sizeof(float), "table"); - - for (a = 0; a < cuma->totpoint - 1; a++, fp += 2 * CM_RESOL) { - correct_bezpart(bezt[a].vec[1], bezt[a].vec[2], bezt[a + 1].vec[0], bezt[a + 1].vec[1]); - BKE_curve_forward_diff_bezier(bezt[a].vec[1][0], bezt[a].vec[2][0], bezt[a + 1].vec[0][0], bezt[a + 1].vec[1][0], fp, CM_RESOL - 1, 2 * sizeof(float)); - BKE_curve_forward_diff_bezier(bezt[a].vec[1][1], bezt[a].vec[2][1], bezt[a + 1].vec[0][1], bezt[a + 1].vec[1][1], fp + 1, CM_RESOL - 1, 2 * sizeof(float)); - } - - /* store first and last handle for extrapolation, unit length */ - cuma->ext_in[0] = bezt[0].vec[0][0] - bezt[0].vec[1][0]; - cuma->ext_in[1] = bezt[0].vec[0][1] - bezt[0].vec[1][1]; - range = sqrtf(cuma->ext_in[0] * cuma->ext_in[0] + cuma->ext_in[1] * cuma->ext_in[1]); - cuma->ext_in[0] /= range; - cuma->ext_in[1] /= range; - - a = cuma->totpoint - 1; - cuma->ext_out[0] = bezt[a].vec[1][0] - bezt[a].vec[2][0]; - cuma->ext_out[1] = bezt[a].vec[1][1] - bezt[a].vec[2][1]; - range = sqrtf(cuma->ext_out[0] * cuma->ext_out[0] + cuma->ext_out[1] * cuma->ext_out[1]); - cuma->ext_out[0] /= range; - cuma->ext_out[1] /= range; - - /* cleanup */ - MEM_freeN(bezt); - - range = CM_TABLEDIV * (cuma->maxtable - cuma->mintable); - cuma->range = 1.0f / range; - - /* now make a table with CM_TABLE equal x distances */ - fp = allpoints; - lastpoint = allpoints + 2 * (totpoint - 1); - cmp = MEM_callocN((CM_TABLE + 1) * sizeof(CurveMapPoint), "dist table"); - - for (a = 0; a <= CM_TABLE; a++) { - curf = cuma->mintable + range * (float)a; - cmp[a].x = curf; - - /* get the first x coordinate larger than curf */ - while (curf >= fp[0] && fp != lastpoint) { - fp += 2; - } - if (fp == allpoints || (curf >= fp[0] && fp == lastpoint)) - cmp[a].y = curvemap_calc_extend(cuma, curf, allpoints, lastpoint); - else { - float fac1 = fp[0] - fp[-2]; - float fac2 = fp[0] - curf; - if (fac1 > FLT_EPSILON) - fac1 = fac2 / fac1; - else - fac1 = 0.0f; - cmp[a].y = fac1 * fp[-1] + (1.0f - fac1) * fp[1]; - } - } - - MEM_freeN(allpoints); - cuma->table = cmp; + CurveMapPoint *cmp = cuma->curve; + BezTriple *bezt; + float *fp, *allpoints, *lastpoint, curf, range; + int a, totpoint; + + if (cuma->curve == NULL) + return; + + /* default rect also is table range */ + cuma->mintable = clipr->xmin; + cuma->maxtable = clipr->xmax; + + /* hrmf... we now rely on blender ipo beziers, these are more advanced */ + bezt = MEM_callocN(cuma->totpoint * sizeof(BezTriple), "beztarr"); + + for (a = 0; a < cuma->totpoint; a++) { + cuma->mintable = min_ff(cuma->mintable, cmp[a].x); + cuma->maxtable = max_ff(cuma->maxtable, cmp[a].x); + bezt[a].vec[1][0] = cmp[a].x; + bezt[a].vec[1][1] = cmp[a].y; + if (cmp[a].flag & CUMA_HANDLE_VECTOR) { + bezt[a].h1 = bezt[a].h2 = HD_VECT; + } + else if (cmp[a].flag & CUMA_HANDLE_AUTO_ANIM) { + bezt[a].h1 = bezt[a].h2 = HD_AUTO_ANIM; + } + else { + bezt[a].h1 = bezt[a].h2 = HD_AUTO; + } + } + + const BezTriple *bezt_prev = NULL; + for (a = 0; a < cuma->totpoint; a++) { + const BezTriple *bezt_next = (a != cuma->totpoint - 1) ? &bezt[a + 1] : NULL; + calchandle_curvemap(&bezt[a], bezt_prev, bezt_next); + bezt_prev = &bezt[a]; + } + + /* first and last handle need correction, instead of pointing to center of next/prev, + * we let it point to the closest handle */ + if (cuma->totpoint > 2) { + float hlen, nlen, vec[3]; + + if (bezt[0].h2 == HD_AUTO) { + + hlen = len_v3v3(bezt[0].vec[1], bezt[0].vec[2]); /* original handle length */ + /* clip handle point */ + copy_v3_v3(vec, bezt[1].vec[0]); + if (vec[0] < bezt[0].vec[1][0]) + vec[0] = bezt[0].vec[1][0]; + + sub_v3_v3(vec, bezt[0].vec[1]); + nlen = len_v3(vec); + if (nlen > FLT_EPSILON) { + mul_v3_fl(vec, hlen / nlen); + add_v3_v3v3(bezt[0].vec[2], vec, bezt[0].vec[1]); + sub_v3_v3v3(bezt[0].vec[0], bezt[0].vec[1], vec); + } + } + a = cuma->totpoint - 1; + if (bezt[a].h2 == HD_AUTO) { + + hlen = len_v3v3(bezt[a].vec[1], bezt[a].vec[0]); /* original handle length */ + /* clip handle point */ + copy_v3_v3(vec, bezt[a - 1].vec[2]); + if (vec[0] > bezt[a].vec[1][0]) + vec[0] = bezt[a].vec[1][0]; + + sub_v3_v3(vec, bezt[a].vec[1]); + nlen = len_v3(vec); + if (nlen > FLT_EPSILON) { + mul_v3_fl(vec, hlen / nlen); + add_v3_v3v3(bezt[a].vec[0], vec, bezt[a].vec[1]); + sub_v3_v3v3(bezt[a].vec[2], bezt[a].vec[1], vec); + } + } + } + /* make the bezier curve */ + if (cuma->table) + MEM_freeN(cuma->table); + totpoint = (cuma->totpoint - 1) * CM_RESOL; + fp = allpoints = MEM_callocN(totpoint * 2 * sizeof(float), "table"); + + for (a = 0; a < cuma->totpoint - 1; a++, fp += 2 * CM_RESOL) { + correct_bezpart(bezt[a].vec[1], bezt[a].vec[2], bezt[a + 1].vec[0], bezt[a + 1].vec[1]); + BKE_curve_forward_diff_bezier(bezt[a].vec[1][0], + bezt[a].vec[2][0], + bezt[a + 1].vec[0][0], + bezt[a + 1].vec[1][0], + fp, + CM_RESOL - 1, + 2 * sizeof(float)); + BKE_curve_forward_diff_bezier(bezt[a].vec[1][1], + bezt[a].vec[2][1], + bezt[a + 1].vec[0][1], + bezt[a + 1].vec[1][1], + fp + 1, + CM_RESOL - 1, + 2 * sizeof(float)); + } + + /* store first and last handle for extrapolation, unit length */ + cuma->ext_in[0] = bezt[0].vec[0][0] - bezt[0].vec[1][0]; + cuma->ext_in[1] = bezt[0].vec[0][1] - bezt[0].vec[1][1]; + range = sqrtf(cuma->ext_in[0] * cuma->ext_in[0] + cuma->ext_in[1] * cuma->ext_in[1]); + cuma->ext_in[0] /= range; + cuma->ext_in[1] /= range; + + a = cuma->totpoint - 1; + cuma->ext_out[0] = bezt[a].vec[1][0] - bezt[a].vec[2][0]; + cuma->ext_out[1] = bezt[a].vec[1][1] - bezt[a].vec[2][1]; + range = sqrtf(cuma->ext_out[0] * cuma->ext_out[0] + cuma->ext_out[1] * cuma->ext_out[1]); + cuma->ext_out[0] /= range; + cuma->ext_out[1] /= range; + + /* cleanup */ + MEM_freeN(bezt); + + range = CM_TABLEDIV * (cuma->maxtable - cuma->mintable); + cuma->range = 1.0f / range; + + /* now make a table with CM_TABLE equal x distances */ + fp = allpoints; + lastpoint = allpoints + 2 * (totpoint - 1); + cmp = MEM_callocN((CM_TABLE + 1) * sizeof(CurveMapPoint), "dist table"); + + for (a = 0; a <= CM_TABLE; a++) { + curf = cuma->mintable + range * (float)a; + cmp[a].x = curf; + + /* get the first x coordinate larger than curf */ + while (curf >= fp[0] && fp != lastpoint) { + fp += 2; + } + if (fp == allpoints || (curf >= fp[0] && fp == lastpoint)) + cmp[a].y = curvemap_calc_extend(cuma, curf, allpoints, lastpoint); + else { + float fac1 = fp[0] - fp[-2]; + float fac2 = fp[0] - curf; + if (fac1 > FLT_EPSILON) + fac1 = fac2 / fac1; + else + fac1 = 0.0f; + cmp[a].y = fac1 * fp[-1] + (1.0f - fac1) * fp[1]; + } + } + + MEM_freeN(allpoints); + cuma->table = cmp; } /* call when you do images etc, needs restore too. also verifies tables */ /* it uses a flag to prevent premul or free to happen twice */ void curvemapping_premultiply(CurveMapping *cumap, int restore) { - int a; - - if (restore) { - if (cumap->flag & CUMA_PREMULLED) { - for (a = 0; a < 3; a++) { - MEM_freeN(cumap->cm[a].table); - cumap->cm[a].table = cumap->cm[a].premultable; - cumap->cm[a].premultable = NULL; - - copy_v2_v2(cumap->cm[a].ext_in, cumap->cm[a].premul_ext_in); - copy_v2_v2(cumap->cm[a].ext_out, cumap->cm[a].premul_ext_out); - zero_v2(cumap->cm[a].premul_ext_in); - zero_v2(cumap->cm[a].premul_ext_out); - } - - cumap->flag &= ~CUMA_PREMULLED; - } - } - else { - if ((cumap->flag & CUMA_PREMULLED) == 0) { - /* verify and copy */ - for (a = 0; a < 3; a++) { - if (cumap->cm[a].table == NULL) - curvemap_make_table(cumap->cm + a, &cumap->clipr); - cumap->cm[a].premultable = cumap->cm[a].table; - cumap->cm[a].table = MEM_mallocN((CM_TABLE + 1) * sizeof(CurveMapPoint), "premul table"); - memcpy(cumap->cm[a].table, cumap->cm[a].premultable, (CM_TABLE + 1) * sizeof(CurveMapPoint)); - } - - if (cumap->cm[3].table == NULL) - curvemap_make_table(cumap->cm + 3, &cumap->clipr); - - /* premul */ - for (a = 0; a < 3; a++) { - int b; - for (b = 0; b <= CM_TABLE; b++) { - cumap->cm[a].table[b].y = curvemap_evaluateF(cumap->cm + 3, cumap->cm[a].table[b].y); - } - - copy_v2_v2(cumap->cm[a].premul_ext_in, cumap->cm[a].ext_in); - copy_v2_v2(cumap->cm[a].premul_ext_out, cumap->cm[a].ext_out); - mul_v2_v2(cumap->cm[a].ext_in, cumap->cm[3].ext_in); - mul_v2_v2(cumap->cm[a].ext_out, cumap->cm[3].ext_out); - } - - cumap->flag |= CUMA_PREMULLED; - } - } + int a; + + if (restore) { + if (cumap->flag & CUMA_PREMULLED) { + for (a = 0; a < 3; a++) { + MEM_freeN(cumap->cm[a].table); + cumap->cm[a].table = cumap->cm[a].premultable; + cumap->cm[a].premultable = NULL; + + copy_v2_v2(cumap->cm[a].ext_in, cumap->cm[a].premul_ext_in); + copy_v2_v2(cumap->cm[a].ext_out, cumap->cm[a].premul_ext_out); + zero_v2(cumap->cm[a].premul_ext_in); + zero_v2(cumap->cm[a].premul_ext_out); + } + + cumap->flag &= ~CUMA_PREMULLED; + } + } + else { + if ((cumap->flag & CUMA_PREMULLED) == 0) { + /* verify and copy */ + for (a = 0; a < 3; a++) { + if (cumap->cm[a].table == NULL) + curvemap_make_table(cumap->cm + a, &cumap->clipr); + cumap->cm[a].premultable = cumap->cm[a].table; + cumap->cm[a].table = MEM_mallocN((CM_TABLE + 1) * sizeof(CurveMapPoint), "premul table"); + memcpy( + cumap->cm[a].table, cumap->cm[a].premultable, (CM_TABLE + 1) * sizeof(CurveMapPoint)); + } + + if (cumap->cm[3].table == NULL) + curvemap_make_table(cumap->cm + 3, &cumap->clipr); + + /* premul */ + for (a = 0; a < 3; a++) { + int b; + for (b = 0; b <= CM_TABLE; b++) { + cumap->cm[a].table[b].y = curvemap_evaluateF(cumap->cm + 3, cumap->cm[a].table[b].y); + } + + copy_v2_v2(cumap->cm[a].premul_ext_in, cumap->cm[a].ext_in); + copy_v2_v2(cumap->cm[a].premul_ext_out, cumap->cm[a].ext_out); + mul_v2_v2(cumap->cm[a].ext_in, cumap->cm[3].ext_in); + mul_v2_v2(cumap->cm[a].ext_out, cumap->cm[3].ext_out); + } + + cumap->flag |= CUMA_PREMULLED; + } + } } static int sort_curvepoints(const void *a1, const void *a2) { - const struct CurveMapPoint *x1 = a1, *x2 = a2; + const struct CurveMapPoint *x1 = a1, *x2 = a2; - if (x1->x > x2->x) return 1; - else if (x1->x < x2->x) return -1; - return 0; + if (x1->x > x2->x) + return 1; + else if (x1->x < x2->x) + return -1; + return 0; } /* ************************ more CurveMapping calls *************** */ @@ -803,158 +836,161 @@ static int sort_curvepoints(const void *a1, const void *a2) /* note; only does current curvemap! */ void curvemapping_changed(CurveMapping *cumap, const bool rem_doubles) { - CurveMap *cuma = cumap->cm + cumap->cur; - CurveMapPoint *cmp = cuma->curve; - rctf *clipr = &cumap->clipr; - float thresh = 0.01f * BLI_rctf_size_x(clipr); - float dx = 0.0f, dy = 0.0f; - int a; - - cumap->changed_timestamp++; - - /* clamp with clip */ - if (cumap->flag & CUMA_DO_CLIP) { - for (a = 0; a < cuma->totpoint; a++) { - if (cmp[a].flag & CUMA_SELECT) { - if (cmp[a].x < clipr->xmin) - dx = min_ff(dx, cmp[a].x - clipr->xmin); - else if (cmp[a].x > clipr->xmax) - dx = max_ff(dx, cmp[a].x - clipr->xmax); - if (cmp[a].y < clipr->ymin) - dy = min_ff(dy, cmp[a].y - clipr->ymin); - else if (cmp[a].y > clipr->ymax) - dy = max_ff(dy, cmp[a].y - clipr->ymax); - } - } - for (a = 0; a < cuma->totpoint; a++) { - if (cmp[a].flag & CUMA_SELECT) { - cmp[a].x -= dx; - cmp[a].y -= dy; - } - } - - /* ensure zoom-level respects clipping */ - if (BLI_rctf_size_x(&cumap->curr) > BLI_rctf_size_x(&cumap->clipr)) { - cumap->curr.xmin = cumap->clipr.xmin; - cumap->curr.xmax = cumap->clipr.xmax; - } - if (BLI_rctf_size_y(&cumap->curr) > BLI_rctf_size_y(&cumap->clipr)) { - cumap->curr.ymin = cumap->clipr.ymin; - cumap->curr.ymax = cumap->clipr.ymax; - } - } - - - qsort(cmp, cuma->totpoint, sizeof(CurveMapPoint), sort_curvepoints); - - /* remove doubles, threshold set on 1% of default range */ - if (rem_doubles && cuma->totpoint > 2) { - for (a = 0; a < cuma->totpoint - 1; a++) { - dx = cmp[a].x - cmp[a + 1].x; - dy = cmp[a].y - cmp[a + 1].y; - if (sqrtf(dx * dx + dy * dy) < thresh) { - if (a == 0) { - cmp[a + 1].flag |= CUMA_HANDLE_VECTOR; - if (cmp[a + 1].flag & CUMA_SELECT) - cmp[a].flag |= CUMA_SELECT; - } - else { - cmp[a].flag |= CUMA_HANDLE_VECTOR; - if (cmp[a].flag & CUMA_SELECT) - cmp[a + 1].flag |= CUMA_SELECT; - } - break; /* we assume 1 deletion per edit is ok */ - } - } - if (a != cuma->totpoint - 1) - curvemap_remove(cuma, 2); - } - curvemap_make_table(cuma, clipr); + CurveMap *cuma = cumap->cm + cumap->cur; + CurveMapPoint *cmp = cuma->curve; + rctf *clipr = &cumap->clipr; + float thresh = 0.01f * BLI_rctf_size_x(clipr); + float dx = 0.0f, dy = 0.0f; + int a; + + cumap->changed_timestamp++; + + /* clamp with clip */ + if (cumap->flag & CUMA_DO_CLIP) { + for (a = 0; a < cuma->totpoint; a++) { + if (cmp[a].flag & CUMA_SELECT) { + if (cmp[a].x < clipr->xmin) + dx = min_ff(dx, cmp[a].x - clipr->xmin); + else if (cmp[a].x > clipr->xmax) + dx = max_ff(dx, cmp[a].x - clipr->xmax); + if (cmp[a].y < clipr->ymin) + dy = min_ff(dy, cmp[a].y - clipr->ymin); + else if (cmp[a].y > clipr->ymax) + dy = max_ff(dy, cmp[a].y - clipr->ymax); + } + } + for (a = 0; a < cuma->totpoint; a++) { + if (cmp[a].flag & CUMA_SELECT) { + cmp[a].x -= dx; + cmp[a].y -= dy; + } + } + + /* ensure zoom-level respects clipping */ + if (BLI_rctf_size_x(&cumap->curr) > BLI_rctf_size_x(&cumap->clipr)) { + cumap->curr.xmin = cumap->clipr.xmin; + cumap->curr.xmax = cumap->clipr.xmax; + } + if (BLI_rctf_size_y(&cumap->curr) > BLI_rctf_size_y(&cumap->clipr)) { + cumap->curr.ymin = cumap->clipr.ymin; + cumap->curr.ymax = cumap->clipr.ymax; + } + } + + qsort(cmp, cuma->totpoint, sizeof(CurveMapPoint), sort_curvepoints); + + /* remove doubles, threshold set on 1% of default range */ + if (rem_doubles && cuma->totpoint > 2) { + for (a = 0; a < cuma->totpoint - 1; a++) { + dx = cmp[a].x - cmp[a + 1].x; + dy = cmp[a].y - cmp[a + 1].y; + if (sqrtf(dx * dx + dy * dy) < thresh) { + if (a == 0) { + cmp[a + 1].flag |= CUMA_HANDLE_VECTOR; + if (cmp[a + 1].flag & CUMA_SELECT) + cmp[a].flag |= CUMA_SELECT; + } + else { + cmp[a].flag |= CUMA_HANDLE_VECTOR; + if (cmp[a].flag & CUMA_SELECT) + cmp[a + 1].flag |= CUMA_SELECT; + } + break; /* we assume 1 deletion per edit is ok */ + } + } + if (a != cuma->totpoint - 1) + curvemap_remove(cuma, 2); + } + curvemap_make_table(cuma, clipr); } void curvemapping_changed_all(CurveMapping *cumap) { - int a, cur = cumap->cur; + int a, cur = cumap->cur; - for (a = 0; a < CM_TOT; a++) { - if (cumap->cm[a].curve) { - cumap->cur = a; - curvemapping_changed(cumap, false); - } - } + for (a = 0; a < CM_TOT; a++) { + if (cumap->cm[a].curve) { + cumap->cur = a; + curvemapping_changed(cumap, false); + } + } - cumap->cur = cur; + cumap->cur = cur; } /* table should be verified */ float curvemap_evaluateF(const CurveMap *cuma, float value) { - float fi; - int i; - - /* index in table */ - fi = (value - cuma->mintable) * cuma->range; - i = (int)fi; - - /* fi is table float index and should check against table range i.e. [0.0 CM_TABLE] */ - if (fi < 0.0f || fi > CM_TABLE) - return curvemap_calc_extend(cuma, value, &cuma->table[0].x, &cuma->table[CM_TABLE].x); - else { - if (i < 0) return cuma->table[0].y; - if (i >= CM_TABLE) return cuma->table[CM_TABLE].y; - - fi = fi - (float)i; - return (1.0f - fi) * cuma->table[i].y + (fi) * cuma->table[i + 1].y; - } + float fi; + int i; + + /* index in table */ + fi = (value - cuma->mintable) * cuma->range; + i = (int)fi; + + /* fi is table float index and should check against table range i.e. [0.0 CM_TABLE] */ + if (fi < 0.0f || fi > CM_TABLE) + return curvemap_calc_extend(cuma, value, &cuma->table[0].x, &cuma->table[CM_TABLE].x); + else { + if (i < 0) + return cuma->table[0].y; + if (i >= CM_TABLE) + return cuma->table[CM_TABLE].y; + + fi = fi - (float)i; + return (1.0f - fi) * cuma->table[i].y + (fi)*cuma->table[i + 1].y; + } } /* works with curve 'cur' */ float curvemapping_evaluateF(const CurveMapping *cumap, int cur, float value) { - const CurveMap *cuma = cumap->cm + cur; - float val = curvemap_evaluateF(cuma, value); - - /* account for clipping */ - if (cumap->flag & CUMA_DO_CLIP) { - if (val < cumap->curr.ymin) - val = cumap->curr.ymin; - else if (val > cumap->curr.ymax) - val = cumap->curr.ymax; - } - - return val; + const CurveMap *cuma = cumap->cm + cur; + float val = curvemap_evaluateF(cuma, value); + + /* account for clipping */ + if (cumap->flag & CUMA_DO_CLIP) { + if (val < cumap->curr.ymin) + val = cumap->curr.ymin; + else if (val > cumap->curr.ymax) + val = cumap->curr.ymax; + } + + return val; } /* vector case */ void curvemapping_evaluate3F(const CurveMapping *cumap, float vecout[3], const float vecin[3]) { - vecout[0] = curvemap_evaluateF(&cumap->cm[0], vecin[0]); - vecout[1] = curvemap_evaluateF(&cumap->cm[1], vecin[1]); - vecout[2] = curvemap_evaluateF(&cumap->cm[2], vecin[2]); + vecout[0] = curvemap_evaluateF(&cumap->cm[0], vecin[0]); + vecout[1] = curvemap_evaluateF(&cumap->cm[1], vecin[1]); + vecout[2] = curvemap_evaluateF(&cumap->cm[2], vecin[2]); } /* RGB case, no black/white points, no premult */ void curvemapping_evaluateRGBF(const CurveMapping *cumap, float vecout[3], const float vecin[3]) { - vecout[0] = curvemap_evaluateF(&cumap->cm[0], curvemap_evaluateF(&cumap->cm[3], vecin[0])); - vecout[1] = curvemap_evaluateF(&cumap->cm[1], curvemap_evaluateF(&cumap->cm[3], vecin[1])); - vecout[2] = curvemap_evaluateF(&cumap->cm[2], curvemap_evaluateF(&cumap->cm[3], vecin[2])); + vecout[0] = curvemap_evaluateF(&cumap->cm[0], curvemap_evaluateF(&cumap->cm[3], vecin[0])); + vecout[1] = curvemap_evaluateF(&cumap->cm[1], curvemap_evaluateF(&cumap->cm[3], vecin[1])); + vecout[2] = curvemap_evaluateF(&cumap->cm[2], curvemap_evaluateF(&cumap->cm[3], vecin[2])); } -static void curvemapping_evaluateRGBF_filmlike(const CurveMapping *cumap, float vecout[3], const float vecin[3], +static void curvemapping_evaluateRGBF_filmlike(const CurveMapping *cumap, + float vecout[3], + const float vecin[3], const int channel_offset[3]) { - const float v0in = vecin[channel_offset[0]]; - const float v1in = vecin[channel_offset[1]]; - const float v2in = vecin[channel_offset[2]]; + const float v0in = vecin[channel_offset[0]]; + const float v1in = vecin[channel_offset[1]]; + const float v2in = vecin[channel_offset[2]]; - const float v0 = curvemap_evaluateF(&cumap->cm[channel_offset[0]], v0in); - const float v2 = curvemap_evaluateF(&cumap->cm[channel_offset[2]], v2in); - const float v1 = v2 + ((v0 - v2) * (v1in - v2in) / (v0in - v2in)); + const float v0 = curvemap_evaluateF(&cumap->cm[channel_offset[0]], v0in); + const float v2 = curvemap_evaluateF(&cumap->cm[channel_offset[2]], v2in); + const float v1 = v2 + ((v0 - v2) * (v1in - v2in) / (v0in - v2in)); - vecout[channel_offset[0]] = v0; - vecout[channel_offset[1]] = v1; - vecout[channel_offset[2]] = v2; + vecout[channel_offset[0]] = v0; + vecout[channel_offset[1]] = v1; + vecout[channel_offset[2]] = v2; } /** same as #curvemapping_evaluate_premulRGBF @@ -966,681 +1002,723 @@ static void curvemapping_evaluateRGBF_filmlike(const CurveMapping *cumap, float * \param black: Use instead of cumap->black * \param bwmul: Use instead of cumap->bwmul */ -void curvemapping_evaluate_premulRGBF_ex( - const CurveMapping *cumap, float vecout[3], const float vecin[3], - const float black[3], const float bwmul[3]) +void curvemapping_evaluate_premulRGBF_ex(const CurveMapping *cumap, + float vecout[3], + const float vecin[3], + const float black[3], + const float bwmul[3]) { - const float r = (vecin[0] - black[0]) * bwmul[0]; - const float g = (vecin[1] - black[1]) * bwmul[1]; - const float b = (vecin[2] - black[2]) * bwmul[2]; - - switch (cumap->tone) { - default: - case CURVE_TONE_STANDARD: - { - vecout[0] = curvemap_evaluateF(&cumap->cm[0], r); - vecout[1] = curvemap_evaluateF(&cumap->cm[1], g); - vecout[2] = curvemap_evaluateF(&cumap->cm[2], b); - break; - } - case CURVE_TONE_FILMLIKE: - { - if (r >= g) { - if (g > b) { - /* Case 1: r >= g > b */ - const int shuffeled_channels[] = {0, 1, 2}; - curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels); - } - else if (b > r) { - /* Case 2: b > r >= g */ - const int shuffeled_channels[] = {2, 0, 1}; - curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels); - } - else if (b > g) { - /* Case 3: r >= b > g */ - const int shuffeled_channels[] = {0, 2, 1}; - curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels); - } - else { - /* Case 4: r >= g == b */ - copy_v2_fl2(vecout, curvemap_evaluateF(&cumap->cm[0], r), curvemap_evaluateF(&cumap->cm[1], g)); - vecout[2] = vecout[1]; - } - } - else { - if (r >= b) { - /* Case 5: g > r >= b */ - const int shuffeled_channels[] = {1, 0, 2}; - curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels); - } - else if (b > g) { - /* Case 6: b > g > r */ - const int shuffeled_channels[] = {2, 1, 0}; - curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels); - } - else { - /* Case 7: g >= b > r */ - const int shuffeled_channels[] = {1, 2, 0}; - curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels); - } - } - break; - } - } + const float r = (vecin[0] - black[0]) * bwmul[0]; + const float g = (vecin[1] - black[1]) * bwmul[1]; + const float b = (vecin[2] - black[2]) * bwmul[2]; + + switch (cumap->tone) { + default: + case CURVE_TONE_STANDARD: { + vecout[0] = curvemap_evaluateF(&cumap->cm[0], r); + vecout[1] = curvemap_evaluateF(&cumap->cm[1], g); + vecout[2] = curvemap_evaluateF(&cumap->cm[2], b); + break; + } + case CURVE_TONE_FILMLIKE: { + if (r >= g) { + if (g > b) { + /* Case 1: r >= g > b */ + const int shuffeled_channels[] = {0, 1, 2}; + curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels); + } + else if (b > r) { + /* Case 2: b > r >= g */ + const int shuffeled_channels[] = {2, 0, 1}; + curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels); + } + else if (b > g) { + /* Case 3: r >= b > g */ + const int shuffeled_channels[] = {0, 2, 1}; + curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels); + } + else { + /* Case 4: r >= g == b */ + copy_v2_fl2( + vecout, curvemap_evaluateF(&cumap->cm[0], r), curvemap_evaluateF(&cumap->cm[1], g)); + vecout[2] = vecout[1]; + } + } + else { + if (r >= b) { + /* Case 5: g > r >= b */ + const int shuffeled_channels[] = {1, 0, 2}; + curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels); + } + else if (b > g) { + /* Case 6: b > g > r */ + const int shuffeled_channels[] = {2, 1, 0}; + curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels); + } + else { + /* Case 7: g >= b > r */ + const int shuffeled_channels[] = {1, 2, 0}; + curvemapping_evaluateRGBF_filmlike(cumap, vecout, vecin, shuffeled_channels); + } + } + break; + } + } } /* RGB with black/white points and premult. tables are checked */ -void curvemapping_evaluate_premulRGBF(const CurveMapping *cumap, float vecout[3], const float vecin[3]) +void curvemapping_evaluate_premulRGBF(const CurveMapping *cumap, + float vecout[3], + const float vecin[3]) { - curvemapping_evaluate_premulRGBF_ex(cumap, vecout, vecin, cumap->black, cumap->bwmul); + curvemapping_evaluate_premulRGBF_ex(cumap, vecout, vecin, cumap->black, cumap->bwmul); } /* same as above, byte version */ -void curvemapping_evaluate_premulRGB(const CurveMapping *cumap, unsigned char vecout_byte[3], const unsigned char vecin_byte[3]) +void curvemapping_evaluate_premulRGB(const CurveMapping *cumap, + unsigned char vecout_byte[3], + const unsigned char vecin_byte[3]) { - float vecin[3], vecout[3]; + float vecin[3], vecout[3]; - vecin[0] = (float) vecin_byte[0] / 255.0f; - vecin[1] = (float) vecin_byte[1] / 255.0f; - vecin[2] = (float) vecin_byte[2] / 255.0f; + vecin[0] = (float)vecin_byte[0] / 255.0f; + vecin[1] = (float)vecin_byte[1] / 255.0f; + vecin[2] = (float)vecin_byte[2] / 255.0f; - curvemapping_evaluate_premulRGBF(cumap, vecout, vecin); + curvemapping_evaluate_premulRGBF(cumap, vecout, vecin); - vecout_byte[0] = unit_float_to_uchar_clamp(vecout[0]); - vecout_byte[1] = unit_float_to_uchar_clamp(vecout[1]); - vecout_byte[2] = unit_float_to_uchar_clamp(vecout[2]); + vecout_byte[0] = unit_float_to_uchar_clamp(vecout[0]); + vecout_byte[1] = unit_float_to_uchar_clamp(vecout[1]); + vecout_byte[2] = unit_float_to_uchar_clamp(vecout[2]); } int curvemapping_RGBA_does_something(const CurveMapping *cumap) { - int a; - - if (cumap->black[0] != 0.0f) return 1; - if (cumap->black[1] != 0.0f) return 1; - if (cumap->black[2] != 0.0f) return 1; - if (cumap->white[0] != 1.0f) return 1; - if (cumap->white[1] != 1.0f) return 1; - if (cumap->white[2] != 1.0f) return 1; - - for (a = 0; a < CM_TOT; a++) { - if (cumap->cm[a].curve) { - if (cumap->cm[a].totpoint != 2) return 1; - - if (cumap->cm[a].curve[0].x != 0.0f) return 1; - if (cumap->cm[a].curve[0].y != 0.0f) return 1; - if (cumap->cm[a].curve[1].x != 1.0f) return 1; - if (cumap->cm[a].curve[1].y != 1.0f) return 1; - } - } - return 0; + int a; + + if (cumap->black[0] != 0.0f) + return 1; + if (cumap->black[1] != 0.0f) + return 1; + if (cumap->black[2] != 0.0f) + return 1; + if (cumap->white[0] != 1.0f) + return 1; + if (cumap->white[1] != 1.0f) + return 1; + if (cumap->white[2] != 1.0f) + return 1; + + for (a = 0; a < CM_TOT; a++) { + if (cumap->cm[a].curve) { + if (cumap->cm[a].totpoint != 2) + return 1; + + if (cumap->cm[a].curve[0].x != 0.0f) + return 1; + if (cumap->cm[a].curve[0].y != 0.0f) + return 1; + if (cumap->cm[a].curve[1].x != 1.0f) + return 1; + if (cumap->cm[a].curve[1].y != 1.0f) + return 1; + } + } + return 0; } void curvemapping_initialize(CurveMapping *cumap) { - int a; + int a; - if (cumap == NULL) return; + if (cumap == NULL) + return; - for (a = 0; a < CM_TOT; a++) { - if (cumap->cm[a].table == NULL) - curvemap_make_table(cumap->cm + a, &cumap->clipr); - } + for (a = 0; a < CM_TOT; a++) { + if (cumap->cm[a].table == NULL) + curvemap_make_table(cumap->cm + a, &cumap->clipr); + } } void curvemapping_table_RGBA(const CurveMapping *cumap, float **array, int *size) { - int a; - - *size = CM_TABLE + 1; - *array = MEM_callocN(sizeof(float) * (*size) * 4, "CurveMapping"); - - for (a = 0; a < *size; a++) { - if (cumap->cm[0].table) - (*array)[a * 4 + 0] = cumap->cm[0].table[a].y; - if (cumap->cm[1].table) - (*array)[a * 4 + 1] = cumap->cm[1].table[a].y; - if (cumap->cm[2].table) - (*array)[a * 4 + 2] = cumap->cm[2].table[a].y; - if (cumap->cm[3].table) - (*array)[a * 4 + 3] = cumap->cm[3].table[a].y; - } + int a; + + *size = CM_TABLE + 1; + *array = MEM_callocN(sizeof(float) * (*size) * 4, "CurveMapping"); + + for (a = 0; a < *size; a++) { + if (cumap->cm[0].table) + (*array)[a * 4 + 0] = cumap->cm[0].table[a].y; + if (cumap->cm[1].table) + (*array)[a * 4 + 1] = cumap->cm[1].table[a].y; + if (cumap->cm[2].table) + (*array)[a * 4 + 2] = cumap->cm[2].table[a].y; + if (cumap->cm[3].table) + (*array)[a * 4 + 3] = cumap->cm[3].table[a].y; + } } /* ***************** Histogram **************** */ -#define INV_255 (1.f / 255.f) +#define INV_255 (1.f / 255.f) BLI_INLINE int get_bin_float(float f) { - int bin = (int)((f * 255.0f) + 0.5f); /* 0.5 to prevent quantisation differences */ + int bin = (int)((f * 255.0f) + 0.5f); /* 0.5 to prevent quantisation differences */ - /* note: clamp integer instead of float to avoid problems with NaN */ - CLAMP(bin, 0, 255); + /* note: clamp integer instead of float to avoid problems with NaN */ + CLAMP(bin, 0, 255); - return bin; + return bin; } -static void save_sample_line(Scopes *scopes, const int idx, const float fx, const float rgb[3], const float ycc[3]) +static void save_sample_line( + Scopes *scopes, const int idx, const float fx, const float rgb[3], const float ycc[3]) { - float yuv[3]; - - /* vectorscope*/ - rgb_to_yuv(rgb[0], rgb[1], rgb[2], &yuv[0], &yuv[1], &yuv[2], BLI_YUV_ITU_BT709); - scopes->vecscope[idx + 0] = yuv[1]; - scopes->vecscope[idx + 1] = yuv[2]; - - /* waveform */ - switch (scopes->wavefrm_mode) { - case SCOPES_WAVEFRM_RGB: - case SCOPES_WAVEFRM_RGB_PARADE: - scopes->waveform_1[idx + 0] = fx; - scopes->waveform_1[idx + 1] = rgb[0]; - scopes->waveform_2[idx + 0] = fx; - scopes->waveform_2[idx + 1] = rgb[1]; - scopes->waveform_3[idx + 0] = fx; - scopes->waveform_3[idx + 1] = rgb[2]; - break; - case SCOPES_WAVEFRM_LUMA: - scopes->waveform_1[idx + 0] = fx; - scopes->waveform_1[idx + 1] = ycc[0]; - break; - case SCOPES_WAVEFRM_YCC_JPEG: - case SCOPES_WAVEFRM_YCC_709: - case SCOPES_WAVEFRM_YCC_601: - scopes->waveform_1[idx + 0] = fx; - scopes->waveform_1[idx + 1] = ycc[0]; - scopes->waveform_2[idx + 0] = fx; - scopes->waveform_2[idx + 1] = ycc[1]; - scopes->waveform_3[idx + 0] = fx; - scopes->waveform_3[idx + 1] = ycc[2]; - break; - } + float yuv[3]; + + /* vectorscope*/ + rgb_to_yuv(rgb[0], rgb[1], rgb[2], &yuv[0], &yuv[1], &yuv[2], BLI_YUV_ITU_BT709); + scopes->vecscope[idx + 0] = yuv[1]; + scopes->vecscope[idx + 1] = yuv[2]; + + /* waveform */ + switch (scopes->wavefrm_mode) { + case SCOPES_WAVEFRM_RGB: + case SCOPES_WAVEFRM_RGB_PARADE: + scopes->waveform_1[idx + 0] = fx; + scopes->waveform_1[idx + 1] = rgb[0]; + scopes->waveform_2[idx + 0] = fx; + scopes->waveform_2[idx + 1] = rgb[1]; + scopes->waveform_3[idx + 0] = fx; + scopes->waveform_3[idx + 1] = rgb[2]; + break; + case SCOPES_WAVEFRM_LUMA: + scopes->waveform_1[idx + 0] = fx; + scopes->waveform_1[idx + 1] = ycc[0]; + break; + case SCOPES_WAVEFRM_YCC_JPEG: + case SCOPES_WAVEFRM_YCC_709: + case SCOPES_WAVEFRM_YCC_601: + scopes->waveform_1[idx + 0] = fx; + scopes->waveform_1[idx + 1] = ycc[0]; + scopes->waveform_2[idx + 0] = fx; + scopes->waveform_2[idx + 1] = ycc[1]; + scopes->waveform_3[idx + 0] = fx; + scopes->waveform_3[idx + 1] = ycc[2]; + break; + } } -void BKE_histogram_update_sample_line(Histogram *hist, ImBuf *ibuf, const ColorManagedViewSettings *view_settings, +void BKE_histogram_update_sample_line(Histogram *hist, + ImBuf *ibuf, + const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings) { - int i, x, y; - const float *fp; - unsigned char *cp; - - int x1 = 0.5f + hist->co[0][0] * ibuf->x; - int x2 = 0.5f + hist->co[1][0] * ibuf->x; - int y1 = 0.5f + hist->co[0][1] * ibuf->y; - int y2 = 0.5f + hist->co[1][1] * ibuf->y; - - struct ColormanageProcessor *cm_processor = NULL; - - hist->channels = 3; - hist->x_resolution = 256; - hist->xmax = 1.0f; - /* hist->ymax = 1.0f; */ /* now do this on the operator _only_ */ - - if (ibuf->rect == NULL && ibuf->rect_float == NULL) return; - - if (ibuf->rect_float) - cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings); - - for (i = 0; i < 256; i++) { - x = (int)(0.5f + x1 + (float)i * (x2 - x1) / 255.0f); - y = (int)(0.5f + y1 + (float)i * (y2 - y1) / 255.0f); - - if (x < 0 || y < 0 || x >= ibuf->x || y >= ibuf->y) { - hist->data_luma[i] = hist->data_r[i] = hist->data_g[i] = hist->data_b[i] = hist->data_a[i] = 0.0f; - } - else { - if (ibuf->rect_float) { - float rgba[4]; - fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x)); - - switch (ibuf->channels) { - case 4: - copy_v4_v4(rgba, fp); - IMB_colormanagement_processor_apply_v4(cm_processor, rgba); - break; - case 3: - copy_v3_v3(rgba, fp); - IMB_colormanagement_processor_apply_v3(cm_processor, rgba); - rgba[3] = 1.0f; - break; - case 2: - copy_v3_fl(rgba, fp[0]); - rgba[3] = fp[1]; - break; - case 1: - copy_v3_fl(rgba, fp[0]); - rgba[3] = 1.0f; - break; - default: - BLI_assert(0); - } - - hist->data_luma[i] = IMB_colormanagement_get_luminance(rgba); - hist->data_r[i] = rgba[0]; - hist->data_g[i] = rgba[1]; - hist->data_b[i] = rgba[2]; - hist->data_a[i] = rgba[3]; - } - else if (ibuf->rect) { - cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x); - hist->data_luma[i] = (float)IMB_colormanagement_get_luminance_byte(cp) / 255.0f; - hist->data_r[i] = (float)cp[0] / 255.0f; - hist->data_g[i] = (float)cp[1] / 255.0f; - hist->data_b[i] = (float)cp[2] / 255.0f; - hist->data_a[i] = (float)cp[3] / 255.0f; - } - } - } - - if (cm_processor) - IMB_colormanagement_processor_free(cm_processor); + int i, x, y; + const float *fp; + unsigned char *cp; + + int x1 = 0.5f + hist->co[0][0] * ibuf->x; + int x2 = 0.5f + hist->co[1][0] * ibuf->x; + int y1 = 0.5f + hist->co[0][1] * ibuf->y; + int y2 = 0.5f + hist->co[1][1] * ibuf->y; + + struct ColormanageProcessor *cm_processor = NULL; + + hist->channels = 3; + hist->x_resolution = 256; + hist->xmax = 1.0f; + /* hist->ymax = 1.0f; */ /* now do this on the operator _only_ */ + + if (ibuf->rect == NULL && ibuf->rect_float == NULL) + return; + + if (ibuf->rect_float) + cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings); + + for (i = 0; i < 256; i++) { + x = (int)(0.5f + x1 + (float)i * (x2 - x1) / 255.0f); + y = (int)(0.5f + y1 + (float)i * (y2 - y1) / 255.0f); + + if (x < 0 || y < 0 || x >= ibuf->x || y >= ibuf->y) { + hist->data_luma[i] = hist->data_r[i] = hist->data_g[i] = hist->data_b[i] = hist->data_a[i] = + 0.0f; + } + else { + if (ibuf->rect_float) { + float rgba[4]; + fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x)); + + switch (ibuf->channels) { + case 4: + copy_v4_v4(rgba, fp); + IMB_colormanagement_processor_apply_v4(cm_processor, rgba); + break; + case 3: + copy_v3_v3(rgba, fp); + IMB_colormanagement_processor_apply_v3(cm_processor, rgba); + rgba[3] = 1.0f; + break; + case 2: + copy_v3_fl(rgba, fp[0]); + rgba[3] = fp[1]; + break; + case 1: + copy_v3_fl(rgba, fp[0]); + rgba[3] = 1.0f; + break; + default: + BLI_assert(0); + } + + hist->data_luma[i] = IMB_colormanagement_get_luminance(rgba); + hist->data_r[i] = rgba[0]; + hist->data_g[i] = rgba[1]; + hist->data_b[i] = rgba[2]; + hist->data_a[i] = rgba[3]; + } + else if (ibuf->rect) { + cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x); + hist->data_luma[i] = (float)IMB_colormanagement_get_luminance_byte(cp) / 255.0f; + hist->data_r[i] = (float)cp[0] / 255.0f; + hist->data_g[i] = (float)cp[1] / 255.0f; + hist->data_b[i] = (float)cp[2] / 255.0f; + hist->data_a[i] = (float)cp[3] / 255.0f; + } + } + } + + if (cm_processor) + IMB_colormanagement_processor_free(cm_processor); } /* if view_settings, it also applies this to byte buffers */ typedef struct ScopesUpdateData { - Scopes *scopes; - const ImBuf *ibuf; - struct ColormanageProcessor *cm_processor; - const unsigned char *display_buffer; - const int ycc_mode; + Scopes *scopes; + const ImBuf *ibuf; + struct ColormanageProcessor *cm_processor; + const unsigned char *display_buffer; + const int ycc_mode; - unsigned int *bin_lum, *bin_r, *bin_g, *bin_b, *bin_a; + unsigned int *bin_lum, *bin_r, *bin_g, *bin_b, *bin_a; } ScopesUpdateData; typedef struct ScopesUpdateDataChunk { - unsigned int bin_lum[256]; - unsigned int bin_r[256]; - unsigned int bin_g[256]; - unsigned int bin_b[256]; - unsigned int bin_a[256]; - float min[3], max[3]; + unsigned int bin_lum[256]; + unsigned int bin_r[256]; + unsigned int bin_g[256]; + unsigned int bin_b[256]; + unsigned int bin_a[256]; + float min[3], max[3]; } ScopesUpdateDataChunk; static void scopes_update_cb(void *__restrict userdata, const int y, const ParallelRangeTLS *__restrict tls) { - const ScopesUpdateData *data = userdata; - - Scopes *scopes = data->scopes; - const ImBuf *ibuf = data->ibuf; - struct ColormanageProcessor *cm_processor = data->cm_processor; - const unsigned char *display_buffer = data->display_buffer; - const int ycc_mode = data->ycc_mode; - - ScopesUpdateDataChunk *data_chunk = tls->userdata_chunk; - unsigned int *bin_lum = data_chunk->bin_lum; - unsigned int *bin_r = data_chunk->bin_r; - unsigned int *bin_g = data_chunk->bin_g; - unsigned int *bin_b = data_chunk->bin_b; - unsigned int *bin_a = data_chunk->bin_a; - float *min = data_chunk->min; - float *max = data_chunk->max; - - const float *rf = NULL; - const unsigned char *rc = NULL; - const int rows_per_sample_line = ibuf->y / scopes->sample_lines; - const int savedlines = y / rows_per_sample_line; - const bool do_sample_line = (savedlines < scopes->sample_lines) && (y % rows_per_sample_line) == 0; - const bool is_float = (ibuf->rect_float != NULL); - - if (is_float) - rf = ibuf->rect_float + ((size_t)y) * ibuf->x * ibuf->channels; - else { - rc = display_buffer + ((size_t)y) * ibuf->x * ibuf->channels; - } - - for (int x = 0; x < ibuf->x; x++) { - float rgba[4], ycc[3], luma; - - if (is_float) { - switch (ibuf->channels) { - case 4: - copy_v4_v4(rgba, rf); - IMB_colormanagement_processor_apply_v4(cm_processor, rgba); - break; - case 3: - copy_v3_v3(rgba, rf); - IMB_colormanagement_processor_apply_v3(cm_processor, rgba); - rgba[3] = 1.0f; - break; - case 2: - copy_v3_fl(rgba, rf[0]); - rgba[3] = rf[1]; - break; - case 1: - copy_v3_fl(rgba, rf[0]); - rgba[3] = 1.0f; - break; - default: - BLI_assert(0); - } - } - else { - for (int c = 4; c--;) - rgba[c] = rc[c] * INV_255; - } - - /* we still need luma for histogram */ - luma = IMB_colormanagement_get_luminance(rgba); - - /* check for min max */ - if (ycc_mode == -1) { - minmax_v3v3_v3(min, max, rgba); - } - else { - rgb_to_ycc(rgba[0], rgba[1], rgba[2], &ycc[0], &ycc[1], &ycc[2], ycc_mode); - mul_v3_fl(ycc, INV_255); - minmax_v3v3_v3(min, max, ycc); - } - /* increment count for histo*/ - bin_lum[get_bin_float(luma)]++; - bin_r[get_bin_float(rgba[0])]++; - bin_g[get_bin_float(rgba[1])]++; - bin_b[get_bin_float(rgba[2])]++; - bin_a[get_bin_float(rgba[3])]++; - - /* save sample if needed */ - if (do_sample_line) { - const float fx = (float)x / (float)ibuf->x; - const int idx = 2 * (ibuf->x * savedlines + x); - save_sample_line(scopes, idx, fx, rgba, ycc); - } - - rf += ibuf->channels; - rc += ibuf->channels; - } + const ScopesUpdateData *data = userdata; + + Scopes *scopes = data->scopes; + const ImBuf *ibuf = data->ibuf; + struct ColormanageProcessor *cm_processor = data->cm_processor; + const unsigned char *display_buffer = data->display_buffer; + const int ycc_mode = data->ycc_mode; + + ScopesUpdateDataChunk *data_chunk = tls->userdata_chunk; + unsigned int *bin_lum = data_chunk->bin_lum; + unsigned int *bin_r = data_chunk->bin_r; + unsigned int *bin_g = data_chunk->bin_g; + unsigned int *bin_b = data_chunk->bin_b; + unsigned int *bin_a = data_chunk->bin_a; + float *min = data_chunk->min; + float *max = data_chunk->max; + + const float *rf = NULL; + const unsigned char *rc = NULL; + const int rows_per_sample_line = ibuf->y / scopes->sample_lines; + const int savedlines = y / rows_per_sample_line; + const bool do_sample_line = (savedlines < scopes->sample_lines) && + (y % rows_per_sample_line) == 0; + const bool is_float = (ibuf->rect_float != NULL); + + if (is_float) + rf = ibuf->rect_float + ((size_t)y) * ibuf->x * ibuf->channels; + else { + rc = display_buffer + ((size_t)y) * ibuf->x * ibuf->channels; + } + + for (int x = 0; x < ibuf->x; x++) { + float rgba[4], ycc[3], luma; + + if (is_float) { + switch (ibuf->channels) { + case 4: + copy_v4_v4(rgba, rf); + IMB_colormanagement_processor_apply_v4(cm_processor, rgba); + break; + case 3: + copy_v3_v3(rgba, rf); + IMB_colormanagement_processor_apply_v3(cm_processor, rgba); + rgba[3] = 1.0f; + break; + case 2: + copy_v3_fl(rgba, rf[0]); + rgba[3] = rf[1]; + break; + case 1: + copy_v3_fl(rgba, rf[0]); + rgba[3] = 1.0f; + break; + default: + BLI_assert(0); + } + } + else { + for (int c = 4; c--;) + rgba[c] = rc[c] * INV_255; + } + + /* we still need luma for histogram */ + luma = IMB_colormanagement_get_luminance(rgba); + + /* check for min max */ + if (ycc_mode == -1) { + minmax_v3v3_v3(min, max, rgba); + } + else { + rgb_to_ycc(rgba[0], rgba[1], rgba[2], &ycc[0], &ycc[1], &ycc[2], ycc_mode); + mul_v3_fl(ycc, INV_255); + minmax_v3v3_v3(min, max, ycc); + } + /* increment count for histo*/ + bin_lum[get_bin_float(luma)]++; + bin_r[get_bin_float(rgba[0])]++; + bin_g[get_bin_float(rgba[1])]++; + bin_b[get_bin_float(rgba[2])]++; + bin_a[get_bin_float(rgba[3])]++; + + /* save sample if needed */ + if (do_sample_line) { + const float fx = (float)x / (float)ibuf->x; + const int idx = 2 * (ibuf->x * savedlines + x); + save_sample_line(scopes, idx, fx, rgba, ycc); + } + + rf += ibuf->channels; + rc += ibuf->channels; + } } -static void scopes_update_finalize(void *__restrict userdata, - void *__restrict userdata_chunk) +static void scopes_update_finalize(void *__restrict userdata, void *__restrict userdata_chunk) { - const ScopesUpdateData *data = userdata; - const ScopesUpdateDataChunk *data_chunk = userdata_chunk; - - unsigned int *bin_lum = data->bin_lum; - unsigned int *bin_r = data->bin_r; - unsigned int *bin_g = data->bin_g; - unsigned int *bin_b = data->bin_b; - unsigned int *bin_a = data->bin_a; - const unsigned int *bin_lum_c = data_chunk->bin_lum; - const unsigned int *bin_r_c = data_chunk->bin_r; - const unsigned int *bin_g_c = data_chunk->bin_g; - const unsigned int *bin_b_c = data_chunk->bin_b; - const unsigned int *bin_a_c = data_chunk->bin_a; - - float (*minmax)[2] = data->scopes->minmax; - const float *min = data_chunk->min; - const float *max = data_chunk->max; - - for (int b = 256; b--;) { - bin_lum[b] += bin_lum_c[b]; - bin_r[b] += bin_r_c[b]; - bin_g[b] += bin_g_c[b]; - bin_b[b] += bin_b_c[b]; - bin_a[b] += bin_a_c[b]; - } - - for (int c = 3; c--;) { - if (min[c] < minmax[c][0]) - minmax[c][0] = min[c]; - if (max[c] > minmax[c][1]) - minmax[c][1] = max[c]; - } + const ScopesUpdateData *data = userdata; + const ScopesUpdateDataChunk *data_chunk = userdata_chunk; + + unsigned int *bin_lum = data->bin_lum; + unsigned int *bin_r = data->bin_r; + unsigned int *bin_g = data->bin_g; + unsigned int *bin_b = data->bin_b; + unsigned int *bin_a = data->bin_a; + const unsigned int *bin_lum_c = data_chunk->bin_lum; + const unsigned int *bin_r_c = data_chunk->bin_r; + const unsigned int *bin_g_c = data_chunk->bin_g; + const unsigned int *bin_b_c = data_chunk->bin_b; + const unsigned int *bin_a_c = data_chunk->bin_a; + + float(*minmax)[2] = data->scopes->minmax; + const float *min = data_chunk->min; + const float *max = data_chunk->max; + + for (int b = 256; b--;) { + bin_lum[b] += bin_lum_c[b]; + bin_r[b] += bin_r_c[b]; + bin_g[b] += bin_g_c[b]; + bin_b[b] += bin_b_c[b]; + bin_a[b] += bin_a_c[b]; + } + + for (int c = 3; c--;) { + if (min[c] < minmax[c][0]) + minmax[c][0] = min[c]; + if (max[c] > minmax[c][1]) + minmax[c][1] = max[c]; + } } -void scopes_update(Scopes *scopes, ImBuf *ibuf, const ColorManagedViewSettings *view_settings, +void scopes_update(Scopes *scopes, + ImBuf *ibuf, + const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings) { - int a; - unsigned int nl, na, nr, ng, nb; - double divl, diva, divr, divg, divb; - const unsigned char *display_buffer = NULL; - unsigned int bin_lum[256] = {0}, - bin_r[256] = {0}, - bin_g[256] = {0}, - bin_b[256] = {0}, - bin_a[256] = {0}; - int ycc_mode = -1; - void *cache_handle = NULL; - struct ColormanageProcessor *cm_processor = NULL; - - if (ibuf->rect == NULL && ibuf->rect_float == NULL) return; - - if (scopes->ok == 1) return; - - if (scopes->hist.ymax == 0.f) scopes->hist.ymax = 1.f; - - /* hmmmm */ - if (!(ELEM(ibuf->channels, 3, 4))) return; - - scopes->hist.channels = 3; - scopes->hist.x_resolution = 256; - - switch (scopes->wavefrm_mode) { - case SCOPES_WAVEFRM_RGB: - /* fall-through */ - case SCOPES_WAVEFRM_RGB_PARADE: - ycc_mode = -1; - break; - case SCOPES_WAVEFRM_LUMA: - case SCOPES_WAVEFRM_YCC_JPEG: - ycc_mode = BLI_YCC_JFIF_0_255; - break; - case SCOPES_WAVEFRM_YCC_601: - ycc_mode = BLI_YCC_ITU_BT601; - break; - case SCOPES_WAVEFRM_YCC_709: - ycc_mode = BLI_YCC_ITU_BT709; - break; - } - - /* convert to number of lines with logarithmic scale */ - scopes->sample_lines = (scopes->accuracy * 0.01f) * (scopes->accuracy * 0.01f) * ibuf->y; - CLAMP_MIN(scopes->sample_lines, 1); - - if (scopes->sample_full) - scopes->sample_lines = ibuf->y; - - /* scan the image */ - for (a = 0; a < 3; a++) { - scopes->minmax[a][0] = 25500.0f; - scopes->minmax[a][1] = -25500.0f; - } - - scopes->waveform_tot = ibuf->x * scopes->sample_lines; - - if (scopes->waveform_1) - MEM_freeN(scopes->waveform_1); - if (scopes->waveform_2) - MEM_freeN(scopes->waveform_2); - if (scopes->waveform_3) - MEM_freeN(scopes->waveform_3); - if (scopes->vecscope) - MEM_freeN(scopes->vecscope); - - scopes->waveform_1 = MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 1"); - scopes->waveform_2 = MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 2"); - scopes->waveform_3 = MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 3"); - scopes->vecscope = MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "vectorscope point channel"); - - if (ibuf->rect_float) { - cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings); - } - else { - display_buffer = (const unsigned char *)IMB_display_buffer_acquire( - ibuf, view_settings, display_settings, &cache_handle); - } - - /* Keep number of threads in sync with the merge parts below. */ - ScopesUpdateData data = { - .scopes = scopes, .ibuf = ibuf, - .cm_processor = cm_processor, .display_buffer = display_buffer, .ycc_mode = ycc_mode, - .bin_lum = bin_lum, .bin_r = bin_r, .bin_g = bin_g, .bin_b = bin_b, .bin_a = bin_a, - }; - ScopesUpdateDataChunk data_chunk = {{0}}; - INIT_MINMAX(data_chunk.min, data_chunk.max); - - ParallelRangeSettings settings; - BLI_parallel_range_settings_defaults(&settings); - settings.use_threading = (ibuf->y > 256); - settings.userdata_chunk = &data_chunk; - settings.userdata_chunk_size = sizeof(data_chunk); - settings.func_finalize = scopes_update_finalize; - BLI_task_parallel_range(0, ibuf->y, - &data, - scopes_update_cb, - &settings); - - /* convert hist data to float (proportional to max count) */ - nl = na = nr = nb = ng = 0; - for (a = 0; a < 256; a++) { - if (bin_lum[a] > nl) nl = bin_lum[a]; - if (bin_r[a] > nr) nr = bin_r[a]; - if (bin_g[a] > ng) ng = bin_g[a]; - if (bin_b[a] > nb) nb = bin_b[a]; - if (bin_a[a] > na) na = bin_a[a]; - } - divl = nl ? 1.0 / (double)nl : 1.0; - diva = na ? 1.0 / (double)na : 1.0; - divr = nr ? 1.0 / (double)nr : 1.0; - divg = ng ? 1.0 / (double)ng : 1.0; - divb = nb ? 1.0 / (double)nb : 1.0; - - for (a = 0; a < 256; a++) { - scopes->hist.data_luma[a] = bin_lum[a] * divl; - scopes->hist.data_r[a] = bin_r[a] * divr; - scopes->hist.data_g[a] = bin_g[a] * divg; - scopes->hist.data_b[a] = bin_b[a] * divb; - scopes->hist.data_a[a] = bin_a[a] * diva; - } - - if (cm_processor) - IMB_colormanagement_processor_free(cm_processor); - if (cache_handle) - IMB_display_buffer_release(cache_handle); - - scopes->ok = 1; + int a; + unsigned int nl, na, nr, ng, nb; + double divl, diva, divr, divg, divb; + const unsigned char *display_buffer = NULL; + unsigned int bin_lum[256] = {0}, bin_r[256] = {0}, bin_g[256] = {0}, bin_b[256] = {0}, + bin_a[256] = {0}; + int ycc_mode = -1; + void *cache_handle = NULL; + struct ColormanageProcessor *cm_processor = NULL; + + if (ibuf->rect == NULL && ibuf->rect_float == NULL) + return; + + if (scopes->ok == 1) + return; + + if (scopes->hist.ymax == 0.f) + scopes->hist.ymax = 1.f; + + /* hmmmm */ + if (!(ELEM(ibuf->channels, 3, 4))) + return; + + scopes->hist.channels = 3; + scopes->hist.x_resolution = 256; + + switch (scopes->wavefrm_mode) { + case SCOPES_WAVEFRM_RGB: + /* fall-through */ + case SCOPES_WAVEFRM_RGB_PARADE: + ycc_mode = -1; + break; + case SCOPES_WAVEFRM_LUMA: + case SCOPES_WAVEFRM_YCC_JPEG: + ycc_mode = BLI_YCC_JFIF_0_255; + break; + case SCOPES_WAVEFRM_YCC_601: + ycc_mode = BLI_YCC_ITU_BT601; + break; + case SCOPES_WAVEFRM_YCC_709: + ycc_mode = BLI_YCC_ITU_BT709; + break; + } + + /* convert to number of lines with logarithmic scale */ + scopes->sample_lines = (scopes->accuracy * 0.01f) * (scopes->accuracy * 0.01f) * ibuf->y; + CLAMP_MIN(scopes->sample_lines, 1); + + if (scopes->sample_full) + scopes->sample_lines = ibuf->y; + + /* scan the image */ + for (a = 0; a < 3; a++) { + scopes->minmax[a][0] = 25500.0f; + scopes->minmax[a][1] = -25500.0f; + } + + scopes->waveform_tot = ibuf->x * scopes->sample_lines; + + if (scopes->waveform_1) + MEM_freeN(scopes->waveform_1); + if (scopes->waveform_2) + MEM_freeN(scopes->waveform_2); + if (scopes->waveform_3) + MEM_freeN(scopes->waveform_3); + if (scopes->vecscope) + MEM_freeN(scopes->vecscope); + + scopes->waveform_1 = MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), + "waveform point channel 1"); + scopes->waveform_2 = MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), + "waveform point channel 2"); + scopes->waveform_3 = MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), + "waveform point channel 3"); + scopes->vecscope = MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), + "vectorscope point channel"); + + if (ibuf->rect_float) { + cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings); + } + else { + display_buffer = (const unsigned char *)IMB_display_buffer_acquire( + ibuf, view_settings, display_settings, &cache_handle); + } + + /* Keep number of threads in sync with the merge parts below. */ + ScopesUpdateData data = { + .scopes = scopes, + .ibuf = ibuf, + .cm_processor = cm_processor, + .display_buffer = display_buffer, + .ycc_mode = ycc_mode, + .bin_lum = bin_lum, + .bin_r = bin_r, + .bin_g = bin_g, + .bin_b = bin_b, + .bin_a = bin_a, + }; + ScopesUpdateDataChunk data_chunk = {{0}}; + INIT_MINMAX(data_chunk.min, data_chunk.max); + + ParallelRangeSettings settings; + BLI_parallel_range_settings_defaults(&settings); + settings.use_threading = (ibuf->y > 256); + settings.userdata_chunk = &data_chunk; + settings.userdata_chunk_size = sizeof(data_chunk); + settings.func_finalize = scopes_update_finalize; + BLI_task_parallel_range(0, ibuf->y, &data, scopes_update_cb, &settings); + + /* convert hist data to float (proportional to max count) */ + nl = na = nr = nb = ng = 0; + for (a = 0; a < 256; a++) { + if (bin_lum[a] > nl) + nl = bin_lum[a]; + if (bin_r[a] > nr) + nr = bin_r[a]; + if (bin_g[a] > ng) + ng = bin_g[a]; + if (bin_b[a] > nb) + nb = bin_b[a]; + if (bin_a[a] > na) + na = bin_a[a]; + } + divl = nl ? 1.0 / (double)nl : 1.0; + diva = na ? 1.0 / (double)na : 1.0; + divr = nr ? 1.0 / (double)nr : 1.0; + divg = ng ? 1.0 / (double)ng : 1.0; + divb = nb ? 1.0 / (double)nb : 1.0; + + for (a = 0; a < 256; a++) { + scopes->hist.data_luma[a] = bin_lum[a] * divl; + scopes->hist.data_r[a] = bin_r[a] * divr; + scopes->hist.data_g[a] = bin_g[a] * divg; + scopes->hist.data_b[a] = bin_b[a] * divb; + scopes->hist.data_a[a] = bin_a[a] * diva; + } + + if (cm_processor) + IMB_colormanagement_processor_free(cm_processor); + if (cache_handle) + IMB_display_buffer_release(cache_handle); + + scopes->ok = 1; } void scopes_free(Scopes *scopes) { - if (scopes->waveform_1) { - MEM_freeN(scopes->waveform_1); - scopes->waveform_1 = NULL; - } - if (scopes->waveform_2) { - MEM_freeN(scopes->waveform_2); - scopes->waveform_2 = NULL; - } - if (scopes->waveform_3) { - MEM_freeN(scopes->waveform_3); - scopes->waveform_3 = NULL; - } - if (scopes->vecscope) { - MEM_freeN(scopes->vecscope); - scopes->vecscope = NULL; - } + if (scopes->waveform_1) { + MEM_freeN(scopes->waveform_1); + scopes->waveform_1 = NULL; + } + if (scopes->waveform_2) { + MEM_freeN(scopes->waveform_2); + scopes->waveform_2 = NULL; + } + if (scopes->waveform_3) { + MEM_freeN(scopes->waveform_3); + scopes->waveform_3 = NULL; + } + if (scopes->vecscope) { + MEM_freeN(scopes->vecscope); + scopes->vecscope = NULL; + } } void scopes_new(Scopes *scopes) { - scopes->accuracy = 30.0; - scopes->hist.mode = HISTO_MODE_RGB; - scopes->wavefrm_alpha = 0.3; - scopes->vecscope_alpha = 0.3; - scopes->wavefrm_height = 100; - scopes->vecscope_height = 100; - scopes->hist.height = 100; - scopes->ok = 0; - scopes->waveform_1 = NULL; - scopes->waveform_2 = NULL; - scopes->waveform_3 = NULL; - scopes->vecscope = NULL; + scopes->accuracy = 30.0; + scopes->hist.mode = HISTO_MODE_RGB; + scopes->wavefrm_alpha = 0.3; + scopes->vecscope_alpha = 0.3; + scopes->wavefrm_height = 100; + scopes->vecscope_height = 100; + scopes->hist.height = 100; + scopes->ok = 0; + scopes->waveform_1 = NULL; + scopes->waveform_2 = NULL; + scopes->waveform_3 = NULL; + scopes->vecscope = NULL; } void BKE_color_managed_display_settings_init(ColorManagedDisplaySettings *settings) { - const char *display_name = IMB_colormanagement_display_get_default_name(); + const char *display_name = IMB_colormanagement_display_get_default_name(); - BLI_strncpy(settings->display_device, display_name, sizeof(settings->display_device)); + BLI_strncpy(settings->display_device, display_name, sizeof(settings->display_device)); } void BKE_color_managed_display_settings_copy(ColorManagedDisplaySettings *new_settings, const ColorManagedDisplaySettings *settings) { - BLI_strncpy(new_settings->display_device, settings->display_device, sizeof(new_settings->display_device)); + BLI_strncpy(new_settings->display_device, + settings->display_device, + sizeof(new_settings->display_device)); } void BKE_color_managed_view_settings_init_render( - ColorManagedViewSettings *view_settings, - const ColorManagedDisplaySettings *display_settings, - const char *view_transform) + ColorManagedViewSettings *view_settings, + const ColorManagedDisplaySettings *display_settings, + const char *view_transform) { - struct ColorManagedDisplay *display = - IMB_colormanagement_display_get_named( - display_settings->display_device); + struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named( + display_settings->display_device); - if (!view_transform) { - view_transform = IMB_colormanagement_display_get_default_view_transform_name(display); - } + if (!view_transform) { + view_transform = IMB_colormanagement_display_get_default_view_transform_name(display); + } - /* TODO(sergey): Find a way to make look query more reliable with non - * default configuration. */ - STRNCPY(view_settings->view_transform, view_transform); - STRNCPY(view_settings->look, "None"); + /* TODO(sergey): Find a way to make look query more reliable with non + * default configuration. */ + STRNCPY(view_settings->view_transform, view_transform); + STRNCPY(view_settings->look, "None"); - view_settings->flag = 0; - view_settings->gamma = 1.0f; - view_settings->exposure = 0.0f; - view_settings->curve_mapping = NULL; + view_settings->flag = 0; + view_settings->gamma = 1.0f; + view_settings->exposure = 0.0f; + view_settings->curve_mapping = NULL; - IMB_colormanagement_validate_settings(display_settings, view_settings); + IMB_colormanagement_validate_settings(display_settings, view_settings); } void BKE_color_managed_view_settings_init_default( - struct ColorManagedViewSettings *view_settings, - const struct ColorManagedDisplaySettings *display_settings) + struct ColorManagedViewSettings *view_settings, + const struct ColorManagedDisplaySettings *display_settings) { - IMB_colormanagement_init_default_view_settings( - view_settings, display_settings); + IMB_colormanagement_init_default_view_settings(view_settings, display_settings); } void BKE_color_managed_view_settings_copy(ColorManagedViewSettings *new_settings, const ColorManagedViewSettings *settings) { - BLI_strncpy(new_settings->look, settings->look, sizeof(new_settings->look)); - BLI_strncpy(new_settings->view_transform, settings->view_transform, sizeof(new_settings->view_transform)); - - new_settings->flag = settings->flag; - new_settings->exposure = settings->exposure; - new_settings->gamma = settings->gamma; - - if (settings->curve_mapping) - new_settings->curve_mapping = curvemapping_copy(settings->curve_mapping); - else - new_settings->curve_mapping = NULL; + BLI_strncpy(new_settings->look, settings->look, sizeof(new_settings->look)); + BLI_strncpy(new_settings->view_transform, + settings->view_transform, + sizeof(new_settings->view_transform)); + + new_settings->flag = settings->flag; + new_settings->exposure = settings->exposure; + new_settings->gamma = settings->gamma; + + if (settings->curve_mapping) + new_settings->curve_mapping = curvemapping_copy(settings->curve_mapping); + else + new_settings->curve_mapping = NULL; } void BKE_color_managed_view_settings_free(ColorManagedViewSettings *settings) { - if (settings->curve_mapping) - curvemapping_free(settings->curve_mapping); + if (settings->curve_mapping) + curvemapping_free(settings->curve_mapping); } -void BKE_color_managed_colorspace_settings_init(ColorManagedColorspaceSettings *colorspace_settings) +void BKE_color_managed_colorspace_settings_init( + ColorManagedColorspaceSettings *colorspace_settings) { - BLI_strncpy(colorspace_settings->name, "", sizeof(colorspace_settings->name)); + BLI_strncpy(colorspace_settings->name, "", sizeof(colorspace_settings->name)); } -void BKE_color_managed_colorspace_settings_copy(ColorManagedColorspaceSettings *colorspace_settings, - const ColorManagedColorspaceSettings *settings) +void BKE_color_managed_colorspace_settings_copy( + ColorManagedColorspaceSettings *colorspace_settings, + const ColorManagedColorspaceSettings *settings) { - BLI_strncpy(colorspace_settings->name, settings->name, sizeof(colorspace_settings->name)); + BLI_strncpy(colorspace_settings->name, settings->name, sizeof(colorspace_settings->name)); } bool BKE_color_managed_colorspace_settings_equals(const ColorManagedColorspaceSettings *settings1, const ColorManagedColorspaceSettings *settings2) { - return STREQ(settings1->name, settings2->name); + return STREQ(settings1->name, settings2->name); } -- cgit v1.2.3