LCOV - code coverage report
Current view: top level - frmts/gtiff/libtiff - tif_open.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 241 381 63.3 %
Date: 2026-02-14 05:03:47 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       70514 : int _TIFFgetMode(TIFFOpenOptions *opts, thandle_t clientdata, const char *mode,
      56             :                  const char *module)
      57             : {
      58       70514 :     int m = -1;
      59             : 
      60       70514 :     switch (mode[0])
      61             :     {
      62       31046 :         case 'r':
      63       31046 :             m = O_RDONLY;
      64       31046 :             if (mode[1] == '+')
      65        3841 :                 m = O_RDWR;
      66       31046 :             break;
      67       39444 :         case 'w':
      68             :         case 'a':
      69       39444 :             m = O_RDWR | O_CREAT;
      70       39444 :             if (mode[0] == 'w')
      71       39444 :                 m |= O_TRUNC;
      72       39444 :             break;
      73          24 :         default:
      74          24 :             _TIFFErrorEarly(opts, clientdata, module, "\"%s\": Bad mode", mode);
      75           0 :             break;
      76             :     }
      77       70490 :     return (m);
      78             : }
      79             : 
      80       70556 : TIFFOpenOptions *TIFFOpenOptionsAlloc(void)
      81             : {
      82             :     TIFFOpenOptions *opts =
      83       70556 :         (TIFFOpenOptions *)_TIFFcalloc(1, sizeof(TIFFOpenOptions));
      84       70514 :     return opts;
      85             : }
      86             : 
      87       70534 : 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       70518 : void TIFFOpenOptionsSetMaxCumulatedMemAlloc(TIFFOpenOptions *opts,
     107             :                                             tmsize_t max_cumulated_mem_alloc)
     108             : {
     109       70518 :     opts->max_cumulated_mem_alloc = max_cumulated_mem_alloc;
     110       70518 : }
     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       70543 : void TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions *opts,
     122             :                                         TIFFErrorHandlerExtR handler,
     123             :                                         void *errorhandler_user_data)
     124             : {
     125       70543 :     opts->errorhandler = handler;
     126       70543 :     opts->errorhandler_user_data = errorhandler_user_data;
     127       70543 : }
     128             : 
     129       70552 : void TIFFOpenOptionsSetWarningHandlerExtR(TIFFOpenOptions *opts,
     130             :                                           TIFFErrorHandlerExtR handler,
     131             :                                           void *warnhandler_user_data)
     132             : {
     133       70552 :     opts->warnhandler = handler;
     134       70552 :     opts->warnhandler_user_data = warnhandler_user_data;
     135       70552 : }
     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      720186 : void *_TIFFmallocExt(TIFF *tif, tmsize_t s)
     174             : {
     175      720186 :     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      720186 :     if (tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
     182             :     {
     183      648120 :         if (s > tif->tif_max_cumulated_mem_alloc -
     184      648120 :                     tif->tif_cur_cumulated_mem_alloc ||
     185      647982 :             s > TIFF_TMSIZE_T_MAX - LEADING_AREA_TO_STORE_ALLOC_SIZE)
     186             :         {
     187         157 :             _TIFFEmitErrorAboveMaxCumulatedMemAlloc(tif, "_TIFFmallocExt", s);
     188           0 :             return NULL;
     189             :         }
     190      647963 :         void *ptr = _TIFFmalloc(LEADING_AREA_TO_STORE_ALLOC_SIZE + s);
     191      648257 :         if (!ptr)
     192           0 :             return NULL;
     193      648257 :         tif->tif_cur_cumulated_mem_alloc += s;
     194      648257 :         memcpy(ptr, &s, sizeof(s));
     195      648257 :         return (char *)ptr + LEADING_AREA_TO_STORE_ALLOC_SIZE;
     196             :     }
     197       72066 :     return _TIFFmalloc(s);
     198             : }
     199             : 
     200             : /** calloc() version that takes into account memory-specific open options */
     201        9808 : void *_TIFFcallocExt(TIFF *tif, tmsize_t nmemb, tmsize_t siz)
     202             : {
     203        9808 :     if (nmemb <= 0 || siz <= 0 || nmemb > TIFF_TMSIZE_T_MAX / siz)
     204           0 :         return NULL;
     205        9808 :     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        9808 :     if (tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
     215             :     {
     216        9808 :         const tmsize_t s = nmemb * siz;
     217        9808 :         if (s > tif->tif_max_cumulated_mem_alloc -
     218        9808 :                     tif->tif_cur_cumulated_mem_alloc ||
     219        9808 :             s > TIFF_TMSIZE_T_MAX - LEADING_AREA_TO_STORE_ALLOC_SIZE)
     220             :         {
     221           0 :             _TIFFEmitErrorAboveMaxCumulatedMemAlloc(tif, "_TIFFcallocExt", s);
     222           0 :             return NULL;
     223             :         }
     224        9808 :         void *ptr = _TIFFcalloc(LEADING_AREA_TO_STORE_ALLOC_SIZE + s, 1);
     225        9808 :         if (!ptr)
     226           0 :             return NULL;
     227        9808 :         tif->tif_cur_cumulated_mem_alloc += s;
     228        9808 :         memcpy(ptr, &s, sizeof(s));
     229        9808 :         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     1834320 : void *_TIFFreallocExt(TIFF *tif, void *p, tmsize_t s)
     236             : {
     237     1834320 :     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     1834320 :     if (tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
     244             :     {
     245     1753700 :         void *oldPtr = p;
     246     1753700 :         tmsize_t oldSize = 0;
     247     1753700 :         if (p)
     248             :         {
     249      568905 :             oldPtr = (char *)p - LEADING_AREA_TO_STORE_ALLOC_SIZE;
     250      568905 :             memcpy(&oldSize, oldPtr, sizeof(oldSize));
     251      568905 :             assert(oldSize <= tif->tif_cur_cumulated_mem_alloc);
     252             :         }
     253     1753700 :         if (s > oldSize &&
     254     1752160 :             (s > tif->tif_max_cumulated_mem_alloc -
     255     1752160 :                      (tif->tif_cur_cumulated_mem_alloc - oldSize) ||
     256     1752420 :              s > TIFF_TMSIZE_T_MAX - LEADING_AREA_TO_STORE_ALLOC_SIZE))
     257             :         {
     258           0 :             _TIFFEmitErrorAboveMaxCumulatedMemAlloc(tif, "_TIFFreallocExt",
     259             :                                                     s - oldSize);
     260           0 :             return NULL;
     261             :         }
     262             :         void *newPtr =
     263     1753970 :             _TIFFrealloc(oldPtr, LEADING_AREA_TO_STORE_ALLOC_SIZE + s);
     264     1754090 :         if (newPtr == NULL)
     265           0 :             return NULL;
     266     1754090 :         tif->tif_cur_cumulated_mem_alloc -= oldSize;
     267     1754090 :         tif->tif_cur_cumulated_mem_alloc += s;
     268     1754090 :         memcpy(newPtr, &s, sizeof(s));
     269     1754090 :         return (char *)newPtr + LEADING_AREA_TO_STORE_ALLOC_SIZE;
     270             :     }
     271       80616 :     return _TIFFrealloc(p, s);
     272             : }
     273             : 
     274             : /** free() version that takes into account memory-specific open options */
     275     1965810 : void _TIFFfreeExt(TIFF *tif, void *p)
     276             : {
     277     1965810 :     if (p != NULL && tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
     278             :     {
     279     1843320 :         void *oldPtr = (char *)p - LEADING_AREA_TO_STORE_ALLOC_SIZE;
     280             :         tmsize_t oldSize;
     281     1843320 :         memcpy(&oldSize, oldPtr, sizeof(oldSize));
     282     1843320 :         assert(oldSize <= tif->tif_cur_cumulated_mem_alloc);
     283     1843320 :         tif->tif_cur_cumulated_mem_alloc -= oldSize;
     284     1843320 :         p = oldPtr;
     285             :     }
     286     1965810 :     _TIFFfree(p);
     287     1965730 : }
     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       70523 : 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       70523 :         n.a8[0] = 1;
     332       70523 :         n.a8[1] = 0;
     333             :         (void)n;
     334             : #ifdef WORDS_BIGENDIAN
     335             :         assert(n.a16 == 256);
     336             : #else
     337       70523 :         assert(n.a16 == 1);
     338             : #endif
     339             :     }
     340             : 
     341       70523 :     m = _TIFFgetMode(opts, clientdata, mode, module);
     342       70512 :     if (m == -1)
     343           0 :         goto bad2;
     344       70512 :     size_to_alloc = (tmsize_t)(sizeof(TIFF) + strlen(name) + 1);
     345       70512 :     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       70512 :     if (opts && opts->max_cumulated_mem_alloc > 0 &&
     357       70477 :         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       70512 :     tif = (TIFF *)_TIFFmallocExt(NULL, size_to_alloc);
     368       70556 :     if (tif == NULL)
     369             :     {
     370           0 :         _TIFFErrorEarly(opts, clientdata, module,
     371             :                         "%s: Out of memory (TIFF structure)", name);
     372           0 :         goto bad2;
     373             :     }
     374       70556 :     _TIFFmemset(tif, 0, sizeof(*tif));
     375       70527 :     tif->tif_name = (char *)tif + sizeof(TIFF);
     376       70527 :     strcpy(tif->tif_name, name);
     377       70527 :     tif->tif_mode = m & ~(O_CREAT | O_TRUNC);
     378       70527 :     tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER; /* non-existent directory */
     379       70527 :     tif->tif_curdircount = TIFF_NON_EXISTENT_DIR_NUMBER;
     380       70527 :     tif->tif_curoff = 0;
     381       70527 :     tif->tif_curstrip = (uint32_t)-1; /* invalid strip */
     382       70527 :     tif->tif_row = (uint32_t)-1;      /* read/write pre-increment */
     383       70527 :     tif->tif_clientdata = clientdata;
     384       70527 :     tif->tif_readproc = readproc;
     385       70527 :     tif->tif_writeproc = writeproc;
     386       70527 :     tif->tif_seekproc = seekproc;
     387       70527 :     tif->tif_closeproc = closeproc;
     388       70527 :     tif->tif_sizeproc = sizeproc;
     389       70527 :     tif->tif_mapproc = mapproc ? mapproc : _tiffDummyMapProc;
     390       70527 :     tif->tif_unmapproc = unmapproc ? unmapproc : _tiffDummyUnmapProc;
     391       70527 :     if (opts)
     392             :     {
     393       70479 :         tif->tif_errorhandler = opts->errorhandler;
     394       70479 :         tif->tif_errorhandler_user_data = opts->errorhandler_user_data;
     395       70479 :         tif->tif_warnhandler = opts->warnhandler;
     396       70479 :         tif->tif_warnhandler_user_data = opts->warnhandler_user_data;
     397       70479 :         tif->tif_max_single_mem_alloc = opts->max_single_mem_alloc;
     398       70479 :         tif->tif_max_cumulated_mem_alloc = opts->max_cumulated_mem_alloc;
     399       70479 :         tif->tif_warn_about_unknown_tags = opts->warn_about_unknown_tags;
     400             :     }
     401             : 
     402       70527 :     if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc)
     403             :     {
     404          50 :         TIFFErrorExtR(tif, module,
     405             :                       "One of the client procedures is NULL pointer.");
     406           0 :         _TIFFfreeExt(NULL, tif);
     407           0 :         goto bad2;
     408             :     }
     409             : 
     410       70477 :     _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       70502 :     tif->tif_flags = FILLORDER_MSB2LSB;
     417       70502 :     if (m == O_RDONLY)
     418       27238 :         tif->tif_flags |= TIFF_MAPPED;
     419             : 
     420             : #ifdef STRIPCHOP_DEFAULT
     421       70502 :     if (m == O_RDONLY || m == O_RDWR)
     422       31073 :         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      287195 :     for (cp = mode; *cp; cp++)
     481      216693 :         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       29212 :             case 'l':
     490             : #ifdef WORDS_BIGENDIAN
     491             :                 if ((m & O_CREAT))
     492             :                     tif->tif_flags |= TIFF_SWAB;
     493             : #endif
     494       29212 :                 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       23931 :             case 'C':
     520       23931 :                 if (m == O_RDONLY)
     521       23145 :                     tif->tif_flags |= TIFF_STRIPCHOP;
     522       23931 :                 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       25193 :             case 'D':
     535       25193 :                 tif->tif_flags |= TIFF_DEFERSTRILELOAD;
     536       25193 :                 break;
     537       24056 :             case 'O':
     538       24056 :                 if (m == O_RDONLY)
     539       24051 :                     tif->tif_flags |=
     540             :                         (TIFF_LAZYSTRILELOAD_ASKED | TIFF_DEFERSTRILELOAD);
     541       24056 :                 break;
     542      113557 :             default:
     543      113557 :                 break;
     544             :         }
     545             : 
     546             : #ifdef DEFER_STRILE_LOAD
     547             :     /* Compatibility with old DEFER_STRILE_LOAD compilation flag */
     548             :     /* Probably unneeded, since to the best of my knowledge (E. Rouault) */
     549             :     /* GDAL was the only user of this, and will now use the new 'D' flag */
     550             :     tif->tif_flags |= TIFF_DEFERSTRILELOAD;
     551             : #endif
     552             : 
     553             :     /*
     554             :      * Read in TIFF header.
     555             :      */
     556      101582 :     if ((m & O_TRUNC) ||
     557       31039 :         !ReadOK(tif, &tif->tif_header, sizeof(TIFFHeaderClassic)))
     558             :     {
     559       39444 :         if (tif->tif_mode == O_RDONLY)
     560             :         {
     561           0 :             TIFFErrorExtR(tif, name, "Cannot read TIFF header");
     562           2 :             goto bad;
     563             :         }
     564             :         /*
     565             :          * Setup header and write.
     566             :          */
     567             : #ifdef WORDS_BIGENDIAN
     568             :         tif->tif_header.common.tiff_magic =
     569             :             (tif->tif_flags & TIFF_SWAB) ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN;
     570             : #else
     571       39444 :         tif->tif_header.common.tiff_magic =
     572       39444 :             (tif->tif_flags & TIFF_SWAB) ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
     573             : #endif
     574             :         TIFFHeaderUnion tif_header_swapped;
     575       39444 :         if (!(tif->tif_flags & TIFF_BIGTIFF))
     576             :         {
     577       39364 :             tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC;
     578       39364 :             tif->tif_header.classic.tiff_diroff = 0;
     579       39364 :             tif->tif_header_size = sizeof(TIFFHeaderClassic);
     580             :             /* Swapped copy for writing */
     581       39364 :             _TIFFmemcpy(&tif_header_swapped, &tif->tif_header,
     582             :                         sizeof(TIFFHeaderUnion));
     583       39364 :             if (tif->tif_flags & TIFF_SWAB)
     584          79 :                 TIFFSwabShort(&tif_header_swapped.common.tiff_version);
     585             :         }
     586             :         else
     587             :         {
     588          80 :             tif->tif_header.common.tiff_version = TIFF_VERSION_BIG;
     589          80 :             tif->tif_header.big.tiff_offsetsize = 8;
     590          80 :             tif->tif_header.big.tiff_unused = 0;
     591          80 :             tif->tif_header.big.tiff_diroff = 0;
     592          80 :             tif->tif_header_size = sizeof(TIFFHeaderBig);
     593             :             /* Swapped copy for writing */
     594          80 :             _TIFFmemcpy(&tif_header_swapped, &tif->tif_header,
     595             :                         sizeof(TIFFHeaderUnion));
     596          80 :             if (tif->tif_flags & TIFF_SWAB)
     597             :             {
     598           4 :                 TIFFSwabShort(&tif_header_swapped.common.tiff_version);
     599           4 :                 TIFFSwabShort(&tif_header_swapped.big.tiff_offsetsize);
     600             :             }
     601             :         }
     602             :         /*
     603             :          * The doc for "fopen" for some STD_C_LIBs says that if you
     604             :          * open a file for modify ("+"), then you must fseek (or
     605             :          * fflush?) between any freads and fwrites.  This is not
     606             :          * necessary on most systems, but has been shown to be needed
     607             :          * on Solaris.
     608             :          */
     609       39444 :         TIFFSeekFile(tif, 0, SEEK_SET);
     610       39444 :         if (!WriteOK(tif, &tif_header_swapped,
     611             :                      (tmsize_t)(tif->tif_header_size)))
     612             :         {
     613           2 :             TIFFErrorExtR(tif, name, "Error writing TIFF header");
     614           2 :             goto bad;
     615             :         }
     616             :         /*
     617             :          * Setup default directory.
     618             :          */
     619       39442 :         if (!TIFFDefaultDirectory(tif))
     620           0 :             goto bad;
     621       39440 :         tif->tif_diroff = 0;
     622       39440 :         tif->tif_lastdiroff = 0;
     623       39440 :         tif->tif_setdirectory_force_absolute = FALSE;
     624             :         /* tif_curdircount = 0 means 'empty file opened for writing, but no IFD
     625             :          * written yet' */
     626       39440 :         tif->tif_curdircount = 0;
     627       39440 :         return (tif);
     628             :     }
     629             : 
     630             :     /*
     631             :      * Setup the byte order handling according to the opened file for reading.
     632             :      */
     633       31099 :     if (tif->tif_header.common.tiff_magic != TIFF_BIGENDIAN &&
     634       30865 :         tif->tif_header.common.tiff_magic != TIFF_LITTLEENDIAN
     635             : #if MDI_SUPPORT
     636             :         &&
     637             : #if HOST_BIGENDIAN
     638             :         tif->tif_header.common.tiff_magic != MDI_BIGENDIAN
     639             : #else
     640             :         tif->tif_header.common.tiff_magic != MDI_LITTLEENDIAN
     641             : #endif
     642             :     )
     643             :     {
     644             :         TIFFErrorExtR(tif, name,
     645             :                       "Not a TIFF or MDI file, bad magic number %" PRIu16
     646             :                       " (0x%" PRIx16 ")",
     647             : #else
     648             :     )
     649             :     {
     650           0 :         TIFFErrorExtR(tif, name,
     651             :                       "Not a TIFF file, bad magic number %" PRIu16
     652             :                       " (0x%" PRIx16 ")",
     653             : #endif
     654           0 :                       tif->tif_header.common.tiff_magic,
     655           0 :                       tif->tif_header.common.tiff_magic);
     656           0 :         goto bad;
     657             :     }
     658       31099 :     if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN)
     659             :     {
     660             : #ifndef WORDS_BIGENDIAN
     661         222 :         tif->tif_flags |= TIFF_SWAB;
     662             : #endif
     663             :     }
     664             :     else
     665             :     {
     666             : #ifdef WORDS_BIGENDIAN
     667             :         tif->tif_flags |= TIFF_SWAB;
     668             : #endif
     669             :     }
     670       31099 :     if (tif->tif_flags & TIFF_SWAB)
     671         222 :         TIFFSwabShort(&tif->tif_header.common.tiff_version);
     672       31036 :     if ((tif->tif_header.common.tiff_version != TIFF_VERSION_CLASSIC) &&
     673         295 :         (tif->tif_header.common.tiff_version != TIFF_VERSION_BIG))
     674             :     {
     675           0 :         TIFFErrorExtR(tif, name,
     676             :                       "Not a TIFF file, bad version number %" PRIu16
     677             :                       " (0x%" PRIx16 ")",
     678           0 :                       tif->tif_header.common.tiff_version,
     679           0 :                       tif->tif_header.common.tiff_version);
     680           0 :         goto bad;
     681             :     }
     682       31036 :     if (tif->tif_header.common.tiff_version == TIFF_VERSION_CLASSIC)
     683             :     {
     684       30741 :         if (tif->tif_flags & TIFF_SWAB)
     685         211 :             TIFFSwabLong(&tif->tif_header.classic.tiff_diroff);
     686       30738 :         tif->tif_header_size = sizeof(TIFFHeaderClassic);
     687             :     }
     688             :     else
     689             :     {
     690         295 :         if (!ReadOK(tif,
     691             :                     ((uint8_t *)(&tif->tif_header) + sizeof(TIFFHeaderClassic)),
     692             :                     (sizeof(TIFFHeaderBig) - sizeof(TIFFHeaderClassic))))
     693             :         {
     694           0 :             TIFFErrorExtR(tif, name, "Cannot read TIFF header");
     695           0 :             goto bad;
     696             :         }
     697         295 :         if (tif->tif_flags & TIFF_SWAB)
     698             :         {
     699          11 :             TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize);
     700          11 :             TIFFSwabLong8(&tif->tif_header.big.tiff_diroff);
     701             :         }
     702         295 :         if (tif->tif_header.big.tiff_offsetsize != 8)
     703             :         {
     704           0 :             TIFFErrorExtR(tif, name,
     705             :                           "Not a TIFF file, bad BigTIFF offsetsize %" PRIu16
     706             :                           " (0x%" PRIx16 ")",
     707           0 :                           tif->tif_header.big.tiff_offsetsize,
     708           0 :                           tif->tif_header.big.tiff_offsetsize);
     709           0 :             goto bad;
     710             :         }
     711         295 :         if (tif->tif_header.big.tiff_unused != 0)
     712             :         {
     713           0 :             TIFFErrorExtR(tif, name,
     714             :                           "Not a TIFF file, bad BigTIFF unused %" PRIu16
     715             :                           " (0x%" PRIx16 ")",
     716           0 :                           tif->tif_header.big.tiff_unused,
     717           0 :                           tif->tif_header.big.tiff_unused);
     718           0 :             goto bad;
     719             :         }
     720         295 :         tif->tif_header_size = sizeof(TIFFHeaderBig);
     721         295 :         tif->tif_flags |= TIFF_BIGTIFF;
     722             :     }
     723       31033 :     tif->tif_flags |= TIFF_MYBUFFER;
     724       31033 :     tif->tif_rawcp = tif->tif_rawdata = 0;
     725       31033 :     tif->tif_rawdatasize = 0;
     726       31033 :     tif->tif_rawdataoff = 0;
     727       31033 :     tif->tif_rawdataloaded = 0;
     728             : 
     729       31033 :     switch (mode[0])
     730             :     {
     731       31111 :         case 'r':
     732       31111 :             if (!(tif->tif_flags & TIFF_BIGTIFF))
     733       30824 :                 tif->tif_nextdiroff = tif->tif_header.classic.tiff_diroff;
     734             :             else
     735         287 :                 tif->tif_nextdiroff = tif->tif_header.big.tiff_diroff;
     736             :             /*
     737             :              * Try to use a memory-mapped file if the client
     738             :              * has not explicitly suppressed usage with the
     739             :              * 'm' flag in the open mode (see above).
     740             :              */
     741       31111 :             if (tif->tif_flags & TIFF_MAPPED)
     742             :             {
     743             :                 toff_t n;
     744       27258 :                 if (TIFFMapFileContents(tif, (void **)(&tif->tif_base), &n))
     745             :                 {
     746          16 :                     tif->tif_size = (tmsize_t)n;
     747          16 :                     assert((toff_t)tif->tif_size == n);
     748             :                 }
     749             :                 else
     750       27231 :                     tif->tif_flags &= ~TIFF_MAPPED;
     751             :             }
     752             :             /*
     753             :              * Sometimes we do not want to read the first directory (for
     754             :              * example, it may be broken) and want to proceed to other
     755             :              * directories. I this case we use the TIFF_HEADERONLY flag to open
     756             :              * file and return immediately after reading TIFF header.
     757             :              * However, the pointer to TIFFSetField() and TIFFGetField()
     758             :              * (i.e. tif->tif_tagmethods.vsetfield and
     759             :              * tif->tif_tagmethods.vgetfield) need to be initialized, which is
     760             :              * done in TIFFDefaultDirectory().
     761             :              */
     762       31100 :             if (tif->tif_flags & TIFF_HEADERONLY)
     763             :             {
     764           0 :                 if (!TIFFDefaultDirectory(tif))
     765           0 :                     goto bad;
     766           0 :                 return (tif);
     767             :             }
     768             : 
     769             :             /*
     770             :              * Setup initial directory.
     771             :              */
     772       31100 :             if (TIFFReadDirectory(tif))
     773             :             {
     774       31010 :                 return (tif);
     775             :             }
     776          49 :             break;
     777           0 :         case 'a':
     778             :             /*
     779             :              * New directories are automatically append
     780             :              * to the end of the directory chain when they
     781             :              * are written out (see TIFFWriteDirectory).
     782             :              */
     783           0 :             if (!TIFFDefaultDirectory(tif))
     784           0 :                 goto bad;
     785           0 :             return (tif);
     786           0 :         default:
     787           0 :             break;
     788             :     }
     789           0 : bad:
     790           0 :     tif->tif_mode = O_RDONLY; /* XXX avoid flush */
     791           0 :     TIFFCleanup(tif);
     792          15 : bad2:
     793          15 :     return ((TIFF *)0);
     794             : }
     795             : 
     796             : /*
     797             :  * Query functions to access private data.
     798             :  */
     799             : 
     800             : /*
     801             :  * Return open file's name.
     802             :  */
     803           6 : const char *TIFFFileName(TIFF *tif) { return (tif->tif_name); }
     804             : 
     805             : /*
     806             :  * Set the file name.
     807             :  */
     808           0 : const char *TIFFSetFileName(TIFF *tif, const char *name)
     809             : {
     810           0 :     const char *old_name = tif->tif_name;
     811           0 :     tif->tif_name = (char *)name;
     812           0 :     return (old_name);
     813             : }
     814             : 
     815             : /*
     816             :  * Return open file's I/O descriptor.
     817             :  */
     818           0 : int TIFFFileno(TIFF *tif) { return (tif->tif_fd); }
     819             : 
     820             : /*
     821             :  * Set open file's I/O descriptor, and return previous value.
     822             :  */
     823           0 : int TIFFSetFileno(TIFF *tif, int fd)
     824             : {
     825           0 :     int old_fd = tif->tif_fd;
     826           0 :     tif->tif_fd = fd;
     827           0 :     return old_fd;
     828             : }
     829             : 
     830             : /*
     831             :  * Return open file's clientdata.
     832             :  */
     833      100216 : thandle_t TIFFClientdata(TIFF *tif) { return (tif->tif_clientdata); }
     834             : 
     835             : /*
     836             :  * Set open file's clientdata, and return previous value.
     837             :  */
     838           0 : thandle_t TIFFSetClientdata(TIFF *tif, thandle_t newvalue)
     839             : {
     840           0 :     thandle_t m = tif->tif_clientdata;
     841           0 :     tif->tif_clientdata = newvalue;
     842           0 :     return m;
     843             : }
     844             : 
     845             : /*
     846             :  * Return read/write mode.
     847             :  */
     848           0 : int TIFFGetMode(TIFF *tif) { return (tif->tif_mode); }
     849             : 
     850             : /*
     851             :  * Return read/write mode.
     852             :  */
     853           0 : int TIFFSetMode(TIFF *tif, int mode)
     854             : {
     855           0 :     int old_mode = tif->tif_mode;
     856           0 :     tif->tif_mode = mode;
     857           0 :     return (old_mode);
     858             : }
     859             : 
     860             : /*
     861             :  * Return nonzero if file is organized in
     862             :  * tiles; zero if organized as strips.
     863             :  */
     864     5086770 : int TIFFIsTiled(TIFF *tif) { return (isTiled(tif)); }
     865             : 
     866             : /*
     867             :  * Return current row being read/written.
     868             :  */
     869           0 : uint32_t TIFFCurrentRow(TIFF *tif) { return (tif->tif_row); }
     870             : 
     871             : /*
     872             :  * Return index of the current directory.
     873             :  */
     874           0 : tdir_t TIFFCurrentDirectory(TIFF *tif) { return (tif->tif_curdir); }
     875             : 
     876             : /*
     877             :  * Return current strip.
     878             :  */
     879           0 : uint32_t TIFFCurrentStrip(TIFF *tif) { return (tif->tif_curstrip); }
     880             : 
     881             : /*
     882             :  * Return current tile.
     883             :  */
     884           0 : uint32_t TIFFCurrentTile(TIFF *tif) { return (tif->tif_curtile); }
     885             : 
     886             : /*
     887             :  * Return nonzero if the file has byte-swapped data.
     888             :  */
     889      107394 : int TIFFIsByteSwapped(TIFF *tif) { return ((tif->tif_flags & TIFF_SWAB) != 0); }
     890             : 
     891             : /*
     892             :  * Return nonzero if the data is returned up-sampled.
     893             :  */
     894           0 : int TIFFIsUpSampled(TIFF *tif) { return (isUpSampled(tif)); }
     895             : 
     896             : /*
     897             :  * Return nonzero if the data is returned in MSB-to-LSB bit order.
     898             :  */
     899           0 : int TIFFIsMSB2LSB(TIFF *tif) { return (isFillOrder(tif, FILLORDER_MSB2LSB)); }
     900             : 
     901             : /*
     902             :  * Return nonzero if given file was written in big-endian order.
     903             :  */
     904       26825 : int TIFFIsBigEndian(TIFF *tif)
     905             : {
     906       26825 :     return (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN);
     907             : }
     908             : 
     909             : /*
     910             :  * Return nonzero if given file is BigTIFF style.
     911             :  */
     912        2910 : int TIFFIsBigTIFF(TIFF *tif) { return ((tif->tif_flags & TIFF_BIGTIFF) != 0); }
     913             : 
     914             : /*
     915             :  * Return pointer to file read method.
     916             :  */
     917           0 : TIFFReadWriteProc TIFFGetReadProc(TIFF *tif) { return (tif->tif_readproc); }
     918             : 
     919             : /*
     920             :  * Return pointer to file write method.
     921             :  */
     922           0 : TIFFReadWriteProc TIFFGetWriteProc(TIFF *tif) { return (tif->tif_writeproc); }
     923             : 
     924             : /*
     925             :  * Return pointer to file seek method.
     926             :  */
     927           0 : TIFFSeekProc TIFFGetSeekProc(TIFF *tif) { return (tif->tif_seekproc); }
     928             : 
     929             : /*
     930             :  * Return pointer to file close method.
     931             :  */
     932           0 : TIFFCloseProc TIFFGetCloseProc(TIFF *tif) { return (tif->tif_closeproc); }
     933             : 
     934             : /*
     935             :  * Return pointer to file size requesting method.
     936             :  */
     937       15832 : TIFFSizeProc TIFFGetSizeProc(TIFF *tif) { return (tif->tif_sizeproc); }
     938             : 
     939             : /*
     940             :  * Return pointer to memory mapping method.
     941             :  */
     942           0 : TIFFMapFileProc TIFFGetMapFileProc(TIFF *tif) { return (tif->tif_mapproc); }
     943             : 
     944             : /*
     945             :  * Return pointer to memory unmapping method.
     946             :  */
     947           0 : TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF *tif)
     948             : {
     949           0 :     return (tif->tif_unmapproc);
     950             : }

Generated by: LCOV version 1.14