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 static int dviprt_read_S_cfg(dviprt_cfg_t *,dviprt_cfg_i *);
43 static int dviprt_read_QR_cfg(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 static 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 static 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 static int dviprt_set_select
432   (dviprt_cfg_item_t *,uchar **,dviprt_cfg_t *,dviprt_cfg_i *);
433 static int dviprt_set_integer
434   (dviprt_cfg_item_t *, uchar *, dviprt_cfg_t *,dviprt_cfg_i *);
435 static int dviprt_set_strings
436   (dviprt_cfg_item_t *,uchar *,dviprt_cfg_t *,dviprt_cfg_i *);
437 static int dviprt_set_rpexpr
438   (dviprt_cfg_item_t *,uchar *,int , dviprt_cfg_t *,dviprt_cfg_i *,int);
439 static int dviprt_set_code
440   (dviprt_cfg_item_t *,uchar *,dviprt_cfg_t *,dviprt_cfg_i *);
441 
442 static long dviprt_oct2long(uchar *,uchar *,uchar **);
443 static long dviprt_dec2long(uchar *,uchar *,uchar **);
444 static long dviprt_hex2long(uchar *,uchar *,uchar **);
445 
446 static int dviprt_printtokenerror(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 static 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 static 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 static 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 static 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 static 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 static 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 static 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 static 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 static 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 static 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 static 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 #if 0
1437 static FILE *dviprt_messagestream = stderr;
1438 #else  /* patch for glibc 2.1.x by Shin Fukui <shita@april.co.jp> */
1439 static FILE *dviprt_messagestream;
1440 #endif
1441 
1442 /*--- library functions ---*/
1443 int
dviprt_setmessagestream(FILE * fp)1444 dviprt_setmessagestream(FILE *fp)
1445 {
1446   dviprt_messagestream = fp;
1447   return 0;
1448 }
1449 
1450 /*--- internal routines ---*/
1451 static int
dviprt_initcfg_(dviprt_cfg_t * pcfg,dviprt_cfg_i * pinfo)1452 dviprt_initcfg_(dviprt_cfg_t *pcfg,dviprt_cfg_i *pinfo)
1453 {
1454   int i;
1455 
1456   for (i=0;i<CFG_INTEGER_TYPE_COUNT;i++)
1457     pcfg->integer[i] = -1;
1458   for (i=0;i<CFG_STRINGS_TYPE_COUNT;i++)
1459     pcfg->strings[i] = NULL;
1460   for (i=0;i<CFG_PRTCODE_TYPE_COUNT;i++) {
1461     pcfg->prtcode[i] = NULL;
1462     pcfg->prtcode_size[i] = 0;
1463   }
1464   pinfo->pcodebuf = pinfo->codebuf;
1465   pinfo->line_no = 0;
1466   return 0;
1467 }
1468 
1469 static int
dviprt_setcfgbuffer_(dviprt_cfg_i * pinfo,int rsize,int csize)1470 dviprt_setcfgbuffer_(dviprt_cfg_i *pinfo,int rsize,int csize)
1471 {
1472   pinfo->temp_readbuf_f = pinfo->temp_codebuf_f = 0;
1473 
1474   if (pinfo->readbuf == NULL) {
1475     pinfo->readbuf_size = rsize;
1476     if (rsize>0) {
1477       pinfo->temp_readbuf_f = 1;
1478       pinfo->readbuf = (uchar *)malloc(rsize);
1479       if (pinfo->readbuf == NULL) {
1480       no_mem:
1481         dviprt_printmessage(pinfo->fname,-1);
1482         dviprt_printmessage("Memory exhausted.\n",-1);
1483         return CFG_ERROR_MEMORY;
1484       }
1485     }
1486   }
1487   if (pinfo->codebuf == NULL) {
1488     pinfo->codebuf_size = csize;
1489     if (csize>0) {
1490       pinfo->temp_codebuf_f = 1;
1491       pinfo->codebuf = (uchar *)malloc(csize);
1492       if (pinfo->codebuf == NULL) goto no_mem;
1493     }
1494   }
1495   return 0;
1496 }
1497 
1498 static int
dviprt_resetcfgbuffer_(dviprt_cfg_i * pinfo)1499 dviprt_resetcfgbuffer_(dviprt_cfg_i *pinfo)
1500 {
1501   if (pinfo->temp_readbuf_f) free(pinfo->readbuf);
1502   if (pinfo->temp_codebuf_f) free(pinfo->codebuf);
1503   pinfo->temp_codebuf_f = pinfo->temp_readbuf_f = 0;
1504   return 0;
1505 }
1506 
1507 char dviprt_message_buffer[128];
1508 
1509 static int
dviprt_printmessage(char * str,int len)1510 dviprt_printmessage(char *str,int len)
1511 {
1512   if (dviprt_messagestream && str) {
1513     if (len >= 0) fwrite(str,len,1,dviprt_messagestream);
1514     else fputs(str,dviprt_messagestream);
1515     fflush(dviprt_messagestream);
1516   }
1517   return 0;
1518 }
1519 
1520 static int
dviprt_printcfgerrorheader(dviprt_cfg_i * pinfo)1521 dviprt_printcfgerrorheader(dviprt_cfg_i *pinfo)
1522 {
1523   if (pinfo) {
1524     char *fn = pinfo->fname;
1525     if (fn == NULL) fn = "-";
1526     dviprt_printmessage(fn,-1);
1527     dviprt_printmessage(": ",-1);
1528     if (pinfo->line_no>0) {
1529       sprintf(dviprt_message_buffer,"%d: ",pinfo->line_no);
1530       dviprt_printmessage(dviprt_message_buffer,-1);
1531     }
1532   }
1533   return 0;
1534 }
1535 
1536 static int
dviprt_printerror(char * msg,int len)1537 dviprt_printerror(char *msg,int len)
1538 {
1539   dviprt_printmessage("*ERROR* ",-1);
1540   dviprt_printmessage(msg,len);
1541   return 0;
1542 }
1543 
1544 static int
dviprt_printcfgerror(dviprt_cfg_i * pinfo,char * msg,int len)1545 dviprt_printcfgerror(dviprt_cfg_i *pinfo,char *msg,int len)
1546 {
1547   dviprt_printcfgerrorheader(pinfo);
1548   dviprt_printerror(msg,len);
1549   return 0;
1550 }
1551 
1552 static int
dviprt_printwarning(char * msg,int len)1553 dviprt_printwarning(char *msg,int len)
1554 {
1555   dviprt_printmessage("*WARNING* ",-1);
1556   dviprt_printmessage(msg,len);
1557   return 0;
1558 }
1559 
1560 static int
dviprt_printcfgwarning(dviprt_cfg_i * pinfo,char * msg,int len)1561 dviprt_printcfgwarning(dviprt_cfg_i *pinfo,char *msg,int len)
1562 {
1563   dviprt_printcfgerrorheader(pinfo);
1564   dviprt_printwarning(msg,len);
1565   return 0;
1566 }
1567 /***** End of util.c *****/
1568 
1569 
1570 /***** From print.c *****/
1571 /* $Id: PRINT.C 1.1 1994/08/30 02:27:02 kaz Exp kaz $ */
1572 
1573 
1574 /*--- forward declarations ---*/
1575 static int dviprt_getmaximalwidth(dviprt_print *);
1576 static int dviprt_flush_buffer(dviprt_print *,uchar far *);
1577 static int dviprt_output_transpose(dviprt_print *,uchar far *,uint);
1578 static int dviprt_output_nontranspose(dviprt_print *,uchar far *,uint);
1579 static int dviprt_output_nontranspose_reverse(dviprt_print *,uchar far *,uint);
1580 static int dviprt_reverse_bits(uchar far *,uint);
1581 static int dviprt_transpose8x8(uchar far *,uint, uchar far *,uint);
1582 static int dviprt_output_expr(dviprt_print *,int,uint,uint);
1583 static int dviprt_default_outputproc(uchar far *,long ,void *);
1584 static long dviprt_getbuffersize(dviprt_print *);
1585 
1586 /*--- library functions ---*/
1587 long
dviprt_initlibrary(dviprt_print * pprint,dviprt_cfg_t * pprt,uint width,uint height)1588 dviprt_initlibrary(dviprt_print *pprint,dviprt_cfg_t *pprt,uint width,uint height)
1589 {
1590   dviprt_encoder *pencode;
1591   uint pins = pprt->integer[CFG_PINS]*8;
1592 
1593   pprint->printer = pprt;
1594   height += (pins-1);
1595   height /= pins;
1596   height *= pins;
1597   pprint->bitmap_width = width; /* width by bytes */
1598   pprint->bitmap_height = height;
1599   pprint->buffer_width = MIN(width,pprt->integer[CFG_MAXIMAL_UNIT]);
1600   pprint->page_count = 0;
1601   pprint->output_bytes = 0;
1602   pprint->tempbuffer_f = 0;
1603   pencode = dviprt_getencoder_((int)pprt->integer[CFG_ENCODE]);
1604   if (pencode == NULL) return CFG_ERROR_NOT_SUPPORTED;
1605   pprint->encode_getbuffersize_proc = pencode->getworksize;
1606   pprint->encode_encode_proc = pencode->encode;
1607 
1608   pprint->output_bytes = 0;
1609   pprint->pstream = NULL;
1610   pprint->output_proc = NULL;
1611 
1612   if (pprt->integer[CFG_UPPER_POS] & CFG_NON_TRANSPOSE_BIT) {
1613     pprint->output_maximal_unit =
1614       (pprt->integer[CFG_UPPER_POS] & CFG_REVERSE_BIT) ?
1615 	dviprt_output_nontranspose_reverse : dviprt_output_nontranspose;
1616   }
1617   else
1618     pprint->output_maximal_unit = dviprt_output_transpose;
1619   return dviprt_getbuffersize(pprint);
1620 }
1621 
1622 int
dviprt_setstream(dviprt_print * pprint,int (* func)(uchar far *,long,void *),void * pstream)1623   dviprt_setstream
1624 #ifdef __PROTOTYPES__
1625   (dviprt_print *pprint,int (*func)(uchar far *,long ,void*),void *pstream)
1626 #else
1627 (pprint,func,pstream)
1628 dviprt_print *pprint;
1629 int (*func)();
1630 void *pstream;
1631 #endif
1632 {
1633   if (pprint->page_count) {
1634     int code = dviprt_output_expr(pprint,CFG_FORM_FEED,0,0);
1635     if (code < 0) return code;
1636     pprint->page_count = 0;
1637   }
1638   pprint->output_bytes = 0;
1639   pprint->pstream = pstream;
1640   pprint->output_proc = (func == NULL) ? dviprt_default_outputproc : func;
1641   return 0;
1642 }
1643 
1644 int
dviprt_setbuffer(dviprt_print * pprint,uchar far * buf)1645 dviprt_setbuffer(dviprt_print *pprint,uchar far *buf)
1646 {
1647   if (pprint->tempbuffer_f) {
1648     BufferFree(pprint->encode_buffer);
1649   }
1650   pprint->tempbuffer_f = 0;
1651   if (buf == NULL) {
1652     long s = dviprt_getbuffersize(pprint);
1653     if (s) {
1654       buf = (uchar far *)BufferAlloc(s);
1655       if (buf == NULL) return CFG_ERROR_MEMORY;
1656       pprint->tempbuffer_f = 1;
1657     }
1658   }
1659   pprint->encode_buffer = buf;
1660   pprint->source_buffer =
1661     buf + pprint->encode_getbuffersize_proc(pprint,dviprt_getmaximalwidth(pprint));
1662   return 0;
1663 }
1664 
1665 int
dviprt_beginpage(dviprt_print * pprint)1666 dviprt_beginpage(dviprt_print *pprint)
1667 {
1668   int code;
1669   pprint->device_x = pprint->device_y = 0;
1670   pprint->bitmap_x = pprint->bitmap_y = 0;
1671   if (pprint->page_count == 0) { /* bit_image_mode */
1672     code = dviprt_output_expr(pprint,CFG_BIT_IMAGE_MODE,0,0);
1673   }
1674   else { /* form_feed */
1675     code = dviprt_output_expr(pprint,CFG_FORM_FEED,0,0);
1676   }
1677   pprint->page_count++;
1678   if (code < 0) return code;
1679   return 0;
1680 }
1681 
1682 int
dviprt_outputscanlines(dviprt_print * pprint,uchar far * fb)1683 dviprt_outputscanlines(dviprt_print *pprint,uchar far *fb)
1684 {
1685   dviprt_cfg_t *pprt;
1686   int code;
1687   uint bw;
1688 
1689   pprt = pprint->printer;
1690   bw = pprint->bitmap_width;
1691 
1692   if (pprt->prtcode_size[CFG_SKIP_SPACES] <= 0) {
1693     pprint->bitmap_x = bw;
1694     pprint->last_x = 0;
1695   }
1696   else {
1697     uint uw,rw;
1698     uint mu;
1699     uint bx,lx;
1700     uint pins = dviprt_getscanlines(pprint);
1701     mu = pprt->integer[CFG_MINIMAL_UNIT];
1702     bx = lx = 0;
1703 
1704     for (rw= bw; rw > 0 ;rw -= uw) {
1705       uint x,y;
1706       uchar far *in;
1707 
1708       uw = MIN(mu,rw);
1709       in = fb + bx;
1710       for (x = uw; x>0 ; x--) {
1711         uchar far *test;
1712         test = in;
1713         for (y = pins ; y > 0 ;y--) {
1714           if (*test) goto next_unit;
1715           test += bw;
1716         }
1717         in++;
1718       }
1719 
1720       if (bx > lx) {
1721         pprint->bitmap_x = bx;
1722         pprint->last_x = lx;
1723         code = dviprt_flush_buffer(pprint,fb); /* output buffered unit */
1724         if (code < 0) return code;
1725         lx = pprint->last_x + uw;
1726       }
1727       else lx += uw;
1728 
1729     next_unit:
1730       bx += uw;
1731     }
1732     pprint->bitmap_x = bx;
1733     pprint->last_x = lx;
1734   }
1735   code = (pprint->last_x < pprint->bitmap_x) ? dviprt_flush_buffer(pprint,fb) : 0;
1736   pprint->bitmap_y++;
1737   return code;
1738 }
1739 
1740 int
dviprt_endbitmap(dviprt_print * pprint)1741 dviprt_endbitmap(dviprt_print *pprint)
1742 {
1743   if (pprint->page_count) {
1744     int code = dviprt_output_expr(pprint,CFG_NORMAL_MODE,0,0);
1745     if (code < 0) return code;
1746   }
1747   return 0;
1748 }
1749 
1750 int
dviprt_unsetbuffer(dviprt_print * pprint)1751 dviprt_unsetbuffer(dviprt_print *pprint)
1752 {
1753   if (pprint->tempbuffer_f) {
1754     BufferFree(pprint->encode_buffer);
1755     pprint->tempbuffer_f = 0;
1756   }
1757   return 0;
1758 }
1759 
1760 int
dviprt_output(dviprt_print * pprint,uchar far * buf,long s)1761 dviprt_output(dviprt_print *pprint,uchar far *buf,long s)
1762 {
1763   int c = pprint->output_proc(buf,s,pprint->pstream);
1764   pprint->output_bytes += s;
1765   return c;
1766 }
1767 
1768 /*--- internal routines ---*/
1769 static int
dviprt_getmaximalwidth(dviprt_print * pprint)1770 dviprt_getmaximalwidth(dviprt_print *pprint)
1771 {
1772   return MIN(pprint->printer->integer[CFG_MAXIMAL_UNIT],pprint->bitmap_width);
1773 }
1774 
1775 static long
dviprt_getbuffersize(dviprt_print * pprint)1776 dviprt_getbuffersize(dviprt_print *pprint)
1777 {
1778   long w = dviprt_getmaximalwidth(pprint);
1779   long e = pprint->encode_getbuffersize_proc(pprint,w);
1780   switch (pprint->printer->integer[CFG_UPPER_POS]
1781 	  & (CFG_NON_TRANSPOSE_BIT | CFG_REVERSE_BIT)) {
1782   case CFG_LEFT_IS_HIGH:
1783     return e;
1784   default:
1785     return w * dviprt_getscanlines(pprint) + e;
1786   }
1787 }
1788 
1789 static int
dviprt_flush_buffer(dviprt_print * pprint,uchar far * fb)1790 dviprt_flush_buffer(dviprt_print *pprint,uchar far *fb)
1791 {
1792   dviprt_cfg_t *pprt;
1793   int code;
1794 
1795   pprt = pprint->printer;
1796   while (pprint->device_y < pprint->bitmap_y) { /* skip vertical spaces */
1797     pprint->device_y++;
1798     code = dviprt_output_expr(pprint,CFG_LINE_FEED,0,0);
1799     pprint->device_x = 0;
1800   }
1801   while (pprint->last_x < pprint->bitmap_x) {
1802     int w;
1803     while (pprint->device_x < pprint->last_x) { /* skip horizontal spaces */
1804       w = MIN(pprt->integer[CFG_MAXIMAL_UNIT],
1805 	      pprint->last_x - pprint->device_x);
1806       code = dviprt_output_expr(pprint,CFG_SKIP_SPACES,w,0);
1807       pprint->device_x += w;
1808     }
1809     w = MIN(pprt->integer[CFG_MAXIMAL_UNIT],pprint->bitmap_x-pprint->last_x);
1810     code = pprint->output_maximal_unit(pprint,fb+pprint->last_x,w);
1811     if (code < 0) return code;
1812     pprint->last_x += w;
1813     if (!(pprt->integer[CFG_UPPER_POS] & CFG_NON_MOVING))
1814       pprint->device_x += w;
1815   }
1816   return 0;
1817 }
1818 
1819 static int
dviprt_output_nontranspose(dviprt_print * pprint,uchar far * fb,uint width)1820 dviprt_output_nontranspose(dviprt_print *pprint,uchar far *fb,uint width)
1821 {
1822   int code;
1823   uint dsize;
1824   uint y;
1825   uint pins;
1826 
1827   pins = dviprt_getscanlines(pprint);
1828 
1829   dsize = 0;
1830   pprint->psource = fb;
1831   for (y = pins ; y>0 ; y--) {
1832     int dsize_line;
1833     dsize_line = pprint->encode_encode_proc(pprint,(long)width,0);
1834     if (dsize_line < 0) return dsize_line;
1835     dsize += dsize_line;
1836     pprint->psource += pprint->bitmap_width;
1837   }
1838 
1839   code = dviprt_output_expr(pprint,CFG_SEND_BIT_IMAGE,width,dsize);
1840   if (code < 0) return code;
1841 
1842   pprint->psource = fb;
1843   for (y = pins ; y>0 ; y--) {
1844     int dsize_line;
1845     dsize_line = pprint->encode_encode_proc(pprint,(long)width,1);
1846     code = dviprt_output_expr(pprint,CFG_BIT_ROW_HEADER,width,dsize_line);
1847     if (code < 0) return code;
1848     code = dviprt_output(pprint,pprint->poutput,dsize_line);
1849     if (code < 0) return code;
1850     pprint->psource += pprint->bitmap_width;
1851   }
1852 
1853   code = dviprt_output_expr(pprint,CFG_AFTER_BIT_IMAGE,width,dsize);
1854   if (code < 0) return code;
1855 
1856   return 0;
1857 }
1858 
1859 
1860 static int
dviprt_output_nontranspose_reverse(dviprt_print * pprint,uchar far * fb,uint width)1861 dviprt_output_nontranspose_reverse(dviprt_print *pprint,uchar far *fb,uint width)
1862 {
1863   uchar far *psrc;
1864   uchar far *pbuf;
1865   int code;
1866   uint src_size;
1867   uint dsize;
1868   uint y;
1869   uint pins;
1870 
1871   pins = dviprt_getscanlines(pprint);
1872   src_size = width * pins;
1873 
1874   psrc = pprint->source_buffer;
1875   for (y = pins ; y > 0; y--) {
1876     uint i;
1877     pbuf = fb;
1878     for (i=width;i>0;i--) *psrc++ = *pbuf++;
1879     fb += pprint->bitmap_width;
1880   }
1881 
1882   /* here, reverse bits */
1883   psrc = pprint->source_buffer;
1884   dviprt_reverse_bits(psrc,src_size);
1885 
1886 
1887   dsize = 0;
1888   pprint->psource = pprint->source_buffer;
1889   for (y = pins ; y>0 ; y--) {
1890     int dsize_line;
1891     dsize_line = pprint->encode_encode_proc(pprint,(long)width,0);
1892     if (dsize_line < 0) return dsize_line;
1893     dsize += dsize_line;
1894     pprint->psource += width;
1895   }
1896 
1897   code = dviprt_output_expr(pprint,CFG_SEND_BIT_IMAGE,width,dsize);
1898   if (code < 0) return code;
1899 
1900   pprint->psource = pprint->source_buffer;
1901   for (y = pins ; y>0 ; y--) {
1902     int dsize_line;
1903     dsize_line = pprint->encode_encode_proc(pprint,(long)width,1);
1904     code = dviprt_output_expr(pprint,CFG_BIT_ROW_HEADER,width,dsize_line);
1905     if (code < 0) return code;
1906     code = dviprt_output(pprint,pprint->poutput,dsize_line);
1907     if (code < 0) return code;
1908     pprint->psource += width;
1909   }
1910 
1911   code = dviprt_output_expr(pprint,CFG_AFTER_BIT_IMAGE,width,dsize);
1912   if (code < 0) return code;
1913 
1914   return 0;
1915 }
1916 
1917 static int
dviprt_output_transpose(dviprt_print * pprint,uchar far * fb,uint width)1918 dviprt_output_transpose(dviprt_print *pprint,uchar far *fb,uint width)
1919 {
1920   uchar far *psrc;
1921   uchar far *pbuf;
1922   int code;
1923   uint src_size;
1924   uint dsize;
1925   uint pins,pins8;
1926   int y;
1927 
1928   pins8 = pprint->printer->integer[CFG_PINS];
1929   pins = pins8 * 8;
1930   src_size = width * pins;
1931   psrc = pprint->source_buffer;
1932   {
1933     uchar far *pdst;
1934     uint sskip;
1935     sskip = pprint->bitmap_width * 8;
1936     for (y = pins8-1; y >= 0 ; y--) {
1937       uint i;
1938       pbuf = fb;
1939       pdst = psrc;
1940       for (i=width;i>0;i--) {
1941         dviprt_transpose8x8(pbuf,pprint->bitmap_width,pdst,pins8);
1942         pbuf ++;
1943         pdst += pins;
1944       }
1945       fb += sskip;
1946       psrc++;
1947     }
1948   }
1949 
1950   psrc = pprint->source_buffer;
1951 
1952   /* here, reverse bits */
1953   if (pprint->printer->integer[CFG_UPPER_POS] & CFG_REVERSE_BIT)
1954     dviprt_reverse_bits(psrc,src_size);
1955 
1956   dsize = 0;
1957   pprint->psource = pprint->source_buffer;
1958   for (y = pins ; y>0 ; y--) {
1959     int dsize_line;
1960     dsize_line = pprint->encode_encode_proc(pprint,(long)width,0);
1961     if (dsize_line < 0) return dsize_line;
1962     dsize += dsize_line;
1963     pprint->psource += width;
1964   }
1965 
1966   code = dviprt_output_expr(pprint,CFG_SEND_BIT_IMAGE,width,dsize);
1967   if (code < 0) return code;
1968 
1969   pprint->psource = pprint->source_buffer;
1970   for (y = pins ; y>0 ; y--) {
1971     uint dsize_line;
1972     dsize_line = pprint->encode_encode_proc(pprint,(long)width,1);
1973     code = dviprt_output(pprint,pprint->poutput,dsize_line);
1974     if (code < 0) return code;
1975     pprint->psource += width;
1976   }
1977 
1978   code = dviprt_output_expr(pprint,CFG_AFTER_BIT_IMAGE,width,dsize);
1979   if (code < 0) return code;
1980 
1981   return 0;
1982 }
1983 
1984 static int
dviprt_transpose8x8(uchar far * inp,uint line_size,uchar far * outp,uint dist)1985 dviprt_transpose8x8(uchar far *inp,uint line_size,uchar far *outp,uint dist)
1986 {
1987   register uint ae, bf, cg, dh;
1988   {
1989     uchar far *ptr4 = inp + (line_size << 2);
1990     ae = ((uint)*inp << 8) + *ptr4;
1991     inp += line_size, ptr4 += line_size;
1992     bf = ((uint)*inp << 8) + *ptr4;
1993     inp += line_size, ptr4 += line_size;
1994     cg = ((uint)*inp << 8) + *ptr4;
1995     inp += line_size, ptr4 += line_size;
1996     dh = ((uint)*inp << 8) + *ptr4;
1997   }
1998   /* Check for all 8 bytes being the same. */
1999   /* This is especially worth doing for the case where all are zero. */
2000   if ( ae == bf && ae == cg && ae == dh && (ae >> 8) == (ae & 0xff) ) {
2001     if ( ae == 0 ) goto store;
2002     *outp = -((ae >> 7) & 1);
2003     outp += dist;
2004     *outp = -((ae >> 6) & 1);
2005     outp += dist;
2006     *outp = -((ae >> 5) & 1);
2007     outp += dist;
2008     *outp = -((ae >> 4) & 1);
2009     outp += dist;
2010     *outp = -((ae >> 3) & 1);
2011     outp += dist;
2012     *outp = -((ae >> 2) & 1);
2013     outp += dist;
2014     *outp = -((ae >> 1) & 1);
2015     outp += dist;
2016     *outp = -(ae & 1);
2017   }
2018   else {
2019     register uint temp;
2020 
2021     /* Transpose a block of bits between registers. */
2022 #define transpose(r,s,mask,shift)\
2023     r ^= (temp = ((s >> shift) ^ r) & mask);\
2024       s ^= temp << shift
2025 
2026 	/* Transpose blocks of 4 x 4 */
2027 #define transpose4(r) transpose(r,r,0x00f0,4)
2028 	transpose4(ae);
2029     transpose4(bf);
2030     transpose4(cg);
2031     transpose4(dh);
2032 
2033     /* Transpose blocks of 2 x 2 */
2034     transpose(ae, cg, 0x3333, 2);
2035     transpose(bf, dh, 0x3333, 2);
2036 
2037     /* Transpose blocks of 1 x 1 */
2038     transpose(ae, bf, 0x5555, 1);
2039     transpose(cg, dh, 0x5555, 1);
2040 
2041   store:	*outp = ae >> 8;
2042     outp += dist;
2043     *outp = bf >> 8;
2044     outp += dist;
2045     *outp = cg >> 8;
2046     outp += dist;
2047     *outp = dh >> 8;
2048     outp += dist;
2049     *outp = (uchar)ae;
2050     outp += dist;
2051     *outp = (uchar)bf;
2052     outp += dist;
2053     *outp = (uchar)cg;
2054     outp += dist;
2055     *outp = (uchar)dh;
2056   }
2057   return 0;
2058 }
2059 
2060 static int
dviprt_reverse_bits(uchar far * buf,uint s)2061 dviprt_reverse_bits(uchar far *buf,uint s)
2062 {
2063   static uchar rev[256] = {
2064     0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
2065     0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
2066     0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
2067     0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
2068     0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
2069     0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
2070     0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
2071     0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
2072     0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
2073     0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
2074     0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
2075     0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
2076     0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
2077     0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
2078     0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
2079     0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
2080     0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
2081     0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
2082     0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
2083     0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
2084     0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
2085     0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
2086     0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
2087     0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
2088     0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
2089     0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
2090     0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
2091     0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
2092     0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
2093     0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
2094     0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
2095     0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
2096   };
2097   while (s-- > 0) {
2098     *buf = rev[*buf];
2099     buf++;
2100   }
2101   return 0;
2102 }
2103 
2104 
2105 static int
dviprt_output_expr(dviprt_print * pprint,int numb,uint width,uint dsize)2106 dviprt_output_expr(dviprt_print *pprint,int numb,uint width,uint dsize)
2107 {
2108   uchar *pcode;
2109   dviprt_cfg_t *pprt;
2110   uint v;
2111   uint len;
2112 
2113   pprt = pprint->printer;
2114   if (pprt->prtcode[numb] == NULL) return 0;
2115   pcode = pprt->prtcode[numb];
2116   len = pprt->prtcode_size[numb];
2117 
2118   while (*pcode && len>0) {
2119     if (*pcode & CFG_FMT_BIT) {
2120       uint stack[CFG_STACK_DEPTH];
2121       int stack_p = -1;
2122       uchar fmt = *pcode++;
2123       uint l = *pcode++;
2124       len -=2;
2125       while (l>0) {
2126         if ((*pcode & CFG_EXPR_TYPE_BIT) == CFG_OP) {
2127           uint v2 = stack[stack_p--];
2128           v = stack[stack_p--];
2129           switch (*pcode) {
2130           case CFG_OP_ADD: v += v2; break;
2131           case CFG_OP_SUB: v -= v2; break;
2132           case CFG_OP_MUL: v *= v2; break;
2133           case CFG_OP_DIV:
2134             if (v2 == 0) { /* divided by zero. */
2135             div_by_zero:
2136               return CFG_ERROR_DIV0;
2137             }
2138             v /= v2;
2139             break;
2140           case CFG_OP_MOD:
2141             if (v2 == 0) goto div_by_zero;
2142             v %= v2;
2143             break;
2144           case CFG_OP_SHL: v <<= v2; break;
2145           case CFG_OP_SHR: v >>= v2; break;
2146           case CFG_OP_AND: v &= v2; break;
2147           case CFG_OP_OR : v |= v2; break;
2148           case CFG_OP_XOR: v ^= v2; break;
2149           default:
2150             ;
2151           }
2152           stack[++stack_p] = v;
2153         }
2154         else if ((*pcode & CFG_EXPR_TYPE_BIT) == CFG_VAL) {
2155           {
2156             switch (*pcode) {
2157             case CFG_VAL_DEFAULT: v = width*8; break;
2158             case CFG_VAL_CONSTANT: v = pprt->integer[CFG_CONSTANT]; break;
2159             case CFG_VAL_WIDTH: v = pprint->bitmap_width*8; break;
2160             case CFG_VAL_HEIGHT: v = pprint->bitmap_height; break;
2161             case CFG_VAL_PAGE:
2162             case CFG_VAL_PAGECOUNT: v = pprint->page_count; break;
2163             case CFG_VAL_DATASIZE: v = dsize; break;
2164             case CFG_VAL_X_DPI: v = (int)pprt->integer[CFG_DPI]; break;
2165             case CFG_VAL_Y_DPI:
2166               v = pprt->integer[CFG_Y_DPI] > 0 ?
2167 		pprt->integer[CFG_Y_DPI] : pprt->integer[CFG_DPI];
2168               break;
2169             case CFG_VAL_PINS_BYTE: v = pprt->integer[CFG_PINS]; break;
2170             case CFG_VAL_X_POS: v = pprint->device_x*8; break;
2171             case CFG_VAL_Y_POS:
2172               v = pprint->device_y * dviprt_getscanlines(pprint);
2173               break;
2174             }
2175           }
2176           stack[++stack_p] = v;
2177         }
2178         else {
2179           stack[++stack_p] = *pcode;
2180         }
2181         l--; pcode++; len--;
2182       }
2183       v = stack[stack_p];
2184       if ((fmt & CFG_FMT_FORMAT_BIT) == CFG_FMT_STRINGS) {
2185         uint l = *pcode++;
2186         len--;
2187         while (v-- > 0)
2188           dviprt_output(pprint,(uchar far *)pcode,l);
2189         pcode += l;
2190         len -= l;
2191       }
2192       else if ((fmt & CFG_FMT_FORMAT_BIT) == CFG_FMT_ASSIGNMENT) {
2193         pprint->uservar[fmt&0x0f] = v;
2194       }
2195       else { uchar valbuf[10];
2196 	     int cols = fmt & CFG_FMT_COLUMN_BIT;
2197 	     int i;
2198 
2199 	     switch (fmt & CFG_FMT_FORMAT_BIT) {
2200 	     case CFG_FMT_BIN_LTOH:
2201 	       for (i=0;i<cols;i++) {
2202 		 valbuf[i] = v&0xff;
2203 		 v >>= 8;
2204 	       }
2205 	       break;
2206 	     case CFG_FMT_BIN_HTOL:
2207 	       for (i=cols-1;i>=0;i--) {
2208 		 valbuf[i] = v&0xff;
2209 		 v >>= 8;
2210 	       }
2211 	       break;
2212 	     default:
2213 	       { char *f;
2214 		 char fmtbuf[10];
2215 		 switch(fmt & CFG_FMT_FORMAT_BIT) {
2216 		 case CFG_FMT_HEX_UPPER: f = "X"; break;
2217 		 case CFG_FMT_HEX_LOWER: f = "x"; break;
2218 		 case CFG_FMT_DECIMAL: f = "u"; break;
2219 		 case CFG_FMT_OCTAL: f = "o"; break;
2220 		 }
2221 		 if (cols == 0)
2222 		   strcpy(fmtbuf,"%");
2223 		 else
2224 		   sprintf(fmtbuf,"%%0%d",cols);
2225 		 strcat(fmtbuf,f);
2226 		 sprintf(valbuf,fmtbuf,stack[stack_p]);
2227 		 cols = strlen(valbuf);
2228 		 if (fmt & CFG_FMT_ISO_BIT)
2229 		   valbuf[cols-1] |= 0x10;
2230 	       }
2231 	       break;
2232 	     }
2233 	     dviprt_output(pprint,(uchar far *)valbuf, cols);
2234 	   }
2235     }
2236     else {
2237       uint l = *pcode++;
2238       len--;
2239       dviprt_output(pprint,(uchar far *)pcode,l);
2240       pcode += l;
2241       len -= l;
2242     }
2243   }
2244   return 0;
2245 }
2246 
2247 static int
dviprt_default_outputproc(uchar far * buf,long s,void * fp)2248 dviprt_default_outputproc(uchar far *buf,long s,void *fp)
2249 {
2250 #ifdef __MSDOS_REAL__
2251   while (s-- > 0) {
2252     if (fputc(*buf++,fp) == EOF)
2253       return CFG_ERROR_OUTPUT;
2254   }
2255   return 0;
2256 #else
2257   return fwrite(buf,s,1,fp) == 1 ? 0 : CFG_ERROR_OUTPUT;
2258 #endif
2259 }
2260 /***** End of print.c *****/
2261 
2262 
2263 /***** From encode.c *****/
2264 /* $Id: ENCODE.C 1.1 1994/08/30 02:27:02 kaz Exp kaz $ */
2265 
2266 
2267 #define DVIPRT_SUPPORT_FAX 1
2268 #define DVIPRT_SUPPORT_PCL 1
2269 
2270 /*--- forward declarations ---*/
2271 static long dviprt_null_getworksize(dviprt_print *,long );
2272 static long dviprt_null_encode(dviprt_print *,long ,int );
2273 static long dviprt_hex_getworksize(dviprt_print *,long );
2274 static long dviprt_hex_encode(dviprt_print *,long ,int );
2275 #if DVIPRT_SUPPORT_FAX
2276 static long dviprt_fax_getworksize(dviprt_print *,long );
2277 static long dviprt_fax_encode(dviprt_print *,long ,int );
2278 #endif
2279 #if DVIPRT_SUPPORT_PCL
2280 static long dviprt_pcl1_getworksize(dviprt_print *,long );
2281 static long dviprt_pcl1_encode(dviprt_print *,long ,int );
2282 static long dviprt_pcl2_getworksize(dviprt_print *,long );
2283 static long dviprt_pcl2_encode(dviprt_print *,long ,int );
2284 #endif
2285 
2286 static dviprt_encoder dviprt_encoder_list[] = {
2287   { CFG_ENCODE_NULL, dviprt_null_getworksize,dviprt_null_encode},
2288   { CFG_ENCODE_HEX, dviprt_hex_getworksize,dviprt_hex_encode},
2289 #if DVIPRT_SUPPORT_FAX
2290   { CFG_ENCODE_FAX, dviprt_fax_getworksize,dviprt_fax_encode},
2291 #endif
2292 #if DVIPRT_SUPPORT_PCL
2293   { CFG_ENCODE_PCL1, dviprt_pcl1_getworksize,dviprt_pcl1_encode},
2294   { CFG_ENCODE_PCL2, dviprt_pcl2_getworksize,dviprt_pcl2_encode},
2295 #endif
2296   { -1 },
2297 };
2298 
2299 /*--- internal routines ---*/
2300 /* The users MUST NOT USE these functions */
2301 static dviprt_encoder *
dviprt_getencoder_(int no)2302 dviprt_getencoder_(int no)
2303 {
2304   int i;
2305   for (i=0;dviprt_encoder_list[i].no >= 0;i++)
2306     if (no == dviprt_encoder_list[i].no)
2307       return dviprt_encoder_list+i;
2308   return NULL;
2309 }
2310 
2311 static long
dviprt_null_getworksize(dviprt_print * pprint,long s)2312 dviprt_null_getworksize(dviprt_print *pprint,long s)
2313 {
2314   return 0;
2315 }
2316 static long
dviprt_null_encode(dviprt_print * pprint,long s,int f)2317 dviprt_null_encode(dviprt_print *pprint,long s,int f)
2318 {
2319   pprint->poutput = pprint->psource;
2320   return s;
2321 }
2322 
2323 static long
dviprt_hex_getworksize(dviprt_print * pprint,long s)2324 dviprt_hex_getworksize(dviprt_print *pprint,long s)
2325 {
2326   return s*2;
2327 }
2328 static long
dviprt_hex_encode(dviprt_print * pprint,long s,int f)2329 dviprt_hex_encode(dviprt_print *pprint,long s,int f)
2330 {
2331   if (f) {
2332     uchar far *w;
2333     uchar far *buf;
2334     static uchar hex[] = "0123456789ABCDEF";
2335     int i=s;
2336     w = pprint->poutput = pprint->encode_buffer;
2337     buf = pprint->psource;
2338     while (i-->0) {
2339       *w++ = hex[(*buf>>4)&0x0f];
2340       *w++ = hex[*buf&0x0f];
2341       buf++;
2342     }
2343   }
2344   return s*2;
2345 }
2346 
2347 #if DVIPRT_SUPPORT_PCL
2348 static long
dviprt_pcl1_getworksize(dviprt_print * pprint,long s)2349 dviprt_pcl1_getworksize(dviprt_print *pprint,long s)
2350 {
2351   return s*2;
2352 }
2353 static long
dviprt_pcl1_encode(dviprt_print * pprint,long s,int f)2354 dviprt_pcl1_encode(dviprt_print *pprint,long s,int f)
2355 {
2356   uchar far *src;
2357   uchar far *end;
2358   uchar far *out;
2359   long total = 0;
2360 
2361   src = pprint->psource;
2362   end = src + s;
2363   out = pprint->poutput = pprint->encode_buffer;
2364 
2365   while ( src < end  ) {
2366     uchar test = *src++;
2367     uchar far *run = src;
2368     while ( src < end && *src == test ) src++;
2369     if (f) {
2370       while ( src - run > 255 ) {
2371         *out++ = 255;
2372         *out++ = test;
2373         total += 2;
2374         run += 256;
2375       }
2376       *out++ = src - run;
2377       *out++ = test;
2378       total += 2;
2379     }
2380     else {
2381       total += (((src-run)/255 + ((src-run)%255) ? 1 : 0)) * 2;
2382     }
2383   }
2384   return total;
2385 }
2386 
2387 static long
dviprt_pcl2_getworksize(dviprt_print * pprint,long s)2388 dviprt_pcl2_getworksize(dviprt_print *pprint,long s)
2389 {
2390   return s + s/127 + 1;
2391 }
2392 static long
dviprt_pcl2_encode(dviprt_print * pprint,long s,int f)2393 dviprt_pcl2_encode(dviprt_print *pprint,long s,int f)
2394 {
2395   uchar far *exam;
2396   uchar far *cptr;
2397   uchar far *end;
2398   uchar far *src;
2399   long total = 0;
2400 
2401   src = pprint->psource;
2402   exam = src;
2403   cptr = pprint->poutput = pprint->encode_buffer;
2404   end = exam + s;
2405 
2406   for ( ; ; ) {
2407     uchar test = *exam++;
2408     int len;
2409     while ((test != *exam) && (exam < end))
2410       test = *exam++;
2411     if (exam < end) exam--;
2412     len = exam - src;
2413     if (f) {
2414       while (len > 0){
2415         int i;
2416         int count = len;
2417         if (count>127) count=127;
2418         *cptr++=count-1;
2419         for (i = 0 ; i < count ; i++) *cptr++ = *src++;
2420         len -= count;
2421         total += (count+1);
2422       }
2423     }
2424     else {
2425       total += len + ((len/127)+(len%127 ? 1 : 0));
2426     }
2427     if (exam >= end) break;
2428     exam++;
2429     while ((test == *exam) && (exam < end))
2430       exam++;
2431     len = exam - src;
2432     if (f) {
2433       while (len > 0) {
2434         int count = len;
2435         if (count > 127) count = 127;
2436         *cptr++ = (257-count);
2437         *cptr++ = test;
2438         len -= count;
2439         total += 2;
2440       }
2441     }
2442     else {
2443       total += ((len/127 + (len%127) ? 1 : 0)) * 2;
2444     }
2445     if (exam >= end) break;
2446     src = exam;
2447   }
2448   return total;
2449 }
2450 #endif /* DVIPRT_SUPPORT_PCL */
2451 
2452 #if DVIPRT_SUPPORT_FAX
2453 static long
dviprt_fax_getworksize(dviprt_print * pprint,long s)2454 dviprt_fax_getworksize(dviprt_print *pprint,long s)
2455 {
2456   long size = s * 8 + 7;
2457   return MAX(size*2/9+4,size/8) * dviprt_getscanlines(pprint) + 1;
2458 }
2459 
2460 #define MAX_FAX_WIDTH	2623
2461 typedef struct {
2462   int	data;
2463   int	length;
2464 } FaxEncode_t;
2465 typedef struct {
2466   uchar i_bitbuf;
2467   uchar far *i_buf;
2468   int i_count;
2469 
2470   uchar o_bitbuf;
2471   uchar far *o_buf;
2472   int o_count;
2473   int o_bufcount;
2474 } FaxEncodeInfo;
2475 static int dviprt_fax_set_white(int,FaxEncodeInfo *);
2476 static int dviprt_fax_set_black(int,FaxEncodeInfo *);
2477 static int dviprt_fax_set_bitcount(FaxEncode_t *,FaxEncodeInfo *);
2478 
2479 static long
dviprt_fax_encode(dviprt_print * pprint,long s,int f)2480 dviprt_fax_encode(dviprt_print *pprint,long s,int f)
2481 {
2482   static FaxEncode_t eol_code = {0x800,12};
2483   int allruns = 0;
2484   int width = s * 8;
2485   int top_bit_count = 8;
2486   FaxEncodeInfo info;
2487   uchar far *src_end;
2488   uchar recover;
2489 
2490   src_end = pprint->psource + s;
2491   recover = *src_end;
2492   *src_end = 0xaa;
2493 
2494   /* initializing */
2495   info.i_buf = pprint->psource;
2496   info.i_bitbuf = *info.i_buf++;
2497   info.i_count = 8;
2498   info.o_buf = pprint->poutput = pprint->encode_buffer;
2499   info.o_bitbuf = 0;
2500   info.o_count = 8;
2501   info.o_bufcount = 0;
2502 
2503   dviprt_fax_set_bitcount(&eol_code,&info);
2504 
2505   for(;;){
2506     static uchar ROW[9] =
2507       {0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
2508     static uchar MASK[9] =
2509       {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
2510     int white_run_length;
2511     int black_run_length;
2512 
2513     /* count run-length */
2514     /* remaining bits in the current byte are white? */
2515     if (!(info.i_bitbuf &= MASK[info.i_count])){
2516       do{
2517 	top_bit_count += 8; /* next byte is also white	*/
2518       } while(!(info.i_bitbuf = *info.i_buf++));
2519       info.i_count = 8;
2520     }
2521     /* current byte contains white and black bits 	*/
2522     while(!(info.i_bitbuf & ROW[info.i_count]))
2523       info.i_count--;		/* skip white bits 	*/
2524     white_run_length = top_bit_count - (black_run_length = info.i_count);
2525 
2526     /* remaining bits in the current byte are black?	*/
2527     if (info.i_bitbuf == MASK[info.i_count]){
2528       do{
2529 	black_run_length += 8;
2530 	/* next byte is also black	*/
2531       } while((info.i_bitbuf = *info.i_buf++) == 0xff);
2532       info.i_count = 8;
2533     }
2534     else info.i_count--;	/* skip the top black bit	*/
2535 
2536     /* current byte contains white and black bits 	*/
2537     while(info.i_bitbuf & ROW[info.i_count])
2538       info.i_count--;		/* skip black bits	 		*/
2539     black_run_length -= (top_bit_count = info.i_count);
2540 
2541     /* output */
2542     if((allruns += white_run_length) < width)
2543       dviprt_fax_set_white(white_run_length,&info);
2544     else{
2545       dviprt_fax_set_white(white_run_length + width - allruns,&info);
2546       break;
2547     }
2548     if((allruns += black_run_length) < width)
2549       dviprt_fax_set_black(black_run_length,&info);
2550     else{
2551       dviprt_fax_set_black(black_run_length + width - allruns,&info);
2552       break;
2553     }
2554   }
2555 
2556   info.o_bufcount++;
2557   if (info.o_count < 8)
2558     *info.o_buf++ = info.o_bitbuf;
2559   else
2560     *info.o_buf++ = 0;
2561   *src_end = recover;
2562 
2563   return info.o_bufcount;
2564 }
2565 
2566 static int
dviprt_fax_set_bitcount(FaxEncode_t * pt,FaxEncodeInfo * info)2567 dviprt_fax_set_bitcount(FaxEncode_t *pt,FaxEncodeInfo *info)
2568 {
2569   int	data, length;
2570 
2571   data = pt->data;
2572   length = pt->length;
2573   while( (length -= info->o_count) >= 0 ){
2574     *info->o_buf++ = ((data << (8 - info->o_count))|info->o_bitbuf);
2575     info->o_bitbuf = 0;
2576     info->o_bufcount++;
2577     data >>= info->o_count;
2578     info->o_count = 8;
2579   }
2580   info->o_bitbuf |= (data << (8 - info->o_count));
2581   info->o_count = -length;
2582   return 0;
2583 }
2584 
2585 static int
dviprt_fax_set_white(int count,FaxEncodeInfo * info)2586 dviprt_fax_set_white(int count,FaxEncodeInfo *info)
2587 {
2588   static FaxEncode_t white_count_list[]={
2589     { 0x00AC,      8,	}, /*    0 */
2590     { 0x0038,      6,	}, /*    1 */
2591     { 0x000E,      4,	}, /*    2 */
2592     { 0x0001,      4,	}, /*    3 */
2593     { 0x000D,      4,	}, /*    4 */
2594     { 0x0003,      4,	}, /*    5 */
2595     { 0x0007,      4,	}, /*    6 */
2596     { 0x000F,      4,	}, /*    7 */
2597     { 0x0019,      5,	}, /*    8 */
2598     { 0x0005,      5,	}, /*    9 */
2599     { 0x001C,      5,	}, /*   10 */
2600     { 0x0002,      5,	}, /*   11 */
2601     { 0x0004,      6,	}, /*   12 */
2602     { 0x0030,      6,	}, /*   13 */
2603     { 0x000B,      6,	}, /*   14 */
2604     { 0x002B,      6,	}, /*   15 */
2605     { 0x0015,      6,	}, /*   16 */
2606     { 0x0035,      6,	}, /*   17 */
2607     { 0x0072,      7,	}, /*   18 */
2608     { 0x0018,      7,	}, /*   19 */
2609     { 0x0008,      7,	}, /*   20 */
2610     { 0x0074,      7,	}, /*   21 */
2611     { 0x0060,      7,	}, /*   22 */
2612     { 0x0010,      7,	}, /*   23 */
2613     { 0x000A,      7,	}, /*   24 */
2614     { 0x006A,      7,	}, /*   25 */
2615     { 0x0064,      7,	}, /*   26 */
2616     { 0x0012,      7,	}, /*   27 */
2617     { 0x000C,      7,	}, /*   28 */
2618     { 0x0040,      8,	}, /*   29 */
2619     { 0x00C0,      8,	}, /*   30 */
2620     { 0x0058,      8,	}, /*   31 */
2621     { 0x00D8,      8,	}, /*   32 */
2622     { 0x0048,      8,	}, /*   33 */
2623     { 0x00C8,      8,	}, /*   34 */
2624     { 0x0028,      8,	}, /*   35 */
2625     { 0x00A8,      8,	}, /*   36 */
2626     { 0x0068,      8,	}, /*   37 */
2627     { 0x00E8,      8,	}, /*   38 */
2628     { 0x0014,      8,	}, /*   39 */
2629     { 0x0094,      8,	}, /*   40 */
2630     { 0x0054,      8,	}, /*   41 */
2631     { 0x00D4,      8,	}, /*   42 */
2632     { 0x0034,      8,	}, /*   43 */
2633     { 0x00B4,      8,	}, /*   44 */
2634     { 0x0020,      8,	}, /*   45 */
2635     { 0x00A0,      8,	}, /*   46 */
2636     { 0x0050,      8,	}, /*   47 */
2637     { 0x00D0,      8,	}, /*   48 */
2638     { 0x004A,      8,	}, /*   49 */
2639     { 0x00CA,      8,	}, /*   50 */
2640     { 0x002A,      8,	}, /*   51 */
2641     { 0x00AA,      8,	}, /*   52 */
2642     { 0x0024,      8,	}, /*   53 */
2643     { 0x00A4,      8,	}, /*   54 */
2644     { 0x001A,      8,	}, /*   55 */
2645     { 0x009A,      8,	}, /*   56 */
2646     { 0x005A,      8,	}, /*   57 */
2647     { 0x00DA,      8,	}, /*   58 */
2648     { 0x0052,      8,	}, /*   59 */
2649     { 0x00D2,      8,	}, /*   60 */
2650     { 0x004C,      8,	}, /*   61 */
2651     { 0x00CC,      8,	}, /*   62 */
2652     { 0x002C,      8,	}, /*   63 */
2653 
2654     { 0x001B,      5,	}, /*   64 */
2655     { 0x0009,      5,	}, /*  128 */
2656     { 0x003A,      6,	}, /*  192 */
2657     { 0x0076,      7,	}, /*  256 */
2658     { 0x006C,      8,	}, /*  320 */
2659     { 0x00EC,      8,	}, /*  384 */
2660     { 0x0026,      8,	}, /*  448 */
2661     { 0x00A6,      8,	}, /*  512 */
2662     { 0x0016,      8,	}, /*  576 */
2663     { 0x00E6,      8,	}, /*  640 */
2664     { 0x0066,      9,	}, /*  704 */
2665     { 0x0166,      9,	}, /*  768 */
2666     { 0x0096,      9,	}, /*  832 */
2667     { 0x0196,      9,	}, /*  896 */
2668     { 0x0056,      9,	}, /*  960 */
2669     { 0x0156,      9,	}, /* 1024 */
2670     { 0x00D6,      9,	}, /* 1088 */
2671     { 0x01D6,      9,	}, /* 1152 */
2672     { 0x0036,      9,	}, /* 1216 */
2673     { 0x0136,      9,	}, /* 1280 */
2674     { 0x00B6,      9,	}, /* 1344 */
2675     { 0x01B6,      9,	}, /* 1408 */
2676     { 0x0032,      9,	}, /* 1472 */
2677     { 0x0132,      9,	}, /* 1536 */
2678     { 0x00B2,      9,	}, /* 1600 */
2679     { 0x0006,      6,	}, /* 1664 */
2680     { 0x01B2,      9,	}, /* 1728 */
2681 
2682     { 0x0080,     11,	}, /* 1792 */
2683     { 0x0180,     11,	}, /* 1856 */
2684     { 0x0580,     11,	}, /* 1920 */
2685     { 0x0480,     12,	}, /* 1984 */
2686     { 0x0C80,     12,	}, /* 2048 */
2687     { 0x0280,     12,	}, /* 2112 */
2688     { 0x0A80,     12,	}, /* 2176 */
2689     { 0x0680,     12,	}, /* 2240 */
2690     { 0x0E80,     12,	}, /* 2304 */
2691     { 0x0380,     12,	}, /* 2368 */
2692     { 0x0B80,     12,	}, /* 2432 */
2693     { 0x0780,     12,	}, /* 2496 */
2694     { 0x0F80,     12,	}, /* 2560 */
2695   };
2696   while (count >= 64){
2697     if(count <= MAX_FAX_WIDTH){
2698       dviprt_fax_set_bitcount((white_count_list + 63) + (count/64),info);
2699       break;
2700     }
2701     dviprt_fax_set_white(MAX_FAX_WIDTH,info);
2702     dviprt_fax_set_black(0,info);
2703     count -= MAX_FAX_WIDTH;
2704   }
2705   dviprt_fax_set_bitcount(white_count_list + (count & 63) ,info);
2706   return 0;
2707 }
2708 
2709 static int
dviprt_fax_set_black(int count,FaxEncodeInfo * info)2710 dviprt_fax_set_black(int count,FaxEncodeInfo *info)
2711 {
2712   static FaxEncode_t black_count_list[]={
2713     { 0x03B0,     10,	}, /*    0 */
2714     { 0x0002,      3,	}, /*    1 */
2715     { 0x0003,      2,	}, /*    2 */
2716     { 0x0001,      2,	}, /*    3 */
2717     { 0x0006,      3,	}, /*    4 */
2718     { 0x000C,      4,	}, /*    5 */
2719     { 0x0004,      4,	}, /*    6 */
2720     { 0x0018,      5,	}, /*    7 */
2721     { 0x0028,      6,	}, /*    8 */
2722     { 0x0008,      6,	}, /*    9 */
2723     { 0x0010,      7,	}, /*   10 */
2724     { 0x0050,      7,	}, /*   11 */
2725     { 0x0070,      7,	}, /*   12 */
2726     { 0x0020,      8,	}, /*   13 */
2727     { 0x00E0,      8,	}, /*   14 */
2728     { 0x0030,      9,	}, /*   15 */
2729     { 0x03A0,     10,	}, /*   16 */
2730     { 0x0060,     10,	}, /*   17 */
2731     { 0x0040,     10,	}, /*   18 */
2732     { 0x0730,     11,	}, /*   19 */
2733     { 0x00B0,     11,	}, /*   20 */
2734     { 0x01B0,     11,	}, /*   21 */
2735     { 0x0760,     11,	}, /*   22 */
2736     { 0x00A0,     11,	}, /*   23 */
2737     { 0x0740,     11,	}, /*   24 */
2738     { 0x00C0,     11,	}, /*   25 */
2739     { 0x0530,     12,	}, /*   26 */
2740     { 0x0D30,     12,	}, /*   27 */
2741     { 0x0330,     12,	}, /*   28 */
2742     { 0x0B30,     12,	}, /*   29 */
2743     { 0x0160,     12,	}, /*   30 */
2744     { 0x0960,     12,	}, /*   31 */
2745     { 0x0560,     12,	}, /*   32 */
2746     { 0x0D60,     12,	}, /*   33 */
2747     { 0x04B0,     12,	}, /*   34 */
2748     { 0x0CB0,     12,	}, /*   35 */
2749     { 0x02B0,     12,	}, /*   36 */
2750     { 0x0AB0,     12,	}, /*   37 */
2751     { 0x06B0,     12,	}, /*   38 */
2752     { 0x0EB0,     12,	}, /*   39 */
2753     { 0x0360,     12,	}, /*   40 */
2754     { 0x0B60,     12,	}, /*   41 */
2755     { 0x05B0,     12,	}, /*   42 */
2756     { 0x0DB0,     12,	}, /*   43 */
2757     { 0x02A0,     12,	}, /*   44 */
2758     { 0x0AA0,     12,	}, /*   45 */
2759     { 0x06A0,     12,	}, /*   46 */
2760     { 0x0EA0,     12,	}, /*   47 */
2761     { 0x0260,     12,	}, /*   48 */
2762     { 0x0A60,     12,	}, /*   49 */
2763     { 0x04A0,     12,	}, /*   50 */
2764     { 0x0CA0,     12,	}, /*   51 */
2765     { 0x0240,     12,	}, /*   52 */
2766     { 0x0EC0,     12,	}, /*   53 */
2767     { 0x01C0,     12,	}, /*   54 */
2768     { 0x0E40,     12,	}, /*   55 */
2769     { 0x0140,     12,	}, /*   56 */
2770     { 0x01A0,     12,	}, /*   57 */
2771     { 0x09A0,     12,	}, /*   58 */
2772     { 0x0D40,     12,	}, /*   59 */
2773     { 0x0340,     12,	}, /*   60 */
2774     { 0x05A0,     12,	}, /*   61 */
2775     { 0x0660,     12,	}, /*   62 */
2776     { 0x0E60,     12,	}, /*   63 */
2777 
2778     { 0x03C0,     10,	}, /*   64 */
2779     { 0x0130,     12,	}, /*  128 */
2780     { 0x0930,     12,	}, /*  192 */
2781     { 0x0DA0,     12,	}, /*  256 */
2782     { 0x0CC0,     12,	}, /*  320 */
2783     { 0x02C0,     12,	}, /*  384 */
2784     { 0x0AC0,     12,	}, /*  448 */
2785     { 0x06C0,     13,	}, /*  512 */
2786     { 0x16C0,     13,	}, /*  576 */
2787     { 0x0A40,     13,	}, /*  640 */
2788     { 0x1A40,     13,	}, /*  704 */
2789     { 0x0640,     13,	}, /*  768 */
2790     { 0x1640,     13,	}, /*  832 */
2791     { 0x09C0,     13,	}, /*  896 */
2792     { 0x19C0,     13,	}, /*  960 */
2793     { 0x05C0,     13,	}, /* 1024 */
2794     { 0x15C0,     13,	}, /* 1088 */
2795     { 0x0DC0,     13,	}, /* 1152 */
2796     { 0x1DC0,     13,	}, /* 1216 */
2797     { 0x0940,     13,	}, /* 1280 */
2798     { 0x1940,     13,	}, /* 1344 */
2799     { 0x0540,     13,	}, /* 1408 */
2800     { 0x1540,     13,	}, /* 1472 */
2801     { 0x0B40,     13,	}, /* 1536 */
2802     { 0x1B40,     13,	}, /* 1600 */
2803     { 0x04C0,     13,	}, /* 1664 */
2804     { 0x14C0,     13, }, /* 1728 */
2805 
2806     { 0x0080,     11,	}, /* 1792 */
2807     { 0x0180,     11,	}, /* 1856 */
2808     { 0x0580,     11,	}, /* 1920 */
2809     { 0x0480,     12,	}, /* 1984 */
2810     { 0x0C80,     12,	}, /* 2048 */
2811     { 0x0280,     12,	}, /* 2112 */
2812     { 0x0A80,     12,	}, /* 2176 */
2813     { 0x0680,     12,	}, /* 2240 */
2814     { 0x0E80,     12,	}, /* 2304 */
2815     { 0x0380,     12,	}, /* 2368 */
2816     { 0x0B80,     12,	}, /* 2432 */
2817     { 0x0780,     12,	}, /* 2496 */
2818     { 0x0F80,     12,	}, /* 2560 */
2819   };
2820 
2821   while (count >= 64){
2822     if(count <= MAX_FAX_WIDTH){
2823       dviprt_fax_set_bitcount((black_count_list + 63) + (count/64),info);
2824       break;
2825     }
2826     dviprt_fax_set_black(MAX_FAX_WIDTH,info);
2827     dviprt_fax_set_white(0,info);
2828     count -= MAX_FAX_WIDTH;
2829   }
2830   dviprt_fax_set_bitcount(black_count_list + (count & 63),info);
2831   return 0;
2832 }
2833 #endif /* DVIPRT_SUPPORT_FAX */
2834 /***** End of encode.c *****/
2835