From: Florian Forster Date: Thu, 16 Aug 2007 15:13:57 +0000 (+0200) Subject: A much stripped down version of `PV_transForm' (accompanied by `copy_pixel'). X-Git-Url: https://git.octo.it/?p=libopano.git;a=commitdiff_plain;h=f021ce36e37def0e39914e92c8ad2ba49c847c6f A much stripped down version of `PV_transForm' (accompanied by `copy_pixel'). Much much much cleaner \o/. And, it works! :) --- diff --git a/src/panolib.c b/src/panolib.c index 9a6a12d..e9c04ef 100644 --- a/src/panolib.c +++ b/src/panolib.c @@ -16,6 +16,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /*------------------------------------------------------------*/ +#include +#include +#include + #include "filter.h" #include "utils_math.h" @@ -31,55 +35,11 @@ int *mweights[256]; void matrix_matrix_mult ( double m1[3][3],double m2[3][3],double result[3][3]); -void PV_transForm( TrformStr *TrPtr, int dist_r, int dist_e, int mt[3][3]); +void PV_transForm( TrformStr *TrPtr, double dist_r, double dist_e, int mt[3][3]); int PV_atan2(int y, int x); int PV_sqrt( int x1, int x2 ); -// Bilinear interpolator - -static void bil( unsigned char *dst, unsigned char **rgb, - int dx,int dy) -{ - int yr, yg, yb,weight; - int rd, gd, bd ; - register unsigned char *r; - int *w1, *w2; - - - w1 = mweights[dx]; w2 = mweights[255 - dx]; - - r = rgb[0] + 1; - - rd = w2[*r++]; gd = w2[*r++]; bd = w2[*r++]; - //weight = 255 - dx; rd = weight * *r++; gd = weight * *r++; bd = weight * *r++; - - r++; - rd += w1[*r++]; gd += w1[*r++]; bd += w1[*r]; - //rd += dx * *r++; gd += dx * *r++; bd += dx * *r; - - - r = rgb[1] + 1; - - yr = w2[*r++]; yg = w2[*r++]; yb = w2[*r++]; - //rd = weight * *r++; gd = weight * *r++; bd = weight * *r++; - - r++; - yr += w1[*r++]; yg += w1[*r++]; yb += w1[*r]; - //rd += dx * *r++; gd += dx * *r++; bd += dx * *r; - - weight = 255 - dy; - rd = rd * weight + yr * dy; - gd = gd * weight + yg * dy; - bd = bd * weight + yb * dy; - - *dst++ = rd >> 16; - *dst++ = gd >> 16; - *dst = bd >> 16; -} - - - /* * Extract image from pano in TrPtr->src using parameters in prefs (ignore * image parameters in TrPtr) @@ -115,44 +75,62 @@ void PV_ExtractStill( TrformStr *TrPtr ) } - PV_transForm( TrPtr, (int)(p[0]+.5), (int)(p[1]+.5), mi); + PV_transForm( TrPtr, p[0], p[1], mi); return; } - - +typedef enum interpolator_e +{ + NNEIGHBOUR, + BILINEAR +} interpolator_t; + +static int copy_pixel (Image *dest, Image *src, + int x_dest, int y_dest, + double x_src_fp, double y_src_fp, + interpolator_t interp) +{ + uint32_t pixel_value; + uint32_t *src_data = (uint32_t *) (*src->data); + uint32_t *dest_data = (uint32_t *) (*dest->data); + + interp = NNEIGHBOUR; + + if (interp == NNEIGHBOUR) + { + int x_src = (int) (x_src_fp + 0.5) % src->width; + int y_src = (int) (y_src_fp + 0.5) % src->height; + + if ((x_src < 0) || (x_src >= src->width) + || (y_src < 0) || (y_src >= src->height)) + pixel_value = 0x000000FF; + else + pixel_value = src_data[(y_src * src->width) + x_src]; + } + dest_data[(y_dest * dest->width) + x_dest] = pixel_value; + + return (0); +} /* int copy_pixel */ // Main transformation function. Destination image is calculated using transformation // Function "func". Either all colors (color = 0) or one of rgb (color =1,2,3) are // determined. If successful, TrPtr->success = 1. Memory for destination image // must have been allocated and locked! -void PV_transForm( TrformStr *TrPtr, int dist_r, int dist_e, int mt[3][3]) +void PV_transForm( TrformStr *TrPtr, double dist_r, double dist_e, int mt[3][3]) { 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 x_src, y_src; - - unsigned char *rgb[2] , - cdata[16]; // Image data handed to sampler - - - int mix = TrPtr->src->width - 1; // maximum x-index src - int miy = TrPtr->src->height - 1;// maximum y-index src + unsigned char *dest,*src;// Source and destination image data // Variables used to convert screen coordinates to cartesian coordinates - int w2 = TrPtr->dest->width / 2 ; - int h2 = TrPtr->dest->height / 2 ; - int sw2 = TrPtr->src->width / 2 ; - int sh2 = TrPtr->src->height / 2 ; + int dest_width_left = TrPtr->dest->width / 2 ; + int dest_height_top = TrPtr->dest->height / 2 ; + int src_width_left = TrPtr->src->width / 2 ; + int src_height_top = TrPtr->src->height / 2 ; - int BytesPerLine = TrPtr->src->bytesPerLine; int v[3]; int x_min, x_max, y_min, y_max; @@ -165,120 +143,33 @@ void PV_transForm( TrformStr *TrPtr, int dist_r, int dist_e, int mt[3][3]) dest = *TrPtr->dest->data; src = *TrPtr->src->data; // is locked - x_min = -w2; x_max = TrPtr->dest->width - w2; - y_min = -h2; y_max = TrPtr->dest->height - h2; + x_min = -dest_width_left; x_max = TrPtr->dest->width - dest_width_left; + y_min = -dest_height_top; y_max = TrPtr->dest->height - dest_height_top; - cy = 0; - - if( TrPtr->interpolator == _bilinear ) + for(y_dest = y_min; y_dest < y_max; y_dest++) { - for(y_dest = y_min; y_dest < y_max; y_dest++, cy+=TrPtr->dest->bytesPerLine) + for(x_dest = x_min; x_dest < x_max; x_dest++) { - dst = dest + cy + 1; - for(x_dest = x_min; x_dest < x_max; x_dest++, dst+=4) - { - 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; - - 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 = x_src & 255; dy = y_src & 255; // fraction - - x_src = (x_src >> 8) + sw2; - y_src = (y_src >> 8) + sh2; - - - if( y_src >= 0 && y_src < miy && x_src >= 0 && x_src < mix ) // all interpolation pixels inside image - // (most pixels) - { - sry = src + y_src * BytesPerLine + x_src * 4; - rgb[0] = sry; - rgb[1] = sry + BytesPerLine; - } - else // edge pixels - { - int x_copy = x_src; - - rgb[0] = cdata; - if( y_src < 0 ) - sry = src; - else if( y_src > miy ) - sry = src + miy * BytesPerLine; - else - sry = src + y_src * BytesPerLine; - - if( x_src < 0 ) x_src = mix; - if( x_src > mix) x_src = 0; - *(long*)rgb[0] = *(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[0]+4) = *(long*)(sry + x_src*4); - - - - rgb[1] = cdata+8; - y_src+=1; - if( y_src < 0 ) - sry = src; - else if( y_src > miy ) - sry = src + miy * BytesPerLine; - else - 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); - - - } - bil( dst, rgb, dx, dy ); - } + double x_src_fp; + double y_src_fp; + + 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; + v[1] = v[1] >> 8; + + x_src_fp = dist_e * atan2 (v[0], v[2]); + y_src_fp = dist_e * atan2 (v[1], sqrt (v[2] * v[2] + v[0] * v[0])); + + copy_pixel (TrPtr->dest, TrPtr->src, + dest_width_left + x_dest, dest_height_top + y_dest, + src_width_left + x_src_fp, src_height_top + y_src_fp, + NNEIGHBOUR); } } - else if( TrPtr->interpolator == _nn ) - { - for(y_dest = y_min; y_dest < y_max; y_dest++, cy+=TrPtr->dest->bytesPerLine) - { - dst = dest + cy; - for(x_dest = x_min; x_dest < x_max; x_dest++, dst+=4) - { - 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; - 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 = x_src & 255; dy = y_src & 255; // fraction - - - x_src = (x_src >> 8) + sw2; - y_src = (y_src >> 8) + sh2; - - 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 + y_src * BytesPerLine + x_src * 4); - } - } - } - - TrPtr->success = 1; return; } @@ -336,9 +227,8 @@ void matrix_matrix_mult( double m1[3][3],double m2[3][3],double result[3][3]) 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 */ - - -int PV_atan2(int y, int x) +#if 0 +static int orig_PV_atan2(int y, int x) { // return atan2(y,x) * 256*NATAN; if( x > 0 ) @@ -370,9 +260,14 @@ int PV_atan2(int y, int x) return -atan_LU[ (int)(NATAN * (-y) / ( x - y ))] + (int)(PI*256*NATAN); } -} - +} /* int orig_PV_atan2 */ +#endif +int PV_atan2(int y, int x) +{ + double ret = atan2 (y, x) * NATAN * 256.0; + return ((int) ret); +} /* int PV_atan2 */ int SetUpAtan() { diff --git a/src/utils_math.c b/src/utils_math.c index 09b424f..744192a 100644 --- a/src/utils_math.c +++ b/src/utils_math.c @@ -28,7 +28,6 @@ #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) @@ -79,63 +78,6 @@ int utils_sqrt2 (int x1, int x2) 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 : */ diff --git a/src/utils_math.h b/src/utils_math.h index 08e2831..9f411dc 100644 --- a/src/utils_math.h +++ b/src/utils_math.h @@ -16,5 +16,9 @@ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA **/ +#ifndef UTILS_MATH_H +#define UTILS_MATH_H 1 + int utils_sqrt2 (int x1, int x2); -int utils_atan2 (int y, int x); + +#endif /* UTILS_MATH_H */