aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/lib/engines/common/evas_scale_smooth_scaler.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/lib/engines/common/evas_scale_smooth_scaler.c')
-rw-r--r--libraries/evas/src/lib/engines/common/evas_scale_smooth_scaler.c211
1 files changed, 211 insertions, 0 deletions
diff --git a/libraries/evas/src/lib/engines/common/evas_scale_smooth_scaler.c b/libraries/evas/src/lib/engines/common/evas_scale_smooth_scaler.c
new file mode 100644
index 0000000..599bfda
--- /dev/null
+++ b/libraries/evas/src/lib/engines/common/evas_scale_smooth_scaler.c
@@ -0,0 +1,211 @@
1void
2SCALE_FUNC(RGBA_Image *src, RGBA_Image *dst,
3 RGBA_Draw_Context *dc,
4 int src_region_x, int src_region_y,
5 int src_region_w, int src_region_h,
6 int dst_region_x, int dst_region_y,
7 int dst_region_w, int dst_region_h)
8{
9 DATA32 *dst_ptr;
10 int dst_clip_x, dst_clip_y, dst_clip_w, dst_clip_h;
11 int src_w, src_h, dst_w, dst_h;
12
13 if (!(RECTS_INTERSECT(dst_region_x, dst_region_y, dst_region_w, dst_region_h, 0, 0, dst->cache_entry.w, dst->cache_entry.h)))
14 return;
15 if (!(RECTS_INTERSECT(src_region_x, src_region_y, src_region_w, src_region_h, 0, 0, src->cache_entry.w, src->cache_entry.h)))
16 return;
17
18 src_w = src->cache_entry.w;
19 src_h = src->cache_entry.h;
20 dst_w = dst->cache_entry.w;
21 dst_h = dst->cache_entry.h;
22
23 if (dc->clip.use)
24 {
25 dst_clip_x = dc->clip.x;
26 dst_clip_y = dc->clip.y;
27 dst_clip_w = dc->clip.w;
28 dst_clip_h = dc->clip.h;
29 if (dst_clip_x < 0)
30 {
31 dst_clip_w += dst_clip_x;
32 dst_clip_x = 0;
33 }
34 if (dst_clip_y < 0)
35 {
36 dst_clip_h += dst_clip_y;
37 dst_clip_y = 0;
38 }
39 if ((dst_clip_w <= 0) || (dst_clip_h <= 0)) return;
40 if ((dst_clip_x + dst_clip_w) > dst_w) dst_clip_w = dst_w - dst_clip_x;
41 if ((dst_clip_y + dst_clip_h) > dst_h) dst_clip_h = dst_h - dst_clip_y;
42 }
43 else
44 {
45 dst_clip_x = 0;
46 dst_clip_y = 0;
47 dst_clip_w = dst_w;
48 dst_clip_h = dst_h;
49 }
50
51 if (dst_clip_x < dst_region_x)
52 {
53 dst_clip_w += dst_clip_x - dst_region_x;
54 dst_clip_x = dst_region_x;
55 }
56 if ((dst_clip_x + dst_clip_w) > (dst_region_x + dst_region_w))
57 dst_clip_w = dst_region_x + dst_region_w - dst_clip_x;
58 if (dst_clip_y < dst_region_y)
59 {
60 dst_clip_h += dst_clip_y - dst_region_y;
61 dst_clip_y = dst_region_y;
62 }
63 if ((dst_clip_y + dst_clip_h) > (dst_region_y + dst_region_h))
64 dst_clip_h = dst_region_y + dst_region_h - dst_clip_y;
65
66 if ((src_region_w <= 0) || (src_region_h <= 0) ||
67 (dst_region_w <= 0) || (dst_region_h <= 0) ||
68 (dst_clip_w <= 0) || (dst_clip_h <= 0))
69 return;
70
71 /* sanitise x */
72 if (src_region_x < 0)
73 {
74 dst_region_x -= (src_region_x * dst_region_w) / src_region_w;
75 dst_region_w += (src_region_x * dst_region_w) / src_region_w;
76 src_region_w += src_region_x;
77 src_region_x = 0;
78 }
79 if (src_region_x >= src_w) return;
80 if ((src_region_x + src_region_w) > src_w)
81 {
82 dst_region_w = (dst_region_w * (src_w - src_region_x)) / (src_region_w);
83 src_region_w = src_w - src_region_x;
84 }
85 if (dst_region_w <= 0) return;
86 if (src_region_w <= 0) return;
87 if (dst_clip_x < 0)
88 {
89 dst_clip_w += dst_clip_x;
90 dst_clip_x = 0;
91 }
92 if (dst_clip_w <= 0) return;
93 if (dst_clip_x >= dst_w) return;
94 if (dst_clip_x < dst_region_x)
95 {
96 dst_clip_w += (dst_clip_x - dst_region_x);
97 dst_clip_x = dst_region_x;
98 }
99 if ((dst_clip_x + dst_clip_w) > dst_w)
100 {
101 dst_clip_w = dst_w - dst_clip_x;
102 }
103 if (dst_clip_w <= 0) return;
104
105 /* sanitise y */
106 if (src_region_y < 0)
107 {
108 dst_region_y -= (src_region_y * dst_region_h) / src_region_h;
109 dst_region_h += (src_region_y * dst_region_h) / src_region_h;
110 src_region_h += src_region_y;
111 src_region_y = 0;
112 }
113 if (src_region_y >= src_h) return;
114 if ((src_region_y + src_region_h) > src_h)
115 {
116 dst_region_h = (dst_region_h * (src_h - src_region_y)) / (src_region_h);
117 src_region_h = src_h - src_region_y;
118 }
119 if (dst_region_h <= 0) return;
120 if (src_region_h <= 0) return;
121 if (dst_clip_y < 0)
122 {
123 dst_clip_h += dst_clip_y;
124 dst_clip_y = 0;
125 }
126 if (dst_clip_h <= 0) return;
127 if (dst_clip_y >= dst_h) return;
128 if (dst_clip_y < dst_region_y)
129 {
130 dst_clip_h += (dst_clip_y - dst_region_y);
131 dst_clip_y = dst_region_y;
132 }
133 if ((dst_clip_y + dst_clip_h) > dst_h)
134 {
135 dst_clip_h = dst_h - dst_clip_y;
136 }
137 if (dst_clip_h <= 0) return;
138
139 /* some maximum region sizes to avoid insane calc point tables */
140 if (dst_clip_w > 65536) return;
141 if (dst_clip_h > 65536) return;
142 if (dst_region_w > (65536 * 1024)) return;
143 if (dst_region_h > (65536 * 1024)) return;
144
145 /* figure out dst jump
146 * NB: Unused currently, so commented out */
147// dst_jump = dst_w - dst_clip_w;
148
149 /* figure out dest start ptr */
150 dst_ptr = dst->image.data + dst_clip_x + (dst_clip_y * dst_w);
151
152/* FIXME:
153 *
154 * things to do later for speedups:
155 *
156 * break upscale into 3 cases (as listed below - up:up, 1:up, up:1)
157 *
158 * break downscale into more cases (as listed below)
159 *
160 * roll func (blend/copy/cultiply/cmod) code into inner loop of scaler.
161 * (578 fps vs 550 in mmx upscale in evas demo - this means probably
162 * a good 10-15% speedup over the func call, but means massively larger
163 * code)
164 *
165 * anything involving downscaling has no mmx equivalent code and maybe the
166 * C could do with a little work.
167 *
168 * ---------------------------------------------------------------------------
169 *
170 * (1 = no scaling (1:1 ratio), + = scale up, - = scale down)
171 * (* == fully optimised mmx, # = fully optimised C)
172 *
173 * h:v mmx C
174 *
175 * 1:1 * #
176 *
177 * +:+ * #
178 * 1:+ * #
179 * +:1 * #
180 *
181 * 1:-
182 * -:1
183 * +:-
184 * -:+
185 * -:-
186 *
187 */
188
189 /* if 1:1 scale */
190 if ((dst_region_w == src_region_w) &&
191 (dst_region_h == src_region_h))
192 {
193#include "evas_scale_smooth_scaler_noscale.c"
194 }
195 else
196 {
197 /* scaling up only - dont need anything except original */
198// if ((!dc->anti_alias) || ((dst_region_w >= src_region_w) && (dst_region_h >= src_region_h)))
199 if (((dst_region_w >= src_region_w) && (dst_region_h >= src_region_h)))
200 {
201#include "evas_scale_smooth_scaler_up.c"
202 return;
203 }
204 else
205 /* scaling down... funkiness */
206 {
207#include "evas_scale_smooth_scaler_down.c"
208 return;
209 }
210 }
211}