⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 g3p9bit.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>enum{	ERR,	EOL,	MAKE,	TERM,};enum{	White,	Black,};typedef struct Tab{	ushort	run;	ushort	bits;	int		code;} Tab;Tab	wtab[8192];Tab	btab[8192];uchar	bitrev[256];uchar	bitnonrev[256];int	readrow(uchar *rev, int*);void	initwbtab(void);void	sync(uchar*);int	readfile(int, char*, char*);int		nbytes;uchar	*bytes;uchar	*pixels;uchar	*buf;int		y;uint		bitoffset;uint		word24;enum{	Bytes	= 1024*1024,	Lines	= 1410,	/* 1100 for A4, 1410 for B4 */	Dots		= 1728,};voiderror(char *fmt, ...){	char buf[256];	va_list arg;	if(fmt){		va_start(arg, fmt);		vseprint(buf, buf+sizeof buf, fmt, arg);		va_end(arg);		fprint(2, "g3: %s\n", buf);	}	exits(fmt);}voidusage(void){	fprint(2, "usage: g3p9bit [-gy] file\n");	exits("usage");}voidmain(int argc, char **argv){	int y, fd, n, m;	char *t;	char *file, err[ERRMAX], tbuf[5*12+1];	int gray=0;	int yscale=1;	ARGBEGIN{	case 'g':		/* do simulated 2bit gray to compress x */		gray++;		break;	case 'y':		/* double each scan line to double the y resolution */		yscale=2;		break;	default:		usage();	}ARGEND	if(argc > 1)		usage();	initwbtab();	buf = malloc(1024*1024);	t = malloc((Dots/8)*Lines);	if(buf==nil || t==nil)		error("malloc failed: %r\n");	pixels = (uchar*)t;	file = "<stdin>";	fd = 0;	if(argc > 0){		file = argv[0];		fd = open(file, OREAD);		if(fd < 0)			error("can't open %s", file);	}	y = readfile(fd, file, err);	if(y < 0)		error(err);	sprint(tbuf, "%11d %11d %11d %11d %11d ", gray, 0, 0, Dots/(gray+1), y*yscale);	write(1, tbuf, 5*12);	n = (Dots/8)*y*yscale;	/* write in pieces; brazil pipes work badly with huge counts */	while(n > 0){		if(yscale > 1)	/* write one scan line */			m = Dots/8;		else{	/* write lots */			m = n;			if(m > 8192)				m = 8192;		}		for(y=0; y<yscale; y++){			if(write(1, t, m) != m)				error("write error");			n -= m;		}		t += m;	}	if(err[0])		error(err);	error(nil);}enum{	Hvres,	Hbaud,	Hwidth,	Hlength,	Hcomp,	HenabECM,	HenabBFT,	Hmsperscan,};int	defhdr[8] = {	0,		/* 98 lpi */	0,		/* 2400 baud */	0,		/* 1728 pixels in 215mm */	0,		/* A4, 297mm */	0,		/* 1-D modified huffman */	0,		/* disable ECM */	0,		/* disable BFT */	3,		/* 10 ms per scan */};intcrackhdr(uchar *ap, int *hdr){	char *p, *q;	int i;	p = (char*)ap;	q = p;	for(i=0; i<8; i++){		if(*p<'0' || '9'<*p)			return -1;		hdr[i] = strtol(p, &q, 0);		p = q+1;	}	return p-(char*)ap;}intreadfile(int f, char *file, char *err){	int i, r, lines;	uchar *rev;	int hdr[8];	err[0] = 0;	memset(pixels, 0, (Dots/8) * Lines);	nbytes = readn(f, buf, 1024*1024);	if(nbytes==1024*1024 || nbytes<=100){    bad:		sprint(err, "g3: file improper size or format: %s", file);		return -1;	}	bytes = buf;	if(bytes[0]=='I' && bytes[1]=='I' && bytes[2]=='*'){	/* dumb PC format */		bytes += 0xf3;		nbytes -= 0xf3;		rev = bitrev;		memmove(hdr, defhdr, sizeof defhdr);	}else if(bytes[0] == 0 && strcmp((char*)bytes+1, "PC Research, Inc") == 0){	/* digifax format */		memmove(hdr, defhdr, sizeof defhdr);		if(bytes[45] == 0x40 && bytes[29] == 1)	/* high resolution */			hdr[Hvres] = 1;		else			hdr[Hvres] = 0;		/* hdr[26] | (hdr[27]<<8) is page number */		bytes += 64;		nbytes -= 64;		rev = bitnonrev;	}else{		while(nbytes > 2){			if(bytes[0]=='\n'){				if(strncmp((char*)bytes+1, "FDCS=", 5) == 0){					i = crackhdr(bytes+6, hdr);					if(i < 0){						sprint(err, "g3: bad FDCS in header: %s", file);						return -1;					}					if(hdr[Hwidth] != 0){						sprint(err, "g3: unsupported width: %s", file);						return -1;					}					if(hdr[Hcomp] != 0){						sprint(err, "g3: unsupported compression: %s", file);						return -1;					}					bytes += i+1;					nbytes -= i+1;					continue;				}				if(bytes[1] == '\n'){					bytes += 2;					nbytes -= 2;					break;				}			}			bytes++;			nbytes--;		}		if(nbytes < 2)			goto bad;		rev = bitnonrev;	}	bitoffset = 24;	word24 = 0;	sync(rev);	lines = Lines;	if(hdr[Hvres] == 1)		lines *= 2;	for(y=0; y<lines; y++){		r = readrow(rev, hdr);		if(r < 0)			break;		if(r == 0)			sync(rev);	}	if(hdr[Hvres] == 1)		y /= 2;//	if(y < 100)//		goto bad;	return y;}intreadrow(uchar *rev, int *hdr){	int bo, state;	Tab *tab, *t;	int x, oldx, x2, oldx2, dx, xx;	uint w24;	uchar *p, *q;	state = White;	oldx = 0;	bo = bitoffset;	w24 = word24;	x = y;	if(hdr[Hvres] == 1)	/* high resolution */		x /= 2;	p = pixels + x*Dots/8;	x = 0;loop:	if(x > Dots)		return 0;	if(state == White)		tab = wtab;	else		tab = btab;	if(bo > (24-13)) {		do {			if(nbytes <= 0)				return -1;			w24 = (w24<<8) | rev[*bytes];			bo -= 8;			bytes++;			nbytes--;		} while(bo >= 8);	}	t = tab + ((w24 >> (24-13-bo)) & 8191);	x += t->run;	bo += t->bits;	if(t->code == TERM){		if(state == White)			oldx = x;		else{			oldx2 = oldx;			x2 = x;			xx = oldx2&7;			q = p+oldx2/8;			if(x2/8 == oldx2/8)	/* all in one byte, but if((x2&7)==0), do harder case */				*q |= (0xFF>>xx) & (0xFF<<(8-(x2&7)));			else{				dx = x2 - oldx2;				/* leading edge */				if(xx){					*q++ |= 0xFF>>xx;					dx -= 8-xx;				}				/* middle */				while(dx >= 8){					*q++ = 0xFF;					dx -= 8;				}				/* trailing edge */				if(dx)					*q |= 0xFF<<(8-dx);			}		}		state ^= White^Black;		goto loop;	}	if(t->code == ERR){		bitoffset = bo;		word24 = w24;		return 0;	}	if(t->code == EOL){		bitoffset = bo;		word24 = w24;		return 1;	}	goto loop;	return 0;}voidsync(uchar *rev){	Tab *t;	int c;	c = 0;loop:	if(bitoffset > (24-13)) {		do {			if(nbytes <= 0)				return;			word24 = (word24<<8) | rev[*bytes];			bitoffset -= 8;			bytes++;			nbytes--;		} while(bitoffset >= 8);	}	t = wtab + ((word24 >> (24-13-bitoffset)) & 8191);	if(t->code != EOL) {		bitoffset++;		c++;		goto loop;	}	bitoffset += t->bits;}typedef struct File{	char	*val;	int	code;}File;File ibtab[] = {#include "btab"{nil, 0}};File iwtab[] = {#include "wtab"{nil, 0}};intbinary(char *s){	int n;	n = 0;	while(*s)		n = n*2 + *s++-'0';	return n;}voidtabinit(File *file, Tab *tab){	int i, j, v, r, l;	char *b;	for(v=0; v<8192; v++) {		tab[v].run = 0;		tab[v].bits = 1;		tab[v].code = ERR;	}	for(i=0; b=file[i].val; i++){		l = strlen(b);		v = binary(b);		r = file[i].code;		if(l > 13)			fprint(2, "g3: oops1 l = %d %s\n", l, b);		v = v<<(13-l);		for(j=0; j<(1<<((13-l))); j++) {			if(tab[v].code != ERR)				fprint(2, "g3: oops2 %d %s\n", r, b);			tab[v].run = r;			tab[v].bits = l;			tab[v].code = TERM;			if(r < 0) {				tab[v].run = 0;				tab[v].code = EOL;				if(r < -1) {					tab[v].bits = 1;					tab[v].code = MAKE;				}			}			if(r >= 64) {				tab[v].code = MAKE;			}			v++;		}	}	for(i=0; i<256; i++)		for(j=0; j<8; j++)			if(i & (1<<j))				bitrev[i] |= 0x80 >> j;	for(i=0; i<256; i++)		bitnonrev[i] = i;}voidinitwbtab(void){	tabinit(iwtab, wtab);	tabinit(ibtab, btab);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -