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.
41 long myStreamStartPos;
49 long myStreamStartPos;
53 _tiffosReadProc(thandle_t, tdata_t, tsize_t)
59 _tiffisReadProc(thandle_t fd, tdata_t buf, tsize_t size)
61 tiffis_data *data = (tiffis_data *)fd;
63 data->myIS->read((char *)buf, (int)size);
65 return data->myIS->gcount();
69 _tiffosWriteProc(thandle_t fd, tdata_t buf, tsize_t size)
71 tiffos_data *data = (tiffos_data *)fd;
72 ostream *os = data->myOS;
73 int pos = os->tellp();
75 os->write((const char *)buf, size);
77 return ((int)os->tellp()) - pos;
81 _tiffisWriteProc(thandle_t, tdata_t, tsize_t)
87 _tiffosSeekProc(thandle_t fd, toff_t off, int whence)
89 tiffos_data *data = (tiffos_data *)fd;
90 ostream *os = data->myOS;
92 // if the stream has already failed, don't do anything
98 os->seekp(data->myStreamStartPos + off, ios::beg);
101 os->seekp(off, ios::cur);
104 os->seekp(off, ios::end);
108 // Attempt to workaround problems with seeking past the end of the
109 // stream. ofstream doesn't have a problem with this but
110 // ostrstream/ostringstream does. In that situation, add intermediate
113 ios::iostate old_state;
116 old_state = os->rdstate();
117 // reset the fail bit or else tellp() won't work below
118 os->clear(os->rdstate() & ~ios::failbit);
121 origin = data->myStreamStartPos;
124 origin = os->tellp();
127 os->seekp(0, ios::end);
128 origin = os->tellp();
131 // restore original stream state
132 os->clear(old_state);
134 // only do something if desired seek position is valid
135 if( origin + off > data->myStreamStartPos ) {
138 // clear the fail bit
139 os->clear(os->rdstate() & ~ios::failbit);
141 // extend the stream to the expected size
142 os->seekp(0, ios::end);
143 num_fill = origin + off - (toff_t)os->tellp();
144 for( toff_t i = 0; i < num_fill; i++ )
148 os->seekp(origin + off, ios::beg);
156 _tiffisSeekProc(thandle_t fd, toff_t off, int whence)
158 tiffis_data *data = (tiffis_data *)fd;
162 data->myIS->seekg(data->myStreamStartPos + off, ios::beg);
165 data->myIS->seekg(off, ios::cur);
168 data->myIS->seekg(off, ios::end);
172 return ((long)data->myIS->tellg()) - data->myStreamStartPos;
176 _tiffosSizeProc(thandle_t fd)
178 tiffos_data *data = (tiffos_data *)fd;
179 ostream *os = data->myOS;
180 toff_t pos = os->tellp();
183 os->seekp(0, ios::end);
191 _tiffisSizeProc(thandle_t fd)
193 tiffis_data *data = (tiffis_data *)fd;
194 int pos = data->myIS->tellg();
197 data->myIS->seekg(0, ios::end);
198 len = data->myIS->tellg();
199 data->myIS->seekg(pos);
205 _tiffosCloseProc(thandle_t fd)
207 // Our stream was not allocated by us, so it shouldn't be closed by us.
208 delete (tiffos_data *)fd;
213 _tiffisCloseProc(thandle_t fd)
215 // Our stream was not allocated by us, so it shouldn't be closed by us.
216 delete (tiffis_data *)fd;
221 _tiffDummyMapProc(thandle_t , tdata_t* , toff_t* )
227 _tiffDummyUnmapProc(thandle_t , tdata_t , toff_t )
232 * Open a TIFF file descriptor for read/writing.
235 _tiffStreamOpen(const char* name, const char* mode, void *fd)
239 if( strchr(mode, 'w') ) {
240 tiffos_data *data = new tiffos_data;
241 data->myOS = (ostream *)fd;
242 data->myStreamStartPos = data->myOS->tellp();
245 tif = TIFFClientOpen(name, mode,
247 _tiffosReadProc, _tiffosWriteProc,
248 _tiffosSeekProc, _tiffosCloseProc,
250 _tiffDummyMapProc, _tiffDummyUnmapProc);
252 tiffis_data *data = new tiffis_data;
253 data->myIS = (istream *)fd;
254 data->myStreamStartPos = data->myIS->tellg();
256 tif = TIFFClientOpen(name, mode,
258 _tiffisReadProc, _tiffisWriteProc,
259 _tiffisSeekProc, _tiffisCloseProc,
261 _tiffDummyMapProc, _tiffDummyUnmapProc);
268 TIFFStreamOpen(const char* name, ostream *os)
270 // If os is either a ostrstream or ostringstream, and has no data
271 // written to it yet, then tellp() will return -1 which will break us.
272 // We workaround this by writing out a dummy character and
273 // then seek back to the beginning.
274 if( !os->fail() && (int)os->tellp() < 0 ) {
279 // NB: We don't support mapped files with streams so add 'm'
280 return _tiffStreamOpen(name, "wm", os);
284 TIFFStreamOpen(const char* name, istream *is)
286 // NB: We don't support mapped files with streams so add 'm'
287 return _tiffStreamOpen(name, "rm", is);
290 /* vim: set ts=8 sts=8 sw=8 noet: */