dynamic keyframes, textbox rework, andrea ffmpeg.opts, perpetual chkpt undo, lv2...
[goodguy/history.git] / cinelerra-5.1 / plugins / huesaturation / huesaturation.C
index a574e905837506c8d8445426297089d7c3b73313..727f54f26d28b5a12dee0925d12a454e7565b301 100644 (file)
@@ -2,23 +2,24 @@
 /*
  * 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 "bccolors.h"
 #include "bcdisplayinfo.h"
 #include "clip.h"
 #include "bchash.h"
@@ -26,7 +27,7 @@
 #include "guicast.h"
 #include "language.h"
 #include "loadbalance.h"
-#include "cicolors.h"
+#include "bccolors.h"
 #include "playback3d.h"
 #include "pluginvclient.h"
 #include "vframe.h"
@@ -53,13 +54,13 @@ class HueConfig
 {
 public:
        HueConfig();
-       
+
        void copy_from(HueConfig &src);
        int equivalent(HueConfig &src);
-       void interpolate(HueConfig &prev, 
-               HueConfig &next, 
-               long prev_frame, 
-               long next_frame, 
+       void interpolate(HueConfig &prev,
+               HueConfig &next,
+               long prev_frame,
+               long next_frame,
                long current_frame);
        float hue, saturation, value;
 };
@@ -128,7 +129,6 @@ public:
        HueUnit(HueEffect *plugin, HueEngine *server);
        void process_package(LoadPackage *package);
        HueEffect *plugin;
-       YUV yuv;
 };
 
 class HueEffect : public PluginVClient
@@ -136,8 +136,8 @@ class HueEffect : public PluginVClient
 public:
        HueEffect(PluginServer *server);
        ~HueEffect();
-       
-       
+
+
        PLUGIN_CLASS_MEMBERS(HueConfig);
        int process_buffer(VFrame *frame,
                int64_t start_position,
@@ -175,7 +175,7 @@ HueConfig::HueConfig()
 {
        hue = saturation = value = 0;
 }
-       
+
 void HueConfig::copy_from(HueConfig &src)
 {
        hue = src.hue;
@@ -184,14 +184,14 @@ void HueConfig::copy_from(HueConfig &src)
 }
 int HueConfig::equivalent(HueConfig &src)
 {
-       return EQUIV(hue, src.hue) && 
-               EQUIV(saturation, src.saturation) && 
+       return EQUIV(hue, src.hue) &&
+               EQUIV(saturation, src.saturation) &&
                EQUIV(value, src.value);
 }
-void HueConfig::interpolate(HueConfig &prev, 
-       HueConfig &next, 
-       long prev_frame, 
-       long next_frame, 
+void HueConfig::interpolate(HueConfig &prev,
+       HueConfig &next,
+       long prev_frame,
+       long next_frame,
        long current_frame)
 {
        double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
@@ -210,13 +210,13 @@ void HueConfig::interpolate(HueConfig &prev,
 
 
 HueSlider::HueSlider(HueEffect *plugin, int x, int y, int w)
- : BC_FSlider(x, 
+ : BC_FSlider(x,
                        y,
                        0,
-                       w, 
-                       w, 
-                       (float)MINHUE, 
-                       (float)MAXHUE, 
+                       w,
+                       w,
+                       (float)MINHUE,
+                       (float)MAXHUE,
                        plugin->config.hue)
 {
        this->plugin = plugin;
@@ -235,13 +235,13 @@ int HueSlider::handle_event()
 
 
 SaturationSlider::SaturationSlider(HueEffect *plugin, int x, int y, int w)
- : BC_FSlider(x, 
+ : BC_FSlider(x,
                        y,
                        0,
-                       w, 
-                       w, 
-                       (float)MINSATURATION, 
-                       (float)MAXSATURATION, 
+                       w,
+                       w,
+                       (float)MINSATURATION,
+                       (float)MAXSATURATION,
                        plugin->config.saturation)
 {
        this->plugin = plugin;
@@ -255,7 +255,7 @@ int SaturationSlider::handle_event()
 
 char* SaturationSlider::get_caption()
 {
-       float fraction = ((float)plugin->config.saturation - MINSATURATION) / 
+       float fraction = ((float)plugin->config.saturation - MINSATURATION) /
                MAXSATURATION;;
        sprintf(string, "%0.4f", fraction);
        return string;
@@ -268,13 +268,13 @@ char* SaturationSlider::get_caption()
 
 
 ValueSlider::ValueSlider(HueEffect *plugin, int x, int y, int w)
- : BC_FSlider(x, 
+ : BC_FSlider(x,
                        y,
                        0,
-                       w, 
-                       w, 
-                       (float)MINVALUE, 
-                       (float)MAXVALUE, 
+                       w,
+                       w,
+                       (float)MINVALUE,
+                       (float)MAXVALUE,
                        plugin->config.value)
 {
        this->plugin = plugin;
@@ -399,9 +399,9 @@ HueUnit::HueUnit(HueEffect *plugin, HueEngine *server)
                                u = (int)in_row[1]; \
                                v = (int)in_row[2]; \
                                if(max == 0xffff) \
-                                       yuv.yuv_to_rgb_16(r_i, g_i, b_i, y, u, v); \
+                                       YUV::yuv.yuv_to_rgb_16(r_i, g_i, b_i, y, u, v); \
                                else \
-                                       yuv.yuv_to_rgb_8(r_i, g_i, b_i, y, u, v); \
+                                       YUV::yuv.yuv_to_rgb_8(r_i, g_i, b_i, y, u, v); \
                                HSV::rgb_to_hsv((float)r_i / max, \
                                        (float)g_i / max, \
                                        (float)b_i / max, \
@@ -526,11 +526,11 @@ HueEffect::HueEffect(PluginServer *server)
  : PluginVClient(server)
 {
        engine = 0;
-       
+
 }
 HueEffect::~HueEffect()
 {
-       
+
        if(engine) delete engine;
 }
 
@@ -540,12 +540,12 @@ int HueEffect::process_buffer(VFrame *frame,
 {
        load_configuration();
 
-       read_frame(frame, 
-               0, 
-               start_position, 
+       read_frame(frame,
+               0,
+               start_position,
                frame_rate,
                get_use_opengl());
-       
+
 
        this->input = frame;
        this->output = frame;
@@ -562,13 +562,13 @@ int HueEffect::process_buffer(VFrame *frame,
                }
 
                if(!engine) engine = new HueEngine(this, PluginClient::smp + 1);
-               
+
                engine->process_packages();
        }
        return 0;
 }
 
-const char* HueEffect::plugin_title() { return _("Hue saturation"); }
+const char* HueEffect::plugin_title() { return N_("Hue saturation"); }
 int HueEffect::is_realtime() { return 1; }
 
 NEW_WINDOW_MACRO(HueEffect, HueWindow)
@@ -578,7 +578,7 @@ LOAD_CONFIGURATION_MACRO(HueEffect, HueConfig)
 void HueEffect::save_data(KeyFrame *keyframe)
 {
        FileXML output;
-       output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
+       output.set_shared_output(keyframe->xbuf);
        output.tag.set_title("HUESATURATION");
        output.tag.set_property("HUE", config.hue);
        output.tag.set_property("SATURATION", config.saturation);
@@ -592,7 +592,7 @@ void HueEffect::save_data(KeyFrame *keyframe)
 void HueEffect::read_data(KeyFrame *keyframe)
 {
        FileXML input;
-       input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data()));
+       input.set_shared_input(keyframe->xbuf);
        while(!input.read_tag())
        {
                if(input.tag.title_is("HUESATURATION"))
@@ -619,7 +619,7 @@ void HueEffect::update_gui()
 int HueEffect::handle_opengl()
 {
 #ifdef HAVE_GL
-       const char *yuv_saturation_frag = 
+       const char *yuv_saturation_frag =
                "uniform sampler2D tex;\n"
                "uniform float s_offset;\n"
                "uniform float v_offset;\n"
@@ -635,7 +635,7 @@ int HueEffect::handle_opengl()
                "}\n";
 
 
-       const char *yuv_frag = 
+       const char *yuv_frag =
                "uniform sampler2D tex;\n"
                "uniform float h_offset;\n"
                "uniform float s_offset;\n"
@@ -655,7 +655,7 @@ int HueEffect::handle_opengl()
                "       gl_FragColor = pixel;\n"
                "}\n";
 
-       const char *rgb_frag = 
+       const char *rgb_frag =
                "uniform sampler2D tex;\n"
                "uniform float h_offset;\n"
                "uniform float s_offset;\n"
@@ -677,38 +677,26 @@ int HueEffect::handle_opengl()
        get_output()->to_texture();
        get_output()->enable_opengl();
 
-       unsigned int frag_shader = 0;
-       switch(get_output()->get_color_model())
-       {
-               case BC_YUV888:
-               case BC_YUVA8888:
-// This is a lousy approximation but good enough for the masker.
-                       if(EQUIV(config.hue, 0))
-                               frag_shader = VFrame::make_shader(0,
-                                       yuv_saturation_frag,
-                                       0);
-                       else
-                               frag_shader = VFrame::make_shader(0,
-                                       yuv_frag,
-                                       0);
-                       break;
-               default:
-                       frag_shader = VFrame::make_shader(0,
-                               rgb_frag,
-                               0);
-                       break;
-       }
-
-
-       if(frag_shader > 0) 
-       {
-               glUseProgram(frag_shader);
-               glUniform1i(glGetUniformLocation(frag_shader, "tex"), 0);
-               glUniform1f(glGetUniformLocation(frag_shader, "h_offset"), config.hue);
-               glUniform1f(glGetUniformLocation(frag_shader, "s_offset"), 
+       const char *shader_stack[16];
+       memset(shader_stack,0, sizeof(shader_stack));
+       int current_shader = 0;
+
+       int need_color_matrix = BC_CModels::is_yuv(get_output()->get_color_model()) ? 1 : 0;
+       if( need_color_matrix ) shader_stack[current_shader++] = bc_gl_colors;
+       shader_stack[current_shader++] = !need_color_matrix ? rgb_frag :
+               EQUIV(config.hue, 0) ? yuv_saturation_frag: yuv_frag ;
+
+       shader_stack[current_shader] = 0;
+        unsigned int shader = VFrame::make_shader(shader_stack);
+       if(shader > 0) {
+               glUseProgram(shader);
+               glUniform1i(glGetUniformLocation(shader, "tex"), 0);
+               glUniform1f(glGetUniformLocation(shader, "h_offset"), config.hue);
+               glUniform1f(glGetUniformLocation(shader, "s_offset"),
                        ((float)config.saturation - MINSATURATION) / MAXSATURATION);
-               glUniform1f(glGetUniformLocation(frag_shader, "v_offset"), 
+               glUniform1f(glGetUniformLocation(shader, "v_offset"),
                        ((float)config.value - MINVALUE) / MAXVALUE);
+               if( need_color_matrix ) BC_GL_COLORS(shader);
        }
 
        get_output()->init_screen();