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

📄 imftiledinputfile.cpp

📁 image converter source code
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    //    _tileBuffer->post ();}voidTileBufferTask::execute (){    try    {        //        // Calculate information about the tile        //            Box2i tileRange = Imf::dataWindowForTile (_ifd->tileDesc,                                                  _ifd->minX, _ifd->maxX,                                                  _ifd->minY, _ifd->maxY,                                                  _tileBuffer->dx,                                                  _tileBuffer->dy,                                                  _tileBuffer->lx,                                                  _tileBuffer->ly);            int numPixelsPerScanLine = tileRange.max.x - tileRange.min.x + 1;            int numPixelsInTile = numPixelsPerScanLine *                            (tileRange.max.y - tileRange.min.y + 1);            int sizeOfTile = _ifd->bytesPerPixel * numPixelsInTile;                //        // Uncompress the data, if necessary        //            if (_tileBuffer->compressor && _tileBuffer->dataSize < sizeOfTile)        {            _tileBuffer->format = _tileBuffer->compressor->format();            _tileBuffer->dataSize = _tileBuffer->compressor->uncompressTile		(_tileBuffer->buffer, _tileBuffer->dataSize,		 tileRange, _tileBuffer->uncompressedData);        }        else        {            //            // If the line is uncompressed, it's in XDR format,            // regardless of the compressor's output format.            //                _tileBuffer->format = Compressor::XDR;            _tileBuffer->uncompressedData = _tileBuffer->buffer;        }            //        // Convert the tile of pixel data back from the machine-independent	// representation, and store the result in the frame buffer.        //            const char *readPtr = _tileBuffer->uncompressedData;                                                        // points to where we                                                        // read from in the                                                        // tile block                //        // Iterate over the scan lines in the tile.        //            for (int y = tileRange.min.y; y <= tileRange.max.y; ++y)        {            //            // Iterate over all image channels.            //                        for (unsigned int i = 0; i < _ifd->slices.size(); ++i)            {                const TInSliceInfo &slice = _ifd->slices[i];                    //                // These offsets are used to facilitate both                // absolute and tile-relative pixel coordinates.                //                            int xOffset = slice.xTileCoords * tileRange.min.x;                int yOffset = slice.yTileCoords * tileRange.min.y;                    //                // Fill the frame buffer with pixel data.                //                    if (slice.skip)                {                    //                    // The file contains data for this channel, but                    // the frame buffer contains no slice for this channel.                    //                        skipChannel (readPtr, slice.typeInFile,                                 numPixelsPerScanLine);                }                else                {                    //                    // The frame buffer contains a slice for this channel.                    //                        char *writePtr = slice.base +                                     (y - yOffset) * slice.yStride +                                     (tileRange.min.x - xOffset) *                                     slice.xStride;                    char *endPtr = writePtr +                                   (numPixelsPerScanLine - 1) * slice.xStride;                                                        copyIntoFrameBuffer (readPtr, writePtr, endPtr,                                         slice.xStride,                                         slice.fill, slice.fillValue,                                         _tileBuffer->format,                                         slice.typeInFrameBuffer,                                         slice.typeInFile);                }            }        }    }    catch (std::exception &e)    {        if (!_tileBuffer->hasException)        {            _tileBuffer->exception = e.what ();            _tileBuffer->hasException = true;        }    }    catch (...)    {        if (!_tileBuffer->hasException)        {            _tileBuffer->exception = "unrecognized exception";            _tileBuffer->hasException = true;        }    }}TileBufferTask *newTileBufferTask    (TaskGroup *group,     TiledInputFile::Data *ifd,     int number,     int dx, int dy,     int lx, int ly){    //    // Wait for a tile buffer to become available,    // fill the buffer with raw data from the file,    // and create a new TileBufferTask whose execute()    // method will uncompress the tile and copy the    // tile's pixels into the frame buffer.    //    TileBuffer *tileBuffer = ifd->getTileBuffer (number);    try    {	tileBuffer->wait();		tileBuffer->dx = dx;	tileBuffer->dy = dy;	tileBuffer->lx = lx;	tileBuffer->ly = ly;	tileBuffer->uncompressedData = 0;	readTileData (ifd, dx, dy, lx, ly,		      tileBuffer->buffer,		      tileBuffer->dataSize);    }    catch (...)    {	//	// Reading from the file caused an exception.	// Signal that the tile buffer is free, and	// re-throw the exception.	//	tileBuffer->post();	throw;    }    return new TileBufferTask (group, ifd, tileBuffer);}} // namespaceTiledInputFile::TiledInputFile (const char fileName[], int numThreads):    _data (new Data (true, numThreads)){    //    // This constructor is called when a user    // explicitly wants to read a tiled file.    //    try    {	_data->is = new StdIFStream (fileName);	_data->header.readFrom (*_data->is, _data->version);	initialize();    }    catch (Iex::BaseExc &e)    {	delete _data;	REPLACE_EXC (e, "Cannot open image file "			"\"" << fileName << "\". " << e);	throw;    }    catch (...)    {	delete _data;        throw;    }}TiledInputFile::TiledInputFile (IStream &is, int numThreads):    _data (new Data (false, numThreads)){    //    // This constructor is called when a user    // explicitly wants to read a tiled file.    //    try    {	_data->is = &is;	_data->header.readFrom (*_data->is, _data->version);	initialize();    }    catch (Iex::BaseExc &e)    {	delete _data;	REPLACE_EXC (e, "Cannot open image file "			"\"" << is.fileName() << "\". " << e);	throw;    }    catch (...)    {	delete _data;        throw;    }}TiledInputFile::TiledInputFile    (const Header &header,     IStream *is,     int version,     int numThreads):    _data (new Data (false, numThreads)){    //    // This constructor called by class Imf::InputFile    // when a user wants to just read an image file, and    // doesn't care or know if the file is tiled.    //    _data->is = is;    _data->header = header;    _data->version = version;    initialize();}voidTiledInputFile::initialize (){    if (!isTiled (_data->version))	throw Iex::ArgExc ("Expected a tiled file but the file is not tiled.");    _data->header.sanityCheck (true);    _data->tileDesc = _data->header.tileDescription();    _data->lineOrder = _data->header.lineOrder();    //    // Save the dataWindow information    //        const Box2i &dataWindow = _data->header.dataWindow();    _data->minX = dataWindow.min.x;    _data->maxX = dataWindow.max.x;    _data->minY = dataWindow.min.y;    _data->maxY = dataWindow.max.y;    //    // Precompute level and tile information to speed up utility functions    //    precalculateTileInfo (_data->tileDesc,			  _data->minX, _data->maxX,			  _data->minY, _data->maxY,			  _data->numXTiles, _data->numYTiles,			  _data->numXLevels, _data->numYLevels);        _data->bytesPerPixel = calculateBytesPerPixel (_data->header);    _data->maxBytesPerTileLine = _data->bytesPerPixel * _data->tileDesc.xSize;    _data->tileBufferSize = _data->maxBytesPerTileLine * _data->tileDesc.ySize;    //    // Create all the TileBuffers and allocate their internal buffers    //    for (size_t i = 0; i < _data->tileBuffers.size(); i++)    {        _data->tileBuffers[i] = new TileBuffer (newTileCompressor						  (_data->header.compression(),						   _data->maxBytesPerTileLine,						   _data->tileDesc.ySize,						   _data->header));        if (!_data->is->isMemoryMapped ())            _data->tileBuffers[i]->buffer = new char [_data->tileBufferSize];    }    _data->tileOffsets = TileOffsets (_data->tileDesc.mode,				      _data->numXLevels,				      _data->numYLevels,				      _data->numXTiles,				      _data->numYTiles);    _data->tileOffsets.readFrom (*(_data->is), _data->fileIsComplete);    _data->currentPosition = _data->is->tellg();}TiledInputFile::~TiledInputFile (){    if (!_data->is->isMemoryMapped())        for (size_t i = 0; i < _data->tileBuffers.size(); i++)            delete [] _data->tileBuffers[i]->buffer;    delete _data;}const char *TiledInputFile::fileName () const{    return _data->is->fileName();}const Header &TiledInputFile::header () const{    return _data->header;}intTiledInputFile::version () const{    return _data->version;}void	TiledInputFile::setFrameBuffer (const FrameBuffer &frameBuffer){    Lock lock (*_data);    //    // Set the frame buffer    //    //    // Check if the new frame buffer descriptor is    // compatible with the image file header.    //    const ChannelList &channels = _data->header.channels();    for (FrameBuffer::ConstIterator j = frameBuffer.begin();         j != frameBuffer.end();         ++j)    {        ChannelList::ConstIterator i = channels.find (j.name());        if (i == channels.end())            continue;        if (i.channel().xSampling != j.slice().xSampling ||            i.channel().ySampling != j.slice().ySampling)            THROW (Iex::ArgExc, "X and/or y subsampling factors "				"of \"" << i.name() << "\" channel "				"of input file \"" << fileName() << "\" are "				"not compatible with the frame buffer's "				"subsampling factors.");    }    //    // Initialize the slice table for readPixels().    //    vector<TInSliceInfo> slices;    ChannelList::ConstIterator i = channels.begin();    for (FrameBuffer::ConstIterator j = frameBuffer.begin();         j != frameBuffer.end();         ++j)    {        while (i != channels.end() && strcmp (i.name(), j.name()) < 0)        {            //            // 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;        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -