tif_stream.cxx
上传用户:looem2003
上传日期:2014-07-20
资源大小:13733k
文件大小:7k
- /* $Id: tif_stream.cxx,v 1.5 2005/07/26 08:11:13 dron Exp $ */
- /*
- * Copyright (c) 1988-1996 Sam Leffler
- * Copyright (c) 1991-1996 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 UNIX-specific Routines.
- */
- #include "tiffiop.h"
- #include <iostream>
- using namespace std;
- class tiffis_data
- {
- public:
- istream *myIS;
- long myStreamStartPos;
- };
- class tiffos_data
- {
- public:
- ostream *myOS;
- long myStreamStartPos;
- };
- static tsize_t
- _tiffosReadProc(thandle_t, tdata_t, tsize_t)
- {
- return 0;
- }
- static tsize_t
- _tiffisReadProc(thandle_t fd, tdata_t buf, tsize_t size)
- {
- tiffis_data *data = (tiffis_data *)fd;
- data->myIS->read((char *)buf, (int)size);
- return data->myIS->gcount();
- }
- static tsize_t
- _tiffosWriteProc(thandle_t fd, tdata_t buf, tsize_t size)
- {
- tiffos_data *data = (tiffos_data *)fd;
- ostream *os = data->myOS;
- int pos = os->tellp();
- os->write((const char *)buf, size);
- return ((int)os->tellp()) - pos;
- }
- static tsize_t
- _tiffisWriteProc(thandle_t, tdata_t, tsize_t)
- {
- return 0;
- }
- static toff_t
- _tiffosSeekProc(thandle_t fd, toff_t off, int whence)
- {
- tiffos_data *data = (tiffos_data *)fd;
- ostream *os = data->myOS;
- // if the stream has already failed, don't do anything
- if( os->fail() )
- return os->tellp();
- switch(whence) {
- case SEEK_SET:
- os->seekp(data->myStreamStartPos + off, ios::beg);
- break;
- case SEEK_CUR:
- os->seekp(off, ios::cur);
- break;
- case SEEK_END:
- os->seekp(off, ios::end);
- break;
- }
- // Attempt to workaround problems with seeking past the end of the
- // stream. ofstream doesn't have a problem with this but
- // ostrstream/ostringstream does. In that situation, add intermediate
- // ' ' characters.
- if( os->fail() ) {
- ios::iostate old_state;
- toff_t origin;
- old_state = os->rdstate();
- // reset the fail bit or else tellp() won't work below
- os->clear(os->rdstate() & ~ios::failbit);
- switch( whence ) {
- case SEEK_SET:
- origin = data->myStreamStartPos;
- break;
- case SEEK_CUR:
- origin = os->tellp();
- break;
- case SEEK_END:
- os->seekp(0, ios::end);
- origin = os->tellp();
- break;
- }
- // restore original stream state
- os->clear(old_state);
- // only do something if desired seek position is valid
- if( origin + off > data->myStreamStartPos ) {
- toff_t num_fill;
- // clear the fail bit
- os->clear(os->rdstate() & ~ios::failbit);
- // extend the stream to the expected size
- os->seekp(0, ios::end);
- num_fill = origin + off - (toff_t)os->tellp();
- for( toff_t i = 0; i < num_fill; i++ )
- os->put(' ');
- // retry the seek
- os->seekp(origin + off, ios::beg);
- }
- }
- return os->tellp();
- }
- static toff_t
- _tiffisSeekProc(thandle_t fd, toff_t off, int whence)
- {
- tiffis_data *data = (tiffis_data *)fd;
- switch(whence) {
- case SEEK_SET:
- data->myIS->seekg(data->myStreamStartPos + off, ios::beg);
- break;
- case SEEK_CUR:
- data->myIS->seekg(off, ios::cur);
- break;
- case SEEK_END:
- data->myIS->seekg(off, ios::end);
- break;
- }
- return ((long)data->myIS->tellg()) - data->myStreamStartPos;
- }
- static toff_t
- _tiffosSizeProc(thandle_t fd)
- {
- tiffos_data *data = (tiffos_data *)fd;
- ostream *os = data->myOS;
- toff_t pos = os->tellp();
- toff_t len;
- os->seekp(0, ios::end);
- len = os->tellp();
- os->seekp(pos);
- return len;
- }
- static toff_t
- _tiffisSizeProc(thandle_t fd)
- {
- tiffis_data *data = (tiffis_data *)fd;
- int pos = data->myIS->tellg();
- int len;
- data->myIS->seekg(0, ios::end);
- len = data->myIS->tellg();
- data->myIS->seekg(pos);
- return len;
- }
- static int
- _tiffosCloseProc(thandle_t fd)
- {
- // Our stream was not allocated by us, so it shouldn't be closed by us.
- delete (tiffos_data *)fd;
- return 0;
- }
- static int
- _tiffisCloseProc(thandle_t fd)
- {
- // Our stream was not allocated by us, so it shouldn't be closed by us.
- delete (tiffis_data *)fd;
- return 0;
- }
- static int
- _tiffDummyMapProc(thandle_t , tdata_t* , toff_t* )
- {
- return (0);
- }
- static void
- _tiffDummyUnmapProc(thandle_t , tdata_t , toff_t )
- {
- }
- /*
- * Open a TIFF file descriptor for read/writing.
- */
- static TIFF*
- _tiffStreamOpen(const char* name, const char* mode, void *fd)
- {
- TIFF* tif;
- if( strchr(mode, 'w') ) {
- tiffos_data *data = new tiffos_data;
- data->myOS = (ostream *)fd;
- data->myStreamStartPos = data->myOS->tellp();
- // Open for writing.
- tif = TIFFClientOpen(name, mode,
- (thandle_t) data,
- _tiffosReadProc, _tiffosWriteProc,
- _tiffosSeekProc, _tiffosCloseProc,
- _tiffosSizeProc,
- _tiffDummyMapProc, _tiffDummyUnmapProc);
- } else {
- tiffis_data *data = new tiffis_data;
- data->myIS = (istream *)fd;
- data->myStreamStartPos = data->myIS->tellg();
- // Open for reading.
- tif = TIFFClientOpen(name, mode,
- (thandle_t) data,
- _tiffisReadProc, _tiffisWriteProc,
- _tiffisSeekProc, _tiffisCloseProc,
- _tiffisSizeProc,
- _tiffDummyMapProc, _tiffDummyUnmapProc);
- }
- return (tif);
- }
- TIFF*
- TIFFStreamOpen(const char* name, ostream *os)
- {
- // If os is either a ostrstream or ostringstream, and has no data
- // written to it yet, then tellp() will return -1 which will break us.
- // We workaround this by writing out a dummy character and
- // then seek back to the beginning.
- if( !os->fail() && (int)os->tellp() < 0 ) {
- *os << ' ';
- os->seekp(0);
- }
- // NB: We don't support mapped files with streams so add 'm'
- return _tiffStreamOpen(name, "wm", os);
- }
- TIFF*
- TIFFStreamOpen(const char* name, istream *is)
- {
- // NB: We don't support mapped files with streams so add 'm'
- return _tiffStreamOpen(name, "rm", is);
- }
- /* vim: set ts=8 sts=8 sw=8 noet: */