ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/vgaimage.c
Revision: 2.9
Committed: Tue Oct 27 09:08:28 1998 UTC (25 years, 6 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Changes since 2.8: +2 -0 lines
Log Message:
changed getheader() to listen to return value of passed function

File Contents

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