/*LINTLIBRARY*/ /* @(#)kerterm.c 1.2 89/12/11 * * Popi graphics driver for kermit TERM windows. * written by Frank Crawford - Q.H.Tours. * * Popi was originally written by Gerard J. Holzmann - AT&T Bell Labs. * This version is based on the code in his Prentice Hall book, * "Beyond Photography - the digital darkroom," ISBN 0-13-074410-7, * which is copyright (c) 1988 by Bell Telephone Laboratories, Inc. * * Permission is given to distribute these extensions, as long as these * introductory messages are not removed, and no monies are exchanged. * * No responsibility is taken for any errors or inaccuracies inherent * either to the comments or the code of this program, but if reported * (see README file) then an attempt will be made to fix them. */ #include #include #include #include "popi.h" #define KER_MAX_X 1023 /* Maximum Kermit X value */ #define KER_MAX_Y 779 /* Maximum Kermit Y value */ #define PC_MAX_X 640 /* Number of PC X value (EGA Card) */ #define PC_MAX_Y 350 /* Number of PC Y value (EGA Card) */ #define MAX_GREY 2 /* Max. Greyscale value (Black, Low-int, Hi-int) */ int thresh[MAX_GREY][BITSPERPIXEL][BITSPERPIXEL] = { { /* Array containing threshold values for low value. */ { 0, 64, 16, 80, 4, 68, 20, 84, }, { 96, 32, 112, 48, 100, 36, 116, 52, }, { 24, 88, 8, 72, 28, 92, 12, 76, }, { 120, 56, 104, 40, 124, 60, 108, 44, }, { 6, 70, 22, 86, 2, 66, 18, 82, }, { 102, 38, 118, 54, 98, 34, 114, 50, }, { 30, 94, 14, 78, 26, 90, 10, 74, }, { 126, 62, 110, 46, 122, 58, 106, 42, }, }, { /* Array containing threshold values for high value. */ { 128, 192, 144, 208, 132, 196, 148, 212, }, { 224, 160, 240, 176, 228, 164, 244, 180, }, { 152, 216, 136, 200, 156, 220, 140, 204, }, { 248, 184, 232, 168, 252, 188, 236, 172, }, { 134, 198, 150, 214, 130, 194, 146, 210, }, { 230, 166, 246, 182, 226, 162, 242, 178, }, { 158, 222, 142, 206, 154, 218, 138, 202, }, { 254, 190, 238, 174, 250, 186, 234, 170, }, }, }; /* There are ten exportable routines used by the popi program. * * These are: * * disp_init(argc, argv) - called from main at the start. * disp_finish() - called from main prior to exit. * disp_imgstart() - called prior to drawing an image. * disp_imgend() - called after drawing an image. * disp_putline(line, y) - to draw an image scanline. * disp_getchar() - to get the next character typed. * disp_ungetc(c) - put back the last character typed. * disp_prompt() - display popi prompt and clear input buffer. * disp_error(errtype) - display error message. * disp_percentdone(n) - display percentage value of conversion. */ /*ARGSUSED*/ void disp_init(argc,argv) int argc; char *argv[]; { } void disp_finish() { } void disp_intr(signal) int signal; { disp_imgend(); exit(signal); } void disp_imgstart() { (void) signal(SIGINT, disp_intr); putchar('\033'); putchar('\f'); } void disp_imgend() { char ch; putchar('\033'); putchar('['); putchar('0'); putchar('m'); PRINTF("\037\n\n\007Hit return when ready:"); fflush(stdout); while (read(1, &ch, 1) == 1 && ch != '\n') /* Because of inconsistent use */ ; putchar('\033'); putchar('['); putchar('?'); putchar('3'); putchar('8'); putchar('l'); fflush(stdout); (void) signal(SIGINT, SIG_DFL); } static void coord(x, y, repeat) int x, y; int repeat; { /* * This function goes to a lot of effort to optimes the number of * characters sent down the line. */ int hi_x, lo_x, hi_y, lo_y; static int sav_x = -1, sav_y = -1; y = KER_MAX_Y - y; /* To invert picture */ hi_x = (x / 32); lo_x = (x % 32); hi_y = (y / 32); lo_y = (y % 32); if (!repeat || y != sav_y) { putchar(hi_y + 0x20); putchar(lo_y + 0x60); putchar(hi_x + 0x20); } else if (hi_x != (sav_x / 32)) { putchar(lo_y + 0x60); putchar(hi_x + 0x20); } putchar(lo_x + 0x40); sav_x = x; sav_y = y; } void disp_putline(line,y) /* Output scanline y. */ pixel_t *line; int y; { int x; int real_x, real_y; int repeat, level; static old_level = 0; repeat = 0; /* * Calculate the real pixel location to handle the grey-scale threshold * values. */ real_y = (y * PC_MAX_Y) / (KER_MAX_Y + 1); putchar('\034'); for (x = 0; x < Xsize; x++, line++) { /* See above */ real_x = (x * PC_MAX_X) / (KER_MAX_X + 1); for (level = 0; level < MAX_GREY; level++) if (*line < thresh[level][real_y % BITSPERPIXEL][real_x % BITSPERPIXEL]) break; if (level != old_level) { if (level != 0) { putchar('\033'); putchar('['); putchar((level == 1) ? '0' : '1'); putchar('m'); } old_level = level; } if (level != 0) coord(x, y, repeat++); } putchar('\n'); } disp_getchar() /* Get next user typed character. */ { return(getchar()); } void disp_ungetc(c) /* Put back the last character typed. */ char c ; { UNGETC(c, stdin); } disp_prompt() /* Display popi prompt and clear input line. */ { PRINTF("-> "); return 3; } void disp_error(errtype, pos) /* Display error message. */ int errtype, pos ; { extern int errno; extern char *sys_errlist[]; if (errtype & ERR_PARSE) { int i; for (i=1; i < pos; ++i) PUTC('-', stderr); PUTC('^', stderr); PUTC('\n', stderr); } FPRINTF(stderr, "%s\n", ErrBuf); /* we assume errno hasn't been reset by the preceding output */ if (errtype & ERR_SYS) FPRINTF(stderr, "\t(%s)\n", sys_errlist[errno]); } void disp_percentdone(percent) int percent; { static int lastpercent = 100; if (!Verbose) return; if (percent == 100) { printf("\r \n"); return; } if (percent != lastpercent && percent % 5 == 0) { printf("\r%2d%% ", percent); fflush(stdout); lastpercent = percent; } }