LCOV - code coverage report
Current view: top level - frmts/gtiff/libtiff - tif_open.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 235 369 63.7 %
Date: 2024-05-04 12:52:34 Functions: 17 42 40.5 %

          Line data    Source code
       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             : /*
      26             :  * TIFF Library.
      27             :  */
      28             : 
      29             : #ifdef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
      30             : #undef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
      31             : #endif
      32             : 
      33             : #include "tiffiop.h"
      34             : #include <assert.h>
      35             : #include <limits.h>
      36             : 
      37             : /*
      38             :  * Dummy functions to fill the omitted client procedures.
      39             :  */
      40           0 : static int _tiffDummyMapProc(thandle_t fd, void **pbase, toff_t *psize)
      41             : {
      42             :     (void)fd;
      43             :     (void)pbase;
      44             :     (void)psize;
      45           0 :     return (0);
      46             : }
      47             : 
      48           0 : static void _tiffDummyUnmapProc(thandle_t fd, void *base, toff_t size)
      49             : {
      50             :     (void)fd;
      51             :     (void)base;
      52             :     (void)size;
      53           0 : }
      54             : 
      55       56456 : int _TIFFgetMode(TIFFOpenOptions *opts, thandle_t clientdata, const char *mode,
      56             :                  const char *module)
      57             : {
      58       56456 :     int m = -1;
      59             : 
      60       56456 :     switch (mode[0])
      61             :     {
      62       21471 :         case 'r':
      63       21471 :             m = O_RDONLY;
      64       21471 :             if (mode[1] == '+')
      65        2545 :                 m = O_RDWR;
      66       21471 :             break;
      67       34980 :         case 'w':
      68             :         case 'a':
      69       34980 :             m = O_RDWR | O_CREAT;
      70       34980 :             if (mode[0] == 'w')
      71       34980 :                 m |= O_TRUNC;
      72       34980 :             break;
      73           5 :         default:
      74           5 :             _TIFFErrorEarly(opts, clientdata, module, "\"%s\": Bad mode", mode);
      75           0 :             break;
      76             :     }
      77       56451 :     return (m);
      78             : }
      79             : 
      80       56470 : TIFFOpenOptions *TIFFOpenOptionsAlloc()
      81             : {
      82             :     TIFFOpenOptions *opts =
      83       56470 :         (TIFFOpenOptions *)_TIFFcalloc(1, sizeof(TIFFOpenOptions));
      84       56449 :     return opts;
      85             : }
      86             : 
      87       56450 : void TIFFOpenOptionsFree(TIFFOpenOptions *opts) { _TIFFfree(opts); }
      88             : 
      89             : /** Define a limit in bytes for a single memory allocation done by libtiff.
      90             :  *  If max_single_mem_alloc is set to 0, which is the default, no other limit
      91             :  *  that the underlying _TIFFmalloc() or
      92             :  *  TIFFOpenOptionsSetMaxCumulatedMemAlloc() will be applied.
      93             :  */
      94           0 : void TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions *opts,
      95             :                                          tmsize_t max_single_mem_alloc)
      96             : {
      97           0 :     opts->max_single_mem_alloc = max_single_mem_alloc;
      98           0 : }
      99             : 
     100             : /** Define a limit in bytes for the cumulated memory allocations done by libtiff
     101             :  *  on a given TIFF handle.
     102             :  *  If max_cumulated_mem_alloc is set to 0, which is the default, no other limit
     103             :  *  that the underlying _TIFFmalloc() or
     104             :  *  TIFFOpenOptionsSetMaxSingleMemAlloc() will be applied.
     105             :  */
     106       56451 : void TIFFOpenOptionsSetMaxCumulatedMemAlloc(TIFFOpenOptions *opts,
     107             :                                             tmsize_t max_cumulated_mem_alloc)
     108             : {
     109       56451 :     opts->max_cumulated_mem_alloc = max_cumulated_mem_alloc;
     110       56451 : }
     111             : 
     112       56462 : void TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions *opts,
     113             :                                         TIFFErrorHandlerExtR handler,
     114             :                                         void *errorhandler_user_data)
     115             : {
     116       56462 :     opts->errorhandler = handler;
     117       56462 :     opts->errorhandler_user_data = errorhandler_user_data;
     118       56462 : }
     119             : 
     120       56460 : void TIFFOpenOptionsSetWarningHandlerExtR(TIFFOpenOptions *opts,
     121             :                                           TIFFErrorHandlerExtR handler,
     122             :                                           void *warnhandler_user_data)
     123             : {
     124       56460 :     opts->warnhandler = handler;
     125       56460 :     opts->warnhandler_user_data = warnhandler_user_data;
     126       56460 : }
     127             : 
     128           0 : static void _TIFFEmitErrorAboveMaxSingleMemAlloc(TIFF *tif,
     129             :                                                  const char *pszFunction,
     130             :                                                  tmsize_t s)
     131             : {
     132           0 :     TIFFErrorExtR(tif, pszFunction,
     133             :                   "Memory allocation of %" PRIu64
     134             :                   " bytes is beyond the %" PRIu64
     135             :                   " byte limit defined in open options",
     136           0 :                   (uint64_t)s, (uint64_t)tif->tif_max_single_mem_alloc);
     137           0 : }
     138             : 
     139           0 : static void _TIFFEmitErrorAboveMaxCumulatedMemAlloc(TIFF *tif,
     140             :                                                     const char *pszFunction,
     141             :                                                     tmsize_t s)
     142             : {
     143           0 :     TIFFErrorExtR(tif, pszFunction,
     144             :                   "Cumulated memory allocation of %" PRIu64 " + %" PRIu64
     145             :                   " bytes is beyond the %" PRIu64
     146             :                   " cumulated byte limit defined in open options",
     147           0 :                   (uint64_t)tif->tif_cur_cumulated_mem_alloc, (uint64_t)s,
     148           0 :                   (uint64_t)tif->tif_max_cumulated_mem_alloc);
     149           0 : }
     150             : 
     151             : /* When allocating memory, we write at the beginning of the buffer it size.
     152             :  * This allows us to keep track of the total memory allocated when we
     153             :  * malloc/calloc/realloc and free. In theory we need just SIZEOF_SIZE_T bytes
     154             :  * for that, but on x86_64, allocations of more than 16 bytes are aligned on
     155             :  * 16 bytes. Hence using 2 * SIZEOF_SIZE_T.
     156             :  * It is critical that _TIFFmallocExt/_TIFFcallocExt/_TIFFreallocExt are
     157             :  * paired with _TIFFfreeExt.
     158             :  * CMakeLists.txt defines TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS, which in
     159             :  * turn disables the definition of the non Ext version in tiffio.h
     160             :  */
     161             : #define LEADING_AREA_TO_STORE_ALLOC_SIZE (2 * SIZEOF_SIZE_T)
     162             : 
     163             : /** malloc() version that takes into account memory-specific open options */
     164      573487 : void *_TIFFmallocExt(TIFF *tif, tmsize_t s)
     165             : {
     166      573487 :     if (tif != NULL && tif->tif_max_single_mem_alloc > 0 &&
     167           0 :         s > tif->tif_max_single_mem_alloc)
     168             :     {
     169           0 :         _TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFmallocExt", s);
     170           0 :         return NULL;
     171             :     }
     172      573487 :     if (tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
     173             :     {
     174      516392 :         if (s > tif->tif_max_cumulated_mem_alloc -
     175      516392 :                     tif->tif_cur_cumulated_mem_alloc ||
     176      516404 :             s > TIFF_TMSIZE_T_MAX - LEADING_AREA_TO_STORE_ALLOC_SIZE)
     177             :         {
     178           0 :             _TIFFEmitErrorAboveMaxCumulatedMemAlloc(tif, "_TIFFmallocExt", s);
     179           0 :             return NULL;
     180             :         }
     181      516403 :         void *ptr = _TIFFmalloc(LEADING_AREA_TO_STORE_ALLOC_SIZE + s);
     182      516495 :         if (!ptr)
     183           0 :             return NULL;
     184      516495 :         tif->tif_cur_cumulated_mem_alloc += s;
     185      516495 :         memcpy(ptr, &s, sizeof(s));
     186      516495 :         return (char *)ptr + LEADING_AREA_TO_STORE_ALLOC_SIZE;
     187             :     }
     188       57095 :     return _TIFFmalloc(s);
     189             : }
     190             : 
     191             : /** calloc() version that takes into account memory-specific open options */
     192        9133 : void *_TIFFcallocExt(TIFF *tif, tmsize_t nmemb, tmsize_t siz)
     193             : {
     194        9133 :     if (nmemb <= 0 || siz <= 0 || nmemb > TIFF_TMSIZE_T_MAX / siz)
     195           0 :         return NULL;
     196        9133 :     if (tif != NULL && tif->tif_max_single_mem_alloc > 0)
     197             :     {
     198           0 :         if (nmemb * siz > tif->tif_max_single_mem_alloc)
     199             :         {
     200           0 :             _TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFcallocExt",
     201             :                                                  nmemb * siz);
     202           0 :             return NULL;
     203             :         }
     204             :     }
     205        9133 :     if (tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
     206             :     {
     207        9133 :         const tmsize_t s = nmemb * siz;
     208        9133 :         if (s > tif->tif_max_cumulated_mem_alloc -
     209        9133 :                     tif->tif_cur_cumulated_mem_alloc ||
     210        9133 :             s > TIFF_TMSIZE_T_MAX - LEADING_AREA_TO_STORE_ALLOC_SIZE)
     211             :         {
     212           0 :             _TIFFEmitErrorAboveMaxCumulatedMemAlloc(tif, "_TIFFcallocExt", s);
     213           0 :             return NULL;
     214             :         }
     215        9133 :         void *ptr = _TIFFcalloc(LEADING_AREA_TO_STORE_ALLOC_SIZE + s, 1);
     216        9133 :         if (!ptr)
     217           0 :             return NULL;
     218        9133 :         tif->tif_cur_cumulated_mem_alloc += s;
     219        9133 :         memcpy(ptr, &s, sizeof(s));
     220        9133 :         return (char *)ptr + LEADING_AREA_TO_STORE_ALLOC_SIZE;
     221             :     }
     222           0 :     return _TIFFcalloc(nmemb, siz);
     223             : }
     224             : 
     225             : /** realloc() version that takes into account memory-specific open options */
     226     1390320 : void *_TIFFreallocExt(TIFF *tif, void *p, tmsize_t s)
     227             : {
     228     1390320 :     if (tif != NULL && tif->tif_max_single_mem_alloc > 0 &&
     229           0 :         s > tif->tif_max_single_mem_alloc)
     230             :     {
     231           0 :         _TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFreallocExt", s);
     232           0 :         return NULL;
     233             :     }
     234     1390320 :     if (tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
     235             :     {
     236     1335620 :         void *oldPtr = p;
     237     1335620 :         tmsize_t oldSize = 0;
     238     1335620 :         if (p)
     239             :         {
     240      446133 :             oldPtr = (char *)p - LEADING_AREA_TO_STORE_ALLOC_SIZE;
     241      446133 :             memcpy(&oldSize, oldPtr, sizeof(oldSize));
     242      446133 :             assert(oldSize <= tif->tif_cur_cumulated_mem_alloc);
     243             :         }
     244     1335620 :         if (s > oldSize &&
     245     1334430 :             (s > tif->tif_max_cumulated_mem_alloc -
     246     1334430 :                      (tif->tif_cur_cumulated_mem_alloc - oldSize) ||
     247     1334390 :              s > TIFF_TMSIZE_T_MAX - LEADING_AREA_TO_STORE_ALLOC_SIZE))
     248             :         {
     249          42 :             _TIFFEmitErrorAboveMaxCumulatedMemAlloc(tif, "_TIFFreallocExt",
     250             :                                                     s - oldSize);
     251           0 :             return NULL;
     252             :         }
     253             :         void *newPtr =
     254     1335580 :             _TIFFrealloc(oldPtr, LEADING_AREA_TO_STORE_ALLOC_SIZE + s);
     255     1335790 :         if (newPtr == NULL)
     256           0 :             return NULL;
     257     1335790 :         tif->tif_cur_cumulated_mem_alloc -= oldSize;
     258     1335790 :         tif->tif_cur_cumulated_mem_alloc += s;
     259     1335790 :         memcpy(newPtr, &s, sizeof(s));
     260     1335790 :         return (char *)newPtr + LEADING_AREA_TO_STORE_ALLOC_SIZE;
     261             :     }
     262       54701 :     return _TIFFrealloc(p, s);
     263             : }
     264             : 
     265             : /** free() version that takes into account memory-specific open options */
     266     1503000 : void _TIFFfreeExt(TIFF *tif, void *p)
     267             : {
     268     1503000 :     if (p != NULL && tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
     269             :     {
     270     1415210 :         void *oldPtr = (char *)p - LEADING_AREA_TO_STORE_ALLOC_SIZE;
     271             :         tmsize_t oldSize;
     272     1415210 :         memcpy(&oldSize, oldPtr, sizeof(oldSize));
     273     1415210 :         assert(oldSize <= tif->tif_cur_cumulated_mem_alloc);
     274     1415210 :         tif->tif_cur_cumulated_mem_alloc -= oldSize;
     275     1415210 :         p = oldPtr;
     276             :     }
     277     1503000 :     _TIFFfree(p);
     278     1503080 : }
     279             : 
     280           0 : TIFF *TIFFClientOpen(const char *name, const char *mode, thandle_t clientdata,
     281             :                      TIFFReadWriteProc readproc, TIFFReadWriteProc writeproc,
     282             :                      TIFFSeekProc seekproc, TIFFCloseProc closeproc,
     283             :                      TIFFSizeProc sizeproc, TIFFMapFileProc mapproc,
     284             :                      TIFFUnmapFileProc unmapproc)
     285             : {
     286           0 :     return TIFFClientOpenExt(name, mode, clientdata, readproc, writeproc,
     287             :                              seekproc, closeproc, sizeproc, mapproc, unmapproc,
     288             :                              NULL);
     289             : }
     290             : 
     291       56471 : TIFF *TIFFClientOpenExt(const char *name, const char *mode,
     292             :                         thandle_t clientdata, TIFFReadWriteProc readproc,
     293             :                         TIFFReadWriteProc writeproc, TIFFSeekProc seekproc,
     294             :                         TIFFCloseProc closeproc, TIFFSizeProc sizeproc,
     295             :                         TIFFMapFileProc mapproc, TIFFUnmapFileProc unmapproc,
     296             :                         TIFFOpenOptions *opts)
     297             : {
     298             :     static const char module[] = "TIFFClientOpenExt";
     299             :     TIFF *tif;
     300             :     int m;
     301             :     const char *cp;
     302             : 
     303             :     /* The following are configuration checks. They should be redundant, but
     304             :      * should not compile to any actual code in an optimised release build
     305             :      * anyway. If any of them fail, (makefile-based or other) configuration is
     306             :      * not correct */
     307             :     assert(sizeof(uint8_t) == 1);
     308             :     assert(sizeof(int8_t) == 1);
     309             :     assert(sizeof(uint16_t) == 2);
     310             :     assert(sizeof(int16_t) == 2);
     311             :     assert(sizeof(uint32_t) == 4);
     312             :     assert(sizeof(int32_t) == 4);
     313             :     assert(sizeof(uint64_t) == 8);
     314             :     assert(sizeof(int64_t) == 8);
     315             :     {
     316             :         union
     317             :         {
     318             :             uint8_t a8[2];
     319             :             uint16_t a16;
     320             :         } n;
     321       56471 :         n.a8[0] = 1;
     322       56471 :         n.a8[1] = 0;
     323             :         (void)n;
     324             : #ifdef WORDS_BIGENDIAN
     325             :         assert(n.a16 == 256);
     326             : #else
     327       56471 :         assert(n.a16 == 1);
     328             : #endif
     329             :     }
     330             : 
     331       56471 :     m = _TIFFgetMode(opts, clientdata, mode, module);
     332       56452 :     if (m == -1)
     333           0 :         goto bad2;
     334       56452 :     tmsize_t size_to_alloc = (tmsize_t)(sizeof(TIFF) + strlen(name) + 1);
     335       56452 :     if (opts && opts->max_single_mem_alloc > 0 &&
     336           0 :         size_to_alloc > opts->max_single_mem_alloc)
     337             :     {
     338           0 :         _TIFFErrorEarly(opts, clientdata, module,
     339             :                         "%s: Memory allocation of %" PRIu64
     340             :                         " bytes is beyond the %" PRIu64
     341             :                         " byte limit defined in open options",
     342             :                         name, (uint64_t)size_to_alloc,
     343           0 :                         (uint64_t)opts->max_single_mem_alloc);
     344           0 :         goto bad2;
     345             :     }
     346       56452 :     if (opts && opts->max_cumulated_mem_alloc > 0 &&
     347       56457 :         size_to_alloc > opts->max_cumulated_mem_alloc)
     348             :     {
     349           0 :         _TIFFErrorEarly(opts, clientdata, module,
     350             :                         "%s: Memory allocation of %" PRIu64
     351             :                         " bytes is beyond the %" PRIu64
     352             :                         " cumulated byte limit defined in open options",
     353             :                         name, (uint64_t)size_to_alloc,
     354           0 :                         (uint64_t)opts->max_cumulated_mem_alloc);
     355           0 :         goto bad2;
     356             :     }
     357       56452 :     tif = (TIFF *)_TIFFmallocExt(NULL, size_to_alloc);
     358       56470 :     if (tif == NULL)
     359             :     {
     360           0 :         _TIFFErrorEarly(opts, clientdata, module,
     361             :                         "%s: Out of memory (TIFF structure)", name);
     362           0 :         goto bad2;
     363             :     }
     364       56470 :     _TIFFmemset(tif, 0, sizeof(*tif));
     365       56462 :     tif->tif_name = (char *)tif + sizeof(TIFF);
     366       56462 :     strcpy(tif->tif_name, name);
     367       56462 :     tif->tif_mode = m & ~(O_CREAT | O_TRUNC);
     368       56462 :     tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER; /* non-existent directory */
     369       56462 :     tif->tif_curoff = 0;
     370       56462 :     tif->tif_curstrip = (uint32_t)-1; /* invalid strip */
     371       56462 :     tif->tif_row = (uint32_t)-1;      /* read/write pre-increment */
     372       56462 :     tif->tif_clientdata = clientdata;
     373       56462 :     tif->tif_readproc = readproc;
     374       56462 :     tif->tif_writeproc = writeproc;
     375       56462 :     tif->tif_seekproc = seekproc;
     376       56462 :     tif->tif_closeproc = closeproc;
     377       56462 :     tif->tif_sizeproc = sizeproc;
     378       56462 :     tif->tif_mapproc = mapproc ? mapproc : _tiffDummyMapProc;
     379       56462 :     tif->tif_unmapproc = unmapproc ? unmapproc : _tiffDummyUnmapProc;
     380       56462 :     if (opts)
     381             :     {
     382       56447 :         tif->tif_errorhandler = opts->errorhandler;
     383       56447 :         tif->tif_errorhandler_user_data = opts->errorhandler_user_data;
     384       56447 :         tif->tif_warnhandler = opts->warnhandler;
     385       56447 :         tif->tif_warnhandler_user_data = opts->warnhandler_user_data;
     386       56447 :         tif->tif_max_single_mem_alloc = opts->max_single_mem_alloc;
     387       56447 :         tif->tif_max_cumulated_mem_alloc = opts->max_cumulated_mem_alloc;
     388             :     }
     389             : 
     390       56462 :     if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc)
     391             :     {
     392          15 :         TIFFErrorExtR(tif, module,
     393             :                       "One of the client procedures is NULL pointer.");
     394           0 :         _TIFFfreeExt(NULL, tif);
     395           0 :         goto bad2;
     396             :     }
     397             : 
     398       56447 :     _TIFFSetDefaultCompressionState(tif); /* setup default state */
     399             :     /*
     400             :      * Default is to return data MSB2LSB and enable the
     401             :      * use of memory-mapped files and strip chopping when
     402             :      * a file is opened read-only.
     403             :      */
     404       56468 :     tif->tif_flags = FILLORDER_MSB2LSB;
     405       56468 :     if (m == O_RDONLY)
     406       18939 :         tif->tif_flags |= TIFF_MAPPED;
     407             : 
     408             : #ifdef STRIPCHOP_DEFAULT
     409       56468 :     if (m == O_RDONLY || m == O_RDWR)
     410       21468 :         tif->tif_flags |= STRIPCHOP_DEFAULT;
     411             : #endif
     412             : 
     413             :     /*
     414             :      * Process library-specific flags in the open mode string.
     415             :      * The following flags may be used to control intrinsic library
     416             :      * behavior that may or may not be desirable (usually for
     417             :      * compatibility with some application that claims to support
     418             :      * TIFF but only supports some brain dead idea of what the
     419             :      * vendor thinks TIFF is):
     420             :      *
     421             :      * 'l' use little-endian byte order for creating a file
     422             :      * 'b' use big-endian byte order for creating a file
     423             :      * 'L' read/write information using LSB2MSB bit order
     424             :      * 'B' read/write information using MSB2LSB bit order
     425             :      * 'H' read/write information using host bit order
     426             :      * 'M' enable use of memory-mapped files when supported
     427             :      * 'm' disable use of memory-mapped files
     428             :      * 'C' enable strip chopping support when reading
     429             :      * 'c' disable strip chopping support
     430             :      * 'h' read TIFF header only, do not load the first IFD
     431             :      * '4' ClassicTIFF for creating a file (default)
     432             :      * '8' BigTIFF for creating a file
     433             :      * 'D' enable use of deferred strip/tile offset/bytecount array loading.
     434             :      * 'O' on-demand loading of values instead of whole array loading (implies
     435             :      * D)
     436             :      *
     437             :      * The use of the 'l' and 'b' flags is strongly discouraged.
     438             :      * These flags are provided solely because numerous vendors,
     439             :      * typically on the PC, do not correctly support TIFF; they
     440             :      * only support the Intel little-endian byte order.  This
     441             :      * support is not configured by default because it supports
     442             :      * the violation of the TIFF spec that says that readers *MUST*
     443             :      * support both byte orders.  It is strongly recommended that
     444             :      * you not use this feature except to deal with busted apps
     445             :      * that write invalid TIFF.  And even in those cases you should
     446             :      * bang on the vendors to fix their software.
     447             :      *
     448             :      * The 'L', 'B', and 'H' flags are intended for applications
     449             :      * that can optimize operations on data by using a particular
     450             :      * bit order.  By default the library returns data in MSB2LSB
     451             :      * bit order for compatibility with older versions of this
     452             :      * library.  Returning data in the bit order of the native CPU
     453             :      * makes the most sense but also requires applications to check
     454             :      * the value of the FillOrder tag; something they probably do
     455             :      * not do right now.
     456             :      *
     457             :      * The 'M' and 'm' flags are provided because some virtual memory
     458             :      * systems exhibit poor behavior when large images are mapped.
     459             :      * These options permit clients to control the use of memory-mapped
     460             :      * files on a per-file basis.
     461             :      *
     462             :      * The 'C' and 'c' flags are provided because the library support
     463             :      * for chopping up large strips into multiple smaller strips is not
     464             :      * application-transparent and as such can cause problems.  The 'c'
     465             :      * option permits applications that only want to look at the tags,
     466             :      * for example, to get the unadulterated TIFF tag information.
     467             :      */
     468      228003 :     for (cp = mode; *cp; cp++)
     469      171535 :         switch (*cp)
     470             :         {
     471          82 :             case 'b':
     472             : #ifndef WORDS_BIGENDIAN
     473          82 :                 if (m & O_CREAT)
     474          82 :                     tif->tif_flags |= TIFF_SWAB;
     475             : #endif
     476          82 :                 break;
     477       28522 :             case 'l':
     478             : #ifdef WORDS_BIGENDIAN
     479             :                 if ((m & O_CREAT))
     480             :                     tif->tif_flags |= TIFF_SWAB;
     481             : #endif
     482       28522 :                 break;
     483           0 :             case 'B':
     484           0 :                 tif->tif_flags =
     485           0 :                     (tif->tif_flags & ~TIFF_FILLORDER) | FILLORDER_MSB2LSB;
     486           0 :                 break;
     487           0 :             case 'L':
     488           0 :                 tif->tif_flags =
     489           0 :                     (tif->tif_flags & ~TIFF_FILLORDER) | FILLORDER_LSB2MSB;
     490           0 :                 break;
     491           0 :             case 'H':
     492           0 :                 TIFFWarningExtR(tif, name,
     493             :                                 "H(ost) mode is deprecated. Since "
     494             :                                 "libtiff 4.5.1, it is an alias of 'B' / "
     495             :                                 "FILLORDER_MSB2LSB.");
     496           0 :                 tif->tif_flags =
     497           0 :                     (tif->tif_flags & ~TIFF_FILLORDER) | FILLORDER_MSB2LSB;
     498           0 :                 break;
     499           0 :             case 'M':
     500           0 :                 if (m == O_RDONLY)
     501           0 :                     tif->tif_flags |= TIFF_MAPPED;
     502           0 :                 break;
     503           0 :             case 'm':
     504           0 :                 if (m == O_RDONLY)
     505           0 :                     tif->tif_flags &= ~TIFF_MAPPED;
     506           0 :                 break;
     507       15829 :             case 'C':
     508       15829 :                 if (m == O_RDONLY)
     509       15147 :                     tif->tif_flags |= TIFF_STRIPCHOP;
     510       15829 :                 break;
     511         579 :             case 'c':
     512         579 :                 if (m == O_RDONLY)
     513         579 :                     tif->tif_flags &= ~TIFF_STRIPCHOP;
     514         579 :                 break;
     515           0 :             case 'h':
     516           0 :                 tif->tif_flags |= TIFF_HEADERONLY;
     517           0 :                 break;
     518          74 :             case '8':
     519          74 :                 if (m & O_CREAT)
     520          74 :                     tif->tif_flags |= TIFF_BIGTIFF;
     521          74 :                 break;
     522       16879 :             case 'D':
     523       16879 :                 tif->tif_flags |= TIFF_DEFERSTRILELOAD;
     524       16879 :                 break;
     525       15832 :             case 'O':
     526       15832 :                 if (m == O_RDONLY)
     527       15831 :                     tif->tif_flags |=
     528             :                         (TIFF_LAZYSTRILELOAD | TIFF_DEFERSTRILELOAD);
     529       15832 :                 break;
     530             :         }
     531             : 
     532             : #ifdef DEFER_STRILE_LOAD
     533             :     /* Compatibility with old DEFER_STRILE_LOAD compilation flag */
     534             :     /* Probably unneeded, since to the best of my knowledge (E. Rouault) */
     535             :     /* GDAL was the only user of this, and will now use the new 'D' flag */
     536             :     tif->tif_flags |= TIFF_DEFERSTRILELOAD;
     537             : #endif
     538             : 
     539             :     /*
     540             :      * Read in TIFF header.
     541             :      */
     542      249487 :     if ((m & O_TRUNC) ||
     543       21470 :         !ReadOK(tif, &tif->tif_header, sizeof(TIFFHeaderClassic)))
     544             :     {
     545       34980 :         if (tif->tif_mode == O_RDONLY)
     546             :         {
     547           0 :             TIFFErrorExtR(tif, name, "Cannot read TIFF header");
     548           2 :             goto bad;
     549             :         }
     550             :         /*
     551             :          * Setup header and write.
     552             :          */
     553             : #ifdef WORDS_BIGENDIAN
     554             :         tif->tif_header.common.tiff_magic =
     555             :             (tif->tif_flags & TIFF_SWAB) ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN;
     556             : #else
     557       34980 :         tif->tif_header.common.tiff_magic =
     558       34980 :             (tif->tif_flags & TIFF_SWAB) ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
     559             : #endif
     560             :         TIFFHeaderUnion tif_header_swapped;
     561       34980 :         if (!(tif->tif_flags & TIFF_BIGTIFF))
     562             :         {
     563       34906 :             tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC;
     564       34906 :             tif->tif_header.classic.tiff_diroff = 0;
     565       34906 :             tif->tif_header_size = sizeof(TIFFHeaderClassic);
     566             :             /* Swapped copy for writing */
     567       34906 :             _TIFFmemcpy(&tif_header_swapped, &tif->tif_header,
     568             :                         sizeof(TIFFHeaderUnion));
     569       34906 :             if (tif->tif_flags & TIFF_SWAB)
     570          78 :                 TIFFSwabShort(&tif_header_swapped.common.tiff_version);
     571             :         }
     572             :         else
     573             :         {
     574          74 :             tif->tif_header.common.tiff_version = TIFF_VERSION_BIG;
     575          74 :             tif->tif_header.big.tiff_offsetsize = 8;
     576          74 :             tif->tif_header.big.tiff_unused = 0;
     577          74 :             tif->tif_header.big.tiff_diroff = 0;
     578          74 :             tif->tif_header_size = sizeof(TIFFHeaderBig);
     579             :             /* Swapped copy for writing */
     580          74 :             _TIFFmemcpy(&tif_header_swapped, &tif->tif_header,
     581             :                         sizeof(TIFFHeaderUnion));
     582          74 :             if (tif->tif_flags & TIFF_SWAB)
     583             :             {
     584           4 :                 TIFFSwabShort(&tif_header_swapped.common.tiff_version);
     585           4 :                 TIFFSwabShort(&tif_header_swapped.big.tiff_offsetsize);
     586             :             }
     587             :         }
     588             :         /*
     589             :          * The doc for "fopen" for some STD_C_LIBs says that if you
     590             :          * open a file for modify ("+"), then you must fseek (or
     591             :          * fflush?) between any freads and fwrites.  This is not
     592             :          * necessary on most systems, but has been shown to be needed
     593             :          * on Solaris.
     594             :          */
     595       34980 :         TIFFSeekFile(tif, 0, SEEK_SET);
     596       34980 :         if (!WriteOK(tif, &tif_header_swapped,
     597             :                      (tmsize_t)(tif->tif_header_size)))
     598             :         {
     599           2 :             TIFFErrorExtR(tif, name, "Error writing TIFF header");
     600           2 :             goto bad;
     601             :         }
     602             :         /*
     603             :          * Setup default directory.
     604             :          */
     605       34978 :         if (!TIFFDefaultDirectory(tif))
     606           0 :             goto bad;
     607       34978 :         tif->tif_diroff = 0;
     608       34978 :         tif->tif_lastdiroff = 0;
     609       34978 :         tif->tif_setdirectory_force_absolute = FALSE;
     610       34978 :         return (tif);
     611             :     }
     612             : 
     613             :     /*
     614             :      * Setup the byte order handling according to the opened file for reading.
     615             :      */
     616       21502 :     if (tif->tif_header.common.tiff_magic != TIFF_BIGENDIAN &&
     617       21267 :         tif->tif_header.common.tiff_magic != TIFF_LITTLEENDIAN
     618             : #if MDI_SUPPORT
     619             :         &&
     620             : #if HOST_BIGENDIAN
     621             :         tif->tif_header.common.tiff_magic != MDI_BIGENDIAN
     622             : #else
     623             :         tif->tif_header.common.tiff_magic != MDI_LITTLEENDIAN
     624             : #endif
     625             :     )
     626             :     {
     627             :         TIFFErrorExtR(tif, name,
     628             :                       "Not a TIFF or MDI file, bad magic number %" PRIu16
     629             :                       " (0x%" PRIx16 ")",
     630             : #else
     631             :     )
     632             :     {
     633           0 :         TIFFErrorExtR(tif, name,
     634             :                       "Not a TIFF file, bad magic number %" PRIu16
     635             :                       " (0x%" PRIx16 ")",
     636             : #endif
     637           0 :                       tif->tif_header.common.tiff_magic,
     638           0 :                       tif->tif_header.common.tiff_magic);
     639           0 :         goto bad;
     640             :     }
     641       21502 :     if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN)
     642             :     {
     643             : #ifndef WORDS_BIGENDIAN
     644         217 :         tif->tif_flags |= TIFF_SWAB;
     645             : #endif
     646             :     }
     647             :     else
     648             :     {
     649             : #ifdef WORDS_BIGENDIAN
     650             :         tif->tif_flags |= TIFF_SWAB;
     651             : #endif
     652             :     }
     653       21502 :     if (tif->tif_flags & TIFF_SWAB)
     654         217 :         TIFFSwabShort(&tif->tif_header.common.tiff_version);
     655       21478 :     if ((tif->tif_header.common.tiff_version != TIFF_VERSION_CLASSIC) &&
     656         280 :         (tif->tif_header.common.tiff_version != TIFF_VERSION_BIG))
     657             :     {
     658           0 :         TIFFErrorExtR(tif, name,
     659             :                       "Not a TIFF file, bad version number %" PRIu16
     660             :                       " (0x%" PRIx16 ")",
     661           0 :                       tif->tif_header.common.tiff_version,
     662           0 :                       tif->tif_header.common.tiff_version);
     663           0 :         goto bad;
     664             :     }
     665       21478 :     if (tif->tif_header.common.tiff_version == TIFF_VERSION_CLASSIC)
     666             :     {
     667       21198 :         if (tif->tif_flags & TIFF_SWAB)
     668         206 :             TIFFSwabLong(&tif->tif_header.classic.tiff_diroff);
     669       21187 :         tif->tif_header_size = sizeof(TIFFHeaderClassic);
     670             :     }
     671             :     else
     672             :     {
     673         280 :         if (!ReadOK(tif,
     674             :                     ((uint8_t *)(&tif->tif_header) + sizeof(TIFFHeaderClassic)),
     675             :                     (sizeof(TIFFHeaderBig) - sizeof(TIFFHeaderClassic))))
     676             :         {
     677           0 :             TIFFErrorExtR(tif, name, "Cannot read TIFF header");
     678           0 :             goto bad;
     679             :         }
     680         280 :         if (tif->tif_flags & TIFF_SWAB)
     681             :         {
     682          11 :             TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize);
     683          11 :             TIFFSwabLong8(&tif->tif_header.big.tiff_diroff);
     684             :         }
     685         280 :         if (tif->tif_header.big.tiff_offsetsize != 8)
     686             :         {
     687           0 :             TIFFErrorExtR(tif, name,
     688             :                           "Not a TIFF file, bad BigTIFF offsetsize %" PRIu16
     689             :                           " (0x%" PRIx16 ")",
     690           0 :                           tif->tif_header.big.tiff_offsetsize,
     691           0 :                           tif->tif_header.big.tiff_offsetsize);
     692           0 :             goto bad;
     693             :         }
     694         280 :         if (tif->tif_header.big.tiff_unused != 0)
     695             :         {
     696           0 :             TIFFErrorExtR(tif, name,
     697             :                           "Not a TIFF file, bad BigTIFF unused %" PRIu16
     698             :                           " (0x%" PRIx16 ")",
     699           0 :                           tif->tif_header.big.tiff_unused,
     700           0 :                           tif->tif_header.big.tiff_unused);
     701           0 :             goto bad;
     702             :         }
     703         280 :         tif->tif_header_size = sizeof(TIFFHeaderBig);
     704         280 :         tif->tif_flags |= TIFF_BIGTIFF;
     705             :     }
     706       21467 :     tif->tif_flags |= TIFF_MYBUFFER;
     707       21467 :     tif->tif_rawcp = tif->tif_rawdata = 0;
     708       21467 :     tif->tif_rawdatasize = 0;
     709       21467 :     tif->tif_rawdataoff = 0;
     710       21467 :     tif->tif_rawdataloaded = 0;
     711             : 
     712       21467 :     switch (mode[0])
     713             :     {
     714       21496 :         case 'r':
     715       21496 :             if (!(tif->tif_flags & TIFF_BIGTIFF))
     716       21213 :                 tif->tif_nextdiroff = tif->tif_header.classic.tiff_diroff;
     717             :             else
     718         283 :                 tif->tif_nextdiroff = tif->tif_header.big.tiff_diroff;
     719             :             /*
     720             :              * Try to use a memory-mapped file if the client
     721             :              * has not explicitly suppressed usage with the
     722             :              * 'm' flag in the open mode (see above).
     723             :              */
     724       21496 :             if (tif->tif_flags & TIFF_MAPPED)
     725             :             {
     726             :                 toff_t n;
     727       18938 :                 if (TIFFMapFileContents(tif, (void **)(&tif->tif_base), &n))
     728             :                 {
     729          16 :                     tif->tif_size = (tmsize_t)n;
     730          16 :                     assert((toff_t)tif->tif_size == n);
     731             :                 }
     732             :                 else
     733       18915 :                     tif->tif_flags &= ~TIFF_MAPPED;
     734             :             }
     735             :             /*
     736             :              * Sometimes we do not want to read the first directory (for
     737             :              * example, it may be broken) and want to proceed to other
     738             :              * directories. I this case we use the TIFF_HEADERONLY flag to open
     739             :              * file and return immediately after reading TIFF header.
     740             :              */
     741       21489 :             if (tif->tif_flags & TIFF_HEADERONLY)
     742           0 :                 return (tif);
     743             : 
     744             :             /*
     745             :              * Setup initial directory.
     746             :              */
     747       21489 :             if (TIFFReadDirectory(tif))
     748             :             {
     749       21453 :                 return (tif);
     750             :             }
     751          27 :             break;
     752           0 :         case 'a':
     753             :             /*
     754             :              * New directories are automatically append
     755             :              * to the end of the directory chain when they
     756             :              * are written out (see TIFFWriteDirectory).
     757             :              */
     758           0 :             if (!TIFFDefaultDirectory(tif))
     759           0 :                 goto bad;
     760           0 :             return (tif);
     761             :     }
     762           0 : bad:
     763           0 :     tif->tif_mode = O_RDONLY; /* XXX avoid flush */
     764           0 :     TIFFCleanup(tif);
     765          14 : bad2:
     766          14 :     return ((TIFF *)0);
     767             : }
     768             : 
     769             : /*
     770             :  * Query functions to access private data.
     771             :  */
     772             : 
     773             : /*
     774             :  * Return open file's name.
     775             :  */
     776           6 : const char *TIFFFileName(TIFF *tif) { return (tif->tif_name); }
     777             : 
     778             : /*
     779             :  * Set the file name.
     780             :  */
     781           0 : const char *TIFFSetFileName(TIFF *tif, const char *name)
     782             : {
     783           0 :     const char *old_name = tif->tif_name;
     784           0 :     tif->tif_name = (char *)name;
     785           0 :     return (old_name);
     786             : }
     787             : 
     788             : /*
     789             :  * Return open file's I/O descriptor.
     790             :  */
     791           0 : int TIFFFileno(TIFF *tif) { return (tif->tif_fd); }
     792             : 
     793             : /*
     794             :  * Set open file's I/O descriptor, and return previous value.
     795             :  */
     796           0 : int TIFFSetFileno(TIFF *tif, int fd)
     797             : {
     798           0 :     int old_fd = tif->tif_fd;
     799           0 :     tif->tif_fd = fd;
     800           0 :     return old_fd;
     801             : }
     802             : 
     803             : /*
     804             :  * Return open file's clientdata.
     805             :  */
     806       91428 : thandle_t TIFFClientdata(TIFF *tif) { return (tif->tif_clientdata); }
     807             : 
     808             : /*
     809             :  * Set open file's clientdata, and return previous value.
     810             :  */
     811           0 : thandle_t TIFFSetClientdata(TIFF *tif, thandle_t newvalue)
     812             : {
     813           0 :     thandle_t m = tif->tif_clientdata;
     814           0 :     tif->tif_clientdata = newvalue;
     815           0 :     return m;
     816             : }
     817             : 
     818             : /*
     819             :  * Return read/write mode.
     820             :  */
     821           0 : int TIFFGetMode(TIFF *tif) { return (tif->tif_mode); }
     822             : 
     823             : /*
     824             :  * Return read/write mode.
     825             :  */
     826           0 : int TIFFSetMode(TIFF *tif, int mode)
     827             : {
     828           0 :     int old_mode = tif->tif_mode;
     829           0 :     tif->tif_mode = mode;
     830           0 :     return (old_mode);
     831             : }
     832             : 
     833             : /*
     834             :  * Return nonzero if file is organized in
     835             :  * tiles; zero if organized as strips.
     836             :  */
     837     4785430 : int TIFFIsTiled(TIFF *tif) { return (isTiled(tif)); }
     838             : 
     839             : /*
     840             :  * Return current row being read/written.
     841             :  */
     842           0 : uint32_t TIFFCurrentRow(TIFF *tif) { return (tif->tif_row); }
     843             : 
     844             : /*
     845             :  * Return index of the current directory.
     846             :  */
     847           0 : tdir_t TIFFCurrentDirectory(TIFF *tif) { return (tif->tif_curdir); }
     848             : 
     849             : /*
     850             :  * Return current strip.
     851             :  */
     852           0 : uint32_t TIFFCurrentStrip(TIFF *tif) { return (tif->tif_curstrip); }
     853             : 
     854             : /*
     855             :  * Return current tile.
     856             :  */
     857           0 : uint32_t TIFFCurrentTile(TIFF *tif) { return (tif->tif_curtile); }
     858             : 
     859             : /*
     860             :  * Return nonzero if the file has byte-swapped data.
     861             :  */
     862      103723 : int TIFFIsByteSwapped(TIFF *tif) { return ((tif->tif_flags & TIFF_SWAB) != 0); }
     863             : 
     864             : /*
     865             :  * Return nonzero if the data is returned up-sampled.
     866             :  */
     867           0 : int TIFFIsUpSampled(TIFF *tif) { return (isUpSampled(tif)); }
     868             : 
     869             : /*
     870             :  * Return nonzero if the data is returned in MSB-to-LSB bit order.
     871             :  */
     872           0 : int TIFFIsMSB2LSB(TIFF *tif) { return (isFillOrder(tif, FILLORDER_MSB2LSB)); }
     873             : 
     874             : /*
     875             :  * Return nonzero if given file was written in big-endian order.
     876             :  */
     877       26219 : int TIFFIsBigEndian(TIFF *tif)
     878             : {
     879       26219 :     return (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN);
     880             : }
     881             : 
     882             : /*
     883             :  * Return nonzero if given file is BigTIFF style.
     884             :  */
     885           0 : int TIFFIsBigTIFF(TIFF *tif) { return ((tif->tif_flags & TIFF_BIGTIFF) != 0); }
     886             : 
     887             : /*
     888             :  * Return pointer to file read method.
     889             :  */
     890           0 : TIFFReadWriteProc TIFFGetReadProc(TIFF *tif) { return (tif->tif_readproc); }
     891             : 
     892             : /*
     893             :  * Return pointer to file write method.
     894             :  */
     895           0 : TIFFReadWriteProc TIFFGetWriteProc(TIFF *tif) { return (tif->tif_writeproc); }
     896             : 
     897             : /*
     898             :  * Return pointer to file seek method.
     899             :  */
     900           0 : TIFFSeekProc TIFFGetSeekProc(TIFF *tif) { return (tif->tif_seekproc); }
     901             : 
     902             : /*
     903             :  * Return pointer to file close method.
     904             :  */
     905           0 : TIFFCloseProc TIFFGetCloseProc(TIFF *tif) { return (tif->tif_closeproc); }
     906             : 
     907             : /*
     908             :  * Return pointer to file size requesting method.
     909             :  */
     910       10175 : TIFFSizeProc TIFFGetSizeProc(TIFF *tif) { return (tif->tif_sizeproc); }
     911             : 
     912             : /*
     913             :  * Return pointer to memory mapping method.
     914             :  */
     915           0 : TIFFMapFileProc TIFFGetMapFileProc(TIFF *tif) { return (tif->tif_mapproc); }
     916             : 
     917             : /*
     918             :  * Return pointer to memory unmapping method.
     919             :  */
     920           0 : TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF *tif)
     921             : {
     922           0 :     return (tif->tif_unmapproc);
     923             : }

Generated by: LCOV version 1.14