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