Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 35 additions & 11 deletions CImg.h
Original file line number Diff line number Diff line change
Expand Up @@ -5735,6 +5735,7 @@ namespace cimg_library {
// Get the file or directory attributes with support for UTF-8 paths (Windows only).
#if cimg_OS==2
inline DWORD win_getfileattributes(const char *const path);
inline BOOL win_getfileattributesEx(const char* const path, WIN32_FILE_ATTRIBUTE_DATA* attr);
#endif

//! Check if a path is a directory.
Expand Down Expand Up @@ -67570,24 +67571,24 @@ namespace cimg_library {
\return File size or '-1' if file does not exist.
**/
inline cimg_int64 fsize(std::FILE *const file) {
if (!file) return (cimg_int64)-1;
cimg_int64 siz = -1;
if (!file) return siz;

#if cimg_OS==1 // Optimized for POSIX Environments (Linux, macOS, BSD, etc.)
const int fd = fileno(file);
struct stat st;
if (fd>=0 && !fstat(fd,&st)) return (cimg_int64)st.st_size;
#elif cimg_OS==2 // Optimized for Windows Environments (MSVC, MinGW)
if (!fstat(fd,&st)) siz = (cimg_int64)st.st_size;
#elif cimg_OS==2 // Optimized for Windows Environements (MSVC, MinGW)
const int fd = _fileno(file);
if (fd>=0) {
const cimg_int64 siz = (cimg_int64)_filelengthi64(fd);
if (siz>=0) return siz;
}
siz = (cimg_int64)_filelengthi64(fd);
#endif
// Fallback, used for non-POSIX systems or if fstat failed (pipes or sockets).
const cimg_long pos = cimg::ftell(file);
cimg::fseek(file,0,SEEK_END);
const cimg_int64 siz = (cimg_int64)cimg::ftell(file);
cimg::fseek(file,pos,SEEK_SET);
if (siz < 0) {
const cimg_long pos = cimg::ftell(file);
cimg::fseek(file, 0, SEEK_END);
siz = (cimg_int64)cimg::ftell(file);
cimg::fseek(file, pos, SEEK_SET);
}
return siz;
}

Expand All @@ -67602,6 +67603,16 @@ namespace cimg_library {
#if cimg_OS==1 // Optimized for POSIX Environments (Linux, macOS, BSD, etc.)
struct stat st;
if (!stat(filename,&st)) return (cimg_int64)st.st_size;
#elif cimg_OS==2
WIN32_FILE_ATTRIBUTE_DATA attr;
if (win_getfileattributesEx(filename, &attr)) {
if (!(attr.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
LARGE_INTEGER size;
size.HighPart = attr.nFileSizeHigh;
size.LowPart = attr.nFileSizeLow;
return (cimg_int64)size.QuadPart;
}
}
#endif
// Fallback for other systems.
std::FILE *const file = cimg::std_fopen(filename, "rb");
Expand Down Expand Up @@ -67694,6 +67705,19 @@ namespace cimg_library {
}
return res;
}

inline BOOL win_getfileattributesEx(const char* const path, WIN32_FILE_ATTRIBUTE_DATA* attr) {
BOOL res = GetFileAttributesExA(path, GetFileExInfoStandard, attr);
if (!res) {
// Try alternative method, with wide-character string.
int err = MultiByteToWideChar(CP_UTF8, 0, path, -1, 0, 0);
if (err) {
CImg<wchar_t> wpath((unsigned int)err);
if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, err)) res = GetFileAttributesExW(wpath, GetFileExInfoStandard, attr);
}
}
return res;
}
#endif

//! Get/set path to the <i>Program Files/</i> directory (Windows only).
Expand Down