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