diff --git a/include/SFML/Graphics/Image.hpp b/include/SFML/Graphics/Image.hpp index 46270da79..e9c5cf269 100644 --- a/include/SFML/Graphics/Image.hpp +++ b/include/SFML/Graphics/Image.hpp @@ -33,6 +33,7 @@ #include #include +#include #include #include @@ -148,15 +149,15 @@ public: /// This function fails if the image is empty, or if /// the format was invalid. /// - /// \param output Buffer to fill with encoded data /// \param format Encoding format to use /// - /// \return True if saving was successful + /// \return Buffer with encoded data if saving was successful, + /// otherwise std::nullopt /// /// \see create, loadFromFile, loadFromMemory, saveToFile /// //////////////////////////////////////////////////////////// - [[nodiscard]] bool saveToMemory(std::vector& output, std::string_view format) const; + [[nodiscard]] std::optional> saveToMemory(std::string_view format) const; //////////////////////////////////////////////////////////// /// \brief Return the size (width and height) of the image diff --git a/src/SFML/Graphics/Image.cpp b/src/SFML/Graphics/Image.cpp index a6167235f..f8162acd6 100644 --- a/src/SFML/Graphics/Image.cpp +++ b/src/SFML/Graphics/Image.cpp @@ -141,9 +141,9 @@ bool Image::saveToFile(const std::filesystem::path& filename) const } //////////////////////////////////////////////////////////// -bool Image::saveToMemory(std::vector& output, std::string_view format) const +std::optional> Image::saveToMemory(std::string_view format) const { - return priv::ImageLoader::getInstance().saveImageToMemory(std::string(format), output, m_pixels, m_size); + return priv::ImageLoader::getInstance().saveImageToMemory(std::string(format), m_pixels, m_size); } diff --git a/src/SFML/Graphics/ImageLoader.cpp b/src/SFML/Graphics/ImageLoader.cpp index 736849d35..70a4c854d 100644 --- a/src/SFML/Graphics/ImageLoader.cpp +++ b/src/SFML/Graphics/ImageLoader.cpp @@ -282,47 +282,47 @@ bool ImageLoader::saveImageToFile(const std::filesystem::path& filename, } //////////////////////////////////////////////////////////// -bool ImageLoader::saveImageToMemory(const std::string& format, - std::vector& output, - const std::vector& pixels, - const Vector2u& size) +std::optional> ImageLoader::saveImageToMemory(const std::string& format, + const std::vector& 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 - const std::string specified = toLower(format); const Vector2i convertedSize = Vector2i(size); + std::vector buffer; + if (specified == "bmp") { // BMP format - if (stbi_write_bmp_to_func(&bufferFromCallback, &output, convertedSize.x, convertedSize.y, 4, pixels.data())) - return true; + if (stbi_write_bmp_to_func(bufferFromCallback, &buffer, convertedSize.x, convertedSize.y, 4, pixels.data())) + return buffer; } else if (specified == "tga") { // TGA format - if (stbi_write_tga_to_func(&bufferFromCallback, &output, convertedSize.x, convertedSize.y, 4, pixels.data())) - return true; + if (stbi_write_tga_to_func(&bufferFromCallback, &buffer, convertedSize.x, convertedSize.y, 4, pixels.data())) + return buffer; } else if (specified == "png") { // PNG format - if (stbi_write_png_to_func(&bufferFromCallback, &output, convertedSize.x, convertedSize.y, 4, pixels.data(), 0)) - return true; + if (stbi_write_png_to_func(&bufferFromCallback, &buffer, convertedSize.x, convertedSize.y, 4, pixels.data(), 0)) + return buffer; } else if (specified == "jpg" || specified == "jpeg") { // JPG format - if (stbi_write_jpg_to_func(&bufferFromCallback, &output, convertedSize.x, convertedSize.y, 4, pixels.data(), 90)) - return true; + if (stbi_write_jpg_to_func(&bufferFromCallback, &buffer, convertedSize.x, convertedSize.y, 4, pixels.data(), 90)) + return buffer; } } err() << "Failed to save image with format " << std::quoted(format) << std::endl; - return false; + return std::nullopt; } } // namespace sf::priv diff --git a/src/SFML/Graphics/ImageLoader.hpp b/src/SFML/Graphics/ImageLoader.hpp index 6f1c67cb3..0f891fe0d 100644 --- a/src/SFML/Graphics/ImageLoader.hpp +++ b/src/SFML/Graphics/ImageLoader.hpp @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -122,17 +123,15 @@ public: /// \brief Save an array of pixels as an encoded image buffer /// /// \param format Must be "bmp", "png", "tga" or "jpg"/"jpeg". - /// \param output Buffer to fill with encoded data /// \param pixels Array of pixels to save to image /// \param size Size of image to save, in pixels /// - /// \return True if saving was successful + /// \return Buffer with encoded data if saving was successful /// //////////////////////////////////////////////////////////// - bool saveImageToMemory(const std::string& format, - std::vector& output, - const std::vector& pixels, - const Vector2u& size); + std::optional> saveImageToMemory(const std::string& format, + const std::vector& pixels, + const Vector2u& size); private: //////////////////////////////////////////////////////////// diff --git a/test/Graphics/Image.test.cpp b/test/Graphics/Image.test.cpp index 15395c5e5..29c2cc95e 100644 --- a/test/Graphics/Image.test.cpp +++ b/test/Graphics/Image.test.cpp @@ -207,48 +207,44 @@ TEST_CASE("[Graphics] sf::Image") SECTION("saveToMemory()") { - sf::Image image; - std::vector output; + sf::Image image; SECTION("Empty") { - CHECK(!image.saveToMemory(output, "test.jpg")); - CHECK(output.empty()); + CHECK(!image.saveToMemory("test.jpg")); } SECTION("Invalid size") { image.create({10, 0}, sf::Color::Magenta); - CHECK(!image.saveToMemory(output, "test.jpg")); - CHECK(output.empty()); + CHECK(!image.saveToMemory("test.jpg")); image.create({0, 10}, sf::Color::Magenta); - CHECK(!image.saveToMemory(output, "test.jpg")); - CHECK(output.empty()); + CHECK(!image.saveToMemory("test.jpg")); } image.create({16, 16}, sf::Color::Magenta); SECTION("No extension") { - CHECK(!image.saveToMemory(output, "")); - CHECK(output.empty()); + CHECK(!image.saveToMemory("")); } SECTION("Invalid extension") { - CHECK(!image.saveToMemory(output, ".")); - CHECK(output.empty()); - CHECK(!image.saveToMemory(output, "gif")); - CHECK(output.empty()); - CHECK(!image.saveToMemory(output, ".jpg")); // Supposed to be "jpg" - CHECK(output.empty()); + CHECK(!image.saveToMemory(".")); + CHECK(!image.saveToMemory("gif")); + CHECK(!image.saveToMemory(".jpg")); // Supposed to be "jpg" } SECTION("Successful save") { + std::optional> maybeOutput; + SECTION("To bmp") { - REQUIRE(image.saveToMemory(output, "bmp")); + maybeOutput = image.saveToMemory("bmp"); + REQUIRE(maybeOutput.has_value()); + const auto& output = *maybeOutput; REQUIRE(output.size() == 1146); CHECK(output[0] == 66); CHECK(output[1] == 77); @@ -262,7 +258,9 @@ TEST_CASE("[Graphics] sf::Image") SECTION("To tga") { - REQUIRE(image.saveToMemory(output, "tga")); + maybeOutput = image.saveToMemory("tga"); + REQUIRE(maybeOutput.has_value()); + const auto& output = *maybeOutput; REQUIRE(output.size() == 98); CHECK(output[0] == 0); CHECK(output[1] == 0); @@ -272,7 +270,9 @@ TEST_CASE("[Graphics] sf::Image") SECTION("To png") { - REQUIRE(image.saveToMemory(output, "png")); + maybeOutput = image.saveToMemory("png"); + REQUIRE(maybeOutput.has_value()); + const auto& output = *maybeOutput; REQUIRE(output.size() == 92); CHECK(output[0] == 137); CHECK(output[1] == 80);