From: Florian Forster Date: Sat, 18 Aug 2007 10:57:25 +0000 (+0200) Subject: panolib.c: Implemented bilinear interpolation. X-Git-Url: https://git.octo.it/?p=libopano.git;a=commitdiff_plain;h=6daddf39485747a5aa004a3a0a7d7a893807def1 panolib.c: Implemented bilinear interpolation. It's used in the viewer when no button is pressed. --- diff --git a/src/panolib.c b/src/panolib.c index 425a839..2686059 100644 --- a/src/panolib.c +++ b/src/panolib.c @@ -21,6 +21,7 @@ #include #include "filter.h" +#include "panolib.h" #include "utils_math.h" #include "utils_image.h" @@ -67,16 +68,6 @@ static void set_transformation_matrix (double m[3][3], matrix_matrix_mult( dummy, my, m); } /* void SetMatrix */ -/* - * Extract image from pano in TrPtr->src using parameters in prefs (ignore - * image parameters in TrPtr) - */ -typedef enum interpolator_e -{ - NNEIGHBOUR, - BILINEAR -} interpolator_t; - static int copy_pixel (ui_image_t *dest, const ui_image_t *src, int x_dest, int y_dest, double x_src_fp, double y_src_fp, @@ -84,9 +75,60 @@ static int copy_pixel (ui_image_t *dest, const ui_image_t *src, { uint32_t pixel_dest = (y_dest * dest->width) + x_dest; - interp = NNEIGHBOUR; + assert (x_src_fp >= 0.0); + assert (y_src_fp >= 0.0); + + if (interp == BILINEAR) + { + int x_src_left; + int x_src_right; + int y_src_top; + int y_src_bottom; + + double x_right_frac; + double y_bottom_frac; + + int i; + + x_src_left = (int) x_src_fp; + x_src_right = x_src_left + 1; + y_src_top = (int) y_src_fp; + y_src_bottom = y_src_top + 1; + + x_right_frac = x_src_fp - x_src_left; + y_bottom_frac = y_src_fp - y_src_top; + + assert (x_src_right < src->width); + assert (y_src_bottom < src->height); + + assert ((x_right_frac >= 0.0) && (x_right_frac <= 1.0)); + assert ((y_bottom_frac >= 0.0) && (y_bottom_frac <= 1.0)); - if (interp == NNEIGHBOUR) + for (i = 0; i < 3; i++) + { + uint8_t values[2][2]; + double value_left; + double value_right; + double value_final; + + values[0][0] = src->data[i][(y_src_top * src->width) + x_src_left]; + values[0][1] = src->data[i][(y_src_top * src->width) + x_src_right]; + values[1][0] = src->data[i][(y_src_bottom * src->width) + x_src_left]; + values[1][1] = src->data[i][(y_src_bottom * src->width) + x_src_right]; + + value_left = (1.0 - y_bottom_frac) * values[0][0] + + y_bottom_frac * values[1][0]; + value_right = (1.0 - y_bottom_frac) * values[0][1] + + y_bottom_frac * values[1][1]; + + value_final = (1.0 - x_right_frac) * value_left + x_right_frac * value_right; + + assert ((value_final >= 0.0) && (value_final <= 255.0)); + + dest->data[i][pixel_dest] = (uint8_t) (value_final + 0.5); + } + } + else /* 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; @@ -117,7 +159,7 @@ static int copy_pixel (ui_image_t *dest, const ui_image_t *src, // must have been allocated and locked! int pl_extract_view (ui_image_t *view, const ui_image_t *pano, - double pitch, double yaw, double fov) + double pitch, double yaw, double fov, interpolator_t interp) { int x_dest, y_dest; // Loop through destination image @@ -165,110 +207,13 @@ int pl_extract_view (ui_image_t *view, const ui_image_t *pano, copy_pixel (view, pano, dest_width_left + x_dest, dest_height_top + y_dest, src_width_left + x_src_fp, src_height_top + y_src_fp, - NNEIGHBOUR); + interp); /* FIXME */ } } return (0); } -#if 0 -void matrix_inv_mult( double m[3][3], double vector[3] ) -{ - register int i; - register double v0 = vector[0]; - register double v1 = vector[1]; - register double v2 = vector[2]; - - for(i=0; i<3; i++) - { - vector[i] = m[0][i] * v0 + m[1][i] * v1 + m[2][i] * v2; - } -} -#endif - -#define ID_0 0xff -#define ID_1 0xd8 -#define ID_2 0xff -#define ID_3 0xe0 -#define ID_4 0x00 -#define ID_5 0x10 -#define ID_6 0x4a -#define ID_7 0x46 -#define ID_8 0x49 -#define ID_9 0x46 -#define ID_10 0x00 - -#define ID_LENGTH 11 - -// Find last jpeg inside image; create and copy to file jpeg -int extractJPEG( fullPath *image, fullPath *jpeg ) -{ - file_spec fnum; - long count; - unsigned char* im; - int i, idx = -1; - unsigned char ch; - - if( myopen( image, read_bin, fnum ) ) - return -1; - - - count = 1; i=0; // Get file length - - while( count == 1 ) - { - myread( fnum, count, &ch ); - if(count==1) i++; - } - myclose(fnum); - - count = i; - - im = (UCHAR*)malloc( count ); - if( im == NULL ) - { - PrintError("Not enough memory"); - return -1; - } - - if( myopen( image, read_bin, fnum ) ) - return -1; - - myread(fnum,count,im); - myclose(fnum); - - if( i != count ) - return -1; - - count -= ID_LENGTH; - - for(i=0; iwidth, cev->height); ui_destroy (view); view = ui_create (cev->width, cev->height); @@ -434,6 +432,9 @@ int main( int argc, char** argv ) case ButtonRelease: btn_current_pressed = 0; + /* Re-draw the image (when no button is pressed better interpolation is + * used. */ + isChanged = 1; break; case MotionNotify: @@ -495,7 +496,8 @@ int main( int argc, char** argv ) if (isChanged != 0) { - pl_extract_view (view, pano, pitch, yaw, fov); + pl_extract_view (view, pano, pitch, yaw, fov, + (btn_current_pressed == 0) ? BILINEAR : NNEIGHBOUR); draw_window (view); } } /* while (done == 0) */