summaryrefslogtreecommitdiff
path: root/src/lib/evas/include/evas_filter.h
blob: 1d1a17139917fb53ddf054c5654a5461256e5a78 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
#ifndef _EVAS_FILTER_H
#define _EVAS_FILTER_H

#include "evas_common_private.h"

typedef struct _Evas_Filter_Context Evas_Filter_Context;
typedef struct _Evas_Filter_Command Evas_Filter_Command;
typedef struct _Evas_Filter_Program Evas_Filter_Program;
typedef struct _Evas_Filter_Instruction Evas_Filter_Instruction;
typedef struct _Evas_Filter_Buffer Evas_Filter_Buffer;
typedef enum _Evas_Filter_Mode Evas_Filter_Mode;
typedef enum _Evas_Filter_Blur_Type Evas_Filter_Blur_Type;
typedef enum _Evas_Filter_Channel Evas_Filter_Channel;
typedef enum _Evas_Filter_Displacement_Flags Evas_Filter_Displacement_Flags;
typedef enum _Evas_Filter_Bump_Flags Evas_Filter_Bump_Flags;
typedef enum _Evas_Filter_Fill_Mode Evas_Filter_Fill_Mode;
typedef enum _Evas_Filter_Transform_Flags Evas_Filter_Transform_Flags;

typedef Eina_Bool (* Evas_Filter_Apply_Func) (Evas_Filter_Command *cmd);
typedef void (* Evas_Filter_Cb) (Evas_Filter_Context *ctx, void *data);

#define EVAS_FILTER_BUFFER_RGBA  EINA_FALSE
#define EVAS_FILTER_BUFFER_ALPHA EINA_TRUE

enum _Evas_Filter_Mode
{
   EVAS_FILTER_MODE_BLEND,        /**< Blend with current context render_op */
   EVAS_FILTER_MODE_BLUR,         /**< @see Evas_Filter_Blur_Type */
   EVAS_FILTER_MODE_CURVE,        /**< Apply color curve */
   EVAS_FILTER_MODE_DISPLACE,     /**< Apply XY displacement based on RG mask */
   EVAS_FILTER_MODE_FILL,         /**< Fill a buffer with a solid color */
   EVAS_FILTER_MODE_MASK,         /**< Apply Alpha or RGBA texture on image */
   EVAS_FILTER_MODE_BUMP,         /**< Apply bump mapping (light effect) */
   EVAS_FILTER_MODE_TRANSFORM,    /**< Apply a simple geometrical transformation */
   EVAS_FILTER_MODE_LAST
};

enum _Evas_Filter_Blur_Type
{
   EVAS_FILTER_BLUR_GAUSSIAN = 0x0, // Gaussian or sine curve. O(nm)
   EVAS_FILTER_BLUR_BOX      = 0x1, // Optimizable. But, UGLY. O(n)
   EVAS_FILTER_BLUR_MOTION   = 0x2, // Not implemented
   EVAS_FILTER_BLUR_LAST,
   EVAS_FILTER_BLUR_DEFAULT  = EVAS_FILTER_BLUR_GAUSSIAN
};

enum _Evas_Filter_Channel
{
   EVAS_FILTER_CHANNEL_ALPHA = 0,
   EVAS_FILTER_CHANNEL_RED   = 1,
   EVAS_FILTER_CHANNEL_GREEN = 2,
   EVAS_FILTER_CHANNEL_BLUE  = 3,
   EVAS_FILTER_CHANNEL_RGB   = 4
};

enum _Evas_Filter_Displacement_Flags
{
   EVAS_FILTER_DISPLACE_NEAREST  = 0x0,   /**< Interpolate between pixels (linear interpolation) */
   EVAS_FILTER_DISPLACE_LINEAR   = 0x1,   /**< Interpolate between pixels (linear interpolation) */
   EVAS_FILTER_DISPLACE_BLACK    = 0x0,   /**< Use black (or transparent) when going out of bounds) */
   EVAS_FILTER_DISPLACE_STRETCH  = 0x2,   /**< Stretch border pixels when going out of bounds */
   EVAS_FILTER_DISPLACE_BITMASK  = 0x3
};

enum _Evas_Filter_Bump_Flags
{
   EVAS_FILTER_BUMP_NORMAL       = 0x0,
   EVAS_FILTER_BUMP_COMPENSATE   = 0x1    /**< Compensate for darkening (diffuse light) or brightening (specular light) of zero gradient surfaces */
};

