1 #include "bcdisplayinfo.h"
8 #include "../colors/plugincolors.h"
9 #include "pluginvclient.h"
17 class InvertVideoEffect;
20 class InvertVideoConfig
25 void copy_from(InvertVideoConfig &src);
26 int equivalent(InvertVideoConfig &src);
27 void interpolate(InvertVideoConfig &prev,
28 InvertVideoConfig &next,
36 class InvertVideoEnable : public BC_CheckBox
39 InvertVideoEnable(InvertVideoEffect *plugin, int *output, int x, int y, char *text);
41 InvertVideoEffect *plugin;
45 class InvertVideoWindow : public BC_Window
48 InvertVideoWindow(InvertVideoEffect *plugin, int x, int y);
49 void create_objects();
51 InvertVideoEnable *r, *g, *b, *a;
52 InvertVideoEffect *plugin;
55 PLUGIN_THREAD_HEADER(InvertVideoEffect, InvertVideoThread, InvertVideoWindow)
57 class InvertVideoEffect : public PluginVClient
60 InvertVideoEffect(PluginServer *server);
62 int process_realtime(VFrame *input, VFrame *output);
68 void save_data(KeyFrame *keyframe);
69 void read_data(KeyFrame *keyframe);
74 int load_configuration();
76 InvertVideoConfig config;
77 InvertVideoThread *thread;
85 REGISTER_PLUGIN(InvertVideoEffect)
93 InvertVideoConfig::InvertVideoConfig()
101 void InvertVideoConfig::copy_from(InvertVideoConfig &src)
109 int InvertVideoConfig::equivalent(InvertVideoConfig &src)
117 void InvertVideoConfig::interpolate(InvertVideoConfig &prev,
118 InvertVideoConfig &next,
132 InvertVideoEnable::InvertVideoEnable(InvertVideoEffect *plugin, int *output, int x, int y, char *text)
133 : BC_CheckBox(x, y, *output, text)
135 this->plugin = plugin;
136 this->output = output;
138 int InvertVideoEnable::handle_event()
140 *output = get_value();
141 plugin->send_configure_change();
149 InvertVideoWindow::InvertVideoWindow(InvertVideoEffect *plugin, int x, int y)
150 : BC_Window(plugin->gui_string,
161 this->plugin = plugin;
164 void InvertVideoWindow::create_objects()
167 add_subwindow(r = new InvertVideoEnable(plugin, &plugin->config.r, x, y, _("Invert R")));
169 add_subwindow(g = new InvertVideoEnable(plugin, &plugin->config.g, x, y, _("Invert G")));
171 add_subwindow(b = new InvertVideoEnable(plugin, &plugin->config.b, x, y, _("Invert B")));
173 add_subwindow(a = new InvertVideoEnable(plugin, &plugin->config.a, x, y, _("Invert A")));
179 WINDOW_CLOSE_EVENT(InvertVideoWindow)
185 PLUGIN_THREAD_OBJECT(InvertVideoEffect, InvertVideoThread, InvertVideoWindow)
192 InvertVideoEffect::InvertVideoEffect(PluginServer *server)
193 : PluginVClient(server)
195 PLUGIN_CONSTRUCTOR_MACRO
197 InvertVideoEffect::~InvertVideoEffect()
199 PLUGIN_DESTRUCTOR_MACRO
202 char* InvertVideoEffect::plugin_title() { return N_("Invert Video"); }
203 int InvertVideoEffect::is_realtime() { return 1; }
205 NEW_PICON_MACRO(InvertVideoEffect)
206 SHOW_GUI_MACRO(InvertVideoEffect, InvertVideoThread)
207 RAISE_WINDOW_MACRO(InvertVideoEffect)
208 SET_STRING_MACRO(InvertVideoEffect)
209 LOAD_CONFIGURATION_MACRO(InvertVideoEffect, InvertVideoConfig)
211 void InvertVideoEffect::update_gui()
215 thread->window->lock_window();
216 load_configuration();
217 thread->window->r->update(config.r);
218 thread->window->g->update(config.g);
219 thread->window->b->update(config.b);
220 thread->window->a->update(config.a);
221 thread->window->unlock_window();
225 int InvertVideoEffect::load_defaults()
227 char directory[BCTEXTLEN];
228 sprintf(directory, "%sinvertvideo.rc", BCASTDIR);
229 defaults = new Defaults(directory);
231 config.r = defaults->get("R", config.r);
232 config.g = defaults->get("G", config.g);
233 config.b = defaults->get("B", config.b);
234 config.a = defaults->get("A", config.a);
238 int InvertVideoEffect::save_defaults()
240 defaults->update("R", config.r);
241 defaults->update("G", config.g);
242 defaults->update("B", config.b);
243 defaults->update("A", config.a);
248 void InvertVideoEffect::save_data(KeyFrame *keyframe)
251 output.set_shared_string(keyframe->data, MESSAGESIZE);
252 output.tag.set_title("INVERTVIDEO");
253 output.tag.set_property("R", config.r);
254 output.tag.set_property("G", config.g);
255 output.tag.set_property("B", config.b);
256 output.tag.set_property("A", config.a);
258 output.terminate_string();
261 void InvertVideoEffect::read_data(KeyFrame *keyframe)
264 input.set_shared_string(keyframe->data, strlen(keyframe->data));
265 while(!input.read_tag())
267 if(input.tag.title_is("INVERTVIDEO"))
269 config.r = input.tag.get_property("R", config.r);
270 config.g = input.tag.get_property("G", config.g);
271 config.b = input.tag.get_property("B", config.b);
272 config.a = input.tag.get_property("A", config.a);
278 #define INVERT_MACRO(type, components, max) \
280 for(int i = 0; i < input->get_h(); i++) \
282 type *in_row = (type*)input->get_rows()[i]; \
283 type *out_row = (type*)output->get_rows()[i]; \
285 for(int j = 0; j < w; j++) \
287 if(config.r) out_row[0] = max - in_row[0]; \
288 if(config.g) out_row[1] = max - in_row[1]; \
289 if(config.b) out_row[2] = max - in_row[2]; \
290 if(components == 4) \
291 if(config.a) out_row[3] = max - in_row[3]; \
293 in_row += components; \
294 out_row += components; \
299 int InvertVideoEffect::process_realtime(VFrame *input, VFrame *output)
301 load_configuration();
303 if(!config.r && !config.g && !config.b && !config.a)
305 if(input->get_rows()[0] != output->get_rows()[0])
306 output->copy_from(input);
310 int w = input->get_w();
312 switch(input->get_color_model())
315 INVERT_MACRO(float, 3, 1.0)
319 INVERT_MACRO(unsigned char, 3, 0xff)
322 INVERT_MACRO(float, 4, 1.0)
326 INVERT_MACRO(unsigned char, 4, 0xff)
330 INVERT_MACRO(uint16_t, 3, 0xffff)
332 case BC_RGBA16161616:
333 case BC_YUVA16161616:
334 INVERT_MACRO(uint16_t, 4, 0xffff)