/*
	5d.c

	m51.bat = cl /AL make5d.c vimage3 graphlib

*/
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "font.h"
#include "nomouse.h"

#define MAX_BUFF 32768
#define MAXSIZE 16384

#define RED      240
#define ORANGE   241
#define YELLOW   242
#define GREEN    243
#define CYAN     244
#define BLUE     245
#define PURPLE   246
#define MAGENTA  247
#define BROWN    248
#define D_BLUE   249
#define D_CYAN   250
#define BLACK    251
#define D_GREY   252
#define M_GREY   253
#define L_GREY   254
#define WHITE    255

#define MENUXC 550
#define MENU_V  4

char Path[10][100];
int NumPath=0;
char *Menu_V[MENU_V]=
{
	"cursor on image",
	"rectangle image",
	"slice RGB scatter",
	"exit image view"
};
struct   Color
{
	unsigned char  r, g, b;
}Lut[256];
struct Color Vcolor[16]=
{
	{ 255,  0,  0},
	{ 255,128,  0},
	{ 191,191,  0},
	{   0,255,  0},
	{   0,191,191},
	{  40, 40,255},
	{ 128,  0,255},
	{ 191,  0,191},
	{  96, 28, 14},
	{   0, 20, 60},
	{   0,128,128},
	{   0,  0,  0},
	{  46, 46, 46},
	{ 128,128,128},
	{ 191,191,191},
	{ 255,255,255}
};
char SubType[20],VideoType='X';
struct board
{
	int row,col,color;
}B_Id;
int FontSize=2;
int ScreenXs=640,ScreenYs=480;
unsigned char Buffer[3][MAXSIZE],Outbuff[MAXSIZE][3],Mbuff[MAX_BUFF];
unsigned char BoxBuff[3][8][256];
int Cr=0xd;
struct image_header
{
	int row,col,sample;		/* source color image */
	int imgrow,imgcol;		/* sub image '.?5d' */
	char infile[3][100];
	int negative[3];
	int imgmax[3],imgmin[3];
	int dummy[92];
	struct Color lut[256];
}Hdr;
int Source_Row,Source_Col;
int Range[3];
char Palette[100],Image[100];

unsigned char getpt();
char fsplit(char *,char *,char *,char *);
FILE *fopen_path(char *filename,char *type);
int load_names_path(char *filename);

main(argc,argv)

int argc;
char *argv[];

{
	int i,j,k;
	char string[100],lblname[100],ans,name_5d[100];
	int numfile,len;
	FILE *fp;

	if(argc>1)
	{
		for(i=1;i<argc;i++)
		{
			 if(argv[i][0]=='/'&&(argv[i][1]=='X'||argv[i][1]=='x'))
				VideoType='X';
			 if(argv[i][0]=='/'&&(argv[i][1]=='Y'||argv[i][1]=='y'))
				VideoType='Y';
			 if(argv[i][0]=='/'&&(argv[i][1]=='E'||argv[i][1]=='e'))
				VideoType='E';
			if(argv[i][0]=='/'&&(argv[i][1]=='V'||argv[i][1]=='v'))
				VideoType='V';
			if(argv[i][0]=='/'&&(argv[i][1]=='S'||argv[i][1]=='s'))
			{
				VideoType='S';
				FontSize=3;
			}
			if(argv[i][1]==':'||argv[i][0]==92)	
			{
				strcpy(Path[NumPath],argv[i]);
				len=strlen(Path[NumPath]);
				if(Path[NumPath][len-1]!=92)
				{
					Path[NumPath][len+1]='\0';
					Path[NumPath][len]=92;
				}
				NumPath+=1;
			}
		}
	}
	video_on();
	video_off();
	do
	{
		printf("\n\n   v -- view 5-D image file\n");
		printf("   h -- check header\n");
		printf("   m -- make 5-D image file from IMVIS output composite\n");
		printf("\n   x -- exit program\n\n");
		ans=getch();
		if(ans=='v')
		{
			load_composite(string);
		}
		if(ans=='m')
		{
			numfile=get_file_name("*.lbl",lblname);
			if(numfile<0)
				exit(0);
			read_lbl(lblname);
			check_hdr();
			process_set(lblname,name_5d);
			make_scatter(name_5d);
			print_hdr();
		}
		if(ans=='h')
			scan_hdrs();
	}while(ans!='x'&&ans!=27);
}

/***********************************************************************
**
**
**
**
************************************************************************/

int rectangle_mode(xaxis,yaxis,xc,yc,scale,size,fp)

int *xaxis,*yaxis,*xc,*yc,scale,size;
FILE *fp;

