/*
	imvis.c

    cl /AL /Gy /F 6000 imvis.c proj vimage3 graphlib mouseg grf

    by Russell A. Ambroziak, Ph. D., 11/25/91

	U. S. Geological Survey
	Office of Energy and Marine Geology
	National Center , STOP 915
	Reston, VA 22092

	Tel:  703-648-6168
	Fax:  703-648-5464

    modified by J.Phillips, 3/93 to include:
        1. Ellipsoidal Transverse Mercator projection
            (alb_elip.c replaced by proj.c; alb_elip.h replaced by proj.h)
        2. Escape exit from main menu.
        3. No erasure of overlays when zoom is called on an unzoomed image.
        4. Clear screen on normal exit.
        5. Fixed possible zero-divide in change_color.
        6. None or Null projection for plotting lines and points on
           unprojected images.
    modified by J.Phillips, 6/94 to include:
        6. Digitizing option.
        7. More mouse control.


FORMAT for Albers PROJECTION DATA:  (all lines must be present)

Projection = Albers equal area eliptical
    23.0  Lat0
    29.5  Lat1
    45.5  Lat2
   -96.0  Lon0
-2630000  X0
 3328046  Y0
    2000  PixelSize (meters)
       7  ellipsoid (Clark 1866) [0-10]

FORMAT for Transverse Mercator PROJECTION DATA:  (all lines must be present)

Projection = Ellipsoidal Transverse Mercator
    23.0  Lat0
   -96.0  Lon0
   .9996  k0
-2630000  X0
 3328046  Y0
    2000  PixelSize (meters)
       7  ellipsoid (Clark 1866) [0-10]

FORMAT for Unprojected DATA:  (all lines must be present)

Projection = None
-2630000  X0
 3328046  Y0
    2000  PixelSize (meters)

FORMAT for CAPTION DATA:  (all lines must be present)

CAPTION = 3 LINES 
TEXT_COLOR = 245
TEXT_SIZE = 2
Southern bank of the Potomac River at Westmoreland State
Park, Westmoreland County
(48 miles east of Fredericksburg on Rt 3)


standard 'img8bit.c' graphic colors:

241   0   0   0 Black
242  70  70  70 Dark Grey
243 127 127 127 Medium Grey
244 191 191 191 Light Grey
245 255 255 255 White
246 255   0   0 Red
247 255 128   0 Orange
248 191 192   0 Yellow
249   0 191   0 Green
250   0 191 191 Cyan
251   0   0 255 Blue
252 191   0 191 Magenta
253  96  28  14 Buff
254   0  91  91 Dark Cyan
255   0 128   0 Dark Green

*/
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
#include <sys\types.h>
#include <sys\timeb.h>
#include <direct.h>
#include "font.h"
#include "mouseg.h"
#include "proj.h"
/*#include "alb_elip.h"*/

#define MAX_BUFF 32768
#define MENU_I 11
#define MENUXC 550
#define MENU_C 7
#define MENU_D 3
#define MENU_S 3
#define NUM_IMAGE 15
#define S_SIZE 40
#define F_SIZE 20
#define T_SIZE 15
#define PAUSE printf("HIT ANY KEY TO CONTINUE.\n");getch()
#define MAX_LL 6
#define NUM_DP 100
#define STR_LEN 100
#define MAX_NUM 300
#define S_SIZE 40
#define NAME_SIZE 100
#define NUM_TYPE 25
#define NUM_SIZE 25
#define R      6367.40
#define PI		3.1415927
#define BLACK     0
#define D_GREY    1
#define L_GREY    2
#define WHITE     3
#define BUFF      4
#define L_BUFF    5
#define BROWN     6
#define RED       7
#define ORANGE    8
#define YELLOW    9
#define GREEN    10
#define D_GREEN  11
#define VD_GREEN 12
#define BLUE     13
#define D_BLUE   14
#define MAGENTA  15
#define S_SIZE 40
#define MAX_X 640
#define B_LINES 48

float MaxLat,MinLat,MaxLon,MinLon;
extern int LastN;
extern char LastId[];
int MouseStat=0;
int Mouse=1;
extern char GF_String[][S_SIZE];
char MString[300][25];
char Group_Name[NUM_TYPE][30];
struct line_name
{
	char filename[54];
	float max_pix,min_pix;
	int color;
}MapFile[NUM_TYPE][NUM_SIZE];
int Vector=0;
int Ns[NUM_TYPE];

extern char GF_String[MAX_NUM][S_SIZE];
int GF_Order[MAX_NUM];
long Hist[256],Delay;
float Fhist[3][256],Fsum[3],Ftot[3];
struct file_id
{
	char name[S_SIZE];
	long size;
	unsigned date,time;
};
extern struct file_id GF_File[300];
int Menu=0;
struct board
{
	int row,col,color;
}B_Id;
int FontSize=2;
char *menu_s[MENU_S]=
{
	"display image",
	"cycle images",
	"exit set"
};
struct navigation
{
	int numlat,numlon,numx,numy;
	double B_Lat[MAX_LL],B_Lon[MAX_LL];
	double B_Y[MAX_LL],B_X[MAX_LL];
}Nav;
int NumPath=1;
char Path[NUM_DP][STR_LEN];
char String[100];
int PathOn=0;
int Num_Active_Image=1;
char *LastFile;
char *menu_l[NUM_IMAGE+1]=
{
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              ",
	 "\0                              "
};
struct menu Menu_Mouse_i[8]=
{
	{
		"System",' ',1,
		3,
		"Color",'C',1,
		"Targa File",'T',1,
		"Hide Menu",'H',1
	},
	{
		"Zoom",'z',1,
		0
	},
	{
		"Analyze",' ',1,
		5,
		"pixel info",'p',1,
		"histogram",'h',1,
        "shade",'S',1,
		"smooth",'s',1,
		"rescale",'R',1
	},
	{
		"Plot",' ',1,
		3,
		"boundary",'b',1,
		"labels .grf",'l',1,
		"caption",'c',1
	},
    {
        "Digitize",'v',1,0
    },
	{
		"Quit",'x',1,
		0
	},
	{
		"*"
	}
};
char *menu_i[MENU_I]=
	{"zoom",						/*  0 */
	"change color",			/*  1 */
	"pixel info",				/*  2 */
	"output Targa file",		/*  3 */
	"histogram",				/*  4 */
	"Shade",						/*  5 */
	"smooth",					/*  6 */
	"boundary plot",			/*  7 */
	"rescale image",			/*  8 */
	"label plot (.grf)",				/*  9 */
	"exit image"				/* 10 */
};
char *menu_c[MENU_C]=
	{
		"change +/-,789,123",
        "stretch RGB",
		"reset",
		"change one color",
		"save new table",
        "contrast",
		"exit color"
	};
char *menu_d[MENU_D]=
    {
        "append",
        "replace",
        "exit"
    };
float Hue[256],Sat[256];
int Max[256],Mid[256],Min[256];
char VideoType='X';
int OneImage=0;
char OneImageName[100];
int Black=0,White=191,Center=128,Num_Color=256,Red=246,Cyan=250;
int D_Grey=46,L_Grey=191,M_Grey=128;
int ScreenXs=640,ScreenYs=480;
struct   Color
{
	unsigned char  r, g, b;
};
struct Color Vcolor[16]=
{
	{   0,  0,  0},
	{  46, 46, 46},
	{ 128,128,128},
	{ 255,255,255},
	{ 105, 90, 75},
	{ 130,111, 93},
	{  96, 28, 14},
	{ 255,  0,  0},
	{ 255,128,  0},
	{ 160,160,  0},
	{   0,200,  0},
	{   0,120,  0},
	{   0, 72,  0},
	{   0,  0,200},
	{   0, 20, 60},
	{ 255,  0,255}
};
struct Color Blk={  0,  0,  0};
struct Color D_G={ 46, 46, 46};
struct Color M_G={127,127,127};
struct Color L_G={191,191,191};
struct Color Wht={255,255,255};
struct Color Rd={255,0,0};
struct Color Cn={0,199,199};
unsigned char ActiveLut;
struct caption
{
	int lines,color,size,wide;
	char text[5][100];
};
struct image_header
{
	int row,col;
	int sample;
	int record_bytes,file_records;
	int record_col_header;
	int row_col_header;
	long header_bytes;
	int imbedded_header;
	int sample_bits;
	int data_max,data_min;
	char infile[100],image[100],Lut[100],pal_type,label[100];
	struct caption cap;
	int vga_color[256];
	struct Color lut[256],lutm[256],lutc[256];
}Hdr[NUM_IMAGE];
char ProjType;
int P;
double X0,Y0,PixelSize;	/* Albers elip */
struct Color Qlut[256];
int Scale[NUM_IMAGE][256];
int Range[NUM_IMAGE][3],Reverse[NUM_IMAGE];
char Channel[3][100],ChannelOn=0;
long Sample_Rate=1;
int Img=0,Sample=1,Xc=0,Yc=0,Speed=16,Row,Col,ZoomSample=1,ScreenZoom=-1;

unsigned char Inbuff[BUFSIZ];
unsigned char Mbuff[MAX_BUFF],Buffer[4096],OutBuff[1024][4];
int TgaHdr[9]={0,2,0,0,0,0,640,480,32};
unsigned char MaxHues[256][3]=
{
255,  0,  0,255, 32,  0,255, 42,  0,255, 53,  0,255, 60,  0,255, 68,  0,
255, 73,  0,255, 80,  0,255, 84,  0,255, 90,  0,255, 94,  0,255,100,  0,
255,103,  0,255,108,  0,255,112,  0,255,116,  0,255,121,  0,255,124,  0,
255,128,  0,255,132,  0,255,135,  0,255,139,  0,255,143,  0,255,146,  0,
255,150,  0,255,154,  0,255,157,  0,255,161,  0,255,164,  0,255,168,  0,
255,172,  0,255,176,  0,255,179,  0,255,183,  0,255,186,  0,255,190,  0,
255,194,  0,255,198,  0,255,202,  0,255,206,  0,255,210,  0,255,214,  0,
255,218,  0,255,222,  0,255,227,  0,255,231,  0,255,236,  0,255,241,  0,
255,245,  0,255,250,  0,254,255,  0,249,255,  0,244,255,  0,240,255,  0,
234,255,  0,229,255,  0,224,255,  0,220,255,  0,214,255,  0,209,255,  0,
204,255,  0,199,255,  0,194,255,  0,190,255,  0,184,255,  0,179,255,  0,
174,255,  0,169,255,  0,164,255,  0,158,255,  0,152,255,  0,147,255,  0,
141,255,  0,135,255,  0,130,255,  0,123,255,  0,116,255,  0,109,255,  0,
102,255,  0, 94,255,  0, 87,255,  0, 78,255,  0, 68,255,  0, 58,255,  0,
 42,255,  0, 23,255,  0,  0,255, 36,  0,255, 58,  0,255, 73,  0,255, 87,
  0,255,101,  0,255,113,  0,255,125,  0,255,135,  0,255,146,  0,255,156,
  0,255,166,  0,255,176,  0,255,186,  0,255,196,  0,255,204,  0,255,214,
  0,255,224,  0,255,233,  0,255,243,  0,255,252,  0,248,255,  0,239,255,
  0,230,255,  0,222,255,  0,214,255,  0,207,255,  0,200,255,  0,194,255,
  0,187,255,  0,181,255,  0,174,255,  0,169,255,  0,163,255,  0,157,255,
  0,152,255,  0,146,255,  0,141,255,  0,136,255,  0,131,255,  0,126,255,
  0,121,255,  0,116,255,  0,111,255,  0,106,255,  0,101,255,  0, 96,255,
  0, 92,255,  0, 86,255,  0, 81,255,  0, 77,255,  0, 71,255,  0, 66,255,
  0, 60,255,  0, 53,255,  0, 48,255,  0, 39,255,  0, 32,255,  0, 23,255,
  0,  0,255, 16,  0,255, 23,  0,255, 28,  0,255, 32,  0,255, 36,  0,255,
 39,  0,255, 42,  0,255, 45,  0,255, 48,  0,255, 50,  0,255, 53,  0,255,
 58,  0,255, 60,  0,255, 62,  0,255, 64,  0,255, 66,  0,255, 68,  0,255,
 70,  0,255, 73,  0,255, 75,  0,255, 77,  0,255, 78,  0,255, 81,  0,255,
 83,  0,255, 84,  0,255, 87,  0,255, 89,  0,255, 92,  0,255, 93,  0,255,
 94,  0,255, 97,  0,255, 98,  0,255,101,  0,255,103,  0,255,105,  0,255,
107,  0,255,109,  0,255,111,  0,255,113,  0,255,115,  0,255,117,  0,255,
119,  0,255,122,  0,255,124,  0,255,126,  0,255,129,  0,255,131,  0,255,
134,  0,255,135,  0,255,138,  0,255,140,  0,255,143,  0,255,145,  0,255,
148,  0,255,151,  0,255,154,  0,255,156,  0,255,160,  0,255,163,  0,255,
166,  0,255,169,  0,255,173,  0,255,176,  0,255,179,  0,255,183,  0,255,
188,  0,255,192,  0,255,196,  0,255,200,  0,255,204,  0,255,209,  0,255,
214,  0,255,220,  0,255,225,  0,255,231,  0,255,237,  0,255,244,  0,255,
250,  0,255,255,  0,252,255,  0,245,255,  0,238,255,  0,231,255,  0,224,
255,  0,217,255,  0,210,255,  0,203,255,  0,196,255,  0,190,255,  0,183,
255,  0,176,255,  0,170,255,  0,163,255,  0,156,255,  0,151,255,  0,144,
255,  0,137,255,  0,131,255,  0,125,255,  0,118,255,  0,112,255,  0,105,
255,  0, 98,255,  0, 90,255,  0, 83,255,  0, 77,255,  0, 68,255,  0, 60,
255,  0, 50,255,  0, 42,255,  0, 28,255,  0, 23
};

char SubType[20];

unsigned char getpt();
int process_image(int filenum);
long set_time(long delay);
int scale_rgb(int r,int g,int b);
char change_range(int *img,int *c,int *speed);
int plot_Range(int xc,int yc,int *c,int on);
char set_point(float *point,float *speed);
int set_Range(float *point,int *c);
int load_Fhist(char *type,int *c);
int plot_image(int img,int xc,int yc,int base,int color);
int print_range(int r,int g,int b,float *point,int iop);
int scale(int img);
int make_cmg_image(int r,int g,int b,int sample,char *name);
int load_quick_color_image(int r,int g,int b);
int plot_full_qc_image(int sample,int r,int g,int b,int qr,int qg,int qb);
int scroll_any_list(int xc,int yc,int xs,int ys,
		char *string[],int num,char *out_string,
		int menu,int cursor,int box,int highlight,int base);
int histo(int xc,int yc,int xs,int ys,
		int bxc,int byc,int bxs,int bys,int val,int img);
int add_disk_path(char *string);
int open_image(FILE *fp,int filenum);
int rescale_image(void);
int smooth(int img);
int shade(int img,int scale);
int plot_vectors(void);
int graph_locate(int *x,int *y,int *speed);
int get_xy(int *x,int *y,int *speed,int *imgx,int *imgy);
int video_off(void);
void pixel_locate(int *x,int *y,int *speed,int img);
double clat(double x,double y);
double clon(double x,double y);
double cy(double lat,double lon);
double cx(double lat,double lon);
int change_color(void);
int load_image(int filenum);
int screen_mm(void);
int plot_sub_image(FILE *fp,int sample,int filenum);
int plot_full_image(FILE *fp,int sample,int filenum);
int limit_area_fixed(int *xc,int *yc,int *xs,int *ys,int *speed,int *sample);
int read_lbl(char *label,int filenum);
int xy_ll(double x,double y,double *lat,double *lon);
int ll_xy(double *x,double *y,double lat,double lon);
int copy_hdr(int d,int s);
int set_lut(char type,char *filename);
/*int do_menu_buff(char *menu[],int num,int xc,int yc,
        int start,int back,int words,int boxs,int font[128][25]);*/
int M_do_menu(char *menu[],
        int num,int xc,int yc,int start,int back,int words,int boxs,
        int font[128][25]);
int save_sub_mem(int xc,int yc,int xs,int ys);
int recall_sub_mem(int xc,int yc,int xs,int ys);
char fsplit(char *instring,char *path,char *name,char *type);
FILE *open_to_write_digit(char *name,int color);
FILE *open_to_write_text(char *name);
FILE *open_to_read_text(char *name);
FILE *open_to_write_binary(char *name);
FILE *open_to_read_binary(char *name);

main(argc,argv)

int argc;
char *argv[];

{
	int i,i1,j,k;
	char string[100],ans;
    int numfile=0,scan=0,len,slen,val,lastn=-1;
	FILE *fp,*fpmenu;
	char pathbuffer[101],mstring[100],lastid[100];
	long li;

    if(mouse_initialize(4))
    {
        printf("Mouse initialized.\n\n");
		MouseStat=Mouse=4;	/* sensitivity set to maximum (1 is minimum) */
    }
	Delay=set_time((long)10000);
	if(argc>1)
	{
		for(i=1;i<argc;i++)
		{
			if(strcmpi(argv[i-1],"MOUSE")==0&&strcmpi(argv[i],"ON")==0)
			{
				if(mouse_initialize(4))
				{
					printf("Mouse initialized.\n\n");
					printf("\n\nHIT ANY KEY TO CONTINUE\n\n");
					getch();
					MouseStat=Mouse=4;/* sensitivity set to maximum (1 is minimum) */
				}

			}
			if(argv[i][1]==':')
				add_disk_path(argv[i]);
			if(argv[i][0]=='/'&&argv[i][1]=='m')
			{
				strcpy(mstring,argv[i+1]);
				fpmenu=open_to_read_text(mstring);
				if(!fpmenu)
				{
					printf("Could not open menu file '%s' to read.\n",mstring);
					exit(0);
				}
				fgets(mstring,100,fpmenu);
				while(fgets(string,100,fpmenu))
				{
					for(i=0;i<strlen(string);i++)
						if(string[i]==0xa||string[i]==0xd)
							string[i]='\0';
					sscanf(string,"%s",MString[Menu++]);
					len=strlen(MString[Menu-1]);
					slen=strlen(string);
					strcpy(GF_String[Menu-1],string+len+1);
				}
				if(Menu<1)
				{
					printf("No menu entries\n\n");
					exit(0);
				}
			}
			if(argv[i][0]=='/'&&(argv[i][1]=='O'||argv[i][1]=='o'))
			{
				OneImage=1;
				strcpy(OneImageName,argv[i+1]);
			}
			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(strcmpi(argv[i],"scan")==0)
				scan=1;
		}
	}
	if(OneImage==1)
	{
		fp=open_to_read_binary(OneImageName);
		if(!fp)
		{
			printf("Could not open '%s'.\n\n",OneImageName);
			printf("Hit any key to continue.\n\n");
			getch();
			exit(0);
		}
		numfile=0;
		strcpy(Hdr[Img].infile,OneImageName);
	}
	video_on();
	set_lut('G',LastFile);
	SetVideoMode(0,&B_Id);

/* use SubPaths with type of SubType for sub images */
									/* move all Path up 1 */
	for(i=NumPath;i>0;i--)
		strcpy(Path[i],Path[i-1]);
	NumPath+=1;
									/* add '?mp\' to a new set of Paths */
	for(i=2;i<NumPath;i++)
		sprintf(Path[NumPath+i-2],"%s%s\\",Path[i],SubType+1);
	NumPath+=NumPath-2;

	getcwd(pathbuffer,100);
	sprintf(Path[0],"%s\\%s\\",pathbuffer,SubType+1);
	if(Menu>0)
	{
		WriteStringAtxy(40,0,39,(char)112,mstring);
		while((val=scroll_list(40,1,40,21,GF_String,Menu,string))>=0)
		{
			if(read_lbl(MString[val],Img)==1)
				process_image(Img);
			SetVideoMode(0,&B_Id);
			WriteStringAtxy(40,0,39,(char)112,mstring);
		}
		exit(0);
	}
	if(scan==1)
	{
		numfile=load_names("*.lbl");
		sort_name(numfile);
		if(numfile>0)
		{
			video_on();
			set_lut('G',LastFile);
			for(i1=0;i1<numfile;i1++)
			{
				i=GF_Order[i1];
				if(read_lbl(GF_File[i].name,0)==1)
				{
					Row=Hdr[0].row;
					Col=Hdr[0].col;
					Sample=0;
					do
					{
						Sample+=1;
                        Row=Hdr[0].row/Sample;
						Col=Hdr[0].col/Sample;
					}while(Col>ScreenXs||Row>ScreenYs);
					fp=open_to_read_binary(Hdr[0].image);
					if(fp)
					{
						if(Hdr[0].pal_type>0)
						set_lut(Hdr[0].pal_type,LastFile);
						else
						{
							if(set_lut('P',Hdr[0].Lut)<0)
								set_lut('G',LastFile);
						}
						if(plot_full_image(fp,Sample,0)<0)
							break;
						screen_mm();
                        if(fp) fclose(fp);
						plot_font_h(White,2,2,Hdr[0].image,FontSize,Font);
						for(li=0;li<Delay;li++);
					}
				}
			}
			SetVideoMode(0,&B_Id);
		}
		exit(0);
	}
	do
	{
		if(OneImage==0)
		{
			for(i=0;i<NumPath;i++)
			{
				strcpy(String,Path[i]);
				strcat(String,"*.lbl");
    printf("IMVIS - display PDS images or\n");
    printf("        process image sets.\n\n");
    printf("Select image using up/down arrow\n");
    printf("  keys and <Enter> key, or use\n");
    printf("  the mouse and the left mouse \n");
    printf("  button.\n\n");
    printf("Hit <Esc> key to exit.\n\n");
        printf("When a box appears on an image use:\n");
		printf("     (l)arger or \n");
        printf("     (s)maller \n");
        printf("          to change size.\n\n");
        printf("If the shape of the box can be\n");
        printf("changed use:\n");
		printf("     (H)igher,\n");
		printf("     (S)horter,\n");
		printf("     (W)ider, or\n");
        printf("     (N)arrower\n");
        printf("          to change shape.\n\n");
                 if(MouseStat==0)
                    Mouse=0;
               numfile=get_file_name(String,Hdr[Img].infile);
				Mouse=4;
				ScreenZoom=-1;
				if(numfile>=0)
				{
					strcpy(lastid,String);
					lastn=numfile;
					break;
				}
				if(numfile<0&&i==NumPath-1)
				{
                    printf("Hit 'Esc' to quit\n");
                    printf("Any other key to continue...");
					if(getch()==27)
                    {
                        SetVideoMode(0,&B_Id);
                        exit(0);
                    }
					i=-1;
				}
				if(lastn>=0)
				{
					LastN=lastn;
					strcpy(LastId,lastid);
				}
			}
		}
		strcpy(Hdr[Img].label,Hdr[Img].infile);
		if(numfile>=0)
		{
			for(k=0;k<strlen(Hdr[Img].infile);k++)
			if(Hdr[Img].infile[k]=='.')
				Hdr[Img].infile[k]='\0';
			strcpy(string,Hdr[Img].infile);
			strcat(string,".lbl");		
			if(read_lbl(Hdr[Img].label,Img)==1)
				process_image(Img);
			else
				process_set();
		}
		SetVideoMode(0,&B_Id);
	}while(numfile>=0&&OneImage==0);
}

