/* 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 2006, 2007 Øyvind Kolås */ #ifndef __GEGL_BUFFER_H__ #define __GEGL_BUFFER_H__ #include #include #include "gegl-buffer-matrix2.h" #include "gegl-buffer-enums.h" #define GEGL_AUTO_ROWSTRIDE 0 G_BEGIN_DECLS typedef struct _GeglTileBackend GeglTileBackend; typedef struct _GeglBuffer GeglBuffer; typedef struct _GeglSampler GeglSampler; typedef struct _GeglRectangle GeglRectangle; struct _GeglRectangle { gint x; gint y; gint width; gint height; }; /*** * GeglBuffer: * * GeglBuffer is the API used by GEGL for storing and retrieving raster data. * GeglBuffer heavily relies on babl for translation and description of * different pixel formats. * * Internally GeglBuffer currently uses a tiled mipmap pyramid structure that * can be swapped to disk. In the future GeglBuffer might also support a linear * backend, a GPU memory backend and a network backend for buffers. */ /** * gegl_buffer_new: (skip) * @extent: the geometry of the buffer (origin, width and height) a * GeglRectangle. * @format: the Babl pixel format to be used, create one with babl_format("RGBA * u8") and similar. * * Create a new GeglBuffer of a given format with a given extent. It is * possible to pass in NULL for both extent and format, a NULL extent creates * an empty buffer and a NULL format makes the buffer default to "RGBA float". */ GeglBuffer * gegl_buffer_new (const GeglRectangle *extent, const Babl *format); /** * gegl_buffer_new_for_backend: * @extent: the geometry of the buffer (origin, width and height) a * GeglRectangle. * @backend: an instance of a GeglTileBackend subclass. * * Create a new GeglBuffer from a backend, if NULL is passed in the extent of * the buffer will be inherited from the extent of the backend. * * returns a GeglBuffer, that holds a reference to the provided backend. */ GeglBuffer * gegl_buffer_new_for_backend (const GeglRectangle *extent, GeglTileBackend *backend); /** * gegl_buffer_add_handler: * @buffer: a #GeglBuffer * @handler: a #GeglTileHandler * * Add a new tile handler in the existing chain of tile handler of a GeglBuffer. */ void gegl_buffer_add_handler (GeglBuffer *buffer, gpointer handler); /** * gegl_buffer_remove_handler: * @buffer: a #GeglBuffer * @handler: a #GeglTileHandler * * Remove the provided tile handler in the existing chain of tile handler of a GeglBuffer. */ void gegl_buffer_remove_handler (GeglBuffer *buffer, gpointer handler); /** * gegl_buffer_open: * @path: the path to a gegl buffer on disk. * * Open an existing on-disk GeglBuffer, this buffer is opened in a monitored * state so multiple instances of gegl can share the same buffer. Sets on * one buffer are reflected in the other. * * Returns: (transfer full): a GeglBuffer object. */ GeglBuffer * gegl_buffer_open (const gchar *path); /** * gegl_buffer_save: * @buffer: (transfer none): a #GeglBuffer. * @path: the path where the gegl buffer will be saved, any writable GIO uri is valid. * @roi: the region of interest to write, this is the tiles that will be collected and * written to disk. * * Write a GeglBuffer to a file. */ void gegl_buffer_save (GeglBuffer *buffer, const gchar *path, const GeglRectangle *roi); /** * gegl_buffer_load: * @path: the path to a gegl buffer on disk. * * Loads an existing GeglBuffer from disk, if it has previously been saved with * gegl_buffer_save it should be possible to open through any GIO transport, buffers * that have been used as swap needs random access to be opened. * * Returns: (transfer full): a #GeglBuffer object. */ GeglBuffer * gegl_buffer_load (const gchar *path); /** * gegl_buffer_flush: * @buffer: a #GeglBuffer * * Flushes all unsaved data to disk, this is not necessary for shared * geglbuffers opened with gegl_buffer_open since they auto-sync on writes. */ void gegl_buffer_flush (GeglBuffer *buffer); /** * gegl_buffer_create_sub_buffer: * @buffer: (transfer none): parent buffer. * @extent: (transfer none): coordinates of new buffer. * * Create a new sub GeglBuffer, that is a view on a larger buffer. * * Return value: (transfer full): the new sub buffer */ GeglBuffer * gegl_buffer_create_sub_buffer (GeglBuffer *buffer, const GeglRectangle *extent); /** * gegl_buffer_get_extent: * @buffer: the buffer to operate on. * * Returns a pointer to a GeglRectangle structure defining the geometry of a * specific GeglBuffer, this is also the default width/height of buffers passed * in to gegl_buffer_set and gegl_buffer_get (with a scale of 1.0 at least). */ const GeglRectangle * gegl_buffer_get_extent (GeglBuffer *buffer); /** * gegl_buffer_set_extent: * @buffer: the buffer to operate on. * @extent: new extent. * * Changes the size and position that is considered active in a buffer, this * operation is valid on any buffer, reads on subbuffers outside the master * buffer's extent are at the moment undefined. * * Returns TRUE if the change of extent was successful. */ gboolean gegl_buffer_set_extent (GeglBuffer *buffer, const GeglRectangle *extent); /** * gegl_buffer_set_abyss: * @buffer: the buffer to operate on. * @abyss: new abyss. * * Changes the size and position of the abyss rectangle of a buffer. * * Returns TRUE if the change of abyss was successful. */ gboolean gegl_buffer_set_abyss (GeglBuffer *buffer, const GeglRectangle *abyss); /* convenience access macros */ /** * gegl_buffer_get_x: * @buffer: a GeglBuffer * * Evaluates to the X coordinate of the upper left corner of the buffer's extent. */ #define gegl_buffer_get_x(buffer) (gegl_buffer_get_extent(buffer)->x) /** * gegl_buffer_get_y: * @buffer: a GeglBuffer * * Evaluates to the Y coordinate of the upper left corner of the buffer's extent. */ #define gegl_buffer_get_y(buffer) (gegl_buffer_get_extent(buffer)->y) /** * gegl_buffer_get_width: * @buffer: a GeglBuffer * * Evaluates to the width of the buffer's extent. */ #define gegl_buffer_get_width(buffer) (gegl_buffer_get_extent(buffer)->width) /** * gegl_buffer_get_height: * @buffer: a GeglBuffer * * Evaluates to the height of the buffer's extent. */ #define gegl_buffer_get_height(buffer) (gegl_buffer_get_extent(buffer)->height) /** * gegl_buffer_get_pixel_count: * @buffer: a GeglBuffer * * Returns the number of pixels of the extent of the buffer. */ #define gegl_buffer_get_pixel_count(buffer) (gegl_buffer_get_width(buffer) * gegl_buffer_get_height(buffer)) /** * gegl_buffer_get: (skip) * @buffer: the buffer to retrieve data from. * @rect: the coordinates we want to retrieve data from, and width/height of * destination buffer, if NULL equal to the extent of the buffer. The * coordinates and dimensions are after scale has been applied. * @scale: sampling scale, 1.0 = pixel for pixel 2.0 = magnify, 0.5 scale down. * @format: the BablFormat to store in the linear buffer @dest. * @dest: the memory destination for a linear buffer for the pixels, the size needed * depends on the requested BablFormat. * @rowstride: rowstride in bytes, or GEGL_AUTO_ROWSTRIDE to compute the * rowstride based on the width and bytes per pixel for the specified format. * @repeat_mode: how requests outside the buffer extent are handled. * Valid values: GEGL_ABYSS_NONE (abyss pixels are zeroed), GEGL_ABYSS_WHITE * (abyss pixels are white), GEGL_ABYSS_BLACK (abyss pixels are black), * GEGL_ABYSS_CLAMP (coordinates are clamped to the abyss rectangle), * GEGL_ABYSS_LOOP (buffer contents are tiled if outside of the abyss rectangle) * this argument also takes a GEGL_BUFFER_FILTER value or'ed into it, allowing * to specify trade-off of performance/quality, valid values are: * GEGL_BUFFER_FILTER_NEAREST, GEGL_BUFFER_FILTER_BILINEAR, * GEGL_BUFFER_FILTER_BOX and GEGL_BUFFER_FILTER_AUTO. * * Fetch a rectangular linear buffer of pixel data from the GeglBuffer, the * data is converted to the desired BablFormat, if the BablFormat stored and * fetched is the same this amounts to a series of memcpy's aligned to demux * the tile structure into a linear buffer. * */ void gegl_buffer_get (GeglBuffer *buffer, const GeglRectangle *rect, gdouble scale, const Babl *format, gpointer dest, gint rowstride, GeglAbyssPolicy repeat_mode); /** * gegl_buffer_set: (skip) * @buffer: the buffer to modify. * @rect: the coordinates we want to change the data of and the width/height of * the linear buffer being set. * the data when setting. * @mipmap_level: the scale level being set, 0 = 1:1 = default = base mipmap level, * 1 = 1:2, 2=1:4, 3=1:8 .. * @format: the babl_format the linear buffer @src. * @src: linear buffer of image data to be stored in @buffer. * @rowstride: rowstride in bytes, or GEGL_AUTO_ROWSTRIDE to compute the * rowstride based on the width and bytes per pixel for the specified format. * * Store a linear raster buffer into the GeglBuffer. */ void gegl_buffer_set (GeglBuffer *buffer, const GeglRectangle *rect, gint mipmap_level, const Babl *format, const void *src, gint rowstride); /** * gegl_buffer_set_color_from_pixel: * @buffer: a #GeglBuffer * @rect: a rectangular region to fill with a color. * @pixel: pointer to the data of a single pixel * @pixel_format: the babl format of the pixel, if missing - the soft format of dst. * * Sets the region covered by rect to the the provided pixel. */ void gegl_buffer_set_color_from_pixel (GeglBuffer *buffer, const GeglRectangle *rect, gconstpointer pixel, const Babl *pixel_format); /** * gegl_buffer_set_pattern: * @buffer: a #GeglBuffer * @rect: the region of @buffer to fill * @pattern: a #GeglBuffer to be repeated as a pattern * @x_offset: where the pattern starts horizontally * @y_offset: where the pattern starts vertical * * Fill a region with a repeating pattern. Offsets parameters are * relative to the origin (0, 0) and not to the rectangle. So be carefull * about the origin of @pattern and @buffer extents. */ void gegl_buffer_set_pattern (GeglBuffer *buffer, const GeglRectangle *rect, GeglBuffer *pattern, gint x_offset, gint y_offset); /** * gegl_buffer_get_format: (skip) * @buffer: a #GeglBuffer * * Get the babl format of the buffer, this might not be the format the buffer * was originally created with, you need to use gegl_buffer_set_format (buf, * NULL); to retrieve the original format (potentially having saved away the * original format of the buffer to re-set it.) * * Returns: the babl format used for storing pixels in the buffer. * */ const Babl * gegl_buffer_get_format (GeglBuffer *buffer); /** * gegl_buffer_set_format: (skip) * @buffer: a #GeglBuffer * @format: the new babl format, must have same bpp as original format. * * Set the babl format of the buffer, setting the babl format of the buffer * requires the new format to have exactly the same bytes per pixel as the * original format. If NULL is passed in the format of the buffer is reset to * the original format. * * Returns: the new babl format or NULL if the passed-in buffer was * incompatible (then the original format is still used). */ const Babl * gegl_buffer_set_format (GeglBuffer *buffer, const Babl *format); /** * gegl_buffer_clear: * @buffer: a #GeglBuffer * @roi: a rectangular region * * Clears the provided rectangular region by setting all the associated memory * to 0. */ void gegl_buffer_clear (GeglBuffer *buffer, const GeglRectangle *roi); /** * gegl_buffer_copy: * @src: (transfer none): source buffer. * @src_rect: source rectangle (or NULL to copy entire source buffer) * @repeat_mode: the abyss policy to be using if src_rect is outside src's extent. * @dst: (transfer none): destination buffer. * @dst_rect: position of upper left destination pixel (or NULL to match @src_rect) * * Copy a region from source buffer to destination buffer. * * If the babl_formats of the buffers are the same, and the tile boundaries * align, this will create copy-on-write tiles in the destination buffer. * * This function never does any scaling. When src_rect and dst_rect do not have * the same width and height, the size of src_rect is used. */ void gegl_buffer_copy (GeglBuffer *src, const GeglRectangle *src_rect, GeglAbyssPolicy repeat_mode, GeglBuffer *dst, const GeglRectangle *dst_rect); /** * gegl_buffer_dup: * @buffer: (transfer none): the GeglBuffer to duplicate. * * Duplicate a buffer (internally uses gegl_buffer_copy). Aligned tiles * will create copy-on-write clones in the new buffer. * * Return value: (transfer full): the new buffer */ GeglBuffer * gegl_buffer_dup (GeglBuffer *buffer); /** * gegl_buffer_sample_at_level: (skip) * @buffer: the GeglBuffer to sample from * @x: x coordinate to sample in buffer coordinates * @y: y coordinate to sample in buffer coordinates * @scale: a matrix that indicates scaling factors, see * gegl_sampler_compute_scale the same. * @dest: buffer capable of storing one pixel in @format. * @format: the format to store the sampled color in. * @level: mipmap level to sample from (@x and @y are level 0 coordinates) * @sampler_type: the sampler type to use, * to be ported from working code. Valid values: GEGL_SAMPLER_NEAREST, * GEGL_SAMPLER_LINEAR, GEGL_SAMPLER_CUBIC, GEGL_SAMPLER_NOHALO and * GEGL_SAMPLER_LOHALO * @repeat_mode: how requests outside the buffer extent are handled. * Valid values: GEGL_ABYSS_NONE (abyss pixels are zeroed), GEGL_ABYSS_WHITE * (abyss pixels are white), GEGL_ABYSS_BLACK (abyss pixels are black), * GEGL_ABYSS_CLAMP (coordinates are clamped to the abyss rectangle), * GEGL_ABYSS_LOOP (buffer contents are tiled if outside of the abyss rectangle). * * Query interpolate pixel values at a given coordinate using a specified form * of interpolation. * * If you intend to take multiple samples, consider using * gegl_buffer_sampler_new_at_level() to create a sampler object instead, which * is more efficient. */ void gegl_buffer_sample_at_level (GeglBuffer *buffer, gdouble x, gdouble y, GeglBufferMatrix2 *scale, gpointer dest, const Babl *format, gint level, GeglSamplerType sampler_type, GeglAbyssPolicy repeat_mode); /** * gegl_buffer_sample: (skip) * @buffer: the GeglBuffer to sample from * @x: x coordinate to sample in buffer coordinates * @y: y coordinate to sample in buffer coordinates * @scale: a matrix that indicates scaling factors, see * gegl_sampler_compute_scale the same. * @dest: buffer capable of storing one pixel in @format. * @format: the format to store the sampled color in. * @sampler_type: the sampler type to use, * to be ported from working code. Valid values: GEGL_SAMPLER_NEAREST, * GEGL_SAMPLER_LINEAR, GEGL_SAMPLER_CUBIC, GEGL_SAMPLER_NOHALO and * GEGL_SAMPLER_LOHALO * @repeat_mode: how requests outside the buffer extent are handled. * Valid values: GEGL_ABYSS_NONE (abyss pixels are zeroed), GEGL_ABYSS_WHITE * (abyss pixels are white), GEGL_ABYSS_BLACK (abyss pixels are black), * GEGL_ABYSS_CLAMP (coordinates are clamped to the abyss rectangle), * GEGL_ABYSS_LOOP (buffer contents are tiled if outside of the abyss rectangle). * * Query interpolate pixel values at a given coordinate using a specified form * of interpolation. * * If you intend to take multiple samples, consider using * gegl_buffer_sampler_new() to create a sampler object instead, which is more * efficient. */ void gegl_buffer_sample (GeglBuffer *buffer, gdouble x, gdouble y, GeglBufferMatrix2 *scale, gpointer dest, const Babl *format, GeglSamplerType sampler_type, GeglAbyssPolicy repeat_mode); /** * gegl_buffer_sample_cleanup: * @buffer: the GeglBuffer to sample from * * Clean up resources used by sampling framework of buffer. * * Deprecated: 0.4.2: This function has no effect. It is not necessary to call * it after using gegl_buffer_sample() or gegl_buffer_sample_at_level(). */ G_DEPRECATED void gegl_buffer_sample_cleanup (GeglBuffer *buffer); typedef void (*GeglSamplerGetFun) (GeglSampler *self, gdouble x, gdouble y, GeglBufferMatrix2 *scale, void *output, GeglAbyssPolicy repeat_mode); /** * gegl_sampler_get_fun: (skip) * * Get the raw sampler function, the raw sampler function does not do * additional NaN / inifinity checks on passed in coordinates. */ GeglSamplerGetFun gegl_sampler_get_fun (GeglSampler *sampler); /** * gegl_buffer_sampler_new: (skip) * @buffer: buffer to create a new sampler for * @format: format we want data back in * @sampler_type: the sampler type to use, * to be ported from working code. Valid values: GEGL_SAMPLER_NEAREST, * GEGL_SAMPLER_LINEAR, GEGL_SAMPLER_CUBIC, GEGL_SAMPLER_NOHALO and * GEGL_SAMPLER_LOHALO * * Create a new sampler, when you are done with the sampler, g_object_unref * it. * * Samplers only hold weak references to buffers, so if its buffer is freed * the sampler will become invalid. */ GeglSampler * gegl_buffer_sampler_new (GeglBuffer *buffer, const Babl *format, GeglSamplerType sampler_type); /** * gegl_buffer_sampler_new_at_level: (skip) * @buffer: buffer to create a new sampler for * @format: format we want data back in * @sampler_type: the sampler type to use, * @level: the mipmap level to create a sampler for * to be ported from working code. Valid values: GEGL_SAMPLER_NEAREST, * GEGL_SAMPLER_LINEAR, GEGL_SAMPLER_CUBIC, GEGL_SAMPLER_NOHALO and * GEGL_SAMPLER_LOHALO * * Create a new sampler, when you are done with the sampler, g_object_unref * it. * * Samplers only hold weak references to buffers, so if its buffer is freed * the sampler will become invalid. */ GeglSampler * gegl_buffer_sampler_new_at_level (GeglBuffer *buffer, const Babl *format, GeglSamplerType sampler_type, gint level); /** * gegl_sampler_get: * @sampler: a GeglSampler gotten from gegl_buffer_sampler_new * @x: x coordinate to sample * @y: y coordinate to sample * @scale: matrix representing extent of sampling area in source buffer. * @output: memory location for output data. * @repeat_mode: how requests outside the buffer extent are handled. * Valid values: GEGL_ABYSS_NONE (abyss pixels are zeroed), GEGL_ABYSS_WHITE * (abyss pixels are white), GEGL_ABYSS_BLACK (abyss pixels are black), * GEGL_ABYSS_CLAMP (coordinates are clamped to the abyss rectangle), * GEGL_ABYSS_LOOP (buffer contents are tiled if outside of the abyss rectangle). * * Perform a sampling with the provided @sampler. */ void gegl_sampler_get (GeglSampler *sampler, gdouble x, gdouble y, GeglBufferMatrix2 *scale, void *output, GeglAbyssPolicy repeat_mode); /* code template utility, updates the jacobian matrix using * a user defined mapping function for displacement, example * with an identity transform (note that for the identity * transform this is massive computational overhead that can * be skipped by passing NULL to the sampler. * * #define gegl_unmap(x,y,dx,dy) { dx=x; dy=y; } * * gegl_sampler_compute_scale (scale, x, y); * gegl_unmap(x,y,sample_x,sample_y); * gegl_buffer_sample (buffer, sample_x, sample_y, scale, dest, format, * GEGL_SAMPLER_LOHALO); * * #undef gegl_unmap // IMPORTANT undefine map macro */ #define gegl_sampler_compute_scale(matrix, x, y) \ { \ float ax, ay, bx, by; \ gegl_unmap(x + 0.5, y, ax, ay); \ gegl_unmap(x - 0.5, y, bx, by); \ matrix.coeff[0][0] = ax - bx; \ matrix.coeff[1][0] = ay - by; \ gegl_unmap(x, y + 0.5, ax, ay); \ gegl_unmap(x, y - 0.5, bx, by); \ matrix.coeff[0][1] = ax - bx; \ matrix.coeff[1][1] = ay - by; \ } /** * gegl_sampler_get_context_rect: * @sampler: a GeglSampler gotten from gegl_buffer_sampler_new * * Returns:The context rectangle of the given @sampler. */ const GeglRectangle * gegl_sampler_get_context_rect (GeglSampler *sampler); /** * gegl_buffer_linear_new: (skip) * @extent: dimensions of buffer. * @format: desired pixel format. * * Creates a GeglBuffer backed by a linear memory buffer, of the given * @extent in the specified @format. babl_format ("R'G'B'A u8") for instance * to make a normal 8bit buffer. * * Returns: a GeglBuffer that can be used as any other GeglBuffer. */ GeglBuffer * gegl_buffer_linear_new (const GeglRectangle *extent, const Babl *format); /** * gegl_buffer_linear_new_from_data: (skip) * @data: a pointer to a linear buffer in memory. * @format: the format of the data in memory * @extent: the dimensions (and upper left coordinates) of linear buffer. * @rowstride: the number of bytes between rowstarts in memory (or 0 to * autodetect) * @destroy_fn: function to call to free data or NULL if memory should not be * freed. * @destroy_fn_data: extra argument to be passed to void destroy(ptr, data) type * function. * * Creates a GeglBuffer backed by a linear memory buffer that already exists, * of the given @extent in the specified @format. babl_format ("R'G'B'A u8") * for instance to make a normal 8bit buffer. * * Returns: a GeglBuffer that can be used as any other GeglBuffer. */ GeglBuffer * gegl_buffer_linear_new_from_data (const gpointer data, const Babl *format, const GeglRectangle *extent, gint rowstride, GDestroyNotify destroy_fn, gpointer destroy_fn_data); /** * gegl_buffer_linear_open: (skip) * @buffer: a #GeglBuffer. * @extent: region to open, pass NULL for entire buffer. * @rowstride: return location for rowstride. * @format: desired format or NULL to use buffers format. * * Raw direct random access to the full data of a buffer in linear memory. * * Returns: a pointer to a linear memory region describing the buffer, if the * request is compatible with the underlying data storage direct access * to the underlying data is provided. Otherwise, it returns a copy of the data. */ gpointer gegl_buffer_linear_open (GeglBuffer *buffer, const GeglRectangle *extent, gint *rowstride, const Babl *format); /** * gegl_buffer_linear_close: * @buffer: a #GeglBuffer. * @linear: a previously returned buffer. * * This function makes sure GeglBuffer and underlying code is aware of changes * being made to the linear buffer. If the request was not a compatible one * it is written back to the buffer. Multiple concurrent users can be handed * the same buffer (both raw access and converted). */ void gegl_buffer_linear_close (GeglBuffer *buffer, gpointer linear); /** * gegl_buffer_get_abyss: * @buffer: a #GeglBuffer. * * Return the abyss extent of a buffer, this expands out to the parents extent in * subbuffers. */ const GeglRectangle * gegl_buffer_get_abyss (GeglBuffer *buffer); /** * gegl_buffer_share_storage: * @buffer1: a #GeglBuffer. * @buffer2: a #GeglBuffer. * * Checks if a pair of buffers share the same underlying tile storage. * * Returns TRUE if @buffer1 and @buffer2 share the same storage. */ gboolean gegl_buffer_share_storage (GeglBuffer *buffer1, GeglBuffer *buffer2); /** * gegl_buffer_signal_connect: * @buffer: a GeglBuffer * @detailed_signal: only "changed" expected for now * @c_handler: (scope async) : c function callback * @data: user data: * * This function should be used instead of g_signal_connect when connecting to * the GeglBuffer::changed signal handler, GeglBuffer contains additional * machinery to avoid the overhead of changes when no signal handler have been * connected, if regular g_signal_connect is used; then no signals will be * emitted. * * Returns: an handle like g_signal_connect. */ glong gegl_buffer_signal_connect (GeglBuffer *buffer, const char *detailed_signal, GCallback c_handler, gpointer data); /** * gegl_buffer_freeze_changed: * @buffer: a GeglBuffer * * Blocks emission of the "changed" signal for @buffer. * * While the signal is blocked, changes to @buffer are accumulated, and will * be emitted once the signal is unblocked, using gegl_buffer_thaw_changed(). */ void gegl_buffer_freeze_changed (GeglBuffer *buffer); /** * gegl_buffer_thaw_changed: * @buffer: a GeglBuffer * * Unblocks emission of the "changed" signal for @buffer. * * Once all calls to gegl_buffer_freeze_changed() are matched by corresponding * calls to gegl_buffer_freeze_changed(), all accumulated changes are emitted. */ void gegl_buffer_thaw_changed (GeglBuffer *buffer); /** * gegl_buffer_flush_ext: * @buffer: a GeglBuffer * @rect: rectangle * * Invokes the external flush function, if any is set on the provided buffer - * this ensures that data pending - in the current implementation only OpenCL - * externally to be synchronized with the buffer. Multi threaded code should * call such a synchronization before branching out to avoid each of the * threads having an implicit synchronization of its own. */ void gegl_buffer_flush_ext (GeglBuffer *buffer, const GeglRectangle *rect); #include "gegl-buffer-iterator.h" #include "gegl-rectangle.h" #include "gegl-memory.h" #include "gegl-scratch.h" GType gegl_buffer_get_type (void) G_GNUC_CONST; #define GEGL_TYPE_BUFFER (gegl_buffer_get_type ()) #define GEGL_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEGL_TYPE_BUFFER, GeglBuffer)) #define GEGL_IS_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEGL_TYPE_BUFFER)) G_DEFINE_AUTOPTR_CLEANUP_FUNC (GeglBuffer, g_object_unref) G_END_DECLS #endif