{
	int i,j,k;
	char ans,ans2;
	int x[3],y[3],ix,iy,ixo,iyo;
	int bxsize=ScreenXs/40,bysize=ScreenXs/40,speed=8;
	int bxsizeo=bxsize,bysizeo=bysize;
	unsigned char point[3],pbuff[3][50];
	long offsethdr,offset,lcol=Hdr.imgcol,lrow=Hdr.imgrow;
	int dark=BLACK,mark=BROWN,plot=0,markcolor=BROWN,high=45/FontSize;

	paint_box(0,D_GREY,Outbuff,ScreenXs/2,0,ScreenXs/2,ScreenYs/2);
	paint_box(0,mark,Outbuff,ScreenXs/2,0,bxsize,bysize);
	plot_font_h(L_GREY,ScreenXs/2+bxsize+4,2,"Marker Color",FontSize,Font);
	plot_font_h(L_GREY,ScreenXs/2+2,bysize+2,
			"'c' or 'C' to change",FontSize,Font);
	plot_font_h(L_GREY,ScreenXs/2+2,bysize+2+high*1,
			"arrows to move box",FontSize,Font);
	plot_font_h(L_GREY,ScreenXs/2+2,bysize+2+high*2,
			"<Enter> to mark",FontSize,Font);
	plot_font_h(L_GREY,ScreenXs/2+2,bysize+2+high*3,
			"<Esc> to exit",FontSize,Font);
	plot_font_h(L_GREY,ScreenXs/2+2,bysize+2+high*4,
			"(l)arger,(s)maller",FontSize,Font);
	plot_font_h(L_GREY,ScreenXs/2+2,bysize+2+high*5,
			"(N)arrower,(W)ider",FontSize,Font);
	plot_font_h(L_GREY,ScreenXs/2+2,bysize+2+high*6,
			"(S)horter,(H)igher",FontSize,Font);
	offsethdr=(long)sizeof(struct image_header);
	offsethdr+=(long)Hdr.imgrow*(long)Hdr.imgcol;
	ix=ixo=Hdr.imgcol/2-bxsize/2;
	iy=iyo=Hdr.imgrow/2-bysize/2;
	if(iy<0)iy=0;
	if(ix<0)ix=0;
	tbox_val(0,ix,iy,bxsize,bysize,Mbuff,dark,WHITE,180);
	offset=lcol*(long)iy+(long)ix;
	do
	{
		if(plot==0)
			ans=getch();
		plot=0;
		if(ans==0)
		{
			ans2=getch();
			if(ans2==82)
				dark+=1;
			if(ans2==83)
				dark-=1;
			if(dark<240)
				dark=255;
			if(dark>255)
				dark=240;
			if(ans2==71||ans2==72||ans2==73)
				iy-=speed;
			if(ans2==79||ans2==80||ans2==81)
				iy+=speed;
			if(ans2==71||ans2==75||ans2==79)
				ix-=speed;
			if(ans2==73||ans2==77||ans2==81)
				ix+=speed;
			if(ix<0)
				ix=0;
			if(iy<0)
				iy=0;
			if(ix>=Hdr.imgcol)
				ix=Hdr.imgcol-1;
			if(iy>=Hdr.imgrow)
				iy=Hdr.imgrow-1;
			if(ix+bxsize>Hdr.imgcol)
				ix=Hdr.imgcol-bxsize;
			if(iy+bysize>Hdr.imgrow)
				iy=Hdr.imgrow-bysize;
			unbox(0,ixo,iyo,bxsizeo,bysizeo,Mbuff);
			tbox_val(0,ix,iy,bxsize,bysize,Mbuff,dark,WHITE,180);
			ixo=ix;
			iyo=iy;
		}
		if(ans=='l'||ans=='s'||ans=='H'||ans=='W'||ans=='N'||ans=='S')
		{
			if(ans=='l'||ans=='W')
				bxsize+=speed;
			if(ans=='l'||ans=='H')
				bysize+=speed;
			if(ans=='s'||ans=='N')
				bxsize-=speed;
			if(ans=='s'||ans=='S')
				bysize-=speed;
			if(bxsize<4)
				bxsize=4;
			if(bysize<4)
				bysize=4;
			if(bxsize>Hdr.imgcol)
				bxsize=Hdr.imgcol;
			if(bysize>Hdr.imgrow)
				bysize=Hdr.imgrow;
			if(ix+bxsize>Hdr.imgcol)
				ix=Hdr.imgcol-bxsize;
			if(iy+bysize>Hdr.imgrow)
				iy=Hdr.imgrow-bysize;
			if(ix<0)
				ix=0;
			if(iy<0)
				iy=0;
			unbox(0,ixo,iyo,bxsizeo,bysizeo,Mbuff);
			tbox_val(0,ix,iy,bxsize,bysize,Mbuff,dark,WHITE,180);
			bxsizeo=bxsize;
			bysizeo=bysize;
			ixo=ix;
			iyo=iy;
		}
		if(ans=='+'&&speed<32)
			speed*=2;
		if(ans=='-'&&speed>1)
			speed/=2;
		if(ans==13)		/* mark points */
		{
			for(i=iy;i<iy+bysize;i++)
			{
				offset=lcol*(long)i+(long)ix;
				fseek(fp,offsethdr+offset*3,SEEK_SET);
				fread((char *)Outbuff,sizeof(char),bxsize*3,fp);
				for(j=0;j<bxsize;j++)
				{
					set_xy(x,y,xaxis,yaxis,xc,yc,Outbuff[j],scale,size);
					for(k=0;k<3;k++)
						plotpt(0,x[k],y[k],mark);
				}
			}
			while((ans=getch())=='c'||ans=='C'||ans=='f')
			{
				if(ans=='f')
				{
					if(markcolor==WHITE)
						markcolor=BLACK;
					else
						markcolor=WHITE;
				}
				if(ans=='c')
				{
					markcolor+=1;
					if(markcolor>255)
					markcolor=RED;
				}
				if(ans=='C')
				{
					markcolor-=1;
					if(markcolor<RED)
					markcolor=255;
				}
				WritePaletteIndex(&Hdr.lut[markcolor],mark);
			}
			plot=1;
			offset=lcol*lrow;
			fseek(fp,offsethdr+offset*3,SEEK_SET);
			for(k=0;k<3;k++)
			{
				for(i=0;i<size;i++)
				{
					if(fread((char *)Buffer[0],sizeof(char),size,fp)<size)
					{
						video_off();
						printf("Could not read! \n");
						exit(0);
					}
					plotrow(0,xc[k],xc[k]+size-1,yc[k]+i,Buffer[0]);
				}
			}
		}
	}while(ans!=27);
	unbox(0,ixo,iyo,bxsize,bysize,Mbuff);
	paint_box(0,D_GREY,Outbuff,ScreenXs/2,0,ScreenXs/2,ScreenYs/2);
}




/***********************************************************************
**
**
**
**
************************************************************************/

int make_scatter(string)

char *string;

{
	int i,j,k,m,n;
	FILE *fp;
	int numfile;
	char type[10],*cname[3],number[100],*str1,*str2;
	int xc[3],yc[3],size=ScreenXs/5,scale,x[3],y[3];
	int xaxis[3],yaxis[3];
	int val,wide;
	unsigned char point[3];
	int color[3],len,hi,csize=3840/ScreenXs;

	scale=640/ScreenXs;
	scale*=2;
	yc[0]=yc[1]=yc[2]=ScreenYs/2+40/FontSize;
	xc[0]=ScreenXs/4;
	xc[1]=ScreenXs/4*2;
	xc[2]=ScreenXs/4*3;
	xaxis[0]=xaxis[2]=0;
	yaxis[0]=yaxis[1]=1;
	xaxis[1]=yaxis[2]=2;
	color[0]=RED;color[1]=GREEN;color[2]=BLUE;
	cname[0]=Hdr.infile[0];
	cname[1]=Hdr.infile[1];
	cname[2]=Hdr.infile[2];
	hi=19/(FontSize+1)/2;
	fp=fopen_path(string,"a+b");
	rewind(fp);
	if(!fp)
	{
		printf("Could not open '%s' to read.\n",string);
		exit(0);
	}
	fread((char *)&Hdr,sizeof(struct image_header),1,fp);
	for(k=0;k<3;k++)
	{
		Range[k]=Hdr.imgmax[k]-Hdr.imgmin[k];
		if(Range[k]<size)
			Range[k]=size;
	}
	for(k=0;k<16;k++)
	{
		Hdr.lut[k+240].r=Vcolor[k].r;
		Hdr.lut[k+240].g=Vcolor[k].g;
		Hdr.lut[k+240].b=Vcolor[k].b;
	}
	video_on();
	WritePalette(Hdr.lut);
	paint_box(0,D_GREY,Outbuff,0,0,ScreenXs,ScreenYs);
	for(i=0;i<Hdr.imgrow;i++)
	{
		fread((char *)Buffer[0],sizeof(char),Hdr.imgcol,fp);
		plotrow(0,0,Hdr.imgcol-1,i,Buffer[0]);
	}
	for(k=0;k<3;k++)
	{
		box(0,xc[k]-1,yc[k],L_GREY,size+1,size+1);
		plot_font_h(color[xaxis[k]],xc[k]+2,yc[k]+size+3,
			cname[xaxis[k]],FontSize,Font);
		plot_font_v(color[yaxis[k]],xc[k]-22/FontSize-2,yc[k]+size-3,
			cname[yaxis[k]],FontSize,Font);
		for(n=50;n<256;n+=50)
		{
			for(m=0;m<3;m++)
				point[m]=n;
			sprintf(number,"%d",n);
			len=strlen(number)*15;
			len/=FontSize+1;
			set_xy(x,y,xaxis,yaxis,xc,yc,point,scale,size);
			if(x[k]>xc[k]&&x[k]<xc[k]+size)
				plotln(0,x[k],yc[k]+1,x[k],yc[k]+size-1,BLACK);
			if(y[k]>yc[k]&&y[k]<yc[k]+size)
				plotln(0,xc[k]+1,y[k],xc[k]+size-1,y[k],BLACK);
		}
		for(n=50;n<256;n+=50)
		{
			for(m=0;m<3;m++)
				point[m]=n;
			sprintf(number,"%d",n);
			len=strlen(number)*15;
			len/=FontSize+1;
			hi=19/(FontSize+1)/2;
			set_xy(x,y,xaxis,yaxis,xc,yc,point,scale,size);
			if(x[k]>xc[k]+10&&x[k]<xc[k]+size-10)
			{
				plot_font_v(D_CYAN,x[k]-hi,yc[k]+len+2,number,FontSize+1,Font);
				plot_font_v(D_CYAN,x[k]-hi,yc[k]+size-2,number,FontSize+1,Font);
			}
			if(y[k]>yc[k]+10&&y[k]<yc[k]+size-10)
			{
				plot_font_h(D_CYAN,xc[k]+size-len-2,y[k]-hi,number,FontSize+1,Font);
				plot_font_h(D_CYAN,xc[k]+2,y[k]-hi,number,FontSize+1,Font);
			}
		}
	}
	for(i=0;i<Hdr.imgrow;i++)
	{
		if(kbhit()>0)
		{
			val=getch();
			if(val==27)
				return(-2);
		}
		fread((char *)Outbuff,sizeof(char),Hdr.imgcol*3,fp);
		for(j=0;j<Hdr.imgcol;j++)
		{
			val=getpt(0,j,i);
			set_xy(x,y,xaxis,yaxis,xc,yc,Outbuff[j],scale,size);
			for(k=0;k<3;k++)
				plotpt(0,x[k],y[k],val);
		}
	}
	fseek(fp,(long)0,SEEK_END);
	for(k=0;k<3;k++)
	{
		for(i=0;i<size;i++)
		{
			getrow(0,xc[k],xc[k]+size-1,yc[k]+i,Buffer[0]);
			if(fwrite((char *)Buffer[0],sizeof(char),size,fp)<size)
			{
				video_off();
				printf("Could not write to '%s'\n",string);
				exit(0);
			}
		}
	}
	cursor_mode(xaxis,yaxis,xc,yc,scale,size,fp);
	fclose(fp);
	video_off();
}

/***********************************************************************
**
**
**
**
************************************************************************/

int load_composite(string)

char *string;

{
	int i,j,k,m,n;
	FILE *fp;
	int numfile;
	char type[10],*cname[3],number[100],*str1,*str2;
	int xc[3],yc[3],size=ScreenXs/5,scale,x[3],y[3];
	int xaxis[3],yaxis[3];
	int val,wide;
	unsigned char point[3];
	int color[3],len,hi,csize=3840/ScreenXs;
	long offset;
	int v_num=0;
	char disk,path[50],name[50];

	scale=640/ScreenXs;
	scale*=2;
	yc[0]=yc[1]=yc[2]=ScreenYs/2+40/FontSize;
	xc[0]=ScreenXs/4;
	xc[1]=ScreenXs/4*2;
	xc[2]=ScreenXs/4*3;
	xaxis[0]=xaxis[2]=0;
	yaxis[0]=yaxis[1]=1;
	xaxis[1]=yaxis[2]=2;
	color[0]=RED;color[1]=GREEN;color[2]=BLUE;
	cname[0]=Hdr.infile[0];
	cname[1]=Hdr.infile[1];
	cname[2]=Hdr.infile[2];
	sprintf(type,"*.%c5d",VideoType);
	hi=19/(FontSize+1)/2;
	while(numfile=get_file_name(type,string)>=0)
	{
		fp=fopen_path(string,"rb");
		if(!fp)
		{
			printf("Could not open '%s' to read.\n",string);
			exit(0);
		}
		fread((char *)&Hdr,sizeof(struct image_header),1,fp);
		for(k=0;k<3;k++)
		{
			Range[k]=Hdr.imgmax[k]-Hdr.imgmin[k];
			if(Range[k]<size)
				Range[k]=size;
		}
		for(k=0;k<16;k++)
		{
			Hdr.lut[k+240].r=Vcolor[k].r;
			Hdr.lut[k+240].g=Vcolor[k].g;
			Hdr.lut[k+240].b=Vcolor[k].b;
		}
		video_on();
		WritePalette(Hdr.lut);
		paint_box(0,D_GREY,Outbuff,0,0,ScreenXs,ScreenYs);
		str1="USGS/OEMG 5-D ";
		str2="Image Viewer";
		if(VideoType=='S')
		{
			wide=15/3;
			plot_font_h(L_GREY,xc[0],yc[0]+size+14,str1,3,Font);
			rainbow(str2,xc[0]+wide*strlen(str1),
				yc[0]+size+14,3);
		}
		else if(VideoType=='Y')
		{
			wide=15;
			plot_font_h(L_GREY,xc[0],yc[0]+size+22,str1,1,Font);
			rainbow(str2,xc[0]+wide*strlen(str1),
				yc[0]+size+22,FontSize-1);
		}
		else
		{
			wide=15;
			plot_font_h(L_GREY,xc[0],yc[0]+size+48,str1,1,Font);
			rainbow(str2,xc[0]+wide*strlen(str1),
				yc[0]+size+48,FontSize-1);
		}
		plot_font_h(L_GREY,2,Hdr.imgrow+2,string,FontSize,Font);
		for(i=0;i<Hdr.imgrow;i++)
		{
			fread((char *)Buffer[0],sizeof(char),Hdr.imgcol,fp);
			plotrow(0,0,Hdr.imgcol-1,i,Buffer[0]);
		}
		offset=(long)Hdr.imgrow*(long)Hdr.imgcol;
		for(k=0;k<3;k++)
		{
			box(0,xc[k]-1,yc[k],L_GREY,size+1,size+1);
			plot_font_h(color[xaxis[k]],xc[k]+2,yc[k]+size+2,
				cname[xaxis[k]],FontSize,Font);
			plot_font_v(color[yaxis[k]],xc[k]-19/FontSize-2,yc[k]+size-3,
				cname[yaxis[k]],FontSize,Font);
			sprintf(number,"%d",k+1);
			plot_font_h(L_GREY,xc[k]+2,ScreenYs/2+2,number,FontSize,Font);
		}
		fseek(fp,offset*3,SEEK_CUR);	
		for(k=0;k<3;k++)
		{
			for(i=0;i<size;i++)
			{
				if(fread((char *)Buffer[0],sizeof(char),size,fp)<size)
				{
					video_off();
					printf("Could not read to '%s'\n",string);
					exit(0);
				}
				plotrow(0,xc[k],xc[k]+size-1,yc[k]+i,Buffer[0]);
			}
		}
		v_num=0;
		do
		{
			v_num=do_menu_buff(Menu_V,MENU_V,MENUXC,25,v_num,
					D_GREY,L_GREY,WHITE,Font);
			if(v_num==0)
				cursor_mode(xaxis,yaxis,xc,yc,scale,size,fp);
			if(v_num==1)
				rectangle_mode(xaxis,yaxis,xc,yc,scale,size,fp);
			if(v_num==2)
				cookie_cut(xaxis,yaxis,xc,yc,scale,size,fp);
		}while(v_num<MENU_V-1);
		fclose(fp);
		video_off();
	}
}

/***********************************************************************
**
**
**
**
************************************************************************/

int cookie_cut(xaxis,yaxis,xc,yc,scale,size,fp)

int *xaxis,*yaxis,*xc,*yc,scale,size;
FILE *fp;

