1// tiff stream interface class implementation
2
3#include "tiffstream.h"
4
5const char* TiffStream::m_name = "TiffStream";
6
7TiffStream::TiffStream()
8{
9    m_tif = NULL;
10
11
12    m_inStream = NULL;
13	m_outStream = NULL;
14	m_ioStream = NULL;
15
16	m_streamLength = 0;
17
18	m_this = reinterpret_cast<thandle_t>(this);
19};
20
21TiffStream::~TiffStream()
22{
23    if(m_tif != NULL) TIFFClose(m_tif);
24}
25
26TIFF*
27TiffStream::makeFileStream(istream* str)
28{
29    m_inStream = str;
30	m_outStream = NULL;
31	m_ioStream = NULL;
32    m_streamLength = getSize(m_this);
33
34    m_tif =  TIFFClientOpen(m_name,
35                           "r",
36						   m_this,
37						   read,
38						   write,
39						   seek,
40						   close,
41						   size,
42						   map,
43						   unmap);
44    return m_tif;
45}
46
47TIFF*
48TiffStream::makeFileStream(ostream* str)
49{
50	m_inStream = NULL;
51    m_outStream = str;
52	m_ioStream = NULL;
53	m_streamLength = getSize(m_this);
54
55	m_tif =  TIFFClientOpen(m_name,
56                           "w",
57						   m_this,
58						   read,
59						   write,
60						   seek,
61						   close,
62						   size,
63						   map,
64						   unmap);
65    return m_tif;
66}
67
68TIFF*
69TiffStream::makeFileStream(iostream* str)
70{
71	m_inStream = NULL;
72	m_outStream = NULL;
73    m_ioStream = str;
74	m_streamLength = getSize(m_this);
75
76    m_tif =  TIFFClientOpen(m_name,
77	                       "r+w",
78						   m_this,
79						   read,
80						   write,
81						   seek,
82						   close,
83						   size,
84						   map,
85						   unmap);
86    return m_tif;
87}
88
89tsize_t
90TiffStream::read(thandle_t fd, tdata_t buf, tsize_t size)
91{
92	istream* istr;
93	TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
94    if(ts->m_inStream != NULL) {
95	    istr = ts->m_inStream;
96	} else if(ts->m_ioStream != NULL) {
97	    istr = ts->m_ioStream;
98	}
99
100	int remain = ts->m_streamLength - ts->tell(fd);
101	int actual = remain < size ? remain : size;
102	istr->read(reinterpret_cast<char*>(buf), actual);
103    return istr->gcount();
104}
105
106tsize_t
107TiffStream::write(thandle_t fd, tdata_t buf, tsize_t size)
108{
109	TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
110	ostream* ostr;
111	if(ts->m_outStream != NULL) {
112	    ostr = ts->m_outStream;
113	} else if(ts->m_ioStream != NULL) {
114	    ostr = ts->m_ioStream;
115	}
116
117	streampos start = ostr->tellp();
118	ostr->write(reinterpret_cast<const char*>(buf), size);
119	return ostr->tellp() - start;
120}
121
122toff_t
123TiffStream::seek(thandle_t fd, toff_t offset, int origin)
124{
125    TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
126    if(ts->seekInt(fd, offset, origin) == true) return offset;
127	else return -1;
128}
129
130int
131TiffStream::close(thandle_t fd)
132{
133    TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
134	if(ts->m_inStream != NULL) {
135		ts->m_inStream = NULL;
136		return 0;
137	} else if(ts->m_outStream != NULL) {
138		ts->m_outStream = NULL;
139		return 0;
140	} else if(ts->m_ioStream != NULL) {
141		ts->m_ioStream = NULL;
142		return 0;
143	}
144    return -1;
145}
146
147toff_t
148TiffStream::size(thandle_t fd)
149{
150    TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
151    return ts->getSize(fd);
152}
153
154int
155TiffStream::map(thandle_t fd, tdata_t* phase, toff_t* psize)
156{
157    return 0;
158}
159
160void
161TiffStream::unmap(thandle_t fd, tdata_t base, tsize_t size)
162{
163}
164
165unsigned int
166TiffStream::getSize(thandle_t fd)
167{
168	if(!isOpen(fd)) return 0;
169
170    unsigned int pos = tell(fd);
171	seekInt(fd, 0, end);
172	unsigned int size = tell(fd);
173	seekInt(fd, pos, beg);
174
175	return size;
176}
177
178unsigned int
179TiffStream::tell(thandle_t fd)
180{
181    TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
182    if(ts->m_inStream != NULL) {
183	    return ts->m_inStream->tellg();
184	} else if(ts->m_outStream != NULL) {
185	    return ts->m_outStream->tellp();
186	} else if(ts->m_ioStream != NULL) {
187		return ts->m_ioStream->tellg();
188	}
189	return 0;
190}
191
192bool
193TiffStream::seekInt(thandle_t fd, unsigned int offset, int origin)
194{
195	if(!isOpen(fd)) return false;
196
197	ios::seek_dir org;
198	switch(origin) {
199	case beg:
200		org = ios::beg;
201		break;
202	case cur:
203		org = ios::cur;
204		break;
205	case end:
206		org = ios::end;
207		break;
208	}
209
210	TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
211    if(ts->m_inStream != NULL) {
212	    ts->m_inStream->seekg(offset, org);
213		return true;
214	} else if(ts->m_outStream != NULL) {
215	    ts->m_outStream->seekp(offset, org);
216		return true;
217	} else if(ts->m_ioStream != NULL) {
218	    ts->m_ioStream->seekg(offset, org);
219		ts->m_ioStream->seekp(offset, org);
220		return true;
221	}
222    return false;
223}
224
225bool
226TiffStream::isOpen(thandle_t fd)
227{
228	TiffStream* ts = reinterpret_cast<TiffStream*>(fd);
229	return (ts->m_inStream != NULL ||
230		   ts->m_outStream != NULL ||
231		   ts->m_ioStream != NULL);
232}/*
233 * Local Variables:
234 * mode: c++
235 * c-basic-offset: 8
236 * fill-column: 78
237 * End:
238 */
239