This is tif_open.c in view mode; [Download] [Up]
#ifndef lint static char rcsid[] = "/mode/users/src/master/tiff/libtiff/tif_open.c,v 1.3 1994/06/29 17:20:49 fedor 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); } #ifdef HAVE_STREAMS_STREAMS_H static int DECLARE2(getStreamMode, char*, mode, char*, module) { int m = -1; switch (mode[0]) { case 'r': m = TF_READONLY; if (mode[1] == '+') m = TF_READWRITE; break; case 'w': m = TF_READWRITE; break; case 'a': /* TIFFOpen will take care or seeking to the end of file */ m = TF_READWRITE; break; default: TIFFError(module, "\"%s\": Bad mode", mode); break; } return (m); } #endif /* * Open a TIFF file for read/writing. */ TIFF * TIFFOpen(name, mode) char *name, *mode; { static char module[] = "TIFFOpen"; int m, fd; #ifdef HAVE_STREAMS_STREAMS_H m = getStreamMode(mode, module); #else m = getMode(mode, module); #endif if (m == -1) return ((TIFF *)0); #ifdef STREAM_SUPPORT #ifdef HAVE_STREAMS_STREAMS_H fd = (int) TFMapFile(name, m); #else fd = (int) TFMapFile(name, mode); #endif /* If the file doesn't exist, open from memory */ if (fd == 0 && m != TF_READONLY) { fd = (int) TFOpenMemory(NULL, 0, m); } /* There is no TF_APPEND, but we account for it anyway */ if (fd != 0 && mode[0] == 'a') TFSeek((TFStream *)fd, 0, TF_FROMEND); if (fd == 0) { TIFFError(module, "%s: Cannot open", name); return ((TIFF *)0); } #else fd = TIFFOpenFile(name, m, 0666); if (fd < 0) { TIFFError(module, "%s: Cannot open", name); return ((TIFF *)0); } #endif 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; int mystream; #ifdef STREAM_SUPPORT /* If name is NULL, then we do not own the stream and should not close it, but we still need a name, so that other routines can use it (namely the rest of this one). */ mystream = 0; if (name) mystream = TIFF_MYSTREAM; else name = "Tiff Stream"; #endif 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; #ifdef STREAM_SUPPORT tif->tif_flags = mystream; #endif 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); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.