summaryrefslogtreecommitdiff
path: root/src/lib/evas/common/evas_scale_smooth_scaler.c
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2012-11-04 11:51:42 +0000
committerVincent Torri <vincent.torri@gmail.com>2012-11-04 11:51:42 +0000
commitc15e9c6575c3b5f39ded167dda5259de3de96151 (patch)
tree5115d7ae3620af24c2bc094cd062575af7adeda9 /src/lib/evas/common/evas_scale_smooth_scaler.c
parenta5ac6a987caec5a7f7596a25d0a065b9cc94c50c (diff)
merge: and now Evas
I've tested make -j 3 install and it works nicely I've tested expedite with software and opengl xlib, and it works. Not tested other engines, so please report any problems (engines or other) on the ML. TODO: examples and tests, I'll add them later ISSUE: Eina_Unicode size check. It indirectly depends on eina_config.h, which is created at the end of the configure script. So its size is always 0. I don't know how that size is used, so I can't do a lot, for now. SVN revision: 78895
Diffstat (limited to 'src/lib/evas/common/evas_scale_smooth_scaler.c')
-rw-r--r--src/lib/evas/common/evas_scale_smooth_scaler.c211
1 files changed, 211 insertions, 0 deletions
diff --git a/src/lib/evas/common/evas_scale_smooth_scaler.c b/src/lib/evas/common/evas_scale_smooth_scaler.c
new file mode 100644
index 0000000000..599bfda9fd
--- /dev/null
+++ b/src/lib/evas/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}