fix silly sized scaling issue.
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sat, 12 Feb 2011 14:50:25 +0000 (14:50 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Sat, 12 Feb 2011 14:50:25 +0000 (14:50 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@56962 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

ChangeLog
src/lib/engines/common/evas_scale_smooth.c
src/lib/engines/common/evas_scale_smooth_scaler.c
src/lib/engines/common/evas_scale_smooth_scaler_down.c
src/lib/engines/common/evas_scale_smooth_scaler_downx.c
src/lib/engines/common/evas_scale_smooth_scaler_downx_downy.c
src/lib/engines/common/evas_scale_smooth_scaler_downy.c

index 79ada45..e3a3972 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
           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.
index 00d3243..b8f392b 100644 (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
index d119411..599bfda 100644 (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;
index 859f2f3..357eb32 100644 (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))
      {
      }
    /* 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"
      }
index 466135f..50b2e5c 100644 (file)
    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
 
                  dptr += dst_w;  dst_clip_w = w;
                  yp++;  yapp++;
-                 xp = xpoints + dxx;
-                 xapp = xapoints + dxx;
+                 xp = xpoints;// + dxx;
+                 xapp = xapoints;// + dxx;
               }
          }
        else
                  pbuf = buf;
                  dptr += dst_w;  dst_clip_w = w;
                  yp++;  yapp++;
-                 xp = xpoints + dxx;
-                 xapp = xapoints + dxx;
+                 xp = xpoints;// + dxx;
+                 xapp = xapoints;// + dxx;
               }
          }
      }
index bfe47d7..ab0c74e 100644 (file)
    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 */
 #endif
             pbuf = buf;
             dptr += dst_w;   dst_clip_w = w;
-            xp = xpoints + dxx;
-            xapp = xapoints + dxx;
+            xp = xpoints;// + dxx;
+            xapp = xapoints;// + dxx;
             yp++;  yapp++;
          }
      }
                  ysli++;
 #endif
                  dptr += dst_w;   dst_clip_w = w;
-                 xp = xpoints + dxx;
-                 xapp = xapoints + dxx;
+                 xp = xpoints;// + dxx;
+                 xapp = xapoints;// + dxx;
                  yp++;  yapp++;
               }
          }
 #endif
                  pbuf = buf;
                  dptr += dst_w;   dst_clip_w = w;
-                 xp = xpoints + dxx;
-                 xapp = xapoints + dxx;
+                 xp = xpoints;// + dxx;
+                 xapp = xapoints;// + dxx;
                  yp++;  yapp++;
               }
          }
index a6cf34c..4c5448e 100644 (file)
    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
 #endif
                  dptr += dst_w;  dst_clip_w = w;
                  yp++;  yapp++;
-                 xp = xpoints + dxx;
-                 xapp = xapoints + dxx;
+                 xp = xpoints;// + dxx;
+                 xapp = xapoints;// + dxx;
               }
          }
        else
                  pbuf = buf;
                  dptr += dst_w;  dst_clip_w = w;
                  yp++;  yapp++;
-                 xp = xpoints + dxx;
-                 xapp = xapoints + dxx;
+                 xp = xpoints;// + dxx;
+                 xapp = xapoints;// + dxx;
               }
          }
      }