#include "theme.h"
#include "vframe.h"
-
-
-
REGISTER_PLUGIN(GradientMain)
-
-
-
-
-
GradientConfig::GradientConfig()
{
reset();
}
void GradientConfig::reset()
-
{
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;
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);
-
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);
return result;
}
-
-
-
-
-
-
-
-
-
-
#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;
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;
}
+
void GradientWindow::create_objects()
{
int margin = plugin->get_theme()->widget_border;
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;
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;
- int x1 = x;
- int y1 = y;
-
+ int x1 = x, y1 = y;
BC_Title *title1;
add_subwindow(title1 = new BC_Title(x, y, _("Inner radius:")));
-
y += BC_Slider::get_span(0) + margin;
-
BC_Title *title2;
add_subwindow(title2 = new BC_Title(x, y, _("Outer radius:")));
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(out_radius = new GradientOutRadius(plugin, x, y));
y += out_radius->get_h() + margin;
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();
}
{
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));
}
}
- 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,
- 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_y_title->get_w() + 10,
- y));
+ x + center_y_title->get_w() + 10, y));
}
}
show_window();
}
-
-
-
void GradientWindow::update_in_color()
{
//printf("GradientWindow::update_in_color 1 %08x\n", plugin->config.get_in_color());
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;
}
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)
{
- if(!strcmp(text, to_text(GradientConfig::LINEAR)))
+ if( !strcmp(text, to_text(GradientConfig::LINEAR)) )
return GradientConfig::LINEAR;
return GradientConfig::RADIAL;
}
}
-
-
GradientCenterX::GradientCenterX(GradientMain *plugin, int x, int y)
: BC_FPot(x, y, plugin->config.center_x, 0, 100)
{
}
-
GradientCenterY::GradientCenterY(GradientMain *plugin, int x, int y)
: BC_FPot(x, y, plugin->config.center_y, 0, 100)
{
}
-
-
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;
}
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;
}
}
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)
{
- if(!strcmp(text, to_text(GradientConfig::LINEAR)))
+ if( !strcmp(text, to_text(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;
}
}
-
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;
}
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;
}
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;
}
-
GradientOutColorThread::GradientOutColorThread(GradientMain *plugin,
GradientWindow *window)
: ColorPicker(1, _("Outer color"))
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;
}
-
-
-
-
-
-
-
-
-
-
GradientMain::GradientMain(PluginServer *server)
: PluginVClient(server)
{
gradient = 0;
engine = 0;
overlayer = 0;
+ table = 0;
+ table_size = 0;
}
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"); }
{
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;
- 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();
- 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;
}
- if(!gradient)
+ if( !gradient )
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
- 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;
}
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);
}
}
}
#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"
"\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 =
- " 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 =
- " 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 =
" 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";
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;
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();
- 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);
- 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);
- 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;
- 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; }
- default:
+ default: {
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"),
- (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; }
}
}
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;
- 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;
}
-#define CREATE_GRADIENT(type, temp, components, max) \
-{ \
+#define CREATE_GRADIENT(type, temp, components, max) { \
/* 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]; \
- \
- 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 */ \
- 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 */ \
- \
- 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 */ \
- 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; \
} \
} \
}
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 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;
- 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();
- 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,
- int total_clients,
- int total_packages)
+ int total_clients, int total_packages)
: LoadServer(total_clients, total_packages)
{
this->plugin = plugin;
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 /
return new GradientPackage;
}
-
-
-
-