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

📄 imfrgbafile.cpp

📁 对gif
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	Lock lock (*_toYca);
	return _toYca->currentScanLine();
    }
    else
    {
	return _outputFile->currentScanLine();
    }
}


const Header &
RgbaOutputFile::header () const
{
    return _outputFile->header();
}


const FrameBuffer &
RgbaOutputFile::frameBuffer () const
{
    return _outputFile->frameBuffer();
}


const Imath::Box2i &
RgbaOutputFile::displayWindow () const
{
    return _outputFile->header().displayWindow();
}


const Imath::Box2i &
RgbaOutputFile::dataWindow () const
{
    return _outputFile->header().dataWindow();
}


float	
RgbaOutputFile::pixelAspectRatio () const
{
    return _outputFile->header().pixelAspectRatio();
}


const Imath::V2f
RgbaOutputFile::screenWindowCenter () const
{
    return _outputFile->header().screenWindowCenter();
}


float	
RgbaOutputFile::screenWindowWidth () const
{
    return _outputFile->header().screenWindowWidth();
}


LineOrder
RgbaOutputFile::lineOrder () const
{
    return _outputFile->header().lineOrder();
}


Compression
RgbaOutputFile::compression () const
{
    return _outputFile->header().compression();
}


RgbaChannels
RgbaOutputFile::channels () const
{
    return rgbaChannels (_outputFile->header().channels());
}


void		
RgbaOutputFile::updatePreviewImage (const PreviewRgba newPixels[])
{
    _outputFile->updatePreviewImage (newPixels);
}


void		
RgbaOutputFile::setYCRounding (unsigned int roundY, unsigned int roundC)
{
    if (_toYca)
    {
	Lock lock (*_toYca);
	_toYca->setYCRounding (roundY, roundC);
    }
}


void	
RgbaOutputFile::breakScanLine  (int y, int offset, int length, char c)
{
    _outputFile->breakScanLine (y, offset, length, c);
}


class RgbaInputFile::FromYca: public Mutex
{
  public:

     FromYca (InputFile &inputFile, RgbaChannels rgbaChannels);
    ~FromYca ();

    void		setFrameBuffer (Rgba *base,
					size_t xStride,
					size_t yStride);

    void		readPixels (int scanLine1, int scanLine2);

  private:

    void		readPixels (int scanLine);
    void		rotateBuf1 (int d);
    void		rotateBuf2 (int d);
    void		readYCAScanLine (int y, Rgba buf[]);
    void		padTmpBuf ();

    InputFile &		_inputFile;
    bool		_readC;
    int			_xMin;
    int			_yMin;
    int 		_yMax;
    int			_width;
    int			_height;
    int			_currentScanLine;
    LineOrder		_lineOrder;
    V3f			_yw;
    Rgba *		_buf1[N + 2];
    Rgba *		_buf2[3];
    Rgba *		_tmpBuf;
    Rgba *		_fbBase;
    size_t		_fbXStride;
    size_t		_fbYStride;
};


RgbaInputFile::FromYca::FromYca (InputFile &inputFile,
				 RgbaChannels rgbaChannels)
:
    _inputFile (inputFile)
{
    _readC = (rgbaChannels & WRITE_C)? true: false;

    const Box2i dw = _inputFile.header().dataWindow();

    _xMin = dw.min.x;
    _yMin = dw.min.y;
    _yMax = dw.max.y;
    _width  = dw.max.x - dw.min.x + 1;
    _height = dw.max.y - dw.min.y + 1;
    _currentScanLine = dw.min.y - N - 2;
    _lineOrder = _inputFile.header().lineOrder();
    _yw = ywFromHeader (_inputFile.header());

    for (int i = 0; i < N + 2; ++i)
	_buf1[i] = new Rgba[_width];
    
    for (int i = 0; i < 3; ++i)
	_buf2[i] = new Rgba[_width];

    _tmpBuf = new Rgba[_width + N - 1];

    _fbBase = 0;
    _fbXStride = 0;
    _fbYStride = 0;
}


