From ef98dca4769208bf99eafef80e44bbd5357100c8 Mon Sep 17 00:00:00 2001 From: Kai Aoki Date: Fri, 16 Jan 2026 17:30:57 +0900 Subject: [PATCH 1/2] Perform the same console init process as llama-cli --- tools/mtmd/mtmd-cli.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/mtmd/mtmd-cli.cpp b/tools/mtmd/mtmd-cli.cpp index 054c7faa6a..97e4072625 100644 --- a/tools/mtmd/mtmd-cli.cpp +++ b/tools/mtmd/mtmd-cli.cpp @@ -298,6 +298,9 @@ int main(int argc, char ** argv) { int n_predict = params.n_predict < 0 ? INT_MAX : params.n_predict; + console::init(params.simple_io, params.use_color); + atexit([]() { console::cleanup(); }); + // Ctrl+C handling { #if defined (__unix__) || (defined (__APPLE__) && defined (__MACH__)) From cb9588ab6884091835222780e11e6a2084dc9e70 Mon Sep 17 00:00:00 2001 From: Kai Aoki Date: Fri, 16 Jan 2026 17:30:58 +0900 Subject: [PATCH 2/2] mtmd: Fix/Add non-ASCII file path support on Windows --- tools/mtmd/clip.cpp | 21 +++++++++++++++++++++ tools/mtmd/mtmd-helper.cpp | 30 ++++++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/tools/mtmd/clip.cpp b/tools/mtmd/clip.cpp index 9b076e0c56..d4e34ae2a9 100644 --- a/tools/mtmd/clip.cpp +++ b/tools/mtmd/clip.cpp @@ -24,6 +24,13 @@ #include #include +#ifdef _WIN32 +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#endif + struct clip_logger_state g_logger_state = {clip_log_callback_default, NULL}; //#define CLIP_DEBUG_FUNCTIONS @@ -1837,7 +1844,21 @@ struct clip_model_loader { { std::vector read_buf; +#ifdef _WIN32 + // Convert UTF-8 to UTF-16 for Windows + int wlen = MultiByteToWideChar(CP_UTF8, 0, fname.c_str(), -1, NULL, 0); + if (!wlen) { + throw std::runtime_error(string_format("%s: failed to convert filename to UTF-16: %s\n", __func__, fname.c_str())); + } + std::vector wfname(wlen); + wlen = MultiByteToWideChar(CP_UTF8, 0, fname.c_str(), -1, wfname.data(), wlen); + if (!wlen) { + throw std::runtime_error(string_format("%s: failed to convert filename to UTF-16: %s\n", __func__, fname.c_str())); + } + auto fin = std::ifstream(wfname.data(), std::ios::binary); +#else auto fin = std::ifstream(fname, std::ios::binary); +#endif if (!fin) { throw std::runtime_error(string_format("%s: failed to open %s\n", __func__, fname.c_str())); } diff --git a/tools/mtmd/mtmd-helper.cpp b/tools/mtmd/mtmd-helper.cpp index 902a4b456d..7200d68982 100644 --- a/tools/mtmd/mtmd-helper.cpp +++ b/tools/mtmd/mtmd-helper.cpp @@ -498,13 +498,38 @@ mtmd_bitmap * mtmd_helper_bitmap_init_from_buf(mtmd_context * ctx, const unsigne } mtmd_bitmap * mtmd_helper_bitmap_init_from_file(mtmd_context * ctx, const char * fname) { - std::vector buf; +#ifdef _WIN32 + // Convert UTF-8 to UTF-16 for Windows + int wlen = MultiByteToWideChar(CP_UTF8, 0, fname, -1, NULL, 0); + if (!wlen) { + LOG_ERR("Unable to convert filename to UTF-16: %s\n", fname); + return nullptr; + } + + std::vector wfname(wlen); + wlen = MultiByteToWideChar(CP_UTF8, 0, fname, -1, wfname.data(), wlen); + if (!wlen) { + LOG_ERR("Unable to convert filename to UTF-16: %s\n", fname); + return nullptr; + } + + // Open file with UTF-16 filename + FILE * f = _wfopen(wfname.data(), L"rb"); + if (!f) { + LOG_ERR("Unable to open file %s: %s\n", fname, strerror(errno)); + return nullptr; + } +#else + // On non-Windows platforms, use fopen directly FILE * f = fopen(fname, "rb"); if (!f) { LOG_ERR("Unable to open file %s: %s\n", fname, strerror(errno)); return nullptr; } +#endif + // Read file content + std::vector buf; fseek(f, 0, SEEK_END); long file_size = ftell(f); fseek(f, 0, SEEK_SET); @@ -512,8 +537,9 @@ mtmd_bitmap * mtmd_helper_bitmap_init_from_file(mtmd_context * ctx, const char * size_t n_read = fread(buf.data(), 1, file_size, f); fclose(f); + if (n_read != (size_t)file_size) { - LOG_ERR("Failed to read entire file %s", fname); + LOG_ERR("Failed to read entire file %s\n", fname); return nullptr; }