diff options
author | Ton Roosendaal <ton@blender.org> | 2006-01-12 18:46:29 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2006-01-12 18:46:29 +0300 |
commit | 715794859a99c47a08314acbfe537c4460cb788b (patch) | |
tree | 39730d4c6b2d4a0017c477e3a80570ae1c2ba393 /source/blender/blenkernel | |
parent | 402518c66c251a0b4e83bca474319cacd2ae662a (diff) |
Orange:
- cleanup of color curves code; goes at least twice faster now!
(includes black/white point stuff)
- When using 'Curves' in image window on a byte rect, it creates a (temp)
float rect to operate on. So curves work for regular pictures too now.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_colortools.h | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/colortools.c | 120 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node_shaders.c | 15 |
3 files changed, 108 insertions, 32 deletions
diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h index 22faa244fce..3dc42dcc823 100644 --- a/source/blender/blenkernel/BKE_colortools.h +++ b/source/blender/blenkernel/BKE_colortools.h @@ -45,8 +45,13 @@ void curvemap_reset(struct CurveMap *cuma, struct rctf *clipr); void curvemap_sethandle(struct CurveMap *cuma, int type); void curvemapping_changed(struct CurveMapping *cumap, int rem_doubles); + + /* single curve, no table check */ +float curvemap_evaluateF(struct CurveMap *cuma, float value); + /* single curve, with table check */ float curvemapping_evaluateF(struct CurveMapping *cumap, int cur, float value); void curvemapping_evaluate3F(struct CurveMapping *cumap, float *vecout, const float *vecin); +void curvemapping_evaluateRGBF(struct CurveMapping *cumap, float *vecout, const float *vecin); void curvemapping_do_image(struct CurveMapping *cumap, struct Image *ima); #endif diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index a7bad7d2f4b..30c74fd65cb 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -49,6 +49,7 @@ #include "BLI_blenlib.h" #include "BLI_arithb.h" +#include "IMB_imbuf.h" #include "IMB_imbuf_types.h" /* ********************************* color curve ********************* */ @@ -181,6 +182,11 @@ void curvemap_reset(CurveMap *cuma, rctf *clipr) cuma->curve[1].x= clipr->xmax; cuma->curve[1].y= clipr->ymax; cuma->curve[1].flag= 0; + + if(cuma->table) { + MEM_freeN(cuma->table); + cuma->table= NULL; + } } /* if type==1: vector, else auto */ @@ -271,7 +277,7 @@ static void calchandle_curvemap(BezTriple *bezt, BezTriple *prev, BezTriple *nex } } - +/* only creates a table for a single channel in CurveMapping */ static void curvemap_make_table(CurveMap *cuma, rctf *clipr) { CurveMapPoint *cmp= cuma->curve; @@ -395,6 +401,39 @@ static void curvemap_make_table(CurveMap *cuma, rctf *clipr) cuma->table= cmp; } +/* call when you do images etc, needs restore too. also verifies tables */ +static void curvemapping_premultiply(CurveMapping *cumap, int restore) +{ + static CurveMapPoint *table[3]= {NULL, NULL, NULL}; + int a; + + if(restore) { + for(a=0; a<3; a++) { + MEM_freeN(cumap->cm[a].table); + cumap->cm[a].table= table[a]; + } + } + else { + /* verify and copy */ + for(a=0; a<3; a++) { + if(cumap->cm[a].table==NULL) + curvemap_make_table(cumap->cm+a, &cumap->clipr); + table[a]= cumap->cm[a].table; + cumap->cm[a].table= MEM_dupallocN(cumap->cm[a].table); + } + + 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); + } + } + } +} static int sort_curvepoints(const void *a1, const void *a2) { @@ -458,20 +497,12 @@ void curvemapping_changed(CurveMapping *cumap, int rem_doubles) curvemap_make_table(cuma, clipr); } -/* works with curve 'cur' */ -float curvemapping_evaluateF(CurveMapping *cumap, int cur, float value) +/* table should be verified */ +float curvemap_evaluateF(CurveMap *cuma, float value) { - CurveMap *cuma= cumap->cm+cur; float fi; int i; - - /* allocate or bail out */ - if(cuma->table==NULL) { - curvemap_make_table(cuma, &cumap->clipr); - if(cuma->table==NULL) - return value; - } - + /* index in table */ fi= (value-cuma->mintable)*cuma->range; i= (int)fi; @@ -482,23 +513,50 @@ float curvemapping_evaluateF(CurveMapping *cumap, int cur, float value) return (1.0f-fi)*cuma->table[i].y + (fi)*cuma->table[i+1].y; } -void curvemapping_evaluate3F(CurveMapping *cumap, float *vecout, const float *vecin) +/* works with curve 'cur' */ +float curvemapping_evaluateF(CurveMapping *cumap, int cur, float value) { - if(cumap->cm[3].curve) { - float fac; - - fac= (vecin[0] - cumap->black[0])*cumap->bwmul[0]; - vecout[0]= curvemapping_evaluateF(cumap, 0, curvemapping_evaluateF(cumap, 3, fac)); - fac= (vecin[1] - cumap->black[1])*cumap->bwmul[1]; - vecout[1]= curvemapping_evaluateF(cumap, 1, curvemapping_evaluateF(cumap, 3, fac)); - fac= (vecin[2] - cumap->black[2])*cumap->bwmul[2]; - vecout[2]= curvemapping_evaluateF(cumap, 2, curvemapping_evaluateF(cumap, 3, fac)); - } - else { - vecout[0]= curvemapping_evaluateF(cumap, 0, vecin[0]); - vecout[1]= curvemapping_evaluateF(cumap, 1, vecin[1]); - vecout[2]= curvemapping_evaluateF(cumap, 2, vecin[2]); + CurveMap *cuma= cumap->cm+cur; + + /* allocate or bail out */ + if(cuma->table==NULL) { + curvemap_make_table(cuma, &cumap->clipr); + if(cuma->table==NULL) + return value; } + return curvemap_evaluateF(cuma, value); +} + +/* vector case */ +void curvemapping_evaluate3F(CurveMapping *cumap, float *vecout, const float *vecin) +{ + vecout[0]= curvemapping_evaluateF(cumap, 0, vecin[0]); + vecout[1]= curvemapping_evaluateF(cumap, 1, vecin[1]); + vecout[2]= curvemapping_evaluateF(cumap, 2, vecin[2]); +} + +/* RGB case, no black/white points, no premult */ +void curvemapping_evaluateRGBF(CurveMapping *cumap, float *vecout, const float *vecin) +{ + vecout[0]= curvemapping_evaluateF(cumap, 0, curvemapping_evaluateF(cumap, 3, vecin[0])); + vecout[1]= curvemapping_evaluateF(cumap, 1, curvemapping_evaluateF(cumap, 3, vecin[1])); + vecout[2]= curvemapping_evaluateF(cumap, 2, curvemapping_evaluateF(cumap, 3, vecin[2])); +} + + +/* RGB with black/white points and premult. tables are checked */ +static void curvemapping_evaluate_premulRGBF(CurveMapping *cumap, float *vecout, const float *vecin) +{ + float fac; + + fac= (vecin[0] - cumap->black[0])*cumap->bwmul[0]; + vecout[0]= curvemap_evaluateF(cumap->cm, fac); + + fac= (vecin[1] - cumap->black[1])*cumap->bwmul[1]; + vecout[1]= curvemap_evaluateF(cumap->cm+1, fac); + + fac= (vecin[2] - cumap->black[2])*cumap->bwmul[2]; + vecout[2]= curvemap_evaluateF(cumap->cm+2, fac); } #define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val)) @@ -509,6 +567,10 @@ void curvemapping_do_image(CurveMapping *cumap, Image *ima) if(ima==NULL || ima->ibuf==NULL) return; + if(ima->ibuf->rect_float==NULL) + IMB_float_from_rect(ima->ibuf); + + curvemapping_premultiply(cumap, 0); if(ima->ibuf->rect_float && ima->ibuf->rect) { float *pixf= ima->ibuf->rect_float; @@ -516,11 +578,13 @@ void curvemapping_do_image(CurveMapping *cumap, Image *ima) char *pixc= (char *)ima->ibuf->rect; for(pixel= ima->ibuf->x*ima->ibuf->y; pixel>0; pixel--, pixf+=4, pixc+=4) { - curvemapping_evaluate3F(cumap, col, pixf); + curvemapping_evaluate_premulRGBF(cumap, col, pixf); pixc[0]= FTOCHAR(col[0]); pixc[1]= FTOCHAR(col[1]); pixc[2]= FTOCHAR(col[2]); /* assume alpha was set */ } } + + curvemapping_premultiply(cumap, 1); } diff --git a/source/blender/blenkernel/intern/node_shaders.c b/source/blender/blenkernel/intern/node_shaders.c index b1dfdf0f5b4..944db32ccc1 100644 --- a/source/blender/blenkernel/intern/node_shaders.c +++ b/source/blender/blenkernel/intern/node_shaders.c @@ -490,8 +490,7 @@ static bNodeSocketType sh_node_curve_vec_out[]= { { -1, 0, "" } }; -/* generates normal, does dot product */ -static void node_shader_exec_curve(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +static void node_shader_exec_curve_vec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { /* stack order input: vec */ /* stack order output: vec */ @@ -507,7 +506,7 @@ static bNodeType sh_node_curve_vec= { /* input sock */ sh_node_curve_vec_in, /* output sock */ sh_node_curve_vec_out, /* storage */ "CurveMapping", - /* execfunc */ node_shader_exec_curve + /* execfunc */ node_shader_exec_curve_vec }; @@ -522,6 +521,14 @@ static bNodeSocketType sh_node_curve_rgb_out[]= { { -1, 0, "" } }; +static void node_shader_exec_curve_rgb(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + /* stack order input: vec */ + /* stack order output: vec */ + + curvemapping_evaluateRGBF(node->storage, out[0]->vec, in[0]->vec); +} + static bNodeType sh_node_curve_rgb= { /* type code */ SH_NODE_CURVE_RGB, /* name */ "RGB Curves", @@ -530,7 +537,7 @@ static bNodeType sh_node_curve_rgb= { /* input sock */ sh_node_curve_rgb_in, /* output sock */ sh_node_curve_rgb_out, /* storage */ "CurveMapping", - /* execfunc */ node_shader_exec_curve + /* execfunc */ node_shader_exec_curve_rgb }; |