{
	int i,j,k,m,n;
	char ans,ans2,number[100];
	int x[3],y[3],ix,iy,ixo,iyo;
	int bxsize=ScreenXs/40,bysize=ScreenXs/40;
	int bxsizeo=bxsize,bysizeo=bysize;
	unsigned char point[3],pbuff[3][50];
	long offsethdr,offset;
	int col=Hdr.imgcol,row=Hdr.imgrow;
	int dark=BLACK,mark=BROWN,plot=0,markcolor=BROWN,high=40/FontSize;
	int active=0,hit;
	int datmax[3],datmin[3],dathi[3],datlo[3],dathio[3],datloo[3];
	int xpt[3][9],ypt[3][9],speed=16/scale,direction=-1;

	paint_box(0,D_GREY,Outbuff,ScreenXs/2,0,ScreenXs/2,ScreenYs/2);
	paint_box(0,mark,Outbuff,ScreenXs/2,0,bxsize,bysize);
	plot_font_h(L_GREY,ScreenXs/2+bxsize+4,2,"Marker Color",FontSize,Font);
	plot_font_h(L_GREY,ScreenXs/2+2,bysize+2,
			"'c' or 'C' to change color",FontSize,Font);
	plot_font_h(L_GREY,ScreenXs/2+2,bysize+2+high*1,
			"'i'=IN  'o'=OUT",FontSize,Font);
	plot_font_h(L_GREY,ScreenXs/2+2,bysize+2+high*2,
			"'r' to reset  'f' to flash",FontSize,Font);
	plot_font_h(L_GREY,ScreenXs/2+2,bysize+2+high*3,
			"arrows to move lines",FontSize,Font);
	plot_font_h(L_GREY,ScreenXs/2+2,bysize+2+high*4,
			"1, 2 or 3 to choose box",FontSize,Font);
	plot_font_h(L_GREY,ScreenXs/2+2,bysize+2+high*5,
			"<Enter> to mark",FontSize,Font);
	plot_font_h(L_GREY,ScreenXs/2+2,bysize+2+high*6,
			"<Esc> to exit",FontSize,Font);
	offsethdr=(long)sizeof(struct image_header);
	offsethdr+=(long)Hdr.imgrow*(long)Hdr.imgcol;
	offset=sizeof(struct image_header);
	for(k=0;k<3;k++)
	{
		sprintf(number,"%d",k+1);
		if(k==active)
			plot_font_h(WHITE,xc[k]+2,ScreenYs/2+2,number,FontSize,Font);
		else
			plot_font_h(M_GREY,xc[k]+2,ScreenYs/2+2,number,FontSize,Font);
	}
	set_boxes(datmax,datmin,dathi,datlo,xaxis,yaxis,xc,yc,scale,size);
	for(m=0;m<3;m++)
	{
		dathio[m]=dathi[m];
		datloo[m]=datlo[m];
	}
	tplot_boxes(datmax,datmin,dathi,datlo,xaxis,yaxis,xc,yc,scale,size);
	do
	{
		ans=getch();
		if(ans=='i')
			direction=-1;
		if(ans=='o')
			direction=1;
		if(ans==0)
		{
			ans2=getch();
			if(ans2==72)
			{
				dathi[yaxis[active]]+=speed*direction;
				if(dathi[yaxis[active]]<datlo[yaxis[active]])
					dathi[yaxis[active]]=datlo[yaxis[active]];
				if(dathi[yaxis[active]]>datmax[yaxis[active]])
					dathi[yaxis[active]]=datmax[yaxis[active]];
			}
			if(ans2==80)
			{
				datlo[yaxis[active]]-=speed*direction;
				if(datlo[yaxis[active]]>dathi[yaxis[active]])
					datlo[yaxis[active]]=dathi[yaxis[active]];
				if(datlo[yaxis[active]]<datmin[yaxis[active]])
					datlo[yaxis[active]]=datmin[yaxis[active]];
			}
			if(ans2==77)
			{
				dathi[xaxis[active]]+=speed*direction;
				if(dathi[xaxis[active]]<datlo[xaxis[active]])
					dathi[xaxis[active]]=datlo[xaxis[active]];
				if(dathi[xaxis[active]]>datmax[xaxis[active]])
					dathi[xaxis[active]]=datmax[xaxis[active]];
			}
			if(ans2==75)
			{
				datlo[xaxis[active]]-=speed*direction;
				if(datlo[xaxis[active]]>dathi[xaxis[active]])
					datlo[xaxis[active]]=dathi[xaxis[active]];
				if(datlo[xaxis[active]]<datmin[xaxis[active]])
					datlo[xaxis[active]]=datmin[xaxis[active]];
			}
			unplot_boxes(datmax,datmin,dathio,datloo,xaxis,yaxis,xc,yc,scale,size);
			for(m=0;m<3;m++)
			{
				dathio[m]=dathi[m];
				datloo[m]=datlo[m];
			}
			tplot_boxes(datmax,datmin,dathi,datlo,xaxis,yaxis,xc,yc,scale,size);
		}
		if(ans=='r')
		{
			set_boxes(datmax,datmin,dathi,datlo,xaxis,yaxis,xc,yc,scale,size);
			unplot_boxes(datmax,datmin,dathio,datloo,xaxis,yaxis,xc,yc,scale,size);
			for(m=0;m<3;m++)
			{
				dathio[m]=dathi[m];
				datloo[m]=datlo[m];
			}
			tplot_boxes(datmax,datmin,dathi,datlo,xaxis,yaxis,xc,yc,scale,size);
		}
		if(ans==13)
		{
			fseek(fp,offsethdr,SEEK_SET);
			for(i=0;i<row;i++)
			{
				for(j=0;j<col;j++)
				{
					fread((char *)point,sizeof(char),3,fp);
					hit=1;
					for(m=0;m<3;m++)
					{
						if(point[m]<datlo[m]||point[m]>dathi[m])
						{
							hit=0;
							break;
						}
					}
					if(hit==1)
						plotpt(0,j,i,mark);
				}
			}
			while((ans=getch())=='c'||ans=='C'||ans=='f')
			{
				if(ans=='f')
				{
					if(markcolor==WHITE)
						markcolor=BLACK;
					else
						markcolor=WHITE;
				}
				if(ans=='c')
				{
					markcolor+=1;
					if(markcolor>255)
					markcolor=RED;
				}
				if(ans=='C')
				{
					markcolor-=1;
					if(markcolor<RED)
					markcolor=255;
				}
				WritePaletteIndex(&Hdr.lut[markcolor],mark);
			}
			fseek(fp,offset,SEEK_SET);
			for(i=0;i<Hdr.imgrow;i++)
			{
				fread((char *)Buffer[0],sizeof(char),Hdr.imgcol,fp);
				plotrow(0,0,Hdr.imgcol-1,i,Buffer[0]);
			}
		}
		if(ans=='+'&&speed<32)
			speed*=2;
		if(ans=='-'&&speed>1)
			speed/=2;
		if(ans=='c')
		{
			markcolor+=1;
			if(markcolor>255)
			markcolor=RED;
			WritePaletteIndex(&Hdr.lut[markcolor],mark);
		}
		if(ans=='C')
		{
			markcolor-=1;
			if(markcolor<RED)
			markcolor=255;
			WritePaletteIndex(&Hdr.lut[markcolor],mark);
		}
		if(ans>='1'&&ans<='3')
		{
			active=ans-'1';
			for(k=0;k<3;k++)
			{
				sprintf(number,"%d",k+1);
				if(k==active)
					plot_font_h(WHITE,xc[k]+2,ScreenYs/2+2,number,FontSize,Font);
				else
					plot_font_h(M_GREY,xc[k]+2,ScreenYs/2+2,number,FontSize,Font);
			}
		}
		if(ans==0||ans=='r')
		{
			paint_box(0,D_GREY,Outbuff,0,ScreenYs/2,110/FontSize,90/FontSize);
			sprintf(number,"%3d %3d",datlo[0],dathi[0]);
			plot_font_h(RED,2,ScreenYs/2+2,number,FontSize,Font);
			sprintf(number,"%3d %3d",datlo[1],dathi[1]);
			plot_font_h(GREEN,2,ScreenYs/2+2+30/FontSize,number,FontSize,Font);
			sprintf(number,"%3d %3d",datlo[2],dathi[2]);
			plot_font_h(BLUE,2,ScreenYs/2+2+60/FontSize,number,FontSize,Font);
		}
	}while(ans!=27);
	for(k=0;k<3;k++)
	{
		sprintf(number,"%d",k+1);
		if(k==active)
			plot_font_h(L_GREY,xc[k]+2,ScreenYs/2+2,number,FontSize,Font);
	}
	paint_box(0,D_GREY,Outbuff,ScreenXs/2,0,ScreenXs/2,ScreenYs/2);
	unplot_boxes(datmax,datmin,dathio,datloo,xaxis,yaxis,xc,yc,scale,size);
	for(k=0;k<3;k++)
	{
		sprintf(number,"%d",k+1);
		plot_font_h(L_GREY,xc[k]+2,ScreenYs/2+2,number,FontSize,Font);
	}
	paint_box(0,D_GREY,Outbuff,0,ScreenYs/2,110/FontSize,90/FontSize);
}

/***********************************************************************
**
**
**
**
************************************************************************/

int tplot_boxes(datmax,datmin,dathi,datlo,xaxis,yaxis,xc,yc,scale,size)

int *datmax,*datmin,*dathi,*datlo,*xaxis,*yaxis,*xc,*yc,scale,size;

{
	int i,j,k,m,n;
	int x[3],y[3],px[3][9],py[3][9],val=WHITE;
	unsigned char point[3];

	for(k=0;k<3;k++)
		point[k]=0;
	for(m=0;m<3;m++)
	{
		point[yaxis[m]]=dathi[yaxis[m]];
		point[xaxis[m]]=datlo[xaxis[m]];
		set_xy(x,y,xaxis,yaxis,xc,yc,point,scale,size);
		px[m][0]=px[m][7]=px[m][8]=x[m];
		py[m][0]=py[m][7]=py[m][8]=y[m];

		point[yaxis[m]]=dathi[yaxis[m]];
		point[xaxis[m]]=dathi[xaxis[m]];
		set_xy(x,y,xaxis,yaxis,xc,yc,point,scale,size);
		px[m][1]=px[m][2]=x[m];
		py[m][1]=py[m][2]=y[m];

		point[yaxis[m]]=datlo[yaxis[m]];
		point[xaxis[m]]=dathi[xaxis[m]];
		set_xy(x,y,xaxis,yaxis,xc,yc,point,scale,size);
		px[m][3]=px[m][4]=x[m];
		py[m][3]=py[m][4]=y[m];

		point[yaxis[m]]=datlo[yaxis[m]];
		point[xaxis[m]]=datlo[xaxis[m]];
		set_xy(x,y,xaxis,yaxis,xc,yc,point,scale,size);
		px[m][5]=px[m][6]=x[m];
		py[m][5]=py[m][6]=y[m];
	}
	for(m=0;m<3;m++)
	{
		for(i=0;i<8;i++)
		{
			if(px[m][i]!=px[m][i+1]||py[m][i]!=py[m][i+1])
			{
				tplotln_val(0,px[m][i],py[m][i],px[m][i+1],py[m][i+1],
					BoxBuff[m][i],val);
			}
		}
	}
}

/***********************************************************************
**
**
**
**
************************************************************************/

int unplot_boxes(datmax,datmin,dathi,datlo,xaxis,yaxis,xc,yc,scale,size)

int *datmax,*datmin,*dathi,*datlo,*xaxis,*yaxis,*xc,*yc,scale,size;

{
	int i,j,k,m,n;
	int x[3],y[3],px[3][9],py[3][9],val=WHITE;
	unsigned char point[3];

	for(k=0;k<3;k++)
		point[k]=0;
	for(m=0;m<3;m++)
	{
		point[yaxis[m]]=dathi[yaxis[m]];
		point[xaxis[m]]=datlo[xaxis[m]];
		set_xy(x,y,xaxis,yaxis,xc,yc,point,scale,size);
		px[m][0]=px[m][7]=px[m][8]=x[m];
		py[m][0]=py[m][7]=py[m][8]=y[m];

		point[yaxis[m]]=dathi[yaxis[m]];
		point[xaxis[m]]=dathi[xaxis[m]];
		set_xy(x,y,xaxis,yaxis,xc,yc,point,scale,size);
		px[m][1]=px[m][2]=x[m];
		py[m][1]=py[m][2]=y[m];

		point[yaxis[m]]=datlo[yaxis[m]];
		point[xaxis[m]]=dathi[xaxis[m]];
		set_xy(x,y,xaxis,yaxis,xc,yc,point,scale,size);
		px[m][3]=px[m][4]=x[m];
		py[m][3]=py[m][4]=y[m];

		point[yaxis[m]]=datlo[yaxis[m]];
		point[xaxis[m]]=datlo[xaxis[m]];
		set_xy(x,y,xaxis,yaxis,xc,yc,point,scale,size);
		px[m][5]=px[m][6]=x[m];
		py[m][5]=py[m][6]=y[m];
	}
	for(m=0;m<3;m++)
	{
		for(i=7;i>=0;i--)
		{
			if(px[m][i]!=px[m][i+1]||py[m][i]!=py[m][i+1])
			{
				unplotln(0,px[m][i],py[m][i],px[m][i+1],py[m][i+1],
					BoxBuff[m][i],val);
			}
		}
	}
}

/***********************************************************************
**
**
**
**
************************************************************************/

int set_boxes(datmax,datmin,dathi,datlo,xaxis,yaxis,xc,yc,scale,size)

int *datmax,*datmin,*dathi,*datlo,*xaxis,*yaxis,*xc,*yc,scale,size;


{
	int i,j,k;

	for(k=0;k<3;k++)
	{
		Range[k]=Hdr.imgmax[k]-Hdr.imgmin[k];
		if(Range[k]<size)
			Range[k]=size;
		dathi[k]=datmax[k]=Hdr.imgmax[k];
		datlo[k]=datmin[k]=Hdr.imgmin[k];
	}
}





/********************************************************************
**
**     options:
**
**       -1 -- remove menu but get no answer
**        0 -- return answer and set menu colors to GREYs
**        1 -- return answer but leave colors alone
**
********************************************************************* */

int do_menu_buff(menu,num,xc,yc,start,back,words,boxs,font)

char *menu[];
int num,xc,yc,start,back,words,boxs;
int font[128][25];

{
	int i,j,k;
	char ans,ans2;
	int len=0,l,size=FontSize,val,valo;
	int black=BLACK,dGREY=back,lGREY=words,white=boxs;
	int wide;

	for(k=0;k<num;k++)
		if((l=strlen(menu[k]))>len)len=l;
	if(len==0)return(-1);
	wide=(len+1)*15/size+1;
	if((ScreenXs-1-wide)<xc)xc=ScreenXs-1-wide;

	if((xc+(len+1)*15/size+1)<ScreenXs)
	{
		save_sub_mem(xc,yc,(len+1)*15/size+1,30/size*num+1);
		paint_box(0,dGREY,Buffer,xc,yc,(len+1)*15/size+1,30/size*num+1);
		
		for(k=0;k<num;k++)
		{	
			box(0,xc,yc+k*(30/size),dGREY,(len+1)*15/size,30/size);
			plot_font_h(lGREY,xc+15/size,yc+k*30/size+5/size,menu[k],size,font);
		}
		box(0,xc,yc,M_GREY,(len+1)*15/size,30/size*num);
		val=valo=start;
		box(0,xc,yc+val*(30/size),white,(len+1)*15/size,30/size);
		do
		{
			if((ans=getch())==0)
			{
				ans2=getch();
				if(ans2==50)
				{
					recall_sub_mem(xc,yc,(len+1)*15/size+1,30/size*num+1);

					getch();
					paint_box(0,dGREY,Buffer,
						xc,yc,(len+1)*15/size+1,30/size*num+1);
					for(k=0;k<num;k++)
					{	
						plot_font_h(lGREY,xc+15/size,
									yc+k*30/size+5/size,menu[k],size,font);
					}
				}
				if(ans2=='H')
				{
					if(val>0)val-=1;
					else val=num-1;
				}
				if(ans2=='P')
				{
					if(val<num-1)val+=1;
					else val=0;
				}
			}

			for(i=0;i<num;i++)
				if(ans==menu[i][0])
				{
					val=i;
					ans=13;
				}
			if(ans==27)
			{
				val=num-1;
				ans=13;
			}

			box(0,xc,yc+valo*(30/size),dGREY,(len+1)*15/size,30/size);
			valo=val;
			box(0,xc,yc,M_GREY,(len+1)*15/size,30/size*num);
			box(0,xc,yc+val*(30/size),white,(len+1)*15/size,30/size);
		}while(ans!=13);
	}
	box(0,xc,yc,dGREY,(len+1)*15/size,30/size*num);
	box(0,xc,yc+val*(30/size),M_GREY,(len+1)*15/size,30/size);

	recall_sub_mem(xc,yc,(len+1)*15/size+1,30/size*num+1);
	return(val);
}

/***********************************************************************
**
**
**
**
************************************************************************/

int rainbow(string,xc,yc,size)

char *string;
int xc,yc,size;

{
	int i,j,k;
	int wide=15/size;
	char str1[10];

	str1[1]='\0';
	for(i=0;i<strlen(string);i++)
	{
		str1[0]=string[i];
		plot_font_h(RED+i%8,xc+i*wide,yc,str1,size,Font);
	}
}



