Coverage Report

Created: 2025-04-22 06:20

/src/libspectre/ghostscript/contrib/lips4/gdevl4r.c
Line
Count
Source (jump to first uncovered line)
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
190
lips2p_open(gx_device * pdev)
191
0
{
192
0
    return lips_open(pdev, LIPS2P);
193
0
}
194
195
static int
196
lips3_open(gx_device * pdev)
197
0
{
198
0
    return lips_open(pdev, LIPS3);
199
0
}
200
201
static int
202
bjc880j_open(gx_device * pdev)
203
0
{
204
0
    return lips_open(pdev, BJC880J);
205
0
}
206
207
static int
208
lips4_open(gx_device * pdev)
209
0
{
210
0
    return lips_open(pdev, LIPS4);
211
0
}
212
213
/* Open the printer, adjusting the margins if necessary. */
214
static int
215
lips_open(gx_device * pdev, lips_printer_type ptype)
216
0
{
217
0
    int width = (int)pdev->MediaSize[0];
218
0
    int height = (int)pdev->MediaSize[1];
219
0
    int xdpi = (int)pdev->x_pixels_per_inch;
220
0
    int ydpi = (int)pdev->y_pixels_per_inch;
221
222
    /* Paper Size Check */
223
0
    if (width <= height) { /* portrait */
224
0
        if ((width < LIPS_WIDTH_MIN || width > LIPS_WIDTH_MAX ||
225
0
             height < LIPS_HEIGHT_MIN || height > LIPS_HEIGHT_MAX) &&
226
0
            !(width == LIPS_LEDGER_WIDTH && height == LIPS_LEDGER_HEIGHT))
227
0
            return_error(gs_error_rangecheck);
228
0
    } else {     /* landscape */
229
0
        if ((width < LIPS_HEIGHT_MIN || width > LIPS_HEIGHT_MAX ||
230
0
             height < LIPS_WIDTH_MIN || height > LIPS_WIDTH_MAX) &&
231
0
            !(width == LIPS_LEDGER_HEIGHT && height == LIPS_LEDGER_WIDTH))
232
0
            return_error(gs_error_rangecheck);
233
0
    }
234
235
    /* Resolution Check */
236
0
    if (xdpi != ydpi)
237
0
        return_error(gs_error_rangecheck);
238
0
    else if (ptype == LIPS2P) {
239
        /* LIPS II+ support DPI is 240x240 */
240
0
        if (xdpi != LIPS2P_DPI_MAX)
241
0
            return_error(gs_error_rangecheck);
242
0
    } else if (ptype == LIPS3) {
243
        /* LIPS III supports DPI is 300x300 */
244
0
        if (xdpi != LIPS3_DPI_MAX)
245
0
            return_error(gs_error_rangecheck);
246
0
    } else if (ptype == BJC880J) {
247
0
        if (xdpi < LIPS_DPI_MIN || xdpi > BJC880J_DPI_MAX)
248
0
            return_error(gs_error_rangecheck);
249
0
    } else {     /* LIPS4 supprts DPI is 60x60 - 600x600 and 1200x1200 */
250
0
        if ((xdpi < LIPS_DPI_MIN || xdpi > LIPS4_DPI_MAX) && xdpi != LIPS4_DPI_SUPERFINE)
251
0
            return_error(gs_error_rangecheck);
252
0
    }
253
254
0
    return gdev_prn_open(pdev);
255
0
}
256
257
static int
258
lips_close(gx_device * pdev)
259
0
{
260
0
    gx_device_printer *const ppdev = (gx_device_printer *) pdev;
261
0
    gx_device_lips *const lips = (gx_device_lips *) pdev;
262
263
0
    int code = gdev_prn_open_printer(pdev, 1);
264
265
0
    if (code >= 0) {
266
0
        gp_fprintf(ppdev->file, "%c0J%c", LIPS_DCS, LIPS_ST);
267
0
        if (lips->pjl)
268
0
            gp_fprintf(ppdev->file,
269
0
                "%c%%-12345X"
270
0
                "@PJL SET LPARM : LIPS SW2 = OFF\n"
271
0
                "@PJL EOJ\n"
272
0
                "%c%%-12345X", LIPS_ESC, LIPS_ESC);
273
0
    }
274
0
    return gdev_prn_close(pdev);
275
0
}
276
277
/* Get properties for the lips drivers. */
278
static int
279
lips_get_params(gx_device * pdev, gs_param_list * plist)
280
0
{
281
0
    gx_device_lips *const lips = (gx_device_lips *) pdev;
282
0
    int code = lprn_get_params(pdev, plist);
283
0
    int ncode;
284
0
    gs_param_string usern;
285
286
0
    if (code < 0)
287
0
        return code;
288
289
0
    if ((ncode = param_write_int(plist, LIPS_OPTION_CASSETFEED,
290
0
                                 &lips->cassetFeed)) < 0)
291
0
        code = ncode;
292
293
0
    if ((ncode = param_write_bool(plist, LIPS_OPTION_PJL,
294
0
                                  &lips->pjl)) < 0)
295
0
        code = ncode;
296
297
0
    if ((ncode = param_write_int(plist, LIPS_OPTION_TONERDENSITY,
298
0
                                 &lips->toner_density)) < 0)
299
0
        code = ncode;
300
301
0
    if (lips->toner_saving_set >= 0 &&
302
0
        (code = (lips->toner_saving_set ?
303
0
     param_write_bool(plist, LIPS_OPTION_TONERSAVING, &lips->toner_saving) :
304
0
                 param_write_null(plist, LIPS_OPTION_TONERSAVING))) < 0)
305
0
        code = ncode;
306
307
0
    if (code < 0)
308
0
        return code;
309
310
0
    usern.data = (const byte *)lips->Username,
311
0
        usern.size = strlen(lips->Username),
312
0
        usern.persistent = false;
313
314
0
    return param_write_string(plist, LIPS_OPTION_USER_NAME, &usern);
315
0
}
316
317
static int
318
lips4_get_params(gx_device * pdev, gs_param_list * plist)
319
0
{
320
0
    gx_device_lips4 *const lips4 = (gx_device_lips4 *) pdev;
321
0
    int code = lips_get_params(pdev, plist);
322
0
    int ncode;
323
0
    gs_param_string pmedia;
324
325
0
    if (code < 0)
326
0
        return code;
327
328
0
    if ((ncode = param_write_int(plist, LIPS_OPTION_NUP,
329
0
                                 &lips4->nup)) < 0)
330
0
        code = ncode;
331
332
0
    if ((ncode = param_write_bool(plist, LIPS_OPTION_FACEUP,
333
0
                                  &lips4->faceup)) < 0)
334
0
        code = ncode;
335
336
0
    if (code < 0)
337
0
        return code;
338
339
0
    pmedia.data = (const byte *)lips4->mediaType,
340
0
        pmedia.size = strlen(lips4->mediaType),
341
0
        pmedia.persistent = false;
342
343
0
    return param_write_string(plist, LIPS_OPTION_MEDIATYPE, &pmedia);
344
0
}
345
346
/* Put properties for the lips drivers. */
347
static int
348
lips_put_params(gx_device * pdev, gs_param_list * plist)
349
0
{
350
0
    gx_device_lips *const lips = (gx_device_lips *) pdev;
351
0
    int ecode = 0;
352
0
    int code;
353
0
    gs_param_name param_name;
354
0
    int cass = lips->cassetFeed;
355
0
    bool pjl = lips->pjl;
356
0
    int toner_density = lips->toner_density;
357
0
    bool toner_saving = lips->toner_saving;
358
0
    bool toner_saving_set = lips->toner_saving_set;
359
0
    gs_param_string usern;
360
361
0
    switch (code = param_read_int(plist,
362
0
                                  (param_name = LIPS_OPTION_CASSETFEED),
363
0
                                  &cass)) {
364
0
        case 0:
365
0
            if (cass < -1 || cass > 17 || (cass > 3 && cass < 10))
366
0
                ecode = gs_error_rangecheck;
367
0
            else
368
0
                break;
369
0
            goto casse;
370
0
        default:
371
0
            ecode = code;
372
0
          casse:param_signal_error(plist, param_name, ecode);
373
0
        case 1:
374
0
            break;
375
0
    }
376
377
0
    if ((code = param_read_bool(plist,
378
0
                                (param_name = LIPS_OPTION_PJL),
379
0
                                &pjl)) < 0)
380
0
        param_signal_error(plist, param_name, ecode = code);
381
382
0
    switch (code = param_read_int(plist,
383
0
                                  (param_name = LIPS_OPTION_TONERDENSITY),
384
0
                                  &toner_density)) {
385
0
        case 0:
386
0
            if (toner_density < 0 || toner_density > 8)
387
0
                ecode = gs_error_rangecheck;
388
0
            else
389
0
                break;
390
0
            goto tden;
391
0
        default:
392
0
            ecode = code;
393
0
          tden:param_signal_error(plist, param_name, ecode);
394
0
        case 1:
395
0
            break;
396
0
    }
397
398
0
    if (lips->toner_saving_set >= 0)
399
0
        switch (code = param_read_bool(plist, (param_name = LIPS_OPTION_TONERSAVING),
400
0
                                       &toner_saving)) {
401
0
            case 0:
402
0
                toner_saving_set = 1;
403
0
                break;
404
0
            default:
405
0
                if ((code = param_read_null(plist, param_name)) == 0) {
406
0
                    toner_saving_set = 0;
407
0
                    break;
408
0
                }
409
0
                ecode = code;
410
0
                param_signal_error(plist, param_name, ecode);
411
0
            case 1:
412
0
                break;
413
0
        }
414
0
    switch (code = param_read_string(plist,
415
0
                                     (param_name = LIPS_OPTION_USER_NAME),
416
0
                                     &usern)) {
417
0
        case 0:
418
0
            if (usern.size > LIPS_USERNAME_MAX) {
419
0
                ecode = gs_error_limitcheck;
420
0
                goto userne;
421
0
            } else {   /* Check the validity of ``User Name'' characters */
422
0
                int i;
423
424
0
                for (i = 0; i < usern.size; i++)
425
0
                    if (usern.data[i] < 0x20 ||
426
0
                        usern.data[i] > 0x7e
427
                    /*
428
                       && usern.data[i] < 0xa0) ||
429
                       usern.data[i] > 0xfe
430
                     */
431
0
                        ) {
432
0
                        ecode = gs_error_rangecheck;
433
0
                        goto userne;
434
0
                    }
435
0
            }
436
0
            break;
437
0
        default:
438
0
            ecode = code;
439
0
          userne:param_signal_error(plist, param_name, ecode);
440
          /* Fall through. */
441
0
        case 1:
442
0
            usern.data = 0;
443
0
            break;
444
0
    }
445
446
0
    if (ecode < 0)
447
0
        return ecode;
448
0
    code = lprn_put_params(pdev, plist);
449
0
    if (code < 0)
450
0
        return code;
451
452
0
    lips->cassetFeed = cass;
453
0
    lips->pjl = pjl;
454
0
    lips->toner_density = toner_density;
455
0
    lips->toner_saving = toner_saving;
456
0
    lips->toner_saving_set = toner_saving_set;
457
458
0
    if (usern.data != 0 &&
459
0
        bytes_compare(usern.data, usern.size,
460
0
                      (const byte *)lips->Username, strlen(lips->Username))
461
0
        ) {
462
0
        memcpy(lips->Username, usern.data, usern.size);
463
0
        lips->Username[usern.size] = 0;
464
0
    }
465
0
    return 0;
466
0
}
467
468
static int
469
lips4_put_params(gx_device * pdev, gs_param_list * plist)
470
0
{
471
0
    gx_device_lips4 *const lips4 = (gx_device_lips4 *) pdev;
472
0
    int ecode = 0;
473
0
    int code;
474
0
    gs_param_name param_name;
475
0
    gs_param_string pmedia;
476
0
    bool nup = lips4->nup;
477
0
    bool faceup = lips4->faceup;
478
0
    int old_bpp = pdev->color_info.depth;
479
0
    int bpp = 0;
480
481
0
    switch (code = param_read_int(plist,
482
0
                                  (param_name = LIPS_OPTION_NUP),
483
0
                                  &nup)) {
484
0
        case 0:
485
0
            if (nup != 1 && nup != 2 && nup != 4)
486
0
                ecode = gs_error_rangecheck;
487
0
            else
488
0
                break;
489
0
            goto nupe;
490
0
        default:
491
0
            ecode = code;
492
0
          nupe:param_signal_error(plist, param_name, ecode);
493
0
        case 1:
494
0
            break;
495
0
    }
496
497
0
    if ((code = param_read_bool(plist,
498
0
                                (param_name = LIPS_OPTION_FACEUP),
499
0
                                &faceup)) < 0)
500
0
        param_signal_error(plist, param_name, ecode = code);
501
502
0
    switch (code = param_read_string(plist,
503
0
                                     (param_name = LIPS_OPTION_MEDIATYPE),
504
0
                                     &pmedia)) {
505
0
        case 0:
506
0
            if (pmedia.size >= LIPS_MEDIACHAR_MAX) {
507
0
                ecode = gs_error_limitcheck;
508
0
                goto pmediae;
509
0
            } else {   /* Check the validity of ``MediaType'' characters */
510
0
                if (strcmp((const char *)pmedia.data, "PlainPaper") != 0 &&
511
0
                    strcmp((const char *)pmedia.data, "OHP") != 0 &&
512
0
                    strcmp((const char *)pmedia.data, "TransparencyFilm") != 0 && /* same as OHP */
513
0
                    strcmp((const char *)pmedia.data, "GlossyFilm") != 0 &&
514
0
                    strcmp((const char *)pmedia.data, "CardBoard") != 0
515
0
                    ) {
516
0
                    ecode = gs_error_rangecheck;
517
0
                    goto pmediae;
518
0
                }
519
0
            }
520
0
            break;
521
0
        default:
522
0
            ecode = code;
523
0
          pmediae:param_signal_error(plist, param_name, ecode);
524
          /* Fall through. */
525
0
        case 1:
526
0
            pmedia.data = 0;
527
0
            break;
528
0
    }
529
530
0
    switch (code = param_read_int(plist,
531
0
                                  (param_name = "BitsPerPixel"),
532
0
                                  &bpp)) {
533
0
        case 0:
534
0
            if (bpp != 1 && bpp != 24)
535
0
                ecode = gs_error_rangecheck;
536
0
            else
537
0
                break;
538
0
            goto bppe;
539
0
        default:
540
0
            ecode = code;
541
0
          bppe:param_signal_error(plist, param_name, ecode);
542
0
        case 1:
543
0
            break;
544
0
    }
545
546
0
    if (bpp != 0)
547
0
      {
548
0
        pdev->color_info.depth = bpp;
549
0
        pdev->color_info.num_components = ((bpp == 1) ? 1 : 3);
550
0
        pdev->color_info.max_gray = (bpp >= 8 ? 255 : 1);
551
0
        pdev->color_info.max_color = (bpp >= 8 ? 255 : bpp > 1 ? 1 : 0);
552
0
        pdev->color_info.dither_grays = (bpp >= 8 ? 5 : 2);
553
0
        pdev->color_info.dither_colors = (bpp >= 8 ? 5 : bpp > 1 ? 2 : 0);
554
0
        dev_proc(pdev, map_rgb_color) = ((bpp == 1) ? gdev_prn_map_rgb_color : gx_default_rgb_map_rgb_color);
555
0
      }
556
557
0
    if (ecode < 0)
558
0
        return ecode;
559
0
    code = lips_put_params(pdev, plist);
560
0
    if (code < 0)
561
0
        return code;
562
563
0
    lips4->nup = nup;
564
0
    lips4->faceup = faceup;
565
566
0
    if (pmedia.data != 0 &&
567
0
        bytes_compare(pmedia.data, pmedia.size,
568
0
                   (const byte *)lips4->mediaType, strlen(lips4->mediaType))
569
0
        ) {
570
0
        memcpy(lips4->mediaType, pmedia.data, pmedia.size);
571
0
        lips4->mediaType[pmedia.size] = 0;
572
0
    }
573
0
    if (bpp != 0 && bpp != old_bpp && pdev->is_open)
574
0
        return gs_closedevice(pdev);
575
0
    return 0;
576
0
}
577
578
/* ------ Internal routines ------ */
579
580
static int
581
lips2p_print_page_copies(gx_device_printer * pdev, gp_file * prn_stream, int num_copies)
582
0
{
583
0
    return lips_print_page_copies(pdev, prn_stream, LIPS2P, num_copies);
584
0
}
585
586
static int
587
lips3_print_page_copies(gx_device_printer * pdev, gp_file * prn_stream, int num_copies)
588
0
{
589
0
    return lips_print_page_copies(pdev, prn_stream, LIPS3, num_copies);
590
0
}
591
592
0
#define NUM_LINES 24    /* raster height */
593
0
#define NUM_LINES_4C 256
594
595
static int
596
lips_print_page_copies(gx_device_printer * pdev, gp_file * prn_stream, lips_printer_type ptype, int num_copies)
597
0
{
598
0
    gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
599
0
    int code = 0;
600
0
    int bpl = gdev_mem_bytes_per_scan_line(pdev);
601
0
    int maxY = lprn->BlockLine / lprn->nBh * lprn->nBh;
602
603
    /* Initialize printer. */
604
0
    lips_job_start(pdev, ptype, prn_stream, num_copies);
605
606
0
    if (!(lprn->CompBuf = gs_malloc(pdev->memory->non_gc_memory, bpl * 3 / 2 + 1, maxY, "(CompBuf)")))
607
0
        return_error(gs_error_VMerror);
608
609
0
    lprn->NegativePrint = false; /* not support */
610
0
    lprn->prev_x = lprn->prev_y = 0;
611
0
    code = lprn_print_image(pdev, prn_stream);
612
0
    if (code < 0)
613
0
        return code;
614
615
0
    gs_free(pdev->memory->non_gc_memory, lprn->CompBuf, bpl * 3 / 2 + 1, maxY, "(CompBuf)");
616
617
    /* eject page */
618
0
    lips_job_end(pdev, prn_stream);
619
620
0
    return 0;
621
0
}
622
623
static int
624
bjc880j_print_page_copies(gx_device_printer * pdev, gp_file * prn_stream, int num_copies)
625
0
{
626
0
  return lips4type_print_page_copies(pdev, prn_stream, num_copies, BJC880J);
627
0
}
628
629
static int
630
lips4_print_page_copies(gx_device_printer * pdev, gp_file * prn_stream, int num_copies)
631
0
{
632
0
  return lips4type_print_page_copies(pdev, prn_stream, num_copies, LIPS4);
633
0
}
634
635
static int
636
lips4type_print_page_copies(gx_device_printer * pdev, gp_file * prn_stream, int num_copies, int ptype)
637
0
{
638
0
    gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
639
0
    int code = 0;
640
0
    int bpl = gdev_mem_bytes_per_scan_line(pdev);
641
0
    int maxY = lprn->BlockLine / lprn->nBh * lprn->nBh;
642
643
    /* Initialize printer. */
644
0
    lips_job_start(pdev, ptype, prn_stream, num_copies);
645
646
0
    if (pdev->color_info.depth == 1)
647
0
      {
648
0
        if (!(lprn->CompBuf = gs_malloc(pdev->memory->non_gc_memory, bpl * 3 / 2 + 1, maxY, "(CompBuf)")))
649
0
          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
0
        if (!(lprn->CompBuf2 = gs_malloc(pdev->memory->non_gc_memory, bpl * 2 + 2, maxY, "(CompBuf2)")))
654
0
          return_error(gs_error_VMerror);
655
656
0
        if (lprn->NegativePrint) {
657
0
          int rm = (int)(pdev->width - (dev_l_margin(pdev) + dev_r_margin(pdev)) * pdev->x_pixels_per_inch);
658
0
          int bm = (int)(pdev->height - (dev_t_margin(pdev) + dev_b_margin(pdev)) * pdev->y_pixels_per_inch);
659
          /* Draw black rectangle */
660
0
          gp_fprintf(prn_stream,
661
0
                     "%c{%c%da%c%de%c;;;3}",
662
0
                     LIPS_CSI, LIPS_CSI, rm, LIPS_CSI, bm, LIPS_CSI);
663
0
          gp_fprintf(prn_stream, "%c%dj%c%dk",
664
0
                     LIPS_CSI, rm, LIPS_CSI, bm);
665
0
        }
666
667
0
        lprn->prev_x = lprn->prev_y = 0;
668
0
        code = lprn_print_image(pdev, prn_stream);
669
0
        if (code < 0)
670
0
          return code;
671
672
0
        gs_free(pdev->memory->non_gc_memory, lprn->CompBuf, bpl * 3 / 2 + 1, maxY, "(CompBuf)");
673
0
        gs_free(pdev->memory->non_gc_memory, lprn->CompBuf2, bpl * 3 / 2 + 1, maxY, "(CompBuf2)");
674
0
      }
675
0
    else
676
0
      {
677
0
        code = lips4c_output_page(pdev, prn_stream);
678
679
0
        if (code < 0)
680
0
          return code;
681
0
      }
682
683
    /* eject page */
684
0
    lips_job_end(pdev, prn_stream);
685
686
0
    return 0;
687
0
}
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
712
move_cap(gx_device_printer * pdev, gp_file * prn_stream, int x, int y)
713
0
{
714
0
    gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
715
716
0
    if (x != lprn->prev_x) {
717
0
        if (x > lprn->prev_x)
718
0
            gp_fprintf(prn_stream, "%c%da", LIPS_CSI, x - lprn->prev_x);
719
0
        else
720
0
            gp_fprintf(prn_stream, "%c%dj", LIPS_CSI, lprn->prev_x - x);
721
722
0
        lprn->prev_x = x;
723
0
    }
724
0
    if (y != lprn->prev_y) {
725
0
        if (y > lprn->prev_y)
726
0
            gp_fprintf(prn_stream, "%c%de", LIPS_CSI, y - lprn->prev_y);
727
0
        else
728
0
            gp_fprintf(prn_stream, "%c%dk", LIPS_CSI, lprn->prev_y - y);
729
730
0
        lprn->prev_y = y;
731
0
    }
732
0
}
733
734
static void
735
draw_bubble(gp_file * prn_stream, int width, int height)
736
0
{
737
    /* Draw a rectangle */
738
0
    gp_fprintf(prn_stream,
739
0
               "%c{%c%da%c%de%c}",
740
0
               LIPS_CSI, LIPS_CSI, width, LIPS_CSI, height, LIPS_CSI);
741
0
    gp_fprintf(prn_stream, "%c%dj%c%dk",
742
0
                LIPS_CSI, width, LIPS_CSI, height);
743
0
}
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
774
lips2p_image_out(gx_device_printer * pdev, gp_file * prn_stream, int x, int y, int width, int height)
775
0
{
776
0
    gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
777
0
    int Len;
778
0
    char raw_str[32];   /* LIPS command header (uncompress) */
779
0
    char comp_str[32];    /* LIPS command header (compress) */
780
781
0
    move_cap(pdev, prn_stream, x, y);
782
783
0
    Len = lips_mode3format_encode(lprn->TmpBuf, lprn->CompBuf, width / 8 * height);
784
0
    gs_sprintf(raw_str, "%c%d;%d;%d.r", LIPS_CSI,
785
0
            width / 8 * height, width / 8, (int)pdev->x_pixels_per_inch);
786
0
    gs_sprintf(comp_str, "%c%d;%d;%d;9;%d.r", LIPS_CSI,
787
0
            Len, width / 8, (int)pdev->x_pixels_per_inch, height);
788
789
0
    if (Len < width / 8 * height - strlen(comp_str) + strlen(raw_str)) {
790
0
        gp_fprintf(prn_stream, "%s", comp_str);
791
0
        gp_fwrite(lprn->CompBuf, 1, Len, prn_stream);
792
0
    } else {
793
        /* compression result is bad. */
794
0
        gp_fprintf(prn_stream, "%s", raw_str);
795
0
        gp_fwrite(lprn->TmpBuf, 1, width / 8 * height, prn_stream);
796
0
    }
797
798
0
    if (lprn->ShowBubble)
799
0
        draw_bubble(prn_stream, width, height);
800
0
}
801
802
static void
803
lips4_image_out(gx_device_printer * pdev, gp_file * prn_stream, int x, int y, int width, int height)
804
0
{
805
0
    gx_device_lprn *const lprn = (gx_device_lprn *) pdev;
806
0
    int Len, Len_rle;
807
0
    char raw_str[32];   /* LIPS command header (uncompress) */
808
0
    char comp_str[32];    /* LIPS command header (compress) */
809
810
0
    move_cap(pdev, prn_stream, x, y);
811
812
0
    Len = lips_packbits_encode(lprn->TmpBuf, lprn->CompBuf, width / 8 * height);
813
0
    Len_rle = lips_rle_encode(lprn->TmpBuf, lprn->CompBuf2, width / 8 * height);
814
815
0
    gs_sprintf(raw_str, "%c%d;%d;%d.r", LIPS_CSI,
816
0
            width / 8 * height, width / 8, (int)pdev->x_pixels_per_inch);
817
818
0
    if (Len < Len_rle) {
819
0
        gs_sprintf(comp_str, "%c%d;%d;%d;11;%d.r", LIPS_CSI,
820
0
                Len, width / 8, (int)pdev->x_pixels_per_inch, height);
821
0
        if (Len < width / 8 * height - strlen(comp_str) + strlen(raw_str)) {
822
0
            gp_fprintf(prn_stream, "%s", comp_str);
823
0
            gp_fwrite(lprn->CompBuf, 1, Len, prn_stream);
824
0
        } else {
825
            /* compression result is bad. */
826
0
            gp_fprintf(prn_stream, "%s", raw_str);
827
0
            gp_fwrite(lprn->TmpBuf, 1, width / 8 * height, prn_stream);
828
0
        }
829
0
    } else {
830
        /* 2019-11-28: changed two occurrencies of 'Len' to 'Len_rle' here, but
831
        unable to test. */
832
0
        gs_sprintf(comp_str, "%c%d;%d;%d;10;%d.r", LIPS_CSI,
833
0
                Len_rle, width / 8, (int)pdev->x_pixels_per_inch, height);
834
0
        if (Len_rle < width / 8 * height - strlen(comp_str) + strlen(raw_str)) {
835
0
            gp_fprintf(prn_stream, "%s", comp_str);
836
0
            gp_fwrite(lprn->CompBuf2, 1, Len_rle, prn_stream);
837
0
        } else {
838
            /* compression result is bad. */
839
0
            gp_fprintf(prn_stream, "%s", raw_str);
840
0
            gp_fwrite(lprn->TmpBuf, 1, width / 8 * height, prn_stream);
841
0
        }
842
0
    }
843
844
0
    if (lprn->ShowBubble)
845
0
        draw_bubble(prn_stream, width, height);
846
0
}
847
848
static int
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
0
{
851
0
    int bits_per_pixel = pdev->color_info.depth;
852
0
    int num_components = bits_per_pixel > 8 ? 3 : 1;
853
0
    int nBytesPerLine = gdev_prn_raster(pdev);
854
0
    int Xpixel = nBytesPerLine / num_components;
855
0
    int TotalLen = 0;
856
0
    int num_zerobyte = 0;
857
0
    bool zerobyte_flag = false;
858
0
    int i, y, Len;
859
860
0
    for (i = 0; i < nBytesPerLine; i++) {
861
0
        *(prevBuff + i) = 0x00; /* initialize */
862
0
    }
863
864
0
    for (y = lnum; y < lnum + raster_height; y++) {
865
0
        gdev_prn_copy_scan_lines(pdev, y, pBuff, nBytesPerLine);
866
867
0
        Len = lips_delta_encode(pBuff,
868
0
                                prevBuff, ComBuff, diffBuff,
869
0
                                Xpixel * num_components);
870
871
0
        if (Len == 2 && *ComBuff == 0x01) {
872
0
            if (zerobyte_flag == false) {
873
0
                zerobyte_flag = true;
874
0
                TotalLen = lips_byte_cat(TotalBuff, ComBuff, TotalLen, Len);
875
0
            } else {
876
0
                if (num_zerobyte > 255) {
877
0
                    TotalLen = lips_byte_cat(TotalBuff, ComBuff, TotalLen, Len);
878
0
                } else {
879
0
                    *(TotalBuff + TotalLen - 1) = num_zerobyte;
880
0
                }
881
0
                num_zerobyte++;
882
0
            }
883
0
        } else {
884
0
            TotalLen = lips_byte_cat(TotalBuff, ComBuff, TotalLen, Len);
885
0
            zerobyte_flag = false;
886
0
            num_zerobyte = 0;
887
0
        }
888
0
    }
889
890
0
    gp_fprintf(prn_stream, "%c%d;%d;%d;12;%d;;%d;%d;;1.r", LIPS_CSI,
891
0
               TotalLen, Xpixel, (int)pdev->x_pixels_per_inch,
892
0
               raster_height,
893
0
               bits_per_pixel / num_components,
894
0
               num_components < 3 ? 0 : 10);
895
0
    gp_fwrite(TotalBuff, 1, TotalLen, prn_stream);
896
0
    gp_fputc(0x85, prn_stream); /* CR + LF */
897
898
0
    return 0;
899
0
}
900
901
static int
902
lips4c_output_page(gx_device_printer * pdev, gp_file * prn_stream)
903
0
{
904
0
    byte *pBuff, *ComBuff, *prevBuff, *TotalBuff, *diffBuff;
905
0
    int bits_per_pixel = pdev->color_info.depth;
906
0
    int num_components = bits_per_pixel > 8 ? 3 : 1;
907
0
    int nBytesPerLine = gdev_prn_raster(pdev);
908
0
    int Xpixel = nBytesPerLine / num_components;
909
0
    int lnum = 0;
910
911
    /* Memory Allocate */
912
0
    if (!(pBuff = (byte *) gs_malloc(pdev->memory->non_gc_memory, nBytesPerLine, sizeof(byte), "lips4c_compress_output_page(pBuff)")))
913
0
        return_error(gs_error_VMerror);
914
0
    if (!(prevBuff = (byte *) gs_malloc(pdev->memory->non_gc_memory, nBytesPerLine, sizeof(byte), "lips4c_compress_output_page(prevBuff)")))
915
0
        return_error(gs_error_VMerror);
916
0
    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
0
        return_error(gs_error_VMerror);
918
0
    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
0
        return_error(gs_error_VMerror);
920
0
    if (!(diffBuff = (byte *) gs_malloc(pdev->memory->non_gc_memory, Xpixel * num_components * 2, sizeof(byte), "lips_print_page")))
921
0
        return_error(gs_error_VMerror);
922
923
    /* make output data */
924
0
    while (lnum < pdev->height) {
925
0
        lips4c_write_raster(pdev, prn_stream, pBuff, prevBuff, ComBuff,
926
0
                            TotalBuff, diffBuff, lnum, NUM_LINES_4C);
927
0
        lnum += NUM_LINES_4C;
928
0
    }
929
930
0
    if (pdev->height - (lnum - NUM_LINES_4C) > 0) {
931
0
        lips4c_write_raster(pdev, prn_stream, pBuff, prevBuff, ComBuff,
932
0
                            TotalBuff, diffBuff, lnum - NUM_LINES_4C,
933
0
                            pdev->height - (lnum - NUM_LINES_4C));
934
0
    }
935
    /* Free Memory */
936
0
    gs_free(pdev->memory->non_gc_memory, pBuff, nBytesPerLine, sizeof(byte), "lips4c_compress_output_page(pBuff)");
937
0
    gs_free(pdev->memory->non_gc_memory, prevBuff, nBytesPerLine, sizeof(byte), "lips4c_compress_output_page(prevBuff)");
938
0
    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
0
    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
0
    gs_free(pdev->memory->non_gc_memory, diffBuff, Xpixel * num_components * 2, sizeof(byte), "lips_print_page");
941
942
0
    return 0;
943
0
}
944
945
static void
946
lips_job_start(gx_device_printer * pdev, lips_printer_type ptype, gp_file * prn_stream, int num_copies)
947
0
{
948
0
    gx_device_lips *const lips = (gx_device_lips *) pdev;
949
0
    gx_device_lips4 *const lips4 = (gx_device_lips4 *) pdev;
950
0
    int prev_paper_size, prev_paper_width, prev_paper_height, paper_size;
951
0
    int width = (int)pdev->MediaSize[0];
952
0
    int height = (int)pdev->MediaSize[1];
953
0
    int tm, lm, rm, bm;
954
955
0
    if (pdev->PageCount == 0) {
956
0
        if (lips->pjl) {
957
0
            gp_fprintf(prn_stream,
958
0
                       "%c%%-12345X@PJL CJLMODE\n"
959
0
                       "@PJL JOB\n", LIPS_ESC);
960
0
            if (ptype == LIPS4) {
961
0
                gp_fprintf(prn_stream,
962
0
                           "%c%%-12345X@PJL CJLMODE\n", LIPS_ESC);
963
0
                if ((int)pdev->x_pixels_per_inch == 1200)
964
0
                    gp_fprintf(prn_stream, "@PJL SET RESOLUTION = SUPERFINE\n");
965
0
                else if ((int)pdev->x_pixels_per_inch == 600)
966
0
                    gp_fprintf(prn_stream, "@PJL SET RESOLUTION = FINE\n");
967
0
                else if ((int)pdev->x_pixels_per_inch == 300)
968
0
                    gp_fprintf(prn_stream, "@PJL SET RESOLUTION = QUICK\n");
969
0
            }
970
0
            if (lips->toner_density)
971
0
                gp_fprintf(prn_stream, "@PJL SET TONER-DENSITY=%d\n",
972
0
                           lips->toner_density);
973
0
            if (lips->toner_saving_set) {
974
0
                gp_fprintf(prn_stream, "@PJL SET TONER-SAVING=");
975
0
                if (lips->toner_saving)
976
0
                    gp_fprintf(prn_stream, "ON\n");
977
0
                else
978
0
                    gp_fprintf(prn_stream, "OFF\n");
979
0
            }
980
0
            gp_fprintf(prn_stream,
981
0
                       "@PJL SET LPARM : LIPS SW2 = ON\n"
982
0
                       "@PJL ENTER LANGUAGE = LIPS\n");
983
0
        }
984
0
        gp_fprintf(prn_stream, "%c%%@", LIPS_ESC);
985
0
        if (ptype == LIPS2P)
986
0
            gp_fprintf(prn_stream, "%c21;%d;0J" LIPS2P_STRING LIPS_VERSION "%c",
987
0
                       LIPS_DCS, (int)pdev->x_pixels_per_inch, LIPS_ST);
988
0
        else if (ptype == LIPS3)
989
0
            gp_fprintf(prn_stream, "%c31;%d;0J" LIPS3_STRING LIPS_VERSION "%c",
990
0
                       LIPS_DCS, (int)pdev->x_pixels_per_inch, LIPS_ST);
991
0
        else if (ptype == LIPS4)
992
0
            gp_fprintf(prn_stream, "%c41;%d;0J" LIPS4_STRING LIPS_VERSION "%c",
993
0
                       LIPS_DCS, (int)pdev->x_pixels_per_inch, LIPS_ST);
994
0
        else if (ptype == BJC880J)
995
0
            gp_fprintf(prn_stream, "%c41;%d;0J" BJC880J_STRING LIPS_VERSION "%c",
996
0
                       LIPS_DCS, (int)pdev->x_pixels_per_inch, LIPS_ST);
997
998
0
        if (ptype == LIPS4 || ptype == BJC880J)
999
0
          {
1000
0
            if (pdev->color_info.depth == 24)
1001
0
              gp_fprintf(prn_stream, "%c1\"p", LIPS_CSI);
1002
0
            else
1003
0
              gp_fprintf(prn_stream, "%c0\"p", LIPS_CSI);
1004
0
          }
1005
0
        gp_fprintf(prn_stream, "%c<", LIPS_ESC);
1006
0
        gp_fprintf(prn_stream, "%c11h", LIPS_CSI);  /* Size Unit Mode */
1007
0
    }
1008
    /*                           */
1009
    /* Print Environment Setting */
1010
    /*                           */
1011
    /* Media Selection */
1012
0
    paper_size = lips_media_selection(width, height);
1013
1014
0
    if (ptype == BJC880J) {
1015
        /* Paint Memory Mode Setting */
1016
        /* for BJC-680J/BJC-880J */
1017
0
        if (paper_size == B4_SIZE ||
1018
0
            paper_size == B4_SIZE + LANDSCAPE ||
1019
0
            paper_size == LEGAL_SIZE ||
1020
0
            paper_size == LEGAL_SIZE + LANDSCAPE)
1021
            /* for BJC-880J */
1022
0
            gp_fprintf(prn_stream, "%c3&z", LIPS_CSI);
1023
0
        else if (paper_size == A3_SIZE ||
1024
0
                 paper_size == A3_SIZE + LANDSCAPE ||
1025
0
                 paper_size == LEDGER_SIZE ||
1026
0
                 paper_size == LEDGER_SIZE + LANDSCAPE)
1027
            /* for BJC-880J */
1028
0
            gp_fprintf(prn_stream, "%c4&z", LIPS_CSI);
1029
0
        else
1030
0
            gp_fprintf(prn_stream, "%c2&z", LIPS_CSI);
1031
0
    }
1032
0
    if (ptype == LIPS4) {
1033
0
        if (strcmp(lips4->mediaType, "PlainPaper") == 0)
1034
0
            gp_fprintf(prn_stream, "%c20\'t", LIPS_CSI);
1035
0
        else if (strcmp(lips4->mediaType, "OHP") == 0 ||
1036
0
                 strcmp(lips4->mediaType, "TransparencyFilm") == 0)
1037
0
            gp_fprintf(prn_stream, "%c40\'t", LIPS_CSI);  /* OHP mode (for LBP-2160) */
1038
0
        else if (strcmp(lips4->mediaType, "CardBoard") == 0)
1039
0
            gp_fprintf(prn_stream, "%c30\'t", LIPS_CSI);  /* CardBoard mode (for LBP-2160) */
1040
0
        else if (strcmp(lips4->mediaType, "GlossyFilm") == 0)
1041
0
            gp_fprintf(prn_stream, "%c41\'t", LIPS_CSI);  /* GlossyFile mode (for LBP-2160) */
1042
0
    }
1043
0
    if (ptype == LIPS4 || ptype == BJC880J) {
1044
0
        if (lips4->ManualFeed ||
1045
0
            (strcmp(lips4->mediaType, "PlainPaper") != 0 && strcmp(lips4->mediaType, LIPS_MEDIATYPE_DEFAULT) != 0)) {
1046
0
            if (lips->prev_feed_mode != 10)
1047
0
                gp_fprintf(prn_stream, "%c10q", LIPS_CSI);
1048
0
            lips->prev_feed_mode = 10;
1049
0
        } else {
1050
0
            if (lips->prev_feed_mode != lips->cassetFeed)
1051
0
                gp_fprintf(prn_stream, "%c%dq", LIPS_CSI, lips->cassetFeed);
1052
0
            lips->prev_feed_mode = lips->cassetFeed;
1053
0
        }
1054
0
    } else if (lips->ManualFeed) { /* Use ManualFeed */
1055
0
        if (lips->prev_feed_mode != 1)
1056
0
            gp_fprintf(prn_stream, "%c1q", LIPS_CSI);
1057
0
        lips->prev_feed_mode = 1;
1058
0
    } else {
1059
0
        if (lips->prev_feed_mode != lips->cassetFeed)
1060
0
            gp_fprintf(prn_stream, "%c%dq", LIPS_CSI, lips->cassetFeed);
1061
0
        lips->prev_feed_mode = lips->cassetFeed;
1062
0
    }
1063
1064
    /* Use Verious Paper Size */
1065
0
    prev_paper_size = lips->prev_paper_size;
1066
0
    prev_paper_width = lips->prev_paper_width;
1067
0
    prev_paper_height = lips->prev_paper_height;
1068
1069
0
    if (prev_paper_size != paper_size) {
1070
0
        if (paper_size == USER_SIZE) {
1071
0
            gp_fprintf(prn_stream, "%c2 I", LIPS_CSI);
1072
0
            gp_fprintf(prn_stream, "%c80;%d;%dp", LIPS_CSI,
1073
0
                       width * 10, height * 10);
1074
0
        } else if (paper_size == USER_SIZE + LANDSCAPE) {
1075
0
            gp_fprintf(prn_stream, "%c2 I", LIPS_CSI);
1076
0
            gp_fprintf(prn_stream, "%c81;%d;%dp", LIPS_CSI,
1077
0
                       height * 10, width * 10);
1078
0
        } else {
1079
0
            gp_fprintf(prn_stream, "%c%dp", LIPS_CSI, paper_size);
1080
0
        }
1081
0
    } else if (paper_size == USER_SIZE) {
1082
0
        if (prev_paper_width != width ||
1083
0
            prev_paper_height != height) {
1084
0
            gp_fprintf(prn_stream, "%c2 I", LIPS_CSI);
1085
0
            gp_fprintf(prn_stream, "%c80;%d;%dp", LIPS_CSI,
1086
0
                       width * 10, height * 10);
1087
0
        }
1088
0
    } else if (paper_size == USER_SIZE + LANDSCAPE) {
1089
0
        if (prev_paper_width != width ||
1090
0
            prev_paper_height != height) {
1091
0
            gp_fprintf(prn_stream, "%c2 I", LIPS_CSI);
1092
0
            gp_fprintf(prn_stream, "%c81;%d;%dp", LIPS_CSI,
1093
0
                       height * 10, width * 10);
1094
0
        }
1095
0
    }
1096
    /* desired number of copies */
1097
0
    if (num_copies > 255)
1098
0
        num_copies = 255;
1099
0
    if (lips->prev_num_copies != num_copies) {
1100
0
        gp_fprintf(prn_stream, "%c%dv", LIPS_CSI, num_copies);
1101
0
        lips->prev_num_copies = num_copies;
1102
0
    }
1103
0
    if (ptype == LIPS4) {
1104
0
        if (lips4->faceup)
1105
0
            gp_fprintf(prn_stream, "%c11;12;12~", LIPS_CSI);
1106
0
    }
1107
0
    if (ptype == LIPS4) {
1108
1109
0
        if (pdev->PageCount == 0) {
1110
            /* N-up Printing */
1111
0
            if (lips4->nup != 1) {
1112
0
                gp_fprintf(prn_stream, "%c%d1;;%do", LIPS_CSI, lips4->nup, paper_size);
1113
0
            }
1114
0
        }
1115
        /* Duplex mode */
1116
0
        {
1117
0
            bool dup = lips4->Duplex;
1118
0
            int dupset = lips4->Duplex_set;
1119
0
            bool tum = lips4->Tumble;
1120
1121
0
            if (dupset && dup) {
1122
0
                if (lips4->prev_duplex_mode == 0 ||
1123
0
                    lips4->prev_duplex_mode == 1)
1124
0
                    gp_fprintf(prn_stream, "%c2;#x", LIPS_CSI);  /* duplex */
1125
0
                if (!tum) {
1126
                    /* long edge binding */
1127
0
                    if (lips4->prev_duplex_mode != 2)
1128
0
                        gp_fprintf(prn_stream, "%c0;#w", LIPS_CSI);
1129
0
                    lips4->prev_duplex_mode = 2;
1130
0
                } else {
1131
                    /* short edge binding */
1132
0
                    if (lips4->prev_duplex_mode != 3)
1133
0
                        gp_fprintf(prn_stream, "%c2;#w", LIPS_CSI);
1134
0
                    lips4->prev_duplex_mode = 3;
1135
0
                }
1136
0
            } else if (dupset && !dup) {
1137
0
                if (lips4->prev_duplex_mode != 1)
1138
0
                    gp_fprintf(prn_stream, "%c0;#x", LIPS_CSI);  /* simplex */
1139
0
                lips4->prev_duplex_mode = 1;
1140
0
            }
1141
0
        }
1142
0
    }
1143
0
    if (pdev->PageCount == 0) {
1144
        /* Display text on printer panel */
1145
0
        gp_fprintf(prn_stream, "%c2y%s%c", LIPS_DCS, lips->Username, LIPS_ST);
1146
1147
0
        gp_fprintf(prn_stream, "%c11h", LIPS_CSI);  /* Size Unit Mode */
1148
1149
0
        gp_fprintf(prn_stream, "%c?2;3h", LIPS_CSI);
1150
        /* 2: Disable Auto FF */
1151
        /* 3: Disable Auto CAP Movement */
1152
1153
0
        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
0
    }
1159
0
    if (prev_paper_size != paper_size || paper_size == USER_SIZE ||
1160
0
        paper_size == USER_SIZE + LANDSCAPE) {
1161
0
        if (ptype == LIPS4 || ptype == BJC880J) {
1162
0
            gp_fprintf(prn_stream, "%c?7;%d I", LIPS_CSI,
1163
0
                       (int)pdev->x_pixels_per_inch);  /* SelectSizeUnit */
1164
0
        } else {
1165
0
            gp_fprintf(prn_stream, "%c7 I", LIPS_CSI);  /* SelectSizeUnit */
1166
0
        }
1167
1168
0
        if (ptype == LIPS4 || ptype == BJC880J)
1169
0
          {
1170
0
            if (pdev->color_info.depth == 24)
1171
0
              gp_fprintf(prn_stream, "%c%d G", LIPS_CSI, NUM_LINES_4C);    /* VMI (dots) */
1172
0
            else
1173
0
              gp_fprintf(prn_stream, "%c%d G", LIPS_CSI, NUM_LINES);  /* VMI (dots) */
1174
0
          }
1175
0
    }
1176
0
    if (prev_paper_size != paper_size) {
1177
        /* Top Margin: 63/300 inch + 5 mm */
1178
0
        tm = (int)((63. / 300. + 5. / MMETER_PER_INCH - dev_t_margin(pdev)) * pdev->x_pixels_per_inch);
1179
0
        if (tm > 0)
1180
0
            gp_fprintf(prn_stream, "%c%dk", LIPS_CSI, tm);
1181
0
        if (tm < 0)
1182
0
            gp_fprintf(prn_stream, "%c%de", LIPS_CSI, -tm);
1183
1184
        /* Left Margin: 5 mm left */
1185
0
        lm = (int)((5. / MMETER_PER_INCH - dev_l_margin(pdev)) * pdev->x_pixels_per_inch);
1186
0
        if (lm > 0)
1187
0
            gp_fprintf(prn_stream, "%c%dj", LIPS_CSI, lm);
1188
0
        if (lm < 0)
1189
0
            gp_fprintf(prn_stream, "%c%da", LIPS_CSI, -lm);
1190
1191
        /* Set Top/Left Margins */
1192
0
        gp_fprintf(prn_stream, "%c0;2t", LIPS_CSI);
1193
1194
        /* Bottom Margin: height */
1195
0
        bm = (int)(pdev->height - (dev_t_margin(pdev) + dev_b_margin(pdev)) * pdev->y_pixels_per_inch);
1196
0
        gp_fprintf(prn_stream, "%c%de", LIPS_CSI, bm);
1197
        /* Right Margin: width */
1198
0
        rm = (int)(pdev->width - (dev_l_margin(pdev) + dev_r_margin(pdev)) * pdev->x_pixels_per_inch);
1199
0
        gp_fprintf(prn_stream, "%c%da", LIPS_CSI, rm);
1200
0
        gp_fprintf(prn_stream, "%c1;3t", LIPS_CSI);
1201
1202
        /* move CAP to (0, 0) */
1203
0
        gp_fprintf(prn_stream, "%c%dk\r", LIPS_CSI, bm);
1204
0
    }
1205
0
    lips->prev_paper_size = paper_size;
1206
0
    lips->prev_paper_width = width;
1207
0
    lips->prev_paper_height = height;
1208
0
}
1209
1210
static void
1211
lips_job_end(gx_device_printer * pdev, gp_file * prn_stream)
1212
0
{
1213
    /* Paper eject command */
1214
0
    gp_fprintf(prn_stream, "\r%c", LIPS_FF);
1215
0
}
1216
1217
static int lips_delta_compress(byte * inBuff, byte * prevBuff, byte * diffBuff, int Length);
1218
1219
static int
1220
lips_delta_encode(byte * inBuff, byte * prevBuff, byte * outBuff, byte * diffBuff, int Length)
1221
0
{
1222
0
    int i, j, k, com_size;
1223
1224
0
    com_size = lips_delta_compress(inBuff, prevBuff, diffBuff, Length);
1225
0
    if (com_size < 0) {   /* data is white raster */
1226
0
        *outBuff = 0x01;
1227
0
        *(outBuff + 1) = 0000;
1228
0
        for (k = 0; k < Length; k++)
1229
0
            *(prevBuff + k) = 0000;
1230
0
        return 2;
1231
0
    } else if (com_size == 0) { /* data is the same raster */
1232
0
        *outBuff = 0000;
1233
0
        return 1;
1234
0
    }
1235
0
    for (i = 0; i < com_size / 255; i++) {
1236
0
        *(outBuff + i) = 0377;
1237
0
    }
1238
1239
0
    *(outBuff + i) = (byte) (com_size % 255);
1240
1241
0
    for (j = 0; j < com_size; j++) {
1242
0
        *(outBuff + i + j + 1) = *(diffBuff + j);
1243
0
    }
1244
1245
0
    for (k = 0; k < Length; k++)
1246
0
        *(prevBuff + k) = *(inBuff + k);
1247
1248
0
    return i + j + 1;
1249
0
}
1250
1251
static int
1252
lips_delta_compress(byte * inBuff, byte * prevBuff, byte * diffBuff, int Length)
1253
0
{
1254
0
    int i, j;
1255
0
    bool zero_flag = TRUE;
1256
0
    bool same_flag = TRUE;
1257
0
    int num_bytes = 0;
1258
0
    int num_commandbyte = 0;
1259
0
    int size = 0;
1260
0
    int offset = 0;
1261
1262
0
    for (i = 0; i < Length; i++) {
1263
0
        if (*(inBuff + i) != 0x00)
1264
0
            zero_flag = FALSE;
1265
1266
        /* Compare Buffer */
1267
0
        if (*(inBuff + i) != *(prevBuff + i)) {
1268
0
            num_bytes++;
1269
1270
0
            if (same_flag == TRUE) {
1271
                /* first byte is offset */
1272
0
                if (offset > 31)
1273
0
                    *(diffBuff + size) = 0037;
1274
0
                else
1275
0
                    *(diffBuff + size) = offset;
1276
1277
0
                size++;
1278
0
                num_commandbyte++;
1279
1280
0
                for (j = 0; j < (offset - 31) / 255; j++) {
1281
0
                    *(diffBuff + size) = 0377;
1282
0
                    size++;
1283
0
                    num_commandbyte++;
1284
0
                }
1285
1286
0
                if ((offset - 31) % 255 >= 0) {
1287
0
                    *(diffBuff + size) = (offset - 31) % 255;
1288
0
                    size++;
1289
0
                    num_commandbyte++;
1290
0
                }
1291
0
                same_flag = FALSE;
1292
1293
0
            }
1294
0
        } else {
1295
0
            same_flag = TRUE;
1296
0
            offset++;
1297
0
        }
1298
1299
0
        if (num_bytes > 8) {
1300
            /* write number of data for replace */
1301
0
            *(diffBuff + size - num_commandbyte)
1302
0
                = *(diffBuff + size - num_commandbyte) | 0340;
1303
1304
0
            for (j = 0; j < 8; j++, size++) {
1305
0
                *(diffBuff + size) = *(inBuff + i + j - 8);
1306
0
            }
1307
1308
            /* offset is 0 */
1309
0
            *(diffBuff + size) = 0000;
1310
0
            size++;
1311
1312
0
            num_bytes = 1;
1313
0
            same_flag = FALSE;
1314
0
            num_commandbyte = 1;
1315
0
        } else if (same_flag == true && num_bytes > 0) {
1316
0
            offset = 1;
1317
1318
            /* write number of data for replace */
1319
0
            *(diffBuff + size - num_commandbyte)
1320
0
                = *(diffBuff + size - num_commandbyte) | ((num_bytes - 1) << 5);
1321
1322
            /* write a different bytes */
1323
0
            for (j = 0; j < num_bytes; j++, size++) {
1324
0
                *(diffBuff + size) = *(inBuff + i + j - num_bytes);
1325
0
            }
1326
0
            num_bytes = 0;
1327
0
            num_commandbyte = 0;
1328
0
        }
1329
0
    }
1330
1331
0
    if (num_bytes > 0) {
1332
        /* write number of data for replace */
1333
0
        *(diffBuff + size - num_commandbyte)
1334
0
            = *(diffBuff + size - num_commandbyte) | ((num_bytes - 1) << 5);
1335
1336
0
        for (j = 0; j < num_bytes; j++, size++) {
1337
0
            *(diffBuff + size) = *(inBuff + i + j - num_bytes);
1338
0
        }
1339
0
    }
1340
0
    if (zero_flag)
1341
0
        return -1;
1342
1343
0
    return size;
1344
0
}
1345
1346
/* This routine work like ``strcat'' */
1347
static int
1348
lips_byte_cat(byte * TotalBuff, byte * Buff, int TotalLen, int Len)
1349
0
{
1350
0
    int i;
1351
1352
0
    for (i = 0; i < Len; i++)
1353
0
        *(TotalBuff + TotalLen + i) = *(Buff + i);
1354
1355
0
    return TotalLen + Len;
1356
0
}