1 /* COPYRIGHT (C) 1990, 1992 Aladdin Enterprises.  All rights reserved.
2    Distributed by Free Software Foundation, Inc.
3 
4    This file is part of Ghostscript.
5 
6    Ghostscript is distributed in the hope that it will be useful, but
7    WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
8    to anyone for the consequences of using it or for whether it serves any
9    particular purpose or works at all, unless he says so in writing.  Refer
10    to the Ghostscript General Public License for full details.
11 
12    Everyone is granted permission to copy, modify and redistribute
13    Ghostscript, but only under the conditions described in the Ghostscript
14    General Public License.  A copy of this license is supposed to have been
15    given to you along with Ghostscript so you can know your rights and
16    responsibilities.  It should be in a file named COPYING.  Among other
17    things, the copyright notice and this notice must be preserved on all
18    copies.  */
19 
20 /* dviprlib.c */
21 
22 #include "stdio_.h"
23 #include "ctype_.h"
24 #include "malloc_.h"
25 #include "string_.h"
26 #include "gstypes.h"
27 #include "gsmemory.h"
28 #include "gp.h"
29 
30 /* include library header. */
31 #define dviprlib_implementation
32 #include "dviprlib.h"
33 
34 /* The remainder of this file is a copy of the library for dviprt. */
35 
36 
37 /***** From rcfg.c *****/
38 /* $Id: RCFG.C 1.1 1994/08/30 02:27:02 kaz Exp kaz $ */
39 
40 
41 /*--- forward declarations ---*/
42 private int dviprt_read_S_cfg(P2(dviprt_cfg_t *,dviprt_cfg_i *));
43 private int dviprt_read_QR_cfg(P2(dviprt_cfg_t *,dviprt_cfg_i *));
44 
45 /*--- library functions ---*/
46 int
dviprt_readcfg(char * ifname,dviprt_cfg_t * pcfg,uchar * pcodebuf,int codebuf_s,uchar * pworkbuf,int workbuf_s)47 dviprt_readcfg(char *ifname,dviprt_cfg_t *pcfg,uchar *pcodebuf,int codebuf_s,
48     uchar *pworkbuf,int workbuf_s)
49 {
50   int code;
51   int ver;
52   dviprt_cfg_i info;
53 
54   info.fname = ifname;
55   info.line_no = -1;
56   if (ifname) {
57     info.file = fopen(ifname,gp_fmode_rb);
58     if (info.file == NULL) {
59       dviprt_printcfgerror(&info,"Cannot open.\n",-1);
60       return CFG_ERROR_FILE_OPEN;
61     }
62   }
63   else {
64     info.file = stdin;
65   }
66 
67   fseek(info.file,16,0);
68   ver = fgetc(info.file);
69   fseek(info.file,0,0);
70   info.codebuf = pcodebuf;
71   info.readbuf = pworkbuf;
72   info.codebuf_size = codebuf_s;
73   info.readbuf_size = workbuf_s;
74   code = (ver == 'S') ? dviprt_read_S_cfg(pcfg,&info)
75     : dviprt_read_QR_cfg(pcfg,&info);
76 
77   if (ifname) fclose(info.file);
78   return code;
79 }
80 
81 /*--- internal routines ---*/
82 private int
dviprt_read_S_cfg(dviprt_cfg_t * pcfg,dviprt_cfg_i * pinfo)83 dviprt_read_S_cfg(dviprt_cfg_t *pcfg,dviprt_cfg_i *pinfo)
84 {
85   FILE *ifp;
86   long intoff,stroff,codeoff;
87   int i,count;
88   uchar *pbuf,*rbuf;
89   int code;
90   char *ptype;
91   int n;
92 
93   if ((code = dviprt_setcfgbuffer_(pinfo,100,0)) < 0) return code;
94   dviprt_initcfg_(pcfg,pinfo);
95 
96   ifp = pinfo->file;
97   rbuf = pinfo->readbuf;
98 
99   if (fread(rbuf,20,1,ifp) < 1) {
100     dviprt_printcfgerror(pinfo,"Read error.\n",-1);
101   }
102   if (rbuf[17] != 0xff || rbuf[18] != 0xff) {
103   not_cfg:
104     dviprt_printcfgerror(pinfo,"This file does not seem *.CFG.\n",-1);
105     return CFG_ERROR_OTHER;
106   }
107   if (memcmp(rbuf,CFG_MAGIC_NUMBER,2))
108     goto not_cfg;
109   pcfg->version = rbuf[2] | ((uint)rbuf[3] << 8);
110   if (pcfg->version > CFG_VERSION) {
111     sprintf(dviprt_message_buffer,
112 	    "This *.CFG file is too new version(ver.%u).\n",pcfg->version);
113     dviprt_printcfgerror(pinfo,dviprt_message_buffer,-1);
114     return CFG_ERROR_OTHER;
115   }
116 
117 #define bytes2long(p) ((p)[0] | ((long)(p)[1]<<8) | \
118 		       ((long)(p)[2]<<16) | ((long)(p)[3]<<24))
119   intoff = bytes2long(rbuf+4);
120   stroff = bytes2long(rbuf+8);
121   codeoff = bytes2long(rbuf+12);
122 #undef bytes2long
123 
124   fseek(ifp,intoff,0);
125   count = fgetc(ifp);
126   fread(rbuf,count*3,1,ifp);
127 
128   pbuf = rbuf;
129   for (i=0;i<count;i++) {
130     n = pbuf[0];
131     if (n >= CFG_INTEGER_TYPE_COUNT) {
132       ptype = "integer";
133     unknown_no:
134       sprintf(dviprt_message_buffer,
135 	      "Unknown %s type value No.%d is found.\n",ptype,n);
136       dviprt_printcfgerror(pinfo,dviprt_message_buffer,-1);
137       return CFG_ERROR_OTHER;
138     }
139     pcfg->integer[n] = pbuf[1] | ((uint)pbuf[2]<<8);
140     pbuf += 3;
141   }
142 
143   fseek(ifp,stroff,0);
144   count = fgetc(ifp);
145   pbuf = NULL;
146   for (i=0;i<count;i++) {
147     int l;
148     fread(rbuf,3,1,ifp);
149     n = rbuf[0];
150     l = rbuf[1] | ((uint)rbuf[2]<<8);
151     if (n >= CFG_STRINGS_TYPE_COUNT) {
152       ptype = "strings";
153       goto unknown_no;
154     }
155     if (pinfo->codebuf == NULL) {
156       pcfg->strings[n] = (uchar *)malloc(l+1);
157       if (pcfg->strings[n] == NULL) {
158       no_memory:
159         dviprt_printcfgerror(pinfo,"Memory exhausted.\n",-1);
160         return CFG_ERROR_MEMORY;
161       }
162     }
163     else {
164       pcfg->strings[n] = pinfo->pcodebuf;
165       pinfo->pcodebuf += (l+1);
166     }
167     fread(pcfg->strings[n],l,1,ifp);
168     *(pcfg->strings[n]+l) = 0;
169   }
170 
171   fseek(ifp,codeoff,0);
172   count = fgetc(ifp);
173   for (i=0;i<count;i++) {
174     int l;
175     fread(rbuf,3,1,ifp);
176     n = rbuf[0];
177     l = rbuf[1] | ((uint)rbuf[2]<<8);
178 
179     if (n >= CFG_PRTCODE_TYPE_COUNT) {
180       ptype = "printer code";
181       goto unknown_no;
182     }
183     if (pinfo->codebuf == NULL) {
184       pcfg->prtcode[n] = (uchar *)malloc(l+1);
185       if (pcfg->prtcode[n] == NULL)
186         goto no_memory;
187     }
188     else {
189       pcfg->prtcode[n] = pinfo->pcodebuf;
190       pinfo->pcodebuf += (l+1);
191     }
192     fread(pcfg->prtcode[n],l,1,ifp);
193     *(pcfg->prtcode[n]+l) = 0;
194     pcfg->prtcode_size[n] = l;
195   }
196   dviprt_resetcfgbuffer_(pinfo);
197   return 0;
198 }
199 
200 private int
dviprt_read_QR_cfg(dviprt_cfg_t * pcfg,dviprt_cfg_i * pinfo)201 dviprt_read_QR_cfg(dviprt_cfg_t *pcfg,dviprt_cfg_i *pinfo)
202 {
203 #define	TYPE_BIT		0xc0
204 
205 #define	NO_NUM			0
206 #define	BINARY_LTOH		1
207 #define	BINARY_HTOL		2
208 #define	DECIMAL_3		3
209 #define	DECIMAL_4		4
210 #define	DECIMAL_5		5
211 #define	DECIMAL_V		6
212 
213 #define	TOTAL_BYTE		0x80
214 #define	ISO_NUMBER		0x40
215 #define	DIVIDEBY_2		0x10
216 #define	DIVIDE_ALL		0x30
217 #define	MULT_CONST		0x08
218   enum {
219     BIT_IMAGE_MODE,
220     NORML_MODE,
221     SEND_BIT_IMAGE,
222     SKIP_SPACES,
223     LINE_FEED,
224     FORM_FEED,
225     AFTER_BIT_IMAGE,
226     BIT_ROW_HEADER,
227   };
228   uchar *cfg_buf,*ptr;
229   int ch, type, f_cont, f_type, pos, i, j, k, lens;
230   int f_r_format;
231   long offset;
232   int old2new[] = {
233     CFG_BIT_IMAGE_MODE,
234     CFG_NORMAL_MODE,
235     CFG_SEND_BIT_IMAGE,
236     CFG_SKIP_SPACES,
237     CFG_LINE_FEED,
238     CFG_FORM_FEED,
239     CFG_AFTER_BIT_IMAGE,
240     CFG_BIT_ROW_HEADER,
241   };
242 
243   ch =dviprt_setcfgbuffer_(pinfo,300,TEMP_CODEBUF_SIZE);
244   if (ch < 0) return CFG_ERROR_MEMORY;
245   dviprt_initcfg_(pcfg,pinfo);
246   cfg_buf = pinfo->readbuf;
247   if (fread(cfg_buf,30,1,pinfo->file) < 1) {
248     dviprt_printcfgerror(pinfo,"Read error.\n",-1);
249   }
250   if (cfg_buf[16] == 'P') {
251     dviprt_printcfgerror(pinfo,"This is made by old version.\n",-1);
252     return CFG_ERROR_OTHER;
253   }
254   else if (cfg_buf[16] == 'Q')
255     f_r_format = 0;
256   else if (cfg_buf[16] == 'R')
257     f_r_format = 1;
258   else
259     f_r_format = -1;
260   if (f_r_format == -1 || cfg_buf[18] != 0xff) {
261     dviprt_printcfgerror(pinfo,"This is not the *.CFG file for dviprt.\n",-1);
262     return CFG_ERROR_OTHER;
263   }
264   cfg_buf[16] = '\0';
265   pcfg->version = 0;
266   if (pinfo->temp_codebuf_f) {
267     pcfg->strings[CFG_NAME] = malloc(strlen(cfg_buf)+1);
268     if (pcfg->strings[CFG_NAME] == NULL) {
269     no_memory:
270       dviprt_printcfgerror(pinfo,"Memory exhausted.\n",-1);
271       return CFG_ERROR_MEMORY;
272     }
273   }
274   else {
275     pcfg->strings[CFG_NAME] = pinfo->pcodebuf;
276     pinfo->pcodebuf += strlen(cfg_buf);
277     pinfo->pcodebuf++;
278   }
279   strcpy(pcfg->strings[CFG_NAME],cfg_buf);
280 
281   pcfg->integer[CFG_UPPER_POS] =
282     (cfg_buf[17] & (CFG_LEFT_IS_LOW|CFG_NON_MOVING));
283   pcfg->integer[CFG_ENCODE] =
284     (cfg_buf[17] & 0x10) ? CFG_ENCODE_HEX : CFG_ENCODE_NULL;
285   pcfg->integer[CFG_PINS] = ((uint) (cfg_buf[17]) & 0x0f);
286 
287   ptr = cfg_buf+23;
288   pcfg->integer[CFG_MINIMAL_UNIT] = (uint)ptr[0] | ((uint)ptr[1]<<8);
289   pcfg->integer[CFG_MAXIMAL_UNIT] = (uint)ptr[2] | ((uint)ptr[3]<<8);
290   pcfg->integer[CFG_DPI] =
291     f_r_format ? ((uint)ptr[4] | ((uint)ptr[5]<<8)) : 180;
292   if (cfg_buf[20])
293     pcfg->integer[CFG_CONSTANT] = cfg_buf[20];
294   offset = cfg_buf[19];
295   fseek(pinfo->file,offset,0);
296 
297   for (i = 0; i <= BIT_ROW_HEADER; i++) {
298     uchar *pstart,*plength;
299     uchar prev = 1;
300     if (pinfo->temp_codebuf_f) {
301       pinfo->pcodebuf = pinfo->codebuf;
302     }
303     pstart = pinfo->pcodebuf;
304     do {
305       lens = fgetc(pinfo->file);
306       if (lens == EOF) break;
307       fread(cfg_buf,lens+3,1,pinfo->file);
308       ptr = cfg_buf;
309       f_cont = *ptr++;
310       pos = *ptr++;
311       f_type = *ptr++;
312       type = f_type & 0x7;
313 
314       for (j = 0; j < lens; j++) {
315 	ch = *ptr++;
316 	if (pos == j && type != NO_NUM) {
317 	  uchar *pfmt = pinfo->pcodebuf++;
318 	  plength = pinfo->pcodebuf++;
319 	  *pinfo->pcodebuf++ = CFG_VAL_DEFAULT;
320 	  *plength = 1;
321 	  j++;
322 	  ptr++;
323 	  switch (type) {
324 	  case (BINARY_LTOH):
325 	    *pfmt = CFG_FMT_BIT | CFG_FMT_BIN_LTOH | 2;
326 	    break;
327 	  case (BINARY_HTOL):
328 	    *pfmt = CFG_FMT_BIT | CFG_FMT_BIN_HTOL | 2;
329 	    break;
330 	  case (DECIMAL_3):
331 	    *pfmt = CFG_FMT_BIT | CFG_FMT_DECIMAL | 3;
332 	    j++;
333 	    ptr++;
334 	    break;
335 	  case (DECIMAL_4):
336 	    *pfmt = CFG_FMT_BIT | CFG_FMT_DECIMAL | 4;
337 	    j += 2;
338 	    ptr += 2;
339 	    break;
340 	  case (DECIMAL_5):
341 	    *pfmt = CFG_FMT_BIT | CFG_FMT_DECIMAL | 5;
342 	    j += 3;
343 	    ptr += 3;
344 	    break;
345 	  case (DECIMAL_V):
346 	    *pfmt = CFG_FMT_BIT | CFG_FMT_DECIMAL;
347 	    j++;
348 	    ptr++;
349 	    break;
350 	  default:
351 	    sprintf(dviprt_message_buffer,"Unknown format %02X",type);
352 	    dviprt_printcfgerror(pinfo,dviprt_message_buffer,-1);
353 	    goto ex_func;
354 	  }
355 	  if (f_type & TOTAL_BYTE) {
356 	    *pinfo->pcodebuf++ = CFG_VAL_PINS_BYTE;
357 	    *pinfo->pcodebuf++ = CFG_OP_MUL;
358 	    (*plength) += 2;
359 	  }
360 	  if ((k = (f_type & DIVIDE_ALL)) != 0) {
361 	    *pinfo->pcodebuf = 0;
362 	    for (; k > 0; k -= DIVIDEBY_2) {
363 	      (*pinfo->pcodebuf)++;
364 	    }
365 	    pinfo->pcodebuf++;
366 	    *pinfo->pcodebuf++ = CFG_OP_SHR;
367 	    (*plength) += 2;
368 	  }
369 	  if (f_type & ISO_NUMBER) {
370 	    *pfmt |= CFG_FMT_ISO_BIT;
371 	  }
372 	  if (f_type & MULT_CONST) {
373 	    *pinfo->pcodebuf++ = CFG_VAL_CONSTANT;
374 	    *pinfo->pcodebuf++ = CFG_OP_MUL;
375 	    (*plength) += 2;
376 	  }
377 	  prev = 1;
378 	}
379 	else {
380 	  if (prev == 1 || *plength >= 127) {
381 	    plength = pinfo->pcodebuf++;
382 	    *plength = 0;
383 	  }
384 	  (*plength)++;
385 	  *pinfo->pcodebuf++ = ch;
386 	  prev = 0;
387 	}
388       }
389     } while (f_cont & 0x80);
390     *pinfo->pcodebuf++ = 0;
391     { int n = old2new[i];
392       uint l = pinfo->pcodebuf-pstart;
393       pcfg->prtcode_size[n] = l - 1;
394       if (pinfo->temp_codebuf_f) { /* allocate buffer */
395      	pcfg->prtcode[n] = (uchar *)malloc(l);
396         if (pcfg->prtcode[n] == NULL)
397           goto no_memory;
398 	memcpy(pcfg->prtcode[n],pstart,l);
399       }
400       else {
401 	pcfg->prtcode[n] = pstart;
402       }
403     }
404   }
405  ex_func:
406   dviprt_resetcfgbuffer_(pinfo);
407   return 0;
408 }
409 /***** End of rcfg.c *****/
410 
411 
412 /***** From rsrc.c *****/
413 /* $Id: RSRC.C 1.1 1994/08/30 02:27:02 kaz Exp kaz $ */
414 
415 
416 typedef struct {
417   char *name;
418   signed char type;
419   uchar no;
420   uchar spec_f;
421   uchar req_f;
422   char *info;
423 } dviprt_cfg_item_t;
424 
425 typedef struct {
426   long min;
427   long max;
428 } dviprt_cfg_limit_t;
429 
430 /*--- forward declarations ---*/
431 private int dviprt_set_select
432   (P4(dviprt_cfg_item_t *,uchar **,dviprt_cfg_t *,dviprt_cfg_i *));
433 private int dviprt_set_integer
434   (P4(dviprt_cfg_item_t *, uchar *, dviprt_cfg_t *,dviprt_cfg_i *));
435 private int dviprt_set_strings
436   (P4(dviprt_cfg_item_t *,uchar *,dviprt_cfg_t *,dviprt_cfg_i *));
437 private int dviprt_set_rpexpr
438   (P6(dviprt_cfg_item_t *,uchar *,int , dviprt_cfg_t *,dviprt_cfg_i *,int));
439 private int dviprt_set_code
440   (P4(dviprt_cfg_item_t *,uchar *,dviprt_cfg_t *,dviprt_cfg_i *));
441 
442 private long dviprt_oct2long(P3(uchar *,uchar *,uchar **));
443 private long dviprt_dec2long(P3(uchar *,uchar *,uchar **));
444 private long dviprt_hex2long(P3(uchar *,uchar *,uchar **));
445 
446 private int dviprt_printtokenerror(P4(dviprt_cfg_i *,char *,int ,int));
447 
448 /*--- macros ---*/
449 #define strlcmp(tmplt,str,len) \
450   (!(strncmp(tmplt,str,(int)(len)) == 0 && (int)(len) == strlen(tmplt)))
451 #define set_version(pcfg,v) ((pcfg)->version = MAX(v,(pcfg)->version))
452 
453 enum {
454   ERROR_UNKNOWN_VALUE,ERROR_UNKNOWN_FORMAT,ERROR_UNKNOWN_ESCSEQ,
455   ERROR_OUTOFRANGE,
456   ERROR_INVALID_VALUE,
457   ERROR_COMPLICATED_EXPR,
458   ERROR_INCOMPLETE,
459 };
460 
461 /*--- library functions ---*/
462 int
dviprt_readsrc(char * fname,dviprt_cfg_t * pcfg,uchar * pcodebuf,int codebuf_s,uchar * pworkbuf,int workbuf_s)463 dviprt_readsrc(char *fname,dviprt_cfg_t *pcfg,uchar *pcodebuf,int codebuf_s,
464     uchar *pworkbuf,int workbuf_s)
465 {
466   dviprt_cfg_i info;
467   int code;
468   FILE *ifp;
469   dviprt_cfg_item_t *pitem;
470   int enc = CFG_ENCODE_NULL;
471   enum { T_INTEGER,T_STRINGS,T_CODE,T_SELECT,T_UPPERPOS};
472   static dviprt_cfg_limit_t pins_limit = { 8, 128 };
473   static dviprt_cfg_limit_t positive_limit = { 1, 0x7fff };
474   static dviprt_cfg_limit_t nonnegative_limit = { 0, 0x7fff};
475   static dviprt_cfg_item_t dviprt_items[] = {
476     {NULL,T_STRINGS,CFG_NAME,0,1,NULL},
477     {NULL,T_INTEGER,CFG_PINS,0,1,(char*)&pins_limit},
478     {NULL,T_INTEGER,CFG_MINIMAL_UNIT,0,0,(char*)&positive_limit},
479     {NULL,T_INTEGER,CFG_MAXIMAL_UNIT,0,0,(char*)&positive_limit},
480     {NULL,T_INTEGER,CFG_DPI,0,0,(char*)&positive_limit},
481     {NULL,T_INTEGER,CFG_CONSTANT,0,0,(char*)&nonnegative_limit},
482     {NULL,T_INTEGER,CFG_Y_DPI,0,0,(char*)&positive_limit},
483     {NULL,T_CODE,CFG_BIT_IMAGE_MODE,0,1,NULL},
484     {NULL,T_CODE,CFG_SEND_BIT_IMAGE,0,1,NULL},
485     {NULL,T_CODE,CFG_BIT_ROW_HEADER,0,0,NULL},
486     {NULL,T_CODE,CFG_AFTER_BIT_IMAGE,0,0,NULL},
487     {NULL,T_CODE,CFG_LINE_FEED,0,0,NULL},
488     {NULL,T_CODE,CFG_FORM_FEED,0,0,NULL},
489     {NULL,T_CODE,CFG_NORMAL_MODE,0,1,NULL},
490     {NULL,T_CODE,CFG_SKIP_SPACES,0,1,NULL},
491     {NULL,T_UPPERPOS,CFG_UPPER_POS,0,1,NULL},
492     {NULL,T_SELECT,CFG_ENCODE,0,0,(char*)dviprt_encodename},
493     {NULL,-1},
494   };
495   static dviprt_cfg_item_t encode_info = {
496     "encode",T_STRINGS,CFG_ENCODE_INFO,0,0,NULL
497     };
498   int prtcode_output_bytes[CFG_PRTCODE_TYPE_COUNT];
499 
500   info.line_no = -1;
501   info.fname = fname;
502   if (fname) {
503     info.file = fopen(fname,"r");
504     if (info.file == NULL) {
505       dviprt_printcfgerror(&info,"Cannot open.\n",-1);
506       return CFG_ERROR_FILE_OPEN;
507     }
508   }
509   else {
510     ifp = stdin;
511   }
512   ifp = info.file;
513 
514   info.codebuf = pcodebuf;
515   info.readbuf = pworkbuf;
516   info.codebuf_size = codebuf_s;
517   info.readbuf_size = workbuf_s;
518   /* allocate buffer */
519   if (dviprt_setcfgbuffer_(&info,TEMP_READBUF_SIZE,TEMP_CODEBUF_SIZE) < 0) {
520     fclose(info.file);
521     return CFG_ERROR_MEMORY;
522   }
523 
524   /* initialize */
525   dviprt_initcfg_(pcfg,&info);
526   for (pitem = dviprt_items;pitem->type>=0;pitem++) {
527     if (pitem->name == NULL) {
528       switch (pitem->type) {
529       case T_INTEGER:
530       case T_SELECT:
531       case T_UPPERPOS:
532         pitem->name = dviprt_integername[pitem->no];
533         break;
534       case T_STRINGS:
535         pitem->name = dviprt_stringsname[pitem->no];
536         break;
537       case T_CODE:
538         pitem->name = dviprt_prtcodename[pitem->no];
539         break;
540       }
541     }
542     pitem->spec_f = 0;
543   }
544   encode_info.spec_f = 0;
545   { int i;
546     for (i=0;i<CFG_PRTCODE_TYPE_COUNT;i++)
547       prtcode_output_bytes[i] = 0;
548   }
549 
550   pcfg->version = 1;
551   for ( ; ; ) {
552     uchar *pbuf = info.readbuf;
553     uchar *pchar;
554 
555     if (fgets(info.readbuf,info.readbuf_size,ifp) == NULL) break;
556     info.line_no++;
557     {
558       int len = strlen(pbuf);
559       if ((pbuf[0] < 'a' || pbuf[0] > 'z') && pbuf[0] != '_') {
560         while (pbuf[len-1] != '\n') {
561           if (fgets(info.readbuf,info.readbuf_size,ifp) == NULL)
562             goto end_scan;
563           len = strlen(pbuf);
564         }
565         continue;
566       }
567       if ( len > 0 && pbuf[len-1] == '\n')
568         pbuf[len-1] = 0;
569     }
570     while (*pbuf && *pbuf != ':') pbuf++;
571     if (*pbuf != ':') {
572       dviprt_printcfgerror(&info,"Character ':' is expected.\n",-1);
573       code = CFG_ERROR_SYNTAX;
574       goto end_process;
575     }
576     pchar = pbuf-1;
577     while (pchar >= info.readbuf && isspace(*pchar)) pchar--;
578     *++pchar = 0;
579     pbuf++;
580     for (pitem = dviprt_items;pitem->name;pitem++) {
581       if (strcmp(pitem->name,info.readbuf) == 0) break;
582     }
583     if (pitem->name == NULL) {
584       dviprt_printcfgerror(&info,"Unknown item `",-1);
585       dviprt_printmessage(info.readbuf,-1);
586       dviprt_printmessage("'.\n",-1);
587       code = CFG_ERROR_RANGE;
588       goto end_process;
589     }
590   parse_more:
591     while (*pbuf && isspace(*pbuf)) pbuf++;
592     if (pitem->spec_f) {
593       dviprt_printcfgerror(&info,NULL,0);
594       sprintf(dviprt_message_buffer,
595 	      "Item `%s' is specified twice.\n",pitem->name);
596       dviprt_printmessage(dviprt_message_buffer,-1);
597       code = CFG_ERROR_SYNTAX;
598       goto end_process;
599     }
600     switch (pitem->type) {
601     case T_INTEGER:
602       if ((code = dviprt_set_integer(pitem,pbuf,pcfg,&info)) < 0)
603         goto end_process;
604       if (pitem->no == CFG_PINS) {
605         if (pcfg->integer[CFG_PINS] % 8) {
606           dviprt_printcfgerror(&info,"Value must be a multiple of 8.\n",-1);
607           code = CFG_ERROR_RANGE;
608           goto end_process;
609         }
610         pcfg->integer[CFG_PINS] /= 8;
611       }
612       break;
613     case T_STRINGS:
614       if (info.temp_codebuf_f)
615         info.pcodebuf = info.codebuf;
616       if ((code = dviprt_set_strings(pitem,pbuf,pcfg,&info)) < 0)
617     	goto end_process;
618       if (info.temp_codebuf_f) {
619         pcfg->strings[pitem->no] =
620           (uchar*)malloc(strlen(pcfg->strings[pitem->no])+1);
621         if (pcfg->strings[pitem->no] == NULL) {
622           goto no_more_memory;
623         }
624         strcpy(pcfg->strings[pitem->no],info.codebuf);
625       }
626       break;
627     case T_CODE:
628       if (info.temp_codebuf_f)
629         info.pcodebuf = info.codebuf;
630       if ((code = dviprt_set_code(pitem,pbuf,pcfg,&info)) < 0)
631         goto end_process;
632       prtcode_output_bytes[pitem->no] = code;
633       if (info.temp_codebuf_f) {
634         pcfg->prtcode[pitem->no] =
635           (uchar*)malloc(pcfg->prtcode_size[pitem->no]+1);
636         if (pcfg->prtcode[pitem->no] == NULL) {
637         no_more_memory:
638           dviprt_printcfgerror(&info,"Memory exhausted.\n",-1);
639           code = CFG_ERROR_MEMORY;
640           goto end_process;
641         }
642         memcpy(pcfg->prtcode[pitem->no],info.codebuf,
643 	       pcfg->prtcode_size[pitem->no]+1);
644       }
645       break;
646     case T_SELECT:
647       if ((code = dviprt_set_select(pitem,&pbuf,pcfg,&info)) < 0)
648         goto end_process;
649       if (pitem->no == CFG_ENCODE) {
650         pitem = &encode_info;
651         goto parse_more;
652       }
653       break;
654     case T_UPPERPOS:
655       { uchar *ptmp;
656         uchar upos=0;
657         uchar opt = 0;
658         if (*pbuf == 0) {
659           dviprt_printcfgerror(&info,"No value.\n",-1);
660           code = CFG_ERROR_SYNTAX;
661           goto end_process;
662         }
663         while (*pbuf) {
664           ptmp = pbuf;
665           while (*ptmp && !isspace(*ptmp)) ptmp++;
666           if (strlcmp("HIGH_BIT",pbuf,ptmp-pbuf) == 0)
667             upos = CFG_TOP_IS_HIGH;
668           else if (strlcmp("LOW_BIT",pbuf,ptmp-pbuf) == 0)
669             upos = CFG_TOP_IS_LOW;
670           else if (strlcmp("LEFT_IS_HIGH",pbuf,ptmp-pbuf) == 0)
671             upos = CFG_LEFT_IS_HIGH;
672           else if (strlcmp("LEFT_IS_LOW",pbuf,ptmp-pbuf) == 0)
673             upos = CFG_LEFT_IS_LOW;
674           else if (strlcmp("NON_MOVING",pbuf,ptmp-pbuf) == 0)
675             opt = CFG_NON_MOVING;
676           else if (strlcmp("HEX_MODE",pbuf,ptmp-pbuf) == 0)
677             enc = CFG_ENCODE_HEX;
678           else {
679             dviprt_printtokenerror(&info,pbuf,(int)(ptmp-pbuf),ERROR_UNKNOWN_VALUE);
680             code = CFG_ERROR_RANGE;
681             goto end_process;
682           }
683           pbuf = ptmp;
684           while (*pbuf && isspace(*pbuf)) pbuf++;
685         }
686         pcfg->integer[CFG_UPPER_POS] = upos | opt;
687       }
688       break;
689     }
690     pitem->spec_f = 1;
691   }
692  end_scan:
693 
694   info.line_no = -1;
695   code = 0;
696   for (pitem = dviprt_items;pitem->name;pitem++) {
697     if (!pitem->spec_f && pitem->req_f) {
698       sprintf(dviprt_message_buffer,"%s not found.\n",pitem->name);
699       dviprt_printcfgerror(&info,dviprt_message_buffer,-1);
700       code++;
701     }
702   }
703   if (code) { code = CFG_ERROR_RANGE; goto end_process; }
704 
705   if (pcfg->prtcode[CFG_LINE_FEED] == NULL) {
706     if (info.temp_codebuf_f) {
707       pcfg->prtcode[CFG_LINE_FEED] = info.pcodebuf;
708       info.pcodebuf += 4;
709     }
710     else pcfg->prtcode[CFG_LINE_FEED] = (byte*)malloc(4);
711     memcpy(pcfg->prtcode[CFG_LINE_FEED],"\002\x0d\x0a\000",4);
712     pcfg->prtcode_size[CFG_LINE_FEED] = 3;
713   }
714   if (pcfg->prtcode[CFG_FORM_FEED] == NULL) {
715     if (info.temp_codebuf_f) {
716       pcfg->prtcode[CFG_FORM_FEED] = info.pcodebuf;
717       info.pcodebuf += 4;
718     }
719     else pcfg->prtcode[CFG_FORM_FEED] = (byte*)malloc(4);
720     memcpy(pcfg->prtcode[CFG_FORM_FEED],"\002\x0d\x0c\000",4);
721     pcfg->prtcode_size[CFG_FORM_FEED] = 3;
722   }
723   if (pcfg->integer[CFG_DPI] < 0 && pcfg->integer[CFG_Y_DPI] < 0) {
724     pcfg->integer[CFG_DPI] = 180;
725   }
726   else if (pcfg->integer[CFG_DPI] < 0 || pcfg->integer[CFG_Y_DPI] < 0) {
727     if (pcfg->integer[CFG_DPI] < 0)
728       pcfg->integer[CFG_DPI] = pcfg->integer[CFG_Y_DPI];
729     pcfg->integer[CFG_Y_DPI] = -1;
730   }
731   else if (pcfg->integer[CFG_DPI] == pcfg->integer[CFG_Y_DPI]) {
732     pcfg->integer[CFG_Y_DPI] = -1;
733   }
734   else if (pcfg->integer[CFG_Y_DPI] >= 0) { /* has y_dpi. */
735     set_version(pcfg,2);
736   }
737   if (pcfg->integer[CFG_ENCODE] < 0) {
738     pcfg->integer[CFG_ENCODE] = enc;
739   }
740   if (pcfg->integer[CFG_MAXIMAL_UNIT] < 0) {
741     pcfg->integer[CFG_MAXIMAL_UNIT] = 0x7fff;
742   }
743   if (pcfg->integer[CFG_MINIMAL_UNIT] < 0) {
744     uint v;
745     v = (MAX(prtcode_output_bytes[CFG_SEND_BIT_IMAGE],0) +
746          MAX(prtcode_output_bytes[CFG_AFTER_BIT_IMAGE],0) +
747          MAX(prtcode_output_bytes[CFG_SKIP_SPACES],0))
748       / (pcfg->integer[CFG_PINS]*8) +
749 	MAX(prtcode_output_bytes[CFG_BIT_ROW_HEADER],0);
750     if (v == 0) v = 1;
751     pcfg->integer[CFG_MINIMAL_UNIT] = v;
752   }
753 
754   for (pitem = dviprt_items;pitem->type>=0;pitem++) {
755     if (pitem->spec_f == 0) {
756       sprintf(dviprt_message_buffer,": %s:",pitem->name);
757       switch (pitem->type) {
758       case T_INTEGER:
759         if (pcfg->integer[pitem->no] >= 0) {
760           uint v = pcfg->integer[pitem->no];
761           dviprt_printmessage(fname,-1);
762           dviprt_printmessage(dviprt_message_buffer,-1);
763           sprintf(dviprt_message_buffer," %d\n",v);
764           dviprt_printmessage(dviprt_message_buffer,-1);
765         }
766         break;
767       default: break; /* do nothing */
768       }
769     }
770   }
771 
772  end_process:
773   if (fname) fclose(ifp);
774   dviprt_resetcfgbuffer_(&info);
775 
776   return code;
777 }
778 
779 /*--- internal routines ---*/
780 private int
dviprt_set_integer(dviprt_cfg_item_t * pitem,uchar * buf,dviprt_cfg_t * pcfg,dviprt_cfg_i * pinfo)781 dviprt_set_integer(dviprt_cfg_item_t *pitem,uchar *buf,dviprt_cfg_t *pcfg,
782     dviprt_cfg_i *pinfo)
783 {
784   uchar *pbuf = buf;
785   long v = 0;
786   long max = -1 ,min = -1;
787 
788   if (pitem->info != NULL) {
789     dviprt_cfg_limit_t *plimit = (dviprt_cfg_limit_t *)pitem->info;
790     min = plimit->min;
791     max = plimit->max;
792   }
793   if (min < 0) min = 0;
794   if (max < 0) max = 0xffff;
795   if (*pbuf == 0) {
796     dviprt_printcfgerror(pinfo,"No value.\n",-1);
797     return CFG_ERROR_SYNTAX;
798   }
799   while (*pbuf) {
800     if (!isdigit(*pbuf)) {
801       if (isspace(*pbuf)) break;
802       else goto invalid_val;
803     }
804     v = v*10 + *pbuf - '0';
805     if (v > max) {
806     out_of_range:
807       dviprt_printtokenerror(pinfo,buf,strlen(buf),ERROR_OUTOFRANGE);
808       dviprt_printcfgerror(pinfo,"",-1);
809       sprintf(dviprt_message_buffer,
810 	      "(%u <= value <= %u).\n",(uint)min,(uint)max);
811       dviprt_printmessage(dviprt_message_buffer,-1);
812       return CFG_ERROR_RANGE;
813     }
814     pbuf++;
815   }
816   if (v < min) goto out_of_range;
817 
818   while (*pbuf) {
819     if (!isspace(*pbuf)) {
820     invalid_val:
821       dviprt_printtokenerror(pinfo,buf,strlen(buf),ERROR_INVALID_VALUE);
822       return CFG_ERROR_RANGE;
823     }
824     pbuf++;
825   }
826   pcfg->integer[pitem->no] = v;
827 
828   return 0;
829 }
830 
831 private int
dviprt_set_strings(dviprt_cfg_item_t * pitem,uchar * buf,dviprt_cfg_t * pcfg,dviprt_cfg_i * pinfo)832 dviprt_set_strings(dviprt_cfg_item_t *pitem,uchar *buf,dviprt_cfg_t *pcfg,
833     dviprt_cfg_i *pinfo)
834 {
835   uchar *pend;
836   long len;
837   pend = buf+strlen(buf)-1;
838   while (pend >= buf && isspace(*pend)) pend--;
839   pend++;
840   len = pend - buf;
841   if (len > 0x7fffL) {
842     dviprt_printcfgerror(pinfo,"Too long strings.\n",-1);
843     return CFG_ERROR_RANGE;
844   }
845 
846   pcfg->strings[pitem->no] = pinfo->pcodebuf;
847   strncpy(pinfo->pcodebuf,buf,(int)len);
848   pinfo->pcodebuf[len] = 0;
849   pinfo->pcodebuf += len;
850   pinfo->pcodebuf++;
851   return 0;
852 }
853 
854 private int
dviprt_set_select(dviprt_cfg_item_t * pitem,uchar ** buf,dviprt_cfg_t * pcfg,dviprt_cfg_i * pinfo)855 dviprt_set_select(dviprt_cfg_item_t *pitem,uchar **buf,dviprt_cfg_t *pcfg,
856     dviprt_cfg_i *pinfo)
857 {
858   int i;
859   uchar *ptmp = *buf;
860   uchar *pstart = *buf;
861   uchar **opt;
862   if (*pstart == 0) {
863     dviprt_printcfgerror(pinfo,"No value.\n",-1);
864     return CFG_ERROR_SYNTAX;
865   }
866   while (*ptmp && !isspace(*ptmp)) ptmp++;
867 
868   for (i=0,opt=(uchar**)pitem->info;*opt;i++,opt++) {
869     if (strlcmp(*opt,pstart,ptmp-pstart) == 0) {
870       pcfg->integer[pitem->no] = i;
871       *buf = ptmp;
872       return 0;
873     }
874   }
875   dviprt_printtokenerror(pinfo,pstart,(int)(ptmp-pstart),ERROR_UNKNOWN_VALUE);
876   return CFG_ERROR_RANGE;
877 }
878 
879 #define CFG_TOKEN_ERROR     -1
880 #define CFG_TOKEN_LIMIT_BIT 0x100
881 #define CFG_TOKEN_FMT       0x200
882 
883 private int
dviprt_get_codetype_token(dviprt_cfg_i * pinfo,uchar * pstart,uchar * pend,uchar * stopescseqchars,uchar * limitchars)884 dviprt_get_codetype_token(dviprt_cfg_i *pinfo,uchar *pstart,uchar *pend,uchar *stopescseqchars,
885     uchar *limitchars)
886 {
887   while (pstart < pend && isspace(*pstart)) pstart++;
888   if (pstart >= pend) {
889     pinfo->token = pinfo->endtoken = pstart;
890     return CFG_TOKEN_LIMIT_BIT;
891   }
892   else if (strchr(limitchars,*pstart)) {
893     pinfo->token = pstart;
894     pinfo->endtoken = pstart+1;
895     return CFG_TOKEN_LIMIT_BIT | *pstart;
896   }
897   else if (*pstart == '\\') {
898     int c;
899     long v;
900     uchar *pexpr,*pnext;
901 
902     pexpr = pinfo->token = pstart++;
903     while (pstart < pend && !isspace(*pstart) &&
904            *pstart != '\\' && !strchr(stopescseqchars,*pstart)) {
905       pstart++;
906     }
907     pinfo->endtoken = pstart;
908     if (pinfo->token + 1 == pinfo->endtoken) { /* '\\' only */
909       return '\\';
910     }
911     pexpr++;
912     if (pinfo->endtoken - pexpr == 1) {
913       if (isdigit(*pexpr)) goto parse_decimal_numb;
914       switch (*pexpr) {
915       case 't': c = '\t'; break; /* tab */
916       case 'v': c = '\v'; break; /* tab */
917       case 'n': c = '\n'; break; /* line feed */
918       case 'f': c = '\f'; break; /* form feed */
919       case 'r': c = '\r'; break; /* carrige return */
920       case 'e': c = 0x1b; break; /* escape code */
921       case 's': c = 0x20; break; /* space */
922       default:
923         dviprt_printtokenerror(pinfo,pinfo->token,2,ERROR_UNKNOWN_ESCSEQ);
924         return CFG_TOKEN_ERROR;
925       }
926       return c;
927     }
928     else if (strlcmp("SP",pexpr,pinfo->endtoken - pexpr) == 0)
929       return 0x20;
930     else if (strlcmp("ESC",pexpr,pinfo->endtoken - pexpr) == 0)
931       return 0x1b;
932     switch (*pexpr) {
933     case 'x':
934     case 'X':
935       v = dviprt_hex2long(pexpr+1,pinfo->endtoken,&pnext);
936     check_numb_range:
937       if (pstart != pnext) {
938         dviprt_printtokenerror(pinfo,pinfo->token,
939 			       (int)(pinfo->endtoken - pinfo->token), ERROR_INVALID_VALUE);
940         return CFG_TOKEN_ERROR;
941       }
942       if (v >= 256) {
943         dviprt_printtokenerror(pinfo,pinfo->token,
944 			       (int)(pinfo->endtoken - pinfo->token), ERROR_OUTOFRANGE);
945         return CFG_TOKEN_ERROR;
946       }
947       pinfo->endtoken = pnext;
948       return v;
949     case '0':
950       v = dviprt_oct2long(pexpr,pinfo->endtoken,&pnext);
951       goto check_numb_range;
952     case '1': case '2': case '3': case '4':
953     case '5': case '6': case '7': case '8': case '9':
954     parse_decimal_numb:
955       v = dviprt_dec2long(pexpr,pinfo->endtoken,&pnext);
956       goto check_numb_range;
957     default:
958       return CFG_TOKEN_FMT;
959     }
960   }
961   else {
962     pinfo->token = pstart;
963     pinfo->endtoken = pstart+1;
964     return *pstart;
965   }
966 }
967 
968 private long
dviprt_dec2long(uchar * start,uchar * end,uchar ** next)969 dviprt_dec2long(uchar *start,uchar *end,uchar **next)
970 {
971   long v = 0;
972   while (start < end) {
973     int c = *start;
974     if (isdigit(c)) v = v*10 + c - '0';
975     else break;
976     start++;
977   }
978   *next = start;
979   return v;
980 }
981 
982 private long
dviprt_oct2long(uchar * start,uchar * end,uchar ** next)983 dviprt_oct2long(uchar *start,uchar *end,uchar **next)
984 {
985   long v = 0;
986   while (start < end) {
987     int c = *start;
988     if (c >= '0' && c <= '7') v = v*8 + c - '0';
989     else break;
990     start++;
991   }
992   *next = start;
993   return v;
994 }
995 
996 private long
dviprt_hex2long(uchar * start,uchar * end,uchar ** next)997 dviprt_hex2long(uchar *start,uchar *end,uchar **next)
998 {
999   long v = 0;
1000   while (start < end) {
1001     int c = *start;
1002     if (isdigit(c)) v = v*16 + c - '0';
1003     else if (c >= 'A' && c <= 'F') v = v*16 + c - 'A' + 10;
1004     else if (c >= 'a' && c <= 'f') v = v*16 + c - 'a' + 10;
1005     else break;
1006     start++;
1007   }
1008   *next = start;
1009   return v;
1010 }
1011 
1012 private int
dviprt_set_rpexpr(dviprt_cfg_item_t * pitem,uchar * pbuf,int len,dviprt_cfg_t * pcfg,dviprt_cfg_i * pinfo,int sp)1013 dviprt_set_rpexpr(dviprt_cfg_item_t *pitem,uchar *pbuf,int len,dviprt_cfg_t *pcfg,
1014     dviprt_cfg_i *pinfo,int sp)
1015 {
1016   uchar *pend = pbuf + len;
1017   uchar *plastop = NULL;
1018   int code;
1019 
1020   /* get left expr */
1021   while (pbuf < pend) {
1022     int par_count = 0;
1023     uchar *pcur = pbuf;
1024     while (pcur < pend) {
1025       if (*pcur == '(') par_count++;
1026       else if (*pcur == ')') par_count--;
1027       else if (!isdigit(*pcur) && !isalpha(*pcur) && par_count == 0) {
1028         /* operator */
1029         plastop = pcur;
1030       }
1031       pcur++;
1032     }
1033     if (par_count != 0) {
1034       dviprt_printtokenerror(pinfo,pbuf,(int)(pend-pbuf),ERROR_INCOMPLETE);
1035       return CFG_ERROR_SYNTAX;
1036     }
1037     if (plastop == NULL) {
1038       if (*pbuf != '(') break;
1039       pbuf++;
1040       pend--;
1041     }
1042     else break;
1043   }
1044 
1045   if (plastop == NULL) { /* no operator */
1046     ulong v;
1047     uchar *pdummy;
1048     if (*pbuf == '0') {
1049       uchar a,b,c;
1050       v = dviprt_oct2long(pbuf,pend,&pdummy);
1051     check_intval:
1052       if (pdummy != pend) goto unknown_value;
1053       if (v > 0xffff) {
1054 	dviprt_printtokenerror(pinfo,pbuf,(int)(pend-pbuf),ERROR_OUTOFRANGE);
1055 	return CFG_ERROR_RANGE;
1056       }
1057       a = v & 0x7f;
1058       b = (v>>7) & 0x7f;
1059       c = (v>>14) & 0x03;
1060       if (c) {
1061         *pinfo->pcodebuf++ = c;
1062         *pinfo->pcodebuf++ = 14;
1063         *pinfo->pcodebuf++ = CFG_OP_SHL;
1064       }
1065       if (b) {
1066         *pinfo->pcodebuf++ = b;
1067         *pinfo->pcodebuf++ = 7;
1068         *pinfo->pcodebuf++ = CFG_OP_SHL;
1069         if (c) *pinfo->pcodebuf++ = CFG_OP_OR;
1070       }
1071       if (a) {
1072         *pinfo->pcodebuf++ = a;
1073         if (b || c) *pinfo->pcodebuf++ = CFG_OP_OR;
1074       }
1075       code = 0;
1076     }
1077     else if (isdigit(*pbuf)) {
1078       v = dviprt_dec2long(pbuf,pend,&pdummy);
1079       goto check_intval;
1080     }
1081     else if (pend - pbuf > 1 && (*pbuf == 'x' || *pbuf == 'X')) {
1082       v = dviprt_hex2long(pbuf+1,pend,&pdummy);
1083       goto check_intval;
1084     }
1085     else if (pend - pbuf > 1) {
1086     unknown_value:
1087       dviprt_printtokenerror(pinfo,pbuf,(int)(pend-pbuf),ERROR_UNKNOWN_VALUE);
1088       return CFG_ERROR_RANGE;
1089     }
1090     else {
1091       switch (*pbuf) {
1092       case 'd': v = CFG_VAL_DEFAULT;
1093         if (pitem->no != CFG_SEND_BIT_IMAGE &&
1094             pitem->no != CFG_BIT_ROW_HEADER &&
1095             pitem->no != CFG_AFTER_BIT_IMAGE &&
1096             pitem->no != CFG_SKIP_SPACES)
1097           goto unavailable_value;
1098         break;
1099       case 'c': v = CFG_VAL_CONSTANT; break;
1100       case 'w': v = CFG_VAL_WIDTH; break;
1101       case 'h': v = CFG_VAL_HEIGHT; break;
1102       case 'r': v = CFG_VAL_X_DPI; break;
1103       case 'R': v = CFG_VAL_Y_DPI; break;
1104       case 'p': v = CFG_VAL_PAGE; break;
1105       case 'x': v = CFG_VAL_X_POS; break;
1106       case 'y': v = CFG_VAL_Y_POS; break;
1107       case 'v': v = CFG_VAL_PINS_BYTE; break;
1108       case 's':
1109         v = CFG_VAL_DATASIZE;
1110         if (pitem->no != CFG_SEND_BIT_IMAGE &&
1111             pitem->no != CFG_BIT_ROW_HEADER &&
1112             pitem->no != CFG_AFTER_BIT_IMAGE) {
1113         unavailable_value:
1114           dviprt_printcfgerror(pinfo,"",-1);
1115           sprintf(dviprt_message_buffer,"Variable `%c' in ",(int)*pbuf);
1116           dviprt_printmessage(dviprt_message_buffer,-1);
1117           dviprt_printmessage(pbuf,(int)(pend-pbuf));
1118           sprintf(dviprt_message_buffer," cannot be used in %s.\n",pitem->name);
1119           dviprt_printmessage(dviprt_message_buffer,-1);
1120           return CFG_ERROR_RANGE;
1121         }
1122         break;
1123       default:
1124         goto unknown_value;
1125       }
1126       *pinfo->pcodebuf++ = v;
1127       code = 0;
1128     }
1129   }
1130   else { /* has operator */
1131     uchar op;
1132 
1133     code = dviprt_set_rpexpr(pitem,pbuf,(int)(plastop-pbuf),pcfg,pinfo,sp+1);
1134     if (code < 0) return code;
1135     code = dviprt_set_rpexpr(pitem,plastop+1,(int)(pend-plastop-1),pcfg,pinfo,sp+2);
1136     if (code < 0) return code;
1137 
1138     switch (*plastop) {
1139     case '+': op = CFG_OP_ADD; break;
1140     case '-': op = CFG_OP_SUB; break;
1141     case '*': op = CFG_OP_MUL; break;
1142     case '/': op = CFG_OP_DIV; break;
1143     case '%': op = CFG_OP_MOD; break;
1144     case '<': op = CFG_OP_SHL; break;
1145     case '>': op = CFG_OP_SHR; break;
1146     case '&': op = CFG_OP_AND; break;
1147     case '|': op = CFG_OP_OR ; break;
1148     case '^': op = CFG_OP_XOR; break;
1149     default:
1150       dviprt_printcfgerror(pinfo,NULL,0);
1151       sprintf(dviprt_message_buffer,"Unknown operator %c in ",(int)*pbuf);
1152       dviprt_printmessage(dviprt_message_buffer,-1);
1153       dviprt_printmessage(pbuf,(int)(pend-pbuf));
1154       dviprt_printmessage(".\n",-1);
1155       return CFG_ERROR_SYNTAX;
1156     }
1157     *pinfo->pcodebuf++ = op;
1158   }
1159 
1160   return code;
1161 }
1162 
1163 private int
dviprt_set_code(dviprt_cfg_item_t * pitem,uchar * buf,dviprt_cfg_t * pcfg,dviprt_cfg_i * pinfo)1164 dviprt_set_code(dviprt_cfg_item_t *pitem,uchar *buf,dviprt_cfg_t *pcfg,
1165     dviprt_cfg_i *pinfo)
1166 {
1167   long prev_line;
1168   int prev_type = 1;
1169   uchar *pcount;
1170   uchar *pcode_begin;
1171   uchar *rbuf;
1172   int obytes = 0;
1173 
1174   prev_line = ftell(pinfo->file);
1175   pcode_begin = pinfo->pcodebuf;
1176   rbuf = pinfo->readbuf;
1177 
1178   for ( ; ; ) {
1179     while (*buf) {
1180       int c;
1181       c = dviprt_get_codetype_token(pinfo,buf,buf+strlen(buf),",","");
1182       if (c == CFG_TOKEN_LIMIT_BIT) break; /* no elements remain */
1183       else if (c == CFG_TOKEN_ERROR) return CFG_ERROR_SYNTAX;
1184       if ( c < 256) {        /* character code (raw data) */
1185         if (prev_type) {
1186         new_unit:
1187           pcount = pinfo->pcodebuf++;
1188           (*pcount) = 0;
1189           prev_type = 0;
1190         }
1191         if (*pcount == 127) goto new_unit;
1192         (*pcount)++;
1193         *pinfo->pcodebuf++ = c;
1194         buf = pinfo->endtoken;
1195         obytes++;
1196       }
1197       else if (c == CFG_TOKEN_FMT) { /* format */
1198         uchar *pexpr = pinfo->token;
1199         int div=0,iso=0,mul=0,tl=0;
1200         int cols=0;
1201 	int fmt;
1202         uchar *plength;
1203         uchar *pstart;
1204 
1205         buf = pinfo->token+1;
1206 
1207         /* formats */
1208         switch (*buf) {
1209         case 'b': fmt = CFG_FMT_BIN_LTOH; break;
1210         case 'B': fmt = CFG_FMT_BIN_HTOL; break;
1211         case 'H': fmt = CFG_FMT_HEX_UPPER; break;
1212         case 'h': fmt = CFG_FMT_HEX_LOWER; break;
1213         case 'd': fmt = CFG_FMT_DECIMAL; break;
1214         case 'o': fmt = CFG_FMT_OCTAL; break;
1215         case 's':
1216           buf++;
1217           if (*buf != 't') goto unknown_format;
1218           fmt = CFG_FMT_STRINGS;
1219           break;
1220         default:
1221         unknown_format:
1222           dviprt_printtokenerror(pinfo,pexpr,(int)(pinfo->endtoken-pexpr),
1223 				 ERROR_UNKNOWN_FORMAT);
1224           return CFG_ERROR_SYNTAX;
1225         }
1226         buf++;
1227 
1228         /* columns */
1229         if (fmt == CFG_FMT_STRINGS) ;
1230         else {
1231           if (buf >= pinfo->endtoken) {
1232             dviprt_printtokenerror(pinfo,pexpr,(int)(pinfo->token-pexpr),ERROR_INCOMPLETE);
1233             return CFG_ERROR_SYNTAX;
1234           }
1235 
1236           if (!(*buf >= '1' && *buf <= '7') && *buf != '?') {
1237           invalid_cols:
1238             dviprt_printtokenerror(pinfo,pexpr,(int)(pinfo->endtoken-pexpr),
1239 				   ERROR_UNKNOWN_FORMAT);
1240             return CFG_ERROR_SYNTAX;
1241           }
1242           cols = (*buf == '?') ? 0 : *buf - '0';
1243           if (cols == 0 &&
1244               (fmt == CFG_FMT_BIN_LTOH || fmt == CFG_FMT_BIN_HTOL))
1245             goto invalid_cols;
1246 
1247           buf++;
1248           obytes += (cols == 0) ? 5 : cols;
1249         }
1250 
1251         /* additional format */
1252         while (buf < pinfo->endtoken) {
1253           switch (*buf) {
1254           case 'D': div++; break;
1255           case 'I': iso++; break;
1256           case 'M': mul++; break;
1257           case 'T': tl++; break;
1258           default:
1259             dviprt_printtokenerror(pinfo,pexpr,(int)(buf-pexpr),ERROR_UNKNOWN_FORMAT);
1260             return CFG_ERROR_SYNTAX;
1261           }
1262           if (div > 3 || iso > 1 || mul > 1 || tl > 1) {
1263             dviprt_printtokenerror(pinfo,pexpr,(int)(buf-pexpr),ERROR_UNKNOWN_FORMAT);
1264             return CFG_ERROR_SYNTAX;
1265           }
1266           buf++;
1267         }
1268         *pinfo->pcodebuf++ =
1269           CFG_FMT_BIT | fmt | (iso ? CFG_FMT_ISO_BIT : 0) | cols;
1270         plength = pinfo->pcodebuf;
1271         pinfo->pcodebuf++;
1272         pstart = pinfo->pcodebuf;
1273 
1274         if (*buf == ',' && *(buf+1) != '\"') {
1275 	  int code;
1276           buf++;
1277           pinfo->token = buf;
1278           while (*pinfo->token && *pinfo->token != ',' &&
1279                  *pinfo->token != '\\' && !isspace(*pinfo->token))
1280             pinfo->token++;
1281 	  if (pinfo->token == buf) {
1282             dviprt_printcfgerror(pinfo,"No expression is specified in ",-1);
1283             dviprt_printmessage(pexpr,(int)(buf-pexpr));
1284             dviprt_printmessage(".\n",-1);
1285             return CFG_ERROR_SYNTAX;
1286           }
1287           if ((code = dviprt_set_rpexpr(pitem,buf,(int)(pinfo->token-buf),pcfg,pinfo,0)) < 0)
1288   	    return code;
1289           buf = pinfo->token;
1290         }
1291         else {
1292           *pinfo->pcodebuf++ = CFG_VAL_DEFAULT;
1293         }
1294         if (mul) {
1295           *pinfo->pcodebuf++ = CFG_VAL_CONSTANT;
1296           *pinfo->pcodebuf++ = CFG_OP_MUL;
1297         }
1298         if (tl) {
1299           *pinfo->pcodebuf++ = CFG_VAL_PINS_BYTE;
1300           *pinfo->pcodebuf++ = CFG_OP_MUL;
1301         }
1302         if (div) {
1303           *pinfo->pcodebuf++ = div;
1304           *pinfo->pcodebuf++ = CFG_OP_SHR;
1305         }
1306 	{
1307 	  int length = pinfo->pcodebuf-pstart;
1308 	  if (length > 255) {
1309 	    dviprt_printtokenerror(pinfo,pexpr,(int)(buf-pexpr),ERROR_COMPLICATED_EXPR);
1310 	    return CFG_ERROR_RANGE;
1311 	  }
1312 	  *plength++ = length & 0xff;
1313 	}
1314         if (fmt == CFG_FMT_STRINGS) {
1315           uchar *pslen = pinfo->pcodebuf++;
1316           int len;
1317           if (strlen(buf) < 2 || *buf != ',' || *(buf+1) != '\"') {
1318 	    dviprt_printcfgerror(pinfo,"No strings specified in ",-1);
1319 	    dviprt_printmessage(pexpr,(int)(buf-pexpr));
1320 	    dviprt_printmessage(".\n",-1);
1321             return CFG_ERROR_SYNTAX;
1322           }
1323           buf += 2;
1324           for (len=0; ;len++) {
1325             c = dviprt_get_codetype_token(pinfo,buf,buf+strlen(buf),"\"","\"");
1326             if (c == CFG_TOKEN_ERROR) return CFG_ERROR_SYNTAX;
1327             else if (c == CFG_TOKEN_FMT) {
1328               dviprt_printcfgerror(pinfo,"The format ",-1);
1329               dviprt_printmessage(pinfo->token,
1330 				  (int)(pinfo->endtoken-pinfo->token));
1331               dviprt_printmessage(" cannot to be specified here.\n",-1);
1332               return CFG_ERROR_SYNTAX;
1333             }
1334             else if (c & CFG_TOKEN_LIMIT_BIT) {
1335               if ((c & 0xff) != '\"') {
1336                 dviprt_printcfgerror(pinfo,
1337 				     "Strings must be enclosed with "
1338 				     "double quotations (\").\n",-1);
1339                 return CFG_ERROR_SYNTAX;
1340               }
1341               buf = pinfo->endtoken;
1342               break;
1343             }
1344             *pinfo->pcodebuf++ = c;
1345             buf = pinfo->endtoken;
1346           }
1347           if (len > 255) {
1348             dviprt_printcfgerror(pinfo,"Too long strings.\n",-1);
1349             return CFG_ERROR_RANGE;
1350           }
1351 	  *pslen = len;
1352 	}
1353         prev_type = 1;
1354       }
1355       else {
1356 	dviprt_printcfgerror(pinfo,"Parse error. Unexpected token ",-1);
1357 	dviprt_printmessage(pinfo->token,(int)(pinfo->endtoken-pinfo->token));
1358 	dviprt_printmessage(".\n",-1);
1359 	return CFG_ERROR_SYNTAX;
1360       }
1361     }
1362   next_line:
1363     if (fgets(rbuf,pinfo->readbuf_size,pinfo->file) == NULL) break;
1364     if (!isspace(rbuf[0]) && rbuf[0] != ';') {
1365       fseek(pinfo->file,prev_line,0);
1366       break;
1367     }
1368     prev_line = ftell(pinfo->file);
1369     pinfo->line_no++;
1370     buf = rbuf;
1371     while (*buf && isspace(*buf)) buf++;
1372     if (*buf == ';')
1373       goto next_line; /* comment */
1374     {
1375       int len = strlen(rbuf);
1376       if (len > 0 && rbuf[len-1] == '\n')
1377         rbuf[len-1] = 0;
1378     }
1379   }
1380   pcfg->prtcode[pitem->no] = pcode_begin;
1381   pcfg->prtcode_size[pitem->no] = (pinfo->pcodebuf - pcode_begin) & 0xffff;
1382   *pinfo->pcodebuf++ = 0;
1383   return obytes;
1384 }
1385 
1386 private char *
dviprt_src_errorno2message(int type)1387 dviprt_src_errorno2message(int type)
1388 {
1389   switch (type) {
1390   case ERROR_OUTOFRANGE:
1391     return "Out of range.\n";
1392   case ERROR_UNKNOWN_VALUE:
1393     return "Unknown value.\n";
1394   case ERROR_UNKNOWN_ESCSEQ:
1395     return "Unknown escape sequence.\n";
1396   case ERROR_COMPLICATED_EXPR:
1397     return "Too complicated expression.\n";
1398   case ERROR_INCOMPLETE:
1399     return "Incomplete specification.\n";
1400   case ERROR_UNKNOWN_FORMAT:
1401     return "Unknown format.\n";
1402   case ERROR_INVALID_VALUE:
1403     return "Invalid value.\n";
1404   default:
1405     return NULL;
1406   }
1407 }
1408 
1409 private int
dviprt_printtokenerror(dviprt_cfg_i * pinfo,char * token,int len,int type)1410 dviprt_printtokenerror(dviprt_cfg_i *pinfo,char *token,int len,int type)
1411 {
1412   char *msg;
1413 
1414   dviprt_printcfgerror(pinfo,token,len);
1415   dviprt_printmessage("\n",-1);
1416 
1417   if ((msg = dviprt_src_errorno2message(type)) != NULL)
1418     dviprt_printcfgerror(pinfo,msg,-1);
1419   return 0;
1420 }
1421 
1422 #undef strlcmp
1423 #undef set_version
1424 /***** End of rsrc.c *****/
1425 
1426 
1427 /***** From util.c *****/
1428 /* $Id: UTIL.C 1.1 1994/08/30 02:27:02 kaz Exp kaz $ */
1429 
1430 
1431 char *dviprt_integername[] = { CFG_INTEGER_NAME, NULL };
1432 char *dviprt_stringsname[] = { CFG_STRINGS_NAME, NULL };
1433 char *dviprt_prtcodename[] = { CFG_PRTCODE_NAME, NULL };
1434 char *dviprt_encodename[] = { CFG_ENCODE_NAME, NULL };
1435 
1436 private FILE *dviprt_messagestream;
1437 private void dviprt_messagestream_construct (void) __attribute__((constructor));
dviprt_messagestream_construct(void)1438 private void dviprt_messagestream_construct (void) { dviprt_messagestream = stderr; }
1439 
1440 /*--- library functions ---*/
1441 int
dviprt_setmessagestream(FILE * fp)1442 dviprt_setmessagestream(FILE *fp)
1443 {
1444   dviprt_messagestream = fp;
1445   return 0;
1446 }
1447 
1448 /*--- internal routines ---*/
1449 liblocal int
dviprt_initcfg_(dviprt_cfg_t * pcfg,dviprt_cfg_i * pinfo)1450 dviprt_initcfg_(dviprt_cfg_t *pcfg,dviprt_cfg_i *pinfo)
1451 {
1452   int i;
1453 
1454   for (i=0;i<CFG_INTEGER_TYPE_COUNT;i++)
1455     pcfg->integer[i] = -1;
1456   for (i=0;i<CFG_STRINGS_TYPE_COUNT;i++)
1457     pcfg->strings[i] = NULL;
1458   for (i=0;i<CFG_PRTCODE_TYPE_COUNT;i++) {
1459     pcfg->prtcode[i] = NULL;
1460     pcfg->prtcode_size[i] = 0;
1461   }
1462   pinfo->pcodebuf = pinfo->codebuf;
1463   pinfo->line_no = 0;
1464   return 0;
1465 }
1466 
1467 liblocal int
dviprt_setcfgbuffer_(dviprt_cfg_i * pinfo,int rsize,int csize)1468 dviprt_setcfgbuffer_(dviprt_cfg_i *pinfo,int rsize,int csize)
1469 {
1470   pinfo->temp_readbuf_f = pinfo->temp_codebuf_f = 0;
1471 
1472   if (pinfo->readbuf == NULL) {
1473     pinfo->readbuf_size = rsize;
1474     if (rsize>0) {
1475       pinfo->temp_readbuf_f = 1;
1476       pinfo->readbuf = (uchar *)malloc(rsize);
1477       if (pinfo->readbuf == NULL) {
1478       no_mem:
1479         dviprt_printmessage(pinfo->fname,-1);
1480         dviprt_printmessage("Memory exhausted.\n",-1);
1481         return CFG_ERROR_MEMORY;
1482       }
1483     }
1484   }
1485   if (pinfo->codebuf == NULL) {
1486     pinfo->codebuf_size = csize;
1487     if (csize>0) {
1488       pinfo->temp_codebuf_f = 1;
1489       pinfo->codebuf = (uchar *)malloc(csize);
1490       if (pinfo->codebuf == NULL) goto no_mem;
1491     }
1492   }
1493   return 0;
1494 }
1495 
1496 liblocal int
dviprt_resetcfgbuffer_(dviprt_cfg_i * pinfo)1497 dviprt_resetcfgbuffer_(dviprt_cfg_i *pinfo)
1498 {
1499   if (pinfo->temp_readbuf_f) free(pinfo->readbuf);
1500   if (pinfo->temp_codebuf_f) free(pinfo->codebuf);
1501   pinfo->temp_codebuf_f = pinfo->temp_readbuf_f = 0;
1502   return 0;
1503 }
1504 
1505 char dviprt_message_buffer[128];
1506 
1507 liblocal int
dviprt_printmessage(char * str,int len)1508 dviprt_printmessage(char *str,int len)
1509 {
1510   if (dviprt_messagestream && str) {
1511     if (len >= 0) fwrite(str,len,1,dviprt_messagestream);
1512     else fputs(str,dviprt_messagestream);
1513     fflush(dviprt_messagestream);
1514   }
1515   return 0;
1516 }
1517 
1518 private int
dviprt_printcfgerrorheader(dviprt_cfg_i * pinfo)1519 dviprt_printcfgerrorheader(dviprt_cfg_i *pinfo)
1520 {
1521   if (pinfo) {
1522     char *fn = pinfo->fname;
1523     if (fn == NULL) fn = "-";
1524     dviprt_printmessage(fn,-1);
1525     dviprt_printmessage(": ",-1);
1526     if (pinfo->line_no>0) {
1527       sprintf(dviprt_message_buffer,"%d: ",pinfo->line_no);
1528       dviprt_printmessage(dviprt_message_buffer,-1);
1529     }
1530   }
1531   return 0;
1532 }
1533 
1534 liblocal int
dviprt_printerror(char * msg,int len)1535 dviprt_printerror(char *msg,int len)
1536 {
1537   dviprt_printmessage("*ERROR* ",-1);
1538   dviprt_printmessage(msg,len);
1539   return 0;
1540 }
1541 
1542 liblocal int
dviprt_printcfgerror(dviprt_cfg_i * pinfo,char * msg,int len)1543 dviprt_printcfgerror(dviprt_cfg_i *pinfo,char *msg,int len)
1544 {
1545   dviprt_printcfgerrorheader(pinfo);
1546   dviprt_printerror(msg,len);
1547   return 0;
1548 }
1549 
1550 liblocal int
dviprt_printwarning(char * msg,int len)1551 dviprt_printwarning(char *msg,int len)
1552 {
1553   dviprt_printmessage("*WARNING* ",-1);
1554   dviprt_printmessage(msg,len);
1555   return 0;
1556 }
1557 
1558 liblocal int
dviprt_printcfgwarning(dviprt_cfg_i * pinfo,char * msg,int len)1559 dviprt_printcfgwarning(dviprt_cfg_i *pinfo,char *msg,int len)
1560 {
1561   dviprt_printcfgerrorheader(pinfo);
1562   dviprt_printwarning(msg,len);
1563   return 0;
1564 }
1565 /***** End of util.c *****/
1566 
1567 
1568 /***** From print.c *****/
1569 /* $Id: PRINT.C 1.1 1994/08/30 02:27:02 kaz Exp kaz $ */
1570 
1571 
1572 /*--- forward declarations ---*/
1573 private int dviprt_getmaximalwidth(P1(dviprt_print *));
1574 private int dviprt_flush_buffer(P2(dviprt_print *,uchar far *));
1575 private int dviprt_output_transpose(P3(dviprt_print *,uchar far *,uint ));
1576 private int dviprt_output_nontranspose(P3(dviprt_print *,uchar far *,uint ));
1577 private int dviprt_output_nontranspose_reverse(P3(dviprt_print *,uchar far *,uint ));
1578 private int dviprt_reverse_bits(P2(uchar far *,uint));
1579 private int dviprt_transpose8x8(P4(uchar far *,uint, uchar far *,uint));
1580 private int dviprt_output_expr(P4(dviprt_print *,int,uint,uint));
1581 private int dviprt_default_outputproc(P3(uchar far *,long ,void *));
1582 private long dviprt_getbuffersize(P1(dviprt_print *));
1583 
1584 /*--- library functions ---*/
1585 long
dviprt_initlibrary(dviprt_print * pprint,dviprt_cfg_t * pprt,uint width,uint height)1586 dviprt_initlibrary(dviprt_print *pprint,dviprt_cfg_t *pprt,uint width,uint height)
1587 {
1588   dviprt_encoder *pencode;
1589   uint pins = pprt->integer[CFG_PINS]*8;
1590 
1591   pprint->printer = pprt;
1592   height += (pins-1);
1593   height /= pins;
1594   height *= pins;
1595   pprint->bitmap_width = width; /* width by bytes */
1596   pprint->bitmap_height = height;
1597   pprint->buffer_width = MIN(width,pprt->integer[CFG_MAXIMAL_UNIT]);
1598   pprint->page_count = 0;
1599   pprint->output_bytes = 0;
1600   pprint->tempbuffer_f = 0;
1601   pencode = dviprt_getencoder_((int)pprt->integer[CFG_ENCODE]);
1602   if (pencode == NULL) return CFG_ERROR_NOT_SUPPORTED;
1603   pprint->encode_getbuffersize_proc = pencode->getworksize;
1604   pprint->encode_encode_proc = pencode->encode;
1605 
1606   pprint->output_bytes = 0;
1607   pprint->pstream = NULL;
1608   pprint->output_proc = NULL;
1609 
1610   if (pprt->integer[CFG_UPPER_POS] & CFG_NON_TRANSPOSE_BIT) {
1611     pprint->output_maximal_unit =
1612       (pprt->integer[CFG_UPPER_POS] & CFG_REVERSE_BIT) ?
1613 	dviprt_output_nontranspose_reverse : dviprt_output_nontranspose;
1614   }
1615   else
1616     pprint->output_maximal_unit = dviprt_output_transpose;
1617   return dviprt_getbuffersize(pprint);
1618 }
1619 
1620 int
dviprt_setstream(dviprt_print * pprint,int (* func)(P3 (uchar far *,long,void *)),void * pstream)1621   dviprt_setstream
1622 #ifdef __PROTOTYPES__
1623   (dviprt_print *pprint,int (*func)(P3(uchar far *,long ,void*)),void *pstream)
1624 #else
1625 (pprint,func,pstream)
1626 dviprt_print *pprint;
1627 int (*func)();
1628 void *pstream;
1629 #endif
1630 {
1631   if (pprint->page_count) {
1632     int code = dviprt_output_expr(pprint,CFG_FORM_FEED,0,0);
1633     if (code < 0) return code;
1634     pprint->page_count = 0;
1635   }
1636   pprint->output_bytes = 0;
1637   pprint->pstream = pstream;
1638   pprint->output_proc = (func == NULL) ? dviprt_default_outputproc : func;
1639   return 0;
1640 }
1641 
1642 int
dviprt_setbuffer(dviprt_print * pprint,uchar far * buf)1643 dviprt_setbuffer(dviprt_print *pprint,uchar far *buf)
1644 {
1645   if (pprint->tempbuffer_f) {
1646     BufferFree(pprint->encode_buffer);
1647   }
1648   pprint->tempbuffer_f = 0;
1649   if (buf == NULL) {
1650     long s = dviprt_getbuffersize(pprint);
1651     if (s) {
1652       buf = (uchar far *)BufferAlloc(s);
1653       if (buf == NULL) return CFG_ERROR_MEMORY;
1654       pprint->tempbuffer_f = 1;
1655     }
1656   }
1657   pprint->encode_buffer = buf;
1658   pprint->source_buffer =
1659     buf + pprint->encode_getbuffersize_proc(pprint,dviprt_getmaximalwidth(pprint));
1660   return 0;
1661 }
1662 
1663 int
dviprt_beginpage(dviprt_print * pprint)1664 dviprt_beginpage(dviprt_print *pprint)
1665 {
1666   int code;
1667   pprint->device_x = pprint->device_y = 0;
1668   pprint->bitmap_x = pprint->bitmap_y = 0;
1669   if (pprint->page_count == 0) { /* bit_image_mode */
1670     code = dviprt_output_expr(pprint,CFG_BIT_IMAGE_MODE,0,0);
1671   }
1672   else { /* form_feed */
1673     code = dviprt_output_expr(pprint,CFG_FORM_FEED,0,0);
1674   }
1675   pprint->page_count++;
1676   if (code < 0) return code;
1677   return 0;
1678 }
1679 
1680 int
dviprt_outputscanlines(dviprt_print * pprint,uchar far * fb)1681 dviprt_outputscanlines(dviprt_print *pprint,uchar far *fb)
1682 {
1683   dviprt_cfg_t *pprt;
1684   int code;
1685   uint bw;
1686 
1687   pprt = pprint->printer;
1688   bw = pprint->bitmap_width;
1689 
1690   if (pprt->prtcode_size[CFG_SKIP_SPACES] <= 0) {
1691     pprint->bitmap_x = bw;
1692     pprint->last_x = 0;
1693   }
1694   else {
1695     uint uw,rw;
1696     uint mu;
1697     uint bx,lx;
1698     uint pins = dviprt_getscanlines(pprint);
1699     mu = pprt->integer[CFG_MINIMAL_UNIT];
1700     bx = lx = 0;
1701 
1702     for (rw= bw; rw > 0 ;rw -= uw) {
1703       uint x,y;
1704       uchar far *in;
1705 
1706       uw = MIN(mu,rw);
1707       in = fb + bx;
1708       for (x = uw; x>0 ; x--) {
1709         uchar far *test;
1710         test = in;
1711         for (y = pins ; y > 0 ;y--) {
1712           if (*test) goto next_unit;
1713           test += bw;
1714         }
1715         in++;
1716       }
1717 
1718       if (bx > lx) {
1719         pprint->bitmap_x = bx;
1720         pprint->last_x = lx;
1721         code = dviprt_flush_buffer(pprint,fb); /* output buffered unit */
1722         if (code < 0) return code;
1723         lx = pprint->last_x + uw;
1724       }
1725       else lx += uw;
1726 
1727     next_unit:
1728       bx += uw;
1729     }
1730     pprint->bitmap_x = bx;
1731     pprint->last_x = lx;
1732   }
1733   code = (pprint->last_x < pprint->bitmap_x) ? dviprt_flush_buffer(pprint,fb) : 0;
1734   pprint->bitmap_y++;
1735   return code;
1736 }
1737 
1738 int
dviprt_endbitmap(dviprt_print * pprint)1739 dviprt_endbitmap(dviprt_print *pprint)
1740 {
1741   if (pprint->page_count) {
1742     int code = dviprt_output_expr(pprint,CFG_NORMAL_MODE,0,0);
1743     if (code < 0) return code;
1744   }
1745   return 0;
1746 }
1747 
1748 int
dviprt_unsetbuffer(dviprt_print * pprint)1749 dviprt_unsetbuffer(dviprt_print *pprint)
1750 {
1751   if (pprint->tempbuffer_f) {
1752     BufferFree(pprint->encode_buffer);
1753     pprint->tempbuffer_f = 0;
1754   }
1755   return 0;
1756 }
1757 
1758 int
dviprt_output(dviprt_print * pprint,uchar far * buf,long s)1759 dviprt_output(dviprt_print *pprint,uchar far *buf,long s)
1760 {
1761   int c = pprint->output_proc(buf,s,pprint->pstream);
1762   pprint->output_bytes += s;
1763   return c;
1764 }
1765 
1766 /*--- internal routines ---*/
1767 private int
dviprt_getmaximalwidth(dviprt_print * pprint)1768 dviprt_getmaximalwidth(dviprt_print *pprint)
1769 {
1770   return MIN(pprint->printer->integer[CFG_MAXIMAL_UNIT],pprint->bitmap_width);
1771 }
1772 
1773 private long
dviprt_getbuffersize(dviprt_print * pprint)1774 dviprt_getbuffersize(dviprt_print *pprint)
1775 {
1776   long w = dviprt_getmaximalwidth(pprint);
1777   long e = pprint->encode_getbuffersize_proc(pprint,w);
1778   switch (pprint->printer->integer[CFG_UPPER_POS]
1779 	  & (CFG_NON_TRANSPOSE_BIT | CFG_REVERSE_BIT)) {
1780   case CFG_LEFT_IS_HIGH:
1781     return e;
1782   default:
1783     return w * dviprt_getscanlines(pprint) + e;
1784   }
1785 }
1786 
1787 private int
dviprt_flush_buffer(dviprt_print * pprint,uchar far * fb)1788 dviprt_flush_buffer(dviprt_print *pprint,uchar far *fb)
1789 {
1790   dviprt_cfg_t *pprt;
1791   int code;
1792 
1793   pprt = pprint->printer;
1794   while (pprint->device_y < pprint->bitmap_y) { /* skip vertical spaces */
1795     pprint->device_y++;
1796     code = dviprt_output_expr(pprint,CFG_LINE_FEED,0,0);
1797     pprint->device_x = 0;
1798   }
1799   while (pprint->last_x < pprint->bitmap_x) {
1800     int w;
1801     while (pprint->device_x < pprint->last_x) { /* skip horizontal spaces */
1802       w = MIN(pprt->integer[CFG_MAXIMAL_UNIT],
1803 	      pprint->last_x - pprint->device_x);
1804       code = dviprt_output_expr(pprint,CFG_SKIP_SPACES,w,0);
1805       pprint->device_x += w;
1806     }
1807     w = MIN(pprt->integer[CFG_MAXIMAL_UNIT],pprint->bitmap_x-pprint->last_x);
1808     code = pprint->output_maximal_unit(pprint,fb+pprint->last_x,w);
1809     if (code < 0) return code;
1810     pprint->last_x += w;
1811     if (!(pprt->integer[CFG_UPPER_POS] & CFG_NON_MOVING))
1812       pprint->device_x += w;
1813   }
1814   return 0;
1815 }
1816 
1817 private int
dviprt_output_nontranspose(dviprt_print * pprint,uchar far * fb,uint width)1818 dviprt_output_nontranspose(dviprt_print *pprint,uchar far *fb,uint width)
1819 {
1820   int code;
1821   uint dsize;
1822   uint y;
1823   uint pins;
1824 
1825   pins = dviprt_getscanlines(pprint);
1826 
1827   dsize = 0;
1828   pprint->psource = fb;
1829   for (y = pins ; y>0 ; y--) {
1830     int dsize_line;
1831     dsize_line = pprint->encode_encode_proc(pprint,(long)width,0);
1832     if (dsize_line < 0) return dsize_line;
1833     dsize += dsize_line;
1834     pprint->psource += pprint->bitmap_width;
1835   }
1836 
1837   code = dviprt_output_expr(pprint,CFG_SEND_BIT_IMAGE,width,dsize);
1838   if (code < 0) return code;
1839 
1840   pprint->psource = fb;
1841   for (y = pins ; y>0 ; y--) {
1842     int dsize_line;
1843     dsize_line = pprint->encode_encode_proc(pprint,(long)width,1);
1844     code = dviprt_output_expr(pprint,CFG_BIT_ROW_HEADER,width,dsize_line);
1845     if (code < 0) return code;
1846     code = dviprt_output(pprint,pprint->poutput,dsize_line);
1847     if (code < 0) return code;
1848     pprint->psource += pprint->bitmap_width;
1849   }
1850 
1851   code = dviprt_output_expr(pprint,CFG_AFTER_BIT_IMAGE,width,dsize);
1852   if (code < 0) return code;
1853 
1854   return 0;
1855 }
1856 
1857 
1858 private int
dviprt_output_nontranspose_reverse(dviprt_print * pprint,uchar far * fb,uint width)1859 dviprt_output_nontranspose_reverse(dviprt_print *pprint,uchar far *fb,uint width)
1860 {
1861   uchar far *psrc;
1862   uchar far *pbuf;
1863   int code;
1864   uint src_size;
1865   uint dsize;
1866   uint y;
1867   uint pins;
1868 
1869   pins = dviprt_getscanlines(pprint);
1870   src_size = width * pins;
1871 
1872   psrc = pprint->source_buffer;
1873   for (y = pins ; y > 0; y--) {
1874     uint i;
1875     pbuf = fb;
1876     for (i=width;i>0;i--) *psrc++ = *pbuf++;
1877     fb += pprint->bitmap_width;
1878   }
1879 
1880   /* here, reverse bits */
1881   psrc = pprint->source_buffer;
1882   dviprt_reverse_bits(psrc,src_size);
1883 
1884 
1885   dsize = 0;
1886   pprint->psource = pprint->source_buffer;
1887   for (y = pins ; y>0 ; y--) {
1888     int dsize_line;
1889     dsize_line = pprint->encode_encode_proc(pprint,(long)width,0);
1890     if (dsize_line < 0) return dsize_line;
1891     dsize += dsize_line;
1892     pprint->psource += width;
1893   }
1894 
1895   code = dviprt_output_expr(pprint,CFG_SEND_BIT_IMAGE,width,dsize);
1896   if (code < 0) return code;
1897 
1898   pprint->psource = pprint->source_buffer;
1899   for (y = pins ; y>0 ; y--) {
1900     int dsize_line;
1901     dsize_line = pprint->encode_encode_proc(pprint,(long)width,1);
1902     code = dviprt_output_expr(pprint,CFG_BIT_ROW_HEADER,width,dsize_line);
1903     if (code < 0) return code;
1904     code = dviprt_output(pprint,pprint->poutput,dsize_line);
1905     if (code < 0) return code;
1906     pprint->psource += width;
1907   }
1908 
1909   code = dviprt_output_expr(pprint,CFG_AFTER_BIT_IMAGE,width,dsize);
1910   if (code < 0) return code;
1911 
1912   return 0;
1913 }
1914 
1915 private int
dviprt_output_transpose(dviprt_print * pprint,uchar far * fb,uint width)1916 dviprt_output_transpose(dviprt_print *pprint,uchar far *fb,uint width)
1917 {
1918   uchar far *psrc;
1919   uchar far *pbuf;
1920   int code;
1921   uint src_size;
1922   uint dsize;
1923   uint pins,pins8;
1924   int y;
1925 
1926   pins8 = pprint->printer->integer[CFG_PINS];
1927   pins = pins8 * 8;
1928   src_size = width * pins;
1929   psrc = pprint->source_buffer;
1930   {
1931     uchar far *pdst;
1932     uint sskip;
1933     sskip = pprint->bitmap_width * 8;
1934     for (y = pins8-1; y >= 0 ; y--) {
1935       uint i;
1936       pbuf = fb;
1937       pdst = psrc;
1938       for (i=width;i>0;i--) {
1939         dviprt_transpose8x8(pbuf,pprint->bitmap_width,pdst,pins8);
1940         pbuf ++;
1941         pdst += pins;
1942       }
1943       fb += sskip;
1944       psrc++;
1945     }
1946   }
1947 
1948   psrc = pprint->source_buffer;
1949 
1950   /* here, reverse bits */
1951   if (pprint->printer->integer[CFG_UPPER_POS] & CFG_REVERSE_BIT)
1952     dviprt_reverse_bits(psrc,src_size);
1953 
1954   dsize = 0;
1955   pprint->psource = pprint->source_buffer;
1956   for (y = pins ; y>0 ; y--) {
1957     int dsize_line;
1958     dsize_line = pprint->encode_encode_proc(pprint,(long)width,0);
1959     if (dsize_line < 0) return dsize_line;
1960     dsize += dsize_line;
1961     pprint->psource += width;
1962   }
1963 
1964   code = dviprt_output_expr(pprint,CFG_SEND_BIT_IMAGE,width,dsize);
1965   if (code < 0) return code;
1966 
1967   pprint->psource = pprint->source_buffer;
1968   for (y = pins ; y>0 ; y--) {
1969     uint dsize_line;
1970     dsize_line = pprint->encode_encode_proc(pprint,(long)width,1);
1971     code = dviprt_output(pprint,pprint->poutput,dsize_line);
1972     if (code < 0) return code;
1973     pprint->psource += width;
1974   }
1975 
1976   code = dviprt_output_expr(pprint,CFG_AFTER_BIT_IMAGE,width,dsize);
1977   if (code < 0) return code;
1978 
1979   return 0;
1980 }
1981 
1982 private int
dviprt_transpose8x8(uchar far * inp,uint line_size,uchar far * outp,uint dist)1983 dviprt_transpose8x8(uchar far *inp,uint line_size,uchar far *outp,uint dist)
1984 {
1985   register uint ae, bf, cg, dh;
1986   {
1987     uchar far *ptr4 = inp + (line_size << 2);
1988     ae = ((uint)*inp << 8) + *ptr4;
1989     inp += line_size, ptr4 += line_size;
1990     bf = ((uint)*inp << 8) + *ptr4;
1991     inp += line_size, ptr4 += line_size;
1992     cg = ((uint)*inp << 8) + *ptr4;
1993     inp += line_size, ptr4 += line_size;
1994     dh = ((uint)*inp << 8) + *ptr4;
1995   }
1996   /* Check for all 8 bytes being the same. */
1997   /* This is especially worth doing for the case where all are zero. */
1998   if ( ae == bf && ae == cg && ae == dh && (ae >> 8) == (ae & 0xff) ) {
1999     if ( ae == 0 ) goto store;
2000     *outp = -((ae >> 7) & 1);
2001     outp += dist;
2002     *outp = -((ae >> 6) & 1);
2003     outp += dist;
2004     *outp = -((ae >> 5) & 1);
2005     outp += dist;
2006     *outp = -((ae >> 4) & 1);
2007     outp += dist;
2008     *outp = -((ae >> 3) & 1);
2009     outp += dist;
2010     *outp = -((ae >> 2) & 1);
2011     outp += dist;
2012     *outp = -((ae >> 1) & 1);
2013     outp += dist;
2014     *outp = -(ae & 1);
2015   }
2016   else {
2017     register uint temp;
2018 
2019     /* Transpose a block of bits between registers. */
2020 #define transpose(r,s,mask,shift)\
2021     r ^= (temp = ((s >> shift) ^ r) & mask);\
2022       s ^= temp << shift
2023 
2024 	/* Transpose blocks of 4 x 4 */
2025 #define transpose4(r) transpose(r,r,0x00f0,4)
2026 	transpose4(ae);
2027     transpose4(bf);
2028     transpose4(cg);
2029     transpose4(dh);
2030 
2031     /* Transpose blocks of 2 x 2 */
2032     transpose(ae, cg, 0x3333, 2);
2033     transpose(bf, dh, 0x3333, 2);
2034 
2035     /* Transpose blocks of 1 x 1 */
2036     transpose(ae, bf, 0x5555, 1);
2037     transpose(cg, dh, 0x5555, 1);
2038 
2039   store:	*outp = ae >> 8;
2040     outp += dist;
2041     *outp = bf >> 8;
2042     outp += dist;
2043     *outp = cg >> 8;
2044     outp += dist;
2045     *outp = dh >> 8;
2046     outp += dist;
2047     *outp = (uchar)ae;
2048     outp += dist;
2049     *outp = (uchar)bf;
2050     outp += dist;
2051     *outp = (uchar)cg;
2052     outp += dist;
2053     *outp = (uchar)dh;
2054   }
2055   return 0;
2056 }
2057 
2058 private int
dviprt_reverse_bits(uchar far * buf,uint s)2059 dviprt_reverse_bits(uchar far *buf,uint s)
2060 {
2061   static uchar rev[256] = {
2062     0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
2063     0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
2064     0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
2065     0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
2066     0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
2067     0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
2068     0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
2069     0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
2070     0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
2071     0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
2072     0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
2073     0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
2074     0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
2075     0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
2076     0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
2077     0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
2078     0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
2079     0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
2080     0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
2081     0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
2082     0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
2083     0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
2084     0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
2085     0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
2086     0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
2087     0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
2088     0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
2089     0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
2090     0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
2091     0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
2092     0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
2093     0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
2094   };
2095   while (s-- > 0) {
2096     *buf = rev[*buf];
2097     buf++;
2098   }
2099   return 0;
2100 }
2101 
2102 
2103 private int
dviprt_output_expr(dviprt_print * pprint,int numb,uint width,uint dsize)2104 dviprt_output_expr(dviprt_print *pprint,int numb,uint width,uint dsize)
2105 {
2106   uchar *pcode;
2107   dviprt_cfg_t *pprt;
2108   uint v;
2109   uint len;
2110 
2111   pprt = pprint->printer;
2112   if (pprt->prtcode[numb] == NULL) return 0;
2113   pcode = pprt->prtcode[numb];
2114   len = pprt->prtcode_size[numb];
2115 
2116   while (*pcode && len>0) {
2117     if (*pcode & CFG_FMT_BIT) {
2118       uint stack[CFG_STACK_DEPTH];
2119       int stack_p = -1;
2120       uchar fmt = *pcode++;
2121       uint l = *pcode++;
2122       len -=2;
2123       while (l>0) {
2124         if ((*pcode & CFG_EXPR_TYPE_BIT) == CFG_OP) {
2125           uint v2 = stack[stack_p--];
2126           v = stack[stack_p--];
2127           switch (*pcode) {
2128           case CFG_OP_ADD: v += v2; break;
2129           case CFG_OP_SUB: v -= v2; break;
2130           case CFG_OP_MUL: v *= v2; break;
2131           case CFG_OP_DIV:
2132             if (v2 == 0) { /* divided by zero. */
2133             div_by_zero:
2134               return CFG_ERROR_DIV0;
2135             }
2136             v /= v2;
2137             break;
2138           case CFG_OP_MOD:
2139             if (v2 == 0) goto div_by_zero;
2140             v %= v2;
2141             break;
2142           case CFG_OP_SHL: v <<= v2; break;
2143           case CFG_OP_SHR: v >>= v2; break;
2144           case CFG_OP_AND: v &= v2; break;
2145           case CFG_OP_OR : v |= v2; break;
2146           case CFG_OP_XOR: v ^= v2; break;
2147           default:
2148             ;
2149           }
2150           stack[++stack_p] = v;
2151         }
2152         else if ((*pcode & CFG_EXPR_TYPE_BIT) == CFG_VAL) {
2153           {
2154             switch (*pcode) {
2155             case CFG_VAL_DEFAULT: v = width*8; break;
2156             case CFG_VAL_CONSTANT: v = pprt->integer[CFG_CONSTANT]; break;
2157             case CFG_VAL_WIDTH: v = pprint->bitmap_width*8; break;
2158             case CFG_VAL_HEIGHT: v = pprint->bitmap_height; break;
2159             case CFG_VAL_PAGE:
2160             case CFG_VAL_PAGECOUNT: v = pprint->page_count; break;
2161             case CFG_VAL_DATASIZE: v = dsize; break;
2162             case CFG_VAL_X_DPI: v = (int)pprt->integer[CFG_DPI]; break;
2163             case CFG_VAL_Y_DPI:
2164               v = pprt->integer[CFG_Y_DPI] > 0 ?
2165 		pprt->integer[CFG_Y_DPI] : pprt->integer[CFG_DPI];
2166               break;
2167             case CFG_VAL_PINS_BYTE: v = pprt->integer[CFG_PINS]; break;
2168             case CFG_VAL_X_POS: v = pprint->device_x*8; break;
2169             case CFG_VAL_Y_POS:
2170               v = pprint->device_y * dviprt_getscanlines(pprint);
2171               break;
2172             }
2173           }
2174           stack[++stack_p] = v;
2175         }
2176         else {
2177           stack[++stack_p] = *pcode;
2178         }
2179         l--; pcode++; len--;
2180       }
2181       v = stack[stack_p];
2182       if ((fmt & CFG_FMT_FORMAT_BIT) == CFG_FMT_STRINGS) {
2183         uint l = *pcode++;
2184         len--;
2185         while (v-- > 0)
2186           dviprt_output(pprint,(uchar far *)pcode,l);
2187         pcode += l;
2188         len -= l;
2189       }
2190       else if ((fmt & CFG_FMT_FORMAT_BIT) == CFG_FMT_ASSIGNMENT) {
2191         pprint->uservar[fmt&0x0f] = v;
2192       }
2193       else { uchar valbuf[10];
2194 	     int cols = fmt & CFG_FMT_COLUMN_BIT;
2195 	     int i;
2196 
2197 	     switch (fmt & CFG_FMT_FORMAT_BIT) {
2198 	     case CFG_FMT_BIN_LTOH:
2199 	       for (i=0;i<cols;i++) {
2200 		 valbuf[i] = v&0xff;
2201 		 v >>= 8;
2202 	       }
2203 	       break;
2204 	     case CFG_FMT_BIN_HTOL:
2205 	       for (i=cols-1;i>=0;i--) {
2206 		 valbuf[i] = v&0xff;
2207 		 v >>= 8;
2208 	       }
2209 	       break;
2210 	     default:
2211 	       { char *f;
2212 		 char fmtbuf[10];
2213 		 switch(fmt & CFG_FMT_FORMAT_BIT) {
2214 		 case CFG_FMT_HEX_UPPER: f = "X"; break;
2215 		 case CFG_FMT_HEX_LOWER: f = "x"; break;
2216 		 case CFG_FMT_DECIMAL: f = "u"; break;
2217 		 case CFG_FMT_OCTAL: f = "o"; break;
2218 		 }
2219 		 if (cols == 0)
2220 		   strcpy(fmtbuf,"%");
2221 		 else
2222 		   sprintf(fmtbuf,"%%0%d",cols);
2223 		 strcat(fmtbuf,f);
2224 		 sprintf(valbuf,fmtbuf,stack[stack_p]);
2225 		 cols = strlen(valbuf);
2226 		 if (fmt & CFG_FMT_ISO_BIT)
2227 		   valbuf[cols-1] |= 0x10;
2228 	       }
2229 	       break;
2230 	     }
2231 	     dviprt_output(pprint,(uchar far *)valbuf, cols);
2232 	   }
2233     }
2234     else {
2235       uint l = *pcode++;
2236       len--;
2237       dviprt_output(pprint,(uchar far *)pcode,l);
2238       pcode += l;
2239       len -= l;
2240     }
2241   }
2242   return 0;
2243 }
2244 
2245 private int
dviprt_default_outputproc(uchar far * buf,long s,void * fp)2246 dviprt_default_outputproc(uchar far *buf,long s,void *fp)
2247 {
2248 #ifdef __MSDOS_REAL__
2249   while (s-- > 0) {
2250     if (fputc(*buf++,fp) == EOF)
2251       return CFG_ERROR_OUTPUT;
2252   }
2253   return 0;
2254 #else
2255   return fwrite(buf,s,1,fp) == 1 ? 0 : CFG_ERROR_OUTPUT;
2256 #endif
2257 }
2258 /***** End of print.c *****/
2259 
2260 
2261 /***** From encode.c *****/
2262 /* $Id: ENCODE.C 1.1 1994/08/30 02:27:02 kaz Exp kaz $ */
2263 
2264 
2265 #define DVIPRT_SUPPORT_FAX 1
2266 #define DVIPRT_SUPPORT_PCL 1
2267 
2268 /*--- forward declarations ---*/
2269 private long dviprt_null_getworksize(P2(dviprt_print *,long ));
2270 private long dviprt_null_encode(P3(dviprt_print *,long ,int ));
2271 private long dviprt_hex_getworksize(P2(dviprt_print *,long ));
2272 private long dviprt_hex_encode(P3(dviprt_print *,long ,int ));
2273 #if DVIPRT_SUPPORT_FAX
2274 private long dviprt_fax_getworksize(P2(dviprt_print *,long ));
2275 private long dviprt_fax_encode(P3(dviprt_print *,long ,int ));
2276 #endif
2277 #if DVIPRT_SUPPORT_PCL
2278 private long dviprt_pcl1_getworksize(P2(dviprt_print *,long ));
2279 private long dviprt_pcl1_encode(P3(dviprt_print *,long ,int ));
2280 private long dviprt_pcl2_getworksize(P2(dviprt_print *,long ));
2281 private long dviprt_pcl2_encode(P3(dviprt_print *,long ,int ));
2282 #endif
2283 
2284 private dviprt_encoder dviprt_encoder_list[] = {
2285   { CFG_ENCODE_NULL, dviprt_null_getworksize,dviprt_null_encode},
2286   { CFG_ENCODE_HEX, dviprt_hex_getworksize,dviprt_hex_encode},
2287 #if DVIPRT_SUPPORT_FAX
2288   { CFG_ENCODE_FAX, dviprt_fax_getworksize,dviprt_fax_encode},
2289 #endif
2290 #if DVIPRT_SUPPORT_PCL
2291   { CFG_ENCODE_PCL1, dviprt_pcl1_getworksize,dviprt_pcl1_encode},
2292   { CFG_ENCODE_PCL2, dviprt_pcl2_getworksize,dviprt_pcl2_encode},
2293 #endif
2294   { -1 },
2295 };
2296 
2297 /*--- internal routines ---*/
2298 /* The users MUST NOT USE these functions */
2299 liblocal dviprt_encoder *
dviprt_getencoder_(int no)2300 dviprt_getencoder_(int no)
2301 {
2302   int i;
2303   for (i=0;dviprt_encoder_list[i].no >= 0;i++)
2304     if (no == dviprt_encoder_list[i].no)
2305       return dviprt_encoder_list+i;
2306   return NULL;
2307 }
2308 
2309 private long
dviprt_null_getworksize(dviprt_print * pprint,long s)2310 dviprt_null_getworksize(dviprt_print *pprint,long s)
2311 {
2312   return 0;
2313 }
2314 private long
dviprt_null_encode(dviprt_print * pprint,long s,int f)2315 dviprt_null_encode(dviprt_print *pprint,long s,int f)
2316 {
2317   pprint->poutput = pprint->psource;
2318   return s;
2319 }
2320 
2321 private long
dviprt_hex_getworksize(dviprt_print * pprint,long s)2322 dviprt_hex_getworksize(dviprt_print *pprint,long s)
2323 {
2324   return s*2;
2325 }
2326 private long
dviprt_hex_encode(dviprt_print * pprint,long s,int f)2327 dviprt_hex_encode(dviprt_print *pprint,long s,int f)
2328 {
2329   if (f) {
2330     uchar far *w;
2331     uchar far *buf;
2332     static uchar hex[] = "0123456789ABCDEF";
2333     int i=s;
2334     w = pprint->poutput = pprint->encode_buffer;
2335     buf = pprint->psource;
2336     while (i-->0) {
2337       *w++ = hex[(*buf>>4)&0x0f];
2338       *w++ = hex[*buf&0x0f];
2339       buf++;
2340     }
2341   }
2342   return s*2;
2343 }
2344 
2345 #if DVIPRT_SUPPORT_PCL
2346 private long
dviprt_pcl1_getworksize(dviprt_print * pprint,long s)2347 dviprt_pcl1_getworksize(dviprt_print *pprint,long s)
2348 {
2349   return s*2;
2350 }
2351 private long
dviprt_pcl1_encode(dviprt_print * pprint,long s,int f)2352 dviprt_pcl1_encode(dviprt_print *pprint,long s,int f)
2353 {
2354   uchar far *src;
2355   uchar far *end;
2356   uchar far *out;
2357   long total = 0;
2358 
2359   src = pprint->psource;
2360   end = src + s;
2361   out = pprint->poutput = pprint->encode_buffer;
2362 
2363   while ( src < end  ) {
2364     uchar test = *src++;
2365     uchar far *run = src;
2366     while ( src < end && *src == test ) src++;
2367     if (f) {
2368       while ( src - run > 255 ) {
2369         *out++ = 255;
2370         *out++ = test;
2371         total += 2;
2372         run += 256;
2373       }
2374       *out++ = src - run;
2375       *out++ = test;
2376       total += 2;
2377     }
2378     else {
2379       total += (((src-run)/255 + ((src-run)%255) ? 1 : 0)) * 2;
2380     }
2381   }
2382   return total;
2383 }
2384 
2385 private long
dviprt_pcl2_getworksize(dviprt_print * pprint,long s)2386 dviprt_pcl2_getworksize(dviprt_print *pprint,long s)
2387 {
2388   return s + s/127 + 1;
2389 }
2390 private long
dviprt_pcl2_encode(dviprt_print * pprint,long s,int f)2391 dviprt_pcl2_encode(dviprt_print *pprint,long s,int f)
2392 {
2393   uchar far *exam;
2394   uchar far *cptr;
2395   uchar far *end;
2396   uchar far *src;
2397   long total = 0;
2398 
2399   src = pprint->psource;
2400   exam = src;
2401   cptr = pprint->poutput = pprint->encode_buffer;
2402   end = exam + s;
2403 
2404   for ( ; ; ) {
2405     uchar test = *exam++;
2406     int len;
2407     while ((test != *exam) && (exam < end))
2408       test = *exam++;
2409     if (exam < end) exam--;
2410     len = exam - src;
2411     if (f) {
2412       while (len > 0){
2413         int i;
2414         int count = len;
2415         if (count>127) count=127;
2416         *cptr++=count-1;
2417         for (i = 0 ; i < count ; i++) *cptr++ = *src++;
2418         len -= count;
2419         total += (count+1);
2420       }
2421     }
2422     else {
2423       total += len + ((len/127)+(len%127 ? 1 : 0));
2424     }
2425     if (exam >= end) break;
2426     exam++;
2427     while ((test == *exam) && (exam < end))
2428       exam++;
2429     len = exam - src;
2430     if (f) {
2431       while (len > 0) {
2432         int count = len;
2433         if (count > 127) count = 127;
2434         *cptr++ = (257-count);
2435         *cptr++ = test;
2436         len -= count;
2437         total += 2;
2438       }
2439     }
2440     else {
2441       total += ((len/127 + (len%127) ? 1 : 0)) * 2;
2442     }
2443     if (exam >= end) break;
2444     src = exam;
2445   }
2446   return total;
2447 }
2448 #endif /* DVIPRT_SUPPORT_PCL */
2449 
2450 #if DVIPRT_SUPPORT_FAX
2451 private long
dviprt_fax_getworksize(dviprt_print * pprint,long s)2452 dviprt_fax_getworksize(dviprt_print *pprint,long s)
2453 {
2454   long size = s * 8 + 7;
2455   return MAX(size*2/9+4,size/8) * dviprt_getscanlines(pprint) + 1;
2456 }
2457 
2458 #define MAX_FAX_WIDTH	2623
2459 typedef struct {
2460   int	data;
2461   int	length;
2462 } FaxEncode_t;
2463 typedef struct {
2464   uchar i_bitbuf;
2465   uchar far *i_buf;
2466   int i_count;
2467 
2468   uchar o_bitbuf;
2469   uchar far *o_buf;
2470   int o_count;
2471   int o_bufcount;
2472 } FaxEncodeInfo;
2473 private int dviprt_fax_set_white(P2(int,FaxEncodeInfo *));
2474 private int dviprt_fax_set_black(P2(int,FaxEncodeInfo *));
2475 private int dviprt_fax_set_bitcount(P2(FaxEncode_t *,FaxEncodeInfo *));
2476 
2477 private long
dviprt_fax_encode(dviprt_print * pprint,long s,int f)2478 dviprt_fax_encode(dviprt_print *pprint,long s,int f)
2479 {
2480   static FaxEncode_t eol_code = {0x800,12};
2481   int allruns = 0;
2482   int width = s * 8;
2483   int top_bit_count = 8;
2484   FaxEncodeInfo info;
2485   uchar far *src_end;
2486   uchar recover;
2487 
2488   src_end = pprint->psource + s;
2489   recover = *src_end;
2490   *src_end = 0xaa;
2491 
2492   /* initializing */
2493   info.i_buf = pprint->psource;
2494   info.i_bitbuf = *info.i_buf++;
2495   info.i_count = 8;
2496   info.o_buf = pprint->poutput = pprint->encode_buffer;
2497   info.o_bitbuf = 0;
2498   info.o_count = 8;
2499   info.o_bufcount = 0;
2500 
2501   dviprt_fax_set_bitcount(&eol_code,&info);
2502 
2503   for(;;){
2504     static uchar ROW[9] =
2505       {0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
2506     static uchar MASK[9] =
2507       {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
2508     int white_run_length;
2509     int black_run_length;
2510 
2511     /* count run-length */
2512     /* remaining bits in the current byte are white? */
2513     if (!(info.i_bitbuf &= MASK[info.i_count])){
2514       do{
2515 	top_bit_count += 8; /* next byte is also white	*/
2516       } while(!(info.i_bitbuf = *info.i_buf++));
2517       info.i_count = 8;
2518     }
2519     /* current byte contains white and black bits 	*/
2520     while(!(info.i_bitbuf & ROW[info.i_count]))
2521       info.i_count--;		/* skip white bits 	*/
2522     white_run_length = top_bit_count - (black_run_length = info.i_count);
2523 
2524     /* remaining bits in the current byte are black?	*/
2525     if (info.i_bitbuf == MASK[info.i_count]){
2526       do{
2527 	black_run_length += 8;
2528 	/* next byte is also black	*/
2529       } while((info.i_bitbuf = *info.i_buf++) == 0xff);
2530       info.i_count = 8;
2531     }
2532     else info.i_count--;	/* skip the top black bit	*/
2533 
2534     /* current byte contains white and black bits 	*/
2535     while(info.i_bitbuf & ROW[info.i_count])
2536       info.i_count--;		/* skip black bits	 		*/
2537     black_run_length -= (top_bit_count = info.i_count);
2538 
2539     /* output */
2540     if((allruns += white_run_length) < width)
2541       dviprt_fax_set_white(white_run_length,&info);
2542     else{
2543       dviprt_fax_set_white(white_run_length + width - allruns,&info);
2544       break;
2545     }
2546     if((allruns += black_run_length) < width)
2547       dviprt_fax_set_black(black_run_length,&info);
2548     else{
2549       dviprt_fax_set_black(black_run_length + width - allruns,&info);
2550       break;
2551     }
2552   }
2553 
2554   info.o_bufcount++;
2555   if (info.o_count < 8)
2556     *info.o_buf++ = info.o_bitbuf;
2557   else
2558     *info.o_buf++ = 0;
2559   *src_end = recover;
2560 
2561   return info.o_bufcount;
2562 }
2563 
2564 private int
dviprt_fax_set_bitcount(FaxEncode_t * pt,FaxEncodeInfo * info)2565 dviprt_fax_set_bitcount(FaxEncode_t *pt,FaxEncodeInfo *info)
2566 {
2567   int	data, length;
2568 
2569   data = pt->data;
2570   length = pt->length;
2571   while( (length -= info->o_count) >= 0 ){
2572     *info->o_buf++ = ((data << (8 - info->o_count))|info->o_bitbuf);
2573     info->o_bitbuf = 0;
2574     info->o_bufcount++;
2575     data >>= info->o_count;
2576     info->o_count = 8;
2577   }
2578   info->o_bitbuf |= (data << (8 - info->o_count));
2579   info->o_count = -length;
2580   return 0;
2581 }
2582 
2583 private int
dviprt_fax_set_white(int count,FaxEncodeInfo * info)2584 dviprt_fax_set_white(int count,FaxEncodeInfo *info)
2585 {
2586   static FaxEncode_t white_count_list[]={
2587     { 0x00AC,      8,	}, /*    0 */
2588     { 0x0038,      6,	}, /*    1 */
2589     { 0x000E,      4,	}, /*    2 */
2590     { 0x0001,      4,	}, /*    3 */
2591     { 0x000D,      4,	}, /*    4 */
2592     { 0x0003,      4,	}, /*    5 */
2593     { 0x0007,      4,	}, /*    6 */
2594     { 0x000F,      4,	}, /*    7 */
2595     { 0x0019,      5,	}, /*    8 */
2596     { 0x0005,      5,	}, /*    9 */
2597     { 0x001C,      5,	}, /*   10 */
2598     { 0x0002,      5,	}, /*   11 */
2599     { 0x0004,      6,	}, /*   12 */
2600     { 0x0030,      6,	}, /*   13 */
2601     { 0x000B,      6,	}, /*   14 */
2602     { 0x002B,      6,	}, /*   15 */
2603     { 0x0015,      6,	}, /*   16 */
2604     { 0x0035,      6,	}, /*   17 */
2605     { 0x0072,      7,	}, /*   18 */
2606     { 0x0018,      7,	}, /*   19 */
2607     { 0x0008,      7,	}, /*   20 */
2608     { 0x0074,      7,	}, /*   21 */
2609     { 0x0060,      7,	}, /*   22 */
2610     { 0x0010,      7,	}, /*   23 */
2611     { 0x000A,      7,	}, /*   24 */
2612     { 0x006A,      7,	}, /*   25 */
2613     { 0x0064,      7,	}, /*   26 */
2614     { 0x0012,      7,	}, /*   27 */
2615     { 0x000C,      7,	}, /*   28 */
2616     { 0x0040,      8,	}, /*   29 */
2617     { 0x00C0,      8,	}, /*   30 */
2618     { 0x0058,      8,	}, /*   31 */
2619     { 0x00D8,      8,	}, /*   32 */
2620     { 0x0048,      8,	}, /*   33 */
2621     { 0x00C8,      8,	}, /*   34 */
2622     { 0x0028,      8,	}, /*   35 */
2623     { 0x00A8,      8,	}, /*   36 */
2624     { 0x0068,      8,	}, /*   37 */
2625     { 0x00E8,      8,	}, /*   38 */
2626     { 0x0014,      8,	}, /*   39 */
2627     { 0x0094,      8,	}, /*   40 */
2628     { 0x0054,      8,	}, /*   41 */
2629     { 0x00D4,      8,	}, /*   42 */
2630     { 0x0034,      8,	}, /*   43 */
2631     { 0x00B4,      8,	}, /*   44 */
2632     { 0x0020,      8,	}, /*   45 */
2633     { 0x00A0,      8,	}, /*   46 */
2634     { 0x0050,      8,	}, /*   47 */
2635     { 0x00D0,      8,	}, /*   48 */
2636     { 0x004A,      8,	}, /*   49 */
2637     { 0x00CA,      8,	}, /*   50 */
2638     { 0x002A,      8,	}, /*   51 */
2639     { 0x00AA,      8,	}, /*   52 */
2640     { 0x0024,      8,	}, /*   53 */
2641     { 0x00A4,      8,	}, /*   54 */
2642     { 0x001A,      8,	}, /*   55 */
2643     { 0x009A,      8,	}, /*   56 */
2644     { 0x005A,      8,	}, /*   57 */
2645     { 0x00DA,      8,	}, /*   58 */
2646     { 0x0052,      8,	}, /*   59 */
2647     { 0x00D2,      8,	}, /*   60 */
2648     { 0x004C,      8,	}, /*   61 */
2649     { 0x00CC,      8,	}, /*   62 */
2650     { 0x002C,      8,	}, /*   63 */
2651 
2652     { 0x001B,      5,	}, /*   64 */
2653     { 0x0009,      5,	}, /*  128 */
2654     { 0x003A,      6,	}, /*  192 */
2655     { 0x0076,      7,	}, /*  256 */
2656     { 0x006C,      8,	}, /*  320 */
2657     { 0x00EC,      8,	}, /*  384 */
2658     { 0x0026,      8,	}, /*  448 */
2659     { 0x00A6,      8,	}, /*  512 */
2660     { 0x0016,      8,	}, /*  576 */
2661     { 0x00E6,      8,	}, /*  640 */
2662     { 0x0066,      9,	}, /*  704 */
2663     { 0x0166,      9,	}, /*  768 */
2664     { 0x0096,      9,	}, /*  832 */
2665     { 0x0196,      9,	}, /*  896 */
2666     { 0x0056,      9,	}, /*  960 */
2667     { 0x0156,      9,	}, /* 1024 */
2668     { 0x00D6,      9,	}, /* 1088 */
2669     { 0x01D6,      9,	}, /* 1152 */
2670     { 0x0036,      9,	}, /* 1216 */
2671     { 0x0136,      9,	}, /* 1280 */
2672     { 0x00B6,      9,	}, /* 1344 */
2673     { 0x01B6,      9,	}, /* 1408 */
2674     { 0x0032,      9,	}, /* 1472 */
2675     { 0x0132,      9,	}, /* 1536 */
2676     { 0x00B2,      9,	}, /* 1600 */
2677     { 0x0006,      6,	}, /* 1664 */
2678     { 0x01B2,      9,	}, /* 1728 */
2679 
2680     { 0x0080,     11,	}, /* 1792 */
2681     { 0x0180,     11,	}, /* 1856 */
2682     { 0x0580,     11,	}, /* 1920 */
2683     { 0x0480,     12,	}, /* 1984 */
2684     { 0x0C80,     12,	}, /* 2048 */
2685     { 0x0280,     12,	}, /* 2112 */
2686     { 0x0A80,     12,	}, /* 2176 */
2687     { 0x0680,     12,	}, /* 2240 */
2688     { 0x0E80,     12,	}, /* 2304 */
2689     { 0x0380,     12,	}, /* 2368 */
2690     { 0x0B80,     12,	}, /* 2432 */
2691     { 0x0780,     12,	}, /* 2496 */
2692     { 0x0F80,     12,	}, /* 2560 */
2693   };
2694   while (count >= 64){
2695     if(count <= MAX_FAX_WIDTH){
2696       dviprt_fax_set_bitcount((white_count_list + 63) + (count/64),info);
2697       break;
2698     }
2699     dviprt_fax_set_white(MAX_FAX_WIDTH,info);
2700     dviprt_fax_set_black(0,info);
2701     count -= MAX_FAX_WIDTH;
2702   }
2703   dviprt_fax_set_bitcount(white_count_list + (count & 63) ,info);
2704   return 0;
2705 }
2706 
2707 private int
dviprt_fax_set_black(int count,FaxEncodeInfo * info)2708 dviprt_fax_set_black(int count,FaxEncodeInfo *info)
2709 {
2710   static FaxEncode_t black_count_list[]={
2711     { 0x03B0,     10,	}, /*    0 */
2712     { 0x0002,      3,	}, /*    1 */
2713     { 0x0003,      2,	}, /*    2 */
2714     { 0x0001,      2,	}, /*    3 */
2715     { 0x0006,      3,	}, /*    4 */
2716     { 0x000C,      4,	}, /*    5 */
2717     { 0x0004,      4,	}, /*    6 */
2718     { 0x0018,      5,	}, /*    7 */
2719     { 0x0028,      6,	}, /*    8 */
2720     { 0x0008,      6,	}, /*    9 */
2721     { 0x0010,      7,	}, /*   10 */
2722     { 0x0050,      7,	}, /*   11 */
2723     { 0x0070,      7,	}, /*   12 */
2724     { 0x0020,      8,	}, /*   13 */
2725     { 0x00E0,      8,	}, /*   14 */
2726     { 0x0030,      9,	}, /*   15 */
2727     { 0x03A0,     10,	}, /*   16 */
2728     { 0x0060,     10,	}, /*   17 */
2729     { 0x0040,     10,	}, /*   18 */
2730     { 0x0730,     11,	}, /*   19 */
2731     { 0x00B0,     11,	}, /*   20 */
2732     { 0x01B0,     11,	}, /*   21 */
2733     { 0x0760,     11,	}, /*   22 */
2734     { 0x00A0,     11,	}, /*   23 */
2735     { 0x0740,     11,	}, /*   24 */
2736     { 0x00C0,     11,	}, /*   25 */
2737     { 0x0530,     12,	}, /*   26 */
2738     { 0x0D30,     12,	}, /*   27 */
2739     { 0x0330,     12,	}, /*   28 */
2740     { 0x0B30,     12,	}, /*   29 */
2741     { 0x0160,     12,	}, /*   30 */
2742     { 0x0960,     12,	}, /*   31 */
2743     { 0x0560,     12,	}, /*   32 */
2744     { 0x0D60,     12,	}, /*   33 */
2745     { 0x04B0,     12,	}, /*   34 */
2746     { 0x0CB0,     12,	}, /*   35 */
2747     { 0x02B0,     12,	}, /*   36 */
2748     { 0x0AB0,     12,	}, /*   37 */
2749     { 0x06B0,     12,	}, /*   38 */
2750     { 0x0EB0,     12,	}, /*   39 */
2751     { 0x0360,     12,	}, /*   40 */
2752     { 0x0B60,     12,	}, /*   41 */
2753     { 0x05B0,     12,	}, /*   42 */
2754     { 0x0DB0,     12,	}, /*   43 */
2755     { 0x02A0,     12,	}, /*   44 */
2756     { 0x0AA0,     12,	}, /*   45 */
2757     { 0x06A0,     12,	}, /*   46 */
2758     { 0x0EA0,     12,	}, /*   47 */
2759     { 0x0260,     12,	}, /*   48 */
2760     { 0x0A60,     12,	}, /*   49 */
2761     { 0x04A0,     12,	}, /*   50 */
2762     { 0x0CA0,     12,	}, /*   51 */
2763     { 0x0240,     12,	}, /*   52 */
2764     { 0x0EC0,     12,	}, /*   53 */
2765     { 0x01C0,     12,	}, /*   54 */
2766     { 0x0E40,     12,	}, /*   55 */
2767     { 0x0140,     12,	}, /*   56 */
2768     { 0x01A0,     12,	}, /*   57 */
2769     { 0x09A0,     12,	}, /*   58 */
2770     { 0x0D40,     12,	}, /*   59 */
2771     { 0x0340,     12,	}, /*   60 */
2772     { 0x05A0,     12,	}, /*   61 */
2773     { 0x0660,     12,	}, /*   62 */
2774     { 0x0E60,     12,	}, /*   63 */
2775 
2776     { 0x03C0,     10,	}, /*   64 */
2777     { 0x0130,     12,	}, /*  128 */
2778     { 0x0930,     12,	}, /*  192 */
2779     { 0x0DA0,     12,	}, /*  256 */
2780     { 0x0CC0,     12,	}, /*  320 */
2781     { 0x02C0,     12,	}, /*  384 */
2782     { 0x0AC0,     12,	}, /*  448 */
2783     { 0x06C0,     13,	}, /*  512 */
2784     { 0x16C0,     13,	}, /*  576 */
2785     { 0x0A40,     13,	}, /*  640 */
2786     { 0x1A40,     13,	}, /*  704 */
2787     { 0x0640,     13,	}, /*  768 */
2788     { 0x1640,     13,	}, /*  832 */
2789     { 0x09C0,     13,	}, /*  896 */
2790     { 0x19C0,     13,	}, /*  960 */
2791     { 0x05C0,     13,	}, /* 1024 */
2792     { 0x15C0,     13,	}, /* 1088 */
2793     { 0x0DC0,     13,	}, /* 1152 */
2794     { 0x1DC0,     13,	}, /* 1216 */
2795     { 0x0940,     13,	}, /* 1280 */
2796     { 0x1940,     13,	}, /* 1344 */
2797     { 0x0540,     13,	}, /* 1408 */
2798     { 0x1540,     13,	}, /* 1472 */
2799     { 0x0B40,     13,	}, /* 1536 */
2800     { 0x1B40,     13,	}, /* 1600 */
2801     { 0x04C0,     13,	}, /* 1664 */
2802     { 0x14C0,     13, }, /* 1728 */
2803 
2804     { 0x0080,     11,	}, /* 1792 */
2805     { 0x0180,     11,	}, /* 1856 */
2806     { 0x0580,     11,	}, /* 1920 */
2807     { 0x0480,     12,	}, /* 1984 */
2808     { 0x0C80,     12,	}, /* 2048 */
2809     { 0x0280,     12,	}, /* 2112 */
2810     { 0x0A80,     12,	}, /* 2176 */
2811     { 0x0680,     12,	}, /* 2240 */
2812     { 0x0E80,     12,	}, /* 2304 */
2813     { 0x0380,     12,	}, /* 2368 */
2814     { 0x0B80,     12,	}, /* 2432 */
2815     { 0x0780,     12,	}, /* 2496 */
2816     { 0x0F80,     12,	}, /* 2560 */
2817   };
2818 
2819   while (count >= 64){
2820     if(count <= MAX_FAX_WIDTH){
2821       dviprt_fax_set_bitcount((black_count_list + 63) + (count/64),info);
2822       break;
2823     }
2824     dviprt_fax_set_black(MAX_FAX_WIDTH,info);
2825     dviprt_fax_set_white(0,info);
2826     count -= MAX_FAX_WIDTH;
2827   }
2828   dviprt_fax_set_bitcount(black_count_list + (count & 63),info);
2829   return 0;
2830 }
2831 #endif /* DVIPRT_SUPPORT_FAX */
2832 /***** End of encode.c *****/
2833