New
This commit is contained in:
parent
cf8514ccfa
commit
37854eca77
1
contrib/stream/Makefile
Normal file
1
contrib/stream/Makefile
Normal file
@ -0,0 +1 @@
|
||||
|
30
contrib/stream/README
Normal file
30
contrib/stream/README
Normal file
@ -0,0 +1,30 @@
|
||||
Subject: tiff stream interface (contrib)
|
||||
Date: Thu, 30 Mar 2000 10:48:51 -0800
|
||||
From: "Avi Bleiweiss" <avi@shutterfly.com>
|
||||
To: <warmerda@home.com>, <mike@onshore.com>
|
||||
|
||||
Here at Shutterfly we have augmented the file based tiff library to support
|
||||
C++ streams. The implementation is an adaptor class, which takes any C++
|
||||
stream from the user and in return it deposits i/o operation method pointers
|
||||
(e.g. read, write, seek and close) into the tiff's library client state.
|
||||
|
||||
The class TiffStream has an overloaded factory method - makeFileStream -
|
||||
which takes the C++ stream as an argument, calls TIFFClientOpen and returns
|
||||
a tiff handle. The class retains the tiff handle in its local state and
|
||||
provides a helper function (getTiffHandle) to query the handle at any time.
|
||||
Additional helper method - getStreamSize - provides the stream size to the
|
||||
user. The implementation assumes client responsibility to delete the stream
|
||||
object. The class calls TIFFClose at destruction time.
|
||||
|
||||
Attached are a definition (tiffstream.h) and an implementation
|
||||
(tiffstream.cpp) files of the TiffStream class. No changes are required to
|
||||
the tiff core piece and the class sits on top of the library. The code is
|
||||
fairly tested at this point and is used internally in Shutterfly imaging
|
||||
software. The code is portable across WindowsNT/Linux/Solaris.
|
||||
|
||||
We at Shutterfly believe this software has benefits to the larger community
|
||||
of tiff library users and would like to contribute this software to be part
|
||||
of the tiff distributed package. Let me know of any issue.
|
||||
|
||||
Thanks
|
||||
Avi
|
232
contrib/stream/tiffstream.cpp
Normal file
232
contrib/stream/tiffstream.cpp
Normal file
@ -0,0 +1,232 @@
|
||||
// tiff stream interface class implementation
|
||||
|
||||
#include "tiffstream.h"
|
||||
|
||||
const char* TiffStream::m_name = "TiffStream";
|
||||
|
||||
TiffStream::TiffStream()
|
||||
{
|
||||
m_tif = NULL;
|
||||
|
||||
|
||||
m_inStream = NULL;
|
||||
m_outStream = NULL;
|
||||
m_ioStream = NULL;
|
||||
|
||||
m_streamLength = 0;
|
||||
|
||||
m_this = reinterpret_cast<thandle_t>(this);
|
||||
};
|
||||
|
||||
TiffStream::~TiffStream()
|
||||
{
|
||||
if(m_tif != NULL) TIFFClose(m_tif);
|
||||
}
|
||||
|
||||
TIFF*
|
||||
TiffStream::makeFileStream(istream* str)
|
||||
{
|
||||
m_inStream = str;
|
||||
m_outStream = NULL;
|
||||
m_ioStream = NULL;
|
||||
m_streamLength = getSize(m_this);
|
||||
|
||||
m_tif = TIFFClientOpen(m_name,
|
||||
"r",
|
||||
m_this,
|
||||
read,
|
||||
write,
|
||||
seek,
|
||||
close,
|
||||
size,
|
||||
map,
|
||||
unmap);
|
||||
return m_tif;
|
||||
}
|
||||
|
||||
TIFF*
|
||||
TiffStream::makeFileStream(ostream* str)
|
||||
{
|
||||
m_inStream = NULL;
|
||||
m_outStream = str;
|
||||
m_ioStream = NULL;
|
||||
m_streamLength = getSize(m_this);
|
||||
|
||||
m_tif = TIFFClientOpen(m_name,
|
||||
"w",
|
||||
m_this,
|
||||
read,
|
||||
write,
|
||||
seek,
|
||||
close,
|
||||
size,
|
||||
map,
|
||||
unmap);
|
||||
return m_tif;
|
||||
}
|
||||
|
||||
TIFF*
|
||||
TiffStream::makeFileStream(iostream* str)
|
||||
{
|
||||
m_inStream = NULL;
|
||||
m_outStream = NULL;
|
||||
m_ioStream = str;
|
||||
m_streamLength = getSize(m_this);
|
||||
|
||||
m_tif = TIFFClientOpen(m_name,
|
||||
"r+w",
|
||||
m_this,
|
||||
read,
|
||||
write,
|
||||
seek,
|
||||
close,
|
||||
size,
|
||||
map,
|
||||
unmap);
|
||||
return m_tif;
|
||||
}
|
||||
|
||||
tsize_t
|
||||
TiffStream::read(thandle_t fd, tdata_t buf, tsize_t size)
|
||||
{
|
||||
istream* istr;
|
||||
TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
|
||||
if(ts->m_inStream != NULL) {
|
||||
istr = ts->m_inStream;
|
||||
} else if(ts->m_ioStream != NULL) {
|
||||
istr = ts->m_ioStream;
|
||||
}
|
||||
|
||||
int remain = ts->m_streamLength - ts->tell(fd);
|
||||
int actual = remain < size ? remain : size;
|
||||
istr->read(reinterpret_cast<char*>(buf), actual);
|
||||
return istr->gcount();
|
||||
}
|
||||
|
||||
tsize_t
|
||||
TiffStream::write(thandle_t fd, tdata_t buf, tsize_t size)
|
||||
{
|
||||
TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
|
||||
ostream* ostr;
|
||||
if(ts->m_outStream != NULL) {
|
||||
ostr = ts->m_outStream;
|
||||
} else if(ts->m_ioStream != NULL) {
|
||||
ostr = ts->m_ioStream;
|
||||
}
|
||||
|
||||
streampos start = ostr->tellp();
|
||||
ostr->write(reinterpret_cast<const char*>(buf), size);
|
||||
return ostr->tellp() - start;
|
||||
}
|
||||
|
||||
toff_t
|
||||
TiffStream::seek(thandle_t fd, toff_t offset, int origin)
|
||||
{
|
||||
TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
|
||||
if(ts->seekInt(fd, offset, origin) == true) return offset;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
int
|
||||
TiffStream::close(thandle_t fd)
|
||||
{
|
||||
TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
|
||||
if(ts->m_inStream != NULL) {
|
||||
ts->m_inStream = NULL;
|
||||
return 0;
|
||||
} else if(ts->m_outStream != NULL) {
|
||||
ts->m_outStream = NULL;
|
||||
return 0;
|
||||
} else if(ts->m_ioStream != NULL) {
|
||||
ts->m_ioStream = NULL;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
toff_t
|
||||
TiffStream::size(thandle_t fd)
|
||||
{
|
||||
TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
|
||||
return ts->getSize(fd);
|
||||
}
|
||||
|
||||
int
|
||||
TiffStream::map(thandle_t fd, tdata_t* phase, toff_t* psize)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
TiffStream::unmap(thandle_t fd, tdata_t base, tsize_t size)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned int
|
||||
TiffStream::getSize(thandle_t fd)
|
||||
{
|
||||
if(!isOpen(fd)) return 0;
|
||||
|
||||
unsigned int pos = tell(fd);
|
||||
seekInt(fd, 0, end);
|
||||
unsigned int size = tell(fd);
|
||||
seekInt(fd, pos, beg);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
TiffStream::tell(thandle_t fd)
|
||||
{
|
||||
TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
|
||||
if(ts->m_inStream != NULL) {
|
||||
return ts->m_inStream->tellg();
|
||||
} else if(ts->m_outStream != NULL) {
|
||||
return ts->m_outStream->tellp();
|
||||
} else if(ts->m_ioStream != NULL) {
|
||||
return ts->m_ioStream->tellg();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
TiffStream::seekInt(thandle_t fd, unsigned int offset, int origin)
|
||||
{
|
||||
if(!isOpen(fd)) return false;
|
||||
|
||||
ios::seek_dir org;
|
||||
switch(origin) {
|
||||
case beg:
|
||||
org = ios::beg;
|
||||
break;
|
||||
case cur:
|
||||
org = ios::cur;
|
||||
break;
|
||||
case end:
|
||||
org = ios::end;
|
||||
break;
|
||||
}
|
||||
|
||||
TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
|
||||
if(ts->m_inStream != NULL) {
|
||||
ts->m_inStream->seekg(offset, org);
|
||||
return true;
|
||||
} else if(ts->m_outStream != NULL) {
|
||||
ts->m_outStream->seekp(offset, org);
|
||||
return true;
|
||||
} else if(ts->m_ioStream != NULL) {
|
||||
ts->m_ioStream->seekg(offset, org);
|
||||
ts->m_ioStream->seekp(offset, org);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
TiffStream::isOpen(thandle_t fd)
|
||||
{
|
||||
TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
|
||||
return (ts->m_inStream != NULL ||
|
||||
ts->m_outStream != NULL ||
|
||||
ts->m_ioStream != NULL);
|
||||
}
|
63
contrib/stream/tiffstream.h
Normal file
63
contrib/stream/tiffstream.h
Normal file
@ -0,0 +1,63 @@
|
||||
// tiff stream interface class definition
|
||||
|
||||
#ifndef _TIFF_STREAM_H_
|
||||
#define _TIFF_STREAM_H_
|
||||
|
||||
#include <iostream.h>
|
||||
|
||||
#include "tiffio.h"
|
||||
|
||||
class TiffStream {
|
||||
|
||||
public:
|
||||
// ctor/dtor
|
||||
TiffStream();
|
||||
~TiffStream();
|
||||
|
||||
public:
|
||||
enum SeekDir {
|
||||
beg,
|
||||
cur,
|
||||
end,
|
||||
};
|
||||
|
||||
public:
|
||||
// factory methods
|
||||
TIFF* makeFileStream(iostream* str);
|
||||
TIFF* makeFileStream(istream* str);
|
||||
TIFF* makeFileStream(ostream* str);
|
||||
|
||||
public:
|
||||
// tiff client methods
|
||||
static tsize_t read(thandle_t fd, tdata_t buf, tsize_t size);
|
||||
static tsize_t write(thandle_t fd, tdata_t buf, tsize_t size);
|
||||
static toff_t seek(thandle_t fd, toff_t offset, int origin);
|
||||
static toff_t size(thandle_t fd);
|
||||
static int close(thandle_t fd);
|
||||
static int map(thandle_t fd, tdata_t* phase, toff_t* psize);
|
||||
static void unmap(thandle_t fd, tdata_t base, tsize_t size);
|
||||
|
||||
public:
|
||||
// query method
|
||||
TIFF* getTiffHandle() const { return m_tif; }
|
||||
unsigned int getStreamLength() { return m_streamLength; }
|
||||
|
||||
private:
|
||||
// internal methods
|
||||
unsigned int getSize(thandle_t fd);
|
||||
unsigned int tell(thandle_t fd);
|
||||
bool seekInt(thandle_t fd, unsigned int offset, int origin);
|
||||
bool isOpen(thandle_t fd);
|
||||
|
||||
private:
|
||||
thandle_t m_this;
|
||||
TIFF* m_tif;
|
||||
static const char* m_name;
|
||||
istream* m_inStream;
|
||||
ostream* m_outStream;
|
||||
iostream* m_ioStream;
|
||||
int m_streamLength;
|
||||
|
||||
};
|
||||
|
||||
#endif // _TIFF_STREAM_H_
|
Loading…
Reference in New Issue
Block a user