1 /* $Id: tif_stream.cxx,v 1.1 2005/06/17 13:54:52 vp153 Exp $ */
4 * Copyright (c) 1988-1996 Sam Leffler
5 * Copyright (c) 1991-1996 Silicon Graphics, Inc.
7 * Permission to use, copy, modify, distribute, and sell this software and
8 * its documentation for any purpose is hereby granted without fee, provided
9 * that (i) the above copyright notices and this permission notice appear in
10 * all copies of the software and related documentation, and (ii) the names of
11 * Sam Leffler and Silicon Graphics may not be used in any advertising or
12 * publicity relating to the software without the specific, prior written
13 * permission of Sam Leffler and Silicon Graphics.
15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
28 * TIFF Library UNIX-specific Routines.
40 long myStreamStartPos;
48 long myStreamStartPos;
52 _tiffosReadProc(thandle_t, tdata_t, tsize_t)
58 _tiffisReadProc(thandle_t fd, tdata_t buf, tsize_t size)
60 tiffis_data *data = (tiffis_data *)fd;
62 data->myIS->read((char *)buf, (int)size);
64 return data->myIS->gcount();
68 _tiffosWriteProc(thandle_t fd, tdata_t buf, tsize_t size)
70 tiffos_data *data = (tiffos_data *)fd;
71 ostream *os = data->myOS;
72 int pos = os->tellp();
74 os->write((const char *)buf, size);
76 return ((int)os->tellp()) - pos;
80 _tiffisWriteProc(thandle_t, tdata_t, tsize_t)
86 _tiffosSeekProc(thandle_t fd, toff_t off, int whence)
88 tiffos_data *data = (tiffos_data *)fd;
89 ostream *os = data->myOS;
91 // if the stream has already failed, don't do anything
97 os->seekp(data->myStreamStartPos + off, ios::beg);
100 os->seekp(off, ios::cur);
103 os->seekp(off, ios::end);
107 // Attempt to workaround problems with seeking past the end of the
108 // stream. ofstream doesn't have a problem with this but
109 // ostrstream/ostringstream does. In that situation, add intermediate
112 ios::iostate old_state;
115 old_state = os->rdstate();
116 // reset the fail bit or else tellp() won't work below
117 os->clear(os->rdstate() & ~ios::failbit);
120 origin = data->myStreamStartPos;
123 origin = os->tellp();
126 os->seekp(0, ios::end);
127 origin = os->tellp();
130 // restore original stream state
131 os->clear(old_state);
133 // only do something if desired seek position is valid
134 if( origin + off > data->myStreamStartPos ) {
137 // clear the fail bit
138 os->clear(os->rdstate() & ~ios::failbit);
140 // extend the stream to the expected size
141 os->seekp(0, ios::end);
142 num_fill = origin + off - (toff_t)os->tellp();
143 for( toff_t i = 0; i < num_fill; i++ )
147 os->seekp(origin + off, ios::beg);
155 _tiffisSeekProc(thandle_t fd, toff_t off, int whence)
157 tiffis_data *data = (tiffis_data *)fd;
161 data->myIS->seekg(data->myStreamStartPos + off, ios::beg);
164 data->myIS->seekg(off, ios::cur);
167 data->myIS->seekg(off, ios::end);
171 return ((long)data->myIS->tellg()) - data->myStreamStartPos;
175 _tiffosSizeProc(thandle_t fd)
177 tiffos_data *data = (tiffos_data *)fd;
178 ostream *os = data->myOS;
179 toff_t pos = os->tellp();
182 os->seekp(0, ios::end);
190 _tiffisSizeProc(thandle_t fd)
192 tiffis_data *data = (tiffis_data *)fd;
193 int pos = data->myIS->tellg();
196 data->myIS->seekg(0, ios::end);
197 len = data->myIS->tellg();
198 data->myIS->seekg(pos);
204 _tiffosCloseProc(thandle_t fd)
206 // Our stream was not allocated by us, so it shouldn't be closed by us.
207 delete (tiffos_data *)fd;
212 _tiffisCloseProc(thandle_t fd)
214 // Our stream was not allocated by us, so it shouldn't be closed by us.
215 delete (tiffis_data *)fd;
220 _tiffDummyMapProc(thandle_t , tdata_t* , toff_t* )
226 _tiffDummyUnmapProc(thandle_t , tdata_t , toff_t )
231 * Open a TIFF file descriptor for read/writing.
234 _tiffStreamOpen(const char* name, const char* mode, void *fd)
238 if( strchr(mode, 'w') ) {
239 tiffos_data *data = new tiffos_data;
240 data->myOS = (ostream *)fd;
241 data->myStreamStartPos = data->myOS->tellp();
244 tif = TIFFClientOpen(name, mode,
246 _tiffosReadProc, _tiffosWriteProc,
247 _tiffosSeekProc, _tiffosCloseProc,
249 _tiffDummyMapProc, _tiffDummyUnmapProc);
251 tiffis_data *data = new tiffis_data;
252 data->myIS = (istream *)fd;
253 data->myStreamStartPos = data->myIS->tellg();
255 tif = TIFFClientOpen(name, mode,
257 _tiffisReadProc, _tiffisWriteProc,
258 _tiffisSeekProc, _tiffisCloseProc,
260 _tiffDummyMapProc, _tiffDummyUnmapProc);
267 TIFFStreamOpen(const char* name, ostream *os)
269 // If os is either a ostrstream or ostringstream, and has no data
270 // written to it yet, then tellp() will return -1 which will break us.
271 // We workaround this by writing out a dummy character and
272 // then seek back to the beginning.
273 if( !os->fail() && (int)os->tellp() < 0 ) {
278 // NB: We don't support mapped files with streams so add 'm'
279 return _tiffStreamOpen(name, "wm", os);
283 TIFFStreamOpen(const char* name, istream *is)
285 // NB: We don't support mapped files with streams so add 'm'
286 return _tiffStreamOpen(name, "rm", is);
289 /* vim: set ts=8 sts=8 sw=8 noet: */