|
roentgen |
b75cab |
/* $Id: tif_stream.cxx,v 1.11 2010-12-11 23:12:29 faxguy Exp $ */
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Copyright (c) 1988-1996 Sam Leffler
|
|
roentgen |
b75cab |
* Copyright (c) 1991-1996 Silicon Graphics, Inc.
|
|
roentgen |
b75cab |
*
|
|
roentgen |
b75cab |
* Permission to use, copy, modify, distribute, and sell this software and
|
|
roentgen |
b75cab |
* its documentation for any purpose is hereby granted without fee, provided
|
|
roentgen |
b75cab |
* that (i) the above copyright notices and this permission notice appear in
|
|
roentgen |
b75cab |
* all copies of the software and related documentation, and (ii) the names of
|
|
roentgen |
b75cab |
* Sam Leffler and Silicon Graphics may not be used in any advertising or
|
|
roentgen |
b75cab |
* publicity relating to the software without the specific, prior written
|
|
roentgen |
b75cab |
* permission of Sam Leffler and Silicon Graphics.
|
|
roentgen |
b75cab |
*
|
|
roentgen |
b75cab |
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
|
|
roentgen |
b75cab |
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
|
|
roentgen |
b75cab |
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
|
roentgen |
b75cab |
*
|
|
roentgen |
b75cab |
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
|
|
roentgen |
b75cab |
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
|
|
roentgen |
b75cab |
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
roentgen |
b75cab |
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
|
|
roentgen |
b75cab |
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
|
|
roentgen |
b75cab |
* OF THIS SOFTWARE.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* TIFF Library UNIX-specific Routines.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
#include "tiffiop.h"
|
|
roentgen |
b75cab |
#include <iostream></iostream>
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
#ifndef __VMS
|
|
roentgen |
b75cab |
using namespace std;
|
|
roentgen |
b75cab |
#endif
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
ISO C++ uses a 'std::streamsize' type to define counts. This makes
|
|
roentgen |
b75cab |
it similar to, (but perhaps not the same as) size_t.
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
The std::ios::pos_type is used to represent stream positions as used
|
|
roentgen |
b75cab |
by tellg(), tellp(), seekg(), and seekp(). This makes it similar to
|
|
roentgen |
b75cab |
(but perhaps not the same as) 'off_t'. The std::ios::streampos type
|
|
roentgen |
b75cab |
is used for character streams, but is documented to not be an
|
|
roentgen |
b75cab |
integral type anymore, so it should *not* be assigned to an integral
|
|
roentgen |
b75cab |
type.
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
The std::ios::off_type is used to specify relative offsets needed by
|
|
roentgen |
b75cab |
the variants of seekg() and seekp() which accept a relative offset
|
|
roentgen |
b75cab |
argument.
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
Useful prototype knowledge:
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
Obtain read position
|
|
roentgen |
b75cab |
ios::pos_type basic_istream::tellg()
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
Set read position
|
|
roentgen |
b75cab |
basic_istream& basic_istream::seekg(ios::pos_type)
|
|
roentgen |
b75cab |
basic_istream& basic_istream::seekg(ios::off_type, ios_base::seekdir)
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
Read data
|
|
roentgen |
b75cab |
basic_istream& istream::read(char *str, streamsize count)
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
Number of characters read in last unformatted read
|
|
roentgen |
b75cab |
streamsize istream::gcount();
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
Obtain write position
|
|
roentgen |
b75cab |
ios::pos_type basic_ostream::tellp()
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
Set write position
|
|
roentgen |
b75cab |
basic_ostream& basic_ostream::seekp(ios::pos_type)
|
|
roentgen |
b75cab |
basic_ostream& basic_ostream::seekp(ios::off_type, ios_base::seekdir)
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
Write data
|
|
roentgen |
b75cab |
basic_ostream& ostream::write(const char *str, streamsize count)
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
struct tiffis_data;
|
|
roentgen |
b75cab |
struct tiffos_data;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
extern "C" {
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static tmsize_t _tiffosReadProc(thandle_t, void*, tmsize_t);
|
|
roentgen |
b75cab |
static tmsize_t _tiffisReadProc(thandle_t fd, void* buf, tmsize_t size);
|
|
roentgen |
b75cab |
static tmsize_t _tiffosWriteProc(thandle_t fd, void* buf, tmsize_t size);
|
|
roentgen |
b75cab |
static tmsize_t _tiffisWriteProc(thandle_t, void*, tmsize_t);
|
|
roentgen |
b75cab |
static uint64 _tiffosSeekProc(thandle_t fd, uint64 off, int whence);
|
|
roentgen |
b75cab |
static uint64 _tiffisSeekProc(thandle_t fd, uint64 off, int whence);
|
|
roentgen |
b75cab |
static uint64 _tiffosSizeProc(thandle_t fd);
|
|
roentgen |
b75cab |
static uint64 _tiffisSizeProc(thandle_t fd);
|
|
roentgen |
b75cab |
static int _tiffosCloseProc(thandle_t fd);
|
|
roentgen |
b75cab |
static int _tiffisCloseProc(thandle_t fd);
|
|
roentgen |
b75cab |
static int _tiffDummyMapProc(thandle_t , void** base, toff_t* size );
|
|
roentgen |
b75cab |
static void _tiffDummyUnmapProc(thandle_t , void* base, toff_t size );
|
|
roentgen |
b75cab |
static TIFF* _tiffStreamOpen(const char* name, const char* mode, void *fd);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
struct tiffis_data
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
istream *stream;
|
|
roentgen |
b75cab |
ios::pos_type start_pos;
|
|
roentgen |
b75cab |
};
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
struct tiffos_data
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
ostream *stream;
|
|
roentgen |
b75cab |
ios::pos_type start_pos;
|
|
roentgen |
b75cab |
};
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static tmsize_t
|
|
roentgen |
b75cab |
_tiffosReadProc(thandle_t, void*, tmsize_t)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static tmsize_t
|
|
roentgen |
b75cab |
_tiffisReadProc(thandle_t fd, void* buf, tmsize_t size)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
tiffis_data *data = reinterpret_cast<tiffis_data *="">(fd);</tiffis_data>
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// Verify that type does not overflow.
|
|
roentgen |
b75cab |
streamsize request_size = size;
|
|
roentgen |
b75cab |
if (static_cast<tmsize_t>(request_size) != size)</tmsize_t>
|
|
roentgen |
b75cab |
return static_cast<tmsize_t>(-1);</tmsize_t>
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
data->stream->read((char *) buf, request_size);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
return static_cast<tmsize_t>(data->stream->gcount());</tmsize_t>
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static tmsize_t
|
|
roentgen |
b75cab |
_tiffosWriteProc(thandle_t fd, void* buf, tmsize_t size)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
tiffos_data *data = reinterpret_cast<tiffos_data *="">(fd);</tiffos_data>
|
|
roentgen |
b75cab |
ostream *os = data->stream;
|
|
roentgen |
b75cab |
ios::pos_type pos = os->tellp();
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// Verify that type does not overflow.
|
|
roentgen |
b75cab |
streamsize request_size = size;
|
|
roentgen |
b75cab |
if (static_cast<tmsize_t>(request_size) != size)</tmsize_t>
|
|
roentgen |
b75cab |
return static_cast<tmsize_t>(-1);</tmsize_t>
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
os->write(reinterpret_cast<const *="" char="">(buf), request_size);</const>
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
return static_cast<tmsize_t>(os->tellp() - pos);</tmsize_t>
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static tmsize_t
|
|
roentgen |
b75cab |
_tiffisWriteProc(thandle_t, void*, tmsize_t)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static uint64
|
|
roentgen |
b75cab |
_tiffosSeekProc(thandle_t fd, uint64 off, int whence)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
tiffos_data *data = reinterpret_cast<tiffos_data *="">(fd);</tiffos_data>
|
|
roentgen |
b75cab |
ostream *os = data->stream;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// if the stream has already failed, don't do anything
|
|
roentgen |
b75cab |
if( os->fail() )
|
|
roentgen |
b75cab |
return static_cast<uint64>(-1);</uint64>
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
switch(whence) {
|
|
roentgen |
b75cab |
case SEEK_SET:
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
// Compute 64-bit offset
|
|
roentgen |
b75cab |
uint64 new_offset = static_cast<uint64>(data->start_pos) + off;</uint64>
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// Verify that value does not overflow
|
|
roentgen |
b75cab |
ios::off_type offset = static_cast<ios::off_type>(new_offset);</ios::off_type>
|
|
roentgen |
b75cab |
if (static_cast<uint64>(offset) != new_offset)</uint64>
|
|
roentgen |
b75cab |
return static_cast<uint64>(-1);</uint64>
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
os->seekp(offset, ios::beg);
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
case SEEK_CUR:
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
// Verify that value does not overflow
|
|
roentgen |
b75cab |
ios::off_type offset = static_cast<ios::off_type>(off);</ios::off_type>
|
|
roentgen |
b75cab |
if (static_cast<uint64>(offset) != off)</uint64>
|
|
roentgen |
b75cab |
return static_cast<uint64>(-1);</uint64>
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
os->seekp(offset, ios::cur);
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
case SEEK_END:
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
// Verify that value does not overflow
|
|
roentgen |
b75cab |
ios::off_type offset = static_cast<ios::off_type>(off);</ios::off_type>
|
|
roentgen |
b75cab |
if (static_cast<uint64>(offset) != off)</uint64>
|
|
roentgen |
b75cab |
return static_cast<uint64>(-1);</uint64>
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
os->seekp(offset, ios::end);
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// Attempt to workaround problems with seeking past the end of the
|
|
roentgen |
b75cab |
// stream. ofstream doesn't have a problem with this but
|
|
roentgen |
b75cab |
// ostrstream/ostringstream does. In that situation, add intermediate
|
|
roentgen |
b75cab |
// '\0' characters.
|
|
roentgen |
b75cab |
if( os->fail() ) {
|
|
roentgen |
b75cab |
#ifdef __VMS
|
|
roentgen |
b75cab |
int old_state;
|
|
roentgen |
b75cab |
#else
|
|
roentgen |
b75cab |
ios::iostate old_state;
|
|
roentgen |
b75cab |
#endif
|
|
roentgen |
b75cab |
ios::pos_type origin;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
old_state = os->rdstate();
|
|
roentgen |
b75cab |
// reset the fail bit or else tellp() won't work below
|
|
roentgen |
b75cab |
os->clear(os->rdstate() & ~ios::failbit);
|
|
roentgen |
b75cab |
switch( whence ) {
|
|
roentgen |
b75cab |
case SEEK_SET:
|
|
roentgen |
b75cab |
default:
|
|
roentgen |
b75cab |
origin = data->start_pos;
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case SEEK_CUR:
|
|
roentgen |
b75cab |
origin = os->tellp();
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
case SEEK_END:
|
|
roentgen |
b75cab |
os->seekp(0, ios::end);
|
|
roentgen |
b75cab |
origin = os->tellp();
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
// restore original stream state
|
|
roentgen |
b75cab |
os->clear(old_state);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// only do something if desired seek position is valid
|
|
roentgen |
b75cab |
if( (static_cast<uint64>(origin) + off) > static_cast<uint64>(data->start_pos) ) {</uint64></uint64>
|
|
roentgen |
b75cab |
uint64 num_fill;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// clear the fail bit
|
|
roentgen |
b75cab |
os->clear(os->rdstate() & ~ios::failbit);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// extend the stream to the expected size
|
|
roentgen |
b75cab |
os->seekp(0, ios::end);
|
|
roentgen |
b75cab |
num_fill = (static_cast<uint64>(origin)) + off - os->tellp();</uint64>
|
|
roentgen |
b75cab |
for( uint64 i = 0; i < num_fill; i++ )
|
|
roentgen |
b75cab |
os->put('\0');
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// retry the seek
|
|
roentgen |
b75cab |
os->seekp(static_cast<ios::off_type>(static_cast<uint64>(origin) + off), ios::beg);</uint64></ios::off_type>
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
return static_cast<uint64>(os->tellp());</uint64>
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static uint64
|
|
roentgen |
b75cab |
_tiffisSeekProc(thandle_t fd, uint64 off, int whence)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
tiffis_data *data = reinterpret_cast<tiffis_data *="">(fd);</tiffis_data>
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
switch(whence) {
|
|
roentgen |
b75cab |
case SEEK_SET:
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
// Compute 64-bit offset
|
|
roentgen |
b75cab |
uint64 new_offset = static_cast<uint64>(data->start_pos) + off;</uint64>
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// Verify that value does not overflow
|
|
roentgen |
b75cab |
ios::off_type offset = static_cast<ios::off_type>(new_offset);</ios::off_type>
|
|
roentgen |
b75cab |
if (static_cast<uint64>(offset) != new_offset)</uint64>
|
|
roentgen |
b75cab |
return static_cast<uint64>(-1);</uint64>
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
data->stream->seekg(offset, ios::beg);
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
case SEEK_CUR:
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
// Verify that value does not overflow
|
|
roentgen |
b75cab |
ios::off_type offset = static_cast<ios::off_type>(off);</ios::off_type>
|
|
roentgen |
b75cab |
if (static_cast<uint64>(offset) != off)</uint64>
|
|
roentgen |
b75cab |
return static_cast<uint64>(-1);</uint64>
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
data->stream->seekg(offset, ios::cur);
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
case SEEK_END:
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
// Verify that value does not overflow
|
|
roentgen |
b75cab |
ios::off_type offset = static_cast<ios::off_type>(off);</ios::off_type>
|
|
roentgen |
b75cab |
if (static_cast<uint64>(offset) != off)</uint64>
|
|
roentgen |
b75cab |
return static_cast<uint64>(-1);</uint64>
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
data->stream->seekg(offset, ios::end);
|
|
roentgen |
b75cab |
break;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
return (uint64) (data->stream->tellg() - data->start_pos);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static uint64
|
|
roentgen |
b75cab |
_tiffosSizeProc(thandle_t fd)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
tiffos_data *data = reinterpret_cast<tiffos_data *="">(fd);</tiffos_data>
|
|
roentgen |
b75cab |
ostream *os = data->stream;
|
|
roentgen |
b75cab |
ios::pos_type pos = os->tellp();
|
|
roentgen |
b75cab |
ios::pos_type len;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
os->seekp(0, ios::end);
|
|
roentgen |
b75cab |
len = os->tellp();
|
|
roentgen |
b75cab |
os->seekp(pos);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
return (uint64) len;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static uint64
|
|
roentgen |
b75cab |
_tiffisSizeProc(thandle_t fd)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
tiffis_data *data = reinterpret_cast<tiffis_data *="">(fd);</tiffis_data>
|
|
roentgen |
b75cab |
ios::pos_type pos = data->stream->tellg();
|
|
roentgen |
b75cab |
ios::pos_type len;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
data->stream->seekg(0, ios::end);
|
|
roentgen |
b75cab |
len = data->stream->tellg();
|
|
roentgen |
b75cab |
data->stream->seekg(pos);
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
return (uint64) len;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static int
|
|
roentgen |
b75cab |
_tiffosCloseProc(thandle_t fd)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
// Our stream was not allocated by us, so it shouldn't be closed by us.
|
|
roentgen |
b75cab |
delete reinterpret_cast<tiffos_data *="">(fd);</tiffos_data>
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static int
|
|
roentgen |
b75cab |
_tiffisCloseProc(thandle_t fd)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
// Our stream was not allocated by us, so it shouldn't be closed by us.
|
|
roentgen |
b75cab |
delete reinterpret_cast<tiffis_data *="">(fd);</tiffis_data>
|
|
roentgen |
b75cab |
return 0;
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static int
|
|
roentgen |
b75cab |
_tiffDummyMapProc(thandle_t , void** base, toff_t* size )
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
return (0);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
static void
|
|
roentgen |
b75cab |
_tiffDummyUnmapProc(thandle_t , void* base, toff_t size )
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
* Open a TIFF file descriptor for read/writing.
|
|
roentgen |
b75cab |
*/
|
|
roentgen |
b75cab |
static TIFF*
|
|
roentgen |
b75cab |
_tiffStreamOpen(const char* name, const char* mode, void *fd)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
TIFF* tif;
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
if( strchr(mode, 'w') ) {
|
|
roentgen |
b75cab |
tiffos_data *data = new tiffos_data;
|
|
roentgen |
b75cab |
data->stream = reinterpret_cast<ostream *="">(fd);</ostream>
|
|
roentgen |
b75cab |
data->start_pos = data->stream->tellp();
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// Open for writing.
|
|
roentgen |
b75cab |
tif = TIFFClientOpen(name, mode,
|
|
roentgen |
b75cab |
reinterpret_cast<thandle_t>(data),</thandle_t>
|
|
roentgen |
b75cab |
_tiffosReadProc,
|
|
roentgen |
b75cab |
_tiffosWriteProc,
|
|
roentgen |
b75cab |
_tiffosSeekProc,
|
|
roentgen |
b75cab |
_tiffosCloseProc,
|
|
roentgen |
b75cab |
_tiffosSizeProc,
|
|
roentgen |
b75cab |
_tiffDummyMapProc,
|
|
roentgen |
b75cab |
_tiffDummyUnmapProc);
|
|
roentgen |
b75cab |
} else {
|
|
roentgen |
b75cab |
tiffis_data *data = new tiffis_data;
|
|
roentgen |
b75cab |
data->stream = reinterpret_cast<istream *="">(fd);</istream>
|
|
roentgen |
b75cab |
data->start_pos = data->stream->tellg();
|
|
roentgen |
b75cab |
// Open for reading.
|
|
roentgen |
b75cab |
tif = TIFFClientOpen(name, mode,
|
|
roentgen |
b75cab |
reinterpret_cast<thandle_t>(data),</thandle_t>
|
|
roentgen |
b75cab |
_tiffisReadProc,
|
|
roentgen |
b75cab |
_tiffisWriteProc,
|
|
roentgen |
b75cab |
_tiffisSeekProc,
|
|
roentgen |
b75cab |
_tiffisCloseProc,
|
|
roentgen |
b75cab |
_tiffisSizeProc,
|
|
roentgen |
b75cab |
_tiffDummyMapProc,
|
|
roentgen |
b75cab |
_tiffDummyUnmapProc);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
return (tif);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
} /* extern "C" */
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
TIFF*
|
|
roentgen |
b75cab |
TIFFStreamOpen(const char* name, ostream *os)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
// If os is either a ostrstream or ostringstream, and has no data
|
|
roentgen |
b75cab |
// written to it yet, then tellp() will return -1 which will break us.
|
|
roentgen |
b75cab |
// We workaround this by writing out a dummy character and
|
|
roentgen |
b75cab |
// then seek back to the beginning.
|
|
roentgen |
b75cab |
if( !os->fail() && static_cast<int>(os->tellp()) < 0 ) {</int>
|
|
roentgen |
b75cab |
*os << '\0';
|
|
roentgen |
b75cab |
os->seekp(0);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
// NB: We don't support mapped files with streams so add 'm'
|
|
roentgen |
b75cab |
return _tiffStreamOpen(name, "wm", os);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
TIFF*
|
|
roentgen |
b75cab |
TIFFStreamOpen(const char* name, istream *is)
|
|
roentgen |
b75cab |
{
|
|
roentgen |
b75cab |
// NB: We don't support mapped files with streams so add 'm'
|
|
roentgen |
b75cab |
return _tiffStreamOpen(name, "rm", is);
|
|
roentgen |
b75cab |
}
|
|
roentgen |
b75cab |
|
|
roentgen |
b75cab |
/* vim: set ts=8 sts=8 sw=8 noet: */
|
|
roentgen |
b75cab |
/*
|
|
roentgen |
b75cab |
Local Variables:
|
|
roentgen |
b75cab |
mode: c
|
|
roentgen |
b75cab |
indent-tabs-mode: true
|
|
roentgen |
b75cab |
c-basic-offset: 8
|
|
roentgen |
b75cab |
End:
|
|
roentgen |
b75cab |
*/
|