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