/*
* 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"
#include "guicast.h"
#include "language.h"
#include "loadbalance.h"
-#include "cicolors.h"
+#include "bccolors.h"
#include "playback3d.h"
#include "pluginvclient.h"
#include "vframe.h"
{
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;
};
HueUnit(HueEffect *plugin, HueEngine *server);
void process_package(LoadPackage *package);
HueEffect *plugin;
- YUV yuv;
};
class HueEffect : public PluginVClient
public:
HueEffect(PluginServer *server);
~HueEffect();
-
-
+
+
PLUGIN_CLASS_MEMBERS(HueConfig);
int process_buffer(VFrame *frame,
int64_t start_position,
{
hue = saturation = value = 0;
}
-
+
void HueConfig::copy_from(HueConfig &src)
{
hue = src.hue;
}
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);
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;
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;
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;
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;
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, \
: PluginVClient(server)
{
engine = 0;
-
+
}
HueEffect::~HueEffect()
{
-
+
if(engine) delete engine;
}
{
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;
}
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)
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"
"}\n";
- const char *yuv_frag =
+ const char *yuv_frag =
"uniform sampler2D tex;\n"
"uniform float h_offset;\n"
"uniform float s_offset;\n"
" 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"
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();