tif_unix.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. /*
  2. * Copyright (c) 1988-1997 Sam Leffler
  3. * Copyright (c) 1991-1997 Silicon Graphics, Inc.
  4. *
  5. * Permission to use, copy, modify, distribute, and sell this software and
  6. * its documentation for any purpose is hereby granted without fee, provided
  7. * that (i) the above copyright notices and this permission notice appear in
  8. * all copies of the software and related documentation, and (ii) the names of
  9. * Sam Leffler and Silicon Graphics may not be used in any advertising or
  10. * publicity relating to the software without the specific, prior written
  11. * permission of Sam Leffler and Silicon Graphics.
  12. *
  13. * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
  14. * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  15. * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  16. *
  17. * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  18. * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  19. * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20. * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
  21. * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  22. * OF THIS SOFTWARE.
  23. */
  24. /*
  25. * TIFF Library UNIX-specific Routines. These are should also work with the
  26. * Windows Common RunTime Library.
  27. */
  28. #include "tif_config.h"
  29. #ifdef HAVE_SYS_TYPES_H
  30. #include <sys/types.h>
  31. #endif
  32. #include <errno.h>
  33. #include <stdarg.h>
  34. #include <stdlib.h>
  35. #include <sys/stat.h>
  36. #ifdef HAVE_UNISTD_H
  37. #include <unistd.h>
  38. #endif
  39. #ifdef HAVE_FCNTL_H
  40. #include <fcntl.h>
  41. #endif
  42. #ifdef HAVE_IO_H
  43. #include <io.h>
  44. #endif
  45. #include "tiffiop.h"
  46. #define TIFF_IO_MAX 2147483647U
  47. typedef union fd_as_handle_union
  48. {
  49. int fd;
  50. thandle_t h;
  51. } fd_as_handle_union_t;
  52. static tmsize_t _tiffReadProc(thandle_t fd, void *buf, tmsize_t size)
  53. {
  54. fd_as_handle_union_t fdh;
  55. const size_t bytes_total = (size_t)size;
  56. size_t bytes_read;
  57. tmsize_t count = -1;
  58. if ((tmsize_t)bytes_total != size)
  59. {
  60. errno = EINVAL;
  61. return (tmsize_t)-1;
  62. }
  63. fdh.h = fd;
  64. for (bytes_read = 0; bytes_read < bytes_total; bytes_read += count)
  65. {
  66. char *buf_offset = (char *)buf + bytes_read;
  67. size_t io_size = bytes_total - bytes_read;
  68. if (io_size > TIFF_IO_MAX)
  69. io_size = TIFF_IO_MAX;
  70. count = read(fdh.fd, buf_offset, (TIFFIOSize_t)io_size);
  71. if (count <= 0)
  72. break;
  73. }
  74. if (count < 0)
  75. return (tmsize_t)-1;
  76. return (tmsize_t)bytes_read;
  77. }
  78. static tmsize_t _tiffWriteProc(thandle_t fd, void *buf, tmsize_t size)
  79. {
  80. fd_as_handle_union_t fdh;
  81. const size_t bytes_total = (size_t)size;
  82. size_t bytes_written;
  83. tmsize_t count = -1;
  84. if ((tmsize_t)bytes_total != size)
  85. {
  86. errno = EINVAL;
  87. return (tmsize_t)-1;
  88. }
  89. fdh.h = fd;
  90. for (bytes_written = 0; bytes_written < bytes_total; bytes_written += count)
  91. {
  92. const char *buf_offset = (char *)buf + bytes_written;
  93. size_t io_size = bytes_total - bytes_written;
  94. if (io_size > TIFF_IO_MAX)
  95. io_size = TIFF_IO_MAX;
  96. count = write(fdh.fd, buf_offset, (TIFFIOSize_t)io_size);
  97. if (count <= 0)
  98. break;
  99. }
  100. if (count < 0)
  101. return (tmsize_t)-1;
  102. return (tmsize_t)bytes_written;
  103. /* return ((tmsize_t) write(fdh.fd, buf, bytes_total)); */
  104. }
  105. static uint64_t _tiffSeekProc(thandle_t fd, uint64_t off, int whence)
  106. {
  107. fd_as_handle_union_t fdh;
  108. _TIFF_off_t off_io = (_TIFF_off_t)off;
  109. if ((uint64_t)off_io != off)
  110. {
  111. errno = EINVAL;
  112. return (uint64_t)-1; /* this is really gross */
  113. }
  114. fdh.h = fd;
  115. return ((uint64_t)_TIFF_lseek_f(fdh.fd, off_io, whence));
  116. }
  117. static int _tiffCloseProc(thandle_t fd)
  118. {
  119. fd_as_handle_union_t fdh;
  120. fdh.h = fd;
  121. return (close(fdh.fd));
  122. }
  123. static uint64_t _tiffSizeProc(thandle_t fd)
  124. {
  125. _TIFF_stat_s sb;
  126. fd_as_handle_union_t fdh;
  127. fdh.h = fd;
  128. if (_TIFF_fstat_f(fdh.fd, &sb) < 0)
  129. return (0);
  130. else
  131. return ((uint64_t)sb.st_size);
  132. }
  133. #ifdef HAVE_MMAP
  134. #include <sys/mman.h>
  135. static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize)
  136. {
  137. uint64_t size64 = _tiffSizeProc(fd);
  138. tmsize_t sizem = (tmsize_t)size64;
  139. if (size64 && (uint64_t)sizem == size64)
  140. {
  141. fd_as_handle_union_t fdh;
  142. fdh.h = fd;
  143. *pbase =
  144. (void *)mmap(0, (size_t)sizem, PROT_READ, MAP_SHARED, fdh.fd, 0);
  145. if (*pbase != (void *)-1)
  146. {
  147. *psize = (tmsize_t)sizem;
  148. return (1);
  149. }
  150. }
  151. return (0);
  152. }
  153. static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size)
  154. {
  155. (void)fd;
  156. (void)munmap(base, (off_t)size);
  157. }
  158. #else /* !HAVE_MMAP */
  159. static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize)
  160. {
  161. (void)fd;
  162. (void)pbase;
  163. (void)psize;
  164. return (0);
  165. }
  166. static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size)
  167. {
  168. (void)fd;
  169. (void)base;
  170. (void)size;
  171. }
  172. #endif /* !HAVE_MMAP */
  173. /*
  174. * Open a TIFF file descriptor for read/writing.
  175. */
  176. TIFF *TIFFFdOpen(int fd, const char *name, const char *mode)
  177. {
  178. return TIFFFdOpenExt(fd, name, mode, NULL);
  179. }
  180. TIFF *TIFFFdOpenExt(int fd, const char *name, const char *mode,
  181. TIFFOpenOptions *opts)
  182. {
  183. TIFF *tif;
  184. fd_as_handle_union_t fdh;
  185. fdh.fd = fd;
  186. tif = TIFFClientOpenExt(name, mode, fdh.h, _tiffReadProc, _tiffWriteProc,
  187. _tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
  188. _tiffMapProc, _tiffUnmapProc, opts);
  189. if (tif)
  190. tif->tif_fd = fd;
  191. return (tif);
  192. }
  193. /*
  194. * Open a TIFF file for read/writing.
  195. */
  196. TIFF *TIFFOpen(const char *name, const char *mode)
  197. {
  198. return TIFFOpenExt(name, mode, NULL);
  199. }
  200. TIFF *TIFFOpenExt(const char *name, const char *mode, TIFFOpenOptions *opts)
  201. {
  202. static const char module[] = "TIFFOpen";
  203. int m, fd;
  204. TIFF *tif;
  205. m = _TIFFgetMode(opts, NULL, mode, module);
  206. if (m == -1)
  207. return ((TIFF *)0);
  208. /* for cygwin and mingw */
  209. #ifdef O_BINARY
  210. m |= O_BINARY;
  211. #endif
  212. fd = open(name, m, 0666);
  213. if (fd < 0)
  214. {
  215. if (errno > 0 && strerror(errno) != NULL)
  216. {
  217. _TIFFErrorEarly(opts, NULL, module, "%s: %s", name,
  218. strerror(errno));
  219. }
  220. else
  221. {
  222. _TIFFErrorEarly(opts, NULL, module, "%s: Cannot open", name);
  223. }
  224. return ((TIFF *)0);
  225. }
  226. tif = TIFFFdOpenExt((int)fd, name, mode, opts);
  227. if (!tif)
  228. close(fd);
  229. return tif;
  230. }
  231. #ifdef __WIN32__
  232. #include <windows.h>
  233. /*
  234. * Open a TIFF file with a Unicode filename, for read/writing.
  235. */
  236. TIFF *TIFFOpenW(const wchar_t *name, const char *mode)
  237. {
  238. return TIFFOpenWExt(name, mode, NULL);
  239. }
  240. TIFF *TIFFOpenWExt(const wchar_t *name, const char *mode, TIFFOpenOptions *opts)
  241. {
  242. static const char module[] = "TIFFOpenW";
  243. int m, fd;
  244. int mbsize;
  245. char *mbname;
  246. TIFF *tif;
  247. m = _TIFFgetMode(opts, NULL, mode, module);
  248. if (m == -1)
  249. return ((TIFF *)0);
  250. /* for cygwin and mingw */
  251. #ifdef O_BINARY
  252. m |= O_BINARY;
  253. #endif
  254. fd = _wopen(name, m, 0666);
  255. if (fd < 0)
  256. {
  257. _TIFFErrorEarly(opts, NULL, module, "%ls: Cannot open", name);
  258. return ((TIFF *)0);
  259. }
  260. mbname = NULL;
  261. mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL);
  262. if (mbsize > 0)
  263. {
  264. mbname = _TIFFmalloc(mbsize);
  265. if (!mbname)
  266. {
  267. _TIFFErrorEarly(
  268. opts, NULL, module,
  269. "Can't allocate space for filename conversion buffer");
  270. return ((TIFF *)0);
  271. }
  272. WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, NULL, NULL);
  273. }
  274. tif = TIFFFdOpenExt((int)fd, (mbname != NULL) ? mbname : "<unknown>", mode,
  275. opts);
  276. _TIFFfree(mbname);
  277. if (!tif)
  278. close(fd);
  279. return tif;
  280. }
  281. #endif
  282. void *_TIFFmalloc(tmsize_t s)
  283. {
  284. if (s == 0)
  285. return ((void *)NULL);
  286. return (malloc((size_t)s));
  287. }
  288. void *_TIFFcalloc(tmsize_t nmemb, tmsize_t siz)
  289. {
  290. if (nmemb == 0 || siz == 0)
  291. return ((void *)NULL);
  292. return calloc((size_t)nmemb, (size_t)siz);
  293. }
  294. void _TIFFfree(void *p) { free(p); }
  295. void *_TIFFrealloc(void *p, tmsize_t s) { return (realloc(p, (size_t)s)); }
  296. void _TIFFmemset(void *p, int v, tmsize_t c) { memset(p, v, (size_t)c); }
  297. void _TIFFmemcpy(void *d, const void *s, tmsize_t c)
  298. {
  299. memcpy(d, s, (size_t)c);
  300. }
  301. int _TIFFmemcmp(const void *p1, const void *p2, tmsize_t c)
  302. {
  303. return (memcmp(p1, p2, (size_t)c));
  304. }
  305. static void unixWarningHandler(const char *module, const char *fmt, va_list ap)
  306. {
  307. if (module != NULL)
  308. fprintf(stderr, "%s: ", module);
  309. fprintf(stderr, "Warning, ");
  310. vfprintf(stderr, fmt, ap);
  311. fprintf(stderr, ".\n");
  312. }
  313. TIFFErrorHandler _TIFFwarningHandler = unixWarningHandler;
  314. static void unixErrorHandler(const char *module, const char *fmt, va_list ap)
  315. {
  316. if (module != NULL)
  317. fprintf(stderr, "%s: ", module);
  318. vfprintf(stderr, fmt, ap);
  319. fprintf(stderr, ".\n");
  320. }
  321. TIFFErrorHandler _TIFFerrorHandler = unixErrorHandler;