xref: /reactos/dll/3rdparty/libtiff/tif_stream.cxx (revision 743951ec)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * Copyright (c) 1988-1996 Sam Leffler
3c2c66affSColin Finck  * Copyright (c) 1991-1996 Silicon Graphics, Inc.
4c2c66affSColin Finck  *
5c2c66affSColin Finck  * Permission to use, copy, modify, distribute, and sell this software and
6c2c66affSColin Finck  * its documentation for any purpose is hereby granted without fee, provided
7c2c66affSColin Finck  * that (i) the above copyright notices and this permission notice appear in
8c2c66affSColin Finck  * all copies of the software and related documentation, and (ii) the names of
9c2c66affSColin Finck  * Sam Leffler and Silicon Graphics may not be used in any advertising or
10c2c66affSColin Finck  * publicity relating to the software without the specific, prior written
11c2c66affSColin Finck  * permission of Sam Leffler and Silicon Graphics.
12c2c66affSColin Finck  *
13c2c66affSColin Finck  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14c2c66affSColin Finck  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15c2c66affSColin Finck  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16c2c66affSColin Finck  *
17c2c66affSColin Finck  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18c2c66affSColin Finck  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19c2c66affSColin Finck  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20c2c66affSColin Finck  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21c2c66affSColin Finck  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22c2c66affSColin Finck  * OF THIS SOFTWARE.
23c2c66affSColin Finck  */
24c2c66affSColin Finck 
25c2c66affSColin Finck /*
26c2c66affSColin Finck  * TIFF Library UNIX-specific Routines.
27c2c66affSColin Finck  */
28c2c66affSColin Finck #include "tiffiop.h"
29c2c66affSColin Finck #include <iostream>
30c2c66affSColin Finck 
31c2c66affSColin Finck #ifndef __VMS
32c2c66affSColin Finck using namespace std;
33c2c66affSColin Finck #endif
34c2c66affSColin Finck 
35c2c66affSColin Finck /*
36c2c66affSColin Finck   ISO C++ uses a 'std::streamsize' type to define counts.  This makes
37c2c66affSColin Finck   it similar to, (but perhaps not the same as) size_t.
38c2c66affSColin Finck 
39c2c66affSColin Finck   The std::ios::pos_type is used to represent stream positions as used
40c2c66affSColin Finck   by tellg(), tellp(), seekg(), and seekp().  This makes it similar to
41c2c66affSColin Finck   (but perhaps not the same as) 'off_t'.  The std::ios::streampos type
42c2c66affSColin Finck   is used for character streams, but is documented to not be an
43c2c66affSColin Finck   integral type anymore, so it should *not* be assigned to an integral
44c2c66affSColin Finck   type.
45c2c66affSColin Finck 
46c2c66affSColin Finck   The std::ios::off_type is used to specify relative offsets needed by
47c2c66affSColin Finck   the variants of seekg() and seekp() which accept a relative offset
48c2c66affSColin Finck   argument.
49c2c66affSColin Finck 
50c2c66affSColin Finck   Useful prototype knowledge:
51c2c66affSColin Finck 
52c2c66affSColin Finck   Obtain read position
53c2c66affSColin Finck     ios::pos_type basic_istream::tellg()
54c2c66affSColin Finck 
55c2c66affSColin Finck   Set read position
56c2c66affSColin Finck     basic_istream& basic_istream::seekg(ios::pos_type)
57c2c66affSColin Finck     basic_istream& basic_istream::seekg(ios::off_type, ios_base::seekdir)
58c2c66affSColin Finck 
59c2c66affSColin Finck   Read data
60c2c66affSColin Finck     basic_istream& istream::read(char *str, streamsize count)
61c2c66affSColin Finck 
62c2c66affSColin Finck   Number of characters read in last unformatted read
63c2c66affSColin Finck     streamsize istream::gcount();
64c2c66affSColin Finck 
65c2c66affSColin Finck   Obtain write position
66c2c66affSColin Finck     ios::pos_type basic_ostream::tellp()
67c2c66affSColin Finck 
68c2c66affSColin Finck   Set write position
69c2c66affSColin Finck     basic_ostream& basic_ostream::seekp(ios::pos_type)
70c2c66affSColin Finck     basic_ostream& basic_ostream::seekp(ios::off_type, ios_base::seekdir)
71c2c66affSColin Finck 
72c2c66affSColin Finck   Write data
73c2c66affSColin Finck     basic_ostream& ostream::write(const char *str, streamsize count)
74c2c66affSColin Finck */
75c2c66affSColin Finck 
76c2c66affSColin Finck struct tiffis_data;
77c2c66affSColin Finck struct tiffos_data;
78c2c66affSColin Finck 
79c2c66affSColin Finck extern "C" {
80c2c66affSColin Finck 
81c2c66affSColin Finck 	static tmsize_t _tiffosReadProc(thandle_t, void*, tmsize_t);
82c2c66affSColin Finck 	static tmsize_t _tiffisReadProc(thandle_t fd, void* buf, tmsize_t size);
83c2c66affSColin Finck 	static tmsize_t _tiffosWriteProc(thandle_t fd, void* buf, tmsize_t size);
84c2c66affSColin Finck 	static tmsize_t _tiffisWriteProc(thandle_t, void*, tmsize_t);
85c2c66affSColin Finck 	static uint64   _tiffosSeekProc(thandle_t fd, uint64 off, int whence);
86c2c66affSColin Finck 	static uint64   _tiffisSeekProc(thandle_t fd, uint64 off, int whence);
87c2c66affSColin Finck 	static uint64   _tiffosSizeProc(thandle_t fd);
88c2c66affSColin Finck 	static uint64   _tiffisSizeProc(thandle_t fd);
89c2c66affSColin Finck 	static int      _tiffosCloseProc(thandle_t fd);
90c2c66affSColin Finck 	static int      _tiffisCloseProc(thandle_t fd);
91c2c66affSColin Finck 	static int 	_tiffDummyMapProc(thandle_t , void** base, toff_t* size );
92c2c66affSColin Finck 	static void     _tiffDummyUnmapProc(thandle_t , void* base, toff_t size );
93c2c66affSColin Finck 	static TIFF*    _tiffStreamOpen(const char* name, const char* mode, void *fd);
94c2c66affSColin Finck 
95c2c66affSColin Finck struct tiffis_data
96c2c66affSColin Finck {
97c2c66affSColin Finck 	istream	*stream;
98c2c66affSColin Finck         ios::pos_type start_pos;
99c2c66affSColin Finck };
100c2c66affSColin Finck 
101c2c66affSColin Finck struct tiffos_data
102c2c66affSColin Finck {
103c2c66affSColin Finck 	ostream	*stream;
104c2c66affSColin Finck 	ios::pos_type start_pos;
105c2c66affSColin Finck };
106c2c66affSColin Finck 
107c2c66affSColin Finck static tmsize_t
_tiffosReadProc(thandle_t,void *,tmsize_t)108c2c66affSColin Finck _tiffosReadProc(thandle_t, void*, tmsize_t)
109c2c66affSColin Finck {
110c2c66affSColin Finck         return 0;
111c2c66affSColin Finck }
112c2c66affSColin Finck 
113c2c66affSColin Finck static tmsize_t
_tiffisReadProc(thandle_t fd,void * buf,tmsize_t size)114c2c66affSColin Finck _tiffisReadProc(thandle_t fd, void* buf, tmsize_t size)
115c2c66affSColin Finck {
116c2c66affSColin Finck         tiffis_data	*data = reinterpret_cast<tiffis_data *>(fd);
117c2c66affSColin Finck 
118c2c66affSColin Finck         // Verify that type does not overflow.
119c2c66affSColin Finck         streamsize request_size = size;
120c2c66affSColin Finck         if (static_cast<tmsize_t>(request_size) != size)
121c2c66affSColin Finck           return static_cast<tmsize_t>(-1);
122c2c66affSColin Finck 
123c2c66affSColin Finck         data->stream->read((char *) buf, request_size);
124c2c66affSColin Finck 
125c2c66affSColin Finck         return static_cast<tmsize_t>(data->stream->gcount());
126c2c66affSColin Finck }
127c2c66affSColin Finck 
128c2c66affSColin Finck static tmsize_t
_tiffosWriteProc(thandle_t fd,void * buf,tmsize_t size)129c2c66affSColin Finck _tiffosWriteProc(thandle_t fd, void* buf, tmsize_t size)
130c2c66affSColin Finck {
131c2c66affSColin Finck 	tiffos_data	*data = reinterpret_cast<tiffos_data *>(fd);
132c2c66affSColin Finck 	ostream		*os = data->stream;
133c2c66affSColin Finck 	ios::pos_type	pos = os->tellp();
134c2c66affSColin Finck 
135c2c66affSColin Finck         // Verify that type does not overflow.
136c2c66affSColin Finck         streamsize request_size = size;
137c2c66affSColin Finck         if (static_cast<tmsize_t>(request_size) != size)
138c2c66affSColin Finck           return static_cast<tmsize_t>(-1);
139c2c66affSColin Finck 
140c2c66affSColin Finck 	os->write(reinterpret_cast<const char *>(buf), request_size);
141c2c66affSColin Finck 
142c2c66affSColin Finck 	return static_cast<tmsize_t>(os->tellp() - pos);
143c2c66affSColin Finck }
144c2c66affSColin Finck 
145c2c66affSColin Finck static tmsize_t
_tiffisWriteProc(thandle_t,void *,tmsize_t)146c2c66affSColin Finck _tiffisWriteProc(thandle_t, void*, tmsize_t)
147c2c66affSColin Finck {
148c2c66affSColin Finck 	return 0;
149c2c66affSColin Finck }
150c2c66affSColin Finck 
151c2c66affSColin Finck static uint64
_tiffosSeekProc(thandle_t fd,uint64 off,int whence)152c2c66affSColin Finck _tiffosSeekProc(thandle_t fd, uint64 off, int whence)
153c2c66affSColin Finck {
154c2c66affSColin Finck 	tiffos_data	*data = reinterpret_cast<tiffos_data *>(fd);
155c2c66affSColin Finck 	ostream		*os = data->stream;
156c2c66affSColin Finck 
157c2c66affSColin Finck 	// if the stream has already failed, don't do anything
158c2c66affSColin Finck 	if( os->fail() )
159c2c66affSColin Finck 		return static_cast<uint64>(-1);
160c2c66affSColin Finck 
161c2c66affSColin Finck 	switch(whence) {
162c2c66affSColin Finck 	case SEEK_SET:
163c2c66affSColin Finck 		{
164c2c66affSColin Finck 			// Compute 64-bit offset
165c2c66affSColin Finck 			uint64 new_offset = static_cast<uint64>(data->start_pos) + off;
166c2c66affSColin Finck 
167c2c66affSColin Finck 			// Verify that value does not overflow
168c2c66affSColin Finck 			ios::off_type offset = static_cast<ios::off_type>(new_offset);
169c2c66affSColin Finck 			if (static_cast<uint64>(offset) != new_offset)
170c2c66affSColin Finck 				return static_cast<uint64>(-1);
171c2c66affSColin Finck 
172c2c66affSColin Finck 			os->seekp(offset, ios::beg);
173c2c66affSColin Finck 		break;
174c2c66affSColin Finck 		}
175c2c66affSColin Finck 	case SEEK_CUR:
176c2c66affSColin Finck 		{
177c2c66affSColin Finck 			// Verify that value does not overflow
178c2c66affSColin Finck 			ios::off_type offset = static_cast<ios::off_type>(off);
179c2c66affSColin Finck 			if (static_cast<uint64>(offset) != off)
180c2c66affSColin Finck 				return static_cast<uint64>(-1);
181c2c66affSColin Finck 
182c2c66affSColin Finck 			os->seekp(offset, ios::cur);
183c2c66affSColin Finck 			break;
184c2c66affSColin Finck 		}
185c2c66affSColin Finck 	case SEEK_END:
186c2c66affSColin Finck 		{
187c2c66affSColin Finck 			// Verify that value does not overflow
188c2c66affSColin Finck 			ios::off_type offset = static_cast<ios::off_type>(off);
189c2c66affSColin Finck 			if (static_cast<uint64>(offset) != off)
190c2c66affSColin Finck 				return static_cast<uint64>(-1);
191c2c66affSColin Finck 
192c2c66affSColin Finck 			os->seekp(offset, ios::end);
193c2c66affSColin Finck 			break;
194c2c66affSColin Finck 		}
195c2c66affSColin Finck 	}
196c2c66affSColin Finck 
197c2c66affSColin Finck 	// Attempt to workaround problems with seeking past the end of the
198c2c66affSColin Finck 	// stream.  ofstream doesn't have a problem with this but
199c2c66affSColin Finck 	// ostrstream/ostringstream does. In that situation, add intermediate
200c2c66affSColin Finck 	// '\0' characters.
201c2c66affSColin Finck 	if( os->fail() ) {
202c2c66affSColin Finck #ifdef __VMS
203c2c66affSColin Finck 		int		old_state;
204c2c66affSColin Finck #else
205c2c66affSColin Finck 		ios::iostate	old_state;
206c2c66affSColin Finck #endif
207c2c66affSColin Finck 		ios::pos_type	origin;
208c2c66affSColin Finck 
209c2c66affSColin Finck 		old_state = os->rdstate();
210c2c66affSColin Finck 		// reset the fail bit or else tellp() won't work below
211c2c66affSColin Finck 		os->clear(os->rdstate() & ~ios::failbit);
212c2c66affSColin Finck 		switch( whence ) {
213c2c66affSColin Finck 			case SEEK_SET:
214c2c66affSColin Finck                         default:
215c2c66affSColin Finck 				origin = data->start_pos;
216c2c66affSColin Finck 				break;
217c2c66affSColin Finck 			case SEEK_CUR:
218c2c66affSColin Finck 				origin = os->tellp();
219c2c66affSColin Finck 				break;
220c2c66affSColin Finck 			case SEEK_END:
221c2c66affSColin Finck 				os->seekp(0, ios::end);
222c2c66affSColin Finck 				origin = os->tellp();
223c2c66affSColin Finck 				break;
224c2c66affSColin Finck 		}
225c2c66affSColin Finck 		// restore original stream state
226c2c66affSColin Finck 		os->clear(old_state);
227c2c66affSColin Finck 
228c2c66affSColin Finck 		// only do something if desired seek position is valid
229c2c66affSColin Finck 		if( (static_cast<uint64>(origin) + off) > static_cast<uint64>(data->start_pos) ) {
230c2c66affSColin Finck 			uint64	num_fill;
231c2c66affSColin Finck 
232c2c66affSColin Finck 			// clear the fail bit
233c2c66affSColin Finck 			os->clear(os->rdstate() & ~ios::failbit);
234c2c66affSColin Finck 
235c2c66affSColin Finck 			// extend the stream to the expected size
236c2c66affSColin Finck 			os->seekp(0, ios::end);
237c2c66affSColin Finck 			num_fill = (static_cast<uint64>(origin)) + off - os->tellp();
238c2c66affSColin Finck 			for( uint64 i = 0; i < num_fill; i++ )
239c2c66affSColin Finck 				os->put('\0');
240c2c66affSColin Finck 
241c2c66affSColin Finck 			// retry the seek
242c2c66affSColin Finck 			os->seekp(static_cast<ios::off_type>(static_cast<uint64>(origin) + off), ios::beg);
243c2c66affSColin Finck 		}
244c2c66affSColin Finck 	}
245c2c66affSColin Finck 
246c2c66affSColin Finck 	return static_cast<uint64>(os->tellp());
247c2c66affSColin Finck }
248c2c66affSColin Finck 
249c2c66affSColin Finck static uint64
_tiffisSeekProc(thandle_t fd,uint64 off,int whence)250c2c66affSColin Finck _tiffisSeekProc(thandle_t fd, uint64 off, int whence)
251c2c66affSColin Finck {
252c2c66affSColin Finck 	tiffis_data	*data = reinterpret_cast<tiffis_data *>(fd);
253c2c66affSColin Finck 
254c2c66affSColin Finck 	switch(whence) {
255c2c66affSColin Finck 	case SEEK_SET:
256c2c66affSColin Finck 		{
257c2c66affSColin Finck 			// Compute 64-bit offset
258c2c66affSColin Finck 			uint64 new_offset = static_cast<uint64>(data->start_pos) + off;
259c2c66affSColin Finck 
260c2c66affSColin Finck 			// Verify that value does not overflow
261c2c66affSColin Finck 			ios::off_type offset = static_cast<ios::off_type>(new_offset);
262c2c66affSColin Finck 			if (static_cast<uint64>(offset) != new_offset)
263c2c66affSColin Finck 				return static_cast<uint64>(-1);
264c2c66affSColin Finck 
265c2c66affSColin Finck 			data->stream->seekg(offset, ios::beg);
266c2c66affSColin Finck 			break;
267c2c66affSColin Finck 		}
268c2c66affSColin Finck 	case SEEK_CUR:
269c2c66affSColin Finck 		{
270c2c66affSColin Finck 			// Verify that value does not overflow
271c2c66affSColin Finck 			ios::off_type offset = static_cast<ios::off_type>(off);
272c2c66affSColin Finck 			if (static_cast<uint64>(offset) != off)
273c2c66affSColin Finck 				return static_cast<uint64>(-1);
274c2c66affSColin Finck 
275c2c66affSColin Finck 			data->stream->seekg(offset, ios::cur);
276c2c66affSColin Finck 			break;
277c2c66affSColin Finck 		}
278c2c66affSColin Finck 	case SEEK_END:
279c2c66affSColin Finck 		{
280c2c66affSColin Finck 			// Verify that value does not overflow
281c2c66affSColin Finck 			ios::off_type offset = static_cast<ios::off_type>(off);
282c2c66affSColin Finck 			if (static_cast<uint64>(offset) != off)
283c2c66affSColin Finck 				return static_cast<uint64>(-1);
284c2c66affSColin Finck 
285c2c66affSColin Finck 			data->stream->seekg(offset, ios::end);
286c2c66affSColin Finck 			break;
287c2c66affSColin Finck 		}
288c2c66affSColin Finck 	}
289c2c66affSColin Finck 
290c2c66affSColin Finck 	return (uint64) (data->stream->tellg() - data->start_pos);
291c2c66affSColin Finck }
292c2c66affSColin Finck 
293c2c66affSColin Finck static uint64
_tiffosSizeProc(thandle_t fd)294c2c66affSColin Finck _tiffosSizeProc(thandle_t fd)
295c2c66affSColin Finck {
296c2c66affSColin Finck 	tiffos_data	*data = reinterpret_cast<tiffos_data *>(fd);
297c2c66affSColin Finck 	ostream		*os = data->stream;
298c2c66affSColin Finck 	ios::pos_type	pos = os->tellp();
299c2c66affSColin Finck 	ios::pos_type	len;
300c2c66affSColin Finck 
301c2c66affSColin Finck 	os->seekp(0, ios::end);
302c2c66affSColin Finck 	len = os->tellp();
303c2c66affSColin Finck 	os->seekp(pos);
304c2c66affSColin Finck 
305c2c66affSColin Finck 	return (uint64) len;
306c2c66affSColin Finck }
307c2c66affSColin Finck 
308c2c66affSColin Finck static uint64
_tiffisSizeProc(thandle_t fd)309c2c66affSColin Finck _tiffisSizeProc(thandle_t fd)
310c2c66affSColin Finck {
311c2c66affSColin Finck 	tiffis_data	*data = reinterpret_cast<tiffis_data *>(fd);
312c2c66affSColin Finck 	ios::pos_type	pos = data->stream->tellg();
313c2c66affSColin Finck 	ios::pos_type	len;
314c2c66affSColin Finck 
315c2c66affSColin Finck 	data->stream->seekg(0, ios::end);
316c2c66affSColin Finck 	len = data->stream->tellg();
317c2c66affSColin Finck 	data->stream->seekg(pos);
318c2c66affSColin Finck 
319c2c66affSColin Finck 	return (uint64) len;
320c2c66affSColin Finck }
321c2c66affSColin Finck 
322c2c66affSColin Finck static int
_tiffosCloseProc(thandle_t fd)323c2c66affSColin Finck _tiffosCloseProc(thandle_t fd)
324c2c66affSColin Finck {
325c2c66affSColin Finck 	// Our stream was not allocated by us, so it shouldn't be closed by us.
326c2c66affSColin Finck 	delete reinterpret_cast<tiffos_data *>(fd);
327c2c66affSColin Finck 	return 0;
328c2c66affSColin Finck }
329c2c66affSColin Finck 
330c2c66affSColin Finck static int
_tiffisCloseProc(thandle_t fd)331c2c66affSColin Finck _tiffisCloseProc(thandle_t fd)
332c2c66affSColin Finck {
333c2c66affSColin Finck 	// Our stream was not allocated by us, so it shouldn't be closed by us.
334c2c66affSColin Finck 	delete reinterpret_cast<tiffis_data *>(fd);
335c2c66affSColin Finck 	return 0;
336c2c66affSColin Finck }
337c2c66affSColin Finck 
338c2c66affSColin Finck static int
_tiffDummyMapProc(thandle_t,void ** base,toff_t * size)339c2c66affSColin Finck _tiffDummyMapProc(thandle_t , void** base, toff_t* size )
340c2c66affSColin Finck {
341c2c66affSColin Finck 	(void) base;
342c2c66affSColin Finck 	(void) size;
343c2c66affSColin Finck 	return (0);
344c2c66affSColin Finck }
345c2c66affSColin Finck 
346c2c66affSColin Finck static void
_tiffDummyUnmapProc(thandle_t,void * base,toff_t size)347c2c66affSColin Finck _tiffDummyUnmapProc(thandle_t , void* base, toff_t size )
348c2c66affSColin Finck {
349c2c66affSColin Finck 	(void) base;
350c2c66affSColin Finck 	(void) size;
351c2c66affSColin Finck }
352c2c66affSColin Finck 
353c2c66affSColin Finck /*
354c2c66affSColin Finck  * Open a TIFF file descriptor for read/writing.
355c2c66affSColin Finck  */
356c2c66affSColin Finck static TIFF*
_tiffStreamOpen(const char * name,const char * mode,void * fd)357c2c66affSColin Finck _tiffStreamOpen(const char* name, const char* mode, void *fd)
358c2c66affSColin Finck {
359c2c66affSColin Finck 	TIFF*	tif;
360c2c66affSColin Finck 
361c2c66affSColin Finck 	if( strchr(mode, 'w') ) {
362c2c66affSColin Finck 		tiffos_data	*data = new tiffos_data;
363c2c66affSColin Finck 		data->stream = reinterpret_cast<ostream *>(fd);
364c2c66affSColin Finck 		data->start_pos = data->stream->tellp();
365c2c66affSColin Finck 
366c2c66affSColin Finck 		// Open for writing.
367c2c66affSColin Finck 		tif = TIFFClientOpen(name, mode,
368c2c66affSColin Finck 				reinterpret_cast<thandle_t>(data),
369c2c66affSColin Finck 				_tiffosReadProc,
370c2c66affSColin Finck                                 _tiffosWriteProc,
371c2c66affSColin Finck 				_tiffosSeekProc,
372c2c66affSColin Finck                                 _tiffosCloseProc,
373c2c66affSColin Finck 				_tiffosSizeProc,
374c2c66affSColin Finck 				_tiffDummyMapProc,
375c2c66affSColin Finck                                 _tiffDummyUnmapProc);
376*743951ecSThomas Faber 		if (!tif) {
377*743951ecSThomas Faber 			delete data;
378*743951ecSThomas Faber 		}
379c2c66affSColin Finck 	} else {
380c2c66affSColin Finck 		tiffis_data	*data = new tiffis_data;
381c2c66affSColin Finck 		data->stream = reinterpret_cast<istream *>(fd);
382c2c66affSColin Finck 		data->start_pos = data->stream->tellg();
383c2c66affSColin Finck 		// Open for reading.
384c2c66affSColin Finck 		tif = TIFFClientOpen(name, mode,
385c2c66affSColin Finck 				reinterpret_cast<thandle_t>(data),
386c2c66affSColin Finck 				_tiffisReadProc,
387c2c66affSColin Finck                                 _tiffisWriteProc,
388c2c66affSColin Finck 				_tiffisSeekProc,
389c2c66affSColin Finck                                 _tiffisCloseProc,
390c2c66affSColin Finck 				_tiffisSizeProc,
391c2c66affSColin Finck 				_tiffDummyMapProc,
392c2c66affSColin Finck                                 _tiffDummyUnmapProc);
393*743951ecSThomas Faber 		if (!tif) {
394*743951ecSThomas Faber 			delete data;
395*743951ecSThomas Faber 		}
396c2c66affSColin Finck 	}
397c2c66affSColin Finck 
398c2c66affSColin Finck 	return (tif);
399c2c66affSColin Finck }
400c2c66affSColin Finck 
401c2c66affSColin Finck } /* extern "C" */
402c2c66affSColin Finck 
403c2c66affSColin Finck TIFF*
TIFFStreamOpen(const char * name,ostream * os)404c2c66affSColin Finck TIFFStreamOpen(const char* name, ostream *os)
405c2c66affSColin Finck {
406c2c66affSColin Finck 	// If os is either a ostrstream or ostringstream, and has no data
407c2c66affSColin Finck 	// written to it yet, then tellp() will return -1 which will break us.
408c2c66affSColin Finck 	// We workaround this by writing out a dummy character and
409c2c66affSColin Finck 	// then seek back to the beginning.
410c2c66affSColin Finck 	if( !os->fail() && static_cast<int>(os->tellp()) < 0 ) {
411c2c66affSColin Finck 		*os << '\0';
412c2c66affSColin Finck 		os->seekp(0);
413c2c66affSColin Finck 	}
414c2c66affSColin Finck 
415c2c66affSColin Finck 	// NB: We don't support mapped files with streams so add 'm'
416c2c66affSColin Finck 	return _tiffStreamOpen(name, "wm", os);
417c2c66affSColin Finck }
418c2c66affSColin Finck 
419c2c66affSColin Finck TIFF*
TIFFStreamOpen(const char * name,istream * is)420c2c66affSColin Finck TIFFStreamOpen(const char* name, istream *is)
421c2c66affSColin Finck {
422c2c66affSColin Finck 	// NB: We don't support mapped files with streams so add 'm'
423c2c66affSColin Finck 	return _tiffStreamOpen(name, "rm", is);
424c2c66affSColin Finck }
425c2c66affSColin Finck 
426c2c66affSColin Finck /* vim: set ts=8 sts=8 sw=8 noet: */
427c2c66affSColin Finck /*
428c2c66affSColin Finck  * Local Variables:
429c2c66affSColin Finck  * mode: c
430c2c66affSColin Finck  * c-basic-offset: 8
431c2c66affSColin Finck  * fill-column: 78
432c2c66affSColin Finck  * End:
433c2c66affSColin Finck  */
434c2c66affSColin Finck 
435