/**************************************************************************
**
**
**
************************************************************************* */

int process_image(int filenum)

{
	int i,j,k;
	int num=0;
	int ix=ScreenXs/2,iy=ScreenYs/2,speed=16/(FontSize-1);
	FILE *fpout;
	char string[100],ans,string1[100],string2[100];
	int val;
	int xc=0,yc=0,xs,ys,sample=0,scale=1;
	int bxc,byc,bxs,bys,wxc,wyc,wxs,wys;
	int npt=Hdr[filenum].data_max-Hdr[filenum].data_min+1;
	int chigh=24/FontSize,cwide=15/FontSize;
	int contrast;
	int mrow=0,mcol=0;
	int left,right,row=0,col=0,rowo,colo,num_times,ro,co;

	bxs=          npt/(FontSize-1)+45/(FontSize+1);
	bxc=ScreenXs-(npt/(FontSize-1)+45/(FontSize+1)+1);
	bys=          128/(FontSize-1)+30/(FontSize+1)+4;
	byc=ScreenYs-(128/(FontSize-1)+30/(FontSize+1)+5);
	wys=wxs=wyc=wxc=ScreenYs/6;
	if(load_image(filenum)<0)
		return(-1);
	if(Hdr[filenum].cap.lines>0)
		plot_caption(filenum);
	do
	{
		num=mouse_menu(Menu_Mouse_i,D_Grey,Cyan,White,Black,
					0,ScreenXs-1,0,ScreenYs-1,
					row,col,&mrow,&mcol,Mouse,0,BUTTON_UP);
		if(num=='c')
			plot_caption(filenum);
		if(num=='z')
		{
			load_image(filenum);			
		}
		if(num=='C')
		{
			Img=filenum;
			if(change_color()==0)
			{
				return(0);
			}
		}
		if(num=='p')
		{
            pixel_locate(&ix,&iy,&speed,filenum);
		}
		if(num=='h')
		{
			sprintf(string,"Size and Place graph on screen");
			xc=yc=5;
			ys=20;xs=(strlen(string)+2)*7;
			save_sub_mem(xc,yc,xs,ys);
			paint_box(0,D_Grey,Buffer,xc,yc,xs,ys);
			plot_font_h(White,xc+7,yc+4,string,2,Font);
			limit_area_all(&bxc,&byc,&bxs,&bys,&speed,ScreenXs,ScreenYs,
				1,Buffer,Black,White,Center);
			paint_box(0,Black,Buffer,bxc,byc,bxs,bys);
			box(0,bxc,byc,D_Grey,bxs-1,bys-1);
			recall_sub_mem(xc,yc,xs,ys);
			do
			{
			if(VideoType=='S')
				sprintf(string,"area to process + 'Enter': 'Esc' to exit)");
			else
				sprintf(string,
"Limit area to process for Histogram  ('Enter' to Process  'Esc' to exit)");
				xc=yc=0;
				ys=40/FontSize;
				xs=(strlen(string)+2)*cwide;
				save_sub_mem(xc,yc,xs,ys);
				paint_box(0,D_Grey,Buffer,xc,yc,xs,ys);
				plot_font_h(White,xc+cwide,yc+1,string,FontSize,Font);
				ans=limit_area_all(&wxc,&wyc,&wxs,&wys,&speed,ScreenXs,ScreenYs,
					1,Buffer,Black,White,Center);
				recall_sub_mem(xc,yc,xs,ys);
				if(ans!=27&&wxs>4&&wys>4)
				{
					paint_box(0,Black,Buffer,bxc,byc,bxs,bys);
					box(0,bxc,byc,D_Grey,bxs-1,bys-1);
					histo(wxc,wyc,wxs,wys,bxc,byc,bxs,bys,White,filenum);
				}
			}while(ans!=27);			
			paint_box(0,Black,Buffer,bxc,byc,bxs,bys);
		}
		if(num=='T')
		{
			k=0;
			do
			{
                if(k>0&&fpout)
					fclose(fpout);
				sprintf(string,"imvis%d.tga",k++);
				fpout=open_to_read_binary(string);
			}while(fpout);
            if(fpout) fclose(fpout);
			fpout=open_to_write_binary(string);
			if(!fpout)
			{
				SetVideoMode(0,&B_Id);
				printf("Could not open output file.\n\n");
				exit(0);
			}
			TgaHdr[6]=ScreenXs;
			TgaHdr[7]=ScreenYs;
			fwrite((char *)TgaHdr,sizeof(int),9,fpout);
			for(i=0;i<ScreenYs;i++)
			{
				getrow(0,0,ScreenXs-1,ScreenYs-1-i,Buffer);
				for(j=0;j<ScreenXs;j++)
				{
					val=Buffer[j];
					OutBuff[j][0]=Hdr[Img].lut[val].b;
					OutBuff[j][1]=Hdr[Img].lut[val].g;
					OutBuff[j][2]=Hdr[Img].lut[val].r;
				}
				fwrite((char *)OutBuff,sizeof(char),ScreenXs*4,fpout);
			}
		}
		if(num=='S')	/* shade */
		{
			sprintf(string1," Give contrast (1 to 20)");
			string2[0]='\0';
			get_string(string,Mbuff,string1,string2,0,0,200,65,1,1,
				Font,White);
			sscanf(string,"%d",&contrast);
			shade(Img,contrast);
		}
		if(num=='s')
		{
			smooth(Img);
		}
		if(num=='H')
		{
			if(Mouse!=0)
				mouse_get_button(&right,&left);
			else
				getch();
		}
		if(num=='b')
		{
			plot_vectors();
        }
        if(num=='v')
        {
            save_vectors();
        }
        if(num=='R')
		{
			rescale_image();
		}
		if(num=='l')
			graph_plot(Img);
    }while(num!='x'&&num!=27);
/*    }while(num!='x');*/
	return(1);
}

/**********************************************************************
**
**
**
**********************************************************************/

int plot_caption(int num)

{
	int i,j,k;
	int xc,yc,high,wide;

	if(Hdr[num].cap.lines<=0||Hdr[num].cap.size<=0)
		return(0);
	high=30/Hdr[num].cap.size;
	wide=15/Hdr[num].cap.size;
	xc=ScreenXs-wide*Hdr[num].cap.wide;
	yc=ScreenYs-high*Hdr[num].cap.lines;
	for(i=0;i<Hdr[num].cap.lines;i++)
	{
		plot_font_h(Hdr[num].cap.color,
			xc,yc+i*high,Hdr[num].cap.text[i],
			Hdr[num].cap.size,Font);
	}
}




/**************************************************************************
**
**
**
************************************************************************* */

int video_on()

{
	int i,ret;

	ScreenZoom=-1;
	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')
	{
        ret=SetVideoMode(480,&B_Id);
		if(B_Id.row==480)
		{
			set_lut('G',LastFile);
			strcpy(SubType,".xmg");
		}
		else
		{
			if(i>1)
				VideoType='Y';
			else if(i==1)
				VideoType='V';
			else if(i==0)
				VideoType='E';
		}
	}
	if(VideoType=='V')
	{
		ret=SetVideoMode(0x12,&B_Id);
		strcpy(SubType,".vmg");
	}
	if(VideoType=='Y')
	{
		ret=SetVideoMode(400,&B_Id);
		strcpy(SubType,".ymg");
	}
	if(VideoType=='S')
	{
		ret=SetVideoMode(0x13,&B_Id);
		set_lut('G',LastFile);
		strcpy(SubType,".smg");
		FontSize=3;
	}
	if(VideoType=='E')
	{
		ret=SetVideoMode(0x10,&B_Id);
		strcpy(SubType,".emg");
	}
	ScreenXs=B_Id.col;
	ScreenYs=B_Id.row;
	Num_Color=B_Id.color;
	if(ret>=0)
		return(1);
	else
	{
		SetVideoMode(0,&B_Id);
		printf("Could not boot video board\n\n");
		exit(0);
	}
}

/***********************************************************************
**
**
**
**
************************************************************************/

int tip(img)
{

}

/***********************************************************************
**
**
**
**
************************************************************************/

long set_time(long delay)

{
	int i,j,k;
	struct timeb t1,t2;
	long li,ds,dm,dt;

	ftime(&t1);
	for(li=0;li<delay;li++);
	ftime(&t2);
	ds=t2.time-t1.time;
	dm=(long)t2.millitm-(long)t1.millitm;
	dt=ds*1000+dm;
	if(dt==0)
	{
		delay*=25;
		ftime(&t1);
		for(li=0;li<delay;li++);
		ftime(&t2);
		ds=t2.time-t1.time;
		dm=(long)t2.millitm-(long)t1.millitm;
		dt=ds*1000+dm;
	}
	if(dt>0)
	{
		delay=3000*delay;
		delay/=dt;
	}
	return(delay);
}
/***********************************************************************
**
**
**
**
************************************************************************/

int process_set()

{
	int i,j,k;
	char ans,choice[100],string[100];
	int val,val2;
	FILE *fp;
	int sample=0,smp;
	int num=0;
	long li;
	int r,g,b;
	char *fstring[NUM_IMAGE],points[50];
	long lpoints;
	int row=Hdr[0].row,col=Hdr[0].col;

	for(k=0;k<3;k++)
	{
		Range[k][0]=0;
		Range[k][1]=127;
		Range[k][2]=255;
	}
	if(VideoType=='X'||VideoType=='Y'||VideoType=='S')
		strcpy(GF_String[num++],"display quick color");
	strcpy(GF_String[num++],"make 8-bit color image");
	strcpy(GF_String[num++],"make RGB composit file");
	if(VideoType=='X'||VideoType=='Y'||VideoType=='S')
		strcpy(GF_String[num++],"scale image set");
	strcpy(GF_String[num++],"scan set -- full image");
	if(row>ScreenYs||col>ScreenXs)
		strcpy(GF_String[num++],"scan set -- sub image");
	strcpy(GF_String[num++],"x -- exit set");
	for(i=0;i<Num_Active_Image;i++)
	{
		fstring[i]=Hdr[i].image;
		for(j=0;j<256;j++)
			Scale[i][j]=j;
	}
	i=0;
	Col=Hdr[i].col;
	Row=Hdr[i].row;
	if(Row<=0||Col<=0)
		return(-1);
	video_on();
	set_lut('G',LastFile);
	do
	{
		Sample=sample+=1;
		Row=Hdr[i].row/sample;
		Col=Hdr[i].col/sample;
	}while(Col>ScreenXs||Row>ScreenYs);
	if(Hdr[i].pal_type>0)
		set_lut(Hdr[i].pal_type,LastFile);
	else
	{
		if(set_lut('P',Hdr[i].Lut)<0)
			set_lut('G',LastFile);
	}
	for(i=0;i<Num_Active_Image;i++)
		Hdr[i].sample=sample;
	SetVideoMode(0,&B_Id);
	do
	{
		val=scroll_list_color(40,1,40,21,
			(char *)GF_String,num,choice,23,124,14,63,7);
		if(strcmpi(choice,"make RGB composit file")==0||
			strcmpi(choice,"make 8-bit color image")==0)
		{
			ClearBox(40,79,0,0,3);
			sprintf(string,"Choose RED plane image");
			WriteStringAtxy(40,0,39,(char)4,string);
			r=scroll_any_list(40,1,40,21,
				fstring,Num_Active_Image,string,
				71,4,14,63,7);
			if(r<0)
				return(0);
			sprintf(string,"Choose GREEN plane image");
			WriteStringAtxy(40,0,39,(char)2,string);
			g=scroll_any_list(40,1,40,21,
				fstring,Num_Active_Image,string,
				32,2,14,63,7);
			if(g<0)
				return(0);
			sprintf(string,"Choose BLUE plane image");
			WriteStringAtxy(40,0,39,(char)23,string);
			b=scroll_any_list(40,1,40,21,
				fstring,Num_Active_Image,string,
				23,1,14,63,7);
			if(b<0)
				return(0);
			ClearScreen(0x7);
			printf("Your choices are:\n\n");
			printf("     RED -- '%s'\n",Hdr[r].image);
			printf("   GREEN -- '%s'\n",Hdr[g].image);
			printf("    BLUE -- '%s'\n",Hdr[b].image);
			printf("\nIs this what you want?  (y or n)\n\n");
			ans=getch();
			if(ans=='y')
			{
				if(scale_rgb(r,g,b)>0)
				{
					printf("Input Images:\n");
					printf("     RED -- '%s'\n",Hdr[r].image);
					printf("   GREEN -- '%s'\n",Hdr[g].image);
					printf("    BLUE -- '%s'\n",Hdr[b].image);
					printf("Give output image file name.\n\n");
					scanf("%s",string);
					printf("Give sample rate.  ( 1 = full res 2 = 1/2 size etc.)\n");
					scanf("%d",&smp);
					if(strcmpi(choice,"make 8-bit color image")==0)
					{
						lpoints=(long)Hdr[0].row*(long)Hdr[0].col;
						lpoints/=25000;
						if(lpoints<10)
							lpoints=10;
						sprintf(points,"%ld",lpoints);
						printf("Making 24 bit image file -- 'imvis.cmg'");
						printf(" and info file 'imvis.chn'\n");
						make_cmg_image(r,g,b,smp,"imvis");
                        _fcloseall();
						execlp("img8bit.exe","img8bit","imvis",string,"5",
							"/m",points,"/c","240",NULL);
					}
					else
					{
						printf("Making 24 bit image file -- '%s.cmg'\n",string);
						printf(" and info file '%s.chn'\n",string);
						make_cmg_image(r,g,b,smp,string);
                        _fcloseall();
					}
				}
			}
		}
		if(strcmpi(choice,"display quick color")==0)
		{
			ClearBox(40,79,0,0,7);
			sprintf(string,"Choose RED plane image");
			WriteStringAtxy(40,0,39,(char)4,string);
			r=scroll_any_list(40,1,40,21,
				fstring,Num_Active_Image,string,
				71,4,14,63,7);
			if(r<0)
				return(0);
			sprintf(string,"Choose GREEN plane image");
			WriteStringAtxy(40,0,39,(char)2,string);
			g=scroll_any_list(40,1,40,21,
				fstring,Num_Active_Image,string,
				32,2,14,63,7);
			if(g<0)
				return(0);
			sprintf(string,"Choose BLUE plane image");
			WriteStringAtxy(40,0,39,(char)23,string);
			b=scroll_any_list(40,1,40,21,
				fstring,Num_Active_Image,string,
				23,1,14,63,7);
			if(b<0)
				return(0);
			ClearScreen(0x7);
			printf("Your choices are:\n\n");
			printf("     RED -- '%s'\n",Hdr[r].image);
			printf("   GREEN -- '%s'\n",Hdr[g].image);
			printf("    BLUE -- '%s'\n",Hdr[b].image);
			printf("\nIs this what you want?  (y or n)\n\n");
			ans=getch();
			if(ans=='y')
			{
				load_quick_color_image(r,g,b);
				getch();
				SetVideoMode(0,&B_Id);
			}
		}
		if(strcmpi(choice,"scan set -- full image")==0)
		{
			video_on();
			set_lut('G',LastFile);
			for(i=0;i<Num_Active_Image;i++)
			{
				if(load_sub_image(i)<0)
					break;
				plot_font_h(White,2,2,Hdr[i].image,FontSize,Font);
				for(li=0;li<Delay;li++);
			}
			SetVideoMode(0,&B_Id);
		}
		if(strcmpi(choice,"scan set -- sub image")==0)
		{
			load_image(0);
			for(i=0;i<Num_Active_Image;i++)
			{
				fp=open_to_read_binary(Hdr[i].image);
				if(fp)
				{
					if(plot_sub_image(fp,ZoomSample,i)<0)
						break;
					screen_mm();
					plot_font_h(White,2,2,Hdr[i].image,FontSize,Font);
					for(li=0;li<Delay;li++);
				}
                if(fp) fclose(fp);
			}
			SetVideoMode(0,&B_Id);
		}
		if(strcmpi(choice,"scale image set")==0)
		{
			for(i=0;i<Num_Active_Image;i++)
				scale(i);
		}
	}while(val>=0&&strcmpi(choice,"x -- exit set")!=0);
}

/***********************************************************************
**
**
**
**
************************************************************************/

int scale_rgb(int r,int g,int b)

{
	int i,j,k,m,n;
	int num=0,val,c[3];
	char string[100],choice[100],ans;
	float point[3];
	FILE *fp;
	int dn,num_item,ispeed=2;
	float speed=0.05;
	char *fstring[10];
	int row=Hdr[0].row,col=Hdr[0].col,aimg=0;

	point[0]=0.05;
	point[1]=0.50;
	point[2]=0.95;
	strcpy(GF_String[num++],"Use Current Parameters");
	strcpy(GF_String[num++],"Histogram from full image files");
	if(row>ScreenYs||col>ScreenXs)
		strcpy(GF_String[num++],"Histogram from Sub Images");
	strcpy(GF_String[num++],"Input Scale Parameters");
	strcpy(GF_String[num++],"Exit Scale Option");

	print_range(r,g,b,point,0);
	for(j=0;j<256;j++)
	{
		Scale[r][j]=j;
		Scale[g][j]=j;
		Scale[b][j]=j;
	}
	do
	{
		c[0]=r;c[1]=g,c[2]=b;
		val=scroll_list_color(40,1,40,21,GF_String,num,choice,63,124,14,63,3);
		if(strcmpi(choice,"Use Current Parameters")==0)
		{
			scale(r);
			scale(g);
			scale(b);
			return(1);
		}
		if(strcmpi(choice,"Histogram from full image files")==0)
		{
			if(load_Fhist("full",c)<0)
				return(-1);
			set_Range(point,c);
			SetCursor(0,3);
			print_range(r,g,b,point,1);
			scale(r);
			scale(g);
			scale(b);
		}
		if(strcmpi(choice,"Histogram from Sub Images")==0)
		{
			if(load_Fhist("sub",c)<0)
				return(-1);
			set_Range(point,c);
			SetCursor(0,3);
			print_range(r,g,b,point,1);
			scale(r);
			scale(g);
			scale(b);
		}
/* set scaling for histogram */
		if(strcmpi(choice,"Histogram from full image files")==0||
		   strcmpi(choice,"Histogram from Sub Images")==0)
		{
			fstring[0]="Use as is";
			fstring[1]="Change table";
			fstring[2]="Change image";
			num_item=3;
			ClearBox(40,79,0,0,3);
			sprintf(string,"Choose an Option");
			WriteStringAtxy(40,0,39,(char)4,string);
			scroll_any_list(40,1,40,21,
				fstring,num_item,string,
				63,4,14,63,7);
			if(strcmpi(string,"Change table")==0)
			{
				do
				{
					ans=set_point(point,&speed);
					set_Range(point,c);
					SetCursor(0,3);
					print_range(r,g,b,point,1);
				}while(ans!=13&&ans!=27);
				if(ans!=27)
				{
					scale(r);
					scale(g);
					scale(b);
				}
			}
			for(i=0;i<16;i++)
			{
				Qlut[i].r=Vcolor[i].r;
				Qlut[i].g=Vcolor[i].g;
				Qlut[i].b=Vcolor[i].b;
			}
			if(strcmpi(string,"Change image")==0)
			{
				for(i=0;i<64;i++)
				{
					for(k=0;k<3;k++)
					{
						Qlut[i+(k+1)*64].r=i*4;
						Qlut[i+(k+1)*64].g=i*4;
						Qlut[i+(k+1)*64].b=i*4;
					}
				}
				video_on();
				WritePalette(Qlut);
				plot_image(r,0,0,64,RED);
				plot_image(g,ScreenXs/2,0,128,GREEN);
				plot_image(b,0,ScreenYs/2,192,BLUE);
				screen_mm();
				plot_Range(ScreenXs/2,ScreenYs/2,c,aimg);
				getch();
				point[0]=0.01;point[1]=0.50;point[2]=0.99;
				set_Range(point,c);
				scale(r);
				scale(g);
				scale(b);
				for(i=0;i<64;i++)
				{
					for(k=0;k<3;k++)
					{
						Qlut[i+(k+1)*64].r=Scale[c[k]][i*4];
						Qlut[i+(k+1)*64].g=Scale[c[k]][i*4];
						Qlut[i+(k+1)*64].b=Scale[c[k]][i*4];
					}
				}
				WritePalette(Qlut);
				do
				{
					ans=change_range(&aimg,c,&ispeed);
					if(ans=='r'||ans=='R')
					{
						set_Range(point,c);
						scale(r);
						scale(g);
						scale(b);
						for(i=0;i<64;i++)
						{
							for(k=0;k<3;k++)
							{
								Qlut[i+(k+1)*64].r=Scale[c[k]][i*4];
								Qlut[i+(k+1)*64].g=Scale[c[k]][i*4];
								Qlut[i+(k+1)*64].b=Scale[c[k]][i*4];
							}
						}
					}						
					else
					{
						scale(c[aimg]);
						k=aimg;
						for(i=0;i<64;i++)
						{
							Qlut[i+(k+1)*64].r=Scale[c[k]][i*4];
							Qlut[i+(k+1)*64].g=Scale[c[k]][i*4];
							Qlut[i+(k+1)*64].b=Scale[c[k]][i*4];
						}
					}
					WritePalette(Qlut);
					plot_Range(ScreenXs/2,ScreenYs/2,c,aimg);
				}while(ans!=27);
				SetVideoMode(0,&B_Id);
			}
		}
	}while(val>=0&&strcmpi(choice,"Exit Scale Option")!=0);
	return(1);
}

/***********************************************************************
**
**
**
**
************************************************************************/

char change_range(int *img,int *c,int *speed)

{
	int i,j,k=*img;
	char ans;

	ans=getch();
	if(ans=='n'||ans=='N')
	{
		if(Reverse[c[k]]==0)
			Reverse[c[k]]=1;
		else
			Reverse[c[k]]=0;
	}
	if(ans==13)
	{
		if(k<2)
			k+=1;
		else
			k=0;
	}
	if(ans==8)
	{
		if(k>0)
			k-=1;
		else
			k=2;
	}
	if(ans==0)
	{
		ans=getch();
		if(ans==71)Range[c[k]][0]+=*speed;
		if(ans==72)Range[c[k]][1]+=*speed;
		if(ans==73)Range[c[k]][2]+=*speed;
		if(ans==79)Range[c[k]][0]-=*speed;
		if(ans==80)Range[c[k]][1]-=*speed;
		if(ans==81)Range[c[k]][2]-=*speed;
	}
	else
	{
		if(ans=='7')Range[c[k]][0]+=*speed;
		if(ans=='8')Range[c[k]][1]+=*speed;
		if(ans=='9')Range[c[k]][2]+=*speed;
		if(ans=='1')Range[c[k]][0]-=*speed;
		if(ans=='2')Range[c[k]][1]-=*speed;
		if(ans=='3')Range[c[k]][2]-=*speed;
	}
	for(i=0;i<3;i++)
	{
		if(Range[c[k]][i]<0)Range[c[k]][i]=0;
		if(Range[c[k]][i]>255)Range[c[k]][i]=255;
	}
	if(ans=='+'&&*speed<16)
		*speed*=2;
	if(ans=='-'&&*speed>1)
		*speed/=2;
	*img=k;
	return(ans);
}



/***********************************************************************
**
**
**
************************************************************************/

int plot_Range(int xc,int yc,int *c,int on)

{
	int i,j,k;
	int xs=ScreenXs/2,ys=ScreenYs/2;
	char string[100];
	int color[3];

	color[0]=RED;color[1]=GREEN;color[2]=BLUE;
	for(k=0;k<3;k++)
	{
		if(Reverse[c[k]]==0)
			sprintf(string,"%3d %3d %3d  ",
				Range[c[k]][0],Range[c[k]][1],Range[c[k]][2]);
		else
			sprintf(string,"%3d %3d %3d N",
				Range[c[k]][0],Range[c[k]][1],Range[c[k]][2]);
		if(on==k)
		{
			paint_box(0,BLACK,Mbuff,xc+3,yc+3+k*45/FontSize,
				strlen(string)*15/FontSize+10,32/FontSize);
			box(0,xc+3,yc+3+k*45/FontSize,WHITE,
				strlen(string)*15/FontSize+19,32/FontSize-1);
		}
		else
			paint_box(0,D_GREY,Mbuff,xc+3,yc+3+k*45/FontSize,
				strlen(string)*15/FontSize+20,32/FontSize);
		plot_font_h(color[k],xc+10,yc+5+k*45/FontSize,string,FontSize,Font);
	}
}



/***********************************************************************
**
**
**
**
************************************************************************/

char set_point(float *point,float *speed)

{
	int k;
	char ans;

	ans=getch();
	if(ans==0)
	{
		ans=getch();
		if(ans==71)point[0]+=*speed;
		if(ans==72)point[1]+=*speed;
		if(ans==73)point[2]+=*speed;
		if(ans==79)point[0]-=*speed;
		if(ans==80)point[1]-=*speed;
		if(ans==81)point[2]-=*speed;
	}
	else
	{
		if(ans=='7')point[0]+=*speed;
		if(ans=='8')point[1]+=*speed;
		if(ans=='9')point[2]+=*speed;
		if(ans=='1')point[0]-=*speed;
		if(ans=='2')point[1]-=*speed;
		if(ans=='3')point[2]-=*speed;
	}
	for(k=0;k<3;k++)
	{
		if(point[k]<0.001)point[k]=0.001;
		if(point[k]>1.000)point[k]=1.000;
	}
	if(ans=='+'&&*speed<0.1)
		*speed*=2.0;
	if(ans=='-'&&*speed>0.01)
		*speed/=2.0;
	return(ans);
}



/***********************************************************************
**
**
**
***********************************************************************/

int set_Range(float *point,int *c)

{
	int i,j,k;
	int dn;

	for(k=0;k<3;k++)
	{
		Fsum[k]=0.0;
		Range[c[k]][0]=Range[c[k]][1]=Range[c[k]][2]=-1;
		for(dn=0;dn<256;dn++)
		{
			Fsum[k]+=Fhist[k][dn]/Ftot[k];
			for(i=0;i<3;i++)
				if(Range[c[k]][i]<0&&Fsum[k]>=point[i])
					Range[c[k]][i]=dn;
		}
	}
}



/***********************************************************************
**
**
**
***********************************************************************/

int load_Fhist(char *type,int *c)

{
	int i,j,k,m,n;
	int dn,row,col;
	char string[100],cr=0xd;
	FILE *fp;

	for(k=0;k<3;k++)
	{
		for(dn=0;dn<256;dn++)
			Fhist[k][dn]=0;
		Ftot[k]=0;
		if(strcmpi(type,"full")==0)
		{
			strcpy(string,Hdr[c[k]].image);
			if(strlen(string)<1)
			{
				printf("Bad file name -- too short!\n\n");
				return(-1);
			}
			if(strlen(string)>99)
			{
				printf("Bad file name -- too long!\n\n");
				exit(0);
			}
			fp=open_to_read_binary(string);
			if(!fp)
			{
				printf("Could not find '%s'.\n",string);
				return(-1);
			}
			row=Hdr[0].row;
			col=Hdr[0].col;
			fseek(fp,Hdr[0].header_bytes,SEEK_SET);
		}
		else if(strcmpi(type,"sub")==0)
		{
			strcpy(string,Hdr[c[k]].image);
			if(strlen(string)<1)
			{
				printf("Bad file name -- too short!\n\n");
				return(-1);
			}
			if(strlen(string)>99)
			{
				printf("Bad file name -- too long!\n\n");
				exit(0);
			}
			for(m=0;m<strlen(string);m++)
			if(string[m]=='.')
				string[m]='\0';
			strcat(string,SubType);
			fp=open_to_read_binary(string);
			if(!fp)
			{
				printf("Could not find '%s'.  Try viewing image to create it\n",
					string);
				printf("or try full image option.\n\n");
				return(-1);
			}
			fread((char *)&row,sizeof(int),1,fp);
			fread((char *)&col,sizeof(int),1,fp);
		}
		else
			return(-1);	
		printf("Processing '%s'\n       of %d lines",string,row);
		for(i=0;i<row;i++)
		{
			printf("%c%6d",cr,i+1);
			for(j=0;j<col;j++)
			{
				dn=fgetc(fp);
				Fhist[k][dn]+=1.0;
				Ftot[k]+=1.0;
			}
		}
		printf("\n");
        if(fp) fclose(fp);
	}
	return(1);
}



/***********************************************************************
**
**
**
***********************************************************************/

int plot_image(int img,int xc,int yc,int base,int color)

{
	int i,j,k;
	int row=Hdr[0].row,col=Hdr[0].col;
	char string[100],filename[100];
	FILE *fp;
	long offset;

	if(row>ScreenYs||col>ScreenXs)	/* use sample image */
	{
		strcpy(string,Hdr[img].image);
		for(k=0;k<strlen(string);k++)
			if(string[k]=='.')
				string[k]='\0';
		strcat(string,SubType);
		fp=open_to_read_binary(string);
		if(!fp)
		{
			setbuf(fp,Inbuff);
			printf("Could not find '%s'.  Try viewing image to create it\n",
				string);
			printf("or try full image option.\n\n");
			return(-1);
		}
		fread((char *)&row,sizeof(int),1,fp);
		fread((char *)&col,sizeof(int),1,fp);
	}
	else
	{
		fp=open_to_read_binary(Hdr[img].image);
		if(!fp)
		{
			setbuf(fp,Inbuff);
			printf("Could not find '%s'\n",
				Hdr[img].image);
			return(-1);
		}
		fseek(fp,Hdr[img].header_bytes,SEEK_SET);
	}
	offset=col;
	for(i=0;i<row/2;i++)
	{
		if(Hdr[img].sample_bits==8)
		{
			fread((char *)Mbuff,sizeof(char),col,fp);
			for(j=0;j<col/2;j++)
				Mbuff[j]=Mbuff[j*2]/4+base;
		}
		else if(Hdr[img].sample_bits==16)
		{
			fread((char *)Mbuff,sizeof(char),col*2,fp);
			for(j=0;j<col/2;j++)
				Mbuff[j]=Mbuff[j*4+1]/4+base;
		}
		plotrow(0,xc,xc+col/2-1,yc+i,Mbuff);
		fseek(fp,offset,SEEK_CUR);
	}
	sprintf(string,"%s",Hdr[img].image);
	paint_box(0,D_GREY,Mbuff,xc,yc,strlen(string)*15/FontSize,30/FontSize);
	plot_font_h(color,xc+1,yc+1,string,FontSize,Font);
}





/***********************************************************************
**
**   iop = 0 do not print Change info
**         1 print percentile
**
**
************************************************************************/

int print_range(int r,int g,int b,float *point,int iop)

{
	printf("\n\n");
	printf("--------------------------------------\n");
	printf("        Current Scaling Parameters    \n");
	printf("--------------------------------------\n");
	printf("       Minimum   Mid-Point   Maximum  \n");
	printf("----- ---------- ---------- ----------\n");
	printf("  red%7d%11d%11d    \n",Range[r][0],Range[r][1],Range[r][2]);
	printf("green%7d%11d%11d    \n",Range[g][0],Range[g][1],Range[g][2]);
	printf(" blue%7d%11d%11d    \n",Range[b][0],Range[b][1],Range[b][2]);
	printf("\n\n");
	if(iop==1)
	{
		printf("------------ ---------- --------------\n");
		printf("Use 'Number Pad' to change percentiles\n");
		printf("------------ ---------- --------------\n");
		printf("up       7          8          9\n");
		printf("------------ ---------- --------------\n");
		printf("%12.2f%11.2f%11.2f    percentile\n",point[0],point[1],point[2]);
		printf("------------ ---------- --------------\n");
		printf("down     1          2          3\n");
		printf("------------ ---------- --------------\n");
	}
}




/***********************************************************************
**
**
**
**
************************************************************************/

int scale(int img)

{
	int i,j,k;
	long n1=Range[img][0],n2=Range[img][1],n3=Range[img][2];
	long dn1=n2-n1,dn2=n3-n2;
	long val;

	if(dn1<2||dn2<2)
		return(0);

	for(i=0;i<n1;i++)
		Scale[img][i]=0;
	for(i=n3;i<256;i++)
		Scale[img][i]=255;
	for(i=n1;i<n2;i++)
	{
		val=i-n1;
		val*=127;
		val/=dn1;
		Scale[img][i]=val;
	}
	for(i=n2;i<n3;i++)
	{
		val=i-n2;
		val*=127;
		val/=dn2;
		val+=128;
		Scale[img][i]=val;
	}
	if(Reverse[img]==1)
		for(i=0;i<256;i++)
			Scale[img][i]=255-Scale[img][i];
}



/***********************************************************************
**
**
**
**
************************************************************************/

int make_cmg_image(int r,int g,int b,int sample,char *name)

{
	int i,j,k;
	int row=Hdr[0].row,col=Hdr[0].col;
	int nrow,ncol;
	FILE *fpred,*fpgrn,*fpblu,*fpcmg,*fpchn;
	unsigned char *rbuff,*gbuff,*bbuff;
	char cr=0xd,string[100];
	long offset=(long)col*(long)(sample-1);

	if(sample<1)
		return(0);
	printf("sample = %d  offset = %ld\n",sample,offset);
	nrow=row/sample;
	ncol=col/sample;
	rbuff=Mbuff;
	gbuff=Mbuff+col;
	bbuff=Mbuff+col*2;
	fpred=open_to_read_binary(Hdr[r].image);
	if(!fpred)
	{
        _fcloseall();
		return(-1);
	}
	fpgrn=open_to_read_binary(Hdr[g].image);
	if(!fpgrn)
	{
        _fcloseall();
		return(-1);
	}
	fpblu=open_to_read_binary(Hdr[b].image);
	if(!fpblu)
	{
        _fcloseall();
		return(-1);
	}
							/* make a file ('name'.chn) with file names */
	sprintf(string,"%s.chn",name);
	fpchn=fopen(string,"wt");
	if(fpchn)
	{
		fprintf(fpchn,"SAMPLE_RATE = %d\n",sample);
		fprintf(fpchn,"CHANNEL_INPUT:\n");
		if(Reverse[r]==0)
			fprintf(fpchn,"     RED   = %s Range = %3d %3d %3d\n",
				Hdr[r].image,Range[r][0],Range[r][1],Range[r][2]);
		else
			fprintf(fpchn,"     RED   = %s Range = %3d %3d %3d (Negative)\n",
				Hdr[r].image,Range[r][0],Range[r][1],Range[r][2]);
		if(Reverse[g]==0)
			fprintf(fpchn,"     GREEN = %s Range = %3d %3d %3d\n",
				Hdr[g].image,Range[g][0],Range[g][1],Range[g][2]);
		else
			fprintf(fpchn,"     GREEN = %s Range = %3d %3d %3d (Negative)\n",
				Hdr[g].image,Range[g][0],Range[g][1],Range[g][2]);
		if(Reverse[b]==0)
			fprintf(fpchn,"     BLUE  = %s Range = %3d %3d %3d\n",
				Hdr[b].image,Range[b][0],Range[b][1],Range[b][2]);
		else
			fprintf(fpchn,"     BLUE  = %s Range = %3d %3d %3d (Negative)\n",
				Hdr[b].image,Range[b][0],Range[b][1],Range[b][2]);
        if(fpchn) fclose(fpchn);
	}
	sprintf(string,"%s.cmg",name);
	fpcmg=fopen(string,"wb");
	if(!fpcmg)
	{
        _fcloseall();
		return(-1);
	}
	fseek(fpred,Hdr[r].header_bytes,SEEK_SET);
	fseek(fpgrn,Hdr[g].header_bytes,SEEK_SET);
	fseek(fpblu,Hdr[b].header_bytes,SEEK_SET);

	fwrite((char *)&nrow,sizeof(int),1,fpcmg);
	fwrite((char *)&ncol,sizeof(int),1,fpcmg);
	printf("      of %d",row/sample);
	for(i=0;i<row/sample;i++)
	{
		printf("%c%5d",cr,i+1);
		fread((char *)rbuff,sizeof(char),col,fpred);
		fread((char *)gbuff,sizeof(char),col,fpgrn);
		fread((char *)bbuff,sizeof(char),col,fpblu);
		if(sample>1)
		{
			fseek(fpred,offset,SEEK_CUR);
			fseek(fpgrn,offset,SEEK_CUR);
			fseek(fpblu,offset,SEEK_CUR);
			for(j=0;j<col/sample;j++)
			{
				rbuff[j]=Scale[r][rbuff[j*sample]];
				gbuff[j]=Scale[g][gbuff[j*sample]];
				bbuff[j]=Scale[b][bbuff[j*sample]];
			}	
		}
		else
		{
			for(j=0;j<col;j++)
			{
				rbuff[j]=Scale[r][rbuff[j]];
				gbuff[j]=Scale[g][gbuff[j]];
				bbuff[j]=Scale[b][bbuff[j]];
			}	
		}
		fwrite((char *)rbuff,sizeof(char),col/sample,fpcmg);
		fwrite((char *)gbuff,sizeof(char),col/sample,fpcmg);
		fwrite((char *)bbuff,sizeof(char),col/sample,fpcmg);
	}
	printf("\n");
    _fcloseall();
}





/**************************************************************************
**
**
**
************************************************************************* */

int load_quick_color_image(int r,int g,int b)

{
	int i,j,k;
	int ir,ig,ib;
	int qr=7,qg=7,qb=5;
	int dr=255/qr+1,dg=255/qg+1,db=255/qb+1;
	int xr=255/(qr-1),xg=255/(qg-1),xb=255/(qg-1);
	int sample=0;
	int xs,ys;
	FILE *fpred,*fpgrn,*fpblu;
	long offset=0;
	char string[100];
	int filenum=0;

	fpred=open_to_read_binary(Hdr[r].image);
	if(!fpred)
	{
        _fcloseall();
		return(-1);
	}
	fpgrn=open_to_read_binary(Hdr[g].image);
	if(!fpgrn)
	{
        _fcloseall();
		return(-1);
	}
	fpblu=open_to_read_binary(Hdr[b].image);
	if(!fpblu)
	{
        _fcloseall();
		return(-1);
	}
	for(ir=0;ir<qr;ir++)
		for(ig=0;ig<qg;ig++)
			for(ib=0;ib<qb;ib++)
			{
				i=ir*(qg*qb)+ig*qb+ib;
				Qlut[i].r=ir*xr;
				Qlut[i].g=ig*xg;
				Qlut[i].b=ib*xb;
			}
	Row=Hdr[filenum].row;
	Col=Hdr[filenum].col;
	if(VideoType=='S')
		Speed=8;
	if(Hdr[filenum].sample_bits==0)
		Hdr[filenum].sample_bits=8;
	if((Row==0||Col==0)&&Hdr[filenum].row_col_header==0)
		return(-1);
	video_on();
	WritePalette(Qlut);
	do
	{
		Sample=sample+=1;
		Row=Hdr[filenum].row/sample;
		Col=Hdr[filenum].col/sample;
	}while(Col>ScreenXs||Row>ScreenYs);
	Hdr[filenum].sample=sample;
    _fcloseall();
	plot_full_qc_image(sample,r,g,b,qr,qg,qb);
	screen_mm();
/*
	if(sample>1)
	{
		sample=ZoomSample;
		if(limit_area_fixed(&Xc,&Yc,&xs,&ys,&Speed,&sample)!=27)
		{
			ZoomSample=sample;
			plot_sub_qc_image(fp,sample,filenum);
			screen_mm();
		}
		else
		{
			ZoomSample=Sample;
		}
	}
*/
}


/**************************************************************************
**
**
**
************************************************************************* */

int plot_full_qc_image(int sample,int r,int g,int b,int qr,int qg,int qb)

