91
// class MMIFStream -- a memory-mapped implementation of
92
// class IStream based on class std::ifstream
95
class MMIFStream: public IStream
99
//-------------------------------------------------------
100
// A constructor that opens the file with the given name.
101
// It reads the whole file into an internal buffer and
102
// then immediately closes the file.
103
//-------------------------------------------------------
105
MMIFStream (const char fileName[]);
107
virtual ~MMIFStream ();
109
virtual bool isMemoryMapped () const {return true;}
111
virtual bool read (char c[/*n*/], int n);
112
virtual char* readMemoryMapped (int n);
113
virtual Int64 tellg () {return _pos;}
114
virtual void seekg (Int64 pos) {_pos = pos;}
115
virtual void clear () {}
126
MMIFStream::MMIFStream (const char fileName[]):
132
std::ifstream ifs (fileName, ios_base::binary);
135
// Get length of file
138
ifs.seekg (0, ios::end);
139
_length = ifs.tellg();
140
ifs.seekg (0, ios::beg);
146
_buffer = new char [_length];
149
// Read the entire file
152
ifs.read (_buffer, _length);
157
MMIFStream::~MMIFStream ()
164
MMIFStream::read (char c[/*n*/], int n)
166
if ((_pos < 0 || _pos >= _length) && n != 0)
167
throw Iex::InputExc ("Unexpected end of file.");
172
if (_length - _pos <= n2)
178
memcpy (c, &(_buffer[_pos]), n2);
185
MMIFStream::readMemoryMapped (int n)
187
if (_pos < 0 || _pos >= _length)
188
throw Iex::InputExc ("Unexpected end of file.");
190
if (_pos + n > _length)
191
throw Iex::InputExc ("Reading past end of file.");
193
char* retVal = &(_buffer[_pos]);
89
200
writeReadScanLines (const char fileName[],
96
207
// letting the RgbaOutputFile object open the file,
97
208
// make the RgbaOutputFile object use an existing
98
209
// StdOFStream. Read the image back, using an
99
// existing SgdIFStream, and compare the pixels
100
// with the original data.
210
// existing StdIFStream, and compare the pixels
211
// with the original data. Then read the image
212
// back a second time using a memory-mapped
213
// MMIFStream (see above).
103
cout << "scan-line based file" << endl;
216
cout << "scan-line based file:" << endl;
105
218
Header header (width, height);
108
222
remove (fileName);
109
#ifndef HAVE_IOS_BASE
110
std::ofstream os (fileName, ios::binary);
112
223
std::ofstream os (fileName, ios_base::binary);
114
224
StdOFStream ofs (os, fileName);
115
225
RgbaOutputFile out (ofs, header, WRITE_RGBA);
116
226
out.setFrameBuffer (&p1[0][0], 1, width);
121
#ifndef HAVE_IOS_BASE
122
std::ifstream is (fileName, ios::binary|ios::in);
124
232
std::ifstream is (fileName, ios_base::binary);
126
233
StdIFStream ifs (is, fileName);
127
234
RgbaInputFile in (ifs);
136
243
in.setFrameBuffer (&p2[-dy][-dx], 1, w);
137
244
in.readPixels (dw.min.y, dw.max.y);
139
for (int y = 0; y < h; ++y)
141
for (int x = 0; x < w; ++x)
143
assert (p2[y][x].r == p1[y][x].r);
144
assert (p2[y][x].g == p1[y][x].g);
145
assert (p2[y][x].b == p1[y][x].b);
146
assert (p2[y][x].a == p1[y][x].a);
246
cout << ", comparing";
247
for (int y = 0; y < h; ++y)
249
for (int x = 0; x < w; ++x)
251
assert (p2[y][x].r == p1[y][x].r);
252
assert (p2[y][x].g == p1[y][x].g);
253
assert (p2[y][x].b == p1[y][x].b);
254
assert (p2[y][x].a == p1[y][x].a);
260
cout << ", reading (memory-mapped)";
261
MMIFStream ifs (fileName);
262
RgbaInputFile in (ifs);
264
const Box2i &dw = in.dataWindow();
265
int w = dw.max.x - dw.min.x + 1;
266
int h = dw.max.y - dw.min.y + 1;
270
Array2D<Rgba> p2 (h, w);
271
in.setFrameBuffer (&p2[-dy][-dx], 1, w);
272
in.readPixels (dw.min.y, dw.max.y);
274
cout << ", comparing";
275
for (int y = 0; y < h; ++y)
277
for (int x = 0; x < w; ++x)
279
assert (p2[y][x].r == p1[y][x].r);
280
assert (p2[y][x].g == p1[y][x].g);
281
assert (p2[y][x].b == p1[y][x].b);
282
assert (p2[y][x].a == p1[y][x].a);
151
289
remove (fileName);
162
300
// Save a tiled RGBA image, but instead of letting
163
301
// the TiledRgbaOutputFile object open the file, make
164
302
// it use an existing StdOFStream. Read the image back,
165
// using an existing SgdIFStream, and compare the pixels
166
// with the original data.
303
// using an existing StdIFStream, and compare the pixels
304
// with the original data. Then read the image back a
305
// second time using a memory-mapped MMIFStream (see above).
169
cout << "tiled file" << endl;
308
cout << "tiled file:" << endl;
171
310
Header header (width, height);
174
314
remove (fileName);
175
#ifndef HAVE_IOS_BASE
176
std::ofstream os (fileName, ios::binary);
178
315
std::ofstream os (fileName, ios_base::binary);
180
316
StdOFStream ofs (os, fileName);
181
317
TiledRgbaOutputFile out (ofs, header, WRITE_RGBA, 20, 20, ONE_LEVEL);
182
318
out.setFrameBuffer (&p1[0][0], 1, width);
184
for (int dy = 0; dy < out.numYTiles(); ++dy)
185
for (int dx = 0; dx < out.numXTiles(); ++dx)
186
out.writeTile (dx, dy);
319
out.writeTiles (0, out.numXTiles() - 1, 0, out.numYTiles() - 1);
190
#ifndef HAVE_IOS_BASE
191
std::ifstream is (fileName, ios::binary|ios::in);
193
324
std::ifstream is (fileName, ios_base::binary);
195
325
StdIFStream ifs (is, fileName);
196
326
TiledRgbaInputFile in (ifs);
204
334
Array2D<Rgba> p2 (h, w);
205
335
in.setFrameBuffer (&p2[-dy][-dx], 1, w);
207
for (int dy = 0; dy < in.numYTiles(); ++dy)
208
for (int dx = 0; dx < in.numXTiles(); ++dx)
209
in.readTile (dx, dy);
211
for (int y = 0; y < h; ++y)
213
for (int x = 0; x < w; ++x)
215
assert (p2[y][x].r == p1[y][x].r);
216
assert (p2[y][x].g == p1[y][x].g);
217
assert (p2[y][x].b == p1[y][x].b);
218
assert (p2[y][x].a == p1[y][x].a);
336
in.readTiles (0, in.numXTiles() - 1, 0, in.numYTiles() - 1);
338
cout << ", comparing";
339
for (int y = 0; y < h; ++y)
341
for (int x = 0; x < w; ++x)
343
assert (p2[y][x].r == p1[y][x].r);
344
assert (p2[y][x].g == p1[y][x].g);
345
assert (p2[y][x].b == p1[y][x].b);
346
assert (p2[y][x].a == p1[y][x].a);
352
cout << ", reading (memory-mapped)";
353
MMIFStream ifs (fileName);
354
TiledRgbaInputFile in (ifs);
356
const Box2i &dw = in.dataWindow();
357
int w = dw.max.x - dw.min.x + 1;
358
int h = dw.max.y - dw.min.y + 1;
362
Array2D<Rgba> p2 (h, w);
363
in.setFrameBuffer (&p2[-dy][-dx], 1, w);
364
in.readTiles (0, in.numXTiles() - 1, 0, in.numYTiles() - 1);
366
cout << ", comparing";
367
for (int y = 0; y < h; ++y)
369
for (int x = 0; x < w; ++x)
371
assert (p2[y][x].r == p1[y][x].r);
372
assert (p2[y][x].g == p1[y][x].g);
373
assert (p2[y][x].b == p1[y][x].b);
374
assert (p2[y][x].a == p1[y][x].a);
223
381
remove (fileName);
243
401
writeReadScanLines (IMF_TMP_DIR "imf_test_streams.exr", W, H, p1);
245
403
fillPixels2 (p1, W, H);
246
writeReadTiles (IMF_TMP_DIR "imf_test_streams.exr", W, H, p1);
404
writeReadTiles (IMF_TMP_DIR "imf_test_streams2.exr", W, H, p1);
248
406
cout << "ok\n" << endl;