Condense the xml-cleanup into a short feature-branch
[cinelerra_cv/mob.git] / plugins / swapchannels / swapchannels.C
blobe2994cda13b11d64233d25ca7e105b6c51e2955f
1 #include "bcdisplayinfo.h"
2 #include "clip.h"
3 #include "bchash.h"
4 #include "filexml.h"
5 #include "language.h"
6 #include "picon_png.h"
7 #include "swapchannels.h"
8 #include "vframe.h"
12 #include <stdint.h>
13 #include <string.h>
20 REGISTER_PLUGIN(SwapMain)
29 SwapConfig::SwapConfig()
31         red = RED_SRC;
32         green = GREEN_SRC;
33         blue = BLUE_SRC;
34     alpha = ALPHA_SRC;
38 int SwapConfig::equivalent(SwapConfig &that)
40         return (red == that.red &&
41                 green == that.green &&
42                 blue == that.blue &&
43                 alpha == that.alpha);
46 void SwapConfig::copy_from(SwapConfig &that)
48         red = that.red;
49         green = that.green;
50         blue = that.blue;
51         alpha = that.alpha;
61 SwapWindow::SwapWindow(SwapMain *plugin, int x, int y)
62  : BC_Window(plugin->gui_string, 
63         x,
64         y,
65         250, 
66         170, 
67         250, 
68         170, 
69         0, 
70         0,
71         1)
73         this->plugin = plugin;
76 SwapWindow::~SwapWindow()
80         
81 void SwapWindow::create_objects()
83         int x = 10, y = 10;
84         int margin = 30;
86         add_subwindow(new BC_Title(x, y, _("Swap channels")));
87         y += margin;
88         add_subwindow(new BC_Title(x + 160, y + 5, _("-> Red")));
89         add_subwindow(red = new SwapMenu(plugin, &(plugin->config.red), x, y));
90         red->create_objects();
91         y += margin;
92         add_subwindow(new BC_Title(x + 160, y + 5, _("-> Green")));
93         add_subwindow(green = new SwapMenu(plugin, &(plugin->config.green), x, y));
94         green->create_objects();
95         y += margin;
96         add_subwindow(new BC_Title(x + 160, y + 5, _("-> Blue")));
97         add_subwindow(blue = new SwapMenu(plugin, &(plugin->config.blue), x, y));
98         blue->create_objects();
99         y += margin;
100         add_subwindow(new BC_Title(x + 160, y + 5, _("-> Alpha")));
101         add_subwindow(alpha = new SwapMenu(plugin, &(plugin->config.alpha), x, y));
102         alpha->create_objects();
104         show_window();
105         flush();
108 WINDOW_CLOSE_EVENT(SwapWindow)
116 SwapMenu::SwapMenu(SwapMain *client, int *output, int x, int y)
117  : BC_PopupMenu(x, y, 150, client->output_to_text(*output))
119         this->client = client;
120         this->output = output;
123 int SwapMenu::handle_event()
125         client->send_configure_change();
126         return 1;
129 int SwapMenu::create_objects()
131         add_item(new SwapItem(this, client->output_to_text(RED_SRC)));
132         add_item(new SwapItem(this, client->output_to_text(GREEN_SRC)));
133         add_item(new SwapItem(this, client->output_to_text(BLUE_SRC)));
134         add_item(new SwapItem(this, client->output_to_text(ALPHA_SRC)));
135         add_item(new SwapItem(this, client->output_to_text(NO_SRC)));
136         add_item(new SwapItem(this, client->output_to_text(MAX_SRC)));
137         return 0;
143 SwapItem::SwapItem(SwapMenu *menu, char *title)
144  : BC_MenuItem(title)
146         this->menu = menu;
149 int SwapItem::handle_event()
151         menu->set_text(get_text());
152         *(menu->output) = menu->client->text_to_output(get_text());
153         menu->handle_event();
154         return 1;
165 PLUGIN_THREAD_OBJECT(SwapMain, SwapThread, SwapWindow)
176 SwapMain::SwapMain(PluginServer *server)
177  : PluginVClient(server)
179         reset();
180         PLUGIN_CONSTRUCTOR_MACRO
183 SwapMain::~SwapMain()
185         PLUGIN_DESTRUCTOR_MACRO
186         
187         if(temp) delete temp;
190 void SwapMain::reset()
192         temp = 0;
196 char* SwapMain::plugin_title()  { return N_("Swap channels"); }
197 int SwapMain::is_synthesis() { return 1; }
198 int SwapMain::is_realtime()  { return 1; }
201 SHOW_GUI_MACRO(SwapMain, SwapThread)
202 NEW_PICON_MACRO(SwapMain)
203 SET_STRING_MACRO(SwapMain)
204 RAISE_WINDOW_MACRO(SwapMain)
206 int SwapMain::load_defaults()
208         char directory[1024], string[1024];
209 // set the default directory
210         sprintf(directory, "%sswapchannels.rc", BCASTDIR);
212 // load the defaults
213         defaults = new BC_Hash(directory);
214         defaults->load();
216         config.red = defaults->get("RED", config.red);
217         config.green = defaults->get("GREEN", config.green);
218         config.blue = defaults->get("BLUE", config.blue);
219         config.alpha = defaults->get("ALPHA", config.alpha);
220         return 0;
223 int SwapMain::save_defaults()
225         defaults->update("RED", config.red);
226         defaults->update("GREEN", config.green);
227         defaults->update("BLUE", config.blue);
228         defaults->update("ALPHA", config.alpha);
229         defaults->save();
230         return 0;
233 void SwapMain::save_data(KeyFrame *keyframe)
235         FileXML output;
237 // cause data to be stored directly in text
238         output.set_shared_string(keyframe->data, MESSAGESIZE);
239         output.tag.set_title("SWAPCHANNELS");
240         output.tag.set_property("RED", config.red);
241         output.tag.set_property("GREEN", config.green);
242         output.tag.set_property("BLUE", config.blue);
243         output.tag.set_property("ALPHA", config.alpha);
244         output.append_tag();
245         output.tag.set_title("/SWAPCHANNELS");
246         output.append_tag();
247         output.append_newline();
248         output.terminate_string();
249 // data is now in *text
252 void SwapMain::read_data(KeyFrame *keyframe)
254         FileXML input;
256         input.set_shared_string(keyframe->data, strlen(keyframe->data));
258         int result = 0;
260         while(!result)
261         {
262                 result = input.read_tag();
264                 if(!result)
265                 {
266                         if(input.tag.title_is("SWAPCHANNELS"))
267                         {
268                                 config.red = input.tag.get_property("RED", config.red);
269                                 config.green = input.tag.get_property("GREEN", config.green);
270                                 config.blue = input.tag.get_property("BLUE", config.blue);
271                                 config.alpha = input.tag.get_property("ALPHA", config.alpha);
272                         }
273                 }
274         }
277 void SwapMain::update_gui()
279         if(thread) 
280         {
281                 load_configuration();
282                 thread->window->lock_window();
283                 thread->window->red->set_text(output_to_text(config.red));
284                 thread->window->green->set_text(output_to_text(config.green));
285                 thread->window->blue->set_text(output_to_text(config.blue));
286                 thread->window->alpha->set_text(output_to_text(config.alpha));
287                 thread->window->unlock_window();
288         }
292 void SwapMain::load_configuration()
294         KeyFrame *prev_keyframe;
295         prev_keyframe = get_prev_keyframe(get_source_position());
296         
297         read_data(prev_keyframe);
323 #define MAXMINSRC(src, max) \
324         (src == MAX_SRC ? max : 0)
326 #define SWAP_CHANNELS(type, max, components) \
327 { \
328         int h = input_ptr->get_h(); \
329         int w = input_ptr->get_w(); \
330         int red = config.red; \
331         int green = config.green; \
332         int blue = config.blue; \
333         int alpha = config.alpha; \
335         if(components == 3) \
336         { \
337                 if(red == ALPHA_SRC) red = MAX_SRC; \
338                 if(green == ALPHA_SRC) green = MAX_SRC; \
339                 if(blue == ALPHA_SRC) blue = MAX_SRC; \
340         } \
343         for(int i = 0; i < h; i++) \
344         { \
345                 type *inrow = (type*)input_ptr->get_rows()[i]; \
346                 type *outrow = (type*)temp->get_rows()[i]; \
348                 for(int j = 0; j < w; j++) \
349                 { \
350                         if(red < 4) \
351                                 *outrow++ = *(inrow + red); \
352                         else \
353                                 *outrow++ = MAXMINSRC(red, max); \
355                         if(green < 4) \
356                                 *outrow++ = *(inrow + green); \
357                         else \
358                                 *outrow++ = MAXMINSRC(green, max); \
360                         if(blue < 4) \
361                                 *outrow++ = *(inrow + blue); \
362                         else \
363                                 *outrow++ = MAXMINSRC(blue, max); \
365                         if(components == 4) \
366                         { \
367                                 if(alpha < 4) \
368                                         *outrow++ = *(inrow + alpha); \
369                                 else \
370                                         *outrow++ = MAXMINSRC(alpha, max); \
371                         } \
373                         inrow += components; \
374                 } \
375         } \
377         output_ptr->copy_from(temp); \
382 int SwapMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
384         load_configuration();
387         if(!temp) 
388                 temp = new VFrame(0, 
389                         input_ptr->get_w(), 
390                         input_ptr->get_h(), 
391                         input_ptr->get_color_model());
393         switch(input_ptr->get_color_model())
394         {
395                 case BC_RGB_FLOAT:
396                         SWAP_CHANNELS(float, 1, 3);
397                         break;
398                 case BC_RGBA_FLOAT:
399                         SWAP_CHANNELS(float, 1, 4);
400                         break;
401                 case BC_RGB888:
402                 case BC_YUV888:
403                         SWAP_CHANNELS(unsigned char, 0xff, 3);
404                         break;
405                 case BC_RGBA8888:
406                 case BC_YUVA8888:
407                         SWAP_CHANNELS(unsigned char, 0xff, 4);
408                         break;
409                 case BC_RGB161616:
410                 case BC_YUV161616:
411                         SWAP_CHANNELS(uint16_t, 0xffff, 3);
412                         break;
413                 case BC_RGBA16161616:
414                 case BC_YUVA16161616:
415                         SWAP_CHANNELS(uint16_t, 0xffff, 4);
416                         break;
417         }
418         
419         
420         return 0;
424 char* SwapMain::output_to_text(int value)
426         switch(value)
427         {
428                 case RED_SRC:
429                         return _("Red");
430                         break;
431                 case GREEN_SRC:
432                         return _("Green");
433                         break;
434                 case BLUE_SRC:
435                         return _("Blue");
436                         break;
437                 case ALPHA_SRC:
438                         return _("Alpha");
439                         break;
440                 case NO_SRC:
441                         return _("0%");
442                         break;
443                 case MAX_SRC:
444                         return _("100%");
445                         break;
446                 default:
447                         return "";
448                         break;
449         }
452 int SwapMain::text_to_output(char *text)
454         if(!strcmp(text, _("Red"))) return RED_SRC;
455         if(!strcmp(text, _("Green"))) return GREEN_SRC;
456         if(!strcmp(text, _("Blue"))) return BLUE_SRC;
457         if(!strcmp(text, _("Alpha"))) return ALPHA_SRC;
458         if(!strcmp(text, _("0%"))) return NO_SRC;
459         if(!strcmp(text, _("100%"))) return MAX_SRC;
460         return 0;