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

« back to all changes in this revision

Viewing changes to src/sfilter2.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: sfilter2.c 8250 2007-09-25 13:31:24Z giles $ */
15
 
/* Simple Level 2 filters */
16
 
#include "stdio_.h"             /* includes std.h */
17
 
#include "memory_.h"
18
 
#include "gdebug.h"
19
 
#include "strimpl.h"
20
 
#include "sa85x.h"
21
 
#include "sbtx.h"
22
 
#include "scanchar.h"
23
 
 
24
 
/* ------ ASCII85Encode ------ */
25
 
 
26
 
private_st_A85E_state();
27
 
 
28
 
/* Initialize the state */
29
 
static int
30
 
s_A85E_init(stream_state * st)
31
 
{
32
 
    stream_A85E_state *const ss = (stream_A85E_state *) st;
33
 
 
34
 
    return s_A85E_init_inline(ss);
35
 
}
36
 
 
37
 
/* Process a buffer */
38
 
#define LINE_LIMIT 79           /* not 80, to satisfy Genoa FTS */
39
 
static int
40
 
s_A85E_process(stream_state * st, stream_cursor_read * pr,
41
 
               stream_cursor_write * pw, bool last)
42
 
{
43
 
    stream_A85E_state *const ss = (stream_A85E_state *) st;
44
 
    register const byte *p = pr->ptr;
45
 
    register byte *q = pw->ptr;
46
 
    byte *qn = q + (LINE_LIMIT - ss->count); /* value of q before next EOL */
47
 
    const byte *rlimit = pr->limit;
48
 
    byte *wlimit = pw->limit;
49
 
    int status = 0;
50
 
    int prev = ss->last_char;
51
 
    int count;
52
 
 
53
 
    if_debug3('w', "[w85]initial ss->count = %d, rcount = %d, wcount = %d\n",
54
 
              ss->count, (int)(rlimit - p), (int)(wlimit - q));
55
 
    for (; (count = rlimit - p) >= 4; p += 4) {
56
 
        ulong word =
57
 
            ((ulong) (((uint) p[1] << 8) + p[2]) << 16) +
58
 
            (((uint) p[3] << 8) + p[4]);
59
 
 
60
 
        if (word == 0) {
61
 
            if (q >= qn) {
62
 
                if (wlimit - q < 2) {
63
 
                    status = 1;
64
 
                    break;
65
 
                }
66
 
                *++q = prev = '\n';
67
 
                qn = q + LINE_LIMIT;
68
 
                if_debug1('w', "[w85]EOL at %d bytes written\n",
69
 
                          (int)(q - pw->ptr));
70
 
            } else {
71
 
                if (q >= wlimit) {
72
 
                    status = 1;
73
 
                    break;
74
 
                }
75
 
            }
76
 
            *++q = prev = 'z';
77
 
        } else {
78
 
            ulong v4 = word / 85;       /* max 85^4 */
79
 
            ulong v3 = v4 / 85; /* max 85^3 */
80
 
            uint v2 = v3 / 85;  /* max 85^2 */
81
 
            uint v1 = v2 / 85;  /* max 85 */
82
 
 
83
 
put:        if (q + 5 > qn) {
84
 
                if (q >= wlimit) {
85
 
                    status = 1;
86
 
                    break;
87
 
                }
88
 
                *++q = prev = '\n';
89
 
                qn = q + LINE_LIMIT;
90
 
                if_debug1('w', "[w85]EOL at %d bytes written\n",
91
 
                          (int)(q - pw->ptr));
92
 
                goto put;
93
 
            }
94
 
            if (wlimit - q < 5) {
95
 
                status = 1;
96
 
                break;
97
 
            }
98
 
            q[1] = (byte) v1 + '!';
99
 
            q[2] = (byte) (v2 - v1 * 85) + '!';
100
 
            q[3] = (byte) ((uint) v3 - v2 * 85) + '!';
101
 
            q[4] = (byte) ((uint) v4 - (uint) v3 * 85) + '!';
102
 
            q[5] = (byte) ((uint) word - (uint) v4 * 85) + '!';
103
 
            /*
104
 
             * '%%' or '%!' at the beginning of the line will confuse some
105
 
             * document managers: insert (an) EOL(s) if necessary to prevent
106
 
             * this.
107
 
             */
108
 
            if (q[1] == '%') {
109
 
                if (prev == '%') {
110
 
                    if (qn - q == LINE_LIMIT - 1) {
111
 
                        /* A line would begin with %%. */
112
 
                        *++q = prev = '\n';
113
 
                        qn = q + LINE_LIMIT;
114
 
                        if_debug1('w',
115
 
                                  "[w85]EOL for %%%% at %d bytes written\n",
116
 
                                  (int)(q - pw->ptr));
117
 
                        goto put;
118
 
                    }
119
 
                } else if (prev == '\n' && (q[2] == '%' || q[2] == '!')) {
120
 
                    /*
121
 
                     * We may have to insert more than one EOL if
122
 
                     * there are more than two %s in a row.
123
 
                     */
124
 
                    int extra =
125
 
                        (q[2] == '!' ? 1 : /* else q[2] == '%' */
126
 
                         q[3] == '!' ? 2 :
127
 
                         q[3] != '%' ? 1 :
128
 
                         q[4] == '!' ? 3 :
129
 
                         q[4] != '%' ? 2 :
130
 
                         q[5] == '!' ? 4 :
131
 
                         q[5] != '%' ? 3 : 4);
132
 
 
133
 
                    if (wlimit - q < 5 + extra) {
134
 
                        status = 1;
135
 
                        break;
136
 
                    }
137
 
                    if_debug6('w', "[w]%c%c%c%c%c extra = %d\n",
138
 
                              q[1], q[2], q[3], q[4], q[5], extra);
139
 
                    switch (extra) {
140
 
                        case 4:
141
 
                            q[9] = q[5], q[8] = '\n';
142
 
                            goto e3;
143
 
                        case 3:
144
 
                            q[8] = q[5];
145
 
                          e3:q[7] = q[4], q[6] = '\n';
146
 
                            goto e2;
147
 
                        case 2:
148
 
                            q[7] = q[5], q[6] = q[4];
149
 
                          e2:q[5] = q[3], q[4] = '\n';
150
 
                            goto e1;
151
 
                        case 1:
152
 
                            q[6] = q[5], q[5] = q[4], q[4] = q[3];
153
 
                          e1:q[3] = q[2], q[2] = '\n';
154
 
                    }
155
 
                    if_debug1('w', "[w85]EOL at %d bytes written\n",
156
 
                              (int)(q + 2 * extra - pw->ptr));
157
 
                    qn = q + 2 * extra + LINE_LIMIT;
158
 
                    q += extra;
159
 
                }
160
 
            } else if (q[1] == '!' && prev == '%' &&
161
 
                       qn - q == LINE_LIMIT - 1
162
 
                       ) {
163
 
                /* A line would begin with %!. */
164
 
                *++q = prev = '\n';
165
 
                qn = q + LINE_LIMIT;
166
 
                if_debug1('w', "[w85]EOL for %%! at %d bytes written\n",
167
 
                          (int)(q - pw->ptr));
168
 
                goto put;
169
 
            }
170
 
            prev = *(q += 5);
171
 
        }
172
 
    }
173
 
 end:
174
 
    ss->count = LINE_LIMIT - (qn - q);
175
 
    /* Check for final partial word. */
176
 
    if (last && status == 0 && count < 4) {
177
 
        char buf[5];
178
 
        int nchars = (count == 0 ? 2 : count + 3);
179
 
        ulong word = 0;
180
 
        ulong divisor = 85L * 85 * 85 * 85;
181
 
        int i, space;
182
 
 
183
 
        switch (count) {
184
 
            case 3:
185
 
                word += (uint) p[3] << 8;
186
 
            case 2:
187
 
                word += (ulong) p[2] << 16;
188
 
            case 1:
189
 
                word += (ulong) p[1] << 24;
190
 
                for(i=0; i <= count; i++) {
191
 
                    ulong v = word / divisor;  /* actually only a byte */
192
 
 
193
 
                    buf[i] = (byte) v + '!';
194
 
                    word -= v * divisor;
195
 
                    divisor /= 85;
196
 
                }
197
 
                /*case 0: */
198
 
        }
199
 
        space = count && buf[0] == '%' && 
200
 
          ( (prev == '\n' && ( buf[1] == '%' || buf[1] =='!')) ||
201
 
            (prev == '%'  && qn - q == LINE_LIMIT - 1)
202
 
          );   
203
 
        if (wlimit - q < nchars+space)
204
 
            status = 1;
205
 
        else if (q + nchars+space > qn) {
206
 
            *++q = prev = '\n';
207
 
            qn = q + LINE_LIMIT;
208
 
            goto end;
209
 
        } else {
210
 
            if (count) {
211
 
                if (space)
212
 
                  *++q = ' ';
213
 
                memcpy(q+1, buf, count+1);
214
 
                q += count+1;
215
 
                p += count;
216
 
            }
217
 
            *++q = '~';
218
 
            *++q = '>';
219
 
        }
220
 
    }
221
 
    if_debug3('w', "[w85]final ss->count = %d, %d bytes read, %d written\n",
222
 
              ss->count, (int)(p - pr->ptr), (int)(q - pw->ptr));
223
 
    pr->ptr = p;
224
 
    if (q > pw->ptr)
225
 
        ss->last_char = *q;
226
 
    pw->ptr = q;
227
 
    return status;
228
 
}
229
 
