LCOV - code coverage report
Current view: top level - frmts/gtiff/libtiff - tif_open.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 240 377 63.7 %
Date: 2025-12-17 16:19:51 Functions: 18 43 41.9 %

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

Generated by: LCOV version 1.14