yuv colorspace/range + prefs, ffmpeg colorrange probe, x11 direct force colormodel...
[goodguy/history.git] / cinelerra-5.1 / plugins / gradient / gradient.C
index d4142ad9a80b4756a37bfb8cce6aed4b15cdb663..9b49f85c2770cf96b9c2e98bda86883d37e87f76 100644 (file)
@@ -2,21 +2,21 @@
 /*
  * CINELERRA
  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- * 
+ *
  */
 
 #include <math.h>
@@ -45,6 +45,12 @@ REGISTER_PLUGIN(GradientMain)
 
 
 GradientConfig::GradientConfig()
+{
+       reset();
+}
+
+void GradientConfig::reset()
+
 {
        angle = 0;
        in_radius = 0;
@@ -101,10 +107,10 @@ void GradientConfig::copy_from(GradientConfig &that)
        center_y = that.center_y;
 }
 
-void GradientConfig::interpolate(GradientConfig &prev, 
-       GradientConfig &next, 
-       long prev_frame, 
-       long next_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);
@@ -155,10 +161,10 @@ int GradientConfig::get_out_color()
 
 GradientWindow::GradientWindow(GradientMain *plugin)
  : PluginClientWindow(plugin,
-       350, 
-       290, 
-       350, 
-       290, 
+       350,
+       290,
+       350,
+       290,
        0)
 {
        this->plugin = plugin;
@@ -183,9 +189,9 @@ void GradientWindow::create_objects()
        BC_Title *title;
 
        add_subwindow(title = new BC_Title(x, y, _("Shape:")));
-       add_subwindow(shape = new GradientShape(plugin, 
-               this, 
-               x + title->get_w() + margin, 
+       add_subwindow(shape = new GradientShape(plugin,
+               this,
+               x + title->get_w() + margin,
                y));
        shape->create_objects();
        y += shape->get_h() + margin;
@@ -211,9 +217,11 @@ void GradientWindow::create_objects()
        BC_Title *title2;
        add_subwindow(title2 = new BC_Title(x, y, _("Outer radius:")));
 
+       add_subwindow(reset = new GradientReset(plugin, this, x, y+100));
+
        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;
 
@@ -225,7 +233,6 @@ void GradientWindow::create_objects()
        add_subwindow(in_color = new GradientInColorButton(plugin, this, x, y));
        y += COLOR_H + margin;
 
-
        add_subwindow(out_color = new GradientOutColorButton(plugin, this, x, y));
        x += MAX(in_color->get_w(), out_color->get_w()) + margin;
        y = y1;
@@ -241,18 +248,19 @@ void GradientWindow::create_objects()
        update_out_color();
        update_shape();
 
-       draw_3d_border(in_color_x - 2, 
-               in_color_y - 2, 
-               COLOR_W + 4, 
-               COLOR_H + 4, 
+       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, 
+       draw_3d_border(out_color_x - 2,
+               out_color_y - 2,
+               COLOR_W + 4,
+               COLOR_H + 4,
                1);
 
+
        show_window();
 }
 
@@ -296,6 +304,7 @@ void GradientWindow::update_shape()
                                y));
                }
        }
+       show_window();
 }
 
 
@@ -317,6 +326,12 @@ void GradientWindow::update_out_color()
        flash(out_color_x, out_color_y, COLOR_W, COLOR_H);
 }
 
+void GradientWindow::done_event(int result)
+{
+       in_color_thread->close_window();
+       out_color_thread->close_window();
+}
+
 
 
 
@@ -325,9 +340,9 @@ void GradientWindow::update_out_color()
 
 
 
-GradientShape::GradientShape(GradientMain *plugin, 
-       GradientWindow *gui, 
-       int x, 
+GradientShape::GradientShape(GradientMain *plugin,
+       GradientWindow *gui,
+       int x,
        int y)
  : BC_PopupMenu(x, y, 100, to_text(plugin->config.shape), 1)
 {
@@ -351,7 +366,7 @@ char* GradientShape::to_text(int shape)
 }
 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;
 }
@@ -443,7 +458,7 @@ char* GradientRate::to_text(int shape)
 }
 int GradientRate::from_text(char *text)
 {
-       if(!strcmp(text, to_text(GradientConfig::LINEAR))) 
+       if(!strcmp(text, to_text(GradientConfig::LINEAR)))
                return GradientConfig::LINEAR;
        if(!strcmp(text, to_text(GradientConfig::LOG)))
                return GradientConfig::LOG;
@@ -530,11 +545,24 @@ int GradientOutColorButton::handle_event()
        return 1;
 }
 
