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