1 /* $Id: tif_stream.cxx,v 1.6.2.1 2009-01-01 00:10:43 bfriesen 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.
42 long myStreamStartPos;
50 long myStreamStartPos;
54 _tiffosReadProc(thandle_t, tdata_t, tsize_t)
60 _tiffisReadProc(thandle_t fd, tdata_t buf, tsize_t size)
62 tiffis_data *data = (tiffis_data *)fd;
64 data->myIS->read((char *)buf, (int)size);
66 return data->myIS->gcount();
70 _tiffosWriteProc(thandle_t fd, tdata_t buf, tsize_t size)
72 tiffos_data *data = (tiffos_data *)fd;
73 ostream *os = data->myOS;
74 int pos = os->tellp();
76 os->write((const char *)buf, size);
78 return ((int)os->tellp()) - pos;
82 _tiffisWriteProc(thandle_t, tdata_t, tsize_t)
88 _tiffosSeekProc(thandle_t fd, toff_t off, int whence)
90 tiffos_data *data = (tiffos_data *)fd;
91 ostream *os = data->myOS;
93 // if the stream has already failed, don't do anything
99 os->seekp(data->myStreamStartPos + off, ios::beg);
102 os->seekp(off, ios::cur);
105 os->seekp(off, ios::end);
109 // Attempt to workaround problems with seeking past the end of the
110 // stream. ofstream doesn't have a problem with this but
111 // ostrstream/ostringstream does. In that situation, add intermediate
117 ios::iostate old_state;
121 old_state = os->rdstate();
122 // reset the fail bit or else tellp() won't work below
123 os->clear(os->rdstate() & ~ios::failbit);
126 origin = data->myStreamStartPos;
129 origin = os->tellp();
132 os->seekp(0, ios::end);
133 origin = os->tellp();
136 // restore original stream state
137 os->clear(old_state);
139 // only do something if desired seek position is valid
140 if( origin + off > data->myStreamStartPos ) {
143 // clear the fail bit
144 os->clear(os->rdstate() & ~ios::failbit);
146 // extend the stream to the expected size
147 os->seekp(0, ios::end);
148 num_fill = origin + off - (toff_t)os->tellp();
149 for( toff_t i = 0; i < num_fill; i++ )
153 os->seekp(origin + off, ios::beg);
161 _tiffisSeekProc(thandle_t fd, toff_t off, int whence)
163 tiffis_data *data = (tiffis_data *)fd;
167 data->myIS->seekg(data->myStreamStartPos + off, ios::beg);
170 data->myIS->seekg(off, ios::cur);
173 data->myIS->seekg(off, ios::end);
177 return ((long)data->myIS->tellg()) - data->myStreamStartPos;
181 _tiffosSizeProc(thandle_t fd)
183 tiffos_data *data = (tiffos_data *)fd;
184 ostream *os = data->myOS;
185 toff_t pos = os->tellp();
188 os->seekp(0, ios::end);
196 _tiffisSizeProc(thandle_t fd)
198 tiffis_data *data = (tiffis_data *)fd;
199 int pos = data->myIS->tellg();
202 data->myIS->seekg(0, ios::end);
203 len = data->myIS->tellg();
204 data->myIS->seekg(pos);
210 _tiffosCloseProc(thandle_t fd)
212 // Our stream was not allocated by us, so it shouldn't be closed by us.
213 delete (tiffos_data *)fd;
218 _tiffisCloseProc(thandle_t fd)
220 // Our stream was not allocated by us, so it shouldn't be closed by us.
221 delete (tiffis_data *)fd;
226 _tiffDummyMapProc(thandle_t , tdata_t* , toff_t* )
232 _tiffDummyUnmapProc(thandle_t , tdata_t , toff_t )
237 * Open a TIFF file descriptor for read/writing.
240 _tiffStreamOpen(const char* name, const char* mode, void *fd)
244 if( strchr(mode, 'w') ) {
245 tiffos_data *data = new tiffos_data;
246 data->myOS = (ostream *)fd;
247 data->myStreamStartPos = data->myOS->tellp();
250 tif = TIFFClientOpen(name, mode,
252 _tiffosReadProc, _tiffosWriteProc,
253 _tiffosSeekProc, _tiffosCloseProc,
255 _tiffDummyMapProc, _tiffDummyUnmapProc);
257 tiffis_data *data = new tiffis_data;
258 data->myIS = (istream *)fd;
259 data->myStreamStartPos = data->myIS->tellg();
261 tif = TIFFClientOpen(name, mode,
263 _tiffisReadProc, _tiffisWriteProc,
264 _tiffisSeekProc, _tiffisCloseProc,
266 _tiffDummyMapProc, _tiffDummyUnmapProc);
273 TIFFStreamOpen(const char* name, ostream *os)
275 // If os is either a ostrstream or ostringstream, and has no data
276 // written to it yet, then tellp() will return -1 which will break us.
277 // We workaround this by writing out a dummy character and
278 // then seek back to the beginning.
279 if( !os->fail() && (int)os->tellp() < 0 ) {
284 // NB: We don't support mapped files with streams so add 'm'
285 return _tiffStreamOpen(name, "wm", os);
289 TIFFStreamOpen(const char* name, istream *is)
291 // NB: We don't support mapped files with streams so add 'm'
292 return _tiffStreamOpen(name, "rm", is);
295 /* vim: set ts=8 sts=8 sw=8 noet: */