bluebanana fixes and enhancements
authorGood Guy <[email protected]>
Sun, 2 Apr 2017 19:36:11 +0000 (13:36 -0600)
committerGood Guy <[email protected]>
Sun, 2 Apr 2017 19:36:11 +0000 (13:36 -0600)
cinelerra-5.1/plugins/bluebanana/bluebanana.C
cinelerra-5.1/plugins/bluebanana/bluebananacolor.c
cinelerra-5.1/plugins/bluebanana/bluebananaconfig.C
cinelerra-5.1/plugins/bluebanana/bluebananaconfig.h
cinelerra-5.1/plugins/bluebanana/bluebananaengine.C
cinelerra-5.1/plugins/bluebanana/bluebananawindow.C
cinelerra-5.1/plugins/bluebanana/bluebananawindow.h

index 9e1cc94dc81f300e430f458b1ccdf198e6807c96..2f3399d5676e1a8187599bf0232268fcdc60927d 100644 (file)
@@ -130,6 +130,7 @@ void BluebananaMain::save_data(KeyFrame *keyframe){
   output.tag.set_title("BLUEBANANA");
 
   output.tag.set_property("ACTIVE", config.active);
+  output.tag.set_property("OP", config.op);
   output.tag.set_property("INVERT_SELECTION", config.invert_selection);
   output.tag.set_property("USE_MASK", config.use_mask);
   output.tag.set_property("CAPTURE_MASK", config.capture_mask);
@@ -272,6 +273,7 @@ void BluebananaMain::read_data(KeyFrame *keyframe){
 
     if(!result && input.tag.title_is("BLUEBANANA")){
       config.active = input.tag.get_property("ACTIVE", config.active);
+      config.op = input.tag.get_property("OP", config.op);
       config.invert_selection = input.tag.get_property("INVERT_SELECTION", config.invert_selection);
       config.use_mask = input.tag.get_property("USE_MASK", config.use_mask);
       config.capture_mask = input.tag.get_property("CAPTURE_MASK", config.capture_mask);
index 357518aee8216155a953abded8cff5eece219a47..f770d878775053e2f266952d73091abefdada7d4 100644 (file)
@@ -226,11 +226,16 @@ static inline void RGB_to_rgb8(float *R, float *G, float *B, float *S, float F,
 }
 
 static inline void Aal_to_alp8(float *S, float F, unsigned char *row, int w, int bpp){
-  F = 1.f - F;
-  while(w--){
-    float a = (1 - *S*F)*255.f +.5f;
-    row[3] = CLAMP(a,0,255);
-    row+=bpp;  ++S;
+  if(S){
+    while(w--){
+      float a = *S*F*255.f +.5f;
+      row[3] = CLAMP(a,0,255);
+      row+=bpp;  ++S;
+    }
+  }else{
+    float a = F*255.f +.5f;
+    unsigned char s = CLAMP(a,0,255);
+    while(w--){ row[3] = s; row+=bpp; }
   }
 }
 
@@ -275,11 +280,15 @@ static inline void RGB_to_rgbF(float *R, float *G, float *B, float *S, float F,
 }
 
 static inline void Aal_to_alpF(float *S, float F, float *row, int w, int bpp){
-  F = 1.f - F;
-  while(w--){
-    float a = 1.f - *S*F;
-    row[3] = a;
-    row+=bpp;
+  if(S){
+    while(w--){
+      float a = *S*F;
+      row[3] = a;
+      row+=bpp;
+    }
+  }else{
+    float a = F;
+    while(w--){ row[3] = a; row+=bpp; }
   }
 }
 
index dc964de141fc4e886707bccd3b6a8cf1da236e81..c0c0d0a11fcf4ad78475fddd2dd442bd6f677b58 100644 (file)
@@ -25,6 +25,7 @@
 #include <math.h>
 
 BluebananaConfig::BluebananaConfig() {
+  op = 0;
   mark = 0;
   active = 1;
   use_mask = 0;
@@ -91,6 +92,7 @@ BluebananaConfig::BluebananaConfig() {
 int BluebananaConfig::equivalent(BluebananaConfig &that) {
   if(active != that.active) return 0;
   // mark is no an auto
+  if(op != that.op) return 0;
   if(use_mask != that.use_mask) return 0;
   if(capture_mask != that.capture_mask) return 0;
   if(invert_selection != that.invert_selection) return 0;
@@ -155,6 +157,7 @@ int BluebananaConfig::equivalent(BluebananaConfig &that) {
 
 void BluebananaConfig::copy_from(BluebananaConfig &that) {
   mark = that.mark;
+  op = that.op;
   active = that.active;
   use_mask = that.use_mask;
   capture_mask = that.capture_mask;
@@ -220,6 +223,7 @@ void BluebananaConfig::interpolate(BluebananaConfig &prev,
   double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
   double prev_scale = 1.0 - next_scale;
 
+  op = prev.op;
   active = prev.active;
   use_mask = prev.use_mask;
   capture_mask = prev.capture_mask;
index 124617ac6d9a476a1f162d9449d0590cb85c1130..0761b35b4192a1a73c9e532dcbc4111c758abbd7 100644 (file)
@@ -39,6 +39,7 @@ public:
         int mark;
 
 // auto
+       int op;
         int active;
         int use_mask;
         int capture_mask;
index 924d13fe3ab2e4b97a679582c30e9499508dd5a8..34037de1e25b9a52ec4bc07dce765da1e3b15abc 100644 (file)
@@ -53,6 +53,7 @@ void BluebananaUnit::process_package(LoadPackage *package){
   int j;
 
   int active = plugin->config.active;
+  int op = plugin->config.op;
   int use_mask = plugin->config.use_mask;
   int capture_mask = plugin->config.capture_mask;
   int invert_selection = plugin->config.invert_selection;
@@ -115,7 +116,7 @@ void BluebananaUnit::process_package(LoadPackage *package){
   int byte_advance=0;
   int have_alpha=1;
 
-#define SPLIT 128
+#define SPLIT 256
 
   int tasks = engine->get_total_packages()*16;
   int taski,rowi,coli;
@@ -405,45 +406,77 @@ void BluebananaUnit::process_package(LoadPackage *package){
 
           /* selection modification according to config */
           if(use_mask && have_alpha){
-            if(!have_selection){
-              /* selection consists only of mask */
-              selection_test=0.;
-              for(j = 0; j < todo; j++)
-                selection_test += selection[j] = Avec[j];
-              have_selection=1;
-            }else{
-              if(invert_selection){
-                if(selection_test < SELECT_THRESH){
-                  /* fully selected after invert, clip to mask */
-                  selection_test=0.f;
-                  for(j = 0; j < todo; j++)
-                    selection_test += selection[j] = Avec[j];
-                }else if (selection_test >= todo-SELECT_THRESH){
-                  /* fully deselected after invert */
-                  selection_test=0.;
+            if(!op){
+              if(!have_selection){
+                /* selection consists only of mask */
+                selection_test=0.;
+                for(j = 0; j < todo; j++)
+                  selection_test += selection[j] = Avec[j];
+                have_selection=1;
+              }else{
+                if(invert_selection){
+                  if(selection_test < SELECT_THRESH){
+                    /* fully selected after invert, clip to mask */
+                    selection_test=0.f;
+                    for(j = 0; j < todo; j++)
+                      selection_test += selection[j] = Avec[j];
+                  }else{
+                    /* partial selection after invert, clip to mask */
+                    selection_test=0.f;
+                    for(j = 0; j < todo; j++)
+                      selection_test += selection[j] = Avec[j]*(1.f-selection[j]);
+                  }
                 }else{
-                  /* partial selection after invert, clip to mask */
-                  selection_test=0.f;
-                  for(j = 0; j < todo; j++)
-                    selection_test += selection[j] = Avec[j]*(1.f-selection[j]);
+                  if(selection_test < SELECT_THRESH){
+                    /* fully deselected */
+                  }else if(selection_test >= todo-SELECT_THRESH){
+                    /* fully selected, clip to mask */
+                    selection_test=0.f;
+                    for(j = 0; j < todo; j++)
+                      selection_test += selection[j] = Avec[j];
+                  }else{
+                    /* partial selection, clip to mask */
+                    selection_test=0.f;
+                    for(j = 0; j < todo; j++)
+                      selection_test += selection[j] *= Avec[j];
+                  }
                 }
+              }
+            }else{
+              if(!have_selection){
+                for(j = 0; j < todo; j++) selection[j] = 1;
               }else{
-                if(selection_test < SELECT_THRESH){
-                  /* fully deselected */
-                }else if (selection_test >= todo-SELECT_THRESH){
-                  /* fully selected, clip to mask */
-                  selection_test=0.f;
-                  for(j = 0; j < todo; j++)
-                    selection_test += selection[j] = Avec[j];
+                if(invert_selection){
+                  if(selection_test < SELECT_THRESH){
+                    /* fully selected after invert */
+                    for(j = 0; j < todo; j++) selection[j] = 1;
+                  }else{
+                    /* partial selection after invert, clip to mask */
+                    selection_test=0.f;
+                    for(j = 0; j < todo; j++)
+                      selection_test += selection[j] =
+                        Avec[j]+(1.f-selection[j])-Avec[j]*(1.f-selection[j]);
+                  }
                 }else{
-                  /* partial selection, clip to mask */
-                  selection_test=0.f;
-                  for(j = 0; j < todo; j++)
-                    selection_test += selection[j] *= Avec[j];
+                  if(selection_test < SELECT_THRESH){
+                    /* fully deselected, clip to mask */
+                    selection_test=0.f;
+                    for(j = 0; j < todo; j++)
+                      selection_test += selection[j] = Avec[j];
+                  }else if(selection_test >= todo-SELECT_THRESH){
+                    /* fully selected */
+                  }else{
+                    /* partial selection, clip to mask */
+                    selection_test=0.f;
+                    for(j = 0; j < todo; j++)
+                      selection_test += selection[j] =
+                        selection[j]+Avec[j]-selection[j]*Avec[j];
+                  }
                 }
               }
             }
-            if(selection_test < SELECT_THRESH){
+
+            if(!use_mask && !invert_selection && selection_test < SELECT_THRESH){
               /* skip processing this fragment */
               /* we're using a mask; if the mask is set to capture, we
                  need to restore alpha before skipping */
@@ -893,51 +926,53 @@ void BluebananaUnit::process_package(LoadPackage *package){
               }
             }
           }
-
+          float *s = have_selection?selection:0;
           /* re-layer back into pipeline color format */
           switch(frame->get_color_model()) {
           case BC_RGB888:
-            RGB_to_rgb8(Rvec,Gvec,Bvec,have_selection?selection:0,1.f,row_fragment,todo,3);
+            RGB_to_rgb8(Rvec,Gvec,Bvec,s,1.f,row_fragment,todo,3);
             break;
           case BC_RGBA8888:
-            RGB_to_rgb8(Rvec,Gvec,Bvec,have_selection?selection:0,1.f,row_fragment,todo,4);
+            RGB_to_rgb8(Rvec,Gvec,Bvec,s,1.f,row_fragment,todo,4);
             break;
           case BC_RGB_FLOAT:
-            RGB_to_rgbF(Rvec,Gvec,Bvec,have_selection?selection:0,1.f,(float *)row_fragment,todo,3);
+            RGB_to_rgbF(Rvec,Gvec,Bvec,s,1.f,(float *)row_fragment,todo,3);
             break;
           case BC_RGBA_FLOAT:
-            RGB_to_rgbF(Rvec,Gvec,Bvec,have_selection?selection:0,1.f,(float *)row_fragment,todo,4);
+            RGB_to_rgbF(Rvec,Gvec,Bvec,s,1.f,(float *)row_fragment,todo,4);
             break;
           case BC_YUV888:
-            RGB_to_yuv8(Rvec,Gvec,Bvec,have_selection?selection:0,1.f,row_fragment,todo,3);
+            RGB_to_yuv8(Rvec,Gvec,Bvec,s,1.f,row_fragment,todo,3);
             break;
           case BC_YUVA8888:
-            RGB_to_yuv8(Rvec,Gvec,Bvec,have_selection?selection:0,1.f,row_fragment,todo,4);
+            RGB_to_yuv8(Rvec,Gvec,Bvec,s,1.f,row_fragment,todo,4);
             break;
           }
         }
 
-        if(active || show_ants || (use_mask && capture_mask)){
-
-          if(use_mask && capture_mask){
+        if(active || show_ants || use_mask || capture_mask){
+          if(capture_mask){
             switch(frame->get_color_model()) {
             case BC_RGBA8888:
-              if( have_selection && Aal < 1.f )
-                Aal_to_alp8(selection,Aal,row_fragment,todo,4);
-              else
-                unmask_rgba8(row_fragment,todo);
+              unmask_rgba8(row_fragment,todo);
               break;
             case BC_RGBA_FLOAT:
-              if( have_selection && Aal < 1.f )
-                Aal_to_alpF(selection,Aal,(float *)row_fragment,todo,4);
-              else
-                unmask_rgbaF((float *)row_fragment,todo);
+              unmask_rgbaF((float *)row_fragment,todo);
               break;
             case BC_YUVA8888:
-              if( have_selection && Aal < 1.f )
-                Aal_to_alp8(selection,Aal,row_fragment,todo,4);
-              else
-                unmask_yuva8(row_fragment,todo);
+              unmask_yuva8(row_fragment,todo);
+              break;
+            }
+          }
+          else if(use_mask){
+            float *s = !show_ants&&have_selection?selection:0;
+            switch(frame->get_color_model()) {
+            case BC_RGBA8888:
+            case BC_YUVA8888:
+              Aal_to_alp8(s,Aal,row_fragment,todo,4);
+              break;
+            case BC_RGBA_FLOAT:
+              Aal_to_alpF(s,Aal,(float *)row_fragment,todo,4);
               break;
             }
           }
index 191b635c2a84bd8e99c97ad1fe6822a9f6612590..504957e9a72c4d0a784d450a289412ac3c589c75 100644 (file)
@@ -29,6 +29,7 @@
 #include "bluebananawindow.h"
 #include "keys.h"
 #include "language.h"
+#include "plugin.h"
 #include "brender.h"
 
 #include "bluebananacolor.c"
@@ -1762,6 +1763,31 @@ public:
 };
 
 
+// -------------------------------------------- Op --------------------------------------------
+class BluebananaOp : public BC_CheckBox {
+public:
+  BluebananaOp(BluebananaMain *plugin, BluebananaWindow *gui)
+    : BC_CheckBox(-1, -1, &plugin->config.op, ""){
+    this->plugin = plugin;
+    this->gui = gui;
+  }
+  virtual int handle_event() {
+    if(plugin->config.op != get_value()){
+      plugin->config.op = get_value();
+      gui->enter_config_change();
+      gui->commit_config_change();
+    }
+    return 1;
+  }
+  void update (){
+    if(plugin->config.op != get_value()){
+      this->BC_CheckBox::update(plugin->config.op,1);
+    }
+  };
+  BluebananaMain *plugin;
+  BluebananaWindow *gui;
+};
+
 // -------------------------------------------- Mark --------------------------------------------
 class BluebananaMark : public BC_CheckBox {
 public:
@@ -2063,26 +2089,30 @@ void BluebananaWindow::create_objects()
 
   /* window headline */
   {
-    BC_Title *l = new BC_Title(xmargin,y,_("Color Selection"));
+    BC_Title *l = new BC_Title(xmargin,y,_("Combine Selection"));
     BC_Title *l2 = new BC_Title(-1,-1,_(" Mark Selected Areas"));
     add_subwindow(mark = new BluebananaMark(plugin,this));
     add_subwindow(l);
     add_subwindow(l2);
     padx = l->get_h()*column_padding;
-    label_x = xmargin + l->get_w();
-
-    int x0 = get_w()-xmargin-mark->get_w();
-    mark->reposition_window(x0,y-(mark->get_h()-l->get_h())/2);
-    x0 -= padx+l2->get_w();
-    l2->reposition_window(x0,y);
-    x0-=padx;
+    add_subwindow(op = new BluebananaOp(plugin,this));
+    int x0 = xmargin + l->get_w() + padx;
+    op->reposition_window(x0,y-(op->get_h()-l->get_h())/2);
+    x0 += op->get_w() + padx;
+    int x1 = get_w()-xmargin-mark->get_w();
+    mark->reposition_window(x1,y-(mark->get_h()-l->get_h())/2);
+    x1 -= padx+l2->get_w();
+    l2->reposition_window(x1,y);
+    x1-=padx;
 
     set_color(get_resources()->default_text_color);
-    draw_line(label_x+padx, (int)(y+l->get_h()*.5), x0, (int)(y+l->get_h()*.5));
+    int y0 = y+l->get_h()*.5;
+    draw_line(x0,y0, x1,y0);
 
     y += l->get_h()*(row_padding+1.);
   }
 
+  label_x = xmargin + 100 + padx;
   const char *labels[12]={_("hue"),_("saturation"),_("value"),_("fill"),_("red"),_("green"),_("blue"),_("hue"),_("saturation"),_("value"),_("fade"),_("alpha")};
   for(i=0;i<12;i++){
     add_subwindow(slider_labels[i] = new BC_Title(-1,-1,labels[i]));
@@ -2442,10 +2472,10 @@ int BluebananaWindow::flush_config_change(){
 
 int BluebananaWindow::repeat_event(int64_t d){
   if(d==97){
-    if(config_consume==config_produce)
+    if(config_consume!=config_produce)
       flush_config_change();
-    config_consume=config_produce;
   }
+  if(!plugin->server->plugin->on) return 0;
   if(d==207){
 
     /* if background render is active and we're showing the zebra, mark
index 3967500257f19066e23c17854647811e8f4e2a7e..6f951a762a2e8811d4d6c0642b51467ea0c14242 100644 (file)
@@ -31,6 +31,7 @@ class BluebananaMain;
 class BluebananaThread;
 class BluebananaMark;
 class BluebananaActive;
+class BluebananaOp;
 class BluebananaA2Sel;
 class BluebananaIS;
 class BluebananaUnmask;
@@ -171,6 +172,7 @@ public:
        BluebananaMain *plugin;
 
         BluebananaMark *mark;
+        BluebananaOp *op;
         BluebananaActive *active;
         BluebananaA2Sel *use_mask;
         BluebananaUnmask *capture_mask;