/* Do the final setup of the iter struct */ static void prepare_iteration (GeglBufferIterator *iter) { int index; GeglBufferIteratorPriv *priv = iter->priv; gint origin_offset_x; gint origin_offset_y; /* Set up the origin tile */ /* FIXME: Pick the most compatable buffer, not just the first */ { GeglBuffer *buf = priv->sub_iter[0].buffer; priv->origin_tile.x = buf->shift_x; priv->origin_tile.y = buf->shift_y; priv->origin_tile.width = buf->tile_width; priv->origin_tile.height = buf->tile_height; origin_offset_x = buf->shift_x + priv->sub_iter[0].full_rect.x; origin_offset_y = buf->shift_y + priv->sub_iter[0].full_rect.y; } for (index = 0; index < priv->num_buffers; index++) { SubIterState *sub = &priv->sub_iter[index]; GeglBuffer *buf = sub->buffer; gint current_offset_x = buf->shift_x + priv->sub_iter[index].full_rect.x; gint current_offset_y = buf->shift_y + priv->sub_iter[index].full_rect.y; /* Format converison needed */ if (gegl_buffer_get_format (sub->buffer) != sub->format) sub->access_mode |= GEGL_ITERATOR_INCOMPATIBLE; /* Incompatable tiles */ else if ((priv->origin_tile.width != buf->tile_width) || (priv->origin_tile.height != buf->tile_height) || (abs(origin_offset_x - current_offset_x) % priv->origin_tile.width != 0) || (abs(origin_offset_y - current_offset_y) % priv->origin_tile.height != 0)) { /* Check if the buffer is a linear buffer */ if ((buf->extent.x == -buf->shift_x) && (buf->extent.y == -buf->shift_y) && (buf->extent.width == buf->tile_width) && (buf->extent.height == buf->tile_height)) { sub->linear_tile = gegl_buffer_get_tile (sub->buffer, 0, 0, 0); if (sub->access_mode & GEGL_ACCESS_WRITE) gegl_tile_lock (sub->linear_tile); } else sub->access_mode |= GEGL_ITERATOR_INCOMPATIBLE; } gegl_buffer_lock (sub->buffer); } }
static gpointer gegl_buffer_command (GeglTileSource *source, GeglTileCommand command, gint x, gint y, gint z, gpointer data) { GeglTileHandler *handler = GEGL_TILE_HANDLER (source); switch (command) { case GEGL_TILE_GET: return gegl_buffer_get_tile (source, x, y, z); default: return gegl_tile_handler_source_command (handler, command, x, y, z, data); } }
static void get_tile (GeglBufferIterator *iter, int index) { GeglBufferIteratorPriv *priv = iter->priv; SubIterState *sub = &priv->sub_iter[index]; GeglBuffer *buf = priv->sub_iter[index].buffer; if (sub->linear_tile) { sub->current_tile = sub->linear_tile; sub->real_roi = buf->extent; sub->current_tile_mode = GeglIteratorTileMode_LinearTile; } else { int shift_x = buf->shift_x; // XXX: affect by level? int shift_y = buf->shift_y; int tile_width = buf->tile_width; int tile_height = buf->tile_height; int tile_x = gegl_tile_indice (iter->roi[index].x + shift_x, tile_width); int tile_y = gegl_tile_indice (iter->roi[index].y + shift_y, tile_height); sub->current_tile = gegl_buffer_get_tile (buf, tile_x, tile_y, sub->level); if (sub->access_mode & GEGL_ACCESS_WRITE) gegl_tile_lock (sub->current_tile); sub->real_roi.x = (tile_x * tile_width) - shift_x; sub->real_roi.y = (tile_y * tile_height) - shift_y; sub->real_roi.width = tile_width; sub->real_roi.height = tile_height; sub->current_tile_mode = GeglIteratorTileMode_DirectTile; } sub->row_stride = buf->tile_width * sub->format_bpp; iter->data[index] = gegl_tile_get_data (sub->current_tile); }