📄 imftiledinputfile.cpp
字号:
bool fill = false;
if (i == channels.end() || strcmp (i.name(), j.name()) > 0)
{
//
// Channel i is present in the frame buffer, but not in the file.
// In the frame buffer, slice j will be filled with a default value.
//
fill = true;
}
slices.push_back (TInSliceInfo (j.slice().type,
fill? j.slice().type: i.channel().type,
j.slice().base,
j.slice().xStride,
j.slice().yStride,
fill,
false, // skip
j.slice().fillValue,
(j.slice().xTileCoords)? 1: 0,
(j.slice().yTileCoords)? 1: 0));
if (i != channels.end() && !fill)
++i;
}
while (i != channels.end())
{
//
// Channel i is present in the file but not
// in the frame buffer; data for channel i
// will be skipped during readPixels().
//
slices.push_back (TInSliceInfo (i.channel().type,
i.channel().type,
0, // base
0, // xStride
0, // yStride
false, // fill
true, // skip
0.0)); // fillValue
++i;
}
//
// Store the new frame buffer.
//
_data->frameBuffer = frameBuffer;
_data->slices = slices;
}
const FrameBuffer &
TiledInputFile::frameBuffer () const
{
Lock lock (*_data);
return _data->frameBuffer;
}
bool
TiledInputFile::isComplete () const
{
return _data->fileIsComplete;
}
void
TiledInputFile::readTiles (int dx1, int dx2, int dy1, int dy2, int lx, int ly)
{
//
// Read a range of tiles from the file into the framebuffer
//
try
{
Lock lock (*_data);
if (_data->slices.size() == 0)
throw Iex::ArgExc ("No frame buffer specified "
"as pixel data destination.");
//
// Determine the first and last tile coordinates in both dimensions.
// We always attempt to read the range of tiles in the order that
// they are stored in the file.
//
if (dx1 > dx2)
std::swap (dx1, dx2);
if (dy1 > dy2)
std::swap (dy1, dy2);
int dyStart = dy1;
int dyStop = dy2 + 1;
int dY = 1;
if (_data->lineOrder == DECREASING_Y)
{
dyStart = dy2;
dyStop = dy1 - 1;
dY = -1;
}
//
// Create a task group for all tile buffer tasks. When the
// task group goes out of scope, the destructor waits until
// all tasks are complete.
//
{
TaskGroup taskGroup;
int tileNumber = 0;
for (int dy = dyStart; dy != dyStop; dy += dY)
{
for (int dx = dx1; dx <= dx2; dx++)
{
if (!isValidTile (dx, dy, lx, ly))
THROW (Iex::ArgExc,
"Tile (" << dx << ", " << dy << ", " <<
lx << "," << ly << ") is not a valid tile.");
ThreadPool::addGlobalTask (newTileBufferTask (&taskGroup,
_data,
tileNumber++,
dx, dy,
lx, ly));
}
}
//
// finish all tasks
//
}
//
// Exeption handling:
//
// TileBufferTask::execute() may have encountered exceptions, but
// those exceptions occurred in another thread, not in the thread
// that is executing this call to TiledInputFile::readTiles().
// TileBufferTask::execute() has caught all exceptions and stored
// the exceptions' what() strings in the tile buffers.
// Now we check if any tile buffer contains a stored exception; if
// this is the case then we re-throw the exception in this thread.
// (It is possible that multiple tile buffers contain stored
// exceptions. We re-throw the first exception we find and
// ignore all others.)
//
const string *exception = 0;
for (int i = 0; i < _data->tileBuffers.size(); ++i)
{
TileBuffer *tileBuffer = _data->tileBuffers[i];
if (tileBuffer->hasException && !exception)
exception = &tileBuffer->exception;
tileBuffer->hasException = false;
}
if (exception)
throw Iex::IoExc (*exception);
}
catch (Iex::BaseExc &e)
{
REPLACE_EXC (e, "Error reading pixel data from image "
"file \"" << fileName() << "\". " << e);
throw;
}
}
void
TiledInputFile::readTiles (int dx1, int dx2, int dy1, int dy2, int l)
{
readTiles (dx1, dx2, dy1, dy2, l, l);
}
void
TiledInputFile::readTile (int dx, int dy, int lx, int ly)
{
readTiles (dx, dx, dy, dy, lx, ly);
}
void
TiledInputFile::readTile (int dx, int dy, int l)
{
readTile (dx, dy, l, l);
}
void
TiledInputFile::rawTileData (int &dx, int &dy,
int &lx, int &ly,
const char *&pixelData,
int &pixelDataSize)
{
try
{
Lock lock (*_data);
if (!isValidTile (dx, dy, lx, ly))
throw Iex::ArgExc ("Tried to read a tile outside "
"the image file's data window.");
TileBuffer *tileBuffer = _data->getTileBuffer (0);
readNextTileData (_data, dx, dy, lx, ly,
tileBuffer->buffer,
pixelDataSize);
pixelData = tileBuffer->buffer;
}
catch (Iex::BaseExc &e)
{
REPLACE_EXC (e, "Error reading pixel data from image "
"file \"" << fileName() << "\". " << e);
throw;
}
}
unsigned int
TiledInputFile::tileXSize () const
{
return _data->tileDesc.xSize;
}
unsigned int
TiledInputFile::tileYSize () const
{
return _data->tileDesc.ySize;
}
LevelMode
TiledInputFile::levelMode () const
{
return _data->tileDesc.mode;
}
LevelRoundingMode
TiledInputFile::levelRoundingMode () const
{
return _data->tileDesc.roundingMode;
}
int
TiledInputFile::numLevels () const
{
if (levelMode() == RIPMAP_LEVELS)
THROW (Iex::LogicExc, "Error calling numLevels() on image "
"file \"" << fileName() << "\" "
"(numLevels() is not defined for files "
"with RIPMAP level mode).");
return _data->numXLevels;
}
int
TiledInputFile::numXLevels () const
{
return _data->numXLevels;
}
int
TiledInputFile::numYLevels () const
{
return _data->numYLevels;
}
bool
TiledInputFile::isValidLevel (int lx, int ly) const
{
if (lx < 0 || ly < 0)
return false;
if (levelMode() == MIPMAP_LEVELS && lx != ly)
return false;
if (lx >= numXLevels() || ly >= numYLevels())
return false;
return true;
}
int
TiledInputFile::levelWidth (int lx) const
{
try
{
return levelSize (_data->minX, _data->maxX, lx,
_data->tileDesc.roundingMode);
}
catch (Iex::BaseExc &e)
{
REPLACE_EXC (e, "Error calling levelWidth() on image "
"file \"" << fileName() << "\". " << e);
throw;
}
}
int
TiledInputFile::levelHeight (int ly) const
{
try
{
return levelSize (_data->minY, _data->maxY, ly,
_data->tileDesc.roundingMode);
}
catch (Iex::BaseExc &e)
{
REPLACE_EXC (e, "Error calling levelHeight() on image "
"file \"" << fileName() << "\". " << e);
throw;
}
}
int
TiledInputFile::numXTiles (int lx) const
{
if (lx < 0 || lx >= _data->numXLevels)
{
THROW (Iex::ArgExc, "Error calling numXTiles() on image "
"file \"" << _data->is->fileName() << "\" "
"(Argument is not in valid range).");
}
return _data->numXTiles[lx];
}
int
TiledInputFile::numYTiles (int ly) const
{
if (ly < 0 || ly >= _data->numYLevels)
{
THROW (Iex::ArgExc, "Error calling numYTiles() on image "
"file \"" << _data->is->fileName() << "\" "
"(Argument is not in valid range).");
}
return _data->numYTiles[ly];
}
Box2i
TiledInputFile::dataWindowForLevel (int l) const
{
return dataWindowForLevel (l, l);
}
Box2i
TiledInputFile::dataWindowForLevel (int lx, int ly) const
{
try
{
return Imf::dataWindowForLevel (_data->tileDesc,
_data->minX, _data->maxX,
_data->minY, _data->maxY,
lx, ly);
}
catch (Iex::BaseExc &e)
{
REPLACE_EXC (e, "Error calling dataWindowForLevel() on image "
"file \"" << fileName() << "\". " << e);
throw;
}
}
Box2i
TiledInputFile::dataWindowForTile (int dx, int dy, int l) const
{
return dataWindowForTile (dx, dy, l, l);
}
Box2i
TiledInputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const
{
try
{
if (!isValidTile (dx, dy, lx, ly))
throw Iex::ArgExc ("Arguments not in valid range.");
return Imf::dataWindowForTile (_data->tileDesc,
_data->minX, _data->maxX,
_data->minY, _data->maxY,
dx, dy, lx, ly);
}
catch (Iex::BaseExc &e)
{
REPLACE_EXC (e, "Error calling dataWindowForTile() on image "
"file \"" << fileName() << "\". " << e);
throw;
}
}
bool
TiledInputFile::isValidTile (int dx, int dy, int lx, int ly) const
{
return ((lx < _data->numXLevels && lx >= 0) &&
(ly < _data->numYLevels && ly >= 0) &&
(dx < _data->numXTiles[lx] && dx >= 0) &&
(dy < _data->numYTiles[ly] && dy >= 0));
}
} // namespace Imf
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -