remove Features5, rework gradient plugin, fix paste_edl track title bug, gl_probe...
[goodguy/cinelerra.git] / cinelerra-5.1 / plugins / gradient / gradient.C
index a7f611b4d2e0f58d2ac5b5d43bc9fdfbf10847ed..826f817f6d0de267afad55418b796331e156dfa3 100644 (file)
 #include "theme.h"
 #include "vframe.h"
 
 #include "theme.h"
 #include "vframe.h"
 
-
-
-
 REGISTER_PLUGIN(GradientMain)
 
 REGISTER_PLUGIN(GradientMain)
 
-
-
-
-
-
 GradientConfig::GradientConfig()
 {
        reset();
 }
 
 void GradientConfig::reset()
 GradientConfig::GradientConfig()
 {
        reset();
 }
 
 void GradientConfig::reset()
-
 {
        angle = 0;
        in_radius = 0;
        out_radius = 100;
 {
        angle = 0;
        in_radius = 0;
        out_radius = 100;
-       in_r = 0xff;
-       in_g = 0xff;
-       in_b = 0xff;
-       in_a = 0xff;
-       out_r = 0x0;
-       out_g = 0x0;
-       out_b = 0x0;
-       out_a = 0x0;
+       in_r  = in_g  = in_b  = in_a  = 0xff;
+       out_r = out_g = out_b = out_a = 0x00;
        shape = GradientConfig::LINEAR;
        rate = GradientConfig::LINEAR;
        center_x = 50;
        shape = GradientConfig::LINEAR;
        rate = GradientConfig::LINEAR;
        center_x = 50;
@@ -108,16 +93,12 @@ void GradientConfig::copy_from(GradientConfig &that)
        center_y = that.center_y;
 }
 
        center_y = that.center_y;
 }
 
-void GradientConfig::interpolate(GradientConfig &prev,
-       GradientConfig &next,
-       long prev_frame,
-       long next_frame,
-       long current_frame)
+void GradientConfig::interpolate(GradientConfig &prev, GradientConfig &next,
+               long prev_frame, long next_frame, long current_frame)
 {
        double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
        double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
 
 {
        double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
        double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
 
-
        this->angle = (int)(prev.angle * prev_scale + next.angle * next_scale);
        this->in_radius = (int)(prev.in_radius * prev_scale + next.in_radius * next_scale);
        this->out_radius = (int)(prev.out_radius * prev_scale + next.out_radius * next_scale);
        this->angle = (int)(prev.angle * prev_scale + next.angle * next_scale);
        this->in_radius = (int)(prev.in_radius * prev_scale + next.in_radius * next_scale);
        this->out_radius = (int)(prev.out_radius * prev_scale + next.out_radius * next_scale);
@@ -147,26 +128,11 @@ int GradientConfig::get_out_color()
        return result;
 }
 
        return result;
 }
 
-
-
-
-
-
-
-
-
-
-
 #define COLOR_W 100
 #define COLOR_H 30
 
 GradientWindow::GradientWindow(GradientMain *plugin)
 #define COLOR_W 100
 #define COLOR_H 30
 
 GradientWindow::GradientWindow(GradientMain *plugin)
- : PluginClientWindow(plugin,
-       350,
-       290,
-       350,
-       290,
-       0)
+ : PluginClientWindow(plugin, 350, 290, 350, 290, 0)
 {
        this->plugin = plugin;
        angle = 0;
 {
        this->plugin = plugin;
        angle = 0;
@@ -175,14 +141,16 @@ GradientWindow::GradientWindow(GradientMain *plugin)
        center_y = 0;
        center_x_title = 0;
        center_y_title = 0;
        center_y = 0;
        center_x_title = 0;
        center_y_title = 0;
+       in_color_thread = 0;
+       out_color_thread = 0;
 }
 }
-
 GradientWindow::~GradientWindow()
 {
        delete in_color_thread;
        delete out_color_thread;
 }
 
 GradientWindow::~GradientWindow()
 {
        delete in_color_thread;
        delete out_color_thread;
 }
 
+
 void GradientWindow::create_objects()
 {
        int margin = plugin->get_theme()->widget_border;
 void GradientWindow::create_objects()
 {
        int margin = plugin->get_theme()->widget_border;
@@ -190,10 +158,8 @@ void GradientWindow::create_objects()
        BC_Title *title;
 
        add_subwindow(title = new BC_Title(x, y, _("Shape:")));
        BC_Title *title;
 
        add_subwindow(title = new BC_Title(x, y, _("Shape:")));
-       add_subwindow(shape = new GradientShape(plugin,
-               this,
-               x + title->get_w() + margin,
-               y));
+       add_subwindow(shape = new GradientShape(plugin, this,
+                       x + title->get_w() + margin, y));
        shape->create_objects();
        y += shape->get_h() + margin;
        shape_x = x;
        shape->create_objects();
        y += shape->get_h() + margin;
        shape_x = x;
@@ -202,19 +168,14 @@ void GradientWindow::create_objects()
 
        add_subwindow(title = new BC_Title(x, y, _("Rate:")));
        add_subwindow(rate = new GradientRate(plugin,
 
        add_subwindow(title = new BC_Title(x, y, _("Rate:")));
        add_subwindow(rate = new GradientRate(plugin,
-               x + title->get_w() + margin,
-               y));
+                       x + title->get_w() + margin, y));
        rate->create_objects();
        y += rate->get_h() + margin;
 
        rate->create_objects();
        y += rate->get_h() + margin;
 
-       int x1 = x;
-       int y1 = y;
-
+       int x1 = x, y1 = y;
        BC_Title *title1;
        add_subwindow(title1 = new BC_Title(x, y, _("Inner radius:")));
        BC_Title *title1;
        add_subwindow(title1 = new BC_Title(x, y, _("Inner radius:")));
-
        y += BC_Slider::get_span(0) + margin;
        y += BC_Slider::get_span(0) + margin;
-
        BC_Title *title2;
        add_subwindow(title2 = new BC_Title(x, y, _("Outer radius:")));
 
        BC_Title *title2;
        add_subwindow(title2 = new BC_Title(x, y, _("Outer radius:")));
 
@@ -222,10 +183,8 @@ void GradientWindow::create_objects()
 
        y = y1;
        x += MAX(title1->get_w(), title2->get_w()) + margin;
 
        y = y1;
        x += MAX(title1->get_w(), title2->get_w()) + margin;
-
        add_subwindow(in_radius = new GradientInRadius(plugin, x, y));
        y += in_radius->get_h() + margin;
        add_subwindow(in_radius = new GradientInRadius(plugin, x, y));
        y += in_radius->get_h() + margin;
-
        add_subwindow(out_radius = new GradientOutRadius(plugin, x, y));
        y += out_radius->get_h() + margin;
 
        add_subwindow(out_radius = new GradientOutRadius(plugin, x, y));
        y += out_radius->get_h() + margin;
 
@@ -249,19 +208,11 @@ void GradientWindow::create_objects()
        update_out_color();
        update_shape();
 
        update_out_color();
        update_shape();
 
-       draw_3d_border(in_color_x - 2,
-               in_color_y - 2,
-               COLOR_W + 4,
-               COLOR_H + 4,
-               1);
-
-       draw_3d_border(out_color_x - 2,
-               out_color_y - 2,
-               COLOR_W + 4,
-               COLOR_H + 4,
-               1);
-
+       draw_3d_border(in_color_x - 2, in_color_y - 2,
+               COLOR_W + 4, COLOR_H + 4, 1);
 
 
+       draw_3d_border(out_color_x - 2, out_color_y - 2,
+               COLOR_W + 4, COLOR_H + 4, 1);
        show_window();
 }
 
        show_window();
 }
 
@@ -269,48 +220,32 @@ void GradientWindow::update_shape()
 {
        int x = shape_x, y = shape_y;
 
 {
        int x = shape_x, y = shape_y;
 
-       if(plugin->config.shape == GradientConfig::LINEAR)
-       {
-               delete center_x_title;
-               delete center_y_title;
-               delete center_x;
-               delete center_y;
-               center_x_title = 0;
-               center_y_title = 0;
-               center_x = 0;
-               center_y = 0;
-
-               if(!angle)
-               {
+       if( plugin->config.shape == GradientConfig::LINEAR ) {
+               delete center_x_title;  center_x_title = 0;
+               delete center_y_title;  center_y_title = 0;
+               delete center_x;  center_x = 0;
+               delete center_y;  center_y = 0;
+               if( !angle ) {
                        add_subwindow(angle_title = new BC_Title(x, y, _("Angle:")));
                        add_subwindow(angle = new GradientAngle(plugin, x + angle_title->get_w() + 10, y));
                }
        }
                        add_subwindow(angle_title = new BC_Title(x, y, _("Angle:")));
                        add_subwindow(angle = new GradientAngle(plugin, x + angle_title->get_w() + 10, y));
                }
        }
-       else
-       {
-               delete angle_title;
-               delete angle;
-               angle_title = 0;
-               angle = 0;
-               if(!center_x)
-               {
+       else {
+               delete angle_title;  angle_title = 0;
+               delete angle;  angle = 0;
+               if( !center_x ) {
                        add_subwindow(center_x_title = new BC_Title(x, y, _("Center X:")));
                        add_subwindow(center_x = new GradientCenterX(plugin,
                        add_subwindow(center_x_title = new BC_Title(x, y, _("Center X:")));
                        add_subwindow(center_x = new GradientCenterX(plugin,
-                               x + center_x_title->get_w() + 10,
-                               y));
+                               x + center_x_title->get_w() + 10, y));
                        x += center_x_title->get_w() + 10 + center_x->get_w() + 10;
                        add_subwindow(center_y_title = new BC_Title(x, y, _("Center Y:")));
                        add_subwindow(center_y = new GradientCenterY(plugin,
                        x += center_x_title->get_w() + 10 + center_x->get_w() + 10;
                        add_subwindow(center_y_title = new BC_Title(x, y, _("Center Y:")));
                        add_subwindow(center_y = new GradientCenterY(plugin,
-                               x + center_y_title->get_w() + 10,
-                               y));
+                               x + center_y_title->get_w() + 10, y));
                }
        }
        show_window();
 }
 
                }
        }
        show_window();
 }
 
-
-
-
 void GradientWindow::update_in_color()
 {
 //printf("GradientWindow::update_in_color 1 %08x\n", plugin->config.get_in_color());
 void GradientWindow::update_in_color()
 {
 //printf("GradientWindow::update_in_color 1 %08x\n", plugin->config.get_in_color());
@@ -333,18 +268,7 @@ void GradientWindow::done_event(int result)
        out_color_thread->close_window();
 }
 
        out_color_thread->close_window();
 }
 
-
-
-
-
-
-
-
-
-GradientShape::GradientShape(GradientMain *plugin,
-       GradientWindow *gui,
-       int x,
-       int y)
+GradientShape::GradientShape(GradientMain *plugin, GradientWindow *gui, int x, int y)
  : BC_PopupMenu(x, y, 100, to_text(plugin->config.shape), 1)
 {
        this->plugin = plugin;
  : BC_PopupMenu(x, y, 100, to_text(plugin->config.shape), 1)
 {
        this->plugin = plugin;
@@ -357,17 +281,14 @@ void GradientShape::create_objects()
 }
 char* GradientShape::to_text(int shape)
 {
 }
 char* GradientShape::to_text(int shape)
 {
-       switch(shape)
-       {
-               case GradientConfig::LINEAR:
-                       return _("Linear");
-               default:
-                       return _("Radial");
+       switch( shape ) {
+       case GradientConfig::LINEAR:    return _("Linear");
        }
        }
+       return _("Radial");
 }
 int GradientShape::from_text(char *text)
 {
 }
 int GradientShape::from_text(char *text)
 {
-       if(!strcmp(text, to_text(GradientConfig::LINEAR)))
+       if( !strcmp(text, to_text(GradientConfig::LINEAR)) )
                return GradientConfig::LINEAR;
        return GradientConfig::RADIAL;
 }
                return GradientConfig::LINEAR;
        return GradientConfig::RADIAL;
 }
@@ -380,8 +301,6 @@ int GradientShape::handle_event()
 }
 
 
 }
 
 
-
-
 GradientCenterX::GradientCenterX(GradientMain *plugin, int x, int y)
  : BC_FPot(x, y, plugin->config.center_x, 0, 100)
 {
 GradientCenterX::GradientCenterX(GradientMain *plugin, int x, int y)
  : BC_FPot(x, y, plugin->config.center_x, 0, 100)
 {
@@ -395,7 +314,6 @@ int GradientCenterX::handle_event()
 }
 
 
 }
 
 
-
 GradientCenterY::GradientCenterY(GradientMain *plugin, int x, int y)
  : BC_FPot(x, y, plugin->config.center_y, 0, 100)
 {
 GradientCenterY::GradientCenterY(GradientMain *plugin, int x, int y)
  : BC_FPot(x, y, plugin->config.center_y, 0, 100)
 {
@@ -410,14 +328,8 @@ int GradientCenterY::handle_event()
 }
 
 
 }
 
 
-
-
 GradientAngle::GradientAngle(GradientMain *plugin, int x, int y)
 GradientAngle::GradientAngle(GradientMain *plugin, int x, int y)
- : BC_FPot(x,
-       y,
-       plugin->config.angle,
-       -180,
-       180)
+ : BC_FPot(x, y, plugin->config.angle, -180, 180)
 {
        this->plugin = plugin;
 }
 {
        this->plugin = plugin;
 }
@@ -431,11 +343,7 @@ int GradientAngle::handle_event()
 
 
 GradientRate::GradientRate(GradientMain *plugin, int x, int y)
 
 
 GradientRate::GradientRate(GradientMain *plugin, int x, int y)
- : BC_PopupMenu(x,
-       y,
-       100,
-       to_text(plugin->config.rate),
-       1)
+ : BC_PopupMenu(x, y, 100, to_text(plugin->config.rate), 1)
 {
        this->plugin = plugin;
 }
 {
        this->plugin = plugin;
 }
@@ -447,21 +355,17 @@ void GradientRate::create_objects()
 }
 char* GradientRate::to_text(int shape)
 {
 }
 char* GradientRate::to_text(int shape)
 {
-       switch(shape)
-       {
-               case GradientConfig::LINEAR:
-                       return _("Linear");
-               case GradientConfig::LOG:
-                       return _("Log");
-               default:
-                       return _("Square");
+       switch( shape ) {
+       case GradientConfig::LINEAR:    return _("Linear");
+       case GradientConfig::LOG:       return _("Log");
        }
        }
+       return _("Square");
 }
 int GradientRate::from_text(char *text)
 {
 }
 int GradientRate::from_text(char *text)
 {
-       if(!strcmp(text, to_text(GradientConfig::LINEAR)))
+       if( !strcmp(text, to_text(GradientConfig::LINEAR)) )
                return GradientConfig::LINEAR;
                return GradientConfig::LINEAR;
-       if(!strcmp(text, to_text(GradientConfig::LOG)))
+       if( !strcmp(text, to_text(GradientConfig::LOG)) )
                return GradientConfig::LOG;
        return GradientConfig::SQUARE;
 }
                return GradientConfig::LOG;
        return GradientConfig::SQUARE;
 }
@@ -473,16 +377,9 @@ int GradientRate::handle_event()
 }
 
 
 }
 
 
-
 GradientInRadius::GradientInRadius(GradientMain *plugin, int x, int y)
 GradientInRadius::GradientInRadius(GradientMain *plugin, int x, int y)
- : BC_FSlider(x,
-       y,
-       0,
-       200,
-       200,
-       (float)0,
-       (float)100,
-       (float)plugin->config.in_radius)
+ : BC_FSlider(x, y, 0, 200, 200,
+               0.f, 100.f, (float)plugin->config.in_radius)
 {
        this->plugin = plugin;
 }
 {
        this->plugin = plugin;
 }
@@ -496,14 +393,8 @@ int GradientInRadius::handle_event()
 
 
 GradientOutRadius::GradientOutRadius(GradientMain *plugin, int x, int y)
 
 
 GradientOutRadius::GradientOutRadius(GradientMain *plugin, int x, int y)
- : BC_FSlider(x,
-       y,
-       0,
-       200,
-       200,
-       (float)0,
-       (float)100,
-       (float)plugin->config.out_radius)
+ : BC_FSlider(x, y, 0, 200, 200,
+               0.f, 100.f, (float)plugin->config.out_radius)
 {
        this->plugin = plugin;
 }
 {
        this->plugin = plugin;
 }
@@ -581,21 +472,13 @@ int GradientInColorThread::handle_new_color(int output, int alpha)
        window->flush();
        window->unlock_window();
        plugin->send_configure_change();
        window->flush();
        window->unlock_window();
        plugin->send_configure_change();
-// printf("GradientInColorThread::handle_event 1 %d %d %d %d %d %d %d %d\n",
-// plugin->config.in_r,
-// plugin->config.in_g,
-// plugin->config.in_b,
-// plugin->config.in_a,
-// plugin->config.out_r,
-// plugin->config.out_g,
-// plugin->config.out_b,
-// plugin->config.out_a);
-
+//printf("GradientInColorThread::handle_event 1 %d %d %d %d %d %d %d %d\n",
+// plugin->config.in_r, plugin->config.in_g, plugin->config.in_b, plugin->config.in_a,
+// plugin->config.out_r, plugin->config.out_g, plugin->config.out_b, plugin->config.out_a);
        return 1;
 }
 
 
        return 1;
 }
 
 
-
 GradientOutColorThread::GradientOutColorThread(GradientMain *plugin,
        GradientWindow *window)
  : ColorPicker(1, _("Outer color"))
 GradientOutColorThread::GradientOutColorThread(GradientMain *plugin,
        GradientWindow *window)
  : ColorPicker(1, _("Outer color"))
@@ -615,29 +498,13 @@ int GradientOutColorThread::handle_new_color(int output, int alpha)
        window->flush();
        window->unlock_window();
        plugin->send_configure_change();
        window->flush();
        window->unlock_window();
        plugin->send_configure_change();
-// printf("GradientOutColorThread::handle_event 1 %d %d %d %d %d %d %d %d\n",
-// plugin->config.in_r,
-// plugin->config.in_g,
-// plugin->config.in_b,
-// plugin->config.in_a,
-// plugin->config.out_r,
-// plugin->config.out_g,
-// plugin->config.out_b,
-// plugin->config.out_a);
+//printf("GradientOutColorThread::handle_event 1 %d %d %d %d %d %d %d %d\n",
+// plugin->config.in_r, plugin->config.in_g, plugin->config.in_b, plugin->config.in_a,
+// plugin->config.out_r, plugin->config.out_g, plugin->config.out_b, plugin->config.out_a);
        return 1;
 }
 
 
        return 1;
 }
 
 
-
-
-
-
-
-
-
-
-
-
 GradientMain::GradientMain(PluginServer *server)
  : PluginVClient(server)
 {
 GradientMain::GradientMain(PluginServer *server)
  : PluginVClient(server)
 {
@@ -646,15 +513,16 @@ GradientMain::GradientMain(PluginServer *server)
        gradient = 0;
        engine = 0;
        overlayer = 0;
        gradient = 0;
        engine = 0;
        overlayer = 0;
+       table = 0;
+       table_size = 0;
 }
 
 GradientMain::~GradientMain()
 {
 }
 
 GradientMain::~GradientMain()
 {
-
-
-       if(gradient) delete gradient;
-       if(engine) delete engine;
-       if(overlayer) delete overlayer;
+       delete [] table;
+       delete gradient;
+       delete engine;
+       delete overlayer;
 }
 
 const char* GradientMain::plugin_title() { return N_("Gradient"); }
 }
 
 const char* GradientMain::plugin_title() { return N_("Gradient"); }
@@ -677,69 +545,59 @@ int GradientMain::process_buffer(VFrame *frame,
 {
        this->input = frame;
        this->output = frame;
 {
        this->input = frame;
        this->output = frame;
-       need_reconfigure |= load_configuration();
+       float fw = input->get_w(), fh = input->get_h();
+       gradient_size = hypotf(fw, fh);
+       need_reconfigure = load_configuration();
 
        int need_alpha = config.in_a != 0xff || config.out_a != 0xff;
 
        int need_alpha = config.in_a != 0xff || config.out_a != 0xff;
-       if(need_alpha)
-               read_frame(frame,
-                       0,
-                       start_position,
-                       frame_rate,
-                       get_use_opengl());
-       if(get_use_opengl()) return run_opengl();
+       if( need_alpha )
+               read_frame(frame, 0, start_position, frame_rate, get_use_opengl());
+       if( get_use_opengl() ) return run_opengl();
 
        int gradient_cmodel = input->get_color_model();
 
        int gradient_cmodel = input->get_color_model();
-       if(need_alpha && BC_CModels::components(gradient_cmodel) == 3)
-       {
-               switch(gradient_cmodel)
-               {
-                       case BC_RGB888:
-                               gradient_cmodel = BC_RGBA8888;
-                               break;
-                       case BC_RGB_FLOAT:
-                               gradient_cmodel = BC_RGBA_FLOAT;
-                               break;
-                       case BC_YUV888:
-                               gradient_cmodel = BC_YUVA8888;
-                               break;
+       if( need_alpha && BC_CModels::components(gradient_cmodel) == 3 ) {
+               switch( gradient_cmodel ) {
+               case BC_RGB888:     gradient_cmodel = BC_RGBA8888;    break;
+               case BC_YUV888:     gradient_cmodel = BC_YUVA8888;    break;
+               case BC_RGB_FLOAT:  gradient_cmodel = BC_RGBA_FLOAT;  break;
                }
        }
 
                }
        }
 
-       if(gradient && gradient->get_color_model() != gradient_cmodel)
-       {
+       int bpp = BC_CModels::calculate_pixelsize(gradient_cmodel);
+       int comps = BC_CModels::components(gradient_cmodel);
+       int grad_size1 = gradient_size + 1;
+       int sz = 4 * (bpp / comps) * grad_size1;
+       if( table_size < sz ) {
+               delete [] table;  table = 0;
+       }
+       if( !table ) {
+               table = new uint8_t[table_size = sz];
+               need_reconfigure = 1;
+       }
+
+       if( gradient && gradient->get_color_model() != gradient_cmodel ) {
                delete gradient;
                gradient = 0;
        }
 
                delete gradient;
                gradient = 0;
        }
 
-       if(!gradient)
+       if( !gradient )
                gradient = new VFrame(input->get_w(), input->get_h(),
                        gradient_cmodel, 0);
 
                gradient = new VFrame(input->get_w(), input->get_h(),
                        gradient_cmodel, 0);
 
-       if(!engine) engine = new GradientServer(this,
-               get_project_smp() + 1,
-               get_project_smp() + 1);
+       if( !engine )
+               engine = new GradientServer(this,
+                       get_project_smp() + 1, get_project_smp() + 1);
        engine->process_packages();
 
 // Use overlay routine in GradientServer if mismatched colormodels
        engine->process_packages();
 
 // Use overlay routine in GradientServer if mismatched colormodels
-       if(gradient->get_color_model() == output->get_color_model())
-       {
-               if(!overlayer) overlayer = new OverlayFrame(get_project_smp() + 1);
-               overlayer->overlay(output,
-                       gradient,
-                       0,
-                       0,
-                       input->get_w(),
-                       input->get_h(),
-                       0,
-                       0,
-                       input->get_w(),
-                       input->get_h(),
-                       1.0,
-                       TRANSFER_NORMAL,
-                       NEAREST_NEIGHBOR);
+       if( gradient->get_color_model() == output->get_color_model() ) {
+               if( !overlayer ) overlayer = new OverlayFrame(get_project_smp() + 1);
+               overlayer->overlay(output, gradient,
+                       0, 0, input->get_w(), input->get_h(),
+                       0, 0, input->get_w(), input->get_h(),
+                       1.0, TRANSFER_NORMAL, NEAREST_NEIGHBOR);
        }
 
        }
 
-
        return 0;
 }
 
        return 0;
 }
 
@@ -812,30 +670,23 @@ void GradientMain::read_data(KeyFrame *keyframe)
 
        int result = 0;
 
 
        int result = 0;
 
-       while(!result)
-       {
-               result = input.read_tag();
-
-               if(!result)
-               {
-                       if(input.tag.title_is("GRADIENT"))
-                       {
-                               config.angle = input.tag.get_property("ANGLE", config.angle);
-                               config.rate = input.tag.get_property("RATE", config.rate);
-                               config.in_radius = input.tag.get_property("IN_RADIUS", config.in_radius);
-                               config.out_radius = input.tag.get_property("OUT_RADIUS", config.out_radius);
-                               config.in_r = input.tag.get_property("IN_R", config.in_r);
-                               config.in_g = input.tag.get_property("IN_G", config.in_g);
-                               config.in_b = input.tag.get_property("IN_B", config.in_b);
-                               config.in_a = input.tag.get_property("IN_A", config.in_a);
-                               config.out_r = input.tag.get_property("OUT_R", config.out_r);
-                               config.out_g = input.tag.get_property("OUT_G", config.out_g);
-                               config.out_b = input.tag.get_property("OUT_B", config.out_b);
-                               config.out_a = input.tag.get_property("OUT_A", config.out_a);
-                               config.shape = input.tag.get_property("SHAPE", config.shape);
-                               config.center_x = input.tag.get_property("CENTER_X", config.center_x);
-                               config.center_y = input.tag.get_property("CENTER_Y", config.center_y);
-                       }
+       while( !(result = input.read_tag()) ) {
+               if( input.tag.title_is("GRADIENT") ) {
+                       config.angle = input.tag.get_property("ANGLE", config.angle);
+                       config.rate = input.tag.get_property("RATE", config.rate);
+                       config.in_radius = input.tag.get_property("IN_RADIUS", config.in_radius);
+                       config.out_radius = input.tag.get_property("OUT_RADIUS", config.out_radius);
+                       config.in_r = input.tag.get_property("IN_R", config.in_r);
+                       config.in_g = input.tag.get_property("IN_G", config.in_g);
+                       config.in_b = input.tag.get_property("IN_B", config.in_b);
+                       config.in_a = input.tag.get_property("IN_A", config.in_a);
+                       config.out_r = input.tag.get_property("OUT_R", config.out_r);
+                       config.out_g = input.tag.get_property("OUT_G", config.out_g);
+                       config.out_b = input.tag.get_property("OUT_B", config.out_b);
+                       config.out_a = input.tag.get_property("OUT_A", config.out_a);
+                       config.shape = input.tag.get_property("SHAPE", config.shape);
+                       config.center_x = input.tag.get_property("CENTER_X", config.center_x);
+                       config.center_y = input.tag.get_property("CENTER_Y", config.center_y);
                }
        }
 }
                }
        }
 }
@@ -845,13 +696,10 @@ int GradientMain::handle_opengl()
 #ifdef HAVE_GL
        const char *head_frag =
                "uniform sampler2D tex;\n"
 #ifdef HAVE_GL
        const char *head_frag =
                "uniform sampler2D tex;\n"
-               "uniform float half_w;\n"
-               "uniform float half_h;\n"
-               "uniform float center_x;\n"
-               "uniform float center_y;\n"
-               "uniform float half_gradient_size;\n"
-               "uniform float sin_angle;\n"
-               "uniform float cos_angle;\n"
+               "uniform vec2 tex_dimensions;\n"
+               "uniform vec2 center;\n"
+               "uniform vec2 angle;\n"
+               "uniform float gradient_size;\n"
                "uniform vec4 out_color;\n"
                "uniform vec4 in_color;\n"
                "uniform float in_radius;\n"
                "uniform vec4 out_color;\n"
                "uniform vec4 in_color;\n"
                "uniform float in_radius;\n"
@@ -860,16 +708,14 @@ int GradientMain::handle_opengl()
                "\n"
                "void main()\n"
                "{\n"
                "\n"
                "void main()\n"
                "{\n"
-               "       vec2 out_coord = gl_TexCoord[0].st;\n";
+               "       vec2 out_coord = gl_TexCoord[0].st;\n"
+               "       vec2 in_coord = out_coord * tex_dimensions - center;\n";
 
        const char *linear_shape =
 
        const char *linear_shape =
-               "       vec2 in_coord = vec2(out_coord.x - half_w, half_h - out_coord.y);\n"
-               "       float mag = half_gradient_size - \n"
-               "               (in_coord.x * sin_angle + in_coord.y * cos_angle);\n";
+               "       float mag = 0.5 + dot(in_coord,angle)/gradient_size;\n";
 
        const char *radial_shape =
 
        const char *radial_shape =
-               "       vec2 in_coord = vec2(out_coord.x - center_x, out_coord.y - center_y);\n"
-               "       float mag = length(vec2(in_coord.x, in_coord.y));\n";
+               "       float mag = length(in_coord)/gradient_size;\n";
 
 // No clamp function in NVidia
        const char *linear_rate =
 
 // No clamp function in NVidia
        const char *linear_rate =
@@ -891,7 +737,7 @@ int GradientMain::handle_opengl()
                "       vec4 color = mix(in_color, out_color, opacity);\n"
                "       vec4 bg_color = texture2D(tex, out_coord);\n"
                "       gl_FragColor.rgb = mix(bg_color.rgb, color.rgb, color.a);\n"
                "       vec4 color = mix(in_color, out_color, opacity);\n"
                "       vec4 bg_color = texture2D(tex, out_coord);\n"
                "       gl_FragColor.rgb = mix(bg_color.rgb, color.rgb, color.a);\n"
-               "       gl_FragColor.a = max(bg_color.a, color.a);\n"
+               "       gl_FragColor.a = mix(bg_color.a, 1., color.a);\n"
                "}\n";
 
 
                "}\n";
 
 
@@ -914,7 +760,7 @@ int GradientMain::handle_opengl()
                shader_stack[current_shader++] = shape_frag;
 
        const char *rate_frag = 0;
                shader_stack[current_shader++] = shape_frag;
 
        const char *rate_frag = 0;
-       switch(config.rate) {
+       switch( config.rate ) {
        case GradientConfig::LINEAR:
                rate_frag = linear_rate;
                break;
        case GradientConfig::LINEAR:
                rate_frag = linear_rate;
                break;
@@ -944,76 +790,63 @@ int GradientMain::handle_opengl()
                glUseProgram(shader);
                float w = get_output()->get_w();
                float h = get_output()->get_h();
                glUseProgram(shader);
                float w = get_output()->get_w();
                float h = get_output()->get_h();
+               glUniform1i(glGetUniformLocation(shader, "tex"), 0);
                float texture_w = get_output()->get_texture_w();
                float texture_h = get_output()->get_texture_h();
                float texture_w = get_output()->get_texture_w();
                float texture_h = get_output()->get_texture_h();
-               glUniform1i(glGetUniformLocation(shader, "tex"), 0);
-               glUniform1f(glGetUniformLocation(shader, "half_w"), w / 2 / texture_w);
-               glUniform1f(glGetUniformLocation(shader, "half_h"), h / 2 / texture_h);
-               if(config.shape == GradientConfig::LINEAR)
-               {
-                       glUniform1f(glGetUniformLocation(shader, "center_x"),
-                               w / 2 / texture_w);
-                       glUniform1f(glGetUniformLocation(shader, "center_y"),
-                               h / 2 / texture_h);
-               }
-               else
-               {
-                       glUniform1f(glGetUniformLocation(shader, "center_x"),
-                               (float)config.center_x * w / 100 / texture_w);
-                       glUniform1f(glGetUniformLocation(shader, "center_y"),
-                               (float)config.center_y * h / 100 / texture_h);
+               glUniform2f(glGetUniformLocation(shader, "tex_dimensions"),
+                       texture_w, texture_h);
+               float u = config.shape == GradientConfig::LINEAR ?
+                       0.5f : config.center_x/100.f;
+               float v = config.shape == GradientConfig::LINEAR ?
+                       0.5f : config.center_y/100.f;
+               glUniform2f(glGetUniformLocation(shader, "center"),
+                       u * w, v * h);
+               glUniform1f(glGetUniformLocation(shader, "gradient_size"),
+                       gradient_size);
+               glUniform2f(glGetUniformLocation(shader, "angle"),
+                       -sin(config.angle * (M_PI / 180)), cos(config.angle * (M_PI / 180)));
+
+               float in_radius = (float)config.in_radius/100;
+               float out_radius = (float)config.out_radius/100;
+               if( in_radius > out_radius ) {
+                       float r = in_radius;
+                       in_radius = out_radius;
+                       out_radius = r;
                }
                }
-               float gradient_size = hypotf(w / texture_w, h / texture_h);
-               glUniform1f(glGetUniformLocation(shader, "half_gradient_size"),
-                       gradient_size / 2);
-               glUniform1f(glGetUniformLocation(shader, "sin_angle"),
-                       sin(config.angle * (M_PI / 180)));
-               glUniform1f(glGetUniformLocation(shader, "cos_angle"),
-                       cos(config.angle * (M_PI / 180)));
-               float in_radius = (float)config.in_radius / 100 * gradient_size;
                glUniform1f(glGetUniformLocation(shader, "in_radius"), in_radius);
                glUniform1f(glGetUniformLocation(shader, "in_radius"), in_radius);
-               float out_radius = (float)config.out_radius / 100 * gradient_size;
                glUniform1f(glGetUniformLocation(shader, "out_radius"), out_radius);
                glUniform1f(glGetUniformLocation(shader, "radius_diff"),
                        out_radius - in_radius);
 
                glUniform1f(glGetUniformLocation(shader, "out_radius"), out_radius);
                glUniform1f(glGetUniformLocation(shader, "radius_diff"),
                        out_radius - in_radius);
 
-               switch(get_output()->get_color_model()) {
+               float in_r  = (float)config.in_r  / 0xff;
+               float in_g  = (float)config.in_g  / 0xff;
+               float in_b  = (float)config.in_b  / 0xff;
+               float in_a  = (float)config.in_a  / 0xff;
+               float out_r = (float)config.out_r / 0xff;
+               float out_g = (float)config.out_g / 0xff;
+               float out_b = (float)config.out_b / 0xff;
+               float out_a = (float)config.out_a / 0xff;
+               switch( get_output()->get_color_model() ) {
                case BC_YUV888:
                case BC_YUVA8888: {
                        float in1, in2, in3, in4;
                        float out1, out2, out3, out4;
                case BC_YUV888:
                case BC_YUVA8888: {
                        float in1, in2, in3, in4;
                        float out1, out2, out3, out4;
-                       YUV::yuv.rgb_to_yuv_f(
-                               (float)config.in_r / 0xff,
-                               (float)config.in_g / 0xff,
-                               (float)config.in_b / 0xff,
-                               in1, in2, in3);
-                               in4 = (float)config.in_a / 0xff;
-                       YUV::yuv.rgb_to_yuv_f(
-                               (float)config.out_r / 0xff,
-                               (float)config.out_g / 0xff,
-                               (float)config.out_b / 0xff,
-                               out1, out2, out3);
-                       in2 += 0.5;   in3 += 0.5;
-                       out2 += 0.5;  out3 += 0.5;
-                       out4 = (float)config.out_a / 0xff;
+                       YUV::yuv.rgb_to_yuv_f(in_r,in_g,in_b, in1,in2,in3);
+                       in2  += 0.5;  in3 += 0.5;   in4 = in_a;
+                       YUV::yuv.rgb_to_yuv_f(out_r,out_g,out_b, out1,out2,out3);
+                       out2 += 0.5;  out3 += 0.5;  out4 = out_a;
                        glUniform4f(glGetUniformLocation(shader, "out_color"),
                                out1, out2, out3, out4);
                        glUniform4f(glGetUniformLocation(shader, "in_color"),
                                in1, in2, in3, in4);
                        break; }
 
                        glUniform4f(glGetUniformLocation(shader, "out_color"),
                                out1, out2, out3, out4);
                        glUniform4f(glGetUniformLocation(shader, "in_color"),
                                in1, in2, in3, in4);
                        break; }
 
-               default:
+               default: {
                        glUniform4f(glGetUniformLocation(shader, "out_color"),
                        glUniform4f(glGetUniformLocation(shader, "out_color"),
-                               (float)config.out_r / 0xff,
-                               (float)config.out_g / 0xff,
-                               (float)config.out_b / 0xff,
-                               (float)config.out_a / 0xff);
+                               out_r, out_g, out_b, out_a);
                        glUniform4f(glGetUniformLocation(shader, "in_color"),
                        glUniform4f(glGetUniformLocation(shader, "in_color"),
-                               (float)config.in_r / 0xff,
-                               (float)config.in_g / 0xff,
-                               (float)config.in_b / 0xff,
-                               (float)config.in_a / 0xff);
-                       break;
+                               in_r, in_g, in_b, in_a);
+                       break; }
                }
        }
 
                }
        }
 
@@ -1040,178 +873,139 @@ GradientUnit::GradientUnit(GradientServer *server, GradientMain *plugin)
 
 
 static float calculate_opacity(float mag,
 
 
 static float calculate_opacity(float mag,
-       float in_radius, float out_radius, int rate)
+               float in_radius, float out_radius, int rate)
 {
 {
+       float mag_diff = mag - in_radius;
+       float radius_diff = out_radius - in_radius;
+       if( !radius_diff ) return 1.0;
        float opacity = 0.0;
        float opacity = 0.0;
-       switch(rate)
-       {
-               case GradientConfig::LINEAR:
-                       if(mag < in_radius)
-                               opacity = 0.0;
-                       else
-                       if(mag >= out_radius)
-                               opacity = 1.0;
-                       else
-                               opacity = (float)(mag - in_radius) / (out_radius - in_radius);
-                       break;
-
-               case GradientConfig::LOG:
-                       if(mag < in_radius)
-                               opacity = 0;
-                       else
-// Let this one decay beyond out_radius
-                               opacity = 1 - exp(1.0 * -(float)(mag - in_radius) /
-                                       (out_radius - in_radius));
-                       break;
-
-               case GradientConfig::SQUARE:
-                       if(mag < in_radius)
-                               opacity = 0.0;
-                       else
-                       if(mag >= out_radius)
-                               opacity = 1.0;
-                       else
-                               opacity = powf((float)(mag - in_radius) /
-                                       (out_radius - in_radius), 2.0);
-                       break;
+       switch( rate ) {
+       case GradientConfig::LINEAR:
+               opacity = mag < in_radius ? 0.0 : mag >= out_radius ? 1.0 :
+                               mag_diff / radius_diff;
+               break;
+       case GradientConfig::LOG:
+               opacity = mag < in_radius ? 0.0 : // Let this one decay beyond out_radius
+                               1 - exp(1.0 * -mag_diff / radius_diff);
+               break;
+       case GradientConfig::SQUARE:
+               opacity = mag < in_radius ? 0.0 : mag >= out_radius ? 1.0 :
+                               powf(mag_diff / radius_diff, 2.);
+               break;
        }
        }
-       CLAMP(opacity, 0.0, 1.0);
        return opacity;
 }
 
        return opacity;
 }
 
