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