Fix T70952: EXR files bigger than 2GB don't open on Windows

This commit is contained in:
Brecht Van Lommel 2019-11-06 17:16:46 +01:00
parent 65b414cfb2
commit 64cd9a079b
3 changed files with 24 additions and 6 deletions

@ -125,8 +125,11 @@ void *mmap(void *UNUSED(start), size_t len, int prot, int flags, int fd, off_t o
}
}
/* note len is passed to a 32 bit DWORD, so can't be > 4 GB */
maphandle = CreateFileMapping(fhandle, NULL, prot_flags, 0, len, NULL);
/* Split 64 bit size into low and high bits. */
DWORD len_bits_high = len >> 32;
DWORD len_bits_low = len & 0xFFFFFFFF;
maphandle = CreateFileMapping(fhandle, NULL, prot_flags, len_bits_high, len_bits_low, NULL);
if (maphandle == 0) {
errno = EBADF;
return MAP_FAILED;

@ -67,6 +67,7 @@ typedef struct _stat BLI_stat_t;
typedef struct stat BLI_stat_t;
#endif
int BLI_fstat(int fd, BLI_stat_t *buffer) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
int BLI_stat(const char *path, BLI_stat_t *buffer) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
#ifdef WIN32
int BLI_wstat(const wchar_t *path, BLI_stat_t *buffer);

@ -180,8 +180,8 @@ double BLI_dir_free_space(const char *dir)
*/
size_t BLI_file_descriptor_size(int file)
{
struct stat st;
if ((file < 0) || (fstat(file, &st) == -1)) {
BLI_stat_t st;
if ((file < 0) || (BLI_fstat(file, &st) == -1)) {
return -1;
}
return st.st_size;
@ -246,6 +246,15 @@ int BLI_exists(const char *name)
}
#ifdef WIN32
int BLI_fstat(int fd, BLI_stat_t *buffer)
{
# if defined(_MSC_VER)
return _fstat64(fd, buffer);
# else
return _fstat(fd, buffer);
# endif
}
int BLI_stat(const char *path, BLI_stat_t *buffer)
{
int r;
@ -266,6 +275,11 @@ int BLI_wstat(const wchar_t *path, BLI_stat_t *buffer)
# endif
}
#else
int BLI_fstat(int fd, struct stat *buffer)
{
return fstat(fd, buffer);
}
int BLI_stat(const char *path, struct stat *buffer)
{
return stat(path, buffer);
@ -298,8 +312,8 @@ static void *file_read_data_as_mem_impl(FILE *fp,
size_t pad_bytes,
size_t *r_size)
{
struct stat st;
if (fstat(fileno(fp), &st) == -1) {
BLI_stat_t st;
if (BLI_fstat(fileno(fp), &st) == -1) {
return NULL;
}
if (S_ISDIR(st.st_mode)) {