⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imftiledinputfile.cpp

📁 对gif
💻 CPP
📖 第 1 页 / 共 3 页
字号:

        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 + -