/*------------------------------------------------------------*/
#include "filter.h"
+#include "utils_math.h"
// Lookup Tables for Trig-functions and interpolator
-// Extract image from pano in TrPtr->src
-// using parameters in prefs (ignore image parameters
-// in TrPtr)
-
+/*
+ * Extract image from pano in TrPtr->src using parameters in prefs (ignore
+ * image parameters in TrPtr)
+ */
void PV_ExtractStill( TrformStr *TrPtr )
{
- double a,b; // field of view in rad
+ /* field of view in rad */
+ double a;
+ double b;
+
double p[2];
double mt[3][3];
int mi[3][3],i,k;
- TrPtr->success = 1;
-
a = DEG_TO_RAD( TrPtr->dest->hfov ); // field of view in rad
b = DEG_TO_RAD( TrPtr->src->hfov );
- SetMatrix( DEG_TO_RAD( TrPtr->dest->pitch ),
- DEG_TO_RAD( TrPtr->dest->yaw ),
- 0.0 ,
- mt,
- 1 );
+ /* Set up the transformation matrix `mt' using Euler angles (somehow..) */
+ SetMatrix (DEG_TO_RAD (TrPtr->dest->pitch), /* alpha */
+ DEG_TO_RAD (TrPtr->dest->yaw), /* beta */
+ 0.0, /* gamma */
+ mt, /* output */
+ 1);
p[0] = (double)TrPtr->dest->width/ (2.0 * tan( a / 2.0 ) );
- p[1] = (double)TrPtr->src->width/ b;
+ p[1] = (double) TrPtr->src->width / b;
for(i=0; i<3; i++){
for(k=0; k<3; k++){
void PV_transForm( TrformStr *TrPtr, int dist_r, int dist_e, int mt[3][3])
{
- register int x, y; // Loop through destination image
+ int x_dest, y_dest; // Loop through destination image
unsigned char *dest,*src,*sry, *dst;// Source and destination image data
long cy; // rownum in destimage
int dx,dy;
- int xc; // Cartesian Coordinates of point ("target") in Destination image
- int xs, ys;
+ int x_src, y_src;
unsigned char *rgb[2] ,
cdata[16]; // Image data handed to sampler
int x_min, x_max, y_min, y_max;
int dr1, dr2, dr3;
-
+
dr1 = mt[2][0] * dist_r;
dr2 = mt[2][1] * dist_r;
dr3 = mt[2][2] * dist_r;
-
-
-
-
dest = *TrPtr->dest->data;
src = *TrPtr->src->data; // is locked
if( TrPtr->interpolator == _bilinear )
{
- for(y = y_min; y < y_max; y++, cy+=TrPtr->dest->bytesPerLine)
+ for(y_dest = y_min; y_dest < y_max; y_dest++, cy+=TrPtr->dest->bytesPerLine)
{
dst = dest + cy + 1;
- for(x = x_min; x < x_max; x++, dst+=4)
+ for(x_dest = x_min; x_dest < x_max; x_dest++, dst+=4)
{
- v[0] = mt[0][0] * x + mt[1][0] * y + dr1;
- v[1] = mt[0][1] * x + mt[1][1] * y + dr2;
- v[2] = mt[0][2] * x + mt[1][2] * y + dr3;
+ v[0] = mt[0][0] * x_dest + mt[1][0] * y_dest + dr1;
+ v[1] = mt[0][1] * x_dest + mt[1][1] * y_dest + dr2;
+ v[2] = mt[0][2] * x_dest + mt[1][2] * y_dest + dr3;
v[0] = v[0] >> 8; v[2] = v[2] >> 8;
- xs = dist_e * PV_atan2( v[0], v[2] ) / NATAN ;
-
- ys = dist_e * PV_atan2( v[1], PV_sqrt( abs(v[2]), abs(v[0]) ) ) / NATAN ;
+ x_src = dist_e * PV_atan2( v[0], v[2] ) / NATAN ;
+ y_src = dist_e * PV_atan2( v[1], utils_sqrt2 ( abs(v[2]), abs(v[0]) ) ) / NATAN ;
- dx = xs & 255; dy = ys & 255; // fraction
-
+ dx = x_src & 255; dy = y_src & 255; // fraction
- xs = (xs >> 8) + sw2;
- ys = (ys >> 8) + sh2;
+ x_src = (x_src >> 8) + sw2;
+ y_src = (y_src >> 8) + sh2;
- if( ys >= 0 && ys < miy && xs >= 0 && xs < mix ) // all interpolation pixels inside image
+ if( y_src >= 0 && y_src < miy && x_src >= 0 && x_src < mix ) // all interpolation pixels inside image
// (most pixels)
{
- sry = src + ys * BytesPerLine + xs * 4;
+ sry = src + y_src * BytesPerLine + x_src * 4;
rgb[0] = sry;
rgb[1] = sry + BytesPerLine;
}
else // edge pixels
{
- xc = xs;
+ int x_copy = x_src;
rgb[0] = cdata;
- if( ys < 0 )
+ if( y_src < 0 )
sry = src;
- else if( ys > miy )
+ else if( y_src > miy )
sry = src + miy * BytesPerLine;
else
- sry = src + ys * BytesPerLine;
+ sry = src + y_src * BytesPerLine;
- if( xs < 0 ) xs = mix;
- if( xs > mix) xs = 0;
- *(long*)rgb[0] = *(long*)(sry + xs*4);
+ if( x_src < 0 ) x_src = mix;
+ if( x_src > mix) x_src = 0;
+ *(long*)rgb[0] = *(long*)(sry + x_src*4);
- xs = xc+1;
- if( xs < 0 ) xs = mix;
- if( xs > mix) xs = 0;
- *(long*)(rgb[0]+4) = *(long*)(sry + xs*4);
+ x_src = x_copy+1;
+ if( x_src < 0 ) x_src = mix;
+ if( x_src > mix) x_src = 0;
+ *(long*)(rgb[0]+4) = *(long*)(sry + x_src*4);
rgb[1] = cdata+8;
- ys+=1;
- if( ys < 0 )
+ y_src+=1;
+ if( y_src < 0 )
sry = src;
- else if( ys > miy )
+ else if( y_src > miy )
sry = src + miy * BytesPerLine;
else
- sry = src + ys * BytesPerLine;
- xs = xc;
- if( xs < 0 ) xs = mix;
- if( xs > mix) xs = 0;
- *(long*)rgb[1] = *(long*)(sry + xs*4);
- xs = xc+1;
- if( xs < 0 ) xs = mix;
- if( xs > mix) xs = 0;
- *(long*)(rgb[1]+4) = *(long*)(sry + xs*4);
+ sry = src + y_src * BytesPerLine;
+ x_src = x_copy;
+ if( x_src < 0 ) x_src = mix;
+ if( x_src > mix) x_src = 0;
+ *(long*)rgb[1] = *(long*)(sry + x_src*4);
+ x_src = x_copy+1;
+ if( x_src < 0 ) x_src = mix;
+ if( x_src > mix) x_src = 0;
+ *(long*)(rgb[1]+4) = *(long*)(sry + x_src*4);
}
}
else if( TrPtr->interpolator == _nn )
{
- for(y = y_min; y < y_max; y++, cy+=TrPtr->dest->bytesPerLine)
+ for(y_dest = y_min; y_dest < y_max; y_dest++, cy+=TrPtr->dest->bytesPerLine)
{
dst = dest + cy;
- for(x = x_min; x < x_max; x++, dst+=4)
+ for(x_dest = x_min; x_dest < x_max; x_dest++, dst+=4)
{
- v[0] = mt[0][0] * x + mt[1][0] * y + dr1;
- v[1] = mt[0][1] * x + mt[1][1] * y + dr2;
- v[2] = mt[0][2] * x + mt[1][2] * y + dr3;
+ v[0] = mt[0][0] * x_dest + mt[1][0] * y_dest + dr1;
+ v[1] = mt[0][1] * x_dest + mt[1][1] * y_dest + dr2;
+ v[2] = mt[0][2] * x_dest + mt[1][2] * y_dest + dr3;
v[0] = v[0] >> 8; v[2] = v[2] >> 8;
- xs = dist_e * PV_atan2( v[0], v[2] ) / NATAN ;
+ x_src = dist_e * PV_atan2( v[0], v[2] ) / NATAN ;
- ys = dist_e * PV_atan2( v[1], PV_sqrt( abs(v[2]), abs(v[0]) ) ) / NATAN ;
+ y_src = dist_e * PV_atan2( v[1], utils_sqrt2( abs(v[2]), abs(v[0]) ) ) / NATAN ;
- dx = xs & 255; dy = ys & 255; // fraction
+ dx = x_src & 255; dy = y_src & 255; // fraction
- xs = (xs >> 8) + sw2;
- ys = (ys >> 8) + sh2;
+ x_src = (x_src >> 8) + sw2;
+ y_src = (y_src >> 8) + sh2;
- if( xs < 0 ) xs = 0;
- if( xs > mix ) xs = mix;
- if( ys < 0) ys = 0;
- if( ys > miy ) ys = miy;
+ if( x_src < 0 ) x_src = 0;
+ if( x_src > mix ) x_src = mix;
+ if( y_src < 0) y_src = 0;
+ if( y_src > miy ) y_src = miy;
- *(long*)dst = *(long*)(src + ys * BytesPerLine + xs * 4);
+ *(long*)dst = *(long*)(src + y_src * BytesPerLine + x_src * 4);
}
}
}
return;
}
-
+#if 0
void matrix_inv_mult( double m[3][3], double vector[3] )
{
register int i;
vector[i] = m[0][i] * v0 + m[1][i] * v1 + m[2][i] * v2;
}
}
+#endif
// Set matrix elements based on Euler angles a, b, c
mz[1][0] =-mz[0][1] ; mz[1][1] = mz[0][0] ; mz[1][2] = 0.0;
mz[2][0] = 0.0 ; mz[2][1] = 0.0 ; mz[2][2] = 1.0;
+ /* Calculate `m = mz * mx * my' */
+
if( cl )
matrix_matrix_mult( mz, mx, dummy);
else
matrix_matrix_mult( mx, mz, dummy);
matrix_matrix_mult( dummy, my, m);
-}
+} /* void SetMatrix */
void matrix_matrix_mult( double m1[3][3],double m2[3][3],double result[3][3])
{
register int i,k;
for(i=0;i<3;i++)
- {
for(k=0; k<3; k++)
- {
result[i][k] = m1[i][0] * m2[0][k] + m1[i][1] * m2[1][k] + m1[i][2] * m2[2][k];
- }
- }
-}
+} /* void matrix_matrix_mult */
}
+/*
+ * vim: set tabstop=4 softtabstop=4 shiftwidth=4 :
+ */
--- /dev/null
+/*
+ * Copyright (C) 1998,1999 Helmut Dersch <der@fh-furtwangen.de>
+ * Copyright (C) 2007 Florian octo Forster <octo at verplant.org>
+ *
+ * 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., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ **/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "utils_math.h"
+
+// Lookup Tables for Trig-functions and interpolator
+
+#define ATAN_TABLE_SIZE 4096
+#define SQRT_TABLE_SIZE 4096
+
+static int *atan_table = NULL;
+static int *sqrt_table = NULL;
+
+static int setup_sqrt_table (void)
+{
+ double z;
+ int i;
+
+ sqrt_table = (int *) malloc (SQRT_TABLE_SIZE * sizeof (int));
+ if (sqrt_table == NULL)
+ return (-1);
+
+ /* Calculate the table entries. */
+ for (i = 0; i < SQRT_TABLE_SIZE; i++)
+ {
+ z = ((double) i) / ((double) (SQRT_TABLE_SIZE - 1));
+ sqrt_table[i] = (int) (sqrt( 1.0 + z*z ) * 4096.0 + .5);
+ }
+
+ return (0);
+} /* int setup_sqrt_table */
+
+/*
+ * Calculate
+ * 256 * sqrt(x1^2 + x2^2)
+ * efficiently
+ */
+int utils_sqrt2 (int x1, int x2)
+{
+ int ret;
+
+ if (sqrt_table == NULL)
+ if (setup_sqrt_table () != 0)
+ return (-1);
+
+ if ((x1 == 0) && (x2 == 0))
+ {
+ ret = 0;
+ }
+ else if (x1 > x2)
+ {
+ ret = x1 * sqrt_table[(SQRT_TABLE_SIZE - 1) * x2 / x1] / 16;
+ }
+ else /* (x2 < x1) */
+ {
+ ret = x2 * sqrt_table[(SQRT_TABLE_SIZE - 1) * x1 / x2] / 16;
+ }
+
+ return (ret);
+} /* int utils_sqrt2 */
+
+static int setup_atan_table (void)
+{
+ int i;
+ double z;
+
+ atan_table = (int *) malloc (ATAN_TABLE_SIZE * sizeof (int));
+ if (atan_table == NULL)
+ return (-1);
+
+ for (i = 0; i < (ATAN_TABLE_SIZE - 1); i++)
+ {
+ z = ((double) i) / ((double) (ATAN_TABLE_SIZE - 1));
+ atan_table[i] = atan ( z / (1.0 - z ) ) * ATAN_TABLE_SIZE * 256;
+ }
+ atan_table[ATAN_TABLE_SIZE - 1] = M_PI_4 * ATAN_TABLE_SIZE * 256;
+
+ return 0;
+} /* int setup_atan_table */
+
+int utils_atan2 (int y, int x)
+{
+ if (atan_table == NULL)
+ if (setup_atan_table () != 0)
+ return (-1);
+
+ // return atan2(y,x) * 256*ATAN_TABLE_SIZE;
+ if( x > 0 )
+ {
+ if( y > 0 )
+ {
+ return atan_table[(int)( ATAN_TABLE_SIZE * y / ( x + y ))];
+ }
+ else
+ {
+ return -atan_table[ (int)(ATAN_TABLE_SIZE * (-y) / ( x - y ))];
+ }
+ }
+
+ if( x == 0 )
+ {
+ if( y > 0 )
+ return (int)(256*ATAN_TABLE_SIZE * M_PI_2);
+ else
+ return -(int)(256*ATAN_TABLE_SIZE * M_PI_2);
+ }
+
+ if( y < 0 )
+ {
+ return atan_table[(int)( ATAN_TABLE_SIZE * y / ( x + y ))] - (int)(M_PI*256*ATAN_TABLE_SIZE);
+ }
+ else
+ {
+ return -atan_table[ (int)(ATAN_TABLE_SIZE * (-y) / ( x - y ))] + (int)(M_PI*256*ATAN_TABLE_SIZE);
+ }
+
+}
+
+/*
+ * vim: set tabstop=8 softtabstop=2 shiftwidth=2 :
+ */