ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/vgaimage.c
Revision: 2.10
Committed: Sat Feb 22 02:07:28 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Changes since 2.9: +1 -4 lines
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

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