Orange:
authorTon Roosendaal <ton@blender.org>
Thu, 12 Jan 2006 15:46:29 +0000 (15:46 +0000)
committerTon Roosendaal <ton@blender.org>
Thu, 12 Jan 2006 15:46:29 +0000 (15:46 +0000)
- 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.

source/blender/blenkernel/BKE_colortools.h
source/blender/blenkernel/intern/colortools.c
source/blender/blenkernel/intern/node_shaders.c
source/blender/imbuf/IMB_imbuf.h
source/blender/imbuf/intern/divers.c
source/blender/makesdna/DNA_color_types.h
source/blender/src/editsima.c

index 22faa244fcef9846dde4cbb1a0c3a1fa13d7d961..3dc42dcc8238479866e29a15d222701e8dcf04c8 100644 (file)
@@ -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
index a7bad7d2f4b1351605321595c83ba24ae47023d4..30c74fd65cb36eaa611cccb679555c96a12ea014 100644 (file)
@@ -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);
 }
index b1dfdf0f5b48b5f66da4e6a54df696bdfd3d5447..944db32ccc10ffd620232545abd9487051505ef2 100644 (file)
@@ -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
        
 };
 
index 20a31f5de28b05f47c46bd26e97825b21bd83f79..623e9e901f95c81aaefa72a690701480494c32b1 100644 (file)
@@ -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
index f73431cb28eae3a3dff9f484ea28fefc3134e54f..71292e276116eda72de27daa9062270dde9bfee5 100644 (file)
@@ -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;
+       }
+}
+
index 1829398e4e8cfc3b533812ab8771d62f9530e3c9..5f48daa09317503fa70923d6ae5ec20b62942fa7 100644 (file)
@@ -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
 
index 72e1baa17f3330f87874d348b33621550c657541..897c45160699cc9fa08226cc50d0036484092102 100644 (file)
@@ -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);
                                        }
                                }