Blame libtiff/tif_open.c

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