-#define CREATE_GRADIENT(type, temp, components, max) \
-{ \
+#define CREATE_GRADIENT(type, temp, components, max) { \
 /* Synthesize linear gradient for lookups */ \
 /* Synthesize linear gradient for lookups */ \
+       int grad_size = plugin->gradient_size; \
+       int n = sizeof(type) * (grad_size+1); \
+       void *r_table = (void*) (plugin->table + 0*n); \
+       void *g_table = (void*) (plugin->table + 1*n); \
+       void *b_table = (void*) (plugin->table + 2*n); \
+       void *a_table = (void*) (plugin->table + 3*n); \
+       double grad_size2 = grad_size / 2.; \
  \
  \
-       r_table = malloc(sizeof(type) * gradient_size); \
-       g_table = malloc(sizeof(type) * gradient_size); \
-       b_table = malloc(sizeof(type) * gradient_size); \
-       a_table = malloc(sizeof(type) * gradient_size); \
- \
-       for(int i = 0; i < gradient_size; i++) \
-       { \
-               float opacity = calculate_opacity(i, in_radius, out_radius, plugin->config.rate); \
-               float transparency; \
- \
-               transparency = 1.0 - opacity; \
-               ((type*)r_table)[i] = (type)(out1 * opacity + in1 * transparency); \
-               ((type*)g_table)[i] = (type)(out2 * opacity + in2 * transparency); \
-               ((type*)b_table)[i] = (type)(out3 * opacity + in3 * transparency); \
-               ((type*)a_table)[i] = (type)(out4 * opacity + in4 * transparency); \
+       if( plugin->need_reconfigure ) { \
+               for( int i = 0; i <= grad_size; i++ ) { \
+                       float opacity = calculate_opacity(i, in_radius, out_radius, plugin->config.rate); \
+                       float transparency = 1.0 - opacity; \
+                       ((type*)r_table)[i] = (type)(out1 * opacity + in1 * transparency); \
+                       ((type*)g_table)[i] = (type)(out2 * opacity + in2 * transparency); \
+                       ((type*)b_table)[i] = (type)(out3 * opacity + in3 * transparency); \
+                       ((type*)a_table)[i] = (type)(out4 * opacity + in4 * transparency); \
+               } \
        } \
  \
        } \
  \
-       for(int i = pkg->y1; i < pkg->y2; i++) \
-       { \
+       for( int i = pkg->y1; i < pkg->y2; i++ ) { \
+               double y = half_h - i; \
                type *gradient_row = (type*)plugin->gradient->get_rows()[i]; \
                type *out_row = (type*)plugin->get_output()->get_rows()[i]; \
                type *gradient_row = (type*)plugin->gradient->get_rows()[i]; \
                type *out_row = (type*)plugin->get_output()->get_rows()[i]; \
- \
-               switch(plugin->config.shape) \
-               { \
-                       case GradientConfig::LINEAR: \
-                               for(int j = 0; j < w; j++) \
-                               { \
-                                       int x = j - half_w; \
-                                       int y = -(i - half_h); \
-                \
+               switch( plugin->config.shape ) { \
+               case GradientConfig::LINEAR: \
+                       for( int j = 0; j < w; j++ ) { \
+                               double x = j - half_w; \
 /* Rotate by effect angle */ \
 /* Rotate by effect angle */ \
-                                       int mag = (int)(gradient_size / 2 - \
-                                               (x * sin_angle + y * cos_angle) + \
-                                               0.5); \
-                \
+                               int mag = (grad_size2 - (x * sin_angle + y * cos_angle)) + 0.5; \
 /* Get gradient value from these coords */ \
 /* Get gradient value from these coords */ \
-                \
-                                       if(sizeof(type) == 4) \
-                                       { \
-                                               float opacity = calculate_opacity(mag,  \
-                                                       in_radius,  \
-                                                       out_radius, \
-                                                       plugin->config.rate); \
-                                               float transparency = 1.0 - opacity; \
-                                               gradient_row[0] = (type)(out1 * opacity + in1 * transparency); \
-                                               gradient_row[1] = (type)(out2 * opacity + in2 * transparency); \
-                                               gradient_row[2] = (type)(out3 * opacity + in3 * transparency); \
-                                               if(components == 4) gradient_row[3] = (type)(out4 * opacity + in4 * transparency); \
-                                       } \
-                                       else \
-                                       if(mag < 0) \
-                                       { \
-                                               gradient_row[0] = out1; \
-                                               gradient_row[1] = out2; \
-                                               gradient_row[2] = out3; \
-                                               if(components == 4) gradient_row[3] = out4; \
-                                       } \
-                                       else \
-                                       if(mag >= gradient_size) \
-                                       { \
-                                               gradient_row[0] = in1; \
-                                               gradient_row[1] = in2; \
-                                               gradient_row[2] = in3; \
-                                               if(components == 4) gradient_row[3] = in4; \
-                                       } \
-                                       else \
-                                       { \
-                                               gradient_row[0] = ((type*)r_table)[mag]; \
-                                               gradient_row[1] = ((type*)g_table)[mag]; \
-                                               gradient_row[2] = ((type*)b_table)[mag]; \
-                                               if(components == 4) gradient_row[3] = ((type*)a_table)[mag]; \
-                                       } \
- \
-/* Overlay mixed colormodels onto output */ \
-                                       if(gradient_cmodel != output_cmodel) \
-                                       { \
-                                               temp opacity = gradient_row[3]; \
-                                               temp transparency = max - opacity; \
-                                               out_row[0] = (transparency * out_row[0] + opacity * gradient_row[0]) / max; \
-                                               out_row[1] = (transparency * out_row[1] + opacity * gradient_row[1]) / max; \
-                                               out_row[2] = (transparency * out_row[2] + opacity * gradient_row[2]) / max; \
-                                               out_row += 3; \
-                                       } \
- \
-                                       gradient_row += components; \
+                               if( sizeof(type) == 4 ) { \
+                                       float opacity = calculate_opacity(mag, \
+                                               in_radius, out_radius, plugin->config.rate); \
+                                       float transparency = 1.0 - opacity; \
+                                       gradient_row[0] = (type)(out1 * opacity + in1 * transparency); \
+                                       gradient_row[1] = (type)(out2 * opacity + in2 * transparency); \
+                                       gradient_row[2] = (type)(out3 * opacity + in3 * transparency); \
+                                       if( components == 4 ) \
+                                               gradient_row[3] = (type)(out4 * opacity + in4 * transparency); \
                                } \
                                } \
-                               break; \
- \
-                       case GradientConfig::RADIAL: \
-                               for(int j = 0; j < w; j++) \
-                               { \
-                                       double x = j - center_x; \
-                                       double y = i - center_y; \
-                                       double magnitude = hypot(x, y); \
-                                       int mag = (int)magnitude; \
-                                       if(sizeof(type) == 4) \
-                                       { \
-                                               float opacity = calculate_opacity(mag,  \
-                                                       in_radius,  \
-                                                       out_radius, \
-                                                       plugin->config.rate); \
-                                               float transparency = 1.0 - opacity; \
-                                               gradient_row[0] = (type)(out1 * opacity + in1 * transparency); \
-                                               gradient_row[1] = (type)(out2 * opacity + in2 * transparency); \
-                                               gradient_row[2] = (type)(out3 * opacity + in3 * transparency); \
-                                               if(components == 4) gradient_row[3] = (type)(out4 * opacity + in4 * transparency); \
-                                       } \
-                                       else \
-                                       { \
-                                               gradient_row[0] = ((type*)r_table)[mag]; \
-                                               gradient_row[1] = ((type*)g_table)[mag]; \
-                                               gradient_row[2] = ((type*)b_table)[mag]; \
-                                               if(components == 4) gradient_row[3] = ((type*)a_table)[mag]; \
-                                       } \
+                               else if( mag < 0 ) { \
+                                       gradient_row[0] = in1; \
+                                       gradient_row[1] = in2; \
+                                       gradient_row[2] = in3; \
+                                       if( components == 4 ) \
+                                               gradient_row[3] = in4; \
+                               } \
+                               else if( mag >= grad_size ) { \
+                                       gradient_row[0] = out1; \
+                                       gradient_row[1] = out2; \
+                                       gradient_row[2] = out3; \
+                                       if( components == 4 ) \
+                                               gradient_row[3] = out4; \
+                               } \
+                               else { \
+                                       gradient_row[0] = ((type*)r_table)[mag]; \
+                                       gradient_row[1] = ((type*)g_table)[mag]; \
+                                       gradient_row[2] = ((type*)b_table)[mag]; \
+                                       if( components == 4 ) \
+                                               gradient_row[3] = ((type*)a_table)[mag]; \
+                               } \
+/* no alpha output, Overlay mixed colormodels */ \
+                               if( gradient_cmodel != output_cmodel ) { \
+                                       temp opacity = gradient_row[3]; \
+                                       temp transparency = max - opacity; \
+                                       out_row[0] = (transparency * out_row[0] + opacity * gradient_row[0]) / max; \
+                                       out_row[1] = (transparency * out_row[1] + opacity * gradient_row[1]) / max; \
+                                       out_row[2] = (transparency * out_row[2] + opacity * gradient_row[2]) / max; \
+                                       out_row += 3; \
+                               } \
+                               gradient_row += components; \
+                       } \
+                       break; \
  \
  \
+               case GradientConfig::RADIAL: \
+                       for( int j = 0; j < w; j++ ) { \
+                               double x = j - center_x, y = i - center_y; \
+                               double magnitude = hypot(x, y); \
+                               int mag = (int)magnitude; \
+                               if( sizeof(type) == 4 ) { \
+                                       float opacity = calculate_opacity(mag, \
+                                                       in_radius, out_radius, plugin->config.rate); \
+                                       float transparency = 1.0 - opacity; \
+                                       gradient_row[0] = (type)(out1 * opacity + in1 * transparency); \
+                                       gradient_row[1] = (type)(out2 * opacity + in2 * transparency); \
+                                       gradient_row[2] = (type)(out3 * opacity + in3 * transparency); \
+                                       if( components == 4 ) \
+                                               gradient_row[3] = (type)(out4 * opacity + in4 * transparency); \
+                               } \
+                               else { \
+                                       gradient_row[0] = ((type*)r_table)[mag]; \
+                                       gradient_row[1] = ((type*)g_table)[mag]; \
+                                       gradient_row[2] = ((type*)b_table)[mag]; \
+                                       if( components == 4 ) \
+                                               gradient_row[3] = ((type*)a_table)[mag]; \
+                               } \
 /* Overlay mixed colormodels onto output */ \
 /* Overlay mixed colormodels onto output */ \
-                                       if(gradient_cmodel != output_cmodel) \
-                                       { \
-                                               temp opacity = gradient_row[3]; \
-                                               temp transparency = max - opacity; \
-                                               out_row[0] = (transparency * out_row[0] + opacity * gradient_row[0]) / max; \
-                                               out_row[1] = (transparency * out_row[1] + opacity * gradient_row[1]) / max; \
-                                               out_row[2] = (transparency * out_row[2] + opacity * gradient_row[2]) / max; \
-                                               out_row += 3; \
-                                       } \
- \
-                                       gradient_row += components; \
+                               if( gradient_cmodel != output_cmodel ) { \
+                                       temp opacity = gradient_row[3]; \
+                                       temp transparency = max - opacity; \
+                                       out_row[0] = (transparency * out_row[0] + opacity * gradient_row[0]) / max; \
+                                       out_row[1] = (transparency * out_row[1] + opacity * gradient_row[1]) / max; \
+                                       out_row[2] = (transparency * out_row[2] + opacity * gradient_row[2]) / max; \
+                                       out_row += 3; \
                                } \
                                } \
-                               break; \
+                               gradient_row += components; \
+                       } \
+                       break; \
                } \
        } \
 }
                } \
        } \
 }
@@ -1221,147 +1015,110 @@ void GradientUnit::process_package(LoadPackage *package)
        GradientPackage *pkg = (GradientPackage*)package;
        int h = plugin->input->get_h();
        int w = plugin->input->get_w();
        GradientPackage *pkg = (GradientPackage*)package;
        int h = plugin->input->get_h();
        int w = plugin->input->get_w();
+       int grad_size = plugin->gradient_size;
        int half_w = w / 2;
        int half_h = h / 2;
        int half_w = w / 2;
        int half_h = h / 2;
-       int gradient_size = (int)(ceil(hypot(w, h)));
-       int in_radius = (int)(plugin->config.in_radius / 100 * gradient_size);
-       int out_radius = (int)(plugin->config.out_radius / 100 * gradient_size);
+       int in_radius = (int)(plugin->config.in_radius / 100 * grad_size);
+       int out_radius = (int)(plugin->config.out_radius / 100 * grad_size);
        double sin_angle = sin(plugin->config.angle * (M_PI / 180));
        double cos_angle = cos(plugin->config.angle * (M_PI / 180));
        double center_x = plugin->config.center_x * w / 100;
        double center_y = plugin->config.center_y * h / 100;
        double sin_angle = sin(plugin->config.angle * (M_PI / 180));
        double cos_angle = cos(plugin->config.angle * (M_PI / 180));
        double center_x = plugin->config.center_x * w / 100;
        double center_y = plugin->config.center_y * h / 100;
-       void *r_table = 0;
-       void *g_table = 0;
-       void *b_table = 0;
-       void *a_table = 0;
        int gradient_cmodel = plugin->gradient->get_color_model();
        int output_cmodel = plugin->get_output()->get_color_model();
 
        int gradient_cmodel = plugin->gradient->get_color_model();
        int output_cmodel = plugin->get_output()->get_color_model();
 
-       if(in_radius > out_radius)
-       {
-           in_radius ^= out_radius;
-           out_radius ^= in_radius;
-           in_radius ^= out_radius;
+       if( in_radius > out_radius ) {
+               int r = in_radius;
+               in_radius = out_radius;
+               out_radius = r;
        }
 
        }
 
