| 1 | greg | 2.1 | #ifndef lint | 
| 2 | greg | 2.12 | static const char       RCSid[] = "$Id: vgaimage.c,v 2.11 2004/01/02 12:47:01 schorsch 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 |  |  | } |