aboutsummaryrefslogtreecommitdiff
path: root/src/Cache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Cache.cpp')
-rw-r--r--src/Cache.cpp51
1 files changed, 47 insertions, 4 deletions
diff --git a/src/Cache.cpp b/src/Cache.cpp
index 2a09591..77ba515 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -14,6 +14,7 @@
#include <sibs/SafeSerializer.hpp>
#include <sibs/SafeDeserializer.hpp>
#include <libpreview.h>
+#include <gd.h>
#if OS_FAMILY == OS_FAMILY_POSIX
#include <pwd.h>
@@ -119,8 +120,42 @@ namespace dchat
}
fileReplace(getDchatDir() / "binds", StringView((const char*)serializer.getBuffer().data(), serializer.getBuffer().size()));
}
+
+ static bool downscaleImage(const boost::filesystem::path &filepath, void *data, const int size, const int newWidth, const int newHeight)
+ {
+ gdImagePtr imgPtr = gdImageCreateFromPngPtr(size, data);
+ if(!imgPtr)
+ return false;
+
+ int width = gdImageSX(imgPtr);
+ if(width < newWidth)
+ {
+ gdImageDestroy(imgPtr);
+ return false;
+ }
+
+ int height = gdImageSX(imgPtr);
+ if(height < newHeight)
+ {
+ gdImageDestroy(imgPtr);
+ return false;
+ }
+
+ gdImageSetInterpolationMethod(imgPtr, GD_BILINEAR_FIXED);
+ gdImagePtr newImgPtr = gdImageScale(imgPtr, newWidth, newHeight);
+ if(!newImgPtr)
+ {
+ gdImageDestroy(imgPtr);
+ return false;
+ }
+
+ bool success = (gdImageFile(newImgPtr, filepath.c_str()) == 0);
+ gdImageDestroy(imgPtr);
+ gdImageDestroy(newImgPtr);
+ return success;
+ }
- static ContentByUrlResult loadImageFromFile(const boost::filesystem::path &filepath)
+ static ContentByUrlResult loadImageFromFile(const boost::filesystem::path &filepath, bool loadFromCache)
{
StringView fileContent;
try
@@ -147,8 +182,16 @@ namespace dchat
}
else
{
+ if(!loadFromCache)
+ {
+ if(!downscaleImage(filepath, (void*)fileContent.data, fileContent.size, 100, 100))
+ {
+ fprintf(stderr, "Failed to resize image: %s, using original file\n", filepath.c_str());
+ }
+ }
+
sf::Texture *texture = new sf::Texture();
- if(texture->loadFromMemory(fileContent.data, fileContent.size))
+ if(texture->loadFromFile(filepath.c_str()))
{
delete[] fileContent.data;
fileContent.data = nullptr;
@@ -213,7 +256,7 @@ namespace dchat
}
else
{
- contentByUrlResult = loadImageFromFile(filepath);
+ contentByUrlResult = loadImageFromFile(filepath, false);
contentByUrlResult.lastAccessed = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now().time_since_epoch()).count();
if(contentByUrlResult.type == ContentByUrlResult::Type::CACHED)
{
@@ -350,7 +393,7 @@ namespace dchat
}
// TODO: Do not load content in this thread. Return LOADING status and load it in another thread, because with a lot of images, chat can freeze
- ContentByUrlResult contentByUrlResult = loadImageFromFile(filepath);
+ ContentByUrlResult contentByUrlResult = loadImageFromFile(filepath, true);
if(contentByUrlResult.type == ContentByUrlResult::Type::CACHED)
{
contentByUrlResult.lastAccessed = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now().time_since_epoch()).count();