/* ================================================================*\

	rate.c -- a program to measure the rate at which the
		WinVision frame grabber can digitize images.

	(C) Carlos Puchol, 1993
	    cpg@cs.utexas.edu
	    P.O. Box 7817
	    Austin, TX 78717-7817

	This program may be distributed/modified/copied under the terms
	of the GNU GENERAL PUBLIC LICENSE. It comes as is, with no
	guarantees.

\* ================================================================*/

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>

#include <stdio.h>
#include <fcntl.h>
#include <signal.h>

#define FG_HPOS_SET             0x0001
#define FG_HPOS_GET             0x0002
#define FG_VPOS_SET             0x0003
#define FG_VPOS_GET             0x0004
#define FG_BOARD_SET            0x0005
#define FG_BOARD_GET            0x0006
#define FG_CMAP_SET             0x0007
#define FG_EXPANSION_SET        0x0008

#define WIDTH	187
#define HEIGHT	241

static int	fd;		/* Frame grabber file */

typedef struct {
        int     HSize;
        int     VSize;
        int     HSkip;
        int     VSkip;
        unsigned char   pixels[HEIGHT][WIDTH];
        } t_image;

t_image image;

unsigned char pixel_map[256];		/* Pixel mappings to image */

int	count=0;
int	period=10;	/* Seconds for each test */
char	expansion;	/* Flag to indicate grabbing w/ expansion performed */
int	res;		/* Aux variable for results of the FS operations */

void quitter()
{
	printf("Images grabbed: %d.\n", count);
	exit(-1);
}

void alrmnoexp()
{
	printf("Rate of capture without expansion: %1.1f frames/second\n",
			((float)count)/(float)period);
	expansion = 1;
}

void alrmexp()
{
	printf("Rate of capture with expansion: %1.1f frames/second\n",
			((float)count)/(float)period);
	expansion = 0;
}

void main(argc, argv)
int argc;
char **argv;
{
	signal(SIGINT, quitter);
	signal(SIGQUIT, quitter);
	signal(SIGSTOP, quitter);
	signal(SIGALRM, alrmnoexp);

	open_fgrabber();
	printf("\nThis program tests the rate of capture of the WinVision\n");
	printf("frame grabber in your particular machine setting.\n");
	printf("It will take %d seconds, be patient ... meanwhile :-)\n\n",
		2*period);
	printf("Be kind and let me know by email (cpg@cs.utexas.edu)\n");
	printf("the following data for statistical purposes (along with\n");
	printf("any feedback you may have). If you experience problems,\n");
	printf("send them and I may put you in touch with someone that\n");
	printf("has the same type of machine as you do. Thanks.\n");
	printf("\nMachine type (386/486, DX/DX2, speed, etc):\n");
	printf("Brand a model:\n");
	printf("Amount of memory:\n");
	printf("Amount of cache:\n");
	printf("Linux version:\n");
	printf("Any other data you may consider interesting:\n\n");

	expansion=0;
	count = 0;
	alarm(period);
	while (!expansion) {
		grab_image();
		count++;
	}
	res = ioctl(fd, FG_EXPANSION_SET, 1);
	if (res < 0) {
		perror ("Trying FG_EXPANSION_SET IOCTL to the frame grabber");
		quitter();
	}
	count=0;
	signal(SIGALRM, alrmexp);
	alarm(period);
	while (expansion) {
		grab_image();
		count++;
	}
	printf("\nPerformance test done. Please send the statistics.\n");
}

open_fgrabber()
{

	if ((fd=open("/dev/fgrabber", O_RDWR)) < 0 ) {
		perror("Could not open frame grabber, giving up");
		quitter();
	}

	image.HSize=WIDTH;
	image.VSize=HEIGHT;
	image.HSkip=0;
	image.VSkip=0;
	
	res = ioctl(fd, FG_CMAP_SET, pixel_map);
	if (res < 0) {
		perror ("Trying the FG_CMAP_SET IOCTL to the frame grabber");
		quitter();
	}

	/* camera 1-4 = 0x268, 0x368, 0x2e8, 0x3e8 */

	res = ioctl(fd, FG_EXPANSION_SET, 0);
	if (res < 0) {
		perror ("Trying the FG_EXPANSION_SET IOCTL to the frame grabber");
		quitter();
	}

	res = ioctl(fd, FG_BOARD_SET, 0x268);
	if (res < 0) {
		perror ("Trying the FG_BOARD_SET IOCTL to the frame grabber");
		quitter();
	}
}

grab_image()
{
	int	res, x, y;


	res = read(fd, &image, sizeof(image));
	if (res < 0) {
		perror ("Reading from frame grabber");
		quitter();
	}
}
