home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 1
/
crawlyvol1.bin
/
program
/
grfx_snd
/
tifflib
/
source
/
tif_open.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-13
|
8KB
|
260 lines
#pragma warn -use
static char *sccsid = "@(#)TIFF/tif_open.c 1.19, Copyright (c) Sam Leffler, Dieter Linde, "__DATE__;
#pragma warn .use
/*
* Copyright (c) 1988, 1990 by Sam Leffler, Nov 15 1990
* All rights reserved.
*
* This file is provided for unrestricted use provided that this legend is included on all tape media and as a part of the
* software program in whole or part. Users may copy, modify or distribute this file at will.
*
* TIFF Library.
*/
#include <stdlib.h>
#include "tiffio.h"
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#define ord(e) ((int)e)
/****************************************************************************
* Initialize the bit fill order, the shift & mask tables, and the byte
* swapping state according to the file contents and the machine architecture.
*/
static void
TIFFInitOrder(
register TIFF *tif,
int magic,
int bigendian
)
{
/*** XXX how can we deduce this dynamically? ***/
tif->tif_fillorder = FILLORDER_MSB2LSB;
tif->tif_typemask[0] = 0;
tif->tif_typemask[ord(TIFF_BYTE)] = 0xff;
tif->tif_typemask[ord(TIFF_SHORT)] = 0xffff;
tif->tif_typemask[ord(TIFF_LONG)] = 0xffffffffL;
tif->tif_typemask[ord(TIFF_RATIONAL)] = 0xffffffffL;
tif->tif_typeshift[0] = 0;
tif->tif_typeshift[ord(TIFF_LONG)] = 0;
tif->tif_typeshift[ord(TIFF_RATIONAL)] = 0;
if (magic == TIFF_BIGENDIAN) {
tif->tif_typeshift[ord(TIFF_BYTE)] = 24;
tif->tif_typeshift[ord(TIFF_SHORT)] = 16;
if (!bigendian)
tif->tif_flags |= TIFF_SWAB;
}
else {
tif->tif_typeshift[ord(TIFF_BYTE)] = 0;
tif->tif_typeshift[ord(TIFF_SHORT)] = 0;
if (bigendian)
tif->tif_flags |= TIFF_SWAB;
}
}
/****************************************************************************
*
*/
static int
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, "bad mode '%s'", mode);
break;
}
return(m);
}
/****************************************************************************
* Open a TIFF file descriptor for read/writing.
*/
TIFF *
TIFFFdOpen(
int fd,
char *name,
char *mode
)
{
static char *module = "TIFFFdOpen";
TIFF *tif;
int m, bigendian;
if ((m = getMode(mode, module)) == -1)
goto bad2;
if ((tif = (TIFF *)malloc(sizeof(TIFF) + strlen(name) + 1)) == NULL) {
TIFFError(module, "out of memory allocating TIFF structure");
goto bad2;
}
bzero(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_curoff = 0;
tif->tif_curstrip = -1; /* invalid strip */
tif->tif_row = -1; /* read/write pre-increment */
bigendian = TRUE;
/*
* Read in TIFF header.
*/
if (!ReadOK(fd, &tif->tif_header, sizeof(TIFFHeader))) {
if (tif->tif_mode == O_RDONLY) {
TIFFError(module, "can't 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(module, "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(module, "\"%s\" isn't a TIFF file, bad magic number 0x%04x", name, 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(module, "\"%s\" isn't a TIFF file, bad version number 0x%04x", name, tif->tif_header.tiff_version);
goto bad;
}
/*
* Setup initial directory.
*/
switch (mode[0]) {
case 'r':
tif->tif_nextdiroff = tif->tif_header.tiff_diroff;
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(module, "can't append to a 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(NULL);
bad2:
close(fd);
return(NULL);
}
/****************************************************************************
* Open a TIFF file for read/writing.
*/
TIFF *
TIFFOpen(
char *name,
char *mode
)
{
static char *module = "TIFFOpen";
int m, fd;
m = getMode(mode, module);
if (m == -1)
return(NULL);
if ((fd = TIFFOpenFile(name, m, 0666)) < 0) {
TIFFError(module, "can't open file \"%s\"", name);
return(NULL);
}
return(TIFFFdOpen(fd, name, mode));
}
/****************************************************************************
*
*/
int
TIFFScanlineSize(
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;
#define howmany(x, y) (((x) + ((y) - 1)) / (y))
return((int)howmany(scanline, 8));
}