[Prev][Next][Index][Thread]
Xwindows Qcam movies
Here is my code for displaying the quickcam output in an Xwindow
to give Real Live Motion tm.
There are two parts- a single function QCRead4BitImage that
should be added to Scott's qcam.c file and then a second
file called xstuff.c.
Add -lX11 -lXext to link in x libraries.
To get it to work, modify Scott's program:
right before he first sends commands to camera add:
InitXWindows(qcwidth, qcheight);
InitPalette256();
then instead of qc_read() call, replace with
qc_reset();
...scott's code to send getimage command to QC
QCRead4BitImage(qcwidth, qcheight);
ShowPic();
slap a loop around those statements and voila: movies!
known issues:
It segfaults on exit. 64 palette mode doesn't quite work.
only supports 4 bit image. I think the qc_reset in the loop
is killing frame rate, but it was only way I could get image to update.
Sorry for how piecemile this source and directions are. I was supposed
to "libraryize" and clean it up last nite but a disk error trashed the
whole file so I spent all last nite just recoding what I'd lost.
I figured I'd at least get it out to people so they can tackle some
of the things I've missed.
I'll be working on it more this evening. (nothing quite like a job
to mess with one's "hackin' groove" :^( )
Paul Chinn
here's the code that should go in qcam.c
/* Read a scan from the QC */
extern char *sbuf;
extern char ColorTable[64];
int QCRead4BitImage(int w, int h)
{
int i, hi, lo;
for(i=0;i < w * h;i+=2) {
write_lpcontrol(6);
qc_waithand(1);
hi=read_lpstatus()&0xf0;
write_lpcontrol(0xe);
qc_waithand(0);
lo=(read_lpstatus()&0xf0);
/*4 bit mode has 16 shades of grey. we need to scale to
our 256 palette. Ordinarily we'd multiply the 4 bit value by
16 - but since QC returns value in hi 4 bits, it's already
effectively been mulitplied by 16- so we have to do nothing*/
/*use this code if using a 64 color palette*/
/* sbuf[i] = ColorTable[63 - (hi >> 2) ];
sbuf[i+1] = ColorTable[63 - (lo >> 2)];
*/
/*use this for 256 color*/
sbuf[i] = 256 - hi;
sbuf[i+1] = 256 - lo;
}
return (1);
}
/***************************************
XWindow Support for QuickCam
Paul Chinn
loomer@svpal.org
I took a bunch of this code from the source for VGB
"Virtual GameBoy" emulator by Marat Fayzullin and
Elan Feingold
*****************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/time.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
/** MIT Shared Memory Extension for X ************************/
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>
XShmSegmentInfo SHMInfo;
void ExitXWindows();
/** Various X-related variables ******************************/
Screen *screen;
Display *disp;
Window root,win;
XColor col;
Colormap cmap;
XImage *ximage;
XEvent ev;
GC gc;
int screen_num;
unsigned long white,black;
/*my palette of greys*/
char ColorTable[64];
/*image buffer*/
char *sbuf;
/** Initialize xwindows, and prepare a shared memory buffer for
the image */
int InitXWindows(int width, int height)
{
XGCValues values;
XSizeHints hints;
XWMHints wmhints;
disp=XOpenDisplay(NULL);
if(!disp) {printf("open display failed\n"); return 0;}
screen=DefaultScreenOfDisplay(disp);
screen_num=DefaultScreen(disp);
white=XWhitePixel(disp,screen_num);
black=XBlackPixel(disp,screen_num);
root=DefaultRootWindow(disp);
win=XCreateSimpleWindow(disp,root,0,0,width,height,0,white,black);
if(!win) { printf("create window failed\n");return(0); }
/*tell window manager about our window*/
/*hints.flags=USSize;hints.width=width;hints.height=height;
wmhints.input=True;wmhints.flags=InputHint;
XSetWMHints(disp,win,&wmhints);
XSetWMNormalHints(disp,win,&hints);
*/XStoreName(disp, win, "QuickCam");
XSelectInput(disp, win, ExposureMask);
XMapRaised(disp, win);
XNextEvent(disp, &ev);
gc = XCreateGC(disp, win, 0, &values);
ximage = XShmCreateImage(
disp, DefaultVisual(disp, screen_num), 8,
ZPixmap, NULL, &SHMInfo, width, height);
if(!ximage)
{
printf("CreateImage Failed\n");
return(0);
}
SHMInfo.shmid=shmget(
IPC_PRIVATE,ximage->bytes_per_line*ximage->height,
IPC_CREAT|0777);
if(SHMInfo.shmid < 0)
{
perror("shmget failed:");
return (0);
}
sbuf = ximage->data = SHMInfo.shmaddr = shmat(SHMInfo.shmid, 0, 0);
XShmAttach(disp, &SHMInfo);
signal(SIGHUP, ExitXWindows); signal(SIGINT, ExitXWindows);
signal(SIGQUIT, ExitXWindows); signal(SIGTERM, ExitXWindows);
return(1);
}
void ExitXWindows()
{
XShmDetach(disp, &SHMInfo);
if(SHMInfo.shmaddr)
shmdt(SHMInfo.shmaddr);
if(SHMInfo.shmid > 0)
shmctl(SHMInfo.shmid, IPC_RMID, 0);
}
int InitPalette64()
{
int i;
for(i=0; i<64; i++)
{
col.red =col.green = col.blue = i * 1024;
printf("(%d) ",XAllocColor(disp, DefaultColormap(disp, screen_num), &col));
ColorTable[i] = col.pixel;
printf("%d ", col.pixel);
}
}
int InitPalette256()
{
int i;
cmap = XCreateColormap(disp, win, DefaultVisual(disp, screen_num), AllocAll);
printf("%d\n",cmap);
for(i=0; i< 256; i++)
{
col.pixel = i;
col.red = col.green = col.blue = i *256;
col.flags=0xff;
printf("%d %d\n", i, XStoreColor(disp, cmap, &col));
}
printf("%d \n",XSetWindowColormap(disp, win, cmap));
return (1);
}
void ShowPic(int width, int height)
{
XShmPutImage(disp, win, gc, ximage, 0,0,0,0,width, height, False);
XFlush(disp);
}
Follow-Ups: