ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/vgaimage.c
Revision: 2.6
Committed: Tue Mar 30 11:37:54 1993 UTC (31 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.5: +3 -3 lines
Log Message:
minor bug fix

File Contents

# Content
1 /* Copyright (c) 1993 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 #define hide_cursor() move_cursor(-1,-1)
31 #define show_cursor() move_cursor(mouse_xpos,mouse_ypos)
32
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, 480},
172 {_SVRES256COLOR, 800, 600},
173 {_XRES256COLOR, 1024, 768},
174 {-1, 0, 0}
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 ms_init();
187 initialized = 1;
188 _getvideoconfig(&config);
189 if (maxcolors == 0 | maxcolors > config.numcolors)
190 maxcolors = config.numcolors-2;
191 if (maxcolors <= config.numcolors-2)
192 minpix = 2;
193 else
194 ourwhite = maxcolors-1;
195 _settextcolor(ourwhite);
196 cheight = config.numypixels/config.numtextrows;
197 cwidth = config.numxpixels/config.numtextcols;
198 /* clear scan position array */
199 for (i = 0; i < ymax; i++)
200 scanpos[i] = -1;
201 /* display image */
202 if (greyscale)
203 greyimage();
204 else
205 mappedimage();
206 }
207
208
209 quiterr(err) /* print message and exit */
210 char *err;
211 {
212 if (initialized) {
213 ms_done();
214 _setvideomode(_DEFAULTMODE);
215 }
216 if (err != NULL) {
217 fprintf(stderr, "%s: %s\n", progname, err);
218 exit(1);
219 }
220 exit(0);
221 }
222
223
224 int
225 docommand() /* execute command */
226 {
227 char buf[64];
228 COLOR cval;
229 int com;
230 double comp;
231
232 while (!kbhit())
233 watch_mouse();
234 com = getch();
235 switch (com) { /* interpret command */
236 case 'q':
237 case CTRL('Z'): /* quit */
238 return(0);
239 case '\n':
240 case '\r':
241 case 'l':
242 case 'c': /* value */
243 if (avgbox(cval) == -1)
244 return(-1);
245 switch (com) {
246 case '\n':
247 case '\r': /* radiance */
248 sprintf(buf, "%.3f", intens(cval)/exposure);
249 break;
250 case 'l': /* luminance */
251 sprintf(buf, "%.0fL", luminance(cval)/exposure);
252 break;
253 case 'c': /* color */
254 comp = pow(2.0, (double)scale);
255 sprintf(buf, "(%.2f,%.2f,%.2f)",
256 colval(cval,RED)*comp,
257 colval(cval,GRN)*comp,
258 colval(cval,BLU)*comp);
259 break;
260 }
261 postext(box.xmin+box.xsiz/2, box.ymin+box.ysiz/2);
262 hide_cursor();
263 _outtext(buf);
264 show_cursor();
265 return(1);
266 default:
267 return(-1);
268 }
269 }
270
271
272 watch_mouse() /* look after mousie */
273 {
274 int a_x, a_y, l_x, l_y;
275
276 if (mouse_event & M_MOTION)
277 move_cursor(mouse_xpos, mouse_ypos);
278 if (!(mouse_event & M_LDOWN))
279 return;
280 l_x = a_x = mouse_xpos; l_y = a_y = mouse_ypos;
281 hide_cursor();
282 revbox(a_x, a_y, l_x, l_y); /* show box */
283 do {
284 mouse_event = 0;
285 while (!mouse_event)
286 ;
287 if (mouse_event & M_MOTION) {
288 revbox(a_x, a_y, l_x, l_y);
289 revbox(a_x, a_y, l_x=mouse_xpos, l_y=mouse_ypos);
290 }
291 } while (!(mouse_event & M_LUP));
292 revbox(a_x, a_y, l_x, l_y); /* hide box */
293 show_cursor();
294 box.xmin = mouse_xpos;
295 box.ymin = mouse_ypos;
296 if (box.xmin > a_x) {
297 box.xsiz = box.xmin - a_x + 1;
298 box.xmin = a_x;
299 } else {
300 box.xsiz = a_x - box.xmin + 1;
301 }
302 if (box.ymin > a_y) {
303 box.ysiz = box.ymin - a_y + 1;
304 box.ymin = a_y;
305 } else {
306 box.ysiz = a_y - box.ymin + 1;
307 }
308 mouse_event = 0;
309 }
310
311
312 revbox(x0, y0, x1, y1) /* draw box with reversed lines */
313 int x0, y0, x1, y1;
314 {
315 _setplotaction(_GXOR);
316 _setcolor(255);
317 _moveto(x0, y0);
318 _lineto(x1, y0);
319 _lineto(x1, y1);
320 _lineto(x0, y1);
321 _lineto(x0, y0);
322 }
323
324
325 int
326 avgbox(clr) /* average color over current box */
327 COLOR clr;
328 {
329 static COLOR lc;
330 static int ll, lr, lt, lb;
331 int left, right, top, bottom;
332 int y;
333 double d;
334 COLOR ctmp;
335 register int x;
336
337 setcolor(clr, 0.0, 0.0, 0.0);
338 left = box.xmin;
339 right = left + box.xsiz;
340 if (left < 0)
341 left = 0;
342 if (right > xmax)
343 right = xmax;
344 if (left >= right)
345 return(-1);
346 top = box.ymin;
347 bottom = top + box.ysiz;
348 if (top < 0)
349 top = 0;
350 if (bottom > ymax)
351 bottom = ymax;
352 if (top >= bottom)
353 return(-1);
354 if (left == ll && right == lr && top == lt && bottom == lb) {
355 copycolor(clr, lc);
356 return(0);
357 }
358 for (y = top; y < bottom; y++) {
359 if (getscan(y) == -1)
360 return(-1);
361 for (x = left; x < right; x++) {
362 colr_color(ctmp, scanline[x]);
363 addcolor(clr, ctmp);
364 }
365 }
366 d = 1.0/((right-left)*(bottom-top));
367 scalecolor(clr, d);
368 ll = left; lr = right; lt = top; lb = bottom;
369 copycolor(lc, clr);
370 return(0);
371 }
372
373
374 setpalette() /* set our palette using clrtab */
375 {
376 long cvals[256];
377 register int i;
378
379 cvals[ourblack] = _BLACK;
380 cvals[ourwhite] = _BRIGHTWHITE;
381 for (i = 0; i < maxcolors; i++)
382 cvals[i+minpix] = clrtab[i][BLU]<<14 & 0x3f0000L |
383 clrtab[i][GRN]<<6 & 0x3f00 |
384 clrtab[i][RED]>>2;
385 _remapallpalette(cvals);
386 }
387
388
389 greyimage() /* display greyscale image */
390 {
391 short thiscolor, lastcolor = -1;
392 int y;
393 register int x;
394 /* set gamma correction */
395 setcolrgam(gamcor);
396 /* set up color map */
397 for (x = 0; x < maxcolors; x++)
398 clrtab[x][RED] = clrtab[x][GRN] = clrtab[x][BLU] =
399 ((long)x*256 + 128)/maxcolors;
400 setpalette();
401 _setplotaction(_GPSET);
402 /* read and display file */
403 for (y = 0; y < ymax; y++) {
404 getscan(y);
405 if (scale)
406 shiftcolrs(scanline, xmax, scale);
407 for (x = 0; x < xmax; x++)
408 scanline[x][GRN] = normbright(scanline[x]);
409 colrs_gambs(scanline, xmax);
410 if (maxcolors < 256)
411 for (x = 0; x < xmax; x++) {
412 thiscolor = ((long)scanline[x][GRN] *
413 maxcolors + maxcolors/2) / 256;
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 = scanline[x][GRN];
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 _outtext("Quantizing image -- Please wait...");
438 new_histo();
439 for (y = 0; y < ymax; y++) {
440 if (getscan(y) < 0)
441 quiterr("seek error in getmapped");
442 if (scale)
443 shiftcolrs(scanline, xmax, scale);
444 colrs_gambs(scanline, xmax);
445 cnt_colrs(scanline, xmax);
446 }
447 /* map pixels */
448 if (!new_clrtab(maxcolors))
449 quiterr("cannot create color map");
450 setpalette();
451 _setplotaction(_GPSET);
452 /* display image */
453 for (y = 0; y < ymax; y++) {
454 if (getscan(y) < 0)
455 quiterr("seek error in getmapped");
456 if (scale)
457 shiftcolrs(scanline, xmax, scale);
458 colrs_gambs(scanline, xmax);
459 if (dither)
460 dith_colrs(bscan, scanline, xmax);
461 else
462 map_colrs(bscan, scanline, xmax);
463 for (x = 0; x < xmax; x++) {
464 if (x==0 || bscan[x] != bscan[x-1])
465 _setcolor(bscan[x]+minpix);
466 _setpixel(x, y);
467 }
468 }
469 }
470
471
472 getscan(y)
473 int y;
474 {
475 if (y != cury) {
476 if (scanpos[y] == -1)
477 return(-1);
478 if (fseek(fin, scanpos[y], 0) == -1)
479 quiterr("fseek error");
480 cury = y;
481 } else if (fin != stdin && scanpos[y] == -1)
482 scanpos[y] = ftell(fin);
483
484 if (freadcolrs(scanline, xmax, fin) < 0)
485 quiterr("picture read error");
486
487 cury++;
488 return(0);
489 }
490
491
492 /*
493 * Microsoft Mouse handling routines
494 */
495
496
497 #pragma off (check_stack)
498 void _loadds far mouse_handler (int max, int mcx, int mdx)
499 {
500 #pragma aux mouse_handler parm [EAX] [ECX] [EDX]
501 mouse_event = max;
502 mouse_xpos = mcx;
503 mouse_ypos = mdx;
504 }
505 #pragma on (check_stack)
506
507
508 void
509 move_cursor(newx, newy) /* move cursor to new position */
510 int newx, newy;
511 {
512 static char *imp = NULL;
513 static int curx = -1, cury = -1;
514 #define xcmin (curx-crad<0 ? 0 : curx-crad)
515 #define ycmin (cury-crad<0 ? 0 : cury-crad)
516 #define xcmax (curx+crad>=xmax ? xmax-1 : curx+crad)
517 #define ycmax (cury+crad>=ymax ? ymax-1 : cury+crad)
518
519 if (newx == curx & newy == cury)
520 return;
521 if (imp == NULL &&
522 (imp = bmalloc(_imagesize(0,0,2*crad+1,2*crad+1))) == NULL) {
523 quiterr("out of memory in move_cursor");
524 }
525 if (curx >= 0 & cury >= 0) /* clear old cursor */
526 _putimage(xcmin, ycmin, imp, _GPSET);
527 /* record new position */
528 curx = newx; cury = newy;
529 if (curx < 0 | cury < 0)
530 return; /* no cursor */
531 /* save under new cursor */
532 _getimage(xcmin, ycmin, xcmax, ycmax, imp);
533 /* draw new cursor */
534 _setplotaction(_GPSET);
535 _setcolor(ourwhite);
536 _rectangle(_GFILLINTERIOR, xcmin, cury-1, xcmax, cury+1);
537 _rectangle(_GFILLINTERIOR, curx-1, ycmin, curx+1, ycmax);
538 _setcolor(ourblack);
539 _moveto(xcmin+1, cury);
540 _lineto(xcmax-1, cury);
541 _moveto(curx, ycmin+1);
542 _lineto(curx, ycmax-1);
543 #undef xcmin
544 #undef ycmin
545 #undef xcmax
546 #undef ycmax
547 }
548
549
550 int
551 ms_init()
552 {
553 struct SREGS sregs;
554 union REGS inregs, outregs;
555 int far *ptr;
556 int (far *function_ptr)();
557
558 segread(&sregs);
559
560 /* check for mouse driver */
561
562 inregs.w.ax = 0;
563 int386 (0x33, &inregs, &outregs);
564 if( outregs.w.ax != -1 ) {
565 return(0);
566 }
567
568 crad = ymax/40;
569
570 /* set screen limits */
571
572 inregs.w.ax = 0x7; /* horizontal resolution */
573 inregs.w.cx = 0;
574 inregs.w.dx = xmax-1;
575 int386x( 0x33, &inregs, &outregs, &sregs );
576 inregs.w.ax = 0x8; /* vertical resolution */
577 inregs.w.cx = 0;
578 inregs.w.dx = ymax-1;
579 int386x( 0x33, &inregs, &outregs, &sregs );
580
581 /* install watcher */
582
583 inregs.w.ax = 0xC;
584 inregs.w.cx = M_LDOWN | M_LUP | M_MOTION;
585 function_ptr = mouse_handler;
586 inregs.x.edx = FP_OFF( function_ptr );
587 sregs.es = FP_SEG( function_ptr );
588 int386x( 0x33, &inregs, &outregs, &sregs );
589
590 return(1);
591 }
592
593 ms_done()
594 {
595 union REGS inregs, outregs;
596
597 /* uninstall watcher */
598
599 inregs.w.ax = 0;
600 int386 (0x33, &inregs, &outregs);
601 }