~ubuntu-branches/ubuntu/saucy/pixman/saucy-security

« back to all changes in this revision

Viewing changes to pixman/pixman-edge.c

  • Committer: Bazaar Package Importer
  • Author(s): Julien Cristau
  • Date: 2009-09-28 18:12:47 UTC
  • mfrom: (1.1.8 upstream) (2.1.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090928181247-3iehog63i50htejf
Tags: 0.16.2-1
* New upstream release (closes: #546849).
* Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
#include <string.h>
28
28
 
29
29
#include "pixman-private.h"
 
30
#include "pixman-accessor.h"
 
31
 
 
32
/*
 
33
 * Step across a small sample grid gap
 
34
 */
 
35
#define RENDER_EDGE_STEP_SMALL(edge)                                    \
 
36
    {                                                                   \
 
37
        edge->x += edge->stepx_small;                                   \
 
38
        edge->e += edge->dx_small;                                      \
 
39
        if (edge->e > 0)                                                \
 
40
        {                                                               \
 
41
            edge->e -= edge->dy;                                        \
 
42
            edge->x += edge->signdx;                                    \
 
43
        }                                                               \
 
44
    }
 
45
 
 
46
/*
 
47
 * Step across a large sample grid gap
 
48
 */
 
49
#define RENDER_EDGE_STEP_BIG(edge)                                      \
 
50
    {                                                                   \
 
51
        edge->x += edge->stepx_big;                                     \
 
52
        edge->e += edge->dx_big;                                        \
 
53
        if (edge->e > 0)                                                \
 
54
        {                                                               \
 
55
            edge->e -= edge->dy;                                        \
 
56
            edge->x += edge->signdx;                                    \
 
57
        }                                                               \
 
58
    }
30
59
 
31
60
#ifdef PIXMAN_FB_ACCESSORS
32
61
#define PIXMAN_RASTERIZE_EDGES pixman_rasterize_edges_accessors
38
67
 * 4 bit alpha
39
68
 */
40
69
 
41
 
#define N_BITS  4
42
 
#define rasterizeEdges  fbRasterizeEdges4
 
70
#define N_BITS  4
 
71
#define RASTERIZE_EDGES rasterize_edges_4
43
72
 
44
 
#if BITMAP_BIT_ORDER == LSBFirst
45
 
#define Shift4(o)       ((o) << 2)
 
73
#ifndef WORDS_BIG_ENDIAN
 
74
#define SHIFT_4(o)      ((o) << 2)
46
75
#else
47
 
#define Shift4(o)       ((1-(o)) << 2)
 
76
#define SHIFT_4(o)      ((1 - (o)) << 2)
48
77
#endif
49
78
 
50
 
#define Get4(x,o)       (((x) >> Shift4(o)) & 0xf)
51
 
#define Put4(x,o,v)     (((x) & ~(0xf << Shift4(o))) | (((v) & 0xf) << Shift4(o)))
52
 
 
53
 
#define DefineAlpha(line,x)                          \
54
 
    uint8_t   *__ap = (uint8_t *) line + ((x) >> 1); \
55
 
    int     __ao = (x) & 1
56
 
 
57
 
#define StepAlpha       ((__ap += __ao), (__ao ^= 1))
58
 
 
59
 
#define AddAlpha(a) {                                                   \
60
 
        uint8_t   __o = READ(image, __ap);                              \
61
 
        uint8_t   __a = (a) + Get4(__o, __ao);                          \
62
 
        WRITE(image, __ap, Put4 (__o, __ao, __a | (0 - ((__a) >> 4)))); \
 
79
#define GET_4(x, o)      (((x) >> SHIFT_4 (o)) & 0xf)
 
80
#define PUT_4(x, o, v)                                                  \
 
81
    (((x) & ~(0xf << SHIFT_4 (o))) | (((v) & 0xf) << SHIFT_4 (o)))
 
82
 
 
83
#define DEFINE_ALPHA(line, x)                                           \
 
84
    uint8_t   *__ap = (uint8_t *) line + ((x) >> 1);                    \
 
85
    int __ao = (x) & 1
 
86
 
 
87
#define STEP_ALPHA      ((__ap += __ao), (__ao ^= 1))
 
88
 
 
89
#define ADD_ALPHA(a)                                                    \
 
90
    {                                                                   \
 
91
        uint8_t __o = READ (image, __ap);                               \
 
92
        uint8_t __a = (a) + GET_4 (__o, __ao);                          \
 
93
        WRITE (image, __ap, PUT_4 (__o, __ao, __a | (0 - ((__a) >> 4)))); \
63
94
    }
64
95
 
65
96
#include "pixman-edge-imp.h"
66
97
 
67
 
#undef AddAlpha
68
 
#undef StepAlpha
69
 
#undef DefineAlpha
70
 
#undef rasterizeEdges
 
98
#undef ADD_ALPHA
 
99
#undef STEP_ALPHA
 
100
#undef DEFINE_ALPHA
 
101
#undef RASTERIZE_EDGES
71
102
#undef N_BITS
72
103
 
73
104
 
76
107
 */
77
108
 
78
109
#define N_BITS 1
79
 
#define rasterizeEdges  fbRasterizeEdges1
 
110
#define RASTERIZE_EDGES rasterize_edges_1
80
111
 
81
112
#include "pixman-edge-imp.h"
82
113
 
83
 
#undef rasterizeEdges
 
114
#undef RASTERIZE_EDGES
84
115
#undef N_BITS
85
116
 
86
117
/*
87
118
 * 8 bit alpha
88
119
 */
89
120
 
90
 
static inline uint8_t
 
121
static force_inline uint8_t
91
122
clip255 (int x)
92
123
{
93
 
    if (x > 255) return 255;
 
124
    if (x > 255)
 
125
        return 255;
 
126
 
94
127
    return x;
95
128
}
96
129
 
97
 
#define add_saturate_8(buf,val,length)                          \
98
 
    do {                                                        \
99
 
        int i__ = (length);                                     \
100
 
        uint8_t *buf__ = (buf);                                 \
101
 
        int val__ = (val);                                      \
102
 
                                                                \
103
 
        while (i__--)                                           \
104
 
        {                                                       \
105
 
            WRITE(image, (buf__), clip255 (READ(image, (buf__)) + (val__)));    \
106
 
            (buf__)++;                                          \
107
 
        }                                                       \
 
130
#define ADD_SATURATE_8(buf, val, length)                                \
 
131
    do                                                                  \
 
132
    {                                                                   \
 
133
        int i__ = (length);                                             \
 
134
        uint8_t *buf__ = (buf);                                         \
 
135
        int val__ = (val);                                              \
 
136
                                                                        \
 
137
        while (i__--)                                                   \
 
138
        {                                                               \
 
139
            WRITE (image, (buf__), clip255 (READ (image, (buf__)) + (val__))); \
 
140
            (buf__)++;                                                  \
 
141
        }                                                               \
108
142
    } while (0)
109
143
 
110
144
/*
119
153
 *                   fill_start       fill_end
120
154
 */
121
155
static void
122
 
fbRasterizeEdges8 (pixman_image_t       *image,
123
 
                   pixman_edge_t        *l,
124
 
                   pixman_edge_t        *r,
125
 
                   pixman_fixed_t       t,
126
 
                   pixman_fixed_t       b)
 
156
rasterize_edges_8 (pixman_image_t *image,
 
157
                   pixman_edge_t * l,
 
158
                   pixman_edge_t * r,
 
159
                   pixman_fixed_t  t,
 
160
                   pixman_fixed_t  b)
127
161
{
128
 
    pixman_fixed_t  y = t;
 
162
    pixman_fixed_t y = t;
129
163
    uint32_t  *line;
130
164
    int fill_start = -1, fill_end = -1;
131
165
    int fill_size = 0;
138
172
    for (;;)
139
173
    {
140
174
        uint8_t *ap = (uint8_t *) line;
141
 
        pixman_fixed_t  lx, rx;
142
 
        int     lxi, rxi;
 
175
        pixman_fixed_t lx, rx;
 
176
        int lxi, rxi;
143
177
 
144
 
        /* clip X */
145
 
        lx = l->x;
146
 
        if (lx < 0)
 
178
        /* clip X */
 
179
        lx = l->x;
 
180
        if (lx < 0)
147
181
            lx = 0;
148
 
        rx = r->x;
149
 
        if (pixman_fixed_to_int (rx) >= width)
 
182
 
 
183
        rx = r->x;
 
184
 
 
185
        if (pixman_fixed_to_int (rx) >= width)
 
186
        {
150
187
            /* Use the last pixel of the scanline, covered 100%.
151
188
             * We can't use the first pixel following the scanline,
152
189
             * because accessing it could result in a buffer overrun.
153
190
             */
154
191
            rx = pixman_int_to_fixed (width) - 1;
 
192
        }
155
193
 
156
 
        /* Skip empty (or backwards) sections */
157
 
        if (rx > lx)
158
 
        {
 
194
        /* Skip empty (or backwards) sections */
 
195
        if (rx > lx)
 
196
        {
159
197
            int lxs, rxs;
160
198
 
161
 
            /* Find pixel bounds for span. */
162
 
            lxi = pixman_fixed_to_int (lx);
163
 
            rxi = pixman_fixed_to_int (rx);
 
199
            /* Find pixel bounds for span. */
 
200
            lxi = pixman_fixed_to_int (lx);
 
201
            rxi = pixman_fixed_to_int (rx);
164
202
 
165
203
            /* Sample coverage for edge pixels */
166
 
            lxs = RenderSamplesX (lx, 8);
167
 
            rxs = RenderSamplesX (rx, 8);
 
204
            lxs = RENDER_SAMPLES_X (lx, 8);
 
205
            rxs = RENDER_SAMPLES_X (rx, 8);
168
206
 
169
207
            /* Add coverage across row */
170
 
            if (lxi == rxi)
171
 
            {
172
 
                WRITE(image, ap +lxi, clip255 (READ(image, ap + lxi) + rxs - lxs));
 
208
            if (lxi == rxi)
 
209
            {
 
210
                WRITE (image, ap + lxi,
 
211
                       clip255 (READ (image, ap + lxi) + rxs - lxs));
173
212
            }
174
 
            else
175
 
            {
176
 
                WRITE(image, ap + lxi, clip255 (READ(image, ap + lxi) + N_X_FRAC(8) - lxs));
177
 
 
178
 
                /* Move forward so that lxi/rxi is the pixel span */
179
 
                lxi++;
180
 
 
181
 
                /* Don't bother trying to optimize the fill unless
 
213
            else
 
214
            {
 
215
                WRITE (image, ap + lxi,
 
216
                       clip255 (READ (image, ap + lxi) + N_X_FRAC (8) - lxs));
 
217
 
 
218
                /* Move forward so that lxi/rxi is the pixel span */
 
219
                lxi++;
 
220
 
 
221
                /* Don't bother trying to optimize the fill unless
182
222
                 * the span is longer than 4 pixels. */
183
 
                if (rxi - lxi > 4)
184
 
                {
185
 
                    if (fill_start < 0)
186
 
                    {
187
 
                        fill_start = lxi;
188
 
                        fill_end = rxi;
189
 
                        fill_size++;
190
 
                    }
191
 
                    else
192
 
                    {
193
 
                        if (lxi >= fill_end || rxi < fill_start)
194
 
                        {
195
 
                            /* We're beyond what we saved, just fill it */
196
 
                            add_saturate_8 (ap + fill_start,
197
 
                                            fill_size * N_X_FRAC(8),
198
 
                                            fill_end - fill_start);
199
 
                            fill_start = lxi;
200
 
                            fill_end = rxi;
201
 
                            fill_size = 1;
202
 
                        }
203
 
                        else
204
 
                        {
205
 
                            /* Update fill_start */
206
 
                            if (lxi > fill_start)
207
 
                            {
208
 
                                add_saturate_8 (ap + fill_start,
209
 
                                                fill_size * N_X_FRAC(8),
210
 
                                                lxi - fill_start);
211
 
                                fill_start = lxi;
212
 
                            }
213
 
                            else if (lxi < fill_start)
214
 
                            {
215
 
                                add_saturate_8 (ap + lxi, N_X_FRAC(8),
216
 
                                                fill_start - lxi);
217
 
                            }
218
 
 
219
 
                            /* Update fill_end */
220
 
                            if (rxi < fill_end)
221
 
                            {
222
 
                                add_saturate_8 (ap + rxi,
223
 
                                                fill_size * N_X_FRAC(8),
224
 
                                                fill_end - rxi);
225
 
                                fill_end = rxi;
226
 
                            }
227
 
                            else if (fill_end < rxi)
228
 
                            {
229
 
                                add_saturate_8 (ap + fill_end,
230
 
                                                N_X_FRAC(8),
231
 
                                                rxi - fill_end);
232
 
                            }
233
 
                            fill_size++;
234
 
                        }
235
 
                    }
236
 
                }
237
 
                else
238
 
                {
239
 
                    add_saturate_8 (ap + lxi, N_X_FRAC(8), rxi - lxi);
240
 
                }
241
 
 
242
 
                WRITE(image, ap + rxi, clip255 (READ(image, ap + rxi) + rxs));
 
223
                if (rxi - lxi > 4)
 
224
                {
 
225
                    if (fill_start < 0)
 
226
                    {
 
227
                        fill_start = lxi;
 
228
                        fill_end = rxi;
 
229
                        fill_size++;
 
230
                    }
 
231
                    else
 
232
                    {
 
233
                        if (lxi >= fill_end || rxi < fill_start)
 
234
                        {
 
235
                            /* We're beyond what we saved, just fill it */
 
236
                            ADD_SATURATE_8 (ap + fill_start,
 
237
                                            fill_size * N_X_FRAC (8),
 
238
                                            fill_end - fill_start);
 
239
                            fill_start = lxi;
 
240
                            fill_end = rxi;
 
241
                            fill_size = 1;
 
242
                        }
 
243
                        else
 
244
                        {
 
245
                            /* Update fill_start */
 
246
                            if (lxi > fill_start)
 
247
                            {
 
248
                                ADD_SATURATE_8 (ap + fill_start,
 
249
                                                fill_size * N_X_FRAC (8),
 
250
                                                lxi - fill_start);
 
251
                                fill_start = lxi;
 
252
                            }
 
253
                            else if (lxi < fill_start)
 
254
                            {
 
255
                                ADD_SATURATE_8 (ap + lxi, N_X_FRAC (8),
 
256
                                                fill_start - lxi);
 
257
                            }
 
258
 
 
259
                            /* Update fill_end */
 
260
                            if (rxi < fill_end)
 
261
                            {
 
262
                                ADD_SATURATE_8 (ap + rxi,
 
263
                                                fill_size * N_X_FRAC (8),
 
264
                                                fill_end - rxi);
 
265
                                fill_end = rxi;
 
266
                            }
 
267
                            else if (fill_end < rxi)
 
268
                            {
 
269
                                ADD_SATURATE_8 (ap + fill_end,
 
270
                                                N_X_FRAC (8),
 
271
                                                rxi - fill_end);
 
272
                            }
 
273
                            fill_size++;
 
274
                        }
 
275
                    }
 
276
                }
 
277
                else
 
278
                {
 
279
                    ADD_SATURATE_8 (ap + lxi, N_X_FRAC (8), rxi - lxi);
 
280
                }
 
281
 
 
282
                WRITE (image, ap + rxi, clip255 (READ (image, ap + rxi) + rxs));
243
283
            }
244
284
        }
245
285
 
246
 
        if (y == b) {
 
286
        if (y == b)
 
287
        {
247
288
            /* We're done, make sure we clean up any remaining fill. */
248
 
            if (fill_start != fill_end) {
249
 
                if (fill_size == N_Y_FRAC(8))
250
 
                {
251
 
                    MEMSET_WRAPPED (image, ap + fill_start, 0xff, fill_end - fill_start);
252
 
                }
253
 
                else
254
 
                {
255
 
                    add_saturate_8 (ap + fill_start, fill_size * N_X_FRAC(8),
256
 
                                    fill_end - fill_start);
257
 
                }
258
 
            }
259
 
            break;
260
 
        }
 
289
            if (fill_start != fill_end)
 
290
            {
 
291
                if (fill_size == N_Y_FRAC (8))
 
292
                {
 
293
                    MEMSET_WRAPPED (image, ap + fill_start,
 
294
                                    0xff, fill_end - fill_start);
 
295
                }
 
296
                else
 
297
                {
 
298
                    ADD_SATURATE_8 (ap + fill_start, fill_size * N_X_FRAC (8),
 
299
                                    fill_end - fill_start);
 
300
                }
 
301
            }
 
302
            break;
 
303
        }
261
304
 
262
 
        if (pixman_fixed_frac (y) != Y_FRAC_LAST(8))
263
 
        {
264
 
            RenderEdgeStepSmall (l);
265
 
            RenderEdgeStepSmall (r);
266
 
            y += STEP_Y_SMALL(8);
 
305
        if (pixman_fixed_frac (y) != Y_FRAC_LAST (8))
 
306
        {
 
307
            RENDER_EDGE_STEP_SMALL (l);
 
308
            RENDER_EDGE_STEP_SMALL (r);
 
309
            y += STEP_Y_SMALL (8);
267
310
        }
268
 
        else
269
 
        {
270
 
            RenderEdgeStepBig (l);
271
 
            RenderEdgeStepBig (r);
272
 
            y += STEP_Y_BIG(8);
 
311
        else
 
312
        {
 
313
            RENDER_EDGE_STEP_BIG (l);
 
314
            RENDER_EDGE_STEP_BIG (r);
 
315
            y += STEP_Y_BIG (8);
273
316
            if (fill_start != fill_end)
274
317
            {
275
 
                if (fill_size == N_Y_FRAC(8))
276
 
                {
277
 
                    MEMSET_WRAPPED (image, ap + fill_start, 0xff, fill_end - fill_start);
278
 
                }
279
 
                else
280
 
                {
281
 
                    add_saturate_8 (ap + fill_start, fill_size * N_X_FRAC(8),
282
 
                                    fill_end - fill_start);
283
 
                }
 
318
                if (fill_size == N_Y_FRAC (8))
 
319
                {
 
320
                    MEMSET_WRAPPED (image, ap + fill_start,
 
321
                                    0xff, fill_end - fill_start);
 
322
                }
 
323
                else
 
324
                {
 
325
                    ADD_SATURATE_8 (ap + fill_start, fill_size * N_X_FRAC (8),
 
326
                                    fill_end - fill_start);
 
327
                }
 
328
                
284
329
                fill_start = fill_end = -1;
285
330
                fill_size = 0;
286
 
            }
287
 
            line += stride;
 
331
            }
 
332
            
 
333
            line += stride;
288
334
        }
289
335
    }
290
336
}
294
340
#endif
295
341
void
296
342
PIXMAN_RASTERIZE_EDGES (pixman_image_t *image,
297
 
                        pixman_edge_t   *l,
298
 
                        pixman_edge_t   *r,
299
 
                        pixman_fixed_t  t,
300
 
                        pixman_fixed_t  b)
 
343
                        pixman_edge_t * l,
 
344
                        pixman_edge_t * r,
 
345
                        pixman_fixed_t  t,
 
346
                        pixman_fixed_t  b)
301
347
{
302
348
    switch (PIXMAN_FORMAT_BPP (image->bits.format))
303
349
    {
304
350
    case 1:
305
 
        fbRasterizeEdges1 (image, l, r, t, b);
 
351
        rasterize_edges_1 (image, l, r, t, b);
306
352
        break;
 
353
 
307
354
    case 4:
308
 
        fbRasterizeEdges4 (image, l, r, t, b);
 
355
        rasterize_edges_4 (image, l, r, t, b);
309
356
        break;
 
357
 
310
358
    case 8:
311
 
        fbRasterizeEdges8 (image, l, r, t, b);
 
359
        rasterize_edges_8 (image, l, r, t, b);
312
360
        break;
313
361
    }
314
362
}
317
365
 
318
366
PIXMAN_EXPORT void
319
367
pixman_rasterize_edges (pixman_image_t *image,
320
 
                        pixman_edge_t   *l,
321
 
                        pixman_edge_t   *r,
322
 
                        pixman_fixed_t  t,
323
 
                        pixman_fixed_t  b)
 
368
                        pixman_edge_t * l,
 
369
                        pixman_edge_t * r,
 
370
                        pixman_fixed_t  t,
 
371
                        pixman_fixed_t  b)
324
372
{
325
 
    if (image->common.read_func || image->common.write_func)
 
373
    return_if_fail (image->type == BITS);
 
374
    
 
375
    if (image->bits.read_func || image->bits.write_func)
326
376
        pixman_rasterize_edges_accessors (image, l, r, t, b);
327
377
    else
328
378
        pixman_rasterize_edges_no_accessors (image, l, r, t, b);