/* This file is part of GEGL.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see .
*
* Copyright 2008-2018 Øyvind Kolås
* 2013 Daniel Sabo
*/
#ifndef __GEGL_BUFFER_ITERATOR_H__
#define __GEGL_BUFFER_ITERATOR_H__
#include "gegl-buffer.h"
#define GEGL_BUFFER_READ GEGL_ACCESS_READ
#define GEGL_BUFFER_WRITE GEGL_ACCESS_WRITE
#define GEGL_BUFFER_READWRITE GEGL_ACCESS_READWRITE
typedef struct _GeglBufferIteratorPriv GeglBufferIteratorPriv;
/***
* GeglBufferIterator:
*
* GeglBufferIterator allows to iterate over one or more GeglBuffers.
* In each iteration the new data is available as a linear chunk of
* memory. See gegl_buffer_iterator_new() and gegl_buffer_iterator_next()
*/
typedef struct GeglBufferIteratorItem
{
gpointer data;
GeglRectangle roi;
} GeglBufferIteratorItem;
typedef struct GeglBufferIterator
{
gint length;
GeglBufferIteratorPriv *priv;
GeglBufferIteratorItem items[];
} GeglBufferIterator;
/**
* gegl_buffer_iterator_empty_new: (skip)
* Create a new buffer iterator without adding any buffers.
*
* Returns: a new buffer iterator.
*/
GeglBufferIterator *gegl_buffer_iterator_empty_new (int max_slots);
/**
* gegl_buffer_iterator_new: (skip)
* @buffer: a #GeglBuffer
* @roi: the rectangle to iterate over
* @level: the level at which we are iterating, the roi will indicate the
* extent at 1:1, x,y,width and height are/(2^level)
* @format: the format we want to process this buffers data in, pass 0 to use the buffers format.
* @access_mode: whether we need reading or writing to this buffer one of GEGL_BUFFER_READ, GEGL_BUFFER_WRITE and GEGL_BUFFER_READWRITE.
* @abyss_policy: how request outside the buffer extent are handled.
*
* Create a new buffer iterator, this buffer will be iterated through
* in linear chunks, some chunks might be full tiles the coordinates, see
* the documentation of gegl_buffer_iterator_next for how to use it and
* destroy it.
*
* Returns: a new buffer iterator that can be used to iterate through the
* buffers pixels.
*/
GeglBufferIterator * gegl_buffer_iterator_new (
GeglBuffer *buffer,
const GeglRectangle *roi,
gint level,
const Babl *format,
GeglAccessMode access_mode,
GeglAbyssPolicy abyss_policy,
gint max_slots);
/**
* gegl_buffer_iterator_add: (skip)
* @iterator: a #GeglBufferIterator
* @buffer: a #GeglBuffer
* @roi: the rectangle to iterate over
* @level: the level at which we are iterating, the roi will indicate the
* extent at 1:1, x,y,width and height are/(2^level)
* @format: the format we want to process this buffers data in, pass 0 to use the buffers format.
* @access_mode: whether we need reading or writing to this buffer.
* @abyss_policy: how request outside the buffer extent are handled.
*
* Adds an additional buffer iterator that will be processed in sync with
* the original one, if the buffer doesn't align with the other for tile access
* the corresponding scans and regions will be serialized automatically using
* gegl_buffer_get.
*
* If the buffer shares its tiles with a previously-added buffer (in
* particular, if the same buffer is added more than once), and at least one of
* the buffers is accessed for writing, the corresponding iterated-over areas
* should either completely overlap, or not overlap at all, in the coordinate-
* system of the underlying tile storage (that is, after shifting each area by
* the corresponding buffer's shift-x and shift-y properties). If the areas
* overlap, at most one of the buffers may be accessed for writing, and the
* data pointers of the corresponding iterator items may refer to the same
* data.
*
* Returns: an integer handle refering to the indice in the iterator structure
* of the added buffer.
*/
gint gegl_buffer_iterator_add (GeglBufferIterator *iterator,
GeglBuffer *buffer,
const GeglRectangle *roi,
gint level,
const Babl *format,
GeglAccessMode access_mode,
GeglAbyssPolicy abyss_policy);
/**
* gegl_buffer_iterator_stop: (skip)
* @iterator: a GeglBufferIterator
*
* Cancels the current iteration, freeing up any temporary resources. The
* iterator handle is no longer valid after invoking this function.
*/
void gegl_buffer_iterator_stop (GeglBufferIterator *iterator);
/**
* gegl_buffer_iterator_next: (skip)
* @iterator: a #GeglBufferIterator
*
* Do an iteration, this causes a new set of iterator->data[] to become
* available if there is more data to process. Changed data from a previous
* iteration step will also be saved now. When there is no more data to
* be processed FALSE will be returned (and the iterator handle is no longer
* valid).
*
* Returns: TRUE if there is more work FALSE if iteration is complete.
*/
gboolean gegl_buffer_iterator_next (GeglBufferIterator *iterator);
#endif