1
///////////////////////////////////////////////////////////////////////////
3
// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
6
// All rights reserved.
8
// Redistribution and use in source and binary forms, with or without
9
// modification, are permitted provided that the following conditions are
11
// * Redistributions of source code must retain the above copyright
12
// notice, this list of conditions and the following disclaimer.
13
// * Redistributions in binary form must reproduce the above
14
// copyright notice, this list of conditions and the following disclaimer
15
// in the documentation and/or other materials provided with the
17
// * Neither the name of Industrial Light & Magic nor the names of
18
// its contributors may be used to endorse or promote products derived
19
// from this software without specific prior written permission.
21
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
///////////////////////////////////////////////////////////////////////////
36
//-----------------------------------------------------------------------------
40
//-----------------------------------------------------------------------------
42
#include <ImfTileOffsets.h>
50
TileOffsets::TileOffsets (LevelMode mode,
51
int numXLevels, int numYLevels,
52
const int *numXTiles, const int *numYTiles)
55
_numXLevels (numXLevels),
56
_numYLevels (numYLevels)
63
_offsets.resize (_numXLevels);
65
for (unsigned int l = 0; l < _offsets.size(); ++l)
67
_offsets[l].resize (numYTiles[l]);
69
for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
71
_offsets[l][dy].resize (numXTiles[l]);
78
_offsets.resize (_numXLevels * _numYLevels);
80
for (unsigned int ly = 0; ly < _numYLevels; ++ly)
82
for (unsigned int lx = 0; lx < _numXLevels; ++lx)
84
int l = ly * _numXLevels + lx;
85
_offsets[l].resize (numYTiles[ly]);
87
for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
89
_offsets[l][dy].resize (numXTiles[lx]);
99
TileOffsets::anyOffsetsAreInvalid () const
101
for (unsigned int l = 0; l < _offsets.size(); ++l)
102
for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
103
for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
104
if (_offsets[l][dy][dx] <= 0)
112
TileOffsets::findTiles (IStream &is)
114
for (unsigned int l = 0; l < _offsets.size(); ++l)
116
for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
118
for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
120
Int64 tileOffset = is.tellg();
123
Xdr::read <StreamIO> (is, tileX);
126
Xdr::read <StreamIO> (is, tileY);
129
Xdr::read <StreamIO> (is, levelX);
132
Xdr::read <StreamIO> (is, levelY);
135
Xdr::read <StreamIO> (is, dataSize);
137
Xdr::skip <StreamIO> (is, dataSize);
139
if (!isValidTile(tileX, tileY, levelX, levelY))
142
operator () (tileX, tileY, levelX, levelY) = tileOffset;
150
TileOffsets::reconstructFromFile (IStream &is)
153
// Try to reconstruct a missing tile offset table by sequentially
154
// scanning through the file, and recording the offsets in the file
155
// of the tiles we find.
158
Int64 position = is.tellg();
167
// Suppress all exceptions. This function is called only to
168
// reconstruct the tile offset table for incomplete files,
169
// and exceptions are likely.
179
TileOffsets::readFrom (IStream &is, bool &complete)
182
// Read in the tile offsets from the file's tile offset table
185
for (unsigned int l = 0; l < _offsets.size(); ++l)
186
for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
187
for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
188
Xdr::read <StreamIO> (is, _offsets[l][dy][dx]);
191
// Check if any tile offsets are invalid.
193
// Invalid offsets mean that the file is probably incomplete
194
// (the offset table is the last thing written to the file).
195
// Either some process is still busy writing the file, or
196
// writing the file was aborted.
198
// We should still be able to read the existing parts of the
199
// file. In order to do this, we have to make a sequential
200
// scan over the scan tile to reconstruct the tile offset
204
if (anyOffsetsAreInvalid())
207
reconstructFromFile (is);
218
TileOffsets::writeTo (OStream &os) const
221
// Write the tile offset table to the file, and
222
// return the position of the start of the table
226
Int64 pos = os.tellp();
229
Iex::throwErrnoExc ("Cannot determine current file position (%T).");
231
for (unsigned int l = 0; l < _offsets.size(); ++l)
232
for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
233
for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
234
Xdr::write <StreamIO> (os, _offsets[l][dy][dx]);
241
TileOffsets::isEmpty () const
243
for (unsigned int l = 0; l < _offsets.size(); ++l)
244
for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
245
for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
246
if (_offsets[l][dy][dx] != 0)
253
TileOffsets::isValidTile (int dx, int dy, int lx, int ly) const
261
_offsets.size() > 0 &&
262
_offsets[0].size() > dy &&
263
_offsets[0][dy].size() > dx)
272
if (lx < _numXLevels &&
274
_offsets.size() > lx &&
275
_offsets[lx].size() > dy &&
276
_offsets[lx][dy].size() > dx)
285
if (lx < _numXLevels &&
287
_offsets.size() > lx + ly * _numXLevels &&
288
_offsets[lx + ly * _numXLevels].size() > dy &&
289
_offsets[lx + ly * _numXLevels][dy].size() > dx)
306
TileOffsets::operator () (int dx, int dy, int lx, int ly)
309
// Looks up the value of the tile with tile coordinate (dx, dy)
310
// and level number (lx, ly) in the _offsets array, and returns
311
// the cooresponding offset.
318
return _offsets[0][dy][dx];
323
return _offsets[lx][dy][dx];
328
return _offsets[lx + ly * _numXLevels][dy][dx];
333
throw Iex::ArgExc ("Unknown LevelMode format.");
339
TileOffsets::operator () (int dx, int dy, int l)
341
return operator () (dx, dy, l, l);
346
TileOffsets::operator () (int dx, int dy, int lx, int ly) const
349
// Looks up the value of the tile with tile coordinate (dx, dy)
350
// and level number (lx, ly) in the _offsets array, and returns
351
// the cooresponding offset.
358
return _offsets[0][dy][dx];
363
return _offsets[lx][dy][dx];
368
return _offsets[lx + ly * _numXLevels][dy][dx];
373
throw Iex::ArgExc ("Unknown LevelMode format.");
379
TileOffsets::operator () (int dx, int dy, int l) const
381
return operator () (dx, dy, l, l);
1
///////////////////////////////////////////////////////////////////////////
3
// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
6
// All rights reserved.
8
// Redistribution and use in source and binary forms, with or without
9
// modification, are permitted provided that the following conditions are
11
// * Redistributions of source code must retain the above copyright
12
// notice, this list of conditions and the following disclaimer.
13
// * Redistributions in binary form must reproduce the above
14
// copyright notice, this list of conditions and the following disclaimer
15
// in the documentation and/or other materials provided with the
17
// * Neither the name of Industrial Light & Magic nor the names of
18
// its contributors may be used to endorse or promote products derived
19
// from this software without specific prior written permission.
21
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
///////////////////////////////////////////////////////////////////////////
36
//-----------------------------------------------------------------------------
40
//-----------------------------------------------------------------------------
42
#include <ImfTileOffsets.h>
50
TileOffsets::TileOffsets (LevelMode mode,
51
int numXLevels, int numYLevels,
52
const int *numXTiles, const int *numYTiles)
55
_numXLevels (numXLevels),
56
_numYLevels (numYLevels)
63
_offsets.resize (_numXLevels);
65
for (unsigned int l = 0; l < _offsets.size(); ++l)
67
_offsets[l].resize (numYTiles[l]);
69
for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
71
_offsets[l][dy].resize (numXTiles[l]);
78
_offsets.resize (_numXLevels * _numYLevels);
80
for (unsigned int ly = 0; ly < _numYLevels; ++ly)
82
for (unsigned int lx = 0; lx < _numXLevels; ++lx)
84
int l = ly * _numXLevels + lx;
85
_offsets[l].resize (numYTiles[ly]);
87
for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
89
_offsets[l][dy].resize (numXTiles[lx]);
99
TileOffsets::anyOffsetsAreInvalid () const
101
for (unsigned int l = 0; l < _offsets.size(); ++l)
102
for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
103
for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
104
if (_offsets[l][dy][dx] <= 0)
112
TileOffsets::findTiles (IStream &is)
114
for (unsigned int l = 0; l < _offsets.size(); ++l)
116
for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
118
for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
120
Int64 tileOffset = is.tellg();
123
Xdr::read <StreamIO> (is, tileX);
126
Xdr::read <StreamIO> (is, tileY);
129
Xdr::read <StreamIO> (is, levelX);
132
Xdr::read <StreamIO> (is, levelY);
135
Xdr::read <StreamIO> (is, dataSize);
137
Xdr::skip <StreamIO> (is, dataSize);
139
if (!isValidTile(tileX, tileY, levelX, levelY))
142
operator () (tileX, tileY, levelX, levelY) = tileOffset;
150
TileOffsets::reconstructFromFile (IStream &is)
153
// Try to reconstruct a missing tile offset table by sequentially
154
// scanning through the file, and recording the offsets in the file
155
// of the tiles we find.
158
Int64 position = is.tellg();
167
// Suppress all exceptions. This function is called only to
168
// reconstruct the tile offset table for incomplete files,
169
// and exceptions are likely.
179
TileOffsets::readFrom (IStream &is, bool &complete)
182
// Read in the tile offsets from the file's tile offset table
185
for (unsigned int l = 0; l < _offsets.size(); ++l)
186
for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
187
for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
188
Xdr::read <StreamIO> (is, _offsets[l][dy][dx]);
191
// Check if any tile offsets are invalid.
193
// Invalid offsets mean that the file is probably incomplete
194
// (the offset table is the last thing written to the file).
195
// Either some process is still busy writing the file, or
196
// writing the file was aborted.
198
// We should still be able to read the existing parts of the
199
// file. In order to do this, we have to make a sequential
200
// scan over the scan tile to reconstruct the tile offset
204
if (anyOffsetsAreInvalid())
207
reconstructFromFile (is);
218
TileOffsets::writeTo (OStream &os) const
221
// Write the tile offset table to the file, and
222
// return the position of the start of the table
226
Int64 pos = os.tellp();
229
Iex::throwErrnoExc ("Cannot determine current file position (%T).");
231
for (unsigned int l = 0; l < _offsets.size(); ++l)
232
for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
233
for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
234
Xdr::write <StreamIO> (os, _offsets[l][dy][dx]);
241
TileOffsets::isEmpty () const
243
for (unsigned int l = 0; l < _offsets.size(); ++l)
244
for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
245
for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
246
if (_offsets[l][dy][dx] != 0)
253
TileOffsets::isValidTile (int dx, int dy, int lx, int ly) const
261
_offsets.size() > 0 &&
262
_offsets[0].size() > dy &&
263
_offsets[0][dy].size() > dx)
272
if (lx < _numXLevels &&
274
_offsets.size() > lx &&
275
_offsets[lx].size() > dy &&
276
_offsets[lx][dy].size() > dx)
285
if (lx < _numXLevels &&
287
_offsets.size() > lx + ly * _numXLevels &&
288
_offsets[lx + ly * _numXLevels].size() > dy &&
289
_offsets[lx + ly * _numXLevels][dy].size() > dx)
306
TileOffsets::operator () (int dx, int dy, int lx, int ly)
309
// Looks up the value of the tile with tile coordinate (dx, dy)
310
// and level number (lx, ly) in the _offsets array, and returns
311
// the cooresponding offset.
318
return _offsets[0][dy][dx];
323
return _offsets[lx][dy][dx];
328
return _offsets[lx + ly * _numXLevels][dy][dx];
333
throw Iex::ArgExc ("Unknown LevelMode format.");
339
TileOffsets::operator () (int dx, int dy, int l)
341
return operator () (dx, dy, l, l);
346
TileOffsets::operator () (int dx, int dy, int lx, int ly) const
349
// Looks up the value of the tile with tile coordinate (dx, dy)
350
// and level number (lx, ly) in the _offsets array, and returns
351
// the cooresponding offset.
358
return _offsets[0][dy][dx];
363
return _offsets[lx][dy][dx];
368
return _offsets[lx + ly * _numXLevels][dy][dx];
373
throw Iex::ArgExc ("Unknown LevelMode format.");
379
TileOffsets::operator () (int dx, int dy, int l) const
381
return operator () (dx, dy, l, l);