📄 imftiledinputfile.cpp
字号:
// _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 + -