diff options
Diffstat (limited to 'src/SFML/Graphics/ImageLoader.cpp')
-rw-r--r-- | src/SFML/Graphics/ImageLoader.cpp | 86 |
1 files changed, 68 insertions, 18 deletions
diff --git a/src/SFML/Graphics/ImageLoader.cpp b/src/SFML/Graphics/ImageLoader.cpp index 023541d..ddcdd18 100644 --- a/src/SFML/Graphics/ImageLoader.cpp +++ b/src/SFML/Graphics/ImageLoader.cpp @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2018 Laurent Gomila (laurent@sfml-dev.org) +// Copyright (C) 2007-2023 Laurent Gomila (laurent@sfml-dev.org) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. @@ -28,11 +28,11 @@ #include <SFML/Graphics/ImageLoader.hpp> #include <SFML/System/InputStream.hpp> #include <SFML/System/Err.hpp> -#define STB_IMAGE_IMPLEMENTATION #include <stb_image.h> -#define STB_IMAGE_WRITE_IMPLEMENTATION #include <stb_image_write.h> #include <cctype> +#include <iterator> +#include <cstring> namespace @@ -61,6 +61,14 @@ namespace sf::InputStream* stream = static_cast<sf::InputStream*>(user); return stream->tell() >= stream->getSize(); } + + // stb_image callback for constructing a buffer + void bufferFromCallback(void* context, void* data, int size) + { + sf::Uint8* source = static_cast<sf::Uint8*>(data); + std::vector<sf::Uint8>* dest = static_cast<std::vector<sf::Uint8>*>(context); + std::copy(source, source + size, std::back_inserter(*dest)); + } } @@ -106,13 +114,13 @@ bool ImageLoader::loadImageFromFile(const std::string& filename, std::vector<Uin if (ptr) { // Assign the image properties - size.x = width; - size.y = height; + size.x = static_cast<unsigned int>(width); + size.y = static_cast<unsigned int>(height); - if (width && height) + if (width > 0 && height > 0) { // Copy the loaded pixels to the pixel buffer - pixels.resize(width * height * 4); + pixels.resize(static_cast<std::size_t>(width * height * 4)); memcpy(&pixels[0], ptr, pixels.size()); } @@ -150,13 +158,13 @@ bool ImageLoader::loadImageFromMemory(const void* data, std::size_t dataSize, st if (ptr) { // Assign the image properties - size.x = width; - size.y = height; + size.x = static_cast<unsigned int>(width); + size.y = static_cast<unsigned int>(height); - if (width && height) + if (width > 0 && height > 0) { // Copy the loaded pixels to the pixel buffer - pixels.resize(width * height * 4); + pixels.resize(static_cast<std::size_t>(width * height * 4)); memcpy(&pixels[0], ptr, pixels.size()); } @@ -205,13 +213,13 @@ bool ImageLoader::loadImageFromStream(InputStream& stream, std::vector<Uint8>& p if (ptr) { // Assign the image properties - size.x = width; - size.y = height; + size.x = static_cast<unsigned int>(width); + size.y = static_cast<unsigned int>(height); if (width && height) { // Copy the loaded pixels to the pixel buffer - pixels.resize(width * height * 4); + pixels.resize(static_cast<std::size_t>(width * height * 4)); memcpy(&pixels[0], ptr, pixels.size()); } @@ -241,29 +249,30 @@ bool ImageLoader::saveImageToFile(const std::string& filename, const std::vector // Extract the extension const std::size_t dot = filename.find_last_of('.'); const std::string extension = dot != std::string::npos ? toLower(filename.substr(dot + 1)) : ""; + const Vector2i convertedSize = Vector2i(size); if (extension == "bmp") { // BMP format - if (stbi_write_bmp(filename.c_str(), size.x, size.y, 4, &pixels[0])) + if (stbi_write_bmp(filename.c_str(), convertedSize.x, convertedSize.y, 4, &pixels[0])) return true; } else if (extension == "tga") { // TGA format - if (stbi_write_tga(filename.c_str(), size.x, size.y, 4, &pixels[0])) + if (stbi_write_tga(filename.c_str(), convertedSize.x, convertedSize.y, 4, &pixels[0])) return true; } else if (extension == "png") { // PNG format - if (stbi_write_png(filename.c_str(), size.x, size.y, 4, &pixels[0], 0)) + if (stbi_write_png(filename.c_str(), convertedSize.x, convertedSize.y, 4, &pixels[0], 0)) return true; } else if (extension == "jpg" || extension == "jpeg") { // JPG format - if (stbi_write_jpg(filename.c_str(), size.x, size.y, 4, &pixels[0], 90)) + if (stbi_write_jpg(filename.c_str(), convertedSize.x, convertedSize.y, 4, &pixels[0], 90)) return true; } } @@ -272,6 +281,47 @@ bool ImageLoader::saveImageToFile(const std::string& filename, const std::vector return false; } +//////////////////////////////////////////////////////////// +bool ImageLoader::saveImageToMemory(const std::string& format, std::vector<sf::Uint8>& output, const std::vector<Uint8>& pixels, const Vector2u& size) +{ + // Make sure the image is not empty + if (!pixels.empty() && (size.x > 0) && (size.y > 0)) + { + // Choose function based on format + + std::string specified = toLower(format); + const Vector2i convertedSize = Vector2i(size); + + if (specified == "bmp") + { + // BMP format + if (stbi_write_bmp_to_func(&bufferFromCallback, &output, convertedSize.x, convertedSize.y, 4, &pixels[0])) + return true; + } + else if (specified == "tga") + { + // TGA format + if (stbi_write_tga_to_func(&bufferFromCallback, &output, convertedSize.x, convertedSize.y, 4, &pixels[0])) + return true; + } + else if (specified == "png") + { + // PNG format + if (stbi_write_png_to_func(&bufferFromCallback, &output, convertedSize.x, convertedSize.y, 4, &pixels[0], 0)) + return true; + } + else if (specified == "jpg" || specified == "jpeg") + { + // JPG format + if (stbi_write_jpg_to_func(&bufferFromCallback, &output, convertedSize.x, convertedSize.y, 4, &pixels[0], 90)) + return true; + } + } + + err() << "Failed to save image with format \"" << format << "\"" << std::endl; + return false; +} + } // namespace priv } // namespace sf |