enum _Evas_Filter_Fill_Mode
{
   EVAS_FILTER_FILL_MODE_NONE               = 0x0,
   EVAS_FILTER_FILL_MODE_STRETCH_X          = 0x1,
   EVAS_FILTER_FILL_MODE_STRETCH_Y          = 0x2,
   EVAS_FILTER_FILL_MODE_REPEAT_X           = 0x4,
   EVAS_FILTER_FILL_MODE_REPEAT_Y           = 0x8,
   EVAS_FILTER_FILL_MODE_REPEAT_X_STRETCH_Y = EVAS_FILTER_FILL_MODE_REPEAT_X | EVAS_FILTER_FILL_MODE_STRETCH_Y,
   EVAS_FILTER_FILL_MODE_REPEAT_Y_STRETCH_X = EVAS_FILTER_FILL_MODE_REPEAT_Y | EVAS_FILTER_FILL_MODE_STRETCH_X,
   EVAS_FILTER_FILL_MODE_REPEAT_XY          = EVAS_FILTER_FILL_MODE_REPEAT_X | EVAS_FILTER_FILL_MODE_REPEAT_Y,
   EVAS_FILTER_FILL_MODE_STRETCH_XY         = EVAS_FILTER_FILL_MODE_STRETCH_X | EVAS_FILTER_FILL_MODE_STRETCH_Y
};

enum _Evas_Filter_Transform_Flags
{
   EVAS_FILTER_TRANSFORM_VFLIP = 1
};

/* Parser stuff (high level API) */
Evas_Filter_Program     *evas_filter_program_new(const char *name);
Eina_Bool                evas_filter_program_parse(Evas_Filter_Program *pgm, const char *str);
void                     evas_filter_program_del(Evas_Filter_Program *pgm);
Eina_Bool                evas_filter_context_program_use(Evas_Filter_Context *ctx, Evas_Object *eo_obj, Evas_Filter_Program *pgm);
Eina_Bool                evas_filter_program_padding_get(Evas_Filter_Program *pgm, int *l, int *r, int *t, int *b);
void                     evas_filter_program_proxy_source_bind(Evas_Filter_Program *pgm, const char *name, Evas_Object *object);
Evas_Object             *evas_filter_program_proxy_source_get(Evas_Filter_Program *pgm, const char *name);
void                     evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj, Eina_Bool do_async);

/* Filter context (low level) */
Evas_Filter_Context     *evas_filter_context_new(Evas_Public_Data *evas);
void                     evas_filter_context_destroy(Evas_Filter_Context *ctx);
void                     evas_filter_context_post_run_callback_set(Evas_Filter_Context *ctx, Evas_Filter_Cb cb, void *data);
#define                  evas_filter_context_autodestroy(ctx) evas_filter_context_post_run_callback_set(ctx, ((Evas_Filter_Cb) evas_filter_context_destroy), ctx)

int                      evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only);
int                      evas_filter_buffer_image_new(Evas_Filter_Context *ctx, RGBA_Image *image);
int                      evas_filter_buffer_data_new(Evas_Filter_Context *ctx, void *data, int w, int h, Eina_Bool alpha_only);
#define                  evas_filter_buffer_alloc_new(ctx, w, h, a) evas_filter_buffer_data_new(ctx, NULL, w, h, a)
void                    *evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid);
Eina_Bool                evas_filter_buffer_data_set(Evas_Filter_Context *ctx, int bufid, void *data, int w, int h, Eina_Bool alpha_only);

Eina_Bool                evas_filter_run(Evas_Filter_Context *ctx, Eina_Bool do_async);

/**
 * @brief Blend a source buffer into a destination buffer, allowing X,Y offsets, Alpha to RGBA conversion with color
 * @param ctx            Current filter chain
 * @param draw_context   Current Evas draw context. Current color is used when inbuf is ALPHA and outbuf is RGBA.
 * @param inbuf          Source buffer: ALPHA or RGBA
 * @param outbuf         Destination buffer: ALPHA or RGBA (note: must be RGBA if inbuf is RGBA)
 * @param ox             X offset in the destination buffer
 * @param oy             Y offset in the destination buffer
 * @param fillmode       Specifies whether to repeat or stretch the input onto its destination, and on which axes
 * @return               Filter command ID or -1 in case of error
 */
int                      evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int ox, int oy, Evas_Filter_Fill_Mode fillmode);

/**
 * @brief Apply a blur effect on a buffer
 * @param ctx            Current filter chain
 * @param draw_context   Current Evas draw context. Current color is used when inbuf is ALPHA and outbuf is RGBA.
 * @param inbuf          Source buffer: ALPHA or RGBA
 * @param outbuf         Destination buffer: ALPHA or RGBA (note: must be RGBA if inbuf is RGBA)
 * @param type           Type of blur: BOX, GAUSSIAN or MOTION
 * @param dx             X radius of blur. Can be negative ONLY for MOTION blur
 * @param dy             Y radius of blur. Can be negative ONLY for MOTION blur
 * @param ox             X offset in the destination buffer
 * @param oy             Y offset in the destination buffer
 * @return               Filter command ID or -1 in case of error
 */
int                      evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, Evas_Filter_Blur_Type type, int dx, int dy, int ox, int oy);

/**
 * @brief Fill a buffer with the current color
 * @param ctx            Current filter chain
 * @param draw_context   Current Evas draw context. Current color is used when buf is RGBA, and clip is used to specify the fill area.
 * @param buf            Buffer: ALPHA or RGBA
 * @return               Filter command ID or -1 in case of error
 * @note The current draw context's render operation is ignored (always uses COPY mode).
 */
