summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2014-02-14 16:50:31 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2014-02-17 10:14:11 +0900
commit7cc7af14b8016c74f05759cbbd0e3bc8e37302a5 (patch)
treef1da837f1db7d33f67918e28d9fd448c6c9c5487
parent9472e035461dd42a533cf893362063bb95811f34 (diff)
Evas filters: Fix alpha in displacement filter
If the displacement map has some alpha values (not 0xFF), then the blending should take this alpha into account. This part is fine. BUT, since Evas relies on premultiplied colors... we have a problem: R (dx) and G (dy) have already been scaled down. Actually we would need to load the map in non premultiplied RGBA, otherwise we'll lose precision on dx,dy as soon as A != 0xFF. Well... I guess this will be a limitation of this filter, for now at least. Most displacement maps shouldn't even have any alpha anyways.
-rw-r--r--src/lib/evas/filters/evas_filter_displace.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/src/lib/evas/filters/evas_filter_displace.c b/src/lib/evas/filters/evas_filter_displace.c
index 994cbe990a..362da634e9 100644
--- a/src/lib/evas/filters/evas_filter_displace.c
+++ b/src/lib/evas/filters/evas_filter_displace.c
@@ -77,20 +77,20 @@ _filter_displace_cpu_alpha_do(int w, int h, int map_w, int map_h, int intensity,
77 77
78static void 78static void
79_filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity, 79_filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
80 DATA32 *src, DATA32 *dst, DATA8 *map_start, 80 DATA32 *src, DATA32 *dst, DATA32 *map_start,
81 Eina_Bool stretch, Eina_Bool smooth, 81 Eina_Bool stretch, Eina_Bool smooth,
82 Eina_Bool blend) 82 Eina_Bool blend)
83{ 83{
84 int x, y, map_x, map_y; 84 int x, y, map_x, map_y;
85 const int map_stride = sizeof(DATA32) * map_w;
86 const int dx = RED; 85 const int dx = RED;
87 const int dy = GREEN; 86 const int dy = GREEN;
87 Eina_Bool unpremul = EINA_FALSE;
88 DATA8 *map; 88 DATA8 *map;
89 89
90 for (y = 0, map_y = 0; y < h; y++, map_y++) 90 for (y = 0, map_y = 0; y < h; y++, map_y++)
91 { 91 {
92 if (map_y >= map_h) map_y = 0; 92 if (map_y >= map_h) map_y = 0;
93 map = map_start + (map_y * map_stride); 93 map = (DATA8 *) (map_start + map_y * map_w);
94 94
95 for (x = 0, map_x = 0; x < w; x++, dst++, src++, map_x++) 95 for (x = 0, map_x = 0; x < w; x++, dst++, src++, map_x++)
96 { 96 {
@@ -102,10 +102,17 @@ _filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
102 if (map_x >= map_w) 102 if (map_x >= map_w)
103 { 103 {
104 map_x = 0; 104 map_x = 0;
105 map = map_start + (map_y * map_stride); 105 map = (DATA8 *) (map_start + map_y * map_w);
106 } 106 }
107 else map += sizeof(DATA32); 107 else map += sizeof(DATA32);
108 108
109 if (!map[ALPHA]) continue;
110 if (!unpremul && map[ALPHA] != 0xFF)
111 {
112 unpremul = EINA_TRUE;
113 evas_data_argb_unpremul(map_start, map_w * map_h);
114 }
115
109 // x 116 // x
110 val = ((int) map[dx] - 128) * intensity; 117 val = ((int) map[dx] - 128) * intensity;
111 offx = val >> 7; 118 offx = val >> 7;
@@ -173,6 +180,9 @@ _filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
173 *dst = col; 180 *dst = col;
174 } 181 }
175 } 182 }
183
184 if (unpremul)
185 evas_data_argb_premul(map_start, map_w * map_h);
176} 186}
177 187
178/** 188/**
@@ -226,8 +236,7 @@ static Eina_Bool
226_filter_displace_cpu_rgba(Evas_Filter_Command *cmd) 236_filter_displace_cpu_rgba(Evas_Filter_Command *cmd)
227{ 237{
228 int w, h, map_w, map_h, intensity; 238 int w, h, map_w, map_h, intensity;
229 DATA32 *dst, *src; 239 DATA32 *dst, *src, *map_start;
230 DATA8 *map_start;
231 Eina_Bool stretch, smooth, blend; 240 Eina_Bool stretch, smooth, blend;
232 241
233 w = cmd->input->w; 242 w = cmd->input->w;
@@ -239,7 +248,7 @@ _filter_displace_cpu_rgba(Evas_Filter_Command *cmd)
239 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE); 248 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
240 249
241 src = ((RGBA_Image *) cmd->input->backing)->image.data; 250 src = ((RGBA_Image *) cmd->input->backing)->image.data;
242 map_start = ((RGBA_Image *) cmd->mask->backing)->mask.data; 251 map_start = ((RGBA_Image *) cmd->mask->backing)->image.data;
243 dst = ((RGBA_Image *) cmd->output->backing)->image.data; 252 dst = ((RGBA_Image *) cmd->output->backing)->image.data;
244 EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE); 253 EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
245 EINA_SAFETY_ON_NULL_RETURN_VAL(map_start, EINA_FALSE); 254 EINA_SAFETY_ON_NULL_RETURN_VAL(map_start, EINA_FALSE);