1 /*
2  * * Copyright (C) 2006-2011 Anders Brander <anders@brander.dk>,
3  * * Anders Kvist <akv@lnxbx.dk> and Klaus Post <klauspost@gmail.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  */
19 
20 #ifndef RS_FILTER_H
21 #define RS_FILTER_H
22 
23 #include "rawstudio.h"
24 #include <glib-object.h>
25 
26 G_BEGIN_DECLS
27 
28 /**
29  * Convenience macro to define generic filter
30  */
31 #define RS_DEFINE_FILTER(type_name, TypeName) \
32 static GType type_name##_get_type (GTypeModule *module); \
33 static void type_name##_class_init(TypeName##Class *klass); \
34 static void type_name##_init(TypeName *filter); \
35 static GType type_name##_type = 0; \
36 static GType \
37 type_name##_get_type(GTypeModule *module) \
38 { \
39 	if (!type_name##_type) \
40 	{ \
41 		static const GTypeInfo filter_info = \
42 		{ \
43 			sizeof (TypeName##Class), \
44 			(GBaseInitFunc) NULL, \
45 			(GBaseFinalizeFunc) NULL, \
46 			(GClassInitFunc) type_name##_class_init, \
47 			NULL, \
48 			NULL, \
49 			sizeof (TypeName), \
50 			0, \
51 			(GInstanceInitFunc) type_name##_init \
52 		}; \
53  \
54 		type_name##_type = g_type_module_register_type( \
55 			module, \
56 			RS_TYPE_FILTER, \
57 			#TypeName, \
58 			&filter_info, \
59 			0); \
60 	} \
61 	return type_name##_type; \
62 }
63 
64 #define RS_TYPE_FILTER rs_filter_get_type()
65 #define RS_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RS_TYPE_FILTER, RSFilter))
66 #define RS_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RS_TYPE_FILTER, RSFilterClass))
67 #define RS_IS_FILTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RS_TYPE_FILTER))
68 #define RS_IS_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RS_TYPE_FILTER))
69 #define RS_FILTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RS_TYPE_FILTER, RSFilterClass))
70 
71 #define RS_FILTER_NAME(filter) (((filter)) ? g_type_name(G_TYPE_FROM_CLASS(RS_FILTER_GET_CLASS ((filter)))) : "(nil)")
72 
73 typedef enum {
74 	RS_FILTER_CHANGED_PIXELDATA   = 1<<0,
75 	RS_FILTER_CHANGED_DIMENSION   = 1<<0 | 1<<1, /* This implies pixeldata changed */
76 	RS_FILTER_CHANGED_ICC_PROFILE = 1<<2
77 } RSFilterChangedMask;
78 
79 typedef struct _RSFilter RSFilter;
80 typedef struct _RSFilterClass RSFilterClass;
81 
82 typedef RSFilterResponse *(*RSFilterFunc)(RSFilter *filter, const RSFilterRequest *request);
83 
84 struct _RSFilter {
85 	GObject parent;
86 	gboolean dispose_has_run;
87 
88 	const gchar *label;
89 
90 	RSFilter *previous;
91 	GSList *next_filters;
92 	gboolean enabled;
93 };
94 
95 struct _RSFilterClass {
96 	GObjectClass parent_class;
97 	const gchar *name;
98 	RSFilterFunc get_image;
99 	RSFilterFunc get_image8;
100 	RSFilterResponse *(*get_size)(RSFilter *filter, const RSFilterRequest *request);
101 	void (*previous_changed)(RSFilter *filter, RSFilter *parent, RSFilterChangedMask mask);
102 };
103 
104 GType rs_filter_get_type(void) G_GNUC_CONST;
105 
106 /**
107  * Return a new instance of a RSFilter
108  * @param name The name of the filter
109  * @param previous The previous filter or NULL
110  * @return The newly instantiated RSFilter or NULL
111  */
112 extern RSFilter *rs_filter_new(const gchar *name, RSFilter *previous);
113 
114 /**
115  * Set the previous RSFilter in a RSFilter-chain
116  * @param filter A RSFilter
117  * @param previous A previous RSFilter
118  */
119 extern void rs_filter_set_previous(RSFilter *filter, RSFilter *previous);
120 
121 /**
122  * Signal that a filter has changed, filters depending on this will be invoked
123  * This should only be called from filters
124  * @param filter The changed filter
125  * @param mask A mask indicating what changed
126  */
127 extern void rs_filter_changed(RSFilter *filter, RSFilterChangedMask mask);
128 
129 /**
130  * Get the output image from a RSFilter
131  * @param filter A RSFilter
132  * @param param A RSFilterRequest defining parameters for a image request
133  * @return A RS_IMAGE16, this must be unref'ed
134  */
135 extern RSFilterResponse *rs_filter_get_image(RSFilter *filter, const RSFilterRequest *request);
136 
137 /**
138  * Get 8 bit output image from a RSFilter
139  * @param filter A RSFilter
140  * @param param A RSFilterRequest defining parameters for a image request
141  * @return A RS_IMAGE16, this must be unref'ed
142  */
143 extern RSFilterResponse *rs_filter_get_image8(RSFilter *filter, const RSFilterRequest *request);
144 
145 /**
146  * Get predicted size of a RSFilter
147  * @param filter A RSFilter
148  * @param request A RSFilterRequest defining parameters for the request
149  */
150 extern RSFilterResponse *rs_filter_get_size(RSFilter *filter, const RSFilterRequest *request);
151 
152 /**
153  * Get predicted size of a RSFilter
154  * @param filter A RSFilter
155  * @param request A RSFilterRequest defining parameters for the request
156  * @param width A pointer to a gint where the width will be written or NULL
157  * @param height A pointer to a gint where the height will be written or NULL
158  * @return TRUE if width/height is known, FALSE otherwise
159  */
160 extern gboolean rs_filter_get_size_simple(RSFilter *filter, const RSFilterRequest *request, gint *width, gint *height);
161 
162 /**
163  * Set a GObject property on zero or more filters above #filter recursively
164  * @param filter A RSFilter
165  * @param ... Pairs of property names and values followed by NULL
166  */
167 void
168 rs_filter_set_recursive(RSFilter *filter, ...);
169 
170 /**
171  * Get a GObject property from a RSFilter chain recursively
172  * @param filter A RSFilter
173  * @param ... Pairs of property names and a return pointers followed by NULL
174  */
175 extern void rs_filter_get_recursive(RSFilter *filter, ...);
176 
177 /**
178  * Set enabled state of a RSFilter
179  * @param filter A RSFilter
180  * @param enabled TRUE to enable filter, FALSE to disable
181  * @return Previous state
182  */
183 extern gboolean rs_filter_set_enabled(RSFilter *filter, gboolean enabled);
184 
185 /**
186  * Get enabled state of a RSFilter
187  * @param filter A RSFilter
188  * @return TRUE if filter is enabled, FALSE if disabled
189  */
190 extern gboolean rs_filter_get_enabled(RSFilter *filter);
191 
192 /**
193  * Set a label for a RSFilter - only used for debugging
194  * @param filter A RSFilter
195  * @param label A new label for the RSFilter, this will NOT be copied
196  */
197 extern void rs_filter_set_label(RSFilter *filter, const gchar *label);
198 
199 /**
200  * Get the label for a RSFilter
201  * @param filter A RSFilter
202  * @return The label for the RSFilter or NULL
203  */
204 extern const gchar *rs_filter_get_label(RSFilter *filter);
205 
206 /**
207  * Draw a nice graph of the filter chain
208  * note: Requires graphviz
209  * @param filter The top-most filter to graph
210  */
211 extern void rs_filter_graph(RSFilter *filter);
212 
213 G_END_DECLS
214 
215 #endif /* RS_FILTER_H */
216