1 // simple_blend.c
2 // weed plugin
3 // (c) G. Finch (salsaman) 2005
4 //
5 // released under the GNU GPL 3 or later
6 // see file COPYING or www.gnu.org for details
7
8 ///////////////////////////////////////////////////////////////////
9
10 static int package_version = 1; // version of this package
11
12 //////////////////////////////////////////////////////////////////
13
14 #define NEED_RANDOM
15 #define NEED_PALETTE_UTILS
16
17 #ifndef NEED_LOCAL_WEED_PLUGIN
18 #include <weed/weed-plugin.h>
19 #include <weed/weed-utils.h> // optional
20 #include <weed/weed-plugin-utils.h> // optional
21 #else
22 #include "../../libweed/weed-plugin.h"
23 #include "../../libweed/weed-utils.h" // optional
24 #include "../../libweed/weed-plugin-utils.h" // optional
25 #endif
26
27 #include "weed-plugin-utils.c"
28
29 /////////////////////////////////////////////////////////////
30
pick_direction(uint64_t fastrand_val)31 static inline int pick_direction(uint64_t fastrand_val) {
32 return ((fastrand_val >> 24) & 0x03) + 1;
33 }
34
35
sover_init(weed_plant_t * inst)36 static weed_error_t sover_init(weed_plant_t *inst) {
37 int dirpref;
38 weed_plant_t **in_params = weed_get_plantptr_array(inst, WEED_LEAF_IN_PARAMETERS, NULL);
39
40 if (weed_get_boolean_value(in_params[1], WEED_LEAF_VALUE, NULL) == WEED_TRUE) dirpref = 0;
41 else if (weed_get_boolean_value(in_params[2], WEED_LEAF_VALUE, NULL) == WEED_TRUE) dirpref = 1; // left to right
42 else if (weed_get_boolean_value(in_params[3], WEED_LEAF_VALUE, NULL) == WEED_TRUE) dirpref = 2; // right to left
43 else if (weed_get_boolean_value(in_params[4], WEED_LEAF_VALUE, NULL) == WEED_TRUE) dirpref = 3; // top to bottom
44 else dirpref = 4; // bottom to top
45
46 weed_set_int_value(inst, "plugin_direction", dirpref);
47 return WEED_SUCCESS;
48 }
49
50
sover_process(weed_plant_t * inst,weed_timecode_t timecode)51 static weed_error_t sover_process(weed_plant_t *inst, weed_timecode_t timecode) {
52 weed_plant_t **in_channels = weed_get_plantptr_array(inst, WEED_LEAF_IN_CHANNELS, NULL),
53 *out_channel = weed_get_plantptr_value(inst, WEED_LEAF_OUT_CHANNELS, NULL);
54 unsigned char *src1 = weed_get_voidptr_value(in_channels[0], WEED_LEAF_PIXEL_DATA, NULL);
55 unsigned char *src2 = weed_get_voidptr_value(in_channels[1], WEED_LEAF_PIXEL_DATA, NULL);
56 unsigned char *dst = weed_get_voidptr_value(out_channel, WEED_LEAF_PIXEL_DATA, NULL);
57 int width = weed_get_int_value(in_channels[0], WEED_LEAF_WIDTH, NULL);
58 int height = weed_get_int_value(in_channels[0], WEED_LEAF_HEIGHT, NULL);
59 int irowstride1 = weed_get_int_value(in_channels[0], WEED_LEAF_ROWSTRIDES, NULL);
60 int irowstride2 = weed_get_int_value(in_channels[1], WEED_LEAF_ROWSTRIDES, NULL);
61 int orowstride = weed_get_int_value(out_channel, WEED_LEAF_ROWSTRIDES, NULL);
62 int palette = weed_get_int_value(in_channels[0], WEED_LEAF_CURRENT_PALETTE, NULL);
63 weed_plant_t **in_params;
64
65 register int j;
66
67 int transval;
68 int dirn;
69 int mvlower, mvupper;
70 int bound;
71 int psize = pixel_size(palette);
72
73 in_params = weed_get_plantptr_array(inst, WEED_LEAF_IN_PARAMETERS, NULL);
74 transval = weed_get_int_value(in_params[0], WEED_LEAF_VALUE, NULL);
75 dirn = weed_get_int_value(inst, "plugin_direction", NULL);
76 mvlower = weed_get_boolean_value(in_params[6], WEED_LEAF_VALUE, NULL);
77 mvupper = weed_get_boolean_value(in_params[7], WEED_LEAF_VALUE, NULL);
78
79 if (dirn == 0) {
80 dirn = pick_direction(fastrand(0)); // random
81 weed_set_int_value(inst, "plugin_direction", dirn);
82 }
83
84 // upper is src1, lower is src2
85 // if mvupper, src1 moves, otherwise it stays fixed
86 // if mvlower, src2 moves, otherwise it stays fixed
87
88 // direction tells which way bound moves
89 // bound is dividing line between src1 and src2
90
91 switch (dirn) {
92 case 3:
93 // top to bottom
94 bound = (float)height * (1. - transval / 255.); // how much of src1 to show
95 if (mvupper) src1 += irowstride1 * (height - bound); // if mvupper, slide a part off the top
96 for (j = 0; j < bound; j++) {
97 weed_memcpy(dst, src1, width * psize);
98 src1 += irowstride1;
99 if (!mvlower) src2 += irowstride2; // if !mvlower, cover part of src2
100 dst += orowstride;
101 }
102 for (j = bound; j < height; j++) {
103 weed_memcpy(dst, src2, width * psize);
104 src2 += irowstride2;
105 dst += orowstride;
106 }
107 break;
108 case 4:
109 // bottom to top
110 bound = (float)height * (transval / 255.);
111 if (mvlower) src2 += irowstride2 * (height - bound); // if mvlower we slide in src2 from the top
112 if (!mvupper) src1 += irowstride1 * bound;
113 for (j = 0; j < bound; j++) {
114 weed_memcpy(dst, src2, width * psize);
115 src2 += irowstride2;
116 dst += orowstride;
117 }
118 for (j = bound; j < height; j++) {
119 weed_memcpy(dst, src1, width * psize);
120 src1 += irowstride1;
121 dst += orowstride;
122 }
123 break;
124 case 1:
125 // left to right
126 bound = (float)width * (1. - transval / 255.);
127 for (j = 0; j < height; j++) {
128 weed_memcpy(dst, src1 + (width - bound) * psize * mvupper, bound * psize);
129 weed_memcpy(dst + bound * psize, src2 + bound * psize * !mvlower, (width - bound) * psize);
130 src1 += irowstride1;
131 src2 += irowstride2;
132 dst += orowstride;
133 }
134 break;
135 case 2:
136 // right to left
137 bound = (float)width * (transval / 255.);
138 for (j = 0; j < height; j++) {
139 weed_memcpy(dst, src2 + (width - bound) * psize * mvlower, bound * psize);
140 weed_memcpy(dst + bound * psize, src1 + !mvupper * bound * psize, (width - bound) * psize);
141 src1 += irowstride1;
142 src2 += irowstride2;
143 dst += orowstride;
144 }
145 break;
146 }
147
148 weed_free(in_params);
149 weed_free(in_channels);
150 return WEED_SUCCESS;
151 }
152
153
154 WEED_SETUP_START(200, 200) {
155 int palette_list[] = ALL_PACKED_PALETTES_PLUS;
156 weed_plant_t *in_chantmpls[] = {weed_channel_template_init("in channel 0", 0),
157 weed_channel_template_init("in channel 1", 0), NULL
158 };
159 weed_plant_t *out_chantmpls[] = {weed_channel_template_init("out channel 0", 0), NULL};
160 weed_plant_t *in_params[] = {weed_integer_init("amount", "Transition _value", 0, 0, 255),
161 weed_radio_init("dir_rand", "_Random", 1, 1),
162 weed_radio_init("dir_r2l", "_Right to left", 0, 1),
163 weed_radio_init("dir_l2r", "_Left to right", 0, 1),
164 weed_radio_init("dir_b2t", "_Bottom to top", 0, 1),
165 weed_radio_init("dir_t2b", "_Top to bottom", 0, 1),
166 weed_switch_init("mlower", "_Slide lower clip", WEED_TRUE),
167 weed_switch_init("mupper", "_Slide upper clip", WEED_FALSE), NULL
168 };
169
170 weed_plant_t *filter_class = weed_filter_class_init("slide over", "salsaman", 1, 0, palette_list,
171 sover_init, sover_process, NULL, in_chantmpls, out_chantmpls, in_params, NULL);
172
173 weed_plant_t *gui = weed_filter_get_gui(filter_class);
174
175 char *rfx_strings[] = {"layout|p0|", "layout|hseparator|", "layout|fill|\"Slide direction\"|fill|",
176 "layout|p1|", "layout|p2|p3|", "layout|p4|p5|", "layout|hseparator|"
177 };
178
179 weed_set_string_value(gui, WEED_LEAF_LAYOUT_SCHEME, "RFX");
180 weed_set_string_value(gui, "layout_rfx_delim", "|");
181 weed_set_string_array(gui, "layout_rfx_strings", 7, rfx_strings);
182
183 weed_set_boolean_value(in_params[0], WEED_LEAF_IS_TRANSITION, WEED_TRUE);
184
185 weed_set_int_value(in_params[1], WEED_LEAF_FLAGS, WEED_PARAMETER_REINIT_ON_VALUE_CHANGE);
186 weed_set_int_value(in_params[2], WEED_LEAF_FLAGS, WEED_PARAMETER_REINIT_ON_VALUE_CHANGE);
187 weed_set_int_value(in_params[3], WEED_LEAF_FLAGS, WEED_PARAMETER_REINIT_ON_VALUE_CHANGE);
188 weed_set_int_value(in_params[4], WEED_LEAF_FLAGS, WEED_PARAMETER_REINIT_ON_VALUE_CHANGE);
189 weed_set_int_value(in_params[5], WEED_LEAF_FLAGS, WEED_PARAMETER_REINIT_ON_VALUE_CHANGE);
190
191 weed_plugin_info_add_filter_class(plugin_info, filter_class);
192
193 weed_set_int_value(plugin_info, WEED_LEAF_VERSION, package_version);
194 }
195 WEED_SETUP_END;
196
197