Skip to content

Commit

Permalink
Open filenames as utf8 on windows (#1014)
Browse files Browse the repository at this point in the history
  • Loading branch information
xelatihy authored Aug 16, 2020
1 parent 9ea7ac3 commit bdd7b88
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 135 deletions.
28 changes: 17 additions & 11 deletions libs/yocto/yocto_commonio.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ using std::string;
using std::unordered_set;
using std::vector;
using std::filesystem::path;
using std::filesystem::u8path;
using namespace std::string_literals;

} // namespace yocto
Expand Down Expand Up @@ -364,13 +365,7 @@ inline string replace_extension(const string& filename, const string& ext) {

// Check if a file can be opened for reading.
inline bool exists_file(const string& filename) {
auto fs = fopen(filename.c_str(), "r");
if (fs) {
fclose(fs);
return true;
} else {
return false;
}
return exists(u8path(filename));
}

} // namespace yocto
Expand All @@ -380,10 +375,21 @@ inline bool exists_file(const string& filename) {
// -----------------------------------------------------------------------------
namespace yocto {

// Opens a file with a utf8 file name
inline FILE* fopen_utf8(const char* filename, const char* mode) {
#ifdef _Win32
auto path8 = std::filesystem::u8path(filename);
auto wmode = std::wstring(string{mode}.begin(), string{mode}.end());
return _wfopen(path.c_str(), wmode.c_str());
#else
return fopen(filename, mode);
#endif
}

// Load a text file
inline bool load_text(const string& filename, string& str, string& error) {
// https://stackoverflow.com/questions/174531/how-to-read-the-content-of-a-file-to-a-string-in-c
auto fs = fopen(filename.c_str(), "rb");
auto fs = fopen_utf8(filename.c_str(), "rb");
if (!fs) {
error = filename + ": file not found";
return false;
Expand All @@ -403,7 +409,7 @@ inline bool load_text(const string& filename, string& str, string& error) {
// Save a text file
inline bool save_text(
const string& filename, const string& str, string& error) {
auto fs = fopen(filename.c_str(), "wt");
auto fs = fopen_utf8(filename.c_str(), "wt");
if (!fs) {
error = filename + ": file not found";
return false;
Expand All @@ -420,7 +426,7 @@ inline bool save_text(
inline bool load_binary(
const string& filename, vector<byte>& data, string& error) {
// https://stackoverflow.com/questions/174531/how-to-read-the-content-of-a-file-to-a-string-in-c
auto fs = fopen(filename.c_str(), "rb");
auto fs = fopen_utf8(filename.c_str(), "rb");
if (!fs) {
error = filename + ": file not found";
return false;
Expand All @@ -440,7 +446,7 @@ inline bool load_binary(
// Save a binary file
inline bool save_binary(
const string& filename, const vector<byte>& data, string& error) {
auto fs = fopen(filename.c_str(), "wb");
auto fs = fopen_utf8(filename.c_str(), "wb");
if (!fs) {
error = filename + ": file not found";
return false;
Expand Down
75 changes: 34 additions & 41 deletions libs/yocto/yocto_image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ struct color_space_params {
// Input: red, green, blue, white (x,y) chromoticities
// Algorithm from: SMPTE Recommended Practice RP 177-1993
// http://car.france3.mars.free.fr/HD/INA-%2026%20jan%2006/SMPTE%20normes%20et%20confs/rp177.pdf
static inline mat3f rgb_to_xyz_mat(
inline mat3f rgb_to_xyz_mat(
const vec2f& rc, const vec2f& gc, const vec2f& bc, const vec2f& wc) {
auto rgb = mat3f{
{rc.x, rc.y, 1 - rc.x - rc.y},
Expand All @@ -102,7 +102,7 @@ static inline mat3f rgb_to_xyz_mat(
}

// Construct an RGB color space. Predefined color spaces below
static inline color_space_params get_color_scape_params(color_space space) {
inline color_space_params get_color_scape_params(color_space space) {
static auto make_linear_rgb_space = [](const vec2f& red, const vec2f& green,
const vec2f& blue,
const vec2f& white) {
Expand Down Expand Up @@ -214,25 +214,23 @@ static inline color_space_params get_color_scape_params(color_space space) {
}

// gamma to linear
static inline float gamma_display_to_linear(float x, float gamma) {
inline float gamma_display_to_linear(float x, float gamma) {
return pow(x, gamma);
};
static inline float gamma_linear_to_display(float x, float gamma) {
inline float gamma_linear_to_display(float x, float gamma) {
return pow(x, 1 / gamma);
};

// https://en.wikipedia.org/wiki/Rec._709
static inline float gamma_display_to_linear(
float x, float gamma, const vec4f& abcd) {
inline float gamma_display_to_linear(float x, float gamma, const vec4f& abcd) {
auto& [a, b, c, d] = abcd;
if (x < 1 / d) {
return x / c;
} else {
return pow((x + b) / a, gamma);
}
};
static inline float gamma_linear_to_display(
float x, float gamma, const vec4f& abcd) {
inline float gamma_linear_to_display(float x, float gamma, const vec4f& abcd) {
auto& [a, b, c, d] = abcd;
if (x < d) {
return x * c;
Expand All @@ -242,7 +240,7 @@ static inline float gamma_linear_to_display(
};

// https://en.wikipedia.org/wiki/Academy_Color_Encoding_Systemx
static inline float acescc_display_to_linear(float x) {
inline float acescc_display_to_linear(float x) {
if (x < -0.3013698630f) { // (9.72-15)/17.52
return (exp2(x * 17.52f - 9.72f) - exp2(-16.0f)) * 2;
} else if (x < (log2(65504.0f) + 9.72f) / 17.52f) {
Expand All @@ -252,15 +250,15 @@ static inline float acescc_display_to_linear(float x) {
}
}
// https://en.wikipedia.org/wiki/Academy_Color_Encoding_Systemx
static inline float acescct_display_to_linear(float x) {
inline float acescct_display_to_linear(float x) {
if (x < 0.155251141552511f) {
return (x - 0.0729055341958355f) / 10.5402377416545f;
} else {
return exp2(x * 17.52f - 9.72f);
}
}
// https://en.wikipedia.org/wiki/Academy_Color_Encoding_Systemx
static inline float acescc_linear_to_display(float x) {
inline float acescc_linear_to_display(float x) {
if (x <= 0) {
return -0.3584474886f; // =(log2( pow(2.,-16.))+9.72)/17.52
} else if (x < exp2(-15.0f)) {
Expand All @@ -270,7 +268,7 @@ static inline float acescc_linear_to_display(float x) {
}
}
// https://en.wikipedia.org/wiki/Academy_Color_Encoding_Systemx
static inline float acescct_linear_to_display(float x) {
inline float acescct_linear_to_display(float x) {
if (x <= 0.0078125f) {
return 10.5402377416545f * x + 0.0729055341958355f;
} else {
Expand All @@ -282,14 +280,14 @@ static inline float acescct_linear_to_display(float x) {
// https://github.com/ampas/aces-dev/blob/master/transforms/ctl/lib/ACESlib.Utilities_Color.ctl
// In PQ, we assume that the linear luminance in [0,1] corresponds to
// [0,10000] cd m^2
static inline float pq_display_to_linear(float x) {
inline float pq_display_to_linear(float x) {
auto Np = pow(x, 1 / 78.84375f);
auto L = max(Np - 0.8359375f, 0.0f);
L = L / (18.8515625f - 18.6875f * Np);
L = pow(L, 1 / 0.1593017578125f);
return L;
}
static inline float pq_linear_to_display(float x) {
inline float pq_linear_to_display(float x) {
return pow((0.8359375f + 18.8515625f * pow(x, 0.1593017578125f)) /
(1 + 18.6875f * pow(x, 0.1593017578125f)),
78.84375f);
Expand All @@ -300,14 +298,14 @@ static inline float pq_linear_to_display(float x) {
// range for nominal luminance. But HLG was initially defined in the [0,12]
// range where it maps 1 to 0.5 and 12 to 1. For use in HDR tonemapping that is
// likely a better range to use.
static inline float hlg_display_to_linear(float x) {
inline float hlg_display_to_linear(float x) {
if (x < 0.5f) {
return 3 * 3 * x * x;
} else {
return (exp((x - 0.55991073f) / 0.17883277f) + 0.28466892f) / 12;
}
}
static inline float hlg_linear_to_display(float x) {
inline float hlg_linear_to_display(float x) {
if (x < 1 / 12.0f) {
return sqrt(3 * x);
} else {
Expand Down Expand Up @@ -1411,7 +1409,7 @@ volume<float> make_volume_preset(const string& type) {
namespace yocto {

// Split a string
static inline vector<string> split_string(const string& str) {
static vector<string> split_string(const string& str) {
auto ret = vector<string>();
if (str.empty()) return ret;
auto lpos = (size_t)0;
Expand All @@ -1428,10 +1426,20 @@ static inline vector<string> split_string(const string& str) {
return ret;
}

// Opens a file with a utf8 file name
static FILE* fopen_utf8(const char* filename, const char* mode) {
#ifdef _Win32
auto path8 = std::filesystem::u8path(filename);
auto wmode = std::wstring(string{mode}.begin(), string{mode}.end());
return _wfopen(path.c_str(), wmode.c_str());
#else
return fopen(filename, mode);
#endif
}

// Pfm load
static inline float* load_pfm(
const char* filename, int* w, int* h, int* nc, int req) {
auto fs = fopen(filename, "rb");
static float* load_pfm(const char* filename, int* w, int* h, int* nc, int req) {
auto fs = fopen_utf8(filename, "rb");
if (!fs) return nullptr;
auto fs_guard = std::unique_ptr<FILE, void (*)(FILE*)>{
fs, [](FILE* f) { fclose(f); }};
Expand Down Expand Up @@ -1541,9 +1549,9 @@ static inline float* load_pfm(
}

// save pfm
static inline bool save_pfm(
static bool save_pfm(
const char* filename, int w, int h, int nc, const float* pixels) {
auto fs = fopen(filename, "wb");
auto fs = fopen_utf8(filename, "wb");
if (!fs) return false;
auto fs_guard = std::unique_ptr<FILE, void (*)(FILE*)>{
fs, [](FILE* f) { fclose(f); }};
Expand Down Expand Up @@ -2096,12 +2104,10 @@ bool is_hdr_filename(const string& filename) {
// -----------------------------------------------------------------------------
namespace yocto {

namespace impl {

// Volume load
static inline float* load_yvol(
static float* load_yvol(
const char* filename, int* w, int* h, int* d, int* nc, int req) {
auto fs = fopen(filename, "rb");
auto fs = fopen_utf8(filename, "rb");
if (!fs) return nullptr;
auto fs_guard = std::unique_ptr<FILE, void (*)(FILE*)>{
fs, [](FILE* f) { fclose(f); }};
Expand Down Expand Up @@ -2220,9 +2226,9 @@ static inline float* load_yvol(
}

// save pfm
static inline bool save_yvol(
static bool save_yvol(
const char* filename, int w, int h, int d, int nc, const float* voxels) {
auto fs = fopen(filename, "wb");
auto fs = fopen_utf8(filename, "wb");
if (!fs) return false;
auto fs_guard = std::unique_ptr<FILE, void (*)(FILE*)>{
fs, [](FILE* f) { fclose(f); }};
Expand Down Expand Up @@ -2262,17 +2268,4 @@ bool save_volume(
return true;
}

} // namespace impl

// Loads volume data from binary format.
bool load_volume(const string& filename, volume<float>& vol, string& error) {
return impl::load_volume(filename, vol, error);
}

// Saves volume data in binary format.
bool save_volume(
const string& filename, const volume<float>& vol, string& error) {
return impl::save_volume(filename, vol, error);
}

} // namespace yocto
31 changes: 21 additions & 10 deletions libs/yocto/yocto_modelio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,17 @@ using namespace std::string_literals;
// -----------------------------------------------------------------------------
namespace yocto {

// Opens a file with a utf8 file name
inline FILE* fopen_utf8(const char* filename, const char* mode) {
#ifdef _Win32
auto path8 = std::filesystem::u8path(filename);
auto wmode = std::wstring(string{mode}.begin(), string{mode}.end());
return _wfopen(path.c_str(), wmode.c_str());
#else
return fopen(filename, mode);
#endif
}

// string literals
using namespace std::string_literals;

Expand Down Expand Up @@ -348,7 +359,7 @@ bool load_ply(const string& filename, ply_model* ply, string& error) {
};

// open file
auto fs = fopen(filename.c_str(), "rb");
auto fs = fopen_utf8(filename.c_str(), "rb");
if (!fs) return open_error();
auto fs_guard = std::unique_ptr<FILE, decltype(&fclose)>{fs, fclose};

Expand Down Expand Up @@ -608,7 +619,7 @@ bool save_ply(const string& filename, ply_model* ply, string& error) {
};

// open file
auto fs = fopen(filename.c_str(), "wb");
auto fs = fopen_utf8(filename.c_str(), "wb");
if (!fs) return open_error();
auto fs_guard = std::unique_ptr<FILE, decltype(&fclose)>{fs, fclose};

Expand Down Expand Up @@ -1436,7 +1447,7 @@ inline void remove_obj_comment(string_view& str, char comment_char = '#') {
};

// open file
auto fs = fopen(filename.c_str(), "rt");
auto fs = fopen_utf8(filename.c_str(), "rt");
if (!fs) return open_error();
auto fs_guard = std::unique_ptr<FILE, decltype(&fclose)>{fs, fclose};

Expand Down Expand Up @@ -1676,7 +1687,7 @@ inline void remove_obj_comment(string_view& str, char comment_char = '#') {
};

// open file
auto fs = fopen(filename.c_str(), "rt");
auto fs = fopen_utf8(filename.c_str(), "rt");
if (!fs) return open_error();
auto fs_guard = std::unique_ptr<FILE, decltype(&fclose)>{fs, fclose};

Expand Down Expand Up @@ -1782,7 +1793,7 @@ bool load_obj(const string& filename, obj_model* obj, string& error,
};

// open file
auto fs = fopen(filename.c_str(), "rt");
auto fs = fopen_utf8(filename.c_str(), "rt");
if (!fs) return open_error();
auto fs_guard = std::unique_ptr<FILE, decltype(&fclose)>{fs, fclose};

Expand Down Expand Up @@ -2015,7 +2026,7 @@ inline void format_obj_value(string& str, const obj_vertex& value) {
};

// open file
auto fs = fopen(filename.c_str(), "wt");
auto fs = fopen_utf8(filename.c_str(), "wt");
if (!fs) return open_error();
auto fs_guard = std::unique_ptr<FILE, decltype(&fclose)>{fs, fclose};

Expand Down Expand Up @@ -2196,7 +2207,7 @@ inline void format_obj_value(string& str, const obj_vertex& value) {
};

// open file
auto fs = fopen(filename.c_str(), "wt");
auto fs = fopen_utf8(filename.c_str(), "wt");
if (!fs) return open_error();
auto fs_guard = std::unique_ptr<FILE, decltype(&fclose)>{fs, fclose};

Expand Down Expand Up @@ -2260,7 +2271,7 @@ inline void format_obj_value(string& str, const obj_vertex& value) {
};

// open file
auto fs = fopen(filename.c_str(), "wt");
auto fs = fopen_utf8(filename.c_str(), "wt");
if (!fs) throw std::runtime_error{filename + ": file not found"};
auto fs_guard = std::unique_ptr<FILE, decltype(&fclose)>{fs, fclose};

Expand Down Expand Up @@ -4468,7 +4479,7 @@ struct pbrt_context {
};

// open file
auto fs = fopen(filename.c_str(), "rt");
auto fs = fopen_utf8(filename.c_str(), "rt");
if (!fs) return open_error();
auto fs_guard = std::unique_ptr<FILE, decltype(&fclose)>{fs, fclose};

Expand Down Expand Up @@ -4883,7 +4894,7 @@ bool save_pbrt(
};

// open file
auto fs = fopen(filename.c_str(), "wt");
auto fs = fopen_utf8(filename.c_str(), "wt");
if (!fs) return open_error();
auto fs_guard = std::unique_ptr<FILE, decltype(&fclose)>{fs, fclose};

Expand Down
Loading

0 comments on commit bdd7b88

Please sign in to comment.