~ubuntu-branches/ubuntu/oneiric/ghostscript/oneiric

« back to all changes in this revision

Viewing changes to base/spngp.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2011-07-15 16:49:55 UTC
  • mfrom: (1.1.23 upstream)
  • Revision ID: james.westby@ubuntu.com-20110715164955-uga6qibao6kez05c
Tags: 9.04~dfsg~20110715-0ubuntu1
* New upstream release
   - GIT snapshot from Jult, 12 2011.
* debian/patches/020110406~a54df2d.patch,
  debian/patches/020110408~0791cc8.patch,
  debian/patches/020110408~507cbee.patch,
  debian/patches/020110411~4509a49.patch,
  debian/patches/020110412~78bb9a6.patch,
  debian/patches/020110418~a05ab8a.patch,
  debian/patches/020110420~20b6c78.patch,
  debian/patches/020110420~4ddefa2.patch: Removed upstream patches.
* debian/rules: Generate ABI version number (variable "abi") correctly,
  cutting off repackaging and pre-release parts.
* debian/rules: Added ./lcms2/ directory to DEB_UPSTREAM_REPACKAGE_EXCLUDES.
* debian/copyright: Added lcms2/* to the list of excluded files.
* 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
1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
2
2
   All Rights Reserved.
3
 
  
 
3
 
4
4
   This software is provided AS-IS with no warranty, either express or
5
5
   implied.
6
6
 
11
11
   San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
12
12
*/
13
13
 
14
 
/* $Id: spngp.c 8823 2008-07-07 08:56:59Z ken $ */
 
14
/* $Id$ */
15
15
/* PNG pixel prediction filters */
16
16
#include "memory_.h"
17
17
#include "strimpl.h"
50
50
    stream_PNGP_state *const ss = (stream_PNGP_state *) st;
51
51
 
52
52
    if (ss->prev_row != 0)
53
 
        memset(ss->prev_row + ss->bpp, 0, ss->row_count);
 
53
        memset(ss->prev_row + ss->bpp, 0, ss->row_count);
54
54
    ss->row_left = 0;
55
55
    return 0;
56
56
}
66
66
 
67
67
#if arch_sizeof_long > arch_sizeof_int
68
68
    if (bits_per_row > max_uint * 7L)
69
 
        return ERRC;    /****** WRONG ******/
 
69
        return ERRC;    /****** WRONG ******/
70
70
#endif
71
71
    ss->row_count = (uint) ((bits_per_row + 7) >> 3);
72
72
    ss->end_mask = (1 << (-bits_per_row & 7)) - 1;
73
73
 
74
74
    if (ss->Colors > s_PNG_max_Colors)
75
 
        return ERRC; /* Too many colorants */
 
75
        return ERRC; /* Too many colorants */
76
76
 
77
77
    ss->bpp = (bits_per_pixel + 7) >> 3;
78
78
    if (need_prev) {
79
 
        prev_row = gs_alloc_bytes(st->memory, ss->bpp + ss->row_count,
80
 
                                  "PNGPredictor prev row");
81
 
        if (prev_row == 0)
82
 
            return ERRC;        /****** WRONG ******/
83
 
        memset(prev_row, 0, ss->bpp);
 
79
        prev_row = gs_alloc_bytes(st->memory, ss->bpp + ss->row_count,
 
80
                                  "PNGPredictor prev row");
 
81
        if (prev_row == 0)
 
82
            return ERRC;        /****** WRONG ******/
 
83
        memset(prev_row, 0, ss->bpp);
84
84
    }
85
85
    ss->prev_row = prev_row;
86
86
    /* case_index is only preset for encoding */
110
110
    stream_PNGP_state *const ss = (stream_PNGP_state *) st;
111
111
 
112
112
    if (ss->prev_row)
113
 
        gs_free_object(st->memory, ss->prev_row, "PNGPredictor prev row");
 
113
        gs_free_object(st->memory, ss->prev_row, "PNGPredictor prev row");
114
114
}
115
115
 
116
116
/*
128
128
    /* The definitions of ac and bc are correct, not a typo. */
129
129
    int ac = b - c, bc = a - c, abcc = ac + bc;
130
130
    int pa = (ac < 0 ? -ac : ac), pb = (bc < 0 ? -bc : bc),
131
 
        pc = (abcc < 0 ? -abcc : abcc);
 
131
        pc = (abcc < 0 ? -abcc : abcc);
132
132
 
133
133
    return (pa <= pb && pa <= pc ? a : pb <= pc ? b : c);
