blob: bd321c1af840eb8a6cb52146a30d69f1cb9d05c4 [file] [log] [blame]
#ifndef lint
static char rcsid[] = "$Header: /cvs/bao-parsec/ext/splash2x/apps/volrend/src/libtiff/tif_open.c,v 1.1.1.1 2012/03/29 17:22:43 uid42307 Exp $";
#endif
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992 Sam Leffler
* Copyright (c) 1991, 1992 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
/*
* TIFF Library.
*/
#include "tiffioP.h"
#include "prototypes.h"
#if USE_PROTOTYPES
extern int TIFFDefaultDirectory(TIFF*);
#else
extern int TIFFDefaultDirectory();
#endif
static const long typemask[13] = {
0, /* TIFF_NOTYPE */
0x000000ff, /* TIFF_BYTE */
0xffffffff, /* TIFF_ASCII */
0x0000ffff, /* TIFF_SHORT */
0xffffffff, /* TIFF_LONG */
0xffffffff, /* TIFF_RATIONAL */
0x000000ff, /* TIFF_SBYTE */
0x000000ff, /* TIFF_UNDEFINED */
0x0000ffff, /* TIFF_SSHORT */
0xffffffff, /* TIFF_SLONG */
0xffffffff, /* TIFF_SRATIONAL */
0xffffffff, /* TIFF_FLOAT */
0xffffffff, /* TIFF_DOUBLE */
};
static const int bigTypeshift[13] = {
0, /* TIFF_NOTYPE */
24, /* TIFF_BYTE */
0, /* TIFF_ASCII */
16, /* TIFF_SHORT */
0, /* TIFF_LONG */
0, /* TIFF_RATIONAL */
16, /* TIFF_SBYTE */
16, /* TIFF_UNDEFINED */
24, /* TIFF_SSHORT */
0, /* TIFF_SLONG */
0, /* TIFF_SRATIONAL */
0, /* TIFF_FLOAT */
0, /* TIFF_DOUBLE */
};
static const int litTypeshift[13] = {
0, /* TIFF_NOTYPE */
0, /* TIFF_BYTE */
0, /* TIFF_ASCII */
0, /* TIFF_SHORT */
0, /* TIFF_LONG */
0, /* TIFF_RATIONAL */
0, /* TIFF_SBYTE */
0, /* TIFF_UNDEFINED */
0, /* TIFF_SSHORT */
0, /* TIFF_SLONG */
0, /* TIFF_SRATIONAL */
0, /* TIFF_FLOAT */
0, /* TIFF_DOUBLE */
};
/*
* Initialize the bit fill order, the
* shift & mask tables, and the byte
* swapping state according to the file
* contents and the machine architecture.
*/
static
DECLARE3(TIFFInitOrder, register TIFF*, tif, int, magic, int, bigendian)
{
/* XXX how can we deduce this dynamically? */
tif->tif_fillorder = FILLORDER_MSB2LSB;
tif->tif_typemask = typemask;
if (magic == TIFF_BIGENDIAN) {
tif->tif_typeshift = bigTypeshift;
if (!bigendian)
tif->tif_flags |= TIFF_SWAB;
} else {
tif->tif_typeshift = litTypeshift;
if (bigendian)
tif->tif_flags |= TIFF_SWAB;
}
}
static int
DECLARE2(getMode, char*, mode, char*, module)
{
int m = -1;
switch (mode[0]) {
case 'r':
m = O_RDONLY;
if (mode[1] == '+')
m = O_RDWR;
break;
case 'w':
case 'a':
m = O_RDWR|O_CREAT;
if (mode[0] == 'w')
m |= O_TRUNC;
break;
default:
TIFFError(module, "\"%s\": Bad mode", mode);
break;
}
return (m);
}
/*
* Open a TIFF file for read/writing.
*/
TIFF *
TIFFOpen(name, mode)
char *name, *mode;
{
static char module[] = "TIFFOpen";
int m, fd;
m = getMode(mode, module);
if (m == -1)
return ((TIFF *)0);
fd = TIFFOpenFile(name, m, 0666);
if (fd < 0) {
TIFFError(module, "%s: Cannot open", name);
return ((TIFF *)0);
}
return (TIFFFdOpen(fd, name, mode));
}
/*
* Open a TIFF file descriptor for read/writing.
*/
TIFF *
TIFFFdOpen(fd, name, mode)
int fd;
char *name, *mode;
{
static char module[] = "TIFFFdOpen";
TIFF *tif;
int m, bigendian;
m = getMode(mode, module);
if (m == -1)
goto bad2;
tif = (TIFF *)malloc(sizeof (TIFF) + strlen(name) + 1);
if (tif == NULL) {
TIFFError(module, "%s: Out of memory (TIFF structure)", name);
goto bad2;
}
bzero((char *)tif, sizeof (*tif));
tif->tif_name = (char *)tif + sizeof (TIFF);
strcpy(tif->tif_name, name);
tif->tif_fd = fd;
tif->tif_mode = m &~ (O_CREAT|O_TRUNC);
tif->tif_curdir = -1; /* non-existent directory */
tif->tif_curoff = 0;
tif->tif_curstrip = -1; /* invalid strip */
tif->tif_row = -1; /* read/write pre-increment */
{ int one = 1; bigendian = (*(char *)&one == 0); }
/*
* Read in TIFF header.
*/
if (!ReadOK(fd, &tif->tif_header, sizeof (TIFFHeader))) {
if (tif->tif_mode == O_RDONLY) {
TIFFError(name, "Cannot read TIFF header");
goto bad;
}
/*
* Setup header and write.
*/
tif->tif_header.tiff_magic = bigendian ?
TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
tif->tif_header.tiff_version = TIFF_VERSION;
tif->tif_header.tiff_diroff = 0; /* filled in later */
if (!WriteOK(fd, &tif->tif_header, sizeof (TIFFHeader))) {
TIFFError(name, "Error writing TIFF header");
goto bad;
}
/*
* Setup the byte order handling.
*/
TIFFInitOrder(tif, tif->tif_header.tiff_magic, bigendian);
/*
* Setup default directory.
*/
if (!TIFFDefaultDirectory(tif))
goto bad;
tif->tif_diroff = 0;
return (tif);
}
/*
* Setup the byte order handling.
*/
if (tif->tif_header.tiff_magic != TIFF_BIGENDIAN &&
tif->tif_header.tiff_magic != TIFF_LITTLEENDIAN) {
TIFFError(name, "Not a TIFF file, bad magic number %d (0x%x)",
tif->tif_header.tiff_magic,
tif->tif_header.tiff_magic);
goto bad;
}
TIFFInitOrder(tif, tif->tif_header.tiff_magic, bigendian);
/*
* Swap header if required.
*/
if (tif->tif_flags & TIFF_SWAB) {
TIFFSwabShort(&tif->tif_header.tiff_version);
TIFFSwabLong(&tif->tif_header.tiff_diroff);
}
/*
* Now check version (if needed, it's been byte-swapped).
* Note that this isn't actually a version number, it's a
* magic number that doesn't change (stupid).
*/
if (tif->tif_header.tiff_version != TIFF_VERSION) {
TIFFError(name,
"Not a TIFF file, bad version number %d (0x%x)",
tif->tif_header.tiff_version,
tif->tif_header.tiff_version);
goto bad;
}
tif->tif_flags |= TIFF_MYBUFFER;
tif->tif_rawcp = tif->tif_rawdata = 0;
tif->tif_rawdatasize = 0;
/*
* Setup initial directory.
*/
switch (mode[0]) {
case 'r':
tif->tif_nextdiroff = tif->tif_header.tiff_diroff;
#ifdef MMAP_SUPPORT
if (TIFFMapFileContents(fd, &tif->tif_base, &tif->tif_size))
tif->tif_flags |= TIFF_MAPPED;
#endif
if (TIFFReadDirectory(tif)) {
tif->tif_rawcc = -1;
tif->tif_flags |= TIFF_BUFFERSETUP;
return (tif);
}
break;
case 'a':
/*
* Don't append to file that has information
* byte swapped -- we will write data that is
* in the opposite order.
*/
if (tif->tif_flags & TIFF_SWAB) {
TIFFError(name,
"Cannot append to file that has opposite byte ordering");
goto bad;
}
/*
* New directories are automatically append
* to the end of the directory chain when they
* are written out (see TIFFWriteDirectory).
*/
if (!TIFFDefaultDirectory(tif))
goto bad;
return (tif);
}
bad:
tif->tif_mode = O_RDONLY; /* XXX avoid flush */
TIFFClose(tif);
return ((TIFF *)0);
bad2:
(void) close(fd);
return ((TIFF *)0);
}
TIFFScanlineSize(tif)
TIFF *tif;
{
TIFFDirectory *td = &tif->tif_dir;
long scanline;
scanline = td->td_bitspersample * td->td_imagewidth;
if (td->td_planarconfig == PLANARCONFIG_CONTIG)
scanline *= td->td_samplesperpixel;
return (howmany(scanline, 8));
}
/*
* Query functions to access private data.
*/
/*
* Return open file's name.
*/
char *
TIFFFileName(tif)
TIFF *tif;
{
return (tif->tif_name);
}
/*
* Return open file's I/O descriptor.
*/
int
TIFFFileno(tif)
TIFF *tif;
{
return (tif->tif_fd);
}
/*
* Return read/write mode.
*/
int
TIFFGetMode(tif)
TIFF *tif;
{
return (tif->tif_mode);
}
/*
* Return nonzero if file is organized in
* tiles; zero if organized as strips.
*/
int
TIFFIsTiled(tif)
TIFF *tif;
{
return (isTiled(tif));
}
/*
* Return current row being read/written.
*/
long
TIFFCurrentRow(tif)
TIFF *tif;
{
return (tif->tif_row);
}
/*
* Return index of the current directory.
*/
int
TIFFCurrentDirectory(tif)
TIFF *tif;
{
return (tif->tif_curdir);
}
/*
* Return current strip.
*/
int
TIFFCurrentStrip(tif)
TIFF *tif;
{
return (tif->tif_curstrip);
}
/*
* Return current tile.
*/
int
TIFFCurrentTile(tif)
TIFF *tif;
{
return (tif->tif_curtile);
}