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 (float)(-(lm) * (xdpi)), (float)(-(tm) * (ydpi)),\
60 (float)((lm) * 72.0), (float)((bm) * 72.0f),\
61 (float)((rm) * 72.0), (float)((tm) * 72.0f)\
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 (float)(-(lm) * (xdpi)), (float)(-(tm) * (ydpi)),\
75 (float)((lm) * 72.0), (float)((bm) * 72.0),\
76 (float)((rm) * 72.0), (float)((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, gp_file * fp, int num_copies);
176 static void lips_job_end(gx_device_printer * pdev, gp_file * fp);
177 static int lips_open(gx_device * pdev, lips_printer_type ptype);
178 static int lips4c_output_page(gx_device_printer * pdev, gp_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, gp_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, gp_file * prn_stream, lips_printer_type ptype, int numcopies);
184 static int lips4type_print_page_copies(gx_device_printer * pdev, gp_file * prn_stream, int num_copies, int ptype);
185 #else
186 static int lips_print_page_copies(P4(gx_device_printer * pdev, gp_file * prn_stream, lips_printer_type ptype, int numcopies));
187 static int lips_print_page_copies(P4(gx_device_printer * pdev, gp_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 = (int)pdev->MediaSize[0];
218 int height = (int)pdev->MediaSize[1];
219 int xdpi = (int)pdev->x_pixels_per_inch;
220 int ydpi = (int)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 int code = gdev_prn_open_printer(pdev, 1);
264
265 if (code >= 0) {
266 gp_fprintf(ppdev->file, "%c0J%c", LIPS_DCS, LIPS_ST);
267 if (lips->pjl)
268 gp_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 static 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 static 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 static 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 goto userne;
421 } else { /* Check the validity of ``User Name'' characters */
422 int i;
423
424 for (i = 0; i < usern.size; i++)
425 if (usern.data[i] < 0x20 ||
426 usern.data[i] > 0x7e
427 /*
428 && usern.data[i] < 0xa0) ||
429 usern.data[i] > 0xfe
430 */
431 ) {
432 ecode = gs_error_rangecheck;
433 goto userne;
434 }
435 }
436 break;
437 default:
438 ecode = code;
439 userne:param_signal_error(plist, param_name, ecode);
440 /* Fall through. */
441 case 1:
442 usern.data = 0;
443 break;
444 }
445
446 if (ecode < 0)
447 return ecode;
448 code = lprn_put_params(pdev, plist);
449 if (code < 0)
450 return code;
451
452 lips->cassetFeed = cass;
453 lips->pjl = pjl;
454 lips->toner_density = toner_density;
455 lips->toner_saving = toner_saving;
456 lips->toner_saving_set = toner_saving_set;
457
458 if (usern.data != 0 &&
459 bytes_compare(usern.data, usern.size,
460 (const byte *)lips->Username, strlen(lips->Username))
461 ) {
462 memcpy(lips->Username, usern.data, usern.size);
463 lips->Username[usern.size] = 0;
464 }
465 return 0;
466 }
467
468 static int
lips4_put_params(gx_device * pdev,gs_param_list * plist)469 lips4_put_params(gx_device * pdev, gs_param_list * plist)
470 {
471 gx_device_lips4 *const lips4 = (gx_device_lips4 *) pdev;
472 int ecode = 0;
473 int code;
474 gs_param_name param_name;
475 gs_param_string pmedia;
476 bool nup = lips4->nup;
477 bool faceup = lips4->faceup;
478 int old_bpp = pdev->color_info.depth;
479 int bpp = 0;
480
481 switch (code = param_read_int(plist,
482 (param_name = LIPS_OPTION_NUP),
483 &nup)) {
484 case 0:
485 if (nup != 1 && nup != 2 && nup != 4)
486 ecode = gs_error_rangecheck;
487 else
488 break;
489 goto nupe;
490 default:
491 ecode = code;
492 nupe:param_signal_error(plist, param_name, ecode);
493 case 1:
494 break;
495 }
496
497 if ((code = param_read_bool(plist,
498 (param_name = LIPS_OPTION_FACEUP),
499 &faceup)) < 0)
500 param_signal_error(plist, param_name, ecode = code);
501
502 switch (code = param_read_string(plist,
503 (param_name = LIPS_OPTION_MEDIATYPE),
504 &pmedia)) {
505 case 0:
506 if (pmedia.size >= LIPS_MEDIACHAR_MAX) {
507 ecode = gs_error_limitcheck;
508 goto pmediae;
509 } else { /* Check the validity of ``MediaType'' characters */
510 if (strcmp((const char *)pmedia.data, "PlainPaper") != 0 &&
511 strcmp((const char *)pmedia.data, "OHP") != 0 &&
512 strcmp((const char *)pmedia.data, "TransparencyFilm") != 0 && /* same as OHP */
513 strcmp((const char *)pmedia.data, "GlossyFilm") != 0 &&
514 strcmp((const char *)pmedia.data, "CardBoard") != 0
515 ) {
516 ecode = gs_error_rangecheck;
517 goto pmediae;
518 }
519 }
520 break;
521 default:
522 ecode = code;
523 pmediae:param_signal_error(plist, param_name, ecode);
524 /* Fall through. */
525 case 1:
526 pmedia.data = 0;
527 break;
528 }
529
530 switch (code = param_read_int(plist,
531 (param_name = "BitsPerPixel"),
532 &bpp)) {
533 case 0:
534 if (bpp != 1 && bpp != 24)
535 ecode = gs_error_rangecheck;
536 else
537 break;
538 goto bppe;
539 default:
540 ecode = code;
541 bppe:param_signal_error(plist, param_name, ecode);
542 case 1:
543 break;
544 }
545
546 if (bpp != 0)
547 {
548 pdev->color_info.depth = bpp;
549 pdev->color_info.num_components = ((bpp == 1) ? 1 : 3);
550 pdev->color_info.max_gray = (bpp >= 8 ? 255 : 1);
551 pdev->color_info.max_color = (bpp >= 8 ? 255 : bpp > 1 ? 1 : 0);
552 pdev->color_info.dither_grays = (bpp >= 8 ? 5 : 2);
553 pdev->color_info.dither_colors = (bpp >= 8 ? 5 : bpp > 1 ? 2 : 0);
554 dev_proc(pdev, map_rgb_color) = ((bpp == 1) ? gdev_prn_map_rgb_color : gx_default_rgb_map_rgb_color);
555 }
556
557 if (ecode < 0)
558 return ecode;
559 code = lips_put_params(pdev, plist);
560 if (code < 0)
561 return code;
562
563 lips4->nup = nup;
564 lips4->faceup = faceup;
565
566 if (pmedia.data != 0 &&
567 bytes_compare(pmedia.data, pmedia.size,
568 (const byte *)lips4->mediaType, strlen(lips4->mediaType))
569 ) {
570 memcpy(lips4->mediaType, pmedia.data, pmedia.size);
571 lips4->mediaType[pmedia.size] = 0;
572 }
573 if (bpp != 0 && bpp != old_bpp && pdev->is_open)
574 return gs_closedevice(pdev);
575 return 0;
576 }
577
578 /* ------ Internal routines ------ */
579
580 static int
lips2p_print_page_copies(gx_device_printer * pdev,gp_file * prn_stream,int num_copies)581 lips2p_print_page_copies(gx_device_printer * pdev, gp_file * prn_stream, int num_copies)
582 {
583 return lips_print_page_copies(pdev, prn_stream, LIPS2P, num_copies);
584 }
585
586 static int
lips3_print_page_copies(gx_device_printer * pdev,gp_file * prn_stream,int num_copies)587 lips3_print_page_copies(gx_device_printer * pdev, gp_file * prn_stream, int num_copies)
588 {
589 return lips_print_page_copies(pdev, prn_stream, LIPS3, num_copies);
590 }
591
592 #define NUM_LINES 24 /* raster height */
593 #define NUM_LINES_4C 256
594
595 static int
lips_print_page_copies(gx_device_printer * pdev,gp_file * prn_stream,lips_printer_type ptype,int num_copies)596 lips_print_page_copies(gx_device_printer * pdev, gp_file * prn_stream, lips_printer_type ptype, int num_copies)
597 {
598 gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
599 int code = 0;
600 int bpl = gdev_mem_bytes_per_scan_line(pdev);
601 int maxY = lprn->BlockLine / lprn->nBh * lprn->nBh;
602
603 /* Initialize printer. */
604 lips_job_start(pdev, ptype, prn_stream, num_copies);
605
606 if (!(lprn->CompBuf = gs_malloc(pdev->memory->non_gc_memory, bpl * 3 / 2 + 1, maxY, "(CompBuf)")))
607 return_error(gs_error_VMerror);
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(pdev->memory->non_gc_memory, lprn->CompBuf, bpl * 3 / 2 + 1, maxY, "(CompBuf)");
616
617 /* eject page */
618 lips_job_end(pdev, prn_stream);
619
620 return 0;
621 }
622
623 static int
bjc880j_print_page_copies(gx_device_printer * pdev,gp_file * prn_stream,int num_copies)624 bjc880j_print_page_copies(gx_device_printer * pdev, gp_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,gp_file * prn_stream,int num_copies)630 lips4_print_page_copies(gx_device_printer * pdev, gp_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,gp_file * prn_stream,int num_copies,int ptype)636 lips4type_print_page_copies(gx_device_printer * pdev, gp_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(pdev->memory->non_gc_memory, bpl * 3 / 2 + 1, maxY, "(CompBuf)")))
649 return_error(gs_error_VMerror);
650
651 /* This buffer is used by lips_rle_encode(), which can require double
652 input size plus 2 bytes. */
653 if (!(lprn->CompBuf2 = gs_malloc(pdev->memory->non_gc_memory, bpl * 2 + 2, maxY, "(CompBuf2)")))
654 return_error(gs_error_VMerror);
655
656 if (lprn->NegativePrint) {
657 int rm = (int)(pdev->width - (dev_l_margin(pdev) + dev_r_margin(pdev)) * pdev->x_pixels_per_inch);
658 int bm = (int)(pdev->height - (dev_t_margin(pdev) + dev_b_margin(pdev)) * pdev->y_pixels_per_inch);
659 /* Draw black rectangle */
660 gp_fprintf(prn_stream,
661 "%c{%c%da%c%de%c;;;3}",
662 LIPS_CSI, LIPS_CSI, rm, LIPS_CSI, bm, LIPS_CSI);
663 gp_fprintf(prn_stream, "%c%dj%c%dk",
664 LIPS_CSI, rm, LIPS_CSI, bm);
665 }
666
667 lprn->prev_x = lprn->prev_y = 0;
668 code = lprn_print_image(pdev, prn_stream);
669 if (code < 0)
670 return code;
671
672 gs_free(pdev->memory->non_gc_memory, lprn->CompBuf, bpl * 3 / 2 + 1, maxY, "(CompBuf)");
673 gs_free(pdev->memory->non_gc_memory, lprn->CompBuf2, bpl * 3 / 2 + 1, maxY, "(CompBuf2)");
674 }
675 else
676 {
677 code = lips4c_output_page(pdev, prn_stream);
678
679 if (code < 0)
680 return code;
681 }
682
683 /* eject page */
684 lips_job_end(pdev, prn_stream);
685
686 return 0;
687 }
688
689 #if 0
690 /* Send the page to the printer. */
691 static int
692 lips4c_print_page_copies(gx_device_printer * pdev, gp_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 static void
move_cap(gx_device_printer * pdev,gp_file * prn_stream,int x,int y)712 move_cap(gx_device_printer * pdev, gp_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 gp_fprintf(prn_stream, "%c%da", LIPS_CSI, x - lprn->prev_x);
719 else
720 gp_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 gp_fprintf(prn_stream, "%c%de", LIPS_CSI, y - lprn->prev_y);
727 else
728 gp_fprintf(prn_stream, "%c%dk", LIPS_CSI, lprn->prev_y - y);
729
730 lprn->prev_y = y;
731 }
732 }
733
734 static void
draw_bubble(gp_file * prn_stream,int width,int height)735 draw_bubble(gp_file * prn_stream, int width, int height)
736 {
737 /* Draw a rectangle */
738 gp_fprintf(prn_stream,
739 "%c{%c%da%c%de%c}",
740 LIPS_CSI, LIPS_CSI, width, LIPS_CSI, height, LIPS_CSI);
741 gp_fprintf(prn_stream, "%c%dj%c%dk",
742 LIPS_CSI, width, LIPS_CSI, height);
743 }
744
745 #if 0
746 /* Non Compression Version of image_out */
747 static void
748 lips_image_out(gx_device_printer * pdev, gp_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 gp_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 gp_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,gp_file * prn_stream,int x,int y,int width,int height)774 lips2p_image_out(gx_device_printer * pdev, gp_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 gs_sprintf(raw_str, "%c%d;%d;%d.r", LIPS_CSI,
785 width / 8 * height, width / 8, (int)pdev->x_pixels_per_inch);
786 gs_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 gp_fprintf(prn_stream, "%s", comp_str);
791 gp_fwrite(lprn->CompBuf, 1, Len, prn_stream);
792 } else {
793 /* compression result is bad. */
794 gp_fprintf(prn_stream, "%s", raw_str);
795 gp_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,gp_file * prn_stream,int x,int y,int width,int height)803 lips4_image_out(gx_device_printer * pdev, gp_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 gs_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 gs_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 gp_fprintf(prn_stream, "%s", comp_str);
823 gp_fwrite(lprn->CompBuf, 1, Len, prn_stream);
824 } else {
825 /* compression result is bad. */
826 gp_fprintf(prn_stream, "%s", raw_str);
827 gp_fwrite(lprn->TmpBuf, 1, width / 8 * height, prn_stream);
828 }
829 } else {
830 /* 2019-11-28: changed two occurrencies of 'Len' to 'Len_rle' here, but
831 unable to test. */
832 gs_sprintf(comp_str, "%c%d;%d;%d;10;%d.r", LIPS_CSI,
833 Len_rle, width / 8, (int)pdev->x_pixels_per_inch, height);
834 if (Len_rle < width / 8 * height - strlen(comp_str) + strlen(raw_str)) {
835 gp_fprintf(prn_stream, "%s", comp_str);
836 gp_fwrite(lprn->CompBuf2, 1, Len_rle, prn_stream);
837 } else {
838 /* compression result is bad. */
839 gp_fprintf(prn_stream, "%s", raw_str);
840 gp_fwrite(lprn->TmpBuf, 1, width / 8 * height, prn_stream);
841 }
842 }
843
844 if (lprn->ShowBubble)
845 draw_bubble(prn_stream, width, height);
846 }
847
848 static int
lips4c_write_raster(gx_device_printer * pdev,gp_file * prn_stream,byte * pBuff,byte * prevBuff,byte * ComBuff,byte * TotalBuff,byte * diffBuff,int lnum,int raster_height)849 lips4c_write_raster(gx_device_printer * pdev, gp_file * prn_stream, byte * pBuff, byte * prevBuff, byte * ComBuff, byte * TotalBuff, byte * diffBuff, int lnum, int raster_height)
850 {
851 int bits_per_pixel = pdev->color_info.depth;
852 int num_components = bits_per_pixel > 8 ? 3 : 1;
853 int nBytesPerLine = gdev_prn_raster(pdev);
854 int Xpixel = nBytesPerLine / num_components;
855 int TotalLen = 0;
856 int num_zerobyte = 0;
857 bool zerobyte_flag = false;
858 int i, y, Len;
859
860 for (i = 0; i < nBytesPerLine; i++) {
861 *(prevBuff + i) = 0x00; /* initialize */
862 }
863
864 for (y = lnum; y < lnum + raster_height; y++) {
865 gdev_prn_copy_scan_lines(pdev, y, pBuff, nBytesPerLine);
866
867 Len = lips_delta_encode(pBuff,
868 prevBuff, ComBuff, diffBuff,
869 Xpixel * num_components);
870
871 if (Len == 2 && *ComBuff == 0x01) {
872 if (zerobyte_flag == false) {
873 zerobyte_flag = true;
874 TotalLen = lips_byte_cat(TotalBuff, ComBuff, TotalLen, Len);
875 } else {
876 if (num_zerobyte > 255) {
877 TotalLen = lips_byte_cat(TotalBuff, ComBuff, TotalLen, Len);
878 } else {
879 *(TotalBuff + TotalLen - 1) = num_zerobyte;
880 }
881 num_zerobyte++;
882 }
883 } else {
884 TotalLen = lips_byte_cat(TotalBuff, ComBuff, TotalLen, Len);
885 zerobyte_flag = false;
886 num_zerobyte = 0;
887 }
888 }
889
890 gp_fprintf(prn_stream, "%c%d;%d;%d;12;%d;;%d;%d;;1.r", LIPS_CSI,
891 TotalLen, Xpixel, (int)pdev->x_pixels_per_inch,
892 raster_height,
893 bits_per_pixel / num_components,
894 num_components < 3 ? 0 : 10);
895 gp_fwrite(TotalBuff, 1, TotalLen, prn_stream);
896 gp_fputc(0x85, prn_stream); /* CR + LF */
897
898 return 0;
899 }
900
901 static int
lips4c_output_page(gx_device_printer * pdev,gp_file * prn_stream)902 lips4c_output_page(gx_device_printer * pdev, gp_file * prn_stream)
903 {
904 byte *pBuff, *ComBuff, *prevBuff, *TotalBuff, *diffBuff;
905 int bits_per_pixel = pdev->color_info.depth;
906 int num_components = bits_per_pixel > 8 ? 3 : 1;
907 int nBytesPerLine = gdev_prn_raster(pdev);
908 int Xpixel = nBytesPerLine / num_components;
909 int lnum = 0;
910
911 /* Memory Allocate */
912 if (!(pBuff = (byte *) gs_malloc(pdev->memory->non_gc_memory, nBytesPerLine, sizeof(byte), "lips4c_compress_output_page(pBuff)")))
913 return_error(gs_error_VMerror);
914 if (!(prevBuff = (byte *) gs_malloc(pdev->memory->non_gc_memory, nBytesPerLine, sizeof(byte), "lips4c_compress_output_page(prevBuff)")))
915 return_error(gs_error_VMerror);
916 if (!(ComBuff = (byte *) gs_malloc(pdev->memory->non_gc_memory, Xpixel * num_components + (Xpixel * num_components + 127) * 129 / 128, sizeof(byte), "lips4c_compress_output_page(ComBuff)")))
917 return_error(gs_error_VMerror);
918 if (!(TotalBuff = (byte *) gs_malloc(pdev->memory->non_gc_memory, (Xpixel * num_components + (Xpixel * num_components + 127) * 129 / 128) * NUM_LINES_4C, sizeof(byte), "lips4c_compress_output_page(TotalBuff)")))
919 return_error(gs_error_VMerror);
920 if (!(diffBuff = (byte *) gs_malloc(pdev->memory->non_gc_memory, Xpixel * num_components * 2, sizeof(byte), "lips_print_page")))
921 return_error(gs_error_VMerror);
922
923 /* make output data */
924 while (lnum < pdev->height) {
925 lips4c_write_raster(pdev, prn_stream, pBuff, prevBuff, ComBuff,
926 TotalBuff, diffBuff, lnum, NUM_LINES_4C);
927 lnum += NUM_LINES_4C;
928 }
929
930 if (pdev->height - (lnum - NUM_LINES_4C) > 0) {
931 lips4c_write_raster(pdev, prn_stream, pBuff, prevBuff, ComBuff,
932 TotalBuff, diffBuff, lnum - NUM_LINES_4C,
933 pdev->height - (lnum - NUM_LINES_4C));
934 }
935 /* Free Memory */
936 gs_free(pdev->memory->non_gc_memory, pBuff, nBytesPerLine, sizeof(byte), "lips4c_compress_output_page(pBuff)");
937 gs_free(pdev->memory->non_gc_memory, prevBuff, nBytesPerLine, sizeof(byte), "lips4c_compress_output_page(prevBuff)");
938 gs_free(pdev->memory->non_gc_memory, ComBuff, Xpixel * num_components + (Xpixel * num_components + 127) * 129 / 128, sizeof(byte), "lips4c_compress_output_page(ComBuff)");
939 gs_free(pdev->memory->non_gc_memory, TotalBuff, (Xpixel * num_components + (Xpixel * num_components + 127) * 129 / 128) * NUM_LINES_4C, sizeof(byte), "lips4c_compress_output_page(TotalBuff)");
940 gs_free(pdev->memory->non_gc_memory, diffBuff, Xpixel * num_components * 2, sizeof(byte), "lips_print_page");
941
942 return 0;
943 }
944
945 static void
lips_job_start(gx_device_printer * pdev,lips_printer_type ptype,gp_file * prn_stream,int num_copies)946 lips_job_start(gx_device_printer * pdev, lips_printer_type ptype, gp_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 = (int)pdev->MediaSize[0];
952 int height = (int)pdev->MediaSize[1];
953 int tm, lm, rm, bm;
954
955 if (pdev->PageCount == 0) {
956 if (lips->pjl) {
957 gp_fprintf(prn_stream,
958 "%c%%-12345X@PJL CJLMODE\n"
959 "@PJL JOB\n", LIPS_ESC);
960 if (ptype == LIPS4) {
961 gp_fprintf(prn_stream,
962 "%c%%-12345X@PJL CJLMODE\n", LIPS_ESC);
963 if ((int)pdev->x_pixels_per_inch == 1200)
964 gp_fprintf(prn_stream, "@PJL SET RESOLUTION = SUPERFINE\n");
965 else if ((int)pdev->x_pixels_per_inch == 600)
966 gp_fprintf(prn_stream, "@PJL SET RESOLUTION = FINE\n");
967 else if ((int)pdev->x_pixels_per_inch == 300)
968 gp_fprintf(prn_stream, "@PJL SET RESOLUTION = QUICK\n");
969 }
970 if (lips->toner_density)
971 gp_fprintf(prn_stream, "@PJL SET TONER-DENSITY=%d\n",
972 lips->toner_density);
973 if (lips->toner_saving_set) {
974 gp_fprintf(prn_stream, "@PJL SET TONER-SAVING=");
975 if (lips->toner_saving)
976 gp_fprintf(prn_stream, "ON\n");
977 else
978 gp_fprintf(prn_stream, "OFF\n");
979 }
980 gp_fprintf(prn_stream,
981 "@PJL SET LPARM : LIPS SW2 = ON\n"
982 "@PJL ENTER LANGUAGE = LIPS\n");
983 }
984 gp_fprintf(prn_stream, "%c%%@", LIPS_ESC);
985 if (ptype == LIPS2P)
986 gp_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 gp_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 gp_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 gp_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 gp_fprintf(prn_stream, "%c1\"p", LIPS_CSI);
1002 else
1003 gp_fprintf(prn_stream, "%c0\"p", LIPS_CSI);
1004 }
1005 gp_fprintf(prn_stream, "%c<", LIPS_ESC);
1006 gp_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 gp_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 gp_fprintf(prn_stream, "%c4&z", LIPS_CSI);
1029 else
1030 gp_fprintf(prn_stream, "%c2&z", LIPS_CSI);
1031 }
1032 if (ptype == LIPS4) {
1033 if (strcmp(lips4->mediaType, "PlainPaper") == 0)
1034 gp_fprintf(prn_stream, "%c20\'t", LIPS_CSI);
1035 else if (strcmp(lips4->mediaType, "OHP") == 0 ||
1036 strcmp(lips4->mediaType, "TransparencyFilm") == 0)
1037 gp_fprintf(prn_stream, "%c40\'t", LIPS_CSI); /* OHP mode (for LBP-2160) */
1038 else if (strcmp(lips4->mediaType, "CardBoard") == 0)
1039 gp_fprintf(prn_stream, "%c30\'t", LIPS_CSI); /* CardBoard mode (for LBP-2160) */
1040 else if (strcmp(lips4->mediaType, "GlossyFilm") == 0)
1041 gp_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 gp_fprintf(prn_stream, "%c10q", LIPS_CSI);
1048 lips->prev_feed_mode = 10;
1049 } else {
1050 if (lips->prev_feed_mode != lips->cassetFeed)
1051 gp_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 gp_fprintf(prn_stream, "%c1q", LIPS_CSI);
1057 lips->prev_feed_mode = 1;
1058 } else {
1059 if (lips->prev_feed_mode != lips->cassetFeed)
1060 gp_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 gp_fprintf(prn_stream, "%c2 I", LIPS_CSI);
1072 gp_fprintf(prn_stream, "%c80;%d;%dp", LIPS_CSI,
1073 width * 10, height * 10);
1074 } else if (paper_size == USER_SIZE + LANDSCAPE) {
1075 gp_fprintf(prn_stream, "%c2 I", LIPS_CSI);
1076 gp_fprintf(prn_stream, "%c81;%d;%dp", LIPS_CSI,
1077 height * 10, width * 10);
1078 } else {
1079 gp_fprintf(prn_stream, "%c%dp", LIPS_CSI, paper_size);
1080 }
1081 } else if (paper_size == USER_SIZE) {
1082 if (prev_paper_width != width ||
1083 prev_paper_height != height) {
1084 gp_fprintf(prn_stream, "%c2 I", LIPS_CSI);
1085 gp_fprintf(prn_stream, "%c80;%d;%dp", LIPS_CSI,
1086 width * 10, height * 10);
1087 }
1088 } else if (paper_size == USER_SIZE + LANDSCAPE) {
1089 if (prev_paper_width != width ||
1090 prev_paper_height != height) {
1091 gp_fprintf(prn_stream, "%c2 I", LIPS_CSI);
1092 gp_fprintf(prn_stream, "%c81;%d;%dp", LIPS_CSI,
1093 height * 10, width * 10);
1094 }
1095 }
1096 /* desired number of copies */
1097 if (num_copies > 255)
1098 num_copies = 255;
1099 if (lips->prev_num_copies != num_copies) {
1100 gp_fprintf(prn_stream, "%c%dv", LIPS_CSI, num_copies);
1101 lips->prev_num_copies = num_copies;
1102 }
1103 if (ptype == LIPS4) {
1104 if (lips4->faceup)
1105 gp_fprintf(prn_stream, "%c11;12;12~", LIPS_CSI);
1106 }
1107 if (ptype == LIPS4) {
1108
1109 if (pdev->PageCount == 0) {
1110 /* N-up Printing */
1111 if (lips4->nup != 1) {
1112 gp_fprintf(prn_stream, "%c%d1;;%do", LIPS_CSI, lips4->nup, paper_size);
1113 }
1114 }
1115 /* Duplex mode */
1116 {
1117 bool dup = lips4->Duplex;
1118 int dupset = lips4->Duplex_set;
1119 bool tum = lips4->Tumble;
1120
1121 if (dupset && dup) {
1122 if (lips4->prev_duplex_mode == 0 ||
1123 lips4->prev_duplex_mode == 1)
1124 gp_fprintf(prn_stream, "%c2;#x", LIPS_CSI); /* duplex */
1125 if (!tum) {
1126 /* long edge binding */
1127 if (lips4->prev_duplex_mode != 2)
1128 gp_fprintf(prn_stream, "%c0;#w", LIPS_CSI);
1129 lips4->prev_duplex_mode = 2;
1130 } else {
1131 /* short edge binding */
1132 if (lips4->prev_duplex_mode != 3)
1133 gp_fprintf(prn_stream, "%c2;#w", LIPS_CSI);
1134 lips4->prev_duplex_mode = 3;
1135 }
1136 } else if (dupset && !dup) {
1137 if (lips4->prev_duplex_mode != 1)
1138 gp_fprintf(prn_stream, "%c0;#x", LIPS_CSI); /* simplex */
1139 lips4->prev_duplex_mode = 1;
1140 }
1141 }
1142 }
1143 if (pdev->PageCount == 0) {
1144 /* Display text on printer panel */
1145 gp_fprintf(prn_stream, "%c2y%s%c", LIPS_DCS, lips->Username, LIPS_ST);
1146
1147 gp_fprintf(prn_stream, "%c11h", LIPS_CSI); /* Size Unit Mode */
1148
1149 gp_fprintf(prn_stream, "%c?2;3h", LIPS_CSI);
1150 /* 2: Disable Auto FF */
1151 /* 3: Disable Auto CAP Movement */
1152
1153 gp_fprintf(prn_stream, "%c?1;4;5;6l", LIPS_CSI);
1154 /* 1: Disable Auto NF */
1155 /* 4: Disable Auto LF at CR */
1156 /* 5: Disable Auto CR at LF */
1157 /* 6: Disable Auto CR at FF */
1158 }
1159 if (prev_paper_size != paper_size || paper_size == USER_SIZE ||
1160 paper_size == USER_SIZE + LANDSCAPE) {
1161 if (ptype == LIPS4 || ptype == BJC880J) {
1162 gp_fprintf(prn_stream, "%c?7;%d I", LIPS_CSI,
1163 (int)pdev->x_pixels_per_inch); /* SelectSizeUnit */
1164 } else {
1165 gp_fprintf(prn_stream, "%c7 I", LIPS_CSI); /* SelectSizeUnit */
1166 }
1167
1168 if (ptype == LIPS4 || ptype == BJC880J)
1169 {
1170 if (pdev->color_info.depth == 24)
1171 gp_fprintf(prn_stream, "%c%d G", LIPS_CSI, NUM_LINES_4C); /* VMI (dots) */
1172 else
1173 gp_fprintf(prn_stream, "%c%d G", LIPS_CSI, NUM_LINES); /* VMI (dots) */
1174 }
1175 }
1176 if (prev_paper_size != paper_size) {
1177 /* Top Margin: 63/300 inch + 5 mm */
1178 tm = (int)((63. / 300. + 5. / MMETER_PER_INCH - dev_t_margin(pdev)) * pdev->x_pixels_per_inch);
1179 if (tm > 0)
1180 gp_fprintf(prn_stream, "%c%dk", LIPS_CSI, tm);
1181 if (tm < 0)
1182 gp_fprintf(prn_stream, "%c%de", LIPS_CSI, -tm);
1183
1184 /* Left Margin: 5 mm left */
1185 lm = (int)((5. / MMETER_PER_INCH - dev_l_margin(pdev)) * pdev->x_pixels_per_inch);
1186 if (lm > 0)
1187 gp_fprintf(prn_stream, "%c%dj", LIPS_CSI, lm);
1188 if (lm < 0)
1189 gp_fprintf(prn_stream, "%c%da", LIPS_CSI, -lm);
1190
1191 /* Set Top/Left Margins */
1192 gp_fprintf(prn_stream, "%c0;2t", LIPS_CSI);
1193
1194 /* Bottom Margin: height */
1195 bm = (int)(pdev->height - (dev_t_margin(pdev) + dev_b_margin(pdev)) * pdev->y_pixels_per_inch);
1196 gp_fprintf(prn_stream, "%c%de", LIPS_CSI, bm);
1197 /* Right Margin: width */
1198 rm = (int)(pdev->width - (dev_l_margin(pdev) + dev_r_margin(pdev)) * pdev->x_pixels_per_inch);
1199 gp_fprintf(prn_stream, "%c%da", LIPS_CSI, rm);
1200 gp_fprintf(prn_stream, "%c1;3t", LIPS_CSI);
1201
1202 /* move CAP to (0, 0) */
1203 gp_fprintf(prn_stream, "%c%dk\r", LIPS_CSI, bm);
1204 }
1205 lips->prev_paper_size = paper_size;
1206 lips->prev_paper_width = width;
1207 lips->prev_paper_height = height;
1208 }
1209
1210 static void
lips_job_end(gx_device_printer * pdev,gp_file * prn_stream)1211 lips_job_end(gx_device_printer * pdev, gp_file * prn_stream)
1212 {
1213 /* Paper eject command */
1214 gp_fprintf(prn_stream, "\r%c", LIPS_FF);
1215 }
1216
1217 static int lips_delta_compress(byte * inBuff, byte * prevBuff, byte * diffBuff, int Length);
1218
1219 static int
lips_delta_encode(byte * inBuff,byte * prevBuff,byte * outBuff,byte * diffBuff,int Length)1220 lips_delta_encode(byte * inBuff, byte * prevBuff, byte * outBuff, byte * diffBuff, int Length)
1221 {
1222 int i, j, k, com_size;
1223
1224 com_size = lips_delta_compress(inBuff, prevBuff, diffBuff, Length);
1225 if (com_size < 0) { /* data is white raster */
1226 *outBuff = 0x01;
1227 *(outBuff + 1) = 0000;
1228 for (k = 0; k < Length; k++)
1229 *(prevBuff + k) = 0000;
1230 return 2;
1231 } else if (com_size == 0) { /* data is the same raster */
1232 *outBuff = 0000;
1233 return 1;
1234 }
1235 for (i = 0; i < com_size / 255; i++) {
1236 *(outBuff + i) = 0377;
1237 }
1238
1239 *(outBuff + i) = (byte) (com_size % 255);
1240
1241 for (j = 0; j < com_size; j++) {
1242 *(outBuff + i + j + 1) = *(diffBuff + j);
1243 }
1244
1245 for (k = 0; k < Length; k++)
1246 *(prevBuff + k) = *(inBuff + k);
1247
1248 return i + j + 1;
1249 }
1250
1251 static int
lips_delta_compress(byte * inBuff,byte * prevBuff,byte * diffBuff,int Length)1252 lips_delta_compress(byte * inBuff, byte * prevBuff, byte * diffBuff, int Length)
1253 {
1254 int i, j;
1255 bool zero_flag = TRUE;
1256 bool same_flag = TRUE;
1257 int num_bytes = 0;
1258 int num_commandbyte = 0;
1259 int size = 0;
1260 int offset = 0;
1261
1262 for (i = 0; i < Length; i++) {
1263 if (*(inBuff + i) != 0x00)
1264 zero_flag = FALSE;
1265
1266 /* Compare Buffer */
1267 if (*(inBuff + i) != *(prevBuff + i)) {
1268 num_bytes++;
1269
1270 if (same_flag == TRUE) {
1271 /* first byte is offset */
1272 if (offset > 31)
1273 *(diffBuff + size) = 0037;
1274 else
1275 *(diffBuff + size) = offset;
1276
1277 size++;
1278 num_commandbyte++;
1279
1280 for (j = 0; j < (offset - 31) / 255; j++) {
1281 *(diffBuff + size) = 0377;
1282 size++;
1283 num_commandbyte++;
1284 }
1285
1286 if ((offset - 31) % 255 >= 0) {
1287 *(diffBuff + size) = (offset - 31) % 255;
1288 size++;
1289 num_commandbyte++;
1290 }
1291 same_flag = FALSE;
1292
1293 }
1294 } else {
1295 same_flag = TRUE;
1296 offset++;
1297 }
1298
1299 if (num_bytes > 8) {
1300 /* write number of data for replace */
1301 *(diffBuff + size - num_commandbyte)
1302 = *(diffBuff + size - num_commandbyte) | 0340;
1303
1304 for (j = 0; j < 8; j++, size++) {
1305 *(diffBuff + size) = *(inBuff + i + j - 8);
1306 }
1307
1308 /* offset is 0 */
1309 *(diffBuff + size) = 0000;
1310 size++;
1311
1312 num_bytes = 1;
1313 same_flag = FALSE;
1314 num_commandbyte = 1;
1315 } else if (same_flag == true && num_bytes > 0) {
1316 offset = 1;
1317
1318 /* write number of data for replace */
1319 *(diffBuff + size - num_commandbyte)
1320 = *(diffBuff + size - num_commandbyte) | ((num_bytes - 1) << 5);
1321
1322 /* write a different bytes */
1323 for (j = 0; j < num_bytes; j++, size++) {
1324 *(diffBuff + size) = *(inBuff + i + j - num_bytes);
1325 }
1326 num_bytes = 0;
1327 num_commandbyte = 0;
1328 }
1329 }
1330
1331 if (num_bytes > 0) {
1332 /* write number of data for replace */
1333 *(diffBuff + size - num_commandbyte)
1334 = *(diffBuff + size - num_commandbyte) | ((num_bytes - 1) << 5);
1335
1336 for (j = 0; j < num_bytes; j++, size++) {
1337 *(diffBuff + size) = *(inBuff + i + j - num_bytes);
1338 }
1339 }
1340 if (zero_flag)
1341 return -1;
1342
1343 return size;
1344 }
1345
1346 /* This routine work like ``strcat'' */
1347 static int
lips_byte_cat(byte * TotalBuff,byte * Buff,int TotalLen,int Len)1348 lips_byte_cat(byte * TotalBuff, byte * Buff, int TotalLen, int Len)
1349 {
1350 int i;
1351
1352 for (i = 0; i < Len; i++)
1353 *(TotalBuff + TotalLen + i) = *(Buff + i);
1354
1355 return TotalLen + Len;
1356 }
1357