1 /* This file is part of GEGL
2  *
3  * GEGL is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Lesser General Public
5  * License as published by the Free Software Foundation; either
6  * version 3 of the License, or (at your option) any later version.
7  *
8  * GEGL is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public
14  * License along with GEGL; if not, see <https://www.gnu.org/licenses/>.
15  *
16  * Copyright 2003 Calvin Williamson
17  *           2005-2008 Øyvind Kolås
18  */
19 
20 #ifndef __GEGL_OPERATION_H__
21 #define __GEGL_OPERATION_H__
22 
23 #include <glib-object.h>
24 #include <babl/babl.h>
25 
26 
27 #include "gegl-buffer.h"
28 #include "opencl/gegl-cl.h"
29 
30 G_BEGIN_DECLS
31 
32 #define GEGL_OPERATION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  GEGL_TYPE_OPERATION, GeglOperationClass))
33 #define GEGL_IS_OPERATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  GEGL_TYPE_OPERATION))
34 #define GEGL_OPERATION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  GEGL_TYPE_OPERATION, GeglOperationClass))
35 /* The rest is in gegl-types.h */
36 
37 typedef struct _GeglOperationClass   GeglOperationClass;
38 typedef struct _GeglOperationPrivate GeglOperationPrivate;
39 
40 struct _GeglOperation
41 {
42   GObject parent_instance;
43 
44   /*< private >*/
45   GeglNode *node;  /* the node that this operation object is communicated
46                       with through */
47 };
48 
49 
50 /***
51  * GeglOperation:
52  *
53  * All the image processing code in GEGL is implemented as GeglOperations,
54  * GEGL operations are implemented as GObject with a convenience API called
55  * chanting that abstracts away the boiler plater needed to generate introspectable
56  * named properties of different types.
57  *
58  * Most types of operations like: filters, composers, sources, sinks, point
59  * operations, compositing operations, and spatial operations with fixed
60  * neighbourhoods. These base classes build on top of the GeglOperationsClass:
61  *
62  * See <a href='gegl-plugin.h.html'>gegl-plugin.h</a> for details.
63  */
64 
65 /* the level at which is being operated is stored in the context,
66 */
67 
68 struct _GeglOperationClass
69 {
70   GObjectClass    parent_class;
71 
72   const gchar    *name;        /* name(string) used to create/identify
73                                   this type of operation in GEGL, must be
74                                   set through gegl_operation_class_set_key(s) */
75   const gchar    *compat_name; /* allows specifying an alias that the op is
76                                   also known as, must be set through
77                                   gegl_operation_class_set_key(s) */
78   GHashTable     *keys;        /* hashtable used for storing meta-data about an op */
79 
80   guint           no_cache      :1;  /* do not create a cache for this operation
81                                         (deprecated for "cache_policy") */
82   guint           opencl_support:1;
83   guint           want_in_place:1; /* if possible to use for in-place
84                                       processing, making output buffer =
85                                       input buffer.
86                                       */
87   guint           threaded:1;  /* do threaded processing if possible,
88                                   some base classes have special logic
89                                   to accelerate rendering; this allows opting in/out
90                                   in the sub-classes of these.
91                                 */
92   guint           cache_policy:2; /* cache policy for this operation */
93   guint64         bit_pad:58;
94 
95   /* attach this operation with a GeglNode, override this if you are creating a
96    * GeglGraph, it is already defined for Filters/Sources/Composers.
97    */
98   void          (*attach)                    (GeglOperation *operation);
99 
100   /* Initialize the operation, prepare is called when all properties are
101    * known but before processing will begin. Prepare will be invoked one
102    * or multiple times prior to processing.
103    */
104   void          (*prepare)                   (GeglOperation *operation);
105 
106   /* The bounding rectangle for the data that is defined by this op.
107    */
108   GeglRectangle (*get_bounding_box)          (GeglOperation *operation);
109 
110   /* The output region that is made invalid by a change in the input_roi
111    * rectangle of the buffer passed in on the pad input_pad. Defaults to
112    * returning the input_roi.
113    */
114   GeglRectangle (*get_invalidated_by_change) (GeglOperation       *operation,
115                                               const gchar         *input_pad,
116                                               const GeglRectangle *input_roi);
117 
118   /* The rectangle needed to be correctly computed in a buffer on the named
119    * input_pad, for a given region of interest. Defaults to return the
120    * output_roi.
121    */
122   GeglRectangle (*get_required_for_output)   (GeglOperation       *operation,
123                                               const gchar         *input_pad,
124                                               const GeglRectangle *output_roi);
125 
126   /* The rectangular area that should be processed in one go, by default if not
127    * defined the output roi would be returned. This is useful for file loaders
128    * and operations like contrast stretching which is a point operation but we
129    * need the parameters as the minimum/maximum values in the entire input buffer.
130    */
131   GeglRectangle (*get_cached_region)         (GeglOperation       *operation,
132                                               const GeglRectangle *output_roi);
133 
134   /* Compute the rectangular region output roi for the specified output_pad.
135    * For operations that are sinks (have no output pads), roi is the rectangle
136    * to consume and the output_pad argument is to be ignored.
137    */
138   gboolean      (*process)                   (GeglOperation        *operation,
139                                               GeglOperationContext *context,
140                                               const gchar          *output_pad,
141                                               const GeglRectangle  *roi,
142                                               gint                  level);
143 
144   /* The node providing data for a specific location within the operations
145    * output. The node is responsible for delegating blame to one of it's
146    * inputs taking into account opacity and similar issues.
147    *
148    * XXX: What is GeglNode doing in this part of the API?,
149    * perhaps we should only point out which pad the data is coming from?
150    */
151   GeglNode*     (*detect)                    (GeglOperation       *operation,
152                                               gint                 x,
153                                               gint                 y);
154 
155   GeglClRunData *cl_data;
156 
157   /* Class method for runtime checks for an operation availability. In
158    * particular it allows for operations to be built and installed while
159    * depending on runtime dependencies. If is_available() is set and returns
160    * %FALSE, then the operation will be set invisible.
161    */
162   gboolean      (*is_available)              (void);
163 
164   gpointer      pad[8];
165 };
166 
167 GeglRectangle   gegl_operation_get_invalidated_by_change
168                                              (GeglOperation *operation,
169                                               const gchar   *input_pad,
170                                               const GeglRectangle *roi);
171 GeglRectangle   gegl_operation_get_bounding_box  (GeglOperation *operation);
172 
173 /* retrieves the bounding box of an input pad */
174 GeglRectangle * gegl_operation_source_get_bounding_box
175                                              (GeglOperation *operation,
176                                               const gchar   *pad_name);
177 
178 
179 GeglRectangle   gegl_operation_get_cached_region
180                                              (GeglOperation *operation,
181                                               const GeglRectangle *roi);
182 
183 GeglRectangle   gegl_operation_get_required_for_output
184                                              (GeglOperation *operation,
185                                               const gchar   *input_pad,
186                                               const GeglRectangle *roi);
187 
188 GeglNode       *gegl_operation_detect        (GeglOperation *operation,
189                                               gint           x,
190                                               gint           y);
191 
192 
193 /* virtual method invokers that change behavior based on the roi being computed,
194  * needs a context_id being based that is used for storing context data.
195  */
196 
197 void            gegl_operation_attach        (GeglOperation *operation,
198                                               GeglNode      *node);
199 void            gegl_operation_prepare       (GeglOperation *operation);
200 gboolean        gegl_operation_process       (GeglOperation *operation,
201                                               GeglOperationContext *context,
202                                               const gchar          *output_pad,
203                                               const GeglRectangle  *roi,
204                                               gint                  level);
205 
206 /* create a pad for a specified property for this operation, this method is
207  * to be called from the attach method of operations, most operations do not
208  * have to care about this since a super class like filter, sink, source or
209  * composer already does so.
210  */
211 void            gegl_operation_create_pad    (GeglOperation *operation,
212                                               GParamSpec    *param_spec);
213 
214 /* specify the bablformat for a pad on this operation (XXX: document when
215  * this is legal, at the moment, only used internally in some ops,. but might
216  * turn into a global mechanism) */
217 void            gegl_operation_set_format    (GeglOperation *operation,
218                                               const gchar   *pad_name,
219                                               const Babl    *format);
220 
221 
222 const Babl *    gegl_operation_get_format    (GeglOperation *operation,
223                                               const gchar   *pad_name);
224 
225 const gchar *   gegl_operation_get_name      (GeglOperation *operation);
226 
227 
228 /* checks the incoming Babl format on a given pad, can be used in the prepare
229  * stage to make format dependent decisions
230  */
231 const Babl  * gegl_operation_get_source_format (GeglOperation *operation,
232                                                 const gchar   *padname);
233 
234 /* retrieves the node providing data to a named input pad */
235 GeglNode    * gegl_operation_get_source_node   (GeglOperation *operation,
236                                                 const gchar   *pad_name);
237 
238 /* API to change  */
239 void          gegl_operation_class_set_key     (GeglOperationClass *klass,
240                                                 const gchar *key_name,
241                                                 const gchar *key_value);
242 
243 const gchar * gegl_operation_class_get_key     (GeglOperationClass *operation_class,
244                                                 const gchar        *key_name);
245 
246 void          gegl_operation_class_set_keys    (GeglOperationClass *klass,
247                                                 const gchar        *key_name,
248                                                 ...);
249 
250 
251 void          gegl_operation_set_key           (const gchar *operation_type,
252                                                 const gchar *key_name,
253                                                 const gchar *key_value);
254 
255 
256 gboolean      gegl_operation_use_opencl         (const GeglOperation *operation);
257 
258 gboolean      gegl_operation_use_threading         (GeglOperation       *operation,
259                                                     const GeglRectangle *roi);
260 gdouble       gegl_operation_get_pixels_per_thread (GeglOperation       *operation);
261 
262 /* Invalidate a specific rectangle, indicating the any computation depending
263  * on this roi is now invalid.
264  *
265  * @roi : the region to blank or NULL for the nodes current have_rect
266  * @clear_cache: whether any present caches should be zeroed out
267  */
268 void     gegl_operation_invalidate       (GeglOperation       *operation,
269                                           const GeglRectangle *roi,
270                                           gboolean             clear_cache);
271 
272 gboolean gegl_operation_cl_set_kernel_args (GeglOperation *operation,
273                                             cl_kernel      kernel,
274                                             gint          *p,
275                                             cl_int        *err);
276 
277 /* internal utility functions used by gegl, these should not be used
278  * externally */
279 gboolean gegl_can_do_inplace_processing      (GeglOperation       *operation,
280                                               GeglBuffer          *input,
281                                               const GeglRectangle *result);
282 
283 /**
284  * gegl_object_set_has_forked: (skip)
285  * @object: Object to mark
286  *
287  * Mark an object as "forked", indicating that it should not be modified
288  * in place by gegl operations. This should only be used inside of the
289  * process method of a GeglOperation subclass.
290  */
291 void     gegl_object_set_has_forked       (GObject *object);
292 
293 /**
294  * gegl_object_get_has_forked: (skip)
295  * @object: Object to check
296  *
297  * Returns TRUE if the object has been marked as "forked".
298  */
299 gboolean  gegl_object_get_has_forked      (GObject *object);
300 
301 /**
302  * gegl_temp_buffer:
303  *
304  * Returns a singleton scratch buffer for use with multi-threaded processing
305  * dispatch.
306  */
307 guchar    *gegl_temp_buffer (int no, int min_size);
308 
309 void       gegl_operation_progress (GeglOperation *operation, gdouble progress, gchar *message);
310 
311 const Babl *gegl_operation_get_source_space (GeglOperation *operation, const char *in_pad);
312 
313 
314 G_END_DECLS
315 
316 /***
317  */
318 
319 #endif /* __GEGL_OPERATION_H__ */
320