#undef LINE_LIMIT
230
 
 
231
 
/* Stream template */
232
 
const stream_template s_A85E_template = {
233
 
    &st_A85E_state, s_A85E_init, s_A85E_process, 4, 6
234
 
};
235
 
 
236
 
/* ------ ByteTranslateEncode/Decode ------ */
237
 
 
238
 
private_st_BT_state();
239
 
 
240
 
/* Process a buffer.  Note that the same code serves for both streams. */
241
 
static int
242
 
s_BT_process(stream_state * st, stream_cursor_read * pr,
243
 
             stream_cursor_write * pw, bool last)
244
 
{
245
 
    stream_BT_state *const ss = (stream_BT_state *) st;
246
 
    const byte *p = pr->ptr;
247
 
    byte *q = pw->ptr;
248
 
    uint rcount = pr->limit - p;
249
 
    uint wcount = pw->limit - q;
250
 
    uint count;
251
 
    int status;
252
 
 
253
 
    if (rcount <= wcount)
254
 
        count = rcount, status = 0;
255
 
    else
256
 
        count = wcount, status = 1;
257
 
    while (count--)
258
 
        *++q = ss->table[*++p];
259
 
    pr->ptr = p;
260
 
    pw->ptr = q;
261
 
    return status;
262
 
}
263
 
 
264
 
/* Stream template */
265
 
const stream_template s_BTE_template = {
266
 
    &st_BT_state, NULL, s_BT_process, 1, 1
267
 
};
268
 
const stream_template s_BTD_template = {
269
 
    &st_BT_state, NULL, s_BT_process, 1, 1
270
 
};