r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / plugins / swapchannels / swapchannels.C
blob1ab8811cb824c4448df4e2a7a74037acba53bcbc
1 #include "bcdisplayinfo.h"
2 #include "clip.h"
3 #include "defaults.h"
4 #include "filexml.h"
5 #include "picon_png.h"
6 #include "swapchannels.h"
7 #include "vframe.h"
11 #include <stdint.h>
12 #include <string.h>
14 #include <libintl.h>
15 #define _(String) gettext(String)
16 #define gettext_noop(String) String
17 #define N_(String) gettext_noop (String)
24 REGISTER_PLUGIN(SwapMain)
33 SwapConfig::SwapConfig()
35         red = RED_SRC;
36         green = GREEN_SRC;
37         blue = BLUE_SRC;
38     alpha = ALPHA_SRC;
42 int SwapConfig::equivalent(SwapConfig &that)
44         return (red == that.red &&
45                 green == that.green &&
46                 blue == that.blue &&
47                 alpha == that.alpha);
50 void SwapConfig::copy_from(SwapConfig &that)
52         red = that.red;
53         green = that.green;
54         blue = that.blue;
55         alpha = that.alpha;
65 SwapWindow::SwapWindow(SwapMain *plugin, int x, int y)
66  : BC_Window(plugin->gui_string, 
67         x,
68         y,
69         250, 
70         170, 
71         250, 
72         170, 
73         0, 
74         0,
75         1)
77         this->plugin = plugin;
80 SwapWindow::~SwapWindow()
84         
85 void SwapWindow::create_objects()
87         int x = 10, y = 10;
88         int margin = 30;
90         add_subwindow(new BC_Title(x, y, _("Swap channels")));
91         y += margin;
92         add_subwindow(new BC_Title(x + 160, y + 5, _("-> Red")));
93         add_subwindow(red = new SwapMenu(plugin, &(plugin->config.red), x, y));
94         red->create_objects();
95         y += margin;
96         add_subwindow(new BC_Title(x + 160, y + 5, _("-> Green")));
97         add_subwindow(green = new SwapMenu(plugin, &(plugin->config.green), x, y));
98         green->create_objects();
99         y += margin;
100         add_subwindow(new BC_Title(x + 160, y + 5, _("-> Blue")));
101         add_subwindow(blue = new SwapMenu(plugin, &(plugin->config.blue), x, y));
102         blue->create_objects();
103         y += margin;
104         add_subwindow(new BC_Title(x + 160, y + 5, _("-> Alpha")));
105         add_subwindow(alpha = new SwapMenu(plugin, &(plugin->config.alpha), x, y));
106         alpha->create_objects();
108         show_window();
109         flush();
112 int SwapWindow::close_event()
114 // Set result to 1 to indicate a client side close
115         set_done(1);
116         return 1;
123 SwapMenu::SwapMenu(SwapMain *client, int *output, int x, int y)
124  : BC_PopupMenu(x, y, 150, client->output_to_text(*output))
126         this->client = client;
127         this->output = output;
130 int SwapMenu::handle_event()
132         client->send_configure_change();
133         return 1;
136 int SwapMenu::create_objects()
138         add_item(new SwapItem(this, client->output_to_text(RED_SRC)));
139         add_item(new SwapItem(this, client->output_to_text(GREEN_SRC)));
140         add_item(new SwapItem(this, client->output_to_text(BLUE_SRC)));
141         add_item(new SwapItem(this, client->output_to_text(ALPHA_SRC)));
142         add_item(new SwapItem(this, client->output_to_text(NO_SRC)));
143         add_item(new SwapItem(this, client->output_to_text(MAX_SRC)));
144         return 0;
150 SwapItem::SwapItem(SwapMenu *menu, char *title)
151  : BC_MenuItem(title)
153         this->menu = menu;
156 int SwapItem::handle_event()
158         menu->set_text(get_text());
159         *(menu->output) = menu->client->text_to_output(get_text());
160         menu->handle_event();
161         return 1;
172 PLUGIN_THREAD_OBJECT(SwapMain, SwapThread, SwapWindow)
183 SwapMain::SwapMain(PluginServer *server)
184  : PluginVClient(server)
186         reset();
187         PLUGIN_CONSTRUCTOR_MACRO
190 SwapMain::~SwapMain()
192         PLUGIN_DESTRUCTOR_MACRO
193         
194         if(temp) delete temp;
197 void SwapMain::reset()
199         temp = 0;
202 int SwapMain::is_realtime() 
204         return 1;
207 char* SwapMain::plugin_title() 
209         return _("Swap channels");
212 int SwapMain::is_synthesis()
214         return 1;
217 SHOW_GUI_MACRO(SwapMain, SwapThread)
218 NEW_PICON_MACRO(SwapMain)
219 SET_STRING_MACRO(SwapMain)
220 RAISE_WINDOW_MACRO(SwapMain)
222 int SwapMain::load_defaults()
224         char directory[1024], string[1024];
225 // set the default directory
226         sprintf(directory, "%sswapchannels.rc", BCASTDIR);
228 // load the defaults
229         defaults = new Defaults(directory);
230         defaults->load();
232         config.red = defaults->get("RED", config.red);
233         config.green = defaults->get("GREEN", config.green);
234         config.blue = defaults->get("BLUE", config.blue);
235         config.alpha = defaults->get("ALPHA", config.alpha);
236         return 0;
239 int SwapMain::save_defaults()
241         defaults->update("RED", config.red);
242         defaults->update("GREEN", config.green);
243         defaults->update("BLUE", config.blue);
244         defaults->update("ALPHA", config.alpha);
245         defaults->save();
246         return 0;
249 void SwapMain::save_data(KeyFrame *keyframe)
251         FileXML output;
253 // cause data to be stored directly in text
254         output.set_shared_string(keyframe->data, MESSAGESIZE);
255         output.tag.set_title("SWAPCHANNELS");
256         output.tag.set_property("RED", config.red);
257         output.tag.set_property("GREEN", config.green);
258         output.tag.set_property("BLUE", config.blue);
259         output.tag.set_property("ALPHA", config.alpha);
260         output.append_tag();
261         output.append_newline();
262         output.terminate_string();
263 // data is now in *text
266 void SwapMain::read_data(KeyFrame *keyframe)
268         FileXML input;
270         input.set_shared_string(keyframe->data, strlen(keyframe->data));
272         int result = 0;
274         while(!result)
275         {
276                 result = input.read_tag();
278                 if(!result)
279                 {
280                         if(input.tag.title_is("SWAPCHANNELS"))
281                         {
282                                 config.red = input.tag.get_property("RED", config.red);
283                                 config.green = input.tag.get_property("GREEN", config.green);
284                                 config.blue = input.tag.get_property("BLUE", config.blue);
285                                 config.alpha = input.tag.get_property("ALPHA", config.alpha);
286                         }
287                 }
288         }
291 void SwapMain::update_gui()
293         if(thread) 
294         {
295                 load_configuration();
296                 thread->window->lock_window();
297                 thread->window->red->set_text(output_to_text(config.red));
298                 thread->window->green->set_text(output_to_text(config.green));
299                 thread->window->blue->set_text(output_to_text(config.blue));
300                 thread->window->alpha->set_text(output_to_text(config.alpha));
301                 thread->window->unlock_window();
302         }
306 void SwapMain::load_configuration()
308         KeyFrame *prev_keyframe;
309         prev_keyframe = get_prev_keyframe(get_source_position());
310         
311         read_data(prev_keyframe);
337 #define MAXMINSRC(src, max) \
338         (src == MAX_SRC ? max : 0)
340 #define SWAP_CHANNELS(type, max, components) \
341 { \
342         int h = input_ptr->get_h(); \
343         int w = input_ptr->get_w(); \
344         int red = config.red; \
345         int green = config.green; \
346         int blue = config.blue; \
347         int alpha = config.alpha; \
349         if(components == 3) \
350         { \
351                 if(red == ALPHA_SRC) red = MAX_SRC; \
352                 if(green == ALPHA_SRC) green = MAX_SRC; \
353                 if(blue == ALPHA_SRC) blue = MAX_SRC; \
354         } \
357         for(int i = 0; i < h; i++) \
358         { \
359                 type *inrow = (type*)input_ptr->get_rows()[i]; \
360                 type *outrow = (type*)temp->get_rows()[i]; \
362                 for(int j = 0; j < w; j++) \
363                 { \
364                         if(red < 4) \
365                                 *outrow++ = *(inrow + red); \
366                         else \
367                                 *outrow++ = MAXMINSRC(red, max); \
369                         if(green < 4) \
370                                 *outrow++ = *(inrow + green); \
371                         else \
372                                 *outrow++ = MAXMINSRC(green, max); \
374                         if(blue < 4) \
375                                 *outrow++ = *(inrow + blue); \
376                         else \
377                                 *outrow++ = MAXMINSRC(blue, max); \
379                         if(components == 4) \
380                         { \
381                                 if(alpha < 4) \
382                                         *outrow++ = *(inrow + alpha); \
383                                 else \
384                                         *outrow++ = MAXMINSRC(alpha, max); \
385                         } \
387                         inrow += components; \
388                 } \
389         } \
391         output_ptr->copy_from(temp); \
396 int SwapMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
398         load_configuration();
401         if(!temp) 
402                 temp = new VFrame(0, 
403                         input_ptr->get_w(), 
404                         input_ptr->get_h(), 
405                         input_ptr->get_color_model());
407         switch(input_ptr->get_color_model())
408         {
409                 case BC_RGB888:
410                 case BC_YUV888:
411                         SWAP_CHANNELS(unsigned char, 0xff, 3);
412                         break;
413                 case BC_RGBA8888:
414                 case BC_YUVA8888:
415                         SWAP_CHANNELS(unsigned char, 0xff, 4);
416                         break;
417                 case BC_RGB161616:
418                 case BC_YUV161616:
419                         SWAP_CHANNELS(uint16_t, 0xffff, 3);
420                         break;
421                 case BC_RGBA16161616:
422                 case BC_YUVA16161616:
423                         SWAP_CHANNELS(uint16_t, 0xffff, 4);
424                         break;
425         }
426         
427         
428         return 0;
432 char* SwapMain::output_to_text(int value)
434         switch(value)
435         {
436                 case RED_SRC:
437                         return _("Red");
438                         break;
439                 case GREEN_SRC:
440                         return _("Green");
441                         break;
442                 case BLUE_SRC:
443                         return _("Blue");
444                         break;
445                 case ALPHA_SRC:
446                         return _("Alpha");
447                         break;
448                 case NO_SRC:
449                         return _("0%");
450                         break;
451                 case MAX_SRC:
452                         return _("100%");
453                         break;
454                 default:
455                         return "";
456                         break;
457         }
460 int SwapMain::text_to_output(char *text)
462         if(!strcmp(text, _("Red"))) return RED_SRC;
463         if(!strcmp(text, _("Green"))) return GREEN_SRC;
464         if(!strcmp(text, _("Blue"))) return BLUE_SRC;
465         if(!strcmp(text, _("Alpha"))) return ALPHA_SRC;
466         if(!strcmp(text, _("0%"))) return NO_SRC;
467         if(!strcmp(text, _("100%"))) return MAX_SRC;
468         return 0;