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

« back to all changes in this revision

Viewing changes to base/gdevfax.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
/* $Id: gdevfax.c 8655 2008-04-21 14:53:38Z leonardo $ */
 
14
/* Fax devices */
 
15
#include "gdevprn.h"
 
16
#include "strimpl.h"
 
17
#include "scfx.h"
 
18
#include "gdevfax.h"
 
19
 
 
20
/* The device descriptors */
 
21
static dev_proc_print_page(faxg3_print_page);
 
22
static dev_proc_print_page(faxg32d_print_page);
 
23
static dev_proc_print_page(faxg4_print_page);
 
24
 
 
25
/* Define procedures that adjust the paper size. */
 
26
const gx_device_procs gdev_fax_std_procs =
 
27
    prn_params_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close,
 
28
                     gdev_fax_get_params, gdev_fax_put_params);
 
29
 
 
30
#define FAX_DEVICE(dname, print_page)\
 
31
{\
 
32
    FAX_DEVICE_BODY(gx_device_fax, gdev_fax_std_procs, dname, print_page)\
 
33
}
 
34
 
 
35
 
 
36
const gx_device_fax gs_faxg3_device =
 
37
    FAX_DEVICE("faxg3", faxg3_print_page);
 
38
 
 
39
const gx_device_fax gs_faxg32d_device =
 
40
    FAX_DEVICE("faxg32d", faxg32d_print_page);
 
41
 
 
42
const gx_device_fax gs_faxg4_device =
 
43
    FAX_DEVICE("faxg4", faxg4_print_page);
 
44
 
 
45
/* Open the device. */
 
46
/* This is no longer needed: we retain it for client backward compatibility. */
 
47
int
 
48
gdev_fax_open(gx_device * dev)
 
49
{
 
50
    return gdev_prn_open(dev);
 
51
}
 
52
 
 
53
/* Get/put the AdjustWidth parameter. */
 
54
int
 
55
gdev_fax_get_params(gx_device * dev, gs_param_list * plist)
 
56
{
 
57
    gx_device_fax *const fdev = (gx_device_fax *)dev;
 
58
    int code = gdev_prn_get_params(dev, plist);
 
59
    int ecode = code;
 
60
 
 
61
    if ((code = param_write_int(plist, "AdjustWidth", &fdev->AdjustWidth)) < 0)
 
62
        ecode = code;
 
63
    return ecode;
 
64
}
 
65
int
 
66
gdev_fax_put_params(gx_device * dev, gs_param_list * plist)
 
67
{
 
68
    gx_device_fax *const fdev = (gx_device_fax *)dev;
 
69
    int ecode = 0;
 
70
    int code;
 
71
    int aw = fdev->AdjustWidth;
 
72
    const char *param_name;
 
73
 
 
74
    switch (code = param_read_int(plist, (param_name = "AdjustWidth"), &aw)) {
 
75
        case 0:
 
76
            if (aw >= 0 && aw <= 1)
 
77
                break;
 
78
            code = gs_error_rangecheck;
 
79
        default:
 
80
            ecode = code;
 
81
            param_signal_error(plist, param_name, ecode);
 
82
        case 1:
 
83
            break;
 
84
    }
 
85
 
 
86
    if (ecode < 0)
 
87
        return ecode;
 
88
    code = gdev_prn_put_params(dev, plist);
 
89
    if (code < 0)
 
90
        return code;
 
91
 
 
92
    fdev->AdjustWidth = aw;
 
93
    return code;
 
94
}
 
95
 
 
96
/* Initialize the stream state with a set of default parameters. */
 
97
/* These select the same defaults as the CCITTFaxEncode filter, */
 
98
/* except we set BlackIs1 = true. */
 
99
static void
 
100
gdev_fax_init_state_adjust(stream_CFE_state *ss,
 
101
                           const gx_device_fax *fdev,
 
102
                           int adjust_width)
 
