panolib.c: Implemented bilinear interpolation.
authorFlorian Forster <octo@leeloo.lan.home.verplant.org>
Sat, 18 Aug 2007 10:57:25 +0000 (12:57 +0200)
committerFlorian Forster <octo@leeloo.lan.home.verplant.org>
Sat, 18 Aug 2007 10:57:25 +0000 (12:57 +0200)
It's used in the viewer when no button is pressed.

src/panolib.c
src/panolib.h
src/viewer.c

index 425a839..2686059 100644 (file)
@@ -21,6 +21,7 @@
 #include <assert.h>
 
 #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; i<count; i++)
-       {
-               if( im[i] == ID_0 && im[i+1] == ID_1 && im[i+2] == ID_2 && im[i+3] == ID_3 
-                                       && im[i+4] == ID_4 && im[i+5] == ID_5 && im[i+6] == ID_6 && im[i+7] == ID_7
-                                       && im[i+8] == ID_8 && im[i+9] == ID_9 && im[i+10] == ID_10)
-                               idx = i;
-       }
-
-       if( idx == -1 ) // No jpeg found
-       {
-               free(im);
-               return -1;
-       }
-       
-       count = count + ID_LENGTH - idx;
-       
-       mycreate( jpeg, 'GKON','JPEG');
-       if( myopen( jpeg, write_bin, fnum ) )
-               return -1;
-       mywrite( fnum, count, im+idx );
-       free( im );
-       myclose( fnum );
-       return 0;
-}
-               
-
 /*
  * vim: set tabstop=4 softtabstop=4 shiftwidth=4 :
  */
index 98af710..07f4723 100644 (file)
 
 #include "utils_image.h"
 
+typedef enum interpolator_e
+{
+       NNEIGHBOUR,
+       BILINEAR
+} interpolator_t;
+
 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);
 
 #endif /* PANOLIB_H */
index 3494d19..8967b9c 100644 (file)
@@ -286,7 +286,7 @@ int main( int argc, char** argv )
        1);
   visual_g  = DefaultVisual(disp_g, screen_g);
 
-  pl_extract_view (view, pano, pitch, yaw, fov);
+  pl_extract_view (view, pano, pitch, yaw, fov, BILINEAR);
   draw_window (view);
 
   done = 0;
@@ -341,8 +341,6 @@ int main( int argc, char** argv )
       case ConfigureNotify:
        {
          XConfigureEvent *cev = (XConfigureEvent *) &event;
-         printf ("XConfigureEvent received: width = %i; height = %i;\n",
-             cev->width, 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) */