diff options
Diffstat (limited to 'src/QuickMedia.cpp')
-rw-r--r-- | src/QuickMedia.cpp | 119 |
1 files changed, 111 insertions, 8 deletions
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 75bc027..6db58c9 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -13,6 +13,7 @@ #include "../include/GoogleCaptcha.hpp" #include "../include/Notification.hpp" #include "../include/ImageViewer.hpp" +#include "../include/ImageUtils.hpp" #include <cppcodec/base64_rfc4648.hpp> #include <SFML/Graphics/RectangleShape.hpp> @@ -68,6 +69,11 @@ static int get_monitor_max_hz(Display *display) { return 60; } +static void get_screen_resolution(Display *display, int *width, int *height) { + *width = DefaultScreenOfDisplay(display)->width; + *height = DefaultScreenOfDisplay(display)->height; +} + static bool has_gl_ext(Display *disp, const char *ext) { const char *extensions = glXQueryExtensionsString(disp, DefaultScreen(disp)); if(!extensions) @@ -193,6 +199,14 @@ namespace QuickMedia { } Program::~Program() { + running = false; + if(upscale_images) { + { + std::unique_lock<std::mutex> lock(image_upscale_mutex); + image_upscale_cv.notify_one(); + } + image_upscale_thead.join(); + } delete related_media_body; delete body; delete current_plugin; @@ -223,6 +237,7 @@ namespace QuickMedia { fprintf(stderr, " plugin The plugin to use. Should be either 4chan, manganelo, mangatown, mangadex, pornhub, youtube or dmenu\n"); fprintf(stderr, " --tor Use tor. Disabled by default\n"); fprintf(stderr, " --use-system-mpv-config Use system mpv config instead of no config. Disabled by default\n"); + fprintf(stderr, " --upscale-images Upscale low-resolution manga pages using waifu2x-ncnn-vulkan. Disabled by default\n"); fprintf(stderr, " -p Change the placeholder text for dmenu\n"); fprintf(stderr, "EXAMPLES:\n"); fprintf(stderr, "QuickMedia manganelo\n"); @@ -292,6 +307,8 @@ namespace QuickMedia { use_tor = true; } else if(strcmp(argv[i], "--use-system-mpv-config") == 0) { use_system_mpv_config = true; + } else if(strcmp(argv[i], "--upscale-images") == 0) { + upscale_images = true; } else if(strcmp(argv[i], "-p") == 0) { if(i < argc - 1) { search_placeholder = argv[i + 1]; @@ -309,6 +326,51 @@ namespace QuickMedia { return -2; } + if(upscale_images) { + if(!current_plugin->is_manga()) { + fprintf(stderr, "Option --upscale-images is only valid for manganelo, mangatown and mangadex\n"); + return -2; + } + + if(!is_program_executable_by_name("waifu2x-ncnn-vulkan")) { + fprintf(stderr, "waifu2x-ncnn-vulkan needs to be installed (and accessible from PATH environment variable) when using the --upscale-images option\n"); + return -2; + } + + running = true; + image_upscale_thead = std::thread([this]{ + CopyOp copy_op; + while(running) { + { + std::unique_lock<std::mutex> lock(image_upscale_mutex); + while(images_to_upscale.empty() && running) image_upscale_cv.wait(lock); + if(!running) + break; + copy_op = images_to_upscale.front(); + images_to_upscale.pop_front(); + } + + Path tmp_file = copy_op.source; + tmp_file.append(".tmp.jpg"); + + fprintf(stderr, "Upscaling %s\n", copy_op.source.data.c_str()); + const char *args[] = { "waifu2x-ncnn-vulkan", "-i", copy_op.source.data.c_str(), "-o", tmp_file.data.c_str(), nullptr }; + if(exec_program(args, nullptr, nullptr) != 0) { + fprintf(stderr, "Warning: failed to upscale %s with waifu2x-ncnn-vulkan\n", copy_op.source.data.c_str()); + // No conversion, but we need the file to have the destination name to see that the operation completed (and read it) + if(rename(copy_op.source.data.c_str(), copy_op.destination.data.c_str()) != 0) + perror(tmp_file.data.c_str()); + continue; + } + + if(rename(tmp_file.data.c_str(), copy_op.destination.data.c_str()) != 0) + perror(tmp_file.data.c_str()); + } + }); + } else { + running = true; + } + current_plugin->use_tor = use_tor; window.setTitle("QuickMedia - " + current_plugin->name); @@ -1828,6 +1890,7 @@ namespace QuickMedia { } } + // TODO: Cancel download when navigating to another non-manga page void Program::download_chapter_images_if_needed(Manga *image_plugin) { if(downloading_chapter_url == images_url) return; @@ -1910,10 +1973,35 @@ namespace QuickMedia { return false; } - if(rename(image_filepath_tmp.data.c_str(), image_filepath.data.c_str()) != 0) { - perror("rename"); - show_notification("Storage", "Failed to save image to file: " + image_filepath_tmp.data, Urgency::CRITICAL); - return false; + bool rename_immediately = true; + if(upscale_images) { + int screen_width, screen_height; + get_screen_resolution(disp, &screen_width, &screen_height); + + int image_width, image_height; + if(image_get_resolution(image_filepath_tmp, &image_width, &image_height)) { + if(image_height < screen_height * 0.75) { + rename_immediately = false; + CopyOp copy_op; + copy_op.source = image_filepath_tmp; + copy_op.destination = image_filepath; + std::unique_lock<std::mutex> lock(image_upscale_mutex); + images_to_upscale.push_back(std::move(copy_op)); + image_upscale_cv.notify_one(); + } else { + fprintf(stderr, "Info: not upscaling %s because the file is already large on your monitor (screen height: %d, image height: %d)\n", image_filepath_tmp.data.c_str(), screen_height, image_height); + } + } else { + fprintf(stderr, "Warning: failed to upscale %s because QuickMedia failed to recognize the resolution of the image\n", image_filepath_tmp.data.c_str()); + } + } + + if(rename_immediately) { + if(rename(image_filepath_tmp.data.c_str(), image_filepath.data.c_str()) != 0) { + perror(image_filepath_tmp.data.c_str()); + show_notification("Storage", "Failed to save image to file: " + image_filepath.data, Urgency::CRITICAL); + return false; + } } return true; @@ -1922,6 +2010,7 @@ namespace QuickMedia { } void Program::image_page() { + image_download_cancel = false; search_bar->onTextUpdateCallback = nullptr; search_bar->onTextSubmitCallback = nullptr; @@ -2024,25 +2113,25 @@ namespace QuickMedia { if(event.key.code == sf::Keyboard::Up) { if(image_index > 0) { --image_index; - return; + goto end_of_images_page; } else if(image_index == 0 && body->get_selected_item() < (int)body->items.size() - 1) { // TODO: Make this work if the list is sorted differently than from newest to oldest. body->filter_search_fuzzy(""); body->select_next_item(); select_episode(body->items[body->get_selected_item()].get(), true); image_index = 99999; // Start at the page that shows we are at the end of the chapter - return; + goto end_of_images_page; } } else if(event.key.code == sf::Keyboard::Down) { if(image_index < num_images) { ++image_index; - return; + goto end_of_images_page; } else if(image_index == num_images && body->get_selected_item() > 0) { // TODO: Make this work if the list is sorted differently than from newest to oldest. body->filter_search_fuzzy(""); body->select_previous_item(); select_episode(body->items[body->get_selected_item()].get(), true); - return; + goto end_of_images_page; } } else if(event.key.code == sf::Keyboard::Escape) { current_page = Page::EPISODE_LIST; @@ -2112,9 +2201,17 @@ namespace QuickMedia { window.display(); } + + end_of_images_page: + if(current_page != Page::IMAGES && current_page != Page::IMAGES_CONTINUOUS) { + image_download_cancel = true; + std::unique_lock<std::mutex> lock(image_upscale_mutex); + images_to_upscale.clear(); + } } void Program::image_continuous_page() { + image_download_cancel = false; search_bar->onTextUpdateCallback = nullptr; search_bar->onTextSubmitCallback = nullptr; @@ -2182,6 +2279,12 @@ namespace QuickMedia { } } } + + if(current_page != Page::IMAGES && current_page != Page::IMAGES_CONTINUOUS) { + image_download_cancel = true; + std::unique_lock<std::mutex> lock(image_upscale_mutex); + images_to_upscale.clear(); + } } void Program::content_list_page() { |