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

📄 imftiledoutputfile.cpp

📁 image converter source code
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            dyStart = dy2;            dyStop  = dy1 - 1;            dY      = -1;        }                int numTiles = (dx2 - dx1 + 1) * (dy2 - dy1 + 1);        int numTasks = min ((int)_data->tileBuffers.size(), numTiles);        //        // 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;                //            // Add in the initial compression tasks to the thread pool            //                int nextCompBuffer = 0;	    int dxComp         = dx1;	    int dyComp         = dyStart;            while (nextCompBuffer < numTasks)            {                ThreadPool::addGlobalTask (new TileBufferTask (&taskGroup,                                                               _data,                                                               nextCompBuffer++,                                                               dxComp, dyComp,                                                               lx, ly));                dxComp++;                if (dxComp > dx2)                {                    dxComp = dx1;                    dyComp += dY;                }            }                        //            // Write the compressed buffers and add in more compression	    // tasks until done            //                int nextWriteBuffer = 0;	    int dxWrite         = dx1;	    int dyWrite         = dyStart;            while (nextWriteBuffer < numTiles)            {		//                // Wait until the nextWriteBuffer is ready to be written		//                TileBuffer* writeBuffer =                                    _data->getTileBuffer (nextWriteBuffer);                writeBuffer->wait();    		//                // Write the tilebuffer		//                bufferedTileWrite (_data, dxWrite, dyWrite, lx, ly,                                   writeBuffer->dataPtr,                                   writeBuffer->dataSize);                		//                // Release the lock on nextWriteBuffer		//                writeBuffer->post();                		//                // If there are no more tileBuffers to compress, then		// only continue to write out remaining tileBuffers,		// otherwise keep adding compression tasks.		//                if (nextCompBuffer < numTiles)                {		    //                    // add nextCompBuffer as a compression Task		    //                    ThreadPool::addGlobalTask			(new TileBufferTask (&taskGroup,					     _data,					     nextCompBuffer,                                             dxComp, dyComp,					     lx, ly));                }                    nextWriteBuffer++;                dxWrite++;                if (dxWrite > dx2)                {                    dxWrite = dx1;                    dyWrite += dY;                }                                    nextCompBuffer++;                dxComp++;                if (dxComp > dx2)                {                    dxComp = dx1;                    dyComp += dY;                }            }	    //            // 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 TiledOutputFile::writeTiles().	// 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, "Failed to write pixel data to image "                        "file \"" << fileName() << "\". " << e);        throw;    }}void	TiledOutputFile::writeTiles (int dx1, int dxMax, int dyMin, int dyMax, int l){    writeTiles (dx1, dxMax, dyMin, dyMax, l, l);}void	TiledOutputFile::writeTile (int dx, int dy, int lx, int ly){    writeTiles (dx, dx, dy, dy, lx, ly);}voidTiledOutputFile::writeTile (int dx, int dy, int l){    writeTile(dx, dy, l, l);}void	TiledOutputFile::copyPixels (TiledInputFile &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 (!hdr.hasTileDescription() || !inHdr.hasTileDescription())        THROW (Iex::ArgExc, "Cannot perform a quick pixel copy from image "			    "file \"" << in.fileName() << "\" to image "			    "file \"" << fileName() << "\".  The "                            "output file is tiled, but the input file is not.  "                            "Try using OutputFile::copyPixels() instead.");    if (!(hdr.tileDescription() == inHdr.tileDescription()))        THROW (Iex::ArgExc, "Quick pixel copy from image "			    "file \"" << in.fileName() << "\" to image "			    "file \"" << fileName() << "\" failed. "			    "The files have different tile descriptions.");    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.    //    if (!_data->tileOffsets.isEmpty())        THROW (Iex::LogicExc, "Quick pixel copy from image "			      "file \"" << in.fileName() << "\" to image "			      "file \"" << _data->os->fileName() << "\" "                              "failed. \"" << fileName() << "\" "                              "already contains pixel data.");    //    // Calculate the total number of tiles in the file    //    int numAllTiles = 0;    switch (levelMode ())    {      case ONE_LEVEL:      case MIPMAP_LEVELS:        for (size_t i_l = 0; i_l < numLevels (); ++i_l)            numAllTiles += numXTiles (i_l) * numYTiles (i_l);        break;      case RIPMAP_LEVELS:        for (size_t i_ly = 0; i_ly < numYLevels (); ++i_ly)            for (size_t i_lx = 0; i_lx < numXLevels (); ++i_lx)                numAllTiles += numXTiles (i_lx) * numYTiles (i_ly);        break;      default:        throw Iex::ArgExc ("Unknown LevelMode format.");    }    for (int i = 0; i < numAllTiles; ++i)    {        const char *pixelData;        int pixelDataSize;                int dx = _data->nextTileToWrite.dx;        int dy = _data->nextTileToWrite.dy;        int lx = _data->nextTileToWrite.lx;        int ly = _data->nextTileToWrite.ly;        in.rawTileData (dx, dy, lx, ly, pixelData, pixelDataSize);        writeTileData (_data, dx, dy, lx, ly, pixelData, pixelDataSize);    }}void	TiledOutputFile::copyPixels (InputFile &in){    copyPixels (*in.tFile());}unsigned intTiledOutputFile::tileXSize () const{    return _data->tileDesc.xSize;}unsigned intTiledOutputFile::tileYSize () const{    return _data->tileDesc.ySize;}LevelModeTiledOutputFile::levelMode () const{    return _data->tileDesc.mode;}LevelRoundingModeTiledOutputFile::levelRoundingMode () const{    return _data->tileDesc.roundingMode;}intTiledOutputFile::numLevels () const{    if (levelMode() == RIPMAP_LEVELS)	THROW (Iex::LogicExc, "Error calling numLevels() on image "			      "file \"" << fileName() << "\" "			      "(numLevels() is not defined for RIPMAPs).");    return _data->numXLevels;}intTiledOutputFile::numXLevels () const{    return _data->numXLevels;}intTiledOutputFile::numYLevels () const{    return _data->numYLevels;}bool	TiledOutputFile::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;}intTiledOutputFile::levelWidth (int lx) const{    try    {	int retVal = levelSize (_data->minX, _data->maxX, lx,			        _data->tileDesc.roundingMode);                return retVal;    }    catch (Iex::BaseExc &e)    {	REPLACE_EXC (e, "Error calling levelWidth() on image "			"file \"" << fileName() << "\". " << e);	throw;    }}intTiledOutputFile::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;    }}intTiledOutputFile::numXTiles (int lx) const{    if (lx < 0 || lx >= _data->numXLevels)	THROW (Iex::LogicExc, "Error calling numXTiles() on image "			      "file \"" << _data->os->fileName() << "\" "			      "(Argument is not in valid range).");    return _data->numXTiles[lx];}intTiledOutputFile::numYTiles (int ly) const{   if (ly < 0 || ly >= _data->numYLevels)	THROW (Iex::LogicExc, "Error calling numXTiles() on image "			      "file \"" << _data->os->fileName() << "\" "			      "(Argument is not in valid range).");    return _data->numYTiles[ly];}Box2iTiledOutputFile::dataWindowForLevel (int l) const{    return dataWindowForLevel (l, l);}Box2iTiledOutputFile::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;    }}Box2iTiledOutputFile::dataWindowForTile (int dx, int dy, int l) const{    return dataWindowForTile (dx, dy, l, l);}Box2iTiledOutputFile::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;    }}boolTiledOutputFile::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));}voidTiledOutputFile::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;    }}voidTiledOutputFile::breakTile     (int dx, int dy,     int lx, int ly,     int offset,     int length,     char c){    Lock lock (*_data);    Int64 position = _data->tileOffsets (dx, dy, lx, ly);    if (!position)	THROW (Iex::ArgExc,	       "Cannot overwrite tile "	       "(" << dx << ", " << dy << ", " << lx << "," << ly << "). "	       "The tile 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 + -