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