1 /* An edge detection filter.
2  * This is very simple filter - it initializes smalliter image and then
3  * does an simple edge detection algo on it.
4  */
5 #include "config.h"
6 #include <cstdlib>
7 #include <cstdio> /*for NULL */
8 #define SLARGEITER
9 #include "xthread.h"
10 #include "filter.h"
11 
12 #define spixel_t pixel8_t
13 #include "c256.h"
14 #define do_edge do_edge8
15 #include "edged.h"
16 
17 #undef spixel_t
18 #define spixel_t pixel16_t
19 #include "truecolor.h"
20 #define do_edge do_edge32
21 #include "edged.h"
22 
23 #include "true24.h"
24 #define do_edge do_edge24
25 #include "edged.h"
26 
27 #include "hicolor.h"
28 #define do_edge do_edge16
29 #include "edged.h"
30 
requirement(struct filter * f,struct requirements * r)31 static int requirement(struct filter *f, struct requirements *r)
32 {
33     f->req = *r;
34     r->nimages = 1;
35     r->flags &= ~IMAGEDATA;
36     r->supportedmask = MASK1BPP | MASK3BPP | MASK2BPP | MASK4BPP;
37     return (f->next->action->requirement(f->next, r));
38 }
39 
initialize(struct filter * f,struct initdata * i)40 static int initialize(struct filter *f, struct initdata *i)
41 {
42     inhermisc(f, i);
43     /*in/out coloring modes looks better in iter modes. This also saves some
44        memory in truecolor. */
45     if (f->data != NULL)
46         destroypalette((struct palette *)f->data);
47     f->data = createpalette(
48         0, 65536, i->image->bytesperpixel <= 1 ? SMALLITER : LARGEITER, 0,
49         65536, NULL, NULL, NULL, NULL, NULL);
50     if (!inherimage(f, i, TOUCHIMAGE | NEWIMAGE, 0, 0,
51                     (struct palette *)f->data, 0, 0))
52         return 0;
53     return (f->previous->action->initialize(f->previous, i));
54 }
55 
getinstance(const struct filteraction * a)56 static struct filter *getinstance(const struct filteraction *a)
57 {
58     struct filter *f = createfilter(a);
59     f->name = "Edge detection";
60     return (f);
61 }
62 
destroyinstance(struct filter * f)63 static void destroyinstance(struct filter *f)
64 {
65     if (f->data != NULL)
66         destroypalette((struct palette *)f->data);
67     destroyinheredimage(f);
68     free(f);
69 }
70 
doit(struct filter * f,int flags,int time)71 static int doit(struct filter *f, int flags, int time)
72 {
73     int val;
74     int size = f->childimage->palette->type == SMALLITER ? 240 : 65520;
75     if (f->image->palette->size < size)
76         size = f->image->palette->size;
77     if (((struct palette *)f->data)->size != size)
78         ((struct palette *)f->data)->size = size,
79                          ((struct palette *)f->data)->version++;
80     updateinheredimage(f);
81     val = f->previous->action->doit(f->previous, flags, time);
82     drivercall(*f->image, xth_function(do_edge8, f, f->image->height),
83                xth_function(do_edge16, f, f->image->height),
84                xth_function(do_edge24, f, f->image->height),
85                xth_function(do_edge32, f, f->image->height));
86     xth_sync();
87     return val;
88 }
89 
90 const struct filteraction edge_filter = {"Edge detection",
91                                          "edge",
92                                          0,
93                                          getinstance,
94                                          destroyinstance,
95                                          doit,
96                                          requirement,
97                                          initialize,
98                                          convertupgeneric,
99                                          convertdowngeneric,
100                                          NULL};
101