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