1 /* Panorama_Tools - Generate, Edit and Convert Panoramic Images
2 Copyright (C) 1998,1999,2000 - Helmut Dersch der@fh-furtwangen.de
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18 /*------------------------------------------------------------*/
22 #include <X11/Xutil.h>
23 #include <X11/cursorfont.h>
24 #include <X11/keysym.h>
25 #include <X11/Xatom.h>
32 #include "utils_image.h"
34 #define DEF_VIEW_WIDTH 400
35 #define DEF_VIEW_HEIGHT 300
37 char text[] = "PTViewer";
47 static int copy_rgb_to_zpixmap (XImage *dest, const ui_image_t *src)
58 uint32_t dest_pixel_value;
64 uint32_t dest_r_maxval;
65 uint32_t dest_g_maxval;
66 uint32_t dest_b_maxval;
68 uint32_t dest_r_offset;
69 uint32_t dest_g_offset;
70 uint32_t dest_b_offset;
75 dest_r_maxval = dest->red_mask;
76 dest_g_maxval = dest->green_mask;
77 dest_b_maxval = dest->blue_mask;
78 for (x = 0; x < dest->depth; x++)
80 if ((dest_r_maxval & 0x01) == 0)
85 if ((dest_g_maxval & 0x01) == 0)
90 if ((dest_b_maxval & 0x01) == 0)
97 src_data = (uint32_t *) *src->data;
100 for (y = 0; y < dest->height; y++)
102 for (x = 0; x < dest->width; x++, pixel++)
106 src_r = src->data[0][pixel];
107 src_g = src->data[1][pixel];
108 src_b = src->data[2][pixel];
110 dest_r = dest_r_maxval * src_r / 255;
111 dest_g = dest_g_maxval * src_g / 255;
112 dest_b = dest_b_maxval * src_b / 255;
115 | ((dest_r << dest_r_offset) & dest->red_mask)
116 | ((dest_g << dest_g_offset) & dest->green_mask)
117 | ((dest_b << dest_b_offset) & dest->blue_mask);
119 for (bytenum = 0; bytenum < (dest->depth / 8); bytenum++)
121 dest->data[(pixel * dest->bits_per_pixel / 8) + bytenum] =
122 (dest_pixel_value >> (dest->bits_per_pixel - (8 * (bytenum + 1)))) & 0xFF;
128 } /* int copy_rgb_to_zpixmap */
130 static int draw_window (const ui_image_t *img)
132 static XImage *ximage = NULL;
134 if ((ximage != NULL) && ((img->width != ximage->width) || (img->height != ximage->height)))
137 XDestroyImage (ximage);
144 ximage = XCreateImage(disp_g, visual_g, depth_g, ZPixmap, 0,
145 NULL, img->width, img->height,
150 ximage->byte_order= MSBFirst;
152 data = (char *) malloc (img->width * img->height * depth_g / 8);
154 if (ximage->data == NULL)
156 XDestroyImage (ximage);
162 copy_rgb_to_zpixmap (ximage, img);
163 XPutImage(disp_g, window_g, gc, ximage, 0, 0,
164 0, 0, ximage->width, ximage->height);
167 } /* int draw_window */
169 #define ZOOM_SPEED 1.03
171 static void zoom_in (double *fov)
173 *fov = *fov / ZOOM_SPEED;
178 static void zoom_out (double *fov)
180 *fov = *fov * ZOOM_SPEED;
183 } /* void zoom_out */
185 int main( int argc, char** argv )
188 unsigned long color_fg, color_bg;
190 static Atom proto_atom= None, delete_atom= None;
193 unsigned int button_state = 0;
199 /* Detect mouse movement direction */
210 disp_g = XOpenDisplay("");
211 screen_g = DefaultScreen(disp_g);
212 depth_g = DefaultDepth(disp_g, screen_g);
214 color_bg = WhitePixel(disp_g,screen_g);
215 color_fg = BlackPixel(disp_g,screen_g);
217 // Load panoramic image
220 PrintError("No image file supplied");
224 if( strcmp( argv[1], "-h" ) == 0 ) /* FIXME: Use getopt */
226 PrintError( "%s\n %s\nUsage: PTViewer Imagefile", "PTViewer", LONGVERSION );
230 pano = ui_create_file (argv[1]);
233 PrintError ("Unable to read pano file.");
237 printf ("Panorama `%s', %ux%u pixels, loaded.\n",
238 argv[1], pano->width, pano->height);
240 view = ui_create (DEF_VIEW_WIDTH, DEF_VIEW_HEIGHT); /* FIXME: Possibly chose another size */
243 PrintError ("Unable to create view.");
247 hint.width = view->width;
248 hint.height = view->height;
251 window_g = XCreateSimpleWindow(disp_g,
252 DefaultRootWindow(disp_g),
254 view->width, view->height,
258 XSetStandardProperties(disp_g,
266 gc = XCreateGC(disp_g,window_g,0,0);
267 XSetBackground(disp_g,gc,color_bg);
268 XSetForeground(disp_g,gc,color_fg);
270 event_mask = ButtonPressMask | ButtonReleaseMask | Button1MotionMask
271 | KeyPressMask | KeyReleaseMask | StructureNotifyMask
272 | EnterWindowMask | LeaveWindowMask| ExposureMask;
274 XSelectInput(disp_g, window_g, event_mask);
275 XMapRaised(disp_g,window_g);
277 proto_atom = XInternAtom(disp_g, "WM_PROTOCOLS", False);
278 delete_atom = XInternAtom(disp_g, "WM_DELETE_WINDOW", False);
279 if ((proto_atom != None) && (delete_atom != None))
280 XChangeProperty(disp_g, window_g, proto_atom, XA_ATOM, 32,
281 PropModeReplace, (unsigned char *)&delete_atom,
283 visual_g = DefaultVisual(disp_g, screen_g);
285 pl_extract_view (view, pano, pitch, yaw, fov);
294 XMaskEvent (disp_g, event_mask, &event);
302 case ConfigureNotify:
304 XConfigureEvent *cev = (XConfigureEvent *) &event;
305 printf ("XConfigureEvent received: width = %i; height = %i;\n",
306 cev->width, cev->height);
307 /* TODO, FIXME: re-create `view' and `ximage' with cev->width, cev->height */
313 XKeyEvent *kev = (XKeyEvent *) &event;
314 KeySym ks = XLookupKeysym (kev, 0);
334 printf ("Ignoring KeyRelease event.\n");
340 XButtonEvent *bev = (XButtonEvent *) &event;
341 button_state = bev->state;
347 XMotionEvent *mev = (XMotionEvent *) &event;
349 pos_x_old = pos_x_new;
350 pos_y_old = pos_y_new;
354 if (button_state & Button1Mask)
356 double yaw_diff = (pos_x_new - pos_x_old) / 24.0;
359 else if (yaw_diff < -90.0)
365 else if (yaw <= -180.0)
368 pitch -= (pos_y_new - pos_y_old) / 24.0;
371 else if (pitch < -90.0)
380 printf ("Unhandled event type: 0x%02x\n",
382 } /* switch (event.type) */
386 pl_extract_view (view, pano, pitch, yaw, fov);
389 } /* while (done == 0) */
392 XDestroyWindow(disp_g, window_g);
393 XCloseDisplay(disp_g);
405 void PrintError( char* fmt, ...)
411 vsprintf(message, fmt, ap);
414 printf("%s\n", message);
417 void** mymalloc( long numBytes ) // Memory allocation, use Handles
421 mem = (char**)malloc( sizeof(char*) ); // Allocate memory for pointer
426 (*mem) = (char*) malloc( numBytes ); // Allocate numBytes
437 void myfree( void** Hdl ) // free Memory, use Handles
439 free( (char*) *Hdl );
440 free( (char**) Hdl );
444 void SetImageDefaults(Image *im)
447 im->bytesPerLine = 0;
451 im->bitsPerPixel = 0;
453 im->dataformat = _RGB;
458 // SetCorrectDefaults( &(im->cP) );
462 // expand image from 3 to 4 bits per pixel. No pad bytes allowed.
463 // Memory must be allocated
464 void ThreeToFourBPP( Image *im )
466 register int x,y,c1,c2;
468 if( im->bitsPerPixel == 32 || im->bitsPerPixel == 64) // Nothing to do
473 if( im->bitsPerPixel == 24 ) // Convert to 4byte / pixel
475 for( y = im->height-1; y>=0; y--)
477 for( x= im->width-1; x>=0; x--)
479 c1 = (y * im->width + x) * 4;
480 c2 = y * im->bytesPerLine + x * 3;
481 (*(im->data))[c1++] = UCHAR_MAX;
482 (*(im->data))[c1++] = (*(im->data))[c2++];
483 (*(im->data))[c1++] = (*(im->data))[c2++];
484 (*(im->data))[c1++] = (*(im->data))[c2++];
487 im->bitsPerPixel = 32;
488 im->bytesPerLine = im->width * 4;
490 else if( im->bitsPerPixel == 48 ) // Convert to 8byte / pixel
492 for( y = im->height-1; y>=0; y--)
494 for( x= im->width-1; x>=0; x--)
496 c1 = (y * im->width + x) * 4;
497 c2 = y * im->bytesPerLine/2 + x * 3;
498 ((USHORT*)(*(im->data)))[c1++] = USHRT_MAX;
499 ((USHORT*)(*(im->data)))[c1++] = ((USHORT*)(*(im->data)))[c2++];
500 ((USHORT*)(*(im->data)))[c1++] = ((USHORT*)(*(im->data)))[c2++];
501 ((USHORT*)(*(im->data)))[c1++] = ((USHORT*)(*(im->data)))[c2++];
504 im->bitsPerPixel = 64;
505 im->bytesPerLine = im->width * 8;
507 im->dataSize = im->height * im->bytesPerLine;
511 * vim: set shiftwidth=2 tabstop=8 softtabstop=2 :