~ubuntu-branches/ubuntu/precise/inkscape/precise-updates

« back to all changes in this revision

Viewing changes to src/libnr/nr-compose-transform.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alex Valavanis
  • Date: 2010-09-12 19:44:58 UTC
  • mfrom: (1.1.12 upstream) (45.1.3 maverick)
  • Revision ID: james.westby@ubuntu.com-20100912194458-4sjwmbl7dlsrk5dc
Tags: 0.48.0-1ubuntu1
* Merge with Debian unstable (LP: #628048, LP: #401567, LP: #456248, 
  LP: #463602, LP: #591986)
* debian/control: 
  - Ubuntu maintainers
  - Promote python-lxml, python-numpy, python-uniconvertor to Recommends.
  - Demote pstoedit to Suggests (universe package).
  - Suggests ttf-dejavu instead of ttf-bitstream-vera (LP: #513319)
* debian/rules:
  - Run intltool-update on build (Ubuntu-specific).
  - Add translation domain to .desktop files (Ubuntu-specific).
* debian/dirs:
  - Add usr/share/pixmaps.  Allow inkscape.xpm installation
* drop 50-poppler-API.dpatch (now upstream)
* drop 51-paste-in-unwritable-directory.dpatch (now upstream) 

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
#include "nr-pixops.h"
17
17
#include "nr-matrix.h"
18
18
 
19
 
 
20
 
#ifdef WITH_MMX
 
19
/*#ifdef WITH_MMX
21
20
#ifdef __cplusplus
22
21
extern "C" {
23
 
#endif /* __cplusplus */
24
 
/* fixme: */
25
 
int nr_have_mmx (void);
26
 
void nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0 (unsigned char *px, int w, int h, int rs,
27
 
                                                          const unsigned char *spx, int sw, int sh, int srs,
28
 
                                                          const long *FFd2s, unsigned int alpha);
29
 
void nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n (unsigned char *px, int w, int h, int rs,
30
 
                                                          const unsigned char *spx, int sw, int sh, int srs,
31
 
                                                          const long *FFd2s, const long *FF_S, unsigned int alpha, int dbits);
 
22
#endif // __cplusplus
 
23
/ * fixme: * /
 
24
/ *int nr_have_mmx (void);
32
25
#define NR_PIXOPS_MMX (1 && nr_have_mmx ())
33
26
#ifdef __cplusplus
34
27
}
35
28
#endif //__cplusplus
36
29
#endif
 
30
*/
37
31
 
38
32
/* fixme: Implement missing (Lauris) */
39
33
/* fixme: PREMUL colors before calculating average (Lauris) */
40
34
 
41
35
/* Fixed point precision */
42
36
#define FBITS 12
 
37
#define FBITS_HP 18 // In some places we need a higher precision
43
38
 
44
39
void nr_R8G8B8A8_N_EMPTY_R8G8B8A8_N_TRANSFORM (unsigned char *px, int w, int h, int rs,
45
40
                                               const unsigned char *spx, int sw, int sh, int srs,
70
65
        int x, y;
71
66
 
72
67
        if (alpha == 0) return;
 
68
    if (alpha>255) {
 
69
        g_warning("In transform PPN alpha=%u>255",alpha);
 
70
    }
 
71
 
 
72
    // The color component is stored temporarily with a range of [0,255^3], so more supersampling and we get an overflow (fortunately Inkscape's preferences also doesn't allow a higher setting)
 
73
    if (xd+yd>8) {
 
74
        xd = 4;
 
75
        yd = 4;
 
76
    }
73
77
 
74
78
        xsize = (1 << xd);
75
79
        ysize = (1 << yd);
76
80
        size = xsize * ysize;
77
81
        dbits = xd + yd;
 
82
    unsigned int rounding_fix = size/2;
78
83
 
79
84
        /* Set up fixed point matrix */
80
 
        FFs_x_x = (long) (d2s[0] * (1 << FBITS) + 0.5);
81
 
        FFs_x_y = (long) (d2s[1] * (1 << FBITS) + 0.5);
82
 
        FFs_y_x = (long) (d2s[2] * (1 << FBITS) + 0.5);
83
 
        FFs_y_y = (long) (d2s[3] * (1 << FBITS) + 0.5);
84
 
        FFs__x = (long) (d2s[4] * (1 << FBITS) + 0.5);
85
 
        FFs__y = (long) (d2s[5] * (1 << FBITS) + 0.5);
 
85
        FFs_x_x = (long) floor(d2s[0] * (1 << FBITS) + 0.5);
 
86
        FFs_x_y = (long) floor(d2s[1] * (1 << FBITS) + 0.5);
 
87
        FFs_y_x = (long) floor(d2s[2] * (1 << FBITS) + 0.5);
 
88
        FFs_y_y = (long) floor(d2s[3] * (1 << FBITS) + 0.5);
 
89
        FFs__x = (long) floor(d2s[4] * (1 << FBITS) + 0.5);
 
90
        FFs__y = (long) floor(d2s[5] * (1 << FBITS) + 0.5);
86
91
 
87
92
        FFs_x_x_S = FFs_x_x >> xd;
88
93
        FFs_x_y_S = FFs_x_y >> xd;
119
124
                                        sy = (FFsy + FF_sy_S[i]) >> FBITS;
120
125
                                        if ((sy >= 0) && (sy < sh)) {
121
126
                                                const unsigned char *s;
122
 
                                                unsigned int ca;
123
127
                                                s = spx + sy * srs + sx * 4;
124
 
                                                ca = NR_PREMUL_112 (s[3], alpha);
125
 
                                                r += NR_PREMUL_121 (s[0], ca);
126
 
                                                g += NR_PREMUL_121 (s[1], ca);
127
 
                                                b += NR_PREMUL_121 (s[2], ca);
128
 
                                                a += NR_NORMALIZE_21(ca);
 
128
                                                r += NR_PREMUL_112 (s[0], s[3]); // s in [0,255]
 
129
                                                g += NR_PREMUL_112 (s[1], s[3]);
 
130
                                                b += NR_PREMUL_112 (s[2], s[3]);
 
131
                                                a += s[3];
 
132
                        // a=sum(s3)
 
133
                        // r,g,b in [0,sum(s3)*255]
129
134
                                        }
130
135
                                }
131
136
                        }
132
 
                        a >>= dbits;
 
137
                        a = (a*alpha + rounding_fix) >> dbits;
 
138
            // a=sum(s3)*alpha/size=avg(s3)*alpha
 
139
            // Compare to nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_P
133
140
                        if (a != 0) {
134
 
                                r = r >> dbits;
135
 
                                g = g >> dbits;
136
 
                                b = b >> dbits;
137
 
                                if (a == 255) {
138
 
                                        /* Transparent BG, premul src */
139
 
                                        d[0] = r;
140
 
                                        d[1] = g;
141
 
                                        d[2] = b;
142
 
                                        d[3] = a;
 
141
                                r = (r*alpha + rounding_fix) >> dbits;
 
142
                                g = (g*alpha + rounding_fix) >> dbits;
 
143
                                b = (b*alpha + rounding_fix) >> dbits;
 
144
                // r,g,b in [0,avg(s3)*alpha*255]=[0,a*255]
 
145
                if (a == 255*255) {
 
146
                                        /* Full coverage, demul src */
 
147
                                        d[0] = NR_NORMALIZE_31(r);
 
148
                                        d[1] = NR_NORMALIZE_31(g);
 
149
                                        d[2] = NR_NORMALIZE_31(b);
 
150
                                        d[3] = NR_NORMALIZE_21(a);
 
151
                } else if (d[3] == 0) {
 
152
                    /* Only foreground, demul src */
 
153
                    d[0] = NR_DEMUL_321(r,a);
 
154
                    d[1] = NR_DEMUL_321(g,a);
 
155
                    d[2] = NR_DEMUL_321(b,a);
 
156
                    d[3] = NR_NORMALIZE_21(a);
143
157
                                } else {
144
158
                                        unsigned int ca;
145
159
                                        /* Full composition */
146
 
                                        ca = NR_COMPOSEA_112(a, d[3]);
147
 
                                        d[0] = NR_COMPOSENNN_111121 (r, a, d[0], d[3], ca);
148
 
                                        d[1] = NR_COMPOSENNN_111121 (g, a, d[1], d[3], ca);
149
 
                                        d[2] = NR_COMPOSENNN_111121 (b, a, d[2], d[3], ca);
150
 
                                        d[3] = NR_NORMALIZE_21(ca);
 
160
                                        ca = NR_COMPOSEA_213(a, d[3]);
 
161
                                        d[0] = NR_COMPOSEPNN_321131 (r, a, d[0], d[3], ca);
 
162
                                        d[1] = NR_COMPOSEPNN_321131 (g, a, d[1], d[3], ca);
 
163
                                        d[2] = NR_COMPOSEPNN_321131 (b, a, d[2], d[3], ca);
 
164
                                        d[3] = NR_NORMALIZE_31(ca);
151
165
                                }
152
166
                        }
153
167
                        /* Advance pointers */
168
182
static void
169
183
nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0 (unsigned char *px, int w, int h, int rs,
170
184
                                                 const unsigned char *spx, int sw, int sh, int srs,
171
 
                                                 const long *FFd2s, unsigned int alpha)
 
185
                                                 const long long *FFd2s, unsigned int alpha)
172
186
{
173
 
        unsigned char *d0;
174
 
        int FFsx0, FFsy0;
 
187
    unsigned char *d0;
 
188
        long long FFsx0, FFsy0;
175
189
        int x, y;
176
190
 
177
191
        d0 = px;
180
194
 
181
195
        for (y = 0; y < h; y++) {
182
196
                unsigned char *d;
183
 
                long FFsx, FFsy;
 
197
                long long FFsx, FFsy;
184
198
                d = d0;
185
199
                FFsx = FFsx0;
186
200
                FFsy = FFsy0;
187
201
                for (x = 0; x < w; x++) {
188
202
                        long sx, sy;
189
 
                        sx = FFsx >> FBITS;
 
203
                        sx = long(FFsx >> FBITS_HP);
190
204
                        if ((sx >= 0) && (sx < sw)) {
191
 
                                sy = FFsy >> FBITS;
 
205
                                sy = long(FFsy >> FBITS_HP);
192
206
                                if ((sy >= 0) && (sy < sh)) {
193
207
                                        const unsigned char *s;
194
208
                                        unsigned int a;
224
238
static void
225
239
nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n (unsigned char *px, int w, int h, int rs,
226
240
                                                 const unsigned char *spx, int sw, int sh, int srs,
227
 
                                                 const long *FFd2s, const long *FF_S, unsigned int alpha, int dbits)
 
241
                                                 const long long *FFd2s, const long *FF_S, unsigned int alpha, int dbits)
228
242
{
229
243
        int size;
230
244
        unsigned char *d0;
231
 
        int FFsx0, FFsy0;
 
245
        long long FFsx0, FFsy0;
232
246
        int x, y;
233
247
 
234
248
        size = (1 << dbits);
235
 
    unsigned alpha_rounding_fix = size * 255;
236
 
    unsigned rgb_rounding_fix = size * (255 * 256);
237
 
    if (alpha > 127) ++alpha;
 
249
    unsigned int rounding_fix = size/2;
238
250
 
239
251
        d0 = px;
240
252
        FFsx0 = FFd2s[4];
242
254
 
243
255
        for (y = 0; y < h; y++) {
244
256
                unsigned char *d;
245
 
                long FFsx, FFsy;
 
257
                long long FFsx, FFsy;
246
258
                d = d0;
247
259
                FFsx = FFsx0;
248
260
                FFsy = FFsy0;
252
264
                        r = g = b = a = 0;
253
265
                        for (i = 0; i < size; i++) {
254
266
                                long sx, sy;
255
 
                                sx = (FFsx + FF_S[2 * i]) >> FBITS;
 
267
                                sx = (long (FFsx >> (FBITS_HP - FBITS)) + FF_S[2 * i]) >> FBITS;
256
268
                                if ((sx >= 0) && (sx < sw)) {
257
 
                                        sy = (FFsy + FF_S[2 * i + 1]) >> FBITS;
 
269
                                        sy = (long (FFsy >> (FBITS_HP - FBITS)) + FF_S[2 * i + 1]) >> FBITS;
258
270
                                        if ((sy >= 0) && (sy < sh)) {
259
271
                                                const unsigned char *s;
260
 
                                                unsigned int ca;
261
272
                                                s = spx + sy * srs + sx * 4;
262
 
                                                ca = NR_PREMUL_112(s[3], alpha);
263
 
                                                r += NR_PREMUL_123(s[0], ca);
264
 
                                                g += NR_PREMUL_123(s[1], ca);
265
 
                                                b += NR_PREMUL_123(s[2], ca);
266
 
                                                a += ca;
 
273
                                                r += NR_PREMUL_112(s[0], s[3]);
 
274
                                                g += NR_PREMUL_112(s[1], s[3]);
 
275
                                                b += NR_PREMUL_112(s[2], s[3]);
 
276
                                                a += s[3];
267
277
                                        }
268
278
                                }
269
279
                        }
270
 
                        a = (a + alpha_rounding_fix) >> (8 + dbits);
 
280
                        a = (a*alpha + rounding_fix) >> dbits;
271
281
                        if (a != 0) {
272
 
                                r = (r + rgb_rounding_fix) >> (16 + dbits);
273
 
                                g = (g + rgb_rounding_fix) >> (16 + dbits);
274
 
                                b = (b + rgb_rounding_fix) >> (16 + dbits);
275
 
                                if ((a == 255) || (d[3] == 0)) {
 
282
                                r = (r*alpha + rounding_fix) >> dbits;
 
283
                                g = (g*alpha + rounding_fix) >> dbits;
 
284
                                b = (b*alpha + rounding_fix) >> dbits;
 
285
                                if ((a == 255*255) || (d[3] == 0)) {
276
286
                                        /* Transparent BG, premul src */
277
 
                                        d[0] = r;
278
 
                                        d[1] = g;
279
 
                                        d[2] = b;
280
 
                                        d[3] = a;
 
287
                                        d[0] = NR_NORMALIZE_31(r);
 
288
                                        d[1] = NR_NORMALIZE_31(g);
 
289
                                        d[2] = NR_NORMALIZE_31(b);
 
290
                                        d[3] = NR_NORMALIZE_21(a);
281
291
                                } else {
282
 
                                        d[0] = NR_COMPOSEPPP_1111 (r, a, d[0]);
283
 
                                        d[1] = NR_COMPOSEPPP_1111 (g, a, d[1]);
284
 
                                        d[2] = NR_COMPOSEPPP_1111 (b, a, d[2]);
285
 
                                        d[3] = NR_COMPOSEA_111(a, d[3]);
 
292
                                        d[0] = NR_COMPOSEPPP_3211 (r, a, d[0]);
 
293
                                        d[1] = NR_COMPOSEPPP_3211 (g, a, d[1]);
 
294
                                        d[2] = NR_COMPOSEPPP_3211 (b, a, d[2]);
 
295
                                        d[3] = NR_COMPOSEA_211(a, d[3]);
286
296
                                }
287
297
                        }
288
298
                        /* Advance pointers */
302
312
{
303
313
        int dbits;
304
314
        long FFd2s[6];
 
315
        long long FFd2s_HP[6]; // with higher precision
305
316
        int i;
306
317
 
307
318
        if (alpha == 0) return;
308
 
 
309
 
        dbits = xd + yd;
 
319
    if (alpha>255) {
 
320
        g_warning("In transform PPN alpha=%u>255",alpha);
 
321
    }
 
322
 
 
323
    // The color component is stored temporarily with a range of [0,255^3], so more supersampling and we get an overflow (fortunately Inkscape's preferences also doesn't allow a higher setting)
 
324
    if (xd+yd>8) {
 
325
        xd = 4;
 
326
        yd = 4;
 
327
    }
 
328
 
 
329
    dbits = xd + yd;
310
330
 
311
331
        for (i = 0; i < 6; i++) {
312
 
                FFd2s[i] = (long) (d2s[i] * (1 << FBITS) + 0.5);
 
332
                FFd2s[i] = (long) floor(d2s[i] * (1 << FBITS) + 0.5);
 
333
                FFd2s_HP[i] = (long long) floor(d2s[i] * (1 << FBITS_HP) + 0.5);;
313
334
        }
314
335
 
315
336
        if (dbits == 0) {
316
 
#ifdef WITH_MMX
317
 
                if (NR_PIXOPS_MMX) {
318
 
                        /* WARNING: MMX composer REQUIRES w > 0 and h > 0 */
319
 
                        nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0 (px, w, h, rs, spx, sw, sh, srs, FFd2s, alpha);
320
 
                        return;
321
 
                }
322
 
#endif
323
 
                nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0 (px, w, h, rs, spx, sw, sh, srs, FFd2s, alpha);
 
337
                nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0 (px, w, h, rs, spx, sw, sh, srs, FFd2s_HP, alpha);
324
338
        } else {
325
339
                int xsize, ysize;
326
340
                long FFs_x_x_S, FFs_x_y_S, FFs_y_x_S, FFs_y_y_S;
344
358
                        }
345
359
                }
346
360
 
347
 
#ifdef WITH_MMX
348
 
                if (NR_PIXOPS_MMX) {
349
 
                        /* WARNING: MMX composer REQUIRES w > 0 and h > 0 */
350
 
                        nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n (px, w, h, rs, spx, sw, sh, srs, FFd2s, FF_S, alpha, dbits);
351
 
                        return;
352
 
                }
353
 
#endif
354
 
                nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n (px, w, h, rs, spx, sw, sh, srs, FFd2s, FF_S, alpha, dbits);
 
361
                nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n (px, w, h, rs, spx, sw, sh, srs, FFd2s_HP, FF_S, alpha, dbits);
355
362
        }
356
363
}
357
364