From 0bde1e25a1de46b1e494f5e924deba84e103cf9c Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Sat, 12 Feb 2011 14:50:25 +0000 Subject: [PATCH] fix silly sized scaling issue. SVN revision: 56962 --- legacy/evas/ChangeLog | 10 ++++ .../lib/engines/common/evas_scale_smooth.c | 53 +++++++++++-------- .../engines/common/evas_scale_smooth_scaler.c | 6 +++ .../common/evas_scale_smooth_scaler_down.c | 25 ++++----- .../common/evas_scale_smooth_scaler_downx.c | 20 +++---- .../evas_scale_smooth_scaler_downx_downy.c | 20 +++---- .../common/evas_scale_smooth_scaler_downy.c | 20 +++---- 7 files changed, 89 insertions(+), 65 deletions(-) diff --git a/legacy/evas/ChangeLog b/legacy/evas/ChangeLog index 79ada457bd..e3a3972a22 100644 --- a/legacy/evas/ChangeLog +++ b/legacy/evas/ChangeLog @@ -64,3 +64,13 @@ normal image cache to avoid excess texture uploads when cycling images often. Should improve performance in some cases. + +2011-02-12 Carsten Haitzler (The Rasterman) + + * Fix "rediculous scaling size" bug, where scaling images to + sizes like 1 billion pixels high or wide caused evas to try + allocate scaletables on the stack and the stack just couldn't + handle it. Now it only allocates a table for the visible + region which will always be sane, and even has insanity + checks now. At worst you'll get an unrendered image if the + values are silly and some slowness. No crashes. diff --git a/legacy/evas/src/lib/engines/common/evas_scale_smooth.c b/legacy/evas/src/lib/engines/common/evas_scale_smooth.c index 00d32433c6..b8f392b707 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_smooth.c +++ b/legacy/evas/src/lib/engines/common/evas_scale_smooth.c @@ -2,24 +2,24 @@ #include "evas_scale_smooth.h" #include "evas_blend_private.h" -#define SCALE_CALC_X_POINTS(P, SW, DW) \ - P = alloca((DW + 1) * sizeof (int)); \ - scale_calc_x_points(P, SW, DW); +#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) \ - P = alloca((DH + 1) * sizeof (DATA32 *)); \ - scale_calc_y_points(P, SRC, SW, SH, DH); +#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) \ - P = alloca(D * sizeof (int)); \ - scale_calc_a_points(P, S, D); +#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); -static void scale_calc_x_points(int *p, int sw, int dw); -static void scale_calc_a_points(int *p, int s, int d); +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) +scale_calc_y_points(DATA32** p, DATA32 *src, int sw, int sh, int dh, int cy, int ch) { int i, val, inc; @@ -27,14 +27,16 @@ scale_calc_y_points(DATA32** p, DATA32 *src, int sw, int sh, int dh) inc = (sh << 16) / dh; for (i = 0; i < dh; i++) { - p[i] = src + ((val >> 16) * sw); + if ((i >= cy) && (i < (cy + ch))) + p[i - cy] = src + ((val >> 16) * sw); val += inc; } - p[i] = p[i - 1]; + 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) +scale_calc_x_points(int *p, int sw, int dw, int cx, int cw) { int i, val, inc; @@ -42,14 +44,16 @@ scale_calc_x_points(int *p, int sw, int dw) inc = (sw << 16) / dw; for (i = 0; i < dw; i++) { - p[i] = val >> 16; + if ((i >= cx) && (i < (cx + cw))) + p[i - cx] = val >> 16; val += inc; } - p[i] = p[i - 1]; + 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) +scale_calc_a_points(int *p, int s, int d, int c, int cc) { int i, val, inc; @@ -59,8 +63,11 @@ scale_calc_a_points(int *p, int s, int d) inc = (s << 16) / d; for (i = 0; i < d; i++) { - p[i] = (val >> 8) - ((val >> 8) & 0xffffff00); - if ((val >> 16) >= (s - 1)) p[i] = 0; + 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; } } @@ -74,11 +81,11 @@ scale_calc_a_points(int *p, int s, int d) for (i = 0; i < d; i++) { ap = ((0x100 - ((val >> 8) & 0xff)) * Cp) >> 8; - p[i] = ap | (Cp << 16); + if ((i >= c) && (i < (c + cc))) + p[i - c] = ap | (Cp << 16); val += inc; } } -// sleep(1); } #ifdef BUILD_SCALE_SMOOTH diff --git a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler.c b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler.c index d11941186c..599bfda9fd 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler.c +++ b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler.c @@ -136,6 +136,12 @@ SCALE_FUNC(RGBA_Image *src, RGBA_Image *dst, } if (dst_clip_h <= 0) return; + /* some maximum region sizes to avoid insane calc point tables */ + if (dst_clip_w > 65536) return; + if (dst_clip_h > 65536) return; + if (dst_region_w > (65536 * 1024)) return; + if (dst_region_h > (65536 * 1024)) return; + /* figure out dst jump * NB: Unused currently, so commented out */ // dst_jump = dst_w - dst_clip_w; diff --git a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_down.c b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_down.c index 859f2f38df..357eb322ca 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_down.c +++ b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_down.c @@ -8,20 +8,21 @@ RGBA_Gfx_Func func; src_data = src->image.data; - - SCALE_CALC_X_POINTS(xpoints, src_region_w, dst_region_w); - SCALE_CALC_Y_POINTS(ypoints, src_data, src_w, src_region_h, dst_region_h); - SCALE_CALC_A_POINTS(xapoints, src_region_w, dst_region_w); - SCALE_CALC_A_POINTS(yapoints, src_region_h, dst_region_h); - + + /* some maximum region sizes to avoid insane calc point tables */ + SCALE_CALC_X_POINTS(xpoints, src_region_w, dst_region_w, dst_clip_x - dst_region_x, dst_clip_w); + SCALE_CALC_Y_POINTS(ypoints, src_data, src_w, src_region_h, dst_region_h, dst_clip_y - dst_region_y, dst_clip_h); + SCALE_CALC_A_POINTS(xapoints, src_region_w, dst_region_w, dst_clip_x - dst_region_x, dst_clip_w); + SCALE_CALC_A_POINTS(yapoints, src_region_h, dst_region_h, dst_clip_y - dst_region_y, dst_clip_h); + /* a scanline buffer */ buf = alloca(dst_clip_w * sizeof(DATA32)); - + if (dc->mul.use) - func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, dst_clip_w, dc->render_op); + func = evas_common_gfx_func_composite_pixel_color_span_get(src, dc->mul.col, dst, dst_clip_w, dc->render_op); else - func = evas_common_gfx_func_composite_pixel_span_get(src, dst, dst_clip_w, dc->render_op); - /* scaling down vertically */ + func = evas_common_gfx_func_composite_pixel_span_get(src, dst, dst_clip_w, dc->render_op); + /* scaling down vertically */ if ((dst_region_w >= src_region_w) && (dst_region_h < src_region_h)) { @@ -29,13 +30,13 @@ } /* scaling down horizontally */ else if ((dst_region_w < src_region_w) && - (dst_region_h >= src_region_h)) + (dst_region_h >= src_region_h)) { #include "evas_scale_smooth_scaler_downx.c" } /* scaling down both vertically & horizontally */ else if ((dst_region_w < src_region_w) && - (dst_region_h < src_region_h)) + (dst_region_h < src_region_h)) { #include "evas_scale_smooth_scaler_downx_downy.c" } diff --git a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downx.c b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downx.c index 466135fd5a..50b2e5c20f 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downx.c +++ b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downx.c @@ -14,10 +14,10 @@ dyy = dst_clip_y - dst_region_y; dxx = dst_clip_x - dst_region_x; - xp = xpoints + dxx; - yp = ypoints + dyy; - xapp = xapoints + dxx; - yapp = yapoints + dyy; + xp = xpoints;// + dxx; + yp = ypoints;// + dyy; + xapp = xapoints;// + dxx; + yapp = yapoints;// + dyy; pbuf = buf; if (src->cache_entry.flags.alpha) @@ -97,8 +97,8 @@ pbuf = buf; dptr += dst_w; dst_clip_w = w; yp++; yapp++; - xp = xpoints + dxx; - xapp = xapoints + dxx; + xp = xpoints;// + dxx; + xapp = xapoints;// + dxx; } } else @@ -175,8 +175,8 @@ dptr += dst_w; dst_clip_w = w; yp++; yapp++; - xp = xpoints + dxx; - xapp = xapoints + dxx; + xp = xpoints;// + dxx; + xapp = xapoints;// + dxx; } } else @@ -251,8 +251,8 @@ pbuf = buf; dptr += dst_w; dst_clip_w = w; yp++; yapp++; - xp = xpoints + dxx; - xapp = xapoints + dxx; + xp = xpoints;// + dxx; + xapp = xapoints;// + dxx; } } } diff --git a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downx_downy.c b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downx_downy.c index bfe47d71d2..ab0c74ecaa 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downx_downy.c +++ b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downx_downy.c @@ -17,10 +17,10 @@ dyy = dst_clip_y - dst_region_y; dxx = dst_clip_x - dst_region_x; - xp = xpoints + dxx; - yp = ypoints + dyy; - xapp = xapoints + dxx; - yapp = yapoints + dyy; + xp = xpoints;// + dxx; + yp = ypoints;// + dyy; + xapp = xapoints;// + dxx; + yapp = yapoints;// + dyy; pbuf = buf; /*#ifndef SCALE_USING_MMX */ /* for now there's no mmx down scaling - so C only */ @@ -145,8 +145,8 @@ #endif pbuf = buf; dptr += dst_w; dst_clip_w = w; - xp = xpoints + dxx; - xapp = xapoints + dxx; + xp = xpoints;// + dxx; + xapp = xapoints;// + dxx; yp++; yapp++; } } @@ -261,8 +261,8 @@ ysli++; #endif dptr += dst_w; dst_clip_w = w; - xp = xpoints + dxx; - xapp = xapoints + dxx; + xp = xpoints;// + dxx; + xapp = xapoints;// + dxx; yp++; yapp++; } } @@ -375,8 +375,8 @@ #endif pbuf = buf; dptr += dst_w; dst_clip_w = w; - xp = xpoints + dxx; - xapp = xapoints + dxx; + xp = xpoints;// + dxx; + xapp = xapoints;// + dxx; yp++; yapp++; } } diff --git a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downy.c b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downy.c index a6cf34cb84..4c5448e271 100644 --- a/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downy.c +++ b/legacy/evas/src/lib/engines/common/evas_scale_smooth_scaler_downy.c @@ -14,10 +14,10 @@ dyy = dst_clip_y - dst_region_y; dxx = dst_clip_x - dst_region_x; - xp = xpoints + dxx; - yp = ypoints + dyy; - xapp = xapoints + dxx; - yapp = yapoints + dyy; + xp = xpoints;// + dxx; + yp = ypoints;// + dyy; + xapp = xapoints;// + dxx; + yapp = yapoints;// + dyy; pbuf = buf; if (src->cache_entry.flags.alpha) @@ -98,8 +98,8 @@ pbuf = buf; dptr += dst_w; dst_clip_w = w; yp++; yapp++; - xp = xpoints + dxx; - xapp = xapoints + dxx; + xp = xpoints;// + dxx; + xapp = xapoints;// + dxx; } } else @@ -176,8 +176,8 @@ #endif dptr += dst_w; dst_clip_w = w; yp++; yapp++; - xp = xpoints + dxx; - xapp = xapoints + dxx; + xp = xpoints;// + dxx; + xapp = xapoints;// + dxx; } } else @@ -252,8 +252,8 @@ pbuf = buf; dptr += dst_w; dst_clip_w = w; yp++; yapp++; - xp = xpoints + dxx; - xapp = xapoints + dxx; + xp = xpoints;// + dxx; + xapp = xapoints;// + dxx; } } }