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