summaryrefslogtreecommitdiff
path: root/src/SFML/Graphics/ImageLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/SFML/Graphics/ImageLoader.cpp')
-rw-r--r--src/SFML/Graphics/ImageLoader.cpp86
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