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