X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;ds=sidebyside;f=cinelerra-5.1%2Fplugins%2Fperspective%2Fperspective.C;fp=cinelerra-5.1%2Fplugins%2Fperspective%2Fperspective.C;h=6e2c7f9758503a162de8eccfa951dfa8cdebad2c;hb=680d2000be2db33da1e2733461854158067f5862;hp=e270bc8c86627df86c5ea3e37a014a9a8dc2b59b;hpb=e94d765d190f22937e955f0e6ff9b70d167786f8;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/plugins/perspective/perspective.C b/cinelerra-5.1/plugins/perspective/perspective.C index e270bc8c..6e2c7f97 100644 --- a/cinelerra-5.1/plugins/perspective/perspective.C +++ b/cinelerra-5.1/plugins/perspective/perspective.C @@ -36,15 +36,12 @@ REGISTER_PLUGIN(PerspectiveMain) PerspectiveConfig::PerspectiveConfig() { - x1 = 0; - y1 = 0; - x2 = 100; - y2 = 0; - x3 = 100; - y3 = 100; - x4 = 0; - y4 = 100; + x1 = 0; y1 = 0; + x2 = 100; y2 = 0; + x3 = 100; y3 = 100; + x4 = 0; y4 = 100; mode = AffineEngine::PERSPECTIVE; + smoothing = AffineEngine::AF_DEFAULT; window_w = 400; window_h = 450; current_point = 0; @@ -63,31 +60,26 @@ int PerspectiveConfig::equivalent(PerspectiveConfig &that) EQUIV(x4, that.x4) && EQUIV(y4, that.y4) && mode == that.mode && + smoothing == that.smoothing && forward == that.forward; } void PerspectiveConfig::copy_from(PerspectiveConfig &that) { - x1 = that.x1; - y1 = that.y1; - x2 = that.x2; - y2 = that.y2; - x3 = that.x3; - y3 = that.y3; - x4 = that.x4; - y4 = that.y4; + x1 = that.x1; y1 = that.y1; + x2 = that.x2; y2 = that.y2; + x3 = that.x3; y3 = that.y3; + x4 = that.x4; y4 = that.y4; mode = that.mode; + smoothing = that.smoothing; window_w = that.window_w; window_h = that.window_h; current_point = that.current_point; forward = that.forward; } -void PerspectiveConfig::interpolate(PerspectiveConfig &prev, - PerspectiveConfig &next, - int64_t prev_frame, - int64_t next_frame, - int64_t current_frame) +void PerspectiveConfig::interpolate(PerspectiveConfig &prev, PerspectiveConfig &next, + int64_t prev_frame, int64_t next_frame, int64_t current_frame) { double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame); double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame); @@ -100,28 +92,15 @@ void PerspectiveConfig::interpolate(PerspectiveConfig &prev, this->x4 = prev.x4 * prev_scale + next.x4 * next_scale; this->y4 = prev.y4 * prev_scale + next.y4 * next_scale; mode = prev.mode; + smoothing = prev.smoothing; forward = prev.forward; } - - - - - - - - - - - PerspectiveWindow::PerspectiveWindow(PerspectiveMain *plugin) : PluginClientWindow(plugin, - plugin->config.window_w, - plugin->config.window_h, - plugin->config.window_w, - plugin->config.window_h, - 0) + plugin->config.window_w, plugin->config.window_h, + plugin->config.window_w, plugin->config.window_h, 0) { //printf("PerspectiveWindow::PerspectiveWindow 1 %d %d\n", plugin->config.window_w, plugin->config.window_h); this->plugin = plugin; @@ -136,69 +115,43 @@ void PerspectiveWindow::create_objects() int x = 10, y = 10; add_subwindow(canvas = new PerspectiveCanvas(plugin, - x, - y, - get_w() - 20, - get_h() - 140)); + x, y, get_w() - 20, get_h() - 140)); canvas->set_cursor(CROSS_CURSOR, 0, 0); y += canvas->get_h() + 10; add_subwindow(new BC_Title(x, y, _("Current X:"))); x += 80; this->x = new PerspectiveCoord(this, - plugin, - x, - y, - plugin->get_current_x(), - 1); + plugin, x, y, plugin->get_current_x(), 1); this->x->create_objects(); x += 140; add_subwindow(new BC_Title(x, y, _("Y:"))); x += 20; this->y = new PerspectiveCoord(this, - plugin, - x, - y, - plugin->get_current_y(), - 0); + plugin, x, y, plugin->get_current_y(), 0); this->y->create_objects(); - y += 30; - x = 10; - add_subwindow(new PerspectiveReset(plugin, x, y)); - x += 100; + x = 10; y += 30; add_subwindow(mode_perspective = new PerspectiveMode(plugin, - x, - y, - AffineEngine::PERSPECTIVE, - _("Perspective"))); + x, y, AffineEngine::PERSPECTIVE, _("Perspective"))); x += 120; add_subwindow(mode_sheer = new PerspectiveMode(plugin, - x, - y, - AffineEngine::SHEER, - _("Sheer"))); - x = 110; - y += 30; + x, y, AffineEngine::SHEER, _("Sheer"))); + x += 100; + add_subwindow(affine = new PerspectiveAffine(this, x, y)); + affine->create_objects(); + x = 10; y += 30; add_subwindow(mode_stretch = new PerspectiveMode(plugin, - x, - y, - AffineEngine::STRETCH, - _("Stretch"))); + x, y, AffineEngine::STRETCH, _("Stretch"))); + x += 120; + add_subwindow(new PerspectiveReset(plugin, x, y)); update_canvas(); - y += 30; - x = 10; + x = 10; y += 30; add_subwindow(new BC_Title(x, y, _("Perspective direction:"))); x += 170; add_subwindow(forward = new PerspectiveDirection(plugin, - x, - y, - 1, - _("Forward"))); + x, y, 1, _("Forward"))); x += 100; add_subwindow(reverse = new PerspectiveDirection(plugin, - x, - y, - 0, - _("Reverse"))); + x, y, 0, _("Reverse"))); show_window(); } @@ -216,29 +169,19 @@ void PerspectiveWindow::update_canvas() int x1, y1, x2, y2, x3, y3, x4, y4; calculate_canvas_coords(x1, y1, x2, y2, x3, y3, x4, y4); -// printf("PerspectiveWindow::update_canvas %d,%d %d,%d %d,%d %d,%d\n", -// x1, -// y1, -// x2, -// y2, -// x3, -// y3, -// x4, -// y4); +//printf("PerspectiveWindow::update_canvas %d,%d %d,%d %d,%d %d,%d\n", +// x1, y1, x2, y2, x3, y3, x4, y4); // Draw divisions canvas->set_color(WHITE); #define DIVISIONS 10 - for(int i = 0; i <= DIVISIONS; i++) - { -// latitude - canvas->draw_line( + for( int i=0; i<=DIVISIONS; ++i ) { + canvas->draw_line( // latitude x1 + (x4 - x1) * i / DIVISIONS, y1 + (y4 - y1) * i / DIVISIONS, x2 + (x3 - x2) * i / DIVISIONS, y2 + (y3 - y2) * i / DIVISIONS); -// longitude - canvas->draw_line( + canvas->draw_line( // longitude x1 + (x2 - x1) * i / DIVISIONS, y1 + (y2 - y1) * i / DIVISIONS, x4 + (x3 - x4) * i / DIVISIONS, @@ -285,20 +228,14 @@ void PerspectiveWindow::update_coord() y->update(plugin->get_current_y()); } -void PerspectiveWindow::calculate_canvas_coords(int &x1, - int &y1, - int &x2, - int &y2, - int &x3, - int &y3, - int &x4, - int &y4) +void PerspectiveWindow::calculate_canvas_coords( + int &x1, int &y1, int &x2, int &y2, + int &x3, int &y3, int &x4, int &y4) { int w = canvas->get_w() - 1; int h = canvas->get_h() - 1; - if(plugin->config.mode == AffineEngine::PERSPECTIVE || - plugin->config.mode == AffineEngine::STRETCH) - { + if( plugin->config.mode == AffineEngine::PERSPECTIVE || + plugin->config.mode == AffineEngine::STRETCH ) { x1 = (int)(plugin->config.x1 * w / 100); y1 = (int)(plugin->config.y1 * h / 100); x2 = (int)(plugin->config.x2 * w / 100); @@ -308,8 +245,7 @@ void PerspectiveWindow::calculate_canvas_coords(int &x1, x4 = (int)(plugin->config.x4 * w / 100); y4 = (int)(plugin->config.y4 * h / 100); } - else - { + else { x1 = (int)(plugin->config.x1 * w) / 100; y1 = 0; x2 = x1 + w; @@ -322,13 +258,8 @@ void PerspectiveWindow::calculate_canvas_coords(int &x1, } - - PerspectiveCanvas::PerspectiveCanvas(PerspectiveMain *plugin, - int x, - int y, - int w, - int h) + int x, int y, int w, int h) : BC_SubWindow(x, y, w, h, BLACK) { this->plugin = plugin; @@ -336,12 +267,9 @@ PerspectiveCanvas::PerspectiveCanvas(PerspectiveMain *plugin, } - - int PerspectiveCanvas::button_press_event() { - if(is_event_win() && cursor_inside()) - { + if( is_event_win() && cursor_inside() ) { // Set current point int x1, y1, x2, y2, x3, y3, x4, y4; int cursor_x = get_cursor_x(); @@ -360,40 +288,32 @@ int PerspectiveCanvas::button_press_event() // y3); float min = distance1; plugin->config.current_point = 0; - if(distance2 < min) - { + if( distance2 < min ) { min = distance2; plugin->config.current_point = 1; } - if(distance3 < min) - { + if( distance3 < min ) { min = distance3; plugin->config.current_point = 2; } - if(distance4 < min) - { + if( distance4 < min ) { min = distance4; plugin->config.current_point = 3; } - if(plugin->config.mode == AffineEngine::SHEER) - { - if(plugin->config.current_point == 1) + if( plugin->config.mode == AffineEngine::SHEER ) { + if( plugin->config.current_point == 1 ) plugin->config.current_point = 0; - else - if(plugin->config.current_point == 2) + else if( plugin->config.current_point == 2 ) plugin->config.current_point = 3; } start_cursor_x = cursor_x; start_cursor_y = cursor_y; - if(alt_down() || shift_down()) - { - if(alt_down()) - state = PerspectiveCanvas::DRAG_FULL; - else - state = PerspectiveCanvas::ZOOM; - + if( alt_down() || shift_down() ) { + state = alt_down() ? + PerspectiveCanvas::DRAG_FULL : + PerspectiveCanvas::ZOOM; // Get starting positions start_x1 = plugin->config.x1; start_y1 = plugin->config.y1; @@ -404,10 +324,8 @@ int PerspectiveCanvas::button_press_event() start_x4 = plugin->config.x4; start_y4 = plugin->config.y4; } - else - { + else { state = PerspectiveCanvas::DRAG; - // Get starting positions start_x1 = plugin->get_current_x(); start_y1 = plugin->get_current_y(); @@ -422,8 +340,7 @@ int PerspectiveCanvas::button_press_event() int PerspectiveCanvas::button_release_event() { - if(state != PerspectiveCanvas::NONE) - { + if( state != PerspectiveCanvas::NONE ) { state = PerspectiveCanvas::NONE; return 1; } @@ -432,18 +349,14 @@ int PerspectiveCanvas::button_release_event() int PerspectiveCanvas::cursor_motion_event() { - if(state != PerspectiveCanvas::NONE) - { + if( state != PerspectiveCanvas::NONE ) { int w = get_w() - 1; int h = get_h() - 1; - if(state == PerspectiveCanvas::DRAG) - { + if( state == PerspectiveCanvas::DRAG ) { plugin->set_current_x((float)(get_cursor_x() - start_cursor_x) / w * 100 + start_x1); plugin->set_current_y((float)(get_cursor_y() - start_cursor_y) / h * 100 + start_y1); } - else - if(state == PerspectiveCanvas::DRAG_FULL) - { + else if( state == PerspectiveCanvas::DRAG_FULL ) { plugin->config.x1 = ((float)(get_cursor_x() - start_cursor_x) / w * 100 + start_x1); plugin->config.y1 = ((float)(get_cursor_y() - start_cursor_y) / h * 100 + start_y1); plugin->config.x2 = ((float)(get_cursor_x() - start_cursor_x) / w * 100 + start_x2); @@ -453,17 +366,9 @@ int PerspectiveCanvas::cursor_motion_event() plugin->config.x4 = ((float)(get_cursor_x() - start_cursor_x) / w * 100 + start_x4); plugin->config.y4 = ((float)(get_cursor_y() - start_cursor_y) / h * 100 + start_y4); } - else - if(state == PerspectiveCanvas::ZOOM) - { - float center_x = (start_x1 + - start_x2 + - start_x3 + - start_x4) / 4; - float center_y = (start_y1 + - start_y2 + - start_y3 + - start_y4) / 4; + else if( state == PerspectiveCanvas::ZOOM ) { + float center_x = (start_x1 + start_x2 + start_x3 + start_x4) / 4; + float center_y = (start_y1 + start_y2 + start_y3 + start_y4) / 4; float zoom = (float)(get_cursor_y() - start_cursor_y + 640) / 640; plugin->config.x1 = center_x + (start_x1 - center_x) * zoom; plugin->config.y1 = center_y + (start_y1 - center_y) * zoom; @@ -484,16 +389,8 @@ int PerspectiveCanvas::cursor_motion_event() } - - - - PerspectiveCoord::PerspectiveCoord(PerspectiveWindow *gui, - PerspectiveMain *plugin, - int x, - int y, - float value, - int is_x) + PerspectiveMain *plugin, int x, int y, float value, int is_x) : BC_TumbleTextBox(gui, value, (float)-100, (float)200, x, y, 100) { this->plugin = plugin; @@ -502,39 +399,28 @@ PerspectiveCoord::PerspectiveCoord(PerspectiveWindow *gui, int PerspectiveCoord::handle_event() { - if(is_x) - plugin->set_current_x(atof(get_text())); + float v = atof(get_text()); + if( is_x ) + plugin->set_current_x(v); else - plugin->set_current_y(atof(get_text())); + plugin->set_current_y(v); ((PerspectiveWindow*)plugin->thread->window)->update_canvas(); plugin->send_configure_change(); return 1; } - - - - - - -PerspectiveReset::PerspectiveReset(PerspectiveMain *plugin, - int x, - int y) +PerspectiveReset::PerspectiveReset(PerspectiveMain *plugin, int x, int y) : BC_GenericButton(x, y, _("Reset")) { this->plugin = plugin; } int PerspectiveReset::handle_event() { - plugin->config.x1 = 0; - plugin->config.y1 = 0; - plugin->config.x2 = 100; - plugin->config.y2 = 0; - plugin->config.x3 = 100; - plugin->config.y3 = 100; - plugin->config.x4 = 0; - plugin->config.y4 = 100; + plugin->config.x1 = 0; plugin->config.y1 = 0; + plugin->config.x2 = 100; plugin->config.y2 = 0; + plugin->config.x3 = 100; plugin->config.y3 = 100; + plugin->config.x4 = 0; plugin->config.y4 = 100; ((PerspectiveWindow*)plugin->thread->window)->update_canvas(); ((PerspectiveWindow*)plugin->thread->window)->update_coord(); plugin->send_configure_change(); @@ -542,20 +428,8 @@ int PerspectiveReset::handle_event() } - - - - - - - - - PerspectiveMode::PerspectiveMode(PerspectiveMain *plugin, - int x, - int y, - int value, - char *text) + int x, int y, int value, char *text) : BC_Radial(x, y, plugin->config.mode == value, text) { this->plugin = plugin; @@ -571,8 +445,6 @@ int PerspectiveMode::handle_event() } - - PerspectiveDirection::PerspectiveDirection(PerspectiveMain *plugin, int x, int y, @@ -592,15 +464,53 @@ int PerspectiveDirection::handle_event() } +int PerspectiveAffineItem::handle_event() +{ + ((PerspectiveAffine *)get_popup_menu())->update(id); + return 1; +} +PerspectiveAffine::PerspectiveAffine(PerspectiveWindow *gui, int x, int y) + : BC_PopupMenu(x, y, 100, "", 1) +{ + this->gui = gui; + affine_modes[AffineEngine::AF_DEFAULT] = _("default"); + affine_modes[AffineEngine::AF_NEAREST] = _("Nearest"); + affine_modes[AffineEngine::AF_LINEAR] = _("Linear"); + affine_modes[AffineEngine::AF_CUBIC] = _("Cubic"); + mode = -1; +} +PerspectiveAffine::~PerspectiveAffine() +{ + int id = total_items(); + while( --id >= 0 ) + remove_item(get_item(id)); + for( int id=0; idplugin->config.smoothing, 0); +} - - - - - - +void PerspectiveAffine::update(int mode, int send) +{ + if( this->mode == mode ) return; + this->mode = mode; + set_text(affine_modes[mode]); + gui->plugin->config.smoothing = mode; + if( send ) gui->plugin->send_configure_change(); +} PerspectiveMain::PerspectiveMain(PluginServer *server) : PluginVClient(server) @@ -621,27 +531,23 @@ const char* PerspectiveMain::plugin_title() { return _("Perspective"); } int PerspectiveMain::is_realtime() { return 1; } - NEW_WINDOW_MACRO(PerspectiveMain, PerspectiveWindow) LOAD_CONFIGURATION_MACRO(PerspectiveMain, PerspectiveConfig) - - void PerspectiveMain::update_gui() { - if(thread) - { + if( !thread ) return; //printf("PerspectiveMain::update_gui 1\n"); - thread->window->lock_window(); + thread->window->lock_window(); + PerspectiveWindow *gui = (PerspectiveWindow*)thread->window; //printf("PerspectiveMain::update_gui 2\n"); - load_configuration(); - ((PerspectiveWindow*)thread->window)->update_coord(); - ((PerspectiveWindow*)thread->window)->update_mode(); - ((PerspectiveWindow*)thread->window)->update_canvas(); - thread->window->unlock_window(); + load_configuration(); + gui->update_coord(); + gui->update_mode(); + gui->update_canvas(); + thread->window->unlock_window(); //printf("PerspectiveMain::update_gui 3\n"); - } } @@ -666,6 +572,7 @@ void PerspectiveMain::save_data(KeyFrame *keyframe) output.tag.set_property("Y4", config.y4); output.tag.set_property("MODE", config.mode); + output.tag.set_property("SMOOTHING", config.smoothing); output.tag.set_property("FORWARD", config.forward); output.tag.set_property("WINDOW_W", config.window_w); output.tag.set_property("WINDOW_H", config.window_h); @@ -679,320 +586,187 @@ void PerspectiveMain::save_data(KeyFrame *keyframe) void PerspectiveMain::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("PERSPECTIVE")) - { - config.x1 = input.tag.get_property("X1", config.x1); - config.x2 = input.tag.get_property("X2", config.x2); - config.x3 = input.tag.get_property("X3", config.x3); - config.x4 = input.tag.get_property("X4", config.x4); - config.y1 = input.tag.get_property("Y1", config.y1); - config.y2 = input.tag.get_property("Y2", config.y2); - config.y3 = input.tag.get_property("Y3", config.y3); - config.y4 = input.tag.get_property("Y4", config.y4); - - config.mode = input.tag.get_property("MODE", config.mode); - config.forward = input.tag.get_property("FORWARD", config.forward); - config.window_w = input.tag.get_property("WINDOW_W", config.window_w); - config.window_h = input.tag.get_property("WINDOW_H", config.window_h); - } + while(!(result = input.read_tag()) ) { + if(input.tag.title_is("PERSPECTIVE")) { + config.x1 = input.tag.get_property("X1", config.x1); + config.x2 = input.tag.get_property("X2", config.x2); + config.x3 = input.tag.get_property("X3", config.x3); + config.x4 = input.tag.get_property("X4", config.x4); + config.y1 = input.tag.get_property("Y1", config.y1); + config.y2 = input.tag.get_property("Y2", config.y2); + config.y3 = input.tag.get_property("Y3", config.y3); + config.y4 = input.tag.get_property("Y4", config.y4); + + config.mode = input.tag.get_property("MODE", config.mode); + config.smoothing = input.tag.get_property("SMOOTHING", config.smoothing); + config.forward = input.tag.get_property("FORWARD", config.forward); + config.window_w = input.tag.get_property("WINDOW_W", config.window_w); + config.window_h = input.tag.get_property("WINDOW_H", config.window_h); } } } float PerspectiveMain::get_current_x() { - switch(config.current_point) - { - case 0: - return config.x1; - break; - case 1: - return config.x2; - break; - case 2: - return config.x3; - break; - case 3: - return config.x4; - break; + switch( config.current_point ) { + case 0: return config.x1; + case 1: return config.x2; + case 2: return config.x3; + case 3: return config.x4; } return 0; } float PerspectiveMain::get_current_y() { - switch(config.current_point) - { - case 0: - return config.y1; - break; - case 1: - return config.y2; - break; - case 2: - return config.y3; - break; - case 3: - return config.y4; - break; + switch( config.current_point ) { + case 0: return config.y1; + case 1: return config.y2; + case 2: return config.y3; + case 3: return config.y4; } return 0; } void PerspectiveMain::set_current_x(float value) { - switch(config.current_point) - { - case 0: - config.x1 = value; - break; - case 1: - config.x2 = value; - break; - case 2: - config.x3 = value; - break; - case 3: - config.x4 = value; - break; + switch( config.current_point ) { + case 0: config.x1 = value; break; + case 1: config.x2 = value; break; + case 2: config.x3 = value; break; + case 3: config.x4 = value; break; } } void PerspectiveMain::set_current_y(float value) { - switch(config.current_point) - { - case 0: - config.y1 = value; - break; - case 1: - config.y2 = value; - break; - case 2: - config.y3 = value; - break; - case 3: - config.y4 = value; - break; + switch( config.current_point ) { + case 0: config.y1 = value; break; + case 1: config.y2 = value; break; + case 2: config.y3 = value; break; + case 3: config.y4 = value; break; } } - - int PerspectiveMain::process_buffer(VFrame *frame, - int64_t start_position, - double frame_rate) + int64_t start_position, double frame_rate) { /*int need_reconfigure =*/ load_configuration(); + int smoothing = config.smoothing; +// default smoothing uses opengl if possible + int use_opengl = smoothing != AffineEngine::AF_DEFAULT ? 0 : +// Opengl does some funny business with stretching. + config.mode == AffineEngine::PERSPECTIVE || + config.mode == AffineEngine::SHEER ? get_use_opengl() : 0; + + read_frame(frame, 0, start_position, frame_rate, use_opengl); // Do nothing + if( EQUIV(config.x1, 0) && EQUIV(config.y1, 0) && - EQUIV(config.x2, 100) && EQUIV(config.y2, 0) && - EQUIV(config.x3, 100) && EQUIV(config.y3, 100) && - EQUIV(config.x4, 0) && EQUIV(config.y4, 100)) - { - read_frame(frame, - 0, - start_position, - frame_rate, - get_use_opengl()); + EQUIV(config.x2, 100) && EQUIV(config.y2, 0) && + EQUIV(config.x3, 100) && EQUIV(config.y3, 100) && + EQUIV(config.x4, 0) && EQUIV(config.y4, 100) ) return 1; + + if( !engine ) { + int cpus = get_project_smp() + 1; + engine = new AffineEngine(cpus, cpus); } + engine->set_interpolation(smoothing); -// Opengl does some funny business with stretching. - int use_opengl = get_use_opengl() && - (config.mode == AffineEngine::PERSPECTIVE || - config.mode == AffineEngine::SHEER); - read_frame(frame, - 0, - start_position, - frame_rate, - use_opengl); - - if(!engine) engine = new AffineEngine(get_project_smp() + 1, - get_project_smp() + 1); - - if(use_opengl) + if( use_opengl ) return run_opengl(); - - this->input = frame; this->output = frame; - int w = frame->get_w(); - int h = frame->get_h(); + int w = frame->get_w(), need_w = w; + int h = frame->get_h(), need_h = h; int color_model = frame->get_color_model(); - - if(temp && - config.mode == AffineEngine::STRETCH && - (temp->get_w() != w * AFFINE_OVERSAMPLE || - temp->get_h() != h * AFFINE_OVERSAMPLE)) - { - delete temp; - temp = 0; - } - else - if(temp && - (config.mode == AffineEngine::PERSPECTIVE || - config.mode == AffineEngine::SHEER) && - (temp->get_w() != w || - temp->get_h() != h)) - { - delete temp; - temp = 0; - } - - if(config.mode == AffineEngine::STRETCH) - { - if(!temp) - { - temp = new VFrame(0, - -1, - w * AFFINE_OVERSAMPLE, - h * AFFINE_OVERSAMPLE, - color_model, - -1); - } - temp->clear_frame(); - } - - if(config.mode == AffineEngine::PERSPECTIVE || - config.mode == AffineEngine::SHEER) - { - if(frame->get_rows()[0] == frame->get_rows()[0]) - { - if(!temp) - { - temp = new VFrame(0, - -1, - w, - h, - color_model, - -1); + switch( config.mode ) { + case AffineEngine::STRETCH: + need_w *= AFFINE_OVERSAMPLE; + need_h *= AFFINE_OVERSAMPLE; + case AffineEngine::SHEER: + case AffineEngine::PERSPECTIVE: + if( temp ) { + if( temp->get_w() != need_w || temp->get_h() != need_h || + temp->get_color_model() != color_model ) { + delete temp; temp = 0; } - temp->copy_from(input); - input = temp; } + if( !temp ) + temp = new VFrame(need_w, need_h, color_model); + break; + } + switch( config.mode ) { + case AffineEngine::STRETCH: + temp->clear_frame(); + break; + case AffineEngine::PERSPECTIVE: + case AffineEngine::SHEER: + temp->copy_from(input); + input = temp; output->clear_frame(); + break; + default: + delete temp; temp = 0; + break; } - - engine->process(output, - input, - temp, - config.mode, - config.x1, - config.y1, - config.x2, - config.y2, - config.x3, - config.y3, - config.x4, - config.y4, + engine->process(output, input, temp, config.mode, + config.x1, config.y1, config.x2, config.y2, + config.x3, config.y3, config.x4, config.y4, config.forward); - - - // Resample - if(config.mode == AffineEngine::STRETCH) - { -#define RESAMPLE(type, components, chroma_offset) \ -{ \ - for(int i = 0; i < h; i++) \ - { \ - type *out_row = (type*)output->get_rows()[i]; \ - type *in_row1 = (type*)temp->get_rows()[i * AFFINE_OVERSAMPLE]; \ - type *in_row2 = (type*)temp->get_rows()[i * AFFINE_OVERSAMPLE + 1]; \ - for(int j = 0; j < w; j++) \ - { \ - out_row[0] = (in_row1[0] + \ - in_row1[components] + \ - in_row2[0] + \ - in_row2[components]) / \ - AFFINE_OVERSAMPLE / \ - AFFINE_OVERSAMPLE; \ - out_row[1] = ((in_row1[1] + \ - in_row1[components + 1] + \ - in_row2[1] + \ - in_row2[components + 1]) - \ - chroma_offset * \ - AFFINE_OVERSAMPLE * \ - AFFINE_OVERSAMPLE) / \ - AFFINE_OVERSAMPLE / \ - AFFINE_OVERSAMPLE + \ - chroma_offset; \ - out_row[2] = ((in_row1[2] + \ - in_row1[components + 2] + \ - in_row2[2] + \ - in_row2[components + 2]) - \ - chroma_offset * \ - AFFINE_OVERSAMPLE * \ - AFFINE_OVERSAMPLE) / \ - AFFINE_OVERSAMPLE / \ - AFFINE_OVERSAMPLE + \ - chroma_offset; \ - if(components == 4) \ - { \ - out_row[3] = (in_row1[3] + \ - in_row1[components + 3] + \ - in_row2[3] + \ - in_row2[components + 3]) / \ - AFFINE_OVERSAMPLE / \ - AFFINE_OVERSAMPLE; \ - } \ - out_row += components; \ - in_row1 += components * AFFINE_OVERSAMPLE; \ - in_row2 += components * AFFINE_OVERSAMPLE; \ - } \ - } \ -} - - switch(frame->get_color_model()) - { - case BC_RGB_FLOAT: - RESAMPLE(float, 3, 0) - break; - case BC_RGB888: - RESAMPLE(unsigned char, 3, 0) - break; - case BC_RGBA_FLOAT: - RESAMPLE(float, 4, 0) - break; - case BC_RGBA8888: - RESAMPLE(unsigned char, 4, 0) - break; - case BC_YUV888: - RESAMPLE(unsigned char, 3, 0x80) - break; - case BC_YUVA8888: - RESAMPLE(unsigned char, 4, 0x80) - break; - case BC_RGB161616: - RESAMPLE(uint16_t, 3, 0) - break; - case BC_RGBA16161616: - RESAMPLE(uint16_t, 4, 0) - break; - case BC_YUV161616: - RESAMPLE(uint16_t, 3, 0x8000) - break; - case BC_YUVA16161616: - RESAMPLE(uint16_t, 4, 0x8000) - break; + if( config.mode == AffineEngine::STRETCH ) { + +#define RESAMPLE(tag, type, components, chroma_offset) \ +case tag: { \ + int os = AFFINE_OVERSAMPLE, os2 = os*os; \ + for( int i=0; iget_rows()[i]; \ + type *in_row1 = (type*)temp->get_rows()[i * os]; \ + type *in_row2 = (type*)temp->get_rows()[i * os + 1]; \ + for( int j=0; jget_color_model() ) { + RESAMPLE( BC_RGB_FLOAT, float, 3, 0 ); + RESAMPLE( BC_RGB888, unsigned char, 3, 0 ); + RESAMPLE( BC_RGBA_FLOAT, float, 4, 0 ); + RESAMPLE( BC_RGBA8888, unsigned char, 4, 0 ); + RESAMPLE( BC_YUV888, unsigned char, 3, 0x80 ); + RESAMPLE( BC_YUVA8888, unsigned char, 4, 0x80 ); + RESAMPLE( BC_RGB161616, uint16_t, 3, 0 ); + RESAMPLE( BC_RGBA16161616, uint16_t, 4, 0 ); + RESAMPLE( BC_YUV161616, uint16_t, 3, 0x8000 ); + RESAMPLE( BC_YUVA16161616, uint16_t, 4, 0x8000 ); } } @@ -1004,26 +778,12 @@ int PerspectiveMain::handle_opengl() { #ifdef HAVE_GL engine->set_opengl(1); - engine->process(get_output(), - get_output(), - get_output(), - config.mode, - config.x1, - config.y1, - config.x2, - config.y2, - config.x3, - config.y3, - config.x4, - config.y4, + engine->process(get_output(), get_output(), get_output(), config.mode, + config.x1, config.y1, config.x2, config.y2, + config.x3, config.y3, config.x4, config.y4, config.forward); engine->set_opengl(0); return 0; #endif } - - - - -