windowscodecs: Workaround libtiff bug when it defines toff_t as 32-bit for 32-bit builds. Take 2.
Dmitry Timoshkov
dmitry at baikal.ru
Sat Jul 27 04:16:34 CDT 2013
This version of the patch detetcs libtiff version at run-time and uses
v3 or v4 compatible callbacks depending on currently loaded libtiff version.
---
dlls/windowscodecs/tiffformat.c | 65 +++++++++++++++++++++++++++++++++++------
1 file changed, 56 insertions(+), 9 deletions(-)
diff --git a/dlls/windowscodecs/tiffformat.c b/dlls/windowscodecs/tiffformat.c
index 62f1ad7..c69658f 100644
--- a/dlls/windowscodecs/tiffformat.c
+++ b/dlls/windowscodecs/tiffformat.c
@@ -57,12 +57,14 @@ static CRITICAL_SECTION init_tiff_cs = { &init_tiff_cs_debug, -1, 0, 0, 0, 0 };
static const WCHAR wszTiffCompressionMethod[] = {'T','i','f','f','C','o','m','p','r','e','s','s','i','o','n','M','e','t','h','o','d',0};
static const WCHAR wszCompressionQuality[] = {'C','o','m','p','r','e','s','s','i','o','n','Q','u','a','l','i','t','y',0};
+static unsigned libtiff_ver_n = 4;
static void *libtiff_handle;
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
MAKE_FUNCPTR(TIFFClientOpen);
MAKE_FUNCPTR(TIFFClose);
MAKE_FUNCPTR(TIFFCurrentDirOffset);
MAKE_FUNCPTR(TIFFGetField);
+MAKE_FUNCPTR(TIFFGetVersion);
MAKE_FUNCPTR(TIFFIsByteSwapped);
MAKE_FUNCPTR(TIFFNumberOfDirectories);
MAKE_FUNCPTR(TIFFReadDirectory);
@@ -85,6 +87,7 @@ static void *load_libtiff(void)
{
void * (*pTIFFSetWarningHandler)(void *);
void * (*pTIFFSetWarningHandlerExt)(void *);
+ const char *libtiff_version_str;
#define LOAD_FUNCPTR(f) \
if((p##f = wine_dlsym(libtiff_handle, #f, NULL, 0)) == NULL) { \
@@ -97,6 +100,7 @@ static void *load_libtiff(void)
LOAD_FUNCPTR(TIFFClose);
LOAD_FUNCPTR(TIFFCurrentDirOffset);
LOAD_FUNCPTR(TIFFGetField);
+ LOAD_FUNCPTR(TIFFGetVersion);
LOAD_FUNCPTR(TIFFIsByteSwapped);
LOAD_FUNCPTR(TIFFNumberOfDirectories);
LOAD_FUNCPTR(TIFFReadDirectory);
@@ -108,6 +112,21 @@ static void *load_libtiff(void)
LOAD_FUNCPTR(TIFFWriteScanline);
#undef LOAD_FUNCPTR
+ libtiff_version_str = pTIFFGetVersion();
+ if (libtiff_version_str)
+ {
+ const char *ver_str;
+
+ TRACE("libtiff version: %s\n", libtiff_version_str);
+ ver_str = strstr(libtiff_version_str, "Version ");
+ if (ver_str)
+ {
+ ver_str += 8; /* "Version " */
+ libtiff_ver_n = atoi(ver_str);
+ TRACE("libtiff version: %u\n", libtiff_ver_n);
+ }
+ }
+
if ((pTIFFSetWarningHandler = wine_dlsym(libtiff_handle, "TIFFSetWarningHandler", NULL, 0)))
pTIFFSetWarningHandler(NULL);
if ((pTIFFSetWarningHandlerExt = wine_dlsym(libtiff_handle, "TIFFSetWarningHandlerExt", NULL, 0)))
@@ -120,7 +139,8 @@ static void *load_libtiff(void)
return result;
}
-static tsize_t tiff_stream_read(thandle_t client_data, tdata_t data, tsize_t size)
+/* libbtiff 4.0 compatible callbacks */
+static UINT32 tiff_stream_read(thandle_t client_data, tdata_t data, UINT32 size)
{
IStream *stream = (IStream*)client_data;
ULONG bytes_read;
@@ -131,7 +151,7 @@ static tsize_t tiff_stream_read(thandle_t client_data, tdata_t data, tsize_t siz
return bytes_read;
}
-static tsize_t tiff_stream_write(thandle_t client_data, tdata_t data, tsize_t size)
+static UINT32 tiff_stream_write(thandle_t client_data, tdata_t data, UINT32 size)
{
IStream *stream = (IStream*)client_data;
ULONG bytes_written;
@@ -142,7 +162,7 @@ static tsize_t tiff_stream_write(thandle_t client_data, tdata_t data, tsize_t si
return bytes_written;
}
-static toff_t tiff_stream_seek(thandle_t client_data, toff_t offset, int whence)
+static UINT64 tiff_stream_seek(thandle_t client_data, UINT64 offset, int whence)
{
IStream *stream = (IStream*)client_data;
LARGE_INTEGER move;
@@ -178,7 +198,7 @@ static int tiff_stream_close(thandle_t client_data)
return 0;
}
-static toff_t tiff_stream_size(thandle_t client_data)
+static UINT64 tiff_stream_size(thandle_t client_data)
{
IStream *stream = (IStream*)client_data;
STATSTG statstg;
@@ -190,13 +210,35 @@ static toff_t tiff_stream_size(thandle_t client_data)
else return -1;
}
-static int tiff_stream_map(thandle_t client_data, tdata_t *addr, toff_t *size)
+static int tiff_stream_map(thandle_t client_data, tdata_t *addr, UINT64 *size)
+{
+ /* Cannot mmap streams */
+ return 0;
+}
+
+static void tiff_stream_unmap(thandle_t client_data, tdata_t addr, UINT64 size)
+{
+ /* No need to ever do this, since we can't map things. */
+}
+
+/* libbtiff 3.0 compatible callbacks */
+static UINT32 tiff_stream_seek_v3(thandle_t client_data, UINT32 offset, int whence)
+{
+ return tiff_stream_seek(client_data, offset, whence);
+}
+
+static UINT32 tiff_stream_size_v3(thandle_t client_data)
+{
+ return tiff_stream_size(client_data);
+}
+
+static int tiff_stream_map_v3(thandle_t client_data, tdata_t *addr, UINT32 *size)
{
/* Cannot mmap streams */
return 0;
}
-static void tiff_stream_unmap(thandle_t client_data, tdata_t addr, toff_t size)
+static void tiff_stream_unmap_v3(thandle_t client_data, tdata_t addr, UINT32 size)
{
/* No need to ever do this, since we can't map things. */
}
@@ -208,9 +250,14 @@ static TIFF* tiff_open_stream(IStream *stream, const char *mode)
zero.QuadPart = 0;
IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
- return pTIFFClientOpen("<IStream object>", mode, stream, tiff_stream_read,
- tiff_stream_write, tiff_stream_seek, tiff_stream_close,
- tiff_stream_size, tiff_stream_map, tiff_stream_unmap);
+ if (libtiff_ver_n < 4)
+ return pTIFFClientOpen("<IStream object>", mode, stream, (void *)tiff_stream_read,
+ (void *)tiff_stream_write, (void *)tiff_stream_seek_v3, tiff_stream_close,
+ (void *)tiff_stream_size_v3, (void *)tiff_stream_map_v3, (void *)tiff_stream_unmap_v3);
+
+ return pTIFFClientOpen("<IStream object>", mode, stream, (void *)tiff_stream_read,
+ (void *)tiff_stream_write, (void *)tiff_stream_seek, tiff_stream_close,
+ (void *)tiff_stream_size, (void *)tiff_stream_map, (void *)tiff_stream_unmap);
}
typedef struct {
--
1.8.3.3
More information about the wine-patches
mailing list