From 431d62d095761eb82236a2e4d65fd62a90bf72c6 Mon Sep 17 00:00:00 2001 From: Shinwoo Kim Date: Mon, 14 Oct 2019 11:13:15 +0900 Subject: [PATCH] evas filter: Implement grayscale filter in SW Summary: Initial version implementing grayscale filter in SW. Test Plan: 1. Create filter_example with following. efl_gfx_filter_program_set(image, "grayscale ()", "grayscale"); 1. Run. ./filter_example Reviewers: Hermet, jsuya Reviewed By: Hermet Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D10219 --- .../evas/software_generic/filters/meson.build | 1 + .../engines/software_generic/evas_engine.c | 1 + .../filters/evas_engine_filter.h | 1 + .../filters/evas_filter_grayscale.c | 62 +++++++++++++++++++ 4 files changed, 65 insertions(+) create mode 100644 src/modules/evas/engines/software_generic/filters/evas_filter_grayscale.c diff --git a/src/lib/evas/software_generic/filters/meson.build b/src/lib/evas/software_generic/filters/meson.build index b23ce09b1d..17c7bce8c2 100644 --- a/src/lib/evas/software_generic/filters/meson.build +++ b/src/lib/evas/software_generic/filters/meson.build @@ -10,6 +10,7 @@ raw_evas_src = [ 'evas_filter_fill.c', 'evas_filter_mask.c', 'evas_filter_transform.c', + 'evas_filter_grayscale.c', ] foreach file : raw_evas_src diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index 0dc6c64b52..085f053b1d 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -4544,6 +4544,7 @@ _gfx_filter_func_get(Evas_Filter_Command *cmd) case EVAS_FILTER_MODE_FILL: func = eng_filter_fill_func_get(cmd); break; case EVAS_FILTER_MODE_MASK: func = eng_filter_mask_func_get(cmd); break; case EVAS_FILTER_MODE_TRANSFORM: func = eng_filter_transform_func_get(cmd); break; + case EVAS_FILTER_MODE_GRAYSCALE: func = eng_filter_grayscale_func_get(cmd); break; default: return NULL; } diff --git a/src/modules/evas/engines/software_generic/filters/evas_engine_filter.h b/src/modules/evas/engines/software_generic/filters/evas_engine_filter.h index f8bfebdc11..33998f9344 100644 --- a/src/modules/evas/engines/software_generic/filters/evas_engine_filter.h +++ b/src/modules/evas/engines/software_generic/filters/evas_engine_filter.h @@ -13,5 +13,6 @@ Software_Filter_Func eng_filter_displace_func_get(Evas_Filter_Command *cmd); Software_Filter_Func eng_filter_fill_func_get(Evas_Filter_Command *cmd); Software_Filter_Func eng_filter_mask_func_get(Evas_Filter_Command *cmd); Software_Filter_Func eng_filter_transform_func_get(Evas_Filter_Command *cmd); +Software_Filter_Func eng_filter_grayscale_func_get(Evas_Filter_Command *cmd); #endif // EVAS_ENGINE_FILTER_H diff --git a/src/modules/evas/engines/software_generic/filters/evas_filter_grayscale.c b/src/modules/evas/engines/software_generic/filters/evas_filter_grayscale.c new file mode 100644 index 0000000000..9384639916 --- /dev/null +++ b/src/modules/evas/engines/software_generic/filters/evas_filter_grayscale.c @@ -0,0 +1,62 @@ +#include "evas_engine_filter.h" + +static Eina_Bool +_evas_filter_grayscale(Evas_Filter_Command *cmd) +{ + int sw, sh, dw, dh, x, y, slen, dlen; + unsigned int src_len, src_stride, dst_len, dst_stride; + Eina_Bool ret = EINA_FALSE; + DATA32 *ts, *td, *src = NULL, *dst = NULL; + DATA8 r, g, b, gry; + + ector_buffer_size_get(cmd->input->buffer, &sw, &sh); + EINA_SAFETY_ON_FALSE_RETURN_VAL((sw > 0) && (sh > 0), ret); + + ector_buffer_size_get(cmd->output->buffer, &dw, &dh); + EINA_SAFETY_ON_FALSE_RETURN_VAL((dw > 0) && (dh > 0), ret); + + src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ARGB, &src_stride); + EINA_SAFETY_ON_FALSE_GOTO(src, end); + + dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ARGB, &dst_stride); + EINA_SAFETY_ON_FALSE_GOTO(dst, end); + + slen = src_stride / sizeof(*src); + dlen = dst_stride / sizeof(*dst); + + ts = src; + td = dst; + for (y = 0; y < sh ; y++) + { + for (x = 0; x < sw; x++) + { + A_VAL(td + x) = A_VAL(ts + x); + r = R_VAL(ts + x); + g = G_VAL(ts + x); + b = B_VAL(ts + x); + + /* formula from evas_common_convert_rgba_to_8bpp_gry_256_dith */ + gry = ((r * 19596) + (g * 38470) + (b * 7472)) >> 16; + R_VAL(td + x) = G_VAL(td + x) = B_VAL(td + x) = gry; + } + ts += slen; + td += dlen; + } + + ret = EINA_TRUE; + +end: + if (src) ector_buffer_unmap(cmd->input->buffer, src, src_len); + if (dst) ector_buffer_unmap(cmd->output->buffer, dst, dst_len); + return ret; +} + +Software_Filter_Func +eng_filter_grayscale_func_get(Evas_Filter_Command *cmd) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL); + + return _evas_filter_grayscale; +}