134
134
}
135
135
static void
136
136
s_pngp_process(stream_state * st, stream_cursor_write * pw,
137
 
               const byte * dprev, stream_cursor_read * pr,
138
 
               const byte * upprev, const byte * up, uint count)
 
137
               const byte * dprev, stream_cursor_read * pr,
 
138
               const byte * upprev, const byte * up, uint count)
139
139
{
140
140
    stream_PNGP_state *const ss = (stream_PNGP_state *) st;
141
141
    byte *q = pw->ptr + 1;
145
145
    pw->ptr += count;
146
146
    ss->row_left -= count;
147
147
    switch (ss->case_index) {
148
 
        case cEncode + cNone:
149
 
        case cDecode + cNone:
150
 
            memcpy(q, p, count);
151
 
            break;
152
 
        case cEncode + cSub:
153
 
            for (; count; ++q, ++dprev, ++p, --count)
154
 
                *q = (byte) (*p - *dprev);
155
 
            break;
156
 
        case cDecode + cSub:
157
 
            for (; count; ++q, ++dprev, ++p, --count)
158
 
                *q = (byte) (*p + *dprev);
159
 
            break;
160
 
        case cEncode + cUp:
161
 
            for (; count; ++q, ++up, ++p, --count)
162
 
                *q = (byte) (*p - *up);
163
 
            break;
164
 
        case cDecode + cUp:
165
 
            for (; count; ++q, ++up, ++p, --count)
166
 
                *q = (byte) (*p + *up);
167
 
            break;
168
 
        case cEncode + cAverage:
169
 
            for (; count; ++q, ++dprev, ++up, ++p, --count)
170
 
                *q = (byte) (*p - arith_rshift_1((int)*dprev + (int)*up));
171
 
            break;
172
 
        case cDecode + cAverage:
173
 
            for (; count; ++q, ++dprev, ++up, ++p, --count)
174
 
                *q = (byte) (*p + arith_rshift_1((int)*dprev + (int)*up));
175
 
            break;
176
 
        case cEncode + cPaeth:
177
 
            for (; count; ++q, ++dprev, ++up, ++upprev, ++p, --count)
178
 
                *q = (byte) (*p - paeth_predictor(*dprev, *up, *upprev));
179
 
            break;
180
 
        case cDecode + cPaeth:
181
 
            for (; count; ++q, ++dprev, ++up, ++upprev, ++p, --count)
182
 
                *q = (byte) (*p + paeth_predictor(*dprev, *up, *upprev));
183
 
            break;
 
148
        case cEncode + cNone:
 
149
        case cDecode + cNone:
 
150
            memcpy(q, p, count);
 
151
            break;
 
152
        case cEncode + cSub:
 
153
            for (; count; ++q, ++dprev, ++p, --count)
 
154
                *q = (byte) (*p - *dprev);
 
155
            break;
 
156
        case cDecode + cSub:
 
157
            for (; count; ++q, ++dprev, ++p, --count)
 
158
                *q = (byte) (*p + *dprev);
 
159
            break;
 
160
        case cEncode + cUp:
 
161
            for (; count; ++q, ++up, ++p, --count)
 
162
                *q = (byte) (*p - *up);
 
163
            break;
 
164
        case cDecode + cUp:
 
165
            for (; count; ++q, ++up, ++p, --count)
 
166
                *q = (byte) (*p + *up);
 
167
            break;
 
168
        case cEncode + cAverage:
 
169
            for (; count; ++q, ++dprev, ++up, ++p, --count)
 
170
                *q = (byte) (*p - arith_rshift_1((int)*dprev + (int)*up));
 
171
            break;
 
172
        case cDecode + cAverage:
 
173
            for (; count; ++q, ++dprev, ++up, ++p, --count)
 
174
                *q = (byte) (*p + arith_rshift_1((int)*dprev + (int)*up));
 
175
            break;
 
176
        case cEncode + cPaeth:
 
177
            for (; count; ++q, ++dprev, ++up, ++upprev, ++p, --count)
 
178
                *q = (byte) (*p - paeth_predictor(*dprev, *up, *upprev));
 
179
            break;
 
180
        case cDecode + cPaeth:
 
181
            for (; count; ++q, ++dprev, ++up, ++upprev, ++p, --count)
 
182
                *q = (byte) (*p + paeth_predictor(*dprev, *up, *upprev));
 
183
            break;
184
184
    }
185
185
}
186
186
 
