From dd7595a3475407a7fa96a97393bae8c5220e8762 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Wed, 4 Jan 2012 18:41:13 +1000 Subject: Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje. Note that embryo wont be used, but I'm not sure yet if you can build edje without it. --- .../src/lib/engines/common/evas_scale_smooth.c | 532 +++++++++++++++++++++ 1 file changed, 532 insertions(+) create mode 100644 libraries/evas/src/lib/engines/common/evas_scale_smooth.c (limited to 'libraries/evas/src/lib/engines/common/evas_scale_smooth.c') diff --git a/libraries/evas/src/lib/engines/common/evas_scale_smooth.c b/libraries/evas/src/lib/engines/common/evas_scale_smooth.c new file mode 100644 index 0000000..d3aada6 --- /dev/null +++ b/libraries/evas/src/lib/engines/common/evas_scale_smooth.c @@ -0,0 +1,532 @@ +#include "evas_common.h" +#include "evas_scale_smooth.h" +#include "evas_blend_private.h" + +#define SCALE_CALC_X_POINTS(P, SW, DW, CX, CW) \ + P = alloca((CW + 1) * sizeof (int)); \ + scale_calc_x_points(P, SW, DW, CX, CW); + +#define SCALE_CALC_Y_POINTS(P, SRC, SW, SH, DH, CY, CH) \ + P = alloca((CH + 1) * sizeof (DATA32 *)); \ + scale_calc_y_points(P, SRC, SW, SH, DH, CY, CH); + +#define SCALE_CALC_A_POINTS(P, S, D, C, CC) \ + P = alloca(CC * sizeof (int)); \ + scale_calc_a_points(P, S, D, C, CC); + +static void scale_calc_y_points(DATA32 **p, DATA32 *src, int sw, int sh, int dh, int cy, int ch); +static void scale_calc_x_points(int *p, int sw, int dw, int cx, int cw); +static void scale_calc_a_points(int *p, int s, int d, int c, int cc); + +static void +scale_calc_y_points(DATA32** p, DATA32 *src, int sw, int sh, int dh, int cy, int ch) +{ + int i, val, inc; + if (sh > SCALE_SIZE_MAX) return; + val = 0; + inc = (sh << 16) / dh; + for (i = 0; i < dh; i++) + { + if ((i >= cy) && (i < (cy + ch))) + p[i - cy] = src + ((val >> 16) * sw); + val += inc; + } + if ((i >= cy) && (i < (cy + ch))) + p[i - cy] = p[i - cy - 1]; +} + +static void +scale_calc_x_points(int *p, int sw, int dw, int cx, int cw) +{ + int i, val, inc; + if (sw > SCALE_SIZE_MAX) return; + val = 0; + inc = (sw << 16) / dw; + for (i = 0; i < dw; i++) + { + if ((i >= cx) && (i < (cx + cw))) + p[i - cx] = val >> 16; + val += inc; + } + if ((i >= cx) && (i < (cx + cw))) + p[i - cx] = p[i - cx - 1]; +} + +static void +scale_calc_a_points(int *p, int s, int d, int c, int cc) +{ + int i, val, inc; + + if (s > SCALE_SIZE_MAX) return; + if (d >= s) + { + val = 0; + inc = (s << 16) / d; + for (i = 0; i < d; i++) + { + if ((i >= c) && (i < (c + cc))) + { + p[i - c] = (val >> 8) - ((val >> 8) & 0xffffff00); + if ((val >> 16) >= (s - 1)) p[i - c] = 0; + } + val += inc; + } + } + else + { + int ap, Cp; + + val = 0; + inc = (s << 16) / d; + Cp = ((d << 14) / s) + 1; + for (i = 0; i < d; i++) + { + ap = ((0x100 - ((val >> 8) & 0xff)) * Cp) >> 8; + if ((i >= c) && (i < (c + cc))) + p[i - c] = ap | (Cp << 16); + val += inc; + } + } +} + +#ifdef BUILD_SCALE_SMOOTH +#ifdef BUILD_C +EAPI void +evas_common_scale_rgba_mipmap_down_2x2_c(DATA32 *src, DATA32 *dst, int src_w, int src_h) +{ + int x, y, dst_w, dst_h; + DATA32 *src_ptr, *src_ptr2, *dst_ptr; + + dst_w = src_w >> 1; + dst_h = src_h >> 1; + + if (dst_w < 1) dst_w = 1; + if (dst_h < 1) dst_h = 1; + + src_ptr = src; + src_ptr2 = src + src_w; + dst_ptr = dst; + for (y = 0; y < dst_h; y++) + { + src_ptr = src + (y * src_w * 2); + src_ptr2 = src_ptr + src_w; + for (x = 0; x < dst_w; x++) + { + R_VAL(dst_ptr) = (R_VAL(src_ptr) + R_VAL(src_ptr + 1) + R_VAL(src_ptr2) + R_VAL(src_ptr2 + 1)) >> 2; + G_VAL(dst_ptr) = (G_VAL(src_ptr) + G_VAL(src_ptr + 1) + G_VAL(src_ptr2) + G_VAL(src_ptr2 + 1)) >> 2; + B_VAL(dst_ptr) = (B_VAL(src_ptr) + B_VAL(src_ptr + 1) + B_VAL(src_ptr2) + B_VAL(src_ptr2 + 1)) >> 2; + A_VAL(dst_ptr) = (A_VAL(src_ptr) + A_VAL(src_ptr + 1) + A_VAL(src_ptr2) + A_VAL(src_ptr2 + 1)) >> 2; + + src_ptr+=2; + src_ptr2+=2; + dst_ptr++; + } + } +} +#endif +#endif + +#ifdef BUILD_SCALE_SMOOTH +#ifdef BUILD_C +EAPI void +evas_common_scale_rgba_mipmap_down_2x1_c(DATA32 *src, DATA32 *dst, int src_w, int src_h) +{ + int x, y, dst_w, dst_h; + DATA32 *src_ptr, *dst_ptr; + + dst_w = src_w >> 1; + dst_h = src_h >> 1; + + if (dst_w < 1) dst_w = 1; + if (dst_h < 1) dst_h = 1; + + src_ptr = src; + dst_ptr = dst; + for (y = 0; y < dst_h; y++) + { + src_ptr = src + (y * src_w * 2); + for (x = 0; x < dst_w; x++) + { + R_VAL(dst_ptr) = (R_VAL(src_ptr) + R_VAL(src_ptr + 1)) >> 1; + G_VAL(dst_ptr) = (G_VAL(src_ptr) + G_VAL(src_ptr + 1)) >> 1; + B_VAL(dst_ptr) = (B_VAL(src_ptr) + B_VAL(src_ptr + 1)) >> 1; + A_VAL(dst_ptr) = (A_VAL(src_ptr) + A_VAL(src_ptr + 1)) >> 1; + + src_ptr+=2; + dst_ptr++; + } + } +} +#endif +#endif + +#ifdef BUILD_SCALE_SMOOTH +#ifdef BUILD_C +EAPI void +evas_common_scale_rgba_mipmap_down_1x2_c(DATA32 *src, DATA32 *dst, int src_w, int src_h) +{ + int x, y, dst_w, dst_h; + DATA32 *src_ptr, *src_ptr2, *dst_ptr; + + dst_w = src_w >> 1; + dst_h = src_h >> 1; + + if (dst_w < 1) dst_w = 1; + if (dst_h < 1) dst_h = 1; + + src_ptr = src; + dst_ptr = dst; + for (y = 0; y < dst_h; y++) + { + src_ptr = src + (y * src_w * 2); + src_ptr2 = src_ptr + src_w; + for (x = 0; x < dst_w; x++) + { + R_VAL(dst_ptr) = (R_VAL(src_ptr) + R_VAL(src_ptr2)) >> 1; + G_VAL(dst_ptr) = (G_VAL(src_ptr) + G_VAL(src_ptr2)) >> 1; + B_VAL(dst_ptr) = (B_VAL(src_ptr) + B_VAL(src_ptr2)) >> 1; + A_VAL(dst_ptr) = (A_VAL(src_ptr) + A_VAL(src_ptr2)) >> 1; + + src_ptr+=2; + src_ptr2+=2; + dst_ptr++; + } + } +} +#endif +#endif + +#ifdef BUILD_SCALE_SMOOTH +#ifdef BUILD_C +EAPI void +evas_common_scale_rgb_mipmap_down_2x2_c(DATA32 *src, DATA32 *dst, int src_w, int src_h) +{ + int x, y, dst_w, dst_h; + DATA32 *src_ptr, *src_ptr2, *dst_ptr; + + dst_w = src_w >> 1; + dst_h = src_h >> 1; + + if (dst_w < 1) dst_w = 1; + if (dst_h < 1) dst_h = 1; + + src_ptr = src; + src_ptr2 = src + src_w; + dst_ptr = dst; + for (y = 0; y < dst_h; y++) + { + for (x = 0; x < dst_w; x++) + { + R_VAL(dst_ptr) = (R_VAL(src_ptr) + R_VAL(src_ptr + 1) + R_VAL(src_ptr2) + R_VAL(src_ptr2 + 1)) >> 2; + G_VAL(dst_ptr) = (G_VAL(src_ptr) + G_VAL(src_ptr + 1) + G_VAL(src_ptr2) + G_VAL(src_ptr2 + 1)) >> 2; + B_VAL(dst_ptr) = (B_VAL(src_ptr) + B_VAL(src_ptr + 1) + B_VAL(src_ptr2) + B_VAL(src_ptr2 + 1)) >> 2; + A_VAL(dst_ptr) = 0xff; + + src_ptr+=2; + src_ptr2+=2; + dst_ptr++; + } + src_ptr += src_w; + src_ptr2 += src_w; + } +} +#endif +#endif + +#ifdef BUILD_SCALE_SMOOTH +#ifdef BUILD_C +EAPI void +evas_common_scale_rgb_mipmap_down_2x1_c(DATA32 *src, DATA32 *dst, int src_w, int src_h) +{ + int x, y, dst_w, dst_h; + DATA32 *src_ptr, *dst_ptr; + + dst_w = src_w >> 1; + dst_h = src_h >> 1; + + if (dst_w < 1) dst_w = 1; + if (dst_h < 1) dst_h = 1; + + src_ptr = src; + dst_ptr = dst; + for (y = 0; y < dst_h; y++) + { + for (x = 0; x < dst_w; x++) + { + R_VAL(dst_ptr) = (R_VAL(src_ptr) + R_VAL(src_ptr + 1)) >> 1; + G_VAL(dst_ptr) = (G_VAL(src_ptr) + G_VAL(src_ptr + 1)) >> 1; + B_VAL(dst_ptr) = (B_VAL(src_ptr) + B_VAL(src_ptr + 1)) >> 1; + A_VAL(dst_ptr) = 0xff; + + src_ptr+=2; + dst_ptr++; + } + src_ptr += src_w; + } +} +#endif +#endif + +#ifdef BUILD_SCALE_SMOOTH +#ifdef BUILD_C +EAPI void +evas_common_scale_rgb_mipmap_down_1x2_c(DATA32 *src, DATA32 *dst, int src_w, int src_h) +{ + int x, y, dst_w, dst_h; + DATA32 *src_ptr, *src_ptr2, *dst_ptr; + + dst_w = src_w >> 1; + dst_h = src_h >> 1; + + if (dst_w < 1) dst_w = 1; + if (dst_h < 1) dst_h = 1; + + src_ptr = src; + src_ptr2 = src + src_w; + dst_ptr = dst; + for (y = 0; y < dst_h; y++) + { + for (x = 0; x < dst_w; x++) + { + R_VAL(dst_ptr) = (R_VAL(src_ptr) + R_VAL(src_ptr2)) >> 1; + G_VAL(dst_ptr) = (G_VAL(src_ptr) + G_VAL(src_ptr2)) >> 1; + B_VAL(dst_ptr) = (B_VAL(src_ptr) + B_VAL(src_ptr2)) >> 1; + A_VAL(dst_ptr) = 0xff; + + src_ptr+=2; + src_ptr2+=2; + dst_ptr++; + } + src_ptr += src_w; + src_ptr2 += src_w; + } +} +#endif +#endif + +#ifdef BUILD_SCALE_SMOOTH +#ifdef BUILD_MMX +EAPI void +evas_common_scale_rgba_mipmap_down_2x2_mmx(DATA32 *src, DATA32 *dst, int src_w, int src_h) +{ + int x, y, dst_w, dst_h; + DATA32 *src_ptr, *src_ptr2, *dst_ptr; + + dst_w = src_w >> 1; + dst_h = src_h >> 1; + + if (dst_w < 1) dst_w = 1; + if (dst_h < 1) dst_h = 1; + + /* NB: Dead assignments (reassigned to different values below) + src_ptr = src; + src_ptr2 = src + src_w; + */ + + dst_ptr = dst; + for (y = 0; y < dst_h; y++) + { + src_ptr = src + (y * src_w * 2); + src_ptr2 = src_ptr + src_w; + for (x = 0; x < dst_w; x++) + { + punpcklbw_m2r(src_ptr[0], mm0); + punpcklbw_m2r(src_ptr[1], mm1); + punpcklbw_m2r(src_ptr2[0], mm2); + punpcklbw_m2r(src_ptr2[1], mm3); + psrlw_i2r(8, mm0); + psrlw_i2r(8, mm1); + psrlw_i2r(8, mm2); + psrlw_i2r(8, mm3); + paddw_r2r(mm1, mm0); + paddw_r2r(mm2, mm0); + paddw_r2r(mm3, mm0); + psrlw_i2r(2, mm0); + packuswb_r2r(mm0, mm0); + movd_r2m(mm0, dst_ptr[0]); + + src_ptr+=2; + src_ptr2+=2; + dst_ptr++; + } + } +} +#endif +#endif + +#ifdef BUILD_SCALE_SMOOTH +#ifdef BUILD_MMX +EAPI void +evas_common_scale_rgba_mipmap_down_2x1_mmx(DATA32 *src, DATA32 *dst, int src_w, int src_h) +{ + int x, y, dst_w, dst_h; + DATA32 *src_ptr, *dst_ptr; + + dst_w = src_w >> 1; + dst_h = src_h >> 1; + + if (dst_w < 1) dst_w = 1; + if (dst_h < 1) dst_h = 1; + + src_ptr = src; + dst_ptr = dst; + for (y = 0; y < dst_h; y++) + { + src_ptr = src + (y * src_w * 2); + for (x = 0; x < dst_w; x++) + { + punpcklbw_m2r(src_ptr[0], mm0); + punpcklbw_m2r(src_ptr[1], mm1); + psrlw_i2r(8, mm0); + psrlw_i2r(8, mm1); + paddw_r2r(mm1, mm0); + psrlw_i2r(1, mm0); + packuswb_r2r(mm0, mm0); + movd_r2m(mm0, dst_ptr[0]); + + src_ptr+=2; + dst_ptr++; + } + } +} +#endif +#endif + +#ifdef BUILD_SCALE_SMOOTH +#ifdef BUILD_MMX +EAPI void +evas_common_scale_rgba_mipmap_down_1x2_mmx(DATA32 *src, DATA32 *dst, int src_w, int src_h) +{ + int x, y, dst_w, dst_h; + DATA32 *src_ptr, *src_ptr2, *dst_ptr; + + dst_w = src_w >> 1; + dst_h = src_h >> 1; + + if (dst_w < 1) dst_w = 1; + if (dst_h < 1) dst_h = 1; + + /* NB: Dead assignment (gets reassigned later) */ +// src_ptr = src; + + src_ptr2 = src + src_w; + dst_ptr = dst; + for (y = 0; y < dst_h; y++) + { + src_ptr = src + (y * src_w * 2); + src_ptr2 = src_ptr + src_w; + for (x = 0; x < dst_w; x++) + { + punpcklbw_m2r(src_ptr[0], mm0); + punpcklbw_m2r(src_ptr2[0], mm1); + psrlw_i2r(8, mm0); + psrlw_i2r(8, mm1); + paddw_r2r(mm1, mm0); + psrlw_i2r(1, mm0); + packuswb_r2r(mm0, mm0); + movd_r2m(mm0, dst_ptr[0]); + + src_ptr+=2; + src_ptr2+=2; + dst_ptr++; + } + } +} +#endif +#endif + +#ifdef BUILD_SCALE_SMOOTH +# ifdef BUILD_MMX +# undef SCALE_FUNC +# define SCALE_FUNC evas_common_scale_rgba_in_to_out_clip_smooth_mmx +# undef SCALE_USING_MMX +# define SCALE_USING_MMX +# include "evas_scale_smooth_scaler.c" +# endif +# ifdef BUILD_C +# undef SCALE_FUNC +# define SCALE_FUNC evas_common_scale_rgba_in_to_out_clip_smooth_c +# undef SCALE_USING_MMX +# include "evas_scale_smooth_scaler.c" +# endif +EAPI void +evas_common_scale_rgba_in_to_out_clip_smooth(RGBA_Image *src, RGBA_Image *dst, + RGBA_Draw_Context *dc, + int src_region_x, int src_region_y, + int src_region_w, int src_region_h, + int dst_region_x, int dst_region_y, + int dst_region_w, int dst_region_h) +{ +# ifdef BUILD_MMX + int mmx, sse, sse2; +# endif + Cutout_Rects *rects; + Cutout_Rect *r; + int c, cx, cy, cw, ch; + int i; + /* handle cutouts here! */ + + if ((dst_region_w <= 0) || (dst_region_h <= 0)) return; + 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))) + return; +# ifdef BUILD_MMX + evas_common_cpu_can_do(&mmx, &sse, &sse2); +# endif + /* no cutouts - cut right to the chase */ + if (!dc->cutout.rects) + { +# ifdef BUILD_MMX + if (mmx) + evas_common_scale_rgba_in_to_out_clip_smooth_mmx(src, dst, dc, + src_region_x, src_region_y, + src_region_w, src_region_h, + dst_region_x, dst_region_y, + dst_region_w, dst_region_h); + else +# endif +# ifdef BUILD_C + evas_common_scale_rgba_in_to_out_clip_smooth_c(src, dst, dc, + src_region_x, src_region_y, + src_region_w, src_region_h, + dst_region_x, dst_region_y, + dst_region_w, dst_region_h); +# endif + return; + } + /* save out clip info */ + c = dc->clip.use; cx = dc->clip.x; cy = dc->clip.y; cw = dc->clip.w; ch = dc->clip.h; + evas_common_draw_context_clip_clip(dc, 0, 0, dst->cache_entry.w, dst->cache_entry.h); + evas_common_draw_context_clip_clip(dc, dst_region_x, dst_region_y, dst_region_w, dst_region_h); + /* our clip is 0 size.. abort */ + if ((dc->clip.w <= 0) || (dc->clip.h <= 0)) + { + dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch; + return; + } + rects = evas_common_draw_context_apply_cutouts(dc); + for (i = 0; i < rects->active; ++i) + { + r = rects->rects + i; + evas_common_draw_context_set_clip(dc, r->x, r->y, r->w, r->h); +# ifdef BUILD_MMX + if (mmx) + evas_common_scale_rgba_in_to_out_clip_smooth_mmx(src, dst, dc, + src_region_x, src_region_y, + src_region_w, src_region_h, + dst_region_x, dst_region_y, + dst_region_w, dst_region_h); + else +# endif +# ifdef BUILD_C + evas_common_scale_rgba_in_to_out_clip_smooth_c(src, dst, dc, + src_region_x, src_region_y, + src_region_w, src_region_h, + dst_region_x, dst_region_y, + dst_region_w, dst_region_h); +# endif + } + evas_common_draw_context_apply_clear_cutouts(rects); + /* restore clip info */ + dc->clip.use = c; dc->clip.x = cx; dc->clip.y = cy; dc->clip.w = cw; dc->clip.h = ch; +} +#endif -- cgit v1.1