Remove output parameter from sf::Image::saveToMemory

This commit is contained in:
Chris Thrasher 2023-10-26 16:23:27 -06:00
parent 0fcd1dd0f1
commit 5cf740fd93
5 changed files with 44 additions and 44 deletions

View File

@ -33,6 +33,7 @@
#include <SFML/Graphics/Rect.hpp>
#include <filesystem>
#include <optional>
#include <string_view>
#include <vector>
@ -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<std::uint8_t>& output, std::string_view format) const;
[[nodiscard]] std::optional<std::vector<std::uint8_t>> saveToMemory(std::string_view format) const;
////////////////////////////////////////////////////////////
/// \brief Return the size (width and height) of the image

View File

@ -141,9 +141,9 @@ bool Image::saveToFile(const std::filesystem::path& filename) const
}
////////////////////////////////////////////////////////////
bool Image::saveToMemory(std::vector<std::uint8_t>& output, std::string_view format) const
std::optional<std::vector<std::uint8_t>> 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);
}

View File

@ -282,47 +282,47 @@ bool ImageLoader::saveImageToFile(const std::filesystem::path& filename,
}
////////////////////////////////////////////////////////////
bool ImageLoader::saveImageToMemory(const std::string& format,
std::vector<std::uint8_t>& output,
const std::vector<std::uint8_t>& pixels,
const Vector2u& size)
std::optional<std::vector<std::uint8_t>> ImageLoader::saveImageToMemory(const std::string& format,
const std::vector<std::uint8_t>& 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<std::uint8_t> 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

View File

@ -32,6 +32,7 @@
#include <SFML/System/Vector2.hpp>
#include <filesystem>
#include <optional>
#include <string>
#include <vector>
@ -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<std::uint8_t>& output,
const std::vector<std::uint8_t>& pixels,
const Vector2u& size);
std::optional<std::vector<std::uint8_t>> saveImageToMemory(const std::string& format,
const std::vector<std::uint8_t>& pixels,
const Vector2u& size);
private:
////////////////////////////////////////////////////////////

View File

@ -207,48 +207,44 @@ TEST_CASE("[Graphics] sf::Image")
SECTION("saveToMemory()")
{
sf::Image image;
std::vector<std::uint8_t> 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<std::vector<std::uint8_t>> 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);