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

📄 imfoutputfile.cpp

📁 image converter source code
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	    //	    slices.push_back (OutSliceInfo (i.channel().type,					    0, // base					    0, // xStride,					    0, // yStride,					    i.channel().xSampling,					    i.channel().ySampling,					    true)); // zero	}	else	{	    //	    // Channel i is present in the frame buffer.	    //	    slices.push_back (OutSliceInfo (j.slice().type,					    j.slice().base,					    j.slice().xStride,					    j.slice().yStride,					    j.slice().xSampling,					    j.slice().ySampling,					    false)); // zero	}    }    //    // Store the new frame buffer.    //    _data->frameBuffer = frameBuffer;    _data->slices = slices;}const FrameBuffer &OutputFile::frameBuffer () const{    Lock lock (*_data);    return _data->frameBuffer;}void	OutputFile::writePixels (int numScanLines){    try    {        Lock lock (*_data);	if (_data->slices.size() == 0)	    throw Iex::ArgExc ("No frame buffer specified "			       "as pixel data source.");        //        // Maintain two iterators:        //     nextWriteBuffer: next linebuffer to be written to the file        //     nextCompressBuffer: next linebuffer to compress        //        int first = (_data->currentScanLine - _data->minY) /                         _data->linesInBuffer;        int nextWriteBuffer = first;        int nextCompressBuffer;        int stop;        int step;        int scanLineMin;        int scanLineMax;        {            //            // Create a task group for all line buffer tasks. When the            // taskgroup goes out of scope, the destructor waits until	    // all tasks are complete.            //                        TaskGroup taskGroup;                        //            // Determine the range of lineBuffers that intersect the scan	    // line range.  Then add the initial compression tasks to the	    // thread pool.  We always add in at least one task but the	    // individual task might not do anything if numScanLines == 0.            //                if (_data->lineOrder == INCREASING_Y)            {                int last = (_data->currentScanLine + (numScanLines - 1) -                            _data->minY) / _data->linesInBuffer;                    scanLineMin = _data->currentScanLine;                scanLineMax = _data->currentScanLine + numScanLines - 1;                    int numTasks = max (min ((int)_data->lineBuffers.size(),                                         last - first + 1),				    1);                for (int i = 0; i < numTasks; i++)		{                    ThreadPool::addGlobalTask                        (new LineBufferTask (&taskGroup, _data, first + i,                                             scanLineMin, scanLineMax));		}                    nextCompressBuffer = first + numTasks;                stop = last + 1;                step = 1;            }            else            {                int last = (_data->currentScanLine - (numScanLines - 1) -                            _data->minY) / _data->linesInBuffer;                    scanLineMax = _data->currentScanLine;                scanLineMin = _data->currentScanLine - numScanLines + 1;                    int numTasks = max (min ((int)_data->lineBuffers.size(),                                         first - last + 1),				    1);                for (int i = 0; i < numTasks; i++)		{                    ThreadPool::addGlobalTask                        (new LineBufferTask (&taskGroup, _data, first - i,                                             scanLineMin, scanLineMax));		}                    nextCompressBuffer = first - numTasks;                stop = last - 1;                step = -1;            }                        while (true)            {                if (_data->missingScanLines <= 0)                {                    throw Iex::ArgExc ("Tried to write more scan lines "                                       "than specified by the data window.");                }    		//                // Wait until the next line buffer is ready to be written		//                LineBuffer *writeBuffer =		    _data->getLineBuffer (nextWriteBuffer);                writeBuffer->wait();                                int numLines = writeBuffer->scanLineMax -                                writeBuffer->scanLineMin + 1;                _data->missingScanLines -= numLines;    		//                // If the line buffer is only partially full, then it is		// not complete and we cannot write it to disk yet.		//                if (writeBuffer->partiallyFull)                {                    _data->currentScanLine = _data->currentScanLine +                                             step * numLines;                    writeBuffer->post();                        return;                }    		//                // Write the line buffer		//                writePixelData (_data, writeBuffer);                nextWriteBuffer += step;                _data->currentScanLine = _data->currentScanLine +                                         step * numLines;                    #ifdef DEBUG                        assert (_data->currentScanLine ==                            ((_data->lineOrder == INCREASING_Y) ?                             writeBuffer->scanLineMax + 1:                             writeBuffer->scanLineMin - 1));                    #endif                		//                // Release the lock on the line buffer		//                writeBuffer->post();                		//                // If this was the last line buffer in the scanline range		//                if (nextWriteBuffer == stop)                    break;    		//                // If there are no more line buffers to compress,                // then only continue to write out remaining lineBuffers		//                if (nextCompressBuffer == stop)                    continue;    		//                // Add nextCompressBuffer as a compression task		//                ThreadPool::addGlobalTask                    (new LineBufferTask (&taskGroup, _data, nextCompressBuffer,                                         scanLineMin, scanLineMax));                		//                // Update the next line buffer we need to compress		//                nextCompressBuffer += step;            }        	    //            // 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 OutputFile::writePixels().	// 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, "Failed to write pixel data to image "		        "file \"" << fileName() << "\". " << e);	throw;    }}int	OutputFile::currentScanLine () const{    Lock lock (*_data);    return _data->currentScanLine;}void	OutputFile::copyPixels (InputFile &in){    Lock lock (*_data);    //    // Check if this file's and and the InputFile's    // headers are compatible.    //    const Header &hdr = _data->header;    const Header &inHdr = in.header();    if (inHdr.find("tiles") != inHdr.end())	THROW (Iex::ArgExc, "Cannot copy pixels from image "			    "file \"" << in.fileName() << "\" to image "			    "file \"" << fileName() << "\". "                            "The input file is tiled, but the output file is "                            "not. Try using TiledOutputFile::copyPixels "                            "instead.");    if (!(hdr.dataWindow() == inHdr.dataWindow()))	THROW (Iex::ArgExc, "Cannot copy pixels from image "			    "file \"" << in.fileName() << "\" to image "			    "file \"" << fileName() << "\". "                            "The files have different data windows.");    if (!(hdr.lineOrder() == inHdr.lineOrder()))	THROW (Iex::ArgExc, "Quick pixel copy from image "			    "file \"" << in.fileName() << "\" to image "			    "file \"" << fileName() << "\" failed. "			    "The files have different line orders.");    if (!(hdr.compression() == inHdr.compression()))	THROW (Iex::ArgExc, "Quick pixel copy from image "			    "file \"" << in.fileName() << "\" to image "			    "file \"" << fileName() << "\" failed. "			    "The files use different compression methods.");    if (!(hdr.channels() == inHdr.channels()))	THROW (Iex::ArgExc, "Quick pixel copy from image "			    "file \"" << in.fileName() << "\" to image "			    "file \"" << fileName() << "\" failed.  "			    "The files have different channel lists.");    //    // Verify that no pixel data have been written to this file yet.    //    const Box2i &dataWindow = hdr.dataWindow();    if (_data->missingScanLines != dataWindow.max.y - dataWindow.min.y + 1)	THROW (Iex::LogicExc, "Quick pixel copy from image "			      "file \"" << in.fileName() << "\" to image "			      "file \"" << fileName() << "\" failed. "			      "\"" << fileName() << "\" already contains "			      "pixel data.");    //    // Copy the pixel data.    //    while (_data->missingScanLines > 0)    {	const char *pixelData;	int pixelDataSize;	in.rawPixelData (_data->currentScanLine, pixelData, pixelDataSize);	writePixelData (_data, lineBufferMinY (_data->currentScanLine,				               _data->minY,				               _data->linesInBuffer),                        pixelData, pixelDataSize);	_data->currentScanLine += (_data->lineOrder == INCREASING_Y)?				   _data->linesInBuffer: -_data->linesInBuffer;	_data->missingScanLines -= _data->linesInBuffer;    }}voidOutputFile::updatePreviewImage (const PreviewRgba newPixels[]){    Lock lock (*_data);    if (_data->previewPosition <= 0)	THROW (Iex::LogicExc, "Cannot update preview image pixels. "			      "File \"" << fileName() << "\" does not "			      "contain a preview image.");    //    // Store the new pixels in the header's preview image attribute.    //    PreviewImageAttribute &pia =	_data->header.typedAttribute <PreviewImageAttribute> ("preview");    PreviewImage &pi = pia.value();    PreviewRgba *pixels = pi.pixels();    int numPixels = pi.width() * pi.height();    for (int i = 0; i < numPixels; ++i)	pixels[i] = newPixels[i];    //    // Save the current file position, jump to the position in    // the file where the preview image starts, store the new    // preview image, and jump back to the saved file position.    //    Int64 savedPosition = _data->os->tellp();    try    {	_data->os->seekp (_data->previewPosition);	pia.writeValueTo (*_data->os, _data->version);	_data->os->seekp (savedPosition);    }    catch (Iex::BaseExc &e)    {	REPLACE_EXC (e, "Cannot update preview image pixels for "			"file \"" << fileName() << "\". " << e);	throw;    }}void	OutputFile::breakScanLine  (int y, int offset, int length, char c){    Lock lock (*_data);    Int64 position = 	_data->lineOffsets[(y - _data->minY) / _data->linesInBuffer];    if (!position)	THROW (Iex::ArgExc, "Cannot overwrite scan line " << y << ". "			    "The scan line has not yet been stored in "			    "file \"" << fileName() << "\".");    _data->currentPosition = 0;    _data->os->seekp (position + offset);    for (int i = 0; i < length; ++i)	_data->os->write (&c, 1);}} // namespace Imf

⌨️ 快捷键说明

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