~ubuntu-branches/ubuntu/vivid/ghostscript/vivid-security

« back to all changes in this revision

Viewing changes to base/gdevdljm.c

  • Committer: Package Import Robot
  • Author(s): Till Kamppeter
  • Date: 2013-08-09 20:01:36 UTC
  • mfrom: (1.1.37)
  • Revision ID: package-import@ubuntu.com-20130809200136-amb6zrr7hnjb5jq9
Tags: 9.08~rc1~dfsg-0ubuntu1
* New upstream release
   - Ghostscript 9.08rc1.
   - We are using the system's liblcms2 and libopenjpeg now.
* debian/patches/020130401-852e545-pxl-xl-driver-produced-drawing-commands-without-setting-color-space.patch:
  Removed patch backported from upstream.
* debian/patches/ojdk-8007925+8007926.patch,
  debian/patches/ojdk-8007927.patch,
  debian/patches/ojdk-8007929.patch,
  debian/patches/ojdk-8009654.patch: Removed patches on build in liblcms2, we
  use the system's liblcms2 now.
* debian/patches/2001_docdir_fix_for_debian.patch: Manually updated to new
  upstream source code.
* debian/patches/2003_support_multiarch.patch: Refreshed with quilt.
* debian/control: Added build dependencies on liblcms2-dev and
  libopenjpeg-dev.
* debian/rules: Check for removed lcms2/ and openjpeg/ subdirectories in
  the repackaging check again, also set build options for shared liblcms2
  and libopenjpeg libraries.
* debian/rules: Makefile.in and configure.ac are in the root directory of
  the source now and do not need to get linked from base/. Also there is no
  gstoraster and gstopxl CUPS filter in the package any more and no
  "install-cups" make target any more.
* debian/control, debian/rules, debian/ghostscript-cups.install,
  debian/ghostscript-cups.ppd-updater: Removed the ghostscript-cups binary
  package. The files are now provided by cups-filters.
* debian/symbols.common: Updated for new upstream source. Applied patch
  which dpkg-gensymbols generated for debian/libgs9.symbols to this file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2001-2012 Artifex Software, Inc.
2
 
   All Rights Reserved.
3
 
 
4
 
   This software is provided AS-IS with no warranty, either express or
5
 
   implied.
6
 
 
7
 
   This software is distributed under license and may not be copied,
8
 
   modified or distributed except as expressly authorized under the terms
9
 
   of the license contained in the file LICENSE in this distribution.
10
 
 
11
 
   Refer to licensing information at http://www.artifex.com or contact
12
 
   Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134, San Rafael,
13
 
   CA  94903, U.S.A., +1(415)492-9861, for further information.
14
 
*/
15
 
 
16
 
/* Generic monochrome H-P DeskJet/LaserJet driver */
17
 
#include "gdevprn.h"
18
 
#include "gdevdljm.h"
19
 
 
20
 
/*
21
 
 * Thanks for various improvements to:
22
 
 *      Jim Mayer (mayer@wrc.xerox.com)
23
 
 *      Jan-Mark Wams (jms@cs.vu.nl)
24
 
 *      Frans van Hoesel (hoesel@chem.rug.nl)
25
 
 *      George Cameron (g.cameron@biomed.abdn.ac.uk)
26
 
 *      Nick Duffek (nsd@bbc.com)
27
 
 * Thanks for the FS-600 driver to:
28
 
 *      Peter Schildmann (peter.schildmann@etechnik.uni-rostock.de)
29
 
 * Thanks for the LJIIID duplex capability to:
30
 
 *      PDP (Philip) Brown (phil@3soft-uk.com)
31
 
 * Thanks for the OCE 9050 driver to:
32
 
 *      William Bader (wbader@EECS.Lehigh.Edu)
33
 
 * Thanks for the LJ4D duplex capability to:
34
 
 *      Les Johnson <les@infolabs.com>
35
 
 */
36
 
 
37
 
/* See gdevdljm.h for the definitions of the PCL_ features. */
38
 
 
39
 
/* The number of blank lines that make it worthwhile to reposition */
40
 
/* the cursor. */
41
 
#define MIN_SKIP_LINES 7
42
 
 
43
 
/* We round up the LINE_SIZE to a multiple of a ulong for faster scanning. */
44
 
#define W sizeof(word)
45
 
 
46
 
/* Send a page to the printer. */
47
 
int
48
 
dljet_mono_print_page(gx_device_printer * pdev, FILE * prn_stream,
49
 
                      int dots_per_inch, int features, const char *page_init)
