1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
From cc5fce6315dcc1127a3e2106223305ff763be815 Mon Sep 17 00:00:00 2001
From: Hans Petter Jansson <hpj@copyleft.no>
Date: Thu, 10 Nov 2005 19:13:00 +0000
Subject: [PATCH] pixops: Special-case compositing/copying with no scaling
When there is no scaling involved, make gdk_pixbuf_composite_color()
faster by avoiding the scaling code path.
https://bugzilla.gnome.org/show_bug.cgi?id=80927
---
gdk-pixbuf/pixops/pixops.c | 95 +++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 90 insertions(+), 5 deletions(-)
diff --git a/gdk-pixbuf/pixops/pixops.c b/gdk-pixbuf/pixops/pixops.c
index 993223e..29a1c14 100644
--- a/gdk-pixbuf/pixops/pixops.c
+++ b/gdk-pixbuf/pixops/pixops.c
@@ -421,6 +421,86 @@ pixops_composite_nearest (guchar *dest_buf,
}
static void
+pixops_composite_nearest_noscale (guchar *dest_buf,
+ int render_x0,
+ int render_y0,
+ int render_x1,
+ int render_y1,
+ int dest_rowstride,
+ int dest_channels,
+ gboolean dest_has_alpha,
+ const guchar *src_buf,
+ int src_width,
+ int src_height,
+ int src_rowstride,
+ int src_channels,
+ gboolean src_has_alpha,
+ int overall_alpha)
+{
+ int i, j;
+ int x;
+
+ for (i = 0; i < (render_y1 - render_y0); i++)
+ {
+ const guchar *src = src_buf + (i + render_y0) * src_rowstride;
+ guchar *dest = dest_buf + i * dest_rowstride;
+
+ x = render_x0 * src_channels;
+
+ for (j=0; j < (render_x1 - render_x0); j++)
+ {
+ const guchar *p = src + x;
+ unsigned int a0;
+
+ if (src_has_alpha)
+ a0 = (p[3] * overall_alpha) / 0xff;
+ else
+ a0 = overall_alpha;
+
+ switch (a0)
+ {
+ case 0:
+ break;
+ case 255:
+ dest[0] = p[0];
+ dest[1] = p[1];
+ dest[2] = p[2];
+ if (dest_has_alpha)
+ dest[3] = 0xff;
+ break;
+ default:
+ if (dest_has_alpha)
+ {
+ unsigned int w0 = 0xff * a0;
+ unsigned int w1 = (0xff - a0) * dest[3];
+ unsigned int w = w0 + w1;
+
+ dest[0] = (w0 * p[0] + w1 * dest[0]) / w;
+ dest[1] = (w0 * p[1] + w1 * dest[1]) / w;
+ dest[2] = (w0 * p[2] + w1 * dest[2]) / w;
+ dest[3] = w / 0xff;
+ }
+ else
+ {
+ unsigned int a1 = 0xff - a0;
+ unsigned int tmp;
+
+ tmp = a0 * p[0] + a1 * dest[0] + 0x80;
+ dest[0] = (tmp + (tmp >> 8)) >> 8;
+ tmp = a0 * p[1] + a1 * dest[1] + 0x80;
+ dest[1] = (tmp + (tmp >> 8)) >> 8;
+ tmp = a0 * p[2] + a1 * dest[2] + 0x80;
+ dest[2] = (tmp + (tmp >> 8)) >> 8;
+ }
+ break;
+ }
+ dest += dest_channels;
+ x += src_channels;
+ }
+ }
+}
+
+static void
pixops_composite_color_nearest (guchar *dest_buf,
int render_x0,
int render_y0,
@@ -1781,11 +1861,16 @@ _pixops_composite_real (guchar *dest_buf,
if (interp_type == PIXOPS_INTERP_NEAREST)
{
- pixops_composite_nearest (dest_buf, render_x0, render_y0, render_x1,
- render_y1, dest_rowstride, dest_channels,
- dest_has_alpha, src_buf, src_width, src_height,
- src_rowstride, src_channels, src_has_alpha,
- scale_x, scale_y, overall_alpha);
+ if (scale_x == 1.0 && scale_y == 1.0)
+ pixops_composite_nearest_noscale (dest_buf, render_x0, render_y0, render_x1, render_y1,
+ dest_rowstride, dest_channels, dest_has_alpha,
+ src_buf, src_width, src_height, src_rowstride, src_channels,
+ src_has_alpha, overall_alpha);
+ else
+ pixops_composite_nearest (dest_buf, render_x0, render_y0, render_x1, render_y1,
+ dest_rowstride, dest_channels, dest_has_alpha,
+ src_buf, src_width, src_height, src_rowstride, src_channels,
+ src_has_alpha, scale_x, scale_y, overall_alpha);
return;
}
--
2.5.1
|