1 // posterise.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 #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
posterise_process(weed_plant_t * inst,weed_timecode_t timestamp)28 static weed_error_t posterise_process(weed_plant_t *inst, weed_timecode_t timestamp) {
29 weed_plant_t *in_channel = weed_get_plantptr_value(inst, WEED_LEAF_IN_CHANNELS, NULL),
30 *out_channel = weed_get_plantptr_value(inst, WEED_LEAF_OUT_CHANNELS, NULL);
31 weed_plant_t *in_param;
32 unsigned char *src = weed_get_voidptr_value(in_channel, WEED_LEAF_PIXEL_DATA, NULL);
33 unsigned char *dst = weed_get_voidptr_value(out_channel, WEED_LEAF_PIXEL_DATA, NULL);
34 int width = weed_get_int_value(in_channel, WEED_LEAF_WIDTH, NULL) * 3;
35 int height = weed_get_int_value(in_channel, WEED_LEAF_HEIGHT, NULL);
36 int irowstride = weed_get_int_value(in_channel, WEED_LEAF_ROWSTRIDES, NULL);
37 int orowstride = weed_get_int_value(out_channel, WEED_LEAF_ROWSTRIDES, NULL);
38 unsigned char *end = src + height * irowstride;
39
40 int levels;
41 unsigned char levmask = 128;
42
43 register int i;
44
45 in_param = weed_get_plantptr_value(inst, WEED_LEAF_IN_PARAMETERS, NULL);
46 levels = weed_get_int_value(in_param, WEED_LEAF_VALUE, NULL);
47
48 for (i = 1; i < levels; i++) levmask += 128 >> i;
49
50 // new threading arch
51 if (weed_plant_has_leaf(out_channel, WEED_LEAF_OFFSET)) {
52 int offset = weed_get_int_value(out_channel, WEED_LEAF_OFFSET, NULL);
53 int dheight = weed_get_int_value(out_channel, WEED_LEAF_HEIGHT, NULL);
54
55 src += offset * irowstride;
56 dst += offset * orowstride;
57 end = src + dheight * irowstride;
58 }
59
60 for (; src < end; src += irowstride) {
61 for (i = 0; i < width; i++) {
62 dst[i] = src[i] & levmask;
63 }
64 dst += orowstride;
65 }
66 return WEED_SUCCESS;
67 }
68
69
70 WEED_SETUP_START(200, 200) {
71 int palette_list[] = {WEED_PALETTE_RGB24, WEED_PALETTE_BGR24, WEED_PALETTE_END};
72
73 weed_plant_t *in_chantmpls[] = {weed_channel_template_init("in channel 0", 0), NULL};
74 weed_plant_t *out_chantmpls[] = {weed_channel_template_init("out channel 0",
75 WEED_CHANNEL_CAN_DO_INPLACE), NULL
76 };
77
78 weed_plant_t *in_params[] = {weed_integer_init("levels", "Colour _levels", 1, 1, 8), NULL};
79
80 weed_plant_t *filter_class = weed_filter_class_init("posterise", "salsaman", 1, WEED_FILTER_HINT_MAY_THREAD, palette_list,
81 NULL, posterise_process, NULL, in_chantmpls, out_chantmpls, in_params, NULL);
82
83 weed_plugin_info_add_filter_class(plugin_info, filter_class);
84
85 weed_set_int_value(plugin_info, WEED_LEAF_VERSION, package_version);
86 }
87 WEED_SETUP_END;
88
89
90
91
92