tif_win32.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. /* $Id: tif_win32.c,v 1.41 2015-08-23 20:12:44 bfriesen Exp $ */
  2. /*
  3. * Copyright (c) 1988-1997 Sam Leffler
  4. * Copyright (c) 1991-1997 Silicon Graphics, Inc.
  5. *
  6. * Permission to use, copy, modify, distribute, and sell this software and
  7. * its documentation for any purpose is hereby granted without fee, provided
  8. * that (i) the above copyright notices and this permission notice appear in
  9. * all copies of the software and related documentation, and (ii) the names of
  10. * Sam Leffler and Silicon Graphics may not be used in any advertising or
  11. * publicity relating to the software without the specific, prior written
  12. * permission of Sam Leffler and Silicon Graphics.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
  15. * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  16. * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  17. *
  18. * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  19. * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  20. * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21. * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
  22. * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  23. * OF THIS SOFTWARE.
  24. */
  25. /*
  26. * TIFF Library Win32-specific Routines. Adapted from tif_unix.c 4/5/95 by
  27. * Scott Wagner (wagner@itek.com), Itek Graphix, Rochester, NY USA
  28. */
  29. /*
  30. CreateFileA/CreateFileW return type 'HANDLE'.
  31. thandle_t is declared like
  32. DECLARE_HANDLE(thandle_t);
  33. in tiffio.h.
  34. Windows (from winnt.h) DECLARE_HANDLE logic looks like
  35. #ifdef STRICT
  36. typedef void *HANDLE;
  37. #define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
  38. #else
  39. typedef PVOID HANDLE;
  40. #define DECLARE_HANDLE(name) typedef HANDLE name
  41. #endif
  42. See http://bugzilla.maptools.org/show_bug.cgi?id=1941 for problems in WIN64
  43. builds resulting from this. Unfortunately, the proposed patch was lost.
  44. */
  45. #include "tiffiop.h"
  46. #include <windows.h>
  47. static tmsize_t
  48. _tiffReadProc(thandle_t fd, void* buf, tmsize_t size)
  49. {
  50. /* tmsize_t is 64bit on 64bit systems, but the WinAPI ReadFile takes
  51. * 32bit sizes, so we loop through the data in suitable 32bit sized
  52. * chunks */
  53. uint8* ma;
  54. uint64 mb;
  55. DWORD n;
  56. DWORD o;
  57. tmsize_t p;
  58. ma=(uint8*)buf;
  59. mb=size;
  60. p=0;
  61. while (mb>0)
  62. {
  63. n=0x80000000UL;
  64. if ((uint64)n>mb)
  65. n=(DWORD)mb;
  66. if (!ReadFile(fd,(LPVOID)ma,n,&o,NULL))
  67. return(0);
  68. ma+=o;
  69. mb-=o;
  70. p+=o;
  71. if (o!=n)
  72. break;
  73. }
  74. return(p);
  75. }
  76. static tmsize_t
  77. _tiffWriteProc(thandle_t fd, void* buf, tmsize_t size)
  78. {
  79. /* tmsize_t is 64bit on 64bit systems, but the WinAPI WriteFile takes
  80. * 32bit sizes, so we loop through the data in suitable 32bit sized
  81. * chunks */
  82. uint8* ma;
  83. uint64 mb;
  84. DWORD n;
  85. DWORD o;
  86. tmsize_t p;
  87. ma=(uint8*)buf;
  88. mb=size;
  89. p=0;
  90. while (mb>0)
  91. {
  92. n=0x80000000UL;
  93. if ((uint64)n>mb)
  94. n=(DWORD)mb;
  95. if (!WriteFile(fd,(LPVOID)ma,n,&o,NULL))
  96. return(0);
  97. ma+=o;
  98. mb-=o;
  99. p+=o;
  100. if (o!=n)
  101. break;
  102. }
  103. return(p);
  104. }
  105. static uint64
  106. _tiffSeekProc(thandle_t fd, uint64 off, int whence)
  107. {
  108. LARGE_INTEGER offli;
  109. DWORD dwMoveMethod;
  110. offli.QuadPart = off;
  111. switch(whence)
  112. {
  113. case SEEK_SET:
  114. dwMoveMethod = FILE_BEGIN;
  115. break;
  116. case SEEK_CUR:
  117. dwMoveMethod = FILE_CURRENT;
  118. break;
  119. case SEEK_END:
  120. dwMoveMethod = FILE_END;
  121. break;
  122. default:
  123. dwMoveMethod = FILE_BEGIN;
  124. break;
  125. }
  126. offli.LowPart=SetFilePointer(fd,offli.LowPart,&offli.HighPart,dwMoveMethod);
  127. if ((offli.LowPart==INVALID_SET_FILE_POINTER)&&(GetLastError()!=NO_ERROR))
  128. offli.QuadPart=0;
  129. return(offli.QuadPart);
  130. }
  131. static int
  132. _tiffCloseProc(thandle_t fd)
  133. {
  134. return (CloseHandle(fd) ? 0 : -1);
  135. }
  136. static uint64
  137. _tiffSizeProc(thandle_t fd)
  138. {
  139. ULARGE_INTEGER m;
  140. m.LowPart=GetFileSize(fd,&m.HighPart);
  141. return(m.QuadPart);
  142. }
  143. static int
  144. _tiffDummyMapProc(thandle_t fd, void** pbase, toff_t* psize)
  145. {
  146. (void) fd;
  147. (void) pbase;
  148. (void) psize;
  149. return (0);
  150. }
  151. /*
  152. * From "Hermann Josef Hill" <lhill@rhein-zeitung.de>:
  153. *
  154. * Windows uses both a handle and a pointer for file mapping,
  155. * but according to the SDK documentation and Richter's book
  156. * "Advanced Windows Programming" it is safe to free the handle
  157. * after obtaining the file mapping pointer
  158. *
  159. * This removes a nasty OS dependency and cures a problem
  160. * with Visual C++ 5.0
  161. */
  162. static int
  163. _tiffMapProc(thandle_t fd, void** pbase, toff_t* psize)
  164. {
  165. uint64 size;
  166. tmsize_t sizem;
  167. HANDLE hMapFile;
  168. size = _tiffSizeProc(fd);
  169. sizem = (tmsize_t)size;
  170. if ((uint64)sizem!=size)
  171. return (0);
  172. /* By passing in 0 for the maximum file size, it specifies that we
  173. create a file mapping object for the full file size. */
  174. hMapFile = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, 0, NULL);
  175. if (hMapFile == NULL)
  176. return (0);
  177. *pbase = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);
  178. CloseHandle(hMapFile);
  179. if (*pbase == NULL)
  180. return (0);
  181. *psize = size;
  182. return(1);
  183. }
  184. static void
  185. _tiffDummyUnmapProc(thandle_t fd, void* base, toff_t size)
  186. {
  187. (void) fd;
  188. (void) base;
  189. (void) size;
  190. }
  191. static void
  192. _tiffUnmapProc(thandle_t fd, void* base, toff_t size)
  193. {
  194. (void) fd;
  195. (void) size;
  196. UnmapViewOfFile(base);
  197. }
  198. /*
  199. * Open a TIFF file descriptor for read/writing.
  200. * Note that TIFFFdOpen and TIFFOpen recognise the character 'u' in the mode
  201. * string, which forces the file to be opened unmapped.
  202. */
  203. TIFF*
  204. TIFFFdOpen(int ifd, const char* name, const char* mode)
  205. {
  206. TIFF* tif;
  207. int fSuppressMap;
  208. int m;
  209. fSuppressMap=0;
  210. for (m=0; mode[m]!=0; m++)
  211. {
  212. if (mode[m]=='u')
  213. {
  214. fSuppressMap=1;
  215. break;
  216. }
  217. }
  218. tif = TIFFClientOpen(name, mode, (thandle_t)ifd, /* FIXME: WIN64 cast to pointer warning */
  219. _tiffReadProc, _tiffWriteProc,
  220. _tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
  221. fSuppressMap ? _tiffDummyMapProc : _tiffMapProc,
  222. fSuppressMap ? _tiffDummyUnmapProc : _tiffUnmapProc);
  223. if (tif)
  224. tif->tif_fd = ifd;
  225. return (tif);
  226. }
  227. #ifndef _WIN32_WCE
  228. /*
  229. * Open a TIFF file for read/writing.
  230. */
  231. TIFF*
  232. TIFFOpen(const char* name, const char* mode)
  233. {
  234. static const char module[] = "TIFFOpen";
  235. thandle_t fd;
  236. int m;
  237. DWORD dwMode;
  238. TIFF* tif;
  239. m = _TIFFgetMode(mode, module);
  240. switch(m) {
  241. case O_RDONLY: dwMode = OPEN_EXISTING; break;
  242. case O_RDWR: dwMode = OPEN_ALWAYS; break;
  243. case O_RDWR|O_CREAT: dwMode = OPEN_ALWAYS; break;
  244. case O_RDWR|O_TRUNC: dwMode = CREATE_ALWAYS; break;
  245. case O_RDWR|O_CREAT|O_TRUNC: dwMode = CREATE_ALWAYS; break;
  246. default: return ((TIFF*)0);
  247. }
  248. fd = (thandle_t)CreateFileA(name,
  249. (m == O_RDONLY)?GENERIC_READ:(GENERIC_READ | GENERIC_WRITE),
  250. FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode,
  251. (m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL,
  252. NULL);
  253. if (fd == INVALID_HANDLE_VALUE) {
  254. TIFFErrorExt(0, module, "%s: Cannot open", name);
  255. return ((TIFF *)0);
  256. }
  257. tif = TIFFFdOpen((int)fd, name, mode); /* FIXME: WIN64 cast from pointer to int warning */
  258. if(!tif)
  259. CloseHandle(fd);
  260. return tif;
  261. }
  262. /*
  263. * Open a TIFF file with a Unicode filename, for read/writing.
  264. */
  265. TIFF*
  266. TIFFOpenW(const wchar_t* name, const char* mode)
  267. {
  268. static const char module[] = "TIFFOpenW";
  269. thandle_t fd;
  270. int m;
  271. DWORD dwMode;
  272. int mbsize;
  273. char *mbname;
  274. TIFF *tif;
  275. m = _TIFFgetMode(mode, module);
  276. switch(m) {
  277. case O_RDONLY: dwMode = OPEN_EXISTING; break;
  278. case O_RDWR: dwMode = OPEN_ALWAYS; break;
  279. case O_RDWR|O_CREAT: dwMode = OPEN_ALWAYS; break;
  280. case O_RDWR|O_TRUNC: dwMode = CREATE_ALWAYS; break;
  281. case O_RDWR|O_CREAT|O_TRUNC: dwMode = CREATE_ALWAYS; break;
  282. default: return ((TIFF*)0);
  283. }
  284. fd = (thandle_t)CreateFileW(name,
  285. (m == O_RDONLY)?GENERIC_READ:(GENERIC_READ|GENERIC_WRITE),
  286. FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode,
  287. (m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL,
  288. NULL);
  289. if (fd == INVALID_HANDLE_VALUE) {
  290. TIFFErrorExt(0, module, "%S: Cannot open", name);
  291. return ((TIFF *)0);
  292. }
  293. mbname = NULL;
  294. mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL);
  295. if (mbsize > 0) {
  296. mbname = (char *)_TIFFmalloc(mbsize);
  297. if (!mbname) {
  298. TIFFErrorExt(0, module,
  299. "Can't allocate space for filename conversion buffer");
  300. return ((TIFF*)0);
  301. }
  302. WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize,
  303. NULL, NULL);
  304. }
  305. tif = TIFFFdOpen((int)fd, /* FIXME: WIN64 cast from pointer to int warning */
  306. (mbname != NULL) ? mbname : "<unknown>", mode);
  307. if(!tif)
  308. CloseHandle(fd);
  309. _TIFFfree(mbname);
  310. return tif;
  311. }
  312. #endif /* ndef _WIN32_WCE */
  313. void*
  314. _TIFFmalloc(tmsize_t s)
  315. {
  316. if (s == 0)
  317. return ((void *) NULL);
  318. return (malloc((size_t) s));
  319. }
  320. void
  321. _TIFFfree(void* p)
  322. {
  323. free(p);
  324. }
  325. void*
  326. _TIFFrealloc(void* p, tmsize_t s)
  327. {
  328. return (realloc(p, (size_t) s));
  329. }
  330. void
  331. _TIFFmemset(void* p, int v, tmsize_t c)
  332. {
  333. memset(p, v, (size_t) c);
  334. }
  335. void
  336. _TIFFmemcpy(void* d, const void* s, tmsize_t c)
  337. {
  338. memcpy(d, s, (size_t) c);
  339. }
  340. int
  341. _TIFFmemcmp(const void* p1, const void* p2, tmsize_t c)
  342. {
  343. return (memcmp(p1, p2, (size_t) c));
  344. }
  345. #ifndef _WIN32_WCE
  346. #if (_MSC_VER < 1500)
  347. # define vsnprintf _vsnprintf
  348. #endif
  349. static void
  350. Win32WarningHandler(const char* module, const char* fmt, va_list ap)
  351. {
  352. #ifndef TIF_PLATFORM_CONSOLE
  353. LPTSTR szTitle;
  354. LPTSTR szTmp;
  355. LPCTSTR szTitleText = "%s Warning";
  356. LPCTSTR szDefaultModule = "LIBTIFF";
  357. LPCTSTR szTmpModule = (module == NULL) ? szDefaultModule : module;
  358. SIZE_T nBufSize = (strlen(szTmpModule) +
  359. strlen(szTitleText) + strlen(fmt) + 256)*sizeof(char);
  360. if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, nBufSize)) == NULL)
  361. return;
  362. sprintf(szTitle, szTitleText, szTmpModule);
  363. szTmp = szTitle + (strlen(szTitle)+2)*sizeof(char);
  364. vsnprintf(szTmp, nBufSize-(strlen(szTitle)+2)*sizeof(char), fmt, ap);
  365. MessageBoxA(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONINFORMATION);
  366. LocalFree(szTitle);
  367. return;
  368. #else
  369. if (module != NULL)
  370. fprintf(stderr, "%s: ", module);
  371. fprintf(stderr, "Warning, ");
  372. vfprintf(stderr, fmt, ap);
  373. fprintf(stderr, ".\n");
  374. #endif
  375. }
  376. TIFFErrorHandler _TIFFwarningHandler = Win32WarningHandler;
  377. static void
  378. Win32ErrorHandler(const char* module, const char* fmt, va_list ap)
  379. {
  380. #ifndef TIF_PLATFORM_CONSOLE
  381. LPTSTR szTitle;
  382. LPTSTR szTmp;
  383. LPCTSTR szTitleText = "%s Error";
  384. LPCTSTR szDefaultModule = "LIBTIFF";
  385. LPCTSTR szTmpModule = (module == NULL) ? szDefaultModule : module;
  386. SIZE_T nBufSize = (strlen(szTmpModule) +
  387. strlen(szTitleText) + strlen(fmt) + 256)*sizeof(char);
  388. if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, nBufSize)) == NULL)
  389. return;
  390. sprintf(szTitle, szTitleText, szTmpModule);
  391. szTmp = szTitle + (strlen(szTitle)+2)*sizeof(char);
  392. vsnprintf(szTmp, nBufSize-(strlen(szTitle)+2)*sizeof(char), fmt, ap);
  393. MessageBoxA(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONEXCLAMATION);
  394. LocalFree(szTitle);
  395. return;
  396. #else
  397. if (module != NULL)
  398. fprintf(stderr, "%s: ", module);
  399. vfprintf(stderr, fmt, ap);
  400. fprintf(stderr, ".\n");
  401. #endif
  402. }
  403. TIFFErrorHandler _TIFFerrorHandler = Win32ErrorHandler;
  404. #endif /* ndef _WIN32_WCE */
  405. /* vim: set ts=8 sts=8 sw=8 noet: */
  406. /*
  407. * Local Variables:
  408. * mode: c
  409. * c-basic-offset: 8
  410. * fill-column: 78
  411. * End:
  412. */