/*     seq
*  Sequencer
*  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  USAGE   printf("\nUsage: %s xdim ydim [-s] [-l] [-p xwhere ywhere] file1 file2 . . .\n",argv[0])

int xdim,ydim,  		/* size of image on disk */
	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;
struct mpr_data *stuff;
unsigned char *storage,*malloc();

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");
		puts(" -s              step through images");
		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;
					storage = malloc(xdim*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);
	img = mem_create(xsize,ysize,8);   					/* to size of image */
	stuff = mpr_d(img);

	for (i=startpic ; i<argc; 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);
		}

/*
*  if the picture needs to be enlarged, read it into temporary space and then
*  copy it (expand) to the memory pixrect, otherwise, just read it straight
*  into the memory pixrect
*/
		if (xfact > 1) {
			read(file,storage,xdim*ydim);   
			bigimg(stuff->md_image,storage);
		}
		else 
			read(file,stuff->md_image,xdim*ydim);   
			
/*
*  call pixrect raster operation to write the memory image to the screen
*/
		pr_rop(screen,xwhere,ywhere,xsize,ysize,PIX_SRC,img,0,0);

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

	}

	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*xfact;

		for (i=0; i<xdim; i++,p++)
			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;
		}

	}
}
