1 #include "bcdisplayinfo.h"
8 #include "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_buffer(VFrame *frame,
63 int64_t start_position,
70 void save_data(KeyFrame *keyframe);
71 void read_data(KeyFrame *keyframe);
76 int load_configuration();
78 InvertVideoConfig config;
79 InvertVideoThread *thread;
87 REGISTER_PLUGIN(InvertVideoEffect)
95 InvertVideoConfig::InvertVideoConfig()
103 void InvertVideoConfig::copy_from(InvertVideoConfig &src)
111 int InvertVideoConfig::equivalent(InvertVideoConfig &src)
119 void InvertVideoConfig::interpolate(InvertVideoConfig &prev,
120 InvertVideoConfig &next,
134 InvertVideoEnable::InvertVideoEnable(InvertVideoEffect *plugin, int *output, int x, int y, char *text)
135 : BC_CheckBox(x, y, *output, text)
137 this->plugin = plugin;
138 this->output = output;
140 int InvertVideoEnable::handle_event()
142 *output = get_value();
143 plugin->send_configure_change();
151 InvertVideoWindow::InvertVideoWindow(InvertVideoEffect *plugin, int x, int y)
152 : BC_Window(plugin->gui_string,
163 this->plugin = plugin;
166 void InvertVideoWindow::create_objects()
169 add_subwindow(r = new InvertVideoEnable(plugin, &plugin->config.r, x, y, _("Invert R")));
171 add_subwindow(g = new InvertVideoEnable(plugin, &plugin->config.g, x, y, _("Invert G")));
173 add_subwindow(b = new InvertVideoEnable(plugin, &plugin->config.b, x, y, _("Invert B")));
175 add_subwindow(a = new InvertVideoEnable(plugin, &plugin->config.a, x, y, _("Invert A")));
181 WINDOW_CLOSE_EVENT(InvertVideoWindow)
187 PLUGIN_THREAD_OBJECT(InvertVideoEffect, InvertVideoThread, InvertVideoWindow)
194 InvertVideoEffect::InvertVideoEffect(PluginServer *server)
195 : PluginVClient(server)
197 PLUGIN_CONSTRUCTOR_MACRO
199 InvertVideoEffect::~InvertVideoEffect()
201 PLUGIN_DESTRUCTOR_MACRO
204 char* InvertVideoEffect::plugin_title() { return N_("Invert Video"); }
205 int InvertVideoEffect::is_realtime() { return 1; }
207 NEW_PICON_MACRO(InvertVideoEffect)
208 SHOW_GUI_MACRO(InvertVideoEffect, InvertVideoThread)
209 RAISE_WINDOW_MACRO(InvertVideoEffect)
210 SET_STRING_MACRO(InvertVideoEffect)
211 LOAD_CONFIGURATION_MACRO(InvertVideoEffect, InvertVideoConfig)
213 void InvertVideoEffect::update_gui()
217 thread->window->lock_window();
218 load_configuration();
219 thread->window->r->update(config.r);
220 thread->window->g->update(config.g);
221 thread->window->b->update(config.b);
222 thread->window->a->update(config.a);
223 thread->window->unlock_window();
227 int InvertVideoEffect::load_defaults()
229 char directory[BCTEXTLEN];
230 sprintf(directory, "%sinvertvideo.rc", BCASTDIR);
231 defaults = new BC_Hash(directory);
233 config.r = defaults->get("R", config.r);
234 config.g = defaults->get("G", config.g);
235 config.b = defaults->get("B", config.b);
236 config.a = defaults->get("A", config.a);
240 int InvertVideoEffect::save_defaults()
242 defaults->update("R", config.r);
243 defaults->update("G", config.g);
244 defaults->update("B", config.b);
245 defaults->update("A", config.a);
250 void InvertVideoEffect::save_data(KeyFrame *keyframe)
253 output.set_shared_string(keyframe->data, MESSAGESIZE);
254 output.tag.set_title("INVERTVIDEO");
255 output.tag.set_property("R", config.r);
256 output.tag.set_property("G", config.g);
257 output.tag.set_property("B", config.b);
258 output.tag.set_property("A", config.a);
260 output.terminate_string();
263 void InvertVideoEffect::read_data(KeyFrame *keyframe)
266 input.set_shared_string(keyframe->data, strlen(keyframe->data));
267 while(!input.read_tag())
269 if(input.tag.title_is("INVERTVIDEO"))
271 config.r = input.tag.get_property("R", config.r);
272 config.g = input.tag.get_property("G", config.g);
273 config.b = input.tag.get_property("B", config.b);
274 config.a = input.tag.get_property("A", config.a);
280 #define INVERT_MACRO(type, components, max) \
282 for(int i = 0; i < frame->get_h(); i++) \
284 type *in_row = (type*)frame->get_rows()[i]; \
285 type *out_row = (type*)frame->get_rows()[i]; \
287 for(int j = 0; j < w; j++) \
289 if(config.r) out_row[0] = max - in_row[0]; \
290 if(config.g) out_row[1] = max - in_row[1]; \
291 if(config.b) out_row[2] = max - in_row[2]; \
292 if(components == 4) \
293 if(config.a) out_row[3] = max - in_row[3]; \
295 in_row += components; \
296 out_row += components; \
301 int InvertVideoEffect::process_buffer(VFrame *frame,
302 int64_t start_position,
305 load_configuration();
313 if(config.r || config.g || config.b || config.a)
315 int w = frame->get_w();
317 switch(frame->get_color_model())
320 INVERT_MACRO(float, 3, 1.0)
324 INVERT_MACRO(unsigned char, 3, 0xff)
327 INVERT_MACRO(float, 4, 1.0)
331 INVERT_MACRO(unsigned char, 4, 0xff)
335 INVERT_MACRO(uint16_t, 3, 0xffff)
337 case BC_RGBA16161616:
338 case BC_YUVA16161616:
339 INVERT_MACRO(uint16_t, 4, 0xffff)