fix silly sized scaling issue.

SVN revision: 56962
This commit is contained in:
Carsten Haitzler 2011-02-12 14:50:25 +00:00
parent d22176c22d
commit 0bde1e25a1
7 changed files with 89 additions and 65 deletions

View File

@ -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.

View File

@ -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

View File

@ -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;

View File

@ -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"
}

View File

@ -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;
}
}
}

View File

@ -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++;
}
}

View File

@ -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;
}
}
}