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

📄 imfscanlineinputfile.cpp

📁 image converter source code
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            //                const char *readPtr = _lineBuffer->uncompressedData +                                  _ifd->offsetInLineBuffer[y - _ifd->minY];                //            // Iterate over all image channels.            //                for (unsigned int i = 0; i < _ifd->slices.size(); ++i)            {                //                // Test if scan line y of this channel contains any data		// (the scan line contains data only if y % ySampling == 0).                //                    const InSliceInfo &slice = _ifd->slices[i];                    if (modp (y, slice.ySampling) != 0)                    continue;                    //                // Find the x coordinates of the leftmost and rightmost                // sampled pixels (i.e. pixels within the data window                // for which x % xSampling == 0).                //                    int dMinX = divp (_ifd->minX, slice.xSampling);                int dMaxX = divp (_ifd->maxX, slice.xSampling);                    //		// 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, dMaxX - dMinX + 1);                }                else                {                    //                    // The frame buffer contains a slice for this channel.                    //                        char *linePtr  = slice.base +                                        divp (y, slice.ySampling) *                                        slice.yStride;                        char *writePtr = linePtr + dMinX * slice.xStride;                    char *endPtr   = linePtr + dMaxX * slice.xStride;                                        copyIntoFrameBuffer (readPtr, writePtr, endPtr,                                         slice.xStride, slice.fill,                                         slice.fillValue, _lineBuffer->format,                                         slice.typeInFrameBuffer,                                         slice.typeInFile);                }            }        }    }    catch (std::exception &e)    {        if (!_lineBuffer->hasException)        {            _lineBuffer->exception = e.what();            _lineBuffer->hasException = true;        }    }    catch (...)    {        if (!_lineBuffer->hasException)        {            _lineBuffer->exception = "unrecognized exception";            _lineBuffer->hasException = true;        }    }}LineBufferTask *newLineBufferTask    (TaskGroup *group,     ScanLineInputFile::Data *ifd,     int number,     int scanLineMin,     int scanLineMax){    //    // Wait for a line buffer to become available, fill the line    // buffer with raw data from the file if necessary, and create    // a new LineBufferTask whose execute() method will uncompress    // the contents of the buffer and copy the pixels into the    // frame buffer.    //    LineBuffer *lineBuffer = ifd->getLineBuffer (number);    try    {	lineBuffer->wait ();		if (lineBuffer->number != number)	{	    lineBuffer->minY = ifd->minY + number * ifd->linesInBuffer;	    lineBuffer->maxY = lineBuffer->minY + ifd->linesInBuffer - 1;	    	    lineBuffer->number = number;	    lineBuffer->uncompressedData = 0;	    readPixelData (ifd, lineBuffer->minY,			   lineBuffer->buffer,			   lineBuffer->dataSize);	}    }    catch (...)    {	//	// Reading from the file caused an exception.	// Signal that the line buffer is free, and	// re-throw the exception.	//	lineBuffer->number = -1;	lineBuffer->post();	throw;    }        scanLineMin = max (lineBuffer->minY, scanLineMin);    scanLineMax = min (lineBuffer->maxY, scanLineMax);    return new LineBufferTask (group, ifd, lineBuffer,			       scanLineMin, scanLineMax);}} // namespaceScanLineInputFile::ScanLineInputFile    (const Header &header,     IStream *is,     int numThreads):    _data (new Data (is, numThreads)){    try    {	_data->header = header;	_data->lineOrder = _data->header.lineOrder();	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;	size_t maxBytesPerLine = bytesPerLineTable (_data->header,                                                    _data->bytesPerLine);        for (size_t i = 0; i < _data->lineBuffers.size(); i++)        {            _data->lineBuffers[i] = new LineBuffer (newCompressor                                                (_data->header.compression(),                                                 maxBytesPerLine,                                                 _data->header));        }        _data->linesInBuffer =	    numLinesInBuffer (_data->lineBuffers[0]->compressor);        _data->lineBufferSize = maxBytesPerLine * _data->linesInBuffer;        if (!_data->is->isMemoryMapped())            for (size_t i = 0; i < _data->lineBuffers.size(); i++)                _data->lineBuffers[i]->buffer = new char[_data->lineBufferSize];	_data->nextLineBufferMinY = _data->minY - 1;	offsetInLineBufferTable (_data->bytesPerLine,				 _data->linesInBuffer,				 _data->offsetInLineBuffer);	int lineOffsetSize = (dataWindow.max.y - dataWindow.min.y +			      _data->linesInBuffer) / _data->linesInBuffer;	_data->lineOffsets.resize (lineOffsetSize);	readLineOffsets (*_data->is,			 _data->lineOrder,			 _data->lineOffsets,			 _data->fileIsComplete);    }    catch (...)    {	delete _data;	throw;    }}ScanLineInputFile::~ScanLineInputFile (){    if (!_data->is->isMemoryMapped())        for (size_t i = 0; i < _data->lineBuffers.size(); i++)            delete [] _data->lineBuffers[i]->buffer;    delete _data;}const char *ScanLineInputFile::fileName () const{    return _data->is->fileName();}const Header &ScanLineInputFile::header () const{    return _data->header;}intScanLineInputFile::version () const{    return _data->version;}void	ScanLineInputFile::setFrameBuffer (const FrameBuffer &frameBuffer){    Lock lock (*_data);    //    // 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<InSliceInfo> 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 (InSliceInfo (i.channel().type,					   i.channel().type,					   0, // base					   0, // xStride					   0, // yStride					   i.channel().xSampling,					   i.channel().ySampling,					   false,  // fill					   true, // skip					   0.0)); // fillValue	    ++i;	}	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 (InSliceInfo (j.slice().type,				       fill? j.slice().type:				             i.channel().type,				       j.slice().base,				       j.slice().xStride,				       j.slice().yStride,				       j.slice().xSampling,				       j.slice().ySampling,				       fill,				       false, // skip				       j.slice().fillValue));	if (i != channels.end() && !fill)	    ++i;    }    //    // Store the new frame buffer.    //    _data->frameBuffer = frameBuffer;    _data->slices = slices;}const FrameBuffer &ScanLineInputFile::frameBuffer () const{    Lock lock (*_data);    return _data->frameBuffer;}boolScanLineInputFile::isComplete () const{    return _data->fileIsComplete;}void	ScanLineInputFile::readPixels (int scanLine1, int scanLine2){    try    {        Lock lock (*_data);	if (_data->slices.size() == 0)	    throw Iex::ArgExc ("No frame buffer specified "			       "as pixel data destination.");	int scanLineMin = min (scanLine1, scanLine2);	int scanLineMax = max (scanLine1, scanLine2);	if (scanLineMin < _data->minY || scanLineMax > _data->maxY)	    throw Iex::ArgExc ("Tried to read scan line outside "			       "the image file's data window.");        //        // We impose a numbering scheme on the lineBuffers where the first        // scanline is contained in lineBuffer 1.        //        // Determine the first and last lineBuffer numbers in this scanline        // range. We always attempt to read the scanlines in the order that        // they are stored in the file.        //        int start, stop, dl;        if (_data->lineOrder == INCREASING_Y)        {            start = (scanLineMin - _data->minY) / _data->linesInBuffer;            stop  = (scanLineMax - _data->minY) / _data->linesInBuffer + 1;            dl = 1;        }        else        {            start = (scanLineMax - _data->minY) / _data->linesInBuffer;            stop  = (scanLineMin - _data->minY) / _data->linesInBuffer - 1;            dl = -1;        }        //        // Create a task group for all line buffer tasks.  When the	// task group goes out of scope, the destructor waits until	// all tasks are complete.        //                {            TaskGroup taskGroup;                //            // Add the line buffer tasks.            //            // The tasks will execute in the order that they are created            // because we lock the line buffers during construction and the            // constructors are called by the main thread.  Hence, in order	    // for a successive task to execute the previous task which	    // used that line buffer must have completed already.            //                for (int l = start; l != stop; l += dl)            {                ThreadPool::addGlobalTask (newLineBufferTask (&taskGroup,                                                              _data, l,                                                              scanLineMin,                                                              scanLineMax));            }        	    //            // finish all tasks	    //        }        	//	// Exeption handling:	//	// LineBufferTask::execute() may have encountered exceptions, but	// those exceptions occurred in another thread, not in the thread	// that is executing this call to ScanLineInputFile::readPixels().	// LineBufferTask::execute() has caught all exceptions and stored	// the exceptions' what() strings in the line buffers.	// Now we check if any line buffer contains a stored exception; if	// this is the case then we re-throw the exception in this thread.	// (It is possible that multiple line 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->lineBuffers.size(); ++i)	{            LineBuffer *lineBuffer = _data->lineBuffers[i];	    if (lineBuffer->hasException && !exception)		exception = &lineBuffer->exception;	    lineBuffer->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	ScanLineInputFile::readPixels (int scanLine){    readPixels (scanLine, scanLine);}voidScanLineInputFile::rawPixelData (int firstScanLine,				 const char *&pixelData,				 int &pixelDataSize){    try    {        Lock lock (*_data);	if (firstScanLine < _data->minY || firstScanLine > _data->maxY)	{	    throw Iex::ArgExc ("Tried to read scan line outside "			       "the image file's data window.");	}        int minY = lineBufferMinY	    (firstScanLine, _data->minY, _data->linesInBuffer);	readPixelData	    (_data, minY, _data->lineBuffers[0]->buffer, pixelDataSize);	pixelData = _data->lineBuffers[0]->buffer;    }    catch (Iex::BaseExc &e)    {	REPLACE_EXC (e, "Error reading pixel data from image "		        "file \"" << fileName() << "\". " << e);	throw;    }}} // namespace Imf

⌨️ 快捷键说明

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