~ubuntu-branches/ubuntu/jaunty/ghostscript/jaunty-updates

« back to all changes in this revision

Viewing changes to src/gdevpsim.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2009-01-20 16:40:45 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090120164045-lnfhi0n30o5lwhwa
Tags: 8.64.dfsg.1~svn9377-0ubuntu1
* New upstream release (SVN rev 9377)
   o Fixes many bugs concerning PDF rendering, to make the PDF printing
     workflow correctly working.
   o Fixes long-standing bugs in many drivers, like input paper tray and
     duplex options not working for the built-in PCL 4, 5, 5c, 5e, and
     6/XL drivers, PDF input not working for bjc600, bjc800, and cups
     output devices, several options not working and uninitialized
     memory with cups output device.
   o Merged nearly all patches of the Ubuntu and Debian packages upstream.
   o Fixes LP: #317810, LP: #314439, LP: #314018.
* debian/patches/03_libpaper_support.dpatch,
  debian/patches/11_gs-cjk_font_glyph_handling_fix.dpatch,
  debian/patches/12_gs-cjk_vertical_writing_metrics_fix.dpatch,
  debian/patches/13_gs-cjk_cjkps_examples.dpatch,
  debian/patches/20_bbox_segv_fix.dpatch,
  debian/patches/21_brother_7x0_gdi_fix.dpatch,
  debian/patches/22_epsn_margin_workaround.dpatch,
  debian/patches/24_gs_man_fix.dpatch,
  debian/patches/25_toolbin_insecure_tmp_usage_fix.dpatch,
  debian/patches/26_assorted_script_fixes.dpatch,
  debian/patches/29_gs_css_fix.dpatch,
  debian/patches/30_ps2pdf_man_improvement.dpatch,
  debian/patches/31_fix-gc-sigbus.dpatch,
  debian/patches/34_ftbfs-on-hurd-fix.dpatch,
  debian/patches/35_disable_libcairo.dpatch,
  debian/patches/38_pxl-duplex.dpatch,
  debian/patches/39_pxl-resolution.dpatch,
  debian/patches/42_gs-init-ps-delaybind-fix.dpatch,
  debian/patches/45_bjc600-bjc800-pdf-input.dpatch,
  debian/patches/48_cups-output-device-pdf-duplex-uninitialized-memory-fix.dpatch,
  debian/patches/50_lips4-floating-point-exception.dpatch,
  debian/patches/52_cups-device-logging.dpatch,
  debian/patches/55_pcl-input-slot-fix.dpatch,
  debian/patches/57_pxl-input-slot-fix.dpatch,
  debian/patches/60_pxl-cups-driver-pdf.dpatch,
  debian/patches/62_onebitcmyk-pdf.dpatch,
  debian/patches/65_too-big-temp-files-1.dpatch,
  debian/patches/67_too-big-temp-files-2.dpatch,
  debian/patches/70_take-into-account-data-in-stream-buffer-before-refill.dpatch:
  Removed, applied upstream.
* debian/patches/01_docdir_fix_for_debian.dpatch,
  debian/patches/02_gs_man_fix_debian.dpatch,
  debian/patches/01_docdir-fix-for-debian.dpatch,
  debian/patches/02_docdir-fix-for-debian.dpatch: Renamed patches to
  make merging with Debian easier.
* debian/patches/32_improve-handling-of-media-size-changes-from-gv.dpatch, 
  debian/patches/33_bad-params-to-xinitimage-on-large-bitmaps.dpatch:
  regenerated for new source directory structure.
* debian/rules: Corrected paths to remove cidfmap (it is in Resource/Init/
  in GS 8.64) and to install headers (source paths are psi/ and base/ now).
* debian/rules: Remove all fontmaps, as DeFoMa replaces them.
* debian/local/pdftoraster/pdftoraster.c,
  debian/local/pdftoraster/pdftoraster.convs, debian/rules: Removed
  added pdftoraster filter and use the one which comes with Ghostscript.
