ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/vgaimage.c
Revision: 2.2
Committed: Wed Oct 14 18:56:58 1992 UTC (31 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +6 -4 lines
Log Message:
fixed problem where text is overwritten by cursor

File Contents

# User Rev Content
1 greg 2.1 /* Copyright (c) 1992 Regents of the University of California */
2    
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ LBL";
5     #endif
6    
7     /*
8     * vgaimage.c - driver for VGA board under DOS
9     */
10    
11     #include "standard.h"
12     #include <graph.h>
13     #include "color.h"
14     #include "random.h"
15     #include "resolu.h"
16     #include <dos.h>
17     #include <i86.h>
18    
19     #define M_RDOWN 0x8
20     #define M_RUP 0x10
21     #define M_LDOWN 0x2
22     #define M_LUP 0x4
23     #define M_MOTION 0x1
24    
25     int crad;
26     int mouse_event = 0;
27     int mouse_xpos = -1;
28     int mouse_ypos = -1;
29    
30 greg 2.2 #define hide_cursor move_cursor(-1,-1)
31     #define show_cursor move_cursor(mouse_xpos,mouse_ypos)
32 greg 2.1
33     #define CTRL(c) ((c)-'@')
34    
35     #define MAXWIDTH 1024
36     #define MAXHEIGHT 768
37    
38     short ourblack = 0; ourwhite = 1;
39    
40     double gamcor = 2.2; /* gamma correction */
41    
42     int dither = 1; /* dither colors? */
43    
44     int maxcolors = 0; /* maximum colors */
45     int minpix = 0; /* minimum pixel value */
46     int greyscale = 0; /* in grey */
47    
48     int scale = 0; /* scalefactor; power of two */
49    
50     COLR scanline[MAXWIDTH]; /* scan line buffer */
51    
52     int xmax, ymax; /* picture dimensions */
53     FILE *fin = stdin; /* input file */
54     long scanpos[MAXHEIGHT]; /* scan line positions in file */
55     int cury = 0; /* current scan location */
56    
57     double exposure = 1.0; /* exposure compensation used */
58    
59     int wrongformat = 0; /* input in another format? */
60    
61     struct {
62     int xmin, ymin, xsiz, ysiz;
63     } box = {0, 0, 0, 0}; /* current box */
64    
65     int initialized = 0;
66     int cheight, cwidth;
67    
68     #define postext(x,y) _settextposition(1+(y)/cheight,1+(x)/cwidth)
69    
70     char *progname;
71    
72     char errmsg[128];
73    
74     extern BYTE clrtab[256][3]; /* global color map */
75    
76     extern long ftell();
77    
78    
79     main(argc, argv)
80     int argc;
81     char *argv[];
82     {
83     extern char *getenv(), *fixargv0();
84     char *gv;
85     int headline();
86     int i;
87    
88     progname = argv[0] = fixargv0(argv[0]);
89     if ((gv = getenv("GAMMA")) != NULL)
90     gamcor = atof(gv);
91    
92     for (i = 1; i < argc; i++)
93     if (argv[i][0] == '-')
94     switch (argv[i][1]) {
95     case 'c':
96     maxcolors = atoi(argv[++i]);
97     break;
98     case 'b':
99     greyscale = !greyscale;
100     break;
101     case 'm':
102     maxcolors = 2;
103     break;
104     case 'd':
105     dither = !dither;
106     break;
107     case 'e':
108     if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
109     goto userr;
110     scale = atoi(argv[++i]);
111     break;
112     case 'g':
113     gamcor = atof(argv[++i]);
114     break;
115     default:
116     goto userr;
117     }
118     else
119     break;
120    
121     if (i == argc-1) { /* open picture */
122     fin = fopen(argv[i], "r");
123     if (fin == NULL) {
124     sprintf(errmsg, "cannot open file \"%s\"", argv[i]);
125     quiterr(errmsg);
126     }
127     } else if (i != argc)
128     goto userr;
129     setmode(fileno(fin), O_BINARY);
130     /* get header */
131     getheader(fin, headline, NULL);
132     /* get picture dimensions */
133     if (wrongformat || fgetresolu(&xmax, &ymax, fin) < 0)
134     quiterr("bad picture format");
135     if (xmax > MAXWIDTH | ymax > MAXHEIGHT)
136     quiterr("input picture too large for VGA");
137    
138     init(); /* initialize and display */
139    
140     while (docommand()) /* loop on command */
141     ;
142     quiterr(NULL);
143     userr:
144     fprintf(stderr,
145     "Usage: %s [-b][-m][-d][-c ncolors][-e +/-stops] file\n", progname);
146     exit(1);
147     }
148    
149    
150     headline(s) /* get relevant info from header */
151     char *s;
152     {
153     char fmt[32];
154    
155     if (isexpos(s))
156     exposure *= exposval(s);
157     else if (isformat(s)) {
158     formatval(fmt, s);
159     wrongformat = strcmp(fmt, COLRFMT);
160     }
161     }
162    
163    
164     init() /* initialize and load display */
165     {
166     static struct {
167     short mode;
168     short xsiz, ysiz;
169     } video[] = {
170     {_MRES256COLOR, 320, 200},
171     {_VRES256COLOR, 640, 400},
172     {_SVRES256COLOR, 800, 600},
173     {_XRES256COLOR, 1024, 768},
174     -1
175     };
176     struct videoconfig config;
177     register int i;
178     /* pick a card... */
179     for (i = 0; video[i].mode != -1; i++)
180     if (video[i].xsiz >= xmax && video[i].ysiz >= ymax)
181     break;
182     if (video[i].mode == -1)
183     quiterr("input picture too large");
184     if (_setvideomode(video[i].mode) == 0)
185     quiterr("inadequate display card for picture");
186     initialized = 1;
187     _getvideoconfig(&config);
188     if (maxcolors == 0)
189     maxcolors = config.numcolors;
190     if (maxcolors > 4) {
191     maxcolors -= minpix = 2;
192     _settextcolor(ourwhite);
193     }
194     cheight = config.numypixels/config.numtextrows;
195     cwidth = config.numxpixels/config.numtextcols;
196     /* clear scan position array */
197     for (i = 0; i < ymax; i++)
198     scanpos[i] = -1;
199     /* display image */
200     if (greyscale)
201     greyimage();
202     else
203     mappedimage();
204     }
205    
206    
207     quiterr(err) /* print message and exit */
208     char *err;
209     {
210     if (initialized)
211     _setvideomode(_DEFAULTMODE);
212     if (err != NULL) {
213     fprintf(stderr, "%s: %s\n", progname, err);
214     exit(1);
215     }
216     exit(0);
217     }
218    
219    
220     int
221     docommand() /* execute command */
222     {
223     char buf[64];
224     COLOR cval;
225     int com;
226     double comp;
227    
228     while (!kbhit())
229     watch_mouse();
230     com = getch();
231     switch (com) { /* interpret command */
232     case 'q':
233     case CTRL('Z'): /* quit */
234     return(0);
235     case '\n':
236     case '\r':
237     case 'l':
238     case 'c': /* value */
239     if (avgbox(cval) == -1)
240     return(-1);
241     switch (com) {
242     case '\n':
243     case '\r': /* radiance */
244     sprintf(buf, "%.3f", intens(cval)/exposure);
245     break;
246     case 'l': /* luminance */
247     sprintf(buf, "%.0fL", luminance(cval)/exposure);
248     break;
249     case 'c': /* color */
250     comp = pow(2.0, (double)scale);
251     sprintf(buf, "(%.2f,%.2f,%.2f)",
252     colval(cval,RED)*comp,
253     colval(cval,GRN)*comp,
254     colval(cval,BLU)*comp);
255     break;
256     }
257     postext(box.xmin+box.xsiz/2, box.ymin+box.ysiz/2);
258 greg 2.2 hide_cursor();
259 greg 2.1 _outtext(buf);
260 greg 2.2 show_cursor();
261 greg 2.1 return(1);
262     default:
263     return(-1);
264     }
265     }
266    
267    
268     watch_mouse() /* look after mousie */
269     {
270     static int mouse_installed = 0;
271     int a_x, a_y, l_x, l_y;
272    
273     if (!mouse_installed) {
274     ms_init();
275     mouse_installed = 1;
276     }
277     if (mouse_event & M_MOTION)
278     move_cursor(mouse_xpos, mouse_ypos);
279     if (!(mouse_event & M_LDOWN))
280     return;
281     l_x = a_x = mouse_xpos; l_y = a_y = mouse_ypos;
282 greg 2.2 hide_cursor();
283 greg 2.1 revbox(a_x, a_y, l_x, l_y); /* show box */
284     do {
285     mouse_event = 0;
286     while (!mouse_event)
287     ;
288     if (mouse_event & M_MOTION) {
289     revbox(a_x, a_y, l_x, l_y);
290     revbox(a_x, a_y, l_x=mouse_xpos, l_y=mouse_ypos);
291     }
292     } while (!(mouse_event & M_LUP));
293     revbox(a_x, a_y, l_x, l_y); /* hide box */
294 greg 2.2 show_cursor();
295 greg 2.1 box.xmin = mouse_xpos;
296     box.ymin = mouse_ypos;
297     if (box.xmin > a_x) {
298     box.xsiz = box.xmin - a_x + 1;
299     box.xmin = a_x;
300     } else {
301     box.xsiz = a_x - box.xmin + 1;
302     }
303     if (box.ymin > a_y) {
304     box.ysiz = box.ymin - a_y + 1;
305     box.ymin = a_y;
306     } else {
307     box.ysiz = a_y - box.ymin + 1;
308     }
309     mouse_event = 0;
310     }
311    
312    
313     revbox(x0, y0, x1, y1) /* draw box with reversed lines */
314     int x0, y0, x1, y1;
315     {
316     _setplotaction(_GXOR);
317     _setcolor(255);
318     _moveto(x0, y0);
319     _lineto(x1, y0);
320     _lineto(x1, y1);
321     _lineto(x0, y1);
322     _lineto(x0, y0);
323     }
324    
325    
326     int
327     avgbox(clr) /* average color over current box */
328     COLOR clr;
329     {
330     static COLOR lc;
331     static int ll, lr, lt, lb;
332     int left, right, top, bottom;
333     int y;
334     double d;
335     COLOR ctmp;
336     register int x;
337    
338     setcolor(clr, 0.0, 0.0, 0.0);
339     left = box.xmin;
340     right = left + box.xsiz;
341     if (left < 0)
342     left = 0;
343     if (right > xmax)
344     right = xmax;
345     if (left >= right)
346     return(-1);
347     top = box.ymin;
348     bottom = top + box.ysiz;
349     if (top < 0)
350     top = 0;
351     if (bottom > ymax)
352     bottom = ymax;
353     if (top >= bottom)
354     return(-1);
355     if (left == ll && right == lr && top == lt && bottom == lb) {
356     copycolor(clr, lc);
357     return(0);
358     }
359     for (y = top; y < bottom; y++) {
360     if (getscan(y) == -1)
361     return(-1);
362     for (x = left; x < right; x++) {
363     colr_color(ctmp, scanline[x]);
364     addcolor(clr, ctmp);
365     }
366     }
367     d = 1.0/((right-left)*(bottom-top));
368     scalecolor(clr, d);
369     ll = left; lr = right; lt = top; lb = bottom;
370     copycolor(lc, clr);
371     return(0);
372     }
373    
374    
375     setpalette() /* set our palette using clrtab */
376     {
377     long cvals[256];
378     register int i;
379    
380     if (minpix >= 2) {
381     cvals[ourblack] = _BLACK; cvals[ourwhite] = _BRIGHTWHITE;
382     }
383     for (i = 0; i < maxcolors; i++)
384     cvals[i+minpix] = clrtab[i][BLU]<<14 & 0x3f0000L |
385     clrtab[i][GRN]<<6 & 0x3f00 |
386     clrtab[i][RED]>>2;
387     _remapallpalette(cvals);
388     }
389    
390    
391     greyimage() /* display greyscale image */
392     {
393     short thiscolor, lastcolor = -1;
394     int y;
395     register int x;
396     /* set gamma correction */
397     setcolrgam(gamcor);
398     /* set up color map */
399     for (x = 0; x < maxcolors; x++)
400     clrtab[x][RED] = clrtab[x][GRN] =
401     clrtab[x][BLU] = ((long)x*256+maxcolors/2)/maxcolors;
402     setpalette();
403     _setplotaction(_GPSET);
404     /* read and display file */
405     for (y = 0; y < ymax; y++) {
406     getscan(y);
407     if (scale)
408     shiftcolrs(scanline, xmax, scale);
409     colrs_gambs(scanline, xmax);
410     if (maxcolors < 256)
411     for (x = 0; x < xmax; x++) {
412     thiscolor = ((long)normbright(scanline[x]) *
413     maxcolors + 128) >> 8;
414     if (thiscolor != lastcolor)
415     _setcolor((lastcolor=thiscolor)+minpix);
416     _setpixel(x, y);
417     }
418     else
419     for (x = 0; x < xmax; x++) {
420     thiscolor = normbright(scanline[x]);
421     if (thiscolor != lastcolor)
422     _setcolor((lastcolor=thiscolor)+minpix);
423     _setpixel(x, y);
424     }
425     }
426     }
427    
428    
429     mappedimage() /* display color-mapped image */
430     {
431     BYTE bscan[MAXWIDTH];
432     int y;
433     register int x;
434     /* set gamma correction */
435     setcolrgam(gamcor);
436     /* make histogram */
437     new_histo();
438     for (y = 0; y < ymax; y++) {
439     if (getscan(y) < 0)
440     quiterr("seek error in getmapped");
441     if (scale)
442     shiftcolrs(scanline, xmax, scale);
443     colrs_gambs(scanline, xmax);
444     cnt_colrs(scanline, xmax);
445     }
446     /* map pixels */
447     if (!new_clrtab(maxcolors))
448     quiterr("cannot create color map");
449     setpalette();
450     _setplotaction(_GPSET);
451     /* display image */
452     for (y = 0; y < ymax; y++) {
453     if (getscan(y) < 0)
454     quiterr("seek error in getmapped");
455     if (scale)
456     shiftcolrs(scanline, xmax, scale);
457     colrs_gambs(scanline, xmax);
458     if (dither)
459     dith_colrs(bscan, scanline, xmax);
460     else
461     map_colrs(bscan, scanline, xmax);
462     for (x = 0; x < xmax; x++) {
463     if (x==0 || bscan[x] != bscan[x-1])
464     _setcolor(bscan[x]+minpix);
465     _setpixel(x, y);
466     }
467     }
468     }
469    
470    
471     getscan(y)
472     int y;
473     {
474     if (y != cury) {
475     if (scanpos[y] == -1)
476     return(-1);
477     if (fseek(fin, scanpos[y], 0) == -1)
478     quiterr("fseek error");
479     cury = y;
480     } else if (scanpos != NULL && scanpos[y] == -1)
481     scanpos[y] = ftell(fin);
482    
483     if (freadcolrs(scanline, xmax, fin) < 0)
484     quiterr("picture read error");
485    
486     cury++;
487     return(0);
488     }
489    
490    
491     /*
492     * Microsoft Mouse handling routines
493     */
494    
495    
496     #pragma off (check_stack)
497     void _loadds far mouse_handler (int max, int mcx, int mdx)
498     {
499     #pragma aux mouse_handler parm [EAX] [ECX] [EDX]
500     mouse_event = max;
501     mouse_xpos = mcx;
502     mouse_ypos = mdx * (long)ymax / 200; /* kludge */
503     if (mouse_xpos >= xmax) mouse_xpos = xmax-1;
504     if (mouse_ypos >= ymax) mouse_ypos = ymax-1;
505     }
506     #pragma on (check_stack)
507    
508    
509     void
510     move_cursor(newx, newy) /* move cursor to new position */
511     int newx, newy;
512     {
513     static char *imp = NULL;
514     static int curx = -1, cury = -1;
515     #define xcmin (curx-crad<0 ? 0 : curx-crad)
516     #define ycmin (cury-crad<0 ? 0 : cury-crad)
517     #define xcmax (curx+crad>=xmax ? xmax-1 : curx+crad)
518     #define ycmax (cury+crad>=ymax ? ymax-1 : cury+crad)
519    
520     if (newx == curx & newy == cury)
521     return;
522     if (imp == NULL &&
523     (imp = bmalloc(_imagesize(0,0,2*crad+1,2*crad+1))) == NULL) {
524     quiterr("out of memory in move_cursor");
525     }
526     if (curx >= 0 & cury >= 0) /* clear old cursor */
527     _putimage(xcmin, ycmin, imp, _GPSET);
528     /* record new position */
529     curx = newx; cury = newy;
530     if (curx < 0 | cury < 0)
531     return; /* no cursor */
532     /* save under new cursor */
533     _getimage(xcmin, ycmin, xcmax, ycmax, imp);
534     /* draw new cursor */
535     _setplotaction(_GPSET);
536     _setcolor(ourwhite);
537     _rectangle(_GFILLINTERIOR, xcmin, cury-1, xcmax, cury+1);
538     _rectangle(_GFILLINTERIOR, curx-1, ycmin, curx+1, ycmax);
539     _setcolor(ourblack);
540     _moveto(xcmin+1, cury);
541     _lineto(xcmax-1, cury);
542     _moveto(curx, ycmin+1);
543     _lineto(curx, ycmax-1);
544     #undef xcmin
545     #undef ycmin
546     #undef xcmax
547     #undef ycmax
548     }
549    
550    
551     int
552     ms_init()
553     {
554     struct SREGS sregs;
555     union REGS inregs, outregs;
556     int far *ptr;
557     int (far *function_ptr)();
558    
559     segread(&sregs);
560    
561     /* check for mouse driver */
562    
563     inregs.w.ax = 0;
564     int386 (0x33, &inregs, &outregs);
565     if( outregs.w.ax != -1 ) {
566     return(0);
567     }
568    
569     crad = ymax/40;
570    
571     /* install watcher */
572    
573     inregs.w.ax = 0xC;
574     inregs.w.cx = M_LDOWN | M_LUP | M_MOTION;
575     function_ptr = mouse_handler;
576     inregs.x.edx = FP_OFF( function_ptr );
577     sregs.es = FP_SEG( function_ptr );
578     int386x( 0x33, &inregs, &outregs, &sregs );
579    
580     return(1);
581     }