#include "filter.h"
#include "utils_math.h"
+#include "utils_image.h"
#define DEG_TO_RAD(x) ((x) * 2.0 * M_PI / 360.0 )
#define NATAN 2048
#define NSQRT 2048
-int *atan_LU;
-int *sqrt_LU;
-
-
-void matrix_matrix_mult ( double m1[3][3],double m2[3][3],double result[3][3]);
-void PV_transForm( TrformStr *TrPtr, double dist_r, double dist_e, int mt[3][3]);
-int PV_sqrt( int x1, int x2 );
-
-
-/*
- * Extract image from pano in TrPtr->src using parameters in prefs (ignore
- * image parameters in TrPtr)
- */
-void PV_ExtractStill( TrformStr *TrPtr )
+static void matrix_matrix_mult( double m1[3][3],double m2[3][3],double result[3][3])
{
- /* field of view in rad */
- double a;
- double b;
-
- double p[2];
- double mt[3][3];
- int mi[3][3],i,k;
-
- a = DEG_TO_RAD( TrPtr->dest->hfov ); // field of view in rad
- b = DEG_TO_RAD( TrPtr->src->hfov );
+ 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];
+} /* void matrix_matrix_mult */
- /* 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);
+/* Set matrix elements based on Euler angles a, b, c */
+static void set_transformation_matrix (double m[3][3],
+ double a, double b, double c)
+{
+ double mx[3][3], my[3][3], mz[3][3], dummy[3][3];
+
+ // Calculate Matrices;
- p[0] = (double)TrPtr->dest->width/ (2.0 * tan( a / 2.0 ) );
- p[1] = (double) TrPtr->src->width / b;
+ mx[0][0] = 1.0 ; mx[0][1] = 0.0 ; mx[0][2] = 0.0;
+ mx[1][0] = 0.0 ; mx[1][1] = cos(a) ; mx[1][2] = sin(a);
+ mx[2][0] = 0.0 ; mx[2][1] =-mx[1][2] ; mx[2][2] = mx[1][1];
- for(i=0; i<3; i++){
- for(k=0; k<3; k++){
- mi[i][k] = 256 * mt[i][k];
- }
- }
+ my[0][0] = cos(b); my[0][1] = 0.0 ; my[0][2] =-sin(b);
+ my[1][0] = 0.0 ; my[1][1] = 1.0 ; my[1][2] = 0.0;
+ my[2][0] = -my[0][2]; my[2][1] = 0.0 ; my[2][2] = my[0][0];
+
+ mz[0][0] = cos(c) ; mz[0][1] = sin(c) ; mz[0][2] = 0.0;
+ 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' */
- PV_transForm( TrPtr, p[0], p[1], mi);
- return;
-}
+ matrix_matrix_mult( mz, mx, dummy);
+ 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 (Image *dest, Image *src,
+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,
interpolator_t interp)
{
- uint32_t pixel_value;
- uint32_t *src_data = (uint32_t *) (*src->data);
- uint32_t *dest_data = (uint32_t *) (*dest->data);
+ uint32_t pixel_dest = (y_dest * dest->width) + x_dest;
interp = NNEIGHBOUR;
if ((x_src < 0) || (x_src >= src->width)
|| (y_src < 0) || (y_src >= src->height))
- pixel_value = 0x000000FF;
+ {
+ dest->data[0][pixel_dest] = 0;
+ dest->data[1][pixel_dest] = 0;
+ dest->data[2][pixel_dest] = 0;
+ }
else
- pixel_value = src_data[(y_src * src->width) + x_src];
- }
+ {
+ uint32_t pixel_src = (y_src * src->width) + x_src;
- dest_data[(y_dest * dest->width) + x_dest] = pixel_value;
+ dest->data[0][pixel_dest] = src->data[0][pixel_src];
+ dest->data[1][pixel_dest] = src->data[1][pixel_src];
+ dest->data[2][pixel_dest] = src->data[2][pixel_src];
+ }
+ }
return (0);
} /* int copy_pixel */
// determined. If successful, TrPtr->success = 1. Memory for destination image
// must have been allocated and locked!
-void PV_transForm( TrformStr *TrPtr, double dist_r, double dist_e, int mt[3][3])
+int pl_extract_view (ui_image_t *view, const ui_image_t *pano,
+ double pitch, double yaw, double fov)
{
- 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 x_dest, y_dest; // Loop through destination image
-
- 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 dest_width_left = view->width / 2 ;
+ int dest_height_top = view->height / 2 ;
+ int src_width_left = pano->width / 2 ;
+ int src_height_top = pano->height / 2 ;
- int v[3];
- int x_min, x_max, y_min, y_max;
+ double v[3];
+ int x_min, x_max, y_min, y_max;
- int dr1, dr2, dr3;
+ /* The transformation matrix */
+ double tm[3][3];
- 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
+ double dist_r;
+ double dist_e;
- 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;
+ { /* What the fuck does this? -octo */
+ double a = DEG_TO_RAD (fov);
+ double b = 2.0 * M_PI; /* DEG_TO_RAD (360.0) */
+
+ dist_r = ((double) view->width) / (2.0 * tan (a / 2.0));
+ dist_e = ((double) pano->width) / b;
+ }
+
+ set_transformation_matrix (tm, DEG_TO_RAD (pitch), DEG_TO_RAD (yaw), 0.0);
+
+ x_min = -dest_width_left; x_max = view->width - dest_width_left;
+ y_min = -dest_height_top; y_max = view->height - dest_height_top;
for(y_dest = y_min; y_dest < y_max; y_dest++)
{
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;
+ v[0] = tm[0][0] * x_dest + tm[1][0] * y_dest + tm[2][0] * dist_r;
+ v[1] = tm[0][1] * x_dest + tm[1][1] * y_dest + tm[2][1] * dist_r;
+ v[2] = tm[0][2] * x_dest + tm[1][2] * y_dest + tm[2][2] * dist_r;
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,
+ 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);
}
}
- return;
+ return (0);
}
#if 0
}
#endif
-// Set matrix elements based on Euler angles a, b, c
-
-void SetMatrix( double a, double b, double c , double m[3][3], int cl )
-{
- double mx[3][3], my[3][3], mz[3][3], dummy[3][3];
-
-
- // Calculate Matrices;
-
- mx[0][0] = 1.0 ; mx[0][1] = 0.0 ; mx[0][2] = 0.0;
- mx[1][0] = 0.0 ; mx[1][1] = cos(a) ; mx[1][2] = sin(a);
- mx[2][0] = 0.0 ; mx[2][1] =-mx[1][2] ; mx[2][2] = mx[1][1];
-
- my[0][0] = cos(b); my[0][1] = 0.0 ; my[0][2] =-sin(b);
- my[1][0] = 0.0 ; my[1][1] = 1.0 ; my[1][2] = 0.0;
- my[2][0] = -my[0][2]; my[2][1] = 0.0 ; my[2][2] = my[0][0];
-
- mz[0][0] = cos(c) ; mz[0][1] = sin(c) ; mz[0][2] = 0.0;
- 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];
-} /* void matrix_matrix_mult */
-
#define ID_0 0xff
#define ID_1 0xd8
#define ID_2 0xff
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
-#include "filter.h"
-
-void PV_ExtractStill( TrformStr *TrPtr );
-void PV_SetInvMakeParams( struct fDesc *stack, struct MakeParams *mp, Image *im , Image *pn );
-
-void DrawWindow();
-void DrawView(int InterPolator);
-
-int readJPEG ( Image *im, fullPath *sfile );
-int panning = FALSE;
-int zooming_in = FALSE;
-int zooming_out = FALSE;
-
-#define VIEW_WIDTH 400
-#define VIEW_HEIGHT 300
+#include "filter.h"
+#include "panolib.h"
+#include "utils_image.h"
+#define DEF_VIEW_WIDTH 400
+#define DEF_VIEW_HEIGHT 300
char text[] = "PTViewer";
-Image view, pano;
-Display *disp;
-Window win;
-int screen;
-XImage *ximage = NULL;
-GC gc;
-Visual *visual;
-unsigned int depth;
-int oldposx, oldposy;
+Display *disp_g;
+Window window_g;
+int screen_g;
+GC gc;
+Visual *visual_g;
+unsigned int depth_g;
-int main( int argc, char** argv )
+static int copy_rgb_to_zpixmap (XImage *dest, const ui_image_t *src)
{
- XSizeHints hint;
- unsigned long fg, bg;
- int done;
- union
- {
- XEvent event;
- XAnyEvent any;
- XButtonEvent button;
- XKeyEvent key;
- XConfigureEvent configure;
- XExposeEvent expose;
- XMotionEvent motion;
- XResizeRequestEvent resize;
- XClientMessageEvent message;
- } event;
- int newposx, newposy;
- static Atom proto_atom= None, delete_atom= None;
-
-
- // Set up display
-
-
-
- disp = XOpenDisplay("");
- screen = DefaultScreen(disp);
- depth = DefaultDepth(disp, screen);
-
- if( depth != 24 )
- {
- PrintError("Depth = %d, must be 24 pixels", (int)depth);
- }
- bg = WhitePixel(disp,screen);
- fg = BlackPixel(disp,screen);
+ uint32_t *src_data;
- // Load panoramic image
- if( argc < 2 )
- {
- PrintError("No image file supplied");
- exit(0);
- }
-
- if( strcmp( argv[1], "-h" ) == 0 )
- {
- PrintError( "%s\n %s\nUsage: PTViewer Imagefile", "PTViewer", LONGVERSION );
- exit(0);
- }
- if( readJPEG( &pano, (fullPath*)argv[1] ) != 0 )
- {
- PrintError("Could not read panoramic image");
- exit(0);
- }
- pano.hfov = 360.0;
- pano.format = _equirectangular;
-
- // Set up viewer window
-
- SetImageDefaults( &view );
-
- view.hfov = 70.0;
- view.width = VIEW_WIDTH;
- view.height = VIEW_HEIGHT;
- view.bitsPerPixel = 32;
- view.bytesPerLine = view.width * view.bitsPerPixel / 8;
- view.dataSize = view.bytesPerLine * view.height;
- view.format = 1;
- view.data = (unsigned char**)mymalloc( view.dataSize );
- if(view.data == NULL)
- {
- PrintError("Not enough memory");
- exit(0);
- }
+ uint32_t src_r;
+ uint32_t src_g;
+ uint32_t src_b;
+ uint32_t dest_r;
+ uint32_t dest_g;
+ uint32_t dest_b;
+ uint32_t dest_pixel_value;
- hint.x = 200;
- hint.y = 200;
- hint.width = view.width;
- hint.height = view.height;
- hint.flags=PPosition | PSize;
-
- win = XCreateSimpleWindow(disp,
- DefaultRootWindow(disp),
- hint.x,
- hint.y,
- hint.width,
- hint.height,
- 5,
- fg,
- bg);
-
- XSetStandardProperties(disp,
- win,
- text,
- text,
- None,
- argv,
- argc,
- &hint);
- gc = XCreateGC(disp,win,0,0);
- XSetBackground(disp,gc,bg);
- XSetForeground(disp,gc,fg);
-
- XSelectInput(disp,
- win,
- ButtonPressMask | ButtonReleaseMask | Button1MotionMask | KeyPressMask | KeyReleaseMask |
- StructureNotifyMask | EnterWindowMask | LeaveWindowMask| ExposureMask);
- XMapRaised(disp,win);
-
- proto_atom = XInternAtom(disp, "WM_PROTOCOLS", False);
- delete_atom = XInternAtom(disp, "WM_DELETE_WINDOW", False);
- if ((proto_atom != None) && (delete_atom != None))
- XChangeProperty(disp, win, proto_atom, XA_ATOM, 32, PropModeReplace, (unsigned char *)&delete_atom, 1);
-
-
-
- visual = DefaultVisual(disp, screen);
-
- ximage = XCreateImage(disp, visual, depth, ZPixmap, 0,
- NULL, view.width, view.height,
- 8, 0);
- memset( *(view.data), 0, view.dataSize);
- ximage->data = (char *)*(view.data);
- ximage->byte_order= MSBFirst;
+ uint32_t x;
+ uint32_t y;
+ uint32_t pixel;
+ uint32_t dest_r_maxval;
+ uint32_t dest_g_maxval;
+ uint32_t dest_b_maxval;
+ uint32_t dest_r_offset;
+ uint32_t dest_g_offset;
+ uint32_t dest_b_offset;
- done = 0;
- while( done==0)
+ dest_r_offset = 0;
+ dest_g_offset = 0;
+ dest_b_offset = 0;
+ dest_r_maxval = dest->red_mask;
+ dest_g_maxval = dest->green_mask;
+ dest_b_maxval = dest->blue_mask;
+ for (x = 0; x < dest->depth; x++)
{
- int isChanged = 0;
-
- // No XNextEvent
-
- if( XCheckTypedEvent(disp, Expose, (XEvent*)&event) ) DrawWindow();
-
- if( XCheckTypedEvent(disp, KeyPress, (XEvent*)&event) )
- {
- char buf[128];
- KeySym ks;
- XComposeStatus status;
- int nkey = XLookupString(&event.key,buf,128,&ks,&status);
-
- if( nkey == 0 )
- {
- switch(ks)
- {
- case XK_Shift_L:
- case XK_Shift_R: zooming_in = TRUE;
- break;
-
- case XK_Control_L:
- case XK_Control_R: zooming_out = TRUE;
- break;
- }
- }
- else if( nkey == 1 && buf[0] == 'q')
- done = 1;
-
- goto _EventLoop;
- }
-
- if( XCheckTypedEvent(disp, KeyRelease, (XEvent*)&event) )
- {
- char buf[128];
- KeySym ks;
- XComposeStatus status;
-
- if (XLookupString(&event.key,buf,128,&ks,&status) == 0)
- {
- switch(ks)
- {
- case XK_Shift_L:
- case XK_Shift_R: zooming_in = FALSE;
- view.format = 1;
- DrawWindow();
- break;
- case XK_Control_L:
- case XK_Control_R: zooming_out = FALSE;
- view.format = 1;
- DrawWindow();
- break;
- }
- }
- goto _EventLoop;
- }
-
- if( XCheckTypedEvent(disp, MotionNotify, (XEvent*)&event) )
- {
- newposx = event.button.x;
- newposy = event.button.y;
- while (XCheckTypedEvent(disp, MotionNotify, (XEvent*)&event) == True)
- {
- newposx= event.button.x;
- newposy= event.button.y;
- }
- }
-
- if( XCheckTypedEvent(disp, ButtonPress, (XEvent*)&event) )
+ if ((dest_r_maxval & 0x01) == 0)
{
- if (event.button.button == 1)
- {
- panning = TRUE;
- oldposx = newposx = event.button.x;
- oldposy = newposy = event.button.y;
- }
+ dest_r_offset++;
+ dest_r_maxval >>= 1;
}
-
- if( XCheckTypedEvent(disp, ButtonRelease, (XEvent*)&event) )
+ if ((dest_g_maxval & 0x01) == 0)
{
- if (event.button.button == 1)
- {
- panning = FALSE;
- view.format = 1;
- DrawWindow();
- }
+ dest_g_offset++;
+ dest_g_maxval >>= 1;
}
-
- if( XCheckTypedEvent(disp, DestroyNotify, (XEvent*)&event) )
- done = 1;
-
- if( XCheckTypedEvent(disp,ClientMessage , (XEvent*)&event) )
+ if ((dest_b_maxval & 0x01) == 0)
{
- if ((event.message.window == win) && (event.message.data.l[0] == delete_atom))
- done = 1;
+ dest_b_offset++;
+ dest_b_maxval >>= 1;
}
+ }
-
-_EventLoop:
- if( panning )
- {
- double yaw, pitch;
-
- yaw = view.yaw + (newposx - oldposx)/20.0;
- NORM_ANGLE( yaw );
-
- pitch = view.pitch - (newposy - oldposy)/20.0;
- if( pitch > 90.0 ) pitch = 90.0;
- if( pitch < -90.0 ) pitch = -90.0;
-
- if( pitch != view.pitch || yaw != view.yaw )
- {
- view.pitch = pitch;
- view.yaw = yaw;
- isChanged = 1;
- }
- }
- if( zooming_in && view.hfov > 10.5)
- {
- view.hfov /= 1.03;
- isChanged = 1;
- }
- if( zooming_out && view.hfov < 165.0)
- {
- view.hfov *= 1.03;
- isChanged = 1;
- }
- if( zooming_in || zooming_out || panning )
+ src_data = (uint32_t *) *src->data;
+
+ pixel = 0;
+ for (y = 0; y < dest->height; y++)
+ {
+ for (x = 0; x < dest->width; x++, pixel++)
{
- if( isChanged )
+ int32_t bytenum;
+
+ src_r = src->data[0][pixel];
+ src_g = src->data[1][pixel];
+ src_b = src->data[2][pixel];
+
+ dest_r = dest_r_maxval * src_r / 255;
+ dest_g = dest_g_maxval * src_g / 255;
+ dest_b = dest_b_maxval * src_b / 255;
+
+ dest_pixel_value = 0
+ | ((dest_r << dest_r_offset) & dest->red_mask)
+ | ((dest_g << dest_g_offset) & dest->green_mask)
+ | ((dest_b << dest_b_offset) & dest->blue_mask);
+
+ for (bytenum = 0; bytenum < (dest->depth / 8); bytenum++)
{
- view.format = 1;
- DrawWindow();
+ dest->data[(pixel * dest->bits_per_pixel / 8) + bytenum] =
+ (dest_pixel_value >> (dest->bits_per_pixel - (8 * (bytenum + 1)))) & 0xFF;
}
}
+ }
+
+ return (0);
+} /* int copy_rgb_to_zpixmap */
+
+static int draw_window (const ui_image_t *img)
+{
+ static XImage *ximage = NULL;
+
+ if ((ximage != NULL) && ((img->width != ximage->width) || (img->height != ximage->height)))
+ {
+ free (ximage->data);
+ XDestroyImage (ximage);
+ ximage = NULL;
+ }
+
+ if (ximage == NULL)
+ {
+ char *data;
+ ximage = XCreateImage(disp_g, visual_g, depth_g, ZPixmap, 0,
+ NULL, img->width, img->height,
+ 8, 0);
+ if (ximage == NULL)
+ return (-1);
+
+ ximage->byte_order= MSBFirst;
+ data = (char *) malloc (img->width * img->height * depth_g / 8);
+ ximage->data = data;
+ if (ximage->data == NULL)
+ {
+ XDestroyImage (ximage);
+ ximage = NULL;
+ return (-1);
+ }
+ }
+ copy_rgb_to_zpixmap (ximage, img);
+ XPutImage(disp_g, window_g, gc, ximage, 0, 0,
+ 0, 0, ximage->width, ximage->height);
+
+ return (0);
+} /* int draw_window */
+
+#define ZOOM_SPEED 1.03
+
+static void zoom_in (double *fov)
+{
+ *fov = *fov / ZOOM_SPEED;
+ if (*fov < 10.5)
+ *fov = 10.5;
+} /* void zoom_in */
+
+static void zoom_out (double *fov)
+{
+ *fov = *fov * ZOOM_SPEED;
+ if (*fov > 165.0)
+ *fov = 165.0;
+} /* void zoom_out */
+
+int main( int argc, char** argv )
+{
+ XSizeHints hint;
+ unsigned long color_fg, color_bg;
+ int done;
+ static Atom proto_atom= None, delete_atom= None;
+
+ long event_mask;
+ unsigned int button_state = 0;
+
+ double fov = 70.0;
+ double yaw = 0.0;
+ double pitch = 0.0;
+
+ /* Detect mouse movement direction */
+ int pos_x_new = 0;
+ int pos_y_new = 0;
+ int pos_x_old;
+ int pos_y_old;
+
+ ui_image_t *pano;
+ ui_image_t *view;
+
+
+ // Set up display
+ disp_g = XOpenDisplay("");
+ screen_g = DefaultScreen(disp_g);
+ depth_g = DefaultDepth(disp_g, screen_g);
+
+ color_bg = WhitePixel(disp_g,screen_g);
+ color_fg = BlackPixel(disp_g,screen_g);
+
+ // Load panoramic image
+ if( argc < 2 )
+ {
+ PrintError("No image file supplied");
+ exit(0);
+ }
+
+ if( strcmp( argv[1], "-h" ) == 0 ) /* FIXME: Use getopt */
+ {
+ PrintError( "%s\n %s\nUsage: PTViewer Imagefile", "PTViewer", LONGVERSION );
+ exit(0);
+ }
+
+ pano = ui_create_file (argv[1]);
+ if (pano == NULL)
+ {
+ PrintError ("Unable to read pano file.");
+ exit (0);
+ }
+
+ printf ("Panorama `%s', %ux%u pixels, loaded.\n",
+ argv[1], pano->width, pano->height);
+
+ view = ui_create (DEF_VIEW_WIDTH, DEF_VIEW_HEIGHT); /* FIXME: Possibly chose another size */
+ if (view == NULL)
+ {
+ PrintError ("Unable to create view.");
+ exit (0);
+ }
+
+ hint.width = view->width;
+ hint.height = view->height;
+ hint.flags = PSize;
+
+ window_g = XCreateSimpleWindow(disp_g,
+ DefaultRootWindow(disp_g),
+ 0, 0, /* Position */
+ view->width, view->height,
+ 5,
+ color_fg, color_bg);
+
+ XSetStandardProperties(disp_g,
+ window_g,
+ text,
+ text,
+ None,
+ argv,
+ argc,
+ &hint);
+ gc = XCreateGC(disp_g,window_g,0,0);
+ XSetBackground(disp_g,gc,color_bg);
+ XSetForeground(disp_g,gc,color_fg);
+
+ event_mask = ButtonPressMask | ButtonReleaseMask | Button1MotionMask
+ | KeyPressMask | KeyReleaseMask | StructureNotifyMask
+ | EnterWindowMask | LeaveWindowMask| ExposureMask;
+
+ XSelectInput(disp_g, window_g, event_mask);
+ XMapRaised(disp_g,window_g);
+
+ proto_atom = XInternAtom(disp_g, "WM_PROTOCOLS", False);
+ delete_atom = XInternAtom(disp_g, "WM_DELETE_WINDOW", False);
+ if ((proto_atom != None) && (delete_atom != None))
+ XChangeProperty(disp_g, window_g, proto_atom, XA_ATOM, 32,
+ PropModeReplace, (unsigned char *)&delete_atom,
+ 1);
+ visual_g = DefaultVisual(disp_g, screen_g);
+
+ pl_extract_view (view, pano, pitch, yaw, fov);
+ draw_window (view);
+
+ done = 0;
+ while (done == 0)
+ {
+ int isChanged = 0;
+ XEvent event;
+
+ XMaskEvent (disp_g, event_mask, &event);
+
+ switch (event.type)
+ {
+ case Expose:
+ draw_window (view);
+ break;
+
+ case ConfigureNotify:
+ {
+ XConfigureEvent *cev = (XConfigureEvent *) &event;
+ printf ("XConfigureEvent received: width = %i; height = %i;\n",
+ cev->width, cev->height);
+ /* TODO, FIXME: re-create `view' and `ximage' with cev->width, cev->height */
}
- XFreeGC(disp,gc);
- XDestroyWindow(disp, win);
- XCloseDisplay(disp);
+ break;
- return (0);
-}
+ case KeyPress:
+ {
+ XKeyEvent *kev = (XKeyEvent *) &event;
+ KeySym ks = XLookupKeysym (kev, 0);
+
+ switch (ks)
+ {
+ case XK_Shift_L:
+ case XK_Shift_R:
+ zoom_in (&fov);
+ isChanged = 1;
+ break;
+
+ case XK_Control_L:
+ case XK_Control_R:
+ zoom_out (&fov);
+ isChanged = 1;
+ break;
+ }
+ }
+ break;
+
+ case KeyRelease:
+ printf ("Ignoring KeyRelease event.\n");
+ break;
+
+ case ButtonPress:
+ case ButtonRelease:
+ {
+ XButtonEvent *bev = (XButtonEvent *) &event;
+ button_state = bev->state;
+ }
+ break;
+
+ case MotionNotify:
+ {
+ XMotionEvent *mev = (XMotionEvent *) &event;
+
+ pos_x_old = pos_x_new;
+ pos_y_old = pos_y_new;
+ pos_x_new = mev->x;
+ pos_y_new = mev->y;
+
+ if (button_state & Button1Mask)
+ {
+ double yaw_diff = (pos_x_new - pos_x_old) / 24.0;
+ if (yaw_diff > 90.0)
+ yaw_diff = 90.0;
+ else if (yaw_diff < -90.0)
+ yaw_diff = -90.0;
+
+ yaw += yaw_diff;
+ if (yaw > 180.0)
+ yaw -= 360.0;
+ else if (yaw <= -180.0)
+ yaw += 360.0;
+
+ pitch -= (pos_y_new - pos_y_old) / 24.0;
+ if (pitch > 90.0)
+ pitch = 90.0;
+ else if (pitch < -90.0)
+ pitch = -90.0;
+
+ isChanged = 1;
+ }
+ }
+ break;
+
+ default:
+ printf ("Unhandled event type: 0x%02x\n",
+ event.type);
+ } /* switch (event.type) */
+
+ if (isChanged != 0)
+ {
+ pl_extract_view (view, pano, pitch, yaw, fov);
+ draw_window (view);
+ }
+ } /* while (done == 0) */
+
+ XFreeGC(disp_g,gc);
+ XDestroyWindow(disp_g, window_g);
+ XCloseDisplay(disp_g);
+
+ return (0);
+} /* int main */
im->dataSize = im->height * im->bytesPerLine;
}
-static int copy_rgb_to_zpixmap (XImage *dest, const Image *src)
-{
- uint32_t *src_data;
-
- uint32_t src_r;
- uint32_t src_g;
- uint32_t src_b;
-
- uint32_t dest_r;
- uint32_t dest_g;
- uint32_t dest_b;
- uint32_t dest_pixel_value;
-
- uint32_t x;
- uint32_t y;
- uint32_t pixel;
-
- uint32_t dest_r_maxval;
- uint32_t dest_g_maxval;
- uint32_t dest_b_maxval;
-
- uint32_t dest_r_offset;
- uint32_t dest_g_offset;
- uint32_t dest_b_offset;
-
- dest_r_offset = 0;
- dest_g_offset = 0;
- dest_b_offset = 0;
- dest_r_maxval = dest->red_mask;
- dest_g_maxval = dest->green_mask;
- dest_b_maxval = dest->blue_mask;
- for (x = 0; x < dest->depth; x++)
- {
- if ((dest_r_maxval & 0x01) == 0)
- {
- dest_r_offset++;
- dest_r_maxval >>= 1;
- }
- if ((dest_g_maxval & 0x01) == 0)
- {
- dest_g_offset++;
- dest_g_maxval >>= 1;
- }
- if ((dest_b_maxval & 0x01) == 0)
- {
- dest_b_offset++;
- dest_b_maxval >>= 1;
- }
- }
-
- src_data = (uint32_t *) *src->data;
-
- pixel = 0;
- for (y = 0; y < dest->height; y++)
- {
- for (x = 0; x < dest->width; x++, pixel++)
- {
- int32_t bytenum;
-
- src_r = (src_data[pixel] >> 8) & 0xFF;
- src_g = (src_data[pixel] >> 16) & 0xFF;
- src_b = (src_data[pixel] >> 24) & 0xFF;
-
- dest_r = dest_r_maxval * src_r / 0xFF;
- dest_g = dest_g_maxval * src_g / 0xFF;
- dest_b = dest_b_maxval * src_b / 0xFF;
-
- dest_pixel_value = 0
- | ((dest_r << dest_r_offset) & dest->red_mask)
- | ((dest_g << dest_g_offset) & dest->green_mask)
- | ((dest_b << dest_b_offset) & dest->blue_mask);
-
- for (bytenum = 0; bytenum < (dest->depth / 8); bytenum++)
- {
- dest->data[(pixel * dest->bits_per_pixel / 8) + bytenum] =
- (dest_pixel_value >> (dest->bits_per_pixel - (8 * (bytenum + 1)))) & 0xFF;
- }
- }
- }
-
- return (0);
-} /* int copy_rgb_to_zpixmap */
-
-void DrawWindow()
-{
- XWindowAttributes xa;
-
- XGetWindowAttributes( disp, win, &xa );
-
- if( xa.width != view.width || xa.height != view.height )
- {
- myfree((void**)view.data);
- view.width = xa.width;
- view.height = xa.height;
- view.bytesPerLine = view.width * view.bitsPerPixel / 8;
- view.dataSize = view.bytesPerLine * view.height;
- view.format = 1;
- view.data = (unsigned char**)mymalloc( view.dataSize );
- if(view.data == NULL)
- {
- PrintError("Not enough memory");
- exit(0);
- }
-
- ximage = XCreateImage(disp, visual, depth, ZPixmap, 0,
- NULL, view.width, view.height,
- 8, 0);
- ximage->data = (char *)*(view.data);
- ximage->byte_order= MSBFirst;
- }
- if( view.format )
- {
- if( panning || zooming_in || zooming_out)
- DrawView(_nn);
- else
- DrawView(_bilinear);
- }
-
- ximage->data = (char *) malloc (view.dataSize);
- if (ximage->data == NULL)
- return;
- memcpy (ximage->data, *(view.data), view.dataSize);
-
- copy_rgb_to_zpixmap (ximage, &view);
-
- XPutImage(disp, win, gc, ximage, 0, 0, 0, 0, view.width, view.height);
-
- free (ximage->data);
- ximage->data = NULL;
-}
-
-void DrawView(int InterPolator)
-{
- TrformStr Tr;
-
- Tr.interpolator = InterPolator;
-
- Tr.src = &pano;
- Tr.dest = &view;
-
- PV_ExtractStill( &Tr );
-
- view.format = 0;
- return;
-
-}
-
+/*
+ * vim: set shiftwidth=2 tabstop=8 softtabstop=2 :
+ */