+GradientReset::GradientReset(GradientMain *plugin, GradientWindow *window, int x, int y)
+ : BC_GenericButton(x, y, _("Reset"))
+{
+       this->plugin = plugin;
+       this->window = window;
+}
 
+int GradientReset::handle_event()
+{
+       plugin->config.reset();
+       window->update_gui();
+       plugin->send_configure_change();
+       return 1;
+}
 
-GradientInColorThread::GradientInColorThread(GradientMain *plugin, 
+GradientInColorThread::GradientInColorThread(GradientMain *plugin,
        GradientWindow *window)
- : ColorThread(1, _("Inner color"))
+ : ColorPicker(1, _("Inner color"))
 {
        this->plugin = plugin;
        this->window = window;
@@ -546,7 +574,7 @@ int GradientInColorThread::handle_new_color(int output, int alpha)
        plugin->config.in_g = (output & 0xff00) >> 8;
        plugin->config.in_b = (output & 0xff);
        plugin->config.in_a = alpha;
-       
+
        window->lock_window("GradientInColorThread::handle_new_color");
        window->update_in_color();
        window->flush();
@@ -567,9 +595,9 @@ int GradientInColorThread::handle_new_color(int output, int alpha)
 
 
 
-GradientOutColorThread::GradientOutColorThread(GradientMain *plugin, 
+GradientOutColorThread::GradientOutColorThread(GradientMain *plugin,
        GradientWindow *window)
- : ColorThread(1, _("Outer color"))
+ : ColorPicker(1, _("Outer color"))
 {
        this->plugin = plugin;
        this->window = window;
@@ -612,7 +640,7 @@ int GradientOutColorThread::handle_new_color(int output, int alpha)
 GradientMain::GradientMain(PluginServer *server)
  : PluginVClient(server)
 {
-       
+
        need_reconfigure = 1;
        gradient = 0;
        engine = 0;
@@ -621,7 +649,7 @@ GradientMain::GradientMain(PluginServer *server)
 
 GradientMain::~GradientMain()
 {
-       
+
 
        if(gradient) delete gradient;
        if(engine) delete engine;
@@ -652,9 +680,9 @@ int GradientMain::process_buffer(VFrame *frame,
 
        int need_alpha = config.in_a != 0xff || config.out_a != 0xff;
        if(need_alpha)
-               read_frame(frame, 
-                       0, 
-                       start_position, 
+               read_frame(frame,
+                       0,
+                       start_position,
                        frame_rate,
                        get_use_opengl());
        if(get_use_opengl()) return run_opengl();
@@ -682,12 +710,9 @@ int GradientMain::process_buffer(VFrame *frame,
                gradient = 0;
        }
 
-       if(!gradient) gradient = new VFrame(0, 
-               -1,
-               input->get_w(),
-               input->get_h(),
-               gradient_cmodel,
-               -1);
+       if(!gradient)
+               gradient = new VFrame(input->get_w(), input->get_h(),
+                       gradient_cmodel, 0);
 
        if(!engine) engine = new GradientServer(this,
                get_project_smp() + 1,
@@ -698,17 +723,17 @@ int GradientMain::process_buffer(VFrame *frame,
        if(gradient->get_color_model() == output->get_color_model())
        {
                if(!overlayer) overlayer = new OverlayFrame(get_project_smp() + 1);
-               overlayer->overlay(output, 
+               overlayer->overlay(output,
                        gradient,
-                       0, 
-                       0, 
-                       input->get_w(), 
+                       0,
+                       0,
+                       input->get_w(),
+                       input->get_h(),
+                       0,
+                       0,
+                       input->get_w(),
                        input->get_h(),
-                       0, 
-                       0, 
-                       input->get_w(), 
-                       input->get_h(), 
-                       1.0, 
+                       1.0,
                        TRANSFER_NORMAL,
                        NEAREST_NEIGHBOR);
        }
@@ -720,32 +745,32 @@ int GradientMain::process_buffer(VFrame *frame,
 
 void GradientMain::update_gui()
 {
-       if(thread)
-       {
-               if(load_configuration())
-               {
-                       ((GradientWindow*)thread->window)->lock_window("GradientMain::update_gui");
-                       ((GradientWindow*)thread->window)->rate->set_text(GradientRate::to_text(config.rate));
-                       ((GradientWindow*)thread->window)->in_radius->update(config.in_radius);
-                       ((GradientWindow*)thread->window)->out_radius->update(config.out_radius);
-                       ((GradientWindow*)thread->window)->shape->set_text(GradientShape::to_text(config.shape));
-                       if(((GradientWindow*)thread->window)->angle)
-                               ((GradientWindow*)thread->window)->angle->update(config.angle);
-                       if(((GradientWindow*)thread->window)->center_x)
-                               ((GradientWindow*)thread->window)->center_x->update(config.center_x);
-                       if(((GradientWindow*)thread->window)->center_y)
-                               ((GradientWindow*)thread->window)->center_y->update(config.center_y);
-                       ((GradientWindow*)thread->window)->update_in_color();
-                       ((GradientWindow*)thread->window)->update_out_color();
-                       ((GradientWindow*)thread->window)->update_shape();
-                       ((GradientWindow*)thread->window)->unlock_window();
-                       ((GradientWindow*)thread->window)->in_color_thread->update_gui(config.get_in_color(), config.in_a);
-                       ((GradientWindow*)thread->window)->out_color_thread->update_gui(config.get_out_color(), config.out_a);
-               }
-       }
+       if( !thread ) return;
+       if( !load_configuration() ) return;
+       ((GradientWindow*)thread->window)->lock_window("GradientMain::update_gui");
+       GradientWindow *window = (GradientWindow *)thread->window;
+       window->update_gui();
+       window->unlock_window();
 }
 
-
+void GradientWindow::update_gui()
+{
+       GradientConfig &config = plugin->config;
+       rate->set_text(GradientRate::to_text(config.rate));
+       in_radius->update(config.in_radius);
+       out_radius->update(config.out_radius);
+       shape->set_text(GradientShape::to_text(config.shape));
+       if( angle ) angle->update(config.angle);
+       if( center_x ) center_x->update(config.center_x);
+       if( center_y ) center_y->update(config.center_y);
+       update_in_color();
+       update_out_color();
+       update_shape();
+       unlock_window();
+       in_color_thread->update_gui(config.get_in_color(), config.in_a);
+       out_color_thread->update_gui(config.get_out_color(), config.out_a);
+       lock_window("GradientWindow::update_gui");
+}
 
 
 void GradientMain::save_data(KeyFrame *keyframe)
@@ -836,7 +861,7 @@ int GradientMain::handle_opengl()
                "{\n"
                "       vec2 out_coord = gl_TexCoord[0].st;\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";
@@ -846,22 +871,22 @@ int GradientMain::handle_opengl()
                "       float mag = length(vec2(in_coord.x, in_coord.y));\n";
 
 // No clamp function in NVidia
-       const char *linear_rate = 
+       const char *linear_rate =
                "       mag = min(max(mag, in_radius), out_radius);\n"
                "       float opacity = (mag - in_radius) / radius_diff;\n";
 
 // NVidia warns about exp, but exp is in the GLSL spec.
-       const char *log_rate = 
+       const char *log_rate =
                "       mag = max(mag, in_radius);\n"
                "       float opacity = 1.0 - \n"
                "               exp(1.0 * -(mag - in_radius) / radius_diff);\n";
 
-       const char *square_rate = 
+       const char *square_rate =
                "       mag = min(max(mag, in_radius), out_radius);\n"
                "       float opacity = pow((mag - in_radius) / radius_diff, 2.0);\n"
                "       opacity = min(opacity, 1.0);\n";
 
-       const char *tail_frag = 
+       const char *tail_frag =
                "       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"
@@ -906,11 +931,11 @@ int GradientMain::handle_opengl()
        get_output()->init_screen();
        get_output()->bind_texture(0);
 
-       unsigned int frag = VFrame::make_shader(0, 
-               shader_stack[0], 
-               shader_stack[1], 
-               shader_stack[2], 
-               shader_stack[3], 
+       unsigned int frag = VFrame::make_shader(0,
+               shader_stack[0],
+               shader_stack[1],
+               shader_stack[2],
+               shader_stack[3],
                0);
 
        if(frag)
@@ -925,30 +950,30 @@ int GradientMain::handle_opengl()
                glUniform1f(glGetUniformLocation(frag, "half_h"), h / 2 / texture_h);
                if(config.shape == GradientConfig::LINEAR)
                {
-                       glUniform1f(glGetUniformLocation(frag, "center_x"), 
+                       glUniform1f(glGetUniformLocation(frag, "center_x"),
                                w / 2 / texture_w);
-                       glUniform1f(glGetUniformLocation(frag, "center_y"), 
+                       glUniform1f(glGetUniformLocation(frag, "center_y"),
                                h / 2 / texture_h);
                }
                else
                {
-                       glUniform1f(glGetUniformLocation(frag, "center_x"), 
+                       glUniform1f(glGetUniformLocation(frag, "center_x"),
                                (float)config.center_x * w / 100 / texture_w);
-                       glUniform1f(glGetUniformLocation(frag, "center_y"), 
+                       glUniform1f(glGetUniformLocation(frag, "center_y"),
                                (float)config.center_y * h / 100 / texture_h);
                }
                float gradient_size = hypotf(w / texture_w, h / texture_h);
-               glUniform1f(glGetUniformLocation(frag, "half_gradient_size"), 
+               glUniform1f(glGetUniformLocation(frag, "half_gradient_size"),
                        gradient_size / 2);
-               glUniform1f(glGetUniformLocation(frag, "sin_angle"), 
+               glUniform1f(glGetUniformLocation(frag, "sin_angle"),
                        sin(config.angle * (M_PI / 180)));
-               glUniform1f(glGetUniformLocation(frag, "cos_angle"), 
+               glUniform1f(glGetUniformLocation(frag, "cos_angle"),
                        cos(config.angle * (M_PI / 180)));
                float in_radius = (float)config.in_radius / 100 * gradient_size;
                glUniform1f(glGetUniformLocation(frag, "in_radius"), in_radius);
                float out_radius = (float)config.out_radius / 100 * gradient_size;
                glUniform1f(glGetUniformLocation(frag, "out_radius"), out_radius);
-               glUniform1f(glGetUniformLocation(frag, "radius_diff"), 
+               glUniform1f(glGetUniformLocation(frag, "radius_diff"),
                        out_radius - in_radius);
 
                switch(get_output()->get_color_model())
@@ -958,14 +983,14 @@ int GradientMain::handle_opengl()
                        {
                                float in1, in2, in3, in4;
                                float out1, out2, out3, out4;
-                               YUV::rgb_to_yuv_f((float)config.in_r / 0xff,
+                               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::rgb_to_yuv_f((float)config.out_r / 0xff,
+                               YUV::yuv.rgb_to_yuv_f((float)config.out_r / 0xff,
                                        (float)config.out_g / 0xff,
                                        (float)config.out_b / 0xff,
                                        out1,
@@ -976,20 +1001,20 @@ int GradientMain::handle_opengl()
                                out2 += 0.5;
                                out3 += 0.5;
                                out4 = (float)config.out_a / 0xff;
-                               glUniform4f(glGetUniformLocation(frag, "out_color"), 
+                               glUniform4f(glGetUniformLocation(frag, "out_color"),
                                        out1, out2, out3, out4);
-                               glUniform4f(glGetUniformLocation(frag, "in_color"), 
+                               glUniform4f(glGetUniformLocation(frag, "in_color"),
                                        in1, in2, in3, in4);
                                break;
                        }
 
                        default:
-                               glUniform4f(glGetUniformLocation(frag, "out_color"), 
+                               glUniform4f(glGetUniformLocation(frag, "out_color"),
                                        (float)config.out_r / 0xff,
                                        (float)config.out_g / 0xff,
                                        (float)config.out_b / 0xff,
                                        (float)config.out_a / 0xff);
-                               glUniform4f(glGetUniformLocation(frag, "in_color"), 
+                               glUniform4f(glGetUniformLocation(frag, "in_color"),
                                        (float)config.in_r / 0xff,
                                        (float)config.in_g / 0xff,
                                        (float)config.in_b / 0xff,
@@ -1001,7 +1026,7 @@ int GradientMain::handle_opengl()
        get_output()->draw_texture();
        glUseProgram(0);
        get_output()->set_opengl_state(VFrame::SCREEN);
-       
+
 #endif
        return 0;
 }
@@ -1034,7 +1059,7 @@ 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 opacity = 0.0;
@@ -1061,9 +1086,9 @@ static float calculate_opacity(float mag,
 
                case GradientConfig::SQUARE:
                        if(mag < in_radius)
-                               opacity = 0.0; 
+                               opacity = 0.0;
                        else
-                       if(mag >= out_radius) 
+                       if(mag >= out_radius)
                                opacity = 1.0;
                        else
                                opacity = powf((float)(mag - in_radius) /
@@ -1354,8 +1379,8 @@ void GradientUnit::process_package(LoadPackage *package)
 
 
 
-GradientServer::GradientServer(GradientMain *plugin, 
-       int total_clients, 
+GradientServer::GradientServer(GradientMain *plugin,
+       int total_clients,
        int total_packages)
  : LoadServer(total_clients, total_packages)
 {
@@ -1367,10 +1392,10 @@ void GradientServer::init_packages()
        for(int i = 0; i < get_total_packages(); i++)
        {
                GradientPackage *package = (GradientPackage*)get_package(i);
-               package->y1 = plugin->input->get_h() * 
-                       i / 
+               package->y1 = plugin->input->get_h() *
+                       i /
                        get_total_packages();
-               package->y2 = plugin->input->get_h() * 
+               package->y2 = plugin->input->get_h() *
                        (i + 1) /
                        get_total_packages();
        }