#endif
#include "affine.h"
+#include "interp.h"
#include "clip.h"
#include "vframe.h"
float xinc, yinc, winc;
AffineMatrix m, im;
float ttx = 0, tty = 0;
- int itx = 0, ity = 0;
int tx1 = 0, ty1 = 0, tx2 = 0, ty2 = 0;
if(reverse) {
//printf("AffineUnit::process_package %d %d %d %d %d\n",
// __LINE__, min_in_x, max_in_x, min_in_y, max_in_y);
-#define CUBIC_ROW(in_row, chroma_offset) ( !in_row ? 0 : transform_cubic(dx, \
- cp>=min_in_x && cp<max_in_x ? in_row[cp*comps]-chroma_offset : 0, \
- c0>=min_in_x && c0<max_in_x ? in_row[c0*comps]-chroma_offset : 0, \
- c1>=min_in_x && c1<max_in_x ? in_row[c1*comps]-chroma_offset : 0, \
- c2>=min_in_x && c2<max_in_x ? in_row[c2*comps]-chroma_offset : 0) )
-
-
-#define DO_CUBIC(tag, components, type, temp_type, chroma_offset, max) \
+#define DO_INTERP(tag, interp, components, type, temp_type, chroma, max) \
case tag: { \
type **inp_rows = (type**)server->input->get_rows(); \
type **out_rows = (type**)server->output->get_rows(); \
float round_factor = sizeof(type) < 4 ? 0.5 : 0; \
- int comps = components; \
- for( int y=ty1; y<ty2; ++y ) { \
- type *out_row = (type*)out_rows[y]; \
+ INTERP_SETUP(inp_rows, max, min_in_x,min_in_y, max_in_x,max_in_y); \
\
- int x1 = tx1, x2 = tx2; \
- if( x1 < min_out_x ) x1 = min_out_x; \
- if( x2 > max_out_x ) x2 = max_out_x; \
- tx = xinc * x1 + m.values[0][1] * (y + pivot_offset_y) + m.values[0][2] \
- + pivot_offset_x * xinc; \
- ty = yinc * x1 + m.values[1][1] * (y + pivot_offset_y) + m.values[1][2] \
- + pivot_offset_x * yinc; \
- tw = winc * x1 + m.values[2][1] * (y + pivot_offset_y) + m.values[2][2] \
- + pivot_offset_x * winc; \
- type *out = out_row + x1 * comps; \
- for( int x=x1; x<x2; ++x ) { \
-/* Normalize homogeneous coords */ \
- if( tw == 0.0 ) { ttx = 0.0; tty = 0.0; } \
- else { ttx = tx / tw; tty = ty / tw; } \
- itx = (int)ttx; ity = (int)tty; \
-/* the fractional error */ \
- float dx = ttx - itx, dy = tty - ity; \
- if( dx < 0 ) dx += 1; \
- if( dy < 0 ) dy += 1; \
-/* row/col index */ \
- int cp = itx-1, c0 = itx+0, c1 = itx+1, c2 = itx+2; \
- int rp = ity-1, r0 = ity+0, r1 = ity+1, r2 = ity+2; \
- type *rpp, *r0p, *r1p, *r2p; \
- rpp = rp>=min_in_y && rp<max_in_y ? inp_rows[rp] : 0; \
- r0p = r0>=min_in_y && r0<max_in_y ? inp_rows[r0] : 0; \
- r1p = r1>=min_in_y && r1<max_in_y ? inp_rows[r1] : 0; \
- r2p = r2>=min_in_y && r2<max_in_y ? inp_rows[r2] : 0; \
- temp_type r, g, b, a; \
- r = (temp_type)(transform_cubic(dy, \
- CUBIC_ROW(rpp, 0x0), CUBIC_ROW(r0p, 0x0), \
- CUBIC_ROW(r1p, 0x0), CUBIC_ROW(r2p, 0x0)) \
- + round_factor); \
- if(rpp) ++rpp; if(r0p) ++r0p; if(r1p) ++r1p; if(r2p) ++r2p; \
- g = (temp_type)(transform_cubic(dy, \
- CUBIC_ROW(rpp, chroma_offset), CUBIC_ROW(r0p, chroma_offset), \
- CUBIC_ROW(r1p, chroma_offset), CUBIC_ROW(r2p, chroma_offset)) \
- + round_factor) + chroma_offset; \
- if(rpp) ++rpp; if(r0p) ++r0p; if(r1p) ++r1p; if(r2p) ++r2p; \
- b = (temp_type)(transform_cubic(dy, \
- CUBIC_ROW(rpp, chroma_offset), CUBIC_ROW(r0p, chroma_offset), \
- CUBIC_ROW(r1p, chroma_offset), CUBIC_ROW(r2p, chroma_offset)) \
- + round_factor) + chroma_offset; \
- if( components == 4 ) { \
- if(rpp) ++rpp; if(r0p) ++r0p; if(r1p) ++r1p; if(r2p) ++r2p; \
- a = (temp_type)(transform_cubic(dy, \
- CUBIC_ROW(rpp, 0x0), CUBIC_ROW(r0p, 0x0), \
- CUBIC_ROW(r1p, 0x0), CUBIC_ROW(r2p, 0x0)) \
- + round_factor); \
- } \
- if( sizeof(type) < 4 ) { \
- *out++ = CLIP(r, 0, max); \
- *out++ = CLIP(g, 0, max); \
- *out++ = CLIP(b, 0, max); \
- if( components == 4 ) *out++ = CLIP(a, 0, max); \
- } \
- else { \
- *out++ = r; \
- *out++ = g; \
- *out++ = b; \
- if( components == 4 ) *out++ = a; \
- } \
- \
-/* increment the transformed coordinates */ \
- tx += xinc; ty += yinc; tw += winc; \
- } \
- } \
-} break
-
-#define LINEAR_ROW(in_row, chroma_offset) ( !in_row ? 0 : transform_linear(dx, \
- c0>=min_in_x && c0<max_in_x ? in_row[c0*comps]-chroma_offset : 0, \
- c1>=min_in_x && c1<max_in_x ? in_row[c1*comps]-chroma_offset : 0) )
-
-#define DO_LINEAR(tag, components, type, temp_type, chroma_offset, max) \
-case tag: { \
- type **inp_rows = (type**)server->input->get_rows(); \
- type **out_rows = (type**)server->output->get_rows(); \
- int comps = components; \
- float round_factor = sizeof(type) < 4 ? 0.5 : 0; \
for( int y=ty1; y<ty2; ++y ) { \
type *out_row = (type*)out_rows[y]; \
- \
- int x1 = tx1, x2 = tx2; \
- if( x1 < min_out_x ) x1 = min_out_x; \
- if( x2 > max_out_x ) x2 = max_out_x; \
- tx = xinc * x1 + m.values[0][1] * (y + pivot_offset_y) + m.values[0][2] \
- + pivot_offset_x * xinc; \
- ty = yinc * x1 + m.values[1][1] * (y + pivot_offset_y) + m.values[1][2] \
- + pivot_offset_x * yinc; \
- tw = winc * x1 + m.values[2][1] * (y + pivot_offset_y) + m.values[2][2] \
- + pivot_offset_x * winc; \
- type *out = out_row + x1 * comps; \
- for( int x=x1; x<x2; ++x ) { \
-/* Normalize homogeneous coords */ \
- if( tw == 0.0 ) { ttx = 0.0; tty = 0.0; } \
- else { ttx = tx / tw; tty = ty / tw; } \
- itx = (int)ttx; ity = (int)tty; \
-/* the fractional error */ \
- float dx = ttx - itx, dy = tty - ity; \
- if( dx < 0 ) dx += 1; \
- if( dy < 0 ) dy += 1; \
-/* row/col index */ \
- int c0 = itx+0, c1 = itx+1; \
- int r0 = ity+0, r1 = ity+1; \
- type *r0p, *r1p; \
- r0p = r0>=min_in_y && r0<max_in_y ? inp_rows[r0] : 0; \
- r1p = r1>=min_in_y && r1<max_in_y ? inp_rows[r1] : 0; \
- temp_type r, g, b, a; \
- r = (temp_type)(transform_linear(dy, \
- LINEAR_ROW(r0p, 0x0), LINEAR_ROW(r1p, 0x0)) \
- + round_factor); \
- if(r0p) ++r0p; if(r1p) ++r1p; \
- g = (temp_type)(transform_linear(dy, \
- LINEAR_ROW(r0p, chroma_offset), LINEAR_ROW(r1p, chroma_offset)) \
- + round_factor) + chroma_offset; \
- if(r0p) ++r0p; if(r1p) ++r1p; \
- b = (temp_type)(transform_linear(dy, \
- LINEAR_ROW(r0p, chroma_offset), LINEAR_ROW(r1p, chroma_offset)) \
- + round_factor) + chroma_offset; \
- if( components == 4 ) { \
- if(r0p) ++r0p; if(r1p) ++r1p; \
- a = (temp_type)(transform_linear(dy, \
- LINEAR_ROW(r0p, 0x0), LINEAR_ROW(r1p, 0x0)) \
- + round_factor); \
- } \
- if( sizeof(type) < 4 ) { \
- *out++ = CLIP(r, 0, max); \
- *out++ = CLIP(g, 0, max); \
- *out++ = CLIP(b, 0, max); \
- if( components == 4 ) *out++ = CLIP(a, 0, max); \
- } \
- else { \
- *out++ = r; \
- *out++ = g; \
- *out++ = b; \
- if( components == 4 ) *out++ = a; \
- } \
- \
-/* increment the transformed coordinates */ \
- tx += xinc; ty += yinc; tw += winc; \
- } \
- } \
-} break
-
-#define DO_NEAREST(tag, components, type, temp_type, chroma_offset, max) \
-case tag: { \
- type **inp_rows = (type**)server->input->get_rows(); \
- type **out_rows = (type**)server->output->get_rows(); \
- for( int y=ty1; y<ty2; ++y ) { \
- type *out_row = (type*)out_rows[y]; \
- \
int x1 = tx1, x2 = tx2; \
if( x1 < min_out_x ) x1 = min_out_x; \
if( x2 > max_out_x ) x2 = max_out_x; \
tw = winc * x1 + m.values[2][1] * (y + pivot_offset_y) + m.values[2][2] \
+ pivot_offset_x * winc; \
type *out = out_row + x1 * components; \
+ \
for( int x=x1; x<x2; ++x ) { \
/* Normalize homogeneous coords */ \
if( tw == 0.0 ) { ttx = 0.0; tty = 0.0; } \
else { ttx = tx / tw; tty = ty / tw; } \
- itx = (int)ttx; ity = (int)tty; \
-/* row/col index */ \
- type *rp = ity>=min_in_y && ity<max_in_y ? inp_rows[ity] : 0; \
- temp_type r, g, b, a; \
- r = (temp_type)( rp && itx>=min_in_x && itx<max_in_x ? rp[itx*components] : 0 ); \
- if(rp) ++rp; \
- g = (temp_type)( rp && itx>=min_in_x && itx<max_in_x ? rp[itx*components] : 0 ); \
- if(rp) ++rp; \
- b = (temp_type)( rp && itx>=min_in_x && itx<max_in_x ? rp[itx*components] : 0 ); \
+ interp##_SETUP(type, components, ttx, tty); \
+ *out++ = ((temp_type)interp##_interp(0, 0) + round_factor); \
+ interp##_next(); \
+ *out++ = ((temp_type)interp##_interp(chroma, chroma) + round_factor); \
+ interp##_next(); \
+ *out++ = ((temp_type)interp##_interp(chroma, chroma) + round_factor); \
if( components == 4 ) { \
- if(rp) ++rp; \
- a = (temp_type)( rp && itx>=min_in_x && itx<max_in_x ? rp[itx*components] : 0 ); \
+ interp##_next(); \
+ *out++ = ((temp_type)interp##_interp(0, 0) + round_factor); \
} \
- *out++ = r; *out++ = g; *out++ = b; \
- if( components == 4 ) *out++ = a; \
\
/* increment the transformed coordinates */ \
tx += xinc; ty += yinc; tw += winc; \
switch( server->interpolation ) {
case AffineEngine::AF_NEAREST:
switch( server->input->get_color_model() ) {
- DO_NEAREST( BC_RGB_FLOAT, 3, float, float, 0x0, 1.0);
- DO_NEAREST( BC_RGB888, 3, unsigned char, int, 0x0, 0xff);
- DO_NEAREST( BC_RGBA_FLOAT, 4, float, float, 0x0, 1.0);
- DO_NEAREST( BC_RGBA8888, 4, unsigned char, int, 0x0, 0xff);
- DO_NEAREST( BC_YUV888, 3, unsigned char, int, 0x80, 0xff);
- DO_NEAREST( BC_YUVA8888, 4, unsigned char, int, 0x80, 0xff);
- DO_NEAREST( BC_RGB161616, 3, uint16_t, int, 0x0, 0xffff);
- DO_NEAREST( BC_RGBA16161616, 4, uint16_t, int, 0x0, 0xffff);
- DO_NEAREST( BC_YUV161616, 3, uint16_t, int, 0x8000, 0xffff);
- DO_NEAREST( BC_YUVA16161616, 4, uint16_t, int, 0x8000, 0xffff);
+ DO_INTERP( BC_RGB_FLOAT, nearest, 3, float, float, 0x0, 1.0);
+ DO_INTERP( BC_RGB888, nearest, 3, unsigned char, int, 0x0, 0xff);
+ DO_INTERP( BC_RGBA_FLOAT, nearest, 4, float, float, 0x0, 1.0);
+ DO_INTERP( BC_RGBA8888, nearest, 4, unsigned char, int, 0x0, 0xff);
+ DO_INTERP( BC_YUV888, nearest, 3, unsigned char, int, 0x80, 0xff);
+ DO_INTERP( BC_YUVA8888, nearest, 4, unsigned char, int, 0x80, 0xff);
+ DO_INTERP( BC_RGB161616, nearest, 3, uint16_t, int, 0x0, 0xffff);
+ DO_INTERP( BC_RGBA16161616, nearest, 4, uint16_t, int, 0x0, 0xffff);
+ DO_INTERP( BC_YUV161616, nearest, 3, uint16_t, int, 0x8000, 0xffff);
+ DO_INTERP( BC_YUVA16161616, nearest, 4, uint16_t, int, 0x8000, 0xffff);
}
break;
case AffineEngine::AF_LINEAR:
switch( server->input->get_color_model() ) {
- DO_LINEAR( BC_RGB_FLOAT, 3, float, float, 0x0, 1.0);
- DO_LINEAR( BC_RGB888, 3, unsigned char, int, 0x0, 0xff);
- DO_LINEAR( BC_RGBA_FLOAT, 4, float, float, 0x0, 1.0);
- DO_LINEAR( BC_RGBA8888, 4, unsigned char, int, 0x0, 0xff);
- DO_LINEAR( BC_YUV888, 3, unsigned char, int, 0x80, 0xff);
- DO_LINEAR( BC_YUVA8888, 4, unsigned char, int, 0x80, 0xff);
- DO_LINEAR( BC_RGB161616, 3, uint16_t, int, 0x0, 0xffff);
- DO_LINEAR( BC_RGBA16161616, 4, uint16_t, int, 0x0, 0xffff);
- DO_LINEAR( BC_YUV161616, 3, uint16_t, int, 0x8000, 0xffff);
- DO_LINEAR( BC_YUVA16161616, 4, uint16_t, int, 0x8000, 0xffff);
+ DO_INTERP( BC_RGB_FLOAT, bi_linear, 3, float, float, 0x0, 1.0);
+ DO_INTERP( BC_RGB888, bi_linear, 3, unsigned char, int, 0x0, 0xff);
+ DO_INTERP( BC_RGBA_FLOAT, bi_linear, 4, float, float, 0x0, 1.0);
+ DO_INTERP( BC_RGBA8888, bi_linear, 4, unsigned char, int, 0x0, 0xff);
+ DO_INTERP( BC_YUV888, bi_linear, 3, unsigned char, int, 0x80, 0xff);
+ DO_INTERP( BC_YUVA8888, bi_linear, 4, unsigned char, int, 0x80, 0xff);
+ DO_INTERP( BC_RGB161616, bi_linear, 3, uint16_t, int, 0x0, 0xffff);
+ DO_INTERP( BC_RGBA16161616, bi_linear, 4, uint16_t, int, 0x0, 0xffff);
+ DO_INTERP( BC_YUV161616, bi_linear, 3, uint16_t, int, 0x8000, 0xffff);
+ DO_INTERP( BC_YUVA16161616, bi_linear, 4, uint16_t, int, 0x8000, 0xffff);
}
break;
default:
case AffineEngine::AF_CUBIC:
switch( server->input->get_color_model() ) {
- DO_CUBIC( BC_RGB_FLOAT, 3, float, float, 0x0, 1.0);
- DO_CUBIC( BC_RGB888, 3, unsigned char, int, 0x0, 0xff);
- DO_CUBIC( BC_RGBA_FLOAT, 4, float, float, 0x0, 1.0);
- DO_CUBIC( BC_RGBA8888, 4, unsigned char, int, 0x0, 0xff);
- DO_CUBIC( BC_YUV888, 3, unsigned char, int, 0x80, 0xff);
- DO_CUBIC( BC_YUVA8888, 4, unsigned char, int, 0x80, 0xff);
- DO_CUBIC( BC_RGB161616, 3, uint16_t, int, 0x0, 0xffff);
- DO_CUBIC( BC_RGBA16161616, 4, uint16_t, int, 0x0, 0xffff);
- DO_CUBIC( BC_YUV161616, 3, uint16_t, int, 0x8000, 0xffff);
- DO_CUBIC( BC_YUVA16161616, 4, uint16_t, int, 0x8000, 0xffff);
+ DO_INTERP( BC_RGB_FLOAT, bi_cubic, 3, float, float, 0x0, 1.0);
+ DO_INTERP( BC_RGB888, bi_cubic, 3, unsigned char, int, 0x0, 0xff);
+ DO_INTERP( BC_RGBA_FLOAT, bi_cubic, 4, float, float, 0x0, 1.0);
+ DO_INTERP( BC_RGBA8888, bi_cubic, 4, unsigned char, int, 0x0, 0xff);
+ DO_INTERP( BC_YUV888, bi_cubic, 3, unsigned char, int, 0x80, 0xff);
+ DO_INTERP( BC_YUVA8888, bi_cubic, 4, unsigned char, int, 0x80, 0xff);
+ DO_INTERP( BC_RGB161616, bi_cubic, 3, uint16_t, int, 0x0, 0xffff);
+ DO_INTERP( BC_RGBA16161616, bi_cubic, 4, uint16_t, int, 0x0, 0xffff);
+ DO_INTERP( BC_YUV161616, bi_cubic, 3, uint16_t, int, 0x8000, 0xffff);
+ DO_INTERP( BC_YUVA16161616, bi_cubic, 4, uint16_t, int, 0x8000, 0xffff);
}
break;
}
#include "clip.h"
#include "file.h"
#include "filexml.h"
+#include "interp.h"
#include "language.h"
#include "lens.h"
REGISTER_PLUGIN(LensMain)
-
-
-
LensConfig::LensConfig()
{
- for(int i = 0; i < FOV_CHANNELS; i++)
+ reset();
+}
+
+void LensConfig::reset()
+{
+ for( int i=0; i<FOV_CHANNELS; ++i )
fov[i] = 1.0;
aspect = 1.0;
radius = 1.0;
- mode = LensConfig::SHRINK;
+ mode = SPHERICAL_SHRINK;
+ interp = INTERP_BILINEAR;
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;
+ 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 &&
+ interp == that.interp &&
draw_guides == that.draw_guides;
}
void LensConfig::copy_from(LensConfig &that)
{
- for(int i = 0; i < FOV_CHANNELS; i++)
+ for( int i=0; i<FOV_CHANNELS; ++i )
fov[i] = that.fov[i];
aspect = that.aspect;
radius = that.radius;
mode = that.mode;
+ interp = that.interp;
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)
+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++)
+ 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;
+ interp = prev.interp;
draw_guides = prev.draw_guides;
boundaries();
{
CLAMP(center_x, 0.0, 99.0);
CLAMP(center_y, 0.0, 99.0);
- for(int i = 0; i < FOV_CHANNELS; i++)
+ 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)
+LensSlider::LensSlider(LensMain *plugin, 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->plugin = plugin;
this->output = output;
this->text = text;
set_precision(0.01);
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])
- {
+ if( plugin->lock ) {
+ for( int i=0; i<FOV_CHANNELS; ++i ) {
+ if( output == &plugin->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]);
+ if( is_fov ) {
+ for( int i=0; i<FOV_CHANNELS; ++i ) {
+ if( output != &plugin->config.fov[i] ) {
+ plugin->config.fov[i] += difference;
+ plugin->config.boundaries();
+ gui->fov_slider[i]->update(plugin->config.fov[i]);
+ gui->fov_text[i]->update(plugin->config.fov[i]);
}
}
}
}
- client->send_configure_change();
+ plugin->send_configure_change();
return 1;
}
-LensText::LensText(LensMain *client,
- LensGUI *gui,
- LensSlider *slider,
- float *output,
- int x,
- int y)
+LensText::LensText(LensMain *plugin, LensGUI *gui,
+ LensSlider *slider, float *output, int x, int y)
: BC_TextBox(x, y, 100, 1, *output)
{
this->gui = gui;
- this->client = client;
+ this->plugin = plugin;
this->output = output;
this->slider = slider;
}
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])
- {
+ if( plugin->lock ) {
+ for( int i=0; i<FOV_CHANNELS; ++i ) {
+ if( output == &plugin->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]);
+ if( is_fov ) {
+ for( int i=0; i<FOV_CHANNELS; ++i ) {
+ if( output != &plugin->config.fov[i] ) {
+ plugin->config.fov[i] += difference;
+ plugin->config.boundaries();
+ gui->fov_slider[i]->update(plugin->config.fov[i]);
+ gui->fov_text[i]->update(plugin->config.fov[i]);
}
}
}
}
- client->send_configure_change();
+ plugin->send_configure_change();
return 1;
}
-
-LensToggle::LensToggle(LensMain *client,
+LensToggle::LensToggle(LensMain *plugin,
int *output,
int x,
int y,
: BC_CheckBox(x, y, *output, text)
{
this->output = output;
- this->client = client;
+ this->plugin = plugin;
}
int LensToggle::handle_event()
{
*output = get_value();
- client->send_configure_change();
+ plugin->send_configure_change();
return 1;
}
-
-
-
-
-
-
-
-
-LensMode::LensMode(LensMain *plugin,
- LensGUI *gui,
- int x,
- int y)
- : BC_PopupMenu(x,
- y,
- calculate_w(gui),
- "",
- 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;
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::SPHERICAL_SHRINK)));
+ add_item(new BC_MenuItem(to_text(LensConfig::SPHERICAL_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);
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::SPHERICAL_STRETCH)));
+ result = MAX(result, gui->get_text_width(MEDIUMFONT, to_text(LensConfig::SPHERICAL_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;
+ if( !strcmp(text, _("Sphere Stretch")) ) return LensConfig::SPHERICAL_STRETCH;
+ else if( !strcmp(text, _("Sphere Shrink")) ) return LensConfig::SPHERICAL_SHRINK;
+ else if( !strcmp(text, _("Rectilinear Stretch")) ) return LensConfig::RECTILINEAR_STRETCH;
+ else if( !strcmp(text, _("Rectilinear Shrink")) ) return LensConfig::RECTILINEAR_SHRINK;
+ return LensConfig::SPHERICAL_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;
+ switch( mode ) {
+ case LensConfig::SPHERICAL_STRETCH: return _("Sphere Stretch");
+ case LensConfig::SPHERICAL_SHRINK: return _("Sphere Shrink");
+ case LensConfig::RECTILINEAR_STRETCH: return _("Rectilinear Stretch");
+ case LensConfig::RECTILINEAR_SHRINK: return _("Rectilinear Shrink");
}
- return _("Stretch");
+ return _("Sphere Stretch");
}
-
-
-
// LensPresets::LensPresets(LensMain *plugin,
-// LensGUI *gui,
-// int x,
-// int y,
-// int w)
-// : BC_PopupMenu(x,
-// y,
-// w,
-// "",
-// 1)
+// LensGUI *gui, int x, int y, int w)
+// : BC_PopupMenu(x, y, w, "", 1)
// {
// this->plugin = plugin;
// this->gui = gui;
// {
// // Remove existing items
// int total = total_items();
-// for(int i = 0; i < total; i++)
-// {
+// for( int i=0; i<total; ++i ) {
// del_item();
// }
//
// // Create current items
// plugin->load_presets();
-// for(int i = 0; i < plugin->presets.total; i++)
-// {
+// 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)
-// {
+// if( plugin->current_preset >= 0 &&
+// plugin->current_preset < plugin->presets.total ) {
// set_text(plugin->presets.values[plugin->current_preset]->title);
// }
-// else
-// {
+// else {
// set_text("None");
// }
// }
// }
//
//
-//
-//
-//
-//
-// LensSavePreset::LensSavePreset(LensMain *plugin,
-// LensGUI *gui,
-// int x,
-// int y)
-// : BC_GenericButton(x, y, "Save Preset")
+// LensSavePreset::LensSavePreset(LensMain *plugin, LensGUI *gui, int x, int y)
+// : BC_GenericButton(x, y, _("Save Preset"))
// {
// this->plugin = plugin;
// this->gui = gui;
// }
//
//
-//
-//
-//
-//
-//
-// LensDeletePreset::LensDeletePreset(LensMain *plugin,
-// LensGUI *gui,
-// int x,
-// int y)
-// : BC_GenericButton(x, y, "Delete Preset")
+// LensDeletePreset::LensDeletePreset(LensMain *plugin, LensGUI *gui, int x, int y)
+// : BC_GenericButton(x, y, _("Delete Preset"))
// {
// }
//
// }
//
//
-//
-//
-//
-//
-//
-// LensPresetText::LensPresetText(LensMain *plugin,
-// LensGUI *gui,
-// int x,
-// int y,
-// int w)
+// LensPresetText::LensPresetText(LensMain *plugin, LensGUI *gui, int x, int y, int w)
// : BC_TextBox(x, y, w, 1, "")
// {
// this->plugin = plugin;
// }
+LensInterpItem::LensInterpItem(const char *text, int id)
+ : BC_MenuItem(text)
+{
+ this->id = id;
+}
+int LensInterpItem::handle_event()
+{
+ LensInterp *interp = (LensInterp *)get_popup_menu();
+ interp->set_value(id);
+ LensMain *plugin = interp->plugin;
+ plugin->config.interp = id;
+ plugin->send_configure_change();
+ return 1;
+}
+LensInterp::LensInterp(LensMain *plugin, int x, int y)
+ : BC_PopupMenu(x, y, 120, "")
+{
+ this->plugin = plugin;
+}
+void LensInterp::create_objects()
+{
+ add_item(new LensInterpItem(_("Nearest"), LensConfig::INTERP_NEAREST));
+ add_item(new LensInterpItem(_("BiLinear"), LensConfig::INTERP_BILINEAR));
+ add_item(new LensInterpItem(_("BiCubic"), LensConfig::INTERP_BICUBIC));
+ set_value(plugin->config.interp);
+}
+void LensInterp::set_value(int id)
+{
+ for( int i=0, n=total_items(); i<n; ++i ) {
+ LensInterpItem *item = (LensInterpItem *)get_item(i);
+ if( item->id == id ) {
+ set_text(item->get_text());
+ value = id;
+ return;
+ }
+ }
+}
+int LensInterp::get_value()
+{
+ return value;
+}
+LensReset::LensReset(LensMain *plugin, LensGUI *gui, int x, int y)
+ : BC_GenericButton(x, y, _("Reset"))
+{
+ this->plugin = plugin;
+ this->gui = gui;
+}
+int LensReset::handle_event()
+{
+ plugin->config.reset();
+ gui->update_gui();
+ plugin->send_configure_change();
+ return 1;
+}
-
-LensGUI::LensGUI(LensMain *client)
- : PluginClientWindow(client,
- 350,
- 510,
- 350,
- 510,
- 0)
+LensGUI::LensGUI(LensMain *plugin)
+ : PluginClientWindow(plugin, 350, 550, 350, 550, 0)
{
- this->client = client;
+ this->plugin = plugin;
}
LensGUI::~LensGUI()
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;
+ 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));
+ add_tool(fov_slider[i] = new LensSlider(plugin, this,
+ 0, &plugin->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));
+ add_tool(fov_text[i] = new LensText(plugin, this,
+ fov_slider[i], &plugin->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")));
+ add_tool(toggle = new LensToggle(plugin, &plugin->lock, x, y, _("Lock")));
y += toggle->get_h() + 10;
BC_Bar *bar;
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));
+ add_tool(aspect_slider = new LensSlider(plugin, this,
+ 0, &plugin->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));
+ add_tool(aspect_text = new LensText(plugin, this,
+ aspect_slider, &plugin->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));
+ add_tool(radius_slider = new LensSlider(plugin, this,
+ 0, &plugin->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));
+ add_tool(radius_text = new LensText(plugin, this,
+ radius_slider, &plugin->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));
+ add_tool(centerx_slider = new LensSlider(plugin, this,
+ 0, &plugin->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));
+ add_tool(centerx_text = new LensText(plugin, this,
+ centerx_slider, &plugin->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));
+ add_tool(centery_slider = new LensSlider(plugin, this,
+ 0, &plugin->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));
+ add_tool(centery_text = new LensText(plugin, this,
+ centery_slider, &plugin->config.center_y, x1, y));
centery_slider->text = centery_text;
centery_slider->set_precision(1.0);
y += centery_text->get_h() + 10;
y += bar->get_h() + 5;
-// add_tool(reverse = new LensToggle(client,
-// &client->config.reverse,
-// x,
-// y,
-// _("Reverse")));
+// add_tool(reverse = new LensToggle(plugin,
+// &plugin->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")));
+ add_tool(draw_guides = new LensToggle(plugin,
+ &plugin->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));
+ add_tool(mode = new LensMode(plugin, this,
+ x + title->get_w() + 5, y));
mode->create_objects();
y += mode->get_h() + 5;
+ add_tool(title = new BC_Title(x, y, _("Interp:")));
+ x1 = x + title->get_w() + 5;
+ add_tool(interp = new LensInterp(plugin, x1, y));
+ interp->create_objects();
+ y += interp->get_h() + 5;
+
+ add_tool(reset = new LensReset(plugin, this, x, y));
+ y += reset->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));
+// add_tool(presets = new LensPresets(plugin, 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,
+// add_tool(save_preset = new LensSavePreset(plugin, this, x, y));
+// add_tool(preset_text = new LensPresetText(plugin, 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));
+// add_tool(delete_preset = new LensDeletePreset(plugin, this, x, y));
show_window();
flush();
}
-
-
-
-
-
LensMain::LensMain(PluginServer *server)
: PluginVClient(server)
{
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();
- }
+ if( !thread ) return;
+ if( !load_configuration() ) return;
+ ((LensGUI *)thread->window)->lock_window("LensMain::update_gui");
+ LensGUI *gui = (LensGUI *)thread->window;
+ gui->update_gui();
+ gui->unlock_window();
+}
+
+void LensGUI::update_gui()
+{
+ LensConfig &config = plugin->config;
+ for( int i=0; i<FOV_CHANNELS; ++i ) {
+ fov_slider[i]->update(config.fov[i]);
+ fov_text[i]->update(config.fov[i]);
}
+ aspect_slider->update(config.aspect);
+ aspect_text->update(config.aspect);
+ radius_slider->update(config.radius);
+ radius_text->update(config.radius);
+ centerx_slider->update(config.center_x);
+ centerx_text->update(config.center_x);
+ centery_slider->update(config.center_y);
+ centery_text->update(config.center_y);
+ mode->update(config.mode);
+ draw_guides->update(config.draw_guides);
+ interp->set_value(config.interp);
}
//void LensMain::save_presets()
//
//// Save presets
// defaults->update("TOTAL_PRESETS", presets.total);
-// for(int i = 0; i < presets.total; i++)
-// {
+// 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++)
-// {
+// for( int j=0; j<FOV_CHANNELS; ++j ) {
// sprintf(string, "FOCAL_LENGTH_%d_%d", i, j);
// defaults->update(string, preset->fov[j]);
// }
// 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++)
- {
+ 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("INTERP", config.interp);
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);
{
result = input.read_tag();
- if(!result)
- {
- if(input.tag.title_is("LENS"))
- {
- for(int i = 0; i < FOV_CHANNELS; i++)
- {
+ 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.interp = input.tag.get_property("INTERP", config.interp);
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);
VFrame *input;
load_configuration();
- if(get_use_opengl())
- {
+ if( get_use_opengl() ) {
input = frame;
}
- else
- {
+ else {
input = new_temp(frame->get_w(), frame->get_h(), frame->get_color_model());
}
get_use_opengl());
- if(get_use_opengl())
- {
+ if( get_use_opengl() ) {
run_opengl();
return 0;
}
- else
- {
- if(!engine) engine = new LensEngine(this);
+ else {
+ if( !engine ) engine = new LensEngine(this);
engine->process_packages();
- if(config.draw_guides)
- {
+ if( config.draw_guides ) {
// Draw center
#define CENTER_H 20
#define CENTER_W 20
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) { \
+ 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]; \
} \
} \
\
- for(int i = center_y - CENTER_W / 2; i <= center_y + CENTER_W / 2; i++) \
- { \
- if(i >= 0 && i < h) { \
+ for( int i=center_y-CENTER_H/2; i<=center_y+CENTER_H/2; ++i ) { \
+ if( i >= 0 && i < h ) { \
type *vrow = rows[i] + center_x * components; \
vrow[0] = max - vrow[0]; \
vrow[1] = max - vrow[1]; \
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())
+ switch( get_output()->get_color_model() )
{
case BC_RGB_FLOAT:
DRAW_GUIDES(3, float, 1.0)
"{\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"
+ " if( coord_diff.x == 0.0 && coord_diff.y == 0.0 )\n"
" {\n"
" gl_FragColor = texture2D(tex, outcoord);\n"
" }\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"
+ " 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"
+ " 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"
+ " 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"
+ " 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"
" 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"
+ " if( coord_diff.x == 0.0 )\n"
" {\n"
- " if(coord_diff.y < 0.0)\n"
+ " if( coord_diff.y < 0.0 )\n"
" a2 = 3.0 * 3.14159 / 2.0;\n"
" else\n"
" a2 = 3.14159 / 2.0;\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"
+ " 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"
+ " 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"
+ " 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"
+ " 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"
" vec4 z_in = r * atan(radius1) / (3.14159 / 2.0);\n"
"\n"
" float angle;\n"
- " if(coord_diff.x == 0.0)\n"
+ " if( coord_diff.x == 0.0 )\n"
" {\n"
- " if(coord_diff.y < 0.0)\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"
" 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"
+ " 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"
+ " 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"
+ " 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"
+ " 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"
" vec4 z_in = r * atan(radius1) / (3.14159 / 2.0);\n"
"\n"
" float angle;\n"
- " if(coord_diff.x == 0.0)\n"
+ " if( coord_diff.x == 0.0 )\n"
" {\n"
- " if(coord_diff.y < 0.0)\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"
" 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"
+ " 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"
+ " 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"
+ " 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"
+ " 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"
get_output()->enable_opengl();
unsigned int frag_shader = 0;
- switch(config.mode)
+ switch( config.mode )
{
- case LensConfig::SHRINK:
+ case LensConfig::SPHERICAL_SHRINK:
frag_shader = VFrame::make_shader(0, shrink_frag, 0);
break;
- case LensConfig::STRETCH:
+ case LensConfig::SPHERICAL_STRETCH:
frag_shader = VFrame::make_shader(0, stretch_frag, 0);
break;
case LensConfig::RECTILINEAR_STRETCH:
break;
}
- if(frag_shader > 0)
- {
+ if( frag_shader > 0 ) {
float border_color[] = { 0, 0, 0, 0 };
- if(BC_CModels::is_yuv(get_output()->get_color_model()))
- {
+ 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;
+ if( x_factor < 1 ) x_factor = 1;
+ if( y_factor < 1 ) y_factor = 1;
glUseProgram(frag_shader);
glUniform1i(glGetUniformLocation(frag_shader, "tex"), 0);
float *fov = config.fov;
float dim;
float max_z;
- switch(config.mode)
+ switch( config.mode )
{
- case LensConfig::SHRINK:
+ case LensConfig::SPHERICAL_SHRINK:
dim = MAX(width, height) * config.radius;
max_z = dim * sqrt(2.0) / 2;
glUniform4fv(glGetUniformLocation(frag_shader, "border_color"),
(max_z / fov[3]) * 2 / M_PI);
break;
- case LensConfig::STRETCH:
+ case LensConfig::SPHERICAL_STRETCH:
dim = MAX(width, height) * config.radius;
max_z = dim * sqrt(2.0) / 2;
glUniform4f(glGetUniformLocation(frag_shader, "r"),
glUseProgram(0);
- if(config.draw_guides)
- {
+ 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);
return 0;
}
-
-
-
-
-
-
+// do using specified interpolation
+#define DO_LENS(type) \
+ int icolor_model = plugin->get_input()->get_color_model(); \
+ switch( plugin->config.interp ) { \
+ case LensConfig::INTERP_NEAREST: \
+ switch( icolor_model ) { \
+ case BC_RGB888: \
+ DO_LENS_##type(unsigned char, 3, 0xff, 0x0, nearest); \
+ break; \
+ case BC_RGBA8888: \
+ DO_LENS_##type(unsigned char, 4, 0xff, 0x0, nearest); \
+ break; \
+ case BC_RGB_FLOAT: \
+ DO_LENS_##type(float, 3, 1.0, 0.0, nearest); \
+ break; \
+ case BC_RGBA_FLOAT: \
+ DO_LENS_##type(float, 4, 1.0, 0.0, nearest); \
+ break; \
+ case BC_YUV888: \
+ DO_LENS_##type(unsigned char, 3, 0xff, 0x80, nearest); \
+ break; \
+ case BC_YUVA8888: \
+ DO_LENS_##type(unsigned char, 4, 0xff, 0x80, nearest); \
+ break; \
+ } \
+ break; \
+ case LensConfig::INTERP_BILINEAR: \
+ switch( icolor_model ) { \
+ case BC_RGB888: \
+ DO_LENS_##type(unsigned char, 3, 0xff, 0x0, bi_linear); \
+ break; \
+ case BC_RGBA8888: \
+ DO_LENS_##type(unsigned char, 4, 0xff, 0x0, bi_linear); \
+ break; \
+ case BC_RGB_FLOAT: \
+ DO_LENS_##type(float, 3, 1.0, 0.0, bi_linear); \
+ break; \
+ case BC_RGBA_FLOAT: \
+ DO_LENS_##type(float, 4, 1.0, 0.0, bi_linear); \
+ break; \
+ case BC_YUV888: \
+ DO_LENS_##type(unsigned char, 3, 0xff, 0x80, bi_linear); \
+ break; \
+ case BC_YUVA8888: \
+ DO_LENS_##type(unsigned char, 4, 0xff, 0x80, bi_linear); \
+ break; \
+ } \
+ break; \
+ case LensConfig::INTERP_BICUBIC: \
+ switch( icolor_model ) { \
+ case BC_RGB888: \
+ DO_LENS_##type(unsigned char, 3, 0xff, 0x0, bi_cubic); \
+ break; \
+ case BC_RGBA8888: \
+ DO_LENS_##type(unsigned char, 4, 0xff, 0x0, bi_cubic); \
+ break; \
+ case BC_RGB_FLOAT: \
+ DO_LENS_##type(float, 3, 1.0, 0.0, bi_cubic); \
+ break; \
+ case BC_RGBA_FLOAT: \
+ DO_LENS_##type(float, 4, 1.0, 0.0, bi_cubic); \
+ break; \
+ case BC_YUV888: \
+ DO_LENS_##type(unsigned char, 3, 0xff, 0x80, bi_cubic); \
+ break; \
+ case BC_YUVA8888: \
+ DO_LENS_##type(unsigned char, 4, 0xff, 0x80, bi_cubic); \
+ break; \
+ } \
+ break; \
+ }
LensPackage::LensPackage()
- : LoadPackage() {}
-
-
-
-
+ : LoadPackage()
+{
+}
LensUnit::LensUnit(LensEngine *engine, LensMain *plugin)
: LoadClient(engine)
{
}
-void LensUnit::process_shrink(LensPackage *pkg)
+void LensUnit::process_spherical_stretch(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;
+ 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[FOV_CHANNELS];
+ 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];
-// 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;
+ 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_SHRINK(type, components, chroma) \
-{ \
+#define DO_LENS_SPHERICAL_STRETCH(type, components, max, chroma, interp) { \
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 }; \
+ INTERP_SETUP(in_rows, max, 0,0, width,height); \
\
- for(int y = row1; y < row2; y++) \
- { \
+ 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; \
- } \
- \
+ 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 = 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); \
- } \
- } \
+ double a2 = x != center_x ? atan(y_diff / x_diff) : \
+ y < center_y ? 3*M_PI/2 : M_PI/2; \
+ 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; \
+ interp##_SETUP(type, components, x_in, y_in); \
+ for( int j=0; j<i; ++j ) interp##_next(); \
+ *out_row++ = interp##_interp(black[i], black[i]); \
} \
} \
} \
\
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++; \
- } \
+ type *inp_pixel = in_rows[(int)center_y] + (int)center_x * components; \
+ for( int i=0; i<components; ++i ) *out_pixel++ = *inp_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;
- }
+ DO_LENS(SPHERICAL_STRETCH);
}
-void LensUnit::process_stretch(LensPackage *pkg)
+void LensUnit::process_spherical_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 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 = dim * sqrt(2.0) / 2;
+ 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];
- 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);
+// 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_STRETCH(type, components, chroma) \
-{ \
+#define DO_LENS_SPHERICAL_SHRINK(type, components, max, chroma, interp) { \
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 }; \
+ INTERP_SETUP(in_rows, max, 0,0, width,height); \
\
- for(int y = row1; y < row2; y++) \
- { \
+ 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); \
- 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); \
+ for( int x=0; x<width; ++x ) { \
+ double x_diff = x - center_x; \
+ if( !x_diff && !y_diff ) { \
+ type *inp_pixel = in_row + x * components; \
+ for( int c=0; c<components; ++c ) \
+ *out_row++ = *inp_pixel++; \
+ continue; \
} \
- 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); \
- } \
+ 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]; continue; } \
+ 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; \
+ interp##_SETUP(type, components, x_in, y_in); \
+ for( int j=0; j<i; ++j ) interp##_next(); \
+ *out_row++ = interp##_interp(black[i], black[i]); \
} \
} \
} \
\
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++; \
- } \
+ type *inp_pixel = in_rows[(int)center_y] + (int)center_x * components; \
+ for( int i=0; i<components; ++i ) *out_pixel++ = *inp_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;
- }
+ DO_LENS(SPHERICAL_SHRINK);
}
void LensUnit::process_rectilinear_stretch(LensPackage *pkg)
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;
+ 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;
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) \
-{ \
+#define DO_LENS_RECTILINEAR_STRETCH(type, components, max, chroma, interp) { \
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 }; \
+ INTERP_SETUP(in_rows, max, 0,0, width,height); \
\
- for(int y = row1; y < row2; y++) \
- { \
+ 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 */ \
+ for( int x=0; x<width; ++x ) { \
+ double x_diff = (x - center_x); /* Compute magnitude / angle */ \
+ double z = sqrt(x_diff * x_diff + y_diff * y_diff); \
+ double angle = x != center_x ? atan(y_diff / x_diff) : \
+ y < center_y ? 3*M_PI/2 : M_PI/2; \
+ 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); \
- } \
+ interp##_SETUP(type, components, x_in, y_in); \
+ for( int j=0; j<i; ++j ) interp##_next(); \
+ *out_row++ = interp##_interp(black[i], black[i]); \
} \
} \
} \
\
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++; \
- } \
+ type *inp_pixel = in_rows[(int)center_y] + (int)center_x * components; \
+ for( int i=0; i<components; ++i ) *out_pixel++ = *inp_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;
- }
+ DO_LENS(RECTILINEAR_STRETCH);
}
void LensUnit::process_rectilinear_shrink(LensPackage *pkg)
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;
+ 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;
r[2] = max_z / fov[2];
r[3] = max_z / fov[3];
-#define DO_LENS_RECTILINEAR_SHRINK(type, components, chroma) \
-{ \
+#define DO_LENS_RECTILINEAR_SHRINK(type, components, max, chroma, interp) { \
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 }; \
+ INTERP_SETUP(in_rows, max, 0,0, width,height); \
\
- for(int y = row1; y < row2; y++) \
- { \
+ 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 */ \
+ for( int x=0; x<width; ++x ) { \
+ double x_diff = (x - center_x); /* Compute magnitude/angle */ \
+ double z = sqrt(x_diff * x_diff + y_diff * y_diff); \
+ double angle = x != center_x ? atan(y_diff / x_diff) : \
+ y < center_y ? 3*M_PI/2 : M_PI/2; \
+ 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); \
- } \
+ interp##_SETUP(type, components, x_in, y_in); \
+ for( int j=0; j<i; ++j ) interp##_next(); \
+ *out_row++ = interp##_interp(black[i], black[i]); \
} \
} \
} \
\
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++; \
- } \
+ type *inp_pixel = in_rows[(int)center_y] + (int)center_x * components; \
+ for( int i=0; i<components; ++i ) *out_pixel++ = *inp_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;
- }
+ DO_LENS(RECTILINEAR_SHRINK);
}
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;
+ switch( plugin->config.mode ) {
+ case LensConfig::SPHERICAL_STRETCH:
+ process_spherical_stretch(pkg);
+ break;
+ case LensConfig::SPHERICAL_SHRINK:
+ process_spherical_shrink(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)
void LensEngine::init_packages()
{
- for(int i = 0; i < LoadServer::get_total_packages(); i++)
- {
+ int row1 = 0, row2 = 0, n = LoadServer::get_total_packages();
+ for( int i=0; i<n; row1=row2 ) {
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();
+ row2 = plugin->get_input()->get_h() * ++i / n;
+ package->row1 = row1; package->row2 = row2;
}
}