103
{
 
104
    s_CFE_template.set_defaults((stream_state *)ss);
 
105
    ss->Columns = fdev->width;
 
106
    ss->Rows = fdev->height;
 
107
    ss->BlackIs1 = true;
 
108
    if (adjust_width > 0) {
 
109
        /* Adjust the page width to a legal value for fax systems. */
 
110
        if (ss->Columns >= 1680 && ss->Columns <= 1736) {
 
111
            /* Adjust width for A4 paper. */
 
112
            ss->Columns = 1728;
 
113
        } else if (ss->Columns >= 2000 && ss->Columns <= 2056) {
 
114
            /* Adjust width for B4 paper. */
 
115
            ss->Columns = 2048;
 
116
        }
 
117
    }
 
118
}
 
119
void
 
120
gdev_fax_init_state(stream_CFE_state *ss, const gx_device_fax *fdev)
 
121
{
 
122
    gdev_fax_init_state_adjust(ss, fdev, 1);
 
123
}
 
124
void
 
125
gdev_fax_init_fax_state(stream_CFE_state *ss, const gx_device_fax *fdev)
 
126
{
 
127
    gdev_fax_init_state_adjust(ss, fdev, fdev->AdjustWidth);
 
128
}
 
129
 
 
130
/*
 
131
 * Print one strip with fax compression.  Fax devices call this once per
 
132
 * page; TIFF devices call this once per strip.
 
133
 */
 
134
int
 
135
gdev_fax_print_strip(gx_device_printer * pdev, FILE * prn_stream,
 
136
                     const stream_template * temp, stream_state * ss,
 
137
                     int width, int row_first, int row_end /* last + 1 */)
 
138
{
 
139
    gs_memory_t *mem = pdev->memory;
 
140
    int code;
 
141
    stream_cursor_read r;
 
142
    stream_cursor_write w;
 
143
    int in_size = gdev_mem_bytes_per_scan_line((gx_device *) pdev);
 
144
    /*
 
145
     * Because of the width adjustment for fax systems, width may
 
146
     * be different from (either greater than or less than) pdev->width.
 
147
     * Allocate a large enough buffer to account for this.
 
148
     */
 
149
    int col_size = (width * pdev->color_info.depth + 7) >> 3;
 
150
    int max_size = max(in_size, col_size);
 
151
    int lnum;
 
152
    byte *in;
 
153
    byte *out;
 
154
    /* If the file is 'nul', don't even do the writes. */
 
155
    bool nul = !strcmp(pdev->fname, "nul");
 
156
 
 
157
    /* Initialize the common part of the encoder state. */
 
158
    ss->template = temp;
 
159
    ss->memory = mem;
 
160
    /* Now initialize the encoder. */
 
161
    code = temp->init(ss);
 
162
    if (code < 0)
 
163
        return_error(gs_error_limitcheck);      /* bogus, but as good as any */
 
164
 
 
165
    /* Allocate the buffers. */
 
166
    in = gs_alloc_bytes(mem, temp->min_in_size + max_size + 1,
 
167
                        "gdev_stream_print_page(in)");
 
168
#define OUT_SIZE 1000
 
169
    out = gs_alloc_bytes(mem, OUT_SIZE, "gdev_stream_print_page(out)");
 
170
    if (in == 0 || out == 0) {
 
171
        code = gs_note_error(gs_error_VMerror);
 
172
        goto done;
 
173
    }
 
174
    /* Set up the processing loop. */
 
175
    lnum = 0;
 
176
    r.ptr = r.limit = in - 1;
 
177
    w.ptr = out - 1;
 
178
    w.limit = w.ptr + OUT_SIZE;
 
179
#undef OUT_SIZE
 
180
 
 
181
    /* Process the image. */
 
182
    for (lnum = row_first; ;) {
 
183
        int status;
 
184
 
 
185
        if_debug7('w', "[w]lnum=%d r=0x%lx,0x%lx,0x%lx w=0x%lx,0x%lx,0x%lx\n", lnum,
 
186
                  (ulong)in, (ulong)r.ptr, (ulong)r.limit,
 
187
                  (ulong)out, (ulong)w.ptr, (ulong)w.limit);
 
188
        status = temp->process(ss, &r, &w, lnum == row_end);
 
189
        if_debug7('w', "...%d, r=0x%lx,0x%lx,0x%lx w=0x%lx,0x%lx,0x%lx\n", status,
 
190
                  (ulong)in, (ulong)r.ptr, (ulong)r.limit,
 
191
                  (ulong)out, (ulong)w.ptr, (ulong)w.limit);
 
192
        switch (status) {
 
193
            case 0:             /* need more input data */
 
194
                if (lnum == row_end)
 
195
                    goto ok;
 
196
                {
 
197
                    uint left = r.limit - r.ptr;
 
198
 
 
199
                    memcpy(in, r.ptr + 1, left);
 
200
                    code = gdev_prn_copy_scan_lines(pdev, lnum++, in + left, in_size);
 
201
                    if (code < 0) {
 
202
                        gs_note_error(code);
 
203
                        goto done;
 
204
                    }
 
205
                    /* Note: we use col_size here, not in_size. */
 
206
                    if (col_size > in_size) {
 
207
                        memset(in + left + in_size, 0, col_size - in_size);
 
208
                    }
 
209
                    r.limit = in + left + col_size - 1;
 
210
                    r.ptr = in - 1;
 
211
                }
 
212
                break;
 
213
            case 1:             /* need to write output */
 
214
                if (!nul)
 
215
                    fwrite(out, 1, w.ptr + 1 - out, prn_stream);
 
216
                w.ptr = out - 1;
 
217
                break;
 
218
        }
 
219
    }
 
220
 
 
221
  ok:
 
222
    /* Write out any remaining output. */
 
223
    if (!nul)
 
224
        fwrite(out, 1, w.ptr + 1 - out, prn_stream);
 
225
 
 
226
  done:
 
227
    gs_free_object(mem, out, "gdev_stream_print_page(out)");
 
228
    gs_free_object(mem, in, "gdev_stream_print_page(in)");
 
229
    if (temp->release)
 
230
        temp->release(ss);
 
231
    return code;
 
232
}
 