/***********************************************************************
**
**
**
**
************************************************************************/

int cursor_mode(xaxis,yaxis,xc,yc,scale,size,fp)

int *xaxis,*yaxis,*xc,*yc,scale,size;
FILE *fp;

{
	int i,j,k;
	char ans,string[100];
	int x[3],y[3],ix,iy,ixo,iyo,px[3],py[3],pxo[3],pyo[3];
	int csize=ScreenXs/106,speed=8;
	unsigned char point[3],cbuff[50],pbuff[3][50];
	long offsethdr,offset,lcol=Hdr.imgcol;
	int dark=RED,val,high=30/FontSize,wide=15/FontSize;

	paint_box(0,D_GREY,Outbuff,ScreenXs/2,0,ScreenXs/2,ScreenYs/2);
	offsethdr=(long)sizeof(struct image_header);
	offsethdr+=(long)Hdr.imgrow*(long)Hdr.imgcol;
	ix=ixo=Hdr.imgcol/2;
	iy=iyo=Hdr.imgrow/2;
	tcursor_val(0,ix,iy,csize,cbuff,BLACK,WHITE,180);
	offset=lcol*(long)iy+(long)ix;
	fseek(fp,offsethdr+offset*3,SEEK_SET);
	fread((char *)point,sizeof(char),3,fp);
	set_xy(px,py,xaxis,yaxis,xc,yc,point,scale,size);
	for(k=0;k<3;k++)
	{
		tcursor_val(0,px[k],py[k],csize,pbuff[k],dark,WHITE,180);
		pxo[k]=px[k];
		pyo[k]=py[k];
	}
	do
	{
		ans=getch();
		if(ans==0)
		{
			ans=getch();
			if(ans==82)
				dark+=1;
			if(ans==83)
				dark-=1;
			if(dark<240)
				dark=255;
			if(dark>255)
				dark=240;
			if(ans==71||ans==72||ans==73)
				iy-=speed;
			if(ans==79||ans==80||ans==81)
				iy+=speed;
			if(ans==71||ans==75||ans==79)
				ix-=speed;
			if(ans==73||ans==77||ans==81)
				ix+=speed;
			if(ix<0)
				ix=0;
			if(iy<0)
				iy=0;
			if(ix>=Hdr.imgcol)
				ix=Hdr.imgcol-1;
			if(iy>=Hdr.imgrow)
				iy=Hdr.imgrow-1;
			uncursor(0,ixo,iyo,csize,cbuff);
			tcursor_val(0,ix,iy,csize,cbuff,dark,WHITE,180);
			for(k=0;k<3;k++)
				uncursor(0,pxo[k],pyo[k],csize,pbuff[k]);
			offset=lcol*(long)iy+(long)ix;
			fseek(fp,offsethdr+offset*3,SEEK_SET);
			fread((char *)point,sizeof(char),3,fp);

			paint_box(0,D_GREY,Outbuff,ScreenXs/2,0,22*wide,5*high+5);
			sprintf(string,"SCREEN");
			plot_font_h(WHITE,ScreenXs/2+4,2,string,FontSize,Font);
			sprintf(string,"X = %3d  Y = %3d",ix,iy);
			plot_font_h(L_GREY,ScreenXs/2+4,2+high,string,FontSize,Font);
			val=getpt(0,ix,iy);
			sprintf(string,"DN = %3d",val);
			plot_font_h(L_GREY,ScreenXs/2+4,2+2*high,string,FontSize,Font);
			sprintf(string,"%3d",Hdr.lut[val].r);
			plot_font_h(  RED,ScreenXs/2+4+10*wide,2+2*high,string,FontSize,Font);
			sprintf(string,"%3d",Hdr.lut[val].g);
			plot_font_h(GREEN,ScreenXs/2+4+14*wide,2+2*high,string,FontSize,Font);
			sprintf(string,"%3d",Hdr.lut[val].b);
			plot_font_h( BLUE,ScreenXs/2+4+18*wide,2+2*high,string,FontSize,Font);
			sprintf(string,"DATA");
			plot_font_h(WHITE,ScreenXs/2+4,2+3*high,string,FontSize,Font);
			sprintf(string,"%3d",point[0]);
			plot_font_h(  RED,ScreenXs/2+4+10*wide,2+4*high,string,FontSize,Font);
			sprintf(string,"%3d",point[1]);
			plot_font_h(GREEN,ScreenXs/2+4+14*wide,2+4*high,string,FontSize,Font);
			sprintf(string,"%3d",point[2]);
			plot_font_h( BLUE,ScreenXs/2+4+18*wide,2+4*high,string,FontSize,Font);
			set_xy(px,py,xaxis,yaxis,xc,yc,point,scale,size);
			for(k=0;k<3;k++)
			{
				tcursor_val(0,px[k],py[k],csize,pbuff[k],dark,WHITE,180);
				pxo[k]=px[k];
				pyo[k]=py[k];
			}
			ixo=ix;
			iyo=iy;
		}
		if(ans=='+'&&speed<32)
			speed*=2;
		if(ans=='-'&&speed>1)
			speed/=2;
	}while(ans!=27);
	uncursor(0,ixo,iyo,csize,cbuff);
	for(k=0;k<3;k++)
		uncursor(0,pxo[k],pyo[k],csize,pbuff[k]);
	paint_box(0,D_GREY,Outbuff,ScreenXs/2,0,22*wide,5*high+5);
}


/***********************************************************************
**
**
**
**
************************************************************************/

int set_xy(x,y,xaxis,yaxis,xc,yc,point,scale,size)

int *x,*y,*xaxis,*yaxis,*xc,*yc,scale,size;
unsigned char *point;

{
	int i,j,k;
	long dist[3];

	for(k=0;k<3;k++)
	{
		dist[k]=((long)point[k]-(long)Hdr.imgmin[k])*255;
		dist[k]/=(long)Range[k];
		dist[k]/=(long)scale;
	}
	for(k=0;k<3;k++)
	{
		x[k]=(int)dist[xaxis[k]]+xc[k];
		y[k]=yc[k]+size-(int)dist[yaxis[k]];
	}
}


/***********************************************************************
**
**
**
**
************************************************************************/

int scan_hdrs()

{
	int i,j,k;
	char type[100],string[100];
	int numfile;
	FILE *fp;

	sprintf(type,"*.%c5d",VideoType);
	numfile=get_file_name(type,string);
	if(numfile<0)
		exit(0);
	fp=fopen_path(string,"rb");
	if(!fp)
	{
		printf("Could not open '%s' to read.\n",string);
		exit(0);
	}
	fread((char *)&Hdr,sizeof(struct image_header),1,fp);
	print_hdr();
}




/***********************************************************************
**
**
**
**
************************************************************************/

int print_hdr()

{
	int i,j,k;
	int black=0,white=0;

	printf("Source Color Image:\n");
	printf("   row = %d  column = %d  sample rate = %d\n",
		Hdr.row,Hdr.col,Hdr.sample);
	printf("5-D Image:\n");
	printf("   row = %d  col = %d\n",Hdr.imgrow,Hdr.imgcol);
	printf("Source Images:\n");
	for(k=0;k<3;k++)
	{
		printf("    %20s  %3d %3d",Hdr.infile[k],Hdr.imgmin[k],Hdr.imgmax[k]);
		if(Hdr.negative[k]==1)
			printf(" (Negative)\n");
		else
			printf("\n");
	}
	for(i=0;i<256;i++)
	{
		if(Hdr.lut[i].r==0&&Hdr.lut[i].g==0&&Hdr.lut[i].b==0)
			black+=1;
		if(Hdr.lut[i].r==255&&Hdr.lut[i].g==255&&Hdr.lut[i].b==255)
			white+=1;
	}
	printf("Color Palette Contains ");
	if(black==1)
		printf("1 black");
	else
		printf("%d blacks",black);
	if(white==1)
		printf(" and 1 white");
	else
		printf(" and %d whites",white);
}



