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:
authorTon Roosendaal <ton@blender.org>2006-01-12 18:46:29 +0300
committerTon Roosendaal <ton@blender.org>2006-01-12 18:46:29 +0300
commit715794859a99c47a08314acbfe537c4460cb788b (patch)
tree39730d4c6b2d4a0017c477e3a80570ae1c2ba393 /source/blender/blenkernel
parent402518c66c251a0b4e83bca474319cacd2ae662a (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.h5
-rw-r--r--source/blender/blenkernel/intern/colortools.c120
-rw-r--r--source/blender/blenkernel/intern/node_shaders.c15
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
};