Removed unused code.
[libopano.git] / src / panolib.c
index 58d190b..8b9f30b 100644 (file)
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 /*------------------------------------------------------------*/
+#include <stdlib.h>
+#include <stdint.h>
+#include <assert.h>
+
 #include "filter.h"
+#include "utils_math.h"
 
+#define DEG_TO_RAD(x) ((x) * 2.0 * M_PI / 360.0 )
 
 // Lookup Tables for Trig-functions and interpolator
 
 
 int *atan_LU;
 int *sqrt_LU;
-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]);
-int    PV_atan2(int y, int x);
+void   PV_transForm( TrformStr *TrPtr, double dist_r, double dist_e, int mt[3][3]);
 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)
-
+/*
+ * 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++){
@@ -112,181 +74,105 @@ 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])
 {
-       register int            x, y;                   // 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; 
-
-       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
+       int x_dest, y_dest;                     // Loop through destination image
+       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;
 
        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
 
-       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 = y_min; y < y_max; y++, cy+=TrPtr->dest->bytesPerLine)
+               for(x_dest = x_min; x_dest < x_max; x_dest++)
                {
-                       dst = dest + cy + 1;
-                       for(x = x_min; x < x_max; x++, 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] = 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 ;
-
-                               dx = xs & 255; dy = ys & 255; // fraction
-                       
-                       
-                               xs = (xs >> 8) + sw2;
-                               ys = (ys >> 8) + sh2;
-
-                                       
-                               if( ys >= 0 && ys < miy && xs >= 0 && xs < mix )  // all interpolation pixels inside image
-                                                                                                                                         // (most pixels)
-                               {
-                                       sry = src + ys * BytesPerLine + xs * 4;
-                                       rgb[0] = sry;
-                                       rgb[1] = sry + BytesPerLine;
-                               }
-                               else // edge pixels
-                               {
-                                       xc = xs;
-
-                                       rgb[0] = cdata;
-                                       if( ys < 0 )
-                                               sry = src;
-                                       else if( ys > miy )
-                                               sry = src + miy * BytesPerLine;
-                                       else
-                                               sry = src + ys  * BytesPerLine;
-                                       
-                                       if( xs < 0 )  xs = mix;
-                                       if( xs > mix) xs = 0;
-                                       *(long*)rgb[0] = *(long*)(sry + xs*4);
-
-                                       xs = xc+1;
-                                       if( xs < 0 )  xs = mix;
-                                       if( xs > mix) xs = 0;
-                                       *(long*)(rgb[0]+4) = *(long*)(sry + xs*4);
-
-
-
-                                       rgb[1] = cdata+8;
-                                       ys+=1;
-                                       if( ys < 0 )
-                                               sry = src;
-                                       else if( ys > 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);
-                                       
-                                       
-                               }
-                               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 = y_min; y < y_max; y++, cy+=TrPtr->dest->bytesPerLine)
-               {
-                       dst = dest + cy;
-                       for(x = x_min; x < x_max; x++, 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] = 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 ;
-
-                               dx      = xs & 255; dy = ys & 255; // fraction
-                       
-                       
-                               xs = (xs >> 8) + sw2;
-                               ys = (ys >> 8) + sh2;
-
-                               if( xs < 0 )    xs = 0;
-                               if( xs > mix )  xs = mix;
-                               if( ys < 0)     ys = 0;
-                               if( ys > miy )  ys = miy;
-
-                               *(long*)dst = *(long*)(src + ys * BytesPerLine + xs * 4);
-                       }
-               }
-       }
-
-       TrPtr->success = 1;
        return;
 }
 
-
+#if 0
 void matrix_inv_mult( double m[3][3], double vector[3] )
 {
        register int i;
@@ -299,6 +185,7 @@ void matrix_inv_mult( double m[3][3], double vector[3] )
                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
 
@@ -321,149 +208,23 @@ void SetMatrix( double a, double b, double c , double m[3][3], int cl )
        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];
-               }
-       }
-}
-
-
-
-int PV_atan2(int y, int x)
-{
-       // return atan2(y,x) * 256*NATAN;
-       if( x > 0 )
-       {
-               if( y > 0 )
-               {
-                       return  atan_LU[(int)( NATAN * y / ( x + y ))];
-               }
-               else
-               {
-                       return -atan_LU[ (int)(NATAN * (-y) / ( x - y ))];
-               }
-       }
-
-       if( x == 0 )
-       {
-               if( y > 0 )
-                       return  (int)(256*NATAN*PI / 2.0);
-               else
-                       return  -(int)(256*NATAN*PI / 2.0);
-       }
-       
-       if( y < 0 )
-       {
-               return  atan_LU[(int)( NATAN * y / ( x + y ))] - (int)(PI*256*NATAN);
-       }
-       else
-       {
-               return -atan_LU[ (int)(NATAN * (-y) / ( x - y ))] + (int)(PI*256*NATAN);
-       }
-       
-}
-
-
-
-int SetUpAtan()
-{
-       int i;
-       double dz = 1.0 / (double)NATAN;
-       double z = 0.0;
-       
-       atan_LU = (int*) malloc( (NATAN+1) * sizeof( int ));
-       
-       if( atan_LU == NULL )
-               return -1;
-               
-       for( i=0; i< NATAN; i++, z+=dz )
-               atan_LU[i] = atan( z / (1.0 - z ) ) * NATAN * 256;
-               
-       atan_LU[NATAN] = PI/4.0 * NATAN * 256;
-       
-       // Print a test
-#if 0  
-       for(i = -10; i< 10; i++)
-       {
-               int k;
-               for(k=-10; k<10; k++)
-               {
-                       printf("i =  %d  k = %d   atan2(i,k) = %g    LUatan(i,k) = %g diff = %g\n", i,k,atan2(i,k), 
-                               (double)PV_atan2(i,k) / (256*NATAN) , atan2(i,k) - (double)PV_atan2(i,k) / (256*NATAN));
-               }
-       }
-       exit(0);
-#endif 
-       return 0;
-}
-
-int SetUpSqrt()
-{
-       int i;
-       double dz = 1.0 / (double)NSQRT;
-       double z = 0.0;
-       
-       sqrt_LU = (int*) malloc( (NSQRT+1) * sizeof( int ));
-       
-       if( sqrt_LU == NULL )
-               return -1;
-               
-       for( i=0; i< NSQRT; i++, z+=dz )
-               sqrt_LU[i] = sqrt( 1.0 + z*z ) * 256 * NSQRT;
-               
-       sqrt_LU[NSQRT] = sqrt(2.0) * 256 * NSQRT;
-       
-       return 0;
-}
-
-int SetUpMweights()
-{
-       int i,k;
-       
-       for(i=0; i<256; i++)
-       {
-               mweights[i] = (int*)malloc( 256 * sizeof(int) );
-               if( mweights[i] == NULL ) return -1;
-       }
-       for(i=0; i<256; i++)
-       {
-               for(k=0; k<256; k++)
-               {
-                       mweights[i][k] = i*k;
-               }
-       }
-       
-       return 0;
-}
-
-
-int PV_sqrt( int x1, int x2 )
-{
-       if( x1 > x2 )
-       {
-               return  x1 * sqrt_LU[ NSQRT * x2 /  x1 ] / NSQRT;
-       }
-       else
-       {
-               if( x2 == 0 ) return 0;
-               return x2 * sqrt_LU[ NSQRT * x1 /  x2 ] / NSQRT;
-       }
-}
-
+} /* void matrix_matrix_mult */
 
 #define ID_0 0xff
 #define ID_1 0xd8
@@ -547,3 +308,6 @@ int extractJPEG( fullPath *image, fullPath *jpeg )
 }
                
 
+/*
+ * vim: set tabstop=4 softtabstop=4 shiftwidth=4 :
+ */