1 #include "bcdisplayinfo.h"
7 #include "plugincolors.h"
8 #include "pluginvclient.h"
15 #define _(String) gettext(String)
16 #define gettext_noop(String) String
17 #define N_(String) gettext_noop (String)
20 class InvertVideoEffect;
23 class InvertVideoConfig
28 void copy_from(InvertVideoConfig &src);
29 int equivalent(InvertVideoConfig &src);
30 void interpolate(InvertVideoConfig &prev,
31 InvertVideoConfig &next,
39 class InvertVideoEnable : public BC_CheckBox
42 InvertVideoEnable(InvertVideoEffect *plugin, int *output, int x, int y, char *text);
44 InvertVideoEffect *plugin;
48 class InvertVideoWindow : public BC_Window
51 InvertVideoWindow(InvertVideoEffect *plugin, int x, int y);
52 void create_objects();
54 InvertVideoEnable *r, *g, *b, *a;
55 InvertVideoEffect *plugin;
58 PLUGIN_THREAD_HEADER(InvertVideoEffect, InvertVideoThread, InvertVideoWindow)
60 class InvertVideoEffect : public PluginVClient
63 InvertVideoEffect(PluginServer *server);
65 int process_realtime(VFrame *input, VFrame *output);
71 void save_data(KeyFrame *keyframe);
72 void read_data(KeyFrame *keyframe);
77 int load_configuration();
79 InvertVideoConfig config;
80 InvertVideoThread *thread;
88 REGISTER_PLUGIN(InvertVideoEffect)
96 InvertVideoConfig::InvertVideoConfig()
104 void InvertVideoConfig::copy_from(InvertVideoConfig &src)
112 int InvertVideoConfig::equivalent(InvertVideoConfig &src)
120 void InvertVideoConfig::interpolate(InvertVideoConfig &prev,
121 InvertVideoConfig &next,
135 InvertVideoEnable::InvertVideoEnable(InvertVideoEffect *plugin, int *output, int x, int y, char *text)
136 : BC_CheckBox(x, y, *output, text)
138 this->plugin = plugin;
139 this->output = output;
141 int InvertVideoEnable::handle_event()
143 *output = get_value();
144 plugin->send_configure_change();
152 InvertVideoWindow::InvertVideoWindow(InvertVideoEffect *plugin, int x, int y)
153 : BC_Window(plugin->gui_string,
164 this->plugin = plugin;
167 void InvertVideoWindow::create_objects()
170 add_subwindow(r = new InvertVideoEnable(plugin, &plugin->config.r, x, y, _("Invert R")));
172 add_subwindow(g = new InvertVideoEnable(plugin, &plugin->config.g, x, y, _("Invert G")));
174 add_subwindow(b = new InvertVideoEnable(plugin, &plugin->config.b, x, y, _("Invert B")));
176 add_subwindow(a = new InvertVideoEnable(plugin, &plugin->config.a, x, y, _("Invert A")));
182 int InvertVideoWindow::close_event()
184 // Set result to 1 to indicate a client side close
193 PLUGIN_THREAD_OBJECT(InvertVideoEffect, InvertVideoThread, InvertVideoWindow)
200 InvertVideoEffect::InvertVideoEffect(PluginServer *server)
201 : PluginVClient(server)
203 PLUGIN_CONSTRUCTOR_MACRO
205 InvertVideoEffect::~InvertVideoEffect()
207 PLUGIN_DESTRUCTOR_MACRO
209 int InvertVideoEffect::is_realtime()
214 char* InvertVideoEffect::plugin_title()
216 return _("Invert Video");
219 NEW_PICON_MACRO(InvertVideoEffect)
220 SHOW_GUI_MACRO(InvertVideoEffect, InvertVideoThread)
221 RAISE_WINDOW_MACRO(InvertVideoEffect)
222 SET_STRING_MACRO(InvertVideoEffect)
223 LOAD_CONFIGURATION_MACRO(InvertVideoEffect, InvertVideoConfig)
225 void InvertVideoEffect::update_gui()
229 thread->window->lock_window();
230 load_configuration();
231 thread->window->r->update(config.r);
232 thread->window->g->update(config.g);
233 thread->window->b->update(config.b);
234 thread->window->a->update(config.a);
235 thread->window->unlock_window();
239 int InvertVideoEffect::load_defaults()
241 char directory[BCTEXTLEN];
242 sprintf(directory, "%sinvertvideo.rc", BCASTDIR);
243 defaults = new Defaults(directory);
245 config.r = defaults->get("R", config.r);
246 config.g = defaults->get("G", config.g);
247 config.b = defaults->get("B", config.b);
248 config.a = defaults->get("A", config.a);
252 int InvertVideoEffect::save_defaults()
254 defaults->update("R", config.r);
255 defaults->update("G", config.g);
256 defaults->update("B", config.b);
257 defaults->update("A", config.a);
262 void InvertVideoEffect::save_data(KeyFrame *keyframe)
265 output.set_shared_string(keyframe->data, MESSAGESIZE);
266 output.tag.set_title("INVERTVIDEO");
267 output.tag.set_property("R", config.r);
268 output.tag.set_property("G", config.g);
269 output.tag.set_property("B", config.b);
270 output.tag.set_property("A", config.a);
272 output.terminate_string();
275 void InvertVideoEffect::read_data(KeyFrame *keyframe)
278 input.set_shared_string(keyframe->data, strlen(keyframe->data));
279 while(!input.read_tag())
281 if(input.tag.title_is("INVERTVIDEO"))
283 config.r = input.tag.get_property("R", config.r);
284 config.g = input.tag.get_property("G", config.g);
285 config.b = input.tag.get_property("B", config.b);
286 config.a = input.tag.get_property("A", config.a);
292 #define INVERT_MACRO(type, components, max) \
294 for(int i = 0; i < input->get_h(); i++) \
296 type *in_row = (type*)input->get_rows()[i]; \
297 type *out_row = (type*)output->get_rows()[i]; \
299 for(int j = 0; j < w; j++) \
301 if(config.r) out_row[0] = max - in_row[0]; \
302 if(config.g) out_row[1] = max - in_row[1]; \
303 if(config.b) out_row[2] = max - in_row[2]; \
304 if(components == 4) \
305 if(config.a) out_row[3] = max - in_row[3]; \
307 in_row += components; \
308 out_row += components; \
313 int InvertVideoEffect::process_realtime(VFrame *input, VFrame *output)
315 load_configuration();
317 if(!config.r && !config.g && !config.b && !config.a)
319 if(input->get_rows()[0] != output->get_rows()[0])
320 output->copy_from(input);
324 int w = input->get_w();
326 switch(input->get_color_model())
330 INVERT_MACRO(unsigned char, 3, 0xff)
334 INVERT_MACRO(unsigned char, 4, 0xff)
338 INVERT_MACRO(uint16_t, 3, 0xffff)
340 case BC_RGBA16161616:
341 case BC_YUVA16161616:
342 INVERT_MACRO(uint16_t, 4, 0xffff)