Home | History | Annotate | Download | only in libtiff
      1 /* $Id: tif_open.c,v 1.48 2016-11-20 22:29:47 erouault 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 brain dead 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 compatibility 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  */
    726