10 #if defined(HAVE_OPENCV) || defined(HAVE_OPENCV4)
12 #include "opencv4/opencv2/core/core.hpp"
14 #include "opencv2/core/core.hpp"
36 static int our_plugin_id = 0;
37 static weed_plant_t *expected_hi = NULL, *expected_pi = NULL;
38 static boolean suspect =
FALSE;
40 static int ncbcalls = 0;
42 static boolean fx_inited =
FALSE;
45 weed_process_f procfunc;
49 char padding[
DEF_ALIGN - ((
sizeof(weed_process_f) -
sizeof(weed_plant_t *)
50 -
sizeof(weed_timecode_t) -
sizeof(weed_error_t)) %
DEF_ALIGN)];
53 static weed_plantptr_t statsplant = NULL;
55 static int load_compound_fx(
void);
69 if (!weed_plant_has_leaf(slayer, key))
return weed_leaf_delete(dlayer, key);
70 else return weed_leaf_copy(dlayer, key, slayer, key);
75 #ifdef DEBUG_FILTER_MUTEXES
77 g_print(
"trylock of %d\n", key);
87 #ifdef DEBUG_FILTER_MUTEXES
89 g_print(
"trylock of %d returned %d\n", key, retval);
95 #ifndef DEBUG_FILTER_MUTEXES
112 char *msg =
lives_strdup_printf(
"attempted double unlock of fx key %d, err was %d", key, ret);
133 weed_plant_t *filter;
149 if (!plist)
return TRUE;
150 for (i = 0; i < npals; i++) {
151 if (plist[i] == WEED_PALETTE_END)
break;
168 for (i = 0; i < npals; i++) {
170 if (
palette == WEED_PALETTE_NONE)
continue;
181 if (get_compound_parent &&
184 return weed_get_plantptr_value(inst, WEED_LEAF_FILTER_CLASS, NULL);
188 static boolean all_outs_alpha(weed_plant_t *filt,
boolean ign_opt) {
192 if (!nouts)
return FALSE;
197 for (
int i = 0; i < nouts; i++) {
209 static boolean all_ins_alpha(weed_plant_t *filt,
boolean ign_opt) {
212 boolean has_mandatory_in =
FALSE;
215 if (nins == 0)
return FALSE;
220 for (
int i = 0; i < nins; i++) {
222 has_mandatory_in =
TRUE;
228 if (!has_mandatory_in) {
229 for (
int i = 0; i < nins; i++) {
244 weed_plant_t *filt = pl;
246 boolean has_out_params =
FALSE;
247 boolean has_in_params =
FALSE;
248 boolean all_out_alpha =
TRUE;
249 boolean all_in_alpha =
TRUE;
250 boolean has_in_alpha =
FALSE;
256 all_out_alpha = all_outs_alpha(filt,
TRUE);
257 all_in_alpha = all_ins_alpha(filt,
TRUE);
259 filter_flags = weed_get_int_value(filt, WEED_LEAF_FLAGS, NULL);
260 if (weed_plant_has_leaf(filt, WEED_LEAF_OUT_PARAMETER_TEMPLATES)) has_out_params =
TRUE;
261 if (weed_plant_has_leaf(filt, WEED_LEAF_IN_PARAMETER_TEMPLATES)) has_in_params =
TRUE;
264 if (in_channels == 0 && out_channels > 0) {
269 if (out_channels >= 1 && in_channels >= 1 && (all_in_alpha || has_in_alpha) && !all_out_alpha)
274 if (in_channels > 2 && out_channels == 1) {
291 weed_plant_t *filt = pl;
292 boolean has_video_chansi;
323 weed_plant_t **ctmpls;
324 int count = 0, nchans;
329 if (!ctmpls)
return FALSE;
330 for (i = 0; i < nchans; i++) {
336 if (!ctmpls)
return FALSE;
337 for (i = 0; i < nchans; i++) {
349 #define MAX_WEED_INSTANCES 65536
352 static int fg_generator_key;
353 static int bg_generator_key;
356 static int fg_generator_mode;
357 static int bg_generator_mode;
361 static int bg_gen_to_start;
362 static int fg_gen_to_start;
365 static int fg_generator_clip;
369 static weed_plant_t **weed_filters;
371 static LiVESList *weed_fx_sorted_list;
374 static weed_plant_t **key_to_instance[
FX_KEYS_MAX];
375 static weed_plant_t **key_to_instance_copy[
FX_KEYS_MAX];
380 static int num_weed_filters;
388 #define NHASH_TYPES 8
405 static int next_free_key;
417 key_to_instance_copy[i][0] = key_to_instance[i][0];
418 key_to_instance[i][0] = NULL;
426 key_to_instance[i][0] = key_to_instance_copy[i][0];
431 static char *weed_filter_get_type(weed_plant_t *filter,
boolean getsub,
boolean format) {
433 char *tmp1, *tmp2, *ret;
482 weed_plant_t *filter, *hinfo, *pinfo;
484 for (i = 0; i < num_weed_filters; i++) {
485 filter = weed_filters[i];
486 hinfo = weed_get_plantptr_value(filter, WEED_LEAF_HOST_INFO, NULL);
488 pinfo = weed_get_plantptr_value(filter, WEED_LEAF_PLUGIN_INFO, NULL);
490 hinfo = weed_get_plantptr_value(pinfo, WEED_LEAF_HOST_INFO, NULL);
497 static weed_plant_t *get_enabled_channel_inner(weed_plant_t *inst,
int which,
boolean is_in,
boolean audio_only) {
500 weed_plant_t **channels = NULL;
501 weed_plant_t *retval, *ctmpl = NULL;
515 if (!nchans)
return NULL;
518 if (weed_get_boolean_value(channels[i], WEED_LEAF_DISABLED, NULL) == WEED_FALSE) {
524 if (which < 0)
break;
530 retval = channels[i];
538 return get_enabled_channel_inner(inst, which, is_in,
FALSE);
544 return get_enabled_channel_inner(inst, which, is_in,
TRUE);
551 weed_plant_t **ctmpls;
552 weed_plant_t *retval;
560 if (!ctmpls)
return NULL;
565 retval = ctmpls[i - 1];
579 weed_plant_t **in_chans;
583 if (nchans <= chnum) {
598 weed_plant_t **in_chans;
599 weed_plant_t *ctmpl, *achan;
602 if (!in_chans)
return NULL;
604 for (
register int i = 0; i < nchans; i++) {
623 weed_plant_t **in_ctmpls;
626 if (!in_ctmpls)
return FALSE;
628 for (
register int i = 0; i < nchans; i++) {
643 if (!in_ctmpls)
return FALSE;
644 for (
int i = 0; i < nchans; i++) {
657 weed_plant_t **out_chans;
662 if (nchans <= chnum) {
677 weed_plant_t **out_ctmpls;
681 if (!out_ctmpls)
return FALSE;
683 for (
int i = 0; i < nchans; i++) {
696 weed_plant_t **out_ctmpls;
700 if (!out_ctmpls)
return FALSE;
702 for (
int i = 0; i < nchans; i++) {
715 weed_plant_t *filter = plant;
726 weed_plant_t **chans, *ctmpl;
727 int flags = weed_get_int_value(ptmpl, WEED_LEAF_FLAGS, NULL);
730 if (flags & WEED_PARAMETER_VARIABLE_SIZE)
return TRUE;
732 if (!inst)
return FALSE;
734 if (!(flags & WEED_PARAMETER_VALUE_PER_CHANNEL))
return FALSE;
736 if ((nchans = weed_leaf_num_elements(inst, WEED_LEAF_IN_CHANNELS)) == 0)
739 chans = weed_get_plantptr_array(inst, WEED_LEAF_IN_CHANNELS, NULL);
741 for (
int i = 0; i < nchans; i++) {
742 if (weed_get_boolean_value(chans[i], WEED_LEAF_DISABLED, NULL) == WEED_TRUE)
continue;
743 ctmpl = weed_get_plantptr_value(chans[i], WEED_LEAF_TEMPLATE, NULL);
744 if (weed_plant_has_leaf(ctmpl, WEED_LEAF_MAX_REPEATS) && weed_get_int_value(ctmpl, WEED_LEAF_MAX_REPEATS, NULL) != 1) {
779 static void create_filter_map(uint64_t rteval) {
786 filter_map[count++] = init_events[i];
791 filter_map[count] = NULL;
806 boolean needs_filter_map =
FALSE;
807 weed_timecode_t last_tc = 0;
812 if (init_events[i]) {
814 init_events[i] = NULL;
818 needs_filter_map =
TRUE;
824 if (needs_filter_map) {
869 int best_palette = palette_list[0];
870 boolean has_alpha, is_rgb, is_alpha, is_yuv, mismatch;
877 is_yuv = !is_alpha && !is_rgb;
879 for (
int i = 0; (num_palettes > 0 && i < num_palettes) || (num_palettes <= 0 && palette_list[i] != WEED_PALETTE_END); i++) {
880 if (palette_list[i] ==
palette) {
887 else mismatch =
FALSE;
889 switch (palette_list[i]) {
890 case WEED_PALETTE_RGB24:
891 case WEED_PALETTE_BGR24:
892 if (
palette == WEED_PALETTE_RGB24 ||
palette == WEED_PALETTE_BGR24)
return palette_list[i];
895 best_palette == WEED_PALETTE_RGBFLOAT)
896 && !(best_palette == WEED_PALETTE_RGB24 || best_palette == WEED_PALETTE_BGR24))
897 best_palette = palette_list[i];
899 case WEED_PALETTE_RGBA32:
900 case WEED_PALETTE_BGRA32:
901 if (
palette == WEED_PALETTE_RGBA32 ||
palette == WEED_PALETTE_BGRA32) best_palette = palette_list[i];
902 case WEED_PALETTE_ARGB32:
903 if ((is_rgb || mismatch) && (has_alpha || best_palette == WEED_PALETTE_RGBFLOAT
904 || best_palette == WEED_PALETTE_RGBAFLOAT)
905 && best_palette != WEED_PALETTE_RGBA32
906 && !(
palette == WEED_PALETTE_ARGB32 && best_palette == WEED_PALETTE_BGRA32))
907 best_palette = palette_list[i];
909 case WEED_PALETTE_RGBAFLOAT:
910 if ((is_rgb || mismatch) && best_palette == WEED_PALETTE_RGBFLOAT && has_alpha)
911 best_palette = WEED_PALETTE_RGBAFLOAT;
913 case WEED_PALETTE_RGBFLOAT:
914 if ((is_rgb || mismatch) && best_palette == WEED_PALETTE_RGBAFLOAT && !has_alpha)
915 best_palette = WEED_PALETTE_RGBFLOAT;
918 case WEED_PALETTE_YUVA4444P:
919 if (is_yuv && has_alpha)
return WEED_PALETTE_YUVA4444P;
920 if ((mismatch || is_yuv)
921 && (has_alpha || (best_palette != WEED_PALETTE_YUV444P && best_palette != WEED_PALETTE_YUV888)))
922 best_palette = WEED_PALETTE_YUVA4444P;
924 case WEED_PALETTE_YUV444P:
925 if (is_yuv && !has_alpha)
return WEED_PALETTE_YUV444P;
926 if ((mismatch || is_yuv)
927 && (!has_alpha || (best_palette != WEED_PALETTE_YUVA4444P && best_palette != WEED_PALETTE_YUVA8888)))
928 best_palette = WEED_PALETTE_YUV444P;
930 case WEED_PALETTE_YUVA8888:
931 if ((mismatch || is_yuv) && (has_alpha || (best_palette != WEED_PALETTE_YUV444P && best_palette != WEED_PALETTE_YUV888)))
932 best_palette = WEED_PALETTE_YUVA8888;
934 case WEED_PALETTE_YUV888:
935 if ((mismatch || is_yuv)
936 && (!has_alpha || (best_palette != WEED_PALETTE_YUVA4444P && best_palette != WEED_PALETTE_YUVA8888)))
937 best_palette = WEED_PALETTE_YUV888;
939 case WEED_PALETTE_YUV422P:
940 case WEED_PALETTE_UYVY:
941 case WEED_PALETTE_YUYV:
942 if ((mismatch || is_yuv) && (best_palette != WEED_PALETTE_YUVA4444P && best_palette != WEED_PALETTE_YUV444P
943 && best_palette != WEED_PALETTE_YUVA8888 && best_palette != WEED_PALETTE_YUV888))
944 best_palette = palette_list[i];
946 case WEED_PALETTE_YUV420P:
947 case WEED_PALETTE_YVU420P:
948 if ((mismatch || is_yuv) && (best_palette == WEED_PALETTE_YUV411 ||
weed_palette_is_alpha(best_palette)))
949 best_palette = palette_list[i];
953 if (palette_list[i] == WEED_PALETTE_YUV411 && !is_alpha) best_palette = WEED_PALETTE_A8;
954 if (palette_list[i] == WEED_PALETTE_A8) best_palette = WEED_PALETTE_A8;
955 if (palette_list[i] == WEED_PALETTE_A1 && (best_palette != WEED_PALETTE_A8))
956 best_palette = WEED_PALETTE_A1;
962 #ifdef DEBUG_PALETTES
963 lives_printerr(
"Debug: best palette for %d is %d\n",
palette, best_palette);
970 static boolean get_fixed_channel_size(weed_plant_t *
template,
int *width,
int *height) {
971 weed_size_t nwidths = weed_leaf_num_elements(
template, WEED_LEAF_WIDTH);
972 weed_size_t nheights = weed_leaf_num_elements(
template, WEED_LEAF_HEIGHT);
973 int *heights, *widths;
975 int oheight = 0, owidth = 0;
977 if (!width || nwidths == 0) defined++;
980 *width = weed_get_int_value(
template, WEED_LEAF_WIDTH, NULL);
985 if (!height || nheights == 0) defined++;
988 *height = weed_get_int_value(
template, WEED_LEAF_HEIGHT, NULL);
992 if (defined == 2)
return TRUE;
995 if (nwidths != nheights) {
1000 widths = weed_get_int_array(
template, WEED_LEAF_WIDTH, NULL);
1001 heights = weed_get_int_array(
template, WEED_LEAF_HEIGHT, NULL);
1003 if (width) owidth = *width;
1004 if (height) oheight = *height;
1006 for (i = 0; i < nwidths; i++) {
1009 if (!width) defined++;
1012 if (*width >= owidth) defined++;
1014 if (!height) defined++;
1016 *height = heights[i];
1017 if (*height >= oheight) defined++;
1019 if (defined == 2)
return TRUE;
1025 #define MIN_CHAN_WIDTH 4
1026 #define MIN_CHAN_HEIGHT 4
1028 #define MAX_CHAN_WIDTH 16384
1029 #define MAX_CHAN_HEIGHT 16384
1046 static void set_channel_size(weed_plant_t *filter, weed_plant_t *channel,
int width,
int height) {
1048 boolean check_ctmpl =
FALSE;
1057 if (filter_flags & WEED_FILTER_CHANNEL_SIZES_MAY_VARY) {
1061 if (check_ctmpl && weed_plant_has_leaf(chantmpl, WEED_LEAF_WIDTH)) {
1062 get_fixed_channel_size(chantmpl, &width, &height);
1064 if (weed_plant_has_leaf(filter, WEED_LEAF_WIDTH)) {
1065 get_fixed_channel_size(filter, &width, &height);
1070 if (weed_plant_has_leaf(filter, WEED_LEAF_HSTEP)) {
1071 width =
ALIGN_CEIL(width, weed_get_int_value(filter, WEED_LEAF_HSTEP, NULL));
1075 if (check_ctmpl && weed_plant_has_leaf(chantmpl, WEED_LEAF_MAXWIDTH)) {
1076 max = weed_get_int_value(chantmpl, WEED_LEAF_MAXWIDTH, NULL);
1077 if (max > 0 && width > max) width = max;
1078 }
else if (weed_plant_has_leaf(filter, WEED_LEAF_MAXWIDTH)) {
1079 max = weed_get_int_value(filter, WEED_LEAF_MAXWIDTH, NULL);
1080 if (width > max) width = max;
1082 if (check_ctmpl && weed_plant_has_leaf(chantmpl, WEED_LEAF_MINWIDTH)) {
1083 min = weed_get_int_value(chantmpl, WEED_LEAF_MINWIDTH, NULL);
1084 if (min > 0 && width < min) width = min;
1085 }
else if (weed_plant_has_leaf(filter, WEED_LEAF_MINWIDTH)) {
1086 min = weed_get_int_value(filter, WEED_LEAF_MINWIDTH, NULL);
1087 if (width < min) width = min;
1095 width = (width >> 1) << 1;
1096 weed_set_int_value(channel, WEED_LEAF_WIDTH, width);
1098 if (check_ctmpl && weed_plant_has_leaf(chantmpl, WEED_LEAF_HEIGHT)) {
1099 get_fixed_channel_size(chantmpl, &width, &height);
1101 if (weed_plant_has_leaf(filter, WEED_LEAF_HEIGHT)) {
1102 get_fixed_channel_size(filter, &width, &height);
1107 if (weed_plant_has_leaf(filter, WEED_LEAF_VSTEP)) {
1108 height =
ALIGN_CEIL(height, weed_get_int_value(filter, WEED_LEAF_VSTEP, NULL));
1112 if (check_ctmpl && weed_plant_has_leaf(chantmpl, WEED_LEAF_MAXHEIGHT)) {
1113 max = weed_get_int_value(chantmpl, WEED_LEAF_MAXHEIGHT, NULL);
1114 if (max > 0 && height > max) height = max;
1115 }
else if (weed_plant_has_leaf(filter, WEED_LEAF_MAXHEIGHT)) {
1116 max = weed_get_int_value(filter, WEED_LEAF_MAXHEIGHT, NULL);
1117 if (height > max) height = max;
1119 if (check_ctmpl && weed_plant_has_leaf(chantmpl, WEED_LEAF_MINHEIGHT)) {
1120 min = weed_get_int_value(chantmpl, WEED_LEAF_MINHEIGHT, NULL);
1121 if (min > 0 && height < min) height = min;
1122 }
else if (weed_plant_has_leaf(filter, WEED_LEAF_MINHEIGHT)) {
1123 min = weed_get_int_value(filter, WEED_LEAF_MINHEIGHT, NULL);
1124 if (height < min) height = min;
1131 height = (height >> 1) << 1;
1132 weed_set_int_value(channel, WEED_LEAF_HEIGHT, height);
1138 for (i = 0; array[i]; i++) {
1139 if (set_readonly)
weed_add_plant_flags(array[i], WEED_FLAG_IMMUTABLE | WEED_FLAG_UNDELETABLE,
"plugin_");
1149 weed_plant_t *plugin_info;
1153 else plugin_info = weed_get_plantptr_value(filter, WEED_LEAF_PLUGIN_INFO, NULL);
1155 ret = lives_get_current_dir();
1171 weed_plant_t *filter, *orig_inst = inst;
1174 boolean deinit_first =
FALSE;
1175 weed_error_t retval;
1186 if (weed_get_int_value(gui, WEED_LEAF_EASE_OUT, NULL) > 0) {
1188 uint64_t new_rte =
GU641 << (key);
1210 if (weed_plant_has_leaf(filter, WEED_LEAF_INIT_FUNC)) {
1211 weed_init_f init_func = (weed_init_f)weed_get_funcptr_value(filter, WEED_LEAF_INIT_FUNC, NULL);
1215 retval = (*init_func)(inst);
1226 LiVESWidget *textwidget =
1248 if (retval != WEED_SUCCESS) {
1259 if (!deinit_first) {
1276 if (reinit_compound) {
1278 if (inst)
goto reinit;
1284 return filter_error;
1291 weed_plant_t *instance, *last_inst, *next_inst;
1302 last_inst = instance;
1324 static void *thread_process_func(
void *arg) {
1325 struct _procvals *procvals = (
struct _procvals *)arg;
1326 procvals->ret = (*procvals->procfunc)(procvals->inst, procvals->tc);
1331 #define SLICE_ALIGN 2
1335 struct _procvals *procvals;
1337 weed_plant_t **xinst = NULL;
1338 weed_plant_t **xchannels, *xchan;
1340 weed_error_t retval;
1345 weed_plant_t **out_channels = weed_get_plantptr_array_counted(inst, WEED_LEAF_OUT_CHANNELS, &nchannels);
1346 boolean plugin_invalid =
FALSE;
1347 boolean filter_invalid =
FALSE;
1348 boolean needs_reinit =
FALSE;
1351 int slices, slices_per_thread, to_use;
1352 int heights[2], *xheights;
1354 int dheight, height, xheight = 0, cheight;
1359 weed_process_f process_func = (weed_process_f)weed_get_funcptr_value(filter, WEED_LEAF_PROCESS_FUNC, NULL);
1362 if (weed_plant_has_leaf(filter, WEED_LEAF_VSTEP)) {
1363 minh = weed_get_int_value(filter, WEED_LEAF_VSTEP, NULL);
1364 if (minh > vstep) vstep = minh;
1367 for (i = 0; i < nchannels; i++) {
1374 cheight = height * vrt;
1375 if (xheight == 0 || cheight < xheight) xheight = cheight;
1382 slices = xheight / vstep;
1385 to_use =
ALIGN_CEIL(slices, slices_per_thread) / slices_per_thread;
1388 procvals = (
struct _procvals *)
lives_calloc(to_use,
sizeof(
struct _procvals));
1389 procvals->ret = WEED_SUCCESS;
1390 xinst = (weed_plant_t **)
lives_calloc(to_use,
sizeof(weed_plant_t *));
1393 for (i = 0; i < nchannels; i++) {
1394 heights[1] = height = weed_get_int_value(out_channels[i], WEED_LEAF_HEIGHT, NULL);
1395 slices = height / vstep;
1396 slices_per_thread =
CEIL((
double)slices / (
double)to_use, 1.);
1397 dheight = slices_per_thread * vstep;
1398 heights[0] = dheight;
1399 weed_set_int_value(out_channels[i], WEED_LEAF_OFFSET, 0);
1400 weed_set_int_array(out_channels[i], WEED_LEAF_HEIGHT, 2, heights);
1403 for (j = 0; j < to_use; j++) {
1409 if (j < to_use - 1) {
1411 xinst[j] = weed_plant_copy(inst);
1413 xchannels = (weed_plant_t **)
lives_calloc(nchannels,
sizeof(weed_plant_t *));
1419 for (i = 0; i < nchannels; i++) {
1420 if (j < to_use - 1) {
1421 xchan = xchannels[i] = weed_plant_copy(out_channels[i]);
1423 xchan = out_channels[i];
1425 xheights = weed_get_int_array(out_channels[i], WEED_LEAF_HEIGHT, NULL);
1426 height = xheights[1];
1427 dheight = xheights[0];
1428 offset = dheight * j;
1429 if ((height - offset) < dheight) dheight = height - offset;
1430 xheights[0] = dheight;
1431 weed_set_int_value(xchan, WEED_LEAF_OFFSET, offset);
1432 weed_set_int_array(xchan, WEED_LEAF_HEIGHT, 2, xheights);
1436 if (j < to_use - 1) {
1437 weed_set_plantptr_array(xinst[j], WEED_LEAF_OUT_CHANNELS, nchannels, xchannels);
1441 procvals[j].procfunc = process_func;
1442 procvals[j].inst = xinst[j];
1443 procvals[j].tc = tc;
1445 if (j < to_use - 1) {
1451 (*thread_process_func)(&procvals[j]);
1452 retval = procvals[j].ret;
1453 if (retval == WEED_ERROR_PLUGIN_INVALID) plugin_invalid =
TRUE;
1454 if (retval == WEED_ERROR_FILTER_INVALID) filter_invalid =
TRUE;
1455 if (retval == WEED_ERROR_REINIT_NEEDED) needs_reinit =
TRUE;
1460 for (j = 0; j < nthreads; j++) {
1462 retval = procvals[j].ret;
1463 if (retval == WEED_ERROR_PLUGIN_INVALID) plugin_invalid =
TRUE;
1464 if (retval == WEED_ERROR_FILTER_INVALID) filter_invalid =
TRUE;
1465 if (retval == WEED_ERROR_REINIT_NEEDED) needs_reinit =
TRUE;
1467 xchannels = weed_get_plantptr_array(xinst[j], WEED_LEAF_OUT_CHANNELS, NULL);
1468 for (i = 0; i < nchannels; i++) {
1469 weed_plant_free(xchannels[i]);
1472 weed_plant_free(xinst[j]);
1475 for (i = 0; i < nchannels; i++) {
1477 xheights = weed_get_int_array(out_channels[i], WEED_LEAF_HEIGHT, NULL);
1478 weed_set_int_value(out_channels[i], WEED_LEAF_HEIGHT, xheights[1]);
1480 weed_leaf_delete(out_channels[i], WEED_LEAF_OFFSET);
1496 static lives_filter_error_t check_cconx(weed_plant_t *inst,
int nchans,
boolean *needs_reinit) {
1497 weed_plant_t **in_channels;
1505 }
else mode = key_modes[key];
1517 in_channels = weed_get_plantptr_array(inst, WEED_LEAF_IN_CHANNELS, NULL);
1519 for (
int i = 0; i < nchans; i++) {
1520 if (!
weed_palette_is_alpha(weed_get_int_value(in_channels[i], WEED_LEAF_CURRENT_PALETTE, NULL)))
continue;
1526 if (!weed_get_voidptr_value(in_channels[i], WEED_LEAF_PIXEL_DATA, NULL)) {
1527 weed_plant_t *chantmpl = weed_get_plantptr_value(in_channels[i], WEED_LEAF_TEMPLATE, NULL);
1529 if (weed_get_boolean_value(in_channels[i], WEED_LEAF_DISABLED, NULL) == WEED_FALSE)
1586 int opwidth,
int opheight, weed_timecode_t tc) {
1591 weed_plant_t **in_channels = NULL, **out_channels = NULL, *channel, *chantmpl;
1592 weed_plant_t **in_ctmpls;
1593 weed_plant_t *def_channel = NULL;
1597 int *in_tracks, *out_tracks;
1606 boolean rowstrides_changed;
1607 boolean needs_reinit =
FALSE, inplace =
FALSE;
1608 boolean all_out_alpha =
TRUE;
1610 boolean resized =
FALSE, letterboxed =
FALSE;
1611 boolean letterbox =
FALSE;
1613 int num_palettes, num_in_tracks = 0, num_out_tracks;
1614 int inwidth, inheight, inpalette, outpalette, opalette, channel_flags, filter_flags = 0;
1615 int palette, cpalette, def_palette = 0;
1616 int outwidth, outheight;
1617 int numplanes = 0, width, height, xwidth, xheight;
1619 int maxinwidth = 4, maxinheight = 4, mininwidth = -1, mininheight = -1;
1620 int iclamping, isampling, isubspace;
1623 int num_ctmpl, num_inc, num_outc;
1624 int osubspace = -1, osampling = -1, oclamping = -1;
1625 int num_in_alpha = 0, num_out_alpha = 0;
1643 maxinwidth = opwidth;
1645 maxinheight = opheight;
1648 out_channels = weed_get_plantptr_array(inst, WEED_LEAF_OUT_CHANNELS, NULL);
1656 filter_flags = weed_get_int_value(filter, WEED_LEAF_FLAGS, NULL);
1665 in_channels = weed_get_plantptr_array(inst, WEED_LEAF_IN_CHANNELS, NULL);
1669 if ((!out_channels && weed_plant_has_leaf(inst, WEED_LEAF_OUT_PARAMETERS)) ||
1670 (all_outs_alpha(filter,
TRUE))) {
1673 pdata = weed_get_voidptr_value(channel, WEED_LEAF_PIXEL_DATA, NULL);
1679 weed_set_int_value(channel, WEED_LEAF_WIDTH, width);
1680 weed_set_int_value(channel, WEED_LEAF_HEIGHT, height);
1682 set_channel_size(filter, channel, width, height);
1684 if (weed_plant_has_leaf(filter, WEED_LEAF_ALIGNMENT_HINT)) {
1685 int rowstride_alignment_hint = weed_get_int_value(filter, WEED_LEAF_ALIGNMENT_HINT, NULL);
1686 if (rowstride_alignment_hint >
ALIGN_DEF)
1687 THREADVAR(rowstride_alignment_hint) = rowstride_alignment_hint;
1733 num_inc = weed_leaf_num_elements(inst, WEED_LEAF_IN_CHANNELS);
1735 for (i = 0; i < num_inc; i++) {
1737 weed_get_boolean_value(in_channels[i], WEED_LEAF_DISABLED, NULL) == WEED_FALSE)
1741 num_inc -= num_in_alpha;
1743 retval = check_cconx(inst, num_inc + num_in_alpha, &needs_reinit);
1748 if (num_in_tracks > num_inc) num_in_tracks = num_inc;
1751 if (num_inc > num_in_tracks) {
1752 for (i = num_in_tracks; i < num_inc + num_in_alpha; i++) {
1754 if (weed_get_boolean_value(in_channels[i], WEED_LEAF_DISABLED, NULL) == WEED_FALSE)
1762 while (layers[lcount]) lcount++;
1764 for (k = i = 0; i < num_in_tracks; i++) {
1765 if (in_tracks[i] < 0) {
1772 channel = in_channels[k];
1775 if (in_tracks[i] >= lcount) {
1778 for (j = k; j < num_in_tracks + num_in_alpha; j++) {
1780 channel = in_channels[j];
1781 chantmpl = weed_get_plantptr_value(channel, WEED_LEAF_TEMPLATE, NULL);
1783 if (weed_get_boolean_value(channel, WEED_LEAF_DISABLED, NULL) == WEED_FALSE)
1793 layer = layers[in_tracks[i]];
1795 if (!weed_get_voidptr_value(layer, WEED_LEAF_PIXEL_DATA, NULL)) {
1805 channel = in_channels[k];
1806 chantmpl = weed_get_plantptr_value(channel, WEED_LEAF_TEMPLATE, NULL);
1808 if (weed_get_boolean_value(channel, WEED_LEAF_DISABLED, NULL) == WEED_FALSE)
1822 in_ctmpls = weed_get_plantptr_array_counted(filter, WEED_LEAF_IN_CHANNEL_TEMPLATES, &num_ctmpl);
1825 for (i = 0; i < num_inc + num_in_alpha; i++) {
1827 if (weed_get_boolean_value(in_channels[i], WEED_LEAF_DISABLED, NULL) == WEED_TRUE ||
1830 for (j = 0; j < num_ctmpl; j++) {
1832 if (chantmpl == in_ctmpls[j]) {
1839 for (j = 0; j < num_ctmpl; j++) {
1854 num_outc = weed_leaf_num_elements(inst, WEED_LEAF_OUT_CHANNELS);
1856 for (i = 0; i < num_outc; i++) {
1858 if (weed_get_boolean_value(out_channels[i], WEED_LEAF_DISABLED, NULL) == WEED_FALSE)
1861 if (weed_get_boolean_value(out_channels[i], WEED_LEAF_DISABLED, NULL) == WEED_FALSE &&
1868 if (!init_event ||
num_compound_fx(inst) > 1) num_out_tracks -= num_out_alpha;
1870 if (num_out_tracks < 0) num_out_tracks = 0;
1872 if (nmandout > num_out_tracks) {
1881 for (i = 0; i < num_out_tracks + num_out_alpha; i++) {
1882 if (i >= num_outc)
continue;
1883 channel = out_channels[i];
1886 if (weed_get_boolean_value(channel, WEED_LEAF_DISABLED, NULL) == WEED_TRUE ||
1888 all_out_alpha =
FALSE;
1891 for (j = i = 0; i < num_in_tracks; i++) {
1893 if (weed_get_boolean_value(in_channels[j], WEED_LEAF_DISABLED, NULL) == WEED_TRUE ||
1898 layer = layers[in_tracks[i]];
1905 #define FX_WAIT_LIM 10000 // microseconds * 10
1924 if (clip ==
mainw->
scrap_file && num_in_tracks <= 1 && num_out_tracks <= 1) {
1933 if (filter_flags & WEED_FILTER_CHANNEL_SIZES_MAY_VARY) svary =
TRUE;
1934 if (filter_flags & WEED_FILTER_IS_CONVERTER) is_converter =
TRUE;
1936 if (maxinwidth == 4 && inwidth > 4) maxinwidth = inwidth;
1937 if (maxinheight == 4 && inheight > 4) maxinheight = inheight;
1951 if (inwidth >= maxinwidth && inheight >= maxinheight) {
1952 maxinwidth = inwidth;
1953 maxinheight = inheight;
1956 if (inwidth > maxinwidth) maxinwidth = inwidth;
1957 if (inheight > maxinheight) maxinheight = inheight;
1961 if (mininwidth == -1 || inwidth < mininwidth) mininwidth = inwidth;
1962 if (mininheight == -1 || inheight < mininheight) mininheight = inheight;
1969 switch (pb_quality) {
1971 if (maxinwidth > opwidth) opwidth = maxinwidth;
1972 if (maxinheight > opheight) opheight = maxinheight;
1976 if (maxinwidth > opwidth || maxinheight > opheight) {
1977 calc_maxspect(opwidth, opheight, &maxinwidth, &maxinheight);
1978 opwidth = maxinwidth;
1979 opheight = maxinheight;
1981 calc_maxspect(maxinwidth, maxinheight, &opwidth, &opheight);
1984 if (maxinwidth > opwidth) maxinwidth = opwidth;
1985 if (maxinheight > opheight) maxinheight = opheight;
1986 opwidth = maxinwidth;
1987 opheight = maxinheight;
1993 if (mininwidth < opwidth || mininheight < opheight) {
1994 calc_maxspect(mininwidth, mininheight, &opwidth, &opheight);
1996 calc_maxspect(opwidth, opheight, &mininwidth, &mininheight);
1997 opwidth = mininwidth;
1998 opheight = mininheight;
2001 if (mininwidth < opwidth) opwidth = mininwidth;
2002 if (mininheight < opheight) opheight = mininheight;
2008 opwidth = (opwidth >> 1) << 1;
2009 opheight = (opheight >> 1) << 1;
2018 for (k = i = 0; k < num_inc + num_in_alpha; k++) {
2019 int owidth, oheight;
2022 if (!channel)
break;
2026 if (!def_channel) def_channel = channel;
2041 layer = layers[in_tracks[i]];
2050 if (is_converter || def_channel != channel) {
2052 inwidth = weed_get_int_value(layer, WEED_LEAF_WIDTH, NULL);
2053 inheight = weed_get_int_value(layer, WEED_LEAF_HEIGHT, NULL);
2069 if (owidth != width || oheight != height) {
2070 set_channel_size(filter, channel, width, height);
2073 if (channel_flags & WEED_CHANNEL_REINIT_ON_SIZE_CHANGE) {
2074 boolean oneeds_reinit = needs_reinit;
2075 needs_reinit =
TRUE;
2076 if (channel_flags & WEED_CHANNEL_NEEDS_NATURAL_SIZE) {
2077 int *nsizes = weed_get_int_array(channel, WEED_LEAF_NATURAL_SIZE, NULL);
2085 lnsizes = weed_get_int_array(layer, WEED_LEAF_NATURAL_SIZE, NULL);
2086 if (nsizes[0] == lnsizes[0] && nsizes[1] == lnsizes[1]) needs_reinit = oneeds_reinit;
2095 if (channel_flags & WEED_CHANNEL_NEEDS_NATURAL_SIZE) {
2097 weed_leaf_dup(channel, layer, WEED_LEAF_NATURAL_SIZE);
2139 for (i = 0; i < num_in_tracks; i++) {
2140 int tgamma = WEED_GAMMA_UNKNOWN;
2157 layer = layers[in_tracks[i]];
2168 if (filter_flags & WEED_FILTER_PALETTES_MAY_VARY) {
2172 if ((channel_flags & WEED_CHANNEL_REINIT_ON_PALETTE_CHANGE)
2173 || ((channel_flags & WEED_CHANNEL_REINIT_ON_ROWSTRIDES_CHANGE)
2177 opalette = inpalette;
2183 needs_reinit =
TRUE;
2188 if (opalette != inpalette) {
2192 if (i > 0 && !pvary &&
palette != def_palette) {
2200 if (channel_flags & WEED_CHANNEL_REINIT_ON_PALETTE_CHANGE) needs_reinit =
TRUE;
2210 if (!needs_reinit && (channel_flags & WEED_CHANNEL_REINIT_ON_PALETTE_CHANGE) != 0
2213 oclamping = iclamping;
2214 osampling = isampling;
2215 osubspace = isubspace;
2217 if (i > 0 && !pvary) {
2222 oclamping = weed_get_int_value(layer, WEED_LEAF_YUV_CLAMPING, NULL);
2225 oclamping = weed_get_int_value(def_channel, WEED_LEAF_YUV_CLAMPING, NULL);
2227 oclamping = WEED_YUV_CLAMPING_UNCLAMPED;
2229 if (pvary && weed_plant_has_leaf(chantmpl, WEED_LEAF_YUV_CLAMPING)) {
2230 oclamping = weed_get_int_value(chantmpl, WEED_LEAF_YUV_CLAMPING, NULL);
2232 if (weed_plant_has_leaf(filter, WEED_LEAF_YUV_CLAMPING)) {
2233 oclamping = weed_get_int_value(filter, WEED_LEAF_YUV_CLAMPING, NULL);
2240 osampling = weed_get_int_value(layer, WEED_LEAF_YUV_SAMPLING, NULL);
2243 osampling = weed_get_int_value(def_channel, WEED_LEAF_YUV_SAMPLING, NULL);
2245 osampling = WEED_YUV_SAMPLING_DEFAULT;
2246 if (pvary && weed_plant_has_leaf(chantmpl, WEED_LEAF_YUV_SAMPLING)) {
2247 osampling = weed_get_int_value(chantmpl, WEED_LEAF_YUV_SAMPLING, NULL);
2248 }
else if (weed_plant_has_leaf(filter, WEED_LEAF_YUV_SAMPLING)) {
2249 osampling = weed_get_int_value(filter, WEED_LEAF_YUV_SAMPLING, NULL);
2256 osubspace = weed_get_int_value(layer, WEED_LEAF_YUV_SUBSPACE, NULL);
2259 osubspace = weed_get_int_value(def_channel, WEED_LEAF_YUV_SUBSPACE, NULL);
2261 osampling = WEED_YUV_SUBSPACE_YUV;
2262 if (pvary && weed_plant_has_leaf(chantmpl, WEED_LEAF_YUV_SUBSPACE)) {
2263 osubspace = weed_get_int_value(chantmpl, WEED_LEAF_YUV_SUBSPACE, NULL);
2265 if (weed_plant_has_leaf(filter, WEED_LEAF_YUV_SUBSPACE)) {
2266 osubspace = weed_get_int_value(filter, WEED_LEAF_YUV_SUBSPACE, NULL);
2268 osubspace = WEED_YUV_SUBSPACE_YUV;
2273 if (channel_flags & WEED_CHANNEL_REINIT_ON_PALETTE_CHANGE) {
2274 if (oclamping != iclamping || isampling != osampling || isubspace != osubspace) {
2278 : WEED_PALETTE_RGB24);
2285 needs_reinit =
TRUE;
2294 && weed_get_int_value(layer, WEED_LEAF_YUV_CLAMPING, NULL) != oclamping)) {
2321 letterboxed =
FALSE;
2328 if ((!svary && (inwidth != width || inheight != height))
2329 || (svary && (inwidth > width || inheight > height || letterbox))) {
2331 if (letterbox && !orig_layer) {
2345 if (xwidth != width || height != xheight) {
2346 if (!
letterbox_layer(layer, width, height, xwidth, xheight, interp, opalette, oclamping)) {
2351 lbvals[0] = (width - xwidth) >> 1;
2352 lbvals[1] = (height - xheight) >> 1;
2354 lbvals[3] = xheight;
2355 weed_set_int_array(channel, WEED_LEAF_INNER_SIZE, 4, lbvals);
2366 if (weed_plant_has_leaf(channel, WEED_LEAF_INNER_SIZE))
2367 weed_leaf_delete(channel, WEED_LEAF_INNER_SIZE);
2368 if (!
resize_layer(layer, width, height, interp, opalette, oclamping)) {
2382 if (weed_plant_has_leaf(channel, WEED_LEAF_INNER_SIZE))
2383 weed_leaf_delete(channel, WEED_LEAF_INNER_SIZE);
2391 if (filter_flags & WEED_FILTER_PREF_LINEAR_GAMMA)
2392 tgamma = WEED_GAMMA_LINEAR;
2394 tgamma =
cfile->gamma_type;
2397 if (cpalette != opalette) {
2414 rowstrides_changed =
rowstrides_differ(numplanes, rowstrides, nchr, channel_rows);
2418 if (rowstrides_changed && (channel_flags & WEED_CHANNEL_REINIT_ON_ROWSTRIDES_CHANGE))
2419 needs_reinit =
TRUE;
2421 if (tgamma != WEED_GAMMA_UNKNOWN) {
2426 xwidth, xheight,
TRUE);
2458 for (i = 0; i < num_out_tracks + num_out_alpha; i++) {
2462 if (!channel)
break;
2481 weed_set_int64_value(channel, WEED_LEAF_TIMECODE, tc);
2487 || (in_tracks && out_tracks && in_tracks[0] == out_tracks[0]))) {
2488 if (channel_flags & WEED_CHANNEL_CAN_DO_INPLACE) {
2524 weed_set_int_value(channel, WEED_LEAF_CURRENT_PALETTE,
palette);
2538 if (svary && is_converter) {
2550 set_channel_size(filter, channel, width, height);
2552 if (weed_plant_has_leaf(filter, WEED_LEAF_ALIGNMENT_HINT)) {
2553 int rowstride_alignment_hint = weed_get_int_value(filter, WEED_LEAF_ALIGNMENT_HINT, NULL);
2554 if (rowstride_alignment_hint >
ALIGN_DEF) {
2555 THREADVAR(rowstride_alignment_hint) = rowstride_alignment_hint;
2565 if (filter_flags & WEED_FILTER_PREF_LINEAR_GAMMA)
2581 rowstrides_changed =
rowstrides_differ(nchr, channel_rows, numplanes, rowstrides);
2589 if ((rowstrides_changed && (channel_flags & WEED_CHANNEL_REINIT_ON_ROWSTRIDES_CHANGE))) needs_reinit =
TRUE;
2591 if ((outwidth != width || outheight != height) && (channel_flags & WEED_CHANNEL_REINIT_ON_SIZE_CHANGE))
2592 needs_reinit =
TRUE;
2595 && (oclamping != iclamping || osampling != isampling || osubspace != isubspace)))
2596 if (channel_flags & WEED_CHANNEL_REINIT_ON_PALETTE_CHANGE) needs_reinit =
TRUE;
2610 ? WEED_GAMMA_LINEAR : WEED_GAMMA_SRGB, inst,
TRUE);
2612 ? WEED_GAMMA_LINEAR : WEED_GAMMA_SRGB, inst,
FALSE);
2616 weed_set_double_value(inst, WEED_LEAF_FPS,
cfile->pb_fps);
2634 if (retval == WEED_ERROR_REINIT_NEEDED) {
2635 needs_reinit =
TRUE;
2638 for (k = 0; k < num_inc + num_in_alpha; k++) {
2642 layer = layers[in_tracks[k]];
2654 for (i = k = 0; k < num_out_tracks + num_out_alpha; k++) {
2656 if (!channel)
break;
2658 layer = layers[out_tracks[i]];
2659 weed_set_boolean_value(layer,
"letterboxed", letterbox);
2682 for (i = 0; i < num_inc + num_in_alpha; i++) {
2684 weed_set_boolean_value(in_channels[i], WEED_LEAF_DISABLED, WEED_FALSE);
2691 for (i = 0; i < num_in_tracks; i++) {
2693 layer = layers[in_tracks[i]];
2711 static lives_filter_error_t enable_disable_channels(weed_plant_t *inst,
boolean is_in,
int *tracks,
int num_tracks,
2713 weed_plant_t **layers) {
2717 weed_plant_t *channel, **channels, *chantmpl, **ctmpls = NULL, *layer;
2718 int maxcheck = num_tracks, i, j, num_ctmpls, num_channels;
2719 void **pixdata = NULL;
2723 channels = weed_get_plantptr_array_counted(inst, WEED_LEAF_IN_CHANNELS, &num_channels);
2725 channels = weed_get_plantptr_array_counted(inst, WEED_LEAF_OUT_CHANNELS, &num_channels);
2727 if (num_tracks > num_channels) maxcheck = num_tracks = num_channels;
2728 if (num_channels > num_tracks) maxcheck = num_channels;
2730 for (i = 0; i < maxcheck; i++) {
2731 channel = channels[i];
2736 if (i < num_tracks) layer = layers[tracks[i] + nbtracks];
2763 if (num_ctmpls > 0) {
2766 for (i = 0; i < num_channels; i++) {
2770 for (j = 0; j < num_ctmpls; j++) {
2771 if (chantmpl == ctmpls[j]) {
2801 weed_process_f process_func;
2803 boolean did_thread =
FALSE;
2804 int filter_flags = weed_get_int_value(filter, WEED_LEAF_FLAGS, NULL);
2809 weed_mem_chkreg(wee_channel_get_pdt, rs, ht, npl);
2814 filter_flags & WEED_FILTER_HINT_MAY_THREAD) {
2817 retval = process_func_threaded(instance, tc);
2825 process_func = (weed_process_f)weed_get_funcptr_value(filter, WEED_LEAF_PROCESS_FUNC, NULL);
2827 weed_error_t ret = (*process_func)(instance, tc);
2834 weed_mem_chkreg(NULL, NULL, 0, 0);
2845 static lives_filter_error_t weed_apply_audio_instance_inner(weed_plant_t *inst, weed_plant_t *init_event,
2846 weed_plant_t **layers, weed_timecode_t tc,
int nbtracks) {
2854 int *in_tracks = NULL, *out_tracks = NULL;
2857 weed_plant_t **in_channels = NULL, **out_channels = NULL, *channel, *chantmpl;
2864 int num_in_tracks, num_out_tracks;
2896 if (num_in_tracks > num_inc) num_in_tracks = num_inc;
2898 for (i = 0; i < num_in_tracks; i++) {
2899 layer = layers[in_tracks[i] + nbtracks];
2904 weed_set_int64_value(channel, WEED_LEAF_TIMECODE, tc);
2905 weed_leaf_dup(channel, layer, WEED_LEAF_AUDIO_DATA_LENGTH);
2906 weed_leaf_dup(channel, layer, WEED_LEAF_AUDIO_RATE);
2907 weed_leaf_dup(channel, layer, WEED_LEAF_AUDIO_CHANNELS);
2910 weed_leaf_dup(channel, layer, WEED_LEAF_AUDIO_DATA);
2915 for (i = 0; i < num_out_tracks; i++) {
2916 weed_plant_t *inchan;
2918 if (out_tracks[i] != in_tracks[i]) {
2925 layer = layers[out_tracks[i] + nbtracks];
2927 weed_set_int64_value(channel, WEED_LEAF_TIMECODE, tc);
2933 if ((channel_flags & WEED_CHANNEL_CAN_DO_INPLACE)
2937 weed_leaf_dup(channel, inchan, WEED_LEAF_AUDIO_DATA);
2941 adata = (
float **)
lives_calloc(nchans,
sizeof(
float *));
2943 for (i = 0; i < nchans; i++) {
2953 weed_set_voidptr_array(channel, WEED_LEAF_AUDIO_DATA, nchans, (
void **)adata);
2957 weed_leaf_dup(channel, layer, WEED_LEAF_AUDIO_DATA_LENGTH);
2958 weed_leaf_dup(channel, layer, WEED_LEAF_AUDIO_RATE);
2959 weed_leaf_dup(channel, layer, WEED_LEAF_AUDIO_CHANNELS);
2975 for (i = 0; i < num_out_tracks; i++) {
2977 layer = layers[out_tracks[i] + nbtracks];
2978 if (weed_plant_has_leaf(channel, WEED_LEAF_AUDIO_DATA)) {
2982 adata = (
float **)weed_get_voidptr_array_counted(layer, WEED_LEAF_AUDIO_DATA, &nchans);
2983 for (j = 0; j < nchans; j++)
lives_freep((
void **)&adata[j]);
2986 weed_leaf_copy(layer, WEED_LEAF_AUDIO_DATA, channel, WEED_LEAF_AUDIO_DATA);
2990 for (i = 0; i < num_inc; i++) {
3032 int64_t nsamps,
double arate, weed_timecode_t tc,
double * vis) {
3035 weed_plant_t **in_channels = NULL, **out_channels = NULL;
3037 weed_plant_t *instance = NULL, *orig_inst, *filter;
3038 weed_plant_t *channel = NULL;
3039 weed_plant_t *ctmpl;
3041 int *in_tracks = NULL, *out_tracks = NULL;
3043 boolean needs_reinit =
FALSE;
3044 boolean was_init_event =
FALSE;
3046 int flags = 0, cflags;
3051 int numinchans = 0, numoutchans = 0, xnchans, xxnchans, xrate;
3060 instance = init_event;
3062 in_channels = weed_get_plantptr_array(instance, WEED_LEAF_IN_CHANNELS, NULL);
3063 out_channels = weed_get_plantptr_array(instance, WEED_LEAF_OUT_CHANNELS, NULL);
3066 if (!out_channels && weed_plant_has_leaf(instance, WEED_LEAF_OUT_PARAMETERS)) {
3084 in_channels = out_channels = NULL;
3093 was_init_event =
TRUE;
3129 orig_inst = instance;
3135 in_channels = weed_get_plantptr_array_counted(instance, WEED_LEAF_IN_CHANNELS, &numinchans);
3136 out_channels = weed_get_plantptr_array_counted(instance, WEED_LEAF_OUT_CHANNELS, &numoutchans);
3138 retval = enable_disable_channels(instance,
TRUE, in_tracks, ntracks, nbtracks, layers);
3146 if (flags & WEED_FILTER_AUDIO_RATES_MAY_VARY) rvary =
TRUE;
3147 if (flags & WEED_FILTER_CHANNEL_LAYOUTS_MAY_VARY) lvary =
TRUE;
3149 if (vis && vis[0] < 0. && in_tracks[0] <= -nbtracks) {
3151 if (numinchans == 1 && numoutchans == 1 && !(flags & WEED_FILTER_IS_CONVERTER)) {
3157 for (i = 0; i < numinchans; i++) {
3158 if ((channel = in_channels[i]) == NULL)
continue;
3166 if (lvary && weed_plant_has_leaf(ctmpl, WEED_LEAF_AUDIO_CHANNELS))
3167 xnchans = weed_get_int_value(ctmpl, WEED_LEAF_AUDIO_CHANNELS, NULL);
3168 else if (weed_plant_has_leaf(filter, WEED_LEAF_MAX_AUDIO_CHANNELS)) {
3169 xxnchans = weed_get_int_value(filter, WEED_LEAF_MAX_AUDIO_CHANNELS, NULL);
3170 if (xxnchans > 0 && xxnchans < nchans) xnchans = xxnchans;
3172 if (xnchans != nchans) {
3176 if (weed_get_int_value(channel, WEED_LEAF_AUDIO_CHANNELS, NULL) != nchans
3177 && (cflags & WEED_CHANNEL_REINIT_ON_LAYOUT_CHANGE))
3178 needs_reinit =
TRUE;
3179 else weed_set_int_value(channel, WEED_LEAF_AUDIO_CHANNELS, nchans);
3186 if (rvary && weed_plant_has_leaf(ctmpl, WEED_LEAF_AUDIO_RATE))
3187 xrate = weed_get_int_value(ctmpl, WEED_LEAF_AUDIO_RATE, NULL);
3188 else if (weed_plant_has_leaf(filter, WEED_LEAF_AUDIO_RATE))
3189 xrate = weed_get_int_value(filter, WEED_LEAF_AUDIO_RATE, NULL);
3190 if (arate != xrate) {
3196 if (weed_get_int_value(channel, WEED_LEAF_AUDIO_RATE, NULL) != arate) {
3197 if (cflags & WEED_CHANNEL_REINIT_ON_RATE_CHANGE) {
3198 needs_reinit =
TRUE;
3202 weed_set_int_value(channel, WEED_LEAF_AUDIO_RATE, arate);
3205 for (i = 0; i < numoutchans; i++) {
3206 if ((channel = out_channels[i]) == NULL)
continue;
3213 if (lvary && weed_plant_has_leaf(ctmpl, WEED_LEAF_AUDIO_CHANNELS))
3214 xnchans = weed_get_int_value(ctmpl, WEED_LEAF_AUDIO_CHANNELS, NULL);
3215 else if (weed_plant_has_leaf(filter, WEED_LEAF_MAX_AUDIO_CHANNELS)) {
3216 xxnchans = weed_get_int_value(filter, WEED_LEAF_MAX_AUDIO_CHANNELS, NULL);
3217 if (xxnchans > 0 && xxnchans < nchans) xnchans = xxnchans;
3219 if (xnchans != nchans) {
3223 if (weed_get_int_value(channel, WEED_LEAF_AUDIO_CHANNELS, NULL) != nchans
3224 && (cflags & WEED_CHANNEL_REINIT_ON_LAYOUT_CHANGE))
3225 needs_reinit =
TRUE;
3226 else weed_set_int_value(channel, WEED_LEAF_AUDIO_CHANNELS, nchans);
3233 if (rvary && weed_plant_has_leaf(ctmpl, WEED_LEAF_AUDIO_RATE))
3234 xrate = weed_get_int_value(ctmpl, WEED_LEAF_AUDIO_RATE, NULL);
3235 else if (weed_plant_has_leaf(filter, WEED_LEAF_AUDIO_RATE))
3236 xrate = weed_get_int_value(filter, WEED_LEAF_AUDIO_RATE, NULL);
3237 if (arate != xrate) {
3243 if (weed_get_int_value(channel, WEED_LEAF_AUDIO_RATE, NULL) != arate) {
3244 if (cflags & WEED_CHANNEL_REINIT_ON_RATE_CHANGE) {
3245 needs_reinit =
TRUE;
3249 weed_set_int_value(channel, WEED_LEAF_AUDIO_RATE, arate);
3260 if (weed_plant_has_leaf(filter, WEED_LEAF_INIT_FUNC)) {
3261 weed_init_f init_func = (weed_init_f)weed_get_funcptr_value(filter, WEED_LEAF_INIT_FUNC, NULL);
3264 if ((*init_func)(instance) != WEED_SUCCESS) {
3265 key_to_instance[key][key_modes[key]] = NULL;
3283 if (vis && (flags & WEED_FILTER_IS_CONVERTER)) {
3285 if (vmaster != -1) {
3288 double *fvols = weed_get_double_array_counted(in_params[vmaster], WEED_LEAF_VALUE, &nvals);
3289 for (i = 0; i < nvals; i++) {
3290 fvols[i] = fvols[i] * vis[in_tracks[i] + nbtracks];
3291 if (vis[in_tracks[i] + nbtracks] < 0.) fvols[i] = -fvols[i];
3294 weed_set_double_array(in_params[vmaster], WEED_LEAF_VALUE, nvals, fvols);
3303 retval2 = weed_apply_audio_instance_inner(instance, init_event, layers, tc, nbtracks);
3346 static void weed_apply_filter_map(weed_plant_t **layers, weed_plant_t *filter_map, weed_timecode_t tc,
void ***pchains) {
3347 weed_plant_t *instance, *orig_inst;
3348 weed_plant_t *init_event;
3355 weed_error_t filter_error;
3358 boolean needs_reinit;
3365 for (
int i = 0; i < num_inst; i++) {
3366 init_event = (weed_plant_t *)init_events[i];
3380 orig_inst = instance;
3400 boolean is_valid =
FALSE;
3405 filter_hash = weed_get_string_value(init_events[i],
WEED_LEAF_FILTER, NULL);
3409 int nintracks, *in_tracks = weed_get_int_array_counted(init_events[i],
WEED_LEAF_IN_TRACKS, &nintracks);
3410 for (
register int j = 0; j < nintracks; j++) {
3422 if (!is_valid)
continue;
3424 if (pchains && pchains[key]) {
3461 if (filter_error == WEED_SUCCESS && (instance =
get_next_compound_inst(instance)) != NULL)
goto apply_inst2;
3462 if (filter_error == WEED_ERROR_REINIT_NEEDED) {
3485 int opwidth,
int opheight,
void ***pchains) {
3494 weed_plant_t *filter, *instance, *orig_inst, *instance2, *layer;
3497 boolean needs_reinit;
3507 if (filter_map && layers[0]) {
3508 weed_apply_filter_map(layers, filter_map, tc, pchains);
3535 if (weed_get_int_value(gui, WEED_LEAF_EASE_OUT, NULL) > 0) {
3538 if (!weed_get_int_value(gui, WEED_LEAF_EASE_OUT_FRAMES, NULL)) {
3540 uint64_t new_rte =
GU641 << (i);
3542 if (init_events[i]) {
3546 weed_set_int_value(init_events[i], WEED_LEAF_EASE_OUT,
3547 weed_get_int_value(instance, WEED_LEAF_EASE_OUT, NULL));
3583 instance = instance2;
3592 orig_inst = instance;
3613 int xeaseval = weed_get_int_value(gui, WEED_LEAF_EASE_OUT_FRAMES, NULL), myeaseval;
3615 if (xeaseval > myeaseval) {
3616 uint64_t new_rte =
GU641 << (i);
3640 if (filter_error !=
FILTER_SUCCESS) lives_printerr(
"Render error was %d\n", filter_error);
3661 for (i = 0; layers[i]; i++) {
3666 ((weed_get_voidptr_value(layers[i], WEED_LEAF_PIXEL_DATA, NULL)) ||
3673 if (output != -1 || weed_get_int_value(layers[i],
WEED_LEAF_CLIP, NULL) == -1) {
3674 if (!weed_plant_has_leaf(layers[i], WEED_LEAF_PIXEL_DATA))
continue;
3679 if (!weed_plant_has_leaf(layers[i], WEED_LEAF_PIXEL_DATA))
continue;
3690 layer = layers[output];
3694 if (!weed_get_voidptr_value(layer, WEED_LEAF_PIXEL_DATA, NULL)) {
3697 WEED_PALETTE_END)) {
3698 char *msg =
lives_strdup_printf(
"weed_apply_effects created empty pixel_data at tc %ld, map was %p, clip = %d, frame = %d",
3699 tc, filter_map, clip, weed_get_int_value(layer,
WEED_LEAF_FRAME, NULL));
3710 double arate, weed_timecode_t tc,
double * vis) {
3711 int i, num_inst,
error;
3713 weed_plant_t *init_event, *filter;
3727 for (i = 0; i < num_inst; i++) {
3728 init_event = (weed_plant_t *)init_events[i];
3744 weed_plant_t *instance, *filter, *orig_inst, *new_inst;
3747 boolean needs_reinit;
3748 int nsamps, arate, nchans;
3753 if (!alayer)
return;
3805 instance = new_inst;
3815 orig_inst = instance;
3835 goto apply_audio_inst2;
3845 if (filter_error !=
FILTER_SUCCESS) lives_printerr(
"Render error was %d\n", filter_error);
3862 weed_plant_t *filter;
3871 idx = key_to_fx[i][key_modes[i]];
3872 filter = weed_filters[idx];
3888 weed_plant_t *filter;
3895 idx = key_to_fx[i][key_modes[i]];
3896 filter = weed_filters[idx];
3910 static int check_weed_plugin_info(weed_plant_t *plugin_info) {
3913 if (!weed_plant_has_leaf(plugin_info, WEED_LEAF_HOST_INFO))
return -1;
3914 if (!weed_plant_has_leaf(plugin_info, WEED_LEAF_VERSION))
return -2;
3915 if (!weed_plant_has_leaf(plugin_info, WEED_LEAF_FILTERS))
return -3;
3916 return weed_leaf_num_elements(plugin_info, WEED_LEAF_FILTERS);
3920 int num_in_params(weed_plant_t *plant,
boolean skip_hidden,
boolean skip_internal) {
3921 weed_plant_t **params = NULL;
3923 weed_plant_t *param;
3932 if (!(params = weed_get_plantptr_array_counted(plant, WEED_LEAF_IN_PARAMETER_TEMPLATES, &num_params)))
return 0;
3934 if (!(params = weed_get_plantptr_array_counted(plant, WEED_LEAF_IN_PARAMETERS, &num_params)))
goto nip1done;
3937 if (!skip_hidden && !skip_internal) {
3938 counted += num_params;
3942 for (i = 0; i < num_params; i++) {
3961 int num_params,
error;
3965 if (!weed_plant_has_leaf(plant, WEED_LEAF_OUT_PARAMETER_TEMPLATES) ||
3966 !weed_get_plantptr_value(plant, WEED_LEAF_OUT_PARAMETER_TEMPLATES, &
error))
return 0;
3967 num_params = weed_leaf_num_elements(plant, WEED_LEAF_OUT_PARAMETER_TEMPLATES);
3969 if (!weed_plant_has_leaf(plant, WEED_LEAF_OUT_PARAMETERS))
return 0;
3970 if (!weed_get_plantptr_value(plant, WEED_LEAF_OUT_PARAMETERS, &
error))
return 0;
3971 num_params = weed_leaf_num_elements(plant, WEED_LEAF_OUT_PARAMETERS);
3977 int palette = weed_get_int_value(chantmpl, WEED_LEAF_CURRENT_PALETTE, NULL);
3990 weed_plant_t **channels = NULL;
3991 weed_plant_t *filter;
4000 if (!weed_plant_has_leaf(plant, WEED_LEAF_IN_CHANNEL_TEMPLATES))
return 0;
4001 channels = weed_get_plantptr_array_counted(plant, WEED_LEAF_IN_CHANNEL_TEMPLATES, &num_channels);
4004 if (!weed_plant_has_leaf(plant, WEED_LEAF_IN_CHANNELS))
return 0;
4005 channels = weed_get_plantptr_array_counted(plant, WEED_LEAF_IN_CHANNELS, &num_channels);
4008 for (i = 0; i < num_channels; i++) {
4010 weed_plant_t *ctmpl = weed_get_plantptr_value(channels[i], WEED_LEAF_TEMPLATE, NULL);
4014 if (weed_get_boolean_value(channels[i], WEED_LEAF_DISABLED, NULL) == WEED_FALSE) enabled++;
4021 if (count_repeats) {
4023 weed_plant_t *chantmpl;
4025 if (is_template) chantmpl = channels[i];
4026 else chantmpl = weed_get_plantptr_value(channels[i], WEED_LEAF_TEMPLATE, NULL);
4027 if (weed_plant_has_leaf(channels[i], WEED_LEAF_MAX_REPEATS)) {
4028 if (weed_get_boolean_value(channels[i], WEED_LEAF_DISABLED, NULL) == WEED_TRUE &&
4030 repeats = weed_get_int_value(channels[i], WEED_LEAF_MAX_REPEATS, NULL) - 1;
4031 if (repeats == -1) repeats = 1000000;
4044 weed_plant_t **channels = NULL;
4046 int num_channels, i;
4050 channels = weed_get_plantptr_array_counted(plant, WEED_LEAF_OUT_CHANNEL_TEMPLATES, &num_channels);
4052 channels = weed_get_plantptr_array_counted(plant, WEED_LEAF_OUT_CHANNELS, &num_channels);
4055 for (i = 0; i < num_channels; i++) {
4057 if (weed_get_boolean_value(channels[i], WEED_LEAF_DISABLED, NULL) == WEED_FALSE) enabled++;
4061 if (count_repeats) {
4063 weed_plant_t *chantmpl;
4065 if (is_template) chantmpl = channels[i];
4066 else chantmpl = weed_get_plantptr_value(channels[i], WEED_LEAF_TEMPLATE, NULL);
4067 if (weed_plant_has_leaf(channels[i], WEED_LEAF_MAX_REPEATS)) {
4068 if (weed_get_boolean_value(channels[i], WEED_LEAF_DISABLED, NULL) == WEED_TRUE &&
4070 repeats = weed_get_int_value(channels[i], WEED_LEAF_MAX_REPEATS, NULL) - 1;
4071 if (repeats == -1) repeats = 1000000;
4085 static int min_audio_chans(weed_plant_t *plant) {
4089 ents = weed_get_int_array_counted(plant, WEED_LEAF_AUDIO_CHANNELS, &ne);
4090 if (ne == 0)
return 1;
4091 for (i = 0; i < ne; i++) {
4092 if (minas == 1 || (ents[i] > 0 && ents[i] < minas)) minas = ents[i];
4103 static int check_for_lives(weed_plant_t *filter,
int filter_idx) {
4119 weed_plant_t **array = NULL;
4121 int chans_in_mand = 0;
4122 int chans_in_opt_max = 0;
4123 int chans_out_mand = 0;
4124 int chans_out_opt_max = 0;
4125 int achans_in_mand = 0, achans_out_mand = 0;
4127 boolean is_audio =
FALSE;
4128 boolean has_out_params =
FALSE;
4129 boolean all_out_alpha =
TRUE;
4130 boolean hidden =
FALSE;
4134 int num_elements, i;
4135 int naudins = 0, naudouts = 0;
4136 int filter_achans = 0;
4140 if (!weed_plant_has_leaf(filter, WEED_LEAF_NAME))
return 1;
4142 if (!weed_plant_has_leaf(filter, WEED_LEAF_VERSION))
return 3;
4143 if (!weed_plant_has_leaf(filter, WEED_LEAF_PROCESS_FUNC))
return 4;
4148 if (flags & WEED_FILTER_NON_REALTIME)
return 5;
4149 if (flags & WEED_FILTER_CHANNEL_LAYOUTS_MAY_VARY) cvary =
TRUE;
4150 if (flags & WEED_FILTER_PALETTES_MAY_VARY) pvary =
TRUE;
4155 for (i = 0; i < num_elements; i++) {
4156 if (!weed_plant_has_leaf(array[i], WEED_LEAF_NAME)) {
4163 if (filter_achans == 0) {
4164 filter_achans = min_audio_chans(filter);
4169 if (!cvary && (ctachans = min_audio_chans(array[i])) > 0)
4170 naudins += ctachans;
4171 else naudins += filter_achans;
4179 else pkstr = lives_strdup(
"");
4181 "as it requires at least %d input audio channels\n",
4182 filtname, pkstr, naudins);
4195 if (!weed_plant_has_leaf(filter, WEED_LEAF_PALETTE_LIST)) {
4196 if (!pvary || !weed_plant_has_leaf(array[i], WEED_LEAF_PALETTE_LIST)) {
4201 if (!weed_plant_has_leaf(array[i], WEED_LEAF_PALETTE_LIST))
4202 weed_leaf_copy(array[i], WEED_LEAF_PALETTE_LIST, filter, WEED_LEAF_PALETTE_LIST);
4212 if (!is_audio) chans_in_mand++;
4213 else achans_in_mand++;
4218 if (num_elements > 0)
lives_freep((
void **)&array);
4219 if (chans_in_mand > 2) {
4227 else pkstr = lives_strdup(
"");
4229 "as it requires at least %d input video channels\n",
4230 filtname, pkstr, chans_in_mand);
4237 if (achans_in_mand > 0 && chans_in_mand > 0)
return 13;
4242 for (i = 0; i < num_elements; i++) {
4243 if (!weed_plant_has_leaf(array[i], WEED_LEAF_NAME)) {
4250 if (!cvary && (ctachans = min_audio_chans(array[i])) > 0)
4251 naudouts += ctachans;
4252 else naudouts += filter_achans;
4260 if (naudins == 1 && naudouts == 2) {
4269 if (!weed_plant_has_leaf(filter, WEED_LEAF_PALETTE_LIST)) {
4270 if (!pvary || !weed_plant_has_leaf(array[i], WEED_LEAF_PALETTE_LIST)) {
4275 if (!weed_plant_has_leaf(array[i], WEED_LEAF_PALETTE_LIST))
4276 weed_leaf_copy(array[i], WEED_LEAF_PALETTE_LIST, filter, WEED_LEAF_PALETTE_LIST);
4282 chans_out_opt_max++;
4289 }
else achans_out_mand++;
4293 if (num_elements > 0)
lives_freep((
void **)&array);
4294 if (weed_plant_has_leaf(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES)) has_out_params =
TRUE;
4296 if ((chans_out_mand > 1 && !all_out_alpha) || ((chans_out_mand + chans_out_opt_max + achans_out_mand < 1)
4297 && (!has_out_params))) {
4300 if (achans_out_mand > 1 || (achans_out_mand == 1 && chans_out_mand > 0))
return 14;
4301 if (achans_in_mand >= 1 && achans_out_mand == 0 && !(has_out_params))
return 15;
4304 if (weed_plant_has_leaf(filter, WEED_LEAF_GUI)) {
4305 weed_plant_t *gui = weed_get_plantptr_value(filter, WEED_LEAF_GUI, NULL);
4307 if (weed_get_boolean_value(gui, WEED_LEAF_HIDDEN, NULL) == WEED_TRUE) {
4312 if (hidden || (flags & WEED_FILTER_IS_CONVERTER)) {
4318 cand->
list = lives_list_append(cand->
list, LIVES_INT_TO_POINTER(filter_idx));
4323 if (chans_in_mand == 1 && chans_out_mand == 1) {
4324 if ((flags & WEED_FILTER_IS_CONVERTER) && (flags & WEED_FILTER_CHANNEL_SIZES_MAY_VARY)) {
4327 cand->
list = lives_list_append(cand->
list, LIVES_INT_TO_POINTER(filter_idx));
4344 if (err == WEED_ERROR_UNDELETABLE) {
4362 if (err == WEED_ERROR_UNDELETABLE) {
4365 if (err != WEED_SUCCESS) abort();
4372 weed_size_t num_elems,
void *values) {
4380 }
while (err == WEED_ERROR_CONCURRENCY);
4381 if (err == WEED_ERROR_IMMUTABLE) {
4382 int32_t flags = weed_leaf_get_flags(plant, key);
4383 flags ^= WEED_FLAG_IMMUTABLE;
4384 weed_leaf_set_flags(plant, key, flags);
4386 flags |= WEED_FLAG_IMMUTABLE;
4387 weed_leaf_set_flags(plant, key, flags);
4398 static void upd_statsplant(
const char *key) {
4401 if (!statsplant) statsplant = weed_plant_new(0);
4410 void *p = malloc(size);
4411 fprintf(stderr,
"plugin mallocing %ld bytes, got ptr %p\n", size, p);
4412 if (size == 1024)
break_me(
"monitor_malloc");
4428 if (
WEED_PLANT_IS_GUI(plant) && !strcmp(key, WEED_LEAF_FLAGS)) g_print(
"Err was %d\n", err);
4441 upd_statsplant(key);
4446 static void **dta = NULL;
4447 static int *rws = NULL;
4449 static int npls = 0;
4451 void weed_mem_chkreg(
void **data,
int *rs,
int height,
int nplanes) {
4459 void *lives_memcpy_monitor(
void *d,
const void *s,
size_t sz) {
4461 for (
int i = 0; i < npls; i++) {
4462 void *end = dta[i] + rws[i] * ht;
4463 if (d > end && d - end < 8) fprintf(stderr,
"pl overwrite\n");
4471 upd_statsplant(key);
4477 LiVESList *freq = NULL, *sorted = NULL, *list;
4479 int val, i, added = 0, min, lmin = 0;
4480 weed_size_t nleaves;
4482 if (!statsplant)
return;
4483 leaves = weed_plant_list_leaves(statsplant, &nleaves);
4485 for (i = 0; i < nleaves; i++) {
4486 int f = weed_get_int_value(statsplant, leaves[i], NULL);
4487 freq = lives_list_prepend(freq, LIVES_INT_TO_POINTER(f));
4490 while (added < nleaves) {
4491 min = LIVES_MAXINT32;
4492 for (list = freq; list; list = list->next) {
4493 val = LIVES_POINTER_TO_INT(list->data);
4494 if (val < min && val > lmin) min = val;
4498 for (list = freq; list; list = list->next) {
4499 val = LIVES_POINTER_TO_INT(list->data);
4502 sorted = lives_list_prepend(sorted, LIVES_INT_TO_POINTER(i));
4503 if (++added == nleaves)
break;
4507 if (min == lmin)
break;
4510 for (list = sorted; list; list = list->next) {
4511 val = LIVES_POINTER_TO_INT(list->data);
4512 g_print(
"STATS: %s : %d\n", leaves[val], weed_get_int_value(statsplant, leaves[val], NULL));
4516 lives_list_free(freq);
4517 lives_list_free(sorted);
4518 weed_plant_free(statsplant);
4525 int id = LIVES_POINTER_TO_INT(data);
4527 int lib_weed_version = 0;
4528 int lib_filter_version = 0;
4532 our_plugin_id = 100;
4539 if (
id != 100 && ncbcalls > 1) {
4547 expected_hi = xhost_info;
4549 if (
id == our_plugin_id) {
4565 if (weed_plant_has_leaf(xhost_info, WEED_LEAF_WEED_ABI_VERSION)) {
4566 lib_weed_version = weed_get_int_value(xhost_info, WEED_LEAF_WEED_ABI_VERSION, NULL);
4572 weed_set_int_value(xhost_info, WEED_LEAF_WEED_ABI_VERSION,
weed_abi_version);
4574 if (weed_plant_has_leaf(xhost_info, WEED_LEAF_FILTER_API_VERSION)) {
4575 lib_filter_version = weed_get_int_value(xhost_info, WEED_LEAF_FILTER_API_VERSION, NULL);
4576 if (lib_filter_version > WEED_FILTER_API_VERSION)
4577 weed_set_int_value(xhost_info, WEED_LEAF_FILTER_API_VERSION, WEED_FILTER_API_VERSION);
4581 if (weed_plant_has_leaf(xhost_info, WEED_LEAF_PLUGIN_INFO)) {
4583 weed_plant_t *plugin_info = weed_get_plantptr_value(xhost_info, WEED_LEAF_PLUGIN_INFO, NULL);
4584 int pl_max_weed_abi, pl_max_filter_api;
4586 expected_pi = plugin_info;
4591 if (weed_plant_has_leaf(plugin_info, WEED_LEAF_MAX_WEED_ABI_VERSION)) {
4592 pl_max_weed_abi = weed_get_int_value(plugin_info, WEED_LEAF_MAX_WEED_ABI_VERSION, NULL);
4594 if (pl_max_weed_abi < weed_abi_version && pl_max_weed_abi >= 110) {
4595 weed_set_int_value(xhost_info, WEED_LEAF_WEED_ABI_VERSION, pl_max_weed_abi);
4602 if (weed_plant_has_leaf(plugin_info, WEED_LEAF_MAX_WEED_API_VERSION)) {
4603 pl_max_filter_api = weed_get_int_value(plugin_info, WEED_LEAF_MAX_FILTER_API_VERSION, NULL);
4605 if (pl_max_filter_api < WEED_FILTER_API_VERSION && pl_max_filter_api >= 110) {
4606 weed_set_int_value(xhost_info, WEED_LEAF_FILTER_API_VERSION, pl_max_filter_api);
4614 #ifndef USE_STD_MEMFUNCS
4617 weed_set_funcptr_value(xhost_info, WEED_LEAF_MALLOC_FUNC, (weed_funcptr_t)
_ext_malloc);
4618 weed_set_funcptr_value(xhost_info, WEED_LEAF_FREE_FUNC, (weed_funcptr_t)
_ext_free);
4619 weed_set_funcptr_value(xhost_info, WEED_LEAF_REALLOC_FUNC, (weed_funcptr_t)
_ext_realloc);
4620 weed_set_funcptr_value(xhost_info, WEED_LEAF_CALLOC_FUNC, (weed_funcptr_t)
_ext_calloc);
4622 weed_set_funcptr_value(xhost_info, WEED_LEAF_MALLOC_FUNC, (weed_funcptr_t)
lives_malloc);
4623 weed_set_funcptr_value(xhost_info, WEED_LEAF_FREE_FUNC, (weed_funcptr_t)
lives_free);
4624 weed_set_funcptr_value(xhost_info, WEED_LEAF_REALLOC_FUNC, (weed_funcptr_t)
lives_realloc);
4625 weed_set_funcptr_value(xhost_info, WEED_LEAF_CALLOC_FUNC, (weed_funcptr_t)
lives_calloc);
4628 weed_set_funcptr_value(xhost_info, WEED_LEAF_MEMCPY_FUNC, (weed_funcptr_t)
lives_memcpy);
4629 weed_set_funcptr_value(xhost_info, WEED_LEAF_MEMSET_FUNC, (weed_funcptr_t)
lives_memset);
4630 weed_set_funcptr_value(xhost_info, WEED_LEAF_MEMMOVE_FUNC, (weed_funcptr_t)
lives_memmove);
4638 weed_set_funcptr_value(xhost_info, WEED_LEAF_SET_FUNC, (weed_funcptr_t)
_weed_leaf_set);
4639 weed_set_funcptr_value(xhost_info, WEED_LEAF_DELETE_FUNC, (weed_funcptr_t)
_weed_leaf_delete);
4640 weed_set_funcptr_value(xhost_info, WEED_PLANT_FREE_FUNC, (weed_funcptr_t)
_weed_plant_free);
4643 weed_set_string_value(xhost_info, WEED_LEAF_HOST_NAME,
"LiVES");
4644 weed_set_string_value(xhost_info, WEED_LEAF_HOST_VERSION, LiVES_VERSION);
4646 weed_set_string_value(xhost_info, WEED_LEAF_LAYOUT_SCHEMES,
"rfx");
4648 weed_set_int_value(xhost_info, WEED_LEAF_FLAGS, WEED_HOST_SUPPORTS_LINEAR_GAMMA
4649 | WEED_HOST_SUPPORTS_PREMULTIPLIED_ALPHA);
4651 if (fxname && !strcmp(fxname,
"projectM")) {
4655 weed_set_int_value(xhost_info, WEED_LEAF_VERBOSITY, WEED_VERBOSITY_WARN);
4664 static void gen_hashnames(
int i,
int j) {
4665 hashnames[i][0].string = NULL;
4668 hashnames[i][1].string = NULL;
4671 hashnames[i][2].string = NULL;
4674 hashnames[i][3].string = NULL;
4678 hashnames[i][4].string = NULL;
4681 hashnames[i][5].string = NULL;
4684 hashnames[i][6].string = NULL;
4687 hashnames[i][7].string = NULL;
4693 static void load_weed_plugin(
char *plugin_name,
char *plugin_path,
char *dir) {
4694 #if defined TEST_ISOL && defined LM_ID_NEWLM
4695 static Lmid_t lmid = LM_ID_NEWLM;
4696 static boolean have_lmid =
FALSE;
4699 weed_setup_f setup_fn;
4700 weed_plant_t *plugin_info = NULL, **filters = NULL, *filter = NULL;
4701 weed_plant_t *host_info;
4703 int dlflags = RTLD_NOW | RTLD_LOCAL;
4704 int reason, idx = num_weed_filters;
4705 int filters_in_plugin, fnum, j;
4710 const char *frei0r_blacklist[] = {
"Timeout indicator", NULL};
4711 const char *ladspa_blacklist[] = {
"Mag's Notch Filter",
"Identity (Control)",
"Signal Branch (IC)",
4712 "Signal Product (ICIC)",
"Signal Difference (ICMC)",
4713 "Signal Sum (ICIC)",
"Signal Ratio (NCDC)",
4717 char *pwd, *tmp, *msg, *filtname;
4718 char *filter_name = NULL, *package_name = NULL;
4719 boolean blacklisted;
4720 boolean none_valid =
TRUE;
4724 #ifdef RTLD_DEEPBIND
4725 dlflags |= RTLD_DEEPBIND;
4734 lives_printerr(
"Checking plugin %s\n", plugin_path);
4737 #if defined TEST_ISOL && defined LM_ID_NEWLM
4739 handle = dlmopen(LM_ID_NEWLM, plugin_path, dlflags);
4741 handle = dlmopen(lmid, plugin_path, dlflags);
4747 dlinfo(handle, RTLD_DI_LMID, &new_lmid);
4753 if ((handle = dlopen(plugin_path, dlflags))) {
4758 msg =
lives_strdup_printf(
_(
"Unable to load plugin %s\nError was: %s\n"), plugin_path, dlerror());
4763 if ((setup_fn = (weed_setup_f)dlsym(handle,
"weed_setup")) == NULL) {
4783 }
while (our_plugin_id == 0);
4785 weed_set_host_info_callback(
host_info_cb, LIVES_INT_TO_POINTER(our_plugin_id));
4789 expected_hi = expected_pi = NULL;
4793 plugin_info = (*setup_fn)(weed_bootstrap);
4795 if (!plugin_info || (filters_in_plugin = check_weed_plugin_info(plugin_info)) < 1) {
4799 if (plugin_info) weed_plant_free(plugin_info);
4808 if (expected_pi && plugin_info != expected_pi) suspect =
TRUE;
4809 if (weed_plant_has_leaf(plugin_info, WEED_LEAF_HOST_INFO)) {
4810 host_info = weed_get_plantptr_value(plugin_info, WEED_LEAF_HOST_INFO, NULL);
4811 if (!host_info || host_info != expected_hi) {
4813 if (host_info) weed_plant_free(host_info);
4817 if (plugin_info) weed_plant_free(plugin_info);
4822 if (weed_plant_has_leaf(host_info, WEED_LEAF_PLUGIN_INFO)) {
4823 weed_plant_t *pi = weed_get_plantptr_value(host_info, WEED_LEAF_PLUGIN_INFO, NULL);
4824 if (!pi || pi != plugin_info) {
4827 plugin_path, pi, plugin_info, host_info, expected_hi);
4830 if (pi) weed_plant_free(pi);
4831 if (host_info) weed_plant_free(host_info);
4832 if (plugin_info) weed_plant_free(plugin_info);
4839 weed_set_plantptr_value(host_info, WEED_LEAF_PLUGIN_INFO, plugin_info);
4842 if (suspect || !expected_hi) {
4846 if (host_info) weed_plant_free(host_info);
4847 if (plugin_info) weed_plant_free(plugin_info);
4852 host_info = expected_hi;
4854 weed_set_plantptr_value(plugin_info, WEED_LEAF_HOST_INFO, expected_hi);
4868 filters = weed_get_plantptr_array(plugin_info, WEED_LEAF_FILTERS, NULL);
4870 if (weed_plant_has_leaf(plugin_info, WEED_LEAF_PACKAGE_NAME)) {
4872 WEED_LEAF_PACKAGE_NAME, NULL)));
4874 }
else package_name = lives_strdup(
"");
4876 for (fnum = 0; fnum < filters_in_plugin; fnum++) {
4877 filter = filters[fnum];
4878 blacklisted =
FALSE;
4888 blacklisted =
FALSE;
4890 if (!strcmp(package_name,
"Frei0r: ")) {
4891 for (i = 0; frei0r_blacklist[i]; i++) {
4892 if (!strcmp(filtname, frei0r_blacklist[i])) {
4899 if (!strcmp(package_name,
"LADSPA: ")) {
4900 for (i = 0; ladspa_blacklist[i]; i++) {
4901 if (!strcmp(filtname, ladspa_blacklist[i])) {
4911 fprintf(stderr,
"%s", msg);
4921 if (host_info) weed_set_plantptr_value(filter, WEED_LEAF_HOST_INFO, host_info);
4923 if (!(reason = check_for_lives(filter, idx))) {
4924 boolean dup =
FALSE;
4927 weed_filters = (weed_plant_t **)
lives_realloc(weed_filters, num_weed_filters *
sizeof(weed_plant_t *));
4928 weed_filters[idx] = filter;
4931 gen_hashnames(idx, idx);
4933 for (i = 0; i < idx; i++) {
4934 if (hashnames[idx][1].hash == hashnames[i][1].hash
4946 weed_filters = (weed_plant_t **)
lives_realloc(weed_filters, num_weed_filters *
sizeof(weed_plant_t *));
4953 if (hashnames[i][2].hash == hashnames[idx][2].hash
4958 if (weed_get_int_value(filter, WEED_LEAF_VERSION, NULL) <
4959 weed_get_int_value(weed_filters[i], WEED_LEAF_VERSION, NULL)) {
4971 msg =
lives_strdup_printf((tmp =
_(
"Loaded filter %s in plugin %s")), filter_name, plugin_name);
4978 lives_printerr(
"Unsuitable filter \"%s\" in plugin \"%s\", reason code %d\n",
4979 filter_name, plugin_name, reason);
4985 if (none_valid && plugin_info) {
4986 host_info = weed_get_plantptr_value(plugin_info, WEED_LEAF_HOST_INFO, NULL);
4987 if (host_info) weed_plant_free(host_info);
4988 weed_plant_free(plugin_info);
4994 char *dirs = (
_(
"Some plugin directories"));
5005 static void make_fx_defs_menu(
int num_weed_compounds) {
5006 weed_plant_t *filter;
5009 LiVESWidget *pkg_menu;
5010 LiVESWidget *pkg_submenu = NULL;
5012 LiVESList *menu_list = NULL;
5013 LiVESList *pkg_menu_list = NULL;
5014 LiVESList *compound_list = NULL;
5016 char *string, *filter_type, *filter_name;
5017 char *pkg = NULL, *pkgstring;
5021 weed_fx_sorted_list = NULL;
5024 for (i = 0; i < num_weed_filters; i++) {
5025 filter = weed_filters[i];
5035 else hidden =
FALSE;
5041 if (pkg && strcmp(pkg, pkgstring)) {
5043 lives_list_free(pkg_menu_list);
5044 pkg_menu_list = NULL;
5077 lives_list_free(pkg_menu_list);
5078 pkg_menu_list = NULL;
5082 filter_type = weed_filter_get_type(filter,
TRUE,
FALSE);
5091 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(menuitem),
HIDDEN_KEY, LIVES_INT_TO_POINTER((
int)hidden));
5092 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(menuitem),
SECLIST_KEY, &weed_fx_sorted_list);
5093 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(menuitem),
SECLIST_VAL_KEY, LIVES_INT_TO_POINTER(i));
5095 if (pkg) pkg_menu_list = lives_list_prepend(pkg_menu_list, (livespointer)menuitem);
5097 if (i >= num_weed_filters - num_weed_compounds) compound_list = lives_list_prepend(compound_list, (livespointer)menuitem);
5098 else menu_list = lives_list_prepend(menu_list, (livespointer)menuitem);
5109 lives_list_free(pkg_menu_list);
5113 lives_list_free(menu_list);
5115 lives_list_free(compound_list);
5121 LiVESList *weed_plugin_list, *weed_plugin_sublist;
5123 char *subdir_path, *subdir_name, *plugin_path, *plugin_name;
5125 int numdirs, ncompounds;
5128 num_weed_filters = 0;
5130 weed_filters = NULL;
5136 lives_printerr(
"In weed init\n");
5139 fg_gen_to_start = fg_generator_key = fg_generator_clip = fg_generator_mode = -1;
5140 bg_gen_to_start = bg_generator_key = bg_generator_mode = -1;
5145 key_to_instance[i] = (weed_plant_t **)
lives_calloc(max_modes,
sizeof(weed_plant_t *));
5147 key_to_instance_copy[i] = (weed_plant_t **)
lives_calloc(1,
sizeof(weed_plant_t *));
5157 filter_map[i] = NULL;
5158 for (j = 0; j < max_modes; j++) key_to_fx[i][j] = -1;
5165 init_events[i] = NULL;
5182 for (i = 0; i < numdirs; i++) {
5188 LiVESList *listnext = list->next;
5190 plugin_name = (
char *)list->data;
5192 plugin_path = lives_build_filename(dirs[i], plugin_name, NULL);
5193 load_weed_plugin(plugin_name, plugin_path, dirs[i]);
5197 if (list->prev) list->prev->next = listnext;
5198 else weed_plugin_list = listnext;
5199 if (listnext) listnext->prev = list->prev;
5200 list->prev = list->next = NULL;
5201 lives_list_free(list);
5208 for (list = weed_plugin_list; list; list = list->next) {
5210 subdir_name = (
char *)list->data;
5211 subdir_path = lives_build_filename(dirs[i], subdir_name, NULL);
5212 if (!lives_file_test(subdir_path, LIVES_FILE_TEST_IS_DIR) || !strcmp(subdir_name,
"icons") || !strcmp(subdir_name,
"data")) {
5218 list2; list2 = list2 ->next) {
5219 plugin_name = (
char *)list2->data;
5220 plugin_path = lives_build_filename(subdir_path, plugin_name, NULL);
5221 load_weed_plugin(plugin_name, plugin_path, subdir_path);
5231 lives_strfreev(dirs);
5233 d_print(
_(
"Successfully loaded %d Weed filters\n"), num_weed_filters);
5236 ncompounds = load_compound_fx();
5238 make_fx_defs_menu(ncompounds);
5240 weed_fx_sorted_list = lives_list_reverse(weed_fx_sorted_list);
5245 static void weed_plant_free_if_not_in_list(weed_plant_t *plant, LiVESList **freed_ptrs) {
5248 LiVESList *list = *freed_ptrs;
5250 if (plant == (weed_plant_t *)list->data)
return;
5253 *freed_ptrs = lives_list_prepend(*freed_ptrs, (livespointer)plant);
5255 weed_plant_free(plant);
5259 static void weed_filter_free(weed_plant_t *filter, LiVESList **freed_ptrs) {
5261 weed_plant_t **plants, *gui;
5262 boolean is_compound =
FALSE;
5267 plants = weed_get_plantptr_array_counted(filter, WEED_LEAF_IN_PARAMETER_TEMPLATES, &nitems);
5269 for (i = 0; i < nitems; i++) {
5270 if (weed_plant_has_leaf(plants[i], WEED_LEAF_GUI)) {
5271 gui = (weed_get_plantptr_value(plants[i], WEED_LEAF_GUI, NULL));
5272 weed_plant_free_if_not_in_list(gui, freed_ptrs);
5274 weed_plant_free_if_not_in_list(plants[i], freed_ptrs);
5280 weed_plant_free(filter);
5285 if (weed_plant_has_leaf(filter, WEED_LEAF_IN_CHANNEL_TEMPLATES)) {
5286 plants = weed_get_plantptr_array_counted(filter, WEED_LEAF_IN_CHANNEL_TEMPLATES, &nitems);
5288 for (i = 0; i < nitems; i++) weed_plant_free_if_not_in_list(plants[i], freed_ptrs);
5294 if (weed_plant_has_leaf(filter, WEED_LEAF_OUT_CHANNEL_TEMPLATES)) {
5295 plants = weed_get_plantptr_array_counted(filter, WEED_LEAF_OUT_CHANNEL_TEMPLATES, &nitems);
5297 for (i = 0; i < nitems; i++) weed_plant_free_if_not_in_list(plants[i], freed_ptrs);
5303 plants = weed_get_plantptr_array_counted(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES, &nitems);
5306 for (i = 0; i < nitems; i++) {
5307 if (weed_plant_has_leaf(plants[i], WEED_LEAF_GUI))
5308 weed_plant_free(weed_get_plantptr_value(plants[i], WEED_LEAF_GUI, NULL));
5309 weed_plant_free_if_not_in_list(plants[i], freed_ptrs);
5315 if (weed_plant_has_leaf(filter, WEED_LEAF_GUI))
5316 weed_plant_free_if_not_in_list(weed_get_plantptr_value(filter, WEED_LEAF_GUI, NULL), freed_ptrs);
5319 weed_plant_free(filter);
5323 static weed_plant_t *create_compound_filter(
char *plugin_name,
int nfilts,
int *filts) {
5324 weed_plant_t *filter = weed_plant_new(WEED_PLANT_FILTER_CLASS), *xfilter, *gui;
5325 weed_plant_t **in_params = NULL, **out_params = NULL, **params;
5326 weed_plant_t **in_chans, **out_chans;
5330 double tgfps = -1., tfps;
5332 int count, xcount,
error, nvals;
5333 int txparam = -1, tparam, txvolm = -1, tvolm;
5335 register int i, j, x;
5342 for (i = 0; i < nfilts; i++) {
5343 xfilter = weed_filters[filts[i]];
5345 if (weed_plant_has_leaf(xfilter, WEED_LEAF_PREFERRED_FPS)) {
5346 tfps = weed_get_double_value(xfilter, WEED_LEAF_PREFERRED_FPS, &
error);
5347 if (tgfps == -1.) tgfps = tfps;
5348 else if (tgfps != tfps) {
5362 if (weed_plant_has_leaf(xfilter, WEED_LEAF_IN_PARAMETER_TEMPLATES)) {
5368 if (txparam != -1) {
5397 params = weed_get_plantptr_array_counted(xfilter, WEED_LEAF_IN_PARAMETER_TEMPLATES, &nvals);
5400 in_params = (weed_plant_t **)
lives_realloc(in_params, count *
sizeof(weed_plant_t *));
5403 for (j = xcount; j < count; j++) {
5404 in_params[j] = weed_plant_copy(params[x]);
5405 gui = weed_get_plantptr_value(params[x], WEED_LEAF_GUI, &
error);
5406 if (gui) weed_set_plantptr_value(in_params[j], WEED_LEAF_GUI, weed_plant_copy(gui));
5409 weed_set_boolean_value(in_params[j], WEED_LEAF_IS_TRANSITION, WEED_TRUE);
5410 }
else if (weed_plant_has_leaf(in_params[j], WEED_LEAF_IS_TRANSITION))
5411 weed_leaf_delete(in_params[j], WEED_LEAF_IS_TRANSITION);
5414 weed_set_boolean_value(in_params[j], WEED_LEAF_IS_VOLUME_MASTER, WEED_TRUE);
5415 }
else if (weed_plant_has_leaf(in_params[j], WEED_LEAF_IS_VOLUME_MASTER))
5416 weed_leaf_delete(in_params[j], WEED_LEAF_IS_VOLUME_MASTER);
5425 if (tgfps != -1.) weed_set_double_value(filter, WEED_LEAF_PREFERRED_FPS, tgfps);
5428 weed_set_plantptr_array(filter, WEED_LEAF_IN_PARAMETER_TEMPLATES, count, in_params);
5434 for (i = 0; i < nfilts; i++) {
5435 xfilter = weed_filters[filts[i]];
5436 if (weed_plant_has_leaf(xfilter, WEED_LEAF_OUT_PARAMETER_TEMPLATES)) {
5437 params = weed_get_plantptr_array_counted(xfilter, WEED_LEAF_OUT_PARAMETER_TEMPLATES, &nvals);
5440 out_params = (weed_plant_t **)
lives_realloc(out_params, count *
sizeof(weed_plant_t *));
5443 for (j = xcount; j < count; j++) {
5444 out_params[j] = params[x++];
5452 weed_set_plantptr_array(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES, count, out_params);
5458 xfilter = weed_filters[filts[0]];
5459 if (weed_plant_has_leaf(xfilter, WEED_LEAF_IN_CHANNEL_TEMPLATES)) {
5460 in_chans = weed_get_plantptr_array_counted(xfilter, WEED_LEAF_IN_CHANNEL_TEMPLATES, &count);
5461 weed_set_plantptr_array(filter, WEED_LEAF_IN_CHANNEL_TEMPLATES, count, in_chans);
5467 xfilter = weed_filters[filts[nfilts - 1]];
5468 if (weed_plant_has_leaf(xfilter, WEED_LEAF_OUT_CHANNEL_TEMPLATES)) {
5469 out_chans = weed_get_plantptr_array_counted(xfilter, WEED_LEAF_OUT_CHANNEL_TEMPLATES, &count);
5470 weed_set_plantptr_array(filter, WEED_LEAF_OUT_CHANNEL_TEMPLATES, count, out_chans);
5478 static void load_compound_plugin(
char *plugin_name,
char *plugin_path) {
5481 weed_plant_t *filter = NULL, *ptmpl, *iptmpl, *xfilter;
5483 char **array, **svals;
5484 char *author = NULL, *tmp, *key;
5485 int *filters = NULL, *ivals;
5489 boolean ok =
TRUE, autoscale;
5490 int stage = 0, nfilts = 0, fnum, line = 0,
version = 0;
5491 int qvals = 1, ntok, xfilt, xfilt2;
5493 int nparams, nchans, pnum, pnum2, xpnum2, cnum, cnum2, ptype, pptype, pcspace, pflags;
5498 if ((cpdfile = fopen(plugin_path,
"r"))) {
5499 while (fgets(buff, 16384, cpdfile)) {
5501 lives_strstrip(buff);
5503 if (++stage == 5)
break;
5514 filter = create_compound_filter(plugin_name, nfilts, filters);
5521 if (line == 1) author = lives_strdup(buff);
5522 if (line == 2)
version = atoi(buff);
5530 buff, plugin_name, line)));
5537 filters = (
int *)
lives_realloc(filters, ++nfilts *
sizeof(
int));
5538 filters[nfilts - 1] = fnum;
5555 array = lives_strsplit(buff,
"|", ntok);
5557 xfilt = atoi(array[0]);
5558 if (xfilt < 0 || xfilt >= nfilts) {
5561 xfilt, plugin_name, line)));
5566 lives_strfreev(array);
5573 pnum = atoi(array[1]);
5575 if (pnum >= nparams) {
5578 pnum, plugin_name, line)));
5583 lives_strfreev(array);
5592 ptype = weed_leaf_seed_type(ptmpl, WEED_LEAF_DEFAULT);
5593 pflags = weed_get_int_value(ptmpl, WEED_LEAF_FLAGS, &
error);
5596 if (pptype == WEED_PARAM_COLOR) {
5597 pcspace = weed_get_int_value(ptmpl, WEED_LEAF_COLORSPACE, &
error);
5599 if (pcspace == WEED_COLORSPACE_RGBA) qvals = 4;
5604 if ((ntok != weed_leaf_num_elements(ptmpl, WEED_LEAF_DEFAULT) && !(pflags & WEED_PARAMETER_VARIABLE_SIZE)) ||
5605 ntok % qvals != 0) {
5608 plugin_name, line)));
5613 lives_strfreev(array);
5622 for (i = 0; i < ntok; i++) {
5623 ivals[i] = atoi(array[i + 2]);
5625 weed_set_int_array(ptmpl, WEED_LEAF_DEFAULT, ntok, ivals);
5628 case WEED_SEED_DOUBLE:
5630 for (i = 0; i < ntok; i++) {
5631 dvals[i] = strtod(array[i + 2], NULL);
5633 weed_set_double_array(ptmpl, WEED_LEAF_DEFAULT, ntok, dvals);
5636 case WEED_SEED_BOOLEAN:
5638 for (i = 0; i < ntok; i++) {
5639 ivals[i] = atoi(array[i + 2]);
5641 if (ivals[i] != WEED_TRUE && ivals[i] != WEED_FALSE) {
5645 "line %d\n"), pnum, plugin_name, line)));
5650 lives_strfreev(array);
5655 weed_set_boolean_array(ptmpl, WEED_LEAF_DEFAULT, ntok, ivals);
5660 for (i = 0; i < ntok; i++) {
5661 svals[i] = lives_strdup(array[i + 2]);
5663 weed_set_string_array(ptmpl, WEED_LEAF_DEFAULT, ntok, svals);
5664 for (i = 0; i < ntok; i++) {
5670 lives_strfreev(array);
5680 plugin_name, line)));
5688 array = lives_strsplit(buff,
"|", ntok);
5690 xfilt = atoi(array[0]);
5691 if (xfilt < -1 || xfilt >= nfilts) {
5694 xfilt, plugin_name, line)));
5699 lives_strfreev(array);
5703 pnum = atoi(array[1]);
5708 if (weed_plant_has_leaf(xfilter, WEED_LEAF_OUT_PARAMETER_TEMPLATES))
5709 nparams = weed_leaf_num_elements(xfilter, WEED_LEAF_OUT_PARAMETER_TEMPLATES);
5712 if (pnum >= nparams) {
5715 pnum, plugin_name, line)));
5720 lives_strfreev(array);
5725 autoscale = atoi(array[2]);
5727 if (autoscale != WEED_TRUE && autoscale != WEED_FALSE) {
5730 "line %d\n"), pnum, plugin_name, line)));
5735 lives_strfreev(array);
5739 xfilt2 = atoi(array[3]);
5740 if (xfilt >= nfilts) {
5743 xfilt2, plugin_name, line)));
5748 lives_strfreev(array);
5755 pnum2 = atoi(array[4]);
5757 if (pnum2 >= nparams) {
5760 pnum2, plugin_name, line)));
5765 lives_strfreev(array);
5780 if (autoscale == WEED_TRUE) weed_set_boolean_value(iptmpl,
5783 lives_strfreev(array);
5792 plugin_name, line)));
5800 array = lives_strsplit(buff,
"|", ntok);
5802 xfilt = atoi(array[0]);
5803 if (xfilt < 0 || xfilt >= nfilts) {
5806 "line %d\n"), xfilt, plugin_name, line)));
5811 lives_strfreev(array);
5817 if (weed_plant_has_leaf(xfilter, WEED_LEAF_OUT_CHANNEL_TEMPLATES)) {
5818 nchans = weed_leaf_num_elements(xfilter, WEED_LEAF_OUT_CHANNEL_TEMPLATES);
5819 if (!weed_get_plantptr_value(xfilter, WEED_LEAF_OUT_CHANNEL_TEMPLATES, &
error)) nchans = 0;
5822 cnum = atoi(array[1]);
5824 if (cnum >= nchans) {
5827 cnum, plugin_name, line)));
5832 lives_strfreev(array);
5836 xfilt2 = atoi(array[2]);
5837 if (xfilt2 <= xfilt || xfilt >= nfilts) {
5840 xfilt2, plugin_name, line)));
5845 lives_strfreev(array);
5851 if (weed_plant_has_leaf(xfilter, WEED_LEAF_IN_CHANNEL_TEMPLATES)) {
5852 nchans = weed_leaf_num_elements(xfilter, WEED_LEAF_IN_CHANNEL_TEMPLATES);
5853 if (!weed_get_plantptr_value(xfilter, WEED_LEAF_IN_CHANNEL_TEMPLATES, &
error)) nchans = 0;
5856 cnum2 = atoi(array[3]);
5858 if (cnum2 >= nchans) {
5861 cnum2, plugin_name, line)));
5866 lives_strfreev(array);
5879 weed_set_int_array(filter, key, 4, xvals);
5882 lives_strfreev(array);
5888 if (filter) weed_filter_free(filter, NULL);
5899 weed_set_string_value(filter, WEED_LEAF_NAME, filter_name);
5902 weed_set_int_value(filter, WEED_LEAF_VERSION,
version);
5903 idx = num_weed_filters++;
5905 weed_filters = (weed_plant_t **)
lives_realloc(weed_filters, num_weed_filters *
sizeof(weed_plant_t *));
5906 weed_filters[idx] = filter;
5908 gen_hashnames(idx, idx);
5917 static int load_compound_fx(
void) {
5918 LiVESList *compound_plugin_list;
5920 int plugin_idx, onum_filters = num_weed_filters;
5922 char *lives_compound_plugin_path, *plugin_name, *plugin_path;
5929 for (plugin_idx = 0; plugin_idx < lives_list_length(compound_plugin_list); plugin_idx++) {
5930 plugin_name = (
char *)lives_list_nth_data(compound_plugin_list, plugin_idx);
5931 plugin_path = lives_build_path(lives_compound_plugin_path, plugin_name, NULL);
5932 load_compound_plugin(plugin_name, plugin_path);
5946 for (plugin_idx = 0; plugin_idx < lives_list_length(compound_plugin_list); plugin_idx++) {
5947 plugin_name = (
char *)lives_list_nth_data(compound_plugin_list, plugin_idx);
5948 plugin_path = lives_build_path(lives_compound_plugin_path, plugin_name, NULL);
5949 load_compound_plugin(plugin_name, plugin_path);
5956 if (num_weed_filters > onum_filters) {
5957 d_print(
_(
"Successfully loaded %d compound filters\n"), num_weed_filters - onum_filters);
5962 return num_weed_filters - onum_filters;
5967 weed_plant_t *filter, *plugin_info, *host_info;
5968 LiVESList *pinfo = NULL, *list, *freed_plants = NULL, *hostinfo_ptrs = NULL;
5974 if (!fx_inited)
return;
5988 for (i = 0; i < num_weed_filters; i++) {
5989 filter = weed_filters[i];
5990 plugin_info = weed_get_plantptr_value(filter, WEED_LEAF_PLUGIN_INFO, &
error);
5992 weed_filter_free(filter, &freed_plants);
5993 lives_list_free(freed_plants);
5994 freed_plants = NULL;
5998 weed_filter_free(filter, &freed_plants);
5999 if (!pinfo || lives_list_index(pinfo, plugin_info) == -1) {
6000 pinfo = lives_list_append(pinfo, plugin_info);
6003 freed_plants = NULL;
6011 plugin_info = (weed_plant_t *)pinfo->data;
6015 weed_desetup_f desetup_fn;
6016 if ((desetup_fn = (weed_desetup_f)dlsym(handle,
"weed_desetup")) != NULL) {
6028 lives_list_free(freed_plants);
6029 freed_plants = NULL;
6031 host_info = weed_get_plantptr_value((weed_plant_t *)pinfo->data, WEED_LEAF_HOST_INFO, &
error);
6032 weed_plant_free_if_not_in_list(host_info, &hostinfo_ptrs);
6033 weed_plant_free(plugin_info);
6035 pinfo = pinfo->next;
6038 if (list) lives_list_free(list);
6039 if (hostinfo_ptrs) lives_list_free(hostinfo_ptrs);
6041 for (i = 0; i < num_weed_filters; i++) {
6043 if (hashnames[i][j].
string)
lives_free(hashnames[i][j].
string);
6050 lives_list_free(weed_fx_sorted_list);
6061 char *dirs = (
_(
"Some plugin directories"));
6068 static void weed_in_channels_free(weed_plant_t *inst) {
6071 if (num_channels > 0) {
6072 for (
int i = 0; i < num_channels; i++) {
6075 else weed_plant_free(channels[i]);
6083 static void weed_out_channels_free(weed_plant_t *inst) {
6086 if (num_channels > 0) {
6087 for (
int i = 0; i < num_channels; i++) {
6090 else weed_plant_free(channels[i]);
6098 static void weed_channels_free(weed_plant_t *inst) {
6099 weed_in_channels_free(inst);
6100 weed_out_channels_free(inst);
6104 static void weed_gui_free(weed_plant_t *plant) {
6105 weed_plant_t *gui = weed_get_plantptr_value(plant, WEED_LEAF_GUI, NULL);
6106 if (gui) weed_plant_free(gui);
6111 for (
int i = 0; i < num_parameters; i++) {
6112 if (parameters[i]) {
6114 weed_gui_free(parameters[i]);
6115 weed_plant_free(parameters[i]);
6124 if (num_parameters > 0) {
6126 weed_leaf_delete(inst, WEED_LEAF_IN_PARAMETERS);
6132 static void weed_out_parameters_free(weed_plant_t *inst) {
6135 if (num_parameters > 0) {
6136 for (
int i = 0; i < num_parameters; i++) {
6137 if (parameters[i]) weed_plant_free(parameters[i]);
6139 weed_leaf_delete(inst, WEED_LEAF_OUT_PARAMETERS);
6145 static void weed_parameters_free(weed_plant_t *inst) {
6147 weed_out_parameters_free(inst);
6151 static void lives_free_instance(weed_plant_t *inst) {
6152 weed_channels_free(inst);
6153 weed_parameters_free(inst);
6154 weed_plant_free(inst);
6163 if (!inst)
return -2;
6172 msg =
lives_strdup_printf(
"unref of filter instance (%p) with nrefs == %d\n", inst, nrefs);
6174 break_me(
"invalid filt inst unref");
6181 #ifdef DEBUG_REFCOUNT
6182 g_print(
"unref %p, nrefs==%d\n", inst, nrefs);
6185 #ifdef DEBUG_REFCOUNT
6186 g_print(
"FREE %p\n", inst);
6188 lives_free_instance(inst);
6199 if (!inst)
return 0;
6204 #ifdef DEBUG_REFCOUNT
6205 g_print(
"ref %p, nrefs==%d\n", inst, nrefs);
6215 weed_plant_t *instance;
6219 instance = key_to_instance[key][mode];
6220 #ifdef DEBUG_REFCOUNT
6221 if (instance) g_print(
"wio %p at line %d in file %s\n", instance, line, file);
6229 #ifndef DEBUG_REFCOUNT
6249 static weed_plant_t **weed_channels_create(weed_plant_t *filter,
boolean in) {
6250 weed_plant_t **channels, **chantmpls;
6256 boolean pvary =
FALSE;
6261 for (i = 0; i < num_channels; i++) {
6264 else num_repeats = 1;
6265 ccount += num_repeats;
6268 channels = (weed_plant_t **)
lives_calloc((ccount + 1),
sizeof(weed_plant_t *));
6271 if (flags & WEED_FILTER_PALETTES_MAY_VARY) {
6277 for (i = 0; i < num_channels; i++) {
6280 else num_repeats = 1;
6281 for (j = 0; j < num_repeats; j++) {
6283 channels[ccount] = weed_plant_new(WEED_PLANT_CHANNEL);
6284 weed_set_plantptr_value(channels[ccount], WEED_LEAF_TEMPLATE, chantmpls[i]);
6286 int rah =
ALIGN_DEF, nplanes, width, n, pal;
6288 weed_set_voidptr_value(channels[ccount], WEED_LEAF_PIXEL_DATA, NULL);
6290 pal = WEED_PALETTE_END;
6291 if (pvary) pal = weed_get_int_value(chantmpls[i], WEED_LEAF_PALETTE_LIST, NULL);
6292 if (pal == WEED_PALETTE_NONE) pal = weed_get_int_value(filter, WEED_LEAF_PALETTE_LIST, NULL);
6293 weed_set_int_value(channels[ccount], WEED_LEAF_CURRENT_PALETTE, pal);
6294 if (weed_plant_has_leaf(filter, WEED_LEAF_ALIGNMENT_HINT)) {
6295 rah = weed_get_int_value(filter, WEED_LEAF_ALIGNMENT_HINT, NULL);
6302 weed_set_int_array(channels[ccount], WEED_LEAF_ROWSTRIDES, nplanes, rs);
6305 weed_set_boolean_value(channels[ccount], WEED_LEAF_DISABLED,
6308 weed_add_plant_flags(channels[ccount], WEED_FLAG_UNDELETABLE | WEED_FLAG_IMMUTABLE,
"plugin_");
6312 channels[ccount] = NULL;
6323 weed_plant_t **params, **paramtmpls;
6328 if (num_params == 0)
return NULL;
6330 params = (weed_plant_t **)
lives_malloc((num_params + 1) *
sizeof(weed_plant_t *));
6332 for (
int i = 0; i < num_params; i++) {
6333 params[i] = weed_plant_new(WEED_PLANT_PARAMETER);
6334 weed_set_plantptr_value(params[i], WEED_LEAF_TEMPLATE, paramtmpls[i]);
6338 }
else weed_leaf_copy(params[i], WEED_LEAF_VALUE, paramtmpls[i], WEED_LEAF_DEFAULT);
6341 weed_leaf_copy(params[i], WEED_LEAF_VALUE, paramtmpls[i], WEED_LEAF_DEFAULT);
6344 params[num_params] = NULL;
6351 static void set_default_channel_sizes(weed_plant_t *filter, weed_plant_t **in_channels, weed_plant_t **out_channels) {
6353 weed_plant_t *channel, *chantmpl;
6354 boolean has_aud_in_chans =
FALSE;
6360 if ((!in_channels || !in_channels[0]) && (!out_channels || !out_channels[0]))
return;
6362 for (i = 0; in_channels && in_channels[i] &&
6363 !(weed_plant_has_leaf(in_channels[i], WEED_LEAF_DISABLED) &&
6364 weed_get_boolean_value(in_channels[i], WEED_LEAF_DISABLED, NULL) == WEED_TRUE); i++) {
6365 channel = in_channels[i];
6366 chantmpl = weed_get_plantptr_value(channel, WEED_LEAF_TEMPLATE, NULL);
6368 set_channel_size(filter, channel, 320, 240);
6374 weed_set_int_value(channel, WEED_LEAF_AUDIO_CHANNELS,
cfile->achans);
6375 weed_set_int_value(channel, WEED_LEAF_AUDIO_RATE,
cfile->arate);
6377 weed_set_int_value(channel, WEED_LEAF_AUDIO_DATA_LENGTH, 0);
6378 weed_set_voidptr_value(channel, WEED_LEAF_AUDIO_DATA, NULL);
6379 has_aud_in_chans =
TRUE;
6383 for (i = 0; out_channels && out_channels[i]; i++) {
6384 channel = out_channels[i];
6389 set_channel_size(filter, channel, width, height);
6395 weed_set_int_value(channel, WEED_LEAF_AUDIO_CHANNELS,
cfile->achans);
6396 weed_set_int_value(channel, WEED_LEAF_AUDIO_RATE,
cfile->arate);
6398 weed_set_int_value(channel, WEED_LEAF_AUDIO_DATA_LENGTH, 0);
6399 weed_set_voidptr_value(channel, WEED_LEAF_AUDIO_DATA, NULL);
6405 static weed_plant_t *weed_create_instance(weed_plant_t *filter, weed_plant_t **inc, weed_plant_t **outc,
6406 weed_plant_t **inp, weed_plant_t **outp) {
6409 weed_plant_t *inst = weed_plant_new(WEED_PLANT_FILTER_INSTANCE);
6411 int flags = WEED_FLAG_IMMUTABLE | WEED_FLAG_UNDELETABLE, n;
6413 weed_set_plantptr_value(inst, WEED_LEAF_FILTER_CLASS, filter);
6419 for (
int i = 0; i < n; i++) {
6421 weed_leaf_set_flags(outp[i], WEED_LEAF_VALUE, (weed_leaf_get_flags(outp[i], WEED_LEAF_VALUE) | flags) ^ flags);
6432 weed_plant_t **in_ptmpls, **outp;
6439 in_ptmpls = weed_get_plantptr_array_counted(filter, WEED_LEAF_IN_PARAMETER_TEMPLATES, &nptmpls);
6440 if (!in_ptmpls)
return;
6442 for (i = 0; i < nptmpls; i++) {
6448 if (xvals[0] > -1) {
6452 outp = weed_get_plantptr_array(inst, WEED_LEAF_OUT_PARAMETERS, &
error);
6453 oparam = outp[xvals[1]];
6455 }
else oparam = iparam;
6472 weed_plant_t **inc = NULL, **outc = NULL, **inp = NULL, **outp = NULL, **xinp;
6474 weed_plant_t *last_inst = NULL, *first_inst = NULL, *inst, *ofilter = filter;
6475 weed_plant_t *ochan = NULL;
6477 int *filters = NULL, *xvals;
6481 int nfilters, ninpar = 0,
error;
6483 int xcnumx = 0, x, poffset = 0;
6493 for (i = 0; i < nfilters; i++) {
6495 filter = weed_filters[filters[i]];
6499 inc = weed_channels_create(filter,
TRUE);
6500 outc = weed_channels_create(filter,
FALSE);
6502 set_default_channel_sizes(filter, inc, outc);
6507 if (nfilters == 1) xinp = inp;
6510 if (ninpar == 0) xinp = NULL;
6512 xinp = (weed_plant_t **)
lives_malloc((ninpar + 1) *
sizeof(weed_plant_t *));
6514 for (j = poffset; j < poffset + ninpar; j++) xinp[x++] = inp[j];
6521 inst = weed_create_instance(filter, inc, outc, xinp, outp);
6532 }
else first_inst = inst;
6561 if (weed_plant_has_leaf(filter, key)) {
6562 xvals = weed_get_int_array(filter, key, &
error);
6566 if (xvals[0]-- == 0) {
6568 outc = weed_get_plantptr_array(inst, WEED_LEAF_OUT_CHANNELS, &
error);
6569 ochan = outc[xvals[1]];
6572 if (xvals[2]-- == 0) {
6574 inc = weed_get_plantptr_array(inst, WEED_LEAF_IN_CHANNELS, &
error);
6599 weed_plant_t *filter, *gui;
6600 weed_plant_t *new_instance, *inst;
6601 weed_plant_t *event_list;
6605 boolean all_out_alpha;
6606 boolean is_gen =
FALSE;
6607 boolean is_audio_gen =
FALSE;
6611 int inc_count, outc_count;
6619 is_modeswitch =
TRUE;
6620 hotkey = -hotkey - 1;
6623 if (hotkey == fg_generator_key) {
6624 fg_modeswitch =
TRUE;
6637 idx = key_to_fx[hotkey][key_modes[hotkey]];
6638 filter = weed_filters[idx];
6643 if (all_ins_alpha(filter,
TRUE)) inc_count = 0;
6645 if (inc_count == 0) is_gen =
TRUE;
6654 d_print(
_(
"Effect %s cannot be used with this audio player.\n"), fxname);
6665 boolean needs_unlock =
FALSE;
6667 needs_unlock =
TRUE;
6684 is_audio_gen =
TRUE;
6689 all_out_alpha = all_outs_alpha(filter,
TRUE);
6695 if (!all_out_alpha && is_gen && outc_count > 0 && hotkey != fg_generator_key &&
mainw->
num_tr_applied > 0 &&
6700 if (bg_gen_to_start == -1) {
6704 bg_gen_to_start = bg_generator_key = bg_generator_mode = -1;
6709 (fg_modeswitch || (is_gen && outc_count > 0 &&
mainw->
num_tr_applied == 0)) && !is_audio_gen && !all_out_alpha) {
6722 fg_generator_key = fg_generator_clip = fg_generator_mode = -1;
6732 if (inc_count == 2) {
6741 }
else if (is_gen && outc_count > 0 && !is_audio_gen && !all_out_alpha) {
6746 fg_gen_to_start = hotkey;
6747 fg_generator_key = hotkey;
6748 fg_generator_mode = key_modes[hotkey];
6762 new_instance = (weed_plant_t *)rfx->
source;
6784 inst = new_instance;
6787 if (gui && weed_get_int_value(gui, WEED_LEAF_EASE_OUT, NULL)) {
6788 weed_leaf_delete(gui, WEED_LEAF_EASE_OUT);
6795 else if (weed_plant_has_leaf(filter, WEED_LEAF_PREFERRED_FPS))
6796 weed_leaf_copy(inst, WEED_LEAF_TARGET_FPS, filter, WEED_LEAF_PREFERRED_FPS);
6803 inst = new_instance;
6806 weed_plant_t *inst, *next_inst = NULL;
6807 inst = new_instance;
6813 if (weed_plant_has_leaf(filter, WEED_LEAF_INIT_FUNC)) {
6814 weed_init_f init_func;
6816 init_func = (weed_init_f)weed_get_funcptr_value(filter, WEED_LEAF_INIT_FUNC, NULL);
6817 if (init_func && (
error = (*init_func)(inst)) != WEED_SUCCESS) {
6819 filter = weed_filters[idx];
6820 filter_name = weed_get_string_value(filter, WEED_LEAF_NAME, NULL);
6824 key_to_instance[hotkey][key_modes[hotkey]] = NULL;
6830 else next_inst = NULL;
6840 inst = new_instance;
6871 inst = new_instance;
6872 filter = weed_filters[idx];
6875 if (is_gen && outc_count > 0 && !is_audio_gen && !all_out_alpha) {
6879 bg_generator_key = hotkey;
6880 bg_generator_mode = key_modes[hotkey];
6883 fg_generator_key = hotkey;
6884 fg_generator_mode = key_modes[hotkey];
6891 key_to_instance[hotkey][key_modes[hotkey]] = inst;
6904 filter_name = weed_get_string_value(filter, WEED_LEAF_NAME, &weed_error);
6905 d_print(
_(
"Unable to start generator %s (error code: %d)\n"), filter_name,
error);
6909 bg_gen_to_start = bg_generator_key = bg_generator_mode = -1;
6911 fg_generator_key = fg_generator_clip = fg_generator_mode = -1;
6914 key_to_instance[hotkey][key_modes[hotkey]] = NULL;
6934 if (fg_generator_key != -1) {
6940 if (bg_generator_key != -1 && !fg_modeswitch) {
6944 if (hotkey < prefs->rte_keys_virtual) {
6953 if (rte_keys == hotkey) {
6959 key_to_instance[hotkey][key_modes[hotkey]] = inst;
6966 uint64_t rteval, new_rte;
6974 new_rte =
GU641 << (hotkey);
6975 if (!(rteval & new_rte)) rteval |= new_rte;
6976 create_filter_map(rteval);
7005 #ifdef HAVE_PULSE_AUDIO
7010 if (audio_ticks == -1) {
7045 weed_plant_t *filter;
7046 weed_error_t
error = WEED_SUCCESS;
7051 if (weed_plant_has_leaf(filter, WEED_LEAF_INIT_FUNC)) {
7052 weed_init_f init_func = (weed_init_f)weed_get_funcptr_value(filter, WEED_LEAF_INIT_FUNC, NULL);
7055 error = (*init_func)(inst);
7069 weed_plant_t *filter;
7070 weed_error_t
error = WEED_SUCCESS;
7079 if (weed_plant_has_leaf(filter, WEED_LEAF_DEINIT_FUNC)) {
7080 weed_deinit_f deinit_func = (weed_deinit_f)weed_get_funcptr_value(filter, WEED_LEAF_DEINIT_FUNC, NULL);
7083 error = (*deinit_func)(instance);
7101 weed_plant_t *instance, *inst, *last_inst, *next_inst, *filter, *gui;
7103 boolean is_modeswitch =
FALSE;
7104 boolean was_transition =
FALSE;
7105 boolean is_audio_gen =
FALSE;
7106 boolean is_video_gen =
FALSE;
7107 int num_in_chans, num_out_chans;
7112 int needs_unlock = -1;
7115 is_modeswitch =
TRUE;
7116 hotkey = -hotkey - 1;
7128 if (!weed_plant_has_leaf(gui, WEED_LEAF_EASE_OUT)) {
7129 uint64_t new_rte =
GU641 << (hotkey);
7131 if ((easing = weed_get_int_value(gui, WEED_LEAF_EASE_OUT_FRAMES, NULL))) {
7132 int myease =
cfile->pb_fps * 2.;
7133 if (easing < myease) {
7134 weed_set_int_value(gui, WEED_LEAF_EASE_OUT, myease);
7149 if (gui && weed_get_int_value(gui, WEED_LEAF_EASE_OUT, NULL)) {
7150 weed_leaf_delete(gui, WEED_LEAF_EASE_OUT);
7156 last_inst = instance;
7162 else if (num_in_chans == 0) is_video_gen =
TRUE;
7165 if ((is_video_gen || all_ins_alpha(filter,
TRUE)) && num_out_chans > 0 && !all_outs_alpha(filter,
TRUE)) {
7200 #ifdef HAVE_PULSE_AUDIO
7207 if (audio_ticks == -1) {
7234 #ifdef HAVE_PULSE_AUDIO
7256 needs_unlock = hotkey;
7258 key_to_instance[hotkey][key_modes[hotkey]] = NULL;
7259 if (needs_unlock != -1) {
7269 if (num_in_chans == 2) {
7270 was_transition =
TRUE;
7286 else next_inst = NULL;
7304 if (was_transition && !is_modeswitch) {
7309 if (bg_gen_to_start != -1) bg_gen_to_start = -1;
7315 needs_unlock = bg_generator_key;
7318 if (needs_unlock != -1) {
7328 uint64_t rteval, new_rte;
7333 init_events[hotkey] = NULL;
7334 if (pchains[hotkey])
lives_free(pchains[hotkey]);
7335 pchains[hotkey] = NULL;
7337 new_rte =
GU641 << (hotkey);
7338 if (rteval & new_rte) {
7343 create_filter_map(rteval);
7362 if (key_to_instance[i][0]) {
7382 weed_plant_t *instance;
7386 if ((instance = key_to_instance[i][key_modes[i]]) != NULL) {
7388 if (weed_plant_has_leaf(gui, WEED_LEAF_EASE_OUT)) {
7406 weed_plant_t *instance;
7415 if (!
LIVES_IS_PLAYING) bg_gen_to_start = bg_generator_key = bg_generator_mode = -1;
7458 static int register_audio_channels(
int nchannels) {
7475 static int unregister_audio_channels(
int nchannels) {
7486 for (i = 0; i < 2; i++) {
7500 static boolean fill_audio_channel(weed_plant_t *filter, weed_plant_t *achan) {
7508 weed_set_int_value(achan, WEED_LEAF_AUDIO_DATA_LENGTH, 0);
7509 weed_set_voidptr_value(achan, WEED_LEAF_AUDIO_DATA, NULL);
7530 if (achan && audbuf) {
7547 int palette = WEED_PALETTE_END;
7551 if (
palette != WEED_PALETTE_END)
break;
7553 weed_plant_t *instance;
7554 if (i == fg_generator_key)
continue;
7563 for (
int j = 0; j < nvals; j++) {
7564 if (plist[j] == WEED_PALETTE_END)
break;
7565 else for (
int k = 0; k < npals; k++) {
7566 if (palette_list[k] == WEED_PALETTE_END)
break;
7567 if (palette_list[k] == plist[j]) {
7572 if (
palette != WEED_PALETTE_END)
break;
7580 if (
palette == WEED_PALETTE_END) {
7582 for (i = 0; i < npals; i++) {
7590 if (
palette == WEED_PALETTE_END) {
7591 for (i = 0; i < npals; i++) {
7595 if (
palette == WEED_PALETTE_END) {
7596 for (i = 0; i < npals; i++) {
7608 weed_plant_t *channel, **out_channels;
7609 weed_plant_t *filter;
7610 weed_plant_t *chantmpl;
7611 weed_plant_t *achan;
7612 weed_process_f process_func;
7621 int filter_flags = 0, channel_flags;
7622 int num_in_alpha = 0;
7623 int width, height, xwidth, xheight;
7628 boolean did_thread =
FALSE;
7629 boolean needs_reinit =
FALSE;
7630 boolean can_change =
FALSE;
7631 boolean is_bg =
TRUE;
7634 if (!inst)
return NULL;
7638 out_channels = weed_get_plantptr_array_counted(inst, WEED_LEAF_OUT_CHANNELS, &num_channels);
7639 if (num_channels == 0) {
7691 needs_reinit =
FALSE;
7698 if (can_change || !((channel_flags & WEED_CHANNEL_REINIT_ON_PALETTE_CHANGE))) {
7700 if (
palette != WEED_PALETTE_END) {
7708 if (weed_plant_has_leaf(inst, WEED_LEAF_IN_CHANNELS)) {
7710 weed_plant_t **in_channels = weed_get_plantptr_array_counted(inst, WEED_LEAF_IN_CHANNELS, &num_inc);
7711 for (i = 0; i < num_inc; i++) {
7713 weed_get_boolean_value(in_channels[i], WEED_LEAF_DISABLED, NULL) == WEED_FALSE) {
7720 if (num_in_alpha > 0) {
7722 retval = check_cconx(inst, num_in_alpha, &needs_reinit);
7735 if (can_change || (!(channel_flags & WEED_CHANNEL_REINIT_ON_ROWSTRIDES_CHANGE) && !(channel_flags
7736 & WEED_CHANNEL_REINIT_ON_SIZE_CHANGE))) {
7742 boolean is_lbox =
FALSE;
7747 boolean can_resize =
FALSE;
7748 int opwidth, opheight;
7756 xheight = lb_height;
7769 if (xwidth * xheight == 0) {
7780 if (weed_plant_has_leaf(filter, WEED_LEAF_ALIGNMENT_HINT)) {
7781 int rowstride_alignment_hint = weed_get_int_value(filter, WEED_LEAF_ALIGNMENT_HINT, NULL);
7782 if (rowstride_alignment_hint >
ALIGN_DEF) {
7783 THREADVAR(rowstride_alignment_hint) = rowstride_alignment_hint;
7793 for (
int j = 0; j < nplanes; j++)
lives_free(pd[j]);
7795 weed_set_voidptr_value(channel, WEED_LEAF_PIXEL_DATA, NULL);
7796 set_channel_size(filter, channel, xwidth, xheight);
7813 if (xwidth != width || xheight != height) {
7814 if (channel_flags & WEED_CHANNEL_REINIT_ON_SIZE_CHANGE) {
7815 needs_reinit =
TRUE;
7819 if (!needs_reinit && (channel_flags & WEED_CHANNEL_REINIT_ON_ROWSTRIDES_CHANGE)) {
7822 needs_reinit =
TRUE;
7827 if (filter_flags & WEED_FILTER_PREF_LINEAR_GAMMA)
7842 cfile->hsize = width;
7843 cfile->vsize = height;
7849 fill_audio_channel(filter, achan);
7853 < weed_get_double_value(inst, WEED_LEAF_TARGET_FPS, NULL))
7854 weed_set_double_value(inst, WEED_LEAF_TARGET_FPS,
mainw->
inst_fps);
7858 else if (weed_plant_has_leaf(filter, WEED_LEAF_PREFERRED_FPS))
7859 weed_leaf_copy(inst, WEED_LEAF_TARGET_FPS, filter, WEED_LEAF_PREFERRED_FPS);
7868 if (filter_flags & WEED_FILTER_HINT_MAY_THREAD) {
7869 retval = process_func_threaded(inst, tc);
7874 process_func = (weed_process_f)weed_get_funcptr_value(filter, WEED_LEAF_PROCESS_FUNC, NULL);
7876 ret = (*process_func)(inst, tc);
7885 for (i = 0; i < nachans; i++)
lives_freep((
void **)&abuf[i]);
7889 if (ret == WEED_ERROR_REINIT_NEEDED) {
7920 weed_plant_t **out_channels, *channel, *filter, *achan;
7922 int error, num_channels;
7928 boolean is_bg =
FALSE;
7965 filter_name = weed_get_string_value(filter, WEED_LEAF_NAME, &
error);
7984 lives_snprintf(
cfile->type, 40,
"generator:%s", filter_name);
7985 lives_snprintf(
cfile->file_name,
PATH_MAX,
"generator: %s", filter_name);
7994 cfile->ext_src = inst;
8002 if (!is_bg || old_file == -1 || old_file == new_file) fg_generator_clip = new_file;
8006 else if (weed_plant_has_leaf(filter, WEED_LEAF_PREFERRED_FPS))
8007 cfile->pb_fps =
cfile->fps = weed_get_double_value(filter, WEED_LEAF_PREFERRED_FPS, &
error);
8012 out_channels = weed_get_plantptr_array_counted(inst, WEED_LEAF_OUT_CHANNELS, &num_channels);
8013 if (num_channels == 0) {
8015 cfile->ext_src = NULL;
8024 cfile->ext_src = NULL;
8031 cfile->hsize = weed_get_int_value(channel, WEED_LEAF_WIDTH, &
error);
8032 cfile->vsize = weed_get_int_value(channel, WEED_LEAF_HEIGHT, &
error);
8034 palette = weed_get_int_value(channel, WEED_LEAF_CURRENT_PALETTE, &
error);
8036 else cfile->bpp = 24;
8043 if (weed_plant_has_leaf(achan, WEED_LEAF_DISABLED)) weed_leaf_delete(achan, WEED_LEAF_DISABLED);
8044 register_audio_channels(1);
8051 if (!is_bg || old_file == -1 || old_file == new_file) {
8068 new_rte =
GU641 << key;
8102 if (old_file != -1 &&
mainw->
files[old_file]) {
8107 if (!is_bg || old_file == -1 || old_file == new_file) {
8110 if (new_file != old_file) {
8155 weed_plant_t *next_inst = NULL;
8165 key_to_instance[key][key_modes[key]] = NULL;
8183 boolean is_bg =
FALSE;
8225 unregister_audio_channels(1);
8230 key_to_instance[bg_generator_key][bg_generator_mode] = NULL;
8234 bg_gen_to_start = bg_generator_key = bg_generator_mode = -1;
8239 key_to_instance[fg_generator_key][fg_generator_mode] = NULL;
8243 fg_gen_to_start = fg_generator_key = fg_generator_clip = fg_generator_mode = -1;
8258 cfile->ext_src = NULL;
8284 cfile->ext_src = NULL;
8294 cfile->ext_src = NULL;
8296 if (
cfile->achans == 0) {
8321 int bg_gen_key = bg_generator_key;
8328 bg_gen_to_start = bg_gen_key;
8335 weed_plant_t *inst = NULL, *filter;
8336 weed_plant_t *next_inst = NULL, *orig_inst;
8340 weed_error_t
error = WEED_SUCCESS;
8342 int bgs = bg_gen_to_start;
8343 boolean was_started =
FALSE;
8347 if (fg_gen_to_start == bg_gen_to_start) bg_gen_to_start = -1;
8349 if (
cfile->frames == 0 && fg_gen_to_start == -1 && bg_gen_to_start != -1) {
8350 fg_gen_to_start = bg_gen_to_start;
8351 bg_gen_to_start = -1;
8356 if (fg_gen_to_start != -1) {
8367 if (weed_plant_has_leaf(filter, WEED_LEAF_INIT_FUNC)) {
8368 weed_init_f init_func = (weed_init_f)weed_get_funcptr_value(filter, WEED_LEAF_INIT_FUNC, NULL);
8371 error = (*init_func)(inst);
8377 if (
error != WEED_SUCCESS) {
8378 weed_plant_t *oldinst = inst;
8381 key_to_instance[fg_gen_to_start][key_modes[fg_gen_to_start]] = NULL;
8385 filter_name = weed_get_string_value(filter, WEED_LEAF_NAME, NULL);
8386 d_print(
_(
"Failed to start generator %s (%s)\n"), filter_name,
8408 fg_gen_to_start = -1;
8409 cfile->ext_src = NULL;
8425 if (weed_plant_has_leaf(filter, WEED_LEAF_PREFERRED_FPS)) {
8428 cfile->fps = weed_get_double_value(filter, WEED_LEAF_PREFERRED_FPS, &
error);
8435 cfile->ext_src = inst;
8442 fg_gen_to_start = -1;
8447 if (bg_gen_to_start != -1) {
8495 if (
error != WEED_SUCCESS) {
8497 key_to_instance[bg_gen_to_start][key_modes[bg_gen_to_start]] = NULL;
8501 filter_name = weed_get_string_value(filter, WEED_LEAF_NAME, NULL);
8511 else next_inst = NULL;
8531 bg_gen_to_start = -1;
8541 filter_name = weed_get_string_value(filter, WEED_LEAF_NAME, NULL);
8549 lives_snprintf(
cfile->type, 40,
"generator:%s", filter_name);
8550 lives_snprintf(
cfile->file_name,
PATH_MAX,
"generator: %s", filter_name);
8576 bg_gen_to_start = -1;
8589 weed_plant_t **wtmpls;
8590 weed_plant_t *filter, *pgui = NULL;
8591 weed_plant_t *wtmpl;
8592 boolean visible =
TRUE;
8604 }
else filter = plant;
8608 if (i >= num_params) {
8626 if ((weed_plant_has_leaf(wtmpl, WEED_LEAF_COPY_VALUE_TO))
8627 || (pgui && weed_plant_has_leaf(pgui, WEED_LEAF_COPY_VALUE_TO))) {
8629 int flags2 = 0, param_type, param_type2;
8630 weed_plant_t *wtmpl2;
8631 if (weed_plant_has_leaf(wtmpl, WEED_LEAF_COPY_VALUE_TO))
8632 copyto = weed_get_int_value(wtmpl, WEED_LEAF_COPY_VALUE_TO, NULL);
8633 if (pgui && weed_plant_has_leaf(pgui, WEED_LEAF_COPY_VALUE_TO))
8634 copyto = weed_get_int_value(pgui, WEED_LEAF_COPY_VALUE_TO, NULL);
8635 if (copyto == i || copyto < 0) copyto = -1;
8638 wtmpl2 = wtmpls[copyto];
8642 if (param_type == param_type2
8643 && ((flags2 & WEED_PARAMETER_VARIABLE_SIZE)
8644 || (flags2 & WEED_PARAMETER_VALUE_PER_CHANNEL)
8645 || weed_leaf_num_elements(wtmpl, WEED_LEAF_DEFAULT)
8646 == weed_leaf_num_elements(wtmpl2, WEED_LEAF_DEFAULT))) {
8657 int num_params, count = 0;
8659 if (num_params == 0)
return -1;
8660 for (
int i = 0; i < num_params; i++) {
8662 if (weed_get_boolean_value(in_ptmpls[i], WEED_LEAF_IS_TRANSITION, NULL) == WEED_TRUE) {
8674 int error, num_params, i, count = 0;
8675 weed_plant_t **in_ptmpls;
8677 in_ptmpls = weed_get_plantptr_array_counted(filter, WEED_LEAF_IN_PARAMETER_TEMPLATES, &num_params);
8678 if (num_params == 0)
return -1;
8679 for (i = 0; i < num_params; i++) {
8681 if (weed_plant_has_leaf(in_ptmpls[i], WEED_LEAF_IS_VOLUME_MASTER) &&
8682 weed_get_boolean_value(in_ptmpls[i], WEED_LEAF_IS_VOLUME_MASTER, &
error) == WEED_TRUE) {
8697 weed_plant_t *ptmpl;
8700 if (weed_plant_has_leaf(ptmpl, WEED_LEAF_FLAGS)) flags = weed_get_int_value(ptmpl, WEED_LEAF_FLAGS, &
error);
8701 if (flags & WEED_PARAMETER_VALUE_PER_CHANNEL)
return TRUE;
8708 weed_plant_t **ptmpls = weed_get_plantptr_array_counted(filter, WEED_LEAF_IN_PARAMETER_TEMPLATES, &nptmpl);
8710 if (nptmpl == 0)
return FALSE;
8712 for (i = 0; i < nptmpl; i++) {
8724 weed_plant_t *
weed_inst_in_param(weed_plant_t *inst,
int param_num,
boolean skip_hidden,
boolean skip_internal) {
8725 weed_plant_t **in_params;
8726 weed_plant_t *param;
8727 int error, num_params;
8730 if (!weed_plant_has_leaf(inst, WEED_LEAF_IN_PARAMETERS))
continue;
8732 num_params = weed_leaf_num_elements(inst, WEED_LEAF_IN_PARAMETERS);
8734 if (!skip_hidden && !skip_internal) {
8735 if (num_params > param_num) {
8736 in_params = weed_get_plantptr_array(inst, WEED_LEAF_IN_PARAMETERS, &
error);
8737 param = in_params[param_num];
8741 param_num -= num_params;
8748 in_params = weed_get_plantptr_array(inst, WEED_LEAF_IN_PARAMETERS, &
error);
8750 for (i = 0; i < num_params; i++) {
8751 param = in_params[i];
8754 if (count == param_num) {
8772 weed_plant_t **out_params;
8773 weed_plant_t *param;
8774 int error, num_params;
8777 if (!weed_plant_has_leaf(inst, WEED_LEAF_OUT_PARAMETERS))
continue;
8779 num_params = weed_leaf_num_elements(inst, WEED_LEAF_OUT_PARAMETERS);
8781 if (num_params > param_num) {
8782 out_params = weed_get_plantptr_array(inst, WEED_LEAF_OUT_PARAMETERS, &
error);
8783 param = out_params[param_num];
8787 param_num -= num_params;
8796 weed_plant_t **in_params;
8797 weed_plant_t *ptmpl;
8803 in_params = weed_get_plantptr_array_counted(filter, WEED_LEAF_IN_PARAMETER_TEMPLATES, &num_params);
8804 if (num_params <= param_num) {
8809 if (!skip_internal) {
8810 ptmpl = in_params[param_num];
8815 for (i = 0; i < num_params; i++) {
8816 ptmpl = in_params[i];
8818 if (count == param_num) {
8832 weed_plant_t **out_params;
8833 weed_plant_t *ptmpl;
8834 int error, num_params;
8836 if (!weed_plant_has_leaf(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES))
return NULL;
8838 num_params = weed_leaf_num_elements(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES);
8840 if (num_params <= param_num)
return NULL;
8842 out_params = weed_get_plantptr_array(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES, &
error);
8844 ptmpl = out_params[param_num];
8856 weed_plant_t **in_ptmpls;
8857 weed_plant_t *tparamtmpl;
8859 int i, ptype, flags, nparams;
8863 if (!weed_plant_has_leaf(plant, WEED_LEAF_IN_PARAMETER_TEMPLATES))
return -1;
8865 in_ptmpls = weed_get_plantptr_array_counted(plant, WEED_LEAF_IN_PARAMETER_TEMPLATES, &nparams);
8867 for (i = 0; i < nparams; i++) {
8868 tparamtmpl = in_ptmpls[i];
8873 if (gui && ptype == WEED_PARAM_INTEGER && weed_plant_has_leaf(gui, WEED_LEAF_CHOICES))
continue;
8877 if ((ptype == WEED_PARAM_INTEGER || ptype == WEED_PARAM_FLOAT)
8878 && flags == 0 && weed_leaf_num_elements(tparamtmpl, WEED_LEAF_DEFAULT) == 1 &&
8893 int i, ptype, flags, nparams, count = 0;
8894 weed_plant_t **in_ptmpls;
8895 weed_plant_t *tparamtmpl;
8899 if (!weed_plant_has_leaf(plant, WEED_LEAF_IN_PARAMETER_TEMPLATES))
return count;
8901 in_ptmpls = weed_get_plantptr_array_counted(plant, WEED_LEAF_IN_PARAMETER_TEMPLATES, &nparams);
8903 for (i = 0; i < nparams; i++) {
8904 tparamtmpl = in_ptmpls[i];
8907 if ((ptype == WEED_PARAM_INTEGER || ptype == WEED_PARAM_FLOAT)
8908 && flags == 0 && weed_leaf_num_elements(tparamtmpl, WEED_LEAF_DEFAULT) == 1 &&
8921 weed_plant_t *paramtmpl;
8922 weed_plant_t *pgui, *in_param2;
8926 int param_type, param_type2;
8928 if (!in_param)
return -1;
8933 if (pgui && weed_plant_has_leaf(pgui, WEED_LEAF_COPY_VALUE_TO)) {
8934 copyto = weed_get_int_value(pgui, WEED_LEAF_COPY_VALUE_TO, NULL);
8935 if (copyto == pnum || copyto < 0)
return -1;
8938 if (copyto == -1 && weed_plant_has_leaf(paramtmpl, WEED_LEAF_COPY_VALUE_TO))
8939 copyto = weed_get_int_value(paramtmpl, WEED_LEAF_COPY_VALUE_TO, NULL);
8940 if (copyto == pnum || copyto < 0)
return -1;
8948 if (!in_param2)
return -1;
8965 if (flags & WEED_PARAMETER_VALUE_PER_CHANNEL) {
8967 int nvals = weed_leaf_num_elements(in_param2, WEED_LEAF_VALUE);
8969 if (param_type2 == WEED_PARAM_COLOR) {
8970 int cspace = weed_get_int_value(paramtmpl2, WEED_LEAF_COLORSPACE, NULL);
8971 if (cspace == WEED_COLORSPACE_RGB) vsize = 3;
8974 weed_leaf_copy(paramtmpl2,
"host_new_def_backup", paramtmpl2, WEED_LEAF_NEW_DEFAULT);
8975 weed_leaf_copy(in_param2,
"host_value_backup", in_param2, WEED_LEAF_VALUE);
8976 weed_leaf_copy(paramtmpl2, WEED_LEAF_NEW_DEFAULT, in_param, WEED_LEAF_VALUE);
8978 ign_array = weed_get_boolean_array(in_param2, WEED_LEAF_IGNORE, NULL);
8979 for (
int i = 0; i < nvals; i += vsize) {
8980 if (!weed_leaf_elements_equate(in_param2, WEED_LEAF_VALUE, in_param2,
"host_value_backup", i))
8981 ign_array[i] = WEED_FALSE;
8983 ign_array[i] = WEED_TRUE;
8985 weed_set_boolean_array(in_param2, WEED_LEAF_IGNORE, nvals / vsize, ign_array);
8986 weed_leaf_delete(in_param2,
"host_value_backup");
8987 weed_leaf_copy(paramtmpl2, WEED_LEAF_NEW_DEFAULT, paramtmpl2,
"host_new_def_backup");
8988 weed_leaf_delete(paramtmpl2,
"host_new_def_backup");
8991 weed_leaf_copy(in_param2, WEED_LEAF_VALUE, in_param, WEED_LEAF_VALUE);
9003 weed_plant_t *in_param;
9036 #define KEYSCALE 255.
9040 weed_plant_t *inst, *in_param, *paramtmpl;
9042 LiVESList *list = NULL;
9044 weed_plant_t **in_params;
9046 double vald, mind, maxd;
9048 int vali, mini, maxi;
9049 int param_type, pnum, inc_count;
9051 if (hotkey < 0)
return;
9070 in_params = weed_get_plantptr_array(inst, WEED_LEAF_IN_PARAMETERS, NULL);
9071 in_param = in_params[pnum];
9101 switch (param_type) {
9102 case WEED_PARAM_INTEGER:
9103 vali = weed_get_int_value(in_param, WEED_LEAF_VALUE, NULL);
9104 mini = weed_get_int_value(paramtmpl, WEED_LEAF_MIN, NULL);
9105 maxi = weed_get_int_value(paramtmpl, WEED_LEAF_MAX, NULL);
9107 weed_set_int_value(in_param, WEED_LEAF_VALUE, (
int)((
double)mini +
9110 vali = weed_get_int_value(in_param, WEED_LEAF_VALUE, NULL);
9120 case WEED_PARAM_FLOAT:
9121 vald = weed_get_double_value(in_param, WEED_LEAF_VALUE, NULL);
9122 mind = weed_get_double_value(paramtmpl, WEED_LEAF_MIN, NULL);
9123 maxd = weed_get_double_value(paramtmpl, WEED_LEAF_MAX, NULL);
9126 vald = weed_get_double_value(in_param, WEED_LEAF_VALUE, NULL);
9136 case WEED_PARAM_SWITCH:
9138 weed_set_boolean_value(in_param, WEED_LEAF_VALUE, vali);
9139 vali = weed_get_boolean_value(in_param, WEED_LEAF_VALUE, NULL);
9172 weed_plant_t *inst, **in_params, *in_param, *paramtmpl;
9173 int vali, mini, maxi;
9174 double vald, mind, maxd;
9178 if (hotkey < 0)
return 0;
9181 if (!inst)
return 0;
9190 in_params = weed_get_plantptr_array(inst, WEED_LEAF_IN_PARAMETERS, NULL);
9191 in_param = in_params[i];
9196 switch (weed_ptype) {
9197 case WEED_PARAM_INTEGER:
9198 vali = weed_get_int_value(in_param, WEED_LEAF_VALUE, NULL);
9199 mini = weed_get_int_value(paramtmpl, WEED_LEAF_MIN, NULL);
9200 maxi = weed_get_int_value(paramtmpl, WEED_LEAF_MAX, NULL);
9203 return (
double)(vali - mini) / (
double)(maxi - mini) *
KEYSCALE;
9204 case WEED_PARAM_FLOAT:
9205 vald = weed_get_double_value(in_param, WEED_LEAF_VALUE, NULL);
9206 mind = weed_get_double_value(paramtmpl, WEED_LEAF_MIN, NULL);
9207 maxd = weed_get_double_value(paramtmpl, WEED_LEAF_MAX, NULL);
9210 return (vald - mind) / (maxd - mind) *
KEYSCALE;
9211 case WEED_PARAM_SWITCH:
9212 vali = weed_get_boolean_value(in_param, WEED_LEAF_VALUE, NULL);
9260 return weed_filter_get_type(filter, getsub,
TRUE);
9266 char *type = lives_strdup(
"");
9267 weed_plant_t *filter, *inst;
9273 if ((idx = key_to_fx[key][mode]) == -1)
return type;
9274 if ((filter = weed_filters[idx]) == NULL)
return type;
9280 if ((inst = key_to_instance[key][mode]) != NULL) {
9283 }
else type = weed_filter_get_type(filter,
TRUE,
TRUE);
9291 weed_plant_t *filter;
9314 free_key = next_free_key;
9316 if (key_to_fx[i][0] == -1) {
9333 boolean was_started =
FALSE;
9335 int oldkeymode = key_modes[--key];
9336 int orig_mode = mode;
9339 if (key_to_fx[key][mode] == -1)
return FALSE;
9347 if (key_to_instance[key][mode]) {
9349 if (key_modes[key] == mode) modekey = -key - 1;
9350 else key_modes[key] = mode;
9352 key_modes[key] = oldkeymode;
9355 key_to_fx[key][mode] = -1;
9357 if (mode == orig_mode && key_modes[key] == mode) {
9360 if (key_to_fx[key][0] != -1) {
9388 if (key_modes[key] > orig_mode) key_modes[key]--;
9402 if (key_to_fx[key][key_modes[key]] == -1)
return FALSE;
9410 mode >= (key < FX_KEYS_MAX_VIRTUAL ? prefs->max_modes_per_key : 1))
return FALSE;
9411 if (key_to_fx[--key][mode] == -1)
return FALSE;
9419 mode >= (key < FX_KEYS_MAX_VIRTUAL ? prefs->max_modes_per_key : 1))
return -1;
9420 return (key_to_fx[--key][mode]);
9429 return key_modes[--key];
9444 if (key_to_fx[key][i] == -1)
return --i;
9469 return weed_filters[key_to_fx[key][mode]];
9473 #define MAX_AUTHOR_LEN 10
9477 weed_plant_t *filter;
9478 char *filter_name, *tmp;
9480 if (idx == -1)
return lives_strdup(
"");
9481 if ((filter = weed_filters[idx]) == NULL)
return lives_strdup(
"");
9512 weed_plant_t *filter;
9513 if (idx == -1)
return NULL;
9514 if (!(filter = weed_filters[idx]))
return NULL;
9521 weed_plant_t *filter;
9524 if (!inst)
return lives_strdup(
"");
9526 filter_name = weed_get_string_value(filter, WEED_LEAF_NAME, NULL);
9543 weed_plant_t *filter, *plugin_info;
9549 filter = weed_filters[key_to_fx[key][mode]];
9550 plugin_info = weed_get_plantptr_value(filter, WEED_LEAF_PLUGIN_INFO, NULL);
9557 return bg_generator_key;
9561 return fg_generator_key;
9565 return bg_generator_mode;
9569 return fg_generator_mode;
9580 weed_plant_t *inst, **in_params, *ptmpl, *ret;
9584 if (key == -1)
return NULL;
9591 in_params = weed_get_plantptr_array_counted(inst, WEED_LEAF_IN_PARAMETERS, &nparms);
9597 for (i = 0; i < nparms; i++) {
9601 if (ptype == WEED_PARAM_TEXT) {
9627 weed_plant_t *inst, *last_inst;
9641 oldmode = key_modes[key];
9643 if (key_to_fx[key][0] == -1) {
9648 if (newmode == -1) {
9653 newmode = key_modes[key] + 1;
9657 if (newmode == -2) {
9659 newmode = key_modes[key] - 1;
9662 if (key_to_fx[key][newmode] != -1)
break;
9672 if (key_to_fx[key][newmode] == -1) {
9692 if (oldmode != newmode) {
9709 key_modes[real_key] = newmode;
9748 boolean has_gen =
FALSE;
9749 boolean has_non_gen =
FALSE;
9753 if (idx == -1)
return -1;
9758 if (key_to_fx[key][i] != -1) {
9762 else has_non_gen =
TRUE;
9767 key_to_fx[key][i] = idx;
9795 int oldkeymode = key_modes[--key];
9798 boolean has_gen =
FALSE, has_non_gen =
FALSE;
9800 int test = (mode == 0 ? 1 : 0);
9803 if (
id == -1)
return -1;
9807 if ((tid = key_to_fx[key][test]) != -1) {
9809 else has_non_gen =
TRUE;
9813 !all_outs_alpha(weed_filters[
id],
TRUE) && has_non_gen) ||
9826 key_modes[key] = mode;
9828 key_to_fx[key][mode] = id;
9833 key_modes[key] = oldkeymode;
9835 }
else key_to_fx[key][mode] = id;
9845 int key = fg_generator_key;
9846 int mode = fg_generator_mode;
9850 fg_generator_clip = -1;
9852 fg_generator_key = bg_generator_key;
9853 fg_generator_mode = bg_generator_mode;
9854 if (fg_generator_key != -1) {
9857 bg_generator_key = key;
9858 bg_generator_mode = mode;
9867 LiVESList *list = NULL;
9868 char *filter_name, *hashname, *string;
9871 for (i = 0; i < num_weed_filters; i++) {
9873 weed_plant_t *filter = weed_filters[sorted];
9874 filter_name = weed_get_string_value(filter, WEED_LEAF_NAME, &
error);
9875 switch (list_type) {
9878 string = lives_strdup(filter_name);
9879 list = lives_list_append(list, (livespointer)
string);
9884 list = lives_list_append(list, (livespointer)
string);
9889 hashname = lives_strdup(hashnames[sorted][0].
string);
9890 list = lives_list_append(list, (livespointer)hashname);
9915 int num_vals = weed_leaf_num_elements(param, WEED_LEAF_VALUE);
9916 int new_defi, *valis, *nvalis;
9917 double new_defd, *valds, *nvalds;
9918 char *new_defs, **valss, **nvalss;
9922 double *colsds, *cold;
9926 if (index >= vcount) vcount = ++index;
9929 case WEED_PARAM_INTEGER:
9930 if (vcount > num_vals) {
9931 new_defi = weed_get_int_value(paramtmpl, WEED_LEAF_NEW_DEFAULT, NULL);
9932 valis = weed_get_int_array(param, WEED_LEAF_VALUE, NULL);
9934 for (i = 0; i < vcount; i++) {
9935 if (i < num_vals && i < index) nvalis[i] = valis[i];
9936 else if (i <= num_vals && i > index) nvalis[i] = valis[i - 1];
9937 else nvalis[i] = new_defi;
9939 weed_set_int_array(param, WEED_LEAF_VALUE, vcount, nvalis);
9944 case WEED_PARAM_FLOAT:
9945 if (vcount > num_vals) {
9946 new_defd = weed_get_double_value(paramtmpl, WEED_LEAF_NEW_DEFAULT, NULL);
9947 valds = weed_get_double_array(param, WEED_LEAF_VALUE, NULL);
9949 for (i = 0; i < vcount; i++) {
9950 if (i < num_vals && i < index) nvalds[i] = valds[i];
9951 else if (i <= num_vals && i > index) nvalds[i] = valds[i - 1];
9952 else nvalds[i] = new_defd;
9954 weed_set_double_array(param, WEED_LEAF_VALUE, vcount, nvalds);
9960 case WEED_PARAM_SWITCH:
9961 if (vcount > num_vals) {
9962 new_defi = weed_get_boolean_value(paramtmpl, WEED_LEAF_NEW_DEFAULT, NULL);
9963 valis = weed_get_boolean_array(param, WEED_LEAF_VALUE, NULL);
9965 for (i = 0; i < vcount; i++) {
9966 if (i < num_vals && i < index) nvalis[i] = valis[i];
9967 else if (i <= num_vals && i > index) nvalis[i] = valis[i - 1];
9968 else nvalis[i] = new_defi;
9970 weed_set_boolean_array(param, WEED_LEAF_VALUE, vcount, nvalis);
9975 case WEED_PARAM_TEXT:
9976 if (vcount > num_vals) {
9977 new_defs = weed_get_string_value(paramtmpl, WEED_LEAF_NEW_DEFAULT, NULL);
9978 valss = weed_get_string_array(param, WEED_LEAF_VALUE, NULL);
9979 nvalss = (
char **)
lives_malloc(vcount *
sizeof(
char *));
9980 for (i = 0; i < vcount; i++) {
9981 if (i < num_vals && i < index) nvalss[i] = valss[i];
9982 else if (i <= num_vals && i > index) nvalss[i] = valss[i - 1];
9983 else nvalss[i] = new_defs;
9985 weed_set_string_array(param, WEED_LEAF_VALUE, vcount, nvalss);
9987 for (i = 0; i < index; i++) {
9995 case WEED_PARAM_COLOR:
9996 cspace = weed_get_int_value(paramtmpl, WEED_LEAF_COLORSPACE, NULL);
9998 case WEED_COLORSPACE_RGB:
10002 if (index >= vcount) vcount = ++index;
10004 if (weed_leaf_seed_type(paramtmpl, WEED_LEAF_NEW_DEFAULT) == WEED_SEED_INT) {
10005 colsis = weed_get_int_array(param, WEED_LEAF_VALUE, NULL);
10006 if (weed_leaf_num_elements(paramtmpl, WEED_LEAF_NEW_DEFAULT) == 1) {
10008 coli[0] = coli[1] = coli[2] = weed_get_int_value(paramtmpl, WEED_LEAF_NEW_DEFAULT, NULL);
10009 }
else coli = weed_get_int_array(paramtmpl, WEED_LEAF_NEW_DEFAULT, NULL);
10010 valis = weed_get_int_array(param, WEED_LEAF_VALUE, NULL);
10012 for (i = 0; i < vcount; i += 3) {
10013 if (i < num_vals && i < index) {
10014 nvalis[i] = valis[i];
10015 nvalis[i + 1] = valis[i + 1];
10016 nvalis[i + 2] = valis[i + 2];
10017 }
else if (i <= num_vals && i > index) {
10018 nvalis[i] = valis[i - 3];
10019 nvalis[i + 1] = valis[i - 2];
10020 nvalis[i + 2] = valis[i - 1];
10022 nvalis[i] = coli[0];
10023 nvalis[i + 1] = coli[1];
10024 nvalis[i + 2] = coli[2];
10027 weed_set_int_array(param, WEED_LEAF_VALUE, vcount, nvalis);
10032 colsds = weed_get_double_array(param, WEED_LEAF_VALUE, NULL);
10033 if (weed_leaf_num_elements(paramtmpl, WEED_LEAF_NEW_DEFAULT) == 1) {
10035 cold[0] = cold[1] = cold[2] = weed_get_double_value(paramtmpl, WEED_LEAF_NEW_DEFAULT, NULL);
10036 }
else cold = weed_get_double_array(paramtmpl, WEED_LEAF_NEW_DEFAULT, NULL);
10037 valds = weed_get_double_array(param, WEED_LEAF_VALUE, NULL);
10039 for (i = 0; i < vcount; i += 3) {
10040 if (i < num_vals && i < index) {
10041 nvalds[i] = valds[i];
10042 nvalds[i + 1] = valds[i + 1];
10043 nvalds[i + 2] = valds[i + 2];
10044 }
else if (i <= num_vals && i > index) {
10045 nvalds[i] = valds[i - 3];
10046 nvalds[i + 1] = valds[i - 2];
10047 nvalds[i + 2] = valds[i - 1];
10049 nvalds[i] = cold[0];
10050 nvalds[i + 1] = cold[1];
10051 nvalds[i + 2] = cold[2];
10054 weed_set_double_array(param, WEED_LEAF_VALUE, vcount, nvalds);
10066 int *ign_array = weed_get_boolean_array_counted(param, WEED_LEAF_IGNORE, &num_vals);
10067 if (vcount > num_vals) {
10069 for (i = num_vals; i < vcount; i++) {
10070 ign_array[i] = WEED_TRUE;
10072 weed_set_boolean_array(param, WEED_LEAF_IGNORE, vcount, ign_array);
10079 static int get_default_element_int(weed_plant_t *param,
int idx,
int mpy,
int add) {
10082 weed_plant_t *ptmpl = weed_get_plantptr_value(param, WEED_LEAF_TEMPLATE, &
error);
10087 val = valsi[idx * mpy + add];
10091 if (weed_plant_has_leaf(ptmpl, WEED_LEAF_DEFAULT)
10092 && weed_leaf_num_elements(ptmpl, WEED_LEAF_DEFAULT) > idx * mpy + add) {
10093 valsi = weed_get_int_array(ptmpl, WEED_LEAF_DEFAULT, &
error);
10094 val = valsi[idx * mpy + add];
10098 if (weed_leaf_num_elements(ptmpl, WEED_LEAF_NEW_DEFAULT) == mpy) {
10099 valsi = weed_get_int_array(ptmpl, WEED_LEAF_DEFAULT, &
error);
10104 return weed_get_int_value(ptmpl, WEED_LEAF_NEW_DEFAULT, &
error);
10108 static double get_default_element_double(weed_plant_t *param,
int idx,
int mpy,
int add) {
10109 double *valsd, val;
10111 weed_plant_t *ptmpl = weed_get_plantptr_value(param, WEED_LEAF_TEMPLATE, &
error);
10116 val = valsd[idx * mpy + add];
10120 if (weed_plant_has_leaf(ptmpl, WEED_LEAF_DEFAULT)
10121 && weed_leaf_num_elements(ptmpl, WEED_LEAF_DEFAULT) > idx * mpy + add) {
10122 valsd = weed_get_double_array(ptmpl, WEED_LEAF_DEFAULT, &
error);
10123 val = valsd[idx * mpy + add];
10127 if (weed_leaf_num_elements(ptmpl, WEED_LEAF_NEW_DEFAULT) == mpy) {
10128 valsd = weed_get_double_array(ptmpl, WEED_LEAF_DEFAULT, &
error);
10133 return weed_get_double_value(ptmpl, WEED_LEAF_NEW_DEFAULT, &
error);
10137 static int get_default_element_bool(weed_plant_t *param,
int idx) {
10140 weed_plant_t *ptmpl = weed_get_plantptr_value(param, WEED_LEAF_TEMPLATE, &
error);
10149 if (weed_plant_has_leaf(ptmpl, WEED_LEAF_DEFAULT) && weed_leaf_num_elements(ptmpl, WEED_LEAF_DEFAULT) > idx) {
10150 valsi = weed_get_boolean_array(ptmpl, WEED_LEAF_DEFAULT, &
error);
10155 return weed_get_boolean_value(ptmpl, WEED_LEAF_NEW_DEFAULT, &
error);
10159 static char *get_default_element_string(weed_plant_t *param,
int idx) {
10160 char **valss, *val, *val2;
10163 weed_plant_t *ptmpl = weed_get_plantptr_value(param, WEED_LEAF_TEMPLATE, &
error);
10168 val = lives_strdup(valss[idx]);
10169 for (i = 0; i < numvals; i++)
lives_free(valss[i]);
10173 if (weed_plant_has_leaf(ptmpl, WEED_LEAF_DEFAULT) && (numvals = weed_leaf_num_elements(ptmpl, WEED_LEAF_DEFAULT)) > idx) {
10174 valss = weed_get_string_array(ptmpl, WEED_LEAF_DEFAULT, &
error);
10175 val = lives_strdup(valss[idx]);
10176 for (i = 0; i < numvals; i++)
lives_free(valss[i]);
10180 val = weed_get_string_value(ptmpl, WEED_LEAF_NEW_DEFAULT, &
error);
10181 val2 = lives_strdup(val);
10192 weed_plant_t *pchange = (weed_plant_t *)pchain, *last_pchange = NULL;
10193 weed_plant_t *wtmpl;
10194 weed_timecode_t tc_diff = 0, tc_diff2;
10196 char **valss, **nvalss;
10197 double *last_valuesd, *next_valuesd;
10198 double *valds = NULL, *nvalds, last_valued;
10199 double last_valuedr, last_valuedg, last_valuedb, last_valueda;
10200 int *last_valuesi, *next_valuesi;
10201 int *valis = NULL, *nvalis, last_valuei;
10202 int last_valueir, last_valueig, last_valueib, last_valueia;
10203 int *ign, num_ign = 0;
10204 int ptype, cspace = 0;
10205 int got_npc, num_values, xnum, num_pvals, k, j;
10207 if (!pchange)
return TRUE;
10208 if ((num_values = weed_leaf_num_elements(param, WEED_LEAF_VALUE)) == 0)
return FALSE;
10212 last_pchange = pchange;
10218 if ((num_pvals = weed_leaf_num_elements((weed_plant_t *)pchain, WEED_LEAF_VALUE)) > num_values)
10219 num_values = num_pvals;
10221 lpc = (
void **)
lives_calloc(num_values,
sizeof(
void *));
10222 npc = (
void **)
lives_calloc(num_values,
sizeof(
void *));
10224 if (num_values == 1) {
10225 lpc[0] = last_pchange;
10228 pchange = (weed_plant_t *)pchain;
10231 num_pvals = weed_leaf_num_elements(pchange, WEED_LEAF_VALUE);
10232 if (num_pvals > num_values) num_pvals = num_values;
10233 if (weed_plant_has_leaf(pchange, WEED_LEAF_IGNORE)) {
10234 ign = weed_get_boolean_array_counted(pchange, WEED_LEAF_IGNORE, &num_ign);
10237 for (j = 0; j < num_pvals; j++)
if (!ign || j >= num_ign || ign[j] == WEED_FALSE) lpc[j] = pchange;
10239 for (j = 0; j < num_pvals; j++) {
10240 if (!npc[j] && (!ign || j >= num_ign || ign[j] == WEED_FALSE)) npc[j] = pchange;
10243 for (j = 0; j < num_values; j++) {
10244 if (npc[j]) got_npc++;
10246 if (got_npc == num_values) {
10258 case WEED_PARAM_FLOAT:
10259 valds = (
double *)
lives_malloc(num_values * (
sizeof(
double)));
10261 case WEED_PARAM_COLOR:
10262 cspace = weed_get_int_value(wtmpl, WEED_LEAF_COLORSPACE, NULL);
10264 case WEED_COLORSPACE_RGB:
10265 if (!(num_values & 3))
return TRUE;
10266 if (weed_leaf_seed_type(wtmpl, WEED_LEAF_DEFAULT) == WEED_SEED_INT) {
10269 valds = (
double *)
lives_malloc(num_values * (
sizeof(
double)));
10272 case WEED_COLORSPACE_RGBA:
10273 if (num_values & 3)
return TRUE;
10274 if (weed_leaf_seed_type(wtmpl, WEED_LEAF_DEFAULT) == WEED_SEED_INT) {
10277 valds = (
double *)
lives_malloc(num_values * (
sizeof(
double)));
10282 case WEED_PARAM_SWITCH:
10283 case WEED_PARAM_INTEGER:
10288 for (j = 0; j < num_values; j++) {
10290 if (!lpc[j] && !npc[j])
continue;
10291 if (lpc[j] && npc[j]) tc_diff = weed_get_int64_value((weed_plant_t *)npc[j], WEED_LEAF_TIMECODE, NULL) -
10292 weed_get_int64_value((weed_plant_t *)lpc[j], WEED_LEAF_TIMECODE, NULL);
10294 case WEED_PARAM_FLOAT:
10297 valds[j] = get_default_element_double(param, j, 1, 0);
10302 xnum = weed_leaf_num_elements((weed_plant_t *)lpc[j], WEED_LEAF_VALUE);
10304 nvalds = weed_get_double_array((weed_plant_t *)lpc[j], WEED_LEAF_VALUE, NULL);
10305 valds[j] = nvalds[j];
10307 }
else valds[j] = get_default_element_double(param, j, 1, 0);
10311 next_valuesd = weed_get_double_array((weed_plant_t *)npc[j], WEED_LEAF_VALUE, NULL);
10312 last_valuesd = weed_get_double_array_counted((weed_plant_t *)lpc[j], WEED_LEAF_VALUE, &xnum);
10313 if (xnum > j) last_valued = last_valuesd[j];
10314 else last_valued = get_default_element_double(param, j, 1, 0);
10316 valds[j] = last_valued + (double)(next_valuesd[j] - last_valued) / (double)(tc_diff /
TICKS_PER_SECOND_DBL) *
10317 (double)((tc - weed_get_int64_value((weed_plant_t *)lpc[j], WEED_LEAF_TIMECODE, NULL)) /
TICKS_PER_SECOND_DBL);
10322 case WEED_PARAM_COLOR:
10323 if (num_values != weed_leaf_num_elements(last_pchange, WEED_LEAF_VALUE))
break;
10326 case WEED_COLORSPACE_RGB:
10328 if (weed_leaf_seed_type(wtmpl, WEED_LEAF_DEFAULT) == WEED_SEED_INT) {
10331 valis[k] = get_default_element_int(param, j, 3, 0);
10332 valis[k + 1] = get_default_element_int(param, j, 3, 1);
10333 valis[k + 2] = get_default_element_int(param, j, 3, 2);
10339 xnum = weed_leaf_num_elements((weed_plant_t *)lpc[j], WEED_LEAF_VALUE);
10341 nvalis = weed_get_int_array((weed_plant_t *)lpc[j], WEED_LEAF_VALUE, NULL);
10342 valis[k] = nvalis[k];
10343 valis[k + 1] = nvalis[k + 1];
10344 valis[k + 2] = nvalis[k + 2];
10347 valis[k] = get_default_element_int(param, j, 3, 0);
10348 valis[k + 1] = get_default_element_int(param, j, 3, 1);
10349 valis[k + 2] = get_default_element_int(param, j, 3, 2);
10355 next_valuesi = weed_get_int_array((weed_plant_t *)npc[j], WEED_LEAF_VALUE, NULL);
10356 last_valuesi = weed_get_int_array_counted((weed_plant_t *)lpc[j], WEED_LEAF_VALUE, &xnum);
10358 last_valueir = last_valuesi[k];
10359 last_valueig = last_valuesi[k + 1];
10360 last_valueib = last_valuesi[k + 2];
10362 last_valueir = get_default_element_int(param, j, 3, 0);
10363 last_valueig = get_default_element_int(param, j, 3, 1);
10364 last_valueib = get_default_element_int(param, j, 3, 2);
10367 if (!next_valuesi)
continue;
10369 valis[k] = last_valueir + (next_valuesi[k] - last_valueir) / (tc_diff /
TICKS_PER_SECOND_DBL) *
10370 ((tc_diff2 = (tc - weed_get_int64_value((weed_plant_t *)lpc[j],
10372 valis[k + 1] = last_valueig + (next_valuesi[k + 1] - last_valueig) / (tc_diff /
TICKS_PER_SECOND_DBL) *
10374 valis[k + 2] = last_valueib + (next_valuesi[k + 2] - last_valueib) / (tc_diff /
TICKS_PER_SECOND_DBL) *
10382 valds[k] = get_default_element_double(param, j, 3, 0);
10383 valds[k + 1] = get_default_element_double(param, j, 3, 1);
10384 valds[k + 2] = get_default_element_double(param, j, 3, 2);
10390 xnum = weed_leaf_num_elements((weed_plant_t *)lpc[j], WEED_LEAF_VALUE);
10392 nvalds = weed_get_double_array((weed_plant_t *)lpc[j], WEED_LEAF_VALUE, NULL);
10393 valds[k] = nvalds[k];
10394 valds[k + 1] = nvalds[k + 1];
10395 valds[k + 2] = nvalds[k + 2];
10398 valds[k] = get_default_element_double(param, j, 3, 0);
10399 valds[k + 1] = get_default_element_double(param, j, 3, 1);
10400 valds[k + 2] = get_default_element_double(param, j, 3, 2);
10406 next_valuesd = weed_get_double_array((weed_plant_t *)npc[j], WEED_LEAF_VALUE, NULL);
10407 last_valuesd = weed_get_double_array_counted((weed_plant_t *)lpc[j], WEED_LEAF_VALUE, &xnum);
10409 last_valuedr = last_valuesd[k];
10410 last_valuedg = last_valuesd[k + 1];
10411 last_valuedb = last_valuesd[k + 2];
10413 last_valuedr = get_default_element_double(param, j, 3, 0);
10414 last_valuedg = get_default_element_double(param, j, 3, 1);
10415 last_valuedb = get_default_element_double(param, j, 3, 2);
10417 valds[k] = last_valuedr + (next_valuesd[k] - last_valuedr) / (tc_diff /
TICKS_PER_SECOND_DBL) *
10418 ((tc_diff2 = (tc - weed_get_int64_value((weed_plant_t *)lpc[j],
10420 valds[k + 1] = last_valuedg + (next_valuesd[k + 1] - last_valuedg) / (tc_diff /
TICKS_PER_SECOND_DBL) *
10422 valds[k + 2] = last_valuedb + (next_valuesd[k + 2] - last_valuedb) / (tc_diff /
TICKS_PER_SECOND_DBL) *
10430 case WEED_COLORSPACE_RGBA:
10432 if (weed_leaf_seed_type(wtmpl, WEED_LEAF_DEFAULT) == WEED_SEED_INT) {
10435 valis[k] = get_default_element_int(param, j, 4, 0);
10436 valis[k + 1] = get_default_element_int(param, j, 4, 1);
10437 valis[k + 2] = get_default_element_int(param, j, 4, 2);
10438 valis[k + 3] = get_default_element_int(param, j, 4, 3);
10444 xnum = weed_leaf_num_elements((weed_plant_t *)lpc[j], WEED_LEAF_VALUE);
10446 nvalis = weed_get_int_array((weed_plant_t *)lpc[j], WEED_LEAF_VALUE, NULL);
10447 valis[k] = nvalis[k];
10448 valis[k + 1] = nvalis[k + 1];
10449 valis[k + 2] = nvalis[k + 2];
10450 valis[k + 3] = nvalis[k + 3];
10453 valis[k] = get_default_element_int(param, j, 4, 0);
10454 valis[k + 1] = get_default_element_int(param, j, 4, 1);
10455 valis[k + 2] = get_default_element_int(param, j, 4, 2);
10456 valis[k + 3] = get_default_element_int(param, j, 4, 3);
10462 next_valuesi = weed_get_int_array((weed_plant_t *)npc[j], WEED_LEAF_VALUE, NULL);
10463 last_valuesi = weed_get_int_array_counted((weed_plant_t *)lpc[j], WEED_LEAF_VALUE, &xnum);
10465 last_valueir = last_valuesi[k];
10466 last_valueig = last_valuesi[k + 1];
10467 last_valueib = last_valuesi[k + 2];
10468 last_valueia = last_valuesi[k + 3];
10470 last_valueir = get_default_element_int(param, j, 4, 0);
10471 last_valueig = get_default_element_int(param, j, 4, 1);
10472 last_valueib = get_default_element_int(param, j, 4, 2);
10473 last_valueia = get_default_element_int(param, j, 4, 3);
10476 if (!next_valuesi)
continue;
10478 valis[k] = last_valueir + (next_valuesi[k] - last_valueir) / (tc_diff /
TICKS_PER_SECOND_DBL) *
10479 ((tc_diff2 = (tc - weed_get_int64_value((weed_plant_t *)lpc[j],
10481 valis[k + 1] = last_valueig + (next_valuesi[k + 1] - last_valueig) / (tc_diff /
TICKS_PER_SECOND_DBL) *
10483 valis[k + 2] = last_valueib + (next_valuesi[k + 2] - last_valueib) / (tc_diff /
TICKS_PER_SECOND_DBL) *
10485 valis[k + 3] = last_valueia + (next_valuesi[k + 3] - last_valueia) / (tc_diff /
TICKS_PER_SECOND_DBL) *
10493 valds[k] = get_default_element_double(param, j, 4, 0);
10494 valds[k + 1] = get_default_element_double(param, j, 4, 1);
10495 valds[k + 2] = get_default_element_double(param, j, 4, 2);
10496 valds[k + 3] = get_default_element_double(param, j, 4, 3);
10502 xnum = weed_leaf_num_elements((weed_plant_t *)lpc[j], WEED_LEAF_VALUE);
10504 nvalds = weed_get_double_array((weed_plant_t *)lpc[j], WEED_LEAF_VALUE, NULL);
10505 valds[k] = nvalds[k];
10506 valds[k + 1] = nvalds[k + 1];
10507 valds[k + 2] = nvalds[k + 2];
10508 valds[k + 3] = nvalds[k + 3];
10511 valds[k] = get_default_element_double(param, j, 4, 0);
10512 valds[k + 1] = get_default_element_double(param, j, 4, 1);
10513 valds[k + 2] = get_default_element_double(param, j, 4, 2);
10514 valds[k + 3] = get_default_element_double(param, j, 4, 3);
10520 next_valuesd = weed_get_double_array((weed_plant_t *)npc[j], WEED_LEAF_VALUE, NULL);
10521 last_valuesd = weed_get_double_array_counted((weed_plant_t *)lpc[j], WEED_LEAF_VALUE, &xnum);
10523 last_valuedr = last_valuesd[k];
10524 last_valuedg = last_valuesd[k + 1];
10525 last_valuedb = last_valuesd[k + 2];
10526 last_valueda = last_valuesd[k + 3];
10528 last_valuedr = get_default_element_double(param, j, 4, 0);
10529 last_valuedg = get_default_element_double(param, j, 4, 1);
10530 last_valuedb = get_default_element_double(param, j, 4, 2);
10531 last_valueda = get_default_element_double(param, j, 4, 3);
10533 valds[k] = last_valuedr + (next_valuesd[k] - last_valuedr) / (tc_diff /
TICKS_PER_SECOND_DBL) *
10534 ((tc_diff2 = (tc - weed_get_int64_value((weed_plant_t *)lpc[j],
10536 valds[k + 1] = last_valuedg + (next_valuesd[k + 1] - last_valuedg) / (tc_diff /
TICKS_PER_SECOND_DBL) *
10538 valds[k + 2] = last_valuedb + (next_valuesd[k + 2] - last_valuedb) / (tc_diff /
TICKS_PER_SECOND_DBL) *
10540 valds[k + 3] = last_valueda + (next_valuesd[k + 3] - last_valuedb) / (tc_diff /
TICKS_PER_SECOND_DBL) *
10550 case WEED_PARAM_INTEGER:
10554 nvalis = weed_get_int_array((weed_plant_t *)npc[j], WEED_LEAF_VALUE, NULL);
10555 valis[j] = nvalis[j];
10560 xnum = weed_leaf_num_elements((weed_plant_t *)lpc[j], WEED_LEAF_VALUE);
10562 nvalis = weed_get_int_array((weed_plant_t *)lpc[j], WEED_LEAF_VALUE, NULL);
10563 valis[j] = nvalis[j];
10565 }
else valis[j] = get_default_element_int(param, j, 1, 0);
10571 valis[j] = get_default_element_int(param, j, 1, 0);
10576 xnum = weed_leaf_num_elements((weed_plant_t *)lpc[j], WEED_LEAF_VALUE);
10578 nvalis = weed_get_int_array((weed_plant_t *)lpc[j], WEED_LEAF_VALUE, NULL);
10579 valis[j] = nvalis[j];
10581 }
else valis[j] = get_default_element_int(param, j, 1, 0);
10585 next_valuesi = weed_get_int_array((weed_plant_t *)npc[j], WEED_LEAF_VALUE, NULL);
10586 last_valuesi = weed_get_int_array_counted((weed_plant_t *)lpc[j], WEED_LEAF_VALUE, &xnum);
10587 if (xnum > j) last_valuei = last_valuesi[j];
10588 else last_valuei = get_default_element_int(param, j, 1, 0);
10591 ((tc - weed_get_int64_value((weed_plant_t *)lpc[j], WEED_LEAF_TIMECODE, NULL)) /
TICKS_PER_SECOND_DBL) + .5;
10596 case WEED_PARAM_SWITCH:
10599 nvalis = weed_get_boolean_array((weed_plant_t *)npc[j], WEED_LEAF_VALUE, NULL);
10600 valis[j] = nvalis[j];
10605 xnum = weed_leaf_num_elements((weed_plant_t *)lpc[j], WEED_LEAF_VALUE);
10607 nvalis = weed_get_boolean_array((weed_plant_t *)lpc[j], WEED_LEAF_VALUE, NULL);
10608 valis[j] = nvalis[j];
10610 }
else valis[j] = get_default_element_bool(param, j);
10614 case WEED_PARAM_TEXT:
10616 valss = weed_get_string_array(param, WEED_LEAF_VALUE, NULL);
10618 nvalss = weed_get_string_array((weed_plant_t *)npc[j], WEED_LEAF_VALUE, NULL);
10619 valss[j] = lives_strdup(nvalss[j]);
10620 for (k = 0; k < num_values; k++)
lives_free(nvalss[k]);
10622 weed_set_string_array(param, WEED_LEAF_VALUE, num_values, valss);
10623 for (k = 0; k < num_values; k++)
lives_free(valss[k]);
10628 xnum = weed_leaf_num_elements((weed_plant_t *)lpc[j], WEED_LEAF_VALUE);
10630 nvalss = weed_get_string_array((weed_plant_t *)lpc[j], WEED_LEAF_VALUE, NULL);
10631 valss[j] = lives_strdup(nvalss[j]);
10632 for (k = 0; k < xnum; k++)
lives_free(nvalss[k]);
10634 }
else valss[j] = get_default_element_string(param, j);
10635 weed_set_string_array(param, WEED_LEAF_VALUE, num_values, valss);
10636 for (k = 0; k < num_values; k++)
lives_free(valss[k]);
10645 case WEED_PARAM_FLOAT:
10646 weed_set_double_array(param, WEED_LEAF_VALUE, num_values, valds);
10649 case WEED_PARAM_COLOR:
10651 case WEED_COLORSPACE_RGB:
10652 if (weed_leaf_seed_type(wtmpl, WEED_LEAF_DEFAULT) == WEED_SEED_INT) {
10653 weed_set_int_array(param, WEED_LEAF_VALUE, num_values, valis);
10656 weed_set_double_array(param, WEED_LEAF_VALUE, num_values, valds);
10662 case WEED_PARAM_INTEGER:
10663 weed_set_int_array(param, WEED_LEAF_VALUE, num_values, valis);
10666 case WEED_PARAM_SWITCH:
10667 weed_set_boolean_array(param, WEED_LEAF_VALUE, num_values, valis);
10685 weed_plant_t **in_params;
10687 int num_params, offset = 0;
10691 for (
int i = offset; i < offset + num_params; i++) {
10693 pchain = pchains[i];
10703 offset += num_params;
10730 char *
make_weed_hashname(
int filter_idx,
boolean fullname,
boolean use_extra_authors,
char sep,
boolean subs) {
10731 weed_plant_t *filter, *plugin_info;
10734 char *plugin_name, *filter_name, *filter_author, *filter_version, *hashname, *filename;
10736 boolean use_micro =
FALSE;
10740 if (filter_idx < 0 || filter_idx >= num_weed_filters)
return lives_strdup(
"");
10742 if (!fullname) type += 2;
10743 if (use_extra_authors) type++;
10747 use_extra_authors =
FALSE;
10751 xsep[0] = xsep[1] = 0;
10752 if (hashnames[filter_idx][type].
string)
10753 return lives_strdup(hashnames[filter_idx][type].
string);
10756 filter = weed_filters[filter_idx];
10758 if (sep == 0 && hashnames[filter_idx][type].
string) {
10759 return lives_strdup(hashnames[filter_idx][type].
string);
10761 if (weed_plant_has_leaf(filter, WEED_LEAF_PLUGIN_INFO)) {
10762 plugin_info = weed_get_plantptr_value(filter, WEED_LEAF_PLUGIN_INFO, NULL);
10763 if (weed_plant_has_leaf(plugin_info, WEED_LEAF_PACKAGE_NAME)) {
10764 filename = weed_get_string_value(plugin_info, WEED_LEAF_PACKAGE_NAME, NULL);
10767 lives_snprintf(plugin_fname,
PATH_MAX,
"%s", plugin_name);
10771 filename = F2U8(plugin_fname);
10774 return lives_strdup(
"");
10779 if (!use_extra_authors || !weed_plant_has_leaf(filter, WEED_LEAF_EXTRA_AUTHORS))
10782 filter_author = weed_get_string_value(filter, WEED_LEAF_EXTRA_AUTHORS, NULL);
10784 version = weed_get_int_value(filter, WEED_LEAF_VERSION, NULL);
10787 hashname = lives_strconcat(filename, xsep, filter_name, xsep, filter_author, NULL);
10790 int micro_version = weed_get_int_value(filter, WEED_LEAF_MICRO_VERSION, NULL);
10795 hashname = lives_strconcat(filename, filter_name, filter_author, filter_version, NULL);
10800 hashname = lives_strconcat(filename, filter_name, NULL);
10806 char *xhashname =
subst(hashname,
" ",
"_");
10821 static char *fix_hashnames(
const char *old) {
10822 const char *alterations[4] = {
"frei0rFrei0r: ",
"lapdspaLADSPA: ",
"libvisuallibvisual: ", NULL};
10823 const char *replacements[4] = {
"Frei0r",
"LADSPA",
"libvisual", NULL};
10824 char *hashname_new = NULL;
10826 while (alterations[i]) {
10827 if (strstr(old, alterations[i])) {
10828 hashname_new =
subst(old, alterations[i], replacements[i]);
10833 if (hashname_new) {
10834 return hashname_new;
10836 return lives_strdup(old);
10842 char *xhashname = fix_hashnames(hashname);
10846 if (!fullname) type = 2;
10850 for (i = 0; i < num_weed_filters; i++) {
10851 if (numhash == hashnames[i][type].hash) {
10861 if (hashnames && hashnames[0][type].
string) {
10862 for (i = 0; i < num_weed_filters; i++) {
10863 if (numhash == hashnames[i][type].hash) {
10873 for (i = 0; i < num_weed_filters; i++) {
10874 if (numhash == hashnames[i][type].hash) {
10887 static boolean check_match(weed_plant_t *filter,
const char *pkg,
const char *fxname,
const char *auth,
int version) {
10889 weed_plant_t *plugin_info;
10892 char *plugin_name, *filter_name, *filter_author;
10894 int filter_version;
10899 if (weed_plant_has_leaf(filter, WEED_LEAF_PLUGIN_INFO)) {
10900 plugin_info = weed_get_plantptr_value(filter, WEED_LEAF_PLUGIN_INFO, NULL);
10901 if (weed_plant_has_leaf(plugin_info, WEED_LEAF_PACKAGE_NAME)) {
10905 lives_snprintf(plugin_fname,
PATH_MAX,
"%s", plugin_name);
10908 filename = F2U8(plugin_fname);
10921 if (fxname && *fxname) {
10922 filter_name = weed_get_string_value(filter, WEED_LEAF_NAME, NULL);
10930 if (auth && *auth) {
10940 filter_version = weed_get_int_value(filter, WEED_LEAF_VERSION, NULL);
10959 weed_plant_t *filter;
10962 int count = 1, count2 = 0;
10967 for (i = 0; i < num_weed_filters; i++) {
10968 filter = weed_filters[i];
10970 if (check_match(filter, pkg, fxname, auth,
version)) {
10979 for (i = 0; count2 < count - 1; i++) {
10980 filter = weed_filters[i];
10982 if (check_match(filter, pkg, fxname, auth,
version)) {
10983 rvals[count2++] = i;
10988 rvals[count2] = -1;
10996 int highestv = 0,
version, i = 0, hidx = -1;
10998 while ((
version = allversions[i] != -1)) {
11006 if (xversion) *xversion = highestv;
11015 if (idx > -1 && idx < num_weed_filters)
return weed_filters[idx];
11037 static size_t weed_leaf_serialise(
int fd, weed_plant_t *plant,
const char *key,
boolean write_all,
unsigned char **mem) {
11038 void *value = NULL, *valuer = NULL;
11040 size_t totsize = 0;
11061 totsize += 4 + keylen;
11065 st = weed_leaf_seed_type(plant, key);
11066 if (!mem && st == WEED_SEED_PLANTPTR) st = WEED_SEED_VOIDPTR;
11073 ne = weed_leaf_num_elements(plant, key);
11084 if (!mem && !
lives_strcmp(key, WEED_LEAF_PIXEL_DATA)) {
11092 boolean contig =
FALSE;
11093 size_t padding = 0;
11119 for (j = 0; j < nplanes; j++) {
11121 if (contig && j < nplanes - 1) padding = pixel_data[j + 1] - pixel_data[j] - vlen;
11129 for (j = 0; j < nplanes; j++) {
11142 for (j = 0; j < ne; j++) {
11143 vlen = (weed_size_t)weed_leaf_element_size(plant, key, j);
11144 if (!mem && vlen == 0) {
11147 if (st > 64) vlen = 8;
11149 if (st != WEED_SEED_STRING) {
11150 if (vlen == 0) value = NULL;
11153 weed_leaf_get(plant, key, j, value);
11159 weed_leaf_get(plant, key, j, &value);
11162 if (!mem && weed_leaf_seed_type(plant, key) > 64) {
11169 *((uint64_t *)valuer) = (uint64_t)(*((
void **)value));
11170 vlen =
sizeof(uint64_t);
11171 }
else valuer = value;
11175 if (st != WEED_SEED_STRING) {
11186 if (valuer != value)
lives_freep((
void **)&valuer);
11187 totsize += 4 + vlen;
11205 size_t totsize = 0;
11206 weed_size_t nleaves;
11207 char **proplist = weed_plant_list_leaves(plant, &nleaves);
11209 int i = (int)nleaves;
11210 int pd_needed = 0, pd_reqs = 0;
11223 totsize += weed_leaf_serialise(fd, plant, WEED_LEAF_TYPE,
TRUE, mem);
11226 for (i = 1; (prop = proplist[i]); i++) {
11228 if (pd_needed > 0) {
11231 if (pd_reqs > 3) pd_needed = 0;
11238 if (pd_reqs < 4 && (!strcmp(prop, WEED_LEAF_WIDTH) || !strcmp(prop, WEED_LEAF_HEIGHT)
11240 || !strcmp(prop, WEED_LEAF_ROWSTRIDES))) {
11241 if (++pd_reqs == 4 && pd_needed > 1) {
11242 totsize += weed_leaf_serialise(fd, plant, prop,
TRUE, mem);
11244 totsize += weed_leaf_serialise(fd, plant, WEED_LEAF_PIXEL_DATA,
TRUE, mem);
11251 totsize += weed_leaf_serialise(fd, plant, prop,
TRUE, mem);
11259 static int32_t weed_plant_mutate(weed_plantptr_t plant, int32_t newtype) {
11261 int32_t flags = weed_leaf_get_flags(plant, WEED_LEAF_TYPE);
11263 weed_leaf_set_flags(plant, WEED_LEAF_TYPE, flags & ~(WEED_FLAG_IMMUTABLE));
11264 weed_set_int_value(plant, WEED_LEAF_TYPE, newtype);
11266 weed_leaf_set_flags(plant, WEED_LEAF_TYPE, WEED_FLAG_IMMUTABLE);
11271 #define REALIGN_MAX (40 * 1024 * 1024)
11272 #define MAX_FRAME_SIZE MILLIONS(100)
11273 #define MAX_FRAME_SIZE64 3019898880
11275 static int realign_typeleaf(
int fd, weed_plant_t *plant) {
11277 const char XMATCH[8] = {4, 0, 0, 0,
't',
'y',
'p',
'e'};
11283 for (len = 8; len > 0; len--) {
11284 if (!memcmp((
void *)(buff + 12 - len), (
void *)(XMATCH + 8 - len), len))
break;
11286 if (len == 8) len--;
11288 while (--count != 0) {
11289 if (buff[11] == XMATCH[len]) {
11292 nl = (uint32_t)((buff[3] << 24) + (buff[2] << 16) + (buff[1] << 8) + buff[0]);
11296 weed_plant_mutate(plant, type);
11335 static int weed_leaf_deserialise(
int fd, weed_plant_t *plant,
const char *key,
unsigned char **mem,
11336 boolean check_key) {
11337 void **values = NULL;
11348 weed_size_t vlen64_tot = 0;
11350 char *mykey = NULL;
11353 boolean check_ptrs =
FALSE;
11361 if (!key && check_key) {
11366 if (!key || check_key) {
11379 g_print(
"len for %s was %d\n", key, len);
11385 if (!mykey)
return -5;
11404 if (!key) key = mykey;
11419 if (st < 64 && (st != WEED_SEED_INT && st != WEED_SEED_BOOLEAN && st != WEED_SEED_DOUBLE && st != WEED_SEED_INT64 &&
11420 st != WEED_SEED_STRING && st != WEED_SEED_VOIDPTR && st != WEED_SEED_PLANTPTR)) {
11422 g_printerr(
"unknown seed type %d %s\n", st, mykey);
11423 break_me(
"ink. seed type in w.l. deser");
11429 if (check_key && !strcmp(key, WEED_LEAF_TYPE)) {
11431 if (st != WEED_SEED_INT) {
11455 for (j = ne ; j >= 0;
lives_freep((
void **)&values[j--]));
11467 }
else values = NULL;
11469 if (check_key && !strcmp(key, WEED_LEAF_TYPE)) {
11478 if (!mem && !
lives_strcmp(key, WEED_LEAF_PIXEL_DATA)) {
11479 int width, height, pal = 0, *rs = NULL, nplanes = ne;
11487 if (nplanes != ne) {
11488 LIVES_WARN(
"Invalid planes in retrieved layer");
11493 for (j = 0; j < ne; j++) {
11496 for (--j; j >= 0;
lives_freep((
void **)&values[j--]));
11502 if (j == 0 && vlen == 0) {
11505 if (
id == 0x44454557) {
11521 for (
int p = 0; p < nplanes; p++) {
11524 vlen64_tot += vlen64[p];
11546 weed_set_voidptr_value(plant, WEED_LEAF_PIXEL_DATA, NULL);
11560 for (i = 1; i < nplanes; i++) {
11561 values[i] = values[i - 1] + vlen64[i];
11575 for (--j; j >= 0;
lives_freep((
void **)&values[j--]));
11582 xrs = vlen / height;
11586 LIVES_WARN(
"invalid frame size recovering layer");
11587 msg =
lives_strdup_printf(
" for plane %d, size is %d. Should be %d. Will adjust rs to %d, width to %d "
11588 "and height to %d\n", j, vlen, rs[j] * height, xrs, xw, xh);
11602 for (--j; j >= 0; j--)
lives_free(values[j]);
11603 weed_set_voidptr_value(plant, WEED_LEAF_PIXEL_DATA, NULL);
11615 weed_set_voidptr_array(plant, WEED_LEAF_PIXEL_DATA, nplanes, values);
11616 while (nplanes != 0) values[--nplanes] = NULL;
11620 for (i = 0; i < ne; i++) {
11624 for (--i; i >= 0;
lives_freep((
void **)&values[i--]));
11634 if (st == WEED_SEED_STRING) {
11636 for (--i; i >= 0;
lives_freep((
void **)&values[i--]));
11655 if (st != WEED_SEED_STRING)
11659 if (bytes < vlen) {
11660 for (--i; i >= 0;
lives_freep((
void **)&values[i--]));
11670 if (st == WEED_SEED_STRING) {
11676 if (!strcmp(key, WEED_LEAF_TYPE)) {
11677 type = *(int32_t *)(values[0]);
11678 if (type < 0)
return -8;
11682 weed_leaf_set(plant, key, st, 0, NULL);
11685 case WEED_SEED_INT:
11687 case WEED_SEED_BOOLEAN:
11689 for (j = 0; j < ne; j++) ints[j] = *(int32_t *)values[j];
11690 if (!strcmp(key, WEED_LEAF_TYPE)) {
11691 if (weed_plant_has_leaf(plant, WEED_LEAF_TYPE)) {
11692 type = weed_get_int_value(plant, WEED_LEAF_TYPE, &
error);
11693 if (type == WEED_PLANT_UNKNOWN) {
11694 type = weed_plant_mutate(plant, *ints);
11696 if (*ints != type) {
11708 weed_leaf_set(plant, key, st, ne, (
void *)ints);
11711 weed_leaf_set(plant, key, st, ne, (
void *)ints);
11715 case WEED_SEED_DOUBLE:
11717 for (j = 0; j < ne; j++) dubs[j] = *(
double *)values[j];
11718 weed_leaf_set(plant, key, st, ne, (
void *)dubs);
11721 case WEED_SEED_INT64:
11723 for (j = 0; j < ne; j++) int64s[j] = *(int64_t *)values[j];
11724 weed_leaf_set(plant, key, st, ne, (
void *)int64s);
11727 case WEED_SEED_STRING:
11728 weed_leaf_set(plant, key, st, ne, (
void *)values);
11732 boolean add_leaf =
TRUE;
11746 uint64_t *voids = (uint64_t *)
lives_malloc(ne *
sizeof(uint64_t));
11747 for (j = 0; j < ne; j++) voids[j] = (uint64_t)(*(
void **)values[j]);
11748 weed_leaf_set(plant, key, WEED_SEED_INT64, ne, (
void *)voids);
11751 void **voids = (
void **)
lives_malloc(ne *
sizeof(
void *));
11752 for (j = 0; j < ne; j++) voids[j] = values[j];
11753 weed_leaf_set(plant, key, st, ne, (
void *)voids);
11762 for (i = 0; i < ne; i++)
lives_freep((
void **)&values[i]);
11776 int32_t type = WEED_PLANT_UNKNOWN;
11778 boolean block_unk_ptrs =
FALSE;
11788 plant = weed_plant_new(WEED_PLANT_UNKNOWN);
11791 numleaves = realign_typeleaf(fd, plant);
11793 if (newd) weed_plant_free(plant);
11810 plant = weed_plant_new(type);
11814 if (type == WEED_PLANT_UNKNOWN) {
11815 if ((type = weed_leaf_deserialise(fd, plant, WEED_LEAF_TYPE, mem,
TRUE)) <= 0) {
11819 char *msg =
lives_strdup_printf(
"Data mismatch (%d) reading from\n%s", type, badfname ? badfname :
"unknown file");
11825 weed_plant_free(plant);
11828 if (bugfd == fd && !retried) {
11842 while (numleaves--) {
11843 if ((err = weed_leaf_deserialise(fd, plant, NULL, mem, block_unk_ptrs)) != 0) {
11846 char *msg =
lives_strdup_printf(
"Data mismatch (%d) reading from\n%s", err, badfname ? badfname :
"unknown file");
11852 weed_plant_free(plant);
11855 if (bugfd == fd && !retried) {
11863 if ((type = weed_get_plant_type(plant)) == WEED_PLANT_UNKNOWN) {
11865 if (newd) weed_plant_free(plant);
11877 weed_plant_t *filter = weed_filters[idx], **ptmpls;
11880 boolean wrote_hashname =
FALSE;
11884 ptmpls = weed_get_plantptr_array(filter, WEED_LEAF_IN_PARAMETER_TEMPLATES, &num_params);
11885 if (!ptmpls)
return TRUE;
11887 for (i = 0; i < num_params; i++) {
11893 for (i = 0; i < num_params; i++) {
11895 if (!wrote_hashname) {
11902 wrote_hashname =
TRUE;
11913 if (
THREADVAR(write_failed) == fd + 1) {
11922 weed_plant_t *filter, **ptmpls;
11929 int num_params = 0;
11931 boolean read_failed =
FALSE;
11932 boolean found =
FALSE;
11947 vlen = (size_t)vleni;
11950 if (vleni == 0 && vlenz != 0) vlen = (size_t)vlenz;
11963 for (i = 0; i < num_weed_filters; i++) {
11972 for (i = 0; i < num_weed_filters; i++) {
11985 if (i < num_weed_filters) {
11986 filter = weed_filters[i];
11987 ptmpls = weed_get_plantptr_array_counted(filter, WEED_LEAF_IN_PARAMETER_TEMPLATES, &num_params);
11988 }
else num_params = 0;
11995 for (i = 0; i < ntoread; i++) {
12001 if (pnum < num_params) {
12005 weed_plant_t *dummyplant = weed_plant_new(WEED_PLANT_UNKNOWN);
12007 weed_plant_free(dummyplant);
12008 read_failed =
TRUE;
12024 if (
THREADVAR(read_failed) == fd + 1) {
12029 if (
THREADVAR(read_failed) == fd + 1) {
12042 weed_plant_t *filter, **ctmpls;
12046 boolean wrote_hashname =
FALSE;
12049 if (num_channels != 0)
return TRUE;
12051 filter = weed_filters[idx];
12053 ctmpls = weed_get_plantptr_array_counted(filter, WEED_LEAF_OUT_CHANNEL_TEMPLATES, &num_channels);
12054 if (num_channels == 0)
return TRUE;
12056 for (i = 0; i < num_channels; i++) {
12059 if (!wrote_hashname) {
12065 wrote_hashname =
TRUE;
12076 else weed_leaf_serialise(fd, ctmpls[i], WEED_LEAF_WIDTH,
FALSE, NULL);
12079 else weed_leaf_serialise(fd, ctmpls[i], WEED_LEAF_HEIGHT,
FALSE, NULL);
12084 if (
THREADVAR(write_failed) == fd + 1) {
12093 weed_plant_t *filter, **ctmpls;
12100 boolean found =
FALSE;
12104 int i, num_chans = 0, cnum;
12116 vlen = (size_t)vleni;
12119 if (vleni == 0 && vlenz != 0) vlen = (size_t)vlenz;
12135 if (bytes < vlen) {
12140 for (i = 0; i < num_weed_filters; i++) {
12149 for (i = 0; i < num_weed_filters; i++) {
12163 if (i < num_weed_filters) {
12164 filter = weed_filters[i];
12165 ctmpls = weed_get_plantptr_array_counted(filter, WEED_LEAF_OUT_CHANNEL_TEMPLATES, &num_chans);
12183 if (cnum < num_chans && cnum >= 0) {
12190 }
else if (cnum == -1) {
12199 if (
THREADVAR(read_failed) == fd + 1) {
12206 if (
THREADVAR(read_failed) == fd + 1) {
12211 if (
THREADVAR(read_failed) == fd + 1) {
12239 int i, j, nvals, nigns;
12242 weed_plant_t *filter;
12243 int xnparams = 0, maxparams = nparams;
12244 weed_plant_t **key_defs;
12245 weed_timecode_t tc;
12250 idx = key_to_fx[key][mode];
12251 filter = weed_filters[idx];
12255 if (xnparams > maxparams) maxparams = xnparams;
12256 if (!maxparams)
return FALSE;
12258 key_defs = (weed_plant_t **)
lives_calloc(maxparams,
sizeof(weed_plant_t *));
12260 for (i = 0; i < nparams; i++) {
12261 if (key < 0 || i < xnparams) {
12262 key_defs[i] = weed_plant_new(WEED_PLANT_PARAMETER);
12270 if (!nvals)
return TRUE;
12272 if (bytes <
sizeof(weed_timecode_t)) {
12282 for (j = 0; j < nigns; j++) {
12292 if (weed_leaf_deserialise(fd, key_defs[i], WEED_LEAF_VALUE, NULL,
FALSE) < 0)
goto err123;
12295 for (j = 0; j < nvals; j++) {
12297 weed_plant_t *plant = weed_plant_new(WEED_PLANT_PARAMETER);
12309 for (j = 0; j < nigns; j++) {
12316 ret = weed_leaf_deserialise(fd, plant, WEED_LEAF_VALUE, NULL,
FALSE);
12317 weed_plant_free(plant);
12318 if (ret < 0)
goto err123;
12327 for (i = 0; i < nparams; i++) {
12328 if (key_defs[i]) weed_plant_free(key_defs[i]);
12333 if (ret < 0 ||
THREADVAR(read_failed) == fd + 1) {
12345 weed_plant_t **defs, **params;
12348 register int i, j = 0;
12350 if (nparams == 0)
return;
12356 params = weed_get_plantptr_array(inst, WEED_LEAF_IN_PARAMETERS, NULL);
12359 for (i = 0; i < nparams; i++) {
12361 weed_leaf_dup(params[i], defs[j], WEED_LEAF_VALUE);
12373 weed_plant_t *filter;
12374 weed_plant_t **key_defs;
12382 filter = weed_filters[key_to_fx[key][mode]];
12386 for (
int i = 0; i < nparams; i++) {
12387 if (
THREADVAR(write_failed) == fd + 1) {
12391 weed_leaf_serialise(fd, key_defs[i], WEED_LEAF_VALUE,
FALSE, NULL);
12398 weed_plant_t *filter;
12399 weed_plant_t **key_defs;
12406 if (!key_defs)
return;
12408 filter = weed_filters[key_to_fx[key][mode]];
12411 for (
int i = 0; i < nparams; i++)
if (key_defs[i]) weed_plant_free(key_defs[i]);
12420 weed_plant_t **key_defs, **params;
12423 int nparams, poffset = 0;
12428 if (nparams == 0)
return;
12430 key_defs = (weed_plant_t **)
lives_malloc(nparams *
sizeof(weed_plant_t *));
12435 int last = nparams + poffset - 1;
12436 params = weed_get_plantptr_array(inst, WEED_LEAF_IN_PARAMETERS, NULL);
12438 key_defs[++i] = weed_plant_new(WEED_PLANT_PARAMETER);
12439 weed_leaf_dup(key_defs[i], params[i - poffset], WEED_LEAF_VALUE);