forked from enlightenment/efl
evas filter: Implement inverse color filter
Summary: This is the first version of inverse color filter both GL and SW. Test Plan: 1. Create filter_example with following . efl_gfx_filter_program_set(image, "inverse_color ()", "inverse color"); 2. Run. ./filter_example (Use ELM_ACCEL=gl for GL engine) Reviewers: Hermet, jsuya Reviewed By: Hermet Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D10335
This commit is contained in:
parent
0e6e983808
commit
51169ac325
|
@ -1619,6 +1619,28 @@ evas_filter_command_grayscale_add(Evas_Filter_Context *ctx,
|
|||
return cmd;
|
||||
}
|
||||
|
||||
Evas_Filter_Command *
|
||||
evas_filter_command_inverse_color_add(Evas_Filter_Context *ctx,
|
||||
void *draw_context EINA_UNUSED,
|
||||
int inbuf, int outbuf)
|
||||
{
|
||||
Evas_Filter_Command *cmd;
|
||||
Evas_Filter_Buffer *in, *out;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
|
||||
|
||||
in = _filter_buffer_get(ctx, inbuf);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(in, NULL);
|
||||
|
||||
out = _filter_buffer_get(ctx, outbuf);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(out, NULL);
|
||||
|
||||
cmd = _command_new(ctx, EVAS_FILTER_MODE_INVERSE_COLOR, in, NULL, out);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(out, NULL);
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void
|
||||
evas_filter_context_obscured_region_set(Evas_Filter_Context *ctx, Eina_Rectangle rect)
|
||||
{
|
||||
|
|
|
@ -1809,6 +1809,26 @@ _grayscale_instruction_prepare(Evas_Filter_Program *pgm, Evas_Filter_Instruction
|
|||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
@page evasfiltersref
|
||||
Apply inverse color
|
||||
TODO: write down more information
|
||||
*/
|
||||
|
||||
static Eina_Bool
|
||||
_inverse_color_instruction_prepare(Evas_Filter_Program *pgm, Evas_Filter_Instruction *instr)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(instr, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(instr->name, EINA_FALSE);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(!strcasecmp(instr->name, "inverse_color"), EINA_FALSE);
|
||||
|
||||
instr->type = EVAS_FILTER_MODE_INVERSE_COLOR;
|
||||
_instruction_param_seq_add(instr, "src", VT_BUFFER, _buffer_get(pgm, "input"));
|
||||
_instruction_param_seq_add(instr, "dst", VT_BUFFER, _buffer_get(pgm, "output"));
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static int
|
||||
_padding_set_padding_update(Evas_Filter_Program *pgm,
|
||||
Evas_Filter_Instruction *instr,
|
||||
|
@ -2270,6 +2290,7 @@ LUA_GENERIC_FUNCTION(mask)
|
|||
LUA_GENERIC_FUNCTION(padding_set)
|
||||
LUA_GENERIC_FUNCTION(transform)
|
||||
LUA_GENERIC_FUNCTION(grayscale)
|
||||
LUA_GENERIC_FUNCTION(inverse_color)
|
||||
|
||||
static const luaL_Reg _lua_buffer_metamethods[] = {
|
||||
{ "__call", _lua_buffer_new },
|
||||
|
@ -2507,6 +2528,7 @@ _lua_state_create(Evas_Filter_Program *pgm)
|
|||
PUSH_LUA_FUNCTION(padding_set)
|
||||
PUSH_LUA_FUNCTION(transform)
|
||||
PUSH_LUA_FUNCTION(grayscale)
|
||||
PUSH_LUA_FUNCTION(inverse_color)
|
||||
|
||||
for (unsigned k = 0; k < (sizeof(fill_modes) / sizeof(fill_modes[0])); k++)
|
||||
{
|
||||
|
@ -3439,6 +3461,20 @@ _instr2cmd_grayscale(Evas_Filter_Context *ctx,
|
|||
return evas_filter_command_grayscale_add(ctx, dc, src->cid, dst->cid);
|
||||
}
|
||||
|
||||
static Evas_Filter_Command *
|
||||
_instr2cmd_inverse_color(Evas_Filter_Context *ctx,
|
||||
Evas_Filter_Instruction *instr, void *dc)
|
||||
{
|
||||
Buffer *src, *dst;
|
||||
|
||||
src = _instruction_param_getbuf(instr, "src", NULL);
|
||||
dst = _instruction_param_getbuf(instr, "dst", NULL);
|
||||
INSTR_PARAM_CHECK(src);
|
||||
INSTR_PARAM_CHECK(dst);
|
||||
|
||||
return evas_filter_command_inverse_color_add(ctx, dc, src->cid, dst->cid);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_command_from_instruction(Evas_Filter_Context *ctx,
|
||||
Evas_Filter_Instruction *instr, void *dc)
|
||||
|
@ -3478,6 +3514,9 @@ _command_from_instruction(Evas_Filter_Context *ctx,
|
|||
case EVAS_FILTER_MODE_GRAYSCALE:
|
||||
instr2cmd = _instr2cmd_grayscale;
|
||||
break;
|
||||
case EVAS_FILTER_MODE_INVERSE_COLOR:
|
||||
instr2cmd = _instr2cmd_inverse_color;
|
||||
break;
|
||||
case EVAS_FILTER_MODE_PADDING_SET:
|
||||
case EVAS_FILTER_MODE_BUFFER:
|
||||
return EINA_TRUE;
|
||||
|
|
|
@ -70,6 +70,7 @@ enum _Evas_Filter_Mode
|
|||
EVAS_FILTER_MODE_TRANSFORM, /**< Apply a simple geometrical transformation */
|
||||
EVAS_FILTER_MODE_PADDING_SET, /**< Special padding_set instruction to force a specific padding value */
|
||||
EVAS_FILTER_MODE_GRAYSCALE, /**< Leave only grayscale information */
|
||||
EVAS_FILTER_MODE_INVERSE_COLOR,/**< Apply inverse color */
|
||||
EVAS_FILTER_MODE_LAST
|
||||
};
|
||||
|
||||
|
@ -318,6 +319,17 @@ Evas_Filter_Command *evas_filter_command_transform_add(Evas_Filter_Context *
|
|||
*/
|
||||
Evas_Filter_Command *evas_filter_command_grayscale_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf);
|
||||
|
||||
/**
|
||||
* @brief Apply inverse color of the buffer
|
||||
* @param ctx Current filter chain
|
||||
* @param draw_context Current Evas draw context (ignored)
|
||||
* @param inbuf Input buffer (Alpha or RGBA)
|
||||
* @param outbuf Output buffer (Alpha or RGBA), same size as inbuf
|
||||
* @return Filter command or NULL in case of error
|
||||
* @internal
|
||||
*/
|
||||
Evas_Filter_Command *evas_filter_command_inverse_color_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf);
|
||||
|
||||
/* Simple binding between a filter object and its sources */
|
||||
struct _Evas_Filter_Proxy_Binding
|
||||
{
|
||||
|
|
|
@ -11,6 +11,7 @@ raw_evas_src = [
|
|||
'evas_filter_mask.c',
|
||||
'evas_filter_transform.c',
|
||||
'evas_filter_grayscale.c',
|
||||
'evas_filter_inverse_color.c',
|
||||
]
|
||||
|
||||
foreach file : raw_evas_src
|
||||
|
|
|
@ -266,7 +266,8 @@ enum _Shader_Type {
|
|||
SHD_FILTER_CURVE,
|
||||
SHD_FILTER_BLUR_X,
|
||||
SHD_FILTER_BLUR_Y,
|
||||
SHD_FILTER_GRAYSCALE
|
||||
SHD_FILTER_GRAYSCALE,
|
||||
SHD_FILTER_INVERSE_COLOR
|
||||
};
|
||||
|
||||
#define ARRAY_BUFFER_USE 500
|
||||
|
@ -682,6 +683,7 @@ void evas_gl_common_filter_blur_push(Evas_Engine_GL_Context *gc, Ev
|
|||
double dx, double dy, double dw, double dh, const double * const values, const double * const offsets, int count, double radius,
|
||||
Eina_Bool horiz, Eina_Bool alphaonly);
|
||||
void evas_gl_common_filter_grayscale_push(Evas_Engine_GL_Context *gc, Evas_GL_Texture *tex, int x, int y, int w, int h);
|
||||
void evas_gl_common_filter_inverse_color_push(Evas_Engine_GL_Context *gc, Evas_GL_Texture *tex, int x, int y, int w, int h);
|
||||
|
||||
int evas_gl_common_shader_program_init(Evas_GL_Shared *shared);
|
||||
void evas_gl_common_shader_program_shutdown(Evas_GL_Shared *shared);
|
||||
|
|
|
@ -3771,6 +3771,99 @@ evas_gl_common_filter_grayscale_push(Evas_Engine_GL_Context *gc,
|
|||
if (!nomul)
|
||||
PUSH_6_COLORS(pn, r, g, b, a);
|
||||
}
|
||||
|
||||
void
|
||||
evas_gl_common_filter_inverse_color_push(Evas_Engine_GL_Context *gc,
|
||||
Evas_GL_Texture *tex,
|
||||
int x, int y, int w, int h)
|
||||
{
|
||||
double ox1, oy1, ox2, oy2, ox3, oy3, ox4, oy4, pw, ph;
|
||||
GLfloat tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4;
|
||||
GLfloat offsetx, offsety;
|
||||
int r, g, b, a, nomul = 0, pn;
|
||||
Evas_GL_Program *prog;
|
||||
Eina_Bool blend = EINA_TRUE;
|
||||
Eina_Bool smooth = EINA_TRUE;
|
||||
Shader_Type type = SHD_FILTER_INVERSE_COLOR;
|
||||
|
||||
r = R_VAL(&gc->dc->mul.col);
|
||||
g = G_VAL(&gc->dc->mul.col);
|
||||
b = B_VAL(&gc->dc->mul.col);
|
||||
a = A_VAL(&gc->dc->mul.col);
|
||||
if (gc->dc->render_op == EVAS_RENDER_COPY)
|
||||
blend = EINA_FALSE;
|
||||
|
||||
prog = evas_gl_common_shader_program_get(gc, type, NULL, 0, r, g, b, a,
|
||||
w, h, w, h, smooth, tex, EINA_FALSE,
|
||||
NULL, EINA_FALSE, EINA_FALSE, 0, 0,
|
||||
EINA_FALSE, NULL, &nomul, NULL);
|
||||
|
||||
_filter_data_flush(gc, prog);
|
||||
EINA_SAFETY_ON_NULL_RETURN(prog);
|
||||
|
||||
pn = _evas_gl_common_context_push(type, gc, tex, NULL, prog,
|
||||
x, y, w, h, blend, smooth,
|
||||
0, 0, 0, 0, 0, EINA_FALSE);
|
||||
|
||||
gc->pipe[pn].region.type = type;
|
||||
gc->pipe[pn].shader.prog = prog;
|
||||
gc->pipe[pn].shader.cur_tex = tex->pt->texture;
|
||||
gc->pipe[pn].shader.cur_texm = 0;
|
||||
gc->pipe[pn].shader.tex_target = GL_TEXTURE_2D;
|
||||
gc->pipe[pn].shader.smooth = smooth;
|
||||
gc->pipe[pn].shader.mask_smooth = 0;
|
||||
gc->pipe[pn].shader.blend = blend;
|
||||
gc->pipe[pn].shader.render_op = gc->dc->render_op;
|
||||
gc->pipe[pn].shader.clip = 0;
|
||||
gc->pipe[pn].shader.cx = 0;
|
||||
gc->pipe[pn].shader.cy = 0;
|
||||
gc->pipe[pn].shader.cw = 0;
|
||||
gc->pipe[pn].shader.ch = 0;
|
||||
gc->pipe[pn].array.line = 0;
|
||||
gc->pipe[pn].array.use_vertex = 1;
|
||||
gc->pipe[pn].array.use_color = !nomul;
|
||||
gc->pipe[pn].array.use_texuv = 1;
|
||||
gc->pipe[pn].array.use_texuv2 = 0;
|
||||
gc->pipe[pn].array.use_texuv3 = 0;
|
||||
gc->pipe[pn].array.use_texsam = 0;
|
||||
gc->pipe[pn].array.use_mask = 0;
|
||||
gc->pipe[pn].array.use_masksam = 0;
|
||||
|
||||
pipe_region_expand(gc, pn, x, y, w, h);
|
||||
PIPE_GROW(gc, pn, 6);
|
||||
|
||||
_filter_data_alloc(gc, pn, 0);
|
||||
|
||||
pw = tex->pt->w;
|
||||
ph = tex->pt->h;
|
||||
|
||||
ox1 = x;
|
||||
oy1 = y;
|
||||
ox2 = x + w;
|
||||
oy2 = y;
|
||||
ox3 = x + w;
|
||||
oy3 = y + h;
|
||||
ox4 = x;
|
||||
oy4 = y + h;
|
||||
|
||||
offsetx = tex->x;
|
||||
offsety = tex->y;
|
||||
|
||||
tx1 = ((double)(offsetx) + ox1) / pw;
|
||||
ty1 = ((double)(offsety) + oy1) / ph;
|
||||
tx2 = ((double)(offsetx) + ox2) / pw;
|
||||
ty2 = ((double)(offsety) + oy2) / ph;
|
||||
tx3 = ((double)(offsetx) + ox3) / pw;
|
||||
ty3 = ((double)(offsety) + oy3) / ph;
|
||||
tx4 = ((double)(offsetx) + ox4) / pw;
|
||||
ty4 = ((double)(offsety) + oy4) / ph;
|
||||
|
||||
PUSH_6_VERTICES(pn, x, y, w, h);
|
||||
PUSH_6_QUAD(pn, tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4);
|
||||
|
||||
if (!nomul)
|
||||
PUSH_6_COLORS(pn, r, g, b, a);
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
EAPI void
|
||||
|
|
|
@ -46,8 +46,9 @@ typedef enum {
|
|||
SHADER_FLAG_FILTER_DIR_Y = (1 << 24),
|
||||
SHADER_FLAG_FILTER_ALPHA_ONLY = (1 << 25),
|
||||
SHADER_FLAG_FILTER_GRAYSCALE = (1 << 26),
|
||||
SHADER_FLAG_FILTER_INVERSE_COLOR = (1 << 27),
|
||||
} Shader_Flag;
|
||||
#define SHADER_FLAG_COUNT 27
|
||||
#define SHADER_FLAG_COUNT 28
|
||||
|
||||
static const char *_shader_flags[SHADER_FLAG_COUNT] = {
|
||||
"TEX",
|
||||
|
@ -77,6 +78,7 @@ static const char *_shader_flags[SHADER_FLAG_COUNT] = {
|
|||
"FILTER_DIR_Y",
|
||||
"ALPHA_ONLY",
|
||||
"FILTER_GRAYSCALE",
|
||||
"FILTER_INVERSE_COLOR",
|
||||
};
|
||||
|
||||
static Eina_Bool compiler_released = EINA_FALSE;
|
||||
|
@ -829,6 +831,9 @@ evas_gl_common_shader_flags_get(Evas_GL_Shared *shared, Shader_Type type,
|
|||
case SHD_FILTER_GRAYSCALE:
|
||||
flags |= SHADER_FLAG_FILTER_GRAYSCALE;
|
||||
break;
|
||||
case SHD_FILTER_INVERSE_COLOR:
|
||||
flags |= SHADER_FLAG_FILTER_INVERSE_COLOR;
|
||||
break;
|
||||
default:
|
||||
CRI("Impossible shader type.");
|
||||
return 0;
|
||||
|
|
|
@ -217,6 +217,9 @@ static const char fragment_glsl[] =
|
|||
"#ifdef SHD_FILTER_GRAYSCALE\n"
|
||||
" c.rgb = 0.3 * c.r + 0.59 * c.g + 0.11 * c.b;\n"
|
||||
"#endif\n"
|
||||
"#ifdef SHD_FILTER_INVERSE_COLOR\n"
|
||||
" c.rgb = c.a - c.rgb;\n"
|
||||
"#endif\n"
|
||||
"#ifndef SHD_FILTER_BLUR\n"
|
||||
" gl_FragColor =\n"
|
||||
" c\n"
|
||||
|
|
|
@ -234,6 +234,10 @@ vec4 fetch_pixel(float ox, float oy)
|
|||
c.rgb = 0.3 * c.r + 0.59 * c.g + 0.11 * c.b;
|
||||
#endif
|
||||
|
||||
#ifdef SHD_FILTER_INVERSE_COLOR
|
||||
c.rgb = c.a - c.rgba;
|
||||
#endif
|
||||
|
||||
#ifndef SHD_FILTER_BLUR
|
||||
|
||||
gl_FragColor =
|
||||
|
|
|
@ -3128,6 +3128,7 @@ _gfx_filter_func_get(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
|
|||
case EVAS_FILTER_MODE_MASK: funcptr = gl_filter_mask_func_get(re, cmd); break;
|
||||
//case EVAS_FILTER_MODE_TRANSFORM: funcptr = gl_filter_transform_func_get(re, cmd); break;
|
||||
case EVAS_FILTER_MODE_GRAYSCALE: funcptr = gl_filter_grayscale_func_get(re, cmd); break;
|
||||
case EVAS_FILTER_MODE_INVERSE_COLOR: funcptr = gl_filter_inverse_color_func_get(re, cmd); break;
|
||||
default: return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ GL_Filter_Apply_Func gl_filter_fill_func_get(Render_Engine_GL_Generic *re, Evas_
|
|||
GL_Filter_Apply_Func gl_filter_mask_func_get(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd);
|
||||
//GL_Filter_Apply_Func gl_filter_transform_func_get(Evas_Filter_Command *cmd);
|
||||
GL_Filter_Apply_Func gl_filter_grayscale_func_get(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd);
|
||||
GL_Filter_Apply_Func gl_filter_inverse_color_func_get(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd);
|
||||
|
||||
#undef DBG
|
||||
#undef INF
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
#include "gl_engine_filter.h"
|
||||
|
||||
static Eina_Bool
|
||||
_gl_filter_inverse_color(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
|
||||
{
|
||||
Evas_Engine_GL_Context *gc;
|
||||
Evas_GL_Image *image, *surface;
|
||||
RGBA_Draw_Context *dc_save;
|
||||
int w, h;
|
||||
|
||||
w = cmd->input->w;
|
||||
h = cmd->input->h;
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(w == cmd->output->w, EINA_FALSE);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(h == cmd->output->h, EINA_FALSE);
|
||||
|
||||
image = evas_ector_buffer_drawable_image_get(cmd->input->buffer);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE);
|
||||
|
||||
surface = evas_ector_buffer_render_image_get(cmd->output->buffer);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
|
||||
|
||||
gc = gl_generic_context_find(re, 1);
|
||||
evas_gl_common_context_target_surface_set(gc, surface);
|
||||
|
||||
dc_save = gc->dc;
|
||||
gc->dc = evas_common_draw_context_new();
|
||||
evas_common_draw_context_set_multiplier(gc->dc, cmd->draw.R, cmd->draw.G, cmd->draw.B, cmd->draw.A);
|
||||
|
||||
if (cmd->input == cmd->output)
|
||||
gc->dc->render_op = EVAS_RENDER_COPY;
|
||||
else
|
||||
gc->dc->render_op = _gfx_to_evas_render_op(cmd->draw.rop);
|
||||
|
||||
evas_gl_common_filter_inverse_color_push(gc, image->tex, 0, 0, w, h);
|
||||
|
||||
evas_common_draw_context_free(gc->dc);
|
||||
gc->dc = dc_save;
|
||||
|
||||
evas_ector_buffer_engine_image_release(cmd->input->buffer, image);
|
||||
evas_ector_buffer_engine_image_release(cmd->output->buffer, surface);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
GL_Filter_Apply_Func
|
||||
gl_filter_inverse_color_func_get(Render_Engine_GL_Generic *re EINA_UNUSED, 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 _gl_filter_inverse_color;
|
||||
}
|
|
@ -13,6 +13,7 @@ engine_src = files([
|
|||
join_paths('filters','gl_filter_fill.c'),
|
||||
join_paths('filters','gl_filter_mask.c'),
|
||||
join_paths('filters','gl_filter_grayscale.c'),
|
||||
join_paths('filters','gl_filter_inverse_color.c'),
|
||||
])
|
||||
common_engine_src = [
|
||||
'evas_gl_private.h',
|
||||
|
|
|
@ -4545,6 +4545,7 @@ _gfx_filter_func_get(Evas_Filter_Command *cmd)
|
|||
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;
|
||||
case EVAS_FILTER_MODE_INVERSE_COLOR: func = eng_filter_inverse_color_func_get(cmd); break;
|
||||
default: return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,5 +14,6 @@ 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);
|
||||
Software_Filter_Func eng_filter_inverse_color_func_get(Evas_Filter_Command *cmd);
|
||||
|
||||
#endif // EVAS_ENGINE_FILTER_H
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
#include "evas_engine_filter.h"
|
||||
|
||||
static Eina_Bool
|
||||
_evas_filter_inverse_color(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;
|
||||
|
||||
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_VAL(td + x) = A_VAL(ts + x) - R_VAL(ts + x);
|
||||
G_VAL(td + x) = A_VAL(ts + x) - G_VAL(ts + x);
|
||||
B_VAL(td + x) = A_VAL(ts + x) - B_VAL(ts + x);
|
||||
}
|
||||
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_inverse_color_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_inverse_color;
|
||||
}
|
Loading…
Reference in New Issue