furrymyad pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=4fd1c4f25bcb291d821ba3b02a005b721e689a21

commit 4fd1c4f25bcb291d821ba3b02a005b721e689a21
Author: Vitalii Vorobiov <vi.vorob...@samsung.com>
Date:   Mon Jun 13 15:31:48 2016 +0300

    edje_calc: fix interpolate calculation of map colors
    
    There were a problem when while swithcing between states
    (because of program running in transition),
    there is SIGSEV appearing when first state has
    only one point color, and next state more than one.
    
    Basically it looks like this:
    ....
    part {
       name: "rectangle";
       type: RECT;
       description { state: "default" 0.0;
          map {
             on: 1;
             color: 3 255 90 0 255;
          }
       }
       description { state: "moved" 0.0;
          map {
             on: 1;
             color: 0 0 0 255 255;
             color: 1 255 0 0 255;
             color: 2 255 90 0 255;
             color: 3 41 68 59 255;
          }
       }
    }
    <and program that change 'rectangle' state with transition>
    ....
    
    @fix
---
 src/lib/edje/edje_calc.c | 87 ++++++++++++++++++++++--------------------------
 1 file changed, 40 insertions(+), 47 deletions(-)

diff --git a/src/lib/edje/edje_calc.c b/src/lib/edje/edje_calc.c
index add1e75..6c474de 100644
--- a/src/lib/edje/edje_calc.c
+++ b/src/lib/edje/edje_calc.c
@@ -3572,9 +3572,11 @@ static Eina_Bool
 _map_colors_interp(Edje_Calc_Params *p1, Edje_Calc_Params *p2,
                    Edje_Calc_Params_Map *pmap, FLOAT_T pos)
 {
-   Edje_Map_Color *col, *col2, *col3;
-   int i, j, idx = 0;
-   Eina_Bool matched = EINA_FALSE;
+   Edje_Map_Color *col = NULL, *col2 = NULL, *col3;
+   int i, j;
+
+   unsigned char col1_r = 255, col1_g = 255, col1_b = 255, col1_a = 255;
+   unsigned char col2_r = 255, col2_g = 255, col2_b = 255, col2_a = 255;
 
    if ((p1->map->colors_count > 0) || (p2->map->colors_count > 0))
      {
@@ -3582,59 +3584,50 @@ _map_colors_interp(Edje_Calc_Params *p1, 
Edje_Calc_Params *p2,
 
         pmap->colors = (Edje_Map_Color **)malloc(sizeof(Edje_Map_Color *) * 
(int)pmap->colors_count);
 
-        for (i = 0; i < (int)p1->map->colors_count; i++)
+        /* create all Map Color structs at first
+           to make sure we won't get SIGSEV later on cleanup. */
+        for (i = 0; i < (int)pmap->colors_count; i++)
           {
-             col = p1->map->colors[i];
              col3 = malloc(sizeof(Edje_Map_Color));
-             col3->idx = col->idx;
-
-             for (j = 0; j < (int)p2->map->colors_count; j++)
-               {
-                  col2 = p2->map->colors[j];
-                  if (col->idx != col2->idx) continue;
-                  col3->r = INTP(col->r, col2->r, pos);
-                  col3->g = INTP(col->g, col2->g, pos);
-                  col3->b = INTP(col->b, col2->b, pos);
-                  col3->a = INTP(col->a, col2->a, pos);
-                  pmap->colors[idx] = col3;
-                  matched = EINA_TRUE;
-                  break;
-               }
-             if (!matched)
-               {
-                  col3->r = INTP(col->r, 255, pos);
-                  col3->g = INTP(col->g, 255, pos);
-                  col3->b = INTP(col->b, 255, pos);
-                  col3->a = INTP(col->a, 255, pos);
-                  pmap->colors[idx] = col3;
-               }
-             idx++;
-             matched = EINA_FALSE;
-          }
-        for (i = 0; i < (int)p2->map->colors_count; i++)
-          {
-             col = p2->map->colors[i];
+             col3->idx = i; /* we don't care about index position anyway */
 
+             /* find color with idx from first */
              for (j = 0; j < (int)p1->map->colors_count; j++)
                {
-                  col2 = p1->map->colors[j];
-                  if (col->idx != col2->idx) continue;
-                  matched = EINA_TRUE;
-                  break;
+                  col = p1->map->colors[j];
+                  if (col3->idx == col->idx)
+                    {
+                       col1_r = col->r;
+                       col1_g = col->g;
+                       col1_b = col->b;
+                       col1_a = col->a;
+                       break;
+                    }
                }
-             if (!matched)
+             /* find color from idx from second */
+             for (j = 0; j < (int)p2->map->colors_count; j++)
                {
-                  col3 = malloc(sizeof(Edje_Map_Color));
-                  col3->idx = col->idx;
-                  col3->r = INTP(255, col->r, pos);
-                  col3->g = INTP(255, col->g, pos);
-                  col3->b = INTP(255, col->b, pos);
-                  col3->a = INTP(255, col->a, pos);
-                  pmap->colors[idx] = col3;
+                  col2 = p2->map->colors[j];
+                  if (col3->idx == col2->idx)
+                    {
+                       col2_r = col2->r;
+                       col2_g = col2->g;
+                       col2_b = col2->b;
+                       col2_a = col2->a;
+                       break;
+                    }
                }
-             idx++;
-             matched = EINA_FALSE;
+
+             /* interpolate!
+                if color didn't existed, then there are default 255 values */
+             col3->r = INTP(col1_r, col2_r, pos);
+             col3->g = INTP(col1_g, col2_g, pos);
+             col3->b = INTP(col1_b, col2_b, pos);
+             col3->a = INTP(col1_a, col2_a, pos);
+
+             pmap->colors[i] = col3;
           }
+
         return EINA_TRUE;
      }
 

-- 


Reply via email to