/***********************************************************************
**
**
**
**
************************************************************************/

int process_set(lblname,name5d)

char *lblname,*name5d;

{
	int i,j,k;
	char name[100],string[100];
	int missing=0,n;
	FILE *fpimg,*fppal,*fpin[3],*fpout;
	int sampx,sampy,sampin,sampcolor,row,col;
	long offsetin,offsetcolor;
	int xc[3],yc[3],val;

	xc[0]=xc[2]=ScreenXs/2;
	xc[1]=yc[0]=0;
	yc[1]=yc[2]=ScreenYs/2;
	strcpy(name,lblname);
	for(k=0;k<strlen(name);k++)
		if(name[k]=='.')
			name[k]='\0';
	sprintf(string,"%s.%c5d",name,VideoType);
	fpout=fopen_path(string,"wb");
	if(!fpout)
	{
		printf("Could not open '%s' to write.\n",string);
		exit(0);
	}
	strcpy(name5d,string);
	sampx=(Hdr.col+ScreenXs/2-1)/(ScreenXs/2);
	sampy=(Hdr.row+ScreenYs/2-1)/(ScreenYs/2);
	if(sampx>sampy)sampin=sampx;
	else sampin=sampy;
	if(sampin<1)sampin=1;
	offsetin=Source_Col;
	offsetin*=(sampin*Hdr.sample-1);
	printf("sample rate of 8-bit input image is %d\n",sampin);
	printf("sample rate of data images is %d\n",sampin*Hdr.sample);
	sampcolor=sampin;
	if(sampcolor<1)sampcolor=1;
	Hdr.imgrow=row=Hdr.row/sampcolor;
	Hdr.imgcol=col=Hdr.col/sampcolor;
	offsetcolor=Hdr.col;
	offsetcolor*=sampcolor-1;
	if(load_names_path(Image)<1)
	{
		printf("file '%s' could not be found.\n",Image);
		missing+=1;
	}
	if(load_names_path(Palette)<1)
	{
		printf("file '%s' could not be found.\n",Palette);
		missing+=1;
	}
	for(k=0;k<3;k++)
	{
		if(load_names_path(Hdr.infile[k])<1)
		{
			printf("file '%s' could not be found.\n",Hdr.infile[k]);
			missing+=1;
		}
	}
	if(missing>0)
		exit(0);
	video_on();
	fppal=fopen_path(Palette,"rt");
	{
		for(i=0;i<256;i++)
			if(fscanf(fppal,"%d%d%d%d",
				&n,&Hdr.lut[i].r,&Hdr.lut[i].g,&Hdr.lut[i].b)<4)
			{
				printf("'%s' did not have 256 entries.\n",Palette);
				video_off();
				exit(0);
			}
		WritePalette(Hdr.lut);
	}
	fclose(fppal);
	fwrite((char *)&Hdr,sizeof(struct image_header),1,fpout);
	fpimg=fopen_path(Image,"rb");
	for(i=0;i<row;i++)
	{
		fread((char *)Buffer[0],sizeof(char),Hdr.col,fpimg);
		if(sampcolor>1)
		{
			for(j=0;j<col;j++)
				Buffer[0][j]=Buffer[0][j*sampcolor];
			fseek(fpimg,offsetcolor,SEEK_CUR);
		}
		plotrow(0,0,col-1,i,Buffer[0]);
		fwrite((char *)Buffer[0],sizeof(char),Hdr.imgcol,fpout);
	}
	set_lut('G');
	fclose(fpimg);
	for(k=0;k<3;k++)
	{
		fpin[k]=fopen_path(Hdr.infile[k],"rb");
	}
	row=Hdr.row/sampin;
	col=Hdr.col/sampin;
	for(k=0;k<3;k++)
	{
		Hdr.imgmax[k]=-1;
		Hdr.imgmin[k]=256;
	}
	sampin*=Hdr.sample;
	for(i=0;i<row;i++)
	{
		if(kbhit()>0)
		{
			val=getch();
			if(val==27)
			{
				video_off();
				exit(0);
			}
		}
		for(k=0;k<3;k++)
		{
			fread((char *)Buffer[k],sizeof(char),Source_Col,fpin[k]);
			if(sampin>1)
			{
				for(j=0;j<col;j++)
					Buffer[k][j]=Buffer[k][j*sampin];
				fseek(fpin[k],offsetin,SEEK_CUR);
			}
			plotrow(0,xc[k],xc[k]+col-1,yc[k]+i,Buffer[k]);
			for(j=0;j<col;j++)
			{
				if((int)Buffer[k][j]>Hdr.imgmax[k])
					Hdr.imgmax[k]=Buffer[k][j];
				if((int)Buffer[k][j]<Hdr.imgmin[k])
					Hdr.imgmin[k]=Buffer[k][j];
				Outbuff[j][k]=Buffer[k][j];
			}
		}
		fwrite((char *)Outbuff,sizeof(char),Hdr.imgcol*3,fpout);
	}
	for(k=0;k<3;k++)
		fclose(fpin[k]);
	rewind(fpout);
	fwrite((char *)&Hdr,sizeof(struct image_header),1,fpout);
	fclose(fpout);
	video_off();
}

/**********************************************************************
**
**
**
**********************************************************************/

int load_names_path(char *filename)

{
	int i,j,k;
	int msng=0;
	char string[100];


	if(load_names(filename)>=0)
{
printf("filename at 0 = '%s'\n",filename);
		return(1);
}
	for(i=0;i<NumPath;i++)
	{
		sprintf(string,"%s%s",Path[i],filename);
printf("filename at %d = '%s'\n",i+1,filename);
		if(load_names(filename)>=0)
			return(i+2);
	}		
}

/***********************************************************************
**
**
**
**
************************************************************************/

int set_lut(iop)

char iop;

{
	int i,j,k;

	if(iop=='G'||iop=='g')
	{
		for(i=0;i<256;i++)
		{
			Lut[i].r=i;
			Lut[i].g=i;
			Lut[i].b=i;
		}	
		WritePalette(Lut);
	}
}


/**************************************************************************
**
**
**
************************************************************************* */

int video_on()

{
	int i,ret;

	i=GetVideoBoardID();
	if(i==0)
		VideoType='E';
	if(i==1&&(VideoType=='X'||VideoType=='Y'))
		VideoType='S';
	if(i<0)
	{
		printf("Computer will not support enough colors.\n\n");
		exit(0);
	}
	if(VideoType=='X')
	{
		SetVideoMode(480,&B_Id);
		if(B_Id.row==480)
		{
			strcpy(SubType,".xmg");
		}
		else
		{
			if(i>1)
				VideoType='Y';
		}
	}
	if(VideoType=='V')
	{
		ret=SetVideoMode(0x12,&B_Id);
		strcpy(SubType,".vmg");
	}
	if(VideoType=='Y')
	{
		ret=SetVideoMode(400,&B_Id);
		strcpy(SubType,".ymg");
		ScreenXs=640;
		ScreenYs=400;
	}
	if(VideoType=='S')
	{
		ret=SetVideoMode(0x13,&B_Id);
		strcpy(SubType,".smg");
		ScreenXs=320;
		ScreenYs=200;
		FontSize=3;
	}
	if(ret>=0)
		return(1);
	else
	{
		SetVideoMode(0,&B_Id);
		printf("Could not boot video board\n\n");
		exit(0);
	}
}

/********************************************************************
**
**
**
********************************************************************* */

int video_off()

{
	SetVideoMode(0,&B_Id);
}


/***********************************************************************
**
**
**
**
************************************************************************/

int check_hdr()

