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 /* ------ Internal routines ------ */
576
577 static int
lips2p_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_copies)578 lips2p_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, int num_copies)
579 {
580 return lips_print_page_copies(pdev, prn_stream, LIPS2P, num_copies);
581 }
582
583 static int
lips3_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_copies)584 lips3_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, int num_copies)
585 {
586 return lips_print_page_copies(pdev, prn_stream, LIPS3, num_copies);
587 }
588
589 #define NUM_LINES 24 /* raster height */
590 #define NUM_LINES_4C 256
591
592 static int
lips_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,lips_printer_type ptype,int num_copies)593 lips_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, lips_printer_type ptype, int num_copies)
594 {
595 gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
596 int code = 0;
597 int bpl = gdev_mem_bytes_per_scan_line(pdev);
598 int maxY = lprn->BlockLine / lprn->nBh * lprn->nBh;
599
600 /* Initialize printer. */
601 lips_job_start(pdev, ptype, prn_stream, num_copies);
602
603 if (!(lprn->CompBuf = gs_malloc(gs_lib_ctx_get_non_gc_memory_t(), bpl * 3 / 2 + 1, maxY, "(CompBuf)")))
604 return_error(gs_error_VMerror);
605
606 lprn->NegativePrint = false; /* not support */
607 lprn->prev_x = lprn->prev_y = 0;
608 code = lprn_print_image(pdev, prn_stream);
609 if (code < 0)
610 return code;
611
612 gs_free(gs_lib_ctx_get_non_gc_memory_t(), lprn->CompBuf, bpl * 3 / 2 + 1, maxY, "(CompBuf)");
613
614 /* eject page */
615 lips_job_end(pdev, prn_stream);
616
617 return 0;
618 }
619
620 static int
bjc880j_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_copies)621 bjc880j_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, int num_copies)
622 {
623 return lips4type_print_page_copies(pdev, prn_stream, num_copies, BJC880J);
624 }
625
626 static int
lips4_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_copies)627 lips4_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, int num_copies)
628 {
629 return lips4type_print_page_copies(pdev, prn_stream, num_copies, LIPS4);
630 }
631
632 static int
lips4type_print_page_copies(gx_device_printer * pdev,FILE * prn_stream,int num_copies,int ptype)633 lips4type_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, int num_copies, int ptype)
634 {
635 gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
636 int code = 0;
637 int bpl = gdev_mem_bytes_per_scan_line(pdev);
638 int maxY = lprn->BlockLine / lprn->nBh * lprn->nBh;
639
640 /* Initialize printer. */
641 lips_job_start(pdev, ptype, prn_stream, num_copies);
642
643 if (pdev->color_info.depth == 1)
644 {
645 if (!(lprn->CompBuf = gs_malloc(gs_lib_ctx_get_non_gc_memory_t(), bpl * 3 / 2 + 1, maxY, "(CompBuf)")))
646 return_error(gs_error_VMerror);
647 if (!(lprn->CompBuf2 = gs_malloc(gs_lib_ctx_get_non_gc_memory_t(), bpl * 3 / 2 + 1, maxY, "(CompBuf2)")))
648 return_error(gs_error_VMerror);
649
650 if (lprn->NegativePrint) {
651 int rm = pdev->width - (dev_l_margin(pdev) + dev_r_margin(pdev)) * pdev->x_pixels_per_inch;
652 int bm = pdev->height - (dev_t_margin(pdev) + dev_b_margin(pdev)) * pdev->y_pixels_per_inch;
653 /* Draw black rectangle */
654 fprintf(prn_stream,
655 "%c{%c%da%c%de%c;;;3}",
656 LIPS_CSI, LIPS_CSI, rm, LIPS_CSI, bm, LIPS_CSI);
657 fprintf(prn_stream, "%c%dj%c%dk",
658 LIPS_CSI, rm, LIPS_CSI, bm);
659 }
660
661 lprn->prev_x = lprn->prev_y = 0;
662 code = lprn_print_image(pdev, prn_stream);
663 if (code < 0)
664 return code;
665
666 gs_free(gs_lib_ctx_get_non_gc_memory_t(), lprn->CompBuf, bpl * 3 / 2 + 1, maxY, "(CompBuf)");
667 gs_free(gs_lib_ctx_get_non_gc_memory_t(), lprn->CompBuf2, bpl * 3 / 2 + 1, maxY, "(CompBuf2)");
668 }
669 else
670 {
671 code = lips4c_output_page(pdev, prn_stream);
672
673 if (code < 0)
674 return code;
675 }
676
677 /* eject page */
678 lips_job_end(pdev, prn_stream);
679
680 return 0;
681 }
682
683 #if 0
684 /* Send the page to the printer. */
685 static int
686 lips4c_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, int num_copies)
687 {
688 int code;
689
690 lips_job_start(pdev, BJC880J, prn_stream, num_copies);
691
692 /* make output data */
693 code = lips4c_output_page(pdev, prn_stream);
694
695 if (code < 0)
696 return code;
697
698 /* eject page */
699 lips_job_end(pdev, prn_stream);
700
701 return 0;
702 }
703 #endif
704
705 static void
move_cap(gx_device_printer * pdev,FILE * prn_stream,int x,int y)706 move_cap(gx_device_printer * pdev, FILE * prn_stream, int x, int y)
707 {
708 gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
709
710 if (x != lprn->prev_x) {
711 if (x > lprn->prev_x)
712 fprintf(prn_stream, "%c%da", LIPS_CSI, x - lprn->prev_x);
713 else
714 fprintf(prn_stream, "%c%dj", LIPS_CSI, lprn->prev_x - x);
715
716 lprn->prev_x = x;
717 }
718 if (y != lprn->prev_y) {
719 if (y > lprn->prev_y)
720 fprintf(prn_stream, "%c%de", LIPS_CSI, y - lprn->prev_y);
721 else
722 fprintf(prn_stream, "%c%dk", LIPS_CSI, lprn->prev_y - y);
723
724 lprn->prev_y = y;
725 }
726 }
727
728 static void
draw_bubble(FILE * prn_stream,int width,int height)729 draw_bubble(FILE * prn_stream, int width, int height)
730 {
731 /* Draw a rectangle */
732 fprintf(prn_stream,
733 "%c{%c%da%c%de%c}",
734 LIPS_CSI, LIPS_CSI, width, LIPS_CSI, height, LIPS_CSI);
735 fprintf(prn_stream, "%c%dj%c%dk",
736 LIPS_CSI, width, LIPS_CSI, height);
737 }
738
739 #if 0
740 /* Non Compression Version of image_out */
741 static void
742 lips_image_out(gx_device_printer * pdev, FILE * prn_stream, int x, int y, int width, int height)
743 {
744 gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
745
746 int i, j;
747 byte *p;
748 int maxY = lprn->BlockLine / lprn->nBh * lprn->nBh;
749
750 move_cap(pdev, prn_stream, x, y);
751
752 fprintf(prn_stream, "%c%d;%d;%d.r", LIPS_CSI,
753 width / 8 * height, width / 8, (int)pdev->x_pixels_per_inch);
754
755 for (i = 0; i < height; i++) {
756 p = lprn->ImageBuf + ((i + y) % maxY) * raster;
757 for (j = 0; j < width / 8; j++) {
758 fputc(p[j + data_x], prn_stream);
759 }
760 }
761
762 if (lprn->ShowBubble)
763 draw_bubble(prn_stream, width, height);
764 }
765 #endif
766
767 static void
lips2p_image_out(gx_device_printer * pdev,FILE * prn_stream,int x,int y,int width,int height)768 lips2p_image_out(gx_device_printer * pdev, FILE * prn_stream, int x, int y, int width, int height)
769 {
770 gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
771 int Len;
772 char raw_str[32]; /* LIPS command header (uncompress) */
773 char comp_str[32]; /* LIPS command header (compress) */
774
775 move_cap(pdev, prn_stream, x, y);
776
777 Len = lips_mode3format_encode(lprn->TmpBuf, lprn->CompBuf, width / 8 * height);
778 sprintf(raw_str, "%c%d;%d;%d.r", LIPS_CSI,
779 width / 8 * height, width / 8, (int)pdev->x_pixels_per_inch);
780 sprintf(comp_str, "%c%d;%d;%d;9;%d.r", LIPS_CSI,
781 Len, width / 8, (int)pdev->x_pixels_per_inch, height);
782
783 if (Len < width / 8 * height - strlen(comp_str) + strlen(raw_str)) {
784 fprintf(prn_stream, "%s", comp_str);
785 fwrite(lprn->CompBuf, 1, Len, prn_stream);
786 } else {
787 /* compression result is bad. */
788 fprintf(prn_stream, "%s", raw_str);
789 fwrite(lprn->TmpBuf, 1, width / 8 * height, prn_stream);
790 }
791
792 if (lprn->ShowBubble)
793 draw_bubble(prn_stream, width, height);
794 }
795
796 static void
lips4_image_out(gx_device_printer * pdev,FILE * prn_stream,int x,int y,int width,int height)797 lips4_image_out(gx_device_printer * pdev, FILE * prn_stream, int x, int y, int width, int height)
798 {
799 gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
800 int Len, Len_rle;
801 char raw_str[32]; /* LIPS command header (uncompress) */
802 char comp_str[32]; /* LIPS command header (compress) */
803
804 move_cap(pdev, prn_stream, x, y);
805
806 Len = lips_packbits_encode(lprn->TmpBuf, lprn->CompBuf, width / 8 * height);
807 Len_rle = lips_rle_encode(lprn->TmpBuf, lprn->CompBuf2, width / 8 * height);
808
809 sprintf(raw_str, "%c%d;%d;%d.r", LIPS_CSI,
810 width / 8 * height, width / 8, (int)pdev->x_pixels_per_inch);
811
812 if (Len < Len_rle) {
813 sprintf(comp_str, "%c%d;%d;%d;11;%d.r", LIPS_CSI,
814 Len, width / 8, (int)pdev->x_pixels_per_inch, height);
815 if (Len < width / 8 * height - strlen(comp_str) + strlen(raw_str)) {
816 fprintf(prn_stream, "%s", comp_str);
817 fwrite(lprn->CompBuf, 1, Len, prn_stream);
818 } else {
819 /* compression result is bad. */
820 fprintf(prn_stream, "%s", raw_str);
821 fwrite(lprn->TmpBuf, 1, width / 8 * height, prn_stream);
822 }
823 } else {
824 sprintf(comp_str, "%c%d;%d;%d;10;%d.r", LIPS_CSI,
825 Len, width / 8, (int)pdev->x_pixels_per_inch, height);
826 if (Len_rle < width / 8 * height - strlen(comp_str) + strlen(raw_str)) {
827 fprintf(prn_stream, "%s", comp_str);
828 fwrite(lprn->CompBuf2, 1, Len, prn_stream);
829 } else {
830 /* compression result is bad. */
831 fprintf(prn_stream, "%s", raw_str);
832 fwrite(lprn->TmpBuf, 1, width / 8 * height, prn_stream);
833 }
834 }
835
836 if (lprn->ShowBubble)
837 draw_bubble(prn_stream, width, height);
838 }
839
840 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)841 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)
842 {
843 int bits_per_pixel = pdev->color_info.depth;
844 int num_components = bits_per_pixel > 8 ? 3 : 1;
845 int nBytesPerLine = gdev_prn_raster(pdev);
846 int Xpixel = nBytesPerLine / num_components;
847 int TotalLen = 0;
848 int num_zerobyte = 0;
849 bool zerobyte_flag = false;
850 int i, y, Len;
851
852 for (i = 0; i < nBytesPerLine; i++) {
853 *(prevBuff + i) = 0x00; /* initialize */
854 }
855
856 for (y = lnum; y < lnum + raster_height; y++) {
857 gdev_prn_copy_scan_lines(pdev, y, pBuff, nBytesPerLine);
858
859 Len = lips_delta_encode(pBuff,
860 prevBuff, ComBuff, diffBuff,
861 Xpixel * num_components);
862
863 if (Len == 2 && *ComBuff == 0x01) {
864 if (zerobyte_flag == false) {
865 zerobyte_flag = true;
866 TotalLen = lips_byte_cat(TotalBuff, ComBuff, TotalLen, Len);
867 } else {
868 if (num_zerobyte > 255) {
869 TotalLen = lips_byte_cat(TotalBuff, ComBuff, TotalLen, Len);
870 } else {
871 *(TotalBuff + TotalLen - 1) = num_zerobyte;
872 }
873 num_zerobyte++;
874 }
875 } else {
876 TotalLen = lips_byte_cat(TotalBuff, ComBuff, TotalLen, Len);
877 zerobyte_flag = false;
878 num_zerobyte = 0;
879 }
880 }
881
882 fprintf(prn_stream, "%c%d;%d;%d;12;%d;;%d;%d;;1.r", LIPS_CSI,
883 TotalLen, Xpixel, (int)pdev->x_pixels_per_inch,
884 raster_height,
885 bits_per_pixel / num_components,
886 num_components < 3 ? 0 : 10);
887 fwrite(TotalBuff, 1, TotalLen, prn_stream);
888 fputc(0x85, prn_stream); /* CR + LF */
889
890 return 0;
891 }
892
893 static int
lips4c_output_page(gx_device_printer * pdev,FILE * prn_stream)894 lips4c_output_page(gx_device_printer * pdev, FILE * prn_stream)
895 {
896 byte *pBuff, *ComBuff, *prevBuff, *TotalBuff, *diffBuff;
897 int bits_per_pixel = pdev->color_info.depth;
898 int num_components = bits_per_pixel > 8 ? 3 : 1;
899 int nBytesPerLine = gdev_prn_raster(pdev);
900 int Xpixel = nBytesPerLine / num_components;
901 int lnum = 0;
902
903 /* Memory Allocate */
904 if (!(pBuff = (byte *) gs_malloc(gs_lib_ctx_get_non_gc_memory_t(), nBytesPerLine, sizeof(byte), "lips4c_compress_output_page(pBuff)")))
905 return_error(gs_error_VMerror);
906 if (!(prevBuff = (byte *) gs_malloc(gs_lib_ctx_get_non_gc_memory_t(), nBytesPerLine, sizeof(byte), "lips4c_compress_output_page(prevBuff)")))
907 return_error(gs_error_VMerror);
908 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)")))
909 return_error(gs_error_VMerror);
910 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)")))
911 return_error(gs_error_VMerror);
912 if (!(diffBuff = (byte *) gs_malloc(gs_lib_ctx_get_non_gc_memory_t(), Xpixel * num_components * 2, sizeof(byte), "lips_print_page")))
913 return_error(gs_error_VMerror);
914
915 /* make output data */
916 while (lnum < pdev->height) {
917 lips4c_write_raster(pdev, prn_stream, pBuff, prevBuff, ComBuff,
918 TotalBuff, diffBuff, lnum, NUM_LINES_4C);
919 lnum += NUM_LINES_4C;
920 }
921
922 if (pdev->height - (lnum - NUM_LINES_4C) > 0) {
923 lips4c_write_raster(pdev, prn_stream, pBuff, prevBuff, ComBuff,
924 TotalBuff, diffBuff, lnum - NUM_LINES_4C,
925 pdev->height - (lnum - NUM_LINES_4C));
926 }
927 /* Free Memory */
928 gs_free(gs_lib_ctx_get_non_gc_memory_t(), pBuff, nBytesPerLine, sizeof(byte), "lips4c_compress_output_page(pBuff)");
929 gs_free(gs_lib_ctx_get_non_gc_memory_t(), prevBuff, nBytesPerLine, sizeof(byte), "lips4c_compress_output_page(prevBuff)");
930 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)");
931 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)");
932 gs_free(gs_lib_ctx_get_non_gc_memory_t(), diffBuff, Xpixel * num_components * 2, sizeof(byte), "lips_print_page");
933
934 return 0;
935 }
936
937 static void
lips_job_start(gx_device_printer * pdev,lips_printer_type ptype,FILE * prn_stream,int num_copies)938 lips_job_start(gx_device_printer * pdev, lips_printer_type ptype, FILE * prn_stream, int num_copies)
939 {
940 gx_device_lips *const lips = (gx_device_lips *) pdev;
941 gx_device_lips4 *const lips4 = (gx_device_lips4 *) pdev;
942 int prev_paper_size, prev_paper_width, prev_paper_height, paper_size;
943 int width = pdev->MediaSize[0];
944 int height = pdev->MediaSize[1];
945 int tm, lm, rm, bm;
946
947 if (pdev->PageCount == 0) {
948 if (lips->pjl) {
949 fprintf(prn_stream,
950 "%c%%-12345X@PJL CJLMODE\n"
951 "@PJL JOB\n", LIPS_ESC);
952 if (ptype == LIPS4) {
953 fprintf(prn_stream,
954 "%c%%-12345X@PJL CJLMODE\n", LIPS_ESC);
955 if ((int)pdev->x_pixels_per_inch == 1200)
956 fprintf(prn_stream, "@PJL SET RESOLUTION = SUPERFINE\n");
957 else if ((int)pdev->x_pixels_per_inch == 600)
958 fprintf(prn_stream, "@PJL SET RESOLUTION = FINE\n");
959 else if ((int)pdev->x_pixels_per_inch == 300)
960 fprintf(prn_stream, "@PJL SET RESOLUTION = QUICK\n");
961 }
962 if (lips->toner_density)
963 fprintf(prn_stream, "@PJL SET TONER-DENSITY=%d\n",
964 lips->toner_density);
965 if (lips->toner_saving_set) {
966 fprintf(prn_stream, "@PJL SET TONER-SAVING=");
967 if (lips->toner_saving)
968 fprintf(prn_stream, "ON\n");
969 else
970 fprintf(prn_stream, "OFF\n");
971 }
972 fprintf(prn_stream,
973 "@PJL SET LPARM : LIPS SW2 = ON\n"
974 "@PJL ENTER LANGUAGE = LIPS\n");
975 }
976 fprintf(prn_stream, "%c%%@", LIPS_ESC);
977 if (ptype == LIPS2P)
978 fprintf(prn_stream, "%c21;%d;0J" LIPS2P_STRING LIPS_VERSION "%c",
979 LIPS_DCS, (int)pdev->x_pixels_per_inch, LIPS_ST);
980 else if (ptype == LIPS3)
981 fprintf(prn_stream, "%c31;%d;0J" LIPS3_STRING LIPS_VERSION "%c",
982 LIPS_DCS, (int)pdev->x_pixels_per_inch, LIPS_ST);
983 else if (ptype == LIPS4)
984 fprintf(prn_stream, "%c41;%d;0J" LIPS4_STRING LIPS_VERSION "%c",
985 LIPS_DCS, (int)pdev->x_pixels_per_inch, LIPS_ST);
986 else if (ptype == BJC880J)
987 fprintf(prn_stream, "%c41;%d;0J" BJC880J_STRING LIPS_VERSION "%c",
988 LIPS_DCS, (int)pdev->x_pixels_per_inch, LIPS_ST);
989
990 if (ptype == LIPS4 || ptype == BJC880J)
991 {
992 if (pdev->color_info.depth == 24)
993 fprintf(prn_stream, "%c1\"p", LIPS_CSI);
994 else
995 fprintf(prn_stream, "%c0\"p", LIPS_CSI);
996 }
997 fprintf(prn_stream, "%c<", LIPS_ESC);
998 fprintf(prn_stream, "%c11h", LIPS_CSI); /* Size Unit Mode */
999 }
1000 /* */
1001 /* Print Environment Setting */
1002 /* */
1003 /* Media Selection */
1004 paper_size = lips_media_selection(width, height);
1005
1006 if (ptype == BJC880J) {
1007 /* Paint Memory Mode Setting */
1008 /* for BJC-680J/BJC-880J */
1009 if (paper_size == B4_SIZE ||
1010 paper_size == B4_SIZE + LANDSCAPE ||
1011 paper_size == LEGAL_SIZE ||
1012 paper_size == LEGAL_SIZE + LANDSCAPE)
1013 /* for BJC-880J */
1014 fprintf(prn_stream, "%c3&z", LIPS_CSI);
1015 else if (paper_size == A3_SIZE ||
1016 paper_size == A3_SIZE + LANDSCAPE ||
1017 paper_size == LEDGER_SIZE ||
1018 paper_size == LEDGER_SIZE + LANDSCAPE)
1019 /* for BJC-880J */
1020 fprintf(prn_stream, "%c4&z", LIPS_CSI);
1021 else
1022 fprintf(prn_stream, "%c2&z", LIPS_CSI);
1023 }
1024 if (ptype == LIPS4) {
1025 if (strcmp(lips4->mediaType, "PlainPaper") == 0)
1026 fprintf(prn_stream, "%c20\'t", LIPS_CSI);
1027 else if (strcmp(lips4->mediaType, "OHP") == 0 ||
1028 strcmp(lips4->mediaType, "TransparencyFilm") == 0)
1029 fprintf(prn_stream, "%c40\'t", LIPS_CSI); /* OHP mode (for LBP-2160) */
1030 else if (strcmp(lips4->mediaType, "CardBoard") == 0)
1031 fprintf(prn_stream, "%c30\'t", LIPS_CSI); /* CardBoard mode (for LBP-2160) */
1032 else if (strcmp(lips4->mediaType, "GlossyFilm") == 0)
1033 fprintf(prn_stream, "%c41\'t", LIPS_CSI); /* GlossyFile mode (for LBP-2160) */
1034 }
1035 if (ptype == LIPS4 || ptype == BJC880J) {
1036 if (lips4->ManualFeed ||
1037 (strcmp(lips4->mediaType, "PlainPaper") != 0 && strcmp(lips4->mediaType, LIPS_MEDIATYPE_DEFAULT) != 0)) {
1038 if (lips->prev_feed_mode != 10)
1039 fprintf(prn_stream, "%c10q", LIPS_CSI);
1040 lips->prev_feed_mode = 10;
1041 } else {
1042 if (lips->prev_feed_mode != lips->cassetFeed)
1043 fprintf(prn_stream, "%c%dq", LIPS_CSI, lips->cassetFeed);
1044 lips->prev_feed_mode = lips->cassetFeed;
1045 }
1046 } else if (lips->ManualFeed) { /* Use ManualFeed */
1047 if (lips->prev_feed_mode != 1)
1048 fprintf(prn_stream, "%c1q", LIPS_CSI);
1049 lips->prev_feed_mode = 1;
1050 } else {
1051 if (lips->prev_feed_mode != lips->cassetFeed)
1052 fprintf(prn_stream, "%c%dq", LIPS_CSI, lips->cassetFeed);
1053 lips->prev_feed_mode = lips->cassetFeed;
1054 }
1055
1056 /* Use Verious Paper Size */
1057 prev_paper_size = lips->prev_paper_size;
1058 prev_paper_width = lips->prev_paper_width;
1059 prev_paper_height = lips->prev_paper_height;
1060
1061 if (prev_paper_size != paper_size) {
1062 if (paper_size == USER_SIZE) {
1063 fprintf(prn_stream, "%c2 I", LIPS_CSI);
1064 fprintf(prn_stream, "%c80;%d;%dp", LIPS_CSI,
1065 width * 10, height * 10);
1066 } else if (paper_size == USER_SIZE + LANDSCAPE) {
1067 fprintf(prn_stream, "%c2 I", LIPS_CSI);
1068 fprintf(prn_stream, "%c81;%d;%dp", LIPS_CSI,
1069 height * 10, width * 10);
1070 } else {
1071 fprintf(prn_stream, "%c%dp", LIPS_CSI, paper_size);
1072 }
1073 } else if (paper_size == USER_SIZE) {
1074 if (prev_paper_width != width ||
1075 prev_paper_height != height) {
1076 fprintf(prn_stream, "%c2 I", LIPS_CSI);
1077 fprintf(prn_stream, "%c80;%d;%dp", LIPS_CSI,
1078 width * 10, height * 10);
1079 }
1080 } else if (paper_size == USER_SIZE + LANDSCAPE) {
1081 if (prev_paper_width != width ||
1082 prev_paper_height != height) {
1083 fprintf(prn_stream, "%c2 I", LIPS_CSI);
1084 fprintf(prn_stream, "%c81;%d;%dp", LIPS_CSI,
1085 height * 10, width * 10);
1086 }
1087 }
1088 /* desired number of copies */
1089 if (num_copies > 255)
1090 num_copies = 255;
1091 if (lips->prev_num_copies != num_copies) {
1092 fprintf(prn_stream, "%c%dv", LIPS_CSI, num_copies);
1093 lips->prev_num_copies = num_copies;
1094 }
1095 if (ptype == LIPS4) {
1096 if (lips4->faceup)
1097 fprintf(prn_stream, "%c11;12;12~", LIPS_CSI);
1098 }
1099 if (ptype == LIPS4) {
1100
1101 if (pdev->PageCount == 0) {
1102 /* N-up Printing */
1103 if (lips4->nup != 1) {
1104 fprintf(prn_stream, "%c%d1;;%do", LIPS_CSI, lips4->nup, paper_size);
1105 }
1106 }
1107 /* Duplex mode */
1108 {
1109 bool dup = lips4->Duplex;
1110 int dupset = lips4->Duplex_set;
1111 bool tum = lips4->Tumble;
1112
1113 if (dupset && dup) {
1114 if (lips4->prev_duplex_mode == 0 ||
1115 lips4->prev_duplex_mode == 1)
1116 fprintf(prn_stream, "%c2;#x", LIPS_CSI); /* duplex */
1117 if (!tum) {
1118 /* long edge binding */
1119 if (lips4->prev_duplex_mode != 2)
1120 fprintf(prn_stream, "%c0;#w", LIPS_CSI);
1121 lips4->prev_duplex_mode = 2;
1122 } else {
1123 /* short edge binding */
1124 if (lips4->prev_duplex_mode != 3)
1125 fprintf(prn_stream, "%c2;#w", LIPS_CSI);
1126 lips4->prev_duplex_mode = 3;
1127 }
1128 } else if (dupset && !dup) {
1129 if (lips4->prev_duplex_mode != 1)
1130 fprintf(prn_stream, "%c0;#x", LIPS_CSI); /* simplex */
1131 lips4->prev_duplex_mode = 1;
1132 }
1133 }
1134 }
1135 if (pdev->PageCount == 0) {
1136 /* Display text on printer panel */
1137 fprintf(prn_stream, "%c2y%s%c", LIPS_DCS, lips->Username, LIPS_ST);
1138
1139 fprintf(prn_stream, "%c11h", LIPS_CSI); /* Size Unit Mode */
1140
1141 fprintf(prn_stream, "%c?2;3h", LIPS_CSI);
1142 /* 2: Disable Auto FF */
1143 /* 3: Disable Auto CAP Movement */
1144
1145 fprintf(prn_stream, "%c?1;4;5;6l", LIPS_CSI);
1146 /* 1: Disable Auto NF */
1147 /* 4: Disable Auto LF at CR */
1148 /* 5: Disable Auto CR at LF */
1149 /* 6: Disable Auto CR at FF */
1150 }
1151 if (prev_paper_size != paper_size || paper_size == USER_SIZE ||
1152 paper_size == USER_SIZE + LANDSCAPE) {
1153 if (ptype == LIPS4 || ptype == BJC880J) {
1154 fprintf(prn_stream, "%c?7;%d I", LIPS_CSI,
1155 (int)pdev->x_pixels_per_inch); /* SelectSizeUnit */
1156 } else {
1157 fprintf(prn_stream, "%c7 I", LIPS_CSI); /* SelectSizeUnit */
1158 }
1159
1160 if (ptype == LIPS4 || ptype == BJC880J)
1161 {
1162 if (pdev->color_info.depth == 24)
1163 fprintf(prn_stream, "%c%d G", LIPS_CSI, NUM_LINES_4C); /* VMI (dots) */
1164 else
1165 fprintf(prn_stream, "%c%d G", LIPS_CSI, NUM_LINES); /* VMI (dots) */
1166 }
1167 }
1168 if (prev_paper_size != paper_size) {
1169 /* Top Margin: 63/300 inch + 5 mm */
1170 tm = (63. / 300. + 5. / MMETER_PER_INCH - dev_t_margin(pdev)) * pdev->x_pixels_per_inch;
1171 if (tm > 0)
1172 fprintf(prn_stream, "%c%dk", LIPS_CSI, tm);
1173 if (tm < 0)
1174 fprintf(prn_stream, "%c%de", LIPS_CSI, -tm);
1175
1176 /* Left Margin: 5 mm left */
1177 lm = (5. / MMETER_PER_INCH - dev_l_margin(pdev)) * pdev->x_pixels_per_inch;
1178 if (lm > 0)
1179 fprintf(prn_stream, "%c%dj", LIPS_CSI, lm);
1180 if (lm < 0)
1181 fprintf(prn_stream, "%c%da", LIPS_CSI, -lm);
1182
1183 /* Set Top/Left Margins */
1184 fprintf(prn_stream, "%c0;2t", LIPS_CSI);
1185
1186 /* Bottom Margin: height */
1187 bm = pdev->height - (dev_t_margin(pdev) + dev_b_margin(pdev)) * pdev->y_pixels_per_inch;
1188 fprintf(prn_stream, "%c%de", LIPS_CSI, bm);
1189 /* Right Margin: width */
1190 rm = pdev->width - (dev_l_margin(pdev) + dev_r_margin(pdev)) * pdev->x_pixels_per_inch;
1191 fprintf(prn_stream, "%c%da", LIPS_CSI, rm);
1192 fprintf(prn_stream, "%c1;3t", LIPS_CSI);
1193
1194 /* move CAP to (0, 0) */
1195 fprintf(prn_stream, "%c%dk\r", LIPS_CSI, bm);
1196 }
1197 lips->prev_paper_size = paper_size;
1198 lips->prev_paper_width = width;
1199 lips->prev_paper_height = height;
1200 }
1201
1202 static void
lips_job_end(gx_device_printer * pdev,FILE * prn_stream)1203 lips_job_end(gx_device_printer * pdev, FILE * prn_stream)
1204 {
1205 /* Paper eject command */
1206 fprintf(prn_stream, "\r%c", LIPS_FF);
1207 }
1208
1209 static int lips_delta_compress(byte * inBuff, byte * prevBuff, byte * diffBuff, int Length);
1210
1211 static int
lips_delta_encode(byte * inBuff,byte * prevBuff,byte * outBuff,byte * diffBuff,int Length)1212 lips_delta_encode(byte * inBuff, byte * prevBuff, byte * outBuff, byte * diffBuff, int Length)
1213 {
1214 int i, j, k, com_size;
1215
1216 com_size = lips_delta_compress(inBuff, prevBuff, diffBuff, Length);
1217 if (com_size < 0) { /* data is white raster */
1218 *outBuff = 0x01;
1219 *(outBuff + 1) = 0000;
1220 for (k = 0; k < Length; k++)
1221 *(prevBuff + k) = 0000;
1222 return 2;
1223 } else if (com_size == 0) { /* data is the same raster */
1224 *outBuff = 0000;
1225 return 1;
1226 }
1227 for (i = 0; i < com_size / 255; i++) {
1228 *(outBuff + i) = 0377;
1229 }
1230
1231 *(outBuff + i) = (byte) (com_size % 255);
1232
1233 for (j = 0; j < com_size; j++) {
1234 *(outBuff + i + j + 1) = *(diffBuff + j);
1235 }
1236
1237 for (k = 0; k < Length; k++)
1238 *(prevBuff + k) = *(inBuff + k);
1239
1240 return i + j + 1;
1241 }
1242
1243 static int
lips_delta_compress(byte * inBuff,byte * prevBuff,byte * diffBuff,int Length)1244 lips_delta_compress(byte * inBuff, byte * prevBuff, byte * diffBuff, int Length)
1245 {
1246 int i, j;
1247 bool zero_flag = TRUE;
1248 bool same_flag = TRUE;
1249 int num_bytes = 0;
1250 int num_commandbyte = 0;
1251 int size = 0;
1252 int offset = 0;
1253
1254 for (i = 0; i < Length; i++) {
1255 if (*(inBuff + i) != 0x00)
1256 zero_flag = FALSE;
1257
1258 /* Compare Buffer */
1259 if (*(inBuff + i) != *(prevBuff + i)) {
1260 num_bytes++;
1261
1262 if (same_flag == TRUE) {
1263 /* first byte is offset */
1264 if (offset > 31)
1265 *(diffBuff + size) = 0037;
1266 else
1267 *(diffBuff + size) = offset;
1268
1269 size++;
1270 num_commandbyte++;
1271
1272 for (j = 0; j < (offset - 31) / 255; j++) {
1273 *(diffBuff + size) = 0377;
1274 size++;
1275 num_commandbyte++;
1276 }
1277
1278 if ((offset - 31) % 255 >= 0) {
1279 *(diffBuff + size) = (offset - 31) % 255;
1280 size++;
1281 num_commandbyte++;
1282 }
1283 same_flag = FALSE;
1284
1285 }
1286 } else {
1287 same_flag = TRUE;
1288 offset++;
1289 }
1290
1291 if (num_bytes > 8) {
1292 /* write number of data for replace */
1293 *(diffBuff + size - num_commandbyte)
1294 = *(diffBuff + size - num_commandbyte) | 0340;
1295
1296 for (j = 0; j < 8; j++, size++) {
1297 *(diffBuff + size) = *(inBuff + i + j - 8);
1298 }
1299
1300 /* offset is 0 */
1301 *(diffBuff + size) = 0000;
1302 size++;
1303
1304 num_bytes = 1;
1305 same_flag = FALSE;
1306 num_commandbyte = 1;
1307 } else if (same_flag == true && num_bytes > 0) {
1308 offset = 1;
1309
1310 /* write number of data for replace */
1311 *(diffBuff + size - num_commandbyte)
1312 = *(diffBuff + size - num_commandbyte) | ((num_bytes - 1) << 5);
1313
1314 /* write a different bytes */
1315 for (j = 0; j < num_bytes; j++, size++) {
1316 *(diffBuff + size) = *(inBuff + i + j - num_bytes);
1317 }
1318 num_bytes = 0;
1319 num_commandbyte = 0;
1320 }
1321 }
1322
1323 if (num_bytes > 0) {
1324 /* write number of data for replace */
1325 *(diffBuff + size - num_commandbyte)
1326 = *(diffBuff + size - num_commandbyte) | ((num_bytes - 1) << 5);
1327
1328 for (j = 0; j < num_bytes; j++, size++) {
1329 *(diffBuff + size) = *(inBuff + i + j - num_bytes);
1330 }
1331 }
1332 if (zero_flag)
1333 return -1;
1334
1335 return size;
1336 }
1337
1338 /* This routine work like ``strcat'' */
1339 static int
lips_byte_cat(byte * TotalBuff,byte * Buff,int TotalLen,int Len)1340 lips_byte_cat(byte * TotalBuff, byte * Buff, int TotalLen, int Len)
1341 {
1342 int i;
1343
1344 for (i = 0; i < Len; i++)
1345 *(TotalBuff + TotalLen + i) = *(Buff + i);
1346
1347 return TotalLen + Len;
1348 }
1349