{
	int i,j,k;
	int ir,ig,ib;
	long offset;
	char string[100];
	int row,col,val,filenum=0;
	FILE *fpsubr,*fpsubg,*fpsubb,*fpr,*fpg,*fpb;
	int dr=255/qr+1,dg=255/qg+1,db=255/qb+1;
	int xr=255/(qr-1),xg=255/(qg-1),xb=255/(qg-1);
	unsigned offsetr,offsetg,offsetb;

	strcpy(string,Hdr[r].image);
	for(i=0;i<strlen(string);i++)
		if(string[i]=='.')
			string[i]='\0';
	strcat(string,SubType);
	fpsubr=open_to_read_binary(string);
	strcpy(string,Hdr[g].image);
	for(i=0;i<strlen(string);i++)
		if(string[i]=='.')
			string[i]='\0';
	strcat(string,SubType);
	fpsubg=open_to_read_binary(string);
	strcpy(string,Hdr[b].image);
	for(i=0;i<strlen(string);i++)
		if(string[i]=='.')
			string[i]='\0';
	strcat(string,SubType);
	fpsubb=open_to_read_binary(string);
	if(fpsubr&&fpsubg&&fpsubb)
	{
		fread((char *)&row,sizeof(int),1,fpsubr);
		fread((char *)&col,sizeof(int),1,fpsubr);
		fread((char *)&row,sizeof(int),1,fpsubg);
		fread((char *)&col,sizeof(int),1,fpsubg);
		fread((char *)&row,sizeof(int),1,fpsubb);
		fread((char *)&col,sizeof(int),1,fpsubb);
		offsetr=0;
		offsetb=col;
		offsetg=col*2;
		for(i=0;i<row;i++)
		{
			fread((char *)Mbuff+offsetr,sizeof(char),col,fpsubr);
			fread((char *)Mbuff+offsetg,sizeof(char),col,fpsubg);
			fread((char *)Mbuff+offsetb,sizeof(char),col,fpsubb);
			if(kbhit()>0)
			{
				val=getch();
				if(val==27)
					return(-2);
			}
			for(j=0;j<col;j++)
			{
				ir=Scale[r][Mbuff[j+offsetr]]/dr;
				ig=Scale[g][Mbuff[j+offsetg]]/dg;
				ib=Scale[b][Mbuff[j+offsetb]]/db;
				k=ir*(qg*qb)+ig*qb+ib;
				Mbuff[j]=k;
			}
			plotrow(0,0,col-1,i,Mbuff);
		}
	}
	else
	{
        if(fpsubr) fclose(fpsubr);
        if(fpsubg) fclose(fpsubg);
        if(fpsubb) fclose(fpsubb);
		fpr=open_to_read_binary(Hdr[r].image);
		fpg=open_to_read_binary(Hdr[g].image);
		fpb=open_to_read_binary(Hdr[b].image);
		if(fpr&&fpg&&fpb)
		{
			offset=Hdr[r].header_bytes;
				if(offset>0)
					fseek(fpr,offset,SEEK_SET);
			offset=Hdr[g].header_bytes;
				if(offset>0)
					fseek(fpg,offset,SEEK_SET);
			offset=Hdr[b].header_bytes;
				if(offset>0)
					fseek(fpb,offset,SEEK_SET);
			offset=(sample-1);
			offset*=Hdr[r].col;
			for(i=0;i<Row;i++)
			{
				fread((char *)Mbuff+offsetr,sizeof(char),Hdr[r].col,fpr);
				fread((char *)Mbuff+offsetg,sizeof(char),Hdr[g].col,fpg);
				fread((char *)Mbuff+offsetb,sizeof(char),Hdr[b].col,fpb);
				if(kbhit()>0)
				{
					val=getch();
					if(val==27)
						return(-2);
				}
				if(offset>0)
				{
					fseek(fpr,offset,SEEK_CUR);
					fseek(fpg,offset,SEEK_CUR);
					fseek(fpb,offset,SEEK_CUR);
				}
				if(sample>1)
				{
					for(j=0;j<Col;j++)
					{
						ir=Scale[r][Mbuff[j*sample+offsetr]]/dr;
						ig=Scale[g][Mbuff[j*sample+offsetg]]/dg;
						ib=Scale[b][Mbuff[j*sample+offsetb]]/db;
						k=ir*(qg*qb)+ig*qb+ib;
						Mbuff[j]=k;
					}
				}
				else
				{
					for(j=0;j<Col;j++)
					{
						ir=Scale[r][Mbuff[j+offsetr]]/dr;
						ig=Scale[g][Mbuff[j+offsetg]]/dg;
						ib=Scale[b][Mbuff[j+offsetb]]/db;
						k=ir*(qg*qb)+ig*qb+ib;
						Mbuff[j]=k;
					}
				}
				plotrow(3,0,Col-1,i,Mbuff);
			}
            if(fpr) fclose(fpr);
            if(fpg) fclose(fpg);
            if(fpb) fclose(fpb);
		}
	}
    if(fpsubr) fclose(fpsubr);
    if(fpsubg) fclose(fpsubg);
    if(fpsubb) fclose(fpsubb);
}


/********************************************************************
**
**
**
********************************************************************* */

int scroll_any_list(int xc,int yc,int xs,int ys,
		char *string[],int num,char *out_string,
		int menu,int cursor,int box,int highlight,int base)

{
	int i,j,k;
	int x1=xc,x2=xc+xs-1,y1=yc,y2=yc+ys-1;
	int n=0,n1,n2,nlines=ys-2,no;
	char instring[NAME_SIZE];
	char ans,ansc;

	if(num<ys-2)
	{
		ys=num+2;
		y2=yc+ys-1;
		nlines=ys-2;
	}
	n1=n-nlines/2;
	if(n1<0)n1=0;
	n2=n1+nlines-1;
	if(n2>num-1)
	{
		n2=num-1;
		n1=n2-(nlines-1);
	}
/*
3
*/
	ClearBox(x1+1,x2-1,y1+1,y2+2,menu);
	DoubleBox(xc,xc+xs-1,yc,yc+ys-1,box);
	WriteStringAtxy(x1,y2+2,xs,highlight,"'Esc'=Quit  'Enter'=Choose file");

	for(i=0;i<nlines;i++)
	{
		WriteStringAtxy(xc+1,yc+i+1,xs-2,menu,string[i+n1]);
	}
	WriteStringAtxy(xc+1,yc+1+(n-n1),xs-2,cursor,string[n]);
/*
2
*/
	i=0;
	do
	{
		ans=getch();
		if((ans>='a'&&ans<='z')||(ans>='A'&&ans<='Z'))
		{
			n=0;
			i=1;
			instring[0]=ans;
			instring[1]='\0';
			ClearBox(x1,x2,y2+1,y2+1,3);
			WriteStringAtxy(x1,y2+1,xs,highlight,instring);
			do
			{
				if(i>0)
				{
					for(j=n;j<num;j++)
					{
						if(strnicmp((char *)instring,string[j],i)>=0)
						{
							n=j;
							if(strnicmp((char *)instring,string[j],i)==0)
								break;
						}
						else
							break;
					}
					n1=n-nlines/2;
					if(n1<0)n1=0;
					n2=n1+nlines-1;
					if(n2>num-1)
					{
						n2=num-1;
						n1=n2-(nlines-1);
					}
					ClearBox(x1+1,x2-1,y1+1,y2-1,menu);
					for(j=0;j<nlines;j++)
						WriteStringAtxy(xc+1,yc+j+1,xs-2,menu,string[j+n1]);
					WriteStringAtxy(xc+1,yc+1+(n-n1),xs-2,cursor,string[n]);
				}
				ansc=getch();
				if(ansc==0)
				{
					ansc=getch();
					if(ansc!=83&&ans!=82)
						ansc=13;
				}
				if(ansc>31&&ansc<127)
				{
					instring[i]=ansc;
					i+=1;
					instring[i]='\0';
					ClearBox(x1,x2,y2+1,y2+1,menu);
					WriteStringAtxy(x1,y2+1,xs,highlight,instring);
				}
				if(ansc==8)
				{
					n=0;
					if(i>0)
					{
						i-=1;
						instring[i]='\0';
						ClearBox(x1,x2,y2+1,y2+1,menu);
						WriteStringAtxy(x1,y2+1,xs,highlight,instring);
					}
				}
			}while(ansc!=13&&ansc!=27&&ansc!=83&&ans!=82);
			if(ansc==27||ansc==83||ansc==82)
				ans=ansc;
			ClearBox(x1,x2,y2+1,y2+1,menu);
		}
/*
1
*/
		if(ans==0)
		{
			ans=getch();
			WriteStringAtxy(xc+1,yc+1+(n-n1),xs-2,menu,string[n]);
			if(ans==80&&n<num-1)		/* 2 */
				n+=1; 
			if(ans==72&&n>0)			/* 8 */
				n-=1;
			if(n>n2)
			{
				n2=n;
				n1=n2-(nlines-1);
				ScrollUp(1,x1+1,x2-1,y1+1,y2-1,menu);
			}
			if(n<n1)
			{
				n1=n;
				n2=n1+nlines-1;
				ScrollDown(1,x1+1,x2-1,y1+1,y2-1,menu);
			}
			if(ans==73)
			{
				if(n1>0&&n==n1)
				{
					n1-=nlines;
					if(n1<0)n1=0;
					n2=n1+nlines-1;
					n=n1;
					ClearBox(x1+1,x2-1,y1+1,y2-1,menu);
					for(i=0;i<nlines;i++)
						WriteStringAtxy(xc+1,yc+i+1,xs-2,menu,string[i+n1]);
				}
				else if(n>n1)
					n=n1;
			}
			if(ans==71)
			{
				if(n1>0)
				{
					n1=0;
					n2=n1+nlines-1;
					n=0;
					ClearBox(x1+1,x2-1,y1+1,y2-1,menu);
					for(i=0;i<nlines;i++)
						WriteStringAtxy(xc+1,yc+i+1,xs-2,menu,string[i+n1]);
				}
				else if(n>0)
					n=0;
			}
			if(ans==81)
			{
				if(n2<num-1&&n==n2)
				{
					n2+=nlines;
					if(n2>num-1)n2=num-1;
					n1=n2-(nlines-1);
					n=n2;
					ClearBox(x1+1,x2-1,y1+1,y2-1,menu);
					for(i=0;i<nlines;i++)
						WriteStringAtxy(xc+1,yc+i+1,xs-2,menu,string[i+n1]);
				}
				else if(n<n2)
					n=n2;
			}
			if(ans==79)
			{
				if(n2<num-1)
				{
					n2=num-1;
					n1=n2-(nlines-1);
					n=n2;
					ClearBox(x1+1,x2-1,y1+1,y2-1,menu);
					for(i=0;i<nlines;i++)
						WriteStringAtxy(xc+1,yc+i+1,xs-2,menu,string[i+n1]);
				}
				else if(n<n2)
					n=num-1;
			}
			WriteStringAtxy(xc+1,yc+1+(n-n1),xs-2,cursor,string[n]);
		}
	}while(ans!=83&&ans!=27&&ans!=82&&ans!=13);
	ClearBox(xc,xc+xs-1,yc-1,yc+ys+1,base);

	if(ans==83||ans==82||ans==13)		/* 'Del or 'Ins' or 'Enter' */
	{
		strcpy(out_string,string[n]);
		return(n);
	}
	else				/* 'Esc' */
	{
		out_string[0]='\0';
		return(-1);
	}
}



/**************************************************************************
**
**
**
************************************************************************* */

int histo(int xc,int yc,int xs,int ys,
		int bxc,int byc,int bxs,int bys,int val,int img)

{
	int i,j,k,x,y;
	int ival,csize=15/(FontSize+1),size=FontSize+1;
	float fval;
	char string[100];
	long max=0,del=50000,lk;
	
	bys-=30/(FontSize+1)+4;
	bxs-=45/(FontSize+1);
	bxc+=45/(FontSize+1);
	for(k=Hdr[img].data_min;k<=Hdr[img].data_max;k++)
		Hist[k]=0;
	for(i=1;i<ys;i++)
	{
		getrow(3,xc+1,xc+xs-1,i+yc,Buffer);
		for(j=0;j<xs-2;j++)
			Hist[Buffer[j]]+=1;
	}
	for(k=Hdr[img].data_min;k<=Hdr[img].data_max;k++)
		if(Hist[k]>max)
			max=Hist[k];
	if(max<150000)del=25000;
	if(max< 75000)del=12500;
	if(max< 37500)del= 5000;
	if(max< 18750)del= 2500;
	if(max<  9375)del= 2000;
	if(max<  2344)del=  500;
	if(max<  1172)del=  200;
	if(max<   586)del=  100;
	if(max<   293)del=   50;
	if(max<   146)del=   25;
	if(max<    73)del=   10;
	if(max<    36)del=    5;
	if(max<    18)del=    2;
	if(max<     9)del=    1;
	for(lk=0;lk<max;lk+=del)
	{
		fval=lk;
		fval*=bys;
		fval/=(float)max;
		y=fval;
		plotln(0,bxc-2,byc+bys-y,bxc+2,byc+bys-y,val);
		sprintf(string,"%3ld",lk);
		if(y<bys-3)
			plot_font_h(White,bxc-44/size,
					byc+bys-y-12/size,string,size,Font);
	}
	for(k=Hdr[img].data_min;k<=Hdr[img].data_max;k+=50)
	{
		fval=k;
		fval*=bxs;
		fval/=(float)(Hdr[img].data_max-Hdr[img].data_min+1);
		x=fval;
		plotln(0,bxc+x,byc+bys,bxc+x,byc+bys+12/size,val);
		sprintf(string,"%d",k);
		x-=strlen(string)*csize/2;
		if(x+strlen(string)*csize>=bxs)
			x=bxs-1-strlen(string)*csize;
		plot_font_h(White,bxc+x,byc+bys+4,string,
			size,Font);
	}
	for(k=Hdr[img].data_min;k<=Hdr[img].data_max;k++)
	{
		fval=Hist[k];
		fval*=bys;
		fval/=(float)max;
		y=fval;
		fval=k;
		fval*=bxs;
		fval/=(float)(Hdr[img].data_max-Hdr[img].data_min+1);
		x=fval;
		plotln(0,bxc+x,byc+bys-y,bxc+x,byc+bys,val);
	}
}



/**************************************************************************
**
**
**
************************************************************************* */

int add_disk_path(char *string)

{
	int i,j,k;
	char dsk,pth[STR_LEN],nam[10],typ[10],str[STR_LEN];
	int match,add=0;

	dsk=fsplit(string,pth,nam,typ);
	if(dsk>0)
		sprintf(str,"%c:%s",dsk,pth);
	else
		sprintf(str,"%s",pth);
	if((dsk>0||strlen(pth)>0)&&NumPath<NUM_DP)
	{
		match=0;
		for(i=0;i<NumPath;i++)
		{
			if(strcmpi(Path[i],str)==0)
				match=1;
		}
		if(match==0)
		{
			strcpy(Path[NumPath],str);
			NumPath+=1;
			add+=1;
		}
	}
	return(add);
}



/**************************************************************************
**
**
**
************************************************************************* */

int load_sub_image(int filenum)

{
	int i,j,k;
	int sample=0;
	int xs,ys;
	FILE *fp;
	long offset=0;
	char string[100];
	int ret;

	Row=Hdr[filenum].row;
	Col=Hdr[filenum].col;
	if(VideoType=='S')
		Speed=8;

	if(Hdr[filenum].sample_bits==0)
		Hdr[filenum].sample_bits=8;

	if((Row==0||Col==0)&&Hdr[filenum].row_col_header==0)
		return(-1);
	fp=open_to_read_binary(Hdr[filenum].image);
	if(!fp)
		return(-1);
	setbuf(fp,Inbuff);
	if(Hdr[filenum].row_col_header==1)
	{
		fread((char *)&Hdr[filenum].row,sizeof(int),1,fp);
		fread((char *)&Hdr[filenum].col,sizeof(int),1,fp);
		Col=Hdr[filenum].col;
		Row=Hdr[filenum].row;
		if(Row<=0||Col<=0)
			return(-1);
	}
	else if(Hdr[filenum].imbedded_header==1)
	{
		offset=Hdr[filenum].col;
		fseek(fp,offset,SEEK_SET);
	}
	else if(Hdr[filenum].header_bytes>0)
	{
		offset=Hdr[filenum].header_bytes;
		fseek(fp,offset,SEEK_SET);
	}
	do
	{
		Sample=sample+=1;
		Row=Hdr[filenum].row/sample;
		Col=Hdr[filenum].col/sample;
		offset=(sample-1);
		offset*=Hdr[filenum].col;
	}while(Col>ScreenXs||Row>ScreenYs);
	ScreenZoom=Hdr[filenum].sample=sample;
	if(Hdr[filenum].pal_type>0)
		set_lut(Hdr[filenum].pal_type,LastFile);
	else
	{
		if(set_lut('P',Hdr[filenum].Lut)<0)
			set_lut('G',LastFile);
	}
	ret=plot_full_image(fp,sample,filenum);
	screen_mm();
    if(fp) fclose(fp);
	return(ret);
}

/**************************************************************************
**
**
**
************************************************************************* */

int open_image(FILE *fp,int filenum)

{
	fp=open_to_read_binary(Hdr[filenum].image);
	if(!fp)
		return(-1);
	setbuf(fp,Inbuff);
	return(1);
}


/**************************************************************************
**
**
**
************************************************************************* */

int split(char *string,char *path,char *name,char *type)

{
	int i,j,k;
	int dot=-1,last_slash=-1,len=strlen(string),num=0;

	for(i=0;i<len;i++)
	{
		if(string[i]=='.')
			dot=i;
		if(string[i]=='\\')
			last_slash=i;
	}
	last_slash+=1;
	if(dot==-1)
		dot=len-1;
	if(last_slash>0)
	{
		for(i=0;i<last_slash;i++)
			path[i]=string[i];
	}
	path[last_slash]='\0';
	for(i=last_slash;i<dot;i++)
		name[i-last_slash]=string[i];
	name[dot-last_slash]='\0';
	dot+=1;
	for(i=dot;i<len;i++)
		type[i-dot]=string[i];
	type[len-dot]='\0';
	if(strlen(name)>0)
		num+=1;
	if(strlen(type)>0)
		num+=1;

	return(num);
}



/***********************************************************************
**
**
**
**
************************************************************************/

int rescale_image()

{
	int i,j,k;
	int speed=8;
	char ans,string[100];
	int size=FontSize;
	
	Range[0][0]=0;
	Range[0][1]=127;
	Range[0][2]=255;
	scale(0);
	for(i=0;i<256;i++)
	{
		Qlut[i].r=Qlut[i].g=Qlut[i].b=Scale[0][i];
	}	
	WritePalette(Qlut);
	do
	{
		ans=getch();
		if(ans==0)
		{
			ans=getch();
			if(ans==71)Range[0][0]+=speed;
			if(ans==72)Range[0][1]+=speed;
			if(ans==73)Range[0][2]+=speed;
			if(ans==79)Range[0][0]-=speed;
			if(ans==80)Range[0][1]-=speed;
			if(ans==81)Range[0][2]-=speed;
		}
		else
		{
			if(ans=='7')Range[0][0]+=speed;
			if(ans=='8')Range[0][1]+=speed;
			if(ans=='9')Range[0][2]+=speed;
			if(ans=='1')Range[0][0]-=speed;
			if(ans=='2')Range[0][1]-=speed;
			if(ans=='3')Range[0][2]-=speed;
		}
		if(ans=='+'&&speed<16)
			speed*=2.0;
		if(ans=='-'&&speed>1)
			speed/=2.0;
		for(k=0;k<3;k++)
		{
			if(Range[0][k]<0)
				Range[0][k]=0;
			if(Range[0][k]>255)
				Range[0][k]=255;
		}
		if(Range[0][1]<Range[0][0])Range[0][1]=Range[0][0];
		if(Range[0][2]<Range[0][1])Range[0][2]=Range[0][1];
		paint_box(0,D_Grey,Buffer,0,ScreenYs-30/size,ScreenXs,30/size);
		sprintf(string,"%3d  %3d  %3d",Range[0][0],Range[0][1],Range[0][2]);
		plot_font_h(White,2,ScreenYs-30/size+2,string,size,Font);
		scale(0);
		for(i=0;i<256;i++)
		{
			Qlut[i].r=Qlut[i].g=Qlut[i].b=Scale[0][i];
		}	
		WritePalette(Qlut);
	}while(ans!=13);
}




/***********************************************************************
**
**
**
**
************************************************************************/

int smooth(int img)

{
	int i,j,k,m,n;
	unsigned char *buffer[4];
	int sum,num;
	int n1=Hdr[img].data_min,n2=Hdr[img].data_max;

	for(i=0;i<4;i++)
	{
		buffer[i]=(unsigned char *)malloc(ScreenXs);
		if(buffer[i]==NULL)
		{
			SetVideoMode(0);
			printf("malloc failed making buffer[%d]\n\n",i);
			printf("You do not have enough free memory to use this option.\n\n");
            printf("Hit <Esc> key or right mouse button to return to menu\n");
/*            exit(0);*/
            return(0);
		}
	}
	for(i=0;i<2;i++)
		getrow(0,0,ScreenXs-1,i,buffer[i%3]);
	for(i=1;i<ScreenYs-1;i++)
	{
		getrow(0,0,ScreenXs-1,i+1,buffer[(i+1)%3]);
		for(j=1;j<ScreenXs-1;j++)
		{
			buffer[3][j]=buffer[i%3][j];
			if(buffer[i%3][j]>=n1&&buffer[i%3][j]<=n2)
			{
				sum=num=0;
				for(m=-1;m<=1;m++)
				{
					for(n=-1;n<=1;n++)
					{
						if(buffer[(i+m)%3][j+n]>=n1&&buffer[(i+m)%3][j+n]<=n2)
						{
							sum+=buffer[(i+m)%3][j+n];
							num+=1;
						}
					}
				}
				if(num>1)
					buffer[3][j]=sum/num;
			}
		}
		plotrow(0,1,ScreenXs-2,i,buffer[3]+1);
	}
	for(i=0;i<4;i++)
		free(buffer[i]);
}




/***********************************************************************
**
**
**
**
************************************************************************/

int shade(int img,int scale)

