Merge CV, ver=5.1; ops/methods from HV, and interface from CV where possible
[goodguy/history.git] / cinelerra-5.0 / plugins / lens / lens.C
diff --git a/cinelerra-5.0/plugins/lens/lens.C b/cinelerra-5.0/plugins/lens/lens.C
deleted file mode 100644 (file)
index 2491615..0000000
+++ /dev/null
@@ -1,1835 +0,0 @@
-
-/*
- * 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;
-}
-
-