1 // colorkey.c
2 // weed plugin
3 // (c) G. Finch (salsaman) 2006
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 #ifndef NEED_LOCAL_WEED_PLUGIN
15 #include <weed/weed-plugin.h>
16 #include <weed/weed-utils.h> // optional
17 #include <weed/weed-plugin-utils.h> // optional
18 #else
19 #include "../../libweed/weed-plugin.h"
20 #include "../../libweed/weed-utils.h" // optional
21 #include "../../libweed/weed-plugin-utils.h" // optional
22 #endif
23 
24 #include "weed-plugin-utils.c"
25 
26 /////////////////////////////////////////////////////////////
27 
28 
ckey_process(weed_plant_t * inst,weed_timecode_t timecode)29 static weed_error_t ckey_process(weed_plant_t *inst, weed_timecode_t timecode) {
30   weed_plant_t **in_channels = weed_get_plantptr_array(inst, WEED_LEAF_IN_CHANNELS, NULL),
31                  *out_channel = weed_get_plantptr_value(inst, WEED_LEAF_OUT_CHANNELS, NULL);
32   unsigned char *src1 = weed_get_voidptr_value(in_channels[0], WEED_LEAF_PIXEL_DATA, NULL);
33   unsigned char *src2 = weed_get_voidptr_value(in_channels[1], WEED_LEAF_PIXEL_DATA, NULL);
34   unsigned char *dst = weed_get_voidptr_value(out_channel, WEED_LEAF_PIXEL_DATA, NULL);
35   int width = weed_get_int_value(in_channels[0], WEED_LEAF_WIDTH, NULL) * 3;
36   int height = weed_get_int_value(in_channels[0], WEED_LEAF_HEIGHT, NULL);
37   int irowstride1 = weed_get_int_value(in_channels[0], WEED_LEAF_ROWSTRIDES, NULL);
38   int irowstride2 = weed_get_int_value(in_channels[1], WEED_LEAF_ROWSTRIDES, NULL);
39   int orowstride = weed_get_int_value(out_channel, WEED_LEAF_ROWSTRIDES, NULL);
40   int palette = weed_get_int_value(out_channel, WEED_LEAF_CURRENT_PALETTE, NULL);
41   unsigned char *end = src1 + height * irowstride1;
42   int inplace = (src1 == dst);
43   weed_plant_t **in_params;
44   int b_red, b_green, b_blue;
45   int red, green, blue;
46   int b_red_min, b_green_min, b_blue_min;
47   int b_red_max, b_green_max, b_blue_max;
48   double delta, opac, opacx;
49   int *carray;
50 
51   register int j;
52 
53   in_params = weed_get_plantptr_array(inst, WEED_LEAF_IN_PARAMETERS, NULL);
54   delta = weed_get_double_value(in_params[0], WEED_LEAF_VALUE, NULL);
55   opac = weed_get_double_value(in_params[1], WEED_LEAF_VALUE, NULL);
56   carray = weed_get_int_array(in_params[2], WEED_LEAF_VALUE, NULL);
57   b_red = carray[0];
58   b_green = carray[1];
59   b_blue = carray[2];
60   weed_free(carray);
61 
62   b_red_min = b_red - (int)(b_red * delta + .5);
63   b_green_min = b_green - (int)(b_green * delta + .5);
64   b_blue_min = b_blue - (int)(b_blue * delta + .5);
65 
66   b_red_max = b_red + (int)((255 - b_red) * delta + .5);
67   b_green_max = b_green + (int)((255 - b_green) * delta + .5);
68   b_blue_max = b_blue + (int)((255 - b_blue) * delta + .5);
69 
70   for (; src1 < end; src1 += irowstride1) {
71     for (j = 0; j < width; j += 3) {
72       if (palette == WEED_PALETTE_RGB24) {
73         red = src1[j];
74         green = src1[j + 1];
75         blue = src1[j + 2];
76       } else {
77         blue = src1[j];
78         green = src1[j + 1];
79         red = src1[j + 2];
80       }
81       if (red >= b_red_min && red <= b_red_max && green >= b_green_min && green <= b_green_max
82           && blue >= b_blue_min && blue <= b_blue_max) {
83         dst[j] = src1[j] * ((opacx = 1. - opac)) + src2[j] * opac;
84         dst[j + 1] = src1[j + 1] * (opacx) + src2[j + 1] * opac;
85         dst[j + 2] = src1[j + 2] * (opacx) + src2[j + 2] * opac;
86       } else if (!inplace) weed_memcpy(&dst[j], &src1[j], 3);
87     }
88     src2 += irowstride2;
89     dst += orowstride;
90   }
91   weed_free(in_channels);
92   return WEED_SUCCESS;
93 }
94 
95 
96 WEED_SETUP_START(200, 200) {
97   int palette_list[] = {WEED_PALETTE_RGB24, WEED_PALETTE_BGR24, WEED_PALETTE_END};
98   weed_plant_t *in_chantmpls[] = {weed_channel_template_init("in channel 0", 0),
99                                   weed_channel_template_init("in channel 1", 0), NULL
100                                  };
101   weed_plant_t *out_chantmpls[] = {weed_channel_template_init("out channel 0", WEED_CHANNEL_CAN_DO_INPLACE), NULL};
102 
103   weed_plant_t *in_params[] = {weed_float_init("delta", "_Delta", .2, 0., 1.),
104                                weed_float_init("opacity", "_Opacity", 1., 0., 1.), weed_colRGBi_init("col", "_Colour", 0, 0, 255), NULL
105                               };
106   int filter_flags = WEED_FILTER_HINT_MAY_THREAD;
107   weed_plant_t *filter_class = weed_filter_class_init("colour key", "salsaman", 1, filter_flags, palette_list,
108                                NULL, &ckey_process, NULL, in_chantmpls, out_chantmpls, in_params, NULL);
109 
110   weed_plugin_info_add_filter_class(plugin_info, filter_class);
111   weed_set_int_value(plugin_info, WEED_LEAF_VERSION, package_version);
112 }
113 WEED_SETUP_END;
114