886 lines
25 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <Commctrl.h>
#include <tchar.h>
#include <string>
#include <thread>
#include <atomic>
#include <chrono>
#include <iostream>
#include <fstream>
#include <boost/filesystem.hpp>
#include <boost/tokenizer.hpp>
#include <boost/foreach.hpp>
#include <boost/math/common_factor_rt.hpp>
#include <opencv2/opencv.hpp>
#include "resource.h"
#include "../common/waifu2x.h"
#include "CDialog.h"
#include "CControl.h"
#include "MiniDump.h"
#define WM_FAILD_CREATE_DIR (WM_APP + 5)
#define WM_ON_WAIFU2X_ERROR (WM_APP + 6)
#define WM_END_THREAD (WM_APP + 7)
const size_t AR_PATH_MAX(1024);
const int MinCommonDivisor = 50;
const int DefaultCommonDivisor = 128;
const char * const CropSizeListName = "crop_size_list.txt";
// http://stackoverflow.com/questions/10167382/boostfilesystem-get-relative-path
boost::filesystem::path relativePath(const boost::filesystem::path &path, const boost::filesystem::path &relative_to)
{
// create absolute paths
boost::filesystem::path p = boost::filesystem::absolute(path);
boost::filesystem::path r = boost::filesystem::absolute(relative_to);
// if root paths are different, return absolute path
if (p.root_path() != r.root_path())
return p;
// initialize relative path
boost::filesystem::path result;
// find out where the two paths diverge
boost::filesystem::path::const_iterator itr_path = p.begin();
boost::filesystem::path::const_iterator itr_relative_to = r.begin();
while (*itr_path == *itr_relative_to && itr_path != p.end() && itr_relative_to != r.end()) {
++itr_path;
++itr_relative_to;
}
// add "../" for each remaining token in relative_to
if (itr_relative_to != r.end()) {
++itr_relative_to;
while (itr_relative_to != r.end()) {
result /= "..";
++itr_relative_to;
}
}
// add remaining path
while (itr_path != p.end()) {
result /= *itr_path;
++itr_path;
}
return result;
}
std::vector<int> CommonDivisorList(const int N)
{
std::vector<int> list;
const int sq = sqrt(N);
for (int i = 1; i <= sq; i++)
{
if (N % i == 0)
list.push_back(i);
}
const int sqs = list.size();
for (int i = 0; i < sqs; i++)
list.push_back(N / list[i]);
std::sort(list.begin(), list.end());
return list;
}
// <20>_<EFBFBD>C<EFBFBD>A<EFBFBD><41><EFBFBD>O<EFBFBD>p
class DialogEvent
{
private:
HWND dh;
std::vector<int> CropSizeList;
std::string input_str;
std::string output_str;
std::string mode;
int noise_level;
double scale_ratio;
std::string process;
std::string outputExt;
std::string inputFileExt;
int crop_size;
int batch_size;
std::vector<std::string> extList;
std::thread processThread;
std::atomic_bool cancelFlag;
std::string autoSetAddName;
bool isLastError;
std::string logMessage;
std::string usedProcess;
std::chrono::system_clock::duration cuDNNCheckTime;
std::chrono::system_clock::duration InitTime;
std::chrono::system_clock::duration ProcessTime;
private:
std::string AddName() const
{
std::string addstr("(" + mode + ")");
if (mode.find("noise") != mode.npos || mode.find("auto_scale") != mode.npos)
addstr += "(Level" + std::to_string(noise_level) + ")";
if (mode.find("scale") != mode.npos)
addstr += "(x" + std::to_string(scale_ratio) + ")";
return addstr;
}
bool SyncMember(const bool NotSyncCropSize)
{
bool ret = true;
{
char buf[AR_PATH_MAX] = "";
GetWindowTextA(GetDlgItem(dh, IDC_EDIT_INPUT), buf, _countof(buf));
buf[_countof(buf) - 1] = '\0';
input_str = buf;
}
{
char buf[AR_PATH_MAX] = "";
GetWindowTextA(GetDlgItem(dh, IDC_EDIT_OUTPUT), buf, _countof(buf));
buf[_countof(buf) - 1] = '\0';
output_str = buf;
}
if (SendMessage(GetDlgItem(dh, IDC_RADIO_MODE_NOISE), BM_GETCHECK, 0, 0))
mode = "noise";
else if (SendMessage(GetDlgItem(dh, IDC_RADIO_MODE_SCALE), BM_GETCHECK, 0, 0))
mode = "scale";
else if (SendMessage(GetDlgItem(dh, IDC_RADIO_MODE_NOISE_SCALE), BM_GETCHECK, 0, 0))
mode = "noise_scale";
else
mode = "auto_scale";
if (SendMessage(GetDlgItem(dh, IDC_RADIONOISE_LEVEL1), BM_GETCHECK, 0, 0))
noise_level = 1;
else
noise_level = 2;
{
char buf[AR_PATH_MAX] = "";
GetWindowTextA(GetDlgItem(dh, IDC_EDIT_SCALE_RATIO), buf, _countof(buf));
buf[_countof(buf) - 1] = '\0';
char *ptr = nullptr;
scale_ratio = strtod(buf, &ptr);
if (!ptr || *ptr != '\0' || scale_ratio <= 0.0)
{
scale_ratio = 2.0;
ret = false;
MessageBox(dh, TEXT("<EFBFBD>g<EFBFBD><EFBFBD><EFBFBD>0.0<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ł<EFBFBD><EFBFBD><EFBFBD><EFBFBD>K<EFBFBD>v<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD>"), TEXT("<EFBFBD>G<EFBFBD><EFBFBD><EFBFBD>["), MB_OK | MB_ICONERROR);
}
}
{
char buf[AR_PATH_MAX] = "";
GetWindowTextA(GetDlgItem(dh, IDC_EDIT_OUT_EXT), buf, _countof(buf));
buf[_countof(buf) - 1] = '\0';
outputExt = buf;
if (outputExt.length() > 0 && outputExt[0] != '.')
outputExt = "." + outputExt;
}
if (SendMessage(GetDlgItem(dh, IDC_RADIO_MODE_CPU), BM_GETCHECK, 0, 0))
process = "cpu";
else
process = "gpu";
{
char buf[AR_PATH_MAX] = "";
GetWindowTextA(GetDlgItem(dh, IDC_EDIT_INPUT_EXT_LIST), buf, _countof(buf));
buf[_countof(buf) - 1] = '\0';
inputFileExt = buf;
// input_extention_list<73>𕶎<EFBFBD><F095B68E><EFBFBD><EFBFBD>̔z<CC94><7A><EFBFBD>ɂ<EFBFBD><C982><EFBFBD>
typedef boost::char_separator<char> char_separator;
typedef boost::tokenizer<char_separator> tokenizer;
char_separator sep(":", "", boost::drop_empty_tokens);
tokenizer tokens(inputFileExt, sep);
for (tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter)
extList.push_back("." + *tok_iter);
}
if (!NotSyncCropSize)
{
char buf[AR_PATH_MAX] = "";
GetWindowTextA(GetDlgItem(dh, IDC_COMBO_CROP_SIZE), buf, _countof(buf));
buf[_countof(buf) - 1] = '\0';
char *ptr = nullptr;
crop_size = strtol (buf, &ptr, 10);
if (!ptr || *ptr != '\0' || crop_size <= 0)
{
crop_size = 128;
ret = false;
MessageBox(dh, TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>T<EFBFBD>C<EFBFBD>Y<EFBFBD><EFBFBD>0<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ł<EFBFBD><EFBFBD><EFBFBD><EFBFBD>K<EFBFBD>v<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD>"), TEXT("<EFBFBD>G<EFBFBD><EFBFBD><EFBFBD>["), MB_OK | MB_ICONERROR);
}
}
return ret;
}
void SetCropSizeList(const boost::filesystem::path &input_path)
{
HWND hcrop = GetDlgItem(dh, IDC_COMBO_CROP_SIZE);
int gcd = 1;
if (boost::filesystem::is_directory(input_path))
{
BOOST_FOREACH(const boost::filesystem::path& p, std::make_pair(boost::filesystem::recursive_directory_iterator(input_path),
boost::filesystem::recursive_directory_iterator()))
{
if (!boost::filesystem::is_directory(p) && std::find(extList.begin(), extList.end(), p.extension().string()) != extList.end())
{
auto mat = cv::imread(p.string(), cv::IMREAD_UNCHANGED);
if (mat.empty())
continue;
auto size = mat.size();
mat.release();
gcd = boost::math::gcd(size.width, size.height);
}
}
}
else
{
auto mat = cv::imread(input_path.string(), cv::IMREAD_UNCHANGED);
if (mat.empty())
return;
auto size = mat.size();
mat.release();
gcd = boost::math::gcd(size.width, size.height);
}
while (SendMessage(hcrop, CB_GETCOUNT, 0, 0) != 0)
SendMessage(hcrop, CB_DELETESTRING, 0, 0);
// <20>ő<EFBFBD><C591><EFBFBD><EFBFBD>񐔂̖񐔂̃<F1909482><CC83>X<EFBFBD>g<EFBFBD>
std::vector<int> list(CommonDivisorList(gcd));
// MinCommonDivisor<6F><72><EFBFBD><EFBFBD><EFBFBD>̖񐔍폜
list.erase(std::remove_if(list.begin(), list.end(), [](const int v)
{
return v < MinCommonDivisor;
}
), list.end());
int mindiff = INT_MAX;
int defaultIndex = 0;
for (int i = 0; i < list.size(); i++)
{
const int n = list[i];
std::string str(std::to_string(n));
SendMessageA(hcrop, CB_ADDSTRING, 0, (LPARAM)str.c_str());
const int diff = abs(DefaultCommonDivisor - n);
if (diff < mindiff)
{
mindiff = diff;
defaultIndex = i;
}
}
if (SendMessageA(hcrop, CB_ADDSTRING, 0, (LPARAM)"-----------------------") == defaultIndex)
defaultIndex = 1;
// CropSizeList<73>̒l<CC92><6C><EFBFBD>lj<EFBFBD><C789><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD>
for (const auto n : CropSizeList)
{
std::string str(std::to_string(n));
SendMessageA(hcrop, CB_ADDSTRING, 0, (LPARAM)str.c_str());
}
if (GetWindowTextLength(hcrop) == 0)
SendMessage(hcrop, CB_SETCURSEL, defaultIndex, 0);
}
void ProcessWaifu2x()
{
const boost::filesystem::path input_path(boost::filesystem::absolute(input_str));
std::vector<std::pair<std::string, std::string>> file_paths;
if (boost::filesystem::is_directory(input_path)) // input_path<74><68><EFBFBD>t<EFBFBD>H<EFBFBD><48><EFBFBD>_<EFBFBD>Ȃ炻<C882>̃f<CC83>B<EFBFBD><42><EFBFBD>N<EFBFBD>g<EFBFBD><67><EFBFBD>ȉ<EFBFBD><C889>̉摜<CC89>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϊ<EFBFBD>
{
boost::filesystem::path output_path(output_str);
output_path = boost::filesystem::absolute(output_path);
if (!boost::filesystem::exists(output_path))
{
if (!boost::filesystem::create_directory(output_path))
{
SendMessage(dh, WM_FAILD_CREATE_DIR, (WPARAM)&output_path, 0);
PostMessage(dh, WM_END_THREAD, 0, 0);
// printf("<22>o<EFBFBD>̓t<CD83>H<EFBFBD><48><EFBFBD>_<EFBFBD>u%s<>v<EFBFBD>̍쐬<CC8D>Ɏ<EFBFBD><C98E>s<EFBFBD><73><EFBFBD>܂<EFBFBD><DC82><EFBFBD>\n", output_path.string().c_str());
return;
}
}
// <20>ϊ<EFBFBD><CF8A><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̓<EFBFBD><CC93>́A<CD81>o<EFBFBD>̓p<CD83>X<EFBFBD><58><EFBFBD>
const auto func = [this, &input_path, &output_path, &file_paths](const boost::filesystem::path &path)
{
BOOST_FOREACH(const boost::filesystem::path& p, std::make_pair(boost::filesystem::recursive_directory_iterator(path),
boost::filesystem::recursive_directory_iterator()))
{
if (!boost::filesystem::is_directory(p) && std::find(extList.begin(), extList.end(), p.extension().string()) != extList.end())
{
const auto out_relative = relativePath(p, input_path);
const auto out_absolute = output_path / out_relative;
const auto out = (out_absolute.branch_path() / out_absolute.stem()).string() + outputExt;
file_paths.emplace_back(p.string(), out);
}
}
return true;
};
if (!func(input_path))
return;
for (const auto &p : file_paths)
{
const boost::filesystem::path out_path(p.second);
const boost::filesystem::path out_dir(out_path.parent_path());
if (!boost::filesystem::exists(out_dir))
{
if (!boost::filesystem::create_directories(out_dir))
{
SendMessage(dh, WM_FAILD_CREATE_DIR, (WPARAM)&out_dir, 0);
PostMessage(dh, WM_END_THREAD, 0, 0);
//printf("<22>o<EFBFBD>̓t<CD83>H<EFBFBD><48><EFBFBD>_<EFBFBD>u%s<>v<EFBFBD>̍쐬<CC8D>Ɏ<EFBFBD><C98E>s<EFBFBD><73><EFBFBD>܂<EFBFBD><DC82><EFBFBD>\n", out_absolute.string().c_str());
return;
}
}
}
}
else
file_paths.emplace_back(input_str, output_str);
bool isFirst = true;
const auto ProgessFunc = [this, &isFirst](const int ProgressFileMax, const int ProgressFileNow)
{
if (isFirst)
{
isFirst = true;
SendMessage(GetDlgItem(dh, IDC_PROGRESS), PBM_SETRANGE32, 0, ProgressFileMax);
}
SendMessage(GetDlgItem(dh, IDC_PROGRESS), PBM_SETPOS, ProgressFileNow, 0);
};
const auto cuDNNCheckStartTime = std::chrono::system_clock::now();
if (process == "gpu")
Waifu2x::can_use_cuDNN();
const auto cuDNNCheckEndTime = std::chrono::system_clock::now();
Waifu2x::eWaifu2xError ret;
Waifu2x w;
ret = w.init(__argc, __argv, mode, noise_level, scale_ratio, "models", process, crop_size, batch_size);
if(ret != Waifu2x::eWaifu2xError_OK)
SendMessage(dh, WM_ON_WAIFU2X_ERROR, (WPARAM)&ret, 0);
else
{
const auto InitEndTime = std::chrono::system_clock::now();
for (const auto &p : file_paths)
{
ret = w.waifu2x(p.first, p.second, [this]()
{
return cancelFlag;
});
if (ret != Waifu2x::eWaifu2xError_OK)
{
SendMessage(dh, WM_ON_WAIFU2X_ERROR, (WPARAM)&ret, (LPARAM)&p);
if (ret == Waifu2x::eWaifu2xError_Cancel)
break;
}
}
const auto ProcessEndTime = std::chrono::system_clock::now();
cuDNNCheckTime = cuDNNCheckEndTime - cuDNNCheckStartTime;
InitTime = InitEndTime - cuDNNCheckEndTime;
ProcessTime = ProcessEndTime - InitEndTime;
usedProcess = w.used_process();
}
PostMessage(dh, WM_END_THREAD, 0, 0);
}
void ReplaceAddString()
{
SyncMember(true);
const boost::filesystem::path output_path(output_str);
std::string stem = output_path.stem().string();
if (stem.length() > 0 && stem.length() >= autoSetAddName.length())
{
const std::string base = stem.substr(0, stem.length() - autoSetAddName.length());
stem.erase(0, base.length());
if (stem == autoSetAddName)
{
const std::string addstr(AddName());
autoSetAddName = addstr;
boost::filesystem::path new_out_path = output_path.branch_path() / (base + addstr + outputExt);
SetWindowTextA(GetDlgItem(dh, IDC_EDIT_OUTPUT), new_out_path.string().c_str());
}
}
}
void AddLogMessage(const char *msg)
{
if (logMessage.length() == 0)
logMessage += msg;
else
logMessage += std::string("\r\n") + msg;
SetWindowTextA(GetDlgItem(dh, IDC_EDIT_LOG), logMessage.c_str());
}
void Waifu2xTime()
{
char msg[1024 * 2];
char *ptr = msg;
{
std::string p(usedProcess);
if (p == "cpu")
p = "CPU";
else if (p == "gpu")
p = "CUDA";
else if (p == "cudnn")
p = "cuDNN";
ptr += sprintf(ptr, "<EFBFBD>g<EFBFBD>p<EFBFBD>v<EFBFBD><EFBFBD><EFBFBD>Z<EFBFBD>b<EFBFBD>T<EFBFBD>[<5B><><EFBFBD>[<5B>h: %s\r\n", p.c_str());
}
{
uint64_t t = std::chrono::duration_cast<std::chrono::milliseconds>(ProcessTime).count();
const int msec = t % 1000; t /= 1000;
const int sec = t % 60; t /= 60;
const int min = t % 60; t /= 60;
const int hour = (int)t;
ptr += sprintf(ptr, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: %02d:%02d:%02d.%d\r\n", hour, min, sec, msec);
}
{
uint64_t t = std::chrono::duration_cast<std::chrono::milliseconds>(InitTime).count();
const int msec = t % 1000; t /= 1000;
const int sec = t % 60; t /= 60;
const int min = t % 60; t /= 60;
const int hour = (int)t;
ptr += sprintf(ptr, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: %02d:%02d:%02d.%d\r\n", hour, min, sec, msec);
}
if (process == "gpu" || process == "cudnn")
{
uint64_t t = std::chrono::duration_cast<std::chrono::milliseconds>(cuDNNCheckTime).count();
const int msec = t % 1000; t /= 1000;
const int sec = t % 60; t /= 60;
const int min = t % 60; t /= 60;
const int hour = (int)t;
ptr += sprintf(ptr, "cuDNN<EFBFBD>`<60>F<EFBFBD>b<EFBFBD>N<EFBFBD><4E><EFBFBD><EFBFBD>: %02d:%02d:%02d.%d", hour, min, sec, msec);
}
AddLogMessage(msg);
}
public:
DialogEvent() : dh(nullptr), mode("noise_scale"), noise_level(1), scale_ratio(2.0), process("gpu"), outputExt("png"), inputFileExt("png:jpg:jpeg:tif:tiff:bmp"),
crop_size(128), batch_size(1), isLastError(false)
{
}
void Exec(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
{
if (processThread.joinable())
return;
if (!SyncMember(false))
return;
if (input_str.length() == 0)
{
MessageBox(dh, TEXT("<EFBFBD><EFBFBD><EFBFBD>̓p<EFBFBD>X<EFBFBD><EFBFBD><EFBFBD>w<EFBFBD><EFBFBD>ĉ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"), TEXT("<EFBFBD>G<EFBFBD><EFBFBD><EFBFBD>["), MB_OK | MB_ICONERROR);
return;
}
if (output_str.length() == 0)
{
MessageBox(dh, TEXT("<EFBFBD>o<EFBFBD>̓p<EFBFBD>X<EFBFBD><EFBFBD><EFBFBD>w<EFBFBD><EFBFBD>ĉ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"), TEXT("<EFBFBD>G<EFBFBD><EFBFBD><EFBFBD>["), MB_OK | MB_ICONERROR);
return;
}
if (outputExt.length() == 0)
{
MessageBox(dh, TEXT("<EFBFBD>o<EFBFBD>͊g<EFBFBD><EFBFBD><EFBFBD>q<EFBFBD><EFBFBD><EFBFBD>w<EFBFBD><EFBFBD>ĉ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"), TEXT("<EFBFBD>G<EFBFBD><EFBFBD><EFBFBD>["), MB_OK | MB_ICONERROR);
return;
}
SendMessage(GetDlgItem(dh, IDC_PROGRESS), PBM_SETPOS, 0, 0);
cancelFlag = false;
isLastError = false;
processThread = std::thread(std::bind(&DialogEvent::ProcessWaifu2x, this));
EnableWindow(GetDlgItem(dh, IDC_BUTTON_CANCEL), TRUE);
EnableWindow(GetDlgItem(dh, IDC_BUTTON_EXEC), FALSE);
EnableWindow(GetDlgItem(dh, IDC_BUTTON_CHECK_CUDNN), FALSE);
SetWindowTextA(GetDlgItem(hWnd, IDC_EDIT_LOG), "");
logMessage.clear();
}
void WaitThreadExit(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
{
processThread.join();
EnableWindow(GetDlgItem(dh, IDC_BUTTON_CANCEL), FALSE);
EnableWindow(GetDlgItem(dh, IDC_BUTTON_EXEC), TRUE);
EnableWindow(GetDlgItem(dh, IDC_BUTTON_CHECK_CUDNN), TRUE);
if (!isLastError)
{
if (!cancelFlag)
AddLogMessage("<EFBFBD>ϊ<EFBFBD><EFBFBD>ɐ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><EFBFBD><EFBFBD>");
Waifu2xTime();
MessageBeep(MB_ICONASTERISK);
}
else
MessageBoxA(dh, "<EFBFBD>G<EFBFBD><EFBFBD><EFBFBD>[<5B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><DC82><EFBFBD>", "<EFBFBD>G<EFBFBD><EFBFBD><EFBFBD>[", MB_OK | MB_ICONERROR);
}
void OnDialogEnd(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
{
if (!processThread.joinable())
PostQuitMessage(0);
else
MessageBeep(MB_ICONEXCLAMATION);
}
void OnFaildCreateDir(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
{
const boost::filesystem::path *p = (const boost::filesystem::path *)wParam;
// <20>o<EFBFBD>̓t<CD83>H<EFBFBD><48><EFBFBD>_<EFBFBD>u%s<>v<EFBFBD>̍쐬<CC8D>Ɏ<EFBFBD><C98E>s<EFBFBD><73><EFBFBD>܂<EFBFBD><DC82><EFBFBD>\n", out_absolute.string().c_str());
std::wstring msg(L"<EFBFBD>o<EFBFBD>̓t<EFBFBD>H<EFBFBD><EFBFBD><EFBFBD>_\r\n<EFBFBD>u");
msg += p->wstring();
msg += L"<EFBFBD>v\r\n<EFBFBD>̍쐬<EFBFBD>Ɏ<EFBFBD><EFBFBD>s<EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><EFBFBD><EFBFBD>";
MessageBox(dh, msg.c_str(), TEXT("<EFBFBD>G<EFBFBD><EFBFBD><EFBFBD>["), MB_OK | MB_ICONERROR);
isLastError = true;
}
void OnWaifu2xError(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
{
const Waifu2x::eWaifu2xError ret = *(const Waifu2x::eWaifu2xError *)wParam;
if (ret != Waifu2x::eWaifu2xError_OK)
{
char msg[1024] = "";
if (lParam == 0)
{
switch (ret)
{
case Waifu2x::eWaifu2xError_Cancel:
sprintf(msg, "<EFBFBD>L<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Z<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><EFBFBD><EFBFBD>");
break;
case Waifu2x::eWaifu2xError_InvalidParameter:
sprintf(msg, "<EFBFBD>p<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[<5B>^<5E><><EFBFBD>s<EFBFBD><73><EFBFBD>ł<EFBFBD>");
break;
case Waifu2x::eWaifu2xError_FailedOpenModelFile:
sprintf(msg, "<EFBFBD><EFBFBD><EFBFBD>f<EFBFBD><EFBFBD><EFBFBD>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD><EFBFBD><EFBFBD>J<EFBFBD><4A><EFBFBD>܂<EFBFBD><DC82><EFBFBD><EFBFBD>ł<EFBFBD><C582><EFBFBD>");
break;
case Waifu2x::eWaifu2xError_FailedParseModelFile:
sprintf(msg, "<EFBFBD><EFBFBD><EFBFBD>f<EFBFBD><EFBFBD><EFBFBD>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><C482>܂<EFBFBD>");
break;
case Waifu2x::eWaifu2xError_FailedConstructModel:
sprintf(msg, "<EFBFBD>l<EFBFBD>b<EFBFBD>g<EFBFBD><EFBFBD><EFBFBD>[<5B>N<EFBFBD>̍\<EFBFBD>z<EFBFBD>Ɏ<EFBFBD><EFBFBD>s<EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><EFBFBD><EFBFBD>");
break;
}
}
else
{
const auto &fp = *(const std::pair<std::string, std::string> *)lParam;
switch (ret)
{
case Waifu2x::eWaifu2xError_Cancel:
sprintf(msg, "<EFBFBD>L<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Z<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><EFBFBD><EFBFBD>");
break;
case Waifu2x::eWaifu2xError_InvalidParameter:
sprintf(msg, "<EFBFBD>p<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[<5B>^<5E><><EFBFBD>s<EFBFBD><73><EFBFBD>ł<EFBFBD>");
break;
case Waifu2x::eWaifu2xError_FailedOpenInputFile:
sprintf(msg, "<EFBFBD><EFBFBD><EFBFBD>͉摜<EFBFBD>u%s<>v<EFBFBD><76><EFBFBD>J<EFBFBD><4A><EFBFBD>܂<EFBFBD><DC82><EFBFBD><EFBFBD>ł<EFBFBD><C582><EFBFBD>", fp.first.c_str());
break;
case Waifu2x::eWaifu2xError_FailedOpenOutputFile:
sprintf(msg, "<EFBFBD>o<EFBFBD>͉摜<EFBFBD><EFBFBD><EFBFBD>u%s<>v<EFBFBD>ɏ<EFBFBD><C98F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߂܂<DF82><DC82><EFBFBD><EFBFBD>ł<EFBFBD><C582><EFBFBD>", fp.second.c_str());
break;
case Waifu2x::eWaifu2xError_FailedProcessCaffe:
sprintf(msg, "<EFBFBD><EFBFBD><EFBFBD>ԏ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ɏ<EFBFBD><EFBFBD>s<EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><EFBFBD><EFBFBD>");
break;
}
}
AddLogMessage(msg);
if (ret != Waifu2x::eWaifu2xError_Cancel)
isLastError = true;
}
}
void Create(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
{
dh = hWnd;
SendMessage(GetDlgItem(hWnd, IDC_RADIO_MODE_NOISE_SCALE), BM_SETCHECK, BST_CHECKED, 0);
SendMessage(GetDlgItem(hWnd, IDC_RADIONOISE_LEVEL1), BM_SETCHECK, BST_CHECKED, 0);
SendMessage(GetDlgItem(hWnd, IDC_RADIO_MODE_GPU), BM_SETCHECK, BST_CHECKED, 0);
EnableWindow(GetDlgItem(dh, IDC_BUTTON_CANCEL), FALSE);
char text[] = "2.00";
SetWindowTextA(GetDlgItem(hWnd, IDC_EDIT_SCALE_RATIO), text);
SetWindowTextA(GetDlgItem(hWnd, IDC_EDIT_OUT_EXT), outputExt.c_str());
SetWindowTextA(GetDlgItem(hWnd, IDC_EDIT_INPUT_EXT_LIST), inputFileExt.c_str());
std::ifstream ifs(CropSizeListName);
if (ifs)
{
std::string str;
while (getline(ifs, str))
{
char *ptr = nullptr;
const long n = strtol(str.c_str(), &ptr, 10);
if (ptr && *ptr == '\0')
CropSizeList.push_back(n);
}
}
}
void Cancel(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
{
cancelFlag = true;
EnableWindow(GetDlgItem(dh, IDC_BUTTON_CANCEL), FALSE);
}
void RadioButtom(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
{
ReplaceAddString();
}
void CheckCUDNN(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
{
switch (Waifu2x::can_use_cuDNN())
{
case Waifu2x::eWaifu2xcuDNNError_OK:
MessageBox(dh, TEXT("cuDNN<EFBFBD><EFBFBD><EFBFBD>g<EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD>"), TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"), MB_OK | MB_ICONINFORMATION);
break;
case Waifu2x::eWaifu2xcuDNNError_NotFind:
MessageBox(dh, TEXT("cuDNN<EFBFBD>͎g<EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><EFBFBD><EFBFBD>\r\n<EFBFBD>ucudnn64_65.dll<6C>v<EFBFBD><76><EFBFBD><EFBFBD><EFBFBD>‚<EFBFBD><C282><EFBFBD><EFBFBD>܂<EFBFBD><DC82><EFBFBD>"), TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"), MB_OK | MB_ICONERROR);
break;
case Waifu2x::eWaifu2xcuDNNError_OldVersion:
MessageBox(dh, TEXT("cuDNN<EFBFBD>͎g<EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><EFBFBD><EFBFBD>\r\n<EFBFBD>ucudnn64_65.dll<6C>v<EFBFBD>̃o<CC83>[<5B>W<EFBFBD><57><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Â<EFBFBD><C382>ł<EFBFBD><C582>Bv2<76><32><EFBFBD>g<EFBFBD><67><EFBFBD>ĉ<EFBFBD><C489><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B"), TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"), MB_OK | MB_ICONERROR);
break;
case Waifu2x::eWaifu2xcuDNNError_CannotCreate:
MessageBox(dh, TEXT("cuDNN<EFBFBD>͎g<EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><EFBFBD><EFBFBD>\r\ncuDNN<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>o<EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><EFBFBD><EFBFBD>"), TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"), MB_OK | MB_ICONERROR);
break;
default:
MessageBox(dh, TEXT("cuDNN<EFBFBD>͎g<EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><EFBFBD><EFBFBD>"), TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"), MB_OK | MB_ICONERROR);
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD>œn<C593><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD>hWnd<6E><64>IDC_EDIT<49><54>HWND(<28>R<EFBFBD><52><EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>̃C<CC83>x<EFBFBD><78><EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
LRESULT DropInput(HWND hWnd, WPARAM wParam, LPARAM lParam, WNDPROC OrgSubWnd, LPVOID lpData)
{
char szTmp[AR_PATH_MAX];
// <20>h<EFBFBD><68><EFBFBD>b<EFBFBD>v<EFBFBD><76><EFBFBD><EFBFBD>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
UINT FileNum = DragQueryFileA((HDROP)wParam, 0xFFFFFFFF, szTmp, _countof(szTmp));
if (FileNum >= 1)
{
DragQueryFileA((HDROP)wParam, 0, szTmp, _countof(szTmp));
boost::filesystem::path path(szTmp);
if (!boost::filesystem::exists(path))
{
MessageBox(dh, TEXT("<EFBFBD><EFBFBD><EFBFBD>̓t<EFBFBD>@<40>C<EFBFBD><43>/<2F>t<EFBFBD>H<EFBFBD><48><EFBFBD>_<EFBFBD><5F><EFBFBD><EFBFBD><EFBFBD>݂<EFBFBD><DD82>܂<EFBFBD><DC82><EFBFBD>"), TEXT("<EFBFBD>G<EFBFBD><EFBFBD><EFBFBD>["), MB_OK | MB_ICONERROR);
return 0L;
}
if (!SyncMember(true))
return 0L;
if (boost::filesystem::is_directory(path))
{
HWND ho = GetDlgItem(dh, IDC_EDIT_OUTPUT);
const std::string addstr(AddName());
autoSetAddName = AddName();
auto str = (path.branch_path() / (path.stem().string() + addstr)).string();
SetWindowTextA(ho, str.c_str());
SetWindowTextA(hWnd, szTmp);
}
else
{
HWND ho = GetDlgItem(dh, IDC_EDIT_OUTPUT);
std::string outputFileName = szTmp;
const auto tailDot = outputFileName.find_last_of('.');
if (tailDot != outputFileName.npos)
outputFileName.erase(tailDot, outputFileName.length());
const std::string addstr(AddName());
autoSetAddName = addstr;
outputFileName += addstr + outputExt;
SetWindowTextA(ho, outputFileName.c_str());
SetWindowTextA(hWnd, szTmp);
}
SetCropSizeList(path);
}
return 0L;
}
// <20><><EFBFBD><EFBFBD><EFBFBD>œn<C593><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD>hWnd<6E><64>IDC_EDIT<49><54>HWND(<28>R<EFBFBD><52><EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>̃C<CC83>x<EFBFBD><78><EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
LRESULT DropOutput(HWND hWnd, WPARAM wParam, LPARAM lParam, WNDPROC OrgSubWnd, LPVOID lpData)
{
TCHAR szTmp[AR_PATH_MAX];
// <20>h<EFBFBD><68><EFBFBD>b<EFBFBD>v<EFBFBD><76><EFBFBD><EFBFBD>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
UINT FileNum = DragQueryFile((HDROP)wParam, 0xFFFFFFFF, szTmp, AR_PATH_MAX);
if (FileNum >= 1)
{
DragQueryFile((HDROP)wParam, 0, szTmp, AR_PATH_MAX);
SetWindowText(hWnd, szTmp);
}
return 0L;
}
LRESULT TextInput(HWND hWnd, WPARAM wParam, LPARAM lParam, WNDPROC OrgSubWnd, LPVOID lpData)
{
const auto ret = CallWindowProc(OrgSubWnd, hWnd, WM_CHAR, wParam, lParam);
ReplaceAddString();
return ret;
}
};
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
//PVOID hVectoredExceptionHandler = AddVectoredExceptionHandler(1, ExceptionHandler);
// CDialog<6F>N<EFBFBD><4E><EFBFBD>X<EFBFBD>Ń_<C583>C<EFBFBD>A<EFBFBD><41><EFBFBD>O<EFBFBD><4F><EFBFBD><EFBFBD><EC90AC><EFBFBD><EFBFBD>
CDialog cDialog;
CDialog cDialog2;
// IDC_EDIT<49>̃T<CC83>u<EFBFBD>N<EFBFBD><4E><EFBFBD>X
CControl cControlInput(IDC_EDIT_INPUT);
CControl cControlOutput(IDC_EDIT_OUTPUT);
CControl cControlScale(IDC_EDIT_SCALE_RATIO);
CControl cControlOutExt(IDC_EDIT_OUT_EXT);
// <20>o<EFBFBD>^<5E><><EFBFBD><EFBFBD><EFBFBD>֐<EFBFBD><D690><EFBFBD><EFBFBD>܂Ƃ߂<C682><DF82><EFBFBD>N<EFBFBD><4E><EFBFBD>X
// <20>O<EFBFBD><4F><EFBFBD>[<5B>o<EFBFBD><6F><EFBFBD>֐<EFBFBD><D690><EFBFBD><EFBFBD>g<EFBFBD><67><EFBFBD>΃N<CE83><4E><EFBFBD>X<EFBFBD>ɂ܂Ƃ߂<C682><DF82>K<EFBFBD>v<EFBFBD>͂Ȃ<CD82><C882><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̕<EFBFBD><CC95>@<40><><EFBFBD>𗧂‚<F097A782><C282>Ƃ<EFBFBD><C682><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͂<EFBFBD>
DialogEvent cDialogEvent;
// <20>N<EFBFBD><4E><EFBFBD>X<EFBFBD>̊֐<CC8A><D690><EFBFBD><EFBFBD>o<EFBFBD>^<5E><><EFBFBD><EFBFBD><EFBFBD>
// IDC_EDIT<49><54>WM_DROPFILES<45><53><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD>Ƃ<EFBFBD><C682>Ɏ<EFBFBD><C98E>s<EFBFBD><73><EFBFBD><EFBFBD><EFBFBD>֐<EFBFBD><D690>̓o<CC93>^
cControlInput.SetEventCallBack(SetClassCustomFunc(DialogEvent::DropInput, &cDialogEvent), NULL, WM_DROPFILES);
cControlOutput.SetEventCallBack(SetClassCustomFunc(DialogEvent::DropOutput, &cDialogEvent), NULL, WM_DROPFILES);
cControlScale.SetEventCallBack(SetClassCustomFunc(DialogEvent::TextInput, &cDialogEvent), NULL, WM_CHAR);
cControlOutExt.SetEventCallBack(SetClassCustomFunc(DialogEvent::TextInput, &cDialogEvent), NULL, WM_CHAR);
// <20>R<EFBFBD><52><EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>̃T<CC83>u<EFBFBD>N<EFBFBD><4E><EFBFBD>X<EFBFBD><58><EFBFBD>o<EFBFBD>^
cDialog.AddControl(&cControlInput);
cDialog.AddControl(&cControlOutput);
cDialog.AddControl(&cControlScale);
cDialog.AddControl(&cControlOutExt);
// <20>e<EFBFBD>R<EFBFBD><52><EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>̃C<CC83>x<EFBFBD><78><EFBFBD>g<EFBFBD>Ŏ<EFBFBD><C58E>s<EFBFBD><73><EFBFBD><EFBFBD><EFBFBD>֐<EFBFBD><D690>̓o<CC93>^
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::Exec, &cDialogEvent), NULL, IDC_BUTTON_EXEC);
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::Cancel, &cDialogEvent), NULL, IDC_BUTTON_CANCEL);
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::RadioButtom, &cDialogEvent), NULL, IDC_RADIO_MODE_NOISE);
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::RadioButtom, &cDialogEvent), NULL, IDC_RADIO_MODE_SCALE);
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::RadioButtom, &cDialogEvent), NULL, IDC_RADIO_MODE_NOISE_SCALE);
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::RadioButtom, &cDialogEvent), NULL, IDC_RADIO_AUTO_SCALE);
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::RadioButtom, &cDialogEvent), NULL, IDC_RADIONOISE_LEVEL1);
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::RadioButtom, &cDialogEvent), NULL, IDC_RADIONOISE_LEVEL2);
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::RadioButtom, &cDialogEvent), NULL, IDC_RADIO_MODE_CPU);
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::RadioButtom, &cDialogEvent), NULL, IDC_RADIO_MODE_GPU);
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::CheckCUDNN, &cDialogEvent), NULL, IDC_BUTTON_CHECK_CUDNN);
// <20>_<EFBFBD>C<EFBFBD>A<EFBFBD><41><EFBFBD>O<EFBFBD>̃C<CC83>x<EFBFBD><78><EFBFBD>g<EFBFBD>Ŏ<EFBFBD><C58E>s<EFBFBD><73><EFBFBD><EFBFBD><EFBFBD>֐<EFBFBD><D690>̓o<CC93>^
cDialog.SetEventCallBack(SetClassFunc(DialogEvent::Create, &cDialogEvent), NULL, WM_INITDIALOG);
cDialog.SetEventCallBack(SetClassFunc(DialogEvent::OnDialogEnd, &cDialogEvent), NULL, WM_CLOSE);
cDialog.SetEventCallBack(SetClassFunc(DialogEvent::OnFaildCreateDir, &cDialogEvent), NULL, WM_FAILD_CREATE_DIR);
cDialog.SetEventCallBack(SetClassFunc(DialogEvent::OnWaifu2xError, &cDialogEvent), NULL, WM_ON_WAIFU2X_ERROR);
cDialog.SetEventCallBack(SetClassFunc(DialogEvent::WaitThreadExit, &cDialogEvent), NULL, WM_END_THREAD);
// <20>_<EFBFBD>C<EFBFBD>A<EFBFBD><41><EFBFBD>O<EFBFBD><4F><EFBFBD>\<5C><>
cDialog.DoModal(hInstance, IDD_DIALOG);
//RemoveVectoredExceptionHandler(hVectoredExceptionHandler);
return 0;
}