-
-       switch(gradient_cmodel)
-       {
-               case BC_RGB888:
-               {
-                       int in1 = plugin->config.in_r;
-                       int in2 = plugin->config.in_g;
-                       int in3 = plugin->config.in_b;
-                       int in4 = plugin->config.in_a;
-                       int out1 = plugin->config.out_r;
-                       int out2 = plugin->config.out_g;
-                       int out3 = plugin->config.out_b;
-                       int out4 = plugin->config.out_a;
-                       CREATE_GRADIENT(unsigned char, int, 3, 0xff)
-                       break;
-               }
-
-               case BC_RGBA8888:
-               {
-                       int in1 = plugin->config.in_r;
-                       int in2 = plugin->config.in_g;
-                       int in3 = plugin->config.in_b;
-                       int in4 = plugin->config.in_a;
-                       int out1 = plugin->config.out_r;
-                       int out2 = plugin->config.out_g;
-                       int out3 = plugin->config.out_b;
-                       int out4 = plugin->config.out_a;
-                       CREATE_GRADIENT(unsigned char, int, 4, 0xff)
-                       break;
-               }
-
-               case BC_RGB_FLOAT:
-               {
-                       float in1 = (float)plugin->config.in_r / 0xff;
-                       float in2 = (float)plugin->config.in_g / 0xff;
-                       float in3 = (float)plugin->config.in_b / 0xff;
-                       float in4 = (float)plugin->config.in_a / 0xff;
-                       float out1 = (float)plugin->config.out_r / 0xff;
-                       float out2 = (float)plugin->config.out_g / 0xff;
-                       float out3 = (float)plugin->config.out_b / 0xff;
-                       float out4 = (float)plugin->config.out_a / 0xff;
-                       CREATE_GRADIENT(float, float, 3, 1.0)
-                       break;
-               }
-
-               case BC_RGBA_FLOAT:
-               {
-                       float in1 = (float)plugin->config.in_r / 0xff;
-                       float in2 = (float)plugin->config.in_g / 0xff;
-                       float in3 = (float)plugin->config.in_b / 0xff;
-                       float in4 = (float)plugin->config.in_a / 0xff;
-                       float out1 = (float)plugin->config.out_r / 0xff;
-                       float out2 = (float)plugin->config.out_g / 0xff;
-                       float out3 = (float)plugin->config.out_b / 0xff;
-                       float out4 = (float)plugin->config.out_a / 0xff;
-                       CREATE_GRADIENT(float, float, 4, 1.0)
-                       break;
-               }
-
-               case BC_YUV888:
-               {
-                       int in1, in2, in3, in4;
-                       int out1, out2, out3, out4;
-                       YUV::yuv.rgb_to_yuv_8(plugin->config.in_r,
-                               plugin->config.in_g,
-                               plugin->config.in_b,
-                               in1,
-                               in2,
-                               in3);
-                       in4 = plugin->config.in_a;
-                       YUV::yuv.rgb_to_yuv_8(plugin->config.out_r,
-                               plugin->config.out_g,
-                               plugin->config.out_b,
-                               out1,
-                               out2,
-                               out3);
-                       out4 = plugin->config.out_a;
-                       CREATE_GRADIENT(unsigned char, int, 3, 0xff)
-                       break;
-               }
-
-               case BC_YUVA8888:
-               {
-                       int in1, in2, in3, in4;
-                       int out1, out2, out3, out4;
-                       YUV::yuv.rgb_to_yuv_8(plugin->config.in_r,
-                               plugin->config.in_g,
-                               plugin->config.in_b,
-                               in1,
-                               in2,
-                               in3);
-                       in4 = plugin->config.in_a;
-                       YUV::yuv.rgb_to_yuv_8(plugin->config.out_r,
-                               plugin->config.out_g,
-                               plugin->config.out_b,
-                               out1,
-                               out2,
-                               out3);
-                       out4 = plugin->config.out_a;
-                       CREATE_GRADIENT(unsigned char, int, 4, 0xff)
-                       break;
-               }
+       switch( gradient_cmodel ) {
+       case BC_RGB888: {
+               int in1 = plugin->config.in_r;
+               int in2 = plugin->config.in_g;
+               int in3 = plugin->config.in_b;
+               int in4 = plugin->config.in_a;
+               int out1 = plugin->config.out_r;
+               int out2 = plugin->config.out_g;
+               int out3 = plugin->config.out_b;
+               int out4 = plugin->config.out_a;
+               CREATE_GRADIENT(unsigned char, int, 3, 0xff)
+               break; }
+
+       case BC_RGBA8888: {
+               int in1 = plugin->config.in_r;
+               int in2 = plugin->config.in_g;
+               int in3 = plugin->config.in_b;
+               int in4 = plugin->config.in_a;
+               int out1 = plugin->config.out_r;
+               int out2 = plugin->config.out_g;
+               int out3 = plugin->config.out_b;
+               int out4 = plugin->config.out_a;
+               CREATE_GRADIENT(unsigned char, int, 4, 0xff)
+               break; }
+
+       case BC_RGB_FLOAT: {
+               float in1 = (float)plugin->config.in_r / 0xff;
+               float in2 = (float)plugin->config.in_g / 0xff;
+               float in3 = (float)plugin->config.in_b / 0xff;
+               float in4 = (float)plugin->config.in_a / 0xff;
+               float out1 = (float)plugin->config.out_r / 0xff;
+               float out2 = (float)plugin->config.out_g / 0xff;
+               float out3 = (float)plugin->config.out_b / 0xff;
+               float out4 = (float)plugin->config.out_a / 0xff;
+               CREATE_GRADIENT(float, float, 3, 1.0)
+               break; }
+
+       case BC_RGBA_FLOAT: {
+               float in1 = (float)plugin->config.in_r / 0xff;
+               float in2 = (float)plugin->config.in_g / 0xff;
+               float in3 = (float)plugin->config.in_b / 0xff;
+               float in4 = (float)plugin->config.in_a / 0xff;
+               float out1 = (float)plugin->config.out_r / 0xff;
+               float out2 = (float)plugin->config.out_g / 0xff;
+               float out3 = (float)plugin->config.out_b / 0xff;
+               float out4 = (float)plugin->config.out_a / 0xff;
+               CREATE_GRADIENT(float, float, 4, 1.0)
+               break; }
+
+       case BC_YUV888: {
+               int in_r = plugin->config.in_r;
+               int in_g = plugin->config.in_g;
+               int in_b = plugin->config.in_b;
+               int in1, in2, in3, in4;
+               int out1, out2, out3, out4;
+               YUV::yuv.rgb_to_yuv_8(in_r,in_g,in_b, in1,in2,in3);
+               in4 = plugin->config.in_a;
+               int out_r = plugin->config.in_r;
+               int out_g = plugin->config.in_g;
+               int out_b = plugin->config.in_b;
+               YUV::yuv.rgb_to_yuv_8(out_r,out_g,out_b, out1,out2,out3);
+               out4 = plugin->config.out_a;
+               CREATE_GRADIENT(unsigned char, int, 3, 0xff)
+               break; }
+
+       case BC_YUVA8888: {
+               int in_r = plugin->config.in_r;
+               int in_g = plugin->config.in_g;
+               int in_b = plugin->config.in_b;
+               int in1, in2, in3, in4;
+               int out1, out2, out3, out4;
+               YUV::yuv.rgb_to_yuv_8(in_r,in_g,in_b, in1,in2,in3);
+               in4 = plugin->config.in_a;
+               int out_r = plugin->config.in_r;
+               int out_g = plugin->config.in_g;
+               int out_b = plugin->config.in_b;
+               YUV::yuv.rgb_to_yuv_8(out_r,out_g,out_b, out1,out2,out3);
+               out4 = plugin->config.out_a;
+               CREATE_GRADIENT(unsigned char, int, 4, 0xff)
+               break; }
        }
        }
-
-       if(r_table) free(r_table);
-       if(g_table) free(g_table);
-       if(b_table) free(b_table);
-       if(a_table) free(a_table);
 }
 
 
 }
 
 
-
-
-
-
 GradientServer::GradientServer(GradientMain *plugin,
 GradientServer::GradientServer(GradientMain *plugin,
-       int total_clients,
-       int total_packages)
+       int total_clients, int total_packages)
  : LoadServer(total_clients, total_packages)
 {
        this->plugin = plugin;
  : LoadServer(total_clients, total_packages)
 {
        this->plugin = plugin;
@@ -1369,8 +1126,7 @@ GradientServer::GradientServer(GradientMain *plugin,
 
 void GradientServer::init_packages()
 {
 
 void GradientServer::init_packages()
 {
-       for(int i = 0; i < get_total_packages(); i++)
-       {
+       for( int i = 0; i < get_total_packages(); i++ ) {
                GradientPackage *package = (GradientPackage*)get_package(i);
                package->y1 = plugin->input->get_h() *
                        i /
                GradientPackage *package = (GradientPackage*)get_package(i);
                package->y1 = plugin->input->get_h() *
                        i /
@@ -1391,7 +1147,3 @@ LoadPackage* GradientServer::new_package()
        return new GradientPackage;
 }
 
        return new GradientPackage;
 }
 
-
-
-
-