{
	int i,j,k;
	int j1,j2;
	int n1=Hdr[img].data_min,n2=Hdr[img].data_max,num=n2-n1;
	int val,val1,val2,mid=n1+num/2;

	for(i=0;i<256;i++)
	{
		Hdr[img].lutc[i].r=Hdr[img].lut[i].r;
		Hdr[img].lutc[i].g=Hdr[img].lut[i].g;
		Hdr[img].lutc[i].b=Hdr[img].lut[i].b;
	}
	for(i=n1/4;i<=n2/4;i++)
	{
		val=i-n1;
		val*=255*4;
		val/=num;
		Hdr[img].lutc[i].r=Hdr[img].lutc[i].g=Hdr[img].lutc[i].b=val;
	}
	WritePalette(Hdr[Img].lutc);
	for(i=0;i<ScreenYs;i++)
	{
		getrow(0,0,ScreenXs-1,i,Buffer);
        for(j=0;j<ScreenXs;j++)
		{
            val1=Buffer[j];
			if(val1<n1||val1>n2)
				val1=0;
            val2=Buffer[j+1];
			if(val2<n1||val2>n2)
				val2=0;
			val=val2-val1;
			val*=scale;
			val+=mid;
			if(val<n1)
				val=n1;
			if(val>n2)
				val=n2;
            Buffer[j]=val/4;
		}
        plotrow(0,0,ScreenXs-1,i,Buffer);
	}
}


/********************************************************************
**
**
**
********************************************************************* */

int plot_vectors()

{
	int i,j,k,m,n;
	double fSam,fsam,rsam;
	double a0,a1,b0,b1;
	char string[STR_LEN];
	int val,numsec,numpt;
	float mll[4],latlon[2],mnln,mxln,mnlt,mxlt;
	double x,y,lat,lon,lat1,lat2;
	int ix,iy,ixo,iyo,sx,sy;
	float pixsize;
	FILE *fp,*fphdr;
	int num=0,doit;
	int nsample=-1,zscale=1;
	long offset;

	pixsize=PixelSize/1000*(float)ZoomSample;
	if(ScreenZoom<1)
		pixsize/=(float)nsample;
	for(i=0;i<Vector;i++)
		menu_l[i]=Group_Name[i];
	menu_l[Vector]="exit vector plot";
	do
	{
        num=M_do_menu(menu_l,Vector+1,MENUXC,25,num,D_Grey,L_Grey,White,Font);
		i=num;
		if(i<Vector)
		{
			for(j=0;j<Ns[i];j++)
			{
				if(pixsize<MapFile[i][j].max_pix&&pixsize>=MapFile[i][j].min_pix)
				{
					strcpy(string,MapFile[i][j].filename);
					strcat(string,".bin");
					fp=open_to_read_binary(string);
					strcpy(string,MapFile[i][j].filename);
					strcat(string,".hdr");
					fphdr=open_to_read_binary(string);
					if(fphdr&&fp)
					{
						setbuf(fp,Inbuff);
						val=MapFile[i][j].color;
						fread((char *)&numsec,sizeof(int),1,fphdr);
						for(k=0;k<numsec;k++)
						{
							if(kbhit()>0)
							{
								val=getch();
								if(val==27)
									return(-2);
							}
							fread((char *)&offset,sizeof(long),1,fphdr);
							fread((char *)mll,sizeof(float),4,fphdr);
							doit=1;
							mnln=mll[0];mxln=mll[1];mnlt=mll[2];mxlt=mll[3];
							if(mnln>MaxLon||mnlt>MaxLat||mxln<MinLon||mxlt<MinLat)
							doit=0;
							if(doit==1)
							{
								fseek(fp,offset,SEEK_SET);
								fread((char *)&numpt,sizeof(int),1,fp);
								fread((char *)mll,sizeof(float),4,fp);
								for(m=0;m<numpt;m++)
								{
									fread((char *)latlon,sizeof(float),2,fp);
									lat=latlon[0];
									lon=latlon[1];
									ll_xy(&x,&y,lat,lon);
									ix=x;
									iy=y;
									if(m>0)
									{
/*                                        if((ix <ScreenXs&&ix >=0&&iy <ScreenYs&&iy >=0)||
											(ixo<ScreenXs&&ixo>=0&&iyo<ScreenYs&&iyo>=0))
*/
											plotln(0,ix,iy,ixo,iyo,val);
									}
									ixo=ix;
									iyo=iy;
								}
                            }
						}
					}
                    if(fphdr) fclose(fphdr);
                    if(fp) fclose(fp);
				}
			}
		}
	}while(num<Vector);
}

/********************************************************************
**
**
**
********************************************************************* */

int graph_locate(int *x,int *y,int *speed)

{
	char ans,ans2,string[100];
	unsigned char buffer[100],buff[640];
	int csize=6,xo=*x,yo=*y,ix,iy,val;
	float fx,fx0,fx1,fx2,delx,fy,fy0,fy1,fy2,dely;
	int x1,x2,y1,y2;
	int cval,ccolor,cx=ScreenXs/2,cy=ScreenYs/2;

	get_string(string,Mbuff,"Give x and y value of a point",
		"then move cursor and enter",
		10,10,30*15/FontSize,95/FontSize,1,1,
		Font,L_Grey);
	sscanf(string,"%f%f",&fx1,&fy1);
	get_xy(&cx,&cy,speed,&ix,&iy);
	x1=cx;
	y1=cy;
	get_string(string,Mbuff,"Give x and y value of 2nd point",
		"then move cursor and enter",
		10,10,30*15/FontSize,95/FontSize,1,1,
		Font,L_Grey);
	sscanf(string,"%f%f",&fx2,&fy2);
	get_xy(&cx,&cy,speed,&ix,&iy);
	x2=cx;
	y2=cy;
	if(x1==x1&&y1==y2)
		return(-1);
	if(x2!=x1)
		delx=(fx2-fx1)/((float)x2-(float)x1);
	else
		delx=0.0;
	if(y2!=y1)
		dely=(fy2-fy1)/((float)y2-(float)y1);
	else
		dely=0;
	
	cval=getpt(0,*x,*y);
	if(((int)Hdr[Img].lut[cval].r*10+
			(int)Hdr[Img].lut[cval].g*8+(int)Hdr[Img].lut[cval].b*2)>2048)
		ccolor=Black;
	else
		ccolor=White;
	tcursor(0,*x,*y,csize,buffer);
	cursor(0,*x,*y,ccolor,csize);
	paint_box(0,Black,buff,0,ScreenYs-35,121,35);
	sprintf(string,"x=%3d y=%3d",*x,*y);
	plot_font_h(White,2,ScreenYs-33,string,2,Font);
	do
	{
		ans=getch();
		if(ans=='-'&&*speed>1)
			*speed/=2;
		if(ans=='+'&&*speed<ScreenYs/2)
			*speed*=2;
		if(ans==0)
		{
			ans2=getch();
			if(ans2==71||ans2==75||ans2==79)
				*x-=*speed;
			if(ans2==73||ans2==77||ans2==81)
				*x+=*speed;
			if(ans2==71||ans2==72||ans2==73)
				*y-=*speed;
			if(ans2==79||ans2==80||ans2==81)
				*y+=*speed;
			if(*x<0)
				*x=0;
			if(*x>=ScreenXs)
				*x=ScreenXs-1;
			if(*y<0)
				*y=0;
			if(*y>=ScreenYs)
				*y=ScreenYs-1;
			uncursor(0,xo,yo,csize,buffer);
			cval=getpt(0,*x,*y);
			if(((int)Hdr[Img].lut[cval].r*10+
					(int)Hdr[Img].lut[cval].g*8+(int)Hdr[Img].lut[cval].b*2)>2048)
				ccolor=Black;
			else
				ccolor=White;
			tcursor(0,*x,*y,csize,buffer);
			cursor(0,*x,*y,ccolor,csize);
			paint_box(0,Black,buff,0,ScreenYs-35,221,35);
			val=getpt(0,*x,*y);
			fx=(float)(*x-x1)*delx;
			fy=(float)(*y-x1)*dely;
			sprintf(string,"x=%3d y=%3d fx=%0.5f fy=%0.5f",*x,*y,val,fx,fy);
			plot_font_h(White,2,ScreenYs-33,string,2,Font);
			ix=Xc*Sample+*x*ZoomSample;
			iy=Yc*Sample+*y*ZoomSample;
			sprintf(string,"%5d %5d",ix,iy);
			plot_font_h(White,2,ScreenYs-16,string,2,Font);
			xo=*x;
			yo=*y;
		}
	}while(ans!=27&&ans!=13);
	uncursor(0,xo,yo,csize,buffer);
	paint_box(0,Black,buff,0,ScreenYs-33,121,30);
}

/***********************************************************************
**
**
**
**
************************************************************************/

int get_xy(int *x,int *y,int *speed,int *imgx,int *imgy)

{
	char ans,ans2;
	int cval,ccolor,csize=6;
	int ix,iy,xo,yo;

	do
	{
		ans=getch();
		if(ans=='-'&&*speed>1)
			*speed/=2;
		if(ans=='+'&&*speed<ScreenYs/2)
			*speed*=2;
		if(ans==0)
		{
			ans2=getch();
			if(ans2==71||ans2==75||ans2==79)
				*x-=*speed;
			if(ans2==73||ans2==77||ans2==81)
				*x+=*speed;
			if(ans2==71||ans2==72||ans2==73)
				*y-=*speed;
			if(ans2==79||ans2==80||ans2==81)
				*y+=*speed;
			if(*x<0)
				*x=0;
			if(*x>=ScreenXs)
				*x=ScreenXs-1;
			if(*y<0)
				*y=0;
			if(*y>=ScreenYs)
				*y=ScreenYs-1;
			uncursor(0,xo,yo,csize,Buffer);
			cval=getpt(0,*x,*y);
			if(((int)Hdr[Img].lut[cval].r*10+
					(int)Hdr[Img].lut[cval].g*8+(int)Hdr[Img].lut[cval].b*2)>2048)
				ccolor=Black;
			else
				ccolor=White;
			tcursor(0,*x,*y,csize,Buffer);
			cursor(0,*x,*y,ccolor,csize);
			ix=Xc*Sample+*x*ZoomSample;
			iy=Yc*Sample+*y*ZoomSample;
			xo=*x;
			yo=*y;
		}
	}while(ans!=27&&ans!=13);
	uncursor(0,xo,yo,csize,Buffer);
	*imgx=ix;
	*imgy=iy;
}

/********************************************************************
**
**
**
********************************************************************* */

int video_off()

{
	SetVideoMode(0,&B_Id);
}

/********************************************************************
**
**
**
********************************************************************* */

void pixel_locate(int *x,int *y,int *speed,int img)

{
	char ans,ans2,string[100],string2[100];
	unsigned char buffer[100],buff[640];
	int csize=6,xo=*x,yo=*y,ix,iy,val;
	int cval,ccolor;
	unsigned char r,g,b;
	long offset,lx,ly,row=Hdr[img].row,col=Hdr[img].col;
	FILE *fpr,*fpg,*fpb;
	int sample=ScreenZoom,nsample=ScreenZoom*-1+2;
	double lat=0.0,lon=0.0;

	save_sub_mem(0,ScreenYs-35,ScreenXs,35);
	if(ChannelOn==1)	/* RGB channel file names available */
	{
		fpr=fopen(Channel[0],"rb");
		fpg=fopen(Channel[1],"rb");
		fpb=fopen(Channel[2],"rb");
		if(!fpr||!fpg||!fpb)
			ChannelOn=0;		/* at least one file missing */
	}
	cval=getpt(0,*x,*y);
	if(((int)Hdr[Img].lut[cval].r*10+
			(int)Hdr[Img].lut[cval].g*8+(int)Hdr[Img].lut[cval].b*2)>2048)
		ccolor=Black;
	else
		ccolor=White;
	tcursor(0,*x,*y,csize,buffer);
	cursor(0,*x,*y,ccolor,csize);
	paint_box(0,Black,buff,0,ScreenYs-35,ScreenXs,35);
	sprintf(string,"x=%3d y=%3d",*x,*y);
	plot_font_h(White,2,ScreenYs-33,string,2,Font);
	do
	{
		ans=getch();
		if(ans=='-'&&*speed>1)
			*speed/=2;
		if(ans=='+'&&*speed<ScreenYs/2)
			*speed*=2;
		if(ans==0)
		{
			ans2=getch();
			if(ans2==71||ans2==75||ans2==79)
				*x-=*speed;
			if(ans2==73||ans2==77||ans2==81)
				*x+=*speed;
			if(ans2==71||ans2==72||ans2==73)
				*y-=*speed;
			if(ans2==79||ans2==80||ans2==81)
				*y+=*speed;
			if(*x<0)
				*x=0;
			if(*x>=ScreenXs)
				*x=ScreenXs-1;
			if(*y<0)
				*y=0;
			if(*y>=ScreenYs)
				*y=ScreenYs-1;
			uncursor(0,xo,yo,csize,buffer);
			cval=getpt(0,*x,*y);
			if(((int)Hdr[Img].lut[cval].r*10+
				(int)Hdr[Img].lut[cval].g*8+(int)Hdr[Img].lut[cval].b*2)>2048)
				ccolor=Black;
			else
				ccolor=White;
			tcursor(0,*x,*y,csize,buffer);
			cursor(0,*x,*y,ccolor,csize);
			paint_box(0,Black,buff,0,ScreenYs-35,ScreenXs,35);
			val=getpt(0,*x,*y);
			if(sample>0)
			{
				lx=ix=Xc*Sample+*x*sample;
				ly=iy=Yc*Sample+*y*sample;
				lx*=Sample_Rate;
				ly*=Sample_Rate;
			}
			else
			{
				lx=ix=Xc*Sample+*x/nsample;
				ly=iy=Yc*Sample+*y/nsample;
				lx*=Sample_Rate;
				ly*=Sample_Rate;
			}
			if(ChannelOn==1&&ix<col&&iy<row)
			{
				offset=ly*col*Sample_Rate+lx;
				fseek(fpr,offset,SEEK_SET);
				fseek(fpg,offset,SEEK_SET);
				fseek(fpb,offset,SEEK_SET);
				if(fread((char *)&r,sizeof(char),1,fpr)<1)
				{
					SetVideoMode(0,&B_Id);
					printf("could not read '%s'\n",Channel[0]);
					exit(0);
				}
				if(fread((char *)&g,sizeof(char),1,fpg)<1)
				{
					SetVideoMode(0,&B_Id);
					printf("could not read '%s'\n",Channel[1]);
					exit(0);
				}
				if(fread((char *)&b,sizeof(char),1,fpb)<1)
				{
					SetVideoMode(0,&B_Id);
					printf("could not read '%s'\n",Channel[2]);
					exit(0);
				}
			}
			sprintf(string,"x=%3d y=%3d %3d",*x,*y,val);
			if(ChannelOn==1&&ix<col&&iy<row)
			{
				sprintf(string2,"  r:%3d g:%3d b:%3d",r,g,b);
				strcat(string,string2);
			}	
			plot_font_h(White,2,ScreenYs-33,string,2,Font);
            if(ProjType!=0)
			{
                xy_ll((double)*x,(double)*y,&lat,&lon);
				sprintf(string,"%5d %5d lat = %9.5lf lon = %10.5lf",ix,iy,lat,lon);
			}
            else
				sprintf(string,"%5d %5d",ix,iy);
			plot_font_h(White,2,ScreenYs-16,string,2,Font);
			xo=*x;
			yo=*y;
		}
	}while(ans!=27&&ans!=13);
	uncursor(0,xo,yo,csize,buffer);
	paint_box(0,Black,buff,0,ScreenYs-33,121,30);
	recall_sub_mem(0,ScreenYs-35,ScreenXs,35);
    if(ChannelOn==1)    /* RGB channel file names available */
    {
        fclose(fpr);
        fclose(fpg);
        fclose(fpb);
    }
}

/**************************************************************************
**
**
**
************************************************************************* */

double clat(double x,double y)

{
	double lat=Nav.B_Lat[0];

	if(Nav.numlat>1)
		lat+=Nav.B_Lat[1]*y;
	if(Nav.numlat>2)
		lat+=Nav.B_Lat[2]*y*y;
	if(Nav.numlat>3)
		lat+=Nav.B_Lat[3]*x;
	if(Nav.numlat>4)
		lat+=Nav.B_Lat[4]*x*x;
	if(Nav.numlat>5)
		lat+=Nav.B_Lat[5]*y*x;
	return(lat);
}

/**************************************************************************
**
**
**
************************************************************************* */

double clon(double x,double y)

{
	double lon=Nav.B_Lon[0];

	if(Nav.numlon>1)
		lon+=Nav.B_Lon[1]*x;
	if(Nav.numlon>2)
		lon+=Nav.B_Lon[2]*x*x;
	if(Nav.numlon>3)
		lon+=Nav.B_Lon[3]*y;
	if(Nav.numlon>4)
		lon+=Nav.B_Lon[4]*y*y;
	if(Nav.numlon>5)
		lon+=Nav.B_Lon[5]*y*x;
	return(lon);
}

/**************************************************************************
**
**
**
************************************************************************* */

double cy(double lat,double lon)

{
	double y=Nav.B_Y[0];

	if(Nav.numy>1)
		y+=Nav.B_Y[1]*lat;
	if(Nav.numy>2)
		y+=Nav.B_Y[2]*lat*lat;
	if(Nav.numy>3)
		y+=Nav.B_Y[3]*lon;
	if(Nav.numy>4)
		y+=Nav.B_Y[4]*lon*lon;
	if(Nav.numy>5)
		y+=Nav.B_Y[5]*lat*lon;
	return(y);
}

/**************************************************************************
**
**
**
************************************************************************* */

double cx(double lat,double lon)

{
	double x=Nav.B_X[0];

	if(Nav.numx>1)
		x+=Nav.B_X[1]*lon;
	if(Nav.numx>2)
		x+=Nav.B_X[2]*lon*lon;
	if(Nav.numx>3)
		x+=Nav.B_X[3]*lat;
	if(Nav.numx>4)
		x+=Nav.B_X[4]*lat*lat;
	if(Nav.numx>5)
		x+=Nav.B_X[5]*lat*lon;
	return(x);
}


/**************************************************************************
**
**
**
************************************************************************* */

int change_color()