233
 
 
234
/* Print a fax page.  Other fax drivers use this. */
 
235
int
 
236
gdev_fax_print_page(gx_device_printer * pdev, FILE * prn_stream,
 
237
                    stream_CFE_state * ss)
 
238
{
 
239
    return gdev_fax_print_strip(pdev, prn_stream, &s_CFE_template,
 
240
                                (stream_state *)ss, ss->Columns,
 
241
                                0, pdev->height);
 
242
}
 
243
 
 
244
/* Print a 1-D Group 3 page. */
 
245
static int
 
246
faxg3_print_page(gx_device_printer * pdev, FILE * prn_stream)
 
247
{
 
248
    stream_CFE_state state;
 
249
 
 
250
    gdev_fax_init_fax_state(&state, (gx_device_fax *)pdev);
 
251
    state.EndOfLine = true;
 
252
    state.EndOfBlock = false;
 
253
    return gdev_fax_print_page(pdev, prn_stream, &state);
 
254
}
 
255
 
 
256
/* Print a 2-D Group 3 page. */
 
257
static int
 
258
faxg32d_print_page(gx_device_printer * pdev, FILE * prn_stream)
 
259
{
 
260
    stream_CFE_state state;
 
261
 
 
262
    gdev_fax_init_fax_state(&state, (gx_device_fax *)pdev);
 
263
    state.K = (pdev->y_pixels_per_inch < 100 ? 2 : 4);
 
264
    state.EndOfLine = true;
 
265
    state.EndOfBlock = false;
 
266
    return gdev_fax_print_page(pdev, prn_stream, &state);
 
267
}
 
268
 
 
269
/* Print a Group 4 page. */
 
270
static int
 
271
faxg4_print_page(gx_device_printer * pdev, FILE * prn_stream)
 
272
{
 
273
    stream_CFE_state state;
 
274
 
 
275
    gdev_fax_init_fax_state(&state, (gx_device_fax *)pdev);
 
276
    state.K = -1;
 
277
    state.EndOfBlock = false;
 
278
    return gdev_fax_print_page(pdev, prn_stream, &state);
 
279
}