1(Message /usr/users/bradley/Mail/inbox:28)
2Return-Path: tmb@ai.mit.edu
3Received-Date: Wed, 13 Nov 91 07:27:59 EST
4Received: from life.ai.mit.edu by central.cis.upenn.edu
5	id AA18349; Wed, 13 Nov 91 07:27:57 -0500
6Posted-Date: Wed, 13 Nov 91 07:24:28 EST
7Received: from bambleweenie57 (bambleweenie57.ai.mit.edu) by life.ai.mit.edu (4.1/AI-4.10) id AA24831; Wed, 13 Nov 91 07:27:53 EST
8From: tmb@ai.mit.edu (Thomas M. Breuel)
9Received: by bambleweenie57 (4.1/AI-4.10) id AA05108; Wed, 13 Nov 91 07:24:28 EST
10Date: Wed, 13 Nov 91 07:24:28 EST
11Message-Id: <9111131224.AA05108@bambleweenie57>
12To: bradley@central.cis.upenn.edu
13Subject: simple VIS format reader for "xv"
14
15Below you find a "shar" file containing code for reading the two most
16common types of VIS format images: 8bit unsigned and machine-dependent
17single precision floating point. Also included are patches necessary
18to add this reading function to "xv".
19
20VIS format is a simple, flexible image format that has originated here
21at the AI lab and that is used by several vision research labs for
22storing and displaying images. It consists of header lines of the form
23"name=value" followed by a line containing a form-feed as the first
24character, followed by the raw image data.  The lines "DIMS=" and
25"ETYPE=" specify the dimensions of the image and the type of the
26binary data. Later header lines override earlier header lines, which
27makes it possible to keep a history in the header.
28
29I'd appreciate if you could include this in the next version of "xv".
30Eventually, I may send you a nicer version, but this version seems to
31be working.
32
33					Thanks, Thomas.
34
35# This is a shell archive.  Remove anything before this line,
36# then unpack it by saving it in a file and typing "sh file".
37#
38# Wrapped by volterra!tmb on Wed Nov 13 06:59:43 EST 1991
39# Contents:  xvvis.c xvvis.diffs
40
41echo x - xvvis.c
42sed 's/^@//' > "xvvis.c" <<'@//E*O*F xvvis.c//'
43/*
44 * xvvis.c - load routine for 'vis' format pictures
45 *
46 * LoadVIS(fname, numcols)  -  loads a VIS pic, does 24to8 code if nec.
47 * WriteVIS(fp, pic, w, h, r,g,b, numcols, style)
48 * WriteRaw(fp, pic, w, h, r,g,b, numcols, style)
49 */
50
51#include "xv.h"
52
53static int VISError();
54
55int LoadVIS(fname,nc)
56char *fname;
57int   nc;
58{
59	FILE  *fp;
60	char buf[1000];
61	int w=-1,h=-1;
62	char etype[100];
63	int raster=getenv("VIS_RASTER")&&atoi(getenv("VIS_RASTER"));
64
65	fp=fopen(fname,"r");
66	if (!fp) return VISError("unable to open file");
67
68	while(fgets(buf,sizeof buf,fp)) {
69		if(!buf[0]||buf[0]=='\n'||buf[0]=='\f') break;
70		sscanf(buf,"DIMS=%d %d",&w,&h);
71		sscanf(buf,"ETYPE=%s",etype);
72	}
73
74	if(w<0||h<0) {fclose(fp); return VISError("bad format");}
75
76	pWIDE=w; pHIGH=h;
77	{int i; for(i=0;i<256;i++) r[i]=g[i]=b[i]=i;}
78
79	if(!strcmp(etype,"uchar")) {
80		int i,j;
81		pic=(unsigned char*)malloc(w*h);
82		if(!pic) {fclose(fp); return VISError("cannot allocate enough memory");}
83		if(!raster) for(i=0;i<w;i++) for(j=0;j<h;j++) pic[i+(h-j-1)*w]=getc(fp);
84		else for(j=0;j<h;j++) for(i=0;i<w;i++) pic[i+j*w]=getc(fp);
85	} else if(!strcmp(etype,"float")) {
86		int i,j,n;
87		float min=1e38,max=-1e38;
88		float *t;
89		t=(float*)malloc(w*h*sizeof *t);
90		if(!t) {fclose(fp); return VISError("cannot allocate enough memory");}
91		pic=(unsigned char*)malloc(w*h);
92		if(!pic) {free(t); fclose(fp); return VISError("cannot allocate enough memory");}
93		fread(t,sizeof *t,w*h,fp);
94		n=w*h;
95		for(i=0;i<n;i++) {if(t[i]<min) min=t[i]; if(t[i]>max) max=t[i];}
96		if(max==min) max=min+1.0;
97		if(!raster) for(i=0;i<w;i++) for(j=0;j<h;j++) pic[i+(h-j-1)*w]=255*(t[i*h+j]-min)/(max-min);
98		else for(i=0;i<w;i++) for(j=0;j<h;j++) pic[i+j*w]=255*(t[i+j*w]-min)/(max-min);
99		free(t);
100	} else {close(fp); return VISError("unknown ETYPE");}
101
102	fclose(fp);
103	return 0;
104}
105
106static int VISError(st)
107char *st;
108{
109	SetISTR(ISTR_WARNING,"LoadVIS() - %s",cmd,st);
110	Warning();
111	return -1;
112}
113@//E*O*F xvvis.c//
114chmod u=rw,g=r,o=r xvvis.c
115
116echo x - xvvis.diffs
117sed 's/^@//' > "xvvis.diffs" <<'@//E*O*F xvvis.diffs//'
118diff -c xv.orig/Imakefile xv/Imakefile
119*** xv.orig/Imakefile	Wed Nov 13 05:55:55 1991
120--- xv/Imakefile	Wed Nov 13 06:23:48 1991
121***************
122*** 108,118 ****
123
124  SRCS1 =	xv.c xv24to8.c xvbutt.c xvctrl.c xvdir.c xvfish.c xvgam.c\
125  	xvgif.c xvgifwr.c xvinfo.c xvmisc.c xvpbm.c xvpm.c xvscrl.c\
126! 	xvxbm.c vprintf.c xvjpeg.c
127
128  OBJS1 =	xv.o xv24to8.o xvbutt.o xvctrl.o xvdir.o xvfish.o xvgam.o\
129  	xvgif.o xvgifwr.o xvinfo.o xvmisc.o xvpbm.o xvpm.o xvscrl.o \
130! 	xvxbm.o vprintf.o xvjpeg.o $(JOBJS)
131
132  SRCS2=	bggen.c
133  OBJS2=	bggen.o
134--- 108,118 ----
135
136  SRCS1 =	xv.c xv24to8.c xvbutt.c xvctrl.c xvdir.c xvfish.c xvgam.c\
137  	xvgif.c xvgifwr.c xvinfo.c xvmisc.c xvpbm.c xvpm.c xvscrl.c\
138! 	xvxbm.c vprintf.c xvjpeg.c xvvis.c
139
140  OBJS1 =	xv.o xv24to8.o xvbutt.o xvctrl.o xvdir.o xvfish.o xvgam.o\
141  	xvgif.o xvgifwr.o xvinfo.o xvmisc.o xvpbm.o xvpm.o xvscrl.o \
142! 	xvxbm.o vprintf.o xvjpeg.o $(JOBJS) xvvis.o
143
144  SRCS2=	bggen.c
145  OBJS2=	bggen.o
146diff -c xv.orig/xv.c xv/xv.c
147*** xv.orig/xv.c	Wed Nov 13 05:56:12 1991
148--- xv/xv.c	Wed Nov 13 06:22:39 1991
149***************
150*** 54,59 ****
151--- 54,60 ----
152  #define PBM     3
153  #define XBM     4
154  #define JFIF    5
155+ #define VIS 6
156
157  static unsigned long rootbg, rootfg;  /* fg/bg for root border */
158  static int    waitsec = -1;     /* seconds between pics. -1=wait for event */
159***************
160*** 784,789 ****
161--- 785,792 ----
162
163    else if (strncmp(magicno,"#define",7)==0) filetype = XBM;
164
165+   else if (strncmp(magicno,"VISF",4)==0) filetype = VIS;
166+
167    if (filetype == UNKNOWN) {
168      SetISTR(ISTR_INFO,"'%s' not in a recognized format.", basename);
169      Warning();
170***************
171*** 798,803 ****
172--- 801,807 ----
173    case PBM:  i = LoadPBM (filename,ncols); break;
174    case XBM:  i = LoadXBM (filename,ncols); break;
175    case JFIF: i = LoadJFIF(filename,ncols); break;
176+   case VIS: i= LoadVIS(filename,ncols); break;
177    }
178    WaitCursor();
179
180@//E*O*F xvvis.diffs//
181chmod u=rw,g=rw,o=r xvvis.diffs
182
183exit 0
184
185Return-Path: tmb@ai.mit.edu
186Received-Date: Fri, 15 Nov 91 15:40:42 EST
187Received: from life.ai.mit.edu by central.cis.upenn.edu
188	id AA29972; Fri, 15 Nov 91 15:40:34 -0500
189Posted-Date: Fri, 15 Nov 91 15:36:41 EST
190Received: from bambleweenie57 (bambleweenie57.ai.mit.edu) by life.ai.mit.edu (4.1/AI-4.10) id AA21156; Fri, 15 Nov 91 15:40:10 EST
191From: tmb@ai.mit.edu (Thomas M. Breuel)
192Received: by bambleweenie57 (4.1/AI-4.10) id AA09661; Fri, 15 Nov 91 15:36:41 EST
193Date: Fri, 15 Nov 91 15:36:41 EST
194Message-Id: <9111152036.AA09661@bambleweenie57>
195To: bradley@central.cis.upenn.edu
196Subject: VIS support for xv
197
198I added file saving. Here is a shar file with the files that I touched.
199I'd appreciate if this made it into the next release of xv.
200
201				Thanks, Thomas.
202
203
204# This is a shell archive.  Remove anything before this line,
205# then unpack it by saving it in a file and typing "sh file".
206#
207# Wrapped by  on Fri Nov 15 15:35:17 EST 1991
208# Contents:  xv.h xvdir.c xvvis.c
209
210echo x - xv.h
211sed 's/^@//' > "xv.h" <<'@//E*O*F xv.h//'
212/*
213 *  xv.h  -  header file for xv, but you probably guessed as much
214 */
215
216/*
217 * Copyright 1989, 1990 by the University of Pennsylvania
218 *
219 * Permission to use, copy, and distribute for non-commercial purposes,
220 * is hereby granted without fee, providing that the above copyright
221 * notice appear in all copies and that both the copyright notice and this
222 * permission notice appear in supporting documentation.
223 *
224 * The software may be modified for your own purposes, but modified versions
225 * may not be distributed.
226 *
227 * This software is provided "as is" without any express or implied warranty.
228 */
229
230#define REVDATE   "Rev: 11/29/90  (Patchlevel 3)"
231
232#ifdef SVR4             /* SysV release 4 uses dirent */
233#ifndef sgi             /* but Silicon Graphics doesn't */
234#define DIRENT
235#endif
236#endif
237
238
239/* include files */
240#include <stdio.h>
241#include <math.h>
242#include <ctype.h>
243#include <string.h>
244extern int   errno;             /* this SHOULD be in errno.h */
245extern char *sys_errlist[];     /* this SHOULD be in errno.h */
246
247#ifndef __convexc__             /* Convex doesn't have <memory.h> */
248#include <memory.h>             /* for 'memset()' prototype */
249#endif
250
251/* neither IBM AOS 4.3, Convex, nor BSD 4.3 on VAX have <malloc.h> */
252#if !defined(ibm032) && !defined(__convexc__) && \
253    !(defined(vax) && !defined(ultrix))
254#if defined(hp300) || defined(hp800)
255#include <sys/malloc.h>                /* it's in 'sys' on HPs*/
256#else
257#include <malloc.h>
258#endif
259#endif
260
261
262#if defined(NEED_MEMROUTINES)
263#define memcpy(d,s,l) bcopy(s,d,l)
264#endif
265
266
267#include <X11/Xos.h>
268#include <X11/Xlib.h>
269#include <X11/Xutil.h>
270#include <X11/cursorfont.h>
271#include <X11/keysym.h>
272
273
274#if defined(NEEDSTIME) || defined(NEEDSDIR)
275#include <sys/types.h>    /* only include <sys/types.h> once */
276#endif
277
278#ifdef NEEDSTIME
279#ifndef sgi              /* silicon graphics doesn't have timeb.h */
280#include <sys/timeb.h>
281#endif
282#undef SIGCHLD
283#include <signal.h>
284#if defined(sco) && !defined(NOTIMER)
285#include <sys/itimer.h>
286#endif
287#ifndef  sigmask
288#define  sigmask(m)      (1 << ((m)-1))
289#endif
290#endif
291
292#ifdef NEEDSDIR
293#ifndef HPUX
294#ifdef sco
295#include <sys/ndir.h>
296#define lstat stat
297#else
298#ifndef ATT
299#include <sys/dir.h>
300#endif  /* ATT */
301#endif  /* sco */
302#endif  /* not HPUX */
303#include <sys/param.h>
304#include <sys/stat.h>
305#ifdef DIRENT
306#include <dirent.h>
307#endif
308#endif
309
310#ifdef NEEDSVARARGS
311#include <varargs.h>
312#endif
313
314/* signal macros */
315#ifdef SVR4
316#define HOLD_SIG         sighold(SIGALRM)  /* block ALRM sig from occurring */
317#define RELEASE_SIG      sigrelse(SIGALRM) /* */
318#define PAUSE_SIG        sigpause(SIGALRM) /* sleep until ALRM signal */
319#else
320#define HOLD_SIG         sigblock(sigmask(SIGALRM))
321#define RELEASE_SIG      sigblock(0)
322#define PAUSE_SIG        sigpause(0)
323#endif
324
325
326#ifdef i386
327#define MAXPATHLEN    500
328#define UNCOMPRESS    "/usr/local/bin/uncompress"   /* uncompress program */
329#undef  HOLD_SIG
330#define HOLD_SIG      /* don't know how to handle signals  MWS 10/18/90 */
331#undef  RELEASE_SIG
332#define RELEASE_SIG   /* */
333#undef  PAUSE_SIG
334#define PAUSE_SIG     /* */
335#else
336#define UNCOMPRESS "/usr/ucb/uncompress"   /* for uncompressing .Z files */
337#endif
338
339#define PROGNAME  "xv"             /* used in resource database */
340
341#define DEFINFOGEOM "-10+10"       /* default position of info window */
342#define DEFDIRGEOM  "-10-10"       /* default position of directory window */
343#define DEFCTRLGEOM "+400+400"     /* default position of ctrl window */
344#define DEFGAMGEOM  "+10-10"       /* default position of gamma window */
345
346#define INFOWIDE 500               /* (fixed) size of info window */
347#define INFOHIGH 250
348
349#define CTRLWIDE 440               /* (fixed) size of control window */
350#define CTRLHIGH 295
351
352#define DIRWIDE  300               /* (fixed) size of directory window */
353#define DIRHIGH  438
354
355#define GAMWIDE  366               /* (fixed) size of Gamma window */
356#define GAMHIGH  356
357
358#define MAXNAMES 1024   /* max # of files (more than this?  Get REAL!)
359
360/* strings in the INFOBOX (used in SetISTR and GetISTR) */
361#define NISTR         9    /* number of ISTRs */
362#define ISTR_INFO     0
363#define ISTR_WARNING  1
364#define ISTR_FILENAME 2
365#define ISTR_FORMAT   3
366#define ISTR_RES      4
367#define ISTR_CROP     5
368#define ISTR_EXPAND   6
369#define ISTR_COLOR    7
370#define ISTR_COLOR2   8
371
372/* potential values of 'infomode', used in info box drawing routines */
373#define INF_NONE 0    /* empty box */
374#define INF_STR  1    /* just ISTR_INFO */
375#define INF_PART 2    /* filename, format, size and infostr */
376#define INF_FULL 3    /* INF_PART + clipping, expansion, colorinfo */
377
378
379/* buttons in the ctrl window */
380#define NBUTTS  20
381#define BNEXT   0
382#define BPREV   1
383#define BCROP   2
384#define BUNCROP 3
385#define BNORM   4
386#define BMAX    5
387#define BUP2    6
388#define BDN2    7
389#define BUP10   8
390#define BDN10   9
391#define BQUIT   10
392#define B4BY3   11
393#define BSAVE   12
394#define BROTL   13
395#define BINFO   14
396#define BGAMMA  15
397#define BASPECT 16
398#define BROTR   17
399#define BMAXPECT 18
400#define BACROP   19
401
402/* buttons in the 'save' window */
403#define S_NBUTTS 4
404#define S_BOPEN  0
405#define S_BSAVE  1
406#define S_BCANC  2
407#define S_BQUIT  3
408
409
410/* buttons in the 'gamma' window */
411#define G_NBUTTS  17
412#define G_BAPPLY  0
413#define G_BNOGAM  1
414#define G_BRESET  2
415#define G_BDEF    3
416#define G_BGTYPE  4
417#define G_BCLOSE  5
418#define G_BUP_BR  6
419#define G_BDN_BR  7
420#define G_BUP_CN  8
421#define G_BDN_CN  9
422#define G_BHSVRGB 10
423#define G_B1      11
424#define G_B2      12
425#define G_B3      13
426#define G_B4      14
427#define G_BSET    15
428#define G_BUNDO   16
429
430
431/* definitions of first char of dirnames[i] (filetype) */
432#define C_FIFO  'f'    /* FIFO special file */
433#define C_CHR   'c'    /* character special file */
434#define C_DIR   'd'    /* directory */
435#define C_BLK   'b'    /* block special file */
436#define C_LNK   'l'    /* symbolic link */
437#define C_SOCK  's'    /* socket */
438#define C_REG   ' '    /* regular file */
439
440
441/* random string-placing definitions */
442#define SPACING 3      /* vertical space between strings */
443#define ASCENT   (mfinfo->ascent)
444#define DESCENT  (mfinfo->descent)
445#define CHIGH    (ASCENT + DESCENT)
446#define LINEHIGH (CHIGH + SPACING)
447
448
449#define STDINSTR "<stdin>"
450
451
452#ifndef MAIN
453#define WHERE extern
454#else
455#define WHERE
456#endif
457
458typedef unsigned char byte;
459
460typedef struct { Window win;            /* window ID */
461		 int len;               /* length of major axis */
462		 int vert;              /* true if vertical, else horizontal */
463		 int active;            /* true if scroll bar can do anything*/
464		 int min,max;           /* min/max values 'pos' can take */
465		 int val;               /* 'value' of scrollbar */
466		 int page;              /* amt val change on pageup/pagedown */
467		 int tpos;              /* thumb pos. (pixels from tmin) */
468		 int tmin,tmax;         /* min/max thumb offsets (from 0,0) */
469		 int tsize;             /* size of thumb (in pixels) */
470		 unsigned long fg,bg;   /* colors */
471		 void (*drawobj)();     /* redraws obj controlled by scrl*/
472		 int uplit, dnlit;      /* true if up&down arrows are lit */
473	       } SCRL;
474
475typedef struct { Window win;            /* parent window */
476		 int x,y,w,h;           /* size of button rectangle */
477		 int lit;               /* if true, invert colors */
478		 int active;            /* if false, stipple gray */
479		 int toggle;            /* if true, clicking toggles state */
480		 unsigned long fg,bg;   /* colors */
481		 char *str;             /* string in button */
482	       } BUTT;
483
484
485typedef struct { Window win;            /* window */
486		 int x,y,w,h;           /* size of window */
487		 unsigned long fg,bg;   /* colors */
488		 char **str;            /* ptr to list of strings */
489		 int   nstr;            /* number of strings */
490		 int   selected;        /* number of 'selected' string */
491		 int   nlines;          /* number of lines shown at once */
492		 SCRL  scrl;            /* scrollbar that controls list */
493		 int   filetypes;       /* true if filetype icons to be drawn*/
494		 int   dirsonly;        /* if true, only dirs selectable */
495	       } LIST;
496
497
498typedef struct rbutt { Window        win;      /* parent window */
499		       int           x,y;      /* position in parent */
500		       char         *str;      /* the message string */
501		       int           selected; /* selected or not */
502		       int           active;   /* selectable? */
503		       struct rbutt *next;     /* pointer to next in group */
504		       unsigned long fg,bg;    /* colors */
505		     } RBUTT;
506
507/* MACROS */
508#define CENTERX(f,x,str) ((x)-XTextWidth(f,str,strlen(str))/2)
509#define CENTERY(f,y) ((y)-((f->ascent+f->descent)/2)+f->ascent)
510
511/* RANGE forces a to be in the range b..c (inclusive) */
512#define RANGE(a,b,c) { if (a<b) a=b;  if (a>c) a=c; }
513
514/* PTINRECT returns '1' if x,y is in rect (inclusive) */
515#define PTINRECT(x,y,rx,ry,rw,rh) \
516           ((x)>=(rx) && (y)>=(ry) && (x)<=(rx)+(rw) && (y)<=(ry)+(rh))
517
518/* MONO returns total intensity of r,g,b components */
519#define MONO(rd,gn,bl) (((rd)*11 + (gn)*16 + (bl)*5) >> 5)  /*.33R+ .5G+ .17B*/
520
521
522
523/* X stuff */
524WHERE Display       *theDisp;
525WHERE int           theScreen;
526WHERE unsigned int  ncells, dispWIDE, dispHIGH, dispDEEP;
527WHERE Colormap      theCmap, LocalCmap;
528WHERE Window        rootW, mainW;
529WHERE GC            theGC;
530WHERE unsigned long black, white, fg, bg, infofg, infobg;
531WHERE Font          mfont, monofont;
532WHERE XFontStruct   *mfinfo, *monofinfo;
533WHERE Visual        *theVisual;
534WHERE Cursor        arrow, cross;
535WHERE Pixmap        iconPix;
536
537/* global vars used by LOAD routines */
538WHERE byte          *pic;                   /* ptr to loaded picture */
539WHERE unsigned int   pWIDE,pHIGH;           /* size of 'pic' */
540WHERE byte           r[256],g[256],b[256];  /* colormap */
541WHERE char          *cmd;                   /* program name for printf's */
542WHERE int            DEBUG;                 /* print debugging info */
543WHERE int            mono;                  /* true if displaying grayscale */
544
545
546/* more global variables, used by xv and xvmisc */
547WHERE byte          *cpic;         /* cropped version of pic */
548WHERE unsigned int  cWIDE, cHIGH,  /* size of cropped region */
549                    cXOFF, cYOFF;  /* offset of region from 0,0 of pic */
550
551WHERE byte          *epic;         /* expanded version of cpic */
552                                   /* points to pic when at 1:1 expansion */
553                                   /* this is converted to 'theImage' */
554WHERE unsigned int  eWIDE, eHIGH;  /* size of epic */
555WHERE unsigned int  normFact;      /* factor to shrink picture by for 'norm' */
556
557WHERE byte           rorg[256],gorg[256],borg[256];  /* ORIGINAL colormap */
558WHERE byte           gamcr[256];   /* gamma correction curve */
559WHERE byte           fsgamcr[256]; /* gamma correction curve (for FS dither) */
560
561
562WHERE XImage        *theImage;     /* X version of epic */
563
564
565WHERE unsigned long freecols[256]; /* list of pixel values to free */
566WHERE int           nfcols;        /* number of colors to free */
567WHERE unsigned long cols[256];     /* maps pic pixel values to X pixel vals */
568WHERE int           fc2pcol[256];  /* maps freecols into pic pixel values */
569WHERE int           numcols;       /* # of desired colors in picture */
570WHERE int           ncols;         /* max # of (different) colors to alloc */
571
572WHERE char          str[128];      /* dummy string used for error messages */
573
574WHERE int           expand,        /* expansion amount */
575                    bwidth,        /* border width of created windows */
576                    noglob,        /* force to only use colors it alloced */
577                    revvideo,      /* reverse video */
578                    perfect,       /* perfect color.  install own colormap */
579                    fixedaspect,   /* fixed aspect ratio */
580                    slow24,        /* use slow 24to8 algorithm */
581                    ninstall,      /* true if using icccm-complaint WM
582				      (a WM that will does install CMaps */
583                    useroot,       /* true if we should draw in rootW */
584                    noqcheck,      /* true if we should NOT do QuickCheck */
585                    rwcolor,       /* true if we should use R/W color cells */
586                    rwthistime,    /* true if we DID use R/W color cells */
587                    fish,          /* turn on annoying fish */
588                    fishrunning;   /* true if fish are in operation */
589
590WHERE float         defaspect,     /* default aspect ratio to use */
591                    normaspect;    /* normal aspect ratio of this picture */
592
593WHERE int           crx1, cry1,    /* dimensions of cropping rectangle */
594                    crx2, cry2;
595
596
597
598/* stuff used for 'info' box */
599WHERE Window        infoW;
600WHERE int           infoUp;       /* boolean:  whether infobox is visible */
601WHERE int           infoMode;
602
603
604/* stuff used for 'ctrl' box */
605WHERE Window        ctrlW;
606WHERE int           ctrlUp;       /* boolean:  whether ctrlbox is visible */
607WHERE char         *namelist[MAXNAMES];  /* list of file names from argv */
608WHERE char         *dispnames[MAXNAMES]; /* truncated names shown in listbox */
609WHERE int           numnames, curname;
610WHERE LIST          nList;
611WHERE BUTT          but[NBUTTS];         /* command buttons in ctrl window */
612WHERE Pixmap        grayTile, grayStip;  /* for drawing dim things */
613
614/* stuff used for 'directory' box */
615WHERE Window        dirW, ddirW, dnamW;
616WHERE int           dirUp;       /* is dirW mapped or not */
617WHERE LIST          dList;       /* list of filenames in current directory */
618WHERE BUTT          dbut[S_NBUTTS];
619
620/* stuff used for 'gamma' box */
621#define NUMHANDS 4
622WHERE Window        gamW,graphW;
623WHERE int           gamUp;       /* is gamW mapped or not */
624WHERE BUTT          gbut[G_NBUTTS];
625WHERE XPoint        ghand[NUMHANDS];
626
627#undef WHERE
628
629
630
631
632
633/* function declarations for externally-callable functions */
634
635#ifdef __STDC__
636/****************************** XV.C ****************************/
637void DrawWindow(int, int, int, int);
638void WCrop(int, int);
639void WUnCrop(void);
640void WResize(int, int);
641void WRotate(void);
642void InvCropRect(void);
643void MakeRootPic(void);
644void XvFreeColors(Display*, Colormap, unsigned long*, int, unsigned long, int);
645
646/*************************** XVMISC.C ***************************/
647Window CreateWindow(char *, char *, unsigned int, unsigned int,
648		    unsigned long, unsigned long);
649void Resize(int, int);
650void Rotate(int);
651void SortColormap(void);
652void AllocColors(void);
653void AllocRWColors(void);
654void DoMonoAndRV(void);
655void DoCrop(void);
656void UnCrop(void);
657void AutoCrop(void);
658void FSDither(byte *, int, int, byte *);
659void CreateXImage(void);
660void CenterString(Window, char *, int, int);
661void ULineString(Window, char *, int, int);
662int  StringWidth(char *);
663void FakeButtonPress(BUTT *);
664void SetCropString(void);
665void Warning(void);
666void FatalError(char *);
667void LoadFishCursors(void);
668void SetCursors(int);
669void WaitCursor(void);
670void Quit(int);
671void Timer(int);
672
673/*************************** XV24TO8.C **************************/
674int  Conv24to8(byte *, int, int, int);
675void InitFSDTables(void);
676
677/**************************** XVCTRL.C **************************/
678void CreateCtrl(char *);
679void CtrlBox(int);
680void RedrawCtrl(int, int, int, int);
681int  ClickCtrl(int, int);
682void DrawCtrlStr(void);
683void ScrollToCurrent(void);
684
685void LSCreate(LIST *, Window, int, int, int, int, int, char **, int,
686	      unsigned long, unsigned long, void (*)(void), int, int);
687void LSRedraw(LIST *);
688int  LSClick (LIST *, XButtonEvent *);
689void LSNewData(LIST *, char **, int);
690
691
692/*************************** XVINFO.C ***************************/
693void  CreateInfo(char *);
694void  InfoBox(int);
695void  RedrawInfo(int, int, int, int);
696void  SetInfoMode(int);
697void  SetISTR(int, ...);
698char *GetISTR(int);
699
700/**************************** XVDIR.C ***************************/
701void CreateDirW(char *);
702void DirBox(int);
703void RedrawDirW(int,int,int,int);
704int  ClickDirW(int, int);
705void LoadCurrentDirectory(void);
706void RedrawDDirW(void);
707void RedrawDNamW(void);
708void SelectDir(int);
709void DirOpenActive(void);
710void TrackDDirW(int,int);
711int  DirKey(int);
712int  DoSave(void);
713void SetDirFName(char *);
714
715
716/**************************** XVGAM.C **************************/
717void CreateGam(char *);
718void GamBox(int);
719void RedrawGam(int, int, int, int);
720void RedrawGraph(int, int, int, int);
721void ClickGam(int, int);
722void TrackGraph(int, int);
723void GenerateGamma(void);
724void GenerateFSGamma(void);
725void GammifyColors(void);
726void SetGPreset(int, int, int, int, int, int, int);
727
728/*************************** XVSCRL.C ***************************/
729void SCCreate  (SCRL *, Window, int, int, int, int, int, int, int, int,
730                      unsigned long, unsigned long, void (*)(void));
731void SCSetRange(SCRL *, int, int, int, int);
732void SCSetVal  (SCRL *, int);
733void SCRedraw  (SCRL *);
734void SCTrack   (SCRL *, int, int);
735
736
737/**************************** XVBUTT.C ***************************/
738
739void BTCreate(BUTT *, Window, int, int, int, int, char *,
740	      unsigned long, unsigned long);
741void BTSetActive(BUTT *, int);
742void BTRedraw(BUTT *);
743int  BTTrack (BUTT *);
744
745
746RBUTT *RBCreate(RBUTT *, Window, int, int, char*,
747		unsigned long, unsigned long);
748void   RBRedraw(RBUTT *, int);
749void   RBSelect(RBUTT *, int);
750int    RBWhich(RBUTT *);
751int    RBCount(RBUTT *);
752void   RBSetActive(RBUTT *, int, int);
753int    RBClick(RBUTT *, int, int);
754void   RBTrack(RBUTT *, int);
755
756
757/**************************** XVGIF.C ***************************/
758int LoadGIF(char *, int);
759
760/*************************** XVGIFWR.C **************************/
761int WriteGIF(FILE *, byte *, int, int, byte *, byte *, byte *, int, int);
762
763/**************************** XVPM.C ****************************/
764int LoadPM(char *, int);
765int WritePM(FILE *, byte *, int, int, byte *, byte *, byte *, int, int);
766
767/**************************** XVPBM.C ***************************/
768int LoadPBM(char *, int);
769int WritePBM(FILE *, byte *, int, int, byte *, byte *, byte *, int, int, int);
770
771/**************************** XVXBM.C ***************************/
772int LoadXBM(char *, int);
773int WriteXBM(FILE *, byte *, int, int, char *);
774
775/**************************** XVJPEG.C ***************************/
776int LoadJFIF(char *, int);
777
778
779
780
781#else     /* using non-ANSI cc.  Function defs, but no params */
782
783
784
785
786/****************************** XV.C ****************************/
787void DrawWindow(), WCrop(), WUnCrop(), WResize(), WRotate(), InvCropRect();
788void MakeRootPic();
789void XvFreeColors();
790
791/*************************** XVMISC.C ***************************/
792Window CreateWindow();
793void   Resize(), Rotate(), SortColormap(), AllocColors(), DoCrop(), UnCrop();
794void   AutoCrop(), DoMonoAndRV();
795void   AllocRWColors(), FSDither(), CenterString(), ULineString();
796int    StringWidth();
797void   FakeButtonPress(), SetCropString(), Warning(), FatalError(), Quit();
798void   Timer(), CreateXImage(), LoadFishCursors(), SetCursors(), WaitCursor();
799
800/*************************** XV24TO8.C **************************/
801int  Conv24to8();
802void InitFSDTables();
803
804/**************************** XVCTRL.C **************************/
805void CreateCtrl(), CtrlBox(), RedrawCtrl(), DrawCtrlStr(), ScrollToCurrent();
806int  ClickCtrl();
807
808void LSCreate(), LSRedraw(), LSNewData();
809int  LSClick();
810
811/*************************** XVINFO.C ***************************/
812void  CreateInfo(), InfoBox(), RedrawInfo(), SetInfoMode(), SetISTR();
813char *GetISTR();
814
815/**************************** XVDIR.C ***************************/
816void CreateDirW(), DirBox(), RedrawDirW(), LoadCurrentDirectory();
817int  ClickDirW(), DoSave(), DirKey();
818void RedrawDDirW(), RedrawDNamW(), SelectDir(), DirOpenActive(), TrackDDirW();
819void SetDirFName();
820
821/**************************** XVGAM.C **************************/
822void CreateGam(), GamBox(), RedrawGam(), RedrawGraph(), ClickGam();
823void TrackGraph(), GenerateGamma(), GenerateFSGamma(), GammifyColors();
824void SetGPreset();
825
826/*************************** XVSCRL.C ***************************/
827void SCCreate(), SCSetRange(), SCSetVal(), SCRedraw(), SCTrack();
828
829/**************************** XVBUTT.C ***************************/
830void BTCreate(), BTSetActive(), BTRedraw();
831int  BTTrack();
832
833RBUTT *RBCreate();
834void   RBRedraw(), RBSelect(), RBSetActive(), RBTrack();
835int    RBWhich(), RBCount(), RBClick();
836
837/**************************** XVGIF.C ***************************/
838int LoadGIF();
839
840/*************************** XVGIFWR.C **************************/
841int WriteGIF();
842
843/**************************** XVPM.C ****************************/
844int LoadPM(), WritePM();
845
846/**************************** XVPBM.C ***************************/
847int LoadPBM(), WritePBM();
848
849/**************************** XVXBM.C ***************************/
850int LoadXBM(), WriteXBM();
851
852/**************************** XVJPEG.C ***************************/
853int LoadJFIF();
854
855#endif
856@//E*O*F xv.h//
857chmod u=rw,g=r,o=r xv.h
858
859echo x - xvdir.c
860sed 's/^@//' > "xvdir.c" <<'@//E*O*F xvdir.c//'
861/*
862 * xvdir.c - Directory changin', file i/o dialog box
863 *
864 * callable functions:
865 *
866 *   CreateDirW(geom,bwidth)-  creates the dirW window.  Doesn't map it.
867 *   DirBox(vis)            -  random processing based on value of 'vis'
868 *                             maps/unmaps window, etc.
869 *   RedrawDirW(x,y,w,h)    -  called by 'expose' events
870 *   ClickDirW()            -  handles mouse clicks in DirW
871 *   LoadCurrentDirectory() -  loads up current dir information for dirW
872 *   DoSave()               -  calls appropriate save routines
873 *   SetDirFName()          -  sets the 'save-as' filename
874 */
875
876/*
877 * Copyright 1989, 1990 by the University of Pennsylvania
878 *
879 * Permission to use, copy, and distribute for non-commercial purposes,
880 * is hereby granted without fee, providing that the above copyright
881 * notice appear in all copies and that both the copyright notice and this
882 * permission notice appear in supporting documentation.
883 *
884 * The software may be modified for your own purposes, but modified versions
885 * may not be distributed.
886 *
887 * This software is provided "as is" without any express or implied warranty.
888 */
889
890
891#define NEEDSDIR
892#include "xv.h"
893
894#define NLINES 9                   /* # of lines in list control (keep odd) */
895#define LISTW  200
896
897#define BUTTW   60
898#define BUTTH   19
899#define DDWIDE  LISTW-80+15
900
901#define MAXDEEP 30    /* maximum number of directories in cwd path */
902#define MAXFNLEN 40   /* max length of filename being entered */
903
904#define DEFFILENAME ""   /* default filename filled in when program starts */
905
906#ifdef __STDC__
907static void RedrawDList(void);
908static int  dnamcmp(char **, char **);
909#else
910static void RedrawDList();
911static int  dnamcmp();
912#endif
913
914static int    listh;
915static char  *dirnames[MAXNAMES];
916static int    numdirnames = 0, ndirs = 0;
917static char   path[MAXPATHLEN+1];
918static char  *dirs[MAXDEEP];            /* list of directory names */
919static char  *lastdir;                  /* name of the directory we're in */
920static char   filename[MAXFNLEN];       /* filename being entered */
921static RBUTT *formatRB, *colorRB, *sizeRB;
922
923
924/***************************************************/
925void CreateDirW(geom)
926char *geom;
927{
928  int y;
929
930  listh = LINEHIGH * NLINES;
931
932  dirW = CreateWindow("xv save dialog",geom,DIRWIDE, DIRHIGH, infofg, infobg);
933  if (!dirW) FatalError("couldn't create 'save' window!");
934
935  /* create doo-wah's */
936  ddirW = XCreateSimpleWindow(theDisp, dirW, 40, 5, DDWIDE, LINEHIGH,
937			      2, infofg, infobg);
938  if (!ddirW) FatalError("can't create path window");
939  XSelectInput(theDisp, ddirW, ExposureMask | ButtonPressMask);
940
941  dnamW = XCreateSimpleWindow(theDisp, dirW, 80, listh+75-ASCENT-4,
942			      200, LINEHIGH+4, 1, infofg, infobg);
943  if (!dnamW) FatalError("can't create name window");
944  XSelectInput(theDisp, dnamW, ExposureMask);
945
946
947  LSCreate(&dList, dirW, 10, 14+LINEHIGH, LISTW, listh, NLINES,
948	   dirnames, numdirnames,
949	   infofg, infobg, RedrawDList, 1, 0);
950
951  BTCreate(&dbut[S_BOPEN], dirW, 233, dList.y-9+listh/5, 60, BUTTH,
952	   "Open", infofg, infobg);
953  BTCreate(&dbut[S_BSAVE], dirW, 233, dList.y-9+(listh*2)/5, 60, BUTTH,
954	   "Save", infofg, infobg);
955  BTCreate(&dbut[S_BCANC], dirW, 233, dList.y-9+(listh*3)/5, 60, BUTTH,
956	   "Cancel", infofg, infobg);
957  BTCreate(&dbut[S_BQUIT], dirW, 233, dList.y-9+(listh*4)/5, 60, BUTTH,
958	   "Quit", infofg, infobg);
959
960  y = listh + 110;
961  formatRB = RBCreate(NULL, dirW, 26, y, "GIF", infofg, infobg);
962  RBCreate(formatRB, dirW, 26, y+18, "PM", infofg, infobg);
963  RBCreate(formatRB, dirW, 26, y+36, "PBM (raw)", infofg, infobg);
964  RBCreate(formatRB, dirW, 26, y+54, "PBM (ascii)", infofg, infobg);
965  RBCreate(formatRB, dirW, 26, y+72, "X11 Bitmap", infofg, infobg);
966  RBCreate(formatRB, dirW, 26, y+90, "VIS", infofg, infobg);
967
968  colorRB = RBCreate(NULL, dirW, DIRWIDE/2, y, "Full Color", infofg, infobg);
969  RBCreate(colorRB, dirW, DIRWIDE/2, y+18, "Greyscale", infofg, infobg);
970  RBCreate(colorRB, dirW, DIRWIDE/2, y+36, "B/W Dithered", infofg, infobg);
971
972  y = y + 133;
973  sizeRB = RBCreate(NULL, dirW, 26, y, "Normal Size", infofg, infobg);
974  RBCreate(sizeRB, dirW, 26, y+18, "At Current Expansion", infofg, infobg);
975
976  SetDirFName(DEFFILENAME);
977
978  LoadCurrentDirectory();
979
980  XMapSubwindows(theDisp, dirW);
981}
982
983
984/***************************************************/
985void DirBox(vis)
986int vis;
987{
988  if (vis) XMapRaised(theDisp, dirW);
989  else     XUnmapWindow(theDisp, dirW);
990
991  BTSetActive(&but[BSAVE], !vis);
992
993  dirUp = vis;
994}
995
996
997/***************************************************/
998void RedrawDirW(x,y,w,h)
999int x,y,w,h;
1000{
1001  int  i,ypos;
1002  char foo[30];
1003  XRectangle xr;
1004
1005  xr.x = x;  xr.y = y;  xr.width = w;  xr.height = h;
1006  XSetClipRectangles(theDisp, theGC, 0,0, &xr, 1, Unsorted);
1007
1008  if (dList.nstr==1) strcpy(foo,"1 file");
1009                else sprintf(foo,"%d files",dList.nstr);
1010
1011  ypos = dList.y + dList.h + 5 + ASCENT;
1012  XSetForeground(theDisp, theGC, infobg);
1013  XFillRectangle(theDisp, dirW, theGC, 10, ypos-ASCENT, DIRWIDE, CHIGH);
1014  XSetForeground(theDisp, theGC, infofg);
1015  XDrawString(theDisp, dirW, theGC, 10, ypos, foo, strlen(foo));
1016
1017  XDrawString(theDisp, dirW, theGC, 10, dList.h+75, "File name:",10);
1018
1019  for (i=0; i<S_NBUTTS; i++) BTRedraw(&dbut[i]);
1020
1021  RBRedraw(formatRB, -1);
1022  RBRedraw(colorRB, -1);
1023  RBRedraw(sizeRB, -1);
1024
1025  ULineString(dirW, "Format", formatRB->x-16, formatRB->y-3-DESCENT);
1026  ULineString(dirW, "Colors", colorRB->x-16,  colorRB->y-3-DESCENT);
1027  ULineString(dirW, "Size",   sizeRB->x-16,   sizeRB->y-3-DESCENT);
1028
1029  XSetClipMask(theDisp, theGC, None);
1030}
1031
1032
1033/***************************************************/
1034void RedrawDDirW()
1035{
1036  XSetForeground(theDisp, theGC, infofg);
1037  XSetBackground(theDisp, theGC, infobg);
1038
1039  XClearWindow(theDisp, ddirW);
1040  XDrawString(theDisp, ddirW, theGC, 3, ASCENT + 1,
1041              lastdir, strlen(lastdir));
1042}
1043
1044
1045/***************************************************/
1046int ClickDirW(x,y)
1047int x,y;
1048{
1049  BUTT  *bp;
1050  int    bnum;
1051
1052
1053  /* check the RBUTTS first, since they don't DO anything */
1054  if ( (bnum=RBClick(formatRB, x,y)) >= 0) {
1055    RBTrack(formatRB, bnum);
1056    if (RBWhich(formatRB)==4) {  /* turn off FULLCOLOR + GRAYSCALE */
1057      RBSetActive(colorRB,0,0);
1058      RBSetActive(colorRB,1,0);
1059      RBSelect(colorRB,2);
1060    }
1061    else {                       /* turn on FULLCOLOR + GRAYSCALE */
1062      RBSetActive(colorRB,0,1);
1063      RBSetActive(colorRB,1,1);
1064    }
1065    return -1;
1066  }
1067
1068  if ( (bnum=RBClick(colorRB, x,y)) >= 0)
1069    { RBTrack(colorRB, bnum);  return -1; }
1070
1071  if ( (bnum=RBClick(sizeRB, x,y)) >= 0)
1072    { RBTrack(sizeRB, bnum);  return -1; }
1073
1074  for (bnum=0; bnum<S_NBUTTS; bnum++) {
1075    bp = &dbut[bnum];
1076    if (PTINRECT(x, y, bp->x, bp->y, bp->w, bp->h)) break;
1077  }
1078
1079  if (bnum<S_NBUTTS) {   /* found one */
1080    if (BTTrack(bp)) return (bnum);
1081  }
1082
1083  return -1;
1084}
1085
1086
1087/***************************************************/
1088void SelectDir(n)
1089int n;
1090{
1091  int pend;
1092
1093  /* called when entry #n in the dir list was selected/double-clicked */
1094
1095  if (dList.str[n][0] == C_DIR ||
1096      dList.str[n][0] == C_LNK) {  /* it's cool, it's (possibly) a directory */
1097    pend = strlen(path);
1098    strcat(path,dList.str[n]+1);   /* add to pathname */
1099    if (chdir(path)) {
1100      fprintf(stderr,"unable to cd to '%s'\n",path);
1101      path[pend] = '\0';           /* undo path modification */
1102    }
1103    else
1104      LoadCurrentDirectory();
1105  }
1106
1107  else {  /* not a directory */
1108    /* copy the clicked-on filename into the 'save-as' filename */
1109    SetDirFName(dList.str[n]+1);
1110  }
1111}
1112
1113
1114/***************************************************/
1115void TrackDDirW(x,y)
1116int x,y;
1117{
1118  Window        menuW, rW, cW;
1119  int           rx, ry, i,j, sel, lastsel;
1120  unsigned int  mask;
1121
1122  XSetForeground(theDisp, theGC, infofg);
1123  XSetBackground(theDisp, theGC, infobg);
1124
1125  menuW = XCreateSimpleWindow(theDisp, dirW, 40, 5, DDWIDE, ndirs*LINEHIGH,
1126			      2, infofg, infobg);
1127  if (!menuW) FatalError("can't create path window");
1128
1129  XMapRaised(theDisp, menuW);
1130
1131  for (i=ndirs-1, j=0; i>=0; i--,j++)
1132    XDrawString(theDisp, menuW, theGC, 3, j*LINEHIGH + ASCENT + 1,
1133		dirs[i], dirs[i+1]-dirs[i]);
1134
1135  XFlush(theDisp);
1136  XSetFunction(theDisp, theGC, GXinvert);
1137  XSetPlaneMask(theDisp, theGC, infofg ^ infobg);
1138  lastsel = -1;  sel = 0;
1139
1140  while (XQueryPointer(theDisp, menuW, &rW, &cW, &rx, &ry, &x, &y, &mask)) {
1141    if (!(mask & Button1Mask)) break;
1142
1143    /* see if mouse has left window */
1144
1145    sel = y / LINEHIGH;
1146    if (sel>=ndirs) sel = ndirs-1;
1147    if (sel<0) sel = 0;
1148    if (sel != lastsel) {
1149      XFillRectangle(theDisp,menuW,theGC,0,lastsel*LINEHIGH,DDWIDE,LINEHIGH);
1150      XFillRectangle(theDisp,menuW,theGC,0,sel*LINEHIGH,DDWIDE,LINEHIGH);
1151      lastsel = sel;
1152    }
1153  }
1154
1155  XSetFunction(theDisp, theGC, GXcopy);
1156  XSetPlaneMask(theDisp, theGC, AllPlanes);
1157  XDestroyWindow(theDisp, menuW);
1158
1159  if (sel!=0) { /* changed directories */
1160    /* end 'path' by changing trailing '/' (of dir name) to a '\0' */
1161    *(dirs[(ndirs-1)-sel + 1] - 1) = '\0';
1162
1163    /* special case:  if cd to '/', fix path (it's currently "") */
1164    if (path[0] == '\0') strcpy(path,"/");
1165
1166    if (chdir(path)) {
1167      fprintf(stderr,"unable to cd to '%s'\n",path);
1168    }
1169    else
1170      LoadCurrentDirectory();
1171  }
1172}
1173
1174
1175/***************************************************/
1176static void RedrawDList()
1177{
1178  LSRedraw(&dList);
1179}
1180
1181
1182/***************************************************/
1183void LoadCurrentDirectory()
1184{
1185  DIR           *dirp;
1186#ifdef DIRENT
1187  struct dirent *dp;
1188#else
1189  struct direct *dp;
1190#endif
1191  int            i, ftype;
1192  struct stat    st;
1193  char          *dbeg, *dend;
1194
1195  /* get rid of previous file names */
1196  for (i=0; i<numdirnames; i++) free(dirnames[i]);
1197
1198  numdirnames = 0;
1199
1200#ifdef SVR4
1201  getcwd(path, sizeof(path));
1202#else
1203  getwd(path);
1204#endif
1205  if (path[strlen(path)-1] != '/')
1206    strcat(path,"/");   /* tack on a trailing '/' to make path consistent */
1207
1208  /* path will be something like: "/u3/bradley/src/weiner/whatever/" */
1209  /* parse path into individual directory names */
1210  dbeg = dend = path;
1211  for (i=0; i<MAXDEEP && dend; i++) {
1212    dend = strchr(dbeg,'/');  /* find next '/' char */
1213    dirs[i] = dbeg;
1214    dbeg = dend+1;
1215  }
1216  ndirs = i-1;
1217
1218  lastdir = dirs[ndirs-1];
1219  RedrawDDirW();
1220
1221  dirp = opendir(".");
1222  if (!dirp) {
1223    fprintf(stderr,"unable to open current directory");
1224    return;
1225  }
1226
1227  i=0;
1228  while ( (dp = readdir(dirp)) != NULL) {
1229    if (strcmp(dp->d_name, ".")==0 || strcmp(dp->d_name, "..")==0) {
1230      /* skip over '.' and '..' */
1231    }
1232    else {
1233#ifdef DIRENT
1234#ifdef i386
1235      /* Not 100% sure d_reclen is correct, but it works...  MWS 10/18/90 */
1236      dirnames[i] = (char *) malloc(dp->d_reclen + 2); /* filetype + '\0'*/
1237#else
1238      dirnames[i] = (char *) malloc(strlen(dp->d_name) + 3);
1239#endif
1240#else
1241      dirnames[i] = (char *) malloc(dp->d_namlen + 2); /* +2=filetype + '\0'*/
1242#endif
1243      if (!dirnames[i]) FatalError("malloc error while reading directory");
1244      strcpy(dirnames[i]+1, dp->d_name);
1245
1246      /* figure out what type of file the beastie is */
1247      dirnames[i][0] = C_REG;   /* default to normal file, if lstat fails */
1248
1249#if defined(i386) || defined (SYSV)
1250      if (stat(dirnames[i]+1, &st)==0) {
1251#else
1252      if (lstat(dirnames[i]+1, &st)==0) {
1253#endif
1254	ftype = st.st_mode & S_IFMT;   /* mask off uninteresting bits */
1255	if      (ftype == S_IFDIR)  dirnames[i][0] = C_DIR;
1256	else if (ftype == S_IFCHR)  dirnames[i][0] = C_CHR;
1257	else if (ftype == S_IFBLK)  dirnames[i][0] = C_BLK;
1258
1259#ifdef S_IFIFO
1260	else if (ftype == S_IFIFO)  dirnames[i][0] = C_FIFO;
1261#endif
1262
1263#ifdef S_IFLNK
1264	else if (ftype == S_IFLNK)  dirnames[i][0] = C_LNK;
1265#endif
1266
1267#ifdef S_IFSOCK
1268        else if (ftype == S_IFSOCK) dirnames[i][0] = C_SOCK;
1269#endif
1270      }
1271      else {
1272	/* fprintf(stderr,"problems 'stat-ing' files\n");*/
1273	dirnames[i][0] = C_REG;
1274      }
1275      i++;
1276    }
1277  }
1278
1279  closedir(dirp);
1280
1281  numdirnames = i;
1282
1283  qsort((char *) dirnames, numdirnames, sizeof(char *), dnamcmp);
1284  LSNewData(&dList, dirnames, numdirnames);
1285  DirOpenActive();
1286  RedrawDirW(0,0,DIRWIDE,DIRHIGH);
1287}
1288
1289
1290/***************************************************/
1291static int dnamcmp(s1,s2)
1292char **s1, **s2;
1293{
1294  /* sort so that directories are at beginning of list */
1295
1296  /* if both dirs or both not dirs, sort on name */
1297  if ( (**s1 == C_DIR && **s2 == C_DIR) || (**s1 != C_DIR && **s2 != C_DIR))
1298    return (strcmp((*s1)+1, (*s2)+1));
1299
1300  else if (**s1==C_DIR) return -1;  /* s1 is first */
1301  else return 1;                    /* s2 is first */
1302}
1303
1304
1305
1306
1307
1308/***************************************************/
1309int DirKey(c)
1310int c;
1311{
1312  /* got keypress in dirW.  stick on end of filename */
1313  int len;
1314
1315  len = strlen(filename);
1316
1317  if (c>' ' && c<'\177') {              /* printable characters */
1318    if (c=='/') return(-1);             /* no directories in filename */
1319    if (len >= MAXFNLEN-1) return(-1);  /* max length of string */
1320    filename[len]=c;  filename[len+1]='\0';
1321  }
1322
1323  else if (c=='\010' || c=='\177') {    /* BS or DEL */
1324    if (len==0) return(-1);             /* string already empty */
1325    filename[len-1]='\0';
1326  }
1327
1328  else if (c=='\025' || c=='\013') {    /* ^U or ^K clear line */
1329    filename[0] = '\0';
1330  }
1331
1332  else if (c=='\012' || c=='\015') {    /* CR or LF */
1333    FakeButtonPress(&dbut[S_BSAVE]);
1334  }
1335
1336  else return(-1);                      /* unhandled character */
1337
1338  SetDirFName(filename);
1339  return(0);
1340}
1341
1342
1343/***************************************************/
1344void RedrawDNamW()
1345{
1346  int width, len;
1347
1348  len = strlen(filename);
1349  XSetForeground(theDisp, theGC, infofg);
1350  XDrawString(theDisp, dnamW, theGC, 3, ASCENT+3, filename, len);
1351  width = StringWidth(filename);
1352  XDrawLine(theDisp, dnamW, theGC, 3+width+1, 3, 3+width+1,
1353	    3+CHIGH);
1354}
1355
1356
1357/***************************************************/
1358void DirOpenActive()
1359{
1360  if (dList.selected>=dList.nstr || dList.selected<0)
1361    BTSetActive(&dbut[S_BOPEN],0);
1362
1363  else if (dList.str[dList.selected][0] == C_DIR ||
1364      dList.str[dList.selected][0] == C_LNK)
1365    BTSetActive(&dbut[S_BOPEN],1);
1366
1367  else
1368    BTSetActive(&dbut[S_BOPEN],0);
1369
1370  XFlush(theDisp);
1371}
1372
1373
1374
1375/***************************************************/
1376int DoSave()
1377{
1378  FILE *fp;
1379  byte *thepic, *bwpic;
1380  int   w,h,rv,i;
1381
1382  /* opens file, does appropriate color pre-processing, calls save routine
1383     based on chosen format.  Returns '0' if successful */
1384
1385  WaitCursor();
1386
1387  bwpic = NULL;
1388
1389  if (RBWhich(sizeRB)==1) { thepic = epic;  w = eWIDE;  h = eHIGH; }
1390                     else { thepic = cpic;  w = cWIDE;  h = cHIGH; }
1391
1392  if (RBWhich(colorRB)==2) {
1393    /* generate a FSDithered 1-byte per pixel image */
1394    bwpic = (byte *) malloc(w*h);
1395    if (!bwpic) FatalError("unable to malloc dithered picture (DoSave)");
1396    FSDither(thepic, w, h, bwpic);
1397    thepic = bwpic;
1398  }
1399
1400  /* open file */
1401  fp = fopen(filename, "w");
1402  if (!fp) {
1403    SetISTR(ISTR_INFO,"Can't create '%s' -  %s",filename,sys_errlist[errno]);
1404    Warning();
1405    if (bwpic) free(bwpic);
1406    SetCursors(-1);
1407    return -1;
1408  }
1409
1410  if ((mono || ncols==0) && RBWhich(colorRB)==0) {
1411    /* if we're saving color, but we're viewing B/W we have to NOT do
1412       the 'monofication' of the colormap ... */
1413    for (i=0; i<numcols; i++) {
1414      r[i] = rorg[i];  g[i] = gorg[i];  b[i] = borg[i];  /* original */
1415
1416      if (revvideo) {
1417	r[i] = 255-r[i];  g[i] = 255-g[i];  b[i] = 255-b[i];
1418      }
1419   }
1420
1421    GammifyColors();
1422  }
1423
1424  rv = 0;
1425  i = RBWhich(formatRB);
1426  switch (i) {
1427  case 0:  rv = WriteGIF(fp,thepic,w, h, r, g, b, numcols, RBWhich(colorRB));
1428           break;
1429  case 1:  rv = WritePM (fp,thepic,w, h, r, g, b, numcols, RBWhich(colorRB));
1430           break;
1431  case 2:  rv = WritePBM(fp,thepic,w, h, r, g, b, numcols, RBWhich(colorRB),1);
1432           break;
1433  case 3:  rv = WritePBM(fp,thepic,w, h, r, g, b, numcols, RBWhich(colorRB),0);
1434           break;
1435  case 4:  rv = WriteXBM(fp,thepic,w, h, filename);
1436           break;
1437  case 5:  rv = WriteVIS(fp,thepic,w,h,r,g,b,numcols,RBWhich(colorRB));
1438	  break;
1439  }
1440
1441  fclose(fp);
1442  if (rv) unlink(filename);   /* couldn't properly write file:  delete it */
1443
1444  if (!rv) {
1445    SetISTR(ISTR_INFO,"Successfully wrote '%s'",filename);
1446    LoadCurrentDirectory();   /* wrote file: rescan directory */
1447  }
1448
1449  if (bwpic) free(bwpic);
1450
1451  if ((mono || ncols==0) && RBWhich(colorRB)==0) {
1452    /* restore normal colormap */
1453    DoMonoAndRV();
1454    GammifyColors();
1455  }
1456
1457  SetCursors(-1);
1458
1459  return rv;
1460}
1461
1462
1463
1464/***************************************************/
1465void SetDirFName(st)
1466char *st;
1467{
1468  strncpy(filename, st, MAXFNLEN-1);
1469  filename[MAXFNLEN-1] = '\0';  /* make sure it's terminated */
1470  XClearWindow(theDisp, dnamW);
1471  RedrawDNamW();
1472  BTSetActive(&dbut[S_BSAVE], strlen(filename)!=0);
1473}
1474
1475@//E*O*F xvdir.c//
1476chmod u=rw,g=r,o=r xvdir.c
1477
1478echo x - xvvis.c
1479sed 's/^@//' > "xvvis.c" <<'@//E*O*F xvvis.c//'
1480/*
1481 * xvvis.c - load routine for 'vis' format pictures
1482 *
1483 * LoadVIS(fname, numcols)  -  loads a VIS pic, does 24to8 code if nec.
1484 * WriteVIS(fp, pic, w, h, r,g,b, numcols, style)
1485 */
1486
1487/*
1488 * Copyright 1989, 1990 by the University of Pennsylvania
1489 *
1490 * Permission to use, copy, and distribute for non-commercial purposes,
1491 * is hereby granted without fee, providing that the above copyright
1492 * notice appear in all copies and that both the copyright notice and this
1493 * permission notice appear in supporting documentation.
1494 *
1495 * The software may be modified for your own purposes, but modified versions
1496 * may not be distributed.
1497 *
1498 * This software is provided "as is" without any express or implied warranty.
1499 */
1500
1501
1502#include "xv.h"
1503
1504static int VISError();
1505
1506int LoadVIS(fname,nc)
1507char *fname;
1508int   nc;
1509{
1510	FILE  *fp;
1511	char buf[1000];
1512	int w=-1,h=-1;
1513	char etype[100];
1514	int raster=getenv("VIS_RASTER")&&atoi(getenv("VIS_RASTER"));
1515
1516	fp=fopen(fname,"r");
1517	if (!fp) return VISError("unable to open file");
1518
1519	while(fgets(buf,sizeof buf,fp)) {
1520		if(!buf[0]||buf[0]=='\n'||buf[0]=='\f') break;
1521		sscanf(buf,"DIMS=%d %d",&w,&h);
1522		sscanf(buf,"ETYPE=%s",etype);
1523	}
1524
1525	if(w<0||h<0) {fclose(fp); return VISError("bad format");}
1526
1527	pWIDE=w; pHIGH=h;
1528	{int i; for(i=0;i<256;i++) r[i]=g[i]=b[i]=i;}
1529
1530	if(!strcmp(etype,"uchar")) {
1531		int i,j;
1532		pic=(unsigned char*)malloc(w*h);
1533		if(!pic) {fclose(fp); return VISError("cannot allocate enough memory");}
1534		if(!raster) for(i=0;i<w;i++) for(j=0;j<h;j++) pic[i+(h-j-1)*w]=getc(fp);
1535		else for(j=0;j<h;j++) for(i=0;i<w;i++) pic[i+j*w]=getc(fp);
1536	} else if(!strcmp(etype,"float")) {
1537		int i,j,n;
1538		float min=1e38,max=-1e38;
1539		float *t;
1540		t=(float*)malloc(w*h*sizeof *t);
1541		if(!t) {fclose(fp); return VISError("cannot allocate enough memory");}
1542		pic=(unsigned char*)malloc(w*h);
1543		if(!pic) {free(t); fclose(fp); return VISError("cannot allocate enough memory");}
1544		fread(t,sizeof *t,w*h,fp);
1545		n=w*h;
1546		for(i=0;i<n;i++) {if(t[i]<min) min=t[i]; if(t[i]>max) max=t[i];}
1547		if(max==min) max=min+1.0;
1548		if(!raster) for(i=0;i<w;i++) for(j=0;j<h;j++) pic[i+(h-j-1)*w]=255*(t[i*h+j]-min)/(max-min);
1549		else for(i=0;i<w;i++) for(j=0;j<h;j++) pic[i+j*w]=255*(t[i+j*w]-min)/(max-min);
1550		free(t);
1551	} else {close(fp); return VISError("unknown ETYPE");}
1552
1553	fclose(fp);
1554	return 0;
1555}
1556
1557int WriteVIS(fp,thepic,w,h,rmap,gmap,bmap,numcols,colorstyle)
1558FILE *fp;
1559byte *thepic;
1560int w,h;
1561byte *rmap,*gmap,*bmap;
1562{
1563	int i,j;
1564
1565	fprintf(fp,"VISF=\nDIMS=%d %d\nETYPE=uchar\n\f\n",w,h);
1566
1567	if(colorstyle==2) {
1568		for(i=0;i<w;i++) for(j=0;j<h;j++) putc(thepic[i+(h-j-1)*w]?255:0,fp);
1569	} else {
1570		int rgb[256];
1571		for (i=0; i<numcols; i++) rgb[i] = MONO(rmap[i],gmap[i],bmap[i]);
1572		for(i=0;i<w;i++) for(j=0;j<h;j++) putc(rgb[thepic[i+(h-j-1)*w]],fp);
1573	}
1574	return 0;
1575}
1576
1577static int VISError(st)
1578char *st;
1579{
1580	SetISTR(ISTR_WARNING,"LoadVIS() - %s",cmd,st);
1581	Warning();
1582	return -1;
1583}
1584
1585@//E*O*F xvvis.c//
1586chmod u=rw,g=r,o=r xvvis.c
1587
1588exit 0
1589
1590
1591