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

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.10 static const char RCSid[] = "$Id$";
3 greg 2.1 #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 greg 2.3 #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 greg 2.1
22     int crad;
23     int mouse_event = 0;
24     int mouse_xpos = -1;
25     int mouse_ypos = -1;
26    
27 greg 2.3 #define hide_cursor() move_cursor(-1,-1)
28     #define show_cursor() move_cursor(mouse_xpos,mouse_ypos)
29 greg 2.1
30 greg 2.3 #define CTRL(c) ((c)-'@')
31 greg 2.1
32 greg 2.3 #define MAXWIDTH 1024
33     #define MAXHEIGHT 768
34 greg 2.1
35     short ourblack = 0; ourwhite = 1;
36    
37 greg 2.3 double gamcor = 2.2; /* gamma correction */
38 greg 2.1
39 greg 2.3 int dither = 1; /* dither colors? */
40 greg 2.1
41 greg 2.3 int maxcolors = 0; /* maximum colors */
42     int minpix = 0; /* minimum pixel value */
43     int greyscale = 0; /* in grey */
44 greg 2.1
45 greg 2.3 int scale = 0; /* scalefactor; power of two */
46 greg 2.1
47 greg 2.3 COLR scanline[MAXWIDTH]; /* scan line buffer */
48 greg 2.1
49 greg 2.3 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 greg 2.1
54 greg 2.3 double exposure = 1.0; /* exposure compensation used */
55 greg 2.1
56 greg 2.3 int wrongformat = 0; /* input in another format? */
57 greg 2.1
58     struct {
59     int xmin, ymin, xsiz, ysiz;
60 greg 2.3 } box = {0, 0, 0, 0}; /* current box */
61 greg 2.1
62     int initialized = 0;
63     int cheight, cwidth;
64    
65 greg 2.3 #define postext(x,y) _settextposition(1+(y)/cheight,1+(x)/cwidth)
66 greg 2.1
67     char *progname;
68    
69     char errmsg[128];
70    
71 greg 2.3 extern BYTE clrtab[256][3]; /* global color map */
72 greg 2.1
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 greg 2.3
85 greg 2.1 progname = argv[0] = fixargv0(argv[0]);
86 greg 2.8 if ((gv = getenv("DISPLAY_GAMMA")) != NULL)
87 greg 2.1 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 greg 2.3 if (i == argc-1) { /* open picture */
119 greg 2.1 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 greg 2.3 init(); /* initialize and display */
136 greg 2.1
137 greg 2.3 while (docommand()) /* loop on command */
138 greg 2.1 ;
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 gwlarson 2.9 int
148 greg 2.3 headline(s) /* get relevant info from header */
149 greg 2.1 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 gwlarson 2.9 return(0);
160 greg 2.1 }
161    
162    
163 greg 2.3 init() /* initialize and load display */
164 greg 2.1 {
165     static struct {
166 greg 2.3 short mode;
167     short xsiz, ysiz;
168     } video[] = {
169 greg 2.1 {_MRES256COLOR, 320, 200},
170 greg 2.6 {_VRES256COLOR, 640, 480},
171 greg 2.1 {_SVRES256COLOR, 800, 600},
172     {_XRES256COLOR, 1024, 768},
173 greg 2.6 {-1, 0, 0}
174 greg 2.1 };
175 greg 2.3 struct videoconfig config;
176     register int i;
177 greg 2.1 /* 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 greg 2.4 ms_init();
186 greg 2.1 initialized = 1;
187     _getvideoconfig(&config);
188 greg 2.5 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 greg 2.1 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 greg 2.3 quiterr(err) /* print message and exit */
209 greg 2.1 char *err;
210     {
211 greg 2.4 if (initialized) {
212     ms_done();
213 greg 2.1 _setvideomode(_DEFAULTMODE);
214 greg 2.4 }
215 greg 2.1 if (err != NULL) {
216     fprintf(stderr, "%s: %s\n", progname, err);
217     exit(1);
218     }
219     exit(0);
220     }
221    
222    
223     int
224 greg 2.3 docommand() /* execute command */
225 greg 2.1 {
226     char buf[64];
227     COLOR cval;
228     int com;
229 greg 2.3 double comp;
230 greg 2.1
231     while (!kbhit())
232     watch_mouse();
233     com = getch();
234 greg 2.3 switch (com) { /* interpret command */
235 greg 2.1 case 'q':
236 greg 2.3 case CTRL('Z'): /* quit */
237 greg 2.1 return(0);
238     case '\n':
239     case '\r':
240     case 'l':
241 greg 2.3 case 'c': /* value */
242 greg 2.1 if (avgbox(cval) == -1)
243     return(-1);
244     switch (com) {
245     case '\n':
246 greg 2.3 case '\r': /* radiance */
247 greg 2.1 sprintf(buf, "%.3f", intens(cval)/exposure);
248     break;
249 greg 2.3 case 'l': /* luminance */
250 greg 2.1 sprintf(buf, "%.0fL", luminance(cval)/exposure);
251     break;
252 greg 2.3 case 'c': /* color */
253 greg 2.1 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 greg 2.2 hide_cursor();
262 greg 2.1 _outtext(buf);
263 greg 2.2 show_cursor();
264 greg 2.1 return(1);
265     default:
266     return(-1);
267     }
268     }
269    
270    
271 greg 2.3 watch_mouse() /* look after mousie */
272 greg 2.1 {
273 greg 2.3 int a_x, a_y, l_x, l_y;
274 greg 2.1
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 greg 2.2 hide_cursor();
281 greg 2.3 revbox(a_x, a_y, l_x, l_y); /* show box */
282 greg 2.1 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 greg 2.3 revbox(a_x, a_y, l_x, l_y); /* hide box */
292 greg 2.2 show_cursor();
293 greg 2.1 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 greg 2.3 revbox(x0, y0, x1, y1) /* draw box with reversed lines */
312 greg 2.1 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 greg 2.3 avgbox(clr) /* average color over current box */
326 greg 2.1 COLOR clr;
327     {
328     static COLOR lc;
329     static int ll, lr, lt, lb;
330     int left, right, top, bottom;
331     int y;
332 greg 2.3 double d;
333 greg 2.1 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 greg 2.3 setpalette() /* set our palette using clrtab */
374 greg 2.1 {
375 greg 2.3 long cvals[256];
376     register int i;
377 greg 2.1
378 greg 2.5 cvals[ourblack] = _BLACK;
379     cvals[ourwhite] = _BRIGHTWHITE;
380 greg 2.1 for (i = 0; i < maxcolors; i++)
381 greg 2.7 cvals[i+minpix] = (long)clrtab[i][BLU]<<14 & 0x3f0000L |
382 greg 2.1 clrtab[i][GRN]<<6 & 0x3f00 |
383     clrtab[i][RED]>>2;
384     _remapallpalette(cvals);
385     }
386    
387    
388 greg 2.3 greyimage() /* display greyscale image */
389 greg 2.1 {
390 greg 2.3 short thiscolor, lastcolor = -1;
391     int y;
392     register int x;
393 greg 2.1 /* set gamma correction */
394     setcolrgam(gamcor);
395     /* set up color map */
396     for (x = 0; x < maxcolors; x++)
397 greg 2.5 clrtab[x][RED] = clrtab[x][GRN] = clrtab[x][BLU] =
398     ((long)x*256 + 128)/maxcolors;
399 greg 2.1 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 greg 2.5 for (x = 0; x < xmax; x++)
407     scanline[x][GRN] = normbright(scanline[x]);
408 greg 2.1 colrs_gambs(scanline, xmax);
409     if (maxcolors < 256)
410 greg 2.3 for (x = 0; x < xmax; x++) {
411 greg 2.5 thiscolor = ((long)scanline[x][GRN] *
412     maxcolors + maxcolors/2) / 256;
413 greg 2.1 if (thiscolor != lastcolor)
414     _setcolor((lastcolor=thiscolor)+minpix);
415     _setpixel(x, y);
416     }
417     else
418     for (x = 0; x < xmax; x++) {
419 greg 2.5 thiscolor = scanline[x][GRN];
420 greg 2.1 if (thiscolor != lastcolor)
421     _setcolor((lastcolor=thiscolor)+minpix);
422     _setpixel(x, y);
423     }
424     }
425     }
426    
427    
428 greg 2.3 mappedimage() /* display color-mapped image */
429 greg 2.1 {
430 greg 2.3 BYTE bscan[MAXWIDTH];
431     int y;
432     register int x;
433 greg 2.1 /* set gamma correction */
434     setcolrgam(gamcor);
435     /* make histogram */
436 greg 2.4 _outtext("Quantizing image -- Please wait...");
437 greg 2.1 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 greg 2.5 } else if (fin != stdin && scanpos[y] == -1)
481 greg 2.1 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 greg 2.3 mouse_ypos = mdx;
503 greg 2.1 }
504     #pragma on (check_stack)
505    
506    
507     void
508 greg 2.3 move_cursor(newx, newy) /* move cursor to new position */
509 greg 2.1 int newx, newy;
510     {
511     static char *imp = NULL;
512     static int curx = -1, cury = -1;
513 greg 2.3 #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 greg 2.1
518     if (newx == curx & newy == cury)
519     return;
520 greg 2.3 if (imp == NULL &&
521 greg 2.1 (imp = bmalloc(_imagesize(0,0,2*crad+1,2*crad+1))) == NULL) {
522     quiterr("out of memory in move_cursor");
523     }
524 greg 2.3 if (curx >= 0 & cury >= 0) /* clear old cursor */
525 greg 2.1 _putimage(xcmin, ycmin, imp, _GPSET);
526     /* record new position */
527     curx = newx; cury = newy;
528     if (curx < 0 | cury < 0)
529 greg 2.3 return; /* no cursor */
530 greg 2.1 /* 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 greg 2.3
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 greg 2.1 /* 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 greg 2.3 sregs.es = FP_SEG( function_ptr );
587 greg 2.1 int386x( 0x33, &inregs, &outregs, &sregs );
588 greg 2.3
589 greg 2.1 return(1);
590     }
591 greg 2.4
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     }