/* GTK - The GIMP Toolkit * Copyright (C) 2023 Benjamin Otte * * 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 2 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 . */ /** * GdkTextureDownloader: * * The `GdkTextureDownloader` is used to download the contents of a * [class@Gdk.Texture]. * * It is intended to be created as a short-term object for a single download, * but can be used for multiple downloads of different textures or with different * settings. * * `GdkTextureDownloader` can be used to convert data between different formats. * Create a `GdkTexture` for the existing format and then download it in a * different format. * * Since: 4.10 */ #include "config.h" #include "gdktexturedownloaderprivate.h" #include "gdkcolorstateprivate.h" #include "gdkmemoryformatprivate.h" #include "gdkmemorytextureprivate.h" #include "gdktextureprivate.h" G_DEFINE_BOXED_TYPE (GdkTextureDownloader, gdk_texture_downloader, gdk_texture_downloader_copy, gdk_texture_downloader_free) void gdk_texture_downloader_init (GdkTextureDownloader *self, GdkTexture *texture) { self->texture = g_object_ref (texture); self->format = GDK_MEMORY_DEFAULT; self->color_state = gdk_color_state_ref (GDK_COLOR_STATE_SRGB); } void gdk_texture_downloader_finish (GdkTextureDownloader *self) { g_object_unref (self->texture); gdk_color_state_unref (self->color_state); } /** * gdk_texture_downloader_new: * @texture: texture to download * * Creates a new texture downloader for @texture. * * By default, the downloader will convert the data to * the default memory format, and to the sRGB color state. * * Returns: A new texture downloader * * Since: 4.10 **/ GdkTextureDownloader * gdk_texture_downloader_new (GdkTexture *texture) { GdkTextureDownloader *self; g_return_val_if_fail (GDK_IS_TEXTURE (texture), NULL); self = g_new (GdkTextureDownloader, 1); gdk_texture_downloader_init (self, texture); return self; } /** * gdk_texture_downloader_copy: * @self: the downloader to copy * * Creates a copy of the downloader. * * This function is meant for language bindings. * * Returns: A copy of the downloader * * Since: 4.10 **/ GdkTextureDownloader * gdk_texture_downloader_copy (const GdkTextureDownloader *self) { GdkTextureDownloader *copy; g_return_val_if_fail (self != NULL, NULL); copy = gdk_texture_downloader_new (self->texture); gdk_texture_downloader_set_format (copy, self->format); return copy; } /** * gdk_texture_downloader_free: * @self: texture downloader to free * * Frees the given downloader and all its associated resources. * * Since: 4.10 **/ void gdk_texture_downloader_free (GdkTextureDownloader *self) { g_return_if_fail (self != NULL); gdk_texture_downloader_finish (self); g_free (self); } /** * gdk_texture_downloader_set_texture: * @self: a texture downloader * @texture: the new texture to download * * Changes the texture the downloader will download. * * Since: 4.10 **/ void gdk_texture_downloader_set_texture (GdkTextureDownloader *self, GdkTexture *texture) { g_return_if_fail (self != NULL); g_return_if_fail (GDK_IS_TEXTURE (texture)); g_set_object (&self->texture, texture); } /** * gdk_texture_downloader_get_texture: * @self: a texture downloader * * Gets the texture that the downloader will download. * * Returns: (transfer none): The texture to download * * Since: 4.10 **/ GdkTexture * gdk_texture_downloader_get_texture (const GdkTextureDownloader *self) { g_return_val_if_fail (self != NULL, NULL); return self->texture; } /** * gdk_texture_downloader_set_format: * @self: a texture downloader * @format: the format to use * * Sets the format the downloader will download. * * By default, GDK_MEMORY_DEFAULT is set. * * Since: 4.10 */ void gdk_texture_downloader_set_format (GdkTextureDownloader *self, GdkMemoryFormat format) { g_return_if_fail (self != NULL); self->format = format; } /** * gdk_texture_downloader_get_format: * @self: a texture downloader * * Gets the format that the data will be downloaded in. * * Returns: The format of the download * * Since: 4.10 **/ GdkMemoryFormat gdk_texture_downloader_get_format (const GdkTextureDownloader *self) { g_return_val_if_fail (self != NULL, GDK_MEMORY_DEFAULT); return self->format; } /** * gdk_texture_downloader_set_color_state: * @self: a texture downloader * @color_state: the color state to use * * Sets the color state the downloader will convert the data to. * * By default, the sRGB colorstate returned by [func@ColorState.get_srgb] * is used. * * Since: 4.16 */ void gdk_texture_downloader_set_color_state (GdkTextureDownloader *self, GdkColorState *color_state) { if (self->color_state == color_state) return; gdk_color_state_unref (self->color_state); self->color_state = gdk_color_state_ref (color_state); } /** * gdk_texture_downloader_get_color_state: * @self: a texture downloader * * Gets the color state that the data will be downloaded in. * * Returns: The color state of the download * * Since: 4.16 **/ GdkColorState * gdk_texture_downloader_get_color_state (const GdkTextureDownloader *self) { return self->color_state; } /** * gdk_texture_downloader_download_into: * @self: a texture downloader * @data: (array): pointer to enough memory to be filled with the * downloaded data of the texture * @stride: rowstride in bytes * * Downloads the @texture into local memory. * * Since: 4.10 **/ void gdk_texture_downloader_download_into (const GdkTextureDownloader *self, guchar *data, gsize stride) { g_return_if_fail (self != NULL); g_return_if_fail (data != NULL); g_return_if_fail (stride >= gdk_texture_get_width (self->texture) * gdk_memory_format_bytes_per_pixel (self->format)); gdk_texture_do_download (self->texture, self->format, self->color_state, data, stride); } /** * gdk_texture_downloader_download_bytes: * @self: the downloader * @out_stride: (out): The stride of the resulting data in bytes * * Downloads the given texture pixels into a `GBytes`. The rowstride will * be stored in the stride value. * * This function will abort if it tries to download a large texture and * fails to allocate memory. If you think that may happen, you should handle * memory allocation yourself and use [method@Gdk.TextureDownloader.download_into] * once allocation succeeded. * * Returns: The downloaded pixels * * Since: 4.10 **/ GBytes * gdk_texture_downloader_download_bytes (const GdkTextureDownloader *self, gsize *out_stride) { guchar *data; gsize stride; g_return_val_if_fail (self != NULL, NULL); g_return_val_if_fail (out_stride != NULL, NULL); if (GDK_IS_MEMORY_TEXTURE (self->texture) && gdk_texture_get_format (self->texture) == self->format && gdk_color_state_equal (gdk_texture_get_color_state (self->texture), self->color_state)) { GdkMemoryTexture *memtex = GDK_MEMORY_TEXTURE (self->texture); return g_bytes_ref (gdk_memory_texture_get_bytes (memtex, out_stride)); } stride = self->texture->width * gdk_memory_format_bytes_per_pixel (self->format); data = g_malloc_n (stride, self->texture->height); gdk_texture_do_download (self->texture, self->format, self->color_state, data, stride); *out_stride = stride; return g_bytes_new_take (data, stride * self->texture->height); }