00001 #include "bcdisplayinfo.h"
00002 #include "clip.h"
00003 #include "bchash.h"
00004 #include "filexml.h"
00005 #include "language.h"
00006 #include "picon_png.h"
00007 #include "swapchannels.h"
00008 #include "vframe.h"
00009
00010
00011
00012 #include <stdint.h>
00013 #include <string.h>
00014
00015
00016
00017
00018
00019
00020 REGISTER_PLUGIN(SwapMain)
00021
00022
00023
00024
00025
00026
00027
00028
00029 SwapConfig::SwapConfig()
00030 {
00031 red = RED_SRC;
00032 green = GREEN_SRC;
00033 blue = BLUE_SRC;
00034 alpha = ALPHA_SRC;
00035 }
00036
00037
00038 int SwapConfig::equivalent(SwapConfig &that)
00039 {
00040 return (red == that.red &&
00041 green == that.green &&
00042 blue == that.blue &&
00043 alpha == that.alpha);
00044 }
00045
00046 void SwapConfig::copy_from(SwapConfig &that)
00047 {
00048 red = that.red;
00049 green = that.green;
00050 blue = that.blue;
00051 alpha = that.alpha;
00052 }
00053
00054
00055
00056
00057
00058
00059
00060
00061 SwapWindow::SwapWindow(SwapMain *plugin, int x, int y)
00062 : BC_Window(plugin->gui_string,
00063 x,
00064 y,
00065 250,
00066 170,
00067 250,
00068 170,
00069 0,
00070 0,
00071 1)
00072 {
00073 this->plugin = plugin;
00074 }
00075
00076 SwapWindow::~SwapWindow()
00077 {
00078 }
00079
00080
00081 void SwapWindow::create_objects()
00082 {
00083 int x = 10, y = 10;
00084 int margin = 30;
00085
00086 add_subwindow(new BC_Title(x, y, _("Swap channels")));
00087 y += margin;
00088 add_subwindow(new BC_Title(x + 160, y + 5, _("-> Red")));
00089 add_subwindow(red = new SwapMenu(plugin, &(plugin->config.red), x, y));
00090 red->create_objects();
00091 y += margin;
00092 add_subwindow(new BC_Title(x + 160, y + 5, _("-> Green")));
00093 add_subwindow(green = new SwapMenu(plugin, &(plugin->config.green), x, y));
00094 green->create_objects();
00095 y += margin;
00096 add_subwindow(new BC_Title(x + 160, y + 5, _("-> Blue")));
00097 add_subwindow(blue = new SwapMenu(plugin, &(plugin->config.blue), x, y));
00098 blue->create_objects();
00099 y += margin;
00100 add_subwindow(new BC_Title(x + 160, y + 5, _("-> Alpha")));
00101 add_subwindow(alpha = new SwapMenu(plugin, &(plugin->config.alpha), x, y));
00102 alpha->create_objects();
00103
00104 show_window();
00105 flush();
00106 }
00107
00108 WINDOW_CLOSE_EVENT(SwapWindow)
00109
00110
00111
00112
00113
00114
00115
00116 SwapMenu::SwapMenu(SwapMain *client, int *output, int x, int y)
00117 : BC_PopupMenu(x, y, 150, client->output_to_text(*output))
00118 {
00119 this->client = client;
00120 this->output = output;
00121 }
00122
00123 int SwapMenu::handle_event()
00124 {
00125 client->send_configure_change();
00126 return 1;
00127 }
00128
00129 int SwapMenu::create_objects()
00130 {
00131 add_item(new SwapItem(this, client->output_to_text(RED_SRC)));
00132 add_item(new SwapItem(this, client->output_to_text(GREEN_SRC)));
00133 add_item(new SwapItem(this, client->output_to_text(BLUE_SRC)));
00134 add_item(new SwapItem(this, client->output_to_text(ALPHA_SRC)));
00135 add_item(new SwapItem(this, client->output_to_text(NO_SRC)));
00136 add_item(new SwapItem(this, client->output_to_text(MAX_SRC)));
00137 return 0;
00138 }
00139
00140
00141
00142
00143 SwapItem::SwapItem(SwapMenu *menu, char *title)
00144 : BC_MenuItem(title)
00145 {
00146 this->menu = menu;
00147 }
00148
00149 int SwapItem::handle_event()
00150 {
00151 menu->set_text(get_text());
00152 *(menu->output) = menu->client->text_to_output(get_text());
00153 menu->handle_event();
00154 return 1;
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 PLUGIN_THREAD_OBJECT(SwapMain, SwapThread, SwapWindow)
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 SwapMain::SwapMain(PluginServer *server)
00177 : PluginVClient(server)
00178 {
00179 reset();
00180 PLUGIN_CONSTRUCTOR_MACRO
00181 }
00182
00183 SwapMain::~SwapMain()
00184 {
00185 PLUGIN_DESTRUCTOR_MACRO
00186
00187 if(temp) delete temp;
00188 }
00189
00190 void SwapMain::reset()
00191 {
00192 temp = 0;
00193 }
00194
00195
00196 char* SwapMain::plugin_title() { return N_("Swap channels"); }
00197 int SwapMain::is_synthesis() { return 1; }
00198 int SwapMain::is_realtime() { return 1; }
00199
00200
00201 SHOW_GUI_MACRO(SwapMain, SwapThread)
00202 NEW_PICON_MACRO(SwapMain)
00203 SET_STRING_MACRO(SwapMain)
00204 RAISE_WINDOW_MACRO(SwapMain)
00205
00206 int SwapMain::load_defaults()
00207 {
00208 char directory[1024], string[1024];
00209
00210 sprintf(directory, "%sswapchannels.rc", BCASTDIR);
00211
00212
00213 defaults = new BC_Hash(directory);
00214 defaults->load();
00215
00216 config.red = defaults->get("RED", config.red);
00217 config.green = defaults->get("GREEN", config.green);
00218 config.blue = defaults->get("BLUE", config.blue);
00219 config.alpha = defaults->get("ALPHA", config.alpha);
00220 return 0;
00221 }
00222
00223 int SwapMain::save_defaults()
00224 {
00225 defaults->update("RED", config.red);
00226 defaults->update("GREEN", config.green);
00227 defaults->update("BLUE", config.blue);
00228 defaults->update("ALPHA", config.alpha);
00229 defaults->save();
00230 return 0;
00231 }
00232
00233 void SwapMain::save_data(KeyFrame *keyframe)
00234 {
00235 FileXML output;
00236
00237
00238 output.set_shared_string(keyframe->data, MESSAGESIZE);
00239 output.tag.set_title("SWAPCHANNELS");
00240 output.tag.set_property("RED", config.red);
00241 output.tag.set_property("GREEN", config.green);
00242 output.tag.set_property("BLUE", config.blue);
00243 output.tag.set_property("ALPHA", config.alpha);
00244 output.append_tag();
00245 output.tag.set_title("/SWAPCHANNELS");
00246 output.append_tag();
00247 output.append_newline();
00248 output.terminate_string();
00249
00250 }
00251
00252 void SwapMain::read_data(KeyFrame *keyframe)
00253 {
00254 FileXML input;
00255
00256 input.set_shared_string(keyframe->data, strlen(keyframe->data));
00257
00258 int result = 0;
00259
00260 while(!result)
00261 {
00262 result = input.read_tag();
00263
00264 if(!result)
00265 {
00266 if(input.tag.title_is("SWAPCHANNELS"))
00267 {
00268 config.red = input.tag.get_property("RED", config.red);
00269 config.green = input.tag.get_property("GREEN", config.green);
00270 config.blue = input.tag.get_property("BLUE", config.blue);
00271 config.alpha = input.tag.get_property("ALPHA", config.alpha);
00272 }
00273 }
00274 }
00275 }
00276
00277 void SwapMain::update_gui()
00278 {
00279 if(thread)
00280 {
00281 load_configuration();
00282 thread->window->lock_window();
00283 thread->window->red->set_text(output_to_text(config.red));
00284 thread->window->green->set_text(output_to_text(config.green));
00285 thread->window->blue->set_text(output_to_text(config.blue));
00286 thread->window->alpha->set_text(output_to_text(config.alpha));
00287 thread->window->unlock_window();
00288 }
00289 }
00290
00291
00292 void SwapMain::load_configuration()
00293 {
00294 KeyFrame *prev_keyframe;
00295 prev_keyframe = get_prev_keyframe(get_source_position());
00296
00297 read_data(prev_keyframe);
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 #define MAXMINSRC(src, max) \
00324 (src == MAX_SRC ? max : 0)
00325
00326 #define SWAP_CHANNELS(type, max, components) \
00327 { \
00328 int h = input_ptr->get_h(); \
00329 int w = input_ptr->get_w(); \
00330 int red = config.red; \
00331 int green = config.green; \
00332 int blue = config.blue; \
00333 int alpha = config.alpha; \
00334 \
00335 if(components == 3) \
00336 { \
00337 if(red == ALPHA_SRC) red = MAX_SRC; \
00338 if(green == ALPHA_SRC) green = MAX_SRC; \
00339 if(blue == ALPHA_SRC) blue = MAX_SRC; \
00340 } \
00341 \
00342 \
00343 for(int i = 0; i < h; i++) \
00344 { \
00345 type *inrow = (type*)input_ptr->get_rows()[i]; \
00346 type *outrow = (type*)temp->get_rows()[i]; \
00347 \
00348 for(int j = 0; j < w; j++) \
00349 { \
00350 if(red < 4) \
00351 *outrow++ = *(inrow + red); \
00352 else \
00353 *outrow++ = MAXMINSRC(red, max); \
00354 \
00355 if(green < 4) \
00356 *outrow++ = *(inrow + green); \
00357 else \
00358 *outrow++ = MAXMINSRC(green, max); \
00359 \
00360 if(blue < 4) \
00361 *outrow++ = *(inrow + blue); \
00362 else \
00363 *outrow++ = MAXMINSRC(blue, max); \
00364 \
00365 if(components == 4) \
00366 { \
00367 if(alpha < 4) \
00368 *outrow++ = *(inrow + alpha); \
00369 else \
00370 *outrow++ = MAXMINSRC(alpha, max); \
00371 } \
00372 \
00373 inrow += components; \
00374 } \
00375 } \
00376 \
00377 output_ptr->copy_from(temp); \
00378 }
00379
00380
00381
00382 int SwapMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
00383 {
00384 load_configuration();
00385
00386
00387 if(!temp)
00388 temp = new VFrame(0,
00389 input_ptr->get_w(),
00390 input_ptr->get_h(),
00391 input_ptr->get_color_model());
00392
00393 switch(input_ptr->get_color_model())
00394 {
00395 case BC_RGB_FLOAT:
00396 SWAP_CHANNELS(float, 1, 3);
00397 break;
00398 case BC_RGBA_FLOAT:
00399 SWAP_CHANNELS(float, 1, 4);
00400 break;
00401 case BC_RGB888:
00402 case BC_YUV888:
00403 SWAP_CHANNELS(unsigned char, 0xff, 3);
00404 break;
00405 case BC_RGBA8888:
00406 case BC_YUVA8888:
00407 SWAP_CHANNELS(unsigned char, 0xff, 4);
00408 break;
00409 case BC_RGB161616:
00410 case BC_YUV161616:
00411 SWAP_CHANNELS(uint16_t, 0xffff, 3);
00412 break;
00413 case BC_RGBA16161616:
00414 case BC_YUVA16161616:
00415 SWAP_CHANNELS(uint16_t, 0xffff, 4);
00416 break;
00417 }
00418
00419
00420 return 0;
00421 }
00422
00423
00424 char* SwapMain::output_to_text(int value)
00425 {
00426 switch(value)
00427 {
00428 case RED_SRC:
00429 return _("Red");
00430 break;
00431 case GREEN_SRC:
00432 return _("Green");
00433 break;
00434 case BLUE_SRC:
00435 return _("Blue");
00436 break;
00437 case ALPHA_SRC:
00438 return _("Alpha");
00439 break;
00440 case NO_SRC:
00441 return _("0%");
00442 break;
00443 case MAX_SRC:
00444 return _("100%");
00445 break;
00446 default:
00447 return "";
00448 break;
00449 }
00450 }
00451
00452 int SwapMain::text_to_output(char *text)
00453 {
00454 if(!strcmp(text, _("Red"))) return RED_SRC;
00455 if(!strcmp(text, _("Green"))) return GREEN_SRC;
00456 if(!strcmp(text, _("Blue"))) return BLUE_SRC;
00457 if(!strcmp(text, _("Alpha"))) return ALPHA_SRC;
00458 if(!strcmp(text, _("0%"))) return NO_SRC;
00459 if(!strcmp(text, _("100%"))) return MAX_SRC;
00460 return 0;
00461 }
00462
00463