diff --git a/utils/dr_rdpng.cc b/utils/dr_rdpng.cc index d17bfdc25..57a64ae2f 100644 --- a/utils/dr_rdpng.cc +++ b/utils/dr_rdpng.cc @@ -5,6 +5,11 @@ #include #include #include // strerror +#ifndef _MSC_VER +#include +#include +#include +#endif #include "../simmem.h" #include "../simdebug.h" @@ -136,7 +141,56 @@ bool load_block(unsigned char** block, unsigned* width, unsigned* height, const // remember the file name for better error messages. filename_ = fname; - if (FILE* const file = fopen(fname, "rb")) { + FILE* file = fopen(fname, "rb"); + +#ifndef _MSC_VER + if (!file) { + // Try to case-insensitive search. + std::string actual_path; + size_t len = strlen(fname); + actual_path.reserve(len); + const char * sep_beg = fname; + const char * sep_end = sep_beg + strspn(sep_beg, "/"); + if (sep_end == sep_beg) { + // relative + actual_path = "./"; + } + + char const * end = fname + len; + + std::string name; + while (true) { + actual_path.insert(actual_path.end(), sep_beg, sep_end); + sep_beg = sep_end + strcspn(sep_end, "/"); + if (sep_beg == sep_end) { + break; + } + name.assign(sep_end, sep_beg); + DIR * dir = opendir(actual_path.c_str()); + if (!dir) { + break; + } + struct dirent * ent = NULL; + while (ent = readdir(dir)) { + if (!strcasecmp(ent->d_name, name.c_str())) { + actual_path += ent->d_name; + break; + } + } + closedir(dir); + if (!ent) { + break; + } + if (sep_beg == end) { + file = fopen(actual_path.c_str(), "rb"); + break; + } + sep_end = sep_beg + strspn(sep_beg, "/"); + } + } +#endif + + if (file) { read_png(block, width, height, file, base_img_size); fclose(file); return true;