1 /* This file is part of GEGL.
2  *
3  * This library 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  * This library 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 this library; if not, see <https://www.gnu.org/licenses/>.
15  *
16  * Copyright 2008-2018 Øyvind Kolås <pippin@gimp.org>
17  *           2013 Daniel Sabo
18  */
19 
20 #ifndef __GEGL_BUFFER_ITERATOR_H__
21 #define __GEGL_BUFFER_ITERATOR_H__
22 
23 #include "gegl-buffer.h"
24 
25 #define GEGL_BUFFER_READ      GEGL_ACCESS_READ
26 #define GEGL_BUFFER_WRITE     GEGL_ACCESS_WRITE
27 #define GEGL_BUFFER_READWRITE GEGL_ACCESS_READWRITE
28 
29 typedef struct _GeglBufferIteratorPriv GeglBufferIteratorPriv;
30 
31 /***
32  * GeglBufferIterator:
33  *
34  * GeglBufferIterator allows to iterate over one or more GeglBuffers.
35  * In each iteration the new data is available as a linear chunk of
36  * memory. See gegl_buffer_iterator_new() and gegl_buffer_iterator_next()
37  */
38 
39 typedef struct GeglBufferIteratorItem
40 {
41   gpointer      data;
42   GeglRectangle roi;
43 } GeglBufferIteratorItem;
44 
45 typedef struct GeglBufferIterator
46 {
47   gint           length;
48   GeglBufferIteratorPriv *priv;
49   GeglBufferIteratorItem  items[];
50 } GeglBufferIterator;
51 
52 
53 /**
54  * gegl_buffer_iterator_empty_new: (skip)
55  * Create a new buffer iterator without adding any buffers.
56  *
57  * Returns: a new buffer iterator.
58  */
59 GeglBufferIterator *gegl_buffer_iterator_empty_new (int max_slots);
60 
61 /**
62  * gegl_buffer_iterator_new: (skip)
63  * @buffer: a #GeglBuffer
64  * @roi: the rectangle to iterate over
65  * @level: the level at which we are iterating, the roi will indicate the
66  * extent at 1:1, x,y,width and height are/(2^level)
67  * @format: the format we want to process this buffers data in, pass 0 to use the buffers format.
68  * @access_mode: whether we need reading or writing to this buffer one of GEGL_BUFFER_READ, GEGL_BUFFER_WRITE and GEGL_BUFFER_READWRITE.
69  * @abyss_policy: how request outside the buffer extent are handled.
70  *
71  * Create a new buffer iterator, this buffer will be iterated through
72  * in linear chunks, some chunks might be full tiles the coordinates, see
73  * the documentation of gegl_buffer_iterator_next for how to use it and
74  * destroy it.
75  *
76  * Returns: a new buffer iterator that can be used to iterate through the
77  * buffers pixels.
78  */
79 GeglBufferIterator * gegl_buffer_iterator_new  (
80                                                  GeglBuffer          *buffer,
81                                                  const GeglRectangle *roi,
82                                                  gint                 level,
83                                                  const Babl          *format,
84                                                  GeglAccessMode       access_mode,
85                                                  GeglAbyssPolicy      abyss_policy,
86                                                  gint                 max_slots);
87 
88 
89 /**
90  * gegl_buffer_iterator_add: (skip)
91  * @iterator: a #GeglBufferIterator
92  * @buffer: a #GeglBuffer
93  * @roi: the rectangle to iterate over
94  * @level: the level at which we are iterating, the roi will indicate the
95  * extent at 1:1, x,y,width and height are/(2^level)
96  * @format: the format we want to process this buffers data in, pass 0 to use the buffers format.
97  * @access_mode: whether we need reading or writing to this buffer.
98  * @abyss_policy: how request outside the buffer extent are handled.
99  *
100  * Adds an additional buffer iterator that will be processed in sync with
101  * the original one, if the buffer doesn't align with the other for tile access
102  * the corresponding scans and regions will be serialized automatically using
103  * gegl_buffer_get.
104  *
105  * If the buffer shares its tiles with a previously-added buffer (in
106  * particular, if the same buffer is added more than once), and at least one of
107  * the buffers is accessed for writing, the corresponding iterated-over areas
108  * should either completely overlap, or not overlap at all, in the coordinate-
109  * system of the underlying tile storage (that is, after shifting each area by
110  * the corresponding buffer's shift-x and shift-y properties).  If the areas
111  * overlap, at most one of the buffers may be accessed for writing, and the
112  * data pointers of the corresponding iterator items may refer to the same
113  * data.
114  *
115  * Returns: an integer handle refering to the indice in the iterator structure
116  * of the added buffer.
117  */
118 gint                 gegl_buffer_iterator_add  (GeglBufferIterator  *iterator,
119                                                 GeglBuffer          *buffer,
120                                                 const GeglRectangle *roi,
121                                                 gint                 level,
122                                                 const Babl          *format,
123                                                 GeglAccessMode       access_mode,
124                                                 GeglAbyssPolicy      abyss_policy);
125 
126 /**
127  * gegl_buffer_iterator_stop: (skip)
128  * @iterator: a GeglBufferIterator
129  *
130  * Cancels the current iteration, freeing up any temporary resources. The
131  * iterator handle is no longer valid after invoking this function.
132  */
133 void                 gegl_buffer_iterator_stop  (GeglBufferIterator *iterator);
134 
135 /**
136  * gegl_buffer_iterator_next: (skip)
137  * @iterator: a #GeglBufferIterator
138  *
139  * Do an iteration, this causes a new set of iterator->data[] to become
140  * available if there is more data to process. Changed data from a previous
141  * iteration step will also be saved now. When there is no more data to
142  * be processed FALSE will be returned (and the iterator handle is no longer
143  * valid).
144  *
145  * Returns: TRUE if there is more work FALSE if iteration is complete.
146  */
147 gboolean             gegl_buffer_iterator_next (GeglBufferIterator *iterator);
148 
149 
150 
151 #endif
152