Blame libtiff/tif_open.c

Packit Service 2594b8
/* $Id: tif_open.c,v 1.48 2016-11-20 22:29:47 erouault Exp $ */
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Copyright (c) 1988-1997 Sam Leffler
Packit Service 2594b8
 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
Packit Service 2594b8
 *
Packit Service 2594b8
 * Permission to use, copy, modify, distribute, and sell this software and 
Packit Service 2594b8
 * its documentation for any purpose is hereby granted without fee, provided
Packit Service 2594b8
 * that (i) the above copyright notices and this permission notice appear in
Packit Service 2594b8
 * all copies of the software and related documentation, and (ii) the names of
Packit Service 2594b8
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
Packit Service 2594b8
 * publicity relating to the software without the specific, prior written
Packit Service 2594b8
 * permission of Sam Leffler and Silicon Graphics.
Packit Service 2594b8
 * 
Packit Service 2594b8
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
Packit Service 2594b8
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
Packit Service 2594b8
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
Packit Service 2594b8
 * 
Packit Service 2594b8
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
Packit Service 2594b8
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
Packit Service 2594b8
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
Packit Service 2594b8
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
Packit Service 2594b8
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
Packit Service 2594b8
 * OF THIS SOFTWARE.
Packit Service 2594b8
 */
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * TIFF Library.
Packit Service 2594b8
 */
Packit Service 2594b8
#include "tiffiop.h"
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Dummy functions to fill the omitted client procedures.
Packit Service 2594b8
 */