188
188
/* the min of (input data, output data, remaining row length). */
189
189
static uint
190
190
s_pngp_count(const stream_state * st_const, const stream_cursor_read * pr,
191
 
             const stream_cursor_write * pw)
 
191
             const stream_cursor_write * pw)
192
192
{
193
193
    const stream_PNGP_state *const ss_const =
194
 
        (const stream_PNGP_state *)st_const;
 
194
        (const stream_PNGP_state *)st_const;
195
195
    uint rcount = pr->limit - pr->ptr;
196
196
    uint wcount = pw->limit - pw->ptr;
197
197
    uint row_left = ss_const->row_left;
198
198
 
199
199
    if (rcount < row_left)
200
 
        row_left = rcount;
 
200
        row_left = rcount;
201
201
    if (wcount < row_left)
202
 
        row_left = wcount;
 
202
        row_left = wcount;
203
203
    return row_left;
204
204
}
205
205
 
224
224
}
225
225
static int
226
226
s_PNGPE_process(stream_state * st, stream_cursor_read * pr,
227
 
                stream_cursor_write * pw, bool last)
 
227
                stream_cursor_write * pw, bool last)
228
228
{
229
229
    stream_PNGP_state *const ss = (stream_PNGP_state *) st;
230
230
    int bpp = ss->bpp;
231
231
    int status = 0;
232
232
 
233
233
    while (pr->ptr < pr->limit) {
234
 
        uint count;
235
 
 
236
 
        if (ss->row_left == 0) {
237
 
            /* Beginning of row, write algorithm byte. */
238
 
            int predictor;
239
 
 
240
 
            if (pw->ptr >= pw->limit) {
241
 
                status = 1;
242
 
                break;
243
 
            }
244
 
            predictor =
245
 
                (ss->Predictor == cOptimum ?
246
 
                 optimum_predictor(st, pr) :
247
 
                 ss->Predictor);
248
 
            *++(pw->ptr) = (byte) predictor - cNone;
249
 
            ss->case_index = predictor + cEncode;
250
 
            ss->row_left = ss->row_count;
251
 
            memset(ss->prev, 0, bpp);
252
 
            continue;
253
 
        }
254
 
        count = s_pngp_count(st, pr, pw);
255
 
        if (count == 0) {
256
 
            /* We know we have input, so output must be full. */
257
 
            status = 1;
258
 
            break;
259
 
        } {
260
 
            byte *up = ss->prev_row + bpp + ss->row_count - ss->row_left;
261
 
            uint n = min(count, bpp);
262
 
 
263
 
            /* Process bytes whose predecessors are in prev. */
264
 
            s_pngp_process(st, pw, ss->prev, pr, up - bpp, up, n);
265
 
            if (ss->row_left == 0) {
266
 
                if (ss->prev_row) {
267
 
                    memcpy(up - bpp, ss->prev, bpp);
268
 
                    memcpy(up, pr->ptr - (n - 1), n);
269
 
                }
270
 
                continue;
271
 
            }
272
 
            if (ss->prev_row)
273
 
                memcpy(up - bpp, ss->prev, n);
274
 
            if (n < bpp) {
275
 
                /*
276
 
                 * We didn't have both enough input data and enough output
277
 
                 * space to use up all of prev.  Shift more data into prev
278
 
                 * and exit.
279
 
                 */
280
 
                int prev_left = bpp - n;
281
 
 
282
 
                memmove(ss->prev, ss->prev + n, prev_left);
283
 
                memcpy(ss->prev + prev_left, pr->ptr - (n - 1), n);
284
 
                if (pw->ptr >= pw->limit && pr->ptr < pr->limit)
285
 
                    status = 1;
286
 
                break;
287
 
            }
288
 
            /* Process bytes whose predecessors are in the input. */
289
 
            /* We know we have at least bpp input and output bytes, */
290
 
            /* and that n = bpp. */
291
 
            count -= bpp;
292
 
            s_pngp_process(st, pw, pr->ptr - (bpp - 1), pr,
293
 
                           up, up + bpp, count);
294
 
            memcpy(ss->prev, pr->ptr - (bpp - 1), bpp);
295
 
            if (ss->prev_row) {
296
 
                memcpy(up, pr->ptr - (bpp + count - 1), count);
297
 
                if (ss->row_left == 0)
298
 
                    memcpy(up + count, ss->prev, bpp);
299
 
            }
300
 
        }
 
234
        uint count;
 
235
 
 
236
        if (ss->row_left == 0) {
 
237
            /* Beginning of row, write algorithm byte. */
 
238
            int predictor;
 
239
 
 
240
            if (pw->ptr >= pw->limit) {
 
241
                status = 1;
 
242
                break;
 
243
            }
 
244
            predictor =
 
245
                (ss->Predictor == cOptimum ?
 
246
                 optimum_predictor(st, pr) :
 
247
                 ss->Predictor);
 
248
            *++(pw->ptr) = (byte) predictor - cNone;
 
249
            ss->case_index = predictor + cEncode;
 
250
            ss->row_left = ss->row_count;
 
251
            memset(ss->prev, 0, bpp);
 
252
            continue;
 
253
        }
 
254
        count = s_pngp_count(st, pr, pw);
 
255
        if (count == 0) {
 
256
            /* We know we have input, so output must be full. */
 
257
            status = 1;
 
258
            break;
 
259
        } {
 
260
            byte *up = ss->prev_row + bpp + ss->row_count - ss->row_left;
 
261
            uint n = min(count, bpp);
 
262
 
 
263
            /* Process bytes whose predecessors are in prev. */
 
264
            s_pngp_process(st, pw, ss->prev, pr, up - bpp, up, n);
 
265
            if (ss->row_left == 0) {
 
266
                if (ss->prev_row) {
 
267
                    memcpy(up - bpp, ss->prev, bpp);
 
268
                    memcpy(up, pr->ptr - (n - 1), n);
 
269
                }
 
270
                continue;
 
271
            }
 
272
            if (ss->prev_row)
 
273
                memcpy(up - bpp, ss->prev, n);
 
274
            if (n < bpp) {
 
275
                /*
 
276
                 * We didn't have both enough input data and enough output
 
277
                 * space to use up all of prev.  Shift more data into prev
 
278
                 * and exit.
 
279
                 */
 
280
                int prev_left = bpp - n;
 
281
 
 
282
                memmove(ss->prev, ss->prev + n, prev_left);
 
283
                memcpy(ss->prev + prev_left, pr->ptr - (n - 1), n);
 
284
                if (pw->ptr >= pw->limit && pr->ptr < pr->limit)
 
285
                    status = 1;
 
286
                break;
 
287
            }
 
288
            /* Process bytes whose predecessors are in the input. */
 
289
            /* We know we have at least bpp input and output bytes, */
 
290
            /* and that n = bpp. */
 
291
            count -= bpp;
 
292
            s_pngp_process(st, pw, pr->ptr - (bpp - 1), pr,
 
293
                           up, up + bpp, count);
 
294
            memcpy(ss->prev, pr->ptr - (bpp - 1), bpp);
 
295
            if (ss->prev_row) {
 
296
                memcpy(up, pr->ptr - (bpp + count - 1), count);
 
297
                if (ss->row_left == 0)
 
298
                    memcpy(up + count, ss->prev, bpp);
 
299
            }
 
300
        }
301
301
    }
302
302
    return status;
303
303
}
318
318
 */
