From 23ab8cc08d2d6281ef56c184f1e1e905e70a2a22 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sun, 8 Aug 2021 10:48:55 +0200 Subject: Matrix: fix thumbnail upload of small thumbnails, fix small thumbnail creation if webp --- src/AsyncImageLoader.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 6 deletions(-) (limited to 'src/AsyncImageLoader.cpp') diff --git a/src/AsyncImageLoader.cpp b/src/AsyncImageLoader.cpp index ccf9f42..a871078 100644 --- a/src/AsyncImageLoader.cpp +++ b/src/AsyncImageLoader.cpp @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include #include @@ -24,7 +26,7 @@ namespace QuickMedia { 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 create_thumbnail(const Path &thumbnail_path, const Path &thumbnail_path_resized, sf::Vector2i resize_target_size, ContentType content_type, bool symlink_if_no_resize) { Path input_path = thumbnail_path; if(content_type == ContentType::IMAGE_WEBP) { @@ -62,10 +64,47 @@ namespace QuickMedia { 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) { - int res = symlink(input_path.data.c_str(), result_path_tmp.data.c_str()); - if(res == -1 && errno != EEXIST) { - fprintf(stderr, "Failed to save %s\n", thumbnail_path_resized.data.c_str()); - _exit(1); + if(content_type == ContentType::IMAGE_WEBP) { + if(rename_atomic(input_path.data.c_str(), thumbnail_path_resized.data.c_str()) == 0) + _exit(0); + else + _exit(1); + } else if(symlink_if_no_resize) { + int res = symlink(thumbnail_path.data.c_str(), result_path_tmp.data.c_str()); + if(res == -1 && errno != EEXIST) { + fprintf(stderr, "Failed to symlink %s to %s\n", thumbnail_path_resized.data.c_str(), thumbnail_path.data.c_str()); + _exit(1); + } + } else { + // TODO: When mac is supported (or other OS than linux), then fix this for them. Mac for example needs fcopyfile instead of sendfile + int input_file = open(thumbnail_path.data.c_str(), O_RDONLY); + if(input_file == -1) { + fprintf(stderr, "Failed to save %s\n", thumbnail_path_resized.data.c_str()); + _exit(1); + } + + int output_file = creat(result_path_tmp.data.c_str(), 0660); + if(output_file == -1) { + fprintf(stderr, "Failed to save %s\n", thumbnail_path_resized.data.c_str()); + _exit(1); + } + + off_t bytes_copied = 0; + struct stat file_stat; + memset(&file_stat, 0, sizeof(file_stat)); + if(fstat(input_file, &file_stat) == -1) { + fprintf(stderr, "Failed to save %s\n", thumbnail_path_resized.data.c_str()); + _exit(1); + } + + // No need to retry, small files + if(sendfile(output_file, input_file, &bytes_copied, file_stat.st_size) == -1) { + fprintf(stderr, "Failed to save %s\n", thumbnail_path_resized.data.c_str()); + _exit(1); + } + + close(input_file); + close(output_file); } } else { sf::Vector2u clamped_size = clamp_to_size(image.getSize(), sf::Vector2u(resize_target_size.x, resize_target_size.y)); @@ -121,7 +160,7 @@ namespace QuickMedia { return; } - if(create_thumbnail(thumbnail_path, thumbnail_path_resized, resize_target_size, file_analyzer.get_content_type())) { + if(create_thumbnail(thumbnail_path, thumbnail_path_resized, resize_target_size, file_analyzer.get_content_type(), true)) { load_image_from_file(*thumbnail_data->image, thumbnail_path_resized.data); } else { load_image_from_file(*thumbnail_data->image, thumbnail_path.data); @@ -198,6 +237,7 @@ namespace QuickMedia { Path thumbnail_path = get_cache_dir().join("thumbnails").join(sha256.getHash()); if(local) { struct stat file_stat; + memset(&file_stat, 0, sizeof(file_stat)); if(stat(url.c_str(), &file_stat) != 0 || !S_ISREG(file_stat.st_mode)) { thumbnail_data->image = std::make_unique(); thumbnail_data->loading_state = LoadingState::FINISHED_LOADING; -- cgit v1.2.3