2
0

tif_win32.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. /* $Id: tif_win32.c,v 1.39 2011-12-22 17:07:57 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. #include "tiffiop.h"
  30. #include <windows.h>
  31. static tmsize_t
  32. _tiffReadProc(thandle_t fd, void* buf, tmsize_t size)
  33. {
  34. /* tmsize_t is 64bit on 64bit systems, but the WinAPI ReadFile takes
  35. * 32bit sizes, so we loop through the data in suitable 32bit sized
  36. * chunks */
  37. uint8* ma;
  38. uint64 mb;
  39. DWORD n;
  40. DWORD o;
  41. tmsize_t p;
  42. ma=(uint8*)buf;
  43. mb=size;
  44. p=0;
  45. while (mb>0)
  46. {
  47. n=0x80000000UL;
  48. if ((uint64)n>mb)
  49. n=(DWORD)mb;
  50. if (!ReadFile(fd,(LPVOID)ma,n,&o,NULL))
  51. return(0);
  52. ma+=o;
  53. mb-=o;
  54. p+=o;
  55. if (o!=n)
  56. break;
  57. }
  58. return(p);
  59. }
  60. static tmsize_t
  61. _tiffWriteProc(thandle_t fd, void* buf, tmsize_t size)
  62. {
  63. /* tmsize_t is 64bit on 64bit systems, but the WinAPI WriteFile takes
  64. * 32bit sizes, so we loop through the data in suitable 32bit sized
  65. * chunks */
  66. uint8* ma;
  67. uint64 mb;
  68. DWORD n;
  69. DWORD o;
  70. tmsize_t p;
  71. ma=(uint8*)buf;
  72. mb=size;
  73. p=0;
  74. while (mb>0)
  75. {
  76. n=0x80000000UL;
  77. if ((uint64)n>mb)
  78. n=(DWORD)mb;
  79. if (!WriteFile(fd,(LPVOID)ma,n,&o,NULL))
  80. return(0);
  81. ma+=o;
  82. mb-=o;
  83. p+=o;
  84. if (o!=n)
  85. break;
  86. }
  87. return(p);
  88. }
  89. static uint64
  90. _tiffSeekProc(thandle_t fd, uint64 off, int whence)
  91. {
  92. LARGE_INTEGER offli;
  93. DWORD dwMoveMethod;
  94. offli.QuadPart = off;
  95. switch(whence)
  96. {
  97. case SEEK_SET:
  98. dwMoveMethod = FILE_BEGIN;
  99. break;
  100. case SEEK_CUR:
  101. dwMoveMethod = FILE_CURRENT;
  102. break;
  103. case SEEK_END:
  104. dwMoveMethod = FILE_END;
  105. break;
  106. default:
  107. dwMoveMethod = FILE_BEGIN;
  108. break;
  109. }
  110. offli.LowPart=SetFilePointer(fd,offli.LowPart,&offli.HighPart,dwMoveMethod);
  111. if ((offli.LowPart==INVALID_SET_FILE_POINTER)&&(GetLastError()!=NO_ERROR))
  112. offli.QuadPart=0;
  113. return(offli.QuadPart);
  114. }
  115. static int
  116. _tiffCloseProc(thandle_t fd)
  117. {
  118. return (CloseHandle(fd) ? 0 : -1);
  119. }
  120. static uint64
  121. _tiffSizeProc(thandle_t fd)
  122. {
  123. ULARGE_INTEGER m;
  124. m.LowPart=GetFileSize(fd,&m.HighPart);
  125. return(m.QuadPart);
  126. }
  127. static int
  128. _tiffDummyMapProc(thandle_t fd, void** pbase, toff_t* psize)
  129. {
  130. (void) fd;
  131. (void) pbase;
  132. (void) psize;
  133. return (0);
  134. }
  135. /*
  136. * From "Hermann Josef Hill" <lhill@rhein-zeitung.de>:
  137. *
  138. * Windows uses both a handle and a pointer for file mapping,
  139. * but according to the SDK documentation and Richter's book
  140. * "Advanced Windows Programming" it is safe to free the handle
  141. * after obtaining the file mapping pointer
  142. *
  143. * This removes a nasty OS dependency and cures a problem
  144. * with Visual C++ 5.0
  145. */
  146. static int
  147. _tiffMapProc(thandle_t fd, void** pbase, toff_t* psize)
  148. {
  149. uint64 size;
  150. tmsize_t sizem;
  151. HANDLE hMapFile;
  152. size = _tiffSizeProc(fd);
  153. sizem = (tmsize_t)size;
  154. if ((uint64)sizem!=size)
  155. return (0);
  156. /* By passing in 0 for the maximum file size, it specifies that we
  157. create a file mapping object for the full file size. */
  158. hMapFile = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, 0, NULL);
  159. if (hMapFile == NULL)
  160. return (0);
  161. *pbase = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);
  162. CloseHandle(hMapFile);
  163. if (*pbase == NULL)
  164. return (0);
  165. *psize = size;
  166. return(1);
  167. }
  168. static void
  169. _tiffDummyUnmapProc(thandle_t fd, void* base, toff_t size)
  170. {
  171. (void) fd;
  172. (void) base;
  173. (void) size;
  174. }
  175. static void
  176. _tiffUnmapProc(thandle_t fd, void* base, toff_t size)
  177. {
  178. (void) fd;
  179. (void) size;
  180. UnmapViewOfFile(base);
  181. }
  182. /*
  183. * Open a TIFF file descriptor for read/writing.
  184. * Note that TIFFFdOpen and TIFFOpen recognise the character 'u' in the mode
  185. * string, which forces the file to be opened unmapped.
  186. */
  187. TIFF*
  188. TIFFFdOpen(int ifd, const char* name, const char* mode)
  189. {
  190. TIFF* tif;
  191. int fSuppressMap;
  192. int m;
  193. fSuppressMap=0;
  194. for (m=0; mode[m]!=0; m++)
  195. {
  196. if (mode[m]=='u')
  197. {
  198. fSuppressMap=1;
  199. break;
  200. }
  201. }
  202. tif = TIFFClientOpen(name, mode, (thandle_t)ifd,
  203. _tiffReadProc, _tiffWriteProc,
  204. _tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
  205. fSuppressMap ? _tiffDummyMapProc : _tiffMapProc,
  206. fSuppressMap ? _tiffDummyUnmapProc : _tiffUnmapProc);
  207. if (tif)
  208. tif->tif_fd = ifd;
  209. return (tif);
  210. }
  211. #ifndef _WIN32_WCE
  212. /*
  213. * Open a TIFF file for read/writing.
  214. */
  215. TIFF*
  216. TIFFOpen(const char* name, const char* mode)
  217. {
  218. static const char module[] = "TIFFOpen";
  219. thandle_t fd;
  220. int m;
  221. DWORD dwMode;
  222. TIFF* tif;
  223. m = _TIFFgetMode(mode, module);
  224. switch(m) {
  225. case O_RDONLY: dwMode = OPEN_EXISTING; break;
  226. case O_RDWR: dwMode = OPEN_ALWAYS; break;
  227. case O_RDWR|O_CREAT: dwMode = OPEN_ALWAYS; break;
  228. case O_RDWR|O_TRUNC: dwMode = CREATE_ALWAYS; break;
  229. case O_RDWR|O_CREAT|O_TRUNC: dwMode = CREATE_ALWAYS; break;
  230. default: return ((TIFF*)0);
  231. }
  232. fd = (thandle_t)CreateFileA(name,
  233. (m == O_RDONLY)?GENERIC_READ:(GENERIC_READ | GENERIC_WRITE),
  234. FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode,
  235. (m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL,
  236. NULL);
  237. if (fd == INVALID_HANDLE_VALUE) {
  238. TIFFErrorExt(0, module, "%s: Cannot open", name);
  239. return ((TIFF *)0);
  240. }
  241. tif = TIFFFdOpen((int)fd, name, mode);
  242. if(!tif)
  243. CloseHandle(fd);
  244. return tif;
  245. }
  246. /*
  247. * Open a TIFF file with a Unicode filename, for read/writing.
  248. */
  249. TIFF*
  250. TIFFOpenW(const wchar_t* name, const char* mode)
  251. {
  252. static const char module[] = "TIFFOpenW";
  253. thandle_t fd;
  254. int m;
  255. DWORD dwMode;
  256. int mbsize;
  257. char *mbname;
  258. TIFF *tif;
  259. m = _TIFFgetMode(mode, module);
  260. switch(m) {
  261. case O_RDONLY: dwMode = OPEN_EXISTING; break;
  262. case O_RDWR: dwMode = OPEN_ALWAYS; break;
  263. case O_RDWR|O_CREAT: dwMode = OPEN_ALWAYS; break;
  264. case O_RDWR|O_TRUNC: dwMode = CREATE_ALWAYS; break;
  265. case O_RDWR|O_CREAT|O_TRUNC: dwMode = CREATE_ALWAYS; break;
  266. default: return ((TIFF*)0);
  267. }
  268. fd = (thandle_t)CreateFileW(name,
  269. (m == O_RDONLY)?GENERIC_READ:(GENERIC_READ|GENERIC_WRITE),
  270. FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode,
  271. (m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL,
  272. NULL);
  273. if (fd == INVALID_HANDLE_VALUE) {
  274. TIFFErrorExt(0, module, "%S: Cannot open", name);
  275. return ((TIFF *)0);
  276. }
  277. mbname = NULL;
  278. mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL);
  279. if (mbsize > 0) {
  280. mbname = (char *)_TIFFmalloc(mbsize);
  281. if (!mbname) {
  282. TIFFErrorExt(0, module,
  283. "Can't allocate space for filename conversion buffer");
  284. return ((TIFF*)0);
  285. }
  286. WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize,
  287. NULL, NULL);
  288. }
  289. tif = TIFFFdOpen((int)fd,
  290. (mbname != NULL) ? mbname : "<unknown>", mode);
  291. if(!tif)
  292. CloseHandle(fd);
  293. _TIFFfree(mbname);
  294. return tif;
  295. }
  296. #endif /* ndef _WIN32_WCE */
  297. void*
  298. _TIFFmalloc(tmsize_t s)
  299. {
  300. return (malloc((size_t) s));
  301. }
  302. void
  303. _TIFFfree(void* p)
  304. {
  305. free(p);
  306. }
  307. void*
  308. _TIFFrealloc(void* p, tmsize_t s)
  309. {
  310. return (realloc(p, (size_t) s));
  311. }
  312. void
  313. _TIFFmemset(void* p, int v, tmsize_t c)
  314. {
  315. memset(p, v, (size_t) c);
  316. }
  317. void
  318. _TIFFmemcpy(void* d, const void* s, tmsize_t c)
  319. {
  320. memcpy(d, s, (size_t) c);
  321. }
  322. int
  323. _TIFFmemcmp(const void* p1, const void* p2, tmsize_t c)
  324. {
  325. return (memcmp(p1, p2, (size_t) c));
  326. }
  327. #ifndef _WIN32_WCE
  328. #if (_MSC_VER < 1500)
  329. # define vsnprintf _vsnprintf
  330. #endif
  331. static void
  332. Win32WarningHandler(const char* module, const char* fmt, va_list ap)
  333. {
  334. #ifndef TIF_PLATFORM_CONSOLE
  335. LPTSTR szTitle;
  336. LPTSTR szTmp;
  337. LPCTSTR szTitleText = "%s Warning";
  338. LPCTSTR szDefaultModule = "LIBTIFF";
  339. LPCTSTR szTmpModule = (module == NULL) ? szDefaultModule : module;
  340. SIZE_T nBufSize = (strlen(szTmpModule) +
  341. strlen(szTitleText) + strlen(fmt) + 256)*sizeof(char);
  342. if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, nBufSize)) == NULL)
  343. return;
  344. sprintf(szTitle, szTitleText, szTmpModule);
  345. szTmp = szTitle + (strlen(szTitle)+2)*sizeof(char);
  346. vsnprintf(szTmp, nBufSize-(strlen(szTitle)+2)*sizeof(char), fmt, ap);
  347. MessageBoxA(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONINFORMATION);
  348. LocalFree(szTitle);
  349. return;
  350. #else
  351. if (module != NULL)
  352. fprintf(stderr, "%s: ", module);
  353. fprintf(stderr, "Warning, ");
  354. vfprintf(stderr, fmt, ap);
  355. fprintf(stderr, ".\n");
  356. #endif
  357. }
  358. TIFFErrorHandler _TIFFwarningHandler = Win32WarningHandler;
  359. static void
  360. Win32ErrorHandler(const char* module, const char* fmt, va_list ap)
  361. {
  362. #ifndef TIF_PLATFORM_CONSOLE
  363. LPTSTR szTitle;
  364. LPTSTR szTmp;
  365. LPCTSTR szTitleText = "%s Error";
  366. LPCTSTR szDefaultModule = "LIBTIFF";
  367. LPCTSTR szTmpModule = (module == NULL) ? szDefaultModule : module;
  368. SIZE_T nBufSize = (strlen(szTmpModule) +
  369. strlen(szTitleText) + strlen(fmt) + 256)*sizeof(char);
  370. if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, nBufSize)) == NULL)
  371. return;
  372. sprintf(szTitle, szTitleText, szTmpModule);
  373. szTmp = szTitle + (strlen(szTitle)+2)*sizeof(char);
  374. vsnprintf(szTmp, nBufSize-(strlen(szTitle)+2)*sizeof(char), fmt, ap);
  375. MessageBoxA(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONEXCLAMATION);
  376. LocalFree(szTitle);
  377. return;
  378. #else
  379. if (module != NULL)
  380. fprintf(stderr, "%s: ", module);
  381. vfprintf(stderr, fmt, ap);
  382. fprintf(stderr, ".\n");
  383. #endif
  384. }
  385. TIFFErrorHandler _TIFFerrorHandler = Win32ErrorHandler;
  386. #endif /* ndef _WIN32_WCE */
  387. /* vim: set ts=8 sts=8 sw=8 noet: */
  388. /*
  389. * Local Variables:
  390. * mode: c
  391. * c-basic-offset: 8
  392. * fill-column: 78
  393. * End:
  394. */