* debian/ghostscript.links: s/8.63/8.64/

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2001-2006 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, modified
8
 
   or distributed except as expressly authorized under the terms of that
9
 
   license.  Refer to licensing information at http://www.artifex.com/
10
 
   or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
11
 
   San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
12
 
*/
13
 
 
14
 
/* $Id: gdevpsim.c 8250 2007-09-25 13:31:24Z giles $ */
15
 
/* PostScript image output device */
16
 
#include "gdevprn.h"
17
 
#include "gdevpsu.h"
18
 
#include "stream.h"
19
 
#include "strimpl.h"
20
 
#include "sa85x.h"
21
 
#include "srlx.h"
22
 
 
23
 
/*
24
 
 * There are two drivers in this file, both of which produce PostScript
25
 
 * output consisting of a single bitmap per page.  The psmono/psgray
26
 
 * driver produces monochrome Level 1 images using home-grown run length
27
 
 * compression; the psrgb driver produces planar RGB Level 2 images
28
 
 * using the RunLengthEncode filter.
29
 
 */
30
 
 
31
 
/* ---------------- Shared code ---------------- */
32
 
 
33
 
/* Define the device parameters. */
34
 
#ifndef X_DPI
35
 
#  define X_DPI 300
36
 
#endif
37
 
#ifndef Y_DPI
38
 
#  define Y_DPI 300
39
 
#endif
40
 
 
41
 
/* Write the file (if necessary) and page headers. */
42
 
static void
43
 
ps_image_write_headers(FILE *f, gx_device_printer *pdev,
44
 
                       const char *const setup[],
45
 
                       gx_device_pswrite_common_t *pdpc)
46
 
{
47
 
    if (gdev_prn_file_is_new(pdev)) {
48
 
        gs_rect bbox;
49
 
 
50
 
        bbox.p.x = 0;
51
 
        bbox.p.y = 0;
52
 
        bbox.q.x = pdev->width / pdev->HWResolution[0] * 72.0;
53
 
        bbox.q.y = pdev->height / pdev->HWResolution[1] * 72.0;
54
 
        psw_begin_file_header(f, (gx_device *)pdev, &bbox, pdpc, false);
55
 
        psw_print_lines(f, setup);
56
 
        psw_end_file_header(f);
57
 
    }
58
 
    {
59
 
        byte buf[100];          /* arbitrary */
60
 
        stream s;
61
 
 
62
 
        s_init(&s, pdev->memory);
63
 
        swrite_file(&s, f, buf, sizeof(buf));
64
 
        psw_write_page_header(&s, (gx_device *)pdev, pdpc, true, pdev->PageCount + 1, 10);
65
 
        sflush(&s);
66
 
    }
67
 
}
68
 
 
69
 
/* ---------------- Level 1 monochrome driver ---------------- */
70
 
 
71
 
/*
72
 
 * This driver produces a bitmap in the form of a PostScript file that can
73
 
 * be fed to any PostScript printer.  It uses a run-length compression
74
 
 * method that executes quickly (unlike some produced by PostScript
75
 
 * drivers!).
76
 
 *
77
 
 * There are two devices here, one for 1-bit black-and-white and one
78
 
 * for 8-bit gray.  In fact, the same code could also handle 2- and
79
 
 * 4-bit gray output.
80
 
 */
81
 
 
82
 
/* The device descriptor */
83
 
static dev_proc_print_page(psmono_print_page);
84
 
static dev_proc_close_device(psmono_close);
85
 
 
86
 
const gx_device_printer gs_psmono_device =
87
 
prn_device(prn_std_procs, "psmono",
88
 
           DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
89
 
           X_DPI, Y_DPI,
90
 
           0, 0, 0, 0,          /* margins */
91
 
           1, psmono_print_page);
92
 
 
93
 
static const gx_device_procs psgray_procs =
94
 
prn_color_procs(gdev_prn_open, gdev_prn_output_page, psmono_close,
95
 
              gx_default_gray_map_rgb_color, gx_default_gray_map_color_rgb);
96
 
 
97
 