{
	int i,j,k;

	for(i=0;i<3;i++)
	{
		if(strlen(Hdr.infile[i])<1)
		{
			printf("'CHANNEL_INPUT:' heading was not found.");
			printf("  Use 'IMVIS' to create an image set.\n");
			exit(0);
		}
	}
	if(strlen(Palette)<1)
	{
		printf("'PAL_POINTER' heading was not found.");
		printf("  Use 'IMVIS' to create an image set.\n");
		exit(0);
	}	
	if(strlen(Image)<1)
	{
		printf("'IMAGE_POINTER' heading was not found.");
		printf("  Use 'IMVIS' to create an image set.\n");
		exit(0);
	}	
	printf("row = %3d  column = %3d  sample = %d\n",Hdr.row,Hdr.col,Hdr.sample);
	printf("Input Files:\n");
	for(i=0;i<3;i++)
	{
		printf("     %s",Hdr.infile[i]);
		if(Hdr.negative[i]==1)
			printf(" (Negative)\n");
		else
			printf("\n");
	}
	printf("Image file    = '%s'\n",Image);
	printf("Color palette = '%s'\n",Palette);
}



/***********************************************************************
**
**  return:
**
**       -1 = '.lbl' file not found
**       -2 = row < 1
**       -3 = col < 1 or col >= MAXSIZE
**       -4 = numimage < 2 || numimage >= MAXCOL
**       -5 = hit end of file while reading image names
**       -6 = could not open image file
**       -7 = bad data_max/min values
**
************************************************************************/

int read_lbl(name)

char *name;

{
	int i,j,k;
	char string[100],str1[100],str2[100],str3[100];
	int i1,i2,i3,ret;
	FILE *fp;

	strcpy(string,name);
	for(k=0;k<strlen(string);k++)
		if(string[k]=='.')
			string[k]='\0';
	strcat(string,".lbl");
	fp=fopen_path(string,"rt");
	if(!fp)
		return(-1);
	Hdr.row=Hdr.col=Hdr.sample=0;
	while(fgets(string,99,fp))
	{
		sscanf(string,"%s",str1);
		{
			if(strcmpi(str1,"pal_pointer")==0)
			{
				sscanf(string,"%s%s%s",str1,str2,str3);
				k=0;
				for(i=0;i<strlen(str3);i++)
				if(str3[i]!=39)		/* single quote */
					Palette[k++]=str3[i];
				Palette[k]='\0';
			}
			if(strcmpi(str1,"image_pointer")==0)
			{
				sscanf(string,"%s%s%s",str1,str2,str3);
				k=0;
				for(i=0;i<strlen(str3);i++)
				if(str3[i]!=39)		/* single quote */
					Image[k++]=str3[i];
				Image[k]='\0';
			}
			if(strcmpi(str1,"IMAGE_LINES")==0)
			{
				sscanf(string,"%s%s%d",str1,str2,&Hdr.row);
				if(Hdr.row<1)
					return(-2);
				Source_Row=Hdr.row;
			}
			if(strcmpi(str1,"LINE_SAMPLES")==0)
			{
				sscanf(string,"%s%s%d",str1,str2,&Hdr.col);
				if(Hdr.col<1||Hdr.col>MAXSIZE)
					return(-3);
				Source_Col=Hdr.col;
			}
			if(strcmpi(str1,"SOURCE_ROW")==0)
				sscanf(string,"%s%s%d",str1,str2,&Source_Row);
			if(strcmpi(str1,"SOURCE_COL")==0)
				sscanf(string,"%s%s%d",str1,str2,&Source_Col);
			if(strcmpi(str1,"HEADER_BYTES")==0)
			{
				printf("HEADER_BYTES are not allowed.\n");
				exit(0);
			}
			if(strcmpi(str1,"SET_POINTER")==0)
			{
				printf(
				"'SET_POINTER' is not allowed -- should be 'CHANNEL_INPUT:'.\n");
				exit(0);
			}
			if(strcmpi(str1,"SAMPLE_RATE")==0)
			{
				sscanf(string,"%s%s%d",str1,str2,&Hdr.sample);
			}
			if(strcmpi(str1,"CHANNEL_INPUT:")==0)
			{
				for(i=0;i<3;i++)
				{
					if(!fgets(string,99,fp))
					{
						printf("EOF while reading input file names.\n");
						exit(0);
					}
					sscanf(string,"%s%s%s",str1,str2,str3);
					if(strcmpi(str1,"RED")==0)
						k=0;
					else if(strcmpi(str1,"GREEN")==0)
						k=1;
					else if(strcmpi(str1,"BLUE")==0)
						k=2;
					else
					{
						printf(
			"'%s' is not a valid channel color:  Must be RED, GREEN or BLUE\n");
						exit(0);
					}
					strcpy(Hdr.infile[k],str3);
					Hdr.negative[k]=0;
					for(j=0;j<strlen(string)-1;j++)
						if(string[j]=='('&&string[j+1]=='N')
							Hdr.negative[k]=1;
				}
			}
		}
	}	
	fclose(fp);
	if(Hdr.sample>0)
	{
		Source_Col*=Hdr.sample;
		Source_Row*=Hdr.sample;
	}
	return(1);
}

/********************************************************************
**
**
**
********************************************************************* */

int save_sub_mem(xc,yc,xs,ys)

int xc,yc,xs,ys;

{
	int i,j,k;

	for(i=0;i<ys;i++)
		getrow(3,xc,xc+xs-1,i+yc,Mbuff+xs*i);
}

/********************************************************************
**
**
**
********************************************************************* */

int recall_sub_mem(xc,yc,xs,ys)

int xc,yc,xs,ys;

{
	int i,j,k;

	for(i=0;i<ys;i++)
		plotrow(3,xc,xc+xs-1,i+yc,Mbuff+xs*i);
}

/**************************************************************************
**
**
**
************************************************************************* */

char fsplit(instring,path,name,type)

char *instring,*path,*name,*type;

{
	int i,j,k;
	int dot=-1,last_slash=-1,len=strlen(instring),first_slash=-1;
	int num=0,colon=-1;
	int disk=0;
	char string[100];

	strcpy(string,instring);
	path[0]='\0';
	name[0]='\0';
	type[0]='\0';

	for(i=0;i<len;i++)
	{
		if(string[i]==':')
			colon=i;
		else if(string[i]=='\\')
		{
			last_slash=i;
			if(first_slash<0)
				first_slash=i;
		}	
		else if(string[i]=='.')
			dot=i;
	}
	if(dot<0&&first_slash>=0&&last_slash<len-1)  /* d:test */
	{
		string[len]='\\';
		last_slash=len;
		len+=1;
		string[len]='\0';
	}
	if(dot<0&&first_slash<0&&len>colon-1)
	{
		string[len]='.';
		dot=len;
		len+=1;
		string[len]='\0';
	}
	if(colon>0)
		disk=string[0];
	if(first_slash>=0)
	{
		for(i=first_slash;i<=last_slash;i++)
			path[i-first_slash]=string[i];
		path[last_slash-first_slash+1]='\0';
	}
	if(last_slash>0&&last_slash<len-1&&dot>0)
	{
		for(i=last_slash+1;i<dot;i++)
			name[i-last_slash-1]=string[i];
		name[dot-last_slash-1]='\0';
	}
	if(colon>0&&last_slash<0&&dot>0)	/* d:test.img */
	{
		for(i=colon+1;i<dot;i++)
			name[i-colon-1]=string[i];
		name[dot-colon]='\0';
	}
	if(colon<0&&last_slash<0&&dot>0)	/* test.img */
	{
		for(i=0;i<dot;i++)
			name[i]=string[i];
		name[dot]='\0';
	}
	if(dot>0&&dot<len-1)
	{
		for(i=dot+1;i<len;i++)
			type[i-dot-1]=string[i];
		type[len-dot-1]='\0';
		if(strlen(type)>3)
			type[3]='\0';
	}
	return(disk);
}

/**********************************************************************
**
**
**
**********************************************************************/

FILE *fopen_path(char *filename,char *type)

{
	int i,j,k;
	FILE *fp;
	char string[100];

	fp=fopen(filename,type);
	if(fp)
		return(fp);
	for(i=0;i<NumPath;i++)
	{
		sprintf(string,"%s%s",Path[i],filename);
		fp=fopen(string,type);
		if(fp)
			return(fp);
	}
	return(NULL);
}

                    