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