/*     mseq
*  Sequencer that loads as many images into memory as possible
*  Creates very fast displays
*
*  Display images on the Sun-3 console in sequence, suitable for onscreen
*  animation.  Can expand the image size on the fly.
*  Can be adapted to Sun 2's easily
*
*  National Center for Supercomputing Applications
*  University of Illinois, Urbana-Champaign
*
*  by Tim Krauskopf
*  first version 7/11/86
*  modifications 2/20/87
*
*  This program is in the public domain
*
*/
#include "stdio.h"
#include "pixrect/pixrect_hs.h"
#include "memory.h"

#define  DEVICE  "/dev/fb"
#define  SCRX    1152
#define  SCRY    900
#define  MAXFRAMES 500
#define  USAGE   printf("\nUsage: %s xdim ydim [-s] [-l] [-p xwhere ywhere] file1 file2 . . .\n",argv[0])

int xdim,ydim,  		/* size of image on disk */
	nimgs=0,			/* how many images we have saved */
	xwhere= -1,ywhere= -1,	/* where to put it on the screen */
	step=0,				/* single step? */
	startpic=3,			/* for parameter counts */
	xsize,ysize,		/* what final size on screen, after blow-up */
	xfact=1,yfact=1;	/* what factor for blowing up the picture */

struct pixrect *screen,*img[MAXFRAMES],*bimg;
struct mpr_data *stuff,*bstuff;

main(argc,argv)
	int argc;
	char *argv[];
	{
	register i,file;

	if (argc < 4) {
		USAGE;
		puts(" -l              make image as large as possible");
		puts(" -p xloc yloc    position on screen");
		exit(1);
	}

	xdim = atoi(argv[1]);              /*  required parms */
	ydim = atoi(argv[2]);
	if (xdim < 10 || ydim < 10) {
		puts("\n Huh? ");
		exit(1);
	}
	xsize = xdim;
	ysize = ydim;


/*
*  work on parms
*/
	for (i=3; i<argc; i++) {        		/* look at each parm */
		if (*argv[i] == '-') 
			switch ( *(argv[i]+1)) {
				case 'p':                	/* special position on screen */
					xwhere = atoi(argv[++i]);
					ywhere = atoi(argv[++i]);
					if (xwhere > SCRX || ywhere > SCRY) {
						puts("\n Invalid position ");
						USAGE;
						exit(1);
					}
					startpic+=3;
					break;
				case 'l':					/* large pic */
					xfact = SCRX/xdim;		/* how much blow-up can we do? */
					yfact = SCRY/ydim;		/* calculate expansion factor */
					if (xfact > yfact)
						xfact = yfact;
					else
						yfact = xfact;
					xsize = xfact*xdim; 	/* re-calculate actual pixel dimensions*/
					ysize = yfact*ydim;
					startpic++;
					break;
				case 's':               	/* step through pics */
					step = 1;
					startpic++;
					break;
				default:
					USAGE;
					exit(1);
			}
	}
						
/*
*  compute centering values, based on new size
*/
	if (xwhere == -1) {
		xwhere = (SCRX-xsize)/2;
		ywhere = (SCRY-ysize)/2;
		if (xwhere < 0) 
			xwhere = 0;
		if (ywhere < 0)
			ywhere = 0;
	}
/*
*  open the screen information pixrects
*/
	screen = pr_open(DEVICE);
	bimg = mem_create(xsize,ysize,8);   					/* to size of image */
	bstuff = mpr_d(bimg);

	for (i=startpic ; i<argc && i < MAXFRAMES; i++) {  	/* each image */

		if (0 > (file = open(argv[i],0))) {				/* open each file */
			printf("\n %s: error opening %s \n",argv[0],argv[i]);
			exit(1);
		}

/*
*  read the picture into temporary space and then
*  copy it (expand) to the memory pixrect,  only if it is being expanded
*/
			if (0 >= (img[i] = mem_create(xdim,ydim,8))) 
				break;

			stuff = mpr_d(img[i]);
			read(file,stuff->md_image,xdim*ydim);   

			if (xfact > 1) {
				bigimg(bstuff->md_image,stuff->md_image);
			
/*
*  call pixrect raster operation to write the memory image to the screen
*/
				pr_rop(screen,xwhere,ywhere,xsize,ysize,PIX_SRC,bimg,0,0);
			}
			else
				pr_rop(screen,xwhere,ywhere,xsize,ysize,PIX_SRC,img[i],0,0);


		if (step) {
			printf("Press return to continue, 'q' return to quit");
			if ('q' == getchar())
				exit(0);
		}
			
		close(file);

	}

/*
*  use images stored in memory to display on screen quickly
*/
	nimgs = i;
	while (1) { 
		for (i=startpic; i<nimgs; i++) {
			if (xfact > 1) {
				stuff = mpr_d(img[i]);
				bigimg(bstuff->md_image,stuff->md_image);
				pr_rop(screen,xwhere,ywhere,xsize,ysize,PIX_SRC,bimg,0,0);
			}
			else
				pr_rop(screen,xwhere,ywhere,xsize,ysize,PIX_SRC,img[i],0,0);
		}
	}

/*
*  can't get this far
	pr_close(screen);
*/

}

/*****************************************************************************/
/* expandimg
*  copy an image memory to memory, expanding byte by byte to get a larger image.
*  no aliasing, just byte replication
*/
bigimg(targ,src)
	unsigned char *targ,*src;
	{
	register i,j,line;
	register unsigned char *p,*q,*oldq;

	for (line = 0; line < ydim; line++) {
		p = src+line*xdim;
		oldq = q = targ+line*xsize*yfact;

		for (i=0; i<xdim; i++,p++)				/* expand the line horizontally */
			for (j=0; j<xfact; j++)
				*q++ = *p;
		
		for (i=0; i<yfact; i++) {
			memcpy(q,oldq,xsize);				/* make one copy of the line */
			q += xsize;
		}

	}
}

