#ifdef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
#undef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
#endif
#include "tiffiop.h"
#include <stdlib.h>
#include <windows.h>
static inline thandle_t thandle_from_int(int ifd)
{
return (thandle_t)(intptr_t)ifd;
}
static inline int thandle_to_int(thandle_t fd) { return (int)(intptr_t)fd; }
static tmsize_t _tiffReadProc(thandle_t fd, void *buf, tmsize_t size)
{
uint8_t *ma;
uint64_t mb;
DWORD n;
DWORD o;
tmsize_t p;
ma = (uint8_t *)buf;
mb = size;
p = 0;
while (mb > 0)
{
n = 0x80000000UL;
if ((uint64_t)n > mb)
n = (DWORD)mb;
if (!ReadFile(fd, (LPVOID)ma, n, &o, NULL))
return (0);
ma += o;
mb -= o;
p += o;
if (o != n)
break;
}
return (p);
}
static tmsize_t _tiffWriteProc(thandle_t fd, void *buf, tmsize_t size)
{
uint8_t *ma;
uint64_t mb;
DWORD n;
DWORD o;
tmsize_t p;
ma = (uint8_t *)buf;
mb = size;
p = 0;
while (mb > 0)
{
n = 0x80000000UL;
if ((uint64_t)n > mb)
n = (DWORD)mb;
if (!WriteFile(fd, (LPVOID)ma, n, &o, NULL))
return (0);
ma += o;
mb -= o;
p += o;
if (o != n)
break;
}
return (p);
}
static uint64_t _tiffSeekProc(thandle_t fd, uint64_t off, int whence)
{
LARGE_INTEGER offli;
DWORD dwMoveMethod;
offli.QuadPart = off;
switch (whence)
{
case SEEK_SET:
dwMoveMethod = FILE_BEGIN;
break;
case SEEK_CUR:
dwMoveMethod = FILE_CURRENT;
break;
case SEEK_END:
dwMoveMethod = FILE_END;
break;
default:
dwMoveMethod = FILE_BEGIN;
break;
}
offli.LowPart =
SetFilePointer(fd, offli.LowPart, &offli.HighPart, dwMoveMethod);
if ((offli.LowPart == INVALID_SET_FILE_POINTER) &&
(GetLastError() != NO_ERROR))
offli.QuadPart = 0;
return (offli.QuadPart);
}
static int _tiffCloseProc(thandle_t fd) { return (CloseHandle(fd) ? 0 : -1); }
static uint64_t _tiffSizeProc(thandle_t fd)
{
LARGE_INTEGER m;
if (GetFileSizeEx(fd, &m))
return (m.QuadPart);
else
return (0);
}
static int _tiffDummyMapProc(thandle_t fd, void **pbase, toff_t *psize)
{
(void)fd;
(void)pbase;
(void)psize;
return (0);
}
static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize)
{
uint64_t size;
tmsize_t sizem;
HANDLE hMapFile;
size = _tiffSizeProc(fd);
sizem = (tmsize_t)size;
if (!size || (uint64_t)sizem != size)
return (0);
hMapFile = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, 0, NULL);
if (hMapFile == NULL)
return (0);
*pbase = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);
CloseHandle(hMapFile);
if (*pbase == NULL)
return (0);
*psize = size;
return (1);
}
static void _tiffDummyUnmapProc(thandle_t fd, void *base, toff_t size)
{
(void)fd;
(void)base;
(void)size;
}
static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size)
{
(void)fd;
(void)size;
UnmapViewOfFile(base);
}
TIFF *TIFFFdOpen(int ifd, const char *name, const char *mode)
{
return TIFFFdOpenExt(ifd, name, mode, NULL);
}
TIFF *TIFFFdOpenExt(int ifd, const char *name, const char *mode,
TIFFOpenOptions *opts)
{
TIFF *tif;
int fSuppressMap;
int m;
fSuppressMap = 0;
for (m = 0; mode[m] != 0; m++)
{
if (mode[m] == 'u')
{
fSuppressMap = 1;
break;
}
}
tif = TIFFClientOpenExt(
name, mode, thandle_from_int(ifd), _tiffReadProc, _tiffWriteProc,
_tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
fSuppressMap ? _tiffDummyMapProc : _tiffMapProc,
fSuppressMap ? _tiffDummyUnmapProc : _tiffUnmapProc, opts);
if (tif)
tif->tif_fd = ifd;
return (tif);
}
#ifndef _WIN32_WCE
TIFF *TIFFOpen(const char *name, const char *mode)
{
return TIFFOpenExt(name, mode, NULL);
}
TIFF *TIFFOpenExt(const char *name, const char *mode, TIFFOpenOptions *opts)
{
static const char module[] = "TIFFOpen";
thandle_t fd;
int m;
DWORD dwMode;
TIFF *tif;
m = _TIFFgetMode(opts, NULL, mode, module);
switch (m)
{
case O_RDONLY:
dwMode = OPEN_EXISTING;
break;
case O_RDWR:
dwMode = OPEN_EXISTING;
break;
case O_RDWR | O_CREAT:
dwMode = OPEN_ALWAYS;
break;
case O_RDWR | O_TRUNC:
dwMode = CREATE_ALWAYS;
break;
case O_RDWR | O_CREAT | O_TRUNC:
dwMode = CREATE_ALWAYS;
break;
default:
return ((TIFF *)0);
}
fd = (thandle_t)CreateFileA(
name, (m == O_RDONLY) ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE),
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode,
(m == O_RDONLY) ? FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_NORMAL,
NULL);
if (fd == INVALID_HANDLE_VALUE)
{
_TIFFErrorEarly(opts, NULL, module, "%s: Cannot open", name);
return ((TIFF *)0);
}
tif = TIFFFdOpenExt(thandle_to_int(fd), name, mode, opts);
if (!tif)
CloseHandle(fd);
return tif;
}
TIFF *TIFFOpenW(const wchar_t *name, const char *mode)
{
return TIFFOpenWExt(name, mode, NULL);
}
TIFF *TIFFOpenWExt(const wchar_t *name, const char *mode, TIFFOpenOptions *opts)
{
static const char module[] = "TIFFOpenW";
thandle_t fd;
int m;
DWORD dwMode;
int mbsize;
char *mbname;
TIFF *tif;
m = _TIFFgetMode(opts, NULL, mode, module);
switch (m)
{
case O_RDONLY:
dwMode = OPEN_EXISTING;
break;
case O_RDWR:
dwMode = OPEN_EXISTING;
break;
case O_RDWR | O_CREAT:
dwMode = OPEN_ALWAYS;
break;
case O_RDWR | O_TRUNC:
dwMode = CREATE_ALWAYS;
break;
case O_RDWR | O_CREAT | O_TRUNC:
dwMode = CREATE_ALWAYS;
break;
default:
return ((TIFF *)0);
}
fd = (thandle_t)CreateFileW(
name, (m == O_RDONLY) ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE),
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode,
(m == O_RDONLY) ? FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_NORMAL,
NULL);
if (fd == INVALID_HANDLE_VALUE)
{
_TIFFErrorEarly(opts, NULL, module, "%S: Cannot open", name);
return ((TIFF *)0);
}
mbname = NULL;
mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL);
if (mbsize > 0)
{
mbname = (char *)_TIFFmalloc(mbsize);
if (!mbname)
{
_TIFFErrorEarly(
opts, NULL, module,
"Can't allocate space for filename conversion buffer");
return ((TIFF *)0);
}
WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, NULL, NULL);
}
tif = TIFFFdOpenExt(thandle_to_int(fd),
(mbname != NULL) ? mbname : "<unknown>", mode, opts);
if (!tif)
CloseHandle(fd);
_TIFFfree(mbname);
return tif;
}
#endif
void *_TIFFmalloc(tmsize_t s)
{
if (s == 0)
return ((void *)NULL);
return (malloc((size_t)s));
}
void *_TIFFcalloc(tmsize_t nmemb, tmsize_t siz)
{
if (nmemb == 0 || siz == 0)
return ((void *)NULL);
return calloc((size_t)nmemb, (size_t)siz);
}
void _TIFFfree(void *p) { free(p); }
void *_TIFFrealloc(void *p, tmsize_t s) { return (realloc(p, (size_t)s)); }
void _TIFFmemset(void *p, int v, tmsize_t c) { memset(p, v, (size_t)c); }
void _TIFFmemcpy(void *d, const void *s, tmsize_t c)
{
memcpy(d, s, (size_t)c);
}
int _TIFFmemcmp(const void *p1, const void *p2, tmsize_t c)
{
return (memcmp(p1, p2, (size_t)c));
}
#ifndef _WIN32_WCE
static void Win32WarningHandler(const char *module, const char *fmt, va_list ap)
{
if (module != NULL)
fprintf(stderr, "%s: ", module);
fprintf(stderr, "Warning, ");
vfprintf(stderr, fmt, ap);
fprintf(stderr, ".\n");
}
TIFFErrorHandler _TIFFwarningHandler = Win32WarningHandler;
static void Win32ErrorHandler(const char *module, const char *fmt, va_list ap)
{
if (module != NULL)
fprintf(stderr, "%s: ", module);
vfprintf(stderr, fmt, ap);
fprintf(stderr, ".\n");
}
TIFFErrorHandler _TIFFerrorHandler = Win32ErrorHandler;
#endif