xref: /plan9-contrib/sys/src/cmd/postscript/g3p9bit/g3p9bit.c (revision a7a38e3ec879cc47b5698ff7334c127003b75b14)
1219b2ee8SDavid du Colombier #include <u.h>
2219b2ee8SDavid du Colombier #include <libc.h>
3219b2ee8SDavid du Colombier 
4219b2ee8SDavid du Colombier enum
5219b2ee8SDavid du Colombier {
6219b2ee8SDavid du Colombier 	ERR,
7219b2ee8SDavid du Colombier 	EOL,
8219b2ee8SDavid du Colombier 	MAKE,
9219b2ee8SDavid du Colombier 	TERM,
10219b2ee8SDavid du Colombier };
11219b2ee8SDavid du Colombier 
12219b2ee8SDavid du Colombier enum
13219b2ee8SDavid du Colombier {
14219b2ee8SDavid du Colombier 	White,
15219b2ee8SDavid du Colombier 	Black,
16219b2ee8SDavid du Colombier };
17219b2ee8SDavid du Colombier 
18219b2ee8SDavid du Colombier typedef struct Tab
19219b2ee8SDavid du Colombier {
20219b2ee8SDavid du Colombier 	ushort	run;
21219b2ee8SDavid du Colombier 	ushort	bits;
22219b2ee8SDavid du Colombier 	int		code;
23219b2ee8SDavid du Colombier } Tab;
24219b2ee8SDavid du Colombier 
25219b2ee8SDavid du Colombier Tab	wtab[8192];
26219b2ee8SDavid du Colombier Tab	btab[8192];
27219b2ee8SDavid du Colombier uchar	bitrev[256];
28219b2ee8SDavid du Colombier uchar	bitnonrev[256];
29219b2ee8SDavid du Colombier 
30219b2ee8SDavid du Colombier int	readrow(uchar *rev, int*);
31219b2ee8SDavid du Colombier void	initwbtab(void);
32219b2ee8SDavid du Colombier void	sync(uchar*);
33219b2ee8SDavid du Colombier int	readfile(int, char*, char*);
34219b2ee8SDavid du Colombier 
35219b2ee8SDavid du Colombier int		nbytes;
36219b2ee8SDavid du Colombier uchar	*bytes;
37219b2ee8SDavid du Colombier uchar	*pixels;
38219b2ee8SDavid du Colombier uchar	*buf;
39219b2ee8SDavid du Colombier int		y;
40219b2ee8SDavid du Colombier uint		bitoffset;
41219b2ee8SDavid du Colombier uint		word24;
42219b2ee8SDavid du Colombier 
43219b2ee8SDavid du Colombier enum
44219b2ee8SDavid du Colombier {
45219b2ee8SDavid du Colombier 	Bytes	= 1024*1024,
46219b2ee8SDavid du Colombier 	Lines	= 1410,	/* 1100 for A4, 1410 for B4 */
47219b2ee8SDavid du Colombier 	Dots		= 1728,
48219b2ee8SDavid du Colombier };
49219b2ee8SDavid du Colombier 
50219b2ee8SDavid du Colombier void
error(char * fmt,...)517dd7cddfSDavid du Colombier error(char *fmt, ...)
52219b2ee8SDavid du Colombier {
53219b2ee8SDavid du Colombier 	char buf[256];
547dd7cddfSDavid du Colombier 	va_list arg;
55219b2ee8SDavid du Colombier 
567dd7cddfSDavid du Colombier 	if(fmt){
577dd7cddfSDavid du Colombier 		va_start(arg, fmt);
58*9a747e4fSDavid du Colombier 		vseprint(buf, buf+sizeof buf, fmt, arg);
597dd7cddfSDavid du Colombier 		va_end(arg);
60219b2ee8SDavid du Colombier 		fprint(2, "g3: %s\n", buf);
61219b2ee8SDavid du Colombier 	}
627dd7cddfSDavid du Colombier 	exits(fmt);
63219b2ee8SDavid du Colombier }
64219b2ee8SDavid du Colombier 
65219b2ee8SDavid du Colombier void
usage(void)6659cc4ca5SDavid du Colombier usage(void)
6759cc4ca5SDavid du Colombier {
6859cc4ca5SDavid du Colombier 	fprint(2, "usage: g3p9bit [-gy] file\n");
6959cc4ca5SDavid du Colombier 	exits("usage");
7059cc4ca5SDavid du Colombier }
7159cc4ca5SDavid du Colombier 
7259cc4ca5SDavid du Colombier void
main(int argc,char ** argv)73219b2ee8SDavid du Colombier main(int argc, char **argv)
74219b2ee8SDavid du Colombier {
757dd7cddfSDavid du Colombier 	int y, fd, n, m;
76219b2ee8SDavid du Colombier 	char *t;
77*9a747e4fSDavid du Colombier 	char *file, err[ERRMAX], tbuf[5*12+1];
787dd7cddfSDavid du Colombier 	int gray=0;
797dd7cddfSDavid du Colombier 	int yscale=1;
80219b2ee8SDavid du Colombier 
8159cc4ca5SDavid du Colombier 	ARGBEGIN{
8259cc4ca5SDavid du Colombier 	case 'g':
837dd7cddfSDavid du Colombier 		/* do simulated 2bit gray to compress x */
847dd7cddfSDavid du Colombier 		gray++;
8559cc4ca5SDavid du Colombier 		break;
8659cc4ca5SDavid du Colombier 	case 'y':
877dd7cddfSDavid du Colombier 		/* double each scan line to double the y resolution */
887dd7cddfSDavid du Colombier 		yscale=2;
8959cc4ca5SDavid du Colombier 		break;
9059cc4ca5SDavid du Colombier 	default:
9159cc4ca5SDavid du Colombier 		usage();
9259cc4ca5SDavid du Colombier 	}ARGEND
9359cc4ca5SDavid du Colombier 
9459cc4ca5SDavid du Colombier 	if(argc > 1)
9559cc4ca5SDavid du Colombier 		usage();
96219b2ee8SDavid du Colombier 
97219b2ee8SDavid du Colombier 	initwbtab();
98219b2ee8SDavid du Colombier 	buf = malloc(1024*1024);
997dd7cddfSDavid du Colombier 	t = malloc((Dots/8)*Lines);
100219b2ee8SDavid du Colombier 	if(buf==nil || t==nil)
101219b2ee8SDavid du Colombier 		error("malloc failed: %r\n");
1027dd7cddfSDavid du Colombier 	pixels = (uchar*)t;
103219b2ee8SDavid du Colombier 
104219b2ee8SDavid du Colombier 	file = "<stdin>";
105219b2ee8SDavid du Colombier 	fd = 0;
10659cc4ca5SDavid du Colombier 	if(argc > 0){
10759cc4ca5SDavid du Colombier 		file = argv[0];
108219b2ee8SDavid du Colombier 		fd = open(file, OREAD);
109219b2ee8SDavid du Colombier 		if(fd < 0)
110219b2ee8SDavid du Colombier 			error("can't open %s", file);
111219b2ee8SDavid du Colombier 	}
112219b2ee8SDavid du Colombier 	y = readfile(fd, file, err);
113219b2ee8SDavid du Colombier 	if(y < 0)
114219b2ee8SDavid du Colombier 		error(err);
1157dd7cddfSDavid du Colombier 	sprint(tbuf, "%11d %11d %11d %11d %11d ", gray, 0, 0, Dots/(gray+1), y*yscale);
1167dd7cddfSDavid du Colombier 	write(1, tbuf, 5*12);
1177dd7cddfSDavid du Colombier 	n = (Dots/8)*y*yscale;
1187dd7cddfSDavid du Colombier 	/* write in pieces; brazil pipes work badly with huge counts */
1197dd7cddfSDavid du Colombier 	while(n > 0){
1207dd7cddfSDavid du Colombier 		if(yscale > 1)	/* write one scan line */
1217dd7cddfSDavid du Colombier 			m = Dots/8;
1227dd7cddfSDavid du Colombier 		else{	/* write lots */
1237dd7cddfSDavid du Colombier 			m = n;
1247dd7cddfSDavid du Colombier 			if(m > 8192)
1257dd7cddfSDavid du Colombier 				m = 8192;
1267dd7cddfSDavid du Colombier 		}
1277dd7cddfSDavid du Colombier 		for(y=0; y<yscale; y++){
1287dd7cddfSDavid du Colombier 			if(write(1, t, m) != m)
129219b2ee8SDavid du Colombier 				error("write error");
1307dd7cddfSDavid du Colombier 			n -= m;
1317dd7cddfSDavid du Colombier 		}
1327dd7cddfSDavid du Colombier 		t += m;
1337dd7cddfSDavid du Colombier 	}
134219b2ee8SDavid du Colombier 	if(err[0])
135219b2ee8SDavid du Colombier 		error(err);
136219b2ee8SDavid du Colombier 	error(nil);
137219b2ee8SDavid du Colombier }
138219b2ee8SDavid du Colombier 
139219b2ee8SDavid du Colombier enum{
140219b2ee8SDavid du Colombier 	Hvres,
141219b2ee8SDavid du Colombier 	Hbaud,
142219b2ee8SDavid du Colombier 	Hwidth,
143219b2ee8SDavid du Colombier 	Hlength,
144219b2ee8SDavid du Colombier 	Hcomp,
145219b2ee8SDavid du Colombier 	HenabECM,
146219b2ee8SDavid du Colombier 	HenabBFT,
147219b2ee8SDavid du Colombier 	Hmsperscan,
148219b2ee8SDavid du Colombier };
149219b2ee8SDavid du Colombier 
150219b2ee8SDavid du Colombier int	defhdr[8] = {
151219b2ee8SDavid du Colombier 	0,		/* 98 lpi */
152219b2ee8SDavid du Colombier 	0,		/* 2400 baud */
153219b2ee8SDavid du Colombier 	0,		/* 1728 pixels in 215mm */
154219b2ee8SDavid du Colombier 	0,		/* A4, 297mm */
155219b2ee8SDavid du Colombier 	0,		/* 1-D modified huffman */
156219b2ee8SDavid du Colombier 	0,		/* disable ECM */
157219b2ee8SDavid du Colombier 	0,		/* disable BFT */
158219b2ee8SDavid du Colombier 	3,		/* 10 ms per scan */
159219b2ee8SDavid du Colombier };
160219b2ee8SDavid du Colombier 
161219b2ee8SDavid du Colombier int
crackhdr(uchar * ap,int * hdr)162219b2ee8SDavid du Colombier crackhdr(uchar *ap, int *hdr)
163219b2ee8SDavid du Colombier {
164219b2ee8SDavid du Colombier 	char *p, *q;
165219b2ee8SDavid du Colombier 	int i;
166219b2ee8SDavid du Colombier 
167219b2ee8SDavid du Colombier 	p = (char*)ap;
168219b2ee8SDavid du Colombier 	q = p;
169219b2ee8SDavid du Colombier 	for(i=0; i<8; i++){
170219b2ee8SDavid du Colombier 		if(*p<'0' || '9'<*p)
171219b2ee8SDavid du Colombier 			return -1;
172219b2ee8SDavid du Colombier 		hdr[i] = strtol(p, &q, 0);
173219b2ee8SDavid du Colombier 		p = q+1;
174219b2ee8SDavid du Colombier 	}
175219b2ee8SDavid du Colombier 	return p-(char*)ap;
176219b2ee8SDavid du Colombier }
177219b2ee8SDavid du Colombier 
178219b2ee8SDavid du Colombier int
readfile(int f,char * file,char * err)179219b2ee8SDavid du Colombier readfile(int f, char *file, char *err)
180219b2ee8SDavid du Colombier {
181219b2ee8SDavid du Colombier 	int i, r, lines;
182219b2ee8SDavid du Colombier 	uchar *rev;
183219b2ee8SDavid du Colombier 	int hdr[8];
184219b2ee8SDavid du Colombier 
185219b2ee8SDavid du Colombier 	err[0] = 0;
186219b2ee8SDavid du Colombier 	memset(pixels, 0, (Dots/8) * Lines);
1877dd7cddfSDavid du Colombier 	nbytes = readn(f, buf, 1024*1024);
188219b2ee8SDavid du Colombier 	if(nbytes==1024*1024 || nbytes<=100){
189219b2ee8SDavid du Colombier     bad:
190219b2ee8SDavid du Colombier 		sprint(err, "g3: file improper size or format: %s", file);
191219b2ee8SDavid du Colombier 		return -1;
192219b2ee8SDavid du Colombier 	}
193219b2ee8SDavid du Colombier 	bytes = buf;
194219b2ee8SDavid du Colombier 	if(bytes[0]=='I' && bytes[1]=='I' && bytes[2]=='*'){	/* dumb PC format */
195219b2ee8SDavid du Colombier 		bytes += 0xf3;
196219b2ee8SDavid du Colombier 		nbytes -= 0xf3;
197219b2ee8SDavid du Colombier 		rev = bitrev;
198219b2ee8SDavid du Colombier 		memmove(hdr, defhdr, sizeof defhdr);
1997dd7cddfSDavid du Colombier 	}else if(bytes[0] == 0 && strcmp((char*)bytes+1, "PC Research, Inc") == 0){	/* digifax format */
2007dd7cddfSDavid du Colombier 		memmove(hdr, defhdr, sizeof defhdr);
2017dd7cddfSDavid du Colombier 		if(bytes[45] == 0x40 && bytes[29] == 1)	/* high resolution */
2027dd7cddfSDavid du Colombier 			hdr[Hvres] = 1;
2037dd7cddfSDavid du Colombier 		else
2047dd7cddfSDavid du Colombier 			hdr[Hvres] = 0;
2057dd7cddfSDavid du Colombier 		/* hdr[26] | (hdr[27]<<8) is page number */
2067dd7cddfSDavid du Colombier 
2077dd7cddfSDavid du Colombier 		bytes += 64;
2087dd7cddfSDavid du Colombier 		nbytes -= 64;
2097dd7cddfSDavid du Colombier 		rev = bitnonrev;
210219b2ee8SDavid du Colombier 	}else{
211219b2ee8SDavid du Colombier 		while(nbytes > 2){
212219b2ee8SDavid du Colombier 			if(bytes[0]=='\n'){
213219b2ee8SDavid du Colombier 				if(strncmp((char*)bytes+1, "FDCS=", 5) == 0){
214219b2ee8SDavid du Colombier 					i = crackhdr(bytes+6, hdr);
215219b2ee8SDavid du Colombier 					if(i < 0){
216219b2ee8SDavid du Colombier 						sprint(err, "g3: bad FDCS in header: %s", file);
217219b2ee8SDavid du Colombier 						return -1;
218219b2ee8SDavid du Colombier 					}
219219b2ee8SDavid du Colombier 					if(hdr[Hwidth] != 0){
220219b2ee8SDavid du Colombier 						sprint(err, "g3: unsupported width: %s", file);
221219b2ee8SDavid du Colombier 						return -1;
222219b2ee8SDavid du Colombier 					}
223219b2ee8SDavid du Colombier 					if(hdr[Hcomp] != 0){
224219b2ee8SDavid du Colombier 						sprint(err, "g3: unsupported compression: %s", file);
225219b2ee8SDavid du Colombier 						return -1;
226219b2ee8SDavid du Colombier 					}
227219b2ee8SDavid du Colombier 					bytes += i+1;
228219b2ee8SDavid du Colombier 					nbytes -= i+1;
229219b2ee8SDavid du Colombier 					continue;
230219b2ee8SDavid du Colombier 				}
231219b2ee8SDavid du Colombier 				if(bytes[1] == '\n'){
232219b2ee8SDavid du Colombier 					bytes += 2;
233219b2ee8SDavid du Colombier 					nbytes -= 2;
234219b2ee8SDavid du Colombier 					break;
235219b2ee8SDavid du Colombier 				}
236219b2ee8SDavid du Colombier 			}
237219b2ee8SDavid du Colombier 			bytes++;
238219b2ee8SDavid du Colombier 			nbytes--;
239219b2ee8SDavid du Colombier 		}
240219b2ee8SDavid du Colombier 		if(nbytes < 2)
241219b2ee8SDavid du Colombier 			goto bad;
242219b2ee8SDavid du Colombier 		rev = bitnonrev;
243219b2ee8SDavid du Colombier 	}
244219b2ee8SDavid du Colombier 	bitoffset = 24;
245219b2ee8SDavid du Colombier 	word24 = 0;
246219b2ee8SDavid du Colombier 	sync(rev);
247219b2ee8SDavid du Colombier 	lines = Lines;
248219b2ee8SDavid du Colombier 	if(hdr[Hvres] == 1)
249219b2ee8SDavid du Colombier 		lines *= 2;
250219b2ee8SDavid du Colombier 	for(y=0; y<lines; y++){
251219b2ee8SDavid du Colombier 		r = readrow(rev, hdr);
252219b2ee8SDavid du Colombier 		if(r < 0)
253219b2ee8SDavid du Colombier 			break;
254219b2ee8SDavid du Colombier 		if(r == 0)
255219b2ee8SDavid du Colombier 			sync(rev);
256219b2ee8SDavid du Colombier 	}
257219b2ee8SDavid du Colombier 	if(hdr[Hvres] == 1)
258219b2ee8SDavid du Colombier 		y /= 2;
2597dd7cddfSDavid du Colombier //	if(y < 100)
2607dd7cddfSDavid du Colombier //		goto bad;
261219b2ee8SDavid du Colombier 	return y;
262219b2ee8SDavid du Colombier }
263219b2ee8SDavid du Colombier 
264219b2ee8SDavid du Colombier int
readrow(uchar * rev,int * hdr)265219b2ee8SDavid du Colombier readrow(uchar *rev, int *hdr)
266219b2ee8SDavid du Colombier {
267219b2ee8SDavid du Colombier 	int bo, state;
268219b2ee8SDavid du Colombier 	Tab *tab, *t;
269219b2ee8SDavid du Colombier 	int x, oldx, x2, oldx2, dx, xx;
270219b2ee8SDavid du Colombier 	uint w24;
271219b2ee8SDavid du Colombier 	uchar *p, *q;
272219b2ee8SDavid du Colombier 
273219b2ee8SDavid du Colombier 	state = White;
274219b2ee8SDavid du Colombier 	oldx = 0;
275219b2ee8SDavid du Colombier 	bo = bitoffset;
276219b2ee8SDavid du Colombier 	w24 = word24;
277219b2ee8SDavid du Colombier 	x = y;
278219b2ee8SDavid du Colombier 	if(hdr[Hvres] == 1)	/* high resolution */
279219b2ee8SDavid du Colombier 		x /= 2;
280219b2ee8SDavid du Colombier 	p = pixels + x*Dots/8;
281219b2ee8SDavid du Colombier 	x = 0;
282219b2ee8SDavid du Colombier 
283219b2ee8SDavid du Colombier loop:
284219b2ee8SDavid du Colombier 	if(x > Dots)
285219b2ee8SDavid du Colombier 		return 0;
286219b2ee8SDavid du Colombier 	if(state == White)
287219b2ee8SDavid du Colombier 		tab = wtab;
288219b2ee8SDavid du Colombier 	else
289219b2ee8SDavid du Colombier 		tab = btab;
290219b2ee8SDavid du Colombier 	if(bo > (24-13)) {
291219b2ee8SDavid du Colombier 		do {
292219b2ee8SDavid du Colombier 			if(nbytes <= 0)
293219b2ee8SDavid du Colombier 				return -1;
294219b2ee8SDavid du Colombier 			w24 = (w24<<8) | rev[*bytes];
295219b2ee8SDavid du Colombier 			bo -= 8;
296219b2ee8SDavid du Colombier 			bytes++;
297219b2ee8SDavid du Colombier 			nbytes--;
298219b2ee8SDavid du Colombier 		} while(bo >= 8);
299219b2ee8SDavid du Colombier 	}
300219b2ee8SDavid du Colombier 
301219b2ee8SDavid du Colombier 	t = tab + ((w24 >> (24-13-bo)) & 8191);
302219b2ee8SDavid du Colombier 	x += t->run;
303219b2ee8SDavid du Colombier 	bo += t->bits;
304219b2ee8SDavid du Colombier 	if(t->code == TERM){
305219b2ee8SDavid du Colombier 		if(state == White)
306219b2ee8SDavid du Colombier 			oldx = x;
307219b2ee8SDavid du Colombier 		else{
308219b2ee8SDavid du Colombier 			oldx2 = oldx;
309219b2ee8SDavid du Colombier 			x2 = x;
310219b2ee8SDavid du Colombier 			xx = oldx2&7;
311219b2ee8SDavid du Colombier 			q = p+oldx2/8;
312219b2ee8SDavid du Colombier 			if(x2/8 == oldx2/8)	/* all in one byte, but if((x2&7)==0), do harder case */
313219b2ee8SDavid du Colombier 				*q |= (0xFF>>xx) & (0xFF<<(8-(x2&7)));
314219b2ee8SDavid du Colombier 			else{
315219b2ee8SDavid du Colombier 				dx = x2 - oldx2;
316219b2ee8SDavid du Colombier 				/* leading edge */
317219b2ee8SDavid du Colombier 				if(xx){
318219b2ee8SDavid du Colombier 					*q++ |= 0xFF>>xx;
319219b2ee8SDavid du Colombier 					dx -= 8-xx;
320219b2ee8SDavid du Colombier 				}
321219b2ee8SDavid du Colombier 				/* middle */
322219b2ee8SDavid du Colombier 				while(dx >= 8){
323219b2ee8SDavid du Colombier 					*q++ = 0xFF;
324219b2ee8SDavid du Colombier 					dx -= 8;
325219b2ee8SDavid du Colombier 				}
326219b2ee8SDavid du Colombier 				/* trailing edge */
327219b2ee8SDavid du Colombier 				if(dx)
328219b2ee8SDavid du Colombier 					*q |= 0xFF<<(8-dx);
329219b2ee8SDavid du Colombier 			}
330219b2ee8SDavid du Colombier 		}
331219b2ee8SDavid du Colombier 		state ^= White^Black;
332219b2ee8SDavid du Colombier 		goto loop;
333219b2ee8SDavid du Colombier 	}
334219b2ee8SDavid du Colombier 	if(t->code == ERR){
335219b2ee8SDavid du Colombier 		bitoffset = bo;
336219b2ee8SDavid du Colombier 		word24 = w24;
337219b2ee8SDavid du Colombier 		return 0;
338219b2ee8SDavid du Colombier 	}
339219b2ee8SDavid du Colombier 	if(t->code == EOL){
340219b2ee8SDavid du Colombier 		bitoffset = bo;
341219b2ee8SDavid du Colombier 		word24 = w24;
342219b2ee8SDavid du Colombier 		return 1;
343219b2ee8SDavid du Colombier 	}
344219b2ee8SDavid du Colombier 	goto loop;
345219b2ee8SDavid du Colombier }
346219b2ee8SDavid du Colombier 
347219b2ee8SDavid du Colombier 
348219b2ee8SDavid du Colombier void
sync(uchar * rev)349219b2ee8SDavid du Colombier sync(uchar *rev)
350219b2ee8SDavid du Colombier {
351219b2ee8SDavid du Colombier 	Tab *t;
352219b2ee8SDavid du Colombier 	int c;
353219b2ee8SDavid du Colombier 
354219b2ee8SDavid du Colombier 	c = 0;
355219b2ee8SDavid du Colombier loop:
356219b2ee8SDavid du Colombier 	if(bitoffset > (24-13)) {
357219b2ee8SDavid du Colombier 		do {
358219b2ee8SDavid du Colombier 			if(nbytes <= 0)
359219b2ee8SDavid du Colombier 				return;
360219b2ee8SDavid du Colombier 			word24 = (word24<<8) | rev[*bytes];
361219b2ee8SDavid du Colombier 			bitoffset -= 8;
362219b2ee8SDavid du Colombier 			bytes++;
363219b2ee8SDavid du Colombier 			nbytes--;
364219b2ee8SDavid du Colombier 		} while(bitoffset >= 8);
365219b2ee8SDavid du Colombier 	}
366219b2ee8SDavid du Colombier 	t = wtab + ((word24 >> (24-13-bitoffset)) & 8191);
367219b2ee8SDavid du Colombier 	if(t->code != EOL) {
368219b2ee8SDavid du Colombier 		bitoffset++;
369219b2ee8SDavid du Colombier 		c++;
370219b2ee8SDavid du Colombier 		goto loop;
371219b2ee8SDavid du Colombier 	}
372219b2ee8SDavid du Colombier 	bitoffset += t->bits;
373219b2ee8SDavid du Colombier }
374219b2ee8SDavid du Colombier 
375219b2ee8SDavid du Colombier typedef struct File
376219b2ee8SDavid du Colombier {
377219b2ee8SDavid du Colombier 	char	*val;
378219b2ee8SDavid du Colombier 	int	code;
379219b2ee8SDavid du Colombier }File;
380219b2ee8SDavid du Colombier 
381219b2ee8SDavid du Colombier File ibtab[] = {
382219b2ee8SDavid du Colombier #include "btab"
383219b2ee8SDavid du Colombier {nil, 0}
384219b2ee8SDavid du Colombier };
385219b2ee8SDavid du Colombier 
386219b2ee8SDavid du Colombier File iwtab[] = {
387219b2ee8SDavid du Colombier #include "wtab"
388219b2ee8SDavid du Colombier {nil, 0}
389219b2ee8SDavid du Colombier };
390219b2ee8SDavid du Colombier 
391219b2ee8SDavid du Colombier int
binary(char * s)392219b2ee8SDavid du Colombier binary(char *s)
393219b2ee8SDavid du Colombier {
394219b2ee8SDavid du Colombier 	int n;
395219b2ee8SDavid du Colombier 
396219b2ee8SDavid du Colombier 	n = 0;
397219b2ee8SDavid du Colombier 	while(*s)
398219b2ee8SDavid du Colombier 		n = n*2 + *s++-'0';
399219b2ee8SDavid du Colombier 	return n;
400219b2ee8SDavid du Colombier }
401219b2ee8SDavid du Colombier 
402219b2ee8SDavid du Colombier void
tabinit(File * file,Tab * tab)403219b2ee8SDavid du Colombier tabinit(File *file, Tab *tab)
404219b2ee8SDavid du Colombier {
405219b2ee8SDavid du Colombier 	int i, j, v, r, l;
406219b2ee8SDavid du Colombier 	char *b;
407219b2ee8SDavid du Colombier 
408219b2ee8SDavid du Colombier 	for(v=0; v<8192; v++) {
409219b2ee8SDavid du Colombier 		tab[v].run = 0;
410219b2ee8SDavid du Colombier 		tab[v].bits = 1;
411219b2ee8SDavid du Colombier 		tab[v].code = ERR;
412219b2ee8SDavid du Colombier 	}
413219b2ee8SDavid du Colombier 	for(i=0; b=file[i].val; i++){
414219b2ee8SDavid du Colombier 		l = strlen(b);
415219b2ee8SDavid du Colombier 		v = binary(b);
416219b2ee8SDavid du Colombier 		r = file[i].code;
417219b2ee8SDavid du Colombier 		if(l > 13)
418219b2ee8SDavid du Colombier 			fprint(2, "g3: oops1 l = %d %s\n", l, b);
419219b2ee8SDavid du Colombier 
420219b2ee8SDavid du Colombier 		v = v<<(13-l);
421219b2ee8SDavid du Colombier 		for(j=0; j<(1<<((13-l))); j++) {
422219b2ee8SDavid du Colombier 			if(tab[v].code != ERR)
423219b2ee8SDavid du Colombier 				fprint(2, "g3: oops2 %d %s\n", r, b);
424219b2ee8SDavid du Colombier 			tab[v].run = r;
425219b2ee8SDavid du Colombier 			tab[v].bits = l;
426219b2ee8SDavid du Colombier 			tab[v].code = TERM;
427219b2ee8SDavid du Colombier 			if(r < 0) {
428219b2ee8SDavid du Colombier 				tab[v].run = 0;
429219b2ee8SDavid du Colombier 				tab[v].code = EOL;
430219b2ee8SDavid du Colombier 				if(r < -1) {
431219b2ee8SDavid du Colombier 					tab[v].bits = 1;
432219b2ee8SDavid du Colombier 					tab[v].code = MAKE;
433219b2ee8SDavid du Colombier 				}
434219b2ee8SDavid du Colombier 			}
435219b2ee8SDavid du Colombier 			if(r >= 64) {
436219b2ee8SDavid du Colombier 				tab[v].code = MAKE;
437219b2ee8SDavid du Colombier 			}
438219b2ee8SDavid du Colombier 			v++;
439219b2ee8SDavid du Colombier 		}
440219b2ee8SDavid du Colombier 	}
441219b2ee8SDavid du Colombier 
442219b2ee8SDavid du Colombier 	for(i=0; i<256; i++)
443219b2ee8SDavid du Colombier 		for(j=0; j<8; j++)
444219b2ee8SDavid du Colombier 			if(i & (1<<j))
445219b2ee8SDavid du Colombier 				bitrev[i] |= 0x80 >> j;
446219b2ee8SDavid du Colombier 	for(i=0; i<256; i++)
447219b2ee8SDavid du Colombier 		bitnonrev[i] = i;
448219b2ee8SDavid du Colombier }
449219b2ee8SDavid du Colombier 
450219b2ee8SDavid du Colombier void
initwbtab(void)451219b2ee8SDavid du Colombier initwbtab(void)
452219b2ee8SDavid du Colombier {
453219b2ee8SDavid du Colombier 	tabinit(iwtab, wtab);
454219b2ee8SDavid du Colombier 	tabinit(ibtab, btab);
455219b2ee8SDavid du Colombier }
456