ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/vgaimage.c
Revision: 2.11
Committed: Fri Jan 2 12:47:01 2004 UTC (20 years, 3 months ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R6P1, rad3R6
Changes since 2.10: +9 -6 lines
Log Message:
Fixed typing/prototype of getheader() and its callback.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: vgaimage.c,v 2.10 2003/02/22 02:07:28 greg Exp $";
3 #endif
4 /*
5 * vgaimage.c - driver for VGA board under DOS
6 */
7
8 #include <stdio.h>
9
10 #include "standard.h"
11 #include <graph.h>
12 #include "color.h"
13 #include "random.h"
14 #include "resolu.h"
15 #include <dos.h>
16 #include <i86.h>
17
18 #define M_RDOWN 0x8
19 #define M_RUP 0x10
20 #define M_LDOWN 0x2
21 #define M_LUP 0x4
22 #define M_MOTION 0x1
23
24 int crad;
25 int mouse_event = 0;
26 int mouse_xpos = -1;
27 int mouse_ypos = -1;
28
29 #define hide_cursor() move_cursor(-1,-1)
30 #define show_cursor() move_cursor(mouse_xpos,mouse_ypos)
31
32 #define CTRL(c) ((c)-'@')
33
34 #define MAXWIDTH 1024
35 #define MAXHEIGHT 768
36
37 short ourblack = 0; ourwhite = 1;
38
39 double gamcor = 2.2; /* gamma correction */
40
41 int dither = 1; /* dither colors? */
42
43 int maxcolors = 0; /* maximum colors */
44 int minpix = 0; /* minimum pixel value */
45 int greyscale = 0; /* in grey */
46
47 int scale = 0; /* scalefactor; power of two */
48
49 COLR scanline[MAXWIDTH]; /* scan line buffer */
50
51 int xmax, ymax; /* picture dimensions */
52 FILE *fin = stdin; /* input file */
53 long scanpos[MAXHEIGHT]; /* scan line positions in file */
54 int cury = 0; /* current scan location */
55
56 double exposure = 1.0; /* exposure compensation used */
57
58 int wrongformat = 0; /* input in another format? */
59
60 struct {
61 int xmin, ymin, xsiz, ysiz;
62 } box = {0, 0, 0, 0}; /* current box */
63
64 int initialized = 0;
65 int cheight, cwidth;
66
67 #define postext(x,y) _settextposition(1+(y)/cheight,1+(x)/cwidth)
68
69 char *progname;
70
71 char errmsg[128];
72
73 extern BYTE clrtab[256][3]; /* global color map */
74
75 static gethfunc headline;
76
77
78 main(argc, argv)
79 int argc;
80 char *argv[];
81 {
82 extern char *getenv(), *fixargv0();
83 char *gv;
84 int i;
85
86 progname = argv[0] = fixargv0(argv[0]);
87 if ((gv = getenv("DISPLAY_GAMMA")) != NULL)
88 gamcor = atof(gv);
89
90 for (i = 1; i < argc; i++)
91 if (argv[i][0] == '-')
92 switch (argv[i][1]) {
93 case 'c':
94 maxcolors = atoi(argv[++i]);
95 break;
96 case 'b':
97 greyscale = !greyscale;
98 break;
99 case 'm':
100 maxcolors = 2;
101 break;
102 case 'd':
103 dither = !dither;
104 break;
105 case 'e':
106 if (argv[i+1][0] != '+' && argv[i+1][0] != '-')
107 goto userr;
108 scale = atoi(argv[++i]);
109 break;
110 case 'g':
111 gamcor = atof(argv[++i]);
112 break;
113 default:
114 goto userr;
115 }
116 else
117 break;
118
119 if (i == argc-1) { /* open picture */
120 fin = fopen(argv[i], "r");
121 if (fin == NULL) {
122 sprintf(errmsg, "cannot open file \"%s\"", argv[i]);
123 quiterr(errmsg);
124 }
125 } else if (i != argc)
126 goto userr;
127 setmode(fileno(fin), O_BINARY);
128 /* get header */
129 getheader(fin, headline, NULL);
130 /* get picture dimensions */
131 if (wrongformat || fgetresolu(&xmax, &ymax, fin) < 0)
132 quiterr("bad picture format");
133 if (xmax > MAXWIDTH | ymax > MAXHEIGHT)
134 quiterr("input picture too large for VGA");
135
136 init(); /* initialize and display */
137
138 while (docommand()) /* loop on command */
139 ;
140 quiterr(NULL);
141 userr:
142 fprintf(stderr,
143 "Usage: %s [-b][-m][-d][-c ncolors][-e +/-stops] file\n", progname);
144 exit(1);
145 }
146
147
148 static int
149 headline( /* get relevant info from header */
150 char *s,
151 void *p
152 )
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 return(0);
163 }
164
165
166 init() /* initialize and load display */
167 {
168 static struct {
169 short mode;
170 short xsiz, ysiz;
171 } video[] = {
172 {_MRES256COLOR, 320, 200},
173 {_VRES256COLOR, 640, 480},
174 {_SVRES256COLOR, 800, 600},
175 {_XRES256COLOR, 1024, 768},
176 {-1, 0, 0}
177 };
178 struct videoconfig config;
179 register int i;
180 /* 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 ms_init();
189 initialized = 1;
190 _getvideoconfig(&config);
191 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 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 quiterr(err) /* print message and exit */
212 char *err;
213 {
214 if (initialized) {
215 ms_done();
216 _setvideomode(_DEFAULTMODE);
217 }
218 if (err != NULL) {
219 fprintf(stderr, "%s: %s\n", progname, err);
220 exit(1);
221 }
222 exit(0);
223 }
224
225
226 int
227 docommand() /* execute command */
228 {
229 char buf[64];
230 COLOR cval;
231 int com;
232 double comp;
233
234 while (!kbhit())
235 watch_mouse();
236 com = getch();
237 switch (com) { /* interpret command */
238 case 'q':
239 case CTRL('Z'): /* quit */
240 return(0);
241 case '\n':
242 case '\r':
243 case 'l':
244 case 'c': /* value */
245 if (avgbox(cval) == -1)
246 return(-1);
247 switch (com) {
248 case '\n':
249 case '\r': /* radiance */
250 sprintf(buf, "%.3f", intens(cval)/exposure);
251 break;
252 case 'l': /* luminance */
253 sprintf(buf, "%.0fL", luminance(cval)/exposure);
254 break;
255 case 'c': /* color */
256 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 hide_cursor();
265 _outtext(buf);
266 show_cursor();
267 return(1);
268 default:
269 return(-1);
270 }
271 }
272
273
274 watch_mouse() /* look after mousie */
275 {
276 int a_x, a_y, l_x, l_y;
277
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 hide_cursor();
284 revbox(a_x, a_y, l_x, l_y); /* show box */
285 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 revbox(a_x, a_y, l_x, l_y); /* hide box */
295 show_cursor();
296 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 revbox(x0, y0, x1, y1) /* draw box with reversed lines */
315 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 avgbox(clr) /* average color over current box */
329 COLOR clr;
330 {
331 static COLOR lc;
332 static int ll, lr, lt, lb;
333 int left, right, top, bottom;
334 int y;
335 double d;
336 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 setpalette() /* set our palette using clrtab */
377 {
378 long cvals[256];
379 register int i;
380
381 cvals[ourblack] = _BLACK;
382 cvals[ourwhite] = _BRIGHTWHITE;
383 for (i = 0; i < maxcolors; i++)
384 cvals[i+minpix] = (long)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] = clrtab[x][BLU] =
401 ((long)x*256 + 128)/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 for (x = 0; x < xmax; x++)
410 scanline[x][GRN] = normbright(scanline[x]);
411 colrs_gambs(scanline, xmax);
412 if (maxcolors < 256)
413 for (x = 0; x < xmax; x++) {
414 thiscolor = ((long)scanline[x][GRN] *
415 maxcolors + maxcolors/2) / 256;
416 if (thiscolor != lastcolor)
417 _setcolor((lastcolor=thiscolor)+minpix);
418 _setpixel(x, y);
419 }
420 else
421 for (x = 0; x < xmax; x++) {
422 thiscolor = scanline[x][GRN];
423 if (thiscolor != lastcolor)
424 _setcolor((lastcolor=thiscolor)+minpix);
425 _setpixel(x, y);
426 }
427 }
428 }
429
430
431 mappedimage() /* display color-mapped image */
432 {
433 BYTE bscan[MAXWIDTH];
434 int y;
435 register int x;
436 /* set gamma correction */
437 setcolrgam(gamcor);
438 /* make histogram */
439 _outtext("Quantizing image -- Please wait...");
440 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 } else if (fin != stdin && scanpos[y] == -1)
484 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 mouse_ypos = mdx;
506 }
507 #pragma on (check_stack)
508
509
510 void
511 move_cursor(newx, newy) /* move cursor to new position */
512 int newx, newy;
513 {
514 static char *imp = NULL;
515 static int curx = -1, cury = -1;
516 #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
521 if (newx == curx & newy == cury)
522 return;
523 if (imp == NULL &&
524 (imp = bmalloc(_imagesize(0,0,2*crad+1,2*crad+1))) == NULL) {
525 quiterr("out of memory in move_cursor");
526 }
527 if (curx >= 0 & cury >= 0) /* clear old cursor */
528 _putimage(xcmin, ycmin, imp, _GPSET);
529 /* record new position */
530 curx = newx; cury = newy;
531 if (curx < 0 | cury < 0)
532 return; /* no cursor */
533 /* 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
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 /* 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 sregs.es = FP_SEG( function_ptr );
590 int386x( 0x33, &inregs, &outregs, &sregs );
591
592 return(1);
593 }
594
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 }