319
319
static int
320
320
s_PNGPD_process(stream_state * st, stream_cursor_read * pr,
321
 
                stream_cursor_write * pw, bool last)
 
321
                stream_cursor_write * pw, bool last)
322
322
{
323
323
    stream_PNGP_state *const ss = (stream_PNGP_state *) st;
324
324
    int bpp = ss->bpp;
325
325
    int status = 0;
326
326
 
327
327
    while (pr->ptr < pr->limit) {
328
 
        uint count;
329
 
 
330
 
        if (ss->row_left == 0) {
331
 
            /* Beginning of row, read algorithm byte. */
332
 
            int predictor = pr->ptr[1];
333
 
 
334
 
            if (predictor >= cOptimum - cNone) {
335
 
                status = ERRC;
336
 
                break;
337
 
            }
338
 
            pr->ptr++;
339
 
            ss->case_index = predictor + cNone + cDecode;
340
 
            ss->row_left = ss->row_count;
341
 
            memset(ss->prev, 0, bpp);
342
 
            continue;
343
 
        }
344
 
        count = s_pngp_count(st, pr, pw);
345
 
        if (count == 0) {
346
 
            /* We know we have input, so output must be full. */
347
 
            status = 1;
348
 
            break;
349
 
        } {
350
 
            byte *up = ss->prev_row + bpp + ss->row_count - ss->row_left;
351
 
            uint n = min(count, bpp);
352
 
 
353
 
            /* Process bytes whose predecessors are in prev. */
354
 
            s_pngp_process(st, pw, ss->prev, pr, up - bpp, up, n);
355
 
            if (ss->row_left == 0) {
356
 
                if (ss->prev_row) {
357
 
                    memcpy(up - bpp, ss->prev, bpp);
358
 
                    memcpy(up, pw->ptr - (n - 1), n);
359
 
                }
360
 
                continue;
361
 
            }
362
 
            if (ss->prev_row)
363
 
                memcpy(up - bpp, ss->prev, n);
364
 
            if (n < bpp) {
365
 
                /*
366
 
                 * We didn't have both enough input data and enough output
367
 
                 * space to use up all of prev.  Shift more data into prev
368
 
                 * and exit.
369
 
                 */
370
 
                int prev_left = bpp - n;
371
 
 
372
 
                memmove(ss->prev, ss->prev + n, prev_left);
373
 
                memcpy(ss->prev + prev_left, pw->ptr - (n - 1), n);
374
 
                if (pw->ptr >= pw->limit && pr->ptr < pr->limit)
375
 
                    status = 1;
376
 
                break;
377
 
            }
378
 
            /* Process bytes whose predecessors are in the output. */
379
 
            /* We know we have at least bpp input and output bytes, */
380
 
            /* and that n = bpp. */
381
 
            count -= bpp;
382
 
            s_pngp_process(st, pw, pw->ptr - (bpp - 1), pr,
383
 
                           up, up + bpp, count);
384
 
            memcpy(ss->prev, pw->ptr - (bpp - 1), bpp);
385
 
            if (ss->prev_row) {
386
 
                memcpy(up, pw->ptr - (bpp + count - 1), count);
387
 
                if (ss->row_left == 0)
388
 
                    memcpy(up + count, ss->prev, bpp);
389
 
            }
390
 
        }
 
328
        uint count;
 
329
 
 
330
        if (ss->row_left == 0) {
 
331
            /* Beginning of row, read algorithm byte. */
 
332
            int predictor = pr->ptr[1];
 
333
 
 
334
            if (predictor >= cOptimum - cNone) {
 
335
                status = ERRC;
 
336
                break;
 
337
            }
 
338
            pr->ptr++;
 
339
            ss->case_index = predictor + cNone + cDecode;
 
340
            ss->row_left = ss->row_count;
 
341
            memset(ss->prev, 0, bpp);
 
342
            continue;
 
343
        }
 
344
        count = s_pngp_count(st, pr, pw);
 
345
        if (count == 0) {
 
346
            /* We know we have input, so output must be full. */
 
347
            status = 1;
 
348
            break;
 
349
        } {
 
350
            byte *up = ss->prev_row + bpp + ss->row_count - ss->row_left;
 
351
            uint n = min(count, bpp);
 
352
 
 
353
            /* Process bytes whose predecessors are in prev. */
 
354
            s_pngp_process(st, pw, ss->prev, pr, up - bpp, up, n);
 
355
            if (ss->row_left == 0) {
 
356
                if (ss->prev_row) {
 
357
                    memcpy(up - bpp, ss->prev, bpp);
 
358
                    memcpy(up, pw->ptr - (n - 1), n);
 
359
                }
 
360
                continue;
 
361
            }
 
362
            if (ss->prev_row)
 
363
                memcpy(up - bpp, ss->prev, n);
 
364
            if (n < bpp) {
 
365
                /*
 
366
                 * We didn't have both enough input data and enough output
 
367
                 * space to use up all of prev.  Shift more data into prev
 
368
                 * and exit.
 
369
                 */
 
370
                int prev_left = bpp - n;
 
371
 
 
372
                memmove(ss->prev, ss->prev + n, prev_left);
 
373
                memcpy(ss->prev + prev_left, pw->ptr - (n - 1), n);
 
374
                if (pw->ptr >= pw->limit && pr->ptr < pr->limit)
 
375
                    status = 1;
 
376
                break;
 
377
            }
 
378
            /* Process bytes whose predecessors are in the output. */
 
379
            /* We know we have at least bpp input and output bytes, */
 
380
            /* and that n = bpp. */
 
381
            count -= bpp;
 
382
            s_pngp_process(st, pw, pw->ptr - (bpp - 1), pr,
 
383
                           up, up + bpp, count);
 
384
            memcpy(ss->prev, pw->ptr - (bpp - 1), bpp);
 
385
            if (ss->prev_row) {
 
386
                memcpy(up, pw->ptr - (bpp + count - 1), count);
 
387
                if (ss->row_left == 0)
 
388
                    memcpy(up + count, ss->prev, bpp);
 
389
            }
 
390
        }
391
391
    }
392
392
    return status;
393
393
}