X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fplugins%2Fswapchannels%2Fswapchannels.C;fp=cinelerra-5.1%2Fplugins%2Fswapchannels%2Fswapchannels.C;h=bbfd4e6aa721990a50f6c99a39215f0b8db8b923;hb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;hp=0000000000000000000000000000000000000000;hpb=52fcc46226f9df46f9ce9d0566dc568455a7db0b;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/plugins/swapchannels/swapchannels.C b/cinelerra-5.1/plugins/swapchannels/swapchannels.C new file mode 100644 index 00000000..bbfd4e6a --- /dev/null +++ b/cinelerra-5.1/plugins/swapchannels/swapchannels.C @@ -0,0 +1,516 @@ + +/* + * CINELERRA + * Copyright (C) 2008 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "bcdisplayinfo.h" +#include "clip.h" +#include "bchash.h" +#include "filexml.h" +#include "language.h" +#include "swapchannels.h" +#include "vframe.h" + + + +#include +#include + + + + + + +REGISTER_PLUGIN(SwapMain) + + + + + + + + +SwapConfig::SwapConfig() +{ + red = RED_SRC; + green = GREEN_SRC; + blue = BLUE_SRC; + alpha = ALPHA_SRC; +} + + +int SwapConfig::equivalent(SwapConfig &that) +{ + return (red == that.red && + green == that.green && + blue == that.blue && + alpha == that.alpha); +} + +void SwapConfig::copy_from(SwapConfig &that) +{ + red = that.red; + green = that.green; + blue = that.blue; + alpha = that.alpha; +} + + + + + + + + +SwapWindow::SwapWindow(SwapMain *plugin) + : PluginClientWindow(plugin, + 250, + 170, + 250, + 170, + 0) +{ + this->plugin = plugin; +} + +SwapWindow::~SwapWindow() +{ +} + + +void SwapWindow::create_objects() +{ + int x = 10, y = 10; + int margin = 30; + + add_subwindow(new BC_Title(x, y, _("Swap channels"))); + y += margin; + add_subwindow(new BC_Title(x + 160, y + 5, _("-> Red"))); + add_subwindow(red = new SwapMenu(plugin, &(plugin->config.red), x, y)); + red->create_objects(); + y += margin; + add_subwindow(new BC_Title(x + 160, y + 5, _("-> Green"))); + add_subwindow(green = new SwapMenu(plugin, &(plugin->config.green), x, y)); + green->create_objects(); + y += margin; + add_subwindow(new BC_Title(x + 160, y + 5, _("-> Blue"))); + add_subwindow(blue = new SwapMenu(plugin, &(plugin->config.blue), x, y)); + blue->create_objects(); + y += margin; + add_subwindow(new BC_Title(x + 160, y + 5, _("-> Alpha"))); + add_subwindow(alpha = new SwapMenu(plugin, &(plugin->config.alpha), x, y)); + alpha->create_objects(); + + show_window(); + flush(); +} + + + + + + + + + +SwapMenu::SwapMenu(SwapMain *client, int *output, int x, int y) + : BC_PopupMenu(x, y, 150, client->output_to_text(*output)) +{ + this->client = client; + this->output = output; +} + +int SwapMenu::handle_event() +{ + client->send_configure_change(); + return 1; +} + +void SwapMenu::create_objects() +{ + add_item(new SwapItem(this, client->output_to_text(RED_SRC))); + add_item(new SwapItem(this, client->output_to_text(GREEN_SRC))); + add_item(new SwapItem(this, client->output_to_text(BLUE_SRC))); + add_item(new SwapItem(this, client->output_to_text(ALPHA_SRC))); + add_item(new SwapItem(this, client->output_to_text(NO_SRC))); + add_item(new SwapItem(this, client->output_to_text(MAX_SRC))); +} + + + + +SwapItem::SwapItem(SwapMenu *menu, const char *title) + : BC_MenuItem(title) +{ + this->menu = menu; +} + +int SwapItem::handle_event() +{ + menu->set_text(get_text()); + *(menu->output) = menu->client->text_to_output(get_text()); + menu->handle_event(); + return 1; +} + + + + + + + + + + + + + + + + + + + + +SwapMain::SwapMain(PluginServer *server) + : PluginVClient(server) +{ + reset(); + +} + +SwapMain::~SwapMain() +{ + + +// if(temp) delete temp; +} + +void SwapMain::reset() +{ + temp = 0; +} + + +const char* SwapMain::plugin_title() { return _("Swap channels"); } +int SwapMain::is_synthesis() { return 1; } +int SwapMain::is_realtime() { return 1; } + +NEW_WINDOW_MACRO(SwapMain, SwapWindow) + + +void SwapMain::save_data(KeyFrame *keyframe) +{ + FileXML output; + +// cause data to be stored directly in text + output.set_shared_output(keyframe->get_data(), MESSAGESIZE); + output.tag.set_title("SWAPCHANNELS"); + output.tag.set_property("RED", config.red); + output.tag.set_property("GREEN", config.green); + output.tag.set_property("BLUE", config.blue); + output.tag.set_property("ALPHA", config.alpha); + output.append_tag(); + output.tag.set_title("/SWAPCHANNELS"); + output.append_tag(); + output.append_newline(); + output.terminate_string(); +// data is now in *text +} + +void SwapMain::read_data(KeyFrame *keyframe) +{ + FileXML input; + + input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data())); + + int result = 0; + + while(!result) + { + result = input.read_tag(); + + if(!result) + { + if(input.tag.title_is("SWAPCHANNELS")) + { + config.red = input.tag.get_property("RED", config.red); + config.green = input.tag.get_property("GREEN", config.green); + config.blue = input.tag.get_property("BLUE", config.blue); + config.alpha = input.tag.get_property("ALPHA", config.alpha); + } + } + } +} + +void SwapMain::update_gui() +{ + if(thread) + { + load_configuration(); + thread->window->lock_window(); + ((SwapWindow*)thread->window)->red->set_text(output_to_text(config.red)); + ((SwapWindow*)thread->window)->green->set_text(output_to_text(config.green)); + ((SwapWindow*)thread->window)->blue->set_text(output_to_text(config.blue)); + ((SwapWindow*)thread->window)->alpha->set_text(output_to_text(config.alpha)); + thread->window->unlock_window(); + } +} + + +int SwapMain::load_configuration() +{ + KeyFrame *prev_keyframe; + prev_keyframe = get_prev_keyframe(get_source_position()); + + read_data(prev_keyframe); + return 1; +} + + + + + + + + + + + + + + + + + + + + + + + + +#define MAXMINSRC(src, min, max) \ + (src == MAX_SRC ? max : min) + +#define SWAP_CHANNELS(type, min, max, components) \ +{ \ + int h = frame->get_h(); \ + int w = frame->get_w(); \ + int red = config.red; \ + int green = config.green; \ + int blue = config.blue; \ + int alpha = config.alpha; \ + \ + if(components == 3) \ + { \ + if(red == ALPHA_SRC) red = MAX_SRC; \ + if(green == ALPHA_SRC) green = MAX_SRC; \ + if(blue == ALPHA_SRC) blue = MAX_SRC; \ + } \ + \ + \ + for(int i = 0; i < h; i++) \ + { \ + type *inrow = (type*)frame->get_rows()[i]; \ + type *outrow = (type*)temp->get_rows()[i]; \ + \ + for(int j = 0; j < w; j++) \ + { \ + if(red < 4) \ + *outrow++ = *(inrow + red); \ + else \ + *outrow++ = MAXMINSRC(red, 0, max); \ + \ + if(green < 4) \ + *outrow++ = *(inrow + green); \ + else \ + *outrow++ = MAXMINSRC(green, min, max); \ + \ + if(blue < 4) \ + *outrow++ = *(inrow + blue); \ + else \ + *outrow++ = MAXMINSRC(blue, min, max); \ + \ + if(components == 4) \ + { \ + if(alpha < 4) \ + *outrow++ = *(inrow + alpha); \ + else \ + *outrow++ = MAXMINSRC(alpha, 0, max); \ + } \ + \ + inrow += components; \ + } \ + } \ + \ + frame->copy_from(temp); \ +} + + + +int SwapMain::process_buffer(VFrame *frame, + int64_t start_position, + double frame_rate) +{ + load_configuration(); + + read_frame(frame, + 0, + start_position, + frame_rate, + get_use_opengl()); + + +// Use hardware + if(get_use_opengl()) + { + run_opengl(); + return 0; + } + + + temp = new_temp(frame->get_w(), + frame->get_h(), + frame->get_color_model()); + + switch(frame->get_color_model()) + { + case BC_RGB_FLOAT: + SWAP_CHANNELS(float, 0, 1, 3); + break; + case BC_RGBA_FLOAT: + SWAP_CHANNELS(float, 0, 1, 4); + break; + case BC_RGB888: + SWAP_CHANNELS(unsigned char, 0, 0xff, 3); + break; + case BC_YUV888: + SWAP_CHANNELS(unsigned char, 0x80, 0xff, 3); + break; + case BC_RGBA8888: + SWAP_CHANNELS(unsigned char, 0, 0xff, 4); + break; + case BC_YUVA8888: + SWAP_CHANNELS(unsigned char, 0x80, 0xff, 4); + break; + } + + + return 0; +} + + +const char* SwapMain::output_to_text(int value) +{ + switch(value) + { + case RED_SRC: + return _("Red"); + break; + case GREEN_SRC: + return _("Green"); + break; + case BLUE_SRC: + return _("Blue"); + break; + case ALPHA_SRC: + return _("Alpha"); + break; + case NO_SRC: + return "0%"; + break; + case MAX_SRC: + return "100%"; + break; + default: + return ""; + break; + } +} + +int SwapMain::text_to_output(const char *text) +{ + if(!strcmp(text, _("Red"))) return RED_SRC; + if(!strcmp(text, _("Green"))) return GREEN_SRC; + if(!strcmp(text, _("Blue"))) return BLUE_SRC; + if(!strcmp(text, _("Alpha"))) return ALPHA_SRC; + if(!strcmp(text, "0%")) return NO_SRC; + if(!strcmp(text, "100%")) return MAX_SRC; + return 0; +} + +int SwapMain::handle_opengl() +{ +#ifdef HAVE_GL + + char output_frag[BCTEXTLEN]; + sprintf(output_frag, + "uniform sampler2D tex;\n" + "uniform float chroma_offset;\n" + "void main()\n" + "{\n" + " vec4 in_color = texture2D(tex, gl_TexCoord[0].st);\n" + " vec4 out_color;\n"); + +#define COLOR_SWITCH(config, variable) \ + strcat(output_frag, " out_color." variable " = "); \ + switch(config) \ + { \ + case RED_SRC: strcat(output_frag, "in_color.r;\n"); break; \ + case GREEN_SRC: strcat(output_frag, "in_color.g;\n"); break; \ + case BLUE_SRC: strcat(output_frag, "in_color.b;\n"); break; \ + case ALPHA_SRC: strcat(output_frag, "in_color.a;\n"); break; \ + case NO_SRC: strcat(output_frag, "chroma_offset;\n"); break; \ + case MAX_SRC: strcat(output_frag, "1.0;\n"); break; \ + } + + + COLOR_SWITCH(config.red, "r"); + COLOR_SWITCH(config.green, "g"); + COLOR_SWITCH(config.blue, "b"); + COLOR_SWITCH(config.alpha, "a"); + + strcat(output_frag, + " gl_FragColor = out_color;\n" + "}\n"); + + get_output()->to_texture(); + get_output()->enable_opengl(); + get_output()->init_screen(); + get_output()->clear_pbuffer(); + get_output()->bind_texture(0); + + unsigned int shader_id = VFrame::make_shader(0, + output_frag, + 0); + glUseProgram(shader_id); + glUniform1i(glGetUniformLocation(shader_id, "tex"), 0); + glUniform1f(glGetUniformLocation(shader_id, "chroma_offset"), + BC_CModels::is_yuv(get_output()->get_color_model()) ? 0.5 : 0.0); + + get_output()->draw_texture(); + glUseProgram(0); + get_output()->set_opengl_state(VFrame::SCREEN); +#endif + return 0; +} + + +