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