forked from enlightenment/efl
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.
This commit is contained in:
parent
9472e03546
commit
7cc7af14b8
|
@ -77,20 +77,20 @@ _filter_displace_cpu_alpha_do(int w, int h, int map_w, int map_h, int intensity,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
|
_filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
|
||||||
DATA32 *src, DATA32 *dst, DATA8 *map_start,
|
DATA32 *src, DATA32 *dst, DATA32 *map_start,
|
||||||
Eina_Bool stretch, Eina_Bool smooth,
|
Eina_Bool stretch, Eina_Bool smooth,
|
||||||
Eina_Bool blend)
|
Eina_Bool blend)
|
||||||
{
|
{
|
||||||
int x, y, map_x, map_y;
|
int x, y, map_x, map_y;
|
||||||
const int map_stride = sizeof(DATA32) * map_w;
|
|
||||||
const int dx = RED;
|
const int dx = RED;
|
||||||
const int dy = GREEN;
|
const int dy = GREEN;
|
||||||
|
Eina_Bool unpremul = EINA_FALSE;
|
||||||
DATA8 *map;
|
DATA8 *map;
|
||||||
|
|
||||||
for (y = 0, map_y = 0; y < h; y++, map_y++)
|
for (y = 0, map_y = 0; y < h; y++, map_y++)
|
||||||
{
|
{
|
||||||
if (map_y >= map_h) map_y = 0;
|
if (map_y >= map_h) map_y = 0;
|
||||||
map = map_start + (map_y * map_stride);
|
map = (DATA8 *) (map_start + map_y * map_w);
|
||||||
|
|
||||||
for (x = 0, map_x = 0; x < w; x++, dst++, src++, map_x++)
|
for (x = 0, map_x = 0; x < w; x++, dst++, src++, map_x++)
|
||||||
{
|
{
|
||||||
|
@ -102,10 +102,17 @@ _filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
|
||||||
if (map_x >= map_w)
|
if (map_x >= map_w)
|
||||||
{
|
{
|
||||||
map_x = 0;
|
map_x = 0;
|
||||||
map = map_start + (map_y * map_stride);
|
map = (DATA8 *) (map_start + map_y * map_w);
|
||||||
}
|
}
|
||||||
else map += sizeof(DATA32);
|
else map += sizeof(DATA32);
|
||||||
|
|
||||||
|
if (!map[ALPHA]) continue;
|
||||||
|
if (!unpremul && map[ALPHA] != 0xFF)
|
||||||
|
{
|
||||||
|
unpremul = EINA_TRUE;
|
||||||
|
evas_data_argb_unpremul(map_start, map_w * map_h);
|
||||||
|
}
|
||||||
|
|
||||||
// x
|
// x
|
||||||
val = ((int) map[dx] - 128) * intensity;
|
val = ((int) map[dx] - 128) * intensity;
|
||||||
offx = val >> 7;
|
offx = val >> 7;
|
||||||
|
@ -173,6 +180,9 @@ _filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
|
||||||
*dst = col;
|
*dst = col;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (unpremul)
|
||||||
|
evas_data_argb_premul(map_start, map_w * map_h);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -226,8 +236,7 @@ static Eina_Bool
|
||||||
_filter_displace_cpu_rgba(Evas_Filter_Command *cmd)
|
_filter_displace_cpu_rgba(Evas_Filter_Command *cmd)
|
||||||
{
|
{
|
||||||
int w, h, map_w, map_h, intensity;
|
int w, h, map_w, map_h, intensity;
|
||||||
DATA32 *dst, *src;
|
DATA32 *dst, *src, *map_start;
|
||||||
DATA8 *map_start;
|
|
||||||
Eina_Bool stretch, smooth, blend;
|
Eina_Bool stretch, smooth, blend;
|
||||||
|
|
||||||
w = cmd->input->w;
|
w = cmd->input->w;
|
||||||
|
@ -239,7 +248,7 @@ _filter_displace_cpu_rgba(Evas_Filter_Command *cmd)
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
|
||||||
|
|
||||||
src = ((RGBA_Image *) cmd->input->backing)->image.data;
|
src = ((RGBA_Image *) cmd->input->backing)->image.data;
|
||||||
map_start = ((RGBA_Image *) cmd->mask->backing)->mask.data;
|
map_start = ((RGBA_Image *) cmd->mask->backing)->image.data;
|
||||||
dst = ((RGBA_Image *) cmd->output->backing)->image.data;
|
dst = ((RGBA_Image *) cmd->output->backing)->image.data;
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(map_start, EINA_FALSE);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(map_start, EINA_FALSE);
|
||||||
|
|
Loading…
Reference in New Issue