RgbaInputFile::FromYca::~FromYca ()
{
    for (int i = 0; i < N + 2; ++i)
	delete [] _buf1[i];

    for (int i = 0; i < 3; ++i)
	delete [] _buf2[i];

    delete [] _tmpBuf;
}


void
RgbaInputFile::FromYca::setFrameBuffer (Rgba *base,
					size_t xStride,
					size_t yStride)
{
    if (_fbBase == 0)
    {
	FrameBuffer fb;

	fb.insert ("Y",
		   Slice (HALF,					// type
			  (char *) &_tmpBuf[N2 - _xMin].g,	// base
			  sizeof (Rgba),			// xStride
			  0,					// yStride
			  1,					// xSampling
			  1,					// ySampling
			  0.5));				// fillValue

	if (_readC)
	{
	    fb.insert ("RY",
		       Slice (HALF,				// type
			      (char *) &_tmpBuf[N2 - _xMin].r,	// base
			      sizeof (Rgba) * 2,		// xStride
			      0,				// yStride
			      2,				// xSampling
			      2,				// ySampling
			      0.0));				// fillValue

	    fb.insert ("BY",
		       Slice (HALF,				// type
			      (char *) &_tmpBuf[N2 - _xMin].b,	// base
			      sizeof (Rgba) * 2,		// xStride
			      0,				// yStride
			      2,				// xSampling
			      2,				// ySampling
			      0.0));				// fillValue
	}

	fb.insert ("A",
		   Slice (HALF,					// type
			  (char *) &_tmpBuf[N2 - _xMin].a,	// base
			  sizeof (Rgba),			// xStride
			  0,					// yStride
			  1,					// xSampling
			  1,					// ySampling
			  1.0));				// fillValue

	_inputFile.setFrameBuffer (fb);
    }

    _fbBase = base;
    _fbXStride = xStride;
    _fbYStride = yStride;
}


void	
RgbaInputFile::FromYca::readPixels (int scanLine1, int scanLine2)
{
    int minY = min (scanLine1, scanLine2);
    int maxY = max (scanLine1, scanLine2);

    if (_lineOrder == INCREASING_Y)
    {
	for (int y = minY; y <= maxY; ++y)
	    readPixels (y);
    }
    else
    {
	for (int y = maxY; y >= minY; --y)
	    readPixels (y);
    }
}


void	
RgbaInputFile::FromYca::readPixels (int scanLine)
{
    if (_fbBase == 0)
    {
	THROW (Iex::ArgExc, "No frame buffer was specified as the "
			    "pixel data destination for image file "
			    "\"" << _inputFile.fileName() << "\".");
    }

    //
    // In order to convert one scan line to RGB format, we need that
    // scan line plus N2+1 extra scan lines above and N2+1 scan lines
    // below in luminance/chroma format.
    //
    // We allow random access to scan lines, but we buffer partially
    // processed luminance/chroma data in order to make reading pixels
    // in increasing y or decreasing y order reasonably efficient:
    //
    //	_currentScanLine	holds the y coordinate of the scan line
    //				that was most recently read.
    //
    //	_buf1			contains scan lines _currentScanLine-N2-1
    //				through _currentScanLine+N2+1 in
    //				luminance/chroma format.  Odd-numbered
    //				lines contain no chroma data.  Even-numbered
    //				lines have valid chroma data for all pixels.
    //
    //  _buf2			contains scan lines _currentScanLine-1
    //  			through _currentScanLine+1, in RGB format.
    //				Super-saturated pixels (see ImfRgbaYca.h)
    //				have not yet been eliminated.
    //
    // If the scan line we are trying to read now is close enough to
    // _currentScanLine, we don't have to recompute the contents of _buf1
    // and _buf2 from scratch.  We can rotate _buf1 and _buf2, and fill
    // in the missing data.
    //

    int dy = scanLine - _currentScanLine;

    if (abs (dy) < N + 2)
	rotateBuf1 (dy);

    if (abs (dy) < 3)
	rotateBuf2 (dy);

    if (dy < 0)
    {
	{
	    int n = min (-dy, N + 2);
	    int yMin = scanLine - N2 - 1;

	    for (int i = n - 1; i >= 0; --i)
		readYCAScanLine (yMin + i, _buf1[i]);
	}

	{
	    int n = min (-dy, 3);

	    for (int i = 0; i < n; ++i)
	    {
		if ((scanLine + i) & 1)
		{
		    YCAtoRGBA (_yw, _width, _buf1[N2 + i], _buf2[i]);
		}
		else
		{
		    reconstructChromaVert (_width, _buf1 + i, _buf2[i]);
		    YCAtoRGBA (_yw, _width, _buf2[i], _buf2[i]);
		}
	    }
	}
    }
    else
    {
	{
	    int n = min (dy, N + 2);
	    int yMax = scanLine + N2 + 1;

	    for (int i = n - 1; i >= 0; --i)
		readYCAScanLine (yMax - i, _buf1[N + 1 - i]);
	}

	{
	    int n = min (dy, 3);

	    for (int i = 2; i > 2 - n; --i)
	    {
		if ((scanLine + i) & 1)
		{
		    YCAtoRGBA (_yw, _width, _buf1[N2 + i], _buf2[i]);
		}
		else
		{
		    reconstructChromaVert (_width, _buf1 + i, _buf2[i]);
		    YCAtoRGBA (_yw, _width, _buf2[i], _buf2[i]);
		}
	    }
	}
    }

    fixSaturation (_yw, _width, _buf2, _tmpBuf);

    for (int i = 0; i < _width; ++i)
	_fbBase[_fbYStride * scanLine + _fbXStride * (i + _xMin)] = _tmpBuf[i];

    _currentScanLine = scanLine;
}


void
RgbaInputFile::FromYca::rotateBuf1 (int d)
{
    d = modp (d, N + 2);

    Rgba *tmp[N + 2];

    for (int i = 0; i < N + 2; ++i)
	tmp[i] = _buf1[i];

    for (int i = 0; i < N + 2; ++i)
	_buf1[i] = tmp[(i + d) % (N + 2)];
}


void
RgbaInputFile::FromYca::rotateBuf2 (int d)
{
    d = modp (d, 3);

    Rgba *tmp[3];

    for (int i = 0; i < 3; ++i)
	tmp[i] = _buf2[i];

    for (int i = 0; i < 3; ++i)
	_buf2[i] = tmp[(i + d) % 3];
}


void
RgbaInputFile::FromYca::readYCAScanLine (int y, Rgba *buf)
{
    //
    // Clamp y.
    //

    if (y < _yMin)
	y = _yMin;
    else if (y > _yMax)
	y = _yMax - 1;

    //
    // Read scan line y into _tmpBuf.
    //

    _inputFile.readPixels (y);

    //
    // Reconstruct missing chroma samples and copy
    // the scan line into buf.
    //

    if (!_readC)
    {
	for (int i = 0; i < _width; ++i)
	{
	    _tmpBuf[i + N2].r = 0;
	    _tmpBuf[i + N2].b = 0;
	}
    }

    if (y & 1)
    {
	memcpy (buf, _tmpBuf + N2, _width * sizeof (Rgba));
    }
    else
    {
	padTmpBuf();
	reconstructChromaHoriz (_width, _tmpBuf, buf);
    }
}


void
RgbaInputFile::FromYca::padTmpBuf ()
{
    for (int i = 0; i < N2; ++i)
    {
	_tmpBuf[i] = _tmpBuf[N2];
	_tmpBuf[_width + N2 + i] = _tmpBuf[_width + N2 - 2];
    }
}


RgbaInputFile::RgbaInputFile (const char name[], int numThreads):
    _inputFile (new InputFile (name, numThreads)),
    _fromYca (0)
{
    RgbaChannels rgbaChannels = channels();

    if (rgbaChannels & (WRITE_Y | WRITE_C))
	_fromYca = new FromYca (*_inputFile, rgbaChannels);
}


RgbaInputFile::RgbaInputFile (IStream &is, int numThreads):
    _inputFile (new InputFile (is, numThreads)),
    _fromYca (0)
{
    RgbaChannels rgbaChannels = channels();

    if (rgbaChannels & (WRITE_Y | WRITE_C))
	_fromYca = new FromYca (*_inputFile, rgbaChannels);
}


RgbaInputFile::~RgbaInputFile ()
{
    delete _inputFile;
    delete _fromYca;
}


void	
RgbaInputFile::setFrameBuffer (Rgba *base, size_t xStride, size_t yStride)
{
    if (_fromYca)
    {
	Lock lock (*_fromYca);
	_fromYca->setFrameBuffer (base, xStride, yStride);
    }
    else
    {
	size_t xs = xStride * sizeof (Rgba);
	size_t ys = yStride * sizeof (Rgba);

	FrameBuffer fb;

	fb.insert ("R", Slice (HALF,
			       (char *) &base[0].r,
			       xs, ys,
			       1, 1,	// xSampling, ySampling
			       0.0));	// fillValue

	fb.insert ("G", Slice (HALF,
			       (char *) &base[0].g,
			       xs, ys,
			       1, 1,	// xSampling, ySampling
			       0.0));	// fillValue

	fb.insert ("B", Slice (HALF,
			       (char *) &base[0].b,
			       xs, ys,
			       1, 1,	// xSampling, ySampling
			       0.0));	// fillValue

	fb.insert ("A", Slice (HALF,
			       (char *) &base[0].a,
			       xs, ys,
			       1, 1,	// xSampling, ySampling
			       1.0));	// fillValue

	_inputFile->setFrameBuffer (fb);
    }
}


void	
RgbaInputFile::readPixels (int scanLine1, int scanLine2)
{
    if (_fromYca)
    {
	Lock lock (*_fromYca);
	_fromYca->readPixels (scanLine1, scanLine2);
    }
    else
    {
	_inputFile->readPixels (scanLine1, scanLine2);
    }
}


void	
RgbaInputFile::readPixels (int scanLine)
{
    readPixels (scanLine, scanLine);
}


bool
RgbaInputFile::isComplete () const
{
    return _inputFile->isComplete();
}


const Header &
RgbaInputFile::header () const
{
    return _inputFile->header();
}


const char *
RgbaInputFile::fileName () const
{
    return _inputFile->fileName();
}


const FrameBuffer &	
RgbaInputFile::frameBuffer () const
{
    return _inputFile->frameBuffer();
}


const Imath::Box2i &
RgbaInputFile::displayWindow () const
{
    return _inputFile->header().displayWindow();
}


const Imath::Box2i &
RgbaInputFile::dataWindow () const
{
    return _inputFile->header().dataWindow();
}


float	
RgbaInputFile::pixelAspectRatio () const
{
    return _inputFile->header().pixelAspectRatio();
}


const Imath::V2f	
RgbaInputFile::screenWindowCenter () const
{
    return _inputFile->header().screenWindowCenter();
}


float	
RgbaInputFile::screenWindowWidth () const
{
    return _inputFile->header().screenWindowWidth();
}


LineOrder
RgbaInputFile::lineOrder () const
{
    return _inputFile->header().lineOrder();
}


Compression
RgbaInputFile::compression () const
{
    return _inputFile->header().compression();
}


RgbaChannels	
RgbaInputFile::channels () const
{
    return rgbaChannels (_inputFile->header().channels());
}


int
RgbaInputFile::version () const
{
    return _inputFile->version();
}


} // namespace Imf

⌨️ 快捷键说明

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