{
	int i,j,k;
	int num=0;
	int maxr=-1,maxg=-1,maxb=-1,minr=256,ming=256,minb=256;
	float flut[3],flutm[3],fdel[3],fmin[3],fv[3],fr[3];
	float scale=1.0,dels=0.05,max,min,tint[3],brite=1.0;
	FILE *fplut;
	int val,ix=ScreenXs/2,iy=ScreenYs/2,speed=16;
	char ans,ans2,ans3;
	double power=1.0,r,g,b;

	/* put lut into lutc for safe keeping */
	for(i=0;i<256;i++)
	{
		Hdr[Img].lutc[i].r=Hdr[Img].lut[i].r;
		Hdr[Img].lutc[i].g=Hdr[Img].lut[i].g;
		Hdr[Img].lutc[i].b=Hdr[Img].lut[i].b;
	}
	do
	{
        num=M_do_menu(menu_c,MENU_C,MENUXC,25,num,D_Grey,L_Grey,White,Font);
		if(num==0)  /* change saturation and tint and brightness*/
		{
			for(k=0;k<3;k++)
				tint[k]=1.0;
			brite=scale=1.0;
			while((ans=getch())!=27&&ans!=13)
			{
				if(ans==0)
				{
					ans2=getch();
					if(ans2==71)tint[0]+=dels;
					if(ans2==72)tint[1]+=dels;
					if(ans2==73)tint[2]+=dels;
					if(ans2==79)tint[0]-=dels;
					if(ans2==80)tint[1]-=dels;
					if(ans2==81)tint[2]-=dels;
					for(k=0;k<3;k++)
					{
						if(tint[k]<0.0)tint[k]=0.0;
						if(tint[k]>1.0)tint[k]=1.0;
					}
				}
				if(ans=='+')
					scale+=dels;
				if(ans=='-')
					scale-=dels;
				if(scale<0.0)
					scale=0.0;
				if(scale> 2.0)
					scale= 2.0;
				if(ans=='b')
					brite+=dels;
				if(ans=='d')
					brite-=dels;
				if(brite<0.0)
					brite=0.0;
				if(ans=='r')
				{
					for(i=0;i<256;i++)		/* put original (c) into lut */
					{
						Hdr[Img].lut[i].r=Hdr[Img].lutc[i].r;
						Hdr[Img].lut[i].g=Hdr[Img].lutc[i].g;
						Hdr[Img].lut[i].b=Hdr[Img].lutc[i].b;
					}
					scale=1.0;
					for(k=0;k<3;k++)
						tint[k]=1.0;
				}
				for(i=0;i<256;i++)
				{
					fv[0]=Hdr[Img].lut[i].r;
					fv[1]=Hdr[Img].lut[i].g;
					fv[2]=Hdr[Img].lut[i].b;
					max=0.0;min=256.0;
					for(k=0;k<3;k++)
					{
						if(fv[k]>max)max=fv[k];
						if(fv[k]<min)min=fv[k];
					}
					if(max>min)
					{
						for(k=0;k<3;k++)
							fr[k]=(fv[k]-min)/(max-min);
						if(scale>1.0)
							min*=2.0-scale;
						else
							min+=(max-min)*(1.0-scale);
						for(k=0;k<3;k++)
						{
							fv[k]=fr[k]*(max-min)+min+0.5;
							if(fv[k]<0.0)fv[k]=0.0;
							if(fv[k]>256.0)fv[k]=256.0;
						}
					}
					for(k=0;k<3;k++)
					{
						fv[k]*=brite*tint[k];
						if(fv[k]>255.0)
							fv[k]=255.0;
					}
					Hdr[Img].lutm[i].r=fv[0];
					Hdr[Img].lutm[i].g=fv[1];
					Hdr[Img].lutm[i].b=fv[2];
				}
				WritePalette(Hdr[Img].lutm);
			}
			for(i=0;i<256;i++)		/* put changed palette (m) into lut */
			{
				Hdr[Img].lut[i].r=Hdr[Img].lutm[i].r;
				Hdr[Img].lut[i].g=Hdr[Img].lutm[i].g;
				Hdr[Img].lut[i].b=Hdr[Img].lutm[i].b;
			}
		}
		if(num==1)  /* stretch table */
		{
			maxr=-1;
			maxg=-1;
			maxb=-1;
			minr=256;
			ming=256;
			minb=256;
			for(i=0;i<256;i++)
			{
				if((Hdr[Img].lut[i].r<255||Hdr[Img].lut[i].g<255||
						Hdr[Img].lut[i].b<255)&&
					(Hdr[Img].lut[i].r>0||Hdr[Img].lut[i].g>0||Hdr[Img].lut[i].b>0))
				{
					if((int)Hdr[Img].lut[i].r>maxr)maxr=Hdr[Img].lut[i].r;
					if((int)Hdr[Img].lut[i].r<minr)minr=Hdr[Img].lut[i].r;
					if((int)Hdr[Img].lut[i].g>maxg)maxg=Hdr[Img].lut[i].g;
					if((int)Hdr[Img].lut[i].g<ming)ming=Hdr[Img].lut[i].g;
					if((int)Hdr[Img].lut[i].b>maxb)maxb=Hdr[Img].lut[i].b;
					if((int)Hdr[Img].lut[i].b<minb)minb=Hdr[Img].lut[i].b;
				}
			}
			fdel[0]=maxr-minr;
			fdel[1]=maxg-ming;
			fdel[2]=maxb-minb;
			fmin[0]=minr;
			fmin[1]=ming;
			fmin[2]=minb;
			for(i=0;i<256;i++)
			{
				flut[0]=Hdr[Img].lut[i].r;
				flut[1]=Hdr[Img].lut[i].g;
				flut[2]=Hdr[Img].lut[i].b;
				for(k=0;k<3;k++)
				{
                    if(fdel[k]!=0.0)
                        val=(flut[k]-fmin[k])/fdel[k]*255.0;
                    else
                        val=flut[k];
					if(val<0.0)
						val=0.0;
					if(val>255.0)
						val=255.0;
					flutm[k]=val;
				}
				Hdr[Img].lut[i].r=flutm[0];
				Hdr[Img].lut[i].g=flutm[1];
				Hdr[Img].lut[i].b=flutm[2];
			}
			WritePalette(Hdr[Img].lut);
		}
		if(num==2)		/* reset */
		{
			for(i=0;i<256;i++)		/* put original (c) into lut */
			{
				Hdr[Img].lut[i].r=Hdr[Img].lutc[i].r;
				Hdr[Img].lut[i].g=Hdr[Img].lutc[i].g;
				Hdr[Img].lut[i].b=Hdr[Img].lutc[i].b;
			}
			scale=1.0;
			for(k=0;k<3;k++)
				tint[k]=1.0;
			WritePalette(Hdr[Img].lut);
		}
		if(num==4&&VideoType!='V')
		{
			SetVideoMode(0,&B_Id);
			printf(
"\n\nYou have requested that the Look Up Table be changed.  If you proceed\n");
			printf(
"you will replace the current '.pal' file with a new one and the current\n");
			printf(
"file will be destroyed.  You may wish to make a copy of it first.\n\n");
			printf("        Do you wish to continue?  (y or n)\n\n");
			if(getch()=='y')
			{
				if(strlen(Hdr[Img].Lut)>0)
				{
					fplut=open_to_write_text(Hdr[Img].Lut);
					if(fplut)
					{
						for(i=0;i<Num_Color;i++)
							fprintf(fplut,"%3d %3d %3d %3d\n",i,
								Hdr[Img].lut[i].r,
								Hdr[Img].lut[i].g,
								Hdr[Img].lut[i].b);
                        if(fplut) fclose(fplut);
					}
				}
			}
			video_on();
			WritePalette(Hdr[Img].lut);
			return(0);
		}
		if(num==3) /* change one color */
		{
			pixel_locate(&ix,&iy,&speed,Img);
			val=getpt(3,ix,iy);
			while((ans3=getch())!=27)
			{
				if(ans3==0)
				{
					ans3=getch();
					if(ans3==71&&Hdr[Img].lut[val].r<251)
						Hdr[Img].lut[val].r+=4;
					if(ans3==72&&Hdr[Img].lut[val].g<251)
						Hdr[Img].lut[val].g+=4;
					if(ans3==73&&Hdr[Img].lut[val].b<251)
						Hdr[Img].lut[val].b+=4;
					if(ans3==79&&Hdr[Img].lut[val].r>3)
						Hdr[Img].lut[val].r-=4;
					if(ans3==80&&Hdr[Img].lut[val].g>3)
						Hdr[Img].lut[val].g-=4;
					if(ans3==81&&Hdr[Img].lut[val].b>3)
						Hdr[Img].lut[val].b-=4;
					WritePalette(Hdr[Img].lut);	
				}
            }
        }
        if(num==5)  /* change contrast brightness*/
        {
            for(k=0;k<3;k++)
                tint[k]=1.0;
            brite=scale=1.0;
            while((ans=getch())!=27&&ans!=13)
            {
                if(ans==0)
                {
                    ans2=getch();
                    if(ans2==71)power*=1.044273782;
                    if(ans2==72)power*=1.044273782;
                    if(ans2==73)power*=1.044273782;
                    if(ans2==79)power/=1.044273782;
                    if(ans2==80)power/=1.044273782;
                    if(ans2==81)power/=1.044273782;
                    for(i=0;i<256;i++)      /* put original (c) into lut */
                    {
                        r=Hdr[Img].lutc[i].r;
                        g=Hdr[Img].lutc[i].g;
                        b=Hdr[Img].lutc[i].b;
                        r/=255.0;
                        g/=255.0;
                        b/=255.0;
                        r=pow(r,power)*255.0;
                        g=pow(g,power)*255.0;
                        b=pow(b,power)*255.0;
                        Hdr[Img].lut[i].r=r;
                        Hdr[Img].lut[i].g=g;
                        Hdr[Img].lut[i].b=b;
                    }
                    WritePalette(Hdr[Img].lut);
                }
            }
        }
    }while(num<MENU_C-1);
	return(1);
}



/**************************************************************************
**
**
**
************************************************************************* */

int load_image(int filenum)

{
	int i,j,k;
	int sample=0;
	int xs,ys;
	FILE *fp;
	long offset=0;
	char string[100];

    _fcloseall();
	Row=Hdr[filenum].row;
	Col=Hdr[filenum].col;
	if(VideoType=='S')
		Speed=8;

	if(Hdr[filenum].sample_bits==0)
		Hdr[filenum].sample_bits=8;

	if((Row==0||Col==0)&&Hdr[filenum].row_col_header==0)
		return(-1);
	fp=open_to_read_binary(Hdr[filenum].image);
	if(!fp)
		return(-1);
	setbuf(fp,Inbuff);
	if(Hdr[filenum].row_col_header==1)
	{
		fread((char *)&Hdr[filenum].row,sizeof(int),1,fp);
		fread((char *)&Hdr[filenum].col,sizeof(int),1,fp);
		Col=Hdr[filenum].col;
		Row=Hdr[filenum].row;
		if(Row<=0||Col<=0)
		{
            if(fp) fclose(fp);
			return(-1);
		}
	}
	else if(Hdr[filenum].imbedded_header==1)
	{
		offset=Hdr[filenum].col;
		fseek(fp,offset,SEEK_SET);
	}
	else if(Hdr[filenum].header_bytes>0)
	{
		offset=Hdr[filenum].header_bytes;
		fseek(fp,offset,SEEK_SET);
	}
    if(Sample==1||ScreenZoom!=Sample||Xc!=0||Yc!=0)
/*    if(ScreenZoom!=Sample||Xc!=0||Yc!=0)*/
	{
		video_on();
		set_lut('G',LastFile);
		do
		{
			Sample=sample+=1;
			Row=Hdr[filenum].row/sample;
			Col=Hdr[filenum].col/sample;
			offset=(sample-1);
			offset*=Hdr[filenum].col;
		}while(Col>ScreenXs||Row>ScreenYs);
		Hdr[filenum].sample=sample;
		if(Hdr[filenum].pal_type>0)
			set_lut(Hdr[filenum].pal_type,LastFile);
		else
		{
			if(set_lut('P',Hdr[filenum].Lut)<0)
				set_lut('G',LastFile);
		}
		plot_full_image(fp,sample,filenum);
		screen_mm();
	}
	if(sample>-17)
	{
		sample=ZoomSample;
		if(limit_area_fixed(&Xc,&Yc,&xs,&ys,&Speed,&sample)!=27)
		{
			ZoomSample=sample;
			plot_sub_image(fp,sample,filenum);
			screen_mm();
		}
		else
		{
			ScreenZoom=ZoomSample=Sample;
			Xc=Yc=0;
			screen_mm();
		}
	}
    if(fp) fclose(fp);
	return(1);
}

/********************************************************************
**
**
**
********************************************************************* */

int screen_mm()

{
	double lat,lon,x,y;
	double sx=ScreenXs,sy=ScreenYs;
	float flat,flon,lon_r,lon_l;
FILE *fpout;

	MaxLat=-360.0;
	MaxLon=-360.0;
	MinLat= 360.0;
	MinLon= 360.0;
	if(ProjType==0)
	{
		MaxLat= 360.0;
		MaxLon= 360.0;
		MinLat=-360.0;
		MinLon=-360.0;
	}
	else
	{
		x=0.0;y=0.0;
		xy_ll(x,y,&lat,&lon);
		flat=lat;flon=lon;
		if(flat>MaxLat)MaxLat=flat;
		if(flon>MaxLon)MaxLon=flon;
		if(flat<MinLat)MinLat=flat;
		if(flon<MinLon)MinLon=flon;
		x=ScreenXs/2;y=0.0;
		xy_ll(x,y,&lat,&lon);
		flat=lat;flon=lon;
		if(flat>MaxLat)MaxLat=flat;
		if(flon>MaxLon)MaxLon=flon;
		if(flat<MinLat)MinLat=flat;
		if(flon<MinLon)MinLon=flon;
		x=ScreenXs;y=0.0;
		xy_ll(x,y,&lat,&lon);
		flat=lat;flon=lon;
		if(flat>MaxLat)MaxLat=flat;
		if(flon>MaxLon)MaxLon=flon;
		if(flat<MinLat)MinLat=flat;
		if(flon<MinLon)MinLon=flon;
		x=0.0;y=ScreenYs;
		xy_ll(x,y,&lat,&lon);lon_l=lon;
		flat=lat;flon=lon;
		if(flat>MaxLat)MaxLat=flat;
		if(flon>MaxLon)MaxLon=flon;
		if(flat<MinLat)MinLat=flat;
		if(flon<MinLon)MinLon=flon;
		x=ScreenXs/2;y=ScreenYs;
		xy_ll(x,y,&lat,&lon);
		flat=lat;flon=lon;
		if(flat>MaxLat)MaxLat=flat;
		if(flon>MaxLon)MaxLon=flon;
		if(flat<MinLat)MinLat=flat;
		if(flon<MinLon)MinLon=flon;
		x=ScreenXs;y=ScreenYs;
		xy_ll(x,y,&lat,&lon);lon_r=lon;
		flat=lat;flon=lon;
		if(flat>MaxLat)MaxLat=flat;
		if(flon>MaxLon)MaxLon=flon;
		if(flat<MinLat)MinLat=flat;
		if(flon<MinLon)MinLon=flon;
		x=ScreenXs;y=  0.0;
		xy_ll(x,y,&lat,&lon);
		flat=lat;flon=lon;
		if(flat>MaxLat)MaxLat=flat;
		if(flon>MaxLon)MaxLon=flon;
		if(flat<MinLat)MinLat=flat;
		if(flon<MinLon)MinLon=flon;
		x=ScreenXs/2;y=  0.0;
		xy_ll(x,y,&lat,&lon);
		flat=lat;flon=lon;
		if(flat>MaxLat)MaxLat=flat;
		if(flon>MaxLon)MaxLon=flon;
		if(flat<MinLat)MinLat=flat;
		if(flon<MinLon)MinLon=flon;
        if(ProjType!='N')
        {
            if(lon_l>180.0)
                lon_l-=360.0;
            if(lon_r>180.0)
                lon_r-=360.0;
            lat=-89.999;    /* south pole check */
            ll_xy(&x,&y,lat,lon);
            if(x>=0.0&&x<sx&&y>0.0&&y<sy)
            {
                MinLat=-90.001;
                MinLon=-360.0;
                MaxLon= 360.0;
            }
            lat=89.999; /* north pole check */
            ll_xy(&x,&y,lat,lon);
            if(x>=0.0&&x<sx&&y>0.0&&y<sy)
            {
                MaxLat= 90.001;
                MinLon=-360.0;
                MaxLon= 360.0;
            }
            if(lon_l>lon_r) /* date line on screen */
            {
                MinLon=-360.0;
                MaxLon= 360.0;
            }
        }
	}
fpout=fopen("imvis.out","at");
fprintf(fpout,"MaxLat=%f MinLat=%f MaxLon=%f MinLon=%f\n",
MaxLat,MinLat,MaxLon,MinLon);
}

/**************************************************************************
**
**
**
************************************************************************* */

int plot_sub_image(FILE *fp,int sample,int filenum)

{
	int i,j,k;
	long offset,offscale=1;
	int val,nsample=sample*-1+2,zscale=1;

	if(Hdr[filenum].sample_bits==16)
			offscale=2;
	ScreenZoom=sample;
	if(sample<1)
		zscale=nsample;
	rewind(fp);
	offset=Hdr[filenum].col*offscale;
	offset*=Yc*Sample;
	offset+=Xc*Sample*offscale;
	if(Hdr[filenum].header_bytes>0)
		offset+=Hdr[filenum].header_bytes;
	fseek(fp,offset,SEEK_SET);
	Row=ScreenYs;
	Col=ScreenXs;
	offset=Hdr[filenum].col*offscale;
	if(sample>0)
	{
		if((Yc*Sample+Row*sample)>Hdr[filenum].row)
			Row=(Hdr[filenum].row-Yc*Sample)/sample;
		if((Xc*Sample+Col*sample)>Hdr[filenum].col)
			Col=(Hdr[filenum].col-Xc*Sample)/sample;
	}
	else
	{
		if((Yc*Sample+Row/nsample)>Hdr[filenum].row)
			Row=(Hdr[filenum].row-Yc*Sample)*nsample;
		if((Xc*Sample+Col/nsample)>Hdr[filenum].col)
			Col=(Hdr[filenum].col-Xc*Sample)*nsample;
		offset=0;
	}
	offset*=(sample-1)*offscale;
	for(i=0;i<Row/zscale;i++)
	{
		if(Hdr[filenum].sample_bits==8)
		{
			if(fread((char *)Mbuff,sizeof(char),Hdr[filenum].col,fp)<1)
				return(-1);
		}
		else if(Hdr[filenum].sample_bits==16)
		{
			if(fread((char *)Mbuff,sizeof(char),Hdr[filenum].col*2,fp)<1)
				return(-1);
			for(k=0;k<Hdr[filenum].col;k++)
				Mbuff[k]=Mbuff[k*2+1];
		}
		if(kbhit()>0)
		{
			val=getch();
			if(val==27)
				return(-2);
		}
		if(offset>0)
			fseek(fp,offset,SEEK_CUR);
		if(sample>1)
			for(j=0;j<Col;j++)
				Mbuff[j]=Mbuff[j*sample];
		if(sample<1)
			for(j=Col-1;j>0;j--)
				Mbuff[j]=Mbuff[j/nsample];
		if(VideoType=='V'||VideoType=='E')
		{
			if(ActiveLut=='P')
			{
				for(j=0;j<Col;j++)
					Mbuff[j]=Hdr[filenum].vga_color[Mbuff[j]];
			}
			else
			{
				for(j=0;j<Col;j++)
					Mbuff[j]/=16;
			}
		}
		if(sample>0)
			plotrow(3,0,Col-1,i,Mbuff);
		else
			for(k=0;k<nsample;k++)
				plotrow(3,0,Col-1,i*nsample+k,Mbuff);
	}
	return(1);
}


/**************************************************************************
**
**
**
************************************************************************* */

int plot_full_image(FILE *fp,int sample,int filenum)

{
	int i,j,k;
	long offset;
	char string[100];
	int row,col,val;
	FILE *fpsub;

	strcpy(string,Hdr[filenum].image);
	for(i=0;i<strlen(string);i++)
		if(string[i]=='.')
			string[i]='\0';
	strcat(string,SubType);
	fpsub=open_to_read_binary(string);
	if(fpsub)
	{
		fread((char *)&row,sizeof(int),1,fpsub);
		fread((char *)&col,sizeof(int),1,fpsub);
		for(i=0;i<row;i++)
		{
			fread((char *)Mbuff,sizeof(char),col,fpsub);
			if(kbhit()>0)
			{
				val=getch();
				if(val==27)
				{
                    if(fpsub) fclose(fpsub);
					return(-2);
				}
			}
			plotrow(0,0,col-1,i,Mbuff);
		}
        if(fpsub) fclose(fpsub);
	}
	else
	{
		if(!fp)
		{
			SetVideoMode(0,&B_Id);
			printf("In plot_full_image() fp = (null)\n");
			exit(0);
		}
		rewind(fp);
		offset=Hdr[filenum].header_bytes;
		if(offset>0)
			fseek(fp,offset,SEEK_SET);
		offset=(sample-1);
		offset*=Hdr[filenum].col;
		for(i=0;i<Row;i++)
		{
			if(Hdr[filenum].sample_bits==8)
			{
				if(fread((char *)Mbuff,sizeof(char),Hdr[filenum].col,fp)<1)
					return(-1);
			}
			else if(Hdr[filenum].sample_bits==16)
			{
				if(fread((char *)Mbuff,sizeof(char),Hdr[filenum].col*2,fp)<1)
					return(-1);
				for(k=0;k<Hdr[filenum].col;k++)
					Mbuff[k]=Mbuff[k*2+1];
			}
			if(kbhit()>0)
			{
				val=getch();
				if(val==27)
					return(-2);
			}
			if(offset>0)
			{
				fseek(fp,offset,SEEK_CUR);
				if(Hdr[filenum].sample_bits==16)
					fseek(fp,offset,SEEK_CUR);
			}
			if(sample>1)
				for(j=0;j<Col;j++)
					Mbuff[j]=Mbuff[j*sample];
			if(VideoType=='V'||VideoType=='E')
			{
				if(ActiveLut=='P')
				{
					for(j=0;j<Col;j++)
						Mbuff[j]=Hdr[filenum].vga_color[Mbuff[j]];
				}
				else
				{
					for(j=0;j<Col;j++)
						Mbuff[j]/=16;
				}
			}
			plotrow(3,0,Col-1,i,Mbuff);
		}
		if(sample>1)
		{
			fpsub=open_to_write_binary(string);
			if(fpsub)
			{
				fwrite((char *)&Row,sizeof(int),1,fpsub);
				fwrite((char *)&Col,sizeof(int),1,fpsub);
				for(i=0;i<Row;i++)
				{
					getrow(0,0,Col-1,i,Mbuff);
					fwrite((char *)Mbuff,sizeof(char),Col,fpsub);
				}
                if(fpsub) fclose(fpsub);
			}
		}
	}
}

/**************************************************************************
**
**
**
************************************************************************* */

int limit_area_fixed(int *xc,int *yc,int *xs,int *ys,int *speed,int *sample)