int                      evas_filter_command_fill_add(Evas_Filter_Context *ctx, void *draw_context, int buf);

/**
 * @brief evas_filter_command_curve_add
 * @param ctx            Current filter chain
 * @param draw_context   Current Evas draw context. Current color is used when buf is RGBA, and clip is used to specify the fill area.
 * @param inbuf          Input buffer, ALPHA or RGBA.
 * @param outbuf         Output buffer, must have same colorspace as inbuf.
 * @param curve          The data points to use, must contain 256 values.
 * @param channel        Which channel to apply the curve (red, green, blue, alpha or RGB)
 * @return               Filter command ID or -1 in case of error
 */
int                      evas_filter_command_curve_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, DATA8 *curve /* 256 elements */, Evas_Filter_Channel channel);

/**
 * @brief Grow/Shrink an image, as defined in image processing (this is not a scale algorithm!)
 * @param ctx            Current filter chain
 * @param draw_context   Current Evas draw context. Current color is used when inbuf is ALPHA and outbuf is RGBA.
 * @param inbuf          Source buffer: ALPHA or RGBA
 * @param outbuf         Destination buffer: ALPHA or RGBA (note: must be RGBA if inbuf is RGBA)
 * @param radius         Number of pixels to grow by. If negative, shrink instead of grow
 * @param smooth         Use smooth blur and curve for grow (default: true)
 * @return               Filter command ID or -1 in case of error
 */
int                      evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int radius, Eina_Bool smooth);

/**
 * @brief Apply a displacement map to a buffer. This will move pixels from the source to the destination based on pixel per pixel offset, as defined in the displacement map
 * @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
 * @param dispbuf        Displacement map. Should be an RGBA buffer, where the Red and Green channels are the displacement maps for X and Y. Can be also ALPHA buffer, in which case only one dimension can be specified (X or Y).
 * @param flags          Alters how the map is interpreted, @see Evas_Filter_Displacement_Flags
 * @param intensity      Maximum offset possible, if the map's value is maximal at this point (ie. 0 or 255)
 * @param fillmode       Specifies how to repeat and stretch the map to fit the target size
 * @return               Filter command ID or -1 in case of error
 */
int                      evas_filter_command_displacement_map_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int dispbuf, Evas_Filter_Displacement_Flags flags, int intensity, Evas_Filter_Fill_Mode fillmode);

/**
 * @brief Apply a texture to a buffer
 * @param ctx            Current filter chain
 * @param draw_context   Current Evas draw context (ignored)
 * @param inbuf          Input buffer (Alpha or RGBA)
 * @param maskbuf        Texture buffer (Alpha or RGBA)
 * @param outbuf         Output buffer (Alpha or RGBA)
 * @param fillmode       Specifies how to repeat and stretch the mask to fit the target size
 * @return               Filter command ID or -1 in case of error
 * @note For the moment, inbuf can only be ALPHA, and output must be RGBA if mask is RGBA as well
 */
int                      evas_filter_command_mask_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int maskbuf, int outbuf, Evas_Filter_Fill_Mode fillmode);

/**
 * @brief Apply a relief effect based on a bump map (Z map)
 * @param ctx              Current filter chain
 * @param draw_context     Current Evas draw context (ignored)
 * @param inbuf            Input buffer (Alpha or RGBA)
 * @param bumpbuf          Bump map (Alpha only), same size as inbuf. By definition, lows are black (alpha 0) and highs are white (alpha 255).
 * @param outbuf           Output buffer (Alpha or RGBA), same size as inbuf
 * @param azimuth          CCW angle in degrees from the X axis of the light direction. 0 is light from the right, 90 from the top, 180 from the left, 270 from the bottom. All values are valid.
 * @param elevation        Angle in degrees between the XY plane and the light. Only values from 0 (light is perfectly horizontal) to 90 (light comes from the viewer herself) are acceptable.
 * @param depth            Max depth in the bump map. Default value is 10.
 * @param specular_factor  Factor for the specular light effect (shininess). Ranges from 1.0 to 1000+ with logarithmic effects
 * @param black            Darkest color, defines the ambiant light
 * @param color            Light's normal color
 * @param white            Brightest color, used in the shininess effect
 * @param flags            Optional flags: compensation for darkening
 * @param fillmode         Specifies how to repeat and stretch the map to fit the target size
 * @return                 Filter command ID or -1 in case of error
 */
int                      evas_filter_command_bump_map_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int bumpbuf, int outbuf, float azimuth, float elevation, float depth, float specular_factor, DATA32 black, DATA32 color, DATA32 white, Evas_Filter_Bump_Flags flags, Evas_Filter_Fill_Mode fillmode);

/**
 * @brief Apply a geometrical transformation to 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
 * @param flags          Specifies the operation to apply (eg. vflip)
 * @return               Filter command ID or -1 in case of error
 */
int                      evas_filter_command_transform_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, Evas_Filter_Transform_Flags flags);

#endif