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) { GeglBuffer *buffer; GeglTile *tile; gint bpp; g_return_val_if_fail (extent, NULL); g_return_val_if_fail (format, NULL); bpp = babl_format_get_bytes_per_pixel (format); if (rowstride == 0) { rowstride = extent->width; } else { g_return_val_if_fail (rowstride > 0, NULL); g_return_val_if_fail (rowstride % bpp == 0, NULL); rowstride = rowstride / bpp; } buffer = g_object_new (GEGL_TYPE_BUFFER, "x", extent->x, "y", extent->y, "shift-x", -extent->x, "shift-y", -extent->y, "width", extent->width, "height", extent->height, "tile-width", rowstride, "tile-height", extent->height, "format", format, "path", "RAM", NULL); g_object_set_data (G_OBJECT (buffer), "is-linear", (void*)0xf00); tile = gegl_tile_new_bare (); tile->tile_storage = buffer->tile_storage; tile->x = 0; tile->y = 0; tile->z = 0; tile->next_shared = tile; tile->prev_shared = tile; tile->rev = tile->stored_rev + 1; gegl_tile_set_data_full (tile, (gpointer) data, bpp * rowstride * extent->height, destroy_fn, destroy_fn_data); if (buffer->tile_storage->cache) gegl_tile_handler_cache_insert (buffer->tile_storage->cache, tile, 0, 0, 0); gegl_tile_unref (tile); return buffer; }
static GeglTile * get_tile (GeglTileSource *gegl_tile_source, gint x, gint y, gint z) { GeglTileSource *source = ((GeglTileHandler*)(gegl_tile_source))->source; GeglTileHandlerZoom *zoom = (GeglTileHandlerZoom*)(gegl_tile_source); GeglTile *tile = NULL; const Babl *format = gegl_tile_backend_get_format (zoom->backend); gint tile_width; gint tile_height; gint tile_size; if (source) { tile = gegl_tile_source_get_tile (source, x, y, z); } if (tile) return tile; if (z == 0)/* at base level with no tile found->send null, and shared empty tile will be used instead */ { return NULL; } if (z>zoom->tile_storage->seen_zoom) zoom->tile_storage->seen_zoom = z; g_assert (zoom->backend); g_object_get (zoom->backend, "tile-width", &tile_width, "tile-height", &tile_height, "tile-size", &tile_size, NULL); { gint i, j; GeglTile *source_tile[2][2] = { { NULL, NULL }, { NULL, NULL } }; for (i = 0; i < 2; i++) for (j = 0; j < 2; j++) { /* we get the tile from ourselves, to make successive rescales work * correctly */ source_tile[i][j] = gegl_tile_source_get_tile (gegl_tile_source, x * 2 + i, y * 2 + j, z - 1); } if (source_tile[0][0] == NULL && source_tile[0][1] == NULL && source_tile[1][0] == NULL && source_tile[1][1] == NULL) { return NULL; /* no data from level below, return NULL and let GeglTileHandlerEmpty fill in the shared empty tile */ } g_assert (tile == NULL); if (tile == NULL) { tile = gegl_tile_new (tile_size); tile->x = x; tile->y = y; tile->z = z; tile->tile_storage = zoom->tile_storage; if (zoom->cache) gegl_tile_handler_cache_insert (zoom->cache, tile, x, y, z); } gegl_tile_lock (tile); for (i = 0; i < 2; i++) for (j = 0; j < 2; j++) { if (source_tile[i][j]) { set_half (tile, source_tile[i][j], tile_width, tile_height, format, i, j); gegl_tile_unref (source_tile[i][j]); } else { set_blank (tile, tile_width, tile_height, format, i, j); } } gegl_tile_unlock (tile); } return tile; }