{
	int i,j,k;
	int xco=*xc,yco=*yc,xso,yso;
	int ok=0;
	char ans;

	do
	{
		if(*sample>0)
		{
			xso=*xs=ScreenXs/Sample*(*sample);
			yso=*ys=ScreenYs/Sample*(*sample);
		}
		else
		{
			xso=*xs=ScreenXs/Sample/(*sample*-1+2);
			yso=*ys=ScreenYs/Sample/(*sample*-1+2);
		}
		if(*xs+*xc>=ScreenXs||*ys+*yc>=ScreenYs)
		{
			ok=0;
			if(*xc!=0||*yc!=0)
			{
				*xc=*yc=0;
			}
			else
			{
				*sample-=1;
			}
		}
		else
			ok=1;
	}while(ok==0);
	if(*sample>0)
		tbox_val(3,*xc,*yc,*xs,*ys,Mbuff,Black,White,Center);
	else
		tbox_val(3,*xc,*yc,*xs,*ys,Mbuff,Center,Center,Center);
	do
	{
		ans=getch();
		unbox(3,*xc,*yc,*xs,*ys,Mbuff);
		if(ans==27)
		{
			return(27);
		}
		else if(ans=='-'&&*speed>1)*speed/=2;
		else if(ans=='+'&&*speed<ScreenYs)*speed*=2;
		else if(ans=='l'&&*sample<Sample)
			*sample+=1;
		else if(ans=='s')
			*sample-=1;
		if(*sample>0)
		{
			*xs=ScreenXs/Sample*(*sample);
			*ys=ScreenYs/Sample*(*sample);
		}
		else
		{
			*xs=ScreenXs/Sample/(*sample*-1+2);
			*ys=ScreenYs/Sample/(*sample*-1+2);
		}
		if(ans==0)
		{
			ans=getch();
			if(ans==71)
			{
				*xc-=*speed;
				*yc-=*speed;
			}
			else if(ans==73)
			{
				*xc+=*speed;
				*yc-=*speed;
			}
			else if(ans==79)
			{
				*xc-=*speed;
				*yc+=*speed;
			}
			else if(ans==81)
			{
				*xc+=*speed;
				*yc+=*speed;
			}
			else if(ans==72)
				*yc-=*speed;
			else if(ans==80)
				*yc+=*speed;
			else if(ans==75)
				*xc-=*speed;
			else if(ans==77)
				*xc+=*speed;
		}
		if(*xs>ScreenXs)*xs=ScreenXs;
		if(*ys>ScreenYs)*ys=ScreenYs;
		if(*xs<2)*xs=2;
		if(*ys<2)*ys=2;
		if((*xc+*xs)>=ScreenXs)*xc=ScreenXs-*xs;
		if((*yc+*ys)>=ScreenYs)*yc=ScreenYs-*ys;
		if(*xc<0)*xc=0;
		if(*yc<0)*yc=0;
		if(*sample>0)
			tbox_val(3,*xc,*yc,*xs,*ys,Mbuff,Black,White,Center);
		else
			tbox_val(3,*xc,*yc,*xs,*ys,Mbuff,Center,Center,Center);
	}while(ans!=83&&ans!='x'&&ans!=27&&ans!=13);
	unbox(3,*xc,*yc,*xs,*ys,Mbuff);
	return(ans);
}

/**************************************************************************
**
**
**
************************************************************************* */

int read_lbl(char *label,int filenum)

{
	int i,j,k;
	char string1[100],string2[100],string3[100],string[100];
	FILE *fp;
	int status=1,numread,n1,n2,n3,num;
    double lat0,lat1,lat2,lon0,k0;
/*    double lat0,lat1,lat2,lon0;*/

	fp=open_to_read_text(label);	
	if(!fp)
		return(-1);
	Hdr[filenum].header_bytes=0;
	Hdr[filenum].sample_bits=8;
	Hdr[filenum].record_bytes=0;
	Hdr[filenum].file_records=0;
	Hdr[filenum].pal_type=0;
	Hdr[filenum].row_col_header=0;
	Hdr[filenum].cap.lines=0;
	ProjType=0;

	Hdr[filenum].infile[0]='\0';
	Hdr[filenum].image[0]='\0';
	Hdr[filenum].Lut[0]='\0';
	Hdr[filenum].label[0]='\0';

	for(i=0;i<NUM_IMAGE;i++)
		Reverse[i]=0;
	Nav.numlat=Nav.numlon=0;
	Nav.numy  =Nav.numy  =0;
	Hdr[filenum].data_min=0;
	Hdr[filenum].data_max=255;
	Sample_Rate=1;
	ChannelOn=Vector=0;
	while(fscanf(fp,"%s",string1)==1)
	{
		if(strcmpi(string1,"end")==0)
		{
            if(fp) fclose(fp);
			set_menu(Menu_Mouse_i,filenum);
			return(status);
		}
		if(strcmpi(string1,"image_lines")==0&&Hdr[filenum].file_records==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
                if(fp) fclose(fp);
				set_menu(Menu_Mouse_i,filenum);
				return(status);
			}			
			sscanf(string3,"%d",&Hdr[filenum].row);
		}
		if(strcmpi(string1,"SAMPLE_BITS")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
                if(fp) fclose(fp);
				set_menu(Menu_Mouse_i,filenum);
				return(status);
			}			
			sscanf(string3,"%d",&Hdr[filenum].sample_bits);
		}
		if(strcmpi(string1,"CHANNEL_INPUT:")==0)
		{
			ChannelOn=1;
			while(fgetc(fp)!=0xa);	/* skip to end of line */
			for(k=0;k<3;k++)
			{
				if(!fgets(string1,99,fp))
				{
					printf("Invalid CHANNEL_INPUT:\n");
					exit(0);
				}
				sscanf(string1+13,"%s",Channel[k]);
			}
		}
		if(strcmpi(string1,"CAPTION")==0)
		{
			fscanf(fp,"%s%d%s",string1,&Hdr[filenum].cap.lines,string2);
			fscanf(fp,"%s%s%d",string1,string2,&Hdr[filenum].cap.color);
			fscanf(fp,"%s%s%d",string1,string2,&Hdr[filenum].cap.size);
			fgets(string1,100,fp); /* clear cr/lf */
			Hdr[filenum].cap.wide=0;
			for(i=0;i<Hdr[filenum].cap.lines;i++)
			{
				fgets(Hdr[filenum].cap.text[i],100,fp);
				for(j=0;j<100;j++)
					if(Hdr[filenum].cap.text[i][j]==0xa||
					   Hdr[filenum].cap.text[i][j]==0xd)
						Hdr[filenum].cap.text[i][j]='\0';
				if(strlen(Hdr[filenum].cap.text[i])>Hdr[filenum].cap.wide)
					Hdr[filenum].cap.wide=strlen(Hdr[filenum].cap.text[i]);
			}
		}
		if(strcmpi(string1,"SAMPLE_RATE")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			sscanf(string3,"%ld",&Sample_Rate);
			if(Sample_Rate<1||Sample_Rate>30)
			{
				printf("Invalid SAMPLE_RATE = %ld\n",Sample_Rate);
				exit(0);
			}
		}
		if(strcmpi(string1,"Projection")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
                if(fp) fclose(fp);
				set_menu(Menu_Mouse_i,filenum);
				return(status);
			}
			ProjType=string3[0];
            switch(ProjType)
			{
            case 'A':
				while(fgetc(fp)!=0xa);	/* skip to end of line */
				fgets(string1,100,fp);
				sscanf(string1,"%lf",&lat0);
				fgets(string1,100,fp);
				sscanf(string1,"%lf",&lat1);
				fgets(string1,100,fp);
				sscanf(string1,"%lf",&lat2);
				fgets(string1,100,fp);
				sscanf(string1,"%lf",&lon0);
				fgets(string1,100,fp);
				sscanf(string1,"%lf",&X0);
				fgets(string1,100,fp);
				sscanf(string1,"%lf",&Y0);
				fgets(string1,100,fp);
				sscanf(string1,"%lf",&PixelSize);
				fgets(string1,100,fp);
				sscanf(string1,"%d",&P);
                set_alb(P,lat0,lat1,lat2,lon0);
/*                set_const(P,lat0,lat1,lat2,lon0);*/
                break;
            case 'E':
                while(fgetc(fp)!=0xa);
				fgets(string1,100,fp);
                sscanf(string1,"%lf",&lat0);
                fgets(string1,100,fp);
				sscanf(string1,"%lf",&lon0);
                fgets(string1,100,fp);
                sscanf(string1,"%lf",&k0);
                fgets(string1,100,fp);
                sscanf(string1,"%lf",&X0);
				fgets(string1,100,fp);
				sscanf(string1,"%lf",&Y0);
				fgets(string1,100,fp);
				sscanf(string1,"%lf",&PixelSize);
				fgets(string1,100,fp);
				sscanf(string1,"%d",&P);
                set_etm(P,lat0,lon0,k0);
                break;
            case 'N':
                while(fgetc(fp)!=0xa);
                fgets(string1,100,fp);
                sscanf(string1,"%lf",&X0);
                fgets(string1,100,fp);
                sscanf(string1,"%lf",&Y0);
                fgets(string1,100,fp);
                sscanf(string1,"%lf",&PixelSize);
                break;
            default:
                puts("Invalid projection");
                break;
            }
		}
		if(strcmpi(string1,"file_records")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
                if(fp) fclose(fp);
				set_menu(Menu_Mouse_i,filenum);
				return(status);
			}			
			sscanf(string3,"%d",&Hdr[filenum].row);
			Hdr[filenum].file_records=Hdr[filenum].row;
		}
		if(strcmpi(string1,"line_samples")==0&&Hdr[filenum].record_bytes==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
                if(fp) fclose(fp);
				set_menu(Menu_Mouse_i,filenum);
				return(status);
			}			
			sscanf(string3,"%d",&Hdr[filenum].col);
		}
		if(strcmpi(string1,"record_bytes")==0||
			strcmpi(string1,"image_record_bytes")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
                if(fp) fclose(fp);
				set_menu(Menu_Mouse_i,filenum);
				return(status);
			}			
			sscanf(string3,"%d",&Hdr[filenum].col);
			Hdr[filenum].record_bytes=Hdr[filenum].col;
		}
		if(strcmpi(string1,"header_bytes")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
                if(fp) fclose(fp);
				set_menu(Menu_Mouse_i,filenum);
				return(status);
			}			
			sscanf(string3,"%ld",&Hdr[filenum].header_bytes);
		}
		if(strcmpi(string1,"data_max")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
                if(fp) fclose(fp);
				set_menu(Menu_Mouse_i,filenum);
				return(status);
			}			
			sscanf(string3,"%d",&Hdr[filenum].data_max);
		}
		if(strcmpi(string1,"data_min")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
                if(fp) fclose(fp);
				set_menu(Menu_Mouse_i,filenum);
				return(status);
			}			
			sscanf(string3,"%d",&Hdr[filenum].data_min);
		}
		if(strcmpi(string1,"image_pointer")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
                if(fp) fclose(fp);
				set_menu(Menu_Mouse_i,filenum);
				return(status);
			}			
			k=0;
			for(i=0;i<strlen(string3);i++)
				if(string3[i]!=39)		/* single quote */
					Hdr[filenum].image[k++]=string3[i];
			Hdr[filenum].image[k]='\0';
		}
		if(strcmpi(string1,"pal_type")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
                if(fp) fclose(fp);
				set_menu(Menu_Mouse_i,filenum);
				return(status);
			}			
			k=0;
			for(i=0;i<strlen(string3);i++)
				if(string3[i]!=39)		/* single quote */
					string1[k++]=string3[i];
			string1[k]='\0';
			Hdr[filenum].pal_type=string1[0];
		}
		if(strcmpi(string1,"pal_pointer")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
                if(fp) fclose(fp);
				set_menu(Menu_Mouse_i,filenum);
				return(status);
			}			
			k=0;
			for(i=0;i<strlen(string3);i++)
				if(string3[i]!=39)		/* single quote */
					Hdr[filenum].Lut[k++]=string3[i];
			Hdr[filenum].Lut[k]='\0';
		}
		if(strcmpi(string1,"row_col_header")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
                if(fp) fclose(fp);
				set_menu(Menu_Mouse_i,filenum);
				return(status);
			}			
			Hdr[filenum].row_col_header=1;
			Hdr[filenum].header_bytes=4;
		}
		if(strcmpi(string1,"latitude_coef")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
                if(fp) fclose(fp);
				set_menu(Menu_Mouse_i,filenum);
				return(status);
			}			
			sscanf(string3,"%d",&Nav.numlat);
			if(Nav.numlat>MAX_LL||Nav.numlat<2)
			{
				printf("Invalid number of Latitude coefficients '%s'\n\n",string3);
				exit(0);
			}
			for(i=0;i<Nav.numlat;i++)
			{
				fscanf(fp,"%s",string3);
				if(sscanf(string3,"%lf",Nav.B_Lat+i)<1)
				{
					printf("Invalid latitude '%s'\n\n",string3);
					exit(0);
				}
			}
		}
		if(strcmpi(string1,"y_coef")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
                if(fp) fclose(fp);
				set_menu(Menu_Mouse_i,filenum);
				return(status);
			}			
			sscanf(string3,"%d",&Nav.numy);
			if(Nav.numy>MAX_LL||Nav.numy<2)
			{
				printf("Invalid number of Y coefficients '%s'\n\n",string3);
				exit(0);
			}
			for(i=0;i<Nav.numy;i++)
			{
				fscanf(fp,"%s",string3);
				if(sscanf(string3,"%lf",Nav.B_Y+i)<1)
				{
					printf("Invalid Y coef. '%s'\n\n",string3);
					exit(0);
				}
			}
		}
		if(strcmpi(string1,"longitude_coef")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
                if(fp) fclose(fp);
				set_menu(Menu_Mouse_i,filenum);
				return(status);
			}			
			sscanf(string3,"%d",&Nav.numlon);
			if(Nav.numlon>MAX_LL||Nav.numlon<2)
			{
				printf("Invalid number of longitude coefficients '%s'\n\n",string3);
				exit(0);
			}
			for(i=0;i<Nav.numlon;i++)
			{
				fscanf(fp,"%s",string3);
				if(sscanf(string3,"%lf",Nav.B_Lon+i)<1)
				{
					printf("Invalid longitude '%s'\n\n",string3);
					exit(0);
				}
			}
		}
		if(strcmpi(string1,"x_coef")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
                if(fp) fclose(fp);
				set_menu(Menu_Mouse_i,filenum);
				return(status);
			}			
			sscanf(string3,"%d",&Nav.numx);
			if(Nav.numx>MAX_LL||Nav.numx<2)
			{
				printf("Invalid number of X coefficients '%s'\n\n",string3);
				exit(0);
			}
			for(i=0;i<Nav.numx;i++)
			{
				fscanf(fp,"%s",string3);
				if(sscanf(string3,"%lf",Nav.B_X+i)<1)
				{
					printf("Invalid X coef. '%s'\n\n",string3);
					exit(0);
				}
			}
		}
		if(strcmpi(string1,"set_pointer")==0||strcmpi(string1,"set_pointers")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
				printf("invalid 'set_pointer' format\n\n");
				exit(0);
			}
			sscanf(string3,"%d",&Num_Active_Image);
			if(Num_Active_Image>=NUM_IMAGE)
			{
				printf("Invalid number of images in set.\n\n");
				exit(0);
			}
			for(i=0;i<Num_Active_Image;i++)
			{
				Range[i][0]=0;
				Range[i][1]=127;
				Range[i][2]=255;
			}
			for(i=0;i<Num_Active_Image;i++)
			{
				if(!fgets(string,99,fp))
				{
					printf("Error reading 'set_pointer'\n");
					exit(0);
				}
				num=sscanf(string,"%s%d%d%d",string1,&n1,&n2,&n3);
				if(num<1||strlen(string)==0)
				{
					fgets(string,99,fp);
					num=sscanf(string,"%s%d%d%d",string1,&n1,&n2,&n3);
				}
				if(num==4)
				{
					Range[i][0]=n1;
					Range[i][1]=n2;
					Range[i][2]=n3;
				}
				if(num==3)
				{
					Range[i][0]=n1;
					Range[i][2]=n2;
					Range[i][1]=(Range[i][0]+Range[i][1])/2;
				}
				copy_hdr(i,0);
				strcpy(Hdr[i].image,string1);
			}
			set_menu(Menu_Mouse_i,filenum);
			return(Num_Active_Image);
		}
		if(strcmpi(string1,"vector_sets")==0)
		{
			numread=fscanf(fp,"%s%s",string2,string3);
			if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
				numread<2)
			{
				printf("invalid 'vector_sets' format\n\n");
				exit(0);
			}
			sscanf(string3,"%d",&Vector);
			if(Vector<1||Vector>=NUM_TYPE)
			{
				printf("Invalid number of vector sets.\n");
				exit(0);
			}
			for(i=0;i<Vector;i++)
			{
				numread=fscanf(fp,"%s%s%s",Group_Name[i],string2,string3);
				if(strcmpi(string2,"end")==0||strcmpi(string3,"end")==0||
					numread<2)
				{
					printf("invalid 'vector_set' format at set %d\n\n",i+1);
					exit(0);
				}
				sscanf(string3,"%d",Ns+i);
				if(Ns[i]<1||Ns[i]>=NUM_SIZE)
				{
					printf("Invalid number of vectors.\n");
					exit(0);
				}
				for(j=0;j<Ns[i];j++)
				{
					numread=fscanf(fp,"%s%f%f%d",
						MapFile[i][j].filename,&MapFile[i][j].max_pix,
						&MapFile[i][j].min_pix,&MapFile[i][j].color);
					if(numread<4)
					{
						printf("invalid 'vector' format at set i=%d j=%d\n\n",
							i+1,j+1);
						exit(0);
					}
				}
			}
		}
	}
	set_menu(Menu_Mouse_i,filenum);
    if(fp) fclose(fp);
	return(status);
}

/***********************************************************************
**
**
**
**
************************************************************************/

int set_menu(struct menu m[],int num)

{
	int i,j,k;
	int grf;

	grf=load_names("*.grf");
	for(i=0;i<8;i++)
	{
		for(j=0;j<m[i].num_entry;j++)
		{
			m[i].menu[j].status=1;
			if(m[i].menu[j].ret=='c'&&Hdr[num].cap.lines<=0)
				m[i].menu[j].status=0;
			if(m[i].menu[j].ret=='l'&&(ProjType==0||grf==0))
				m[i].menu[j].status=0;
			if(m[i].menu[j].ret=='b'&&(ProjType==0||Vector==0))
                m[i].menu[j].status=0;
            if(m[i].menu[j].ret=='l'&&(MouseStat==0))
                m[i].menu[j].status=0;
        }
	}
}


/***********************************************************************
**
**		x,y in screen coordinates
**
**
************************************************************************/

int xy_ll(double x,double y,double *lat,double *lon)

{
	double nsample=(double)ZoomSample*-1.0+2.0;

	if(ZoomSample>0)
	{
		x=(double)Xc*(double)Sample+x*(double)ZoomSample;
		y=(double)Yc*(double)Sample+y*(double)ZoomSample;
	}
	else
	{
		x=(double)Xc*(double)Sample+x/nsample;
		y=(double)Yc*(double)Sample+y/nsample;
	}
	*lat=*lon=0.0;
    switch(ProjType)
	{
    case 'A':
		x=x*PixelSize+X0;
		y=Y0-y*PixelSize;
		axy_ll_e(x,y,lat,lon);
        return(1);
        break;
    case 'E':
        x=x*PixelSize+X0;
        y=Y0-y*PixelSize;
        txy_ll_e(x,y,lat,lon);
        return(1);
        break;
    case 'N':
        *lon=x*PixelSize+X0;
        *lat=Y0-y*PixelSize;
        return(1);
        break;
    default:
        break;
    }
	return(-1);
}

/***********************************************************************
**
**		x,y in screen coordinates
**
**
************************************************************************/

int ll_xy(double *x,double *y,double lat,double lon)

{
	double nsample=(double)ZoomSample*-1.0+2.0;

    switch(ProjType)
	{
    case 'A':
		all_xy_e(x,y,lat,lon);
		*x=(*x-X0)/PixelSize;
		*y=(Y0-*y)/PixelSize;	
		if(ZoomSample>0)
		{
			*x=(*x-(double)Xc*(double)Sample)/(double)ZoomSample;
			*y=(*y-(double)Yc*(double)Sample)/(double)ZoomSample;
		}
		else
		{
			*x=(*x-(double)Xc*(double)Sample)*nsample;
			*y=(*y-(double)Yc*(double)Sample)*nsample;
        }
        break;
    case 'E':
        tll_xy_e(x,y,lat,lon);
        *x=(*x-X0)/PixelSize;
        *y=(Y0-*y)/PixelSize;   
        if(ZoomSample>0)
        {
            *x=(*x-(double)Xc*(double)Sample)/(double)ZoomSample;
            *y=(*y-(double)Yc*(double)Sample)/(double)ZoomSample;
        }
        else
        {
            *x=(*x-(double)Xc*(double)Sample)*nsample;
            *y=(*y-(double)Yc*(double)Sample)*nsample;
        }
        break;
    case 'N':
        *x=lon;
        *y=lat;
        *x=(*x-X0)/PixelSize;
        *y=(Y0-*y)/PixelSize;   
        if(ZoomSample>0)
        {
            *x=(*x-(double)Xc*(double)Sample)/(double)ZoomSample;
            *y=(*y-(double)Yc*(double)Sample)/(double)ZoomSample;
        }
        else
        {
            *x=(*x-(double)Xc*(double)Sample)*nsample;
            *y=(*y-(double)Yc*(double)Sample)*nsample;
        }
        break;
    default:
        printf("ProjType = %s",ProjType);
        break;
    }
}


/***********************************************************************
**
**
**
**
************************************************************************/

int copy_hdr(int d,int s)

