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"
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)
}
- 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;
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;
}
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 )
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()
{