From 54e83914937f1ebb08fd13e36ec15f53e1c1326d Mon Sep 17 00:00:00 2001 From: jkriege2 Date: Wed, 8 May 2024 15:14:34 +0200 Subject: [PATCH] improved support for large files (>2GB) --- src/CMakeLists.txt | 16 +++++++++++++++ src/tinytiff_ctools_internal.h | 8 ++++++++ src/tinytiffreader.c | 30 +++++++++++++-------------- src/tinytiffwriter.c | 37 +++++++++++++++++----------------- 4 files changed, 58 insertions(+), 33 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ff6eeaa..1e77c07 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -41,6 +41,10 @@ check_symbol_exists(strcat_s "string.h" HAVE_STRCAT_S) check_symbol_exists(memcpy_s "string.h" HAVE_MEMCPY_S) check_symbol_exists(memset_s "string.h" HAVE_MEMSET_S) check_symbol_exists(strnlen_s "string.h" HAVE_STRNLEN_S) +check_symbol_exists(_ftelli64 "stdio.h" HAVE_FTELLI64) +check_symbol_exists(_fseeki64 "stdio.h" HAVE_FSEEKI64) +check_symbol_exists(ftello64 "stdio.h" HAVE_FTELLO64) +check_symbol_exists(fseeko64 "stdio.h" HAVE_FSEEKO64) @@ -95,6 +99,18 @@ endif() if (HAVE_STRNLEN_S) target_compile_definitions(${lib_name} PRIVATE HAVE_STRNLEN_S) endif() +if (HAVE_FTELLI64) + target_compile_definitions(${lib_name} PRIVATE HAVE_FTELLI64) +endif() +if (HAVE_FSEEKI64) + target_compile_definitions(${lib_name} PRIVATE HAVE_FSEEKI64) +endif() +if (HAVE_FTELLO64) + target_compile_definitions(${lib_name} PRIVATE HAVE_FTELLO64) +endif() +if (HAVE_FSEEKO64) + target_compile_definitions(${lib_name} PRIVATE HAVE_FSEEKO64) +endif() add_library(${lib_nameXX} INTERFACE) diff --git a/src/tinytiff_ctools_internal.h b/src/tinytiff_ctools_internal.h index 0e751f2..6837676 100644 --- a/src/tinytiff_ctools_internal.h +++ b/src/tinytiff_ctools_internal.h @@ -21,6 +21,14 @@ #ifndef TINYTIFF_CTOOLS_INTERNAL_H #define TINYTIFF_CTOOLS_INTERNAL_H +#if defined(HAVE_FTELLI64) || defined(HAVE_FTELLO64) +# define TINYTIFF_MAX_FILE_SIZE (0xFFFFFFFE) +#else +# warning COMPILING TinyTIFFWriter without LARGE_FILE_SUPPORT ... File size is limited to 2GB! +# define TINYTIFF_MAX_FILE_SIZE (2*1024*1024*1024-1) +#endif + + #if defined(__has_builtin) # if __has_builtin(__builtin_object_size) # define tinytiff_builtin_object_size(ptr) __builtin_object_size(ptr, 2) diff --git a/src/tinytiffreader.c b/src/tinytiffreader.c index 5ee4627..2cf2aa8 100644 --- a/src/tinytiffreader.c +++ b/src/tinytiffreader.c @@ -235,7 +235,7 @@ int TinyTIFFReader_fOK(const TinyTIFFReaderFile* tiff) { #endif // TINYTIFF_USE_WINAPI_FOR_FILEIO } -int TinyTIFFReader_fseek_set(TinyTIFFReaderFile* tiff, unsigned long offset) { +int TinyTIFFReader_fseek_set(TinyTIFFReaderFile* tiff, long long offset) { #ifdef TINYTIFF_USE_WINAPI_FOR_FILEIO DWORD res = SetFilePointer (tiff->hFile, offset, @@ -245,11 +245,18 @@ int TinyTIFFReader_fseek_set(TinyTIFFReaderFile* tiff, unsigned long offset) { return res; #else +# ifdef HAVE_FSEEKO64 + return fseeko64(tiff->file, offset, SEEK_SET); +# elif defined(HAVE_FSEEKI64) + return _fseeki64(tiff->file, offset, SEEK_SET); +# else return fseek(tiff->file, (long)offset, SEEK_SET); +# endif + #endif // TINYTIFF_USE_WINAPI_FOR_FILEIO } -int TinyTIFFReader_fseek_cur(TinyTIFFReaderFile* tiff, unsigned long offset) { +int TinyTIFFReader_fseek_cur(TinyTIFFReaderFile* tiff, long long offset) { #ifdef TINYTIFF_USE_WINAPI_FOR_FILEIO DWORD res = SetFilePointer (tiff->hFile, offset, @@ -259,7 +266,13 @@ int TinyTIFFReader_fseek_cur(TinyTIFFReaderFile* tiff, unsigned long offset) { return res; #else +# ifdef HAVE_FSEEKO64 + return fseeko64(tiff->file, offset, SEEK_CUR); +# elif defined(HAVE_FSEEKI64) + return _fseeki64(tiff->file, offset, SEEK_CUR); +# else return fseek(tiff->file, (long)offset, SEEK_CUR); +# endif #endif // TINYTIFF_USE_WINAPI_FOR_FILEIO } @@ -279,19 +292,6 @@ unsigned long TinyTIFFReader_fread(void * ptr, unsigned long ptrsize, unsigned l #endif // TINYTIFF_USE_WINAPI_FOR_FILEIO } -#ifdef ENABLE_UNUSED_TinyTIFFReader_ftell // Silence "unused" warning -static long int TinyTIFFReader_ftell ( TinyTIFFReaderFile * tiff ) { -#ifdef TINYTIFF_USE_WINAPI_FOR_FILEIO -DWORD dwPtr = SetFilePointer( tiff->hFile, - 0, - NULL, - FILE_CURRENT ); - return dwPtr; -#else - return ftell(tiff->file); -#endif -} -#endif int TinyTIFFReader_fgetpos(TinyTIFFReaderFile* tiff, TinyTIFFReader_POSTYPE* pos) { #ifdef TINYTIFF_USE_WINAPI_FOR_FILEIO diff --git a/src/tinytiffwriter.c b/src/tinytiffwriter.c index 82cd2dd..1b25379 100644 --- a/src/tinytiffwriter.c +++ b/src/tinytiffwriter.c @@ -57,6 +57,7 @@ #endif // TINYTIFF_USE_WINAPI_FOR_FILEIO + #define TINYTIFFWRITER_DESCRIPTION_SIZE 1024 #define TIFF_LAST_ERROR_SIZE 1024 @@ -216,7 +217,7 @@ static size_t TinyTIFFWriter_fwrite(const void * ptr, size_t size, size_t count, \ingroup tinytiffwriter_internal \internal */ -static long long TinyTIFFWriter_ftell ( TinyTIFFWriterFile * tiff ) { +static int64_t TinyTIFFWriter_ftell ( TinyTIFFWriterFile * tiff ) { #ifdef TINYTIFF_USE_WINAPI_FOR_FILEIO DWORD dwPtr = SetFilePointer( tiff->hFile, 0, @@ -224,28 +225,22 @@ DWORD dwPtr = SetFilePointer( tiff->hFile, FILE_CURRENT ); return dwPtr; #else +# ifdef HAVE_FTELLO64 + return ftello64(tiff->file); +# elif defined(HAVE_FTELLI64) + return _ftelli64(tiff->file); +# else return ftell(tiff->file); +# endif #endif } -int TinyTIFFWriter_fgetpos(TinyTIFFWriterFile* tiff, TinyTIFFWriter_POSTYPE* pos) { -#ifdef TINYTIFF_USE_WINAPI_FOR_FILEIO - *pos= SetFilePointer( tiff->hFile, - 0, - NULL, - FILE_CURRENT ); - return 0; -#else - return fgetpos(tiff->file, pos); -#endif // TINYTIFF_USE_WINAPI_FOR_FILEIO -} - /*! \brief wrapper around fseek \ingroup tinytiffwriter_internal \internal */ -static int TinyTIFFWriter_fseek_set(TinyTIFFWriterFile* tiff, size_t offset) { +static int TinyTIFFWriter_fseek_set(TinyTIFFWriterFile* tiff, long long offset) { #ifdef TINYTIFF_USE_WINAPI_FOR_FILEIO DWORD res = SetFilePointer (tiff->hFile, offset, @@ -255,7 +250,13 @@ static int TinyTIFFWriter_fseek_set(TinyTIFFWriterFile* tiff, size_t offset) { return res; #else +# ifdef HAVE_FSEEKO64 + return fseeko64(tiff->file, offset, SEEK_SET); +# elif defined(HAVE_FSEEKI64) + return _fseeki64(tiff->file, offset, SEEK_SET); +# else return fseek(tiff->file, (long)offset, SEEK_SET); +# endif #endif // TINYTIFF_USE_WINAPI_FOR_FILEIO } @@ -972,10 +973,10 @@ int TinyTIFFWriter_writeImageMultiSample(TinyTIFFWriterFile *tiff, const void *d TinyTIFFWriter_writeIFDEntrySHORT(tiff, TIFF_FIELD_SAMPLEFORMAT, tiff->sampleformat); TinyTIFFWriter_endIFD(tiff, hsize); - TinyTIFFWriter_POSTYPE datapos=0; TinyTIFFWriter_fgetpos(tiff, &datapos); - const TinyTIFFWriter_POSTYPE data_size_expected=tiff->width*tiff->height*tiff->samples*(tiff->bitspersample/8); - const TinyTIFFWriter_POSTYPE expected_endpos=datapos+data_size_expected; - const TinyTIFFWriter_POSTYPE max_endpos=(((TinyTIFFWriter_POSTYPE)0xFFFFFFFF)-(TinyTIFFWriter_POSTYPE)1024); + const int64_t datapos=TinyTIFFWriter_ftell(tiff); + const int64_t data_size_expected=tiff->width*tiff->height*tiff->samples*(tiff->bitspersample/8); + const int64_t expected_endpos=datapos+data_size_expected; + const int64_t max_endpos=(((int64_t)TINYTIFF_MAX_FILE_SIZE)-(int64_t)1024); if (expected_endpos>=max_endpos) { tiff->wasError=TINYTIFF_TRUE; TINYTIFF_SET_LAST_ERROR(tiff, "trying to write behind end of file in TinyTIFFWriter_writeImage() (i.e. too many of a too big frame)\0");