xref: /inferno-os/appl/lib/print/hp_driver.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsythimplement Pdriver;
2*37da2899SCharles.Forsyth
3*37da2899SCharles.Forsythinclude "sys.m";
4*37da2899SCharles.Forsyth	sys: Sys;
5*37da2899SCharles.Forsythinclude "draw.m";
6*37da2899SCharles.Forsyth	draw: Draw;
7*37da2899SCharles.Forsyth	Display, Font, Rect, Point, Image, Screen: import draw;
8*37da2899SCharles.Forsythinclude "bufio.m";
9*37da2899SCharles.Forsyth	bufio: Bufio;
10*37da2899SCharles.Forsyth	Iobuf: import bufio;
11*37da2899SCharles.Forsythinclude "print.m";
12*37da2899SCharles.Forsyth	Printer: import Print;
13*37da2899SCharles.Forsythinclude "scaler.m";
14*37da2899SCharles.Forsyth	scaler: Scaler;
15*37da2899SCharles.Forsyth
16*37da2899SCharles.Forsyth
17*37da2899SCharles.ForsythK: con 0;
18*37da2899SCharles.ForsythC: con 1;
19*37da2899SCharles.ForsythM: con 2;
20*37da2899SCharles.ForsythY: con 3;
21*37da2899SCharles.ForsythClight: con 4;
22*37da2899SCharles.ForsythMlight: con 5;
23*37da2899SCharles.Forsyth
24*37da2899SCharles.ForsythHPTRUE: con 1;
25*37da2899SCharles.ForsythHPFALSE: con 0;
26*37da2899SCharles.ForsythTRUE: con 1;
27*37da2899SCharles.ForsythFALSE: con 0;
28*37da2899SCharles.Forsyth
29*37da2899SCharles.Forsyth# RGB pixel
30*37da2899SCharles.Forsyth
31*37da2899SCharles.ForsythRGB: adt {
32*37da2899SCharles.Forsyth	r, g, b: byte;
33*37da2899SCharles.Forsyth};
34*37da2899SCharles.Forsyth
35*37da2899SCharles.Forsyth
36*37da2899SCharles.Forsyth# KCMY pixel
37*37da2899SCharles.Forsyth
38*37da2899SCharles.ForsythKCMY: adt {
39*37da2899SCharles.Forsyth	k, c, m, y: byte;
40*37da2899SCharles.Forsyth};
41*37da2899SCharles.Forsyth
42*37da2899SCharles.Forsyth
43*37da2899SCharles.Forsyth
44*37da2899SCharles.ForsythDitherParms: adt {
45*37da2899SCharles.Forsyth	fNumPix: int;
46*37da2899SCharles.Forsyth	fInput: array of byte;
47*37da2899SCharles.Forsyth	fErr: array of int;
48*37da2899SCharles.Forsyth	fSymmetricFlag: int;
49*37da2899SCharles.Forsyth	fFEDRes: array of int;
50*37da2899SCharles.Forsyth	fRasterEvenOrOdd: int;
51*37da2899SCharles.Forsyth	fHifipe: int;
52*37da2899SCharles.Forsyth	fOutput1, fOutput2, fOutput3: array of byte;
53*37da2899SCharles.Forsyth};
54*37da2899SCharles.Forsyth
55*37da2899SCharles.Forsyth# magic and wondrous HP colour maps
56*37da2899SCharles.Forsythmap1: array of KCMY;
57*37da2899SCharles.Forsythmap2: array of KCMY;
58*37da2899SCharles.Forsyth
59*37da2899SCharles.ForsythABSOLUTE: con 1;
60*37da2899SCharles.ForsythRELATIVE: con 0;
61*37da2899SCharles.Forsyth
62*37da2899SCharles.ForsythCompression := 1;
63*37da2899SCharles.Forsyth
64*37da2899SCharles.ForsythDEBUG := 0;
65*37da2899SCharles.Forsythstderr: ref Sys->FD;
66*37da2899SCharles.Forsythoutbuf: ref Iobuf;
67*37da2899SCharles.Forsyth
68*37da2899SCharles.ForsythESC: con 27;
69*37da2899SCharles.Forsyth
70*37da2899SCharles.Forsyth# Palettes for Simple_Color
71*37da2899SCharles.Forsyth
72*37da2899SCharles.ForsythPALETTE_RGB: con 3;
73*37da2899SCharles.ForsythPALETTE_CMY: con -3;
74*37da2899SCharles.ForsythPALETTE_KCMY: con -4;
75*37da2899SCharles.ForsythPALETTE_K: con 1;
76*37da2899SCharles.Forsyth
77*37da2899SCharles.Forsyth
78*37da2899SCharles.Forsyth# Initialization
79*37da2899SCharles.Forsyth
80*37da2899SCharles.Forsythinit(debug: int)
81*37da2899SCharles.Forsyth{
82*37da2899SCharles.Forsyth	sys = load Sys Sys->PATH;
83*37da2899SCharles.Forsyth	stderr = sys->fildes(2);
84*37da2899SCharles.Forsyth	draw = load Draw Draw->PATH;
85*37da2899SCharles.Forsyth	bufio = load Bufio Bufio->PATH;
86*37da2899SCharles.Forsyth	scaler = load Scaler Scaler->PATH;
87*37da2899SCharles.Forsyth	if (scaler == nil) fatal("Failed to load Scaler module");
88*37da2899SCharles.Forsyth	DEBUG = debug;
89*37da2899SCharles.Forsyth}
90*37da2899SCharles.Forsyth
91*37da2899SCharles.Forsyth
92*37da2899SCharles.Forsyth# Return printable area in pixels
93*37da2899SCharles.Forsyth
94*37da2899SCharles.Forsythprintable_pixels(p: ref Printer): (int, int)
95*37da2899SCharles.Forsyth{
96*37da2899SCharles.Forsyth	HMARGIN: con 0.6;
97*37da2899SCharles.Forsyth	WMARGIN: con 0.3;
98*37da2899SCharles.Forsyth	winches := p.popt.paper.width_inches - 2.0*WMARGIN;
99*37da2899SCharles.Forsyth	hinches := p.popt.paper.height_inches - 2.0*HMARGIN;
100*37da2899SCharles.Forsyth	wres := real p.popt.mode.resx;
101*37da2899SCharles.Forsyth	hres := real p.popt.mode.resy;
102*37da2899SCharles.Forsyth
103*37da2899SCharles.Forsyth	(x, y) := (int (winches*wres), int (hinches*hres));
104*37da2899SCharles.Forsyth
105*37da2899SCharles.Forsyth	if (p.popt.orientation == Print->PORTRAIT)
106*37da2899SCharles.Forsyth		return (x, y);
107*37da2899SCharles.Forsyth	return (y, x);
108*37da2899SCharles.Forsyth}
109*37da2899SCharles.Forsyth
110*37da2899SCharles.Forsyth
111*37da2899SCharles.Forsyth
112*37da2899SCharles.Forsyth# Send image to printer
113*37da2899SCharles.Forsyth
114*37da2899SCharles.ForsythMASK := array[] of {byte 1, byte 3, byte 15, byte 255, byte 255};
115*37da2899SCharles.ForsythSHIFT := array[] of {7, 6, 4, 0};
116*37da2899SCharles.ForsythGSFACTOR := array[] of {255.0, 255.0/3.0, 255.0/7.0, 1.0, 1.0};
117*37da2899SCharles.Forsythlastp : ref Printer;
118*37da2899SCharles.Forsyth
119*37da2899SCharles.ForsythRefint: adt {
120*37da2899SCharles.Forsyth	value: int;
121*37da2899SCharles.Forsyth};
122*37da2899SCharles.Forsyth
123*37da2899SCharles.Forsythwatchdog(cancel: chan of int, cancelled: ref Refint)
124*37da2899SCharles.Forsyth{
125*37da2899SCharles.Forsyth	<- cancel;
126*37da2899SCharles.Forsyth	cancelled.value = 1;
127*37da2899SCharles.Forsyth}
128*37da2899SCharles.Forsyth
129*37da2899SCharles.Forsythsendimage(p: ref Printer, pfd: ref Sys->FD, display: ref Draw->Display, im: ref Draw->Image, width: int, lmargin: int, cancel: chan of int): int
130*37da2899SCharles.Forsyth{
131*37da2899SCharles.Forsyth	grppid := sys->pctl(Sys->NEWPGRP, nil);
132*37da2899SCharles.Forsyth	cancelled := ref Refint(0);
133*37da2899SCharles.Forsyth	spawn watchdog(cancel, cancelled);
134*37da2899SCharles.Forsyth
135*37da2899SCharles.Forsyth	outopen(pfd);
136*37da2899SCharles.Forsyth	dbg(sys->sprint("image depth=%d from %d,%d to %d,%d\n", im.depth, im.r.min.x, im.r.min.y, im.r.max.x, im.r.max.y));
137*37da2899SCharles.Forsyth	if (p != lastp) {
138*37da2899SCharles.Forsyth		(map1, map2) = readmaps(p);
139*37da2899SCharles.Forsyth		lastp = p;
140*37da2899SCharles.Forsyth	}
141*37da2899SCharles.Forsyth
142*37da2899SCharles.Forsyth	bpp := im.depth;
143*37da2899SCharles.Forsyth	linechan := chan of array of int;
144*37da2899SCharles.Forsyth	if (p.popt.orientation == Print->PORTRAIT)
145*37da2899SCharles.Forsyth		InputWidth := im.r.max.x-im.r.min.x;
146*37da2899SCharles.Forsyth	else
147*37da2899SCharles.Forsyth		InputWidth = im.r.max.y-im.r.min.y;
148*37da2899SCharles.Forsyth	AdjustedInputWidth := (InputWidth+7) - ((InputWidth+7) % 8);
149*37da2899SCharles.Forsyth	dbg(sys->sprint("bpp=%d, InputWidth=%d, AdjustedInputWidth=%d\n",
150*37da2899SCharles.Forsyth						 bpp, InputWidth, AdjustedInputWidth));
151*37da2899SCharles.Forsyth	if (p.popt.orientation == Print->PORTRAIT)
152*37da2899SCharles.Forsyth		spawn row_by_row(im, linechan, AdjustedInputWidth);
153*37da2899SCharles.Forsyth	else
154*37da2899SCharles.Forsyth		spawn rotate(im, linechan, AdjustedInputWidth);
155*37da2899SCharles.Forsyth	DesiredOutputWidth := AdjustedInputWidth;
156*37da2899SCharles.Forsyth	if (width > AdjustedInputWidth)
157*37da2899SCharles.Forsyth		DesiredOutputWidth = width;
158*37da2899SCharles.Forsyth	ScaledWidth := 8*((DesiredOutputWidth)/8);
159*37da2899SCharles.Forsyth	mode := p.popt.mode;
160*37da2899SCharles.Forsyth	Nplanes := 4;
161*37da2899SCharles.Forsyth	if (map2 != nil)
162*37da2899SCharles.Forsyth		Nplanes += 2;
163*37da2899SCharles.Forsyth	Contone := array[Nplanes] of array of byte;
164*37da2899SCharles.Forsyth	ColorDepth := array[Nplanes] of int;
165*37da2899SCharles.Forsyth	ColorDepth[K] = mode.blackdepth;
166*37da2899SCharles.Forsyth	for (col:=1; col<Nplanes; col++)
167*37da2899SCharles.Forsyth		ColorDepth[col] = mode.coldepth;
168*37da2899SCharles.Forsyth	OutputWidth := array[Nplanes] of int;
169*37da2899SCharles.Forsyth	fDitherParms := array[Nplanes] of DitherParms;
170*37da2899SCharles.Forsyth	ErrBuff := array[Nplanes] of array of int;
171*37da2899SCharles.Forsyth	ColorPlane := array[Nplanes] of array of array of array of byte;
172*37da2899SCharles.Forsyth	MixedRes := 0;
173*37da2899SCharles.Forsyth	BaseResX := mode.resx;
174*37da2899SCharles.Forsyth	BaseResY := mode.resy;
175*37da2899SCharles.Forsyth	ResBoost := BaseResX / BaseResY;
176*37da2899SCharles.Forsyth	ResolutionX := array[Nplanes] of int;
177*37da2899SCharles.Forsyth	ResolutionY := array[Nplanes] of int;
178*37da2899SCharles.Forsyth	ResolutionX[K] = mode.resx*mode.blackresmult;
179*37da2899SCharles.Forsyth	ResolutionY[K] = mode.resy*mode.blackresmult;
180*37da2899SCharles.Forsyth	for (col=1; col<Nplanes; col++) {
181*37da2899SCharles.Forsyth		ResolutionX[col] = mode.resx;
182*37da2899SCharles.Forsyth		ResolutionY[col] = mode.resy;
183*37da2899SCharles.Forsyth	}
184*37da2899SCharles.Forsyth	NumRows := array[Nplanes] of int;
185*37da2899SCharles.Forsyth	for (j:=0; j<Nplanes; j++) {
186*37da2899SCharles.Forsyth		if (ResolutionX[j] != ResolutionX[K])
187*37da2899SCharles.Forsyth			MixedRes++;
188*37da2899SCharles.Forsyth		if (MixedRes)
189*37da2899SCharles.Forsyth			# means res(K) !+ res(C,M,Y)
190*37da2899SCharles.Forsyth			NumRows[j] = ResolutionX[j] / BaseResX;
191*37da2899SCharles.Forsyth		else
192*37da2899SCharles.Forsyth			NumRows[j]=1;
193*37da2899SCharles.Forsyth		OutputWidth[j]= ScaledWidth * NumRows[j] * ResBoost;
194*37da2899SCharles.Forsyth		PlaneSize:= OutputWidth[j]/8;
195*37da2899SCharles.Forsyth		Contone[j] = array[OutputWidth[j]] of byte;
196*37da2899SCharles.Forsyth		ColorPlane[j] = array[NumRows[j]] of array of array of  byte;
197*37da2899SCharles.Forsyth		for (jj:=0; jj<NumRows[j]; jj++) {
198*37da2899SCharles.Forsyth			ColorPlane[j][jj] = array[ColorDepth[j]] of array of  byte;
199*37da2899SCharles.Forsyth			for (jjj:=0; jjj<ColorDepth[j]; jjj++) {
200*37da2899SCharles.Forsyth				ColorPlane[j][jj][jjj] = array[PlaneSize] of byte;
201*37da2899SCharles.Forsyth			}
202*37da2899SCharles.Forsyth		}
203*37da2899SCharles.Forsyth		ErrBuff[j] = array[OutputWidth[j]+2] of {* => 0};
204*37da2899SCharles.Forsyth	}
205*37da2899SCharles.Forsyth
206*37da2899SCharles.Forsyth	pcl_startjob(p);
207*37da2899SCharles.Forsyth	if (p.popt.paper.hpcode != "")
208*37da2899SCharles.Forsyth		PCL_Page_Size(p.popt.paper.hpcode);
209*37da2899SCharles.Forsyth	PCL_Move_CAP_H_Units(lmargin*300/BaseResX, ABSOLUTE);
210*37da2899SCharles.Forsyth	PCL_Configure_Raster_Data4(BaseResX, BaseResY, ColorDepth);
211*37da2899SCharles.Forsyth	PCL_Source_Raster_Width(ScaledWidth);
212*37da2899SCharles.Forsyth	PCL_Compression_Method(Compression);
213*37da2899SCharles.Forsyth	PCL_Start_Raster(1);
214*37da2899SCharles.Forsyth	cmap1 := setup_color_map(display, map1, im.depth);
215*37da2899SCharles.Forsyth	if (map2 != nil)
216*37da2899SCharles.Forsyth		cmap2 := setup_color_map(display, map2, im.depth);
217*37da2899SCharles.Forsyth	numerator, denominator: int;
218*37da2899SCharles.Forsyth	if ((ScaledWidth % AdjustedInputWidth)==0) {
219*37da2899SCharles.Forsyth		numerator = ScaledWidth / AdjustedInputWidth;
220*37da2899SCharles.Forsyth		denominator = 1;
221*37da2899SCharles.Forsyth	} else {
222*37da2899SCharles.Forsyth		numerator = ScaledWidth;
223*37da2899SCharles.Forsyth		denominator = AdjustedInputWidth;
224*37da2899SCharles.Forsyth	}
225*37da2899SCharles.Forsyth	rs := scaler->init(DEBUG, AdjustedInputWidth, numerator, denominator);
226*37da2899SCharles.Forsyth	rasterno := 0;
227*37da2899SCharles.Forsyth	col_row: array of int;
228*37da2899SCharles.Forsyth	eof := 0;
229*37da2899SCharles.Forsyth
230*37da2899SCharles.Forsyth	while (!eof) {
231*37da2899SCharles.Forsyth		col_row = <- linechan;
232*37da2899SCharles.Forsyth		if (col_row == nil)
233*37da2899SCharles.Forsyth			eof++;
234*37da2899SCharles.Forsyth		scaler->rasterin(rs, col_row);
235*37da2899SCharles.Forsyth		while ((scaled_col_row := scaler->rasterout(rs)) != nil) {
236*37da2899SCharles.Forsyth			rasterno++;
237*37da2899SCharles.Forsyth			fRasterOdd := rasterno & 1;
238*37da2899SCharles.Forsyth			kcmy_row := SimpleColorMatch(cmap1, scaled_col_row);
239*37da2899SCharles.Forsyth			if (DEBUG) {
240*37da2899SCharles.Forsyth				dbg("Scaled Raster line:");
241*37da2899SCharles.Forsyth				for (q:=0; q<len scaled_col_row; q++) {
242*37da2899SCharles.Forsyth					(r, g, b) := display.cmap2rgb(scaled_col_row[q]);
243*37da2899SCharles.Forsyth					dbg(sys->sprint("%d rgb=(%d,%d,%d) kcmy=(%d,%d,%d,%d)\n", int scaled_col_row[q],
244*37da2899SCharles.Forsyth						r, g, b, int kcmy_row[q].k, int kcmy_row[q].c, int kcmy_row[q].m, int kcmy_row[q].y));
245*37da2899SCharles.Forsyth				}
246*37da2899SCharles.Forsyth				dbg("\n");
247*37da2899SCharles.Forsyth			}
248*37da2899SCharles.Forsyth			Contone_K := Contone[K];
249*37da2899SCharles.Forsyth			Contone_C := Contone[C];
250*37da2899SCharles.Forsyth			Contone_M := Contone[M];
251*37da2899SCharles.Forsyth			Contone_Y := Contone[Y];
252*37da2899SCharles.Forsyth			for (ii:=0; ii<len Contone[K]; ii++) {
253*37da2899SCharles.Forsyth				kcmy := kcmy_row[ii];
254*37da2899SCharles.Forsyth				Contone_K[ii] = kcmy.k;
255*37da2899SCharles.Forsyth				Contone_C[ii] = kcmy.c;
256*37da2899SCharles.Forsyth				Contone_M[ii] = kcmy.m;
257*37da2899SCharles.Forsyth				Contone_Y[ii] = kcmy.y;
258*37da2899SCharles.Forsyth			}
259*37da2899SCharles.Forsyth			if (map2 != nil) {		# For lighter inks
260*37da2899SCharles.Forsyth				kcmy_row_light := SimpleColorMatch(cmap2, scaled_col_row);
261*37da2899SCharles.Forsyth				Contone_Clight := Contone[Clight];
262*37da2899SCharles.Forsyth				Contone_Mlight := Contone[Mlight];
263*37da2899SCharles.Forsyth				for (ii=0; ii<len Contone[Clight]; ii++) {
264*37da2899SCharles.Forsyth					kcmy := kcmy_row_light[ii];
265*37da2899SCharles.Forsyth					Contone_Clight[ii] = kcmy.c;
266*37da2899SCharles.Forsyth					Contone_Mlight[ii] = kcmy.m;
267*37da2899SCharles.Forsyth				}
268*37da2899SCharles.Forsyth			}
269*37da2899SCharles.Forsyth
270*37da2899SCharles.Forsyth			for (i:=0; i< Nplanes; i++) {
271*37da2899SCharles.Forsyth# Pixel multiply here!!
272*37da2899SCharles.Forsyth				fDitherParms[i].fNumPix = OutputWidth[i];
273*37da2899SCharles.Forsyth				fDitherParms[i].fInput = Contone[i];
274*37da2899SCharles.Forsyth				fDitherParms[i].fErr = ErrBuff[i];
275*37da2899SCharles.Forsyth#				fDitherParms[i].fErr++;		// serpentine (?)
276*37da2899SCharles.Forsyth				fDitherParms[i].fSymmetricFlag = 1;
277*37da2899SCharles.Forsyth#				if (i == K)
278*37da2899SCharles.Forsyth#					fDitherParms[i].fFEDResPtr = fBlackFEDResPtr;
279*37da2899SCharles.Forsyth#				else
280*37da2899SCharles.Forsyth#					fDitherParms[i].fFEDResPtr = fColorFEDResPtr;
281*37da2899SCharles.Forsyth				fDitherParms[i].fFEDRes = FEDarray;
282*37da2899SCharles.Forsyth				fDitherParms[i].fRasterEvenOrOdd = fRasterOdd;
283*37da2899SCharles.Forsyth				fDitherParms[i].fHifipe = ColorDepth[i] > 1;
284*37da2899SCharles.Forsyth				for (j=0; j < NumRows[i]; j++) {
285*37da2899SCharles.Forsyth					fDitherParms[i].fOutput1 = ColorPlane[i][j][0];
286*37da2899SCharles.Forsyth					if (fDitherParms[i].fHifipe)
287*37da2899SCharles.Forsyth						fDitherParms[i].fOutput2 = ColorPlane[i][j][1];
288*37da2899SCharles.Forsyth#					dbg(sys->sprint("Dither for Row %d ColorPlane[%d][%d]\n", rasterno, i, j));
289*37da2899SCharles.Forsyth					Dither(fDitherParms[i]);
290*37da2899SCharles.Forsyth				}
291*37da2899SCharles.Forsyth			}
292*37da2899SCharles.Forsyth
293*37da2899SCharles.Forsyth			FINALPLANE: con 3;
294*37da2899SCharles.Forsyth#			NfinalPlanes := 4;
295*37da2899SCharles.Forsyth			for (i=0; i<=FINALPLANE; i++) {
296*37da2899SCharles.Forsyth				cp_i := ColorPlane[i];
297*37da2899SCharles.Forsyth				coldepth_i := ColorDepth[i];
298*37da2899SCharles.Forsyth				finalrow := NumRows[i]-1;
299*37da2899SCharles.Forsyth				for (j=0; j<=finalrow; j++) {
300*37da2899SCharles.Forsyth					cp_i_j := cp_i[j];
301*37da2899SCharles.Forsyth					for (k:=0; k<coldepth_i; k++) {
302*37da2899SCharles.Forsyth						if (i == FINALPLANE && j == finalrow && k == coldepth_i-1)
303*37da2899SCharles.Forsyth							PCL_Transfer_Raster_Row(cp_i_j[k]);
304*37da2899SCharles.Forsyth						else
305*37da2899SCharles.Forsyth							PCL_Transfer_Raster_Plane(cp_i_j[k]);
306*37da2899SCharles.Forsyth						if (cancelled.value) {
307*37da2899SCharles.Forsyth							PCL_Reset();
308*37da2899SCharles.Forsyth							outclose();
309*37da2899SCharles.Forsyth							killgrp(grppid);
310*37da2899SCharles.Forsyth							return -1;
311*37da2899SCharles.Forsyth						}
312*37da2899SCharles.Forsyth					}
313*37da2899SCharles.Forsyth				}
314*37da2899SCharles.Forsyth			}
315*37da2899SCharles.Forsyth		}
316*37da2899SCharles.Forsyth	}
317*37da2899SCharles.Forsyth	PCL_End_Raster();
318*37da2899SCharles.Forsyth	PCL_Reset();
319*37da2899SCharles.Forsyth	outclose();
320*37da2899SCharles.Forsyth	killgrp(grppid);
321*37da2899SCharles.Forsyth	if (cancelled.value)
322*37da2899SCharles.Forsyth		return -1;
323*37da2899SCharles.Forsyth#sys->print("dlen %d, clen %d overruns %d\n", dlen, clen, overruns);
324*37da2899SCharles.Forsyth	return 0;
325*37da2899SCharles.Forsyth}
326*37da2899SCharles.Forsyth
327*37da2899SCharles.Forsyth
328*37da2899SCharles.Forsyth# Send text to printer
329*37da2899SCharles.Forsyth
330*37da2899SCharles.Forsythsendtextfd(p: ref Print->Printer, pfd, tfd: ref Sys->FD, pointsize: real, proportional: int, wrap: int): int
331*37da2899SCharles.Forsyth{
332*37da2899SCharles.Forsyth	outopen(pfd);
333*37da2899SCharles.Forsyth	pcl_startjob(p);
334*37da2899SCharles.Forsyth	if (wrap) PCL_End_of_Line_Wrap(0);
335*37da2899SCharles.Forsyth	LATIN1: con "0N";
336*37da2899SCharles.Forsyth	PCL_Font_Symbol_Set(LATIN1);
337*37da2899SCharles.Forsyth	if (proportional) PCL_Font_Spacing(1);
338*37da2899SCharles.Forsyth	if (pointsize > 0.0) {
339*37da2899SCharles.Forsyth		PCL_Font_Height(pointsize);
340*37da2899SCharles.Forsyth		pitch := 10.0*12.0/pointsize;
341*37da2899SCharles.Forsyth		PCL_Font_Pitch(pitch);
342*37da2899SCharles.Forsyth		spacing := int (6.0*12.0/pointsize);
343*37da2899SCharles.Forsyth		PCL_Line_Spacing(spacing);
344*37da2899SCharles.Forsyth		dbg(sys->sprint("Text: pointsize %f pitch %f spacing %d\n", pointsize, pitch, spacing));
345*37da2899SCharles.Forsyth	}
346*37da2899SCharles.Forsyth	PCL_Line_Termination(3);
347*37da2899SCharles.Forsyth	inbuf := bufio->fopen(tfd, Bufio->OREAD);
348*37da2899SCharles.Forsyth	while ((line := inbuf.gets('\n')) != nil) {
349*37da2899SCharles.Forsyth		ob := array of byte line;
350*37da2899SCharles.Forsyth		outwrite(ob, len ob);
351*37da2899SCharles.Forsyth	}
352*37da2899SCharles.Forsyth	PCL_Reset();
353*37da2899SCharles.Forsyth	outclose();
354*37da2899SCharles.Forsyth	return 0;
355*37da2899SCharles.Forsyth}
356*37da2899SCharles.Forsyth
357*37da2899SCharles.Forsyth
358*37da2899SCharles.Forsyth
359*37da2899SCharles.Forsyth# Common PCL start
360*37da2899SCharles.Forsyth
361*37da2899SCharles.Forsythpcl_startjob(p: ref Printer)
362*37da2899SCharles.Forsyth{
363*37da2899SCharles.Forsyth	PCL_Reset();
364*37da2899SCharles.Forsyth	if (p.popt.duplex) {
365*37da2899SCharles.Forsyth		esc("%-12345X@PJL DEFAULT DUPLEX=ON\n");
366*37da2899SCharles.Forsyth		esc("%-12345X");
367*37da2899SCharles.Forsyth	}
368*37da2899SCharles.Forsyth	if (p.popt.paper.hpcode != "")
369*37da2899SCharles.Forsyth		PCL_Page_Size(p.popt.paper.hpcode);
370*37da2899SCharles.Forsyth	PCL_Orientation(p.popt.orientation);
371*37da2899SCharles.Forsyth	PCL_Duplex(p.popt.duplex);
372*37da2899SCharles.Forsyth}
373*37da2899SCharles.Forsyth
374*37da2899SCharles.Forsyth
375*37da2899SCharles.Forsyth# Spawned to return  sequence of rotated image rows
376*37da2899SCharles.Forsyth
377*37da2899SCharles.Forsythrotate(im: ref Draw->Image, linechan: chan of array of int, adjwidth: int)
378*37da2899SCharles.Forsyth{
379*37da2899SCharles.Forsyth	xmin := im.r.min.x;
380*37da2899SCharles.Forsyth	xmax := im.r.max.x;
381*37da2899SCharles.Forsyth	InputWidth := xmax - xmin;
382*37da2899SCharles.Forsyth	rawchan := chan of array of int;
383*37da2899SCharles.Forsyth	spawn row_by_row(im, rawchan, InputWidth);
384*37da2899SCharles.Forsyth	r_image := array[InputWidth] of {* => array [adjwidth] of {* => 0}};
385*37da2899SCharles.Forsyth	r_row := 0;
386*37da2899SCharles.Forsyth	while ((col_row := <- rawchan) != nil) {
387*37da2899SCharles.Forsyth		endy := len col_row - 1;
388*37da2899SCharles.Forsyth		for (i:=0; i<len col_row; i++)
389*37da2899SCharles.Forsyth			r_image[endy - i][r_row] = col_row[i];
390*37da2899SCharles.Forsyth		r_row++;
391*37da2899SCharles.Forsyth	}
392*37da2899SCharles.Forsyth	for (i:=0; i<len r_image; i++)
393*37da2899SCharles.Forsyth		linechan <-= r_image[i];
394*37da2899SCharles.Forsyth	linechan <-= nil;
395*37da2899SCharles.Forsyth}
396*37da2899SCharles.Forsyth
397*37da2899SCharles.Forsyth
398*37da2899SCharles.Forsyth# Spawned to return sequence of image rows
399*37da2899SCharles.Forsyth
400*37da2899SCharles.Forsythrow_by_row(im: ref Draw->Image, linechan: chan of array of int, adjwidth: int)
401*37da2899SCharles.Forsyth{
402*37da2899SCharles.Forsyth	xmin := im.r.min.x;
403*37da2899SCharles.Forsyth	ymin := im.r.min.y;
404*37da2899SCharles.Forsyth	xmax := im.r.max.x;
405*37da2899SCharles.Forsyth	ymax := im.r.max.y;
406*37da2899SCharles.Forsyth	InputWidth := xmax - xmin;
407*37da2899SCharles.Forsyth	bpp := im.depth;
408*37da2899SCharles.Forsyth	ld := ldepth(im.depth);
409*37da2899SCharles.Forsyth	bytesperline := (InputWidth*bpp+7)/8;
410*37da2899SCharles.Forsyth	rdata := array[bytesperline+10] of byte;
411*37da2899SCharles.Forsyth	pad0 := array [7] of { * => 0};
412*37da2899SCharles.Forsyth	for (y:=ymin; y<ymax; y++) {
413*37da2899SCharles.Forsyth		col_row := array[adjwidth] of int;
414*37da2899SCharles.Forsyth		rect := Rect((xmin, y), (xmax, y+1));
415*37da2899SCharles.Forsyth		np := im.readpixels(rect, rdata);
416*37da2899SCharles.Forsyth		if (np < 0)
417*37da2899SCharles.Forsyth			fatal("Error reading image\n");
418*37da2899SCharles.Forsyth		dbg(sys->sprint("Input Raster line %d: np=%d\n  ", y, np));
419*37da2899SCharles.Forsyth		ind := 0;
420*37da2899SCharles.Forsyth		mask := MASK[ld];
421*37da2899SCharles.Forsyth		shift := SHIFT[ld];
422*37da2899SCharles.Forsyth		col_row[adjwidth-7:] = pad0;	# Pad to adjusted width with white
423*37da2899SCharles.Forsyth		data := rdata[ind];
424*37da2899SCharles.Forsyth		for (q:=0; q<InputWidth; q++) {
425*37da2899SCharles.Forsyth			col := int ((data  >> shift) & mask);
426*37da2899SCharles.Forsyth			shift -= bpp;
427*37da2899SCharles.Forsyth			if (shift < 0) {
428*37da2899SCharles.Forsyth				shift = SHIFT[ld];
429*37da2899SCharles.Forsyth				ind++;
430*37da2899SCharles.Forsyth				data = rdata[ind];
431*37da2899SCharles.Forsyth			}
432*37da2899SCharles.Forsyth			col_row[q] = col;
433*37da2899SCharles.Forsyth		}
434*37da2899SCharles.Forsyth		linechan <-= col_row;
435*37da2899SCharles.Forsyth	}
436*37da2899SCharles.Forsyth	linechan <-= nil;
437*37da2899SCharles.Forsyth}
438*37da2899SCharles.Forsyth
439*37da2899SCharles.Forsyth
440*37da2899SCharles.Forsyth# PCL output routines
441*37da2899SCharles.Forsyth
442*37da2899SCharles.Forsyth
443*37da2899SCharles.ForsythPCL_Reset()
444*37da2899SCharles.Forsyth{
445*37da2899SCharles.Forsyth	esc("E");
446*37da2899SCharles.Forsyth}
447*37da2899SCharles.Forsyth
448*37da2899SCharles.Forsyth
449*37da2899SCharles.ForsythPCL_Orientation(value: int)
450*37da2899SCharles.Forsyth{
451*37da2899SCharles.Forsyth	esc(sys->sprint("&l%dO", value));
452*37da2899SCharles.Forsyth}
453*37da2899SCharles.Forsyth
454*37da2899SCharles.ForsythPCL_Duplex(value: int)
455*37da2899SCharles.Forsyth{
456*37da2899SCharles.Forsyth	esc(sys->sprint("&l%dS", value));
457*37da2899SCharles.Forsyth}
458*37da2899SCharles.Forsyth
459*37da2899SCharles.Forsyth
460*37da2899SCharles.ForsythPCL_Left_Margin(value: int)
461*37da2899SCharles.Forsyth{
462*37da2899SCharles.Forsyth	esc(sys->sprint("&a%dL", value));
463*37da2899SCharles.Forsyth}
464*37da2899SCharles.Forsyth
465*37da2899SCharles.ForsythPCL_Page_Size(value: string)
466*37da2899SCharles.Forsyth{
467*37da2899SCharles.Forsyth	esc(sys->sprint("&l%sA", value));
468*37da2899SCharles.Forsyth}
469*37da2899SCharles.Forsyth
470*37da2899SCharles.Forsyth
471*37da2899SCharles.ForsythPCL_End_of_Line_Wrap(value: int)
472*37da2899SCharles.Forsyth{
473*37da2899SCharles.Forsyth	esc(sys->sprint("&s%dC", value));
474*37da2899SCharles.Forsyth}
475*37da2899SCharles.Forsyth
476*37da2899SCharles.ForsythPCL_Line_Termination(value: int)
477*37da2899SCharles.Forsyth{
478*37da2899SCharles.Forsyth	esc(sys->sprint("&k%dG", value));
479*37da2899SCharles.Forsyth}
480*37da2899SCharles.Forsyth
481*37da2899SCharles.Forsyth
482*37da2899SCharles.ForsythPCL_Font_Symbol_Set(value: string)
483*37da2899SCharles.Forsyth{
484*37da2899SCharles.Forsyth	esc(sys->sprint("(%s", value));
485*37da2899SCharles.Forsyth}
486*37da2899SCharles.Forsyth
487*37da2899SCharles.Forsyth
488*37da2899SCharles.ForsythPCL_Font_Pitch(value: real)
489*37da2899SCharles.Forsyth{
490*37da2899SCharles.Forsyth	esc(sys->sprint("(s%2.2fH", value));
491*37da2899SCharles.Forsyth}
492*37da2899SCharles.Forsyth
493*37da2899SCharles.ForsythPCL_Font_Spacing(value: int)
494*37da2899SCharles.Forsyth{
495*37da2899SCharles.Forsyth	esc(sys->sprint("(s%dP", value));
496*37da2899SCharles.Forsyth}
497*37da2899SCharles.Forsyth
498*37da2899SCharles.ForsythPCL_Font_Height(value: real)
499*37da2899SCharles.Forsyth{
500*37da2899SCharles.Forsyth	esc(sys->sprint("(s%2.2fV", value));
501*37da2899SCharles.Forsyth}
502*37da2899SCharles.Forsyth
503*37da2899SCharles.ForsythPCL_Line_Spacing(value: int)
504*37da2899SCharles.Forsyth{
505*37da2899SCharles.Forsyth	esc(sys->sprint("&l%dD", value));
506*37da2899SCharles.Forsyth}
507*37da2899SCharles.Forsyth
508*37da2899SCharles.Forsyth
509*37da2899SCharles.Forsyth
510*37da2899SCharles.ForsythPCL_Start_Raster(current: int)
511*37da2899SCharles.Forsyth{
512*37da2899SCharles.Forsyth	flag := 0;
513*37da2899SCharles.Forsyth	if (current) flag = 1;
514*37da2899SCharles.Forsyth	esc(sys->sprint("*r%dA", flag));
515*37da2899SCharles.Forsyth}
516*37da2899SCharles.Forsyth
517*37da2899SCharles.Forsyth
518*37da2899SCharles.Forsyth
519*37da2899SCharles.ForsythPCL_End_Raster()
520*37da2899SCharles.Forsyth{
521*37da2899SCharles.Forsyth	esc("*rC");
522*37da2899SCharles.Forsyth}
523*37da2899SCharles.Forsyth
524*37da2899SCharles.Forsyth
525*37da2899SCharles.ForsythPCL_Raster_Resolution(ppi: int)
526*37da2899SCharles.Forsyth{
527*37da2899SCharles.Forsyth	esc(sys->sprint("*t%dR", ppi));
528*37da2899SCharles.Forsyth}
529*37da2899SCharles.Forsyth
530*37da2899SCharles.Forsyth
531*37da2899SCharles.ForsythPCL_Source_Raster_Width(pixels: int)
532*37da2899SCharles.Forsyth{
533*37da2899SCharles.Forsyth	esc(sys->sprint("*r%dS", pixels));
534*37da2899SCharles.Forsyth}
535*37da2899SCharles.Forsyth
536*37da2899SCharles.Forsyth
537*37da2899SCharles.ForsythPCL_Simple_Color(palette: int)
538*37da2899SCharles.Forsyth{
539*37da2899SCharles.Forsyth	esc(sys->sprint("*r%dU", palette));
540*37da2899SCharles.Forsyth}
541*37da2899SCharles.Forsyth
542*37da2899SCharles.ForsythPCL_Compression_Method(ctype: int)
543*37da2899SCharles.Forsyth{
544*37da2899SCharles.Forsyth	esc(sys->sprint("*b%dM", ctype));
545*37da2899SCharles.Forsyth
546*37da2899SCharles.Forsyth}
547*37da2899SCharles.Forsyth
548*37da2899SCharles.Forsyth
549*37da2899SCharles.ForsythPCL_Move_CAP_V_Rows(pos: int, absolute: int)
550*37da2899SCharles.Forsyth{
551*37da2899SCharles.Forsyth	plus := "";
552*37da2899SCharles.Forsyth	if (!absolute && pos > 0) plus = "+";
553*37da2899SCharles.Forsyth	esc(sys->sprint("&a%s%dR", plus, pos));
554*37da2899SCharles.Forsyth}
555*37da2899SCharles.Forsyth
556*37da2899SCharles.ForsythPCL_Move_CAP_H_Cols(pos: int, absolute: int)
557*37da2899SCharles.Forsyth{
558*37da2899SCharles.Forsyth	plus := "";
559*37da2899SCharles.Forsyth	if (!absolute && pos > 0) plus = "+";
560*37da2899SCharles.Forsyth	esc(sys->sprint("&a%s%dC", plus, pos));
561*37da2899SCharles.Forsyth}
562*37da2899SCharles.Forsyth
563*37da2899SCharles.Forsyth# These Units are 1/300 of an inch.
564*37da2899SCharles.Forsyth
565*37da2899SCharles.ForsythPCL_Move_CAP_H_Units(pos: int, absolute: int)
566*37da2899SCharles.Forsyth{
567*37da2899SCharles.Forsyth	plus := "";
568*37da2899SCharles.Forsyth	if (!absolute && pos > 0) plus = "+";
569*37da2899SCharles.Forsyth	esc(sys->sprint("*p%s%dX", plus, pos));
570*37da2899SCharles.Forsyth}
571*37da2899SCharles.Forsyth
572*37da2899SCharles.Forsyth
573*37da2899SCharles.Forsyth
574*37da2899SCharles.ForsythPCL_Move_CAP_V_Units(pos: int, absolute: int)
575*37da2899SCharles.Forsyth{
576*37da2899SCharles.Forsyth	plus := "";
577*37da2899SCharles.Forsyth	if (!absolute && pos > 0) plus = "+";
578*37da2899SCharles.Forsyth	esc(sys->sprint("*p%s%dY", plus, pos));
579*37da2899SCharles.Forsyth}
580*37da2899SCharles.Forsyth
581*37da2899SCharles.Forsyth
582*37da2899SCharles.Forsyth
583*37da2899SCharles.ForsythPCL_Configure_Raster_Data4(hres, vres: int, ColorDepth: array of int)
584*37da2899SCharles.Forsyth{
585*37da2899SCharles.Forsyth	ncomponents := 4;
586*37da2899SCharles.Forsyth	msg := array[ncomponents*6 + 2] of byte;
587*37da2899SCharles.Forsyth	i := 0;
588*37da2899SCharles.Forsyth	msg[i++] = byte 2;	# Format
589*37da2899SCharles.Forsyth	msg[i++] = byte ncomponents;	# KCMY
590*37da2899SCharles.Forsyth	for (c:=0; c<ncomponents; c++) {
591*37da2899SCharles.Forsyth		msg[i++] = byte (hres/256);
592*37da2899SCharles.Forsyth		msg[i++] = byte (hres%256);
593*37da2899SCharles.Forsyth		msg[i++] = byte (vres/256);
594*37da2899SCharles.Forsyth		msg[i++] = byte (vres%256);
595*37da2899SCharles.Forsyth
596*37da2899SCharles.Forsyth		depth := 1 << ColorDepth[c];
597*37da2899SCharles.Forsyth		msg[i++] = byte (depth/256);
598*37da2899SCharles.Forsyth		msg[i++] = byte (depth%256);
599*37da2899SCharles.Forsyth	}
600*37da2899SCharles.Forsyth	if (DEBUG) {
601*37da2899SCharles.Forsyth		dbg("CRD: ");
602*37da2899SCharles.Forsyth		for (ii:=0; ii<len msg; ii++) dbg(sys->sprint("%d(%x) ", int msg[ii], int msg[ii]));
603*37da2899SCharles.Forsyth		dbg("\n");
604*37da2899SCharles.Forsyth	}
605*37da2899SCharles.Forsyth	esc(sys->sprint("*g%dW", len msg));
606*37da2899SCharles.Forsyth	outwrite(msg, len msg);
607*37da2899SCharles.Forsyth}
608*37da2899SCharles.Forsyth
609*37da2899SCharles.Forsythdlen := 0;
610*37da2899SCharles.Forsythclen := 0;
611*37da2899SCharles.Forsythoverruns := 0;
612*37da2899SCharles.ForsythPCL_Transfer_Raster_Plane(data: array of byte)
613*37da2899SCharles.Forsyth{
614*37da2899SCharles.Forsyth	if (DEBUG) {
615*37da2899SCharles.Forsyth		dbg("Transfer_Raster_Plane:");
616*37da2899SCharles.Forsyth		for (i:=0; i<len data; i++) dbg(sys->sprint(" %x", int data[i]));
617*37da2899SCharles.Forsyth		dbg("\n");
618*37da2899SCharles.Forsyth	}
619*37da2899SCharles.Forsyth	if (Compression) {
620*37da2899SCharles.Forsythd := len data;
621*37da2899SCharles.Forsythdlen += d;
622*37da2899SCharles.Forsyth		data = compress(data);
623*37da2899SCharles.Forsythc := len data;
624*37da2899SCharles.Forsythclen += c;
625*37da2899SCharles.Forsythif (c > d)
626*37da2899SCharles.Forsyth	overruns += c-d;
627*37da2899SCharles.Forsyth		if (DEBUG) {
628*37da2899SCharles.Forsyth			dbg("Compressed Transfer_Raster_Plane:");
629*37da2899SCharles.Forsyth			for (i:=0; i<len data; i++) dbg(sys->sprint(" %x", int data[i]));
630*37da2899SCharles.Forsyth			dbg("\n");
631*37da2899SCharles.Forsyth		}
632*37da2899SCharles.Forsyth	}
633*37da2899SCharles.Forsyth	esc(sys->sprint("*b%dV", len data));
634*37da2899SCharles.Forsyth	outwrite(data, len data);
635*37da2899SCharles.Forsyth}
636*37da2899SCharles.Forsyth
637*37da2899SCharles.Forsyth
638*37da2899SCharles.ForsythPCL_Transfer_Raster_Row(data: array of byte)
639*37da2899SCharles.Forsyth{
640*37da2899SCharles.Forsyth	if (DEBUG) {
641*37da2899SCharles.Forsyth		dbg("Transfer_Raster_Row:");
642*37da2899SCharles.Forsyth		for (i:=0; i<len data; i++) dbg(sys->sprint(" %x", int data[i]));
643*37da2899SCharles.Forsyth		dbg("\n");
644*37da2899SCharles.Forsyth	}
645*37da2899SCharles.Forsyth	if (Compression) {
646*37da2899SCharles.Forsyth		data = compress(data);
647*37da2899SCharles.Forsyth		if (DEBUG) {
648*37da2899SCharles.Forsyth			dbg("Compressed Transfer_Raster_Row:");
649*37da2899SCharles.Forsyth			for (i:=0; i<len data; i++) dbg(sys->sprint(" %x", int data[i]));
650*37da2899SCharles.Forsyth			dbg("\n");
651*37da2899SCharles.Forsyth		}
652*37da2899SCharles.Forsyth	}
653*37da2899SCharles.Forsyth	esc(sys->sprint("*b%dW", len data));
654*37da2899SCharles.Forsyth	outwrite(data, len data);
655*37da2899SCharles.Forsyth}
656*37da2899SCharles.Forsyth
657*37da2899SCharles.Forsyth
658*37da2899SCharles.Forsythoutopen(fd: ref Sys->FD)
659*37da2899SCharles.Forsyth{
660*37da2899SCharles.Forsyth	outbuf = bufio->fopen(fd, Bufio->OWRITE);
661*37da2899SCharles.Forsyth	if (outbuf == nil) sys->fprint(stderr, "Failed to open output fd: %r\n");
662*37da2899SCharles.Forsyth}
663*37da2899SCharles.Forsyth
664*37da2899SCharles.Forsythoutclose()
665*37da2899SCharles.Forsyth{
666*37da2899SCharles.Forsyth	outbuf.close();
667*37da2899SCharles.Forsyth}
668*37da2899SCharles.Forsyth
669*37da2899SCharles.Forsyth
670*37da2899SCharles.Forsyth# Write to output using buffered io
671*37da2899SCharles.Forsyth
672*37da2899SCharles.Forsythoutwrite(data: array of byte, length: int)
673*37da2899SCharles.Forsyth{
674*37da2899SCharles.Forsyth	outbuf.write(data, length);
675*37da2899SCharles.Forsyth}
676*37da2899SCharles.Forsyth
677*37da2899SCharles.Forsyth
678*37da2899SCharles.Forsyth# Send escape code to printer
679*37da2899SCharles.Forsyth
680*37da2899SCharles.Forsythesc(s: string)
681*37da2899SCharles.Forsyth{
682*37da2899SCharles.Forsyth	os := sys->sprint("%c%s", ESC, s);
683*37da2899SCharles.Forsyth	ob := array of byte os;
684*37da2899SCharles.Forsyth	outwrite(ob, len ob);
685*37da2899SCharles.Forsyth}
686*37da2899SCharles.Forsyth
687*37da2899SCharles.Forsyth
688*37da2899SCharles.Forsyth# Read all the maps
689*37da2899SCharles.Forsythreadmaps(p: ref Printer): (array of KCMY, array of KCMY)
690*37da2899SCharles.Forsyth{
691*37da2899SCharles.Forsyth
692*37da2899SCharles.Forsyth	mapfile := p.ptype.hpmapfile;
693*37da2899SCharles.Forsyth	mapf1 := Pdriver->DATAPREFIX + mapfile + ".map";
694*37da2899SCharles.Forsyth	m1 := read_map(mapf1);
695*37da2899SCharles.Forsyth	if (m1 == nil) fatal("Failed to read map file");
696*37da2899SCharles.Forsyth	mapf2 := Pdriver->DATAPREFIX + mapfile + "_2.map";
697*37da2899SCharles.Forsyth	m2 := read_map(mapf2);
698*37da2899SCharles.Forsyth	return (m1, m2);
699*37da2899SCharles.Forsyth}
700*37da2899SCharles.Forsyth
701*37da2899SCharles.Forsyth
702*37da2899SCharles.Forsyth# Read a map file
703*37da2899SCharles.Forsyth
704*37da2899SCharles.Forsythread_map(mapfile: string) : array of KCMY
705*37da2899SCharles.Forsyth{
706*37da2899SCharles.Forsyth	mf := bufio->open(mapfile, bufio->OREAD);
707*37da2899SCharles.Forsyth	if (mf == nil) return nil;
708*37da2899SCharles.Forsyth	CUBESIZE: con 9*9*9;
709*37da2899SCharles.Forsyth	marray := array[CUBESIZE] of KCMY;
710*37da2899SCharles.Forsyth	i := 0;
711*37da2899SCharles.Forsyth	while (i <CUBESIZE && (lstr := bufio->mf.gets('\n')) != nil) {
712*37da2899SCharles.Forsyth		(n, toks) := sys->tokenize(lstr, " \t");
713*37da2899SCharles.Forsyth		if (n >= 4) {
714*37da2899SCharles.Forsyth			marray[i].k = byte int hd toks;
715*37da2899SCharles.Forsyth			toks = tl toks;
716*37da2899SCharles.Forsyth			marray[i].c = byte int hd toks;
717*37da2899SCharles.Forsyth			toks = tl toks;
718*37da2899SCharles.Forsyth			marray[i].m = byte int hd toks;
719*37da2899SCharles.Forsyth			toks = tl toks;
720*37da2899SCharles.Forsyth			marray[i].y = byte int hd toks;
721*37da2899SCharles.Forsyth			i++;
722*37da2899SCharles.Forsyth		}
723*37da2899SCharles.Forsyth	}
724*37da2899SCharles.Forsyth	return marray;
725*37da2899SCharles.Forsyth}
726*37da2899SCharles.Forsyth
727*37da2899SCharles.Forsyth
728*37da2899SCharles.Forsyth
729*37da2899SCharles.Forsyth
730*37da2899SCharles.Forsyth# Big interpolation routine
731*37da2899SCharles.Forsyth
732*37da2899SCharles.Forsyth# static data
733*37da2899SCharles.Forsythprev := RGB (byte 255, byte 255, byte 255);
734*37da2899SCharles.Forsythresult: KCMY;
735*37da2899SCharles.Forsythoffset := array[] of { 0, 1, 9, 10, 81, 82, 90, 91 };
736*37da2899SCharles.Forsyth
737*37da2899SCharles.Forsyth
738*37da2899SCharles.ForsythInterpolate(map: array of KCMY, start: int, rgb: RGB, firstpixel: int): KCMY
739*37da2899SCharles.Forsyth{
740*37da2899SCharles.Forsyth	cyan := array[8] of int;
741*37da2899SCharles.Forsyth	magenta := array[8] of int;
742*37da2899SCharles.Forsyth	yellow := array[8] of int;
743*37da2899SCharles.Forsyth	black := array[8] of int;
744*37da2899SCharles.Forsyth
745*37da2899SCharles.Forsyth	if (firstpixel || prev.r != rgb.r || prev.g != rgb.g || prev.b != rgb.b) {
746*37da2899SCharles.Forsyth		prev = rgb;
747*37da2899SCharles.Forsyth		for (j:=0; j<8; j++) {
748*37da2899SCharles.Forsyth			ioff := start+offset[j];
749*37da2899SCharles.Forsyth			cyan[j] = int map[ioff].c;
750*37da2899SCharles.Forsyth			magenta[j] = int map[ioff].m;
751*37da2899SCharles.Forsyth			yellow[j] = int map[ioff].y;
752*37da2899SCharles.Forsyth			black[j] = int map[ioff].k;
753*37da2899SCharles.Forsyth		}
754*37da2899SCharles.Forsyth
755*37da2899SCharles.Forsyth		diff_red := int rgb.r & 16r1f;
756*37da2899SCharles.Forsyth		diff_green := int rgb.g & 16r1f;
757*37da2899SCharles.Forsyth		diff_blue := int rgb.b & 16r1f;
758*37da2899SCharles.Forsyth
759*37da2899SCharles.Forsyth
760*37da2899SCharles.Forsyth        result.c   = byte (((cyan[0] + ( ( (cyan[4] - cyan[0] ) * diff_red) >> 5)) + ( ( ((cyan[2] + ( ( (cyan[6] - cyan[2] ) * diff_red) >> 5)) -(cyan[0] + ( ( (cyan[4] - cyan[0] ) * diff_red) >> 5)) ) * diff_green) >> 5)) + ( ( (((cyan[1] + ( ( (cyan[5] - cyan[1] ) * diff_red) >> 5)) + ( ( ((cyan[3] + ( ( (cyan[7] - cyan[3] ) * diff_red) >> 5)) -(cyan[1] + ( ( (cyan[5] - cyan[1] ) * diff_red) >> 5)) ) * diff_green) >> 5)) -((cyan[0] + ( ( (cyan[4] - cyan[0] ) * diff_red) >> 5)) + ( ( ((cyan[2] + ( ( (cyan[6] - cyan[2] ) * diff_red) >> 5)) -(cyan[0] + ( ( (cyan[4] - cyan[0] ) * diff_red) >> 5)) ) * diff_green) >> 5)) ) * diff_blue) >> 5));
761*37da2899SCharles.Forsyth
762*37da2899SCharles.Forsyth        result.m = byte (((magenta[0] + ( ( (magenta[4] - magenta[0] ) * diff_red) >> 5)) + ( ( ((magenta[2] + ( ( (magenta[6] - magenta[2] ) * diff_red) >> 5)) -(magenta[0] + ( ( (magenta[4] - magenta[0] ) * diff_red) >> 5)) ) * diff_green) >> 5)) + ( ( (((magenta[1] + ( ( (magenta[5] - magenta[1] ) * diff_red) >> 5)) + ( ( ((magenta[3] + ( ( (magenta[7] - magenta[3] ) * diff_red) >> 5)) -(magenta[1] + ( ( (magenta[5] - magenta[1] ) * diff_red) >> 5)) ) * diff_green) >> 5)) -((magenta[0] + ( ( (magenta[4] - magenta[0] ) * diff_red) >> 5)) + ( ( ((magenta[2] + ( ( (magenta[6] - magenta[2] ) * diff_red) >> 5)) -(magenta[0] + ( ( (magenta[4] - magenta[0] ) * diff_red) >> 5)) ) * diff_green) >> 5)) ) * diff_blue) >> 5));
763*37da2899SCharles.Forsyth
764*37da2899SCharles.Forsyth        result.y = byte (((yellow[0] + ( ( (yellow[4] - yellow[0] ) * diff_red) >> 5)) + ( ( ((yellow[2] + ( ( (yellow[6] - yellow[2] ) * diff_red) >> 5)) -(yellow[0] + ( ( (yellow[4] - yellow[0] ) * diff_red) >> 5)) ) * diff_green) >> 5)) + ( ( (((yellow[1] + ( ( (yellow[5] - yellow[1] ) * diff_red) >> 5)) + ( ( ((yellow[3] + ( ( (yellow[7] - yellow[3] ) * diff_red) >> 5)) -(yellow[1] + ( ( (yellow[5] - yellow[1] ) * diff_red) >> 5)) ) * diff_green) >> 5)) -((yellow[0] + ( ( (yellow[4] - yellow[0] ) * diff_red) >> 5)) + ( ( ((yellow[2] + ( ( (yellow[6] - yellow[2] ) * diff_red) >> 5)) -(yellow[0] + ( ( (yellow[4] - yellow[0] ) * diff_red) >> 5)) ) * diff_green) >> 5)) ) * diff_blue) >> 5));
765*37da2899SCharles.Forsyth
766*37da2899SCharles.Forsyth        result.k  = byte (((black[0] + ( ( (black[4] - black[0] ) * diff_red) >> 5)) + ( ( ((black[2] + ( ( (black[6] - black[2] ) * diff_red) >> 5)) -(black[0] + ( ( (black[4] - black[0] ) * diff_red) >> 5)) ) * diff_green) >> 5)) + ( ( (((black[1] + ( ( (black[5] - black[1] ) * diff_red) >> 5)) + ( ( ((black[3] + ( ( (black[7] - black[3] ) * diff_red) >> 5)) -(black[1] + ( ( (black[5] - black[1] ) * diff_red) >> 5)) ) * diff_green) >> 5)) -((black[0] + ( ( (black[4] - black[0] ) * diff_red) >> 5)) + ( ( ((black[2] + ( ( (black[6] - black[2] ) * diff_red) >> 5)) -(black[0] + ( ( (black[4] - black[0] ) * diff_red) >> 5)) ) * diff_green) >> 5)) ) * diff_blue) >> 5));
767*37da2899SCharles.Forsyth
768*37da2899SCharles.Forsyth	}
769*37da2899SCharles.Forsyth	return result;
770*37da2899SCharles.Forsyth}
771*37da2899SCharles.Forsyth
772*37da2899SCharles.Forsyth# Colour RGB to KCMY convertor
773*37da2899SCharles.Forsyth
774*37da2899SCharles.ForsythColorMatch(map: array of KCMY, row: array of RGB): array of KCMY
775*37da2899SCharles.Forsyth{
776*37da2899SCharles.Forsyth	kcmy := array[len row] of KCMY;
777*37da2899SCharles.Forsyth	first := 1;
778*37da2899SCharles.Forsyth	for (i:=0; i<len row; i++) {
779*37da2899SCharles.Forsyth		r := int row[i].r;
780*37da2899SCharles.Forsyth		g := int row[i].g;
781*37da2899SCharles.Forsyth		b := int row[i].b;
782*37da2899SCharles.Forsyth		start := ((r & 16re0) << 1) + ((r & 16re0) >> 1) + (r >> 5) +
783*37da2899SCharles.Forsyth				((g & 16re0) >> 2) + (g >> 5) + (b >> 5);
784*37da2899SCharles.Forsyth		kcmy[i] =  Interpolate(map, start, row[i],  first);
785*37da2899SCharles.Forsyth#		dbg(sys->sprint("+++ for (%d,%d,%d) Interpolate returned (%d,%d,%d,%d)\n", r, g, b, int kcmy[i].k, int kcmy[i].c, int kcmy[i].m, int kcmy[i].y));
786*37da2899SCharles.Forsyth		first = 0;
787*37da2899SCharles.Forsyth	}
788*37da2899SCharles.Forsyth	return kcmy;
789*37da2899SCharles.Forsyth}
790*37da2899SCharles.Forsyth
791*37da2899SCharles.Forsyth
792*37da2899SCharles.Forsyth# Simple version of above to lookup precalculated values
793*37da2899SCharles.Forsyth
794*37da2899SCharles.ForsythSimpleColorMatch(cmap: array of KCMY, colrow: array of int): array of KCMY
795*37da2899SCharles.Forsyth{
796*37da2899SCharles.Forsyth	ncolrow := len colrow;
797*37da2899SCharles.Forsyth	kcmy_row := array[ncolrow] of KCMY;
798*37da2899SCharles.Forsyth	for (i:=0; i<ncolrow; i++)
799*37da2899SCharles.Forsyth		kcmy_row[i] = cmap[colrow[i]];
800*37da2899SCharles.Forsyth	return kcmy_row;
801*37da2899SCharles.Forsyth}
802*37da2899SCharles.Forsyth
803*37da2899SCharles.Forsyth
804*37da2899SCharles.Forsythldepth(d: int): int
805*37da2899SCharles.Forsyth{
806*37da2899SCharles.Forsyth	if(d & (d-1) || d >= 16)
807*37da2899SCharles.Forsyth		return 4;
808*37da2899SCharles.Forsyth	for(i := 0; i < 3; i++)
809*37da2899SCharles.Forsyth		if(d <= (1<<i))
810*37da2899SCharles.Forsyth			break;
811*37da2899SCharles.Forsyth	return i;
812*37da2899SCharles.Forsyth}
813*37da2899SCharles.Forsyth
814*37da2899SCharles.Forsyth
815*37da2899SCharles.Forsyth# Set up color map once and for all
816*37da2899SCharles.Forsyth
817*37da2899SCharles.Forsythsetup_color_map(display: ref Display, map: array of KCMY, depth: int): array of KCMY
818*37da2899SCharles.Forsyth{
819*37da2899SCharles.Forsyth	gsfactor := GSFACTOR[ldepth(depth)];
820*37da2899SCharles.Forsyth	bpp := depth;
821*37da2899SCharles.Forsyth	max := 1 << bpp;
822*37da2899SCharles.Forsyth	rgb_row := array[max] of RGB;
823*37da2899SCharles.Forsyth	for (i:=0; i<max; i++) {
824*37da2899SCharles.Forsyth		if (depth >= 8) {
825*37da2899SCharles.Forsyth			(r, g, b) := display.cmap2rgb(i);
826*37da2899SCharles.Forsyth			rgb_row[i] = RGB (byte r, byte g, byte b);
827*37da2899SCharles.Forsyth		} else {	# BW or Greyscale
828*37da2899SCharles.Forsyth			grey := byte (255-int (real i * gsfactor));
829*37da2899SCharles.Forsyth			rgb_row[i] = RGB (grey, grey, grey);
830*37da2899SCharles.Forsyth		}
831*37da2899SCharles.Forsyth	}
832*37da2899SCharles.Forsyth	kcmy_row := ColorMatch(map, rgb_row);
833*37da2899SCharles.Forsyth
834*37da2899SCharles.Forsyth	return kcmy_row;
835*37da2899SCharles.Forsyth}
836*37da2899SCharles.Forsyth
837*37da2899SCharles.Forsyth
838*37da2899SCharles.Forsyth
839*37da2899SCharles.Forsyth# Dithering
840*37da2899SCharles.Forsyth
841*37da2899SCharles.ForsythtmpShortStore: int;
842*37da2899SCharles.ForsythdiffusionErrorPtr := 1;	# for serpentine??
843*37da2899SCharles.ForsytherrPtr: array of int;
844*37da2899SCharles.ForsythrasterByte1 := 0;
845*37da2899SCharles.ForsythrasterByte2 := 0;
846*37da2899SCharles.Forsyth
847*37da2899SCharles.Forsythrand8 := array [8] of int;
848*37da2899SCharles.Forsythpad8 := array [8] of {* => 0};
849*37da2899SCharles.Forsyth
850*37da2899SCharles.ForsythDither(ditherParms: DitherParms)
851*37da2899SCharles.Forsyth{
852*37da2899SCharles.Forsyth	errPtr = ditherParms.fErr;
853*37da2899SCharles.Forsyth	numLoop := ditherParms.fNumPix;
854*37da2899SCharles.Forsyth	inputPtr := 0;
855*37da2899SCharles.Forsyth	fedResTbl := ditherParms.fFEDRes;
856*37da2899SCharles.Forsyth	symmetricFlag := ditherParms.fSymmetricFlag;
857*37da2899SCharles.Forsyth	doNext8Pixels : int;
858*37da2899SCharles.Forsyth	hifipe := ditherParms.fHifipe;
859*37da2899SCharles.Forsyth	outputPtr1 := 0;
860*37da2899SCharles.Forsyth	outputPtr2 := 0;
861*37da2899SCharles.Forsyth	diffusionErrorPtr = 1;
862*37da2899SCharles.Forsyth	fInput := ditherParms.fInput;
863*37da2899SCharles.Forsyth
864*37da2899SCharles.Forsyth	if(ditherParms.fRasterEvenOrOdd) {
865*37da2899SCharles.Forsyth		tmpShortStore = errPtr[diffusionErrorPtr];
866*37da2899SCharles.Forsyth		errPtr[diffusionErrorPtr]  = 0;
867*37da2899SCharles.Forsyth
868*37da2899SCharles.Forsyth		for (pixelCount := numLoop + 8; (pixelCount -= 8) > 0; ) {
869*37da2899SCharles.Forsyth			if (pixelCount > 16) {
870*37da2899SCharles.Forsyth				# if next 16 pixels are white, skip 8
871*37da2899SCharles.Forsyth#				doNext8Pixels = Forward16PixelsNonWhite(fInput, inputPtr);
872*37da2899SCharles.Forsyth				doNext8Pixels = 0;
873*37da2899SCharles.Forsyth				lim := inputPtr + 16;
874*37da2899SCharles.Forsyth				for (i := inputPtr; i < lim; i++) {
875*37da2899SCharles.Forsyth					if (fInput[i] != byte 0) {
876*37da2899SCharles.Forsyth						doNext8Pixels = 1;
877*37da2899SCharles.Forsyth						break;
878*37da2899SCharles.Forsyth					}
879*37da2899SCharles.Forsyth				}
880*37da2899SCharles.Forsyth			} else {
881*37da2899SCharles.Forsyth				doNext8Pixels = 1;
882*37da2899SCharles.Forsyth			}
883*37da2899SCharles.Forsyth			if (doNext8Pixels) {
884*37da2899SCharles.ForsythFORWARD_FED8(fInput, inputPtr, fedResTbl);
885*37da2899SCharles.ForsythinputPtr += 8;
886*37da2899SCharles.Forsyth#				HPRand8();
887*37da2899SCharles.Forsyth#				FORWARD_FED(rand8[0], 16r80, fInput[inputPtr++], fedResTbl);
888*37da2899SCharles.Forsyth#				FORWARD_FED(rand8[1], 16r40, fInput[inputPtr++], fedResTbl);
889*37da2899SCharles.Forsyth#				FORWARD_FED(rand8[2], 16r20, fInput[inputPtr++], fedResTbl);
890*37da2899SCharles.Forsyth#				FORWARD_FED(rand8[3], 16r10, fInput[inputPtr++], fedResTbl);
891*37da2899SCharles.Forsyth#				FORWARD_FED(rand8[4], 16r08, fInput[inputPtr++], fedResTbl);
892*37da2899SCharles.Forsyth#				FORWARD_FED(rand8[5], 16r04, fInput[inputPtr++], fedResTbl);
893*37da2899SCharles.Forsyth#				FORWARD_FED(rand8[6], 16r02, fInput[inputPtr++], fedResTbl);
894*37da2899SCharles.Forsyth#				FORWARD_FED(rand8[7], 16r01, fInput[inputPtr++], fedResTbl);
895*37da2899SCharles.Forsyth
896*37da2899SCharles.Forsyth				ditherParms.fOutput1[outputPtr1++] = byte rasterByte1;
897*37da2899SCharles.Forsyth				rasterByte1 = 0;
898*37da2899SCharles.Forsyth
899*37da2899SCharles.Forsyth				if (hifipe) {
900*37da2899SCharles.Forsyth					ditherParms.fOutput2[outputPtr2++] = byte rasterByte2;
901*37da2899SCharles.Forsyth					rasterByte2 = 0;
902*37da2899SCharles.Forsyth				}
903*37da2899SCharles.Forsyth			} else {
904*37da2899SCharles.Forsyth				 # Do white space skipping
905*37da2899SCharles.Forsyth				inputPtr += 8;
906*37da2899SCharles.Forsyth				ditherParms.fOutput1[outputPtr1++] = byte 0;
907*37da2899SCharles.Forsyth				if (hifipe) {
908*37da2899SCharles.Forsyth	 				ditherParms.fOutput2[outputPtr2++] = byte 0;
909*37da2899SCharles.Forsyth				}
910*37da2899SCharles.Forsyth				errPtr[diffusionErrorPtr:] = pad8;
911*37da2899SCharles.Forsyth				diffusionErrorPtr += 8;
912*37da2899SCharles.Forsyth
913*37da2899SCharles.Forsyth				rasterByte1 = 0;
914*37da2899SCharles.Forsyth				rasterByte2 = 0;
915*37da2899SCharles.Forsyth				tmpShortStore = 0;
916*37da2899SCharles.Forsyth			}
917*37da2899SCharles.Forsyth		} # for pixelCount
918*37da2899SCharles.Forsyth	} else {
919*37da2899SCharles.Forsyth		rasterByte1 = 0;
920*37da2899SCharles.Forsyth		rasterByte2 = 0;
921*37da2899SCharles.Forsyth		inputPtr  += ( numLoop-1 );
922*37da2899SCharles.Forsyth		outputPtr1 += ( numLoop/8 - 1 );
923*37da2899SCharles.Forsyth		outputPtr2 += ( numLoop/8 - 1 );
924*37da2899SCharles.Forsyth		diffusionErrorPtr += ( numLoop-1 );
925*37da2899SCharles.Forsyth
926*37da2899SCharles.Forsyth		tmpShortStore = errPtr[diffusionErrorPtr];
927*37da2899SCharles.Forsyth		errPtr[diffusionErrorPtr] = 0;
928*37da2899SCharles.Forsyth
929*37da2899SCharles.Forsyth        	for (pixelCount := numLoop + 8; (pixelCount -= 8) > 0; ) {
930*37da2899SCharles.Forsyth			if (pixelCount > 16) {
931*37da2899SCharles.Forsyth				# if next 16 pixels are white, skip 8
932*37da2899SCharles.Forsyth#				doNext8Pixels = Backward16PixelsNonWhite(fInput, inputPtr);
933*37da2899SCharles.Forsyth				doNext8Pixels = 0;
934*37da2899SCharles.Forsyth				lim := inputPtr - 16;
935*37da2899SCharles.Forsyth				for (i := inputPtr; i > lim; i--) {
936*37da2899SCharles.Forsyth					if (fInput[i] != byte 0) {
937*37da2899SCharles.Forsyth						doNext8Pixels = 1;
938*37da2899SCharles.Forsyth						break;
939*37da2899SCharles.Forsyth					}
940*37da2899SCharles.Forsyth				}
941*37da2899SCharles.Forsyth			} else {
942*37da2899SCharles.Forsyth				doNext8Pixels = HPTRUE;
943*37da2899SCharles.Forsyth			}
944*37da2899SCharles.Forsyth
945*37da2899SCharles.Forsyth			if (doNext8Pixels) {
946*37da2899SCharles.Forsyth				BACKWARD_FED8(fInput, inputPtr, fedResTbl);
947*37da2899SCharles.Forsyth				inputPtr -= 8;
948*37da2899SCharles.Forsyth#				HPRand8();
949*37da2899SCharles.Forsyth#				BACKWARD_FED(rand8[0], 16r01, fInput[inputPtr--], fedResTbl);
950*37da2899SCharles.Forsyth#				BACKWARD_FED(rand8[1], 16r02, fInput[inputPtr--], fedResTbl);
951*37da2899SCharles.Forsyth#				BACKWARD_FED(rand8[2], 16r04, fInput[inputPtr--], fedResTbl);
952*37da2899SCharles.Forsyth#				BACKWARD_FED(rand8[3], 16r08, fInput[inputPtr--], fedResTbl);
953*37da2899SCharles.Forsyth#				BACKWARD_FED(rand8[4], 16r10, fInput[inputPtr--], fedResTbl);
954*37da2899SCharles.Forsyth#				BACKWARD_FED(rand8[5], 16r20, fInput[inputPtr--], fedResTbl);
955*37da2899SCharles.Forsyth#				BACKWARD_FED(rand8[6], 16r40, fInput[inputPtr--], fedResTbl);
956*37da2899SCharles.Forsyth#				BACKWARD_FED(rand8[7], 16r80, fInput[inputPtr--], fedResTbl);
957*37da2899SCharles.Forsyth
958*37da2899SCharles.Forsyth				ditherParms.fOutput1[outputPtr1-- ]= byte rasterByte1;
959*37da2899SCharles.Forsyth				rasterByte1 = 0;
960*37da2899SCharles.Forsyth
961*37da2899SCharles.Forsyth				if (hifipe) {
962*37da2899SCharles.Forsyth					ditherParms.fOutput2[outputPtr2--] = byte rasterByte2;
963*37da2899SCharles.Forsyth					rasterByte2 = 0;
964*37da2899SCharles.Forsyth				}
965*37da2899SCharles.Forsyth			} else {
966*37da2899SCharles.Forsyth				# Do white space skipping
967*37da2899SCharles.Forsyth				inputPtr -= 8;
968*37da2899SCharles.Forsyth				ditherParms.fOutput1[outputPtr1--] = byte 0;
969*37da2899SCharles.Forsyth				if (hifipe) {
970*37da2899SCharles.Forsyth					ditherParms.fOutput2[outputPtr2--] = byte 0;
971*37da2899SCharles.Forsyth				}
972*37da2899SCharles.Forsyth				diffusionErrorPtr -= 8;
973*37da2899SCharles.Forsyth  				errPtr[diffusionErrorPtr:] = pad8;
974*37da2899SCharles.Forsyth
975*37da2899SCharles.Forsyth                		rasterByte1 = 0;
976*37da2899SCharles.Forsyth				rasterByte2 = 0;
977*37da2899SCharles.Forsyth				tmpShortStore = 0;
978*37da2899SCharles.Forsyth			}
979*37da2899SCharles.Forsyth		}
980*37da2899SCharles.Forsyth	}
981*37da2899SCharles.Forsyth}
982*37da2899SCharles.Forsyth
983*37da2899SCharles.Forsyth
984*37da2899SCharles.Forsyth
985*37da2899SCharles.Forsyth# Take a step back
986*37da2899SCharles.Forsyth
987*37da2899SCharles.ForsythBackward16PixelsNonWhite(ba: array of byte, inputPtr: int): int
988*37da2899SCharles.Forsyth{
989*37da2899SCharles.Forsyth	lim := inputPtr - 16;
990*37da2899SCharles.Forsyth	for (i := inputPtr; i > lim; i--) {
991*37da2899SCharles.Forsyth		if (ba[i] != byte 0)
992*37da2899SCharles.Forsyth			return TRUE;
993*37da2899SCharles.Forsyth	}
994*37da2899SCharles.Forsyth	return FALSE;
995*37da2899SCharles.Forsyth}
996*37da2899SCharles.Forsyth
997*37da2899SCharles.Forsyth# Take a step forward
998*37da2899SCharles.Forsyth
999*37da2899SCharles.ForsythForward16PixelsNonWhite(ba: array of byte, inputPtr: int): int
1000*37da2899SCharles.Forsyth{
1001*37da2899SCharles.Forsyth	lim := inputPtr + 16;
1002*37da2899SCharles.Forsyth	for (i := inputPtr; i < lim; i++) {
1003*37da2899SCharles.Forsyth		if (ba[i] != byte 0)
1004*37da2899SCharles.Forsyth			return TRUE;
1005*37da2899SCharles.Forsyth	}
1006*37da2899SCharles.Forsyth	return FALSE;
1007*37da2899SCharles.Forsyth}
1008*37da2899SCharles.Forsyth
1009*37da2899SCharles.ForsythFORWARD_FED8(input: array of byte, ix: int, fedResTbl: array of int)
1010*37da2899SCharles.Forsyth{
1011*37da2899SCharles.Forsyth	HPRand8();
1012*37da2899SCharles.Forsyth	randix := 0;
1013*37da2899SCharles.Forsyth
1014*37da2899SCharles.Forsyth	for (bitMask := 16r80; bitMask; bitMask >>= 1) {
1015*37da2899SCharles.Forsyth		tone := int input[ix++];
1016*37da2899SCharles.Forsyth		fedResPtr := tone << 2;
1017*37da2899SCharles.Forsyth		level := fedResTbl[fedResPtr];
1018*37da2899SCharles.Forsyth		if (tone != 0) {
1019*37da2899SCharles.Forsyth			tone = ( tmpShortStore + int fedResTbl[fedResPtr+1] );
1020*37da2899SCharles.Forsyth			if (tone >= rand8[randix++]) {
1021*37da2899SCharles.Forsyth				tone -= 255;
1022*37da2899SCharles.Forsyth				level++;
1023*37da2899SCharles.Forsyth			}
1024*37da2899SCharles.Forsyth			case (level) {
1025*37da2899SCharles.Forsyth			0=>
1026*37da2899SCharles.Forsyth				break;
1027*37da2899SCharles.Forsyth			1=>
1028*37da2899SCharles.Forsyth				rasterByte1 |= bitMask;
1029*37da2899SCharles.Forsyth				break;
1030*37da2899SCharles.Forsyth			2=>
1031*37da2899SCharles.Forsyth				rasterByte2 |= bitMask;
1032*37da2899SCharles.Forsyth				break;
1033*37da2899SCharles.Forsyth			3=>
1034*37da2899SCharles.Forsyth				rasterByte2 |= bitMask; rasterByte1 |= bitMask;
1035*37da2899SCharles.Forsyth				break;
1036*37da2899SCharles.Forsyth			4=>
1037*37da2899SCharles.Forsyth				break;
1038*37da2899SCharles.Forsyth			5=>
1039*37da2899SCharles.Forsyth				rasterByte1 |= bitMask;
1040*37da2899SCharles.Forsyth				break;
1041*37da2899SCharles.Forsyth			6=>
1042*37da2899SCharles.Forsyth				rasterByte2 |= bitMask;
1043*37da2899SCharles.Forsyth				break;
1044*37da2899SCharles.Forsyth			7=>
1045*37da2899SCharles.Forsyth				rasterByte2 |= bitMask; rasterByte1 |= bitMask;
1046*37da2899SCharles.Forsyth				break;
1047*37da2899SCharles.Forsyth			}
1048*37da2899SCharles.Forsyth		} else {
1049*37da2899SCharles.Forsyth			tone = tmpShortStore;
1050*37da2899SCharles.Forsyth		}
1051*37da2899SCharles.Forsyth		halftone := tone >> 1;
1052*37da2899SCharles.Forsyth		errPtr[diffusionErrorPtr++] = halftone;
1053*37da2899SCharles.Forsyth		tmpShortStore = errPtr[diffusionErrorPtr] + (tone - halftone);
1054*37da2899SCharles.Forsyth	}
1055*37da2899SCharles.Forsyth}
1056*37da2899SCharles.Forsyth
1057*37da2899SCharles.Forsyth#FORWARD_FED(thresholdValue: int, bitMask: int, toneb: byte, fedResTbl : array of int)
1058*37da2899SCharles.Forsyth#{
1059*37da2899SCharles.Forsyth#	tone := int toneb;
1060*37da2899SCharles.Forsyth#	fedResPtr := (tone << 2);
1061*37da2899SCharles.Forsyth#	level := fedResTbl[fedResPtr];
1062*37da2899SCharles.Forsyth#	if (tone != 0) {
1063*37da2899SCharles.Forsyth#		tone = ( tmpShortStore + int fedResTbl[fedResPtr+1] );
1064*37da2899SCharles.Forsyth#		if (tone >= thresholdValue) {
1065*37da2899SCharles.Forsyth#			tone -= 255;
1066*37da2899SCharles.Forsyth#			level++;
1067*37da2899SCharles.Forsyth#		}
1068*37da2899SCharles.Forsyth#		case (level) {
1069*37da2899SCharles.Forsyth#		0=>
1070*37da2899SCharles.Forsyth#			break;
1071*37da2899SCharles.Forsyth#		1=>
1072*37da2899SCharles.Forsyth#			rasterByte1 |= bitMask;
1073*37da2899SCharles.Forsyth#			break;
1074*37da2899SCharles.Forsyth#		2=>
1075*37da2899SCharles.Forsyth#			rasterByte2 |= bitMask;
1076*37da2899SCharles.Forsyth#			break;
1077*37da2899SCharles.Forsyth#		3=>
1078*37da2899SCharles.Forsyth#			rasterByte2 |= bitMask; rasterByte1 |= bitMask;
1079*37da2899SCharles.Forsyth#			break;
1080*37da2899SCharles.Forsyth#		4=>
1081*37da2899SCharles.Forsyth#			break;
1082*37da2899SCharles.Forsyth#		5=>
1083*37da2899SCharles.Forsyth#			rasterByte1 |= bitMask;
1084*37da2899SCharles.Forsyth#			break;
1085*37da2899SCharles.Forsyth#		6=>
1086*37da2899SCharles.Forsyth#			rasterByte2 |= bitMask;
1087*37da2899SCharles.Forsyth#			break;
1088*37da2899SCharles.Forsyth#		7=>
1089*37da2899SCharles.Forsyth#			rasterByte2 |= bitMask; rasterByte1 |= bitMask;
1090*37da2899SCharles.Forsyth#			break;
1091*37da2899SCharles.Forsyth#		}
1092*37da2899SCharles.Forsyth#	} else {
1093*37da2899SCharles.Forsyth#		tone = tmpShortStore;
1094*37da2899SCharles.Forsyth#	}
1095*37da2899SCharles.Forsyth#	halftone := tone >> 1;
1096*37da2899SCharles.Forsyth#	errPtr[diffusionErrorPtr++] = halftone;
1097*37da2899SCharles.Forsyth#	tmpShortStore = errPtr[diffusionErrorPtr] + (tone - halftone);
1098*37da2899SCharles.Forsyth##	dbg(sys->sprint("FORWARD_FED: thresh %d bitMask %x toneb %d => rasterbytes %d,%d,%d\n", thresholdValue, bitMask, int toneb, rasterByte1, rasterByte2));
1099*37da2899SCharles.Forsyth#}
1100*37da2899SCharles.Forsyth
1101*37da2899SCharles.ForsythBACKWARD_FED8(input: array of byte, ix: int, fedResTbl: array of int)
1102*37da2899SCharles.Forsyth{
1103*37da2899SCharles.Forsyth	HPRand8();
1104*37da2899SCharles.Forsyth	randix := 0;
1105*37da2899SCharles.Forsyth
1106*37da2899SCharles.Forsyth	for (bitMask := 16r01; bitMask <16r100; bitMask <<= 1) {
1107*37da2899SCharles.Forsyth		tone := int input[ix--];
1108*37da2899SCharles.Forsyth		fedResPtr := (tone << 2);
1109*37da2899SCharles.Forsyth		level := fedResTbl[fedResPtr];
1110*37da2899SCharles.Forsyth		if (tone != 0) {
1111*37da2899SCharles.Forsyth			tone = ( tmpShortStore + int fedResTbl[fedResPtr+1] );
1112*37da2899SCharles.Forsyth			if (tone >= rand8[randix++]) {
1113*37da2899SCharles.Forsyth				tone -= 255;
1114*37da2899SCharles.Forsyth				level++;
1115*37da2899SCharles.Forsyth			}
1116*37da2899SCharles.Forsyth			case (level) {
1117*37da2899SCharles.Forsyth			0=>
1118*37da2899SCharles.Forsyth				break;
1119*37da2899SCharles.Forsyth			1=>
1120*37da2899SCharles.Forsyth				rasterByte1 |= bitMask;
1121*37da2899SCharles.Forsyth				break;
1122*37da2899SCharles.Forsyth			2=>
1123*37da2899SCharles.Forsyth				rasterByte2 |= bitMask;
1124*37da2899SCharles.Forsyth				break;
1125*37da2899SCharles.Forsyth			3=>
1126*37da2899SCharles.Forsyth				rasterByte2 |= bitMask; rasterByte1 |= bitMask;
1127*37da2899SCharles.Forsyth				break;
1128*37da2899SCharles.Forsyth			4=>
1129*37da2899SCharles.Forsyth				break;
1130*37da2899SCharles.Forsyth			5=>
1131*37da2899SCharles.Forsyth				rasterByte1 |= bitMask;
1132*37da2899SCharles.Forsyth				break;
1133*37da2899SCharles.Forsyth			6=>
1134*37da2899SCharles.Forsyth				rasterByte2 |= bitMask;
1135*37da2899SCharles.Forsyth				break;
1136*37da2899SCharles.Forsyth			7=>
1137*37da2899SCharles.Forsyth				rasterByte2 |= bitMask; rasterByte1 |= bitMask;
1138*37da2899SCharles.Forsyth				break;
1139*37da2899SCharles.Forsyth			}
1140*37da2899SCharles.Forsyth		} else {
1141*37da2899SCharles.Forsyth			tone = tmpShortStore;
1142*37da2899SCharles.Forsyth		 }
1143*37da2899SCharles.Forsyth		halftone := tone >> 1;
1144*37da2899SCharles.Forsyth		errPtr[diffusionErrorPtr--] = halftone;
1145*37da2899SCharles.Forsyth		tmpShortStore = errPtr[diffusionErrorPtr] + (tone - halftone);
1146*37da2899SCharles.Forsyth	}
1147*37da2899SCharles.Forsyth}
1148*37da2899SCharles.Forsyth
1149*37da2899SCharles.Forsyth
1150*37da2899SCharles.Forsyth#BACKWARD_FED(thresholdValue: int, bitMask: int, toneb: byte, fedResTbl : array of int)
1151*37da2899SCharles.Forsyth#{
1152*37da2899SCharles.Forsyth#	tone := int toneb;
1153*37da2899SCharles.Forsyth#	fedResPtr := (tone << 2);
1154*37da2899SCharles.Forsyth#	level := fedResTbl[fedResPtr];
1155*37da2899SCharles.Forsyth#	if (tone != 0) {
1156*37da2899SCharles.Forsyth#		tone = ( tmpShortStore + int fedResTbl[fedResPtr+1] );
1157*37da2899SCharles.Forsyth#		if (tone >= thresholdValue) {
1158*37da2899SCharles.Forsyth#			tone -= 255;
1159*37da2899SCharles.Forsyth#			level++;
1160*37da2899SCharles.Forsyth#		}
1161*37da2899SCharles.Forsyth#		case (level) {
1162*37da2899SCharles.Forsyth#		0=>
1163*37da2899SCharles.Forsyth#			break;
1164*37da2899SCharles.Forsyth#		1=>
1165*37da2899SCharles.Forsyth#			rasterByte1 |= bitMask;
1166*37da2899SCharles.Forsyth#			break;
1167*37da2899SCharles.Forsyth#		2=>
1168*37da2899SCharles.Forsyth#			rasterByte2 |= bitMask;
1169*37da2899SCharles.Forsyth#			break;
1170*37da2899SCharles.Forsyth#		3=>
1171*37da2899SCharles.Forsyth#			rasterByte2 |= bitMask; rasterByte1 |= bitMask;
1172*37da2899SCharles.Forsyth#			break;
1173*37da2899SCharles.Forsyth#		4=>
1174*37da2899SCharles.Forsyth#			break;
1175*37da2899SCharles.Forsyth#		5=>
1176*37da2899SCharles.Forsyth#			rasterByte1 |= bitMask;
1177*37da2899SCharles.Forsyth#			break;
1178*37da2899SCharles.Forsyth#		6=>
1179*37da2899SCharles.Forsyth#			rasterByte2 |= bitMask;
1180*37da2899SCharles.Forsyth#			break;
1181*37da2899SCharles.Forsyth#		7=>
1182*37da2899SCharles.Forsyth#			rasterByte2 |= bitMask; rasterByte1 |= bitMask;
1183*37da2899SCharles.Forsyth#			break;
1184*37da2899SCharles.Forsyth#		}
1185*37da2899SCharles.Forsyth#	} else {
1186*37da2899SCharles.Forsyth#		tone = tmpShortStore;
1187*37da2899SCharles.Forsyth#	 }
1188*37da2899SCharles.Forsyth#	halftone := tone >> 1;
1189*37da2899SCharles.Forsyth#	errPtr[diffusionErrorPtr--] = halftone;
1190*37da2899SCharles.Forsyth#	tmpShortStore = errPtr[diffusionErrorPtr] + (tone - halftone);
1191*37da2899SCharles.Forsyth##	dbg(sys->sprint("BACWARD_FED: thresh %d bitMask %x toneb %d => rasterbytes %d,%d,%d\n", thresholdValue, bitMask, int toneb, rasterByte1, rasterByte2));
1192*37da2899SCharles.Forsyth#}
1193*37da2899SCharles.Forsyth
1194*37da2899SCharles.Forsyth
1195*37da2899SCharles.Forsyth# Pixel replication
1196*37da2899SCharles.Forsyth
1197*37da2899SCharles.Forsythpixrep(in: array of RGB): array of RGB
1198*37da2899SCharles.Forsyth{
1199*37da2899SCharles.Forsyth	out := array[2*len in] of RGB;
1200*37da2899SCharles.Forsyth	for (i:=0; i<len in; i++) {
1201*37da2899SCharles.Forsyth		out[i*2] = in[i];
1202*37da2899SCharles.Forsyth		out[i*2+1] = in[i];
1203*37da2899SCharles.Forsyth	}
1204*37da2899SCharles.Forsyth	return out;
1205*37da2899SCharles.Forsyth}
1206*37da2899SCharles.Forsyth
1207*37da2899SCharles.Forsyth
1208*37da2899SCharles.Forsyth
1209*37da2899SCharles.Forsyth
1210*37da2899SCharles.Forsyth
1211*37da2899SCharles.Forsyth
1212*37da2899SCharles.Forsyth# Random numbers
1213*37da2899SCharles.Forsyth
1214*37da2899SCharles.ForsythIM: con 139968;
1215*37da2899SCharles.ForsythIA: con  3877;
1216*37da2899SCharles.ForsythIC: con 29573;
1217*37da2899SCharles.Forsyth
1218*37da2899SCharles.Forsythlast := 42;
1219*37da2899SCharles.Forsyth
1220*37da2899SCharles.Forsyth# Use a really simple and quick random number generator
1221*37da2899SCharles.Forsyth
1222*37da2899SCharles.ForsythHPRand(): int
1223*37da2899SCharles.Forsyth{
1224*37da2899SCharles.Forsyth	return (74 * (last = (last* IA + IC) % IM) / IM ) + 5;
1225*37da2899SCharles.Forsyth}
1226*37da2899SCharles.Forsyth
1227*37da2899SCharles.ForsythHPRand8()
1228*37da2899SCharles.Forsyth{
1229*37da2899SCharles.Forsyth	for (i:= 0; i < 8; i++)
1230*37da2899SCharles.Forsyth		rand8[i] = (74 * (last = (last* IA + IC) % IM) / IM ) + 5;
1231*37da2899SCharles.Forsyth}
1232*37da2899SCharles.Forsyth
1233*37da2899SCharles.Forsyth# Compression
1234*37da2899SCharles.Forsyth
1235*37da2899SCharles.Forsythcompress(rawdata: array of byte): array of byte
1236*37da2899SCharles.Forsyth{
1237*37da2899SCharles.Forsyth	nraw := len rawdata;
1238*37da2899SCharles.Forsyth	comp := array [2*nraw] of byte;	# worst case
1239*37da2899SCharles.Forsyth	ncomp := 0;
1240*37da2899SCharles.Forsyth	for (i:=0; i<nraw;) {
1241*37da2899SCharles.Forsyth		rpt := 0;
1242*37da2899SCharles.Forsyth		val := rawdata[i++];
1243*37da2899SCharles.Forsyth		while (i<nraw && rpt < 255 && rawdata[i] == val) {
1244*37da2899SCharles.Forsyth			rpt++;
1245*37da2899SCharles.Forsyth			i++;
1246*37da2899SCharles.Forsyth		}
1247*37da2899SCharles.Forsyth		comp[ncomp++] = byte rpt;
1248*37da2899SCharles.Forsyth		comp[ncomp++] = val;
1249*37da2899SCharles.Forsyth	}
1250*37da2899SCharles.Forsyth	return comp[0:ncomp];
1251*37da2899SCharles.Forsyth}
1252*37da2899SCharles.Forsyth
1253*37da2899SCharles.Forsyth
1254*37da2899SCharles.Forsyth
1255*37da2899SCharles.Forsyth# Print error message and exit
1256*37da2899SCharles.Forsyth
1257*37da2899SCharles.Forsythfatal(s: string)
1258*37da2899SCharles.Forsyth{
1259*37da2899SCharles.Forsyth	sys->fprint(stderr, "%s\n", s);
1260*37da2899SCharles.Forsyth	exit;
1261*37da2899SCharles.Forsyth}
1262*37da2899SCharles.Forsyth
1263*37da2899SCharles.Forsythkillgrp(pid: int)
1264*37da2899SCharles.Forsyth{
1265*37da2899SCharles.Forsyth	sys->fprint(sys->open("/prog/" + string pid +"/ctl", Sys->OWRITE), "killgrp");
1266*37da2899SCharles.Forsyth}
1267*37da2899SCharles.Forsyth
1268*37da2899SCharles.Forsyth
1269*37da2899SCharles.Forsythdbg(s: string)
1270*37da2899SCharles.Forsyth{
1271*37da2899SCharles.Forsyth	if (DEBUG) sys->fprint(stderr, "%s", s);
1272*37da2899SCharles.Forsyth}
1273*37da2899SCharles.Forsyth
1274*37da2899SCharles.Forsyth
1275*37da2899SCharles.Forsyth
1276*37da2899SCharles.Forsyth# Uninteresting constants
1277*37da2899SCharles.Forsyth
1278*37da2899SCharles.ForsythFEDarray := array[1024] of
1279*37da2899SCharles.Forsyth{
1280*37da2899SCharles.Forsyth   0 ,    0 ,    0 ,    0 ,
1281*37da2899SCharles.Forsyth   0 ,    0 ,    0 ,    0 ,
1282*37da2899SCharles.Forsyth   0 ,    2 ,    0 ,    0 ,
1283*37da2899SCharles.Forsyth   0 ,    3 ,    0 ,    0 ,
1284*37da2899SCharles.Forsyth   0 ,    4 ,    0 ,    0 ,
1285*37da2899SCharles.Forsyth   0 ,    5 ,    0 ,    0 ,
1286*37da2899SCharles.Forsyth   0 ,    6 ,    0 ,    0 ,
1287*37da2899SCharles.Forsyth   0 ,    7 ,    0 ,    0 ,
1288*37da2899SCharles.Forsyth   0 ,    8 ,    0 ,    0 ,
1289*37da2899SCharles.Forsyth   0 ,    9 ,    0 ,    0 ,
1290*37da2899SCharles.Forsyth   0 ,   10 ,    0 ,    0 ,
1291*37da2899SCharles.Forsyth   0 ,   11 ,    0 ,    0 ,
1292*37da2899SCharles.Forsyth   0 ,   12 ,    0 ,    0 ,
1293*37da2899SCharles.Forsyth   0 ,   13 ,    0 ,    0 ,
1294*37da2899SCharles.Forsyth   0 ,   14 ,    0 ,    0 ,
1295*37da2899SCharles.Forsyth   0 ,   15 ,    0 ,    0 ,
1296*37da2899SCharles.Forsyth   0 ,   16 ,    0 ,    0 ,
1297*37da2899SCharles.Forsyth   0 ,   17 ,    0 ,    0 ,
1298*37da2899SCharles.Forsyth   0 ,   18 ,    0 ,    0 ,
1299*37da2899SCharles.Forsyth   0 ,   19 ,    0 ,    0 ,
1300*37da2899SCharles.Forsyth   0 ,   20 ,    0 ,    0 ,
1301*37da2899SCharles.Forsyth   0 ,   21 ,    0 ,    0 ,
1302*37da2899SCharles.Forsyth   0 ,   22 ,    0 ,    0 ,
1303*37da2899SCharles.Forsyth   0 ,   23 ,    0 ,    0 ,
1304*37da2899SCharles.Forsyth   0 ,   24 ,    0 ,    0 ,
1305*37da2899SCharles.Forsyth   0 ,   25 ,    0 ,    0 ,
1306*37da2899SCharles.Forsyth   0 ,   26 ,    0 ,    0 ,
1307*37da2899SCharles.Forsyth   0 ,   27 ,    0 ,    0 ,
1308*37da2899SCharles.Forsyth   0 ,   28 ,    0 ,    0 ,
1309*37da2899SCharles.Forsyth   0 ,   29 ,    0 ,    0 ,
1310*37da2899SCharles.Forsyth   0 ,   30 ,    0 ,    0 ,
1311*37da2899SCharles.Forsyth   0 ,   31 ,    0 ,    0 ,
1312*37da2899SCharles.Forsyth   0 ,   32 ,    0 ,    0 ,
1313*37da2899SCharles.Forsyth   0 ,   33 ,    0 ,    0 ,
1314*37da2899SCharles.Forsyth   0 ,   34 ,    0 ,    0 ,
1315*37da2899SCharles.Forsyth   0 ,   35 ,    0 ,    0 ,
1316*37da2899SCharles.Forsyth   0 ,   36 ,    0 ,    0 ,
1317*37da2899SCharles.Forsyth   0 ,   37 ,    0 ,    0 ,
1318*37da2899SCharles.Forsyth   0 ,   38 ,    0 ,    0 ,
1319*37da2899SCharles.Forsyth   0 ,   39 ,    0 ,    0 ,
1320*37da2899SCharles.Forsyth   0 ,   40 ,    0 ,    0 ,
1321*37da2899SCharles.Forsyth   0 ,   41 ,    0 ,    0 ,
1322*37da2899SCharles.Forsyth   0 ,   42 ,    0 ,    0 ,
1323*37da2899SCharles.Forsyth   0 ,   43 ,    0 ,    0 ,
1324*37da2899SCharles.Forsyth   0 ,   44 ,    0 ,    0 ,
1325*37da2899SCharles.Forsyth   0 ,   45 ,    0 ,    0 ,
1326*37da2899SCharles.Forsyth   0 ,   46 ,    0 ,    0 ,
1327*37da2899SCharles.Forsyth   0 ,   47 ,    0 ,    0 ,
1328*37da2899SCharles.Forsyth   0 ,   48 ,    0 ,    0 ,
1329*37da2899SCharles.Forsyth   0 ,   49 ,    0 ,    0 ,
1330*37da2899SCharles.Forsyth   0 ,   50 ,    0 ,    0 ,
1331*37da2899SCharles.Forsyth   0 ,   51 ,    0 ,    0 ,
1332*37da2899SCharles.Forsyth   0 ,   52 ,    0 ,    0 ,
1333*37da2899SCharles.Forsyth   0 ,   53 ,    0 ,    0 ,
1334*37da2899SCharles.Forsyth   0 ,   54 ,    0 ,    0 ,
1335*37da2899SCharles.Forsyth   0 ,   55 ,    0 ,    0 ,
1336*37da2899SCharles.Forsyth   0 ,   56 ,    0 ,    0 ,
1337*37da2899SCharles.Forsyth   0 ,   57 ,    0 ,    0 ,
1338*37da2899SCharles.Forsyth   0 ,   58 ,    0 ,    0 ,
1339*37da2899SCharles.Forsyth   0 ,   59 ,    0 ,    0 ,
1340*37da2899SCharles.Forsyth   0 ,   60 ,    0 ,    0 ,
1341*37da2899SCharles.Forsyth   0 ,   61 ,    0 ,    0 ,
1342*37da2899SCharles.Forsyth   0 ,   62 ,    0 ,    0 ,
1343*37da2899SCharles.Forsyth   0 ,   63 ,    0 ,    0 ,
1344*37da2899SCharles.Forsyth   0 ,   64 ,    0 ,    0 ,
1345*37da2899SCharles.Forsyth   0 ,   65 ,    0 ,    0 ,
1346*37da2899SCharles.Forsyth   0 ,   66 ,    0 ,    0 ,
1347*37da2899SCharles.Forsyth   0 ,   67 ,    0 ,    0 ,
1348*37da2899SCharles.Forsyth   0 ,   68 ,    0 ,    0 ,
1349*37da2899SCharles.Forsyth   0 ,   69 ,    0 ,    0 ,
1350*37da2899SCharles.Forsyth   0 ,   70 ,    0 ,    0 ,
1351*37da2899SCharles.Forsyth   0 ,   71 ,    0 ,    0 ,
1352*37da2899SCharles.Forsyth   0 ,   72 ,    0 ,    0 ,
1353*37da2899SCharles.Forsyth   0 ,   73 ,    0 ,    0 ,
1354*37da2899SCharles.Forsyth   0 ,   74 ,    0 ,    0 ,
1355*37da2899SCharles.Forsyth   0 ,   75 ,    0 ,    0 ,
1356*37da2899SCharles.Forsyth   0 ,   76 ,    0 ,    0 ,
1357*37da2899SCharles.Forsyth   0 ,   77 ,    0 ,    0 ,
1358*37da2899SCharles.Forsyth   0 ,   78 ,    0 ,    0 ,
1359*37da2899SCharles.Forsyth   0 ,   79 ,    0 ,    0 ,
1360*37da2899SCharles.Forsyth   0 ,   80 ,    0 ,    0 ,
1361*37da2899SCharles.Forsyth   0 ,   81 ,    0 ,    0 ,
1362*37da2899SCharles.Forsyth   0 ,   82 ,    0 ,    0 ,
1363*37da2899SCharles.Forsyth   0 ,   83 ,    0 ,    0 ,
1364*37da2899SCharles.Forsyth   0 ,   84 ,    0 ,    0 ,
1365*37da2899SCharles.Forsyth   0 ,   85 ,    0 ,    0 ,
1366*37da2899SCharles.Forsyth   0 ,   86 ,    0 ,    0 ,
1367*37da2899SCharles.Forsyth   0 ,   87 ,    0 ,    0 ,
1368*37da2899SCharles.Forsyth   0 ,   88 ,    0 ,    0 ,
1369*37da2899SCharles.Forsyth   0 ,   89 ,    0 ,    0 ,
1370*37da2899SCharles.Forsyth   0 ,   90 ,    0 ,    0 ,
1371*37da2899SCharles.Forsyth   0 ,   91 ,    0 ,    0 ,
1372*37da2899SCharles.Forsyth   0 ,   92 ,    0 ,    0 ,
1373*37da2899SCharles.Forsyth   0 ,   93 ,    0 ,    0 ,
1374*37da2899SCharles.Forsyth   0 ,   94 ,    0 ,    0 ,
1375*37da2899SCharles.Forsyth   0 ,   95 ,    0 ,    0 ,
1376*37da2899SCharles.Forsyth   0 ,   96 ,    0 ,    0 ,
1377*37da2899SCharles.Forsyth   0 ,   97 ,    0 ,    0 ,
1378*37da2899SCharles.Forsyth   0 ,   98 ,    0 ,    0 ,
1379*37da2899SCharles.Forsyth   0 ,   99 ,    0 ,    0 ,
1380*37da2899SCharles.Forsyth   0 ,  100 ,    0 ,    0 ,
1381*37da2899SCharles.Forsyth   0 ,  101 ,    0 ,    0 ,
1382*37da2899SCharles.Forsyth   0 ,  102 ,    0 ,    0 ,
1383*37da2899SCharles.Forsyth   0 ,  103 ,    0 ,    0 ,
1384*37da2899SCharles.Forsyth   0 ,  104 ,    0 ,    0 ,
1385*37da2899SCharles.Forsyth   0 ,  105 ,    0 ,    0 ,
1386*37da2899SCharles.Forsyth   0 ,  106 ,    0 ,    0 ,
1387*37da2899SCharles.Forsyth   0 ,  107 ,    0 ,    0 ,
1388*37da2899SCharles.Forsyth   0 ,  108 ,    0 ,    0 ,
1389*37da2899SCharles.Forsyth   0 ,  109 ,    0 ,    0 ,
1390*37da2899SCharles.Forsyth   0 ,  110 ,    0 ,    0 ,
1391*37da2899SCharles.Forsyth   0 ,  111 ,    0 ,    0 ,
1392*37da2899SCharles.Forsyth   0 ,  112 ,    0 ,    0 ,
1393*37da2899SCharles.Forsyth   0 ,  113 ,    0 ,    0 ,
1394*37da2899SCharles.Forsyth   0 ,  114 ,    0 ,    0 ,
1395*37da2899SCharles.Forsyth   0 ,  115 ,    0 ,    0 ,
1396*37da2899SCharles.Forsyth   0 ,  116 ,    0 ,    0 ,
1397*37da2899SCharles.Forsyth   0 ,  117 ,    0 ,    0 ,
1398*37da2899SCharles.Forsyth   0 ,  118 ,    0 ,    0 ,
1399*37da2899SCharles.Forsyth   0 ,  119 ,    0 ,    0 ,
1400*37da2899SCharles.Forsyth   0 ,  120 ,    0 ,    0 ,
1401*37da2899SCharles.Forsyth   0 ,  121 ,    0 ,    0 ,
1402*37da2899SCharles.Forsyth   0 ,  122 ,    0 ,    0 ,
1403*37da2899SCharles.Forsyth   0 ,  123 ,    0 ,    0 ,
1404*37da2899SCharles.Forsyth   0 ,  124 ,    0 ,    0 ,
1405*37da2899SCharles.Forsyth   0 ,  125 ,    0 ,    0 ,
1406*37da2899SCharles.Forsyth   0 ,  126 ,    0 ,    0 ,
1407*37da2899SCharles.Forsyth   0 ,  127 ,    0 ,    0 ,
1408*37da2899SCharles.Forsyth   0 ,  128 ,    0 ,    0 ,
1409*37da2899SCharles.Forsyth   0 ,  129 ,    0 ,    0 ,
1410*37da2899SCharles.Forsyth   0 ,  130 ,    0 ,    0 ,
1411*37da2899SCharles.Forsyth   0 ,  131 ,    0 ,    0 ,
1412*37da2899SCharles.Forsyth   0 ,  132 ,    0 ,    0 ,
1413*37da2899SCharles.Forsyth   0 ,  133 ,    0 ,    0 ,
1414*37da2899SCharles.Forsyth   0 ,  134 ,    0 ,    0 ,
1415*37da2899SCharles.Forsyth   0 ,  135 ,    0 ,    0 ,
1416*37da2899SCharles.Forsyth   0 ,  136 ,    0 ,    0 ,
1417*37da2899SCharles.Forsyth   0 ,  137 ,    0 ,    0 ,
1418*37da2899SCharles.Forsyth   0 ,  138 ,    0 ,    0 ,
1419*37da2899SCharles.Forsyth   0 ,  139 ,    0 ,    0 ,
1420*37da2899SCharles.Forsyth   0 ,  140 ,    0 ,    0 ,
1421*37da2899SCharles.Forsyth   0 ,  141 ,    0 ,    0 ,
1422*37da2899SCharles.Forsyth   0 ,  142 ,    0 ,    0 ,
1423*37da2899SCharles.Forsyth   0 ,  143 ,    0 ,    0 ,
1424*37da2899SCharles.Forsyth   0 ,  144 ,    0 ,    0 ,
1425*37da2899SCharles.Forsyth   0 ,  145 ,    0 ,    0 ,
1426*37da2899SCharles.Forsyth   0 ,  146 ,    0 ,    0 ,
1427*37da2899SCharles.Forsyth   0 ,  147 ,    0 ,    0 ,
1428*37da2899SCharles.Forsyth   0 ,  148 ,    0 ,    0 ,
1429*37da2899SCharles.Forsyth   0 ,  149 ,    0 ,    0 ,
1430*37da2899SCharles.Forsyth   0 ,  150 ,    0 ,    0 ,
1431*37da2899SCharles.Forsyth   0 ,  151 ,    0 ,    0 ,
1432*37da2899SCharles.Forsyth   0 ,  152 ,    0 ,    0 ,
1433*37da2899SCharles.Forsyth   0 ,  153 ,    0 ,    0 ,
1434*37da2899SCharles.Forsyth   0 ,  154 ,    0 ,    0 ,
1435*37da2899SCharles.Forsyth   0 ,  155 ,    0 ,    0 ,
1436*37da2899SCharles.Forsyth   0 ,  156 ,    0 ,    0 ,
1437*37da2899SCharles.Forsyth   0 ,  157 ,    0 ,    0 ,
1438*37da2899SCharles.Forsyth   0 ,  158 ,    0 ,    0 ,
1439*37da2899SCharles.Forsyth   0 ,  159 ,    0 ,    0 ,
1440*37da2899SCharles.Forsyth   0 ,  160 ,    0 ,    0 ,
1441*37da2899SCharles.Forsyth   0 ,  161 ,    0 ,    0 ,
1442*37da2899SCharles.Forsyth   0 ,  162 ,    0 ,    0 ,
1443*37da2899SCharles.Forsyth   0 ,  163 ,    0 ,    0 ,
1444*37da2899SCharles.Forsyth   0 ,  164 ,    0 ,    0 ,
1445*37da2899SCharles.Forsyth   0 ,  165 ,    0 ,    0 ,
1446*37da2899SCharles.Forsyth   0 ,  166 ,    0 ,    0 ,
1447*37da2899SCharles.Forsyth   0 ,  167 ,    0 ,    0 ,
1448*37da2899SCharles.Forsyth   0 ,  168 ,    0 ,    0 ,
1449*37da2899SCharles.Forsyth   0 ,  169 ,    0 ,    0 ,
1450*37da2899SCharles.Forsyth   0 ,  170 ,    0 ,    0 ,
1451*37da2899SCharles.Forsyth   0 ,  171 ,    0 ,    0 ,
1452*37da2899SCharles.Forsyth   0 ,  172 ,    0 ,    0 ,
1453*37da2899SCharles.Forsyth   0 ,  173 ,    0 ,    0 ,
1454*37da2899SCharles.Forsyth   0 ,  174 ,    0 ,    0 ,
1455*37da2899SCharles.Forsyth   0 ,  175 ,    0 ,    0 ,
1456*37da2899SCharles.Forsyth   0 ,  176 ,    0 ,    0 ,
1457*37da2899SCharles.Forsyth   0 ,  177 ,    0 ,    0 ,
1458*37da2899SCharles.Forsyth   0 ,  178 ,    0 ,    0 ,
1459*37da2899SCharles.Forsyth   0 ,  179 ,    0 ,    0 ,
1460*37da2899SCharles.Forsyth   0 ,  180 ,    0 ,    0 ,
1461*37da2899SCharles.Forsyth   0 ,  181 ,    0 ,    0 ,
1462*37da2899SCharles.Forsyth   0 ,  182 ,    0 ,    0 ,
1463*37da2899SCharles.Forsyth   0 ,  183 ,    0 ,    0 ,
1464*37da2899SCharles.Forsyth   0 ,  184 ,    0 ,    0 ,
1465*37da2899SCharles.Forsyth   0 ,  185 ,    0 ,    0 ,
1466*37da2899SCharles.Forsyth   0 ,  186 ,    0 ,    0 ,
1467*37da2899SCharles.Forsyth   0 ,  187 ,    0 ,    0 ,
1468*37da2899SCharles.Forsyth   0 ,  188 ,    0 ,    0 ,
1469*37da2899SCharles.Forsyth   0 ,  189 ,    0 ,    0 ,
1470*37da2899SCharles.Forsyth   0 ,  190 ,    0 ,    0 ,
1471*37da2899SCharles.Forsyth   0 ,  191 ,    0 ,    0 ,
1472*37da2899SCharles.Forsyth   0 ,  192 ,    0 ,    0 ,
1473*37da2899SCharles.Forsyth   0 ,  193 ,    0 ,    0 ,
1474*37da2899SCharles.Forsyth   0 ,  194 ,    0 ,    0 ,
1475*37da2899SCharles.Forsyth   0 ,  195 ,    0 ,    0 ,
1476*37da2899SCharles.Forsyth   0 ,  196 ,    0 ,    0 ,
1477*37da2899SCharles.Forsyth   0 ,  197 ,    0 ,    0 ,
1478*37da2899SCharles.Forsyth   0 ,  198 ,    0 ,    0 ,
1479*37da2899SCharles.Forsyth   0 ,  199 ,    0 ,    0 ,
1480*37da2899SCharles.Forsyth   0 ,  200 ,    0 ,    0 ,
1481*37da2899SCharles.Forsyth   0 ,  201 ,    0 ,    0 ,
1482*37da2899SCharles.Forsyth   0 ,  202 ,    0 ,    0 ,
1483*37da2899SCharles.Forsyth   0 ,  203 ,    0 ,    0 ,
1484*37da2899SCharles.Forsyth   0 ,  204 ,    0 ,    0 ,
1485*37da2899SCharles.Forsyth   0 ,  205 ,    0 ,    0 ,
1486*37da2899SCharles.Forsyth   0 ,  206 ,    0 ,    0 ,
1487*37da2899SCharles.Forsyth   0 ,  207 ,    0 ,    0 ,
1488*37da2899SCharles.Forsyth   0 ,  208 ,    0 ,    0 ,
1489*37da2899SCharles.Forsyth   0 ,  209 ,    0 ,    0 ,
1490*37da2899SCharles.Forsyth   0 ,  210 ,    0 ,    0 ,
1491*37da2899SCharles.Forsyth   0 ,  211 ,    0 ,    0 ,
1492*37da2899SCharles.Forsyth   0 ,  212 ,    0 ,    0 ,
1493*37da2899SCharles.Forsyth   0 ,  213 ,    0 ,    0 ,
1494*37da2899SCharles.Forsyth   0 ,  214 ,    0 ,    0 ,
1495*37da2899SCharles.Forsyth   0 ,  215 ,    0 ,    0 ,
1496*37da2899SCharles.Forsyth   0 ,  216 ,    0 ,    0 ,
1497*37da2899SCharles.Forsyth   0 ,  217 ,    0 ,    0 ,
1498*37da2899SCharles.Forsyth   0 ,  218 ,    0 ,    0 ,
1499*37da2899SCharles.Forsyth   0 ,  219 ,    0 ,    0 ,
1500*37da2899SCharles.Forsyth   0 ,  220 ,    0 ,    0 ,
1501*37da2899SCharles.Forsyth   0 ,  221 ,    0 ,    0 ,
1502*37da2899SCharles.Forsyth   0 ,  222 ,    0 ,    0 ,
1503*37da2899SCharles.Forsyth   0 ,  223 ,    0 ,    0 ,
1504*37da2899SCharles.Forsyth   0 ,  224 ,    0 ,    0 ,
1505*37da2899SCharles.Forsyth   0 ,  225 ,    0 ,    0 ,
1506*37da2899SCharles.Forsyth   0 ,  226 ,    0 ,    0 ,
1507*37da2899SCharles.Forsyth   0 ,  227 ,    0 ,    0 ,
1508*37da2899SCharles.Forsyth   0 ,  228 ,    0 ,    0 ,
1509*37da2899SCharles.Forsyth   0 ,  229 ,    0 ,    0 ,
1510*37da2899SCharles.Forsyth   0 ,  230 ,    0 ,    0 ,
1511*37da2899SCharles.Forsyth   0 ,  231 ,    0 ,    0 ,
1512*37da2899SCharles.Forsyth   0 ,  232 ,    0 ,    0 ,
1513*37da2899SCharles.Forsyth   0 ,  233 ,    0 ,    0 ,
1514*37da2899SCharles.Forsyth   0 ,  234 ,    0 ,    0 ,
1515*37da2899SCharles.Forsyth   0 ,  235 ,    0 ,    0 ,
1516*37da2899SCharles.Forsyth   0 ,  236 ,    0 ,    0 ,
1517*37da2899SCharles.Forsyth   0 ,  237 ,    0 ,    0 ,
1518*37da2899SCharles.Forsyth   0 ,  238 ,    0 ,    0 ,
1519*37da2899SCharles.Forsyth   0 ,  239 ,    0 ,    0 ,
1520*37da2899SCharles.Forsyth   0 ,  240 ,    0 ,    0 ,
1521*37da2899SCharles.Forsyth   0 ,  241 ,    0 ,    0 ,
1522*37da2899SCharles.Forsyth   0 ,  242 ,    0 ,    0 ,
1523*37da2899SCharles.Forsyth   0 ,  243 ,    0 ,    0 ,
1524*37da2899SCharles.Forsyth   0 ,  244 ,    0 ,    0 ,
1525*37da2899SCharles.Forsyth   0 ,  245 ,    0 ,    0 ,
1526*37da2899SCharles.Forsyth   0 ,  246 ,    0 ,    0 ,
1527*37da2899SCharles.Forsyth   0 ,  247 ,    0 ,    0 ,
1528*37da2899SCharles.Forsyth   0 ,  248 ,    0 ,    0 ,
1529*37da2899SCharles.Forsyth   0 ,  249 ,    0 ,    0 ,
1530*37da2899SCharles.Forsyth   0 ,  250 ,    0 ,    0 ,
1531*37da2899SCharles.Forsyth   0 ,  251 ,    0 ,    0 ,
1532*37da2899SCharles.Forsyth   0 ,  252 ,    0 ,    0 ,
1533*37da2899SCharles.Forsyth   0 ,  253 ,    0 ,    0 ,
1534*37da2899SCharles.Forsyth   0 ,  254 ,    0 ,    0 ,
1535*37da2899SCharles.Forsyth   0 ,  254 ,    0 ,    0
1536*37da2899SCharles.Forsyth};
1537