1 #include "evas_common.h"
2 #include "evas_scale_smooth.h"
3 #include "evas_blend_private.h"
5 #define SCALE_CALC_X_POINTS(P, SW, DW) \
6 P = alloca((DW + 1) * sizeof (int)); \
7 scale_calc_x_points(P, SW, DW);
9 #define SCALE_CALC_Y_POINTS(P, SRC, SW, SH, DH) \
10 P = alloca((DH + 1) * sizeof (DATA32 *)); \
11 scale_calc_y_points(P, SRC, SW, SH, DH);
13 #define SCALE_CALC_A_POINTS(P, S, D) \
14 P = alloca(D * sizeof (int)); \
15 scale_calc_a_points(P, S, D);
17 static void scale_calc_y_points(DATA32** p, DATA32 *src, int sw, int sh, int dh);
18 static void scale_calc_x_points(int *p, int sw, int dw);
19 static void scale_calc_a_points(int *p, int s, int d);
22 scale_calc_y_points(DATA32** p, DATA32 *src, int sw, int sh, int dh)
27 inc = (sh << 16) / dh;
28 for (i = 0; i < dh; i++)
30 p[i] = src + ((val >> 16) * sw);
37 scale_calc_x_points(int *p, int sw, int dw)
42 inc = (sw << 16) / dw;
43 for (i = 0; i < dw; i++)
52 scale_calc_a_points(int *p, int s, int d)
60 for (i = 0; i < d; i++)
62 p[i] = (val >> 8) - ((val >> 8) & 0xffffff00);
63 if ((val >> 16) >= (s - 1)) p[i] = 0;
73 Cp = ((d << 14) / s) + 1;
74 for (i = 0; i < d; i++)
76 ap = ((0x100 - ((val >> 8) & 0xff)) * Cp) >> 8;
77 p[i] = ap | (Cp << 16);
84 #ifdef BUILD_SCALE_SMOOTH
87 evas_common_scale_rgba_mipmap_down_2x2_c(DATA32 *src, DATA32 *dst, int src_w, int src_h)
89 int x, y, dst_w, dst_h;
90 DATA32 *src_ptr, *src_ptr2, *dst_ptr;
95 if (dst_w < 1) dst_w = 1;
96 if (dst_h < 1) dst_h = 1;
99 src_ptr2 = src + src_w;
101 for (y = 0; y < dst_h; y++)
103 src_ptr = src + (y * src_w * 2);
104 src_ptr2 = src_ptr + src_w;
105 for (x = 0; x < dst_w; x++)
107 R_VAL(dst_ptr) = (R_VAL(src_ptr) + R_VAL(src_ptr + 1) + R_VAL(src_ptr2) + R_VAL(src_ptr2 + 1)) >> 2;
108 G_VAL(dst_ptr) = (G_VAL(src_ptr) + G_VAL(src_ptr + 1) + G_VAL(src_ptr2) + G_VAL(src_ptr2 + 1)) >> 2;
109 B_VAL(dst_ptr) = (B_VAL(src_ptr) + B_VAL(src_ptr + 1) + B_VAL(src_ptr2) + B_VAL(src_ptr2 + 1)) >> 2;
110 A_VAL(dst_ptr) = (A_VAL(src_ptr) + A_VAL(src_ptr + 1) + A_VAL(src_ptr2) + A_VAL(src_ptr2 + 1)) >> 2;
121 #ifdef BUILD_SCALE_SMOOTH
124 evas_common_scale_rgba_mipmap_down_2x1_c(DATA32 *src, DATA32 *dst, int src_w, int src_h)
126 int x, y, dst_w, dst_h;
127 DATA32 *src_ptr, *dst_ptr;
132 if (dst_w < 1) dst_w = 1;
133 if (dst_h < 1) dst_h = 1;
137 for (y = 0; y < dst_h; y++)
139 src_ptr = src + (y * src_w * 2);
140 for (x = 0; x < dst_w; x++)
142 R_VAL(dst_ptr) = (R_VAL(src_ptr) + R_VAL(src_ptr + 1)) >> 1;
143 G_VAL(dst_ptr) = (G_VAL(src_ptr) + G_VAL(src_ptr + 1)) >> 1;
144 B_VAL(dst_ptr) = (B_VAL(src_ptr) + B_VAL(src_ptr + 1)) >> 1;
145 A_VAL(dst_ptr) = (A_VAL(src_ptr) + A_VAL(src_ptr + 1)) >> 1;
155 #ifdef BUILD_SCALE_SMOOTH
158 evas_common_scale_rgba_mipmap_down_1x2_c(DATA32 *src, DATA32 *dst, int src_w, int src_h)
160 int x, y, dst_w, dst_h;
161 DATA32 *src_ptr, *src_ptr2, *dst_ptr;
166 if (dst_w < 1) dst_w = 1;
167 if (dst_h < 1) dst_h = 1;
171 for (y = 0; y < dst_h; y++)
173 src_ptr = src + (y * src_w * 2);
174 src_ptr2 = src_ptr + src_w;
175 for (x = 0; x < dst_w; x++)
177 R_VAL(dst_ptr) = (R_VAL(src_ptr) + R_VAL(src_ptr2)) >> 1;
178 G_VAL(dst_ptr) = (G_VAL(src_ptr) + G_VAL(src_ptr2)) >> 1;
179 B_VAL(dst_ptr) = (B_VAL(src_ptr) + B_VAL(src_ptr2)) >> 1;
180 A_VAL(dst_ptr) = (A_VAL(src_ptr) + A_VAL(src_ptr2)) >> 1;
191 #ifdef BUILD_SCALE_SMOOTH
194 evas_common_scale_rgb_mipmap_down_2x2_c(DATA32 *src, DATA32 *dst, int src_w, int src_h)
196 int x, y, dst_w, dst_h;
197 DATA32 *src_ptr, *src_ptr2, *dst_ptr;
202 if (dst_w < 1) dst_w = 1;
203 if (dst_h < 1) dst_h = 1;
206 src_ptr2 = src + src_w;
208 for (y = 0; y < dst_h; y++)
210 for (x = 0; x < dst_w; x++)
212 R_VAL(dst_ptr) = (R_VAL(src_ptr) + R_VAL(src_ptr + 1) + R_VAL(src_ptr2) + R_VAL(src_ptr2 + 1)) >> 2;
213 G_VAL(dst_ptr) = (G_VAL(src_ptr) + G_VAL(src_ptr + 1) + G_VAL(src_ptr2) + G_VAL(src_ptr2 + 1)) >> 2;
214 B_VAL(dst_ptr) = (B_VAL(src_ptr) + B_VAL(src_ptr + 1) + B_VAL(src_ptr2) + B_VAL(src_ptr2 + 1)) >> 2;
215 A_VAL(dst_ptr) = 0xff;
228 #ifdef BUILD_SCALE_SMOOTH
231 evas_common_scale_rgb_mipmap_down_2x1_c(DATA32 *src, DATA32 *dst, int src_w, int src_h)
233 int x, y, dst_w, dst_h;
234 DATA32 *src_ptr, *dst_ptr;
239 if (dst_w < 1) dst_w = 1;
240 if (dst_h < 1) dst_h = 1;
244 for (y = 0; y < dst_h; y++)
246 for (x = 0; x < dst_w; x++)
248 R_VAL(dst_ptr) = (R_VAL(src_ptr) + R_VAL(src_ptr + 1)) >> 1;
249 G_VAL(dst_ptr) = (G_VAL(src_ptr) + G_VAL(src_ptr + 1)) >> 1;
250 B_VAL(dst_ptr) = (B_VAL(src_ptr) + B_VAL(src_ptr + 1)) >> 1;
251 A_VAL(dst_ptr) = 0xff;
262 #ifdef BUILD_SCALE_SMOOTH
265 evas_common_scale_rgb_mipmap_down_1x2_c(DATA32 *src, DATA32 *dst, int src_w, int src_h)
267 int x, y, dst_w, dst_h;
268 DATA32 *src_ptr, *src_ptr2, *dst_ptr;
273 if (dst_w < 1) dst_w = 1;
274 if (dst_h < 1) dst_h = 1;
277 src_ptr2 = src + src_w;
279 for (y = 0; y < dst_h; y++)
281 for (x = 0; x < dst_w; x++)
283 R_VAL(dst_ptr) = (R_VAL(src_ptr) + R_VAL(src_ptr2)) >> 1;
284 G_VAL(dst_ptr) = (G_VAL(src_ptr) + G_VAL(src_ptr2)) >> 1;
285 B_VAL(dst_ptr) = (B_VAL(src_ptr) + B_VAL(src_ptr2)) >> 1;
286 A_VAL(dst_ptr) = 0xff;
299 #ifdef BUILD_SCALE_SMOOTH
302 evas_common_scale_rgba_mipmap_down_2x2_mmx(DATA32 *src, DATA32 *dst, int src_w, int src_h)
304 int x, y, dst_w, dst_h;
305 DATA32 *src_ptr, *src_ptr2, *dst_ptr;
310 if (dst_w < 1) dst_w = 1;
311 if (dst_h < 1) dst_h = 1;
313 /* NB: Dead assignments (reassigned to different values below)
315 src_ptr2 = src + src_w;
319 for (y = 0; y < dst_h; y++)
321 src_ptr = src + (y * src_w * 2);
322 src_ptr2 = src_ptr + src_w;
323 for (x = 0; x < dst_w; x++)
325 punpcklbw_m2r(src_ptr[0], mm0);
326 punpcklbw_m2r(src_ptr[1], mm1);
327 punpcklbw_m2r(src_ptr2[0], mm2);
328 punpcklbw_m2r(src_ptr2[1], mm3);
337 packuswb_r2r(mm0, mm0);
338 movd_r2m(mm0, dst_ptr[0]);
349 #ifdef BUILD_SCALE_SMOOTH
352 evas_common_scale_rgba_mipmap_down_2x1_mmx(DATA32 *src, DATA32 *dst, int src_w, int src_h)
354 int x, y, dst_w, dst_h;
355 DATA32 *src_ptr, *dst_ptr;
360 if (dst_w < 1) dst_w = 1;
361 if (dst_h < 1) dst_h = 1;
365 for (y = 0; y < dst_h; y++)
367 src_ptr = src + (y * src_w * 2);
368 for (x = 0; x < dst_w; x++)
370 punpcklbw_m2r(src_ptr[0], mm0);
371 punpcklbw_m2r(src_ptr[1], mm1);
376 packuswb_r2r(mm0, mm0);
377 movd_r2m(mm0, dst_ptr[0]);
387 #ifdef BUILD_SCALE_SMOOTH
390 evas_common_scale_rgba_mipmap_down_1x2_mmx(DATA32 *src, DATA32 *dst, int src_w, int src_h)
392 int x, y, dst_w, dst_h;
393 DATA32 *src_ptr, *src_ptr2, *dst_ptr;
398 if (dst_w < 1) dst_w = 1;
399 if (dst_h < 1) dst_h = 1;
401 /* NB: Dead assignment (gets reassigned later) */
404 src_ptr2 = src + src_w;
406 for (y = 0; y < dst_h; y++)
408 src_ptr = src + (y * src_w * 2);
409 src_ptr2 = src_ptr + src_w;
410 for (x = 0; x < dst_w; x++)
412 punpcklbw_m2r(src_ptr[0], mm0);
413 punpcklbw_m2r(src_ptr2[0], mm1);
418 packuswb_r2r(mm0, mm0);
419 movd_r2m(mm0, dst_ptr[0]);
430 #ifdef BUILD_SCALE_SMOOTH
433 # define SCALE_FUNC evas_common_scale_rgba_in_to_out_clip_smooth_mmx
434 # undef SCALE_USING_MMX
435 # define SCALE_USING_MMX
436 # include "evas_scale_smooth_scaler.c"
440 # define SCALE_FUNC evas_common_scale_rgba_in_to_out_clip_smooth_c
441 # undef SCALE_USING_MMX
442 # include "evas_scale_smooth_scaler.c"
445 evas_common_scale_rgba_in_to_out_clip_smooth(RGBA_Image *src, RGBA_Image *dst,
446 RGBA_Draw_Context *dc,
447 int src_region_x, int src_region_y,
448 int src_region_w, int src_region_h,
449 int dst_region_x, int dst_region_y,
450 int dst_region_w, int dst_region_h)
457 int c, cx, cy, cw, ch;
459 /* handle cutouts here! */
461 if ((dst_region_w <= 0) || (dst_region_h <= 0)) return;
462 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)))
465 evas_common_cpu_can_do(&mmx, &sse, &sse2);
467 /* no cutouts - cut right to the chase */
468 if (!dc->cutout.rects)
472 evas_common_scale_rgba_in_to_out_clip_smooth_mmx(src, dst, dc,
473 src_region_x, src_region_y,
474 src_region_w, src_region_h,
475 dst_region_x, dst_region_y,
476 dst_region_w, dst_region_h);
480 evas_common_scale_rgba_in_to_out_clip_smooth_c(src, dst, dc,
481 src_region_x, src_region_y,
482 src_region_w, src_region_h,
483 dst_region_x, dst_region_y,
484 dst_region_w, dst_region_h);
488 /* save out clip info */
489 c = dc->clip.use; cx = dc->clip.x; cy = dc->clip.y; cw = dc->clip.w; ch = dc->clip.h;
490 evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h);
491 evas_common_draw_context_clip_clip(dc, dst_region_x, dst_region_y, dst_region_w, dst_region_h);
492 /* our clip is 0 size.. abort */
493 if ((dc->clip.w <= 0) || (dc->clip.h <= 0))
495 dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;
498 rects = evas_common_draw_context_apply_cutouts(dc);
499 for (i = 0; i < rects->active; ++i)
501 r = rects->rects + i;
502 evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h);
505 evas_common_scale_rgba_in_to_out_clip_smooth_mmx(src, dst, dc,
506 src_region_x, src_region_y,
507 src_region_w, src_region_h,
508 dst_region_x, dst_region_y,
509 dst_region_w, dst_region_h);
513 evas_common_scale_rgba_in_to_out_clip_smooth_c(src, dst, dc,
514 src_region_x, src_region_y,
515 src_region_w, src_region_h,
516 dst_region_x, dst_region_y,
517 dst_region_w, dst_region_h);
520 evas_common_draw_context_apply_clear_cutouts(rects);
521 /* restore clip info */
522 dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch;