diff options
-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 | ||||
-rw-r--r-- | source/blender/imbuf/IMB_imbuf.h | 1 | ||||
-rw-r--r-- | source/blender/imbuf/intern/divers.c | 24 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_color_types.h | 7 | ||||
-rw-r--r-- | source/blender/src/editsima.c | 28 |
7 files changed, 153 insertions, 47 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 }; diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index 20a31f5de28..623e9e901f9 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -332,6 +332,7 @@ void IMB_de_interlace(struct ImBuf *ibuf); void IMB_interlace(struct ImBuf *ibuf); void IMB_gamwarp(struct ImBuf *ibuf, double gamma); void IMB_rect_from_float(struct ImBuf *ibuf); +void IMB_float_from_rect(struct ImBuf *ibuf); /** * Change the ordering of the colour bytes pointed to by rect from diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c index f73431cb28e..71292e27611 100644 --- a/source/blender/imbuf/intern/divers.c +++ b/source/blender/imbuf/intern/divers.c @@ -192,3 +192,27 @@ void IMB_rect_from_float(struct ImBuf *ibuf) } } +void IMB_float_from_rect(struct ImBuf *ibuf) +{ + /* quick method to convert byte to floatbuf */ + float *tof = ibuf->rect_float; + int i; + unsigned char *to = (unsigned char *) ibuf->rect; + + if(to==NULL) return; + if(tof==NULL) { + imb_addrectfloatImBuf(ibuf); + tof = ibuf->rect_float; + } + + for (i = ibuf->x * ibuf->y; i > 0; i--) + { + tof[0] = ((float)to[0])*(1.0f/255.0f); + tof[1] = ((float)to[1])*(1.0f/255.0f); + tof[2] = ((float)to[2])*(1.0f/255.0f); + tof[3] = ((float)to[3])*(1.0f/255.0f); + to += 4; + tof += 4; + } +} + diff --git a/source/blender/makesdna/DNA_color_types.h b/source/blender/makesdna/DNA_color_types.h index 1829398e4e8..5f48daa0931 100644 --- a/source/blender/makesdna/DNA_color_types.h +++ b/source/blender/makesdna/DNA_color_types.h @@ -49,7 +49,7 @@ typedef struct CurveMapPoint { #define CUMA_VECTOR 2 typedef struct CurveMap { - short totpoint, pad; + short totpoint, flag; float range; /* quick multiply value for reading table */ float mintable, maxtable; /* the x-axis range for the table */ @@ -68,9 +68,8 @@ typedef struct CurveMapping { float bwmul[3], padf; /* black/white point multiply value, for speed */ } CurveMapping; -/* cuma->flag */ -#define CUMA_DO_CLIP 1 - +/* cumap->flag */ +#define CUMA_DO_CLIP 1 #endif diff --git a/source/blender/src/editsima.c b/source/blender/src/editsima.c index 72e1baa17f3..897c4516069 100644 --- a/source/blender/src/editsima.c +++ b/source/blender/src/editsima.c @@ -1464,19 +1464,25 @@ void sima_sample_color(void) zp= ibuf->zbuf + y*ibuf->x + x; if(ibuf->zbuf_float) zpf= ibuf->zbuf_float + y*ibuf->x + x; - - if(ibuf->rect_float) { + if(ibuf->rect_float) fp= (ibuf->rect_float + 4*(y*ibuf->x + x)); - if(G.sima->cumap) { - if(G.qual & LR_CTRLKEY) { - curvemapping_set_black_white(G.sima->cumap, NULL, fp); - curvemapping_do_image(G.sima->cumap, G.sima->image); - } - else if(G.qual & LR_SHIFTKEY) { - curvemapping_set_black_white(G.sima->cumap, fp, NULL); - curvemapping_do_image(G.sima->cumap, G.sima->image); - } + if(G.sima->cumap) { + float vec[3]; + if(fp==NULL) { + fp= vec; + vec[0]= (float)cp[0]/255.0f; + vec[1]= (float)cp[1]/255.0f; + vec[2]= (float)cp[2]/255.0f; + } + + if(G.qual & LR_CTRLKEY) { + curvemapping_set_black_white(G.sima->cumap, NULL, fp); + curvemapping_do_image(G.sima->cumap, G.sima->image); + } + else if(G.qual & LR_SHIFTKEY) { + curvemapping_set_black_white(G.sima->cumap, fp, NULL); + curvemapping_do_image(G.sima->cumap, G.sima->image); } } |