const gx_device_printer gs_psgray_device = {
98
 
    prn_device_body(gx_device_printer, psgray_procs, "psgray",
99
 
                    DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
100
 
                    X_DPI, Y_DPI,
101
 
                    0, 0, 0, 0, /* margins */
102
 
                    1, 8, 255, 0, 256, 1, psmono_print_page)
103
 
};
104
 
 
105
 
static const char *const psmono_setup[] = {
106
 
                /* Initialize the strings for filling runs. */
107
 
    "/.ImageFills [ 0 1 255 {",
108
 
    "  256 string dup 0 1 7 { 3 index put dup } for { 8 16 32 64 128 } {",
109
 
    "    2 copy 0 exch getinterval putinterval dup",
110
 
    "  } forall pop exch pop",
111
 
    "} bind for ] def",
112
 
                /* Initialize the procedure table for input dispatching. */
113
 
    "/.ImageProcs [",
114
 
                /* Stack: <buffer> <file> <xdigits> <previous> <byte> */
115
 
    "  32 { { pop .ImageItem } } repeat",
116
 
    "  16 { {", /* 0x20-0x2f: (N-0x20) data bytes follow */
117
 
    "    32 sub 3 -1 roll add 3 index exch 0 exch getinterval 2 index exch",
118
 
    "    readhexstring pop exch pop 0 exch dup",
119
 
    "  } bind } repeat",
120
 
    "  16 { {", /* 0x30-0x3f: prefix hex digit (N-0x30) to next count */
121
 
    "    48 sub 3 -1 roll add 4 bitshift exch .ImageItem",
122
 
    "  } bind } repeat",
123
 
    "  32 { {", /* 0x40-0x5f: repeat last data byte (N-0x40) times */
124
 
    "    64 sub 3 -1 roll add .ImageFills 2 index dup length 1 sub get get",
125
 
    "    exch 0 exch getinterval 0 3 1 roll",
126
 
    "  } bind } repeat",
127
 
    "  160 { { pop .ImageItem } } repeat",
128
 
    "] readonly def",
129
 
                /* Read one item from a compressed image. */
130
 
                /* Stack contents: <buffer> <file> <xdigits> <previous> */
131
 
    "/.ImageItem {",
132
 
    "  2 index read pop dup .ImageProcs exch get exec",
133
 
    "} bind def",
134
 
                /* Read and print an entire compressed image. */
135
 
    "/.ImageRead {"     /* <width> <height> <bpc> .ImageRead - */
136
 
    "  gsave [",
137
 
      /* Stack: width height bpc -mark- */
138
 
    "    1 0 0 -1 0 7 index",
139
 
      /* Stack: width height bpc -mark- 1 0 0 -1 0 height */
140
 
    "  ] { .ImageItem }",
141
 
        /* Stack: width height bpc <matrix> <proc> */
142
 
    "  4 index 3 index mul 7 add 8 idiv string currentfile 0 ()",
143
 
        /* Stack: width height bpc <matrix> <proc> <buffer> <file> 0 () */
144
 
    "  9 4 roll",
145
 
        /* Stack: <buffer> <file> 0 () width height bpc <matrix> <proc> */
146
 
    "  image pop pop pop pop grestore",
147
 
    "} def",
148
 
    0
149
 
};
150
 
static const gx_device_pswrite_common_t psmono_values =
151
 
    PSWRITE_COMMON_VALUES(1, 0 /*false*/, 1);
152
 
 
153
 
#define data_run_code 0x20
154
 
#define xdigit_code 0x30
155
 
#define max_data_per_line 35
156
 
#define repeat_run_code 0x40
157
 
#define max_repeat_run_code 31
158
 
#define max_repeat_run 255
159
 
 
160
 
/* Send the page to the printer. */
161
 
static void write_data_run(const byte *, int, FILE *, byte);
162
 
static int
163
 
psmono_print_page(gx_device_printer * pdev, FILE * prn_stream)
164
 
{
165
 
    int line_size = gdev_mem_bytes_per_scan_line((gx_device *) pdev);
166
 
    int lnum;
167
 
    byte *line = gs_alloc_bytes(pdev->memory, line_size, "psmono_print_page");
168
 
    byte invert = (pdev->color_info.depth == 1 ? 0xff : 0);
169
 
    gx_device_pswrite_common_t pswrite_common;
170
 
 
171
 
    if (line == 0)
172
 
        return_error(gs_error_VMerror);
173
 
    pswrite_common = psmono_values;
174
 
 
175
 
    /* If this is the first page of the file, */
176
 
    /* write the setup code. */
177
 
    ps_image_write_headers(prn_stream, pdev, psmono_setup, &pswrite_common);
178
 
 
179
 
    /* Write the .ImageRead command. */
180
 
    fprintf(prn_stream,
181
 
            "%d %d %d .ImageRead\n",
182
 
            pdev->width, pdev->height, pdev->color_info.depth);
183
 
 
184
 
    /* Compress each scan line in turn. */
185
 
    for (lnum = 0; lnum < pdev->height; lnum++) {
186
 
        const byte *p;
187
 
        int left = line_size;
188
 
        byte *data;
189
 
 
190
 
        gdev_prn_get_bits(pdev, lnum, line, &data);
191
 
        p = data;
192
 
        /* Loop invariant: p + left = data + line_size. */
193
 
#define min_repeat_run 10
194
 
        while (left >= min_repeat_run) {        /* Detect a maximal run of non-repeated data. */
195
 
            const byte *p1 = p;
196
 
            int left1 = left;
197
 
            byte b;
198
 
            int count, count_left;
199
 
 
200
 
            while (left1 >= min_repeat_run &&
201
 
                   ((b = *p1) != p1[1] ||
202
 
                    b != p1[2] || b != p1[3] || b != p1[4] ||
203
 
                    b != p1[5] || b != p1[6] || b != p1[7] ||
204
 
                    b != p1[8] || b != p1[9])
205
 
                )
206
 
                ++p1, --left1;
207
 
            if (left1 < min_repeat_run)
208
 
                break;          /* no repeated data left */
209
 
            write_data_run(p, (int)(p1 - p + 1), prn_stream,
210
 
                           invert);
211
 
            /* Detect a maximal run of repeated data. */
212
 
            p = ++p1 + (min_repeat_run - 1);
213
 
            left = --left1 - (min_repeat_run - 1);
214
 
            while (left > 0 && *p == b)
215
 
                ++p, --left;
216
 
            for (count = p - p1; count > 0;
217
 
                 count -= count_left
218
 
                ) {
219
 
                count_left = min(count, max_repeat_run);
220
 
                if (count_left > max_repeat_run_code)
221
 
                    fputc(xdigit_code + (count_left >> 4),
222
 
                          prn_stream),
223
 
                        fputc(repeat_run_code + (count_left & 0xf),
224
 
                              prn_stream);
225
 
                else
226
 
                    putc(repeat_run_code + count_left,
227
 
                         prn_stream);
228
 
            }
229
 
            if (ferror(prn_stream))
230
 
                return_error(gs_error_ioerror);
231
 
        }
232
 
        /* Write the remaining data, if any. */
233
 
        write_data_run(p, left, prn_stream, invert);
234
 
    }
235
 
 
236
 
    /* Clean up and return. */
237
 
    fputs("\n", prn_stream);
238
 
    psw_write_page_trailer(prn_stream, 1, true);
239
 
    gs_free_object(pdev->memory, line, "psmono_print_page");
240
 
    if (ferror(prn_stream))
241
 
        return_error(gs_error_ioerror);
242
 
    return 0;
243
 
}
244
 
 
245
 
/* Close the file. */
246
 
static int
247
 
psmono_close(gx_device *dev)
248
 
{
249
 
    int code = psw_end_file(((gx_device_printer *)dev)->file, dev, 
250
 
            &psmono_values, NULL, dev->PageCount);
251
 
    
252
 
    if (code < 0)
253
 
        return code;
254
 
    return gdev_prn_close(dev);
255
 
}
256
 
 
257
 
