1 /* Copyright (C) 1998, 1999 Norihito Ohmori.
2 
3    Ghostscript printer driver
4    for Canon LBP, BJC-680J and BJC-880J printers (LIPS II+/III/IVc/IV)
5 
6    This software 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 GNU General Public License for full details.
11 
12    Everyone is granted permission to copy, modify and redistribute
13    this software, but only under the conditions described in the GNU
14    General Public License.  A copy of this license is supposed to have been
15    given to you along with this software 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 
21 /*$Id: gdevl4r.c $ */
22 /* Raster Version of LIPS driver */
23 
24 #include "gdevlprn.h"
25 #include "gdevlips.h"
26 
27 /* The device descriptors */
28 private dev_proc_open_device(lips2p_open);
29 private dev_proc_open_device(lips3_open);
30 private dev_proc_open_device(bjc880j_open);
31 private dev_proc_open_device(lips4_open);
32 
33 private dev_proc_close_device(lips_close);
34 
35 private dev_proc_print_page_copies(lips2p_print_page_copies);
36 private dev_proc_print_page_copies(lips3_print_page_copies);
37 private dev_proc_print_page_copies(bjc880j_print_page_copies);
38 private dev_proc_print_page_copies(lips4_print_page_copies);
39 
40 private dev_proc_get_params(lips_get_params);
41 private dev_proc_get_params(lips4_get_params);
42 
43 private dev_proc_put_params(lips_put_params);
44 private dev_proc_put_params(lips4_put_params);
45 
46 #if 0
47 private dev_proc_image_out(lips_image_out);
48 
49 #endif
50 private dev_proc_image_out(lips2p_image_out);
51 private dev_proc_image_out(lips4_image_out);
52 
53 #define lips_device(dtype, procs, dname, xdpi, ydpi, lm, bm, rm, tm, color_bits,\
54 		    print_page_copies, image_out, cassetFeed, username)\
55 {        std_device_std_color_full_body(dtype, &procs, dname,\
56           (int)((long)((DEFAULT_WIDTH_10THS) * (xdpi)) / 10),\
57           (int)((long)((DEFAULT_HEIGHT_10THS) * (ydpi)) / 10),\
58           xdpi, ydpi, color_bits,\
59           -(lm) * (xdpi), -(tm) * (ydpi),\
60           (lm) * 72.0, (bm) * 72.0,\
61           (rm) * 72.0, (tm) * 72.0\
62         ),\
63        lp_device_body_rest_(print_page_copies, image_out),\
64 	   cassetFeed, username, LIPS_PJL_DEFAULT,\
65 	   0, 0, 0, 0, 0, 0, 0, -1\
66 }
67 
68 #define lips4_device(dtype, procs, dname, xdpi, ydpi, lm, bm, rm, tm, color_bits,\
69 		    print_page_copies, image_out, cassetFeed, username)\
70 {        std_device_std_color_full_body(dtype, &procs, dname,\
71           (int)((long)((DEFAULT_WIDTH_10THS) * (xdpi)) / 10),\
72           (int)((long)((DEFAULT_HEIGHT_10THS) * (ydpi)) / 10),\
73           xdpi, ydpi, color_bits,\
74           -(lm) * (xdpi), -(tm) * (ydpi),\
75           (lm) * 72.0, (bm) * 72.0,\
76           (rm) * 72.0, (tm) * 72.0\
77         ),\
78        lp_duplex_device_body_rest_(print_page_copies, image_out),\
79   cassetFeed,\
80   username, LIPS_PJL_DEFAULT, 0, 0, 0, 0, 0, 0, 0, -1,\
81   0, LIPS_NUP_DEFAULT, LIPS_FACEUP_DEFAULT,\
82   LIPS_MEDIATYPE_DEFAULT \
83 }
84 
85 typedef struct gx_device_lips_s gx_device_lips;
86 struct gx_device_lips_s {
87     gx_device_common;
88     gx_prn_device_common;
89     gx_lprn_device_common;
90     lips_params_common;
91 };
92 
93 typedef struct gx_device_lips4_s gx_device_lips4;
94 struct gx_device_lips4_s {
95     gx_device_common;
96     gx_prn_device_common;
97     gx_lprn_device_common;
98     lips_params_common;
99     lips4_params_common;
100 };
101 
102 private gx_device_procs lips2p_prn_procs =
103 prn_params_procs(lips2p_open, gdev_prn_output_page, lips_close,
104 		 lips_get_params, lips_put_params);
105 
106 private gx_device_procs lips3_prn_procs =
107 prn_params_procs(lips3_open, gdev_prn_output_page, lips_close,
108 		 lips_get_params, lips_put_params);
109 
110 private gx_device_procs bjc880j_prn_color_procs =
111 prn_params_procs(bjc880j_open, gdev_prn_output_page, lips_close,
112 		       lips4_get_params, lips4_put_params);
113 
114 private gx_device_procs lips4_prn_procs =
115 prn_params_procs(lips4_open, gdev_prn_output_page, lips_close,
116 		       lips4_get_params, lips4_put_params);
117 
118 gx_device_lips far_data gs_lips2p_device =
119 lips_device(gx_device_lips, lips2p_prn_procs, "lips2p",
120 	    LIPS2P_DPI_DEFAULT,
121 	    LIPS2P_DPI_DEFAULT,
122 	    LIPS2P_LEFT_MARGIN_DEFAULT,
123 	    LIPS2P_BOTTOM_MARGIN_DEFAULT,
124 	    LIPS2P_RIGHT_MARGIN_DEFAULT,
125 	    LIPS2P_TOP_MARGIN_DEFAULT,
126 	    1, lips2p_print_page_copies, lips2p_image_out,
127 	    LIPS_CASSETFEED_DEFAULT,
128 	    LIPS_USERNAME_DEFAULT);
129 
130 gx_device_lips far_data gs_lips3_device =
131 lips_device(gx_device_lips, lips3_prn_procs, "lips3",
132 	    LIPS3_DPI_DEFAULT,
133 	    LIPS3_DPI_DEFAULT,
134 	    LIPS3_LEFT_MARGIN_DEFAULT,
135 	    LIPS3_BOTTOM_MARGIN_DEFAULT,
136 	    LIPS3_RIGHT_MARGIN_DEFAULT,
137 	    LIPS3_TOP_MARGIN_DEFAULT,
138 	    1, lips3_print_page_copies, lips2p_image_out,
139 	    LIPS_CASSETFEED_DEFAULT,
140 	    LIPS_USERNAME_DEFAULT);
141 
142 gx_device_lips4 far_data gs_bjc880j_device =
143 lips4_device(gx_device_lips4, bjc880j_prn_color_procs, "bjc880j",
144 	     BJC880J_DPI_DEFAULT,
145 	     BJC880J_DPI_DEFAULT,
146 	     BJC880J_LEFT_MARGIN_DEFAULT,
147 	     BJC880J_BOTTOM_MARGIN_DEFAULT,
148 	     BJC880J_RIGHT_MARGIN_DEFAULT,
149 	     BJC880J_TOP_MARGIN_DEFAULT,
150 	     1, bjc880j_print_page_copies, lips4_image_out,
151 	     LIPS_CASSETFEED_DEFAULT,
152 	     LIPS_USERNAME_DEFAULT);
153 
154 gx_device_lips4 far_data gs_lips4_device =
155 lips4_device(gx_device_lips4, lips4_prn_procs, "lips4",
156 	     LIPS4_DPI_DEFAULT,
157 	     LIPS4_DPI_DEFAULT,
158 	     LIPS4_LEFT_MARGIN_DEFAULT,
159 	     LIPS4_BOTTOM_MARGIN_DEFAULT,
160 	     LIPS4_RIGHT_MARGIN_DEFAULT,
161 	     LIPS4_TOP_MARGIN_DEFAULT,
162 	     1, lips4_print_page_copies, lips4_image_out,
163 	     LIPS_CASSETFEED_DEFAULT,
164 	     LIPS_USERNAME_DEFAULT);
165 
166 /* Printer types */
167 typedef enum {
168     LIPS2P,
169     LIPS3,
170     BJC880J,
171     LIPS4
172 } lips_printer_type;
173 
174 /* Forward references */
175 private void lips_job_start(gx_device_printer * dev, lips_printer_type ptype, FILE * fp, int num_copies);
176 private void lips_job_end(gx_device_printer * pdev, FILE * fp);
177 private int lips_open(gx_device * pdev, lips_printer_type ptype);
178 private int lips4c_output_page(gx_device_printer * pdev, FILE * prn_stream);
179 private int lips_delta_encode(byte * inBuff, byte * prevBuff, byte * outBuff, byte * diffBuff, int Length);
180 private int lips_byte_cat(byte * TotalBuff, byte * Buff, int TotalLen, int Len);
181 #if GS_VERSION_MAJOR >= 8
182 private int lips_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, lips_printer_type ptype, int numcopies);
183 private int lips_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, lips_printer_type ptype, int numcopies);
184 #else
185 private int lips_print_page_copies(P4(gx_device_printer * pdev, FILE * prn_stream, lips_printer_type ptype, int numcopies));
186 private int lips_print_page_copies(P4(gx_device_printer * pdev, FILE * prn_stream, lips_printer_type ptype, int numcopies));
187 #endif
188 private int lips4type_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, int num_copies, int ptype);
189 
190 private int
lips2p_open(gx_device * pdev)191 lips2p_open(gx_device * pdev)
192 {
193     return lips_open(pdev, LIPS2P);
194 }
195 
196 private int
lips3_open(gx_device * pdev)197 lips3_open(gx_device * pdev)
198 {
199     return lips_open(pdev, LIPS3);
200 }
201 
202 private int
bjc880j_open(gx_device * pdev)203 bjc880j_open(gx_device * pdev)
204 {
205     return lips_open(pdev, BJC880J);
206 }
207 
208 private int
lips4_open(gx_device * pdev)209 lips4_open(gx_device * pdev)
210 {
211     return lips_open(pdev, LIPS4);
212 }
213 
214 /* Open the printer, adjusting the margins if necessary. */
215 private int
lips_open(gx_device * pdev,lips_printer_type ptype)216 lips_open(gx_device * pdev, lips_printer_type ptype)
217 {
218     int width = pdev->MediaSize[0];
219     int height = pdev->MediaSize[1];
220     int xdpi = pdev->x_pixels_per_inch;
221     int ydpi = pdev->y_pixels_per_inch;
222 
223     /* Paper Size Check */
224     if (width <= height) {	/* portrait */
225 	if ((width < LIPS_WIDTH_MIN || width > LIPS_WIDTH_MAX ||
226 	     height < LIPS_HEIGHT_MIN || height > LIPS_HEIGHT_MAX) &&
227 	    !(width == LIPS_LEDGER_WIDTH && height == LIPS_LEDGER_HEIGHT))
228 	    return_error(gs_error_rangecheck);
229     } else {			/* landscape */
230 	if ((width < LIPS_HEIGHT_MIN || width > LIPS_HEIGHT_MAX ||
231 	     height < LIPS_WIDTH_MIN || height > LIPS_WIDTH_MAX) &&
232 	    !(width == LIPS_LEDGER_HEIGHT && height == LIPS_LEDGER_WIDTH))
233 	    return_error(gs_error_rangecheck);
234     }
235 
236     /* Resolution Check */
237     if (xdpi != ydpi)
238 	return_error(gs_error_rangecheck);
239     else if (ptype == LIPS2P) {
240 	/* LIPS II+ support DPI is 240x240 */
241 	if (xdpi != LIPS2P_DPI_MAX)
242 	    return_error(gs_error_rangecheck);
243     } else if (ptype == LIPS3) {
244 	/* LIPS III supports DPI is 300x300 */
245 	if (xdpi != LIPS3_DPI_MAX)
246 	    return_error(gs_error_rangecheck);
247     } else if (ptype == BJC880J) {
248 	if (xdpi < LIPS_DPI_MIN || xdpi > BJC880J_DPI_MAX)
249 	    return_error(gs_error_rangecheck);
250     } else {			/* LIPS4 supprts DPI is 60x60 - 600x600 and 1200x1200 */
251 	if ((xdpi < LIPS_DPI_MIN || xdpi > LIPS4_DPI_MAX) && xdpi != LIPS4_DPI_SUPERFINE)
252 	    return_error(gs_error_rangecheck);
253     }
254 
255     return gdev_prn_open(pdev);
256 }
257 
258 private int
lips_close(gx_device * pdev)259 lips_close(gx_device * pdev)
260 {
261     gx_device_printer *const ppdev = (gx_device_printer *) pdev;
262     gx_device_lips *const lips = (gx_device_lips *) pdev;
263 
264     gdev_prn_open_printer(pdev, 1);
265 
266     fprintf(ppdev->file, "%c0J%c", LIPS_DCS, LIPS_ST);
267     if (lips->pjl)
268 	fprintf(ppdev->file,
269 		"%c%%-12345X"
270 		"@PJL SET LPARM : LIPS SW2 = OFF\n"
271 		"@PJL EOJ\n"
272 		"%c%%-12345X", LIPS_ESC, LIPS_ESC);
273 
274     return gdev_prn_close(pdev);
275 }
276 
277 /* Get properties for the lips drivers. */
278 private int
lips_get_params(gx_device * pdev,gs_param_list * plist)279 lips_get_params(gx_device * pdev, gs_param_list * plist)
280 {
281     gx_device_lips *const lips = (gx_device_lips *) pdev;
282     int code = lprn_get_params(pdev, plist);
283     int ncode;
284     gs_param_string usern;
285 
286     if (code < 0)
287 	return code;
288 
289     if ((ncode = param_write_int(plist, LIPS_OPTION_CASSETFEED,
290 				 &lips->cassetFeed)) < 0)
291 	code = ncode;
292 
293     if ((ncode = param_write_bool(plist, LIPS_OPTION_PJL,
294 				  &lips->pjl)) < 0)
295 	code = ncode;
296 
297     if ((ncode = param_write_int(plist, LIPS_OPTION_TONERDENSITY,
298 				 &lips->toner_density)) < 0)
299 	code = ncode;
300 
301     if (lips->toner_saving_set >= 0 &&
302 	(code = (lips->toner_saving_set ?
303      param_write_bool(plist, LIPS_OPTION_TONERSAVING, &lips->toner_saving) :
304 		 param_write_null(plist, LIPS_OPTION_TONERSAVING))) < 0)
305 	code = ncode;
306 
307     if (code < 0)
308 	return code;
309 
310     usern.data = (const byte *)lips->Username,
311 	usern.size = strlen(lips->Username),
312 	usern.persistent = false;
313 
314     return param_write_string(plist, LIPS_OPTION_USER_NAME, &usern);
315 }
316 
317 private int
lips4_get_params(gx_device * pdev,gs_param_list * plist)318 lips4_get_params(gx_device * pdev, gs_param_list * plist)
319 {
320     gx_device_lips4 *const lips4 = (gx_device_lips4 *) pdev;
321     int code = lips_get_params(pdev, plist);
322     int ncode;
323     gs_param_string pmedia;
324 
325     if (code < 0)
326 	return code;
327 
328     if ((ncode = param_write_int(plist, LIPS_OPTION_NUP,
329 				 &lips4->nup)) < 0)
330 	code = ncode;
331 
332     if ((ncode = param_write_bool(plist, LIPS_OPTION_FACEUP,
333 				  &lips4->faceup)) < 0)
334 	code = ncode;
335 
336     if (code < 0)
337 	return code;
338 
339     pmedia.data = (const byte *)lips4->mediaType,
340 	pmedia.size = strlen(lips4->mediaType),
341 	pmedia.persistent = false;
342 
343     return param_write_string(plist, LIPS_OPTION_MEDIATYPE, &pmedia);
344 }
345 
346 /* Put properties for the lips drivers. */
347 private int
lips_put_params(gx_device * pdev,gs_param_list * plist)348 lips_put_params(gx_device * pdev, gs_param_list * plist)
349 {
350     gx_device_lips *const lips = (gx_device_lips *) pdev;
351     int ecode = 0;
352     int code;
353     gs_param_name param_name;
354     int cass = lips->cassetFeed;
355     bool pjl = lips->pjl;
356     int toner_density = lips->toner_density;
357     bool toner_saving = lips->toner_saving;
358     bool toner_saving_set = lips->toner_saving_set;
359     gs_param_string usern;
360 
361     switch (code = param_read_int(plist,
362 				  (param_name = LIPS_OPTION_CASSETFEED),
363 				  &cass)) {
364 	case 0:
365 	    if (cass < -1 || cass > 17 || (cass > 3 && cass < 10))
366 		ecode = gs_error_rangecheck;
367 	    else
368 		break;
369 	    goto casse;
370 	default:
371 	    ecode = code;
372 	  casse:param_signal_error(plist, param_name, ecode);
373 	case 1:
374 	    break;
375     }
376 
377     if ((code = param_read_bool(plist,
378 				(param_name = LIPS_OPTION_PJL),
379 				&pjl)) < 0)
380 	param_signal_error(plist, param_name, ecode = code);
381 
382     switch (code = param_read_int(plist,
383 				  (param_name = LIPS_OPTION_TONERDENSITY),
384 				  &toner_density)) {
385 	case 0:
386 	    if (toner_density < 0 || toner_density > 8)
387 		ecode = gs_error_rangecheck;
388 	    else
389 		break;
390 	    goto tden;
391 	default:
392 	    ecode = code;
393 	  tden:param_signal_error(plist, param_name, ecode);
394 	case 1:
395 	    break;
396     }
397 
398     if (lips->toner_saving_set >= 0)
399 	switch (code = param_read_bool(plist, (param_name = LIPS_OPTION_TONERSAVING),
400 				       &toner_saving)) {
401 	    case 0:
402 		toner_saving_set = 1;
403 		break;
404 	    default:
405 		if ((code = param_read_null(plist, param_name)) == 0) {
406 		    toner_saving_set = 0;
407 		    break;
408 		}
409 		ecode = code;
410 		param_signal_error(plist, param_name, ecode);
411 	    case 1:
412 		break;
413 	}
414     switch (code = param_read_string(plist,
415 				     (param_name = LIPS_OPTION_USER_NAME),
416 				     &usern)) {
417 	case 0:
418 	    if (usern.size > LIPS_USERNAME_MAX)
419 		ecode = gs_error_limitcheck;
420 	    else {		/* Check the validity of ``User Name'' characters */
421 		int i;
422 
423 		for (i = 0; i < usern.size; i++)
424 		    if (usern.data[i] < 0x20 ||
425 			usern.data[i] > 0x7e
426 		    /*
427 		       && usern.data[i] < 0xa0) ||
428 		       usern.data[i] > 0xfe
429 		     */
430 			) {
431 			ecode = gs_error_rangecheck;
432 			goto userne;
433 		    }
434 	    }
435 	    break;
436 	    goto userne;
437 	default:
438 	    ecode = code;
439 	  userne:param_signal_error(plist, param_name, ecode);
440 	case 1:
441 	    usern.data = 0;
442 	    break;
443     }
444 
445     if (ecode < 0)
446 	return ecode;
447     code = lprn_put_params(pdev, plist);
448     if (code < 0)
449 	return code;
450 
451     lips->cassetFeed = cass;
452     lips->pjl = pjl;
453     lips->toner_density = toner_density;
454     lips->toner_saving = toner_saving;
455     lips->toner_saving_set = toner_saving_set;
456 
457     if (usern.data != 0 &&
458 	bytes_compare(usern.data, usern.size,
459 		      (const byte *)lips->Username, strlen(lips->Username))
460 	) {
461 	memcpy(lips->Username, usern.data, usern.size);
462 	lips->Username[usern.size] = 0;
463     }
464     return 0;
465 }
466 
467 private int
lips4_put_params(gx_device * pdev,gs_param_list * plist)468 lips4_put_params(gx_device * pdev, gs_param_list * plist)
469 {
470     gx_device_lips4 *const lips4 = (gx_device_lips4 *) pdev;
471     int ecode = 0;
472     int code;
473     gs_param_name param_name;
474     gs_param_string pmedia;
475     bool nup = lips4->nup;
476     bool faceup = lips4->faceup;
477     int old_bpp = pdev->color_info.depth;
478     int bpp = 0;
479 
480     switch (code = param_read_int(plist,
481 				  (param_name = LIPS_OPTION_NUP),
482 				  &nup)) {
483 	case 0:
484 	    if (nup != 1 && nup != 2 && nup != 4)
485 		ecode = gs_error_rangecheck;
486 	    else
487 		break;
488 	    goto nupe;
489 	default:
490 	    ecode = code;
491 	  nupe:param_signal_error(plist, param_name, ecode);
492 	case 1:
493 	    break;
494     }
495 
496     if ((code = param_read_bool(plist,
497 				(param_name = LIPS_OPTION_FACEUP),
498 				&faceup)) < 0)
499 	param_signal_error(plist, param_name, ecode = code);
500 
501     switch (code = param_read_string(plist,
502 				     (param_name = LIPS_OPTION_MEDIATYPE),
503 				     &pmedia)) {
504 	case 0:
505 	    if (pmedia.size > LIPS_MEDIACHAR_MAX)
506 		ecode = gs_error_limitcheck;
507 	    else {		/* Check the validity of ``MediaType'' characters */
508 		if (strcmp(pmedia.data, "PlainPaper") != 0 &&
509 		    strcmp(pmedia.data, "OHP") != 0 &&
510 		    strcmp(pmedia.data, "TransparencyFilm") != 0 &&	/* same as OHP */
511 		    strcmp(pmedia.data, "GlossyFilm") != 0 &&
512 		    strcmp(pmedia.data, "CardBoard") != 0
513 		    ) {
514 		    ecode = gs_error_rangecheck;
515 		    goto pmediae;
516 		}
517 	    }
518 	    break;
519 	    goto pmediae;
520 	default:
521 	    ecode = code;
522 	  pmediae:param_signal_error(plist, param_name, ecode);
523 	case 1:
524 	    pmedia.data = 0;
525 	    break;
526     }
527 
528     switch (code = param_read_int(plist,
529 				  (param_name = "BitsPerPixel"),
530 				  &bpp)) {
531 	case 0:
532 	    if (bpp != 1 && bpp != 24)
533 		ecode = gs_error_rangecheck;
534 	    else
535 		break;
536 	    goto bppe;
537 	default:
538 	    ecode = code;
539 	  bppe:param_signal_error(plist, param_name, ecode);
540 	case 1:
541 	    break;
542     }
543 
544     if (bpp != 0)
545       {
546 	pdev->color_info.depth = bpp;
547 	pdev->color_info.num_components = ((bpp == 1) ? 1 : 3);
548 	pdev->color_info.max_gray = (bpp >= 8 ? 255 : 1);
549 	pdev->color_info.max_color = (bpp >= 8 ? 255 : bpp > 1 ? 1 : 0);
550 	pdev->color_info.dither_grays = (bpp >= 8 ? 5 : 2);
551 	pdev->color_info.dither_colors = (bpp >= 8 ? 5 : bpp > 1 ? 2 : 0);
552 	dev_proc(pdev, map_rgb_color) = ((bpp == 1) ? gdev_prn_map_rgb_color : gx_default_rgb_map_rgb_color);
553       }
554 
555     if (ecode < 0)
556 	return ecode;
557     code = lips_put_params(pdev, plist);
558     if (code < 0)
559 	return code;
560 
561     lips4->nup = nup;
562     lips4->faceup = faceup;
563 
564     if (pmedia.data != 0 &&
565 	bytes_compare(pmedia.data, pmedia.size,
566 		   (const byte *)lips4->mediaType, strlen(lips4->mediaType))
567 	) {
568 	memcpy(lips4->mediaType, pmedia.data, pmedia.size);
569 	lips4->mediaType[pmedia.size] = 0;
570     }
571     if (bpp != 0 && bpp != old_bpp && pdev->is_open)
572 	return gs_closedevice(pdev);
573     return 0;
574 }
575 
576 
577 /* ------ Internal routines ------ */
578 
579 private int
lips2p_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_copies)580 lips2p_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, int num_copies)
581 {
582     return lips_print_page_copies(pdev, prn_stream, LIPS2P, num_copies);
583 }
584 
585 private int
lips3_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_copies)586 lips3_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, int num_copies)
587 {
588     return lips_print_page_copies(pdev, prn_stream, LIPS3, num_copies);
589 }
590 
591 #define NUM_LINES 24		/* raster height */
592 #define NUM_LINES_4C 256
593 
594 private int
lips_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,lips_printer_type ptype,int num_copies)595 lips_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, lips_printer_type ptype, int num_copies)
596 {
597     gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
598     int code = 0;
599     int bpl = gdev_mem_bytes_per_scan_line(pdev);
600     int maxY = lprn->BlockLine / lprn->nBh * lprn->nBh;
601 
602     /* Initialize printer. */
603     lips_job_start(pdev, ptype, prn_stream, num_copies);
604 
605     if (!(lprn->CompBuf = gs_malloc(bpl * 3 / 2 + 1, maxY, "(CompBuf)")))
606 	return_error(gs_error_VMerror);
607 
608 
609     lprn->NegativePrint = false; /* not support */
610     lprn->prev_x = lprn->prev_y = 0;
611     code = lprn_print_image(pdev, prn_stream);
612     if (code < 0)
613 	return code;
614 
615     gs_free(lprn->CompBuf, bpl * 3 / 2 + 1, maxY, "(CompBuf)");
616 
617     /* eject page */
618     lips_job_end(pdev, prn_stream);
619 
620 
621     return 0;
622 }
623 
624 private int
bjc880j_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_copies)625 bjc880j_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, int num_copies)
626 {
627   return lips4type_print_page_copies(pdev, prn_stream, num_copies, BJC880J);
628 }
629 
630 private int
lips4_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_copies)631 lips4_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, int num_copies)
632 {
633   return lips4type_print_page_copies(pdev, prn_stream, num_copies, LIPS4);
634 }
635 
636 private int
lips4type_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_copies,int ptype)637 lips4type_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, int num_copies, int ptype)
638 {
639     gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
640     int code = 0;
641     int bpl = gdev_mem_bytes_per_scan_line(pdev);
642     int maxY = lprn->BlockLine / lprn->nBh * lprn->nBh;
643 
644     /* Initialize printer. */
645     lips_job_start(pdev, ptype, prn_stream, num_copies);
646 
647     if (pdev->color_info.depth == 1)
648       {
649 	if (!(lprn->CompBuf = gs_malloc(bpl * 3 / 2 + 1, maxY, "(CompBuf)")))
650 	  return_error(gs_error_VMerror);
651 	if (!(lprn->CompBuf2 = gs_malloc(bpl * 3 / 2 + 1, maxY, "(CompBuf2)")))
652 	  return_error(gs_error_VMerror);
653 
654 	if (lprn->NegativePrint) {
655 	  int rm = pdev->width - (dev_l_margin(pdev) + dev_r_margin(pdev)) * pdev->x_pixels_per_inch;
656 	  int bm = pdev->height - (dev_t_margin(pdev) + dev_b_margin(pdev)) * pdev->y_pixels_per_inch;
657 	  /* Draw black rectangle */
658 	  fprintf(prn_stream,
659 		  "%c{%c%da%c%de%c;;;3}",
660 		  LIPS_CSI, LIPS_CSI, rm, LIPS_CSI, bm, LIPS_CSI);
661 	  fprintf(prn_stream, "%c%dj%c%dk",
662 		  LIPS_CSI, rm, LIPS_CSI, bm);
663 	}
664 
665 
666 	lprn->prev_x = lprn->prev_y = 0;
667 	code = lprn_print_image(pdev, prn_stream);
668 	if (code < 0)
669 	  return code;
670 
671 	gs_free(lprn->CompBuf, bpl * 3 / 2 + 1, maxY, "(CompBuf)");
672 	gs_free(lprn->CompBuf2, bpl * 3 / 2 + 1, maxY, "(CompBuf2)");
673       }
674     else
675       {
676 	code = lips4c_output_page(pdev, prn_stream);
677 
678 	if (code < 0)
679 	  return code;
680       }
681 
682     /* eject page */
683     lips_job_end(pdev, prn_stream);
684 
685 
686     return 0;
687 }
688 
689 #if 0
690 /* Send the page to the printer.  */
691 private int
692 lips4c_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, int num_copies)
693 {
694     int code;
695 
696     lips_job_start(pdev, BJC880J, prn_stream, num_copies);
697 
698     /* make output data */
699     code = lips4c_output_page(pdev, prn_stream);
700 
701     if (code < 0)
702 	return code;
703 
704     /* eject page */
705     lips_job_end(pdev, prn_stream);
706 
707     return 0;
708 }
709 #endif
710 
711 private void
move_cap(gx_device_printer * pdev,FILE * prn_stream,int x,int y)712 move_cap(gx_device_printer * pdev, FILE * prn_stream, int x, int y)
713 {
714     gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
715 
716     if (x != lprn->prev_x) {
717 	if (x > lprn->prev_x)
718 	    fprintf(prn_stream, "%c%da", LIPS_CSI, x - lprn->prev_x);
719 	else
720 	    fprintf(prn_stream, "%c%dj", LIPS_CSI, lprn->prev_x - x);
721 
722 	lprn->prev_x = x;
723     }
724     if (y != lprn->prev_y) {
725 	if (y > lprn->prev_y)
726 	    fprintf(prn_stream, "%c%de", LIPS_CSI, y - lprn->prev_y);
727 	else
728 	    fprintf(prn_stream, "%c%dk", LIPS_CSI, lprn->prev_y - y);
729 
730 	lprn->prev_y = y;
731     }
732 }
733 
734 private void
draw_bubble(FILE * prn_stream,int width,int height)735 draw_bubble(FILE * prn_stream, int width, int height)
736 {
737     /* Draw a rectangle */
738     fprintf(prn_stream,
739 	    "%c{%c%da%c%de%c}",
740 	    LIPS_CSI, LIPS_CSI, width, LIPS_CSI, height, LIPS_CSI);
741     fprintf(prn_stream, "%c%dj%c%dk",
742 	    LIPS_CSI, width, LIPS_CSI, height);
743 }
744 
745 
746 #if 0
747 /* Non Compression Version of image_out */
748 private void
749 lips_image_out(gx_device_printer * pdev, FILE * prn_stream, int x, int y, int width, int height)
750 {
751     gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
752 
753     int i, j;
754     byte *p;
755     int maxY = lprn->BlockLine / lprn->nBh * lprn->nBh;
756 
757     move_cap(pdev, prn_stream, x, y);
758 
759     fprintf(prn_stream, "%c%d;%d;%d.r", LIPS_CSI,
760 	    width / 8 * height, width / 8, (int)pdev->x_pixels_per_inch);
761 
762     for (i = 0; i < height; i++) {
763 	p = lprn->ImageBuf + ((i + y) % maxY) * raster;
764 	for (j = 0; j < width / 8; j++) {
765 	    fputc(p[j + data_x], prn_stream);
766 	}
767     }
768 
769     if (lprn->ShowBubble)
770 	draw_bubble(prn_stream, width, height);
771 }
772 #endif
773 
774 private void
lips2p_image_out(gx_device_printer * pdev,FILE * prn_stream,int x,int y,int width,int height)775 lips2p_image_out(gx_device_printer * pdev, FILE * prn_stream, int x, int y, int width, int height)
776 {
777     gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
778     int Len;
779     char raw_str[32];		/* LIPS command header (uncompress) */
780     char comp_str[32];		/* LIPS command header (compress) */
781 
782     move_cap(pdev, prn_stream, x, y);
783 
784     Len = lips_mode3format_encode(lprn->TmpBuf, lprn->CompBuf, width / 8 * height);
785     sprintf(raw_str, "%c%d;%d;%d.r", LIPS_CSI,
786 	    width / 8 * height, width / 8, (int)pdev->x_pixels_per_inch);
787     sprintf(comp_str, "%c%d;%d;%d;9;%d.r", LIPS_CSI,
788 	    Len, width / 8, (int)pdev->x_pixels_per_inch, height);
789 
790     if (Len < width / 8 * height - strlen(comp_str) + strlen(raw_str)) {
791 	fprintf(prn_stream, "%s", comp_str);
792 	fwrite(lprn->CompBuf, 1, Len, prn_stream);
793     } else {
794 	/* compression result is bad. */
795 	fprintf(prn_stream, "%s", raw_str);
796 	fwrite(lprn->TmpBuf, 1, width / 8 * height, prn_stream);
797     }
798 
799     if (lprn->ShowBubble)
800 	draw_bubble(prn_stream, width, height);
801 }
802 
803 private void
lips4_image_out(gx_device_printer * pdev,FILE * prn_stream,int x,int y,int width,int height)804 lips4_image_out(gx_device_printer * pdev, FILE * prn_stream, int x, int y, int width, int height)
805 {
806     gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
807     int Len, Len_rle;
808     char raw_str[32];		/* LIPS command header (uncompress) */
809     char comp_str[32];		/* LIPS command header (compress) */
810 
811     move_cap(pdev, prn_stream, x, y);
812 
813     Len = lips_packbits_encode(lprn->TmpBuf, lprn->CompBuf, width / 8 * height);
814     Len_rle = lips_rle_encode(lprn->TmpBuf, lprn->CompBuf2, width / 8 * height);
815 
816     sprintf(raw_str, "%c%d;%d;%d.r", LIPS_CSI,
817 	    width / 8 * height, width / 8, (int)pdev->x_pixels_per_inch);
818 
819     if (Len < Len_rle) {
820 	sprintf(comp_str, "%c%d;%d;%d;11;%d.r", LIPS_CSI,
821 		Len, width / 8, (int)pdev->x_pixels_per_inch, height);
822 	if (Len < width / 8 * height - strlen(comp_str) + strlen(raw_str)) {
823 	    fprintf(prn_stream, "%s", comp_str);
824 	    fwrite(lprn->CompBuf, 1, Len, prn_stream);
825 	} else {
826 	    /* compression result is bad. */
827 	    fprintf(prn_stream, "%s", raw_str);
828 	    fwrite(lprn->TmpBuf, 1, width / 8 * height, prn_stream);
829 	}
830     } else {
831 	sprintf(comp_str, "%c%d;%d;%d;10;%d.r", LIPS_CSI,
832 		Len, width / 8, (int)pdev->x_pixels_per_inch, height);
833 	if (Len_rle < width / 8 * height - strlen(comp_str) + strlen(raw_str)) {
834 	    fprintf(prn_stream, "%s", comp_str);
835 	    fwrite(lprn->CompBuf2, 1, Len, prn_stream);
836 	} else {
837 	    /* compression result is bad. */
838 	    fprintf(prn_stream, "%s", raw_str);
839 	    fwrite(lprn->TmpBuf, 1, width / 8 * height, prn_stream);
840 	}
841     }
842 
843     if (lprn->ShowBubble)
844 	draw_bubble(prn_stream, width, height);
845 }
846 
847 private int
lips4c_write_raster(gx_device_printer * pdev,FILE * prn_stream,byte * pBuff,byte * prevBuff,byte * ComBuff,byte * TotalBuff,byte * diffBuff,int lnum,int raster_height)848 lips4c_write_raster(gx_device_printer * pdev, FILE * prn_stream, byte * pBuff, byte * prevBuff, byte * ComBuff, byte * TotalBuff, byte * diffBuff, int lnum, int raster_height)
849 {
850     int bits_per_pixel = pdev->color_info.depth;
851     int num_components = bits_per_pixel > 8 ? 3 : 1;
852     int nBytesPerLine = gdev_prn_raster(pdev);
853     int Xpixel = nBytesPerLine / num_components;
854     int TotalLen = 0;
855     int num_zerobyte = 0;
856     bool zerobyte_flag = false;
857     int i, y, Len;
858 
859     for (i = 0; i < nBytesPerLine; i++) {
860 	*(prevBuff + i) = 0x00;	/* initialize */
861     }
862 
863     for (y = lnum; y < lnum + raster_height; y++) {
864 	gdev_prn_copy_scan_lines(pdev, y, pBuff, nBytesPerLine);
865 
866 	Len = lips_delta_encode(pBuff,
867 				prevBuff, ComBuff, diffBuff,
868 				Xpixel * num_components);
869 
870 	if (Len == 2 && *ComBuff == 0x01) {
871 	    if (zerobyte_flag == false) {
872 		zerobyte_flag = true;
873 		TotalLen = lips_byte_cat(TotalBuff, ComBuff, TotalLen, Len);
874 	    } else {
875 		if (num_zerobyte > 255) {
876 		    TotalLen = lips_byte_cat(TotalBuff, ComBuff, TotalLen, Len);
877 		} else {
878 		    *(TotalBuff + TotalLen - 1) = num_zerobyte;
879 		}
880 		num_zerobyte++;
881 	    }
882 	} else {
883 	    TotalLen = lips_byte_cat(TotalBuff, ComBuff, TotalLen, Len);
884 	    zerobyte_flag = false;
885 	    num_zerobyte = 0;
886 	}
887     }
888 
889     fprintf(prn_stream, "%c%d;%d;%d;12;%d;;%d;%d;;1.r", LIPS_CSI,
890 	    TotalLen, Xpixel, (int)pdev->x_pixels_per_inch,
891 	    raster_height,
892 	    bits_per_pixel / num_components,
893 	    num_components < 3 ? 0 : 10);
894     fwrite(TotalBuff, 1, TotalLen, prn_stream);
895     fputc(0x85, prn_stream);	/* CR + LF */
896 
897     return 0;
898 }
899 
900 private int
lips4c_output_page(gx_device_printer * pdev,FILE * prn_stream)901 lips4c_output_page(gx_device_printer * pdev, FILE * prn_stream)
902 {
903     byte *pBuff, *ComBuff, *prevBuff, *TotalBuff, *diffBuff;
904     int bits_per_pixel = pdev->color_info.depth;
905     int num_components = bits_per_pixel > 8 ? 3 : 1;
906     int nBytesPerLine = gdev_prn_raster(pdev);
907     int Xpixel = nBytesPerLine / num_components;
908     int lnum = 0;
909 
910     /* Memory Allocate */
911     if (!(pBuff = (byte *) gs_malloc(nBytesPerLine, sizeof(byte), "lips4c_compress_output_page(pBuff)")))
912 	return_error(gs_error_VMerror);
913     if (!(prevBuff = (byte *) gs_malloc(nBytesPerLine, sizeof(byte), "lips4c_compress_output_page(prevBuff)")))
914 	return_error(gs_error_VMerror);
915     if (!(ComBuff = (byte *) gs_malloc(Xpixel * num_components + (Xpixel * num_components + 127) * 129 / 128, sizeof(byte), "lips4c_compress_output_page(ComBuff)")))
916 	return_error(gs_error_VMerror);
917     if (!(TotalBuff = (byte *) gs_malloc((Xpixel * num_components + (Xpixel * num_components + 127) * 129 / 128) * NUM_LINES_4C, sizeof(byte), "lips4c_compress_output_page(TotalBuff)")))
918 	return_error(gs_error_VMerror);
919     if (!(diffBuff = (byte *) gs_malloc(Xpixel * num_components * 2, sizeof(byte), "lips_print_page")))
920 	return_error(gs_error_VMerror);
921 
922     /* make output data */
923     while (lnum < pdev->height) {
924 	lips4c_write_raster(pdev, prn_stream, pBuff, prevBuff, ComBuff,
925 			    TotalBuff, diffBuff, lnum, NUM_LINES_4C);
926 	lnum += NUM_LINES_4C;
927     }
928 
929     if (pdev->height - (lnum - NUM_LINES_4C) > 0) {
930 	lips4c_write_raster(pdev, prn_stream, pBuff, prevBuff, ComBuff,
931 			    TotalBuff, diffBuff, lnum - NUM_LINES_4C,
932 			    pdev->height - (lnum - NUM_LINES_4C));
933     }
934     /* Free Memory */
935     gs_free(pBuff, nBytesPerLine, sizeof(byte), "lips4c_compress_output_page(pBuff)");
936     gs_free(prevBuff, nBytesPerLine, sizeof(byte), "lips4c_compress_output_page(prevBuff)");
937     gs_free(ComBuff, Xpixel * num_components + (Xpixel * num_components + 127) * 129 / 128, sizeof(byte), "lips4c_compress_output_page(ComBuff)");
938     gs_free(TotalBuff, (Xpixel * num_components + (Xpixel * num_components + 127) * 129 / 128) * NUM_LINES_4C, sizeof(byte), "lips4c_compress_output_page(TotalBuff)");
939     gs_free(diffBuff, Xpixel * num_components * 2, sizeof(byte), "lips_print_page");
940 
941     return 0;
942 }
943 
944 
945 private void
lips_job_start(gx_device_printer * pdev,lips_printer_type ptype,FILE * prn_stream,int num_copies)946 lips_job_start(gx_device_printer * pdev, lips_printer_type ptype, FILE * prn_stream, int num_copies)
947 {
948     gx_device_lips *const lips = (gx_device_lips *) pdev;
949     gx_device_lips4 *const lips4 = (gx_device_lips4 *) pdev;
950     int prev_paper_size, prev_paper_width, prev_paper_height, paper_size;
951     int width = pdev->MediaSize[0];
952     int height = pdev->MediaSize[1];
953     int tm, lm, rm, bm;
954 
955     if (pdev->PageCount == 0) {
956 	if (lips->pjl) {
957 	    fprintf(prn_stream,
958 		    "%c%%-12345X@PJL CJLMODE\n"
959 		    "@PJL JOB\n", LIPS_ESC);
960 	    if (ptype == LIPS4) {
961 		fprintf(prn_stream,
962 			"%c%%-12345X@PJL CJLMODE\n", LIPS_ESC);
963 		if ((int)pdev->x_pixels_per_inch == 1200)
964 		    fprintf(prn_stream, "@PJL SET RESOLUTION = SUPERFINE\n");
965 		else if ((int)pdev->x_pixels_per_inch == 600)
966 		    fprintf(prn_stream, "@PJL SET RESOLUTION = FINE\n");
967 		else if ((int)pdev->x_pixels_per_inch == 300)
968 		    fprintf(prn_stream, "@PJL SET RESOLUTION = QUICK\n");
969 	    }
970 	    if (lips->toner_density)
971 		fprintf(prn_stream, "@PJL SET TONER-DENSITY=%d\n",
972 			lips->toner_density);
973 	    if (lips->toner_saving_set) {
974 		fprintf(prn_stream, "@PJL SET TONER-SAVING=");
975 		if (lips->toner_saving)
976 		    fprintf(prn_stream, "ON\n");
977 		else
978 		    fprintf(prn_stream, "OFF\n");
979 	    }
980 	    fprintf(prn_stream,
981 		    "@PJL SET LPARM : LIPS SW2 = ON\n"
982 		    "@PJL ENTER LANGUAGE = LIPS\n");
983 	}
984 	fprintf(prn_stream, "%c%%@", LIPS_ESC);
985 	if (ptype == LIPS2P)
986 	    fprintf(prn_stream, "%c21;%d;0J" LIPS2P_STRING LIPS_VERSION "%c",
987 		    LIPS_DCS, (int)pdev->x_pixels_per_inch, LIPS_ST);
988 	else if (ptype == LIPS3)
989 	    fprintf(prn_stream, "%c31;%d;0J" LIPS3_STRING LIPS_VERSION "%c",
990 		    LIPS_DCS, (int)pdev->x_pixels_per_inch, LIPS_ST);
991 	else if (ptype == LIPS4)
992 	    fprintf(prn_stream, "%c41;%d;0J" LIPS4_STRING LIPS_VERSION "%c",
993 		    LIPS_DCS, (int)pdev->x_pixels_per_inch, LIPS_ST);
994 	else if (ptype == BJC880J)
995 	    fprintf(prn_stream, "%c41;%d;0J" BJC880J_STRING LIPS_VERSION "%c",
996 		    LIPS_DCS, (int)pdev->x_pixels_per_inch, LIPS_ST);
997 
998 	if (ptype == LIPS4 || ptype == BJC880J)
999 	  {
1000 	    if (pdev->color_info.depth == 24)
1001 	      fprintf(prn_stream, "%c1\"p", LIPS_CSI);
1002 	    else
1003 	      fprintf(prn_stream, "%c0\"p", LIPS_CSI);
1004 	  }
1005 	fprintf(prn_stream, "%c<", LIPS_ESC);
1006 	fprintf(prn_stream, "%c11h", LIPS_CSI);	/* Size Unit Mode */
1007     }
1008     /*                           */
1009     /* Print Environment Setting */
1010     /*                           */
1011     /* Media Selection */
1012     paper_size = lips_media_selection(width, height);
1013 
1014     if (ptype == BJC880J) {
1015 	/* Paint Memory Mode Setting */
1016 	/* for BJC-680J/BJC-880J */
1017 	if (paper_size == B4_SIZE ||
1018 	    paper_size == B4_SIZE + LANDSCAPE ||
1019 	    paper_size == LEGAL_SIZE ||
1020 	    paper_size == LEGAL_SIZE + LANDSCAPE)
1021 	    /* for BJC-880J */
1022 	    fprintf(prn_stream, "%c3&z", LIPS_CSI);
1023 	else if (paper_size == A3_SIZE ||
1024 		 paper_size == A3_SIZE + LANDSCAPE ||
1025 		 paper_size == LEDGER_SIZE ||
1026 		 paper_size == LEDGER_SIZE + LANDSCAPE)
1027 	    /* for BJC-880J */
1028 	    fprintf(prn_stream, "%c4&z", LIPS_CSI);
1029 	else
1030 	    fprintf(prn_stream, "%c2&z", LIPS_CSI);
1031     }
1032     if (ptype == LIPS4) {
1033 	if (strcmp(lips4->mediaType, "PlainPaper") == 0)
1034 	    fprintf(prn_stream, "%c20\'t", LIPS_CSI);
1035 	else if (strcmp(lips4->mediaType, "OHP") == 0 ||
1036 		 strcmp(lips4->mediaType, "TransparencyFilm") == 0)
1037 	    fprintf(prn_stream, "%c40\'t", LIPS_CSI);	/* OHP mode (for LBP-2160) */
1038 	else if (strcmp(lips4->mediaType, "CardBoard") == 0)
1039 	    fprintf(prn_stream, "%c30\'t", LIPS_CSI);	/* CardBoard mode (for LBP-2160) */
1040 	else if (strcmp(lips4->mediaType, "GlossyFilm") == 0)
1041 	    fprintf(prn_stream, "%c41\'t", LIPS_CSI);	/* GlossyFile mode (for LBP-2160) */
1042     }
1043     if (ptype == LIPS4 || ptype == BJC880J) {
1044 	if (lips4->ManualFeed ||
1045 	    (strcmp(lips4->mediaType, "PlainPaper") != 0 && strcmp(lips4->mediaType, LIPS_MEDIATYPE_DEFAULT) != 0)) {
1046 	    if (lips->prev_feed_mode != 10)
1047 		fprintf(prn_stream, "%c10q", LIPS_CSI);
1048 	    lips->prev_feed_mode = 10;
1049 	} else {
1050 	    if (lips->prev_feed_mode != lips->cassetFeed)
1051 		fprintf(prn_stream, "%c%dq", LIPS_CSI, lips->cassetFeed);
1052 	    lips->prev_feed_mode = lips->cassetFeed;
1053 	}
1054     } else if (lips->ManualFeed) {	/* Use ManualFeed */
1055 	if (lips->prev_feed_mode != 1)
1056 	    fprintf(prn_stream, "%c1q", LIPS_CSI);
1057 	lips->prev_feed_mode = 1;
1058     } else {
1059 	if (lips->prev_feed_mode != lips->cassetFeed)
1060 	    fprintf(prn_stream, "%c%dq", LIPS_CSI, lips->cassetFeed);
1061 	lips->prev_feed_mode = lips->cassetFeed;
1062     }
1063 
1064     /* Use Verious Paper Size */
1065     prev_paper_size = lips->prev_paper_size;
1066     prev_paper_width = lips->prev_paper_width;
1067     prev_paper_height = lips->prev_paper_height;
1068 
1069     if (prev_paper_size != paper_size) {
1070 	if (paper_size == USER_SIZE) {
1071 	    fprintf(prn_stream, "%c2 I", LIPS_CSI);
1072 	    fprintf(prn_stream, "%c80;%d;%dp", LIPS_CSI,
1073 		    /* modified by shige 06/27 2003
1074 		    width * 10, height * 10); */
1075 		    /* modified by shige 11/09 2003
1076 		    height * 10, width * 10); */
1077 		    (height * 10 > LIPS_HEIGHT_MAX_720)?
1078 		    LIPS_HEIGHT_MAX_720 : (height * 10),
1079 		    (width * 10 > LIPS_WIDTH_MAX_720)?
1080 		    LIPS_WIDTH_MAX_720 : (width * 10));
1081 	} else if (paper_size == USER_SIZE + LANDSCAPE) {
1082 	    fprintf(prn_stream, "%c2 I", LIPS_CSI);
1083 	    fprintf(prn_stream, "%c81;%d;%dp", LIPS_CSI,
1084 		    /* modified by shige 06/27 2003
1085 		    width * 10, height * 10); */
1086 		    /* modified by shige 11/09 2003
1087 		    width * 10, height * 10); */
1088 		    (width * 10 > LIPS_HEIGHT_MAX_720)?
1089 		    LIPS_HEIGHT_MAX_720 : (width * 10),
1090 		    (height * 10 > LIPS_WIDTH_MAX_720)?
1091 		    LIPS_WIDTH_MAX_720 : (height * 10));
1092 	} else {
1093 	    fprintf(prn_stream, "%c%dp", LIPS_CSI, paper_size);
1094 	}
1095     } else if (paper_size == USER_SIZE) {
1096 	if (prev_paper_width != width ||
1097 	    prev_paper_height != height) {
1098 	    fprintf(prn_stream, "%c2 I", LIPS_CSI);
1099 	    fprintf(prn_stream, "%c80;%d;%dp", LIPS_CSI,
1100 		    /* modified by shige 06/27 2003
1101 		    width * 10, height * 10); */
1102 		    /* modified by shige 11/09 2003
1103 		    height * 10, width * 10); */
1104 		    (height * 10 > LIPS_HEIGHT_MAX_720)?
1105 		    LIPS_HEIGHT_MAX_720 : (height * 10),
1106 		    (width * 10 > LIPS_WIDTH_MAX_720)?
1107 		    LIPS_WIDTH_MAX_720 : (width * 10));
1108 	}
1109     } else if (paper_size == USER_SIZE + LANDSCAPE) {
1110 	if (prev_paper_width != width ||
1111 	    prev_paper_height != height) {
1112 	    fprintf(prn_stream, "%c2 I", LIPS_CSI);
1113 	    fprintf(prn_stream, "%c81;%d;%dp", LIPS_CSI,
1114 		    /* modified by shige 06/27 2003
1115 		    height * 10, width * 10); */
1116 		    /* modified by shige 11/09 2003
1117 		    width * 10, height * 10); */
1118 		    (width * 10 > LIPS_HEIGHT_MAX_720)?
1119 		    LIPS_HEIGHT_MAX_720 : (width * 10),
1120 		    (height * 10 > LIPS_WIDTH_MAX_720)?
1121 		    LIPS_WIDTH_MAX_720 : (height * 10));
1122 	}
1123     }
1124     /* desired number of copies */
1125     if (num_copies > 255)
1126 	num_copies = 255;
1127     if (lips->prev_num_copies != num_copies) {
1128 	fprintf(prn_stream, "%c%dv", LIPS_CSI, num_copies);
1129 	lips->prev_num_copies = num_copies;
1130     }
1131     if (ptype == LIPS4) {
1132 	if (lips4->faceup)
1133 	    fprintf(prn_stream, "%c11;12;12~", LIPS_CSI);
1134     }
1135     if (ptype == LIPS4) {
1136 
1137 	if (pdev->PageCount == 0) {
1138 	    /* N-up Printing */
1139 	    if (lips4->nup != 1) {
1140 		fprintf(prn_stream, "%c%d1;;%do", LIPS_CSI, lips4->nup, paper_size);
1141 	    }
1142 	}
1143 	/* Duplex mode */
1144 	{
1145 	    bool dup = lips4->Duplex;
1146 	    int dupset = lips4->Duplex_set;
1147 	    bool tum = lips4->Tumble;
1148 
1149 	    if (dupset && dup) {
1150 		if (lips4->prev_duplex_mode == 0 ||
1151 		    lips4->prev_duplex_mode == 1)
1152 		    fprintf(prn_stream, "%c2;#x", LIPS_CSI);	/* duplex */
1153 		if (!tum) {
1154 		    /* long edge binding */
1155 		    if (lips4->prev_duplex_mode != 2)
1156 			fprintf(prn_stream, "%c0;#w", LIPS_CSI);
1157 		    lips4->prev_duplex_mode = 2;
1158 		} else {
1159 		    /* short edge binding */
1160 		    if (lips4->prev_duplex_mode != 3)
1161 			fprintf(prn_stream, "%c2;#w", LIPS_CSI);
1162 		    lips4->prev_duplex_mode = 3;
1163 		}
1164 	    } else if (dupset && !dup) {
1165 		if (lips4->prev_duplex_mode != 1)
1166 		    fprintf(prn_stream, "%c0;#x", LIPS_CSI);	/* simplex */
1167 		lips4->prev_duplex_mode = 1;
1168 	    }
1169 	}
1170     }
1171     if (pdev->PageCount == 0) {
1172 	/* Display text on printer panel */
1173 	fprintf(prn_stream, "%c2y%s%c", LIPS_DCS, lips->Username, LIPS_ST);
1174 
1175 	fprintf(prn_stream, "%c11h", LIPS_CSI);	/* Size Unit Mode */
1176 
1177 	fprintf(prn_stream, "%c?2;3h", LIPS_CSI);
1178 	/* 2: Disable Auto FF */
1179 	/* 3: Disable Auto CAP Movement */
1180 
1181 	fprintf(prn_stream, "%c?1;4;5;6l", LIPS_CSI);
1182 	/* 1: Disable Auto NF */
1183 	/* 4: Disable Auto LF at CR */
1184 	/* 5: Disable Auto CR at LF */
1185 	/* 6: Disable Auto CR at FF */
1186     }
1187     if (prev_paper_size != paper_size || paper_size == USER_SIZE ||
1188 	paper_size == USER_SIZE + LANDSCAPE) {
1189 	if (ptype == LIPS4 || ptype == BJC880J) {
1190 	    fprintf(prn_stream, "%c?7;%d I", LIPS_CSI,
1191 		    (int)pdev->x_pixels_per_inch);	/* SelectSizeUnit */
1192 	} else {
1193 	    fprintf(prn_stream, "%c7 I", LIPS_CSI);	/* SelectSizeUnit */
1194 	}
1195 
1196 	if (ptype == LIPS4 || ptype == BJC880J)
1197 	  {
1198 	    if (pdev->color_info.depth == 24)
1199 	      fprintf(prn_stream, "%c%d G", LIPS_CSI, NUM_LINES_4C);		/* VMI (dots) */
1200 	    else
1201 	      fprintf(prn_stream, "%c%d G", LIPS_CSI, NUM_LINES);	/* VMI (dots) */
1202 	  }
1203     }
1204     if (prev_paper_size != paper_size) {
1205 	/* Top Margin: 63/300 inch + 5 mm */
1206 	tm = (63. / 300. + 5. / MMETER_PER_INCH - dev_t_margin(pdev)) * pdev->x_pixels_per_inch;
1207 	if (tm > 0)
1208 	    fprintf(prn_stream, "%c%dk", LIPS_CSI, tm);
1209 	if (tm < 0)
1210 	    fprintf(prn_stream, "%c%de", LIPS_CSI, -tm);
1211 
1212 	/* Left Margin: 5 mm left */
1213 	lm = (5. / MMETER_PER_INCH - dev_l_margin(pdev)) * pdev->x_pixels_per_inch;
1214 	if (lm > 0)
1215 	    fprintf(prn_stream, "%c%dj", LIPS_CSI, lm);
1216 	if (lm < 0)
1217 	    fprintf(prn_stream, "%c%da", LIPS_CSI, -lm);
1218 
1219 	/* Set Top/Left Margins */
1220 	fprintf(prn_stream, "%c0;2t", LIPS_CSI);
1221 
1222 	/* Bottom Margin: height */
1223 	bm = pdev->height - (dev_t_margin(pdev) + dev_b_margin(pdev)) * pdev->y_pixels_per_inch;
1224 	fprintf(prn_stream, "%c%de", LIPS_CSI, bm);
1225 	/* Right Margin: width */
1226 	rm = pdev->width - (dev_l_margin(pdev) + dev_r_margin(pdev)) * pdev->x_pixels_per_inch;
1227 	fprintf(prn_stream, "%c%da", LIPS_CSI, rm);
1228 	fprintf(prn_stream, "%c1;3t", LIPS_CSI);
1229 
1230 	/* move CAP to (0, 0) */
1231 	fprintf(prn_stream, "%c%dk\r", LIPS_CSI, bm);
1232     }
1233     lips->prev_paper_size = paper_size;
1234     lips->prev_paper_width = width;
1235     lips->prev_paper_height = height;
1236 }
1237 
1238 private void
lips_job_end(gx_device_printer * pdev,FILE * prn_stream)1239 lips_job_end(gx_device_printer * pdev, FILE * prn_stream)
1240 {
1241     /* Paper eject command */
1242     fprintf(prn_stream, "\r%c", LIPS_FF);
1243 }
1244 
1245 private int lips_delta_compress(byte * inBuff, byte * prevBuff, byte * diffBuff, int Length);
1246 
1247 private int
lips_delta_encode(byte * inBuff,byte * prevBuff,byte * outBuff,byte * diffBuff,int Length)1248 lips_delta_encode(byte * inBuff, byte * prevBuff, byte * outBuff, byte * diffBuff, int Length)
1249 {
1250     int i, j, k, com_size;
1251 
1252 
1253 
1254     com_size = lips_delta_compress(inBuff, prevBuff, diffBuff, Length);
1255     if (com_size < 0) {		/* data is white raster */
1256 	*outBuff = 0x01;
1257 	*(outBuff + 1) = 0000;
1258 	for (k = 0; k < Length; k++)
1259 	    *(prevBuff + k) = 0000;
1260 	return 2;
1261     } else if (com_size == 0) {	/* data is the same raster */
1262 	*outBuff = 0000;
1263 	return 1;
1264     }
1265     for (i = 0; i < com_size / 255; i++) {
1266 	*(outBuff + i) = 0377;
1267     }
1268 
1269     *(outBuff + i) = (byte) (com_size % 255);
1270 
1271     for (j = 0; j < com_size; j++) {
1272 	*(outBuff + i + j + 1) = *(diffBuff + j);
1273     }
1274 
1275     for (k = 0; k < Length; k++)
1276 	*(prevBuff + k) = *(inBuff + k);
1277 
1278 
1279     return i + j + 1;
1280 }
1281 
1282 private int
lips_delta_compress(byte * inBuff,byte * prevBuff,byte * diffBuff,int Length)1283 lips_delta_compress(byte * inBuff, byte * prevBuff, byte * diffBuff, int Length)
1284 {
1285     int i, j;
1286     bool zero_flag = TRUE;
1287     bool same_flag = TRUE;
1288     int num_bytes = 0;
1289     int num_commandbyte = 0;
1290     int size = 0;
1291     int offset = 0;
1292 
1293     for (i = 0; i < Length; i++) {
1294 	if (*(inBuff + i) != 0x00)
1295 	    zero_flag = FALSE;
1296 
1297 	/* Compare Buffer */
1298 	if (*(inBuff + i) != *(prevBuff + i)) {
1299 	    num_bytes++;
1300 
1301 	    if (same_flag == TRUE) {
1302 		/* first byte is offset */
1303 		if (offset > 31)
1304 		    *(diffBuff + size) = 0037;
1305 		else
1306 		    *(diffBuff + size) = offset;
1307 
1308 		size++;
1309 		num_commandbyte++;
1310 
1311 		for (j = 0; j < (offset - 31) / 255; j++) {
1312 		    *(diffBuff + size) = 0377;
1313 		    size++;
1314 		    num_commandbyte++;
1315 		}
1316 
1317 		if ((offset - 31) % 255 >= 0) {
1318 		    *(diffBuff + size) = (offset - 31) % 255;
1319 		    size++;
1320 		    num_commandbyte++;
1321 		}
1322 		same_flag = FALSE;
1323 
1324 	    }
1325 	} else {
1326 	    same_flag = TRUE;
1327 	    offset++;
1328 	}
1329 
1330 	if (num_bytes > 8) {
1331 	    /* write number of data for replace */
1332 	    *(diffBuff + size - num_commandbyte)
1333 		= *(diffBuff + size - num_commandbyte) | 0340;
1334 
1335 	    for (j = 0; j < 8; j++, size++) {
1336 		*(diffBuff + size) = *(inBuff + i + j - 8);
1337 	    }
1338 
1339 	    /* offset is 0 */
1340 	    *(diffBuff + size) = 0000;
1341 	    size++;
1342 
1343 	    num_bytes = 1;
1344 	    same_flag = FALSE;
1345 	    num_commandbyte = 1;
1346 	} else if (same_flag == true && num_bytes > 0) {
1347 	    offset = 1;
1348 
1349 	    /* write number of data for replace */
1350 	    *(diffBuff + size - num_commandbyte)
1351 		= *(diffBuff + size - num_commandbyte) | ((num_bytes - 1) << 5);
1352 
1353 	    /* write a different bytes */
1354 	    for (j = 0; j < num_bytes; j++, size++) {
1355 		*(diffBuff + size) = *(inBuff + i + j - num_bytes);
1356 	    }
1357 	    num_bytes = 0;
1358 	    num_commandbyte = 0;
1359 	}
1360     }
1361 
1362     if (num_bytes > 0) {
1363 	/* write number of data for replace */
1364 	*(diffBuff + size - num_commandbyte)
1365 	    = *(diffBuff + size - num_commandbyte) | ((num_bytes - 1) << 5);
1366 
1367 	for (j = 0; j < num_bytes; j++, size++) {
1368 	    *(diffBuff + size) = *(inBuff + i + j - num_bytes);
1369 	}
1370     }
1371     if (zero_flag)
1372 	return -1;
1373 
1374     return size;
1375 }
1376 
1377 /* This routine work like ``strcat'' */
1378 private int
lips_byte_cat(byte * TotalBuff,byte * Buff,int TotalLen,int Len)1379 lips_byte_cat(byte * TotalBuff, byte * Buff, int TotalLen, int Len)
1380 {
1381     int i;
1382 
1383     for (i = 0; i < Len; i++)
1384 	*(TotalBuff + TotalLen + i) = *(Buff + i);
1385 
1386     return TotalLen + Len;
1387 }
1388