New comit of SDL2
[supertux.git] / src / SDL2 / external / tiff-4.0.3 / libtiff / tif_open.c
1 /* $Id: tif_open.c,v 1.46 2010-12-06 16:54:54 faxguy Exp $ */
2
3 /*
4  * Copyright (c) 1988-1997 Sam Leffler
5  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
6  *
7  * Permission to use, copy, modify, distribute, and sell this software and 
8  * its documentation for any purpose is hereby granted without fee, provided
9  * that (i) the above copyright notices and this permission notice appear in
10  * all copies of the software and related documentation, and (ii) the names of
11  * Sam Leffler and Silicon Graphics may not be used in any advertising or
12  * publicity relating to the software without the specific, prior written
13  * permission of Sam Leffler and Silicon Graphics.
14  * 
15  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
16  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
17  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
18  * 
19  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
23  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
24  * OF THIS SOFTWARE.
25  */
26
27 /*
28  * TIFF Library.
29  */
30 #include "tiffiop.h"
31
32 /*
33  * Dummy functions to fill the omitted client procedures.
34  */
35 static int
36 _tiffDummyMapProc(thandle_t fd, void** pbase, toff_t* psize)
37 {
38         (void) fd; (void) pbase; (void) psize;
39         return (0);
40 }
41
42 static void
43 _tiffDummyUnmapProc(thandle_t fd, void* base, toff_t size)
44 {
45         (void) fd; (void) base; (void) size;
46 }
47
48 int
49 _TIFFgetMode(const char* mode, const char* module)
50 {
51         int m = -1;
52
53         switch (mode[0]) {
54         case 'r':
55                 m = O_RDONLY;
56                 if (mode[1] == '+')
57                         m = O_RDWR;
58                 break;
59         case 'w':
60         case 'a':
61                 m = O_RDWR|O_CREAT;
62                 if (mode[0] == 'w')
63                         m |= O_TRUNC;
64                 break;
65         default:
66                 TIFFErrorExt(0, module, "\"%s\": Bad mode", mode);
67                 break;
68         }
69         return (m);
70 }
71
72 TIFF*
73 TIFFClientOpen(
74         const char* name, const char* mode,
75         thandle_t clientdata,
76         TIFFReadWriteProc readproc,
77         TIFFReadWriteProc writeproc,
78         TIFFSeekProc seekproc,
79         TIFFCloseProc closeproc,
80         TIFFSizeProc sizeproc,
81         TIFFMapFileProc mapproc,
82         TIFFUnmapFileProc unmapproc
83 )
84 {
85         static const char module[] = "TIFFClientOpen";
86         TIFF *tif;
87         int m;
88         const char* cp;
89
90         /* The following are configuration checks. They should be redundant, but should not
91          * compile to any actual code in an optimised release build anyway. If any of them
92          * fail, (makefile-based or other) configuration is not correct */
93         assert(sizeof(uint8)==1);
94         assert(sizeof(int8)==1);
95         assert(sizeof(uint16)==2);
96         assert(sizeof(int16)==2);
97         assert(sizeof(uint32)==4);
98         assert(sizeof(int32)==4);
99         assert(sizeof(uint64)==8);
100         assert(sizeof(int64)==8);
101         assert(sizeof(tmsize_t)==sizeof(void*));
102         {
103                 union{
104                         uint8 a8[2];
105                         uint16 a16;
106                 } n;
107                 n.a8[0]=1;
108                 n.a8[1]=0;
109                 #ifdef WORDS_BIGENDIAN
110                 assert(n.a16==256);
111                 #else
112                 assert(n.a16==1);
113                 #endif
114         }
115
116         m = _TIFFgetMode(mode, module);
117         if (m == -1)
118                 goto bad2;
119         tif = (TIFF *)_TIFFmalloc((tmsize_t)(sizeof (TIFF) + strlen(name) + 1));
120         if (tif == NULL) {
121                 TIFFErrorExt(clientdata, module, "%s: Out of memory (TIFF structure)", name);
122                 goto bad2;
123         }
124         _TIFFmemset(tif, 0, sizeof (*tif));
125         tif->tif_name = (char *)tif + sizeof (TIFF);
126         strcpy(tif->tif_name, name);
127         tif->tif_mode = m &~ (O_CREAT|O_TRUNC);
128         tif->tif_curdir = (uint16) -1;          /* non-existent directory */
129         tif->tif_curoff = 0;
130         tif->tif_curstrip = (uint32) -1;        /* invalid strip */
131         tif->tif_row = (uint32) -1;             /* read/write pre-increment */
132         tif->tif_clientdata = clientdata;
133         if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) {
134                 TIFFErrorExt(clientdata, module,
135                     "One of the client procedures is NULL pointer.");
136                 goto bad2;
137         }
138         tif->tif_readproc = readproc;
139         tif->tif_writeproc = writeproc;
140         tif->tif_seekproc = seekproc;
141         tif->tif_closeproc = closeproc;
142         tif->tif_sizeproc = sizeproc;
143         if (mapproc)
144                 tif->tif_mapproc = mapproc;
145         else
146                 tif->tif_mapproc = _tiffDummyMapProc;
147         if (unmapproc)
148                 tif->tif_unmapproc = unmapproc;
149         else
150                 tif->tif_unmapproc = _tiffDummyUnmapProc;
151         _TIFFSetDefaultCompressionState(tif);    /* setup default state */
152         /*
153          * Default is to return data MSB2LSB and enable the
154          * use of memory-mapped files and strip chopping when
155          * a file is opened read-only.
156          */
157         tif->tif_flags = FILLORDER_MSB2LSB;
158         if (m == O_RDONLY )
159                 tif->tif_flags |= TIFF_MAPPED;
160
161         #ifdef STRIPCHOP_DEFAULT
162         if (m == O_RDONLY || m == O_RDWR)
163                 tif->tif_flags |= STRIPCHOP_DEFAULT;
164         #endif
165
166         /*
167          * Process library-specific flags in the open mode string.
168          * The following flags may be used to control intrinsic library
169          * behaviour that may or may not be desirable (usually for
170          * compatibility with some application that claims to support
171          * TIFF but only supports some braindead idea of what the
172          * vendor thinks TIFF is):
173          *
174          * 'l' use little-endian byte order for creating a file
175          * 'b' use big-endian byte order for creating a file
176          * 'L' read/write information using LSB2MSB bit order
177          * 'B' read/write information using MSB2LSB bit order
178          * 'H' read/write information using host bit order
179          * 'M' enable use of memory-mapped files when supported
180          * 'm' disable use of memory-mapped files
181          * 'C' enable strip chopping support when reading
182          * 'c' disable strip chopping support
183          * 'h' read TIFF header only, do not load the first IFD
184          * '4' ClassicTIFF for creating a file (default)
185          * '8' BigTIFF for creating a file
186          *
187          * The use of the 'l' and 'b' flags is strongly discouraged.
188          * These flags are provided solely because numerous vendors,
189          * typically on the PC, do not correctly support TIFF; they
190          * only support the Intel little-endian byte order.  This
191          * support is not configured by default because it supports
192          * the violation of the TIFF spec that says that readers *MUST*
193          * support both byte orders.  It is strongly recommended that
194          * you not use this feature except to deal with busted apps
195          * that write invalid TIFF.  And even in those cases you should
196          * bang on the vendors to fix their software.
197          *
198          * The 'L', 'B', and 'H' flags are intended for applications
199          * that can optimize operations on data by using a particular
200          * bit order.  By default the library returns data in MSB2LSB
201          * bit order for compatibiltiy with older versions of this
202          * library.  Returning data in the bit order of the native cpu
203          * makes the most sense but also requires applications to check
204          * the value of the FillOrder tag; something they probably do
205          * not do right now.
206          *
207          * The 'M' and 'm' flags are provided because some virtual memory
208          * systems exhibit poor behaviour when large images are mapped.
209          * These options permit clients to control the use of memory-mapped
210          * files on a per-file basis.
211          *
212          * The 'C' and 'c' flags are provided because the library support
213          * for chopping up large strips into multiple smaller strips is not
214          * application-transparent and as such can cause problems.  The 'c'
215          * option permits applications that only want to look at the tags,
216          * for example, to get the unadulterated TIFF tag information.
217          */
218         for (cp = mode; *cp; cp++)
219                 switch (*cp) {
220                         case 'b':
221                                 #ifndef WORDS_BIGENDIAN
222                                 if (m&O_CREAT)
223                                         tif->tif_flags |= TIFF_SWAB;
224                                 #endif
225                                 break;
226                         case 'l':
227                                 #ifdef WORDS_BIGENDIAN
228                                 if ((m&O_CREAT))
229                                         tif->tif_flags |= TIFF_SWAB;
230                                 #endif
231                                 break;
232                         case 'B':
233                                 tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
234                                     FILLORDER_MSB2LSB;
235                                 break;
236                         case 'L':
237                                 tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
238                                     FILLORDER_LSB2MSB;
239                                 break;
240                         case 'H':
241                                 tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
242                                     HOST_FILLORDER;
243                                 break;
244                         case 'M':
245                                 if (m == O_RDONLY)
246                                         tif->tif_flags |= TIFF_MAPPED;
247                                 break;
248                         case 'm':
249                                 if (m == O_RDONLY)
250                                         tif->tif_flags &= ~TIFF_MAPPED;
251                                 break;
252                         case 'C':
253                                 if (m == O_RDONLY)
254                                         tif->tif_flags |= TIFF_STRIPCHOP;
255                                 break;
256                         case 'c':
257                                 if (m == O_RDONLY)
258                                         tif->tif_flags &= ~TIFF_STRIPCHOP;
259                                 break;
260                         case 'h':
261                                 tif->tif_flags |= TIFF_HEADERONLY;
262                                 break;
263                         case '8':
264                                 if (m&O_CREAT)
265                                         tif->tif_flags |= TIFF_BIGTIFF;
266                                 break;
267                 }
268         /*
269          * Read in TIFF header.
270          */
271         if ((m & O_TRUNC) ||
272             !ReadOK(tif, &tif->tif_header, sizeof (TIFFHeaderClassic))) {
273                 if (tif->tif_mode == O_RDONLY) {
274                         TIFFErrorExt(tif->tif_clientdata, name,
275                             "Cannot read TIFF header");
276                         goto bad;
277                 }
278                 /*
279                  * Setup header and write.
280                  */
281                 #ifdef WORDS_BIGENDIAN
282                 tif->tif_header.common.tiff_magic = tif->tif_flags & TIFF_SWAB
283                     ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN;
284                 #else
285                 tif->tif_header.common.tiff_magic = tif->tif_flags & TIFF_SWAB
286                     ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
287                 #endif
288                 if (!(tif->tif_flags&TIFF_BIGTIFF))
289                 {
290                         tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC;
291                         tif->tif_header.classic.tiff_diroff = 0;
292                         if (tif->tif_flags & TIFF_SWAB)
293                                 TIFFSwabShort(&tif->tif_header.common.tiff_version);
294                         tif->tif_header_size = sizeof(TIFFHeaderClassic);
295                 }
296                 else
297                 {
298                         tif->tif_header.common.tiff_version = TIFF_VERSION_BIG;
299                         tif->tif_header.big.tiff_offsetsize = 8;
300                         tif->tif_header.big.tiff_unused = 0;
301                         tif->tif_header.big.tiff_diroff = 0;
302                         if (tif->tif_flags & TIFF_SWAB)
303                         {
304                                 TIFFSwabShort(&tif->tif_header.common.tiff_version);
305                                 TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize);
306                         }
307                         tif->tif_header_size = sizeof (TIFFHeaderBig);
308                 }
309                 /*
310                  * The doc for "fopen" for some STD_C_LIBs says that if you
311                  * open a file for modify ("+"), then you must fseek (or
312                  * fflush?) between any freads and fwrites.  This is not
313                  * necessary on most systems, but has been shown to be needed
314                  * on Solaris.
315                  */
316                 TIFFSeekFile( tif, 0, SEEK_SET );
317                 if (!WriteOK(tif, &tif->tif_header, (tmsize_t)(tif->tif_header_size))) {
318                         TIFFErrorExt(tif->tif_clientdata, name,
319                             "Error writing TIFF header");
320                         goto bad;
321                 }
322                 /*
323                  * Setup the byte order handling.
324                  */
325                 if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) {
326                         #ifndef WORDS_BIGENDIAN
327                         tif->tif_flags |= TIFF_SWAB;
328                         #endif
329                 } else {
330                         #ifdef WORDS_BIGENDIAN
331                         tif->tif_flags |= TIFF_SWAB;
332                         #endif
333                 }
334                 /*
335                  * Setup default directory.
336                  */
337                 if (!TIFFDefaultDirectory(tif))
338                         goto bad;
339                 tif->tif_diroff = 0;
340                 tif->tif_dirlist = NULL;
341                 tif->tif_dirlistsize = 0;
342                 tif->tif_dirnumber = 0;
343                 return (tif);
344         }
345         /*
346          * Setup the byte order handling.
347          */
348         if (tif->tif_header.common.tiff_magic != TIFF_BIGENDIAN &&
349             tif->tif_header.common.tiff_magic != TIFF_LITTLEENDIAN
350             #if MDI_SUPPORT
351             &&
352             #if HOST_BIGENDIAN
353             tif->tif_header.common.tiff_magic != MDI_BIGENDIAN
354             #else
355             tif->tif_header.common.tiff_magic != MDI_LITTLEENDIAN
356             #endif
357             ) {
358                 TIFFErrorExt(tif->tif_clientdata, name,
359                     "Not a TIFF or MDI file, bad magic number %d (0x%x)",
360             #else
361             ) {
362                 TIFFErrorExt(tif->tif_clientdata, name,
363                     "Not a TIFF file, bad magic number %d (0x%x)",
364             #endif
365                     tif->tif_header.common.tiff_magic,
366                     tif->tif_header.common.tiff_magic);
367                 goto bad;
368         }
369         if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) {
370                 #ifndef WORDS_BIGENDIAN
371                 tif->tif_flags |= TIFF_SWAB;
372                 #endif
373         } else {
374                 #ifdef WORDS_BIGENDIAN
375                 tif->tif_flags |= TIFF_SWAB;
376                 #endif
377         }
378         if (tif->tif_flags & TIFF_SWAB) 
379                 TIFFSwabShort(&tif->tif_header.common.tiff_version);
380         if ((tif->tif_header.common.tiff_version != TIFF_VERSION_CLASSIC)&&
381             (tif->tif_header.common.tiff_version != TIFF_VERSION_BIG)) {
382                 TIFFErrorExt(tif->tif_clientdata, name,
383                     "Not a TIFF file, bad version number %d (0x%x)",
384                     tif->tif_header.common.tiff_version,
385                     tif->tif_header.common.tiff_version);
386                 goto bad;
387         }
388         if (tif->tif_header.common.tiff_version == TIFF_VERSION_CLASSIC)
389         {
390                 if (tif->tif_flags & TIFF_SWAB)
391                         TIFFSwabLong(&tif->tif_header.classic.tiff_diroff);
392                 tif->tif_header_size = sizeof(TIFFHeaderClassic);
393         }
394         else
395         {
396                 if (!ReadOK(tif, ((uint8*)(&tif->tif_header) + sizeof(TIFFHeaderClassic)), (sizeof(TIFFHeaderBig)-sizeof(TIFFHeaderClassic))))
397                 {
398                         TIFFErrorExt(tif->tif_clientdata, name,
399                             "Cannot read TIFF header");
400                         goto bad;
401                 }
402                 if (tif->tif_flags & TIFF_SWAB)
403                 {
404                         TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize);
405                         TIFFSwabLong8(&tif->tif_header.big.tiff_diroff);
406                 }
407                 if (tif->tif_header.big.tiff_offsetsize != 8)
408                 {
409                         TIFFErrorExt(tif->tif_clientdata, name,
410                             "Not a TIFF file, bad BigTIFF offsetsize %d (0x%x)",
411                             tif->tif_header.big.tiff_offsetsize,
412                             tif->tif_header.big.tiff_offsetsize);
413                         goto bad;
414                 }
415                 if (tif->tif_header.big.tiff_unused != 0)
416                 {
417                         TIFFErrorExt(tif->tif_clientdata, name,
418                             "Not a TIFF file, bad BigTIFF unused %d (0x%x)",
419                             tif->tif_header.big.tiff_unused,
420                             tif->tif_header.big.tiff_unused);
421                         goto bad;
422                 }
423                 tif->tif_header_size = sizeof(TIFFHeaderBig);
424                 tif->tif_flags |= TIFF_BIGTIFF;
425         }
426         tif->tif_flags |= TIFF_MYBUFFER;
427         tif->tif_rawcp = tif->tif_rawdata = 0;
428         tif->tif_rawdatasize = 0;
429         tif->tif_rawdataoff = 0;
430         tif->tif_rawdataloaded = 0;
431
432         switch (mode[0]) {
433                 case 'r':
434                         if (!(tif->tif_flags&TIFF_BIGTIFF))
435                                 tif->tif_nextdiroff = tif->tif_header.classic.tiff_diroff;
436                         else
437                                 tif->tif_nextdiroff = tif->tif_header.big.tiff_diroff;
438                         /*
439                          * Try to use a memory-mapped file if the client
440                          * has not explicitly suppressed usage with the
441                          * 'm' flag in the open mode (see above).
442                          */
443                         if (tif->tif_flags & TIFF_MAPPED)
444                         {
445                                 toff_t n;
446                                 if (TIFFMapFileContents(tif,(void**)(&tif->tif_base),&n))
447                                 {
448                                         tif->tif_size=(tmsize_t)n;
449                                         assert((toff_t)tif->tif_size==n);
450                                 }
451                                 else
452                                         tif->tif_flags &= ~TIFF_MAPPED;
453                         }
454                         /*
455                          * Sometimes we do not want to read the first directory (for example,
456                          * it may be broken) and want to proceed to other directories. I this
457                          * case we use the TIFF_HEADERONLY flag to open file and return
458                          * immediately after reading TIFF header.
459                          */
460                         if (tif->tif_flags & TIFF_HEADERONLY)
461                                 return (tif);
462
463                         /*
464                          * Setup initial directory.
465                          */
466                         if (TIFFReadDirectory(tif)) {
467                                 tif->tif_rawcc = (tmsize_t)-1;
468                                 tif->tif_flags |= TIFF_BUFFERSETUP;
469                                 return (tif);
470                         }
471                         break;
472                 case 'a':
473                         /*
474                          * New directories are automatically append
475                          * to the end of the directory chain when they
476                          * are written out (see TIFFWriteDirectory).
477                          */
478                         if (!TIFFDefaultDirectory(tif))
479                                 goto bad;
480                         return (tif);
481         }
482 bad:
483         tif->tif_mode = O_RDONLY;       /* XXX avoid flush */
484         TIFFCleanup(tif);
485 bad2:
486         return ((TIFF*)0);
487 }
488
489 /*
490  * Query functions to access private data.
491  */
492
493 /*
494  * Return open file's name.
495  */
496 const char *
497 TIFFFileName(TIFF* tif)
498 {
499         return (tif->tif_name);
500 }
501
502 /*
503  * Set the file name.
504  */
505 const char *
506 TIFFSetFileName(TIFF* tif, const char *name)
507 {
508         const char* old_name = tif->tif_name;
509         tif->tif_name = (char *)name;
510         return (old_name);
511 }
512
513 /*
514  * Return open file's I/O descriptor.
515  */
516 int
517 TIFFFileno(TIFF* tif)
518 {
519         return (tif->tif_fd);
520 }
521
522 /*
523  * Set open file's I/O descriptor, and return previous value.
524  */
525 int
526 TIFFSetFileno(TIFF* tif, int fd)
527 {
528         int old_fd = tif->tif_fd;
529         tif->tif_fd = fd;
530         return old_fd;
531 }
532
533 /*
534  * Return open file's clientdata.
535  */
536 thandle_t
537 TIFFClientdata(TIFF* tif)
538 {
539         return (tif->tif_clientdata);
540 }
541
542 /*
543  * Set open file's clientdata, and return previous value.
544  */
545 thandle_t
546 TIFFSetClientdata(TIFF* tif, thandle_t newvalue)
547 {
548         thandle_t m = tif->tif_clientdata;
549         tif->tif_clientdata = newvalue;
550         return m;
551 }
552
553 /*
554  * Return read/write mode.
555  */
556 int
557 TIFFGetMode(TIFF* tif)
558 {
559         return (tif->tif_mode);
560 }
561
562 /*
563  * Return read/write mode.
564  */
565 int
566 TIFFSetMode(TIFF* tif, int mode)
567 {
568         int old_mode = tif->tif_mode;
569         tif->tif_mode = mode;
570         return (old_mode);
571 }
572
573 /*
574  * Return nonzero if file is organized in
575  * tiles; zero if organized as strips.
576  */
577 int
578 TIFFIsTiled(TIFF* tif)
579 {
580         return (isTiled(tif));
581 }
582
583 /*
584  * Return current row being read/written.
585  */
586 uint32
587 TIFFCurrentRow(TIFF* tif)
588 {
589         return (tif->tif_row);
590 }
591
592 /*
593  * Return index of the current directory.
594  */
595 uint16
596 TIFFCurrentDirectory(TIFF* tif)
597 {
598         return (tif->tif_curdir);
599 }
600
601 /*
602  * Return current strip.
603  */
604 uint32
605 TIFFCurrentStrip(TIFF* tif)
606 {
607         return (tif->tif_curstrip);
608 }
609
610 /*
611  * Return current tile.
612  */
613 uint32
614 TIFFCurrentTile(TIFF* tif)
615 {
616         return (tif->tif_curtile);
617 }
618
619 /*
620  * Return nonzero if the file has byte-swapped data.
621  */
622 int
623 TIFFIsByteSwapped(TIFF* tif)
624 {
625         return ((tif->tif_flags & TIFF_SWAB) != 0);
626 }
627
628 /*
629  * Return nonzero if the data is returned up-sampled.
630  */
631 int
632 TIFFIsUpSampled(TIFF* tif)
633 {
634         return (isUpSampled(tif));
635 }
636
637 /*
638  * Return nonzero if the data is returned in MSB-to-LSB bit order.
639  */
640 int
641 TIFFIsMSB2LSB(TIFF* tif)
642 {
643         return (isFillOrder(tif, FILLORDER_MSB2LSB));
644 }
645
646 /*
647  * Return nonzero if given file was written in big-endian order.
648  */
649 int
650 TIFFIsBigEndian(TIFF* tif)
651 {
652         return (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN);
653 }
654
655 /*
656  * Return pointer to file read method.
657  */
658 TIFFReadWriteProc
659 TIFFGetReadProc(TIFF* tif)
660 {
661         return (tif->tif_readproc);
662 }
663
664 /*
665  * Return pointer to file write method.
666  */
667 TIFFReadWriteProc
668 TIFFGetWriteProc(TIFF* tif)
669 {
670         return (tif->tif_writeproc);
671 }
672
673 /*
674  * Return pointer to file seek method.
675  */
676 TIFFSeekProc
677 TIFFGetSeekProc(TIFF* tif)
678 {
679         return (tif->tif_seekproc);
680 }
681
682 /*
683  * Return pointer to file close method.
684  */
685 TIFFCloseProc
686 TIFFGetCloseProc(TIFF* tif)
687 {
688         return (tif->tif_closeproc);
689 }
690
691 /*
692  * Return pointer to file size requesting method.
693  */
694 TIFFSizeProc
695 TIFFGetSizeProc(TIFF* tif)
696 {
697         return (tif->tif_sizeproc);
698 }
699
700 /*
701  * Return pointer to memory mapping method.
702  */
703 TIFFMapFileProc
704 TIFFGetMapFileProc(TIFF* tif)
705 {
706         return (tif->tif_mapproc);
707 }
708
709 /*
710  * Return pointer to memory unmapping method.
711  */
712 TIFFUnmapFileProc
713 TIFFGetUnmapFileProc(TIFF* tif)
714 {
715         return (tif->tif_unmapproc);
716 }
717
718 /* vim: set ts=8 sts=8 sw=8 noet: */
719 /*
720  * Local Variables:
721  * mode: c
722  * c-basic-offset: 8
723  * fill-column: 78
724  * End:
725  */