X-Git-Url: https://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fplugins%2Fedge%2Fedge.C;h=14311130aaa168ad1863d548f0be047a7a04d82e;hb=b2eb290b3f6e5c233393017aa152e67c76243130;hp=98120bf3b1a3d0c4cadb32fe222ee4a36a870535;hpb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/plugins/edge/edge.C b/cinelerra-5.1/plugins/edge/edge.C index 98120bf3..14311130 100644 --- a/cinelerra-5.1/plugins/edge/edge.C +++ b/cinelerra-5.1/plugins/edge/edge.C @@ -1,21 +1,21 @@ /* * CINELERRA * Copyright (C) 1997-2015 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 "affine.h" @@ -28,8 +28,6 @@ #include "transportque.inc" #include -// Edge detection from the Gimp - REGISTER_PLUGIN(Edge) EdgeConfig::EdgeConfig() @@ -48,12 +46,8 @@ void EdgeConfig::copy_from(EdgeConfig &that) this->amount = that.amount; } -void EdgeConfig::interpolate( - EdgeConfig &prev, - EdgeConfig &next, - long prev_frame, - long next_frame, - long current_frame) +void EdgeConfig::interpolate( EdgeConfig &prev, EdgeConfig &next, + long prev_frame, long next_frame, long current_frame) { copy_from(next); } @@ -68,16 +62,16 @@ Edge::Edge(PluginServer *server) : PluginVClient(server) { engine = 0; - temp = 0; + dst = 0; } Edge::~Edge() { - if(engine) delete engine; - if(temp) delete temp; + delete engine; + delete dst; } -const char* Edge::plugin_title() { return _("Edge"); } +const char* Edge::plugin_title() { return N_("Edge"); } int Edge::is_realtime() { return 1; } NEW_WINDOW_MACRO(Edge, EdgeWindow); @@ -88,7 +82,7 @@ void Edge::save_data(KeyFrame *keyframe) FileXML output; // cause data to be stored directly in text - output.set_shared_output(keyframe->get_data(), MESSAGESIZE); + output.set_shared_output(keyframe->xbuf); output.tag.set_title("EDGE"); output.tag.set_property("AMOUNT", config.amount); @@ -103,27 +97,16 @@ void Edge::save_data(KeyFrame *keyframe) void Edge::read_data(KeyFrame *keyframe) { FileXML input; - - input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data())); - + input.set_shared_input(keyframe->xbuf); int result = 0; - while(!result) - { - result = input.read_tag(); - - if(!result) - { - if(input.tag.title_is("EDGE")) - { - config.amount = input.tag.get_property("AMOUNT", config.amount); - config.limits(); - - } - else - if(input.tag.title_is("/EDGE")) - { - result = 1; - } + + while( !(result=input.read_tag()) ) { + if(input.tag.title_is("EDGE")) { + config.amount = input.tag.get_property("AMOUNT", config.amount); + config.limits(); + } + else if(input.tag.title_is("/EDGE")) { + result = 1; } } @@ -131,61 +114,41 @@ void Edge::read_data(KeyFrame *keyframe) void Edge::update_gui() { - if(thread) - { - if(load_configuration()) - { - thread->window->lock_window("Edge::update_gui"); - EdgeWindow *window = (EdgeWindow*)thread->window; - window->flush(); - thread->window->unlock_window(); - } - } + if( !thread ) return; + if( !load_configuration() ) return; + thread->window->lock_window("Edge::update_gui"); + EdgeWindow *window = (EdgeWindow*)thread->window; + window->flush(); + thread->window->unlock_window(); } - - -int Edge::process_buffer(VFrame *frame, - int64_t start_position, - double frame_rate) +int Edge::process_buffer(VFrame *frame, int64_t start_position, double frame_rate) { - -// int need_reconfigure = load_configuration(); - int w = frame->get_w(); - int h = frame->get_h(); - int color_model = frame->get_color_model(); + src = frame; + w = src->get_w(), h = src->get_h(); + color_model = frame->get_color_model(); + bpp = BC_CModels::calculate_pixelsize(color_model); + + if( dst && (dst->get_w() != w || dst->get_h() != h || + dst->get_color_model() != color_model ) ) { + delete dst; dst = 0; + } + if( !dst ) + dst = new VFrame(w, h, color_model, 0); -// initialize everything - if(!temp) - { + if( !engine ) engine = new EdgeEngine(this, PluginClient::get_project_smp() + 1, PluginClient::get_project_smp() + 1); - - temp = new VFrame(0, - -1, - w, - h, - color_model, - -1); - - } - - read_frame(frame, - 0, - start_position, - frame_rate, - 0); - engine->process(temp, frame); - frame->copy_from(temp); + read_frame(frame, 0, start_position, frame_rate, 0); + engine->process_packages(); + frame->copy_from(dst); return 0; } - - EdgePackage::EdgePackage() : LoadPackage() { @@ -196,147 +159,64 @@ EdgeUnit::EdgeUnit(EdgeEngine *server) : LoadClient(server) this->server = server; } -EdgeUnit::~EdgeUnit() -{ -} - - -float EdgeUnit::edge_detect(float *data, float max, int do_max) +EdgeUnit::~EdgeUnit() { - const float v_kernel[9] = { 0, 0, 0, - 0, 2, -2, - 0, 2, -2 }; - const float h_kernel[9] = { 0, 0, 0, - 0, -2, -2, - 0, 2, 2 }; - int i; - float v_grad, h_grad; - float amount = server->plugin->config.amount; - - for (i = 0, v_grad = 0, h_grad = 0; i < 9; i++) - { - v_grad += v_kernel[i] * data[i]; - h_grad += h_kernel[i] * data[i]; - } - - float result = sqrt (v_grad * v_grad * amount + - h_grad * h_grad * amount); - if(do_max) - CLAMP(result, 0, max); - return result; } #define EDGE_MACRO(type, max, components, is_yuv) \ { \ - type **input_rows = (type**)server->src->get_rows(); \ - type **output_rows = (type**)server->dst->get_rows(); \ int comps = MIN(components, 3); \ - for(int y = pkg->y1; y < pkg->y2; y++) \ - { \ - for(int x = 0; x < w; x++) \ - { \ -/* kernel is in bounds */ \ - if(y > 0 && x > 0 && y < h - 2 && x < w - 2) \ - { \ - for(int chan = 0; chan < comps; chan++) \ - { \ -/* load kernel */ \ - for(int kernel_y = 0; kernel_y < 3; kernel_y++) \ - { \ - for(int kernel_x = 0; kernel_x < 3; kernel_x++) \ - { \ - kernel[3 * kernel_y + kernel_x] = \ - (type)input_rows[y - 1 + kernel_y][(x - 1 + kernel_x) * components + chan]; \ - \ - if(is_yuv && chan > 0) \ - { \ - kernel[3 * kernel_y + kernel_x] -= 0x80; \ - } \ - \ - } \ - } \ -/* do the business */ \ - output_rows[y][x * components + chan] = edge_detect(kernel, max, sizeof(type) < 4); \ - if(is_yuv && chan > 0) \ - { \ - output_rows[y][x * components + chan] += 0x80; \ - } \ - \ - } \ - \ - if(components == 4) output_rows[y][x * components + 3] = \ - input_rows[y][x * components + 3]; \ + float amounts = amount * amount / max; \ + for( int y=y1; y h_grad ) h_grad = dh; \ + float dv = r0[0] - r0[components] + r1[0] - r1[components]; \ + if( (dv*=dv) > v_grad ) v_grad = dv; \ + } \ + float v = (h_grad + v_grad) * amounts; \ + type t = v > max ? max : v; \ + if( is_yuv ) { \ + *op++ = t; *op++ = 0x80; *op++ = 0x80; \ } \ - else \ - { \ - for(int chan = 0; chan < comps; chan++) \ - { \ -/* load kernel */ \ - for(int kernel_y = 0; kernel_y < 3; kernel_y++) \ - { \ - for(int kernel_x = 0; kernel_x < 3; kernel_x++) \ - { \ - int in_y = y - 1 + kernel_y; \ - int in_x = x - 1 + kernel_x; \ - CLAMP(in_y, 0, h - 1); \ - CLAMP(in_x, 0, w - 1); \ - kernel[3 * kernel_y + kernel_x] = \ - (type)input_rows[in_y][in_x * components + chan]; \ - if(is_yuv && chan > 0) \ - { \ - kernel[3 * kernel_y + kernel_x] -= 0x80; \ - } \ - } \ - } \ -/* do the business */ \ - output_rows[y][x * components + chan] = edge_detect(kernel, max, sizeof(type) < 4); \ - if(is_yuv && chan > 0) \ - { \ - output_rows[y][x * components + chan] += 0x80; \ - } \ - } \ - if(components == 4) output_rows[y][x * components + 3] = \ - input_rows[y][x * components + 3]; \ + else { \ + for( int i=0; iplugin->src; + uint8_t **input_rows = src->get_rows(); + VFrame *dst = server->plugin->dst; + uint8_t **output_rows = dst->get_rows(); + float amount = (float)server->plugin->config.amount; EdgePackage *pkg = (EdgePackage*)package; - int w = server->src->get_w(); - int h = server->src->get_h(); - float kernel[9]; - - switch(server->src->get_color_model()) - { - case BC_RGB_FLOAT: - EDGE_MACRO(float, 1, 3, 0); - break; - case BC_RGBA_FLOAT: - EDGE_MACRO(float, 1, 4, 0); - break; - case BC_RGB888: - EDGE_MACRO(unsigned char, 0xff, 3, 0); - break; - case BC_YUV888: - EDGE_MACRO(unsigned char, 0xff, 3, 1); - break; - case BC_RGBA8888: - EDGE_MACRO(unsigned char, 0xff, 4, 0); - break; - case BC_YUVA8888: - EDGE_MACRO(unsigned char, 0xff, 4, 1); - break; + int x1 = 0, x2 = server->plugin->w-1, bpp = server->plugin->bpp; + int y1 = pkg->y1, y2 = pkg->y2; + + switch( server->plugin->color_model ) { + case BC_RGB_FLOAT: EDGE_MACRO(float, 1, 3, 0); + case BC_RGBA_FLOAT: EDGE_MACRO(float, 1, 4, 0); + case BC_RGB888: EDGE_MACRO(unsigned char, 0xff, 3, 0); + case BC_YUV888: EDGE_MACRO(unsigned char, 0xff, 3, 1); + case BC_RGBA8888: EDGE_MACRO(unsigned char, 0xff, 4, 0); + case BC_YUVA8888: EDGE_MACRO(unsigned char, 0xff, 4, 1); } } -EdgeEngine::EdgeEngine(Edge *plugin, - int total_clients, - int total_packages) +EdgeEngine::EdgeEngine(Edge *plugin, int total_clients, int total_packages) : LoadServer(total_clients, total_packages) { this->plugin = plugin; @@ -349,22 +229,15 @@ EdgeEngine::~EdgeEngine() void EdgeEngine::init_packages() { - for(int i = 0; i < get_total_packages(); i++) - { - EdgePackage *pkg = (EdgePackage*)get_package(i); - pkg->y1 = plugin->get_input(0)->get_h() * i / LoadServer::get_total_packages(); - pkg->y2 = plugin->get_input(0)->get_h() * (i + 1) / LoadServer::get_total_packages(); + int y = 0, h1 = plugin->h-1; + for(int i = 0; i < get_total_packages(); ) { + EdgePackage *pkg = (EdgePackage*)get_package(i++); + pkg->y1 = y; + y = h1 * i / LoadServer::get_total_packages(); + pkg->y2 = y; } } -void EdgeEngine::process(VFrame *dst, VFrame *src) -{ - this->dst = dst; - this->src = src; - process_packages(); -} - - LoadClient* EdgeEngine::new_client() { return new EdgeUnit(this); @@ -375,4 +248,3 @@ LoadPackage* EdgeEngine::new_package() return new EdgePackage; } -