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

# User Rev Content
1 greg 2.1 #ifndef lint
2 schorsch 2.11 static const char RCSid[] = "$Id: vgaimage.c,v 2.10 2003/02/22 02:07:28 greg Exp $";
3 greg 2.1 #endif
4     /*
5     * vgaimage.c - driver for VGA board under DOS
6     */
7    
8 schorsch 2.11 #include <stdio.h>
9    
10 greg 2.1 #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 greg 2.3 #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 greg 2.1
24     int crad;
25     int mouse_event = 0;
26     int mouse_xpos = -1;
27     int mouse_ypos = -1;
28    
29 greg 2.3 #define hide_cursor() move_cursor(-1,-1)
30     #define show_cursor() move_cursor(mouse_xpos,mouse_ypos)
31 greg 2.1
32 greg 2.3 #define CTRL(c) ((c)-'@')
33 greg 2.1
34 greg 2.3 #define MAXWIDTH 1024
35     #define MAXHEIGHT 768
36 greg 2.1
37     short ourblack = 0; ourwhite = 1;
38    
39 greg 2.3 double gamcor = 2.2; /* gamma correction */
40 greg 2.1
41 greg 2.3 int dither = 1; /* dither colors? */
42 greg 2.1
43 greg 2.3 int maxcolors = 0; /* maximum colors */
44     int minpix = 0; /* minimum pixel value */
45     int greyscale = 0; /* in grey */
46 greg 2.1
47 greg 2.3 int scale = 0; /* scalefactor; power of two */
48 greg 2.1
49 greg 2.3 COLR scanline[MAXWIDTH]; /* scan line buffer */
50 greg 2.1
51 greg 2.3 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 greg 2.1
56 greg 2.3 double exposure = 1.0; /* exposure compensation used */
57 greg 2.1
58 greg 2.3 int wrongformat = 0; /* input in another format? */
59 greg 2.1
60     struct {
61     int xmin, ymin, xsiz, ysiz;
62 greg 2.3 } box = {0, 0, 0, 0}; /* current box */
63 greg 2.1
64     int initialized = 0;
65     int cheight, cwidth;
66    
67 greg 2.3 #define postext(x,y) _settextposition(1+(y)/cheight,1+(x)/cwidth)
68 greg 2.1
69     char *progname;
70    
71     char errmsg[128];
72    
73 greg 2.3 extern BYTE clrtab[256][3]; /* global color map */
74 greg 2.1
75 schorsch 2.11 static gethfunc headline;
76 greg 2.1
77    
78     main(argc, argv)
79     int argc;
80     char *argv[];
81     {
82     extern char *getenv(), *fixargv0();
83     char *gv;
84     int i;
85 greg 2.3
86 greg 2.1 progname = argv[0] = fixargv0(argv[0]);
87 greg 2.8 if ((gv = getenv("DISPLAY_GAMMA")) != NULL)
88 greg 2.1 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 greg 2.3 if (i == argc-1) { /* open picture */
120 greg 2.1 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 greg 2.3 init(); /* initialize and display */
137 greg 2.1
138 greg 2.3 while (docommand()) /* loop on command */
139 greg 2.1 ;
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 schorsch 2.11 static int
149     headline( /* get relevant info from header */
150     char *s,
151     void *p
152     )
153 greg 2.1 {
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     }