1 /* WEED is free software; you can redistribute it and/or
2    modify it under the terms of the GNU Lesser General Public
3    License as published by the Free Software Foundation; either
4    version 3 of the License, or (at your option) any later version.
5 
6    Weed is distributed in the hope that it will be useful,
7    but WITHOUT ANY WARRANTY; without even the implied warranty of
8    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
9    Lesser General Public License for more details.
10 
11    You should have received a copy of the GNU Lesser General Public
12    License along with this source code; if not, write to the Free Software
13    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
14 
15    Weed is developed by:
16    Gabriel "Salsaman" Finch - http://lives-video.com
17 
18    partly based on LiViDO, which is developed by:
19    Niels Elburg - http://veejay.sf.net
20    Denis "Jaromil" Rojo - http://freej.dyne.org
21    Tom Schouten - http://zwizwa.fartit.com
22    Andraz Tori - http://cvs.cinelerra.org
23 
24    reviewed with suggestions and contributions from:
25    Silvano "Kysucix" Galliani - http://freej.dyne.org
26    Kentaro Fukuchi - http://megaui.net/fukuchi
27    Jun Iio - http://www.malib.net
28    Carlo Prelz - http://www2.fluido.as:8080/
29 */
30 
31 /* (C) G. Finch, 2005 - 2019 */
32 
33 #ifdef __WEED_HOST__
34 #error This header is intended only for Weed plugins
35 #endif
36 
37 #ifndef __WEED_PLUGIN__
38 #error weed-plugin.h should be included first
39 #endif
40 
41 #ifndef __WEED_PLUGIN_UTILS_H__
42 #define __WEED_PLUGIN_UTILS_H__
43 
44 #ifdef __cplusplus
45 extern "C"
46 {
47 #endif /* __cplusplus */
48 
49 #ifndef NEED_LOCAL_WEED
50 #include <weed/weed.h>
51 #include <weed/weed-palettes.h>
52 #include <weed/weed-effects.h>
53 #else
54 #include "weed.h"
55 #include "weed-palettes.h"
56 #include "weed-effects.h"
57 #endif
58 
59 /* Define EXPORTED for any platform */
60 #if defined _WIN32 || defined __CYGWIN__ || defined IS_MINGW
61 #ifdef WIN_EXPORT
62 #ifdef __GNUC__
63 #define EXPORTED __attribute__ ((dllexport))
64 #else
65 #define EXPORTED __declspec(dllexport) // Note: actually gcc seems to also supports this syntax.
66 #endif
67 #else // WIN_WEX
68 #ifdef __GNUC__
69 #define EXPORTED __attribute__ ((dllimport))
70 #else
71 #define EXPORTED __declspec(dllimport) // Note: actually gcc seems to also supports this syntax.
72 #endif
73 #endif // WINEX
74 #define NOT_EXPORTED
75 #else // MING
76 
77 #if __GNUC__ >= 4
78 #define EXPORTED __attribute__ ((visibility ("default")))
79 #define NOT_EXPORTED  __attribute__ ((visibility ("hidden")))
80 #else
81 #define EXPORTED
82 #define NOT_EXPORTED
83 #endif
84 #endif
85 
86 #define ALLOW_UNUSED
87 #define FN_DECL static
88 
89 // functions for weed_setup()
90 
91 FN_DECL weed_plant_t *weed_plugin_info_init(weed_bootstrap_f weed_boot,
92     int32_t weed_abi_min_version, int32_t weed_abi_max_version,
93     int32_t filter_api_min_version, int32_t weed_filter_api_max_version) ALLOW_UNUSED;
94 
95 FN_DECL weed_plant_t *weed_channel_template_init(const char *name, int flags) ALLOW_UNUSED;
96 
97 FN_DECL weed_plant_t **weed_clone_plants(weed_plant_t **plants) ALLOW_UNUSED;
98 
99 FN_DECL weed_plant_t *weed_filter_class_init(const char *name, const char *author, int version, int flags,
100     int *palette_list, weed_init_f init_func,
101     weed_process_f process_func, weed_deinit_f deinit_func,
102     weed_plant_t **in_chantmpls, weed_plant_t **out_chantmpls,
103     weed_plant_t **in_paramtmpls, weed_plant_t **out_paramtmpls) ALLOW_UNUSED;
104 
105 FN_DECL void weed_plugin_info_add_filter_class(weed_plant_t *plugin_info, weed_plant_t *filter_class) ALLOW_UNUSED;
106 
107 // in params
108 FN_DECL weed_plant_t *weed_text_init(const char *name, const char *label, const char *def) ALLOW_UNUSED;
109 FN_DECL weed_plant_t *weed_float_init(const char *name, const char *label, double def, double min, double max) ALLOW_UNUSED;
110 FN_DECL weed_plant_t *weed_switch_init(const char *name, const char *label, int def) ALLOW_UNUSED;
111 FN_DECL weed_plant_t *weed_integer_init(const char *name, const char *label, int def, int min, int max) ALLOW_UNUSED;
112 FN_DECL weed_plant_t *weed_colRGBd_init(const char *name, const char *label, double red, double green,
113                                         double blue) ALLOW_UNUSED;
114 FN_DECL weed_plant_t *weed_colRGBi_init(const char *name, const char *label, int red, int green, int blue) ALLOW_UNUSED;
115 FN_DECL weed_plant_t *weed_radio_init(const char *name, const char *label, int def, int group) ALLOW_UNUSED;
116 FN_DECL weed_plant_t *weed_string_list_init(const char *name, const char *label, int def, const char **const list) ALLOW_UNUSED;
117 
118 // out params
119 FN_DECL weed_plant_t *weed_out_param_colRGBd_init(const char *name, double red, double green, double blue) ALLOW_UNUSED;
120 FN_DECL weed_plant_t *weed_out_param_colRGBi_init(const char *name, int red, int green, int blue) ALLOW_UNUSED;
121 FN_DECL weed_plant_t *weed_out_param_text_init(const char *name, const char *def) ALLOW_UNUSED;
122 FN_DECL weed_plant_t *weed_out_param_float_init_nominmax(const char *name, double def) ALLOW_UNUSED;
123 FN_DECL weed_plant_t *weed_out_param_float_init(const char *name, double def, double min, double max) ALLOW_UNUSED;
124 FN_DECL weed_plant_t *weed_out_param_switch_init(const char *name, int def) ALLOW_UNUSED;
125 FN_DECL weed_plant_t *weed_out_param_integer_init_nominmax(const char *name, int def) ALLOW_UNUSED;
126 FN_DECL weed_plant_t *weed_out_param_integer_init(const char *name, int def, int min, int max) ALLOW_UNUSED;
127 
128 // value setters
129 FN_DECL void weed_plugin_set_package_version(weed_plant_t *pi, int v);
130 FN_DECL void weed_filter_set_flags(weed_plant_t *filter, int flags);
131 FN_DECL void weed_chantmpl_set_flags(weed_plant_t *chantmpl, int flags);
132 FN_DECL void weed_paramtmpl_set_flags(weed_plant_t *paramtmpl, int flags);
133 FN_DECL void weed_gui_set_flags(weed_plant_t *gui, int flags);
134 FN_DECL void weed_filter_set_name(weed_plant_t *filter, const char *name);
135 FN_DECL void weed_chantmpl_set_name(weed_plant_t *chantmpl, const char *name);
136 FN_DECL void weed_paramtmpl_set_name(weed_plant_t *paramtmpl, const char *name);
137 FN_DECL void weed_paramtmpl_declare_transition(weed_plant_t *pt);
138 //FN_DECL void weed_chantmpl_set_palette_list()
139 
140 // value getters
141 
142 // plugin_info
143 FN_DECL weed_plant_t *weed_get_host_info(weed_plant_t *plugin_info);
144 FN_DECL int weed_get_api_version(weed_plant_t *plugin_info) ALLOW_UNUSED;
145 
146 // host info
147 FN_DECL int weed_get_host_verbosity(weed_plant_t *host_info);
148 //FN_DECL char *weed_get_host_name(weed_plant_t *host_info);
149 //FN_DECL char *weed_get_host_version(weed_plant_t *host_info);
150 FN_DECL int weed_host_get_flags(weed_plant_t *host_info);
151 FN_DECL int weed_host_supports_linear_gamma(weed_plant_t *host_info);
152 FN_DECL int weed_host_supports_premultiplied_alpha(weed_plant_t *host_info);
153 //FN_DECL char **weed_get_host_layout_schemes(weed_plant_t *host_info);
154 
155 // filter_class
156 FN_DECL int weed_filter_get_flags(weed_plant_t *filter);
157 FN_DECL int weed_filter_get_version(weed_plant_t *filter);
158 FN_DECL weed_plant_t *weed_filter_get_gui(weed_plant_t *filter) ALLOW_UNUSED;
159 
160 // param_tmpl
161 FN_DECL weed_plant_t *weed_paramtmpl_get_gui(weed_plant_t *paramt) ALLOW_UNUSED;
162 FN_DECL int weed_paramtmpl_get_flags(weed_plant_t *paramtmpl);
163 
164 // chan tmpl
165 FN_DECL int weed_chantmpl_get_flags(weed_plant_t *chantmpl);
166 
167 // inst
168 FN_DECL weed_plant_t *weed_get_in_channel(weed_plant_t *inst, int idx);
169 FN_DECL weed_plant_t *weed_get_out_channel(weed_plant_t *inst, int idx);
170 FN_DECL weed_plant_t *weed_get_in_param(weed_plant_t *inst, int idx);
171 FN_DECL weed_plant_t *weed_get_out_param(weed_plant_t *inst, int idx);
172 FN_DECL int weed_instance_get_flags(weed_plant_t *inst);
173 FN_DECL weed_plant_t *weed_instance_get_filter(weed_plant_t *inst);
174 FN_DECL weed_plant_t *weed_instance_get_gui(weed_plant_t *inst);
175 
176 // channel
177 FN_DECL void *weed_channel_get_pixel_data(weed_plant_t *channel);
178 FN_DECL int weed_channel_get_width(weed_plant_t *channel);
179 FN_DECL int weed_channel_get_height(weed_plant_t *channel);
180 FN_DECL int weed_channel_get_palette(weed_plant_t *channel);
181 FN_DECL int weed_channel_get_yuv_clamping(weed_plant_t *channel);
182 FN_DECL int weed_channel_get_stride(weed_plant_t *channel);
183 
184 #ifdef NEED_AUDIO
185 FN_DECL weed_plant_t *weed_audio_channel_template_init(const char *name, int flags);
186 FN_DECL int weed_channel_get_audio_rate(weed_plant_t *channel);
187 FN_DECL int weed_channel_get_naudchans(weed_plant_t *channel);
188 FN_DECL int weed_channel_get_audio_length(weed_plant_t *channel);
189 FN_DECL void weed_paramtmpl_declare_volume_master(weed_plant_t *pt);
190 #ifdef __WEED_UTILS_H__
191 FN_DECL float **weed_channel_get_audio_data(weed_plant_t *channel, int *naudchans);
192 #endif
193 #endif
194 
195 FN_DECL int weed_channel_is_disabled(weed_plant_t *channel);
196 
197 // params
198 FN_DECL weed_plant_t  *weed_param_get_template(weed_plant_t *param);
199 FN_DECL weed_plant_t *weed_param_get_gui(weed_plant_t *param) ALLOW_UNUSED;
200 
201 // param values
202 FN_DECL int weed_param_get_value_int(weed_plant_t *param);
203 FN_DECL int weed_param_get_value_boolean(weed_plant_t *param);
204 FN_DECL double weed_param_get_value_double(weed_plant_t *param);
205 FN_DECL int64_t weed_param_get_value_int64(weed_plant_t *param);
206 FN_DECL char *weed_param_get_value_string(weed_plant_t *param);
207 
208 #ifdef __WEED_UTILS_H__
209 FN_DECL int *weed_param_get_array_int(weed_plant_t *param, int *nvalues);
210 FN_DECL int *weed_param_get_array_boolean(weed_plant_t *param, int *nvalues);
211 FN_DECL double *weed_param_get_array_double(weed_plant_t *param, int *nvalues);
212 FN_DECL int64_t *weed_param_get_array_int64(weed_plant_t *param, int *nvalues);
213 FN_DECL char **weed_param_get_array_string(weed_plant_t *param, int *mvalues);
214 FN_DECL weed_plant_t **weed_get_in_channels(weed_plant_t *inst, int *nchans);
215 FN_DECL weed_plant_t **weed_get_out_channels(weed_plant_t *inst, int *nchans);
216 FN_DECL weed_plant_t **weed_get_in_params(weed_plant_t *inst, int *nparams);
217 FN_DECL weed_plant_t **weed_get_out_params(weed_plant_t *inst, int *nparams);
218 FN_DECL int *weed_channel_get_rowstrides(weed_plant_t *channel, int *nplanes);
219 FN_DECL void **weed_channel_get_pixel_data_planar(weed_plant_t *channel, int *nplanes);
220 #endif
221 
222 /* Threading */
223 FN_DECL int weed_is_threading(weed_plant_t *inst);
224 FN_DECL int weed_channel_get_offset(weed_plant_t *channel);
225 FN_DECL int weed_channel_get_real_height(weed_plant_t *channel);
226 
227 // general utils
228 FN_DECL int is_big_endian(void);
229 
230 #ifndef ABS
231 #define ABS(a) (((a) < 0) ? -(a) : (a))
232 #endif
233 
234 // functions for process_func()
235 
236 #ifdef NEED_RANDOM
237 FN_DECL uint64_t fastrand(uint64_t notused);
238 FN_DECL double fastrand_dbl(double range);
239 FN_DECL uint32_t fastrand_int(uint32_t range);
240 #endif
241 
242 #ifdef NEED_ALPHA_SORT // for wrappers, use this to sort filters alphabetically
243 typedef struct dlink_list dlink_list_t;
244 FN_DECL dlink_list_t *add_to_list_sorted(dlink_list_t *list, weed_plant_t *filter, const char *name);
245 FN_DECL int add_filters_from_list(weed_plant_t *plugin_info, dlink_list_t *list);
246 #endif
247 
248 #ifdef NEED_PALETTE_UTILS
249 #define ALL_RGB_PALETTES {WEED_PALETTE_RGB24, WEED_PALETTE_BGR24, WEED_PALETTE_RGBA32, WEED_PALETTE_BGRA32, \
250       WEED_PALETTE_ARGB32, WEED_PALETTE_END}
251 
252 #define ALL_24BIT_PALETTES {WEED_PALETTE_RGB24, WEED_PALETTE_BGR24, WEED_PALETTE_YUV888, WEED_PALETTE_END}
253 
254 #define ALL_32BIT_PALETTES {WEED_PALETTE_RGBA32, WEED_PALETTE_BGRA32, WEED_PALETTE_ARGB32, WEED_PALETTE_YUVA8888,\
255       WEED_PALETTE_END}
256 
257 #define ALL_ALPHA_PALETTES {WEED_PALETTE_AFLOAT, WEED_PALETTE_A8, WEED_PALETTE_A1, WEED_PALETTE_END}
258 
259 /*( omits WEED_PALETTE_YUV411, WEED_PALETTE_UYVY, WEED_PALETTE_YUYV, WEED_PALETTE_RGB_FLOAT
260    and WEED_PALETTE_RGBA_FLOAT as well as the alpha palettes
261   WEED_PALETTE_A1, WEED_PALETTE_A8 and WEED_PALETTE_AFLOAT also WEED_PALETTE_ARGB32 so that alpha is always last*/
262 
263 #define ALL_PACKED_PALETTES {WEED_PALETTE_RGB24, WEED_PALETTE_BGR24, WEED_PALETTE_RGBA32, \
264       WEED_PALETTE_BGRA32, WEED_PALETTE_YUV888, WEED_PALETTE_YUVA8888, WEED_PALETTE_END}
265 
266 #define ALL_PACKED_PALETTES_PLUS {WEED_PALETTE_RGB24, WEED_PALETTE_BGR24, WEED_PALETTE_RGBA32, \
267       WEED_PALETTE_BGRA32, WEED_PALETTE_ARGB32, WEED_PALETTE_YUV888, WEED_PALETTE_YUVA8888, WEED_PALETTE_UYVY, \
268       WEED_PALETTE_YUYV, WEED_PALETTE_END}
269 
270 #define ALL_PLANAR_PALETTES {WEED_PALETTE_YUV444P, WEED_PALETTE_YUVA4444P, WEED_PALETTE_YUV422P, \
271                         WEED_PALETTE_YUV420P, WEED_PALETTE_YVU420P, WEED_PALETTE_END}
272 
273 /* only for packed palettes (for uyvy, yuyv, it's actually the macropixel size, but we'll skip that subtlety here)*/
274 #define pixel_size(pal) ((pal == WEED_PALETTE_RGB24 || pal == WEED_PALETTE_BGR24 || pal == WEED_PALETTE_YUV888) ? 3 : \
275 			 (pal == WEED_PALETTE_RGBA32 || pal == WEED_PALETTE_BGRA32 || pal == WEED_PALETTE_ARGB32 || \
276 			  pal == WEED_PALETTE_YUVA8888 || pal == WEED_PALETTE_UYVY || pal == WEED_PALETTE_YUYV) ? 4 : 0)
277 
278 #define rgb_offset(pal) (pal == WEED_PALETTE_ARGB32 ? 1 : 0)
279 
280 FN_DECL int weed_palette_is_alpha(int pal);
281 FN_DECL int weed_palette_is_rgb(int pal);
282 FN_DECL int weed_palette_is_yuv(int pal);
283 FN_DECL int weed_palette_get_nplanes(int pal);
284 FN_DECL int weed_palette_is_valid(int pal);
285 FN_DECL int weed_palette_is_float(int pal);
286 FN_DECL int weed_palette_has_alpha_channel(int pal);
287 FN_DECL double weed_palette_get_plane_ratio_horizontal(int pal, int plane);
288 FN_DECL double weed_palette_get_plane_ratio_vertical(int pal, int plane);
289 
290 // set src to non-null to preserve the alpha channel (if applicable)
291 // othwerwise alpha will be set to 255
292 // yuv_clamping is ignored fo non-yuv palettes
293 // only valid for non-planar (packed) palettes: RGB24, BGR24, RGBA32, BGRA32, ARGB32, UYVY8888, YUYV8888, YUV888, YUVA8888, and YUV411
294 FN_DECL size_t blank_pixel(uint8_t *dst, int pal, int yuv_clamping, uint8_t *src);
295 
296 // If psrc is non-NULL then the alpha values from psrc will be copied to pdst.
297 // otherwise alpha will be set to 255
298 //
299 // valid for: RGB24, BGR24, RGBA32, BGRA32, ARGB32, UYVY8888, YUYV8888, YUV888, YUVA8888, YUV411
300 //            YUVA4444p, YUV444p, YUV422p, YUV420p, YVU420p
301 // if scanning vertically:
302 // pdst[n], psrc[n] should be increased by rowstrides[n] after each call
303 //
304 // for YUV420 and YVU420: set uvcopy to WEED_TRUE only on even rows,
305 // and increase pdst[1], pdst[2] only on the odd rows (pscr is ignored)
306 //
307 FN_DECL void blank_row(uint8_t **pdst, int width, int pal, int yuv_clamping, int uvcopy, uint8_t **psrc);
308 FN_DECL void blank_frame(void **pdata, int width, int height, int *rowstrides, int pal, int yuv_clamping);
309 #endif
310 
311 #ifdef NEED_PALETTE_CONVERSIONS
312 /* palette conversions use lookup tables for efficiency */
313 // calculate a (rough) luma valu for a pixel; works for any palette (for WEED_PALETTE_UYVY add 1 to *pixel)
314 FN_DECL uint8_t calc_luma(uint8_t *pixel, int palette, int yuv_clamping);
315 
316 FN_DECL uint8_t y_unclamped_to_clamped(uint8_t y);
317 FN_DECL uint8_t y_clamped_to_unclamped(uint8_t y);
318 FN_DECL uint8_t uv_clamped_to_unclamped(uint8_t uv);
319 
320 /* pre multiply or un-pre-multiply alpha for a frame: if un is set to WEED_TRUE we un-pre-multiply, othewise pre-multiply */
321 FN_DECL void alpha_premult(unsigned char *ptr, int width, int height, int rowstride, int pal, int un);
322 #endif
323 
324 #ifdef NEED_FONT_UTILS
325 
326 #include <wchar.h>
327   FN_DECL void weed_parse_font_string(const char *fontstr, char **family, char **fstretch, char **fweight,
328 				    char **fstyle, int *size);
329 #endif
330 
331 #ifdef __cplusplus
332 
333 #define WEED_SETUP_START(weed_api_version, filter_api_version) extern "C" { EXPORTED weed_plant_t *weed_setup(weed_bootstrap_f weed_boot) { \
334     weed_plant_t *plugin_info = weed_plugin_info_init(weed_boot, weed_api_version, weed_api_version, filter_api_version, filter_api_version); \
335  if (plugin_info == NULL) {return NULL;} {
336 
337 #define WEED_SETUP_START_MINMAX(weed_api_min_version, weed_api_max_version, filter_api_min_version, filter_api_max_version) extern "C" { EXPORTED weed_plant_t *weed_setup(weed_bootstrap_f weed_boot) { \
338     weed_plant_t *plugin_info = weed_plugin_info_init(weed_boot, weed_api_min_version, weed_api_max_version, filter_api_min_Version, filter_api_max_version); \
339  if (plugin_info == NULL) {return NULL;} {
340 
341 #define WEED_SETUP_END } return plugin_info;}}
342 
343 #define WEED_DESETUP_START extern "C" { EXPORTED void weed_desetup(void) {
344 #define WEED_DESETUP_END }}
345 
346 #else
347 
348 #define WEED_SETUP_START(weed_api_version, filter_api_version) EXPORTED weed_plant_t *weed_setup(weed_bootstrap_f weed_boot) { \
349     weed_plant_t *plugin_info = weed_plugin_info_init(weed_boot, weed_api_version, weed_api_version, filter_api_version, filter_api_version); \
350  if (plugin_info == NULL) {return NULL;} {
351 
352 #define WEED_SETUP_START_MINMAX(weed_api_min_version, weed_api_max_version, filter_api_min_version, filter_api_max_version) EXPORTED weed_plant_t *weed_setup(weed_bootstrap_f weed_boot) { \
353     weed_plant_t *plugin_info = weed_plugin_info_init(weed_boot, weed_api_min_version, weed_api_max_version, filter_api_min_version, filter_api_max_version); \
354  if (plugin_info == NULL) {return NULL;} {
355 
356 #define WEED_SETUP_END } return plugin_info;}
357 
358 #define WEED_DESETUP_START EXPORTED void weed_desetup(void) {
359 #define WEED_DESETUP_END }
360 
361 #endif
362 
363 #ifdef __cplusplus
364 }
365 #endif
366 
367 #endif
368