Packit Service 2594b8
static int
Packit Service 2594b8
_tiffDummyMapProc(thandle_t fd, void** pbase, toff_t* psize)
Packit Service 2594b8
{
Packit Service 2594b8
	(void) fd; (void) pbase; (void) psize;
Packit Service 2594b8
	return (0);
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
static void
Packit Service 2594b8
_tiffDummyUnmapProc(thandle_t fd, void* base, toff_t size)
Packit Service 2594b8
{
Packit Service 2594b8
	(void) fd; (void) base; (void) size;
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
int
Packit Service 2594b8
_TIFFgetMode(const char* mode, const char* module)
Packit Service 2594b8
{
Packit Service 2594b8
	int m = -1;
Packit Service 2594b8
Packit Service 2594b8
	switch (mode[0]) {
Packit Service 2594b8
	case 'r':
Packit Service 2594b8
		m = O_RDONLY;
Packit Service 2594b8
		if (mode[1] == '+')
Packit Service 2594b8
			m = O_RDWR;
Packit Service 2594b8
		break;
Packit Service 2594b8
	case 'w':
Packit Service 2594b8
	case 'a':
Packit Service 2594b8
		m = O_RDWR|O_CREAT;
Packit Service 2594b8
		if (mode[0] == 'w')
Packit Service 2594b8
			m |= O_TRUNC;
Packit Service 2594b8
		break;
Packit Service 2594b8
	default:
Packit Service 2594b8
		TIFFErrorExt(0, module, "\"%s\": Bad mode", mode);
Packit Service 2594b8
		break;
Packit Service 2594b8
	}
Packit Service 2594b8
	return (m);
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
TIFF*
Packit Service 2594b8
TIFFClientOpen(
Packit Service 2594b8
	const char* name, const char* mode,
Packit Service 2594b8
	thandle_t clientdata,
Packit Service 2594b8
	TIFFReadWriteProc readproc,
Packit Service 2594b8
	TIFFReadWriteProc writeproc,
Packit Service 2594b8
	TIFFSeekProc seekproc,
Packit Service 2594b8
	TIFFCloseProc closeproc,
Packit Service 2594b8
	TIFFSizeProc sizeproc,
Packit Service 2594b8
	TIFFMapFileProc mapproc,
Packit Service 2594b8
	TIFFUnmapFileProc unmapproc
Packit Service 2594b8
)
Packit Service 2594b8
{
Packit Service 2594b8
	static const char module[] = "TIFFClientOpen";
Packit Service 2594b8
	TIFF *tif;
Packit Service 2594b8
	int m;
Packit Service 2594b8
	const char* cp;
Packit Service 2594b8
Packit Service 2594b8
	/* The following are configuration checks. They should be redundant, but should not
Packit Service 2594b8
	 * compile to any actual code in an optimised release build anyway. If any of them
Packit Service 2594b8
	 * fail, (makefile-based or other) configuration is not correct */
Packit Service 2594b8
	assert(sizeof(uint8)==1);
Packit Service 2594b8
	assert(sizeof(int8)==1);
Packit Service 2594b8
	assert(sizeof(uint16)==2);
Packit Service 2594b8
	assert(sizeof(int16)==2);
Packit Service 2594b8
	assert(sizeof(uint32)==4);
Packit Service 2594b8
	assert(sizeof(int32)==4);
Packit Service 2594b8
	assert(sizeof(uint64)==8);
Packit Service 2594b8
	assert(sizeof(int64)==8);
Packit Service 2594b8
	assert(sizeof(tmsize_t)==sizeof(void*));
Packit Service 2594b8
	{
Packit Service 2594b8
		union{
Packit Service 2594b8
			uint8 a8[2];
Packit Service 2594b8
			uint16 a16;
Packit Service 2594b8
		} n;
Packit Service 2594b8
		n.a8[0]=1;
Packit Service 2594b8
		n.a8[1]=0;
Packit Service 2594b8
		#ifdef WORDS_BIGENDIAN
Packit Service 2594b8
		assert(n.a16==256);
Packit Service 2594b8
		#else
Packit Service 2594b8
		assert(n.a16==1);
Packit Service 2594b8
		#endif
Packit Service 2594b8
	}
Packit Service 2594b8
Packit Service 2594b8
	m = _TIFFgetMode(mode, module);
Packit Service 2594b8
	if (m == -1)
Packit Service 2594b8
		goto bad2;
Packit Service 2594b8
	tif = (TIFF *)_TIFFmalloc((tmsize_t)(sizeof (TIFF) + strlen(name) + 1));
Packit Service 2594b8
	if (tif == NULL) {
Packit Service 2594b8
		TIFFErrorExt(clientdata, module, "%s: Out of memory (TIFF structure)", name);
Packit Service 2594b8
		goto bad2;
Packit Service 2594b8
	}
Packit Service 2594b8
	_TIFFmemset(tif, 0, sizeof (*tif));
Packit Service 2594b8
	tif->tif_name = (char *)tif + sizeof (TIFF);
Packit Service 2594b8
	strcpy(tif->tif_name, name);
Packit Service 2594b8
	tif->tif_mode = m &~ (O_CREAT|O_TRUNC);
Packit Service 2594b8
	tif->tif_curdir = (uint16) -1;		/* non-existent directory */
Packit Service 2594b8
	tif->tif_curoff = 0;
Packit Service 2594b8
	tif->tif_curstrip = (uint32) -1;	/* invalid strip */
Packit Service 2594b8
	tif->tif_row = (uint32) -1;		/* read/write pre-increment */
Packit Service 2594b8
	tif->tif_clientdata = clientdata;
Packit Service 2594b8
	if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) {
Packit Service 2594b8
		TIFFErrorExt(clientdata, module,
Packit Service 2594b8
		    "One of the client procedures is NULL pointer.");
Packit Service 2594b8
		goto bad2;
Packit Service 2594b8
	}
Packit Service 2594b8
	tif->tif_readproc = readproc;
Packit Service 2594b8
	tif->tif_writeproc = writeproc;
Packit Service 2594b8
	tif->tif_seekproc = seekproc;
Packit Service 2594b8
	tif->tif_closeproc = closeproc;
Packit Service 2594b8
	tif->tif_sizeproc = sizeproc;
Packit Service 2594b8
	if (mapproc)
Packit Service 2594b8
		tif->tif_mapproc = mapproc;
Packit Service 2594b8
	else
Packit Service 2594b8
		tif->tif_mapproc = _tiffDummyMapProc;
Packit Service 2594b8
	if (unmapproc)
Packit Service 2594b8
		tif->tif_unmapproc = unmapproc;
Packit Service 2594b8
	else
Packit Service 2594b8
		tif->tif_unmapproc = _tiffDummyUnmapProc;
Packit Service 2594b8
	_TIFFSetDefaultCompressionState(tif);    /* setup default state */
Packit Service 2594b8
	/*
Packit Service 2594b8
	 * Default is to return data MSB2LSB and enable the
Packit Service 2594b8
	 * use of memory-mapped files and strip chopping when
Packit Service 2594b8
	 * a file is opened read-only.
Packit Service 2594b8
	 */
Packit Service 2594b8
	tif->tif_flags = FILLORDER_MSB2LSB;
Packit Service 2594b8
	if (m == O_RDONLY )
Packit Service 2594b8
		tif->tif_flags |= TIFF_MAPPED;
Packit Service 2594b8
Packit Service 2594b8
	#ifdef STRIPCHOP_DEFAULT
Packit Service 2594b8
	if (m == O_RDONLY || m == O_RDWR)
Packit Service 2594b8
		tif->tif_flags |= STRIPCHOP_DEFAULT;
Packit Service 2594b8
	#endif
Packit Service 2594b8
Packit Service 2594b8
	/*
Packit Service 2594b8
	 * Process library-specific flags in the open mode string.
Packit Service 2594b8
	 * The following flags may be used to control intrinsic library
Packit Service 2594b8
	 * behaviour that may or may not be desirable (usually for
Packit Service 2594b8
	 * compatibility with some application that claims to support
Packit Service 2594b8
	 * TIFF but only supports some brain dead idea of what the
Packit Service 2594b8
	 * vendor thinks TIFF is):
Packit Service 2594b8
	 *
Packit Service 2594b8
	 * 'l' use little-endian byte order for creating a file
Packit Service 2594b8
	 * 'b' use big-endian byte order for creating a file
Packit Service 2594b8
	 * 'L' read/write information using LSB2MSB bit order
Packit Service 2594b8
	 * 'B' read/write information using MSB2LSB bit order
Packit Service 2594b8
	 * 'H' read/write information using host bit order
Packit Service 2594b8
	 * 'M' enable use of memory-mapped files when supported
Packit Service 2594b8
	 * 'm' disable use of memory-mapped files
Packit Service 2594b8
	 * 'C' enable strip chopping support when reading
Packit Service 2594b8
	 * 'c' disable strip chopping support
Packit Service 2594b8
	 * 'h' read TIFF header only, do not load the first IFD
Packit Service 2594b8
	 * '4' ClassicTIFF for creating a file (default)
Packit Service 2594b8
	 * '8' BigTIFF for creating a file
Packit Service 2594b8
	 *
Packit Service 2594b8
	 * The use of the 'l' and 'b' flags is strongly discouraged.
Packit Service 2594b8
	 * These flags are provided solely because numerous vendors,
Packit Service 2594b8
	 * typically on the PC, do not correctly support TIFF; they
Packit Service 2594b8
	 * only support the Intel little-endian byte order.  This
Packit Service 2594b8
	 * support is not configured by default because it supports
Packit Service 2594b8
	 * the violation of the TIFF spec that says that readers *MUST*
Packit Service 2594b8
	 * support both byte orders.  It is strongly recommended that
Packit Service 2594b8
	 * you not use this feature except to deal with busted apps
Packit Service 2594b8
	 * that write invalid TIFF.  And even in those cases you should
Packit Service 2594b8
	 * bang on the vendors to fix their software.
Packit Service 2594b8
	 *
Packit Service 2594b8
	 * The 'L', 'B', and 'H' flags are intended for applications
Packit Service 2594b8
	 * that can optimize operations on data by using a particular
Packit Service 2594b8
	 * bit order.  By default the library returns data in MSB2LSB
Packit Service 2594b8
	 * bit order for compatibility with older versions of this
Packit Service 2594b8
	 * library.  Returning data in the bit order of the native CPU
Packit Service 2594b8
	 * makes the most sense but also requires applications to check
Packit Service 2594b8
	 * the value of the FillOrder tag; something they probably do
Packit Service 2594b8
	 * not do right now.
Packit Service 2594b8
	 *
Packit Service 2594b8
	 * The 'M' and 'm' flags are provided because some virtual memory
Packit Service 2594b8
	 * systems exhibit poor behaviour when large images are mapped.
Packit Service 2594b8
	 * These options permit clients to control the use of memory-mapped
Packit Service 2594b8
	 * files on a per-file basis.
Packit Service 2594b8
	 *
Packit Service 2594b8
	 * The 'C' and 'c' flags are provided because the library support
Packit Service 2594b8
	 * for chopping up large strips into multiple smaller strips is not
Packit Service 2594b8
	 * application-transparent and as such can cause problems.  The 'c'
Packit Service 2594b8
	 * option permits applications that only want to look at the tags,
Packit Service 2594b8
	 * for example, to get the unadulterated TIFF tag information.
Packit Service 2594b8
	 */
Packit Service 2594b8
	for (cp = mode; *cp; cp++)
Packit Service 2594b8
		switch (*cp) {
Packit Service 2594b8
			case 'b':
Packit Service 2594b8
				#ifndef WORDS_BIGENDIAN
Packit Service 2594b8
				if (m&O_CREAT)
Packit Service 2594b8
					tif->tif_flags |= TIFF_SWAB;
Packit Service 2594b8
				#endif
Packit Service 2594b8
				break;
Packit Service 2594b8
			case 'l':
Packit Service 2594b8
				#ifdef WORDS_BIGENDIAN
Packit Service 2594b8
				if ((m&O_CREAT))
Packit Service 2594b8
					tif->tif_flags |= TIFF_SWAB;
Packit Service 2594b8
				#endif
Packit Service 2594b8
				break;
Packit Service 2594b8
			case 'B':
Packit Service 2594b8
				tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
Packit Service 2594b8
				    FILLORDER_MSB2LSB;
Packit Service 2594b8
				break;
Packit Service 2594b8
			case 'L':
Packit Service 2594b8
				tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
Packit Service 2594b8
				    FILLORDER_LSB2MSB;
Packit Service 2594b8
				break;
Packit Service 2594b8
			case 'H':
Packit Service 2594b8
				tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
Packit Service 2594b8
				    HOST_FILLORDER;
Packit Service 2594b8
				break;
Packit Service 2594b8
			case 'M':
Packit Service 2594b8
				if (m == O_RDONLY)
Packit Service 2594b8
					tif->tif_flags |= TIFF_MAPPED;
Packit Service 2594b8
				break;
Packit Service 2594b8
			case 'm':
Packit Service 2594b8
				if (m == O_RDONLY)
Packit Service 2594b8
					tif->tif_flags &= ~TIFF_MAPPED;
Packit Service 2594b8
				break;
Packit Service 2594b8
			case 'C':
Packit Service 2594b8
				if (m == O_RDONLY)
Packit Service 2594b8
					tif->tif_flags |= TIFF_STRIPCHOP;
Packit Service 2594b8
				break;
Packit Service 2594b8
			case 'c':
Packit Service 2594b8
				if (m == O_RDONLY)
Packit Service 2594b8
					tif->tif_flags &= ~TIFF_STRIPCHOP;
Packit Service 2594b8
				break;
Packit Service 2594b8
			case 'h':
Packit Service 2594b8
				tif->tif_flags |= TIFF_HEADERONLY;
Packit Service 2594b8
				break;
Packit Service 2594b8
			case '8':
Packit Service 2594b8
				if (m&O_CREAT)
Packit Service 2594b8
					tif->tif_flags |= TIFF_BIGTIFF;
Packit Service 2594b8
				break;
Packit Service 2594b8
		}
Packit Service 2594b8
	/*
Packit Service 2594b8
	 * Read in TIFF header.
Packit Service 2594b8
	 */
Packit Service 2594b8
	if ((m & O_TRUNC) ||
Packit Service 2594b8
	    !ReadOK(tif, &tif->tif_header, sizeof (TIFFHeaderClassic))) {
Packit Service 2594b8
		if (tif->tif_mode == O_RDONLY) {
Packit Service 2594b8
			TIFFErrorExt(tif->tif_clientdata, name,
Packit Service 2594b8
			    "Cannot read TIFF header");
Packit Service 2594b8
			goto bad;
Packit Service 2594b8
		}
Packit Service 2594b8
		/*
Packit Service 2594b8
		 * Setup header and write.
Packit Service 2594b8
		 */
Packit Service 2594b8
		#ifdef WORDS_BIGENDIAN
Packit Service 2594b8
		tif->tif_header.common.tiff_magic = (tif->tif_flags & TIFF_SWAB)
Packit Service 2594b8
		    ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN;
Packit Service 2594b8
		#else
Packit Service 2594b8
		tif->tif_header.common.tiff_magic = (tif->tif_flags & TIFF_SWAB)
Packit Service 2594b8
		    ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
Packit Service 2594b8
		#endif
Packit Service 2594b8
		if (!(tif->tif_flags&TIFF_BIGTIFF))
Packit Service 2594b8
		{
Packit Service 2594b8
			tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC;
Packit Service 2594b8
			tif->tif_header.classic.tiff_diroff = 0;
Packit Service 2594b8
			if (tif->tif_flags & TIFF_SWAB)
Packit Service 2594b8
				TIFFSwabShort(&tif->tif_header.common.tiff_version);
Packit Service 2594b8
			tif->tif_header_size = sizeof(TIFFHeaderClassic);
Packit Service 2594b8
		}
Packit Service 2594b8
		else
Packit Service 2594b8
		{
Packit Service 2594b8
			tif->tif_header.common.tiff_version = TIFF_VERSION_BIG;
Packit Service 2594b8
			tif->tif_header.big.tiff_offsetsize = 8;
Packit Service 2594b8
			tif->tif_header.big.tiff_unused = 0;
Packit Service 2594b8
			tif->tif_header.big.tiff_diroff = 0;
Packit Service 2594b8
			if (tif->tif_flags & TIFF_SWAB)
Packit Service 2594b8
			{
Packit Service 2594b8
				TIFFSwabShort(&tif->tif_header.common.tiff_version);
Packit Service 2594b8
				TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize);
Packit Service 2594b8
			}
Packit Service 2594b8
			tif->tif_header_size = sizeof (TIFFHeaderBig);
Packit Service 2594b8
		}
Packit Service 2594b8
		/*
Packit Service 2594b8
		 * The doc for "fopen" for some STD_C_LIBs says that if you
Packit Service 2594b8
		 * open a file for modify ("+"), then you must fseek (or
Packit Service 2594b8
		 * fflush?) between any freads and fwrites.  This is not
Packit Service 2594b8
		 * necessary on most systems, but has been shown to be needed
Packit Service 2594b8
		 * on Solaris.
Packit Service 2594b8
		 */
Packit Service 2594b8
		TIFFSeekFile( tif, 0, SEEK_SET );
Packit Service 2594b8
		if (!WriteOK(tif, &tif->tif_header, (tmsize_t)(tif->tif_header_size))) {
Packit Service 2594b8
			TIFFErrorExt(tif->tif_clientdata, name,
Packit Service 2594b8
			    "Error writing TIFF header");
Packit Service 2594b8
			goto bad;
Packit Service 2594b8
		}
Packit Service 2594b8
		/*
Packit Service 2594b8
		 * Setup the byte order handling.
Packit Service 2594b8
		 */
Packit Service 2594b8
		if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) {
Packit Service 2594b8
			#ifndef WORDS_BIGENDIAN
Packit Service 2594b8
			tif->tif_flags |= TIFF_SWAB;
Packit Service 2594b8
			#endif
Packit Service 2594b8
		} else {
Packit Service 2594b8
			#ifdef WORDS_BIGENDIAN
Packit Service 2594b8
			tif->tif_flags |= TIFF_SWAB;
Packit Service 2594b8
			#endif
Packit Service 2594b8
		}
Packit Service 2594b8
		/*
Packit Service 2594b8
		 * Setup default directory.
Packit Service 2594b8
		 */
Packit Service 2594b8
		if (!TIFFDefaultDirectory(tif))
Packit Service 2594b8
			goto bad;
Packit Service 2594b8
		tif->tif_diroff = 0;
Packit Service 2594b8
		tif->tif_dirlist = NULL;
Packit Service 2594b8
		tif->tif_dirlistsize = 0;
Packit Service 2594b8
		tif->tif_dirnumber = 0;
Packit Service 2594b8
		return (tif);
Packit Service 2594b8
	}
Packit Service 2594b8
	/*
Packit Service 2594b8
	 * Setup the byte order handling.
Packit Service 2594b8
	 */
Packit Service 2594b8
	if (tif->tif_header.common.tiff_magic != TIFF_BIGENDIAN &&
Packit Service 2594b8
	    tif->tif_header.common.tiff_magic != TIFF_LITTLEENDIAN
Packit Service 2594b8
	    #if MDI_SUPPORT
Packit Service 2594b8
	    &&
Packit Service 2594b8
	    #if HOST_BIGENDIAN
Packit Service 2594b8
	    tif->tif_header.common.tiff_magic != MDI_BIGENDIAN
Packit Service 2594b8
	    #else
Packit Service 2594b8
	    tif->tif_header.common.tiff_magic != MDI_LITTLEENDIAN
Packit Service 2594b8
	    #endif
Packit Service 2594b8
	    ) {
Packit Service 2594b8
		TIFFErrorExt(tif->tif_clientdata, name,
Packit Service 2594b8
		    "Not a TIFF or MDI file, bad magic number %d (0x%x)",
Packit Service 2594b8
	    #else
Packit Service 2594b8
	    ) {
Packit Service 2594b8
		TIFFErrorExt(tif->tif_clientdata, name,
Packit Service 2594b8
		    "Not a TIFF file, bad magic number %d (0x%x)",
Packit Service 2594b8
	    #endif
Packit Service 2594b8
		    tif->tif_header.common.tiff_magic,
Packit Service 2594b8
		    tif->tif_header.common.tiff_magic);
Packit Service 2594b8
		goto bad;
Packit Service 2594b8
	}
Packit Service 2594b8
	if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) {
Packit Service 2594b8
		#ifndef WORDS_BIGENDIAN
Packit Service 2594b8
		tif->tif_flags |= TIFF_SWAB;
Packit Service 2594b8
		#endif
Packit Service 2594b8
	} else {
Packit Service 2594b8
		#ifdef WORDS_BIGENDIAN
Packit Service 2594b8
		tif->tif_flags |= TIFF_SWAB;
Packit Service 2594b8
		#endif
Packit Service 2594b8
	}
Packit Service 2594b8
	if (tif->tif_flags & TIFF_SWAB) 
Packit Service 2594b8
		TIFFSwabShort(&tif->tif_header.common.tiff_version);
Packit Service 2594b8
	if ((tif->tif_header.common.tiff_version != TIFF_VERSION_CLASSIC)&&
Packit Service 2594b8
	    (tif->tif_header.common.tiff_version != TIFF_VERSION_BIG)) {
Packit Service 2594b8
		TIFFErrorExt(tif->tif_clientdata, name,
Packit Service 2594b8
		    "Not a TIFF file, bad version number %d (0x%x)",
Packit Service 2594b8
		    tif->tif_header.common.tiff_version,
Packit Service 2594b8
		    tif->tif_header.common.tiff_version);
Packit Service 2594b8
		goto bad;
Packit Service 2594b8
	}
Packit Service 2594b8
	if (tif->tif_header.common.tiff_version == TIFF_VERSION_CLASSIC)
Packit Service 2594b8
	{
Packit Service 2594b8
		if (tif->tif_flags & TIFF_SWAB)
Packit Service 2594b8
			TIFFSwabLong(&tif->tif_header.classic.tiff_diroff);
Packit Service 2594b8
		tif->tif_header_size = sizeof(TIFFHeaderClassic);
Packit Service 2594b8
	}
Packit Service 2594b8
	else
Packit Service 2594b8
	{
Packit Service 2594b8
		if (!ReadOK(tif, ((uint8*)(&tif->tif_header) + sizeof(TIFFHeaderClassic)), (sizeof(TIFFHeaderBig)-sizeof(TIFFHeaderClassic))))
Packit Service 2594b8
		{
Packit Service 2594b8
			TIFFErrorExt(tif->tif_clientdata, name,
Packit Service 2594b8
			    "Cannot read TIFF header");
Packit Service 2594b8
			goto bad;
Packit Service 2594b8
		}
Packit Service 2594b8
		if (tif->tif_flags & TIFF_SWAB)
Packit Service 2594b8
		{
Packit Service 2594b8
			TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize);
Packit Service 2594b8
			TIFFSwabLong8(&tif->tif_header.big.tiff_diroff);
Packit Service 2594b8
		}
Packit Service 2594b8
		if (tif->tif_header.big.tiff_offsetsize != 8)
Packit Service 2594b8
		{
Packit Service 2594b8
			TIFFErrorExt(tif->tif_clientdata, name,
Packit Service 2594b8
			    "Not a TIFF file, bad BigTIFF offsetsize %d (0x%x)",
Packit Service 2594b8
			    tif->tif_header.big.tiff_offsetsize,
Packit Service 2594b8
			    tif->tif_header.big.tiff_offsetsize);
Packit Service 2594b8
			goto bad;
Packit Service 2594b8
		}
Packit Service 2594b8
		if (tif->tif_header.big.tiff_unused != 0)
Packit Service 2594b8
		{
Packit Service 2594b8
			TIFFErrorExt(tif->tif_clientdata, name,
Packit Service 2594b8
			    "Not a TIFF file, bad BigTIFF unused %d (0x%x)",
Packit Service 2594b8
			    tif->tif_header.big.tiff_unused,
Packit Service 2594b8
			    tif->tif_header.big.tiff_unused);
Packit Service 2594b8
			goto bad;
Packit Service 2594b8
		}
Packit Service 2594b8
		tif->tif_header_size = sizeof(TIFFHeaderBig);
Packit Service 2594b8
		tif->tif_flags |= TIFF_BIGTIFF;
Packit Service 2594b8
	}
