Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_colortools.h5
-rw-r--r--source/blender/blenkernel/intern/colortools.c120
-rw-r--r--source/blender/blenkernel/intern/node_shaders.c15
-rw-r--r--source/blender/imbuf/IMB_imbuf.h1
-rw-r--r--source/blender/imbuf/intern/divers.c24
-rw-r--r--source/blender/makesdna/DNA_color_types.h7
-rw-r--r--source/blender/src/editsima.c28
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);
}
}