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

📄 imfb44compressor.cpp

📁 image converter source code
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    //    // We can support uncompressed data in the machine's native    // format only if all image channels are of type HALF.    //    assert (sizeof (unsigned short) == pixelTypeSize (HALF));    if (_numChans == numHalfChans)	_format = NATIVE;}B44Compressor::~B44Compressor (){    delete [] _tmpBuffer;    delete [] _outBuffer;    delete [] _channelData;}intB44Compressor::numScanLines () const{    return _numScanLines;}Compressor::FormatB44Compressor::format () const{    return _format;}intB44Compressor::compress (const char *inPtr,			 int inSize,			 int minY,			 const char *&outPtr){    return compress (inPtr,		     inSize,		     Box2i (V2i (_minX, minY),			    V2i (_maxX, minY + numScanLines() - 1)),		     outPtr);}intB44Compressor::compressTile (const char *inPtr,			     int inSize,			     Imath::Box2i range,			     const char *&outPtr){    return compress (inPtr, inSize, range, outPtr);}intB44Compressor::uncompress (const char *inPtr,			   int inSize,			   int minY,			   const char *&outPtr){    return uncompress (inPtr,		       inSize,		       Box2i (V2i (_minX, minY),			      V2i (_maxX, minY + numScanLines() - 1)),		       outPtr);}intB44Compressor::uncompressTile (const char *inPtr,			       int inSize,			       Imath::Box2i range,			       const char *&outPtr){    return uncompress (inPtr, inSize, range, outPtr);}intB44Compressor::compress (const char *inPtr,			 int inSize,			 Imath::Box2i range,			 const char *&outPtr){    //    // Compress a block of pixel data:  First copy the input pixels    // from the input buffer into _tmpBuffer, rearranging them such    // that blocks of 4x4 pixels of a single channel can be accessed    // conveniently.  Then compress each 4x4 block of HALF pixel data    // and append the result to the output buffer.  Copy UINT and    // FLOAT data to the output buffer without compressing them.    //    outPtr = _outBuffer;    if (inSize == 0)    {	//	// Special case - empty input buffer.	//	return 0;    }    //    // For each channel, detemine how many pixels are stored    // in the input buffer, and where those pixels will be    // placed in _tmpBuffer.    //    int minX = range.min.x;    int maxX = min (range.max.x, _maxX);    int minY = range.min.y;    int maxY = min (range.max.y, _maxY);        unsigned short *tmpBufferEnd = _tmpBuffer;    int i = 0;    for (ChannelList::ConstIterator c = _channels.begin();	 c != _channels.end();	 ++c, ++i)    {	ChannelData &cd = _channelData[i];	cd.start = tmpBufferEnd;	cd.end = cd.start;	cd.nx = numSamples (c.channel().xSampling, minX, maxX);	cd.ny = numSamples (c.channel().ySampling, minY, maxY);	tmpBufferEnd += cd.nx * cd.ny * cd.size;    }    if (_format == XDR)    {	//	// The data in the input buffer are in the machine-independent	// Xdr format.  Copy the HALF channels into _tmpBuffer and	// convert them back into native format for compression.	// Copy UINT and FLOAT channels verbatim into _tmpBuffer.	//	for (int y = minY; y <= maxY; ++y)	{	    for (int i = 0; i < _numChans; ++i)	    {		ChannelData &cd = _channelData[i];		if (modp (y, cd.ys) != 0)		    continue;		if (cd.type == HALF)		{		    for (int x = cd.nx; x > 0; --x)		    {			Xdr::read <CharPtrIO> (inPtr, *cd.end);			++cd.end;		    }		}		else		{		    int n = cd.nx * cd.size;		    memcpy (cd.end, inPtr, n * sizeof (unsigned short));		    inPtr += n * sizeof (unsigned short);		    cd.end += n;		}	    }	}    }    else    {	//	// The input buffer contains only HALF channels, and they	// are in native, machine-dependent format.  Copy the pixels	// into _tmpBuffer.	//	for (int y = minY; y <= maxY; ++y)	{	    for (int i = 0; i < _numChans; ++i)	    {		ChannelData &cd = _channelData[i];		#if defined (DEBUG)		    assert (cd.type == HALF);		#endif		if (modp (y, cd.ys) != 0)		    continue;		int n = cd.nx * cd.size;		memcpy (cd.end, inPtr, n * sizeof (unsigned short));		inPtr  += n * sizeof (unsigned short);		cd.end += n;	    }	}    }    //    // The pixels for each channel have been packed into a contiguous    // block in _tmpBuffer.  HALF channels are in native format; UINT    // and FLOAT channels are in Xdr format.    //    #if defined (DEBUG)	for (int i = 1; i < _numChans; ++i)	    assert (_channelData[i-1].end == _channelData[i].start);	assert (_channelData[_numChans-1].end == tmpBufferEnd);    #endif    //    // For each HALF channel, split the data in _tmpBuffer into 4x4    // pixel blocks.  Compress each block and append the compressed    // data to the output buffer.    //    // UINT and FLOAT channels are copied from _tmpBuffer into the    // output buffer without further processing.    //    char *outEnd = _outBuffer;    for (int i = 0; i < _numChans; ++i)    {	ChannelData &cd = _channelData[i];		if (cd.type != HALF)	{	    //	    // UINT or FLOAT channel.	    //	    int n = cd.nx * cd.ny * cd.size * sizeof (unsigned short);	    memcpy (outEnd, cd.start, n);	    outEnd += n;	    continue;	}		//	// HALF channel	//	for (int y = 0; y < cd.ny; y += 4)	{	    //	    // Copy the next 4x4 pixel block into array s.	    // If the width, cd.nx, or the height, cd.ny, of	    // the pixel data in _tmpBuffer is not divisible	    // by 4, then pad the data by repeating the	    // rightmost column and the bottom row.	    // 	    unsigned short *row0 = cd.start + y * cd.nx;	    unsigned short *row1 = row0 + cd.nx;	    unsigned short *row2 = row1 + cd.nx;	    unsigned short *row3 = row2 + cd.nx;	    if (y + 3 >= cd.ny)	    {		if (y + 1 >= cd.ny)		    row1 = row0;		if (y + 2 >= cd.ny)		    row2 = row1;		row3 = row2;	    }	    for (int x = 0; x < cd.nx; x += 4)	    {		unsigned short s[16];		if (x + 3 >= cd.nx)		{		    int n = cd.nx - x;		    for (int i = 0; i < 4; ++i)		    {			int j = min (i, n - 1);			s[i +  0] = row0[j];			s[i +  4] = row1[j];			s[i +  8] = row2[j];			s[i + 12] = row3[j];		    }		}		else		{		    memcpy (&s[ 0], row0, 4 * sizeof (unsigned short));		    memcpy (&s[ 4], row1, 4 * sizeof (unsigned short));		    memcpy (&s[ 8], row2, 4 * sizeof (unsigned short));		    memcpy (&s[12], row3, 4 * sizeof (unsigned short));		}		row0 += 4;		row1 += 4;		row2 += 4;		row3 += 4;		//		// Compress the contents of array s and append the		// results to the output buffer.		//		if (cd.pLinear)		    convertFromLinear (s);		outEnd += pack (s, (unsigned char *) outEnd,				_optFlatFields, !cd.pLinear);	    }	}    }    return outEnd - _outBuffer;}intB44Compressor::uncompress (const char *inPtr,			   int inSize,			   Imath::Box2i range,			   const char *&outPtr){    //    // This function is the reverse of the compress() function,    // above.  First all pixels are moved from the input buffer    // into _tmpBuffer.  UINT and FLOAT channels are copied    // verbatim; HALF channels are uncompressed in blocks of    // 4x4 pixels.  Then the pixels in _tmpBuffer are copied    // into the output buffer and rearranged such that the data    // for for each scan line form a contiguous block.    //    outPtr = _outBuffer;    if (inSize == 0)    {	return 0;    }    int minX = range.min.x;    int maxX = min (range.max.x, _maxX);    int minY = range.min.y;    int maxY = min (range.max.y, _maxY);        unsigned short *tmpBufferEnd = _tmpBuffer;    int i = 0;    for (ChannelList::ConstIterator c = _channels.begin();	 c != _channels.end();	 ++c, ++i)    {	ChannelData &cd = _channelData[i];	cd.start = tmpBufferEnd;	cd.end = cd.start;	cd.nx = numSamples (c.channel().xSampling, minX, maxX);	cd.ny = numSamples (c.channel().ySampling, minY, maxY);	tmpBufferEnd += cd.nx * cd.ny * cd.size;    }    for (int i = 0; i < _numChans; ++i)    {	ChannelData &cd = _channelData[i];	if (cd.type != HALF)	{	    //	    // UINT or FLOAT channel.	    //	    int n = cd.nx * cd.ny * cd.size * sizeof (unsigned short);	    if (inSize < n)		notEnoughData();	    memcpy (cd.start, inPtr, n);	    inPtr += n;	    inSize -= n;	    continue;	}	//	// HALF channel	//	for (int y = 0; y < cd.ny; y += 4)	{	    unsigned short *row0 = cd.start + y * cd.nx;	    unsigned short *row1 = row0 + cd.nx;	    unsigned short *row2 = row1 + cd.nx;	    unsigned short *row3 = row2 + cd.nx;	    for (int x = 0; x < cd.nx; x += 4)	    {		unsigned short s[16]; 		if (inSize < 3)		    notEnoughData();		if (((const unsigned char *)inPtr)[2] == 0xfc)		{		    unpack3 ((const unsigned char *)inPtr, s);		    inPtr += 3;		    inSize -= 3;		}		else		{		    if (inSize < 14)			notEnoughData();		    unpack14 ((const unsigned char *)inPtr, s);		    inPtr += 14;		    inSize -= 14;		}		if (cd.pLinear)		    convertToLinear (s);		int n = (x + 3 < cd.nx)?			    4 * sizeof (unsigned short) :			    (cd.nx - x) * sizeof (unsigned short);		if (y + 3 < cd.ny)		{		    memcpy (row0, &s[ 0], n);		    memcpy (row1, &s[ 4], n);		    memcpy (row2, &s[ 8], n);		    memcpy (row3, &s[12], n);		}		else		{		    memcpy (row0, &s[ 0], n);		    if (y + 1 < cd.ny)			memcpy (row1, &s[ 4], n);		    if (y + 2 < cd.ny)			memcpy (row2, &s[ 8], n);		}		row0 += 4;		row1 += 4;		row2 += 4;		row3 += 4;	    }	}    }    char *outEnd = _outBuffer;    if (_format == XDR)    {	for (int y = minY; y <= maxY; ++y)	{	    for (int i = 0; i < _numChans; ++i)	    {		ChannelData &cd = _channelData[i];		if (modp (y, cd.ys) != 0)		    continue;		if (cd.type == HALF)		{		    for (int x = cd.nx; x > 0; --x)		    {			Xdr::write <CharPtrIO> (outEnd, *cd.end);			++cd.end;		    }		}		else		{		    int n = cd.nx * cd.size;		    memcpy (outEnd, cd.end, n * sizeof (unsigned short));		    outEnd += n * sizeof (unsigned short);		    cd.end += n;		}	    }	}    }    else    {	for (int y = minY; y <= maxY; ++y)	{	    for (int i = 0; i < _numChans; ++i)	    {		ChannelData &cd = _channelData[i];		#if defined (DEBUG)		    assert (cd.type == HALF);		#endif		if (modp (y, cd.ys) != 0)		    continue;		int n = cd.nx * cd.size;		memcpy (outEnd, cd.end, n * sizeof (unsigned short));		outEnd += n * sizeof (unsigned short);		cd.end += n;	    }	}    }    #if defined (DEBUG)	for (int i = 1; i < _numChans; ++i)	    assert (_channelData[i-1].end == _channelData[i].start);	assert (_channelData[_numChans-1].end == tmpBufferEnd);    #endif    if (inSize > 0)	tooMuchData();    outPtr = _outBuffer;    return outEnd - _outBuffer;}} // namespace Imf

⌨️ 快捷键说明

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