xref: /aosp_15_r20/external/pdfium/third_party/libtiff/tif_open.c (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
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                 TIFFWarningExtR(tif, name,
369                                 "H(ost) mode is deprecated. Since "
370                                 "libtiff 4.5.1, it is an alias of 'B' / "
371                                 "FILLORDER_MSB2LSB.");
372                 tif->tif_flags =
373                     (tif->tif_flags & ~TIFF_FILLORDER) | FILLORDER_MSB2LSB;
374                 break;
375             case 'M':
376                 if (m == O_RDONLY)
377                     tif->tif_flags |= TIFF_MAPPED;
378                 break;
379             case 'm':
380                 if (m == O_RDONLY)
381                     tif->tif_flags &= ~TIFF_MAPPED;
382                 break;
383             case 'C':
384                 if (m == O_RDONLY)
385                     tif->tif_flags |= TIFF_STRIPCHOP;
386                 break;
387             case 'c':
388                 if (m == O_RDONLY)
389                     tif->tif_flags &= ~TIFF_STRIPCHOP;
390                 break;
391             case 'h':
392                 tif->tif_flags |= TIFF_HEADERONLY;
393                 break;
394             case '8':
395                 if (m & O_CREAT)
396                     tif->tif_flags |= TIFF_BIGTIFF;
397                 break;
398             case 'D':
399                 tif->tif_flags |= TIFF_DEFERSTRILELOAD;
400                 break;
401             case 'O':
402                 if (m == O_RDONLY)
403                     tif->tif_flags |=
404                         (TIFF_LAZYSTRILELOAD | TIFF_DEFERSTRILELOAD);
405                 break;
406         }
407 
408 #ifdef DEFER_STRILE_LOAD
409     /* Compatibility with old DEFER_STRILE_LOAD compilation flag */
410     /* Probably unneeded, since to the best of my knowledge (E. Rouault) */
411     /* GDAL was the only user of this, and will now use the new 'D' flag */
412     tif->tif_flags |= TIFF_DEFERSTRILELOAD;
413 #endif
414 
415     /*
416      * Read in TIFF header.
417      */
418     if ((m & O_TRUNC) ||
419         !ReadOK(tif, &tif->tif_header, sizeof(TIFFHeaderClassic)))
420     {
421         if (tif->tif_mode == O_RDONLY)
422         {
423             TIFFErrorExtR(tif, name, "Cannot read TIFF header");
424             goto bad;
425         }
426 /*
427  * Setup header and write.
428  */
429 #ifdef WORDS_BIGENDIAN
430         tif->tif_header.common.tiff_magic =
431             (tif->tif_flags & TIFF_SWAB) ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN;
432 #else
433         tif->tif_header.common.tiff_magic =
434             (tif->tif_flags & TIFF_SWAB) ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
435 #endif
436         if (!(tif->tif_flags & TIFF_BIGTIFF))
437         {
438             tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC;
439             tif->tif_header.classic.tiff_diroff = 0;
440             if (tif->tif_flags & TIFF_SWAB)
441                 TIFFSwabShort(&tif->tif_header.common.tiff_version);
442             tif->tif_header_size = sizeof(TIFFHeaderClassic);
443         }
444         else
445         {
446             tif->tif_header.common.tiff_version = TIFF_VERSION_BIG;
447             tif->tif_header.big.tiff_offsetsize = 8;
448             tif->tif_header.big.tiff_unused = 0;
449             tif->tif_header.big.tiff_diroff = 0;
450             if (tif->tif_flags & TIFF_SWAB)
451             {
452                 TIFFSwabShort(&tif->tif_header.common.tiff_version);
453                 TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize);
454             }
455             tif->tif_header_size = sizeof(TIFFHeaderBig);
456         }
457         /*
458          * The doc for "fopen" for some STD_C_LIBs says that if you
459          * open a file for modify ("+"), then you must fseek (or
460          * fflush?) between any freads and fwrites.  This is not
461          * necessary on most systems, but has been shown to be needed
462          * on Solaris.
463          */
464         TIFFSeekFile(tif, 0, SEEK_SET);
465         if (!WriteOK(tif, &tif->tif_header, (tmsize_t)(tif->tif_header_size)))
466         {
467             TIFFErrorExtR(tif, name, "Error writing TIFF header");
468             goto bad;
469         }
470         /*
471          * Setup the byte order handling.
472          */
473         if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN)
474         {
475 #ifndef WORDS_BIGENDIAN
476             tif->tif_flags |= TIFF_SWAB;
477 #endif
478         }
479         else
480         {
481 #ifdef WORDS_BIGENDIAN
482             tif->tif_flags |= TIFF_SWAB;
483 #endif
484         }
485         /*
486          * Setup default directory.
487          */
488         if (!TIFFDefaultDirectory(tif))
489             goto bad;
490         tif->tif_diroff = 0;
491         tif->tif_lastdiroff = 0;
492         tif->tif_setdirectory_force_absolute = FALSE;
493         return (tif);
494     }
495     /*
496      * Setup the byte order handling.
497      */
498     if (tif->tif_header.common.tiff_magic != TIFF_BIGENDIAN &&
499         tif->tif_header.common.tiff_magic != TIFF_LITTLEENDIAN
500 #if MDI_SUPPORT
501         &&
502 #if HOST_BIGENDIAN
503         tif->tif_header.common.tiff_magic != MDI_BIGENDIAN
504 #else
505         tif->tif_header.common.tiff_magic != MDI_LITTLEENDIAN
506 #endif
507     )
508     {
509         TIFFErrorExtR(tif, name,
510                       "Not a TIFF or MDI file, bad magic number %" PRIu16
511                       " (0x%" PRIx16 ")",
512 #else
513     )
514     {
515         TIFFErrorExtR(tif, name,
516                       "Not a TIFF file, bad magic number %" PRIu16
517                       " (0x%" PRIx16 ")",
518 #endif
519                       tif->tif_header.common.tiff_magic,
520                       tif->tif_header.common.tiff_magic);
521         goto bad;
522     }
523     if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN)
524     {
525 #ifndef WORDS_BIGENDIAN
526         tif->tif_flags |= TIFF_SWAB;
527 #endif
528     }
529     else
530     {
531 #ifdef WORDS_BIGENDIAN
532         tif->tif_flags |= TIFF_SWAB;
533 #endif
534     }
535     if (tif->tif_flags & TIFF_SWAB)
536         TIFFSwabShort(&tif->tif_header.common.tiff_version);
537     if ((tif->tif_header.common.tiff_version != TIFF_VERSION_CLASSIC) &&
538         (tif->tif_header.common.tiff_version != TIFF_VERSION_BIG))
539     {
540         TIFFErrorExtR(tif, name,
541                       "Not a TIFF file, bad version number %" PRIu16
542                       " (0x%" PRIx16 ")",
543                       tif->tif_header.common.tiff_version,
544                       tif->tif_header.common.tiff_version);
545         goto bad;
546     }
547     if (tif->tif_header.common.tiff_version == TIFF_VERSION_CLASSIC)
548     {
549         if (tif->tif_flags & TIFF_SWAB)
550             TIFFSwabLong(&tif->tif_header.classic.tiff_diroff);
551         tif->tif_header_size = sizeof(TIFFHeaderClassic);
552     }
553     else
554     {
555         if (!ReadOK(tif,
556                     ((uint8_t *)(&tif->tif_header) + sizeof(TIFFHeaderClassic)),
557                     (sizeof(TIFFHeaderBig) - sizeof(TIFFHeaderClassic))))
558         {
559             TIFFErrorExtR(tif, name, "Cannot read TIFF header");
560             goto bad;
561         }
562         if (tif->tif_flags & TIFF_SWAB)
563         {
564             TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize);
565             TIFFSwabLong8(&tif->tif_header.big.tiff_diroff);
566         }
567         if (tif->tif_header.big.tiff_offsetsize != 8)
568         {
569             TIFFErrorExtR(tif, name,
570                           "Not a TIFF file, bad BigTIFF offsetsize %" PRIu16
571                           " (0x%" PRIx16 ")",
572                           tif->tif_header.big.tiff_offsetsize,
573                           tif->tif_header.big.tiff_offsetsize);
574             goto bad;
575         }
576         if (tif->tif_header.big.tiff_unused != 0)
577         {
578             TIFFErrorExtR(tif, name,
579                           "Not a TIFF file, bad BigTIFF unused %" PRIu16
580                           " (0x%" PRIx16 ")",
581                           tif->tif_header.big.tiff_unused,
582                           tif->tif_header.big.tiff_unused);
583             goto bad;
584         }
585         tif->tif_header_size = sizeof(TIFFHeaderBig);
586         tif->tif_flags |= TIFF_BIGTIFF;
587     }
588     tif->tif_flags |= TIFF_MYBUFFER;
589     tif->tif_rawcp = tif->tif_rawdata = 0;
590     tif->tif_rawdatasize = 0;
591     tif->tif_rawdataoff = 0;
592     tif->tif_rawdataloaded = 0;
593 
594     switch (mode[0])
595     {
596         case 'r':
597             if (!(tif->tif_flags & TIFF_BIGTIFF))
598                 tif->tif_nextdiroff = tif->tif_header.classic.tiff_diroff;
599             else
600                 tif->tif_nextdiroff = tif->tif_header.big.tiff_diroff;
601             /*
602              * Try to use a memory-mapped file if the client
603              * has not explicitly suppressed usage with the
604              * 'm' flag in the open mode (see above).
605              */
606             if (tif->tif_flags & TIFF_MAPPED)
607             {
608                 toff_t n;
609                 if (TIFFMapFileContents(tif, (void **)(&tif->tif_base), &n))
610                 {
611                     tif->tif_size = (tmsize_t)n;
612                     assert((toff_t)tif->tif_size == n);
613                 }
614                 else
615                     tif->tif_flags &= ~TIFF_MAPPED;
616             }
617             /*
618              * Sometimes we do not want to read the first directory (for
619              * example, it may be broken) and want to proceed to other
620              * directories. I this case we use the TIFF_HEADERONLY flag to open
621              * file and return immediately after reading TIFF header.
622              */
623             if (tif->tif_flags & TIFF_HEADERONLY)
624                 return (tif);
625 
626             /*
627              * Setup initial directory.
628              */
629             if (TIFFReadDirectory(tif))
630             {
631                 return (tif);
632             }
633             break;
634         case 'a':
635             /*
636              * New directories are automatically append
637              * to the end of the directory chain when they
638              * are written out (see TIFFWriteDirectory).
639              */
640             if (!TIFFDefaultDirectory(tif))
641                 goto bad;
642             return (tif);
643     }
644 bad:
645     tif->tif_mode = O_RDONLY; /* XXX avoid flush */
646     TIFFCleanup(tif);
647 bad2:
648     return ((TIFF *)0);
649 }
650 
651 /*
652  * Query functions to access private data.
653  */
654 
655 /*
656  * Return open file's name.
657  */
658 const char *TIFFFileName(TIFF *tif) { return (tif->tif_name); }
659 
660 /*
661  * Set the file name.
662  */
663 const char *TIFFSetFileName(TIFF *tif, const char *name)
664 {
665     const char *old_name = tif->tif_name;
666     tif->tif_name = (char *)name;
667     return (old_name);
668 }
669 
670 /*
671  * Return open file's I/O descriptor.
672  */
673 int TIFFFileno(TIFF *tif) { return (tif->tif_fd); }
674 
675 /*
676  * Set open file's I/O descriptor, and return previous value.
677  */
678 int TIFFSetFileno(TIFF *tif, int fd)
679 {
680     int old_fd = tif->tif_fd;
681     tif->tif_fd = fd;
682     return old_fd;
683 }
684 
685 /*
686  * Return open file's clientdata.
687  */
688 thandle_t TIFFClientdata(TIFF *tif) { return (tif->tif_clientdata); }
689 
690 /*
691  * Set open file's clientdata, and return previous value.
692  */
693 thandle_t TIFFSetClientdata(TIFF *tif, thandle_t newvalue)
694 {
695     thandle_t m = tif->tif_clientdata;
696     tif->tif_clientdata = newvalue;
697     return m;
698 }
699 
700 /*
701  * Return read/write mode.
702  */
703 int TIFFGetMode(TIFF *tif) { return (tif->tif_mode); }
704 
705 /*
706  * Return read/write mode.
707  */
708 int TIFFSetMode(TIFF *tif, int mode)
709 {
710     int old_mode = tif->tif_mode;
711     tif->tif_mode = mode;
712     return (old_mode);
713 }
714 
715 /*
716  * Return nonzero if file is organized in
717  * tiles; zero if organized as strips.
718  */
719 int TIFFIsTiled(TIFF *tif) { return (isTiled(tif)); }
720 
721 /*
722  * Return current row being read/written.
723  */
724 uint32_t TIFFCurrentRow(TIFF *tif) { return (tif->tif_row); }
725 
726 /*
727  * Return index of the current directory.
728  */
729 tdir_t TIFFCurrentDirectory(TIFF *tif) { return (tif->tif_curdir); }
730 
731 /*
732  * Return current strip.
733  */
734 uint32_t TIFFCurrentStrip(TIFF *tif) { return (tif->tif_curstrip); }
735 
736 /*
737  * Return current tile.
738  */
739 uint32_t TIFFCurrentTile(TIFF *tif) { return (tif->tif_curtile); }
740 
741 /*
742  * Return nonzero if the file has byte-swapped data.
743  */
744 int TIFFIsByteSwapped(TIFF *tif) { return ((tif->tif_flags & TIFF_SWAB) != 0); }
745 
746 /*
747  * Return nonzero if the data is returned up-sampled.
748  */
749 int TIFFIsUpSampled(TIFF *tif) { return (isUpSampled(tif)); }
750 
751 /*
752  * Return nonzero if the data is returned in MSB-to-LSB bit order.
753  */
754 int TIFFIsMSB2LSB(TIFF *tif) { return (isFillOrder(tif, FILLORDER_MSB2LSB)); }
755 
756 /*
757  * Return nonzero if given file was written in big-endian order.
758  */
759 int TIFFIsBigEndian(TIFF *tif)
760 {
761     return (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN);
762 }
763 
764 /*
765  * Return nonzero if given file is BigTIFF style.
766  */
767 int TIFFIsBigTIFF(TIFF *tif)
768 {
769     return (tif->tif_header.common.tiff_version == TIFF_VERSION_BIG);
770 }
771 
772 /*
773  * Return pointer to file read method.
774  */
775 TIFFReadWriteProc TIFFGetReadProc(TIFF *tif) { return (tif->tif_readproc); }
776 
777 /*
778  * Return pointer to file write method.
779  */
780 TIFFReadWriteProc TIFFGetWriteProc(TIFF *tif) { return (tif->tif_writeproc); }
781 
782 /*
783  * Return pointer to file seek method.
784  */
785 TIFFSeekProc TIFFGetSeekProc(TIFF *tif) { return (tif->tif_seekproc); }
786 
787 /*
788  * Return pointer to file close method.
789  */
790 TIFFCloseProc TIFFGetCloseProc(TIFF *tif) { return (tif->tif_closeproc); }
791 
792 /*
793  * Return pointer to file size requesting method.
794  */
795 TIFFSizeProc TIFFGetSizeProc(TIFF *tif) { return (tif->tif_sizeproc); }
796 
797 /*
798  * Return pointer to memory mapping method.
799  */
800 TIFFMapFileProc TIFFGetMapFileProc(TIFF *tif) { return (tif->tif_mapproc); }
801 
802 /*
803  * Return pointer to memory unmapping method.
804  */
805 TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF *tif)
806 {
807     return (tif->tif_unmapproc);
808 }
809