Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
tif_stream.cxx
Go to the documentation of this file.
1 /* $Id: tif_stream.cxx,v 1.5 2005/07/26 08:11:13 dron Exp $ */
2 
3 /*
4  * Copyright (c) 1988-1996 Sam Leffler
5  * Copyright (c) 1991-1996 Silicon Graphics, Inc.
6  *
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.
14  *
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.
18  *
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
24  * OF THIS SOFTWARE.
25  */
26 
27 /*
28  * TIFF Library UNIX-specific Routines.
29  */
30 #include "tiffiop.h"
31 #include <iostream>
32 
33 using namespace std;
34 
35 class tiffis_data
36 {
37  public:
38 
39  istream *myIS;
40  long myStreamStartPos;
41 };
42 
43 class tiffos_data
44 {
45  public:
46 
47  ostream *myOS;
48  long myStreamStartPos;
49 };
50 
51 static tsize_t
52 _tiffosReadProc(thandle_t, tdata_t, tsize_t)
53 {
54  return 0;
55 }
56 
57 static tsize_t
58 _tiffisReadProc(thandle_t fd, tdata_t buf, tsize_t size)
59 {
60  tiffis_data *data = (tiffis_data *)fd;
61 
62  data->myIS->read((char *)buf, (int)size);
63 
64  return data->myIS->gcount();
65 }
66 
67 static tsize_t
68 _tiffosWriteProc(thandle_t fd, tdata_t buf, tsize_t size)
69 {
70  tiffos_data *data = (tiffos_data *)fd;
71  ostream *os = data->myOS;
72  int pos = os->tellp();
73 
74  os->write((const char *)buf, size);
75 
76  return ((int)os->tellp()) - pos;
77 }
78 
79 static tsize_t
80 _tiffisWriteProc(thandle_t, tdata_t, tsize_t)
81 {
82  return 0;
83 }
84 
85 static toff_t
86 _tiffosSeekProc(thandle_t fd, toff_t off, int whence)
87 {
88  tiffos_data *data = (tiffos_data *)fd;
89  ostream *os = data->myOS;
90 
91  // if the stream has already failed, don't do anything
92  if( os->fail() )
93  return os->tellp();
94 
95  switch(whence) {
96  case SEEK_SET:
97  os->seekp(data->myStreamStartPos + off, ios::beg);
98  break;
99  case SEEK_CUR:
100  os->seekp(off, ios::cur);
101  break;
102  case SEEK_END:
103  os->seekp(off, ios::end);
104  break;
105  }
106 
107  // Attempt to workaround problems with seeking past the end of the
108  // stream. ofstream doesn't have a problem with this but
109  // ostrstream/ostringstream does. In that situation, add intermediate
110  // '\0' characters.
111  if( os->fail() ) {
112  ios::iostate old_state;
113  toff_t origin;
114 
115  old_state = os->rdstate();
116  // reset the fail bit or else tellp() won't work below
117  os->clear(os->rdstate() & ~ios::failbit);
118  switch( whence ) {
119  case SEEK_SET:
120  origin = data->myStreamStartPos;
121  break;
122  case SEEK_CUR:
123  origin = os->tellp();
124  break;
125  case SEEK_END:
126  os->seekp(0, ios::end);
127  origin = os->tellp();
128  break;
129  }
130  // restore original stream state
131  os->clear(old_state);
132 
133  // only do something if desired seek position is valid
134  if( origin + off > data->myStreamStartPos ) {
135  toff_t num_fill;
136 
137  // clear the fail bit
138  os->clear(os->rdstate() & ~ios::failbit);
139 
140  // extend the stream to the expected size
141  os->seekp(0, ios::end);
142  num_fill = origin + off - (toff_t)os->tellp();
143  for( toff_t i = 0; i < num_fill; i++ )
144  os->put('\0');
145 
146  // retry the seek
147  os->seekp(origin + off, ios::beg);
148  }
149  }
150 
151  return os->tellp();
152 }
153 
154 static toff_t
155 _tiffisSeekProc(thandle_t fd, toff_t off, int whence)
156 {
157  tiffis_data *data = (tiffis_data *)fd;
158 
159  switch(whence) {
160  case SEEK_SET:
161  data->myIS->seekg(data->myStreamStartPos + off, ios::beg);
162  break;
163  case SEEK_CUR:
164  data->myIS->seekg(off, ios::cur);
165  break;
166  case SEEK_END:
167  data->myIS->seekg(off, ios::end);
168  break;
169  }
170 
171  return ((long)data->myIS->tellg()) - data->myStreamStartPos;
172 }
173 
174 static toff_t
175 _tiffosSizeProc(thandle_t fd)
176 {
177  tiffos_data *data = (tiffos_data *)fd;
178  ostream *os = data->myOS;
179  toff_t pos = os->tellp();
180  toff_t len;
181 
182  os->seekp(0, ios::end);
183  len = os->tellp();
184  os->seekp(pos);
185 
186  return len;
187 }
188 
189 static toff_t
190 _tiffisSizeProc(thandle_t fd)
191 {
192  tiffis_data *data = (tiffis_data *)fd;
193  int pos = data->myIS->tellg();
194  int len;
195 
196  data->myIS->seekg(0, ios::end);
197  len = data->myIS->tellg();
198  data->myIS->seekg(pos);
199 
200  return len;
201 }
202 
203 static int
204 _tiffosCloseProc(thandle_t fd)
205 {
206  // Our stream was not allocated by us, so it shouldn't be closed by us.
207  delete (tiffos_data *)fd;
208  return 0;
209 }
210 
211 static int
212 _tiffisCloseProc(thandle_t fd)
213 {
214  // Our stream was not allocated by us, so it shouldn't be closed by us.
215  delete (tiffis_data *)fd;
216  return 0;
217 }
218 
219 static int
220 _tiffDummyMapProc(thandle_t , tdata_t* , toff_t* )
221 {
222  return (0);
223 }
224 
225 static void
226 _tiffDummyUnmapProc(thandle_t , tdata_t , toff_t )
227 {
228 }
229 
230 /*
231  * Open a TIFF file descriptor for read/writing.
232  */
233 static TIFF*
234 _tiffStreamOpen(const char* name, const char* mode, void *fd)
235 {
236  TIFF* tif;
237 
238  if( strchr(mode, 'w') ) {
239  tiffos_data *data = new tiffos_data;
240  data->myOS = (ostream *)fd;
241  data->myStreamStartPos = data->myOS->tellp();
242 
243  // Open for writing.
244  tif = TIFFClientOpen(name, mode,
245  (thandle_t) data,
246  _tiffosReadProc, _tiffosWriteProc,
247  _tiffosSeekProc, _tiffosCloseProc,
248  _tiffosSizeProc,
249  _tiffDummyMapProc, _tiffDummyUnmapProc);
250  } else {
251  tiffis_data *data = new tiffis_data;
252  data->myIS = (istream *)fd;
253  data->myStreamStartPos = data->myIS->tellg();
254  // Open for reading.
255  tif = TIFFClientOpen(name, mode,
256  (thandle_t) data,
257  _tiffisReadProc, _tiffisWriteProc,
258  _tiffisSeekProc, _tiffisCloseProc,
259  _tiffisSizeProc,
260  _tiffDummyMapProc, _tiffDummyUnmapProc);
261  }
262 
263  return (tif);
264 }
265 
266 TIFF*
267 TIFFStreamOpen(const char* name, ostream *os)
268 {
269  // If os is either a ostrstream or ostringstream, and has no data
270  // written to it yet, then tellp() will return -1 which will break us.
271  // We workaround this by writing out a dummy character and
272  // then seek back to the beginning.
273  if( !os->fail() && (int)os->tellp() < 0 ) {
274  *os << '\0';
275  os->seekp(0);
276  }
277 
278  // NB: We don't support mapped files with streams so add 'm'
279  return _tiffStreamOpen(name, "wm", os);
280 }
281 
282 TIFF*
283 TIFFStreamOpen(const char* name, istream *is)
284 {
285  // NB: We don't support mapped files with streams so add 'm'
286  return _tiffStreamOpen(name, "rm", is);
287 }
288 
289 /* vim: set ts=8 sts=8 sw=8 noet: */
int32 tsize_t
Definition: tiffio.h:66
void * tdata_t
Definition: tiffio.h:67
voidpf uLong int origin
Definition: ioapi.h:142
#define SEEK_END
Definition: zconf.h:251
STL namespace.
Definition: tiffiop.h:95
png_uint_32 i
Definition: png.h:2640
GLenum GLuint GLenum GLsizei const GLchar * buf
#define SEEK_CUR
Definition: zconf.h:250
TIFF * TIFFClientOpen(const char *name, const char *mode, thandle_t clientdata, TIFFReadWriteProc readproc, TIFFReadWriteProc writeproc, TIFFSeekProc seekproc, TIFFCloseProc closeproc, TIFFSizeProc sizeproc, TIFFMapFileProc mapproc, TIFFUnmapFileProc unmapproc)
Definition: tif_open.c:141
GLenum GLsizei len
GLenum mode
GLsizei GLsizei GLenum GLenum const GLvoid * data
TIFF * TIFFStreamOpen(const char *name, ostream *os)
Definition: tif_stream.cxx:267
GLuint GLuint end
GLuint const GLchar * name
typedef int
Definition: png.h:978
uint32 toff_t
Definition: tiffio.h:68
GLsizeiptr size
void * thandle_t
Definition: tiffio.h:96
#define SEEK_SET
Definition: zconf.h:249