diff options
author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2014-09-01 13:56:46 +0200 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2014-09-01 13:56:46 +0200 |
commit | 22f703cab05b7cd368f4de9e03991b7664dc5022 (patch) | |
tree | 6f4d50beaa42328e24b1c6b56b6ec059e4ef21a5 /tiff/libtiff/tif_stream.cxx |
Initial import of argyll version 1.5.1-8debian/1.5.1-8
Diffstat (limited to 'tiff/libtiff/tif_stream.cxx')
-rw-r--r-- | tiff/libtiff/tif_stream.cxx | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/tiff/libtiff/tif_stream.cxx b/tiff/libtiff/tif_stream.cxx new file mode 100644 index 0000000..2a2351b --- /dev/null +++ b/tiff/libtiff/tif_stream.cxx @@ -0,0 +1,295 @@ +/* $Id: tif_stream.cxx,v 1.6.2.1 2009-01-01 00:10:43 bfriesen 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> + +#ifndef __VMS +using namespace std; +#endif + +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 + // '\0' characters. + if( os->fail() ) { +#ifdef __VMS + int old_state; +#else + ios::iostate old_state; +#endif + toff_t origin=0; + + 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('\0'); + + // 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 << '\0'; + 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: */ |