clb) (01/24/88)
This program "mac73" reads MacPaint files and displays them on the unixpc (PC7300) console. This routine is based on the program "showPaint" by Rick Kimball (flnexus!kimbal!rick) which appeared recently on the net. However, this routine is completely rewritten and shares nothing in actual code. Functional differences: preserves aspect ratio (circles are circles, not ellipses.) steps through entire image, not just top. Structural differences: expects to be run in 80x24 window, doesn't create new window. displays image scan by scan, direct from disk: no buffering. Creation is by ... cc mac73.c -s -o mac73 Execution is by ... $ mac73 McPaint.pic where "McPaint.pic" is the MacPaint file. It will locate the data fork, unpack and invert the picture, then display the top 288 lines centered horizonally. The program will wait for a "newline", and then shift the image upward, displaying a center slice and wait for a newline. When the user responds, the program moves the image upward to show the bottom of the picture and exits. Note that this program doesn't create a new window, and expects a 80x24 "NOBORDER" console set-up (720x288 pixels). It will not work properly if run from "ua". The aspect ratio algorithm is simply to skip every third line, and seems to give reasonable results for scanned photographs but may not for all "pix". Send questions/comments to ... ihnp4!killer!loci!clb ##---------Cut Here-----## #include <stdio.h> #include <fcntl.h> #include <sys/window.h> /* MacPaint Picture defines */ #define MAC_WIDTH 576 /* 576 pixels */ #define ROW_BYTES 72 /* 576 pixels wide / 8 */ #define NO_OF_LINES 720 /* 720 line */ #define MAX_MACPAINT_SIZE 51840L /* ROW_BYTES * NO_OF_LINES */ #define wbfr scan char scan[1024]; struct urdata ur_image = { 0, 72, 0, 0, 0, 0, 72, 0, 576, 1, SRCSRC, DSTSRC, 0 }; struct urdata ur_top = { 0, 72, 0, 72, 72, 96, 72, 0, 576, 192, SRCSRC, DSTSRC, 0 }; struct utdata slk_text[] = { { WTXTSLK1, " Press <RETURN> to continue ..." }, { WTXTSLK1, "" } }; main(argc, argv) char *argv[]; { int fd; if(argc < 2) exit(0); if((fd=open(argv[1], O_RDONLY)) < 0) { printf("%s: can't open MacPaint file\n", argv[0]); exit(1); } printf("\033[2J\033[1;1H"); /* clear screen, home cursor */ ioctl(0, WIOCSETTEXT, &slk_text[0]); UnPackPaint(fd); ioctl(0, WIOCSETTEXT, &slk_text[1]); } UnPackPaint(fd) { int i, j; if((read(fd, wbfr, 512)) != 512) exit(1); if((strncmp(&wbfr[65], "PNTGMPNT", 8)) == 0) lseek(fd, 128L, 1); ur_image.ur_srcbase = (unsigned short *)scan; for(i=0; i<432; i++) { rd_scan(fd, ROW_BYTES, scan); if(i%3 == 0) continue; rev_bits(scan, ROW_BYTES); ioctl(0, WIOCRASTOP, &ur_image); ur_image.ur_dsty++; } for(j=0; j<2; j++) { gets(wbfr); ioctl(0, WIOCRASTOP, &ur_top); ur_image.ur_dsty = 192; for(i=0; i<144; i++) { rd_scan(fd, ROW_BYTES, scan); if(i%3 == 0) continue; rev_bits(scan, ROW_BYTES); ioctl(0, WIOCRASTOP, &ur_image); ur_image.ur_dsty++; } } close(fd); } #define BIT7 0x80 rd_scan(fd, cnt, dst_p) char *dst_p; { int nbytes; unsigned char bit7; char c_data, r_data; if(cnt <= 0) return(0); bit7 = BIT7; while(cnt > 0) { if(read(fd, &c_data, 1) != 1) return(-1); if(c_data & bit7) /* High bit set ? */ { nbytes = abs(c_data); cnt -= ++nbytes; if(read(fd, &r_data, 1) != 1) return(-1); while(nbytes--) *dst_p++ = r_data; /* repeat src byte */ } else { /* It is a normal zero based counter */ nbytes = c_data; cnt -= ++nbytes; if(read(fd, dst_p, nbytes) < 1) return(-1); dst_p += nbytes; } } return(0); } rev_bits(srcPtr, nbytes) long *srcPtr; { register n_data, o_data; int hi_bits, bitCnt; if(nbytes < 0) return(0); nbytes >>= 2; hi_bits = 0x00010001; /* Let's deal with the short as longs */ while(nbytes--) { n_data = *srcPtr; o_data = 0; for(bitCnt=0; bitCnt<15; bitCnt++) { o_data |= n_data & hi_bits; /* See if this bit is on */ n_data >>= 1; o_data <<= 1; } o_data |= n_data & hi_bits; *srcPtr++ = o_data ^ -1; /* -1 for screen, 0 for printer */ } return(0); }