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
_tiffDummyMapProc(thandle_t fd,void ** pbase,toff_t * psize)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
_tiffDummyUnmapProc(thandle_t fd,void * base,toff_t size)43 _tiffDummyUnmapProc(thandle_t fd, void* base, toff_t size)
44 {
45 	(void) fd; (void) base; (void) size;
46 }
47 
48 int
_TIFFgetMode(const char * mode,const char * module)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*
TIFFClientOpen(const char * name,const char * mode,thandle_t clientdata,TIFFReadWriteProc readproc,TIFFReadWriteProc writeproc,TIFFSeekProc seekproc,TIFFCloseProc closeproc,TIFFSizeProc sizeproc,TIFFMapFileProc mapproc,TIFFUnmapFileProc unmapproc)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  */
726