Skip to content

Commit b6bbf37

Browse files
committed
.
1 parent 8753642 commit b6bbf37

1 file changed

Lines changed: 38 additions & 7 deletions

File tree

CImg.h

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5795,21 +5795,52 @@ namespace cimg_library {
57955795
**/
57965796
inline cimg_int64 fsize(std::FILE *const file) {
57975797
if (!file) return (cimg_int64)-1;
5798-
const cimg_long pos = std::ftell(file);
5799-
cimg::fseek(file,0,SEEK_END);
5800-
const cimg_int64 siz = (cimg_int64)std::ftell(file);
5801-
cimg::fseek(file,pos,SEEK_SET);
5798+
5799+
#if cimg_OS==1 // Optimized for POSIX Environements (Linux, macOS, BSD, etc.)
5800+
const int fd = fileno(file);
5801+
struct stat st;
5802+
if (fd>=0 && !fstat(fd,&st)) return (cimg_int64)st.st_size;
5803+
#elif cimg_OS==2 // Optimized for Windows Environements (MSVC, MinGW)
5804+
const int fd = _fileno(file);
5805+
struct _stati64 st;
5806+
if (fd>=0 && !_fstati64(fd,&st)) return (cimg_int64)st.st_size;
5807+
#endif
5808+
5809+
// Fallback, used for non-POSIX systems or if fstat failed (pipes or sockets).
5810+
const cimg_long pos = cimg::ftell(file);
5811+
cimg::fseek(file, 0, SEEK_END);
5812+
const cimg_int64 siz = (cimg_int64)cimg::ftell(file);
5813+
cimg::fseek(file, pos, SEEK_SET);
58025814
return siz;
58035815
}
58045816

5817+
//! Get file size from filename.
58055818
inline cimg_int64 fsize(const char *const filename) {
5806-
std::FILE *const file = cimg::std_fopen(filename,"rb");
5819+
if (!filename || !*filename) return (cimg_int64)-1;
5820+
5821+
#if cimg_OS==1 // Optimized for POSIX Environements (Linux, macOS, BSD, etc.)
5822+
struct stat st;
5823+
if (!stat(filename,&st)) return (cimg_int64)st.st_size;
5824+
#elif cimg_OS==2 // Optimized for Windows Environements (MSVC, MinGW)
5825+
// Convert UTF-8 path to wchar_t.
5826+
int len = MultiByteToWideChar(CP_UTF8,0,filename,-1,0,0);
5827+
if (len>0) {
5828+
CImg<wchar_t> wfilename((unsigned int)len);
5829+
if (MultiByteToWideChar(CP_UTF8,0,filename,-1,wfilename,len)) {
5830+
struct _stati64 st;
5831+
if (!_wstati64(wfilename,&st)) return (cimg_int64)st.st_size;
5832+
}
5833+
}
5834+
#endif
5835+
5836+
// Fallback.
5837+
std::FILE *const file = cimg::fopen(filename, "rb");
5838+
if (!file) return (cimg_int64)-1;
58075839
const cimg_int64 siz = fsize(file);
58085840
cimg::fclose(file);
58095841
return siz;
58105842
}
58115843

5812-
58135844
// Thread-safe version of std::localtime().
58145845
inline struct tm* localtime(const time_t *const time_ptr, struct tm *const result) {
58155846
#if cimg_OS==2
@@ -65308,7 +65339,7 @@ namespace cimg_library {
6530865339
(Ts2 && !cimg::strcasecmp(Ts2,str_pixeltype)) || \
6530965340
(Ts3 && !cimg::strcasecmp(Ts3,str_pixeltype)))) { \
6531065341
for (unsigned int l = 0; l<=nn1; ++l) { \
65311-
j = 0; while ((i=std::fgetc(nfile))!='\n' && i>=0 && j<255) tmp[j++] = (char)i; tmp[j] = 0;
65342+
j = 0; while ((i=std::fgetc(nfile))!='\n' && i>=0 && j<255) tmp[j++] = (char)i; tmp[j] = 0; \
6531265343
W = H = D = C = 0; \
6531365344
if (cimg_sscanf(tmp._data,"%d %d %d %d",&W,&H,&D,&C)!=4) \
6531465345
throw CImgIOException(_cimglist_instance \

0 commit comments

Comments
 (0)