Blame libtiff/tif_open.c

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