aboutsummaryrefslogtreecommitdiff
path: root/src/AsyncImageLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/AsyncImageLoader.cpp')
-rw-r--r--src/AsyncImageLoader.cpp65
1 files changed, 37 insertions, 28 deletions
diff --git a/src/AsyncImageLoader.cpp b/src/AsyncImageLoader.cpp
index 4661960..c1d4aab 100644
--- a/src/AsyncImageLoader.cpp
+++ b/src/AsyncImageLoader.cpp
@@ -3,7 +3,6 @@
#include "../include/Program.hpp"
#include "../include/ImageUtils.hpp"
#include "../include/Scale.hpp"
-#include "../include/SfmlFixes.hpp"
#include "../include/Utils.hpp"
#include "../external/hash-library/sha256.h"
@@ -22,13 +21,16 @@
#define STB_IMAGE_RESIZE_IMPLEMENTATION
#include "../external/stb/stb_image_resize.h"
+#define STB_IMAGE_WRITE_IMPLEMENTATION
+#include "../external/stb/stb_image_write.h"
+
namespace QuickMedia {
static bool webp_to_png(const Path &thumbnail_path, const Path &destination_path) {
const char *args[] = { "ffmpeg", "-y", "-v", "quiet", "-i", thumbnail_path.data.c_str(), "--", destination_path.data.c_str(), nullptr};
return exec_program(args, nullptr, nullptr) == 0;
}
- bool create_thumbnail(const Path &thumbnail_path, const Path &thumbnail_path_resized, sf::Vector2i resize_target_size, ContentType content_type, bool symlink_if_no_resize) {
+ bool create_thumbnail(const Path &thumbnail_path, const Path &thumbnail_path_resized, mgl::vec2i resize_target_size, ContentType content_type, bool symlink_if_no_resize) {
Path input_path = thumbnail_path;
if(content_type == ContentType::IMAGE_WEBP) {
@@ -56,8 +58,8 @@ namespace QuickMedia {
if(getppid() != parent_pid)
_exit(127);
- sf::Image image;
- if(!image.loadFromFile(input_path.data) || image.getSize().x == 0 || image.getSize().y == 0) {
+ mgl::Image image;
+ if(!image.load_from_file(input_path.data.c_str()) || image.get_size().x == 0 || image.get_size().y == 0) {
fprintf(stderr, "Failed to load %s\n", input_path.data.c_str());
_exit(1);
}
@@ -65,7 +67,7 @@ namespace QuickMedia {
Path result_path_tmp = thumbnail_path_resized;
result_path_tmp.append(".tmp.png");
- if(image.getSize().x <= (unsigned int)resize_target_size.x && image.getSize().y <= (unsigned int)resize_target_size.y) {
+ if(image.get_size().x <= resize_target_size.x && image.get_size().y <= resize_target_size.y) {
if(content_type == ContentType::IMAGE_WEBP) {
if(rename_atomic(input_path.data.c_str(), thumbnail_path_resized.data.c_str()) == 0)
_exit(0);
@@ -109,17 +111,24 @@ namespace QuickMedia {
close(output_file);
}
} else {
- sf::Vector2u clamped_size = clamp_to_size(image.getSize(), sf::Vector2u(resize_target_size.x, resize_target_size.y));
- unsigned char *output_pixels = new unsigned char[clamped_size.x * clamped_size.y * 4];
- stbir_resize_uint8(image.getPixelsPtr(), image.getSize().x, image.getSize().y, 0, output_pixels, clamped_size.x, clamped_size.y, 0, 4);
-
- // TODO: Remove this and use stb write to remove this unecessary extra copy of the data and write the data directly to file after converting it to png
- sf::Image destination_image;
- destination_image.create(clamped_size.x, clamped_size.y, output_pixels);
- if(!destination_image.saveToFile(result_path_tmp.data)) {
- fprintf(stderr, "Failed to save %s\n", thumbnail_path_resized.data.c_str());
- _exit(1);
+ mgl::vec2i clamped_size = clamp_to_size(image.get_size(), mgl::vec2i(resize_target_size.x, resize_target_size.y));
+ unsigned char *output_pixels = new unsigned char[clamped_size.x * clamped_size.y * image.get_num_channels()];
+ stbir_resize_uint8(image.data(), image.get_size().x, image.get_size().y, 0, output_pixels, clamped_size.x, clamped_size.y, 0, image.get_num_channels());
+
+ if(image.get_num_channels() == 4) {
+ if(!stbi_write_png(result_path_tmp.data.c_str(), clamped_size.x, clamped_size.y, 4, output_pixels, 0)) {
+ fprintf(stderr, "Failed to save %s\n", thumbnail_path_resized.data.c_str());
+ _exit(1);
+ }
+ } else {
+ if(!stbi_write_jpg(result_path_tmp.data.c_str(), clamped_size.x, clamped_size.y, image.get_num_channels(), output_pixels, 0)) {
+ fprintf(stderr, "Failed to save %s\n", thumbnail_path_resized.data.c_str());
+ _exit(1);
+ }
}
+
+ // TODO: Resize and save to dxt format which can be loaded faster, uses less memory during loading (since no conversion is needed to upload to gpu),
+ // it uses less memory while in gpu (because its in dxt compressed format) and it gives better rendering performance because of compressed image = smaller = better cache utilization.
}
if(rename_atomic(result_path_tmp.data.c_str(), thumbnail_path_resized.data.c_str()) == 0)
@@ -147,11 +156,11 @@ namespace QuickMedia {
return true;
}
- void AsyncImageLoader::load_create_thumbnail(const Path &thumbnail_path, const Path &thumbnail_path_resized, ThumbnailData *thumbnail_data, sf::Vector2i resize_target_size) {
+ void AsyncImageLoader::load_create_thumbnail(const Path &thumbnail_path, const Path &thumbnail_path_resized, ThumbnailData *thumbnail_data, mgl::vec2i resize_target_size) {
FileAnalyzer file_analyzer;
if(!file_analyzer.load_file(thumbnail_path.data.c_str(), false)) {
fprintf(stderr, "Failed to convert %s to a thumbnail\n", thumbnail_path.data.c_str());
- thumbnail_data->image = std::make_unique<sf::Image>();
+ thumbnail_data->image = std::make_unique<mgl::Image>();
thumbnail_data->loading_state = LoadingState::FINISHED_LOADING;
return;
}
@@ -161,7 +170,7 @@ namespace QuickMedia {
thumbnail_data->loading_state = LoadingState::READY_TO_LOAD;
} else {
fprintf(stderr, "Failed to get first frame of %s\n", thumbnail_path.data.c_str());
- thumbnail_data->image = std::make_unique<sf::Image>();
+ thumbnail_data->image = std::make_unique<mgl::Image>();
thumbnail_data->loading_state = LoadingState::FINISHED_LOADING;
}
return;
@@ -171,7 +180,7 @@ namespace QuickMedia {
thumbnail_data->loading_state = LoadingState::READY_TO_LOAD;
} else {
fprintf(stderr, "Failed to convert %s to a thumbnail\n", thumbnail_path.data.c_str());
- thumbnail_data->image = std::make_unique<sf::Image>();
+ thumbnail_data->image = std::make_unique<mgl::Image>();
thumbnail_data->loading_state = LoadingState::FINISHED_LOADING;
}
}
@@ -190,7 +199,7 @@ namespace QuickMedia {
if(get_file_type(thumbnail_path_resized) == FileType::REGULAR) {
fprintf(stderr, "Loaded %s from thumbnail cache\n", thumbnail_path_resized.data.c_str());
- thumbnail_load_data.thumbnail_data->image = std::make_unique<sf::Image>();
+ thumbnail_load_data.thumbnail_data->image = std::make_unique<mgl::Image>();
thumbnail_load_data.thumbnail_data->loading_state = LoadingState::READY_TO_LOAD;
return;
}
@@ -208,14 +217,14 @@ namespace QuickMedia {
}
static void load_processed_thumbnail(ThumbnailLoadData &thumbnail_load_data) {
- thumbnail_load_data.thumbnail_data->image = std::make_unique<sf::Image>();
+ thumbnail_load_data.thumbnail_data->image = std::make_unique<mgl::Image>();
Path thumbnail_path_resized = thumbnail_load_data.thumbnail_path;
if(thumbnail_load_data.resize_target_size.x != 0 && thumbnail_load_data.resize_target_size.y != 0)
thumbnail_path_resized.append("_" + std::to_string(thumbnail_load_data.resize_target_size.x) + "x" + std::to_string(thumbnail_load_data.resize_target_size.y));
if(get_file_type(thumbnail_path_resized) == FileType::REGULAR) {
- load_image_from_file(*thumbnail_load_data.thumbnail_data->image, thumbnail_path_resized.data);
+ thumbnail_load_data.thumbnail_data->image->load_from_file(thumbnail_path_resized.data.c_str());
thumbnail_load_data.thumbnail_data->loading_state = LoadingState::FINISHED_LOADING;
return;
}
@@ -227,10 +236,10 @@ namespace QuickMedia {
thumbnail_original_path = thumbnail_load_data.thumbnail_path;
if(thumbnail_load_data.resize_target_size.x != 0 && thumbnail_load_data.resize_target_size.y != 0) {
- load_image_from_file(*thumbnail_load_data.thumbnail_data->image, thumbnail_path_resized.data);
+ thumbnail_load_data.thumbnail_data->image->load_from_file(thumbnail_path_resized.data.c_str());
thumbnail_load_data.thumbnail_data->loading_state = LoadingState::FINISHED_LOADING;
} else {
- load_image_from_file(*thumbnail_load_data.thumbnail_data->image, thumbnail_original_path.data);
+ thumbnail_load_data.thumbnail_data->image->load_from_file(thumbnail_original_path.data.c_str());
thumbnail_load_data.thumbnail_data->loading_state = LoadingState::FINISHED_LOADING;
}
}
@@ -304,12 +313,12 @@ namespace QuickMedia {
return exec_program_pipe(args, read_program) == 0;
}
- bool AsyncImageLoader::load_thumbnail(const std::string &url, bool local, sf::Vector2i resize_target_size, std::shared_ptr<ThumbnailData> thumbnail_data, Path &thumbnail_path) {
+ bool AsyncImageLoader::load_thumbnail(const std::string &url, bool local, mgl::vec2i resize_target_size, std::shared_ptr<ThumbnailData> thumbnail_data, Path &thumbnail_path) {
if(thumbnail_data->loading_state != LoadingState::NOT_LOADED)
return true;
if(url.empty()) {
- thumbnail_data->image = std::make_unique<sf::Image>();
+ thumbnail_data->image = std::make_unique<mgl::Image>();
thumbnail_data->loading_state = LoadingState::FINISHED_LOADING;
return false;
}
@@ -319,7 +328,7 @@ namespace QuickMedia {
memset(&file_stat, 0, sizeof(file_stat));
if(stat(url.c_str(), &file_stat) != 0 || !S_ISREG(file_stat.st_mode)) {
fprintf(stderr, "Failed to load thumbnail %s: no such file\n", url.c_str());
- thumbnail_data->image = std::make_unique<sf::Image>();
+ thumbnail_data->image = std::make_unique<mgl::Image>();
thumbnail_data->loading_state = LoadingState::FINISHED_LOADING;
return false;
}
@@ -357,7 +366,7 @@ namespace QuickMedia {
return true;
}
- std::shared_ptr<ThumbnailData> AsyncImageLoader::get_thumbnail(const std::string &url, bool local, sf::Vector2i resize_target_size) {
+ std::shared_ptr<ThumbnailData> AsyncImageLoader::get_thumbnail(const std::string &url, bool local, mgl::vec2i resize_target_size) {
// TODO: Instead of generating a new hash everytime to access thumbnail, cache the hash of the thumbnail url
auto &thumbnail_data = thumbnails[url];
if(!thumbnail_data)