1 #include "bcdisplayinfo.h"
8 #include "loadbalance.h"
10 #include "pluginvclient.h"
33 void copy_from(WaveConfig &src);
34 int equivalent(WaveConfig &src);
35 void interpolate(WaveConfig &prev,
47 class WaveSmear : public BC_Radial
50 WaveSmear(WaveEffect *plugin, WaveWindow *window, int x, int y);
56 class WaveBlacken : public BC_Radial
59 WaveBlacken(WaveEffect *plugin, WaveWindow *window, int x, int y);
66 class WaveReflective : public BC_CheckBox
69 WaveReflective(WaveEffect *plugin, int x, int y);
74 class WaveAmplitude : public BC_FSlider
77 WaveAmplitude(WaveEffect *plugin, int x, int y);
82 class WavePhase : public BC_FSlider
85 WavePhase(WaveEffect *plugin, int x, int y);
90 class WaveLength : public BC_FSlider
93 WaveLength(WaveEffect *plugin, int x, int y);
106 class WaveWindow : public BC_Window
109 WaveWindow(WaveEffect *plugin, int x, int y);
111 void create_objects();
116 // WaveBlacken *blacken;
117 // WaveReflective *reflective;
118 WaveAmplitude *amplitude;
120 WaveLength *wavelength;
124 PLUGIN_THREAD_HEADER(WaveEffect, WaveThread, WaveWindow)
130 class WaveServer : public LoadServer
133 WaveServer(WaveEffect *plugin, int cpus);
134 void init_packages();
135 LoadClient* new_client();
136 LoadPackage* new_package();
140 class WavePackage : public LoadPackage
147 class WaveUnit : public LoadClient
150 WaveUnit(WaveEffect *plugin, WaveServer *server);
151 void process_package(LoadPackage *package);
163 class WaveEffect : public PluginVClient
166 WaveEffect(PluginServer *server);
169 int process_realtime(VFrame *input, VFrame *output);
171 char* plugin_title();
173 int load_configuration();
176 void save_data(KeyFrame *keyframe);
177 void read_data(KeyFrame *keyframe);
185 VFrame *input, *output;
203 WaveConfig::WaveConfig()
212 void WaveConfig::copy_from(WaveConfig &src)
214 this->mode = src.mode;
215 this->reflective = src.reflective;
216 this->amplitude = src.amplitude;
217 this->phase = src.phase;
218 this->wavelength = src.wavelength;
221 int WaveConfig::equivalent(WaveConfig &src)
224 (this->mode == src.mode) &&
225 EQUIV(this->reflective, src.reflective) &&
226 EQUIV(this->amplitude, src.amplitude) &&
227 EQUIV(this->phase, src.phase) &&
228 EQUIV(this->wavelength, src.wavelength);
231 void WaveConfig::interpolate(WaveConfig &prev,
237 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
238 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
240 this->amplitude = prev.amplitude * prev_scale + next.amplitude * next_scale;
241 this->phase = prev.phase * prev_scale + next.phase * next_scale;
242 this->wavelength = prev.wavelength * prev_scale + next.wavelength * next_scale;
243 this->mode = prev.mode;
244 this->reflective = prev.reflective;
254 WaveSmear::WaveSmear(WaveEffect *plugin, WaveWindow *window, int x, int y)
255 : BC_Radial(x, y, plugin->config.mode == SMEAR, _("Smear"))
257 this->plugin = plugin;
258 this->window = window;
260 int WaveSmear::handle_event()
262 plugin->config.mode = SMEAR;
263 window->update_mode();
264 plugin->send_configure_change();
271 WaveBlacken::WaveBlacken(WaveEffect *plugin, WaveWindow *window, int x, int y)
272 : BC_Radial(x, y, plugin->config.mode == BLACKEN, _("Blacken"))
274 this->plugin = plugin;
275 this->window = window;
277 int WaveBlacken::handle_event()
279 plugin->config.mode = BLACKEN;
280 window->update_mode();
281 plugin->send_configure_change();
290 WaveReflective::WaveReflective(WaveEffect *plugin, int x, int y)
291 : BC_CheckBox(x, y, plugin->config.reflective, _("Reflective"))
293 this->plugin = plugin;
295 int WaveReflective::handle_event()
297 plugin->config.reflective = get_value();
298 plugin->send_configure_change();
303 WaveAmplitude::WaveAmplitude(WaveEffect *plugin, int x, int y)
311 plugin->config.amplitude)
313 this->plugin = plugin;
315 int WaveAmplitude::handle_event()
317 plugin->config.amplitude = get_value();
318 plugin->send_configure_change();
324 WavePhase::WavePhase(WaveEffect *plugin, int x, int y)
332 plugin->config.phase)
334 this->plugin = plugin;
336 int WavePhase::handle_event()
338 plugin->config.phase = get_value();
339 plugin->send_configure_change();
343 WaveLength::WaveLength(WaveEffect *plugin, int x, int y)
351 plugin->config.wavelength)
353 this->plugin = plugin;
355 int WaveLength::handle_event()
357 plugin->config.wavelength = get_value();
358 plugin->send_configure_change();
370 WaveWindow::WaveWindow(WaveEffect *plugin, int x, int y)
371 : BC_Window(plugin->gui_string,
382 this->plugin = plugin;
385 WaveWindow::~WaveWindow()
389 void WaveWindow::create_objects()
391 int x = 10, y = 10, x1 = 100;
393 // add_subwindow(new BC_Title(x, y, _("Mode:")));
394 // add_subwindow(smear = new WaveSmear(plugin, this, x1, y));
396 // add_subwindow(blacken = new WaveBlacken(plugin, this, x1, y));
398 // add_subwindow(reflective = new WaveReflective(plugin, x1, y));
400 add_subwindow(new BC_Title(x, y, _("Amplitude:")));
401 add_subwindow(amplitude = new WaveAmplitude(plugin, x1, y));
403 add_subwindow(new BC_Title(x, y, _("Phase:")));
404 add_subwindow(phase = new WavePhase(plugin, x1, y));
406 add_subwindow(new BC_Title(x, y, _("Wavelength:")));
407 add_subwindow(wavelength = new WaveLength(plugin, x1, y));
413 int WaveWindow::close_event()
419 void WaveWindow::update_mode()
421 // smear->update(plugin->config.mode == SMEAR);
422 // blacken->update(plugin->config.mode == BLACKEN);
426 PLUGIN_THREAD_OBJECT(WaveEffect, WaveThread, WaveWindow)
431 REGISTER_PLUGIN(WaveEffect)
436 WaveEffect::WaveEffect(PluginServer *server)
437 : PluginVClient(server)
441 PLUGIN_CONSTRUCTOR_MACRO
444 WaveEffect::~WaveEffect()
446 PLUGIN_DESTRUCTOR_MACRO
448 if(temp_frame) delete temp_frame;
449 if(engine) delete engine;
453 char* WaveEffect::plugin_title() { return N_("Wave"); }
454 int WaveEffect::is_realtime() { return 1; }
456 NEW_PICON_MACRO(WaveEffect)
458 SHOW_GUI_MACRO(WaveEffect, WaveThread)
460 RAISE_WINDOW_MACRO(WaveEffect)
462 SET_STRING_MACRO(WaveEffect)
464 void WaveEffect::update_gui()
468 thread->window->lock_window();
469 load_configuration();
470 thread->window->update_mode();
471 // thread->window->reflective->update(config.reflective);
472 thread->window->amplitude->update(config.amplitude);
473 thread->window->phase->update(config.phase);
474 thread->window->wavelength->update(config.wavelength);
475 thread->window->unlock_window();
480 LOAD_CONFIGURATION_MACRO(WaveEffect, WaveConfig)
482 int WaveEffect::load_defaults()
484 char directory[BCTEXTLEN];
485 // set the default directory
486 sprintf(directory, "%swave.rc", BCASTDIR);
489 defaults = new BC_Hash(directory);
492 config.mode = defaults->get("MODE", config.mode);
493 config.reflective = defaults->get("REFLECTIVE", config.reflective);
494 config.amplitude = defaults->get("AMPLITUDE", config.amplitude);
495 config.phase = defaults->get("PHASE", config.phase);
496 config.wavelength = defaults->get("WAVELENGTH", config.wavelength);
500 int WaveEffect::save_defaults()
502 defaults->update("MODE", config.mode);
503 defaults->update("REFLECTIVE", config.reflective);
504 defaults->update("AMPLITUDE", config.amplitude);
505 defaults->update("PHASE", config.phase);
506 defaults->update("WAVELENGTH", config.wavelength);
511 void WaveEffect::save_data(KeyFrame *keyframe)
515 // cause data to be stored directly in text
516 output.set_shared_string(keyframe->data, MESSAGESIZE);
517 output.tag.set_title("WAVE");
518 output.tag.set_property("MODE", config.mode);
519 output.tag.set_property("REFLECTIVE", config.reflective);
520 output.tag.set_property("AMPLITUDE", config.amplitude);
521 output.tag.set_property("PHASE", config.phase);
522 output.tag.set_property("WAVELENGTH", config.wavelength);
524 output.tag.set_title("/WAVE");
526 output.terminate_string();
529 void WaveEffect::read_data(KeyFrame *keyframe)
533 input.set_shared_string(keyframe->data, strlen(keyframe->data));
535 while(!input.read_tag())
537 if(input.tag.title_is("WAVE"))
539 config.mode = input.tag.get_property("MODE", config.mode);
540 config.reflective = input.tag.get_property("REFLECTIVE", config.reflective);
541 config.amplitude = input.tag.get_property("AMPLITUDE", config.amplitude);
542 config.phase = input.tag.get_property("PHASE", config.phase);
543 config.wavelength = input.tag.get_property("WAVELENGTH", config.wavelength);
549 int WaveEffect::process_realtime(VFrame *input, VFrame *output)
551 load_configuration();
555 //printf("WaveEffect::process_realtime %f %d\n", config.radius, config.use_intensity);
557 this->output = output;
559 if(EQUIV(config.amplitude, 0) || EQUIV(config.wavelength, 0))
561 if(input->get_rows()[0] != output->get_rows()[0])
562 output->copy_from(input);
566 if(input->get_rows()[0] == output->get_rows()[0])
568 if(!temp_frame) temp_frame = new VFrame(0,
571 input->get_color_model());
572 temp_frame->copy_from(input);
573 this->input = temp_frame;
579 engine = new WaveServer(this, (PluginClient::smp + 1));
582 engine->process_packages();
595 WavePackage::WavePackage()
605 WaveUnit::WaveUnit(WaveEffect *plugin, WaveServer *server)
608 this->plugin = plugin;
613 #define WITHIN(a, b, c) ((((a) <= (b)) && ((b) <= (c))) ? 1 : 0)
615 static float bilinear(double x,
628 m0 = (1.0 - x) * v[0] + x * v[1];
629 m1 = (1.0 - x) * v[2] + x * v[3];
631 return((1.0 - y) * m0 + y * m1);
634 void WaveUnit::process_package(LoadPackage *package)
636 WavePackage *pkg = (WavePackage*)package;
637 int w = plugin->input->get_w();
638 int h = plugin->input->get_h();
639 double cen_x, cen_y; /* Center of wave */
640 double xhsiz, yhsiz; /* Half size of selection */
641 double radius, radius2; /* Radius and radius^2 */
645 double xscale, yscale;
651 int x1_in, y1_in, x2_in, y2_in;
652 double phase = plugin->config.phase * M_PI / 180;
658 cen_x = (double) (x2 - 1 + x1) / 2.0;
659 cen_y = (double) (y2 - 1 + y1) / 2.0;
660 xhsiz = (double) (x2 - x1) / 2.0;
661 yhsiz = (double) (y2 - y1) / 2.0;
665 xscale = yhsiz / xhsiz;
668 else if (xhsiz > yhsiz)
671 yscale = xhsiz / yhsiz;
679 radius = MAX(xhsiz, yhsiz);
680 radius2 = radius * radius;
683 wavelength = plugin->config.wavelength / 100 * radius;
688 #define WAVE(type, components, chroma_offset) \
690 int row_size = w * components; \
691 type **in_rows = (type**)plugin->input->get_rows(); \
692 for(int y = pkg->row1; y < pkg->row2; y++) \
694 type *dest = (type*)plugin->output->get_rows()[y]; \
696 for(int x = x1; x < x2; x++) \
698 dx = (x - cen_x) * xscale; \
699 dy = (y - cen_y) * yscale; \
700 d = sqrt(dx * dx + dy * dy); \
702 if(plugin->config.reflective) \
704 amnt = plugin->config.amplitude * \
705 fabs(sin(((d / wavelength) * \
709 needx = (amnt * dx) / xscale + cen_x; \
710 needy = (amnt * dy) / yscale + cen_y; \
714 amnt = plugin->config.amplitude * \
715 sin(((d / wavelength) * \
719 needx = (amnt + dx) / xscale + cen_x; \
720 needy = (amnt + dy) / yscale + cen_y; \
726 if(plugin->config.mode == SMEAR) \
749 type *p = in_rows[CLIP(yi, 0, h - 1)] + \
750 CLIP(xi, 0, w - 1) * components; \
751 x1_in = WITHIN(0, xi, w - 1); \
752 y1_in = WITHIN(0, yi, h - 1); \
753 x2_in = WITHIN(0, xi + 1, w - 1); \
754 y2_in = WITHIN(0, yi + 1, h - 1); \
757 for(int k = 0; k < components; k++) \
759 if (x1_in && y1_in) \
760 values[0] = *(p + k); \
762 values[0] = ((k == 1 || k == 2) ? 0 : chroma_offset); \
764 if (x2_in && y1_in) \
765 values[1] = *(p + components + k); \
767 values[1] = ((k == 1 || k == 2) ? 0 : chroma_offset); \
769 if (x1_in && y2_in) \
770 values[2] = *(p + row_size + k); \
772 values[2] = ((k == 1 || k == 2) ? 0 : chroma_offset); \
777 values[3] = *(p + row_size + components + k); \
779 values[3] = ((k == 1 || k == 2) ? 0 : chroma_offset); \
782 values[3] = ((k == 1 || k == 2) ? 0 : chroma_offset); \
784 val = bilinear(needx, needy, values); \
786 *dest++ = (type)val; \
795 switch(plugin->input->get_color_model())
798 WAVE(unsigned char, 3, 0x0);
804 WAVE(unsigned char, 3, 0x80);
807 WAVE(uint16_t, 3, 0x0);
810 WAVE(uint16_t, 3, 0x8000);
813 WAVE(unsigned char, 4, 0x0);
816 WAVE(unsigned char, 4, 0x0);
819 WAVE(unsigned char, 4, 0x8000);
821 case BC_RGBA16161616:
822 WAVE(uint16_t, 4, 0x0);
824 case BC_YUVA16161616:
825 WAVE(uint16_t, 4, 0x8000);
839 WaveServer::WaveServer(WaveEffect *plugin, int cpus)
840 : LoadServer(cpus, cpus)
842 this->plugin = plugin;
845 void WaveServer::init_packages()
847 for(int i = 0; i < LoadServer::get_total_packages(); i++)
849 WavePackage *pkg = (WavePackage*)get_package(i);
850 pkg->row1 = plugin->input->get_h() * i / LoadServer::get_total_packages();
851 pkg->row2 = plugin->input->get_h() * (i + 1) / LoadServer::get_total_packages();
856 LoadClient* WaveServer::new_client()
858 return new WaveUnit(plugin, this);
861 LoadPackage* WaveServer::new_package()
863 return new WavePackage;