/* Write a run of data on the file. */
258
 
static void
259
 
write_data_run(const byte * data, int count, FILE * f, byte invert)
260
 
{
261
 
    const byte *p = data;
262
 
    const char *const hex_digits = "0123456789abcdef";
263
 
    int left = count;
264
 
    char line[sizeof(count) * 2 + max_data_per_line * 2 + 3];
265
 
    char *q = line;
266
 
 
267
 
    /* Write the count. */
268
 
 
269
 
    if (!count)
270
 
        return;
271
 
    {
272
 
        int shift = sizeof(count) * 8;
273
 
 
274
 
        while ((shift -= 4) > 0 && (count >> shift) == 0);
275
 
        for (; shift > 0; shift -= 4)
276
 
            *q++ = xdigit_code + ((count >> shift) & 0xf);
277
 
        *q++ = data_run_code + (count & 0xf);
278
 
    }
279
 
 
280
 
    /* Write the data. */
281
 
 
282
 
    while (left > 0) {
283
 
        register int wcount = min(left, max_data_per_line);
284
 
 
285
 
        left -= wcount;
286
 
        for (; wcount > 0; ++p, --wcount) {
287
 
            byte b = *p ^ invert;
288
 
 
289
 
            *q++ = hex_digits[b >> 4];
290
 
            *q++ = hex_digits[b & 0xf];
291
 
        }
292
 
        *q++ = '\n';
293
 
        fwrite(line, 1, q - line, f);
294
 
        q = line;
295
 
    }
296
 
 
297
 
}
298
 
 
299
 
/* ---------------- Level 2 RGB driver ---------------- */
300
 
 
301
 
/*
302
 
 * This driver produces plane-separated, run-length-encoded, 24-bit RGB
303
 
 * images suitable for a PostScript Level 2 printer.  LZW compression would
304
 
 * be better, but Unisys' claim to own the compression algorithm and their
305
 
 * demand for licensing and payment even for freely distributed software
306
 
 * rule this out.
307
 
 */
308
 
 
309
 
/* The device descriptor */
310
 
static dev_proc_print_page(psrgb_print_page);
311
 
static dev_proc_close_device(psrgb_close);
312
 
 
313
 
static const gx_device_procs psrgb_procs =
314
 
prn_color_procs(gdev_prn_open, gdev_prn_output_page, psrgb_close,
315
 
                gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb);
316
 
 
317
 
const gx_device_printer gs_psrgb_device = {
318
 
    prn_device_body(gx_device_printer, psrgb_procs, "psrgb",
319
 
                    DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
320
 
                    X_DPI, Y_DPI,
321
 
                    0, 0, 0, 0, /* margins */
322
 
                    3, 24, 255, 255, 256, 256, psrgb_print_page)
323
 
};
324
 
 
325
 
static const char *const psrgb_setup[] = {
326
 
    "/rgbimage {",              /* <width> <height> rgbimage - */
327
 
    "  gsave 2 copy scale /h exch def /w exch def",
328
 
    "  /s1 w string def /s2 w string def /s3 w string def",
329
 
    "  /f currentfile /ASCII85Decode filter /RunLengthDecode filter def",
330
 
    "  w h 8 [w 0 0 h neg 0 h]",
331
 
    "  {f s1 readstring pop} {f s2 readstring pop} {f s3 readstring pop}",
332
 
    "  true 3 colorimage grestore",
333
 
    "} bind def",
334
 
    0
335
 
};
336
 
static const gx_device_pswrite_common_t psrgb_values =
337
 
    PSWRITE_COMMON_VALUES(2, 0 /*false*/, 1);
338
 
 
339
 
/* Send the page to the printer. */
340
 
static int
341
 
psrgb_print_page(gx_device_printer * pdev, FILE * prn_stream)
342
 