50
 
{
51
 
    return dljet_mono_print_page_copies(pdev, prn_stream, 1, dots_per_inch,
52
 
                                        features, page_init, page_init, false);
53
 
}
54
 
int
55
 
dljet_mono_print_page_copies(gx_device_printer * pdev, FILE * prn_stream,
56
 
                             int num_copies, int dots_per_inch, int features,
57
 
                             const char *odd_page_init, const char *even_page_init, bool tumble)
58
 
{
59
 
    int line_size = gdev_mem_bytes_per_scan_line((gx_device *) pdev);
60
 
    int line_size_words = (line_size + W - 1) / W;
61
 
    uint storage_size_words = line_size_words * 8;      /* data, out_row, out_row_alt, prev_row */
62
 
    word *storage;
63
 
    word
64
 
        *data_words,
65
 
        *out_row_words,
66
 
        *out_row_alt_words,
67
 
        *prev_row_words;
68
 
#define data ((byte *)data_words)
69
 
#define out_row ((byte *)out_row_words)
70
 
#define out_row_alt ((byte *)out_row_alt_words)
71
 
#define prev_row ((byte *)prev_row_words)
72
 
    byte *out_data;
73
 
    int x_dpi = (int)pdev->x_pixels_per_inch;
74
 
    int y_dpi = (int)pdev->y_pixels_per_inch;
75
 
    int y_dots_per_pixel = dots_per_inch / y_dpi;
76
 
    int num_rows = dev_print_scan_lines(pdev);
77
 
 
78
 
    int out_count;
79
 
    int compression = -1;
80
 
    static const char *const from2to3 = "\033*b3M";
81
 
    static const char *const from3to2 = "\033*b2M";
82
 
    int penalty_from2to3 = strlen(from2to3);
83
 
    int penalty_from3to2 = strlen(from3to2);
84
 
    int paper_size = gdev_pcl_paper_size((gx_device *) pdev);
85
 
    int code = 0;
86
 
    bool dup = pdev->Duplex;
87
 
    bool dupset = pdev->Duplex_set >= 0;
88
 
 
89
 
    if (num_copies != 1 && !(features & PCL_CAN_PRINT_COPIES))
90
 
        return gx_default_print_page_copies(pdev, prn_stream, num_copies);
91
 
    storage =
92
 
        (ulong *)gs_alloc_byte_array(pdev->memory, storage_size_words, W,
93
 
                                     "hpjet_print_page");
94
 
    if (storage == 0)           /* can't allocate working area */
95
 
        return_error(gs_error_VMerror);
96
 
    data_words = storage;
97
 
    out_row_words = data_words + (line_size_words * 2);
98
 
    out_row_alt_words = out_row_words + (line_size_words * 2);
99
 
    prev_row_words = out_row_alt_words + (line_size_words * 2);
100
 
    /* Clear temp storage */
101
 
    memset(data, 0, storage_size_words * W);
102
 
 
103
 
    /* Initialize printer. */
104
 
    if (pdev->PageCount == 0) {
105
 
        if (features & HACK__IS_A_LJET4PJL) {
106
 
            fputs("\033%-12345X@PJL\r\n@PJL ENTER LANGUAGE = PCL\r\n",
107
 
                  prn_stream);
108
 
        }
109
 
        fputs("\033E", prn_stream);     /* reset printer */
110
 
        /* If the printer supports it, set the paper size */
111
 
        /* based on the actual requested size. */
112
 
        if (features & PCL_CAN_SET_PAPER_SIZE) {
113
 
            fprintf(prn_stream, "\033&l%dA", paper_size);
114
 
        }
115
 
        /* If printer can duplex, set duplex mode appropriately. */
116
 
        if (features & PCL_HAS_DUPLEX) {
117
 
            if (dupset && dup && !tumble)
118
 
                fputs("\033&l1S", prn_stream);
119
 
       else if (dupset && dup && tumble)
120
 
                fputs("\033&l2S", prn_stream);
121
 
            else if (dupset && !dup)
122
 
                fputs("\033&l0S", prn_stream);
123
 
            else                /* default to duplex for this printer */
124
 
                fputs("\033&l1S", prn_stream);
125
 
        }
126
 
    }
127
 
    /* Put out per-page initialization. */
128
 
    /*
129
 
       Modified by karsten@sengebusch.de
130
 
       in duplex mode the sheet is alread in process, so there are some
131
 
       commands which must not be sent to the printer for the 2nd page,
132
 
       as this commands will cause the printer to eject the sheet with
133
 
       only the 1st page printed. This commands are:
134
 
       \033&l%dA (setting paper size)
135
 
       \033&l%dH (setting paper tray)
136
 
       in simplex mode we set this parameters for each page,
137
 
       in duplex mode we set this parameters for each odd page
138
 
    */
139
 
 
140
 
    if ((features & PCL_HAS_DUPLEX) && dupset && dup) {
141
 
       /* We are printing duplex, so change margins as needed */
142
 
       if ((pdev->PageCount%2)==0) {
143
 
          if (features & PCL_CAN_SET_PAPER_SIZE) {
144
 
              fprintf(prn_stream, "\033&l%dA", paper_size);
145
 
          }
146
 
          fputs("\033&l0o0l0E", prn_stream);
147
 
          fputs(odd_page_init, prn_stream);
148
 
       } else
149
 
          fputs(even_page_init, prn_stream);
150
 
    } else {
151
 
        if (features & PCL_CAN_SET_PAPER_SIZE){
152
 
            fprintf(prn_stream, "\033&l%dA", paper_size);
153
 
        }
154
 
        fputs("\033&l0o0l0E", prn_stream);
155
 
        fputs(odd_page_init, prn_stream);
156
 
    }
157
 
 
158
 
    fprintf(prn_stream, "\033&l%dX", num_copies);       /* # of copies */
159
 
 
160
 
    /* End raster graphics, position cursor at top. */
161
 
    fputs("\033*rB\033*p0x0Y", prn_stream);
162
 
 
163
 
    /* The DeskJet and DeskJet Plus reset everything upon */
164
 
    /* receiving \033*rB, so we must reinitialize graphics mode. */
165
 
    if (features & PCL_END_GRAPHICS_DOES_RESET) {
166
 
        fputs(odd_page_init, prn_stream); /* Assume this does the right thing */
167
 
        fprintf(prn_stream, "\033&l%dX", num_copies);   /* # of copies */
168
 
    }
169
 
 
170
 
    /* Set resolution. */
171
 
    fprintf(prn_stream, "\033*t%dR", x_dpi);
172
 
 
173
 
    /* Send each scan line in turn */
174
 
    {
175
 
        int lnum;
176
 
        int num_blank_lines = 0;
177
 
        word rmask = ~(word) 0 << (-pdev->width & (W * 8 - 1));
178
 
 
179
 
        /* Transfer raster graphics. */
180
 
        for (lnum = 0; lnum < num_rows; lnum++) {
181
 
            register word *end_data =
182
 
            data_words + line_size_words;
183
 
 
184
 
            code = gdev_prn_copy_scan_lines(pdev, lnum,
185
 
                                            (byte *) data, line_size);
186
 
            if (code < 0)
187
 
                break;
188
 
            /* Mask off 1-bits beyond the line width. */
189
 
            end_data[-1] &= rmask;
190
 
            /* Remove trailing 0s. */
191
 
            while (end_data > data_words && end_data[-1] == 0)
192
 
                end_data--;
193
 
            if (end_data == data_words) {       /* Blank line */
194
 
                num_blank_lines++;
195
 
                continue;
196
 
            }
197
 
            /* We've reached a non-blank line. */
198
 
            /* Put out a spacing command if necessary. */
199
 
            if (num_blank_lines == lnum) {
200
 
                /* We're at the top of a page. */
201
 
                if (features & PCL_ANY_SPACING) {
202
 
                    if (num_blank_lines > 0)
203
 
                        fprintf(prn_stream, "\033*p+%dY",
204
 
                                num_blank_lines * y_dots_per_pixel);
205
 
                    /* Start raster graphics. */
206
 
                    fputs("\033*r1A", prn_stream);
207
 
                } else if (features & PCL_MODE_3_COMPRESSION) {
208
 
                    /* Start raster graphics. */
209
 
                    fputs("\033*r1A", prn_stream);
210
 
#if 1                           /* don't waste paper */
211
 
                    if (num_blank_lines > 0)
212
 
                        fputs("\033*b0W", prn_stream);
213
 
                    num_blank_lines = 0;
214
 
#else
215
 
                    for (; num_blank_lines; num_blank_lines--)
216
 
                        fputs("\033*b0W", prn_stream);
217
 
#endif
218
 
                } else {
219
 
                    /* Start raster graphics. */
220
 
                    fputs("\033*r1A", prn_stream);
221
 
                    for (; num_blank_lines; num_blank_lines--)
222
 
                        fputs("\033*bW", prn_stream);
223
 
                }
224
 
            }
225
 
            /* Skip blank lines if any */
226
 
            else if (num_blank_lines != 0) {
227
 
                /*
228
 
                 * Moving down from current position causes head motion
229
 
                 * on the DeskJet, so if the number of lines is small,
230
 
                 * we're better off printing blanks.
231
 
                 */
232
 
                /*
233
 
                 * For Canon LBP4i and some others, <ESC>*b<n>Y doesn't
234
 
                 * properly clear the seed row if we are in compression mode
235
 
                 * 3.
236
 
                 */
237
 
                if ((num_blank_lines < MIN_SKIP_LINES && compression != 3) ||
238
 
                    !(features & PCL_ANY_SPACING)
239
 
                    ) {
240
 
                    bool mode_3ns =
241
 
                        (features & PCL_MODE_3_COMPRESSION) &&
242
 
                        !(features & PCL_ANY_SPACING);
243
 
 
244
 
                    if (mode_3ns && compression != 2) {
245
 
                        /* Switch to mode 2 */
246
 
                        fputs(from3to2, prn_stream);
247
 
                        compression = 2;
248
 
                    }
249
 
                    if (features & PCL_MODE_3_COMPRESSION) {
250
 
                        /* Must clear the seed row. */
251
 
                        fputs("\033*b1Y", prn_stream);
252
 
                        num_blank_lines--;
253
 
                    }
254
 
                    if (mode_3ns) {
255
 
                        for (; num_blank_lines; num_blank_lines--)
256
 
                            fputs("\033*b0W", prn_stream);
257
 
                    } else {
258
 
                        for (; num_blank_lines; num_blank_lines--)
259
 
                            fputs("\033*bW", prn_stream);
260
 
                    }
261
 
                } else if (features & PCL3_SPACING) {
262
 
                    fprintf(prn_stream, "\033*p+%dY",
263
 
                            num_blank_lines * y_dots_per_pixel);
264
 
                } else {
265
 
                    fprintf(prn_stream, "\033*b%dY",
266
 
                            num_blank_lines);
267
 
                }
268
 
                /* Clear the seed row (only matters for */
269
 
                /* mode 3 compression). */
270
 
                memset(prev_row, 0, line_size);
271
 
            }
272
 
            num_blank_lines = 0;
273
 
 
274
 
            /* Choose the best compression mode */
275
 
            /* for this particular line. */
276
 
            if (features & PCL_MODE_3_COMPRESSION) {
277
 
                /* Compression modes 2 and 3 are both */
278
 
                /* available.  Try both and see which one */
279
 
                /* produces the least output data. */
280
 
                int count3 = gdev_pcl_mode3compress(line_size, data,
281
 
                                                    prev_row, out_row);
282
 
                int count2 = gdev_pcl_mode2compress(data_words, end_data,
283
 
                                                    out_row_alt);
284
 
                int penalty3 =
285
 
                    (compression == 3 ? 0 : penalty_from2to3);
286
 
                int penalty2 =
287
 
                    (compression == 2 ? 0 : penalty_from3to2);
288
 
 
289
 
                if (count3 + penalty3 < count2 + penalty2) {
290
 
                    if (compression != 3)
291
 
                        fputs(from2to3, prn_stream);
292
 
                    compression = 3;
293
 
                    out_data = out_row;
294
 
                    out_count = count3;
295
 
                } else {
296
 
                    if (compression != 2)
297
 
                        fputs(from3to2, prn_stream);
298
 
                    compression = 2;
299
 
                    out_data = out_row_alt;
300
 
                    out_count = count2;
301
 
                }
302
 
            } else if (features & PCL_MODE_2_COMPRESSION) {
303
 
                out_data = out_row;
304
 
                out_count = gdev_pcl_mode2compress(data_words, end_data,
305
 
                                                   out_row);
306
 
            } else {
307
 
                out_data = data;
308
 
                out_count = (byte *) end_data - data;
309
 
            }
310
 
 
311
 
            /* Transfer the data */
312
 
            fprintf(prn_stream, "\033*b%dW", out_count);
313
 
            fwrite(out_data, sizeof(byte), out_count,
314
 
                   prn_stream);
315
 
        }
316
 
    }
317
 
 
318
 
    /* end raster graphics and eject page */
319
 
    fputs("\033*rB\f", prn_stream);
320
 
 
321
 
    /* free temporary storage */
322
 
    gs_free_object(pdev->memory, storage, "hpjet_print_page");
323
 
 
324
 
    return code;
325
 
}