Packit Service 2594b8
	tif->tif_flags |= TIFF_MYBUFFER;
Packit Service 2594b8
	tif->tif_rawcp = tif->tif_rawdata = 0;
Packit Service 2594b8
	tif->tif_rawdatasize = 0;
Packit Service 2594b8
        tif->tif_rawdataoff = 0;
Packit Service 2594b8
        tif->tif_rawdataloaded = 0;
Packit Service 2594b8
Packit Service 2594b8
	switch (mode[0]) {
Packit Service 2594b8
		case 'r':
Packit Service 2594b8
			if (!(tif->tif_flags&TIFF_BIGTIFF))
Packit Service 2594b8
				tif->tif_nextdiroff = tif->tif_header.classic.tiff_diroff;
Packit Service 2594b8
			else
Packit Service 2594b8
				tif->tif_nextdiroff = tif->tif_header.big.tiff_diroff;
Packit Service 2594b8
			/*
Packit Service 2594b8
			 * Try to use a memory-mapped file if the client
Packit Service 2594b8
			 * has not explicitly suppressed usage with the
Packit Service 2594b8
			 * 'm' flag in the open mode (see above).
Packit Service 2594b8
			 */
Packit Service 2594b8
			if (tif->tif_flags & TIFF_MAPPED)
Packit Service 2594b8
			{
Packit Service 2594b8
				toff_t n;
Packit Service 2594b8
				if (TIFFMapFileContents(tif,(void**)(&tif->tif_base),&n))
Packit Service 2594b8
				{
Packit Service 2594b8
					tif->tif_size=(tmsize_t)n;
Packit Service 2594b8
					assert((toff_t)tif->tif_size==n);
Packit Service 2594b8
				}
Packit Service 2594b8
				else
Packit Service 2594b8
					tif->tif_flags &= ~TIFF_MAPPED;
Packit Service 2594b8
			}
Packit Service 2594b8
			/*
Packit Service 2594b8
			 * Sometimes we do not want to read the first directory (for example,
Packit Service 2594b8
			 * it may be broken) and want to proceed to other directories. I this
Packit Service 2594b8
			 * case we use the TIFF_HEADERONLY flag to open file and return
Packit Service 2594b8
			 * immediately after reading TIFF header.
Packit Service 2594b8
			 */
Packit Service 2594b8
			if (tif->tif_flags & TIFF_HEADERONLY)
Packit Service 2594b8
				return (tif);
Packit Service 2594b8
Packit Service 2594b8
			/*
Packit Service 2594b8
			 * Setup initial directory.
Packit Service 2594b8
			 */
Packit Service 2594b8
			if (TIFFReadDirectory(tif)) {
Packit Service 2594b8
				tif->tif_rawcc = (tmsize_t)-1;
Packit Service 2594b8
				tif->tif_flags |= TIFF_BUFFERSETUP;
Packit Service 2594b8
				return (tif);
Packit Service 2594b8
			}
Packit Service 2594b8
			break;
Packit Service 2594b8
		case 'a':
Packit Service 2594b8
			/*
Packit Service 2594b8
			 * New directories are automatically append
Packit Service 2594b8
			 * to the end of the directory chain when they
Packit Service 2594b8
			 * are written out (see TIFFWriteDirectory).
Packit Service 2594b8
			 */
Packit Service 2594b8
			if (!TIFFDefaultDirectory(tif))
Packit Service 2594b8
				goto bad;
Packit Service 2594b8
			return (tif);
Packit Service 2594b8
	}