{
	int i,j,k;

	Hdr[d].row=Hdr[s].row;
	Hdr[d].col=Hdr[s].col;
	Hdr[d].sample=Hdr[s].sample;
	Hdr[d].record_bytes=Hdr[s].record_bytes;
	Hdr[d].file_records=Hdr[s].file_records;
	Hdr[d].record_col_header=Hdr[s].record_col_header;
	Hdr[d].row_col_header=Hdr[s].row_col_header;
	Hdr[d].header_bytes=Hdr[s].header_bytes;
	Hdr[d].imbedded_header=Hdr[s].imbedded_header;
	Hdr[d].sample_bits=Hdr[s].sample_bits;
	Hdr[d].pal_type=Hdr[s].pal_type;

	strcpy(Hdr[d].infile,Hdr[s].infile);
	strcpy(Hdr[d].image,Hdr[s].image);
	strcpy(Hdr[d].Lut,Hdr[s].Lut);
	strcpy(Hdr[d].label,Hdr[s].label);

	for(i=0;i<256;i++)
	{
		Hdr[d].vga_color[i]=Hdr[s].vga_color[i];

		Hdr[d].lut[i].r=Hdr[s].lut[i].r;
		Hdr[d].lut[i].g=Hdr[s].lut[i].g;
		Hdr[d].lut[i].b=Hdr[s].lut[i].b;
		Hdr[d].lutm[i].r=Hdr[s].lutm[i].r;
		Hdr[d].lutm[i].g=Hdr[s].lutm[i].g;
		Hdr[d].lutm[i].b=Hdr[s].lutm[i].b;
		Hdr[d].lutc[i].r=Hdr[s].lutc[i].r;
		Hdr[d].lutc[i].g=Hdr[s].lutc[i].g;
		Hdr[d].lutc[i].b=Hdr[s].lutc[i].b;
	}
}

/********************************************************************
**
**	type  g -- grey all lut[] files
**			G -- grey only lut[]
**			i -- initial header map
**			r -- reset lut[] to lutc[]
**			p -- positive (0-127) magenta, negative (128-255) green
**
********************************************************************* */

int set_lut(char type,char *filename)

{
	int i,k,hue,brite,j;
	int r,g,b;
	float color[3];
	double dbrite,dval;
	float val,minval,sat,inten;
	float fval,fk;
	FILE *fplut;
	int end=0,scale,sum;
	char string[100];
	long del,mindel,l1,l2,l3,l4,L1,L2,L3;

	scale=1;
	if(Num_Color==16)
		scale=17;
	for(k=0;k<Num_Color;k++)
	{
		Hdr[Img].lut[k].r=k*scale;
		Hdr[Img].lut[k].g=k*scale;
		Hdr[Img].lut[k].b=k*scale;
	}
	ActiveLut='G';
	if(type=='P')
	{
		fplut=open_to_read_text(filename);
		if(fplut)
		{
			i=0;
			do
			{
				i+=1;
				fscanf(fplut,"%s",string);
			}while(strcmpi(string,"end")!=0&&i<50);
			if(strcmpi(string,"end")!=0)
				rewind(fplut);
			for(i=0;i<256;i++)
			{
				fscanf(fplut,"%d%d%d%d",&k,&r,&g,&b);
				Hdr[Img].lut[i].r=r;
				Hdr[Img].lut[i].g=g;
				Hdr[Img].lut[i].b=b;
			}
            if(fplut) fclose(fplut);
		}
		else
			return(-1);
		if(VideoType=='V'||VideoType=='E')
		{
			for(i=0;i<256;i++)
			{
				sum=(int)Hdr[Img].lut[i].r*10;
				sum+=(int)Hdr[Img].lut[i].g*8;
				sum+=(int)Hdr[Img].lut[i].b*2;
				sum/=319;
				Hdr[Img].vga_color[i]=sum;
			}
			for(k=0;k<Num_Color;k++)
			{
				Hdr[Img].lut[k].r=k*scale;
				Hdr[Img].lut[k].g=k*scale;
				Hdr[Img].lut[k].b=k*scale;
			}
		}
		ActiveLut='P';
	}
	if(type=='g')
	{
		for(k=0;k<Num_Color;k++)
		{
			Hdr[Img].lutc[k].r=Hdr[Img].lut[k].r=k*scale;
			Hdr[Img].lutc[k].g=Hdr[Img].lut[k].g=k*scale;
			Hdr[Img].lutc[k].b=Hdr[Img].lut[k].b=k*scale;
		}
		ActiveLut='g';
	}
	if(type=='G')
	{
		for(k=0;k<Num_Color;k++)
		{
			Hdr[Img].lut[k].r=k*scale;
			Hdr[Img].lut[k].g=k*scale;
			Hdr[Img].lut[k].b=k*scale;
		}
		ActiveLut='G';
	}
	if(type=='i')
	{
		for(k=0;k<Num_Color;k++)
		{
			Hdr[Img].lutc[k].r=Hdr[Img].lut[k].r=k*scale;
			Hdr[Img].lutc[k].g=Hdr[Img].lut[k].g=k*scale;
			Hdr[Img].lutc[k].b=Hdr[Img].lut[k].b=k*scale;
		}
		Hdr[Img].lut[ 64].r=  0;Hdr[Img].lut[ 64].g=  0;Hdr[Img].lut[ 64].b=128;
		Hdr[Img].lut[127].r=  0;Hdr[Img].lut[127].g=100;Hdr[Img].lut[127].b=  0;
		Hdr[Img].lut[191].r=255;Hdr[Img].lut[191].g=  0;Hdr[Img].lut[191].b=  0;
		Hdr[Img].lut[192].r=255;Hdr[Img].lut[192].g=128;Hdr[Img].lut[192].b=  0;
		Hdr[Img].lut[193].r=255;Hdr[Img].lut[193].g=255;Hdr[Img].lut[193].b=  0;
		Hdr[Img].lut[194].r=  0;Hdr[Img].lut[194].g=255;Hdr[Img].lut[194].b=  0;
		Hdr[Img].lut[195].r=  0;Hdr[Img].lut[195].g=255;Hdr[Img].lut[195].b=255;
		Hdr[Img].lut[196].r= 20;Hdr[Img].lut[196].g= 55;Hdr[Img].lut[196].b=255;
		Hdr[Img].lut[253].r=100;Hdr[Img].lut[253].g=  1;Hdr[Img].lut[253].b=  1;
		Hdr[Img].lut[254].r=100;Hdr[Img].lut[254].g=  1;Hdr[Img].lut[254].b=  1;
		ActiveLut='i';
	}
	if(type=='r')
	{
		for(k=0;k<Num_Color;k++)
		{
			Hdr[Img].lut[k].r=Hdr[Img].lutc[k].r;
			Hdr[Img].lut[k].g=Hdr[Img].lutc[k].g;
			Hdr[Img].lut[k].b=Hdr[Img].lutc[k].b;
		}
		ActiveLut='r';
	}
	mindel=16777216;
	for(i=0;i<Num_Color;i++)
	{
		l1=Blk.r;
		l2=Hdr[Img].lut[i].r;
		l3=Hdr[Img].lut[i].g;
		l4=Hdr[Img].lut[i].b;
		del=(l1-l2)*(l1-l2)+(l1-l3)*(l1-l3)+(l1-l4)*(l1-l4);
		if(del<mindel)
		{
			mindel=del;
			Black=i;
		}
	}
	mindel=16777216;
	for(i=0;i<Num_Color;i++)
	{
		l1=D_G.r;
		l2=Hdr[Img].lut[i].r;
		l3=Hdr[Img].lut[i].g;
		l4=Hdr[Img].lut[i].b;
		del=(l1-l2)*(l1-l2)+(l1-l3)*(l1-l3)+(l1-l4)*(l1-l4);
		if(del<mindel)
		{
			mindel=del;
			D_Grey=i;
		}
	}
	mindel=16777216;
	for(i=0;i<Num_Color;i++)
	{
		l1=M_G.r;
		l2=Hdr[Img].lut[i].r;
		l3=Hdr[Img].lut[i].g;
		l4=Hdr[Img].lut[i].b;
		del=(l1-l2)*(l1-l2)+(l1-l3)*(l1-l3)+(l1-l4)*(l1-l4);
		if(del<mindel)
		{
			mindel=del;
			M_Grey=i;
		}
	}
	mindel=16777216;
	for(i=0;i<Num_Color;i++)
	{
		l1=L_G.r;
		l2=Hdr[Img].lut[i].r;
		l3=Hdr[Img].lut[i].g;
		l4=Hdr[Img].lut[i].b;
		del=(l1-l2)*(l1-l2)+(l1-l3)*(l1-l3)+(l1-l4)*(l1-l4);
		if(del<mindel)
		{
			mindel=del;
			L_Grey=i;
		}
	}
	mindel=16777216;
	for(i=0;i<Num_Color;i++)
	{
		l1=Wht.r;
		l2=Hdr[Img].lut[i].r;
		l3=Hdr[Img].lut[i].g;
		l4=Hdr[Img].lut[i].b;
		del=(l1-l2)*(l1-l2)+(l1-l3)*(l1-l3)+(l1-l4)*(l1-l4);
		if(del<mindel)
		{
			mindel=del;
			White=i;
		}
	}
	mindel=16777216;
	for(i=0;i<Num_Color;i++)
	{
		L1=Rd.r;
		L2=Rd.g;
		L3=Rd.b;
		l1=Hdr[Img].lut[i].r;
		l2=Hdr[Img].lut[i].g;
		l3=Hdr[Img].lut[i].b;
		del=(l1-L1)*(l1-L1)+(l2-L2)*(l2-L2)+(l3-L3)*(l3-L3);
		if(del<mindel)
		{
			mindel=del;
			Red=i;
		}
	}
	mindel=16777216;
	for(i=0;i<Num_Color;i++)
	{
        L1=Cn.r;
        L2=Cn.g;
        L3=Cn.b;
		l1=Hdr[Img].lut[i].r;
		l2=Hdr[Img].lut[i].g;
		l3=Hdr[Img].lut[i].b;
		del=(l1-L1)*(l1-L1)+(l2-L2)*(l2-L2)+(l3-L3)*(l3-L3);
		if(del<mindel)
		{
			mindel=del;
			Cyan=i;
		}
	}
	WritePalette(Hdr[Img].lut);
	return(1);
}

/********************************************************************
**
**     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 M_do_menu(char *menu[],
		int num,int xc,int yc,int start,int back,int words,int boxs,
		int font[128][25])

{
	int i,j,k;
	char ans=-1,ans2;
	int len=0,l,size=FontSize,val,kval,valo=-1,kbh=0;
	int black=0,dgrey=back,lgrey=words,white=boxs;
	int wide;
	long lxs,lys,buffersize=(long)B_LINES*(long)MAX_X;
	int io=-1,times,jo=-1;
	int row,col,right,left;
	int rowo=-1,colo=-1;
	int top=yc,bot=yc+num*(30/size)-1;
	unsigned char *mbuff;

	mbuff=(unsigned char *)malloc((size_t)buffersize);
	if(mbuff==NULL)
	{
		SetVideoMode(0);
		printf("malloc failed making buffer[%d]\n\n",i);
		printf("You do not have enough free memory to use this option.\n\n");
        printf("Hit <Esc> key or right mouse button to return to menu\n");
/*        exit(0);*/
        return(999);
	}

	for(k=0;k<num;k++)
		if((l=strlen(menu[k]))>len)len=l;
	if(len==0)
	{
		free(mbuff);
		return(-1);
	}
	do
	{
		wide=(len+1)*15/size+1;
		if((ScreenXs-1-wide)<xc)xc=ScreenXs-1-wide;
		lxs=(len+1)*15/size+1;
		lys=30/size*num+1;
		if(lxs*lys>buffersize)
			size+=1;
		if(size>4)
		{
			SetVideoMode(0);			
			printf("Could not fit menu into buffer for 'save_box()'\n");
			exit(0);
		}
	}while(lxs*lys>buffersize);
	if((xc+(len+1)*15/size+1)<ScreenXs)
	{
		if(Mouse>0)
		{
			MouseMove=1;
			mouse_vertical_range(yc,yc+num*(30/size)-1);
			mouse_horizontal_range(xc,xc+(len+1)*15/size);
		}
		save_box(0,dgrey,mbuff,
			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,lgrey,(len+1)*15/size,30/size*num);
		val=valo=start;
		box(0,xc,yc+val*(30/size),white,(len+1)*15/size,30/size);
		if(Mouse==0)
		{
			do
			{
				if((ans=getch())==0)
				{
					ans2=getch();
					if(ans2==50)
					{
						unsave_box(0,dgrey,mbuff,
							xc,yc,(len+1)*15/size+1,30/size*num+1);
						getch();
						paint_box(0,dgrey,Mbuff,
							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;
					}
				box(0,xc,yc+valo*(30/size),dgrey,(len+1)*15/size,30/size);
				valo=val;
				box(0,xc,yc,lgrey,(len+1)*15/size,30/size*num);
				box(0,xc,yc+val*(30/size),white,(len+1)*15/size,30/size);
				if(ans==27)
				{
					val=num-1;
					ans=13;
				}
			}while(ans!=13);
		}
		else
		{
			mouse_times_released(LEFT_BUTTON,&times,&row,&col);
			mouse_times_released(RIGHT_BUTTON,&times,&row,&col);
			kbh=0;
			if((kval=mouse_information(&right,&left,&row,&col))!=0)
			{
				kbh=1;
				if(kval>255)
				{
					kval/=256;
					if(kval==72)
						row-=30/size;
					if(kval==80)
						row+=30/size;
					if(row<top)row=top;
					if(row>bot)row=bot;
					mouse_move_cursor(row,col);
				}
			}
			colo=col;
			rowo=row;	
			do
			{
				kbh=0;
				if((kval=mouse_information(&right,&left,&row,&col))!=0)
				{
					kbh=1;
					if(kval>255)
					{
						kval/=256;
						if(kval==72)
							row-=30/size;	
						if(kval==80)
							row+=30/size;
						if(row<top)row=top;
						if(row>bot)row=bot;
						mouse_move_cursor(row,col);
					}
				}
				if(row!=rowo||col!=colo)
				{
					colo=col;
					rowo=row;
				}
				val=row-yc;
				val/=30/size;
				if(val!=valo)
				{
					box(0,xc,yc+valo*(30/size),dgrey,(len+1)*15/size,30/size);
					valo=val;
					box(0,xc,yc,lgrey,(len+1)*15/size,30/size*num);
					box(0,xc,yc+val*(30/size),white,(len+1)*15/size,30/size);
				}
				if(left>0)
				{
					if(kbh==0)
						do
						{
							mouse_times_released(LEFT_BUTTON,&times,&row,&col);
						}while(times==0);
						ans=13;
				}
				if(right>0)
				{
					val=num-1;
					ans=13;
					if(kbh==0)
						do
						{
							mouse_times_released(RIGHT_BUTTON,&times,&row,&col);
						}while(times==0);
				}
			}while(ans!=13);
			MouseMove=4;
			mouse_vertical_range(0,ScreenYs-1);
			mouse_horizontal_range(0,ScreenXs-1);
		}
	}
	box(0,xc,yc,dgrey,(len+1)*15/size,30/size*num);
	box(0,xc,yc+val*(30/size),lgrey,(len+1)*15/size,30/size);
	unsave_box(0,dgrey,mbuff,
			xc,yc,(len+1)*15/size+1,30/size*num+1);
	free(mbuff);
	return(val);
}

/********************************************************************
**
**     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(char *menu[],int num,int xc,int yc,
		int start,int back,int words,int 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 save_sub_mem(int xc,int yc,int xs,int 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(int xc,int yc,int xs,int ys)

{
	int i,j,k;

	for(i=0;i<ys;i++)
		plotrow(3,xc,xc+xs-1,i+yc,Mbuff+xs*i);
}

/**************************************************************************
**
**
**
************************************************************************* */

char fsplit(char *instring,char *path,char *name,char *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[STR_LEN];

	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 *open_to_write_digit(char *name,int color)

{
    int i,j,k,num,xc,yc,xs,ys;
    int colo,rowo,col,row;
    double x,y;
    float Lat,Lon;
    long lsecnum;
	FILE *fp;
    char string[STR_LEN],string1[STR_LEN],String[2][1000];

	for(j=0;j<NumPath;j++)
	{
		sprintf(string,"%s%s",Path[j],name);
        if((fp=fopen(string,"r")) != NULL)
        {
            fclose(fp);
            strcpy(string1,string);
            strcat(string1," exists");
            xc=yc=5;
            ys=20;xs=(strlen(string1)+2)*7;
            save_sub_mem(xc,yc,xs,ys);
            paint_box(0,D_Grey,Buffer,xc,yc,xs,ys);
            plot_font_h(White,xc+7,yc+4,string1,2,Font);
            num=M_do_menu(menu_d,MENU_D,xs,xc,num,D_Grey,L_Grey,White,Font);
            recall_sub_mem(xc,yc,xs,ys);
            if(num==0)
            {
                fp=fopen(string,"rt");
                while((k=fscanf(fp,"%ld",&lsecnum))>0)
/*                fscanf(fp,"%ld",&lsecnum);*/
                {
/*                    printf("%d\n",lsecnum);*/
                    k=fscanf(fp,"%s%s",String[0],String[1]);
/*                    printf("%s\n%s\n",String[0],String[1]);*/
                    sscanf(String[0],"%f",&Lat);
                    sscanf(String[1],"%f",&Lon);
/*                    printf("%f %f\n",Lat,Lon);*/
                    ll_xy(&x,&y,Lat,Lon);
/*                    printf("%d %d %d %d\n",x,y,Lat,Lon);*/
                    colo=(int)x;
                    rowo=(int)y;
                    if(String[1] [strlen(String[1])-1]!='/')
                    {
                        do
                        {
                            k=fscanf(fp,"%s%s",String[0],String[1]);
                            sscanf(String[0],"%f",&Lat);
                            sscanf(String[1],"%f",&Lon);
                            ll_xy(&x,&y,Lat,Lon);
/*                    printf("%d %d %d %d\n",x,y,Lat,Lon);*/
                            col=(int)x;
                            row=(int)y;
                            plotln(0,colo,rowo,col,row,color);
                            colo=col;
                            rowo=row;
                        }while(String[1][strlen(String[1])-1]!='/');
                    }
                }
                fclose(fp);
                fp=fopen(string,"at");
            }
            if(num==1)
                fp=fopen(string,"wt");
            if(num==2)
                fp=NULL;
        }
        else
            fp=fopen(string,"wt");
		if(fp)
		{
			strcpy(LastFile,name);
			return(fp);
		}
	}
	clearerr(fp);
	fp=NULL;
	return(fp);
}

/***********************************************************************
**
**
**
**
************************************************************************/

FILE *open_to_write_text(char *name)

{
	int i,j,k;
	FILE *fp;
	char string[STR_LEN];

	for(j=0;j<NumPath;j++)
	{
		sprintf(string,"%s%s",Path[j],name);
		fp=fopen(string,"wt");
		if(fp)
		{
			strcpy(LastFile,name);
			return(fp);
		}
	}
	clearerr(fp);
	fp=NULL;
	return(fp);
}

/***********************************************************************
**
**
**
**
************************************************************************/

FILE *open_to_read_text(char *name)

{
	int i,j,k;
	FILE *fp;
	char string[STR_LEN];

	for(j=0;j<NumPath;j++)
	{
		sprintf(string,"%s%s",Path[j],name);
		fp=fopen(string,"rt");
		if(fp)
		{
			strcpy(LastFile,name);
			return(fp);
		}
	}
	clearerr(fp);
	fp=NULL;
	return(fp);
}

/***********************************************************************
**
**
**
**
************************************************************************/

FILE *open_to_write_binary(char *name)

{
	int i,j,k;
	FILE *fp;
	char string[STR_LEN];

	for(j=0;j<NumPath;j++)
	{
		sprintf(string,"%s%s",Path[j],name);
		fp=fopen(string,"wb");
		if(fp)
		{
			strcpy(LastFile,name);
			return(fp);
		}
	}
	clearerr(fp);
	fp=NULL;
	return(fp);
}


/***********************************************************************
**
**
**
**
************************************************************************/

FILE *open_to_read_binary(char *name)

{
	int i,j,k;
	FILE *fp;
	char string[STR_LEN];
	int len;

	string[0]='\0';
	for(j=0;j<NumPath;j++)
	{
		len=strlen(Path[j])+strlen(name);
		if(len>0&&len<STR_LEN);
		{
			sprintf(string,"%s%s",Path[j],name);
			fp=fopen(string,"rb");
			if(fp)
			{
				strcpy(LastFile,name);
				return(fp);
			}	
		}
	}
	clearerr(fp);
	fp=NULL;
	return(fp);
}
int save_vectors()
{
    int k,row,col,rowo,colo,right,left,color;
    char string[100],name[100];
    FILE *fraw;
    double lat,lon;
    if(ProjType==0) return(0);
        get_string(string,Mbuff,"Color index:","(0-255)",0,0,150,65,1,1,Font,White);
        sscanf(string,"%d",&color);
    get_string(string,Mbuff,"Output File prefix:","",0,0,150,47,1,1,Font,White);
    for(k=0;k<strlen(string);k++)
        if(string[k]=='.')
            string[k]='\0';
    sprintf(name,"%s.raw",string);
/*    printf("%s",name);*/
    fraw=open_to_write_digit(name,color);
    if(fraw)
    {
        mouse_move_cursor(ScreenYs/2,ScreenXs/2);
        do
        {
            rowo=-1;
            do
            {
                mouse_get_point(&right,&left,&row,&col,BUTTON_UP);
                if(right==0)
                {
                    if(rowo==-1)
                        fprintf(fraw,"1");
                    if(rowo>=0)
                        plotln(0,colo,rowo,col,row,color);
                    rowo=row;
                    colo=col;
                    xy_ll((double)col,(double)row,&lat,&lon);
                    fprintf(fraw,"\n %9.5lf %10.5lf",lat,lon);
                }
            }while(right==0);
            if(rowo>=0)
                fprintf(fraw,"//\n");
        }while(rowo>=0);
        fclose(fraw);
    }
}


