4 * Copyright (C) 2008-2019 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 REGISTER_PLUGIN(AlphaMain)
35 AlphaConfig::AlphaConfig()
40 void AlphaConfig::reset()
45 int AlphaConfig::equivalent(AlphaConfig &that)
50 void AlphaConfig::copy_from(AlphaConfig &that)
55 void AlphaConfig::interpolate(AlphaConfig &prev, AlphaConfig &next,
56 long prev_frame, long next_frame, long current_frame)
58 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
59 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
61 a = (prev.a * prev_scale + next.a * next_scale);
65 AlphaText::AlphaText(AlphaWindow *window, AlphaMain *plugin,
67 : BC_TumbleTextBox(window, (float)plugin->config.a,
68 (float)OPACITY_MIN, (float)OPACITY_MAX, x, y, xS(60), 2)
70 this->window = window;
71 this->plugin = plugin;
74 AlphaText::~AlphaText()
78 int AlphaText::handle_event()
80 float min = OPACITY_MIN, max = OPACITY_MAX;
81 float output = atof(get_text());
83 if(output > max) output = max;
84 else if(output < min) output = min;
85 plugin->config.a = output;
86 window->alpha_slider->update(plugin->config.a);
87 window->alpha_text->update(plugin->config.a);
88 plugin->send_configure_change();
92 AlphaSlider::AlphaSlider(AlphaWindow *window, AlphaMain *plugin,
94 : BC_FSlider(x, y, 0, w, w, OPACITY_MIN, OPACITY_MAX, plugin->config.a)
96 this->window = window;
97 this->plugin = plugin;
98 enable_show_value(0); // Hide caption
101 AlphaSlider::~AlphaSlider()
105 int AlphaSlider::handle_event()
107 plugin->config.a = get_value();
108 window->alpha_text->update(plugin->config.a);
109 plugin->send_configure_change();
113 AlphaClr::AlphaClr(AlphaWindow *window, AlphaMain *plugin, int x, int y)
114 : BC_Button(x, y, plugin->get_theme()->get_image_set("reset_button"))
116 this->window = window;
117 this->plugin = plugin;
119 AlphaClr::~AlphaClr()
122 int AlphaClr::handle_event()
124 plugin->config.reset();
126 plugin->send_configure_change();
131 #define ALPHA_W xS(420)
132 #define ALPHA_H yS(60)
134 AlphaWindow::AlphaWindow(AlphaMain *plugin)
135 : PluginClientWindow(plugin, ALPHA_W, ALPHA_H, ALPHA_W, ALPHA_H, 0)
137 this->plugin = plugin;
140 AlphaWindow::~AlphaWindow()
144 void AlphaWindow::create_objects()
146 int xs10 = xS(10), xs200 = xS(200);
148 int x = xs10, y = ys10;
149 int x2 = xS(80), x3 = xS(180);
150 int clr_x = get_w()-x - xS(22); // note: clrBtn_w = 22
155 add_subwindow(title = new BC_Title(x, y, _("Alpha:")));
156 alpha_text = new AlphaText(this, plugin, (x + x2), y);
157 alpha_text->create_objects();
158 add_subwindow(alpha_slider = new AlphaSlider(this, plugin, x3, y, xs200));
159 clr_x = x3 + alpha_slider->get_w() + x;
160 add_subwindow(alpha_clr = new AlphaClr(this, plugin, clr_x, y));
164 void AlphaWindow::update()
166 float alpha = plugin->config.a;
167 alpha_text->update(alpha);
168 alpha_slider->update(alpha);
172 AlphaMain::AlphaMain(PluginServer *server)
173 : PluginVClient(server)
177 AlphaMain::~AlphaMain()
181 const char* AlphaMain::plugin_title() { return N_("Alpha"); }
182 int AlphaMain::is_realtime() { return 1; }
184 NEW_WINDOW_MACRO(AlphaMain, AlphaWindow)
186 LOAD_CONFIGURATION_MACRO(AlphaMain, AlphaConfig)
188 int AlphaMain::is_synthesis()
194 int AlphaMain::process_buffer(VFrame *frame,
195 int64_t start_position,
198 load_configuration();
200 read_frame(frame, 0, start_position, frame_rate, get_use_opengl());
201 int w = frame->get_w(), h = frame->get_h();
203 #define MAIN_LOOP(type, components, is_yuv, max) do { \
204 if( components == 4 ) { \
205 for( int y=0; y<h; ++y ) { \
206 type *row = (type*)frame->get_rows()[y]; \
207 for( int x=0; x<w; ++x ) { \
213 else if( is_yuv ) { \
214 type ofs = (max+1)/2; \
215 for( int y=0; y<h; ++y ) { \
216 type *row = (type*)frame->get_rows()[y]; \
217 for( int x=0; x<w; ++x ) { \
218 row[0] = row[0] * a; \
219 row[1] = (row[1]-ofs) * a + ofs; \
220 row[2] = (row[2]-ofs) * a + ofs; \
226 for( int y=0; y<h; ++y ) { \
227 type *row = (type*)frame->get_rows()[y]; \
228 for( int x=0; x<w; ++x ) { \
239 switch( frame->get_color_model() ) {
240 case BC_RGB888: MAIN_LOOP(uint8_t, 3, 0, 0xff); break;
241 case BC_RGB_FLOAT: MAIN_LOOP(float, 3, 0, 1.0 ); break;
242 case BC_YUV888: MAIN_LOOP(uint8_t, 3, 1, 0xff); break;
243 case BC_RGBA8888: MAIN_LOOP(uint8_t, 4, 0, 0xff); break;
244 case BC_RGBA_FLOAT: MAIN_LOOP(float, 4, 0, 1.0 ); break;
245 case BC_YUVA8888: MAIN_LOOP(uint8_t, 4, 1, 0xff); break;
252 void AlphaMain::update_gui()
254 if( !thread ) return;
255 AlphaWindow *window = (AlphaWindow*)thread->window;
256 if( !window ) return;
257 if( !load_configuration() ) return;
258 window->lock_window("AlphaMain::update_gui");
260 window->unlock_window();
264 void AlphaMain::save_data(KeyFrame *keyframe)
267 output.set_shared_output(keyframe->xbuf);
268 output.tag.set_title("ALPHA");
269 output.tag.set_property("A", config.a);
271 output.terminate_string();
274 void AlphaMain::read_data(KeyFrame *keyframe)
277 input.set_shared_input(keyframe->xbuf);
280 while( !(result = input.read_tag()) ) {
281 if( input.tag.title_is("ALPHA") ) {
282 config.a = input.tag.get_property("A", config.a);