Packit Service 2594b8
bad:
Packit Service 2594b8
	tif->tif_mode = O_RDONLY;	/* XXX avoid flush */
Packit Service 2594b8
        TIFFCleanup(tif);
Packit Service 2594b8
bad2:
Packit Service 2594b8
	return ((TIFF*)0);
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Query functions to access private data.
Packit Service 2594b8
 */
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Return open file's name.
Packit Service 2594b8
 */
Packit Service 2594b8
const char *
Packit Service 2594b8
TIFFFileName(TIFF* tif)
Packit Service 2594b8
{
Packit Service 2594b8
	return (tif->tif_name);
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Set the file name.
Packit Service 2594b8
 */
Packit Service 2594b8
const char *
Packit Service 2594b8
TIFFSetFileName(TIFF* tif, const char *name)
Packit Service 2594b8
{
Packit Service 2594b8
	const char* old_name = tif->tif_name;
Packit Service 2594b8
	tif->tif_name = (char *)name;
Packit Service 2594b8
	return (old_name);
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Return open file's I/O descriptor.
Packit Service 2594b8
 */
Packit Service 2594b8
int
Packit Service 2594b8
TIFFFileno(TIFF* tif)
Packit Service 2594b8
{
Packit Service 2594b8
	return (tif->tif_fd);
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Set open file's I/O descriptor, and return previous value.
Packit Service 2594b8
 */
Packit Service 2594b8
int
Packit Service 2594b8
TIFFSetFileno(TIFF* tif, int fd)
Packit Service 2594b8
{
Packit Service 2594b8
        int old_fd = tif->tif_fd;
Packit Service 2594b8
	tif->tif_fd = fd;
Packit Service 2594b8
	return old_fd;
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Return open file's clientdata.
Packit Service 2594b8
 */
Packit Service 2594b8
thandle_t
Packit Service 2594b8
TIFFClientdata(TIFF* tif)
Packit Service 2594b8
{
Packit Service 2594b8
	return (tif->tif_clientdata);
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Set open file's clientdata, and return previous value.
Packit Service 2594b8
 */
Packit Service 2594b8
thandle_t
Packit Service 2594b8
TIFFSetClientdata(TIFF* tif, thandle_t newvalue)
Packit Service 2594b8
{
Packit Service 2594b8
	thandle_t m = tif->tif_clientdata;
Packit Service 2594b8
	tif->tif_clientdata = newvalue;
Packit Service 2594b8
	return m;
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Return read/write mode.
Packit Service 2594b8
 */
Packit Service 2594b8
int
Packit Service 2594b8
TIFFGetMode(TIFF* tif)
Packit Service 2594b8
{
Packit Service 2594b8
	return (tif->tif_mode);
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Return read/write mode.
Packit Service 2594b8
 */
Packit Service 2594b8
int
Packit Service 2594b8
TIFFSetMode(TIFF* tif, int mode)
Packit Service 2594b8
{
Packit Service 2594b8
	int old_mode = tif->tif_mode;
Packit Service 2594b8
	tif->tif_mode = mode;
Packit Service 2594b8
	return (old_mode);
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Return nonzero if file is organized in
Packit Service 2594b8
 * tiles; zero if organized as strips.
Packit Service 2594b8
 */
Packit Service 2594b8
int
Packit Service 2594b8
TIFFIsTiled(TIFF* tif)
Packit Service 2594b8
{
Packit Service 2594b8
	return (isTiled(tif));
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Return current row being read/written.
Packit Service 2594b8
 */
Packit Service 2594b8
uint32
Packit Service 2594b8
TIFFCurrentRow(TIFF* tif)
Packit Service 2594b8
{
Packit Service 2594b8
	return (tif->tif_row);
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Return index of the current directory.
Packit Service 2594b8
 */
Packit Service 2594b8
uint16
Packit Service 2594b8
TIFFCurrentDirectory(TIFF* tif)
Packit Service 2594b8
{
Packit Service 2594b8
	return (tif->tif_curdir);
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Return current strip.
Packit Service 2594b8
 */
Packit Service 2594b8
uint32
Packit Service 2594b8
TIFFCurrentStrip(TIFF* tif)
Packit Service 2594b8
{
Packit Service 2594b8
	return (tif->tif_curstrip);
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Return current tile.
Packit Service 2594b8
 */
Packit Service 2594b8
uint32
Packit Service 2594b8
TIFFCurrentTile(TIFF* tif)
Packit Service 2594b8
{
Packit Service 2594b8
	return (tif->tif_curtile);
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Return nonzero if the file has byte-swapped data.
Packit Service 2594b8
 */
Packit Service 2594b8
int
Packit Service 2594b8
TIFFIsByteSwapped(TIFF* tif)
Packit Service 2594b8
{
Packit Service 2594b8
	return ((tif->tif_flags & TIFF_SWAB) != 0);
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Return nonzero if the data is returned up-sampled.
Packit Service 2594b8
 */
Packit Service 2594b8
int
Packit Service 2594b8
TIFFIsUpSampled(TIFF* tif)
Packit Service 2594b8
{
Packit Service 2594b8
	return (isUpSampled(tif));
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Return nonzero if the data is returned in MSB-to-LSB bit order.
Packit Service 2594b8
 */
Packit Service 2594b8
int
Packit Service 2594b8
TIFFIsMSB2LSB(TIFF* tif)
Packit Service 2594b8
{
Packit Service 2594b8
	return (isFillOrder(tif, FILLORDER_MSB2LSB));
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Return nonzero if given file was written in big-endian order.
Packit Service 2594b8
 */
Packit Service 2594b8
int
Packit Service 2594b8
TIFFIsBigEndian(TIFF* tif)
Packit Service 2594b8
{
Packit Service 2594b8
	return (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN);
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Return pointer to file read method.
Packit Service 2594b8
 */
Packit Service 2594b8
TIFFReadWriteProc
Packit Service 2594b8
TIFFGetReadProc(TIFF* tif)
Packit Service 2594b8
{
Packit Service 2594b8
	return (tif->tif_readproc);
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Return pointer to file write method.
Packit Service 2594b8
 */
Packit Service 2594b8
TIFFReadWriteProc
Packit Service 2594b8
TIFFGetWriteProc(TIFF* tif)
Packit Service 2594b8
{
Packit Service 2594b8
	return (tif->tif_writeproc);
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Return pointer to file seek method.
Packit Service 2594b8
 */
Packit Service 2594b8
TIFFSeekProc
Packit Service 2594b8
TIFFGetSeekProc(TIFF* tif)
Packit Service 2594b8
{
Packit Service 2594b8
	return (tif->tif_seekproc);
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Return pointer to file close method.
Packit Service 2594b8
 */
Packit Service 2594b8
TIFFCloseProc
Packit Service 2594b8
TIFFGetCloseProc(TIFF* tif)
Packit Service 2594b8
{
Packit Service 2594b8
	return (tif->tif_closeproc);
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Return pointer to file size requesting method.
Packit Service 2594b8
 */
Packit Service 2594b8
TIFFSizeProc
Packit Service 2594b8
TIFFGetSizeProc(TIFF* tif)
Packit Service 2594b8
{
Packit Service 2594b8
	return (tif->tif_sizeproc);
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Return pointer to memory mapping method.
Packit Service 2594b8
 */
Packit Service 2594b8
TIFFMapFileProc
Packit Service 2594b8
TIFFGetMapFileProc(TIFF* tif)
Packit Service 2594b8
{
Packit Service 2594b8
	return (tif->tif_mapproc);
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/*
Packit Service 2594b8
 * Return pointer to memory unmapping method.
Packit Service 2594b8
 */
Packit Service 2594b8
TIFFUnmapFileProc
Packit Service 2594b8
TIFFGetUnmapFileProc(TIFF* tif)
Packit Service 2594b8
{
Packit Service 2594b8
	return (tif->tif_unmapproc);
Packit Service 2594b8
}
Packit Service 2594b8
Packit Service 2594b8
/* vim: set ts=8 sts=8 sw=8 noet: */
Packit Service 2594b8
/*
Packit Service 2594b8
 * Local Variables:
Packit Service 2594b8
 * mode: c
Packit Service 2594b8
 * c-basic-offset: 8
Packit Service 2594b8
 * fill-column: 78
Packit Service 2594b8
 * End:
Packit Service 2594b8
 */