{
343
 
    gs_memory_t *mem = pdev->memory;
344
 
    int width = pdev->width;
345
 
    byte *lbuf = gs_alloc_bytes(mem, width * 3,
346
 
                                "psrgb_print_page(lbuf)");
347
 
    int lnum;
348
 
    stream fs, a85s, rls;
349
 
    stream_A85E_state a85state;
350
 
    stream_RLE_state rlstate;
351
 
    byte fsbuf[200];            /* arbitrary, must be >2 */
352
 
    byte a85sbuf[100];          /* arbitrary, must be >=6 */
353
 
    byte rlsbuf[200];           /* arbitrary, must be >128 */
354
 
    gx_device_pswrite_common_t pswrite_common;
355
 
    pswrite_common = psrgb_values;
356
 
 
357
 
    if (lbuf == 0)
358
 
        return_error(gs_error_VMerror);
359
 
    ps_image_write_headers(prn_stream, pdev, psrgb_setup, &pswrite_common);
360
 
    fprintf(prn_stream, "%d %d rgbimage\n", width, pdev->height);
361
 
    s_init(&fs, mem);
362
 
    swrite_file(&fs, prn_stream, fsbuf, sizeof(fsbuf));
363
 
    fs.memory = 0;
364
 
 
365
 
    if (s_A85E_template.set_defaults)
366
 
        (*s_A85E_template.set_defaults) ((stream_state *) & a85state);
367
 
    s_init(&a85s, mem);
368
 
    s_std_init(&a85s, a85sbuf, sizeof(a85sbuf), &s_filter_write_procs,
369
 
               s_mode_write);
370
 
    a85s.memory = 0;
371
 
    a85state.memory = 0;
372
 
    a85state.template = &s_A85E_template;
373
 
    (*s_A85E_template.init) ((stream_state *) & a85state);
374
 
    a85s.state = (stream_state *) & a85state;
375
 
    a85s.procs.process = s_A85E_template.process;
376
 
    a85s.strm = &fs;
377
 
 
378
 
    (*s_RLE_template.set_defaults) ((stream_state *) & rlstate);
379
 
    s_init(&rls, mem);
380
 
    s_std_init(&rls, rlsbuf, sizeof(rlsbuf), &s_filter_write_procs,
381
 
               s_mode_write);
382
 
    rls.memory = 0;
383
 
    rlstate.memory = 0;
384
 
    rlstate.template = &s_RLE_template;
385
 
    (*s_RLE_template.init) ((stream_state *) & rlstate);
386
 
    rls.state = (stream_state *) & rlstate;
387
 
    rls.procs.process = s_RLE_template.process;
388
 
    rls.strm = &a85s;
389
 
 
390
 
    for (lnum = 0; lnum < pdev->height; ++lnum) {
391
 
        byte *data;
392
 
        int i, c;
393
 
 
394
 
        gdev_prn_get_bits(pdev, lnum, lbuf, &data);
395
 
        for (c = 0; c < 3; ++c) {
396
 
            const byte *p;
397
 
 
398
 
            for (i = 0, p = data + c; i < width; ++i, p += 3)
399
 
                sputc(&rls, *p);
400
 
            if (rls.end_status == ERRC)
401
 
              return_error(gs_error_ioerror);
402
 
        }
403
 
    }
404
 
    sclose(&rls);
405
 
    sclose(&a85s);
406
 
    sflush(&fs);
407
 
    fputs("\n", prn_stream);
408
 
    psw_write_page_trailer(prn_stream, 1, true);
409
 
    gs_free_object(mem, lbuf, "psrgb_print_page(lbuf)");
410
 
    if (ferror(prn_stream))
411
 
        return_error(gs_error_ioerror);
412
 
    return 0;
413
 
}
414
 
 
415
 
/* Close the file. */
416
 
static int
417
 
psrgb_close(gx_device *dev)
418
 
{
419
 
    int code = psw_end_file(((gx_device_printer *)dev)->file, dev,
420
 
            &psrgb_values, NULL, dev->PageCount);
421
 
    
422
 
    if (code < 0)
423
 
        return code;
424
 
    return gdev_prn_close(dev);
425
 
}