~ubuntu-branches/debian/experimental/inkscape/experimental

« back to all changes in this revision

Viewing changes to src/display/nr-filter-pixops.h

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Viehmann
  • Date: 2008-09-09 23:29:02 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20080909232902-c50iujhk1w79u8e7
Tags: 0.46-2.1
* Non-maintainer upload.
* Add upstream patch fixing a crash in the open dialog
  in the zh_CN.utf8 locale. Closes: #487623.
  Thanks to Luca Bruno for the patch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef __NR_FILTER_PIXOPS_H__
 
2
#define __NR_FILTER_PIXOPS_H__
 
3
 
 
4
/*
 
5
 * Per-pixel image manipulation functions.
 
6
 * These can be used by all filter primitives, which combine two images on
 
7
 * per-pixel basis. These are at least feBlend, feComposite and feMerge.
 
8
 *
 
9
 * Authors:
 
10
 *   Niko Kiirala <niko@kiirala.com>
 
11
 *
 
12
 * Copyright (C) 2007 authors
 
13
 *
 
14
 * Released under GNU GPL, read the file 'COPYING' for more information
 
15
 */
 
16
 
 
17
namespace NR {
 
18
 
 
19
/**
 
20
 * Mixes the two input images using the function given as template.
 
21
 * The result is placed in out.
 
22
 * The mixing function should have the following type:
 
23
 * void mix(unsigned char *result, unsigned char const *in1,
 
24
 *          unsigned char const *in2);
 
25
 * Each of the parameters for mix-function is a pointer to four bytes of data,
 
26
 * giving the RGBA values for that pixel. The mix function must only access
 
27
 * the four bytes beginning at a pointer given as parameter.
 
28
 */
 
29
/*
 
30
 * The implementation is in a header file because of the template. It has to
 
31
 * be in the same compilation unit as the code using it. Otherwise, linking
 
32
 * the program will not succeed.
 
33
 */
 
34
template <void(*blend)(unsigned char *cr, unsigned char const *ca, unsigned char const *cb)>
 
35
void pixops_mix(NRPixBlock &out, NRPixBlock &in1, NRPixBlock &in2) {
 
36
    unsigned char *in1_data = NR_PIXBLOCK_PX(&in1);
 
37
    unsigned char *in2_data = NR_PIXBLOCK_PX(&in2);
 
38
    unsigned char *out_data = NR_PIXBLOCK_PX(&out);
 
39
    unsigned char zero_rgba[4] = {0, 0, 0, 0};
 
40
 
 
41
    if (in1.area.y0 < in2.area.y0) {
 
42
        // in1 begins before in2 on y-axis
 
43
        for (int y = in1.area.y0 ; y < in2.area.y0 ; y++) {
 
44
            int out_line = (y - out.area.y0) * out.rs;
 
45
            int in_line = (y - in1.area.y0) * in1.rs;
 
46
            for (int x = in1.area.x0 ; x < in1.area.x1 ; x++) {
 
47
                blend(out_data + out_line + 4 * (x - out.area.x0),
 
48
                      in1_data + in_line + 4 * (x - in1.area.x0),
 
49
                      zero_rgba);
 
50
            }
 
51
        }
 
52
    } else if (in1.area.y0 > in2.area.y0) {
 
53
        // in2 begins before in1 on y-axis
 
54
        for (int y = in2.area.y0 ; y < in1.area.y0 ; y++) {
 
55
            int out_line = (y - out.area.y0) * out.rs;
 
56
            int in_line = (y - in2.area.y0) * in2.rs;
 
57
            for (int x = in2.area.x0 ; x < in2.area.x1 ; x++) {
 
58
                blend(out_data + out_line + 4 * (x - out.area.x0),
 
59
                      zero_rgba,
 
60
                      in2_data + in_line + 4 * (x - in2.area.x0));
 
61
            }
 
62
        }
 
63
    }
 
64
 
 
65
    for (int y = std::max(in1.area.y0, in2.area.y0) ;
 
66
         y < std::min(in1.area.y1, in2.area.y1) ; ++y) {
 
67
        int out_line = (y - out.area.y0) * out.rs;
 
68
        int in1_line = (y - in1.area.y0) * in1.rs;
 
69
        int in2_line = (y - in2.area.y0) * in2.rs;
 
70
 
 
71
        if (in1.area.x0 < in2.area.x0) {
 
72
            // in1 begins before in2 on x-axis
 
73
            for (int x = in1.area.x0 ; x < in2.area.x0 ; ++x) {
 
74
                blend(out_data + out_line + 4 * (x - out.area.x0),
 
75
                      in1_data + in1_line + 4 * (x - in1.area.x0),
 
76
                      zero_rgba);
 
77
            }
 
78
        } else if (in1.area.x0 > in2.area.x0) {
 
79
            // in2 begins before in1 on x-axis
 
80
            for (int x = in2.area.x0 ; x < in1.area.x0 ; ++x) {
 
81
                blend(out_data + out_line + 4 * (x - out.area.x0),
 
82
                      zero_rgba,
 
83
                      in2_data + in2_line + 4 * (x - in2.area.x0));
 
84
            }
 
85
        }
 
86
 
 
87
        for (int x = std::max(in1.area.x0, in2.area.x0) ;
 
88
             x < std::min(in1.area.x1, in2.area.x1) ; ++x) {
 
89
            blend(out_data + out_line + 4 * (x - out.area.x0),
 
90
                  in1_data + in1_line + 4 * (x - in1.area.x0),
 
91
                  in2_data + in2_line + 4 * (x - in2.area.x0));
 
92
        }
 
93
 
 
94
        if (in1.area.x1 > in2.area.x1) {
 
95
            // in1 ends after in2 on x-axis
 
96
            for (int x = in2.area.x1 ; x < in1.area.x1 ; ++x) {
 
97
                blend(out_data + out_line + 4 * (x - out.area.x0),
 
98
                      in1_data + in1_line + 4 * (x - in1.area.x0),
 
99
                      zero_rgba);
 
100
            }
 
101
        } else if (in1.area.x1 < in2.area.x1) {
 
102
            // in2 ends after in1 on x-axis
 
103
            for (int x = in1.area.x1 ; x < in2.area.x1 ; ++x) {
 
104
                blend(out_data + out_line + 4 * (x - out.area.x0),
 
105
                      zero_rgba,
 
106
                      in2_data + in2_line + 4 * (x - in2.area.x0));
 
107
            }
 
108
        }
 
109
    }
 
110
 
 
111
    if (in1.area.y1 > in2.area.y1) {
 
112
        // in1 ends after in2 on y-axis
 
113
        for (int y = in2.area.y1 ; y < in1.area.y1 ; y++) {
 
114
            int out_line = (y - out.area.y0) * out.rs;
 
115
            int in_line = (y - in1.area.y0) * in1.rs;
 
116
            for (int x = in1.area.x0 ; x < in1.area.x1 ; x++) {
 
117
                blend(out_data + out_line + 4 * (x - out.area.x0),
 
118
                      in1_data + in_line + 4 * (x - in1.area.x0),
 
119
                      zero_rgba);
 
120
            }
 
121
        }
 
122
    } else if (in1.area.y1 < in2.area.y1) {
 
123
        // in2 ends after in1 on y-axis
 
124
        for (int y = in1.area.y1 ; y < in2.area.y1 ; y++) {
 
125
            int out_line = (y - out.area.y0) * out.rs;
 
126
            int in_line = (y - in2.area.y0) * in2.rs;
 
127
            for (int x = in2.area.x0 ; x < in2.area.x1 ; x++) {
 
128
                blend(out_data + out_line + 4 * (x - out.area.x0),
 
129
                      zero_rgba,
 
130
                      in2_data + in_line + 4 * (x - in2.area.x0));
 
131
            }
 
132
        }
 
133
    }
 
134
}
 
135
 
 
136
} // namespace NR
 
137
 
 
138
#endif // __NR_FILTER_PIXOPS_H_
 
139
/*
 
140
  Local Variables:
 
141
  mode:c++
 
142
  c-file-style:"stroustrup"
 
143
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
 
144
  indent-tabs-mode:nil
 
145
  fill-column:99
 
146
  End:
 
147
*/
 
148
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :