+++ /dev/null
-
-/*
- * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
- *
- * 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 "bchash.h"
-#include "bcsignals.h"
-#include "clip.h"
-#include "filexml.h"
-#include "language.h"
-#include "lens.h"
-
-
-#include <string.h>
-
-
-
-
-REGISTER_PLUGIN(LensMain)
-
-
-
-
-LensConfig::LensConfig()
-{
- for(int i = 0; i < FOV_CHANNELS; i++)
- fov[i] = 1.0;
- aspect = 1.0;
- radius = 1.0;
- mode = LensConfig::SHRINK;
- center_x = 50.0;
- center_y = 50.0;
- draw_guides = 0;
-}
-
-int LensConfig::equivalent(LensConfig &that)
-{
- for(int i = 0; i < FOV_CHANNELS; i++)
- if(!EQUIV(fov[i], that.fov[i])) return 0;
- return EQUIV(aspect, that.aspect) &&
- EQUIV(radius, that.radius) &&
- EQUIV(center_x, that.center_x) &&
- EQUIV(center_y, that.center_y) &&
- mode == that.mode &&
- draw_guides == that.draw_guides;
-}
-
-void LensConfig::copy_from(LensConfig &that)
-{
- for(int i = 0; i < FOV_CHANNELS; i++)
- fov[i] = that.fov[i];
- aspect = that.aspect;
- radius = that.radius;
- mode = that.mode;
- center_x = that.center_x;
- center_y = that.center_y;
- draw_guides = that.draw_guides;
-}
-
-void LensConfig::interpolate(LensConfig &prev,
- LensConfig &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);
-
- for(int i = 0; i < FOV_CHANNELS; i++)
- fov[i] = prev.fov[i] * prev_scale + next.fov[i] * next_scale;
- aspect = prev.aspect * prev_scale + next.aspect * next_scale;
- radius = prev.radius * prev_scale + next.radius * next_scale;
- center_x = prev.center_x * prev_scale + next.center_x * next_scale;
- center_y = prev.center_y * prev_scale + next.center_y * next_scale;
- mode = prev.mode;
- draw_guides = prev.draw_guides;
-
- boundaries();
-}
-
-void LensConfig::boundaries()
-{
- CLAMP(center_x, 0.0, 99.0);
- CLAMP(center_y, 0.0, 99.0);
- for(int i = 0; i < FOV_CHANNELS; i++)
- CLAMP(fov[i], 0.0, 1.0);
- CLAMP(aspect, 0.3, 3.0);
- CLAMP(radius, 0.3, 3.0);
-}
-
-
-
-
-LensSlider::LensSlider(LensMain *client,
- LensGUI *gui,
- LensText *text,
- float *output,
- int x,
- int y,
- float min,
- float max)
- : BC_FSlider(x, y, 0, 200, 200, min, max, *output)
-{
- this->gui = gui;
- this->client = client;
- this->output = output;
- this->text = text;
- set_precision(0.01);
-}
-
-int LensSlider::handle_event()
-{
- float prev_output = *output;
- *output = get_value();
- text->update(*output);
-
- float difference = *output - prev_output;
- int is_fov = 0;
-
- if(client->lock)
- {
- for(int i = 0; i < FOV_CHANNELS; i++)
- {
- if(output == &client->config.fov[i])
- {
- is_fov = 1;
- break;
- }
- }
-
- if(is_fov)
- {
- for(int i = 0; i < FOV_CHANNELS; i++)
- {
- if(output != &client->config.fov[i])
- {
- client->config.fov[i] += difference;
- client->config.boundaries();
- gui->fov_slider[i]->update(client->config.fov[i]);
- gui->fov_text[i]->update(client->config.fov[i]);
- }
- }
- }
- }
-
- client->send_configure_change();
- return 1;
-}
-
-
-
-LensText::LensText(LensMain *client,
- LensGUI *gui,
- LensSlider *slider,
- float *output,
- int x,
- int y)
- : BC_TextBox(x, y, 100, 1, *output)
-{
- this->gui = gui;
- this->client = client;
- this->output = output;
- this->slider = slider;
-}
-
-int LensText::handle_event()
-{
- float prev_output = *output;
- *output = atof(get_text());
- slider->update(*output);
-
- float difference = *output - prev_output;
- int is_fov = 0;
-
- if(client->lock)
- {
- for(int i = 0; i < FOV_CHANNELS; i++)
- {
- if(output == &client->config.fov[i])
- {
- is_fov = 1;
- break;
- }
- }
-
- if(is_fov)
- {
- for(int i = 0; i < FOV_CHANNELS; i++)
- {
- if(output != &client->config.fov[i])
- {
- client->config.fov[i] += difference;
- client->config.boundaries();
- gui->fov_slider[i]->update(client->config.fov[i]);
- gui->fov_text[i]->update(client->config.fov[i]);
- }
- }
- }
- }
-
- client->send_configure_change();
- return 1;
-}
-
-
-
-LensToggle::LensToggle(LensMain *client,
- int *output,
- int x,
- int y,
- const char *text)
- : BC_CheckBox(x, y, *output, text)
-{
- this->output = output;
- this->client = client;
-}
-
-int LensToggle::handle_event()
-{
- *output = get_value();
- client->send_configure_change();
- return 1;
-}
-
-
-
-
-
-
-
-
-
-
-LensMode::LensMode(LensMain *plugin,
- LensGUI *gui,
- int x,
- int y)
- : BC_PopupMenu(x,
- y,
- calculate_w(gui),
- "",
- 1)
-{
- this->plugin = plugin;
- this->gui = gui;
-}
-
-int LensMode::handle_event()
-{
- plugin->config.mode = from_text(get_text());
- plugin->send_configure_change();
- return 1;
-
-}
-
-void LensMode::create_objects()
-{
- add_item(new BC_MenuItem(to_text(LensConfig::SHRINK)));
- add_item(new BC_MenuItem(to_text(LensConfig::STRETCH)));
- add_item(new BC_MenuItem(to_text(LensConfig::RECTILINEAR_STRETCH)));
- add_item(new BC_MenuItem(to_text(LensConfig::RECTILINEAR_SHRINK)));
- update(plugin->config.mode);
-}
-
-void LensMode::update(int mode)
-{
- char string[BCTEXTLEN];
- sprintf(string, "%s", to_text(mode));
- set_text(string);
-}
-
-int LensMode::calculate_w(LensGUI *gui)
-{
- int result = 0;
- result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(LensConfig::STRETCH)));
- result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(LensConfig::SHRINK)));
- result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(LensConfig::RECTILINEAR_STRETCH)));
- result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(LensConfig::RECTILINEAR_SHRINK)));
- return result + 50;
-}
-
-int LensMode::from_text(char *text)
-{
- if(!strcmp(text, _("Sphere Stretch"))) return LensConfig::STRETCH;
- else
- if(!strcmp(text, _("Sphere Shrink"))) return LensConfig::SHRINK;
- else
- if(!strcmp(text, _("Rectilinear Stretch"))) return LensConfig::RECTILINEAR_STRETCH;
- else
- if(!strcmp(text, _("Rectilinear Shrink"))) return LensConfig::RECTILINEAR_SHRINK;
- return LensConfig::STRETCH;
-}
-
-const char* LensMode::to_text(int mode)
-{
- switch(mode)
- {
- case LensConfig::STRETCH:
- return _("Sphere Stretch");
- break;
- case LensConfig::SHRINK:
- return _("Sphere Shrink");
- break;
- case LensConfig::RECTILINEAR_STRETCH:
- return _("Rectilinear Stretch");
- break;
- case LensConfig::RECTILINEAR_SHRINK:
- return _("Rectilinear Shrink");
- break;
- }
- return _("Stretch");
-}
-
-
-
-
-
-// LensPresets::LensPresets(LensMain *plugin,
-// LensGUI *gui,
-// int x,
-// int y,
-// int w)
-// : BC_PopupMenu(x,
-// y,
-// w,
-// "",
-// 1)
-// {
-// this->plugin = plugin;
-// this->gui = gui;
-// }
-//
-// int LensPresets::handle_event()
-// {
-// return 1;
-// }
-//
-// void LensPresets::create_objects()
-// {
-// // Remove existing items
-// int total = total_items();
-// for(int i = 0; i < total; i++)
-// {
-// BC_MenuItem *item = get_item(0);
-// remove_item(item);
-// }
-//
-// // Create current items
-// plugin->load_presets();
-// for(int i = 0; i < plugin->presets.total; i++)
-// {
-// add_item(new BC_MenuItem(plugin->presets.values[i]->title));
-// }
-//
-// // Update text
-// if(plugin->current_preset >= 0 &&
-// plugin->current_preset < plugin->presets.total)
-// {
-// set_text(plugin->presets.values[plugin->current_preset]->title);
-// }
-// else
-// {
-// set_text("None");
-// }
-// }
-//
-// int LensPresets::from_text(LensMain *plugin, char *text)
-// {
-// }
-//
-// char* LensPresets::to_text(LensMain *plugin, int preset)
-// {
-// }
-//
-// void LensPresets::update(int preset)
-// {
-// }
-//
-//
-//
-//
-//
-//
-// LensSavePreset::LensSavePreset(LensMain *plugin,
-// LensGUI *gui,
-// int x,
-// int y)
-// : BC_GenericButton(x, y, "Save Preset")
-// {
-// this->plugin = plugin;
-// this->gui = gui;
-// }
-//
-// int LensSavePreset::handle_event()
-// {
-// }
-//
-//
-//
-//
-//
-//
-//
-// LensDeletePreset::LensDeletePreset(LensMain *plugin,
-// LensGUI *gui,
-// int x,
-// int y)
-// : BC_GenericButton(x, y, "Delete Preset")
-// {
-// }
-//
-// int LensDeletePreset::handle_event()
-// {
-// }
-//
-//
-//
-//
-//
-//
-//
-// LensPresetText::LensPresetText(LensMain *plugin,
-// LensGUI *gui,
-// int x,
-// int y,
-// int w)
-// : BC_TextBox(x, y, w, 1, "")
-// {
-// this->plugin = plugin;
-// this->gui = gui;
-// }
-//
-// int LensPresetText::handle_event()
-// {
-// }
-
-
-
-
-
-
-
-
-
-
-
-
-
-LensGUI::LensGUI(LensMain *client)
- : PluginClientWindow(client,
- 350,
- 510,
- 350,
- 510,
- 0)
-{
- this->client = client;
-}
-
-LensGUI::~LensGUI()
-{
-}
-
-
-void LensGUI::create_objects()
-{
- int x = 10;
- int y = 10;
- int x1;
- BC_Title *title = 0;
- LensToggle *toggle;
-
- for(int i = 0; i < FOV_CHANNELS; i++)
- {
- switch(i)
- {
- case 0: add_tool(title = new BC_Title(x, y, _("R Field of View:"))); break;
- case 1: add_tool(title = new BC_Title(x, y, _("G Field of View:"))); break;
- case 2: add_tool(title = new BC_Title(x, y, _("B Field of View:"))); break;
- case 3: add_tool(title = new BC_Title(x, y, _("A Field of View:"))); break;
- }
-
- y += title->get_h() + 5;
- add_tool(fov_slider[i] = new LensSlider(client,
- this,
- 0,
- &client->config.fov[i],
- x,
- y,
- 0.0001,
- 1.0));
- x1 = x + fov_slider[i]->get_w() + 5;
- add_tool(fov_text[i] = new LensText(client,
- this,
- fov_slider[i],
- &client->config.fov[i],
- x1,
- y));
- fov_slider[i]->text = fov_text[i];
- y += fov_text[i]->get_h() + 5;
- }
-
- add_tool(toggle = new LensToggle(client,
- &client->lock,
- x,
- y,
- _("Lock")));
- y += toggle->get_h() + 10;
-
- BC_Bar *bar;
- add_tool(bar = new BC_Bar(x, y, get_w() - x * 2));
- y += bar->get_h() + 5;
-
- add_tool(title = new BC_Title(x, y, _("Aspect Ratio:")));
- y += title->get_h() + 5;
- add_tool(aspect_slider = new LensSlider(client,
- this,
- 0,
- &client->config.aspect,
- x,
- y,
- 0.333,
- 3.0));
- x1 = x + aspect_slider->get_w() + 5;
- add_tool(aspect_text = new LensText(client,
- this,
- aspect_slider,
- &client->config.aspect,
- x1,
- y));
- aspect_slider->text = aspect_text;
- y += aspect_text->get_h() + 5;
-
-
- add_tool(title = new BC_Title(x, y, _("Radius:")));
- y += title->get_h() + 5;
- add_tool(radius_slider = new LensSlider(client,
- this,
- 0,
- &client->config.radius,
- x,
- y,
- 0.333,
- 3.0));
- x1 = x + radius_slider->get_w() + 5;
- add_tool(radius_text = new LensText(client,
- this,
- radius_slider,
- &client->config.radius,
- x1,
- y));
- radius_slider->text = radius_text;
- y += radius_text->get_h() + 5;
-
-
- add_tool(title = new BC_Title(x, y, _("Center X:")));
- y += title->get_h() + 5;
- add_tool(centerx_slider = new LensSlider(client,
- this,
- 0,
- &client->config.center_x,
- x,
- y,
- 0.0,
- 99.0));
- x1 = x + centerx_slider->get_w() + 5;
- add_tool(centerx_text = new LensText(client,
- this,
- centerx_slider,
- &client->config.center_x,
- x1,
- y));
- centerx_slider->text = centerx_text;
- centerx_slider->set_precision(1.0);
- y += centerx_text->get_h() + 5;
-
-
- add_tool(title = new BC_Title(x, y, _("Center Y:")));
- y += title->get_h() + 5;
- add_tool(centery_slider = new LensSlider(client,
- this,
- 0,
- &client->config.center_y,
- x,
- y,
- 0.0,
- 99.0));
- x1 = x + centery_slider->get_w() + 5;
- add_tool(centery_text = new LensText(client,
- this,
- centery_slider,
- &client->config.center_y,
- x1,
- y));
- centery_slider->text = centery_text;
- centery_slider->set_precision(1.0);
- y += centery_text->get_h() + 10;
-
- add_tool(bar = new BC_Bar(x, y, get_w() - x * 2));
- y += bar->get_h() + 5;
-
-
-// add_tool(reverse = new LensToggle(client,
-// &client->config.reverse,
-// x,
-// y,
-// _("Reverse")));
-// y += reverse->get_h() + 5;
-
- add_tool(draw_guides = new LensToggle(client,
- &client->config.draw_guides,
- x,
- y,
- _("Draw center")));
- y += draw_guides->get_h() + 5;
-
-
- add_tool(title = new BC_Title(x, y, _("Mode:")));
- add_tool(mode = new LensMode(client,
- this,
- x + title->get_w() + 5,
- y));
- mode->create_objects();
- y += mode->get_h() + 5;
-
-
-// add_tool(title = new BC_Title(x, y, _("Preset:")));
-// add_tool(presets = new LensPresets(client,
-// this,
-// x + title->get_w() + 5,
-// y,
-// get_w() - x - title->get_w() - 50));
-// presets->create_objects();
-// y += presets->get_h() + 5;
-//
-// add_tool(save_preset = new LensSavePreset(client,
-// this,
-// x,
-// y));
-// add_tool(preset_text = new LensPresetText(client,
-// this,
-// x + save_preset->get_w() + 5,
-// y,
-// get_w() - x - save_preset->get_w() - 10));
-// y += preset_text->get_h() + 5;
-// add_tool(delete_preset = new LensDeletePreset(client,
-// this,
-// x,
-// y));
-
- show_window();
- flush();
-}
-
-
-
-
-
-
-
-LensMain::LensMain(PluginServer *server)
- : PluginVClient(server)
-{
-
- engine = 0;
- lock = 0;
- current_preset = -1;
-}
-
-LensMain::~LensMain()
-{
-
- delete engine;
- presets.remove_all_objects();
-}
-
-NEW_WINDOW_MACRO(LensMain, LensGUI)
-LOAD_CONFIGURATION_MACRO(LensMain, LensConfig)
-int LensMain::is_realtime() { return 1; }
-const char* LensMain::plugin_title() { return _("Lens"); }
-
-void LensMain::update_gui()
-{
- if(thread)
- {
- if(load_configuration())
- {
- ((LensGUI*)thread->window)->lock_window("LensMain::update_gui");
- for(int i = 0; i < FOV_CHANNELS; i++)
- {
- ((LensGUI*)thread->window)->fov_slider[i]->update(config.fov[i]);
- ((LensGUI*)thread->window)->fov_text[i]->update(config.fov[i]);
- }
- ((LensGUI*)thread->window)->aspect_slider->update(config.aspect);
- ((LensGUI*)thread->window)->aspect_text->update(config.aspect);
- ((LensGUI*)thread->window)->radius_slider->update(config.radius);
- ((LensGUI*)thread->window)->radius_text->update(config.radius);
- ((LensGUI*)thread->window)->centerx_slider->update(config.center_x);
- ((LensGUI*)thread->window)->centerx_text->update(config.center_x);
- ((LensGUI*)thread->window)->centery_slider->update(config.center_y);
- ((LensGUI*)thread->window)->centery_text->update(config.center_y);
- ((LensGUI*)thread->window)->mode->update(config.mode);
- ((LensGUI*)thread->window)->draw_guides->update(config.draw_guides);
- ((LensGUI*)thread->window)->unlock_window();
- }
- }
-}
-
-//void LensMain::save_presets()
-//{
-// char path[BCTEXTLEN], string[BCTEXTLEN];
-// sprintf(path, "%slenspresets.rc", BCASTDIR);
-// BC_Hash *defaults = new BC_Hash(path);
-//
-//// Save presets
-// defaults->update("TOTAL_PRESETS", presets.total);
-// for(int i = 0; i < presets.total; i++)
-// {
-// LensPreset *preset = presets.values[i];
-// sprintf(string, "TITLE_%d", i);
-// defaults->update(string, preset->title);
-//
-// for(int j = 0; j < FOV_CHANNELS; j++)
-// {
-// sprintf(string, "FOCAL_LENGTH_%d_%d", i, j);
-// defaults->update(string, preset->fov[j]);
-// }
-//
-// sprintf(string, "ASPECT_%d", i);
-// defaults->update(string, preset->aspect);
-// sprintf(string, "RADIUS_%d", i);
-// defaults->update(string, preset->radius);
-// sprintf(string, "MODE_%d", i);
-// defaults->update(string, preset->mode);
-// }
-//
-// defaults->save();
-// delete defaults;
-//}
-
-
-void LensMain::save_data(KeyFrame *keyframe)
-{
- FileXML output;
- char string[BCTEXTLEN];
-
-
-
-// cause data to be stored directly in text
- output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
- output.tag.set_title("LENS");
- for(int i = 0; i < FOV_CHANNELS; i++)
- {
- sprintf(string, "FOCAL_LENGTH%d", i);
- output.tag.set_property(string, config.fov[i]);
- }
- output.tag.set_property("ASPECT", config.aspect);
- output.tag.set_property("RADIUS", config.radius);
- output.tag.set_property("MODE", config.mode);
- output.tag.set_property("CENTER_X", config.center_x);
- output.tag.set_property("CENTER_Y", config.center_y);
- output.tag.set_property("DRAW_GUIDES", config.draw_guides);
- output.append_tag();
- output.tag.set_title("/LENS");
- output.append_tag();
- output.append_newline();
- output.terminate_string();
-
-}
-
-
-void LensMain::read_data(KeyFrame *keyframe)
-{
- FileXML input;
- char string[BCTEXTLEN];
-
-
- 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("LENS"))
- {
- for(int i = 0; i < FOV_CHANNELS; i++)
- {
- sprintf(string, "FOCAL_LENGTH%d", i);
- config.fov[i] = input.tag.get_property(string, config.fov[i]);
- }
- config.aspect = input.tag.get_property("ASPECT", config.aspect);
- config.radius = input.tag.get_property("RADIUS", config.radius);
- config.mode = input.tag.get_property("MODE", config.mode);
- config.center_x = input.tag.get_property("CENTER_X", config.center_x);
- config.center_y = input.tag.get_property("CENTER_Y", config.center_y);
- config.draw_guides = input.tag.get_property("DRAW_GUIDES", config.draw_guides);
- }
- }
- }
-}
-
-
-
-int LensMain::process_buffer(VFrame *frame,
- int64_t start_position,
- double frame_rate)
-{
- VFrame *input;
- load_configuration();
-
- if(get_use_opengl())
- {
- input = frame;
- }
- else
- {
- input = new_temp(frame->get_w(), frame->get_h(), frame->get_color_model());
- }
-
- read_frame(input,
- 0,
- start_position,
- frame_rate,
- get_use_opengl());
-
-
- if(get_use_opengl())
- {
- run_opengl();
- return 0;
- }
- else
- {
- if(!engine) engine = new LensEngine(this);
- engine->process_packages();
- if(config.draw_guides)
- {
-// Draw center
-#define CENTER_H 20
-#define CENTER_W 20
-#define DRAW_GUIDES(components, type, max) \
-{ \
- type **rows = (type**)get_output()->get_rows(); \
- if( (center_x >= 0 && center_x < w) || (center_y >= 0 && center_y < h) ) { \
- type *hrow = rows[center_y] + components * (center_x - CENTER_W / 2); \
- for(int i = center_x - CENTER_W / 2; i <= center_x + CENTER_W / 2; i++) \
- { \
- if(i >= 0 && i < w) { \
- hrow[0] = max - hrow[0]; \
- hrow[1] = max - hrow[1]; \
- hrow[2] = max - hrow[2]; \
- hrow += components; \
- } \
- } \
- \
- for(int i = center_y - CENTER_W / 2; i <= center_y + CENTER_W / 2; i++) \
- { \
- if(i >= 0 && i < h) { \
- type *vrow = rows[i] + center_x * components; \
- vrow[0] = max - vrow[0]; \
- vrow[1] = max - vrow[1]; \
- vrow[2] = max - vrow[2]; \
- } \
- } \
- } \
-}
-
- int w = get_output()->get_w();
- int h = get_output()->get_h();
- int center_x = (int)(config.center_x * w / 100);
- int center_y = (int)(config.center_y * h / 100);
- switch(get_output()->get_color_model())
- {
- case BC_RGB_FLOAT:
- DRAW_GUIDES(3, float, 1.0)
- break;
- case BC_RGBA_FLOAT:
- DRAW_GUIDES(4, float, 1.0)
- break;
- case BC_RGB888:
- DRAW_GUIDES(3, unsigned char, 0xff)
- break;
- case BC_RGBA8888:
- DRAW_GUIDES(4, unsigned char, 0xff)
- break;
- case BC_YUV888:
- DRAW_GUIDES(3, unsigned char, 0xff)
- break;
- case BC_YUVA8888:
- DRAW_GUIDES(4, unsigned char, 0xff)
- break;
- }
-
- }
- }
-
- return 0;
-}
-
-
-int LensMain::handle_opengl()
-{
-#ifdef HAVE_GL
- static const char *shrink_frag =
- "uniform sampler2D tex;\n"
- "uniform vec2 texture_extents;\n"
- "uniform vec2 image_extents;\n"
- "uniform vec2 aspect;\n"
- "uniform vec2 center_coord;\n"
- "uniform vec4 border_color;\n"
- "uniform vec4 r;\n"
- "uniform vec4 max_z;\n"
- "void main()\n"
- "{\n"
- " vec2 outcoord = gl_TexCoord[0].st * texture_extents;\n"
- " vec2 coord_diff = outcoord - center_coord;\n"
- " if(coord_diff.x == 0.0 && coord_diff.y == 0.0)\n"
- " {\n"
- " gl_FragColor = texture2D(tex, outcoord);\n"
- " }\n"
- " else\n"
- " {\n"
- " float z = sqrt(coord_diff.x * coord_diff.x +\n"
- " coord_diff.y * coord_diff.y);\n"
- " float a2 = atan(coord_diff.y, coord_diff.x);\n"
- " vec4 a1 = asin(vec4(z, z, z, z) / r);\n"
- " vec4 z_in = a1 * max_z * 2.0 / 3.14159;\n"
- " vec4 in_x;\n"
- " vec4 in_y;\n"
- " in_x = z_in * cos(a2) * aspect.x + center_coord.x;\n"
- " in_y = z_in * sin(a2) * aspect.y + center_coord.y;\n"
- " if(z > r.r || in_x.r < 0.0 || in_x.r >= image_extents.x || in_y.r < 0.0 || in_y.r >= image_extents.y)\n"
- " gl_FragColor.r = border_color.r;\n"
- " else\n"
- " gl_FragColor.r = texture2D(tex, vec2(in_x.r, in_y.r) / texture_extents).r;\n"
- " if(z > r.g || in_x.g < 0.0 || in_x.g >= image_extents.x || in_y.g < 0.0 || in_y.g >= image_extents.y)\n"
- " gl_FragColor.g = border_color.g;\n"
- " else\n"
- " gl_FragColor.g = texture2D(tex, vec2(in_x.g, in_y.g) / texture_extents).g;\n"
- " if(z > r.b || in_x.b < 0.0 || in_x.b >= image_extents.x || in_y.b < 0.0 || in_y.b >= image_extents.y)\n"
- " gl_FragColor.b = border_color.b;\n"
- " else\n"
- " gl_FragColor.b = texture2D(tex, vec2(in_x.b, in_y.b) / texture_extents).b;\n"
- " if(z > r.a || in_x.a < 0.0 || in_x.a >= image_extents.x || in_y.a < 0.0 || in_y.a >= image_extents.y)\n"
- " gl_FragColor.a = border_color.a;\n"
- " else\n"
- " gl_FragColor.a = texture2D(tex, vec2(in_x.a, in_y.a) / texture_extents).a;\n"
- " }\n"
- "}\n";
-
- static const char *stretch_frag =
- "uniform sampler2D tex;\n"
- "uniform vec2 texture_extents;\n"
- "uniform vec2 image_extents;\n"
- "uniform vec2 aspect;\n"
- "uniform vec2 center_coord;\n"
- "uniform vec4 border_color;\n"
- "uniform vec4 r;\n"
- "void main()\n"
- "{\n"
- " vec2 outcoord = gl_TexCoord[0].st * texture_extents;\n"
- " vec2 coord_diff = outcoord - center_coord;\n"
- " float z = sqrt(coord_diff.x * coord_diff.x +\n"
- " coord_diff.y * coord_diff.y);\n"
- " vec4 a1 = (vec4(z, z, z, z) / (3.14159 * r / 2.0)) * (3.14159 / 2.0);\n"
- " vec4 z_in = r * sin(a1);\n"
- " float a2;\n"
- " if(coord_diff.x == 0.0)\n"
- " {\n"
- " if(coord_diff.y < 0.0)\n"
- " a2 = 3.0 * 3.14159 / 2.0;\n"
- " else\n"
- " a2 = 3.14159 / 2.0;\n"
- " }\n"
- " else\n"
- " a2 = atan(coord_diff.y, coord_diff.x);\n"
- " vec4 in_x;\n"
- " vec4 in_y;\n"
- " in_x = z_in * cos(a2) * aspect.x + center_coord.x;\n"
- " in_y = z_in * sin(a2) * aspect.y + center_coord.y;\n"
- " if(in_x.r < 0.0 || in_x.r >= image_extents.x || in_y.r < 0.0 || in_y.r >= image_extents.y)\n"
- " gl_FragColor.r = border_color.r;\n"
- " else\n"
- " gl_FragColor.r = texture2D(tex, vec2(in_x.r, in_y.r) / texture_extents).r;\n"
- " if(in_x.g < 0.0 || in_x.g >= image_extents.x || in_y.g < 0.0 || in_y.g >= image_extents.y)\n"
- " gl_FragColor.g = border_color.g;\n"
- " else\n"
- " gl_FragColor.g = texture2D(tex, vec2(in_x.g, in_y.g) / texture_extents).g;\n"
- " if(in_x.b < 0.0 || in_x.b >= image_extents.x || in_y.b < 0.0 || in_y.b >= image_extents.y)\n"
- " gl_FragColor.b = border_color.b;\n"
- " else\n"
- " gl_FragColor.b = texture2D(tex, vec2(in_x.b, in_y.b) / texture_extents).b;\n"
- " if(in_x.a < 0.0 || in_x.a >= image_extents.x || in_y.a < 0.0 || in_y.a >= image_extents.y)\n"
- " gl_FragColor.a = border_color.a;\n"
- " else\n"
- " gl_FragColor.a = texture2D(tex, vec2(in_x.a, in_y.a) / texture_extents).a;\n"
- "}\n";
-
-
- static const char *rectilinear_stretch_frag =
- "uniform sampler2D tex;\n"
- "uniform vec2 texture_extents;\n"
- "uniform vec2 image_extents;\n"
- "uniform vec2 aspect;\n"
- "uniform vec2 center_coord;\n"
- "uniform vec4 border_color;\n"
- "uniform vec4 r;\n"
- "uniform float radius;\n"
- "void main()\n"
- "{\n"
- " vec2 outcoord = gl_TexCoord[0].st * texture_extents;\n"
- " vec2 coord_diff = outcoord - center_coord;\n"
- " float z = sqrt(coord_diff.x * coord_diff.x +\n"
- " coord_diff.y * coord_diff.y);\n"
- " vec4 radius1 = (vec4(z, z, z, z) / r) * 2.0 * radius;\n"
- " vec4 z_in = r * atan(radius1) / (3.14159 / 2.0);\n"
- "\n"
- " float angle;\n"
- " if(coord_diff.x == 0.0)\n"
- " {\n"
- " if(coord_diff.y < 0.0)\n"
- " angle = 3.0 * 3.14159 / 2.0;\n"
- " else\n"
- " angle = 3.14159 / 2.0;\n"
- " }\n"
- " else\n"
- " angle = atan(coord_diff.y, coord_diff.x);\n"
- " vec4 in_x;\n"
- " vec4 in_y;\n"
- "\n"
- " in_x = z_in * cos(angle) * aspect.x + center_coord.x;\n"
- " in_y = z_in * sin(angle) * aspect.y + center_coord.y;\n"
- " if(in_x.r < 0.0 || in_x.r >= image_extents.x || in_y.r < 0.0 || in_y.r >= image_extents.y)\n"
- " gl_FragColor.r = border_color.r;\n"
- " else\n"
- " gl_FragColor.r = texture2D(tex, vec2(in_x.r, in_y.r) / texture_extents).r;\n"
- " if(in_x.g < 0.0 || in_x.g >= image_extents.x || in_y.g < 0.0 || in_y.g >= image_extents.y)\n"
- " gl_FragColor.g = border_color.g;\n"
- " else\n"
- " gl_FragColor.g = texture2D(tex, vec2(in_x.g, in_y.g) / texture_extents).g;\n"
- " if(in_x.b < 0.0 || in_x.b >= image_extents.x || in_y.b < 0.0 || in_y.b >= image_extents.y)\n"
- " gl_FragColor.b = border_color.b;\n"
- " else\n"
- " gl_FragColor.b = texture2D(tex, vec2(in_x.b, in_y.b) / texture_extents).b;\n"
- " if(in_x.a < 0.0 || in_x.a >= image_extents.x || in_y.a < 0.0 || in_y.a >= image_extents.y)\n"
- " gl_FragColor.a = border_color.a;\n"
- " else\n"
- " gl_FragColor.a = texture2D(tex, vec2(in_x.a, in_y.a) / texture_extents).a;\n"
- "}\n";
-
- static const char *rectilinear_shrink_frag =
- "uniform sampler2D tex;\n"
- "uniform vec2 texture_extents;\n"
- "uniform vec2 image_extents;\n"
- "uniform vec2 aspect;\n"
- "uniform vec2 center_coord;\n"
- "uniform vec4 border_color;\n"
- "uniform vec4 r;\n"
- "uniform float radius;\n"
- "void main()\n"
- "{\n"
- " vec2 outcoord = gl_TexCoord[0].st * texture_extents;\n"
- " vec2 coord_diff = outcoord - center_coord;\n"
- " float z = sqrt(coord_diff.x * coord_diff.x +\n"
- " coord_diff.y * coord_diff.y);\n"
- " vec4 radius1 = (vec4(z, z, z, z) / r) * 2.0 * radius;\n"
- " vec4 z_in = r * atan(radius1) / (3.14159 / 2.0);\n"
- "\n"
- " float angle;\n"
- " if(coord_diff.x == 0.0)\n"
- " {\n"
- " if(coord_diff.y < 0.0)\n"
- " angle = 3.0 * 3.14159 / 2.0;\n"
- " else\n"
- " angle = 3.14159 / 2.0;\n"
- " }\n"
- " else\n"
- " angle = atan(coord_diff.y, coord_diff.x);\n"
- " vec4 in_x;\n"
- " vec4 in_y;\n"
- "\n"
- " in_x = z_in * cos(angle) * aspect.x + center_coord.x;\n"
- " in_y = z_in * sin(angle) * aspect.y + center_coord.y;\n"
- " if(in_x.r < 0.0 || in_x.r >= image_extents.x || in_y.r < 0.0 || in_y.r >= image_extents.y)\n"
- " gl_FragColor.r = border_color.r;\n"
- " else\n"
- " gl_FragColor.r = texture2D(tex, vec2(in_x.r, in_y.r) / texture_extents).r;\n"
- " if(in_x.g < 0.0 || in_x.g >= image_extents.x || in_y.g < 0.0 || in_y.g >= image_extents.y)\n"
- " gl_FragColor.g = border_color.g;\n"
- " else\n"
- " gl_FragColor.g = texture2D(tex, vec2(in_x.g, in_y.g) / texture_extents).g;\n"
- " if(in_x.b < 0.0 || in_x.b >= image_extents.x || in_y.b < 0.0 || in_y.b >= image_extents.y)\n"
- " gl_FragColor.b = border_color.b;\n"
- " else\n"
- " gl_FragColor.b = texture2D(tex, vec2(in_x.b, in_y.b) / texture_extents).b;\n"
- " if(in_x.a < 0.0 || in_x.a >= image_extents.x || in_y.a < 0.0 || in_y.a >= image_extents.y)\n"
- " gl_FragColor.a = border_color.a;\n"
- " else\n"
- " gl_FragColor.a = texture2D(tex, vec2(in_x.a, in_y.a) / texture_extents).a;\n"
- "}\n";
-
- get_output()->to_texture();
- get_output()->enable_opengl();
- unsigned int frag_shader = 0;
-
- switch(config.mode)
- {
- case LensConfig::SHRINK:
- frag_shader = VFrame::make_shader(0, shrink_frag, 0);
- break;
- case LensConfig::STRETCH:
- frag_shader = VFrame::make_shader(0, stretch_frag, 0);
- break;
- case LensConfig::RECTILINEAR_STRETCH:
- frag_shader = VFrame::make_shader(0, rectilinear_stretch_frag, 0);
- break;
- case LensConfig::RECTILINEAR_SHRINK:
- frag_shader = VFrame::make_shader(0, rectilinear_shrink_frag, 0);
- break;
- }
-
- if(frag_shader > 0)
- {
- float border_color[] = { 0, 0, 0, 0 };
- if(BC_CModels::is_yuv(get_output()->get_color_model()))
- {
- border_color[1] = 0.5;
- border_color[2] = 0.5;
- }
-
- double x_factor = config.aspect;
- double y_factor = 1.0 / config.aspect;
- if(x_factor < 1) x_factor = 1;
- if(y_factor < 1) y_factor = 1;
-
- glUseProgram(frag_shader);
- glUniform1i(glGetUniformLocation(frag_shader, "tex"), 0);
- glUniform2f(glGetUniformLocation(frag_shader, "aspect"),
- x_factor,
- y_factor);
- glUniform2f(glGetUniformLocation(frag_shader, "center_coord"),
- (GLfloat)get_input()->get_w() * config.center_x / 100.0,
- (GLfloat)get_input()->get_h() * config.center_y / 100.0);
- glUniform2f(glGetUniformLocation(frag_shader, "texture_extents"),
- (GLfloat)get_input()->get_texture_w(),
- (GLfloat)get_input()->get_texture_h());
- glUniform2f(glGetUniformLocation(frag_shader, "image_extents"),
- (GLfloat)get_input()->get_w(),
- (GLfloat)get_input()->get_h());
-
- int width = get_output()->get_w();
- int height = get_output()->get_h();
- float *fov = config.fov;
- float dim;
- float max_z;
- switch(config.mode)
- {
- case LensConfig::SHRINK:
- dim = MAX(width, height) * config.radius;
- max_z = dim * sqrt(2.0) / 2;
- glUniform4fv(glGetUniformLocation(frag_shader, "border_color"),
- 1,
- (GLfloat*)border_color);
- glUniform4f(glGetUniformLocation(frag_shader, "max_z"),
- max_z / fov[0],
- max_z / fov[1],
- max_z / fov[2],
- max_z / fov[3]);
- glUniform4f(glGetUniformLocation(frag_shader, "r"),
- (max_z / fov[0]) * 2 / M_PI,
- (max_z / fov[1]) * 2 / M_PI,
- (max_z / fov[2]) * 2 / M_PI,
- (max_z / fov[3]) * 2 / M_PI);
- break;
-
- case LensConfig::STRETCH:
- dim = MAX(width, height) * config.radius;
- max_z = dim * sqrt(2.0) / 2;
- glUniform4f(glGetUniformLocation(frag_shader, "r"),
- max_z / M_PI / (fov[0] / 2.0),
- max_z / M_PI / (fov[1] / 2.0),
- max_z / M_PI / (fov[2] / 2.0),
- max_z / M_PI / (fov[3] / 2.0));
- break;
-
- case LensConfig::RECTILINEAR_STRETCH:
- max_z = sqrt(SQR(width) + SQR(height)) / 2;
- glUniform4f(glGetUniformLocation(frag_shader, "r"),
- max_z / M_PI / (fov[0] / 2.0),
- max_z / M_PI / (fov[1] / 2.0),
- max_z / M_PI / (fov[2] / 2.0),
- max_z / M_PI / (fov[3] / 2.0));
- glUniform1f(glGetUniformLocation(frag_shader, "radius"),
- config.radius);
- break;
-
- case LensConfig::RECTILINEAR_SHRINK:
- max_z = sqrt(SQR(width) + SQR(height)) / 2;
- glUniform4f(glGetUniformLocation(frag_shader, "r"),
- max_z / M_PI / (fov[0] / 2.0),
- max_z / M_PI / (fov[1] / 2.0),
- max_z / M_PI / (fov[2] / 2.0),
- max_z / M_PI / (fov[3] / 2.0));
- glUniform1f(glGetUniformLocation(frag_shader, "radius"),
- config.radius);
- break;
- }
-
-
- get_output()->init_screen();
- get_output()->bind_texture(0);
- glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
- get_output()->draw_texture();
- glUseProgram(0);
-
-
- if(config.draw_guides)
- {
- int w = get_output()->get_w();
- int h = get_output()->get_h();
- int center_x = (int)(config.center_x * w / 100);
- int center_y = (int)(config.center_y * h / 100);
-
- glDisable(GL_TEXTURE_2D);
- glColor4f(0.0, 0.0, 0.0, 1.0);
- glBegin(GL_LINES);
- glVertex3f(center_x, -h + center_y - CENTER_H / 2, 0.0);
- glVertex3f(center_x, -h + center_y + CENTER_H / 2, 0.0);
- glEnd();
- glBegin(GL_LINES);
- glVertex3f(center_x - CENTER_W / 2, -h + center_y, 0.0);
- glVertex3f(center_x + CENTER_W / 2, -h + center_y, 0.0);
- glEnd();
- glColor4f(1.0, 1.0, 1.0, 1.0);
- glBegin(GL_LINES);
- glVertex3f(center_x - 1, -h + center_y - CENTER_H / 2 - 1, 0.0);
- glVertex3f(center_x - 1, -h + center_y + CENTER_H / 2 - 1, 0.0);
- glEnd();
- glBegin(GL_LINES);
- glVertex3f(center_x - CENTER_W / 2 - 1, -h + center_y - 1, 0.0);
- glVertex3f(center_x + CENTER_W / 2 - 1, -h + center_y - 1, 0.0);
- glEnd();
- }
- get_output()->set_opengl_state(VFrame::SCREEN);
- }
-
-#endif
- return 0;
-}
-
-
-
-
-
-
-
-
-LensPackage::LensPackage()
- : LoadPackage() {}
-
-
-
-
-
-LensUnit::LensUnit(LensEngine *engine, LensMain *plugin)
- : LoadClient(engine)
-{
- this->plugin = plugin;
-}
-
-LensUnit::~LensUnit()
-{
-}
-
-void LensUnit::process_shrink(LensPackage *pkg)
-{
-
- float *fov = plugin->config.fov;
- float aspect = plugin->config.aspect;
- int row1 = pkg->row1;
- int row2 = pkg->row2;
- int width = plugin->get_input()->get_w();
- int height = plugin->get_input()->get_h();
- double x_factor = aspect;
- double y_factor = 1.0 / aspect;
- if(x_factor < 1) x_factor = 1;
- if(y_factor < 1) y_factor = 1;
- double dim = MAX(width, height) * plugin->config.radius;
- double max_z[FOV_CHANNELS];
- double center_x = width * plugin->config.center_x / 100.0;
- double center_y = height * plugin->config.center_y / 100.0;
- double r[FOV_CHANNELS];
-
-// max_z[0] = sqrt(SQR(width) + SQR(height)) / 2 / fov[0];
-// max_z[1] = sqrt(SQR(width) + SQR(height)) / 2 / fov[1];
-// max_z[2] = sqrt(SQR(width) + SQR(height)) / 2 / fov[2];
-// max_z[3] = sqrt(SQR(width) + SQR(height)) / 2 / fov[3];
- max_z[0] = dim * sqrt(2.0) / 2 / fov[0];
- max_z[1] = dim * sqrt(2.0) / 2 / fov[1];
- max_z[2] = dim * sqrt(2.0) / 2 / fov[2];
- max_z[3] = dim * sqrt(2.0) / 2 / fov[3];
- r[0] = max_z[0] * 2 / M_PI;
- r[1] = max_z[1] * 2 / M_PI;
- r[2] = max_z[2] * 2 / M_PI;
- r[3] = max_z[3] * 2 / M_PI;
-
-#define DO_LENS_SHRINK(type, components, chroma) \
-{ \
- type **in_rows = (type**)plugin->get_temp()->get_rows(); \
- type **out_rows = (type**)plugin->get_input()->get_rows(); \
- type black[4] = { 0, chroma, chroma, 0 }; \
- \
- for(int y = row1; y < row2; y++) \
- { \
- type *out_row = out_rows[y]; \
- type *in_row = in_rows[y]; \
- double y_diff = y - center_y; \
- \
- for(int x = 0; x < width; x++) \
- { \
- double x_diff = x - center_x; \
- if(!x_diff && !y_diff) \
- { \
- type *in_pixel = in_row + x * components; \
- for(int c = 0; c < components; c++) \
- { \
- *out_row++ = *in_pixel++; \
- } \
- continue; \
- } \
- \
- double z = sqrt(x_diff * x_diff + y_diff * y_diff); \
- double a2 = atan(y_diff / x_diff); \
- if(x_diff < 0.0) a2 += M_PI; \
- \
- for(int i = 0; i < components; i++) \
- { \
- if(z > r[i]) \
- { \
- *out_row++ = black[i]; \
- } \
- else \
- { \
- double a1 = asin(z / r[i]); \
- double z_in = a1 * max_z[i] * 2 / M_PI; \
- \
- float x_in = z_in * cos(a2) * x_factor + center_x; \
- float y_in = z_in * sin(a2) * y_factor + center_y; \
- \
- if(x_in < 0.0 || x_in >= width - 1 || \
- y_in < 0.0 || y_in >= height - 1) \
- { \
- *out_row++ = black[i]; \
- } \
- else \
- { \
- float y1_fraction = y_in - floor(y_in); \
- float y2_fraction = 1.0 - y1_fraction; \
- float x1_fraction = x_in - floor(x_in); \
- float x2_fraction = 1.0 - x1_fraction; \
- type *in_pixel1 = in_rows[(int)y_in] + (int)x_in * components; \
- type *in_pixel2 = in_rows[(int)y_in + 1] + (int)x_in * components; \
- *out_row++ = (type)(in_pixel1[i] * x2_fraction * y2_fraction + \
- in_pixel2[i] * x2_fraction * y1_fraction + \
- in_pixel1[i + components] * x1_fraction * y2_fraction + \
- in_pixel2[i + components] * x1_fraction * y1_fraction); \
- } \
- } \
- } \
- } \
- } \
- \
- type *out_pixel = out_rows[(int)center_y] + (int)center_x * components; \
- type *in_pixel = in_rows[(int)center_y] + (int)center_x * components; \
- for(int c = 0; c < components; c++) \
- { \
- *out_pixel++ = *in_pixel++; \
- } \
-}
-
-
- switch(plugin->get_input()->get_color_model())
- {
- case BC_RGB888:
- DO_LENS_SHRINK(unsigned char, 3, 0x0);
- break;
- case BC_RGBA8888:
- DO_LENS_SHRINK(unsigned char, 4, 0x0);
- break;
- case BC_RGB_FLOAT:
- DO_LENS_SHRINK(float, 3, 0.0);
- break;
- case BC_RGBA_FLOAT:
- DO_LENS_SHRINK(float, 4, 0.0);
- break;
- case BC_YUV888:
- DO_LENS_SHRINK(unsigned char, 3, 0x80);
- break;
- case BC_YUVA8888:
- DO_LENS_SHRINK(unsigned char, 4, 0x80);
- break;
- }
-}
-
-void LensUnit::process_stretch(LensPackage *pkg)
-{
- float *fov = plugin->config.fov;
- float aspect = plugin->config.aspect;
- int row1 = pkg->row1;
- int row2 = pkg->row2;
- double x_factor = aspect;
- double y_factor = 1.0 / aspect;
- if(x_factor < 1) x_factor = 1;
- if(y_factor < 1) y_factor = 1;
- int width = plugin->get_input()->get_w();
- int height = plugin->get_input()->get_h();
- double dim = MAX(width, height) * plugin->config.radius;
- double max_z = dim * sqrt(2.0) / 2;
- double center_x = width * plugin->config.center_x / 100.0;
- double center_y = height * plugin->config.center_y / 100.0;
- double r[FOV_CHANNELS];
-
- r[0] = max_z / M_PI / (fov[0] / 2.0);
- r[1] = max_z / M_PI / (fov[1] / 2.0);
- r[2] = max_z / M_PI / (fov[2] / 2.0);
- r[3] = max_z / M_PI / (fov[3] / 2.0);
-
-#define DO_LENS_STRETCH(type, components, chroma) \
-{ \
- type **in_rows = (type**)plugin->get_temp()->get_rows(); \
- type **out_rows = (type**)plugin->get_input()->get_rows(); \
- type black[4] = { 0, chroma, chroma, 0 }; \
- \
- for(int y = row1; y < row2; y++) \
- { \
- type *out_row = out_rows[y]; \
- double y_diff = y - center_y; \
- \
- for(int x = 0; x < width; x++) \
- { \
- double x_diff = (x - center_x); \
- double z = sqrt(x_diff * x_diff + \
- y_diff * y_diff); \
- double a2; \
- if(x == center_x) \
- { \
- if(y < center_y) \
- a2 = 3 * M_PI / 2; \
- else \
- a2 = M_PI / 2; \
- } \
- else \
- { \
- a2 = atan(y_diff / x_diff); \
- } \
- if(x_diff < 0.0) a2 += M_PI; \
- \
- for(int i = 0; i < components; i++) \
- { \
- double a1 = (z / (M_PI * r[i] / 2)) * (M_PI / 2); \
- double z_in = r[i] * sin(a1); \
- \
- double x_in = z_in * cos(a2) * x_factor + center_x; \
- double y_in = z_in * sin(a2) * y_factor + center_y; \
- \
- if(x_in < 0.0 || x_in >= width - 1 || \
- y_in < 0.0 || y_in >= height - 1) \
- { \
- *out_row++ = black[i]; \
- } \
- else \
- { \
- float y1_fraction = y_in - floor(y_in); \
- float y2_fraction = 1.0 - y1_fraction; \
- float x1_fraction = x_in - floor(x_in); \
- float x2_fraction = 1.0 - x1_fraction; \
- type *in_pixel1 = in_rows[(int)y_in] + (int)x_in * components; \
- type *in_pixel2 = in_rows[(int)y_in + 1] + (int)x_in * components; \
- *out_row++ = (type)(in_pixel1[i] * x2_fraction * y2_fraction + \
- in_pixel2[i] * x2_fraction * y1_fraction + \
- in_pixel1[i + components] * x1_fraction * y2_fraction + \
- in_pixel2[i + components] * x1_fraction * y1_fraction); \
- } \
- } \
- } \
- } \
- \
- type *out_pixel = out_rows[(int)center_y] + (int)center_x * components; \
- type *in_pixel = in_rows[(int)center_y] + (int)center_x * components; \
- for(int c = 0; c < components; c++) \
- { \
- *out_pixel++ = *in_pixel++; \
- } \
-}
-
-
- switch(plugin->get_input()->get_color_model())
- {
- case BC_RGB888:
- DO_LENS_STRETCH(unsigned char, 3, 0x0);
- break;
- case BC_RGBA8888:
- DO_LENS_STRETCH(unsigned char, 4, 0x0);
- break;
- case BC_RGB_FLOAT:
- DO_LENS_STRETCH(float, 3, 0.0);
- break;
- case BC_RGBA_FLOAT:
- DO_LENS_STRETCH(float, 4, 0.0);
- break;
- case BC_YUV888:
- DO_LENS_STRETCH(unsigned char, 3, 0x80);
- break;
- case BC_YUVA8888:
- DO_LENS_STRETCH(unsigned char, 4, 0x80);
- break;
- }
-}
-
-void LensUnit::process_rectilinear_stretch(LensPackage *pkg)
-{
- float *fov = plugin->config.fov;
- float aspect = plugin->config.aspect;
- int row1 = pkg->row1;
- int row2 = pkg->row2;
- double x_factor = aspect;
- double y_factor = 1.0 / aspect;
- if(x_factor < 1) x_factor = 1;
- if(y_factor < 1) y_factor = 1;
- int width = plugin->get_input()->get_w();
- int height = plugin->get_input()->get_h();
-// double dim = MAX(width, height) * plugin->config.radius;
-// double max_z = dim * sqrt(2.0) / 2;
- double max_z = sqrt(SQR(width) + SQR(height)) / 2;
- double center_x = width * plugin->config.center_x / 100.0;
- double center_y = height * plugin->config.center_y / 100.0;
- double r[FOV_CHANNELS];
-
- r[0] = max_z / M_PI / (fov[0] / 2.0);
- r[1] = max_z / M_PI / (fov[1] / 2.0);
- r[2] = max_z / M_PI / (fov[2] / 2.0);
- r[3] = max_z / M_PI / (fov[3] / 2.0);
-
-#define DO_LENS_RECTILINEAR_STRETCH(type, components, chroma) \
-{ \
- type **in_rows = (type**)plugin->get_temp()->get_rows(); \
- type **out_rows = (type**)plugin->get_input()->get_rows(); \
- type black[4] = { 0, chroma, chroma, 0 }; \
- \
- for(int y = row1; y < row2; y++) \
- { \
- type *out_row = out_rows[y]; \
- double y_diff = y - center_y; \
- \
- for(int x = 0; x < width; x++) \
- { \
- double x_diff = (x - center_x); \
-/* Compute magnitude */ \
- double z = sqrt(x_diff * x_diff + \
- y_diff * y_diff); \
-/* Compute angle */ \
- double angle; \
- if(x == center_x) \
- { \
- if(y < center_y) \
- angle = 3 * M_PI / 2; \
- else \
- angle = M_PI / 2; \
- } \
- else \
- { \
- angle = atan(y_diff / x_diff); \
- } \
- if(x_diff < 0.0) angle += M_PI; \
- \
- for(int i = 0; i < components; i++) \
- { \
-/* Compute new radius */ \
- double radius1 = (z / r[i]) * 2 * plugin->config.radius; \
- double z_in = r[i] * atan(radius1) / (M_PI / 2); \
- \
- double x_in = z_in * cos(angle) * x_factor + center_x; \
- double y_in = z_in * sin(angle) * y_factor + center_y; \
- \
- if(x_in < 0.0 || x_in >= width - 1 || \
- y_in < 0.0 || y_in >= height - 1) \
- { \
- *out_row++ = black[i]; \
- } \
- else \
- { \
- float y1_fraction = y_in - floor(y_in); \
- float y2_fraction = 1.0 - y1_fraction; \
- float x1_fraction = x_in - floor(x_in); \
- float x2_fraction = 1.0 - x1_fraction; \
- type *in_pixel1 = in_rows[(int)y_in] + (int)x_in * components; \
- type *in_pixel2 = in_rows[(int)y_in + 1] + (int)x_in * components; \
- *out_row++ = (type)(in_pixel1[i] * x2_fraction * y2_fraction + \
- in_pixel2[i] * x2_fraction * y1_fraction + \
- in_pixel1[i + components] * x1_fraction * y2_fraction + \
- in_pixel2[i + components] * x1_fraction * y1_fraction); \
- } \
- } \
- } \
- } \
- \
- type *out_pixel = out_rows[(int)center_y] + (int)center_x * components; \
- type *in_pixel = in_rows[(int)center_y] + (int)center_x * components; \
- for(int c = 0; c < components; c++) \
- { \
- *out_pixel++ = *in_pixel++; \
- } \
-}
-
-
- switch(plugin->get_input()->get_color_model())
- {
- case BC_RGB888:
- DO_LENS_RECTILINEAR_STRETCH(unsigned char, 3, 0x0);
- break;
- case BC_RGBA8888:
- DO_LENS_RECTILINEAR_STRETCH(unsigned char, 4, 0x0);
- break;
- case BC_RGB_FLOAT:
- DO_LENS_RECTILINEAR_STRETCH(float, 3, 0.0);
- break;
- case BC_RGBA_FLOAT:
- DO_LENS_RECTILINEAR_STRETCH(float, 4, 0.0);
- break;
- case BC_YUV888:
- DO_LENS_RECTILINEAR_STRETCH(unsigned char, 3, 0x80);
- break;
- case BC_YUVA8888:
- DO_LENS_RECTILINEAR_STRETCH(unsigned char, 4, 0x80);
- break;
- }
-}
-
-void LensUnit::process_rectilinear_shrink(LensPackage *pkg)
-{
- float *fov = plugin->config.fov;
- float aspect = plugin->config.aspect;
- int row1 = pkg->row1;
- int row2 = pkg->row2;
- double x_factor = aspect;
- double y_factor = 1.0 / aspect;
- if(x_factor < 1) x_factor = 1;
- if(y_factor < 1) y_factor = 1;
- int width = plugin->get_input()->get_w();
- int height = plugin->get_input()->get_h();
- double max_z = MAX(width, height) / 2 * plugin->config.radius;
- double center_x = width * plugin->config.center_x / 100.0;
- double center_y = height * plugin->config.center_y / 100.0;
- double r[FOV_CHANNELS];
-
- r[0] = max_z / fov[0];
- r[1] = max_z / fov[1];
- r[2] = max_z / fov[2];
- r[3] = max_z / fov[3];
-
-#define DO_LENS_RECTILINEAR_SHRINK(type, components, chroma) \
-{ \
- type **in_rows = (type**)plugin->get_temp()->get_rows(); \
- type **out_rows = (type**)plugin->get_input()->get_rows(); \
- type black[4] = { 0, chroma, chroma, 0 }; \
- \
- for(int y = row1; y < row2; y++) \
- { \
- type *out_row = out_rows[y]; \
- double y_diff = y - center_y; \
- \
- for(int x = 0; x < width; x++) \
- { \
- double x_diff = (x - center_x); \
-/* Compute magnitude */ \
- double z = sqrt(x_diff * x_diff + \
- y_diff * y_diff); \
-/* Compute angle */ \
- double angle; \
- if(x == center_x) \
- { \
- if(y < center_y) \
- angle = 3 * M_PI / 2; \
- else \
- angle = M_PI / 2; \
- } \
- else \
- { \
- angle = atan(y_diff / x_diff); \
- } \
- if(x_diff < 0.0) angle += M_PI; \
- \
- for(int i = 0; i < components; i++) \
- { \
-/* Compute new radius */ \
- double radius1 = z / r[i]; \
- double z_in = r[i] * tan(radius1) / (M_PI / 2); \
- \
- double x_in = z_in * cos(angle) * x_factor + center_x; \
- double y_in = z_in * sin(angle) * y_factor + center_y; \
- \
- if(x_in < 0.0 || x_in >= width - 1 || \
- y_in < 0.0 || y_in >= height - 1) \
- { \
- *out_row++ = black[i]; \
- } \
- else \
- { \
- float y1_fraction = y_in - floor(y_in); \
- float y2_fraction = 1.0 - y1_fraction; \
- float x1_fraction = x_in - floor(x_in); \
- float x2_fraction = 1.0 - x1_fraction; \
- type *in_pixel1 = in_rows[(int)y_in] + (int)x_in * components; \
- type *in_pixel2 = in_rows[(int)y_in + 1] + (int)x_in * components; \
- *out_row++ = (type)(in_pixel1[i] * x2_fraction * y2_fraction + \
- in_pixel2[i] * x2_fraction * y1_fraction + \
- in_pixel1[i + components] * x1_fraction * y2_fraction + \
- in_pixel2[i + components] * x1_fraction * y1_fraction); \
- } \
- } \
- } \
- } \
- \
- type *out_pixel = out_rows[(int)center_y] + (int)center_x * components; \
- type *in_pixel = in_rows[(int)center_y] + (int)center_x * components; \
- for(int c = 0; c < components; c++) \
- { \
- *out_pixel++ = *in_pixel++; \
- } \
-}
-
-
- switch(plugin->get_input()->get_color_model())
- {
- case BC_RGB888:
- DO_LENS_RECTILINEAR_SHRINK(unsigned char, 3, 0x0);
- break;
- case BC_RGBA8888:
- DO_LENS_RECTILINEAR_SHRINK(unsigned char, 4, 0x0);
- break;
- case BC_RGB_FLOAT:
- DO_LENS_RECTILINEAR_SHRINK(float, 3, 0.0);
- break;
- case BC_RGBA_FLOAT:
- DO_LENS_RECTILINEAR_SHRINK(float, 4, 0.0);
- break;
- case BC_YUV888:
- DO_LENS_RECTILINEAR_SHRINK(unsigned char, 3, 0x80);
- break;
- case BC_YUVA8888:
- DO_LENS_RECTILINEAR_SHRINK(unsigned char, 4, 0x80);
- break;
- }
-}
-
-void LensUnit::process_package(LoadPackage *package)
-{
- LensPackage *pkg = (LensPackage*)package;
-
- switch(plugin->config.mode)
- {
- case LensConfig::SHRINK:
- process_shrink(pkg);
- break;
- case LensConfig::STRETCH:
- process_stretch(pkg);
- break;
- case LensConfig::RECTILINEAR_STRETCH:
- process_rectilinear_stretch(pkg);
- break;
- case LensConfig::RECTILINEAR_SHRINK :
- process_rectilinear_shrink(pkg);
- break;
- }
-}
-
-
-
-
-
-LensEngine::LensEngine(LensMain *plugin)
- : LoadServer(plugin->PluginClient::smp + 1, plugin->PluginClient::smp + 1)
-// : LoadServer(1, 1)
-{
- this->plugin = plugin;
-}
-
-LensEngine::~LensEngine()
-{
-}
-
-void LensEngine::init_packages()
-{
- for(int i = 0; i < LoadServer::get_total_packages(); i++)
- {
- LensPackage *package = (LensPackage*)LoadServer::get_package(i);
- package->row1 = plugin->get_input()->get_h() * i / LoadServer::get_total_packages();
- package->row2 = plugin->get_input()->get_h() * (i + 1) / LoadServer::get_total_packages();
- }
-}
-
-LoadClient* LensEngine::new_client()
-{
- return new LensUnit(this, plugin);
-}
-
-LoadPackage* LensEngine::new_package()
-{
- return new LensPackage;
-}
-
-