Blame IlmImf/ImfPxr24Compressor.cpp

Packit Service 6754ca
/////////////////////////////////////////////////////////////////////////////
Packit Service 6754ca
//
Packit Service 6754ca
// Copyright (c) 2004, Pixar Animation Studios
Packit Service 6754ca
//
Packit Service 6754ca
// All rights reserved.
Packit Service 6754ca
//
Packit Service 6754ca
// Redistribution and use in source and binary forms, with or without
Packit Service 6754ca
// modification, are permitted provided that the following conditions  are
Packit Service 6754ca
// met:
Packit Service 6754ca
// *       Redistributions of source code must retain the above  copyright
Packit Service 6754ca
// notice, this list of conditions and the following disclaimer.
Packit Service 6754ca
// *       Redistributions in binary form must reproduce the above
Packit Service 6754ca
// copyright notice, this list of conditions and the following  disclaimer
Packit Service 6754ca
// in the documentation and/or other materials provided with the
Packit Service 6754ca
// distribution.
Packit Service 6754ca
// *       Neither the name of Pixar Animation Studios nor the names of
Packit Service 6754ca
// its contributors may be used to endorse or promote products derived
Packit Service 6754ca
// from this software without specific prior written permission.
Packit Service 6754ca
//
Packit Service 6754ca
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit Service 6754ca
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit Service 6754ca
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Packit Service 6754ca
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
Packit Service 6754ca
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
Packit Service 6754ca
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
Packit Service 6754ca
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Packit Service 6754ca
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Packit Service 6754ca
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Packit Service 6754ca
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit Service 6754ca
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit Service 6754ca
//
Packit Service 6754ca
/////////////////////////////////////////////////////////////////////////////
Packit Service 6754ca
Packit Service 6754ca
//-----------------------------------------------------------------------------
Packit Service 6754ca
//
Packit Service 6754ca
//	class Pxr24Compressor
Packit Service 6754ca
//
Packit Service 6754ca
//	This compressor is based on source code that was contributed to
Packit Service 6754ca
//	OpenEXR by Pixar Animation Studios.  The compression method was
Packit Service 6754ca
//	developed by Loren Carpenter.
Packit Service 6754ca
//
Packit Service 6754ca
//	The compressor preprocesses the pixel data to reduce entropy,
Packit Service 6754ca
//	and then calls zlib.
Packit Service 6754ca
//
Packit Service 6754ca
//	Compression of HALF and UINT channels is lossless, but compressing
Packit Service 6754ca
//	FLOAT channels is lossy: 32-bit floating-point numbers are converted
Packit Service 6754ca
//	to 24 bits by rounding the significand to 15 bits.
Packit Service 6754ca
//
Packit Service 6754ca
//	When the compressor is invoked, the caller has already arranged
Packit Service 6754ca
//	the pixel data so that the values for each channel appear in a
Packit Service 6754ca
//	contiguous block of memory.  The compressor converts the pixel
Packit Service 6754ca
//	values to unsigned integers: For UINT, this is a no-op.  HALF
Packit Service 6754ca
//	values are simply re-interpreted as 16-bit integers.  FLOAT
Packit Service 6754ca
//	values are converted to 24 bits, and the resulting bit patterns
Packit Service 6754ca
//	are interpreted as integers.  The compressor then replaces each
Packit Service 6754ca
//	value with the difference between the value and its left neighbor.
Packit Service 6754ca
//	This turns flat fields in the image into zeroes, and ramps into
Packit Service 6754ca
//	strings of similar values.  Next, each difference is split into
Packit Service 6754ca
//	2, 3 or 4 bytes, and the bytes are transposed so that all the
Packit Service 6754ca
//	most significant bytes end up in a contiguous block, followed
Packit Service 6754ca
//	by the second most significant bytes, and so on.  The resulting
Packit Service 6754ca
//	string of bytes is compressed with zlib.
Packit Service 6754ca
//
Packit Service 6754ca
//-----------------------------------------------------------------------------
Packit Service 6754ca
Packit Service 6754ca
#include "ImfPxr24Compressor.h"
Packit Service 6754ca
#include "ImfHeader.h"
Packit Service 6754ca
#include "ImfChannelList.h"
Packit Service 6754ca
#include "ImfMisc.h"
Packit Service 6754ca
#include "ImfCheckedArithmetic.h"
Packit Service 6754ca
#include "ImfNamespace.h"
Packit Service 6754ca
Packit Service 6754ca
#include <ImathFun.h>
Packit Service 6754ca
#include <Iex.h>
Packit Service 6754ca
Packit Service 6754ca
#include <half.h>
Packit Service 6754ca
#include <zlib.h>
Packit Service 6754ca
#include <assert.h>
Packit Service 6754ca
#include <algorithm>
Packit Service 6754ca
Packit Service 6754ca
using namespace std;
Packit Service 6754ca
using namespace IMATH_NAMESPACE;
Packit Service 6754ca
Packit Service 6754ca
OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
Packit Service 6754ca
Packit Service 6754ca
namespace {
Packit Service 6754ca
Packit Service 6754ca
//
Packit Service 6754ca
// Conversion from 32-bit to 24-bit floating-point numbers.
Packit Service 6754ca
// Conversion back to 32 bits is simply an 8-bit shift to the left.
Packit Service 6754ca
//
Packit Service 6754ca
Packit Service 6754ca
inline unsigned int
Packit Service 6754ca
floatToFloat24 (float f)
Packit Service 6754ca
{
Packit Service 6754ca
    union
Packit Service 6754ca
    {
Packit Service 6754ca
	float		f;
Packit Service 6754ca
	unsigned int	i;
Packit Service 6754ca
    } u;
Packit Service 6754ca
Packit Service 6754ca
    u.f = f;
Packit Service 6754ca
Packit Service 6754ca
    //
Packit Service 6754ca
    // Disassemble the 32-bit floating point number, f,
Packit Service 6754ca
    // into sign, s, exponent, e, and significand, m.
Packit Service 6754ca
    //
Packit Service 6754ca
Packit Service 6754ca
    unsigned int s = u.i & 0x80000000;
Packit Service 6754ca
    unsigned int e = u.i & 0x7f800000;
Packit Service 6754ca
    unsigned int m = u.i & 0x007fffff;
Packit Service 6754ca
    unsigned int i;
Packit Service 6754ca
Packit Service 6754ca
    if (e == 0x7f800000)
Packit Service 6754ca
    {
Packit Service 6754ca
	if (m)
Packit Service 6754ca
	{
Packit Service 6754ca
	    //
Packit Service 6754ca
	    // F is a NAN; we preserve the sign bit and
Packit Service 6754ca
	    // the 15 leftmost bits of the significand,
Packit Service 6754ca
	    // with one exception: If the 15 leftmost
Packit Service 6754ca
	    // bits are all zero, the NAN would turn
Packit Service 6754ca
	    // into an infinity, so we have to set at
Packit Service 6754ca
	    // least one bit in the significand.
Packit Service 6754ca
	    //
Packit Service 6754ca
Packit Service 6754ca
	    m >>= 8;
Packit Service 6754ca
	    i = (e >> 8) | m | (m == 0);
Packit Service 6754ca
	}
Packit Service 6754ca
	else
Packit Service 6754ca
	{
Packit Service 6754ca
	    //
Packit Service 6754ca
	    // F is an infinity.
Packit Service 6754ca
	    //
Packit Service 6754ca
Packit Service 6754ca
	    i = e >> 8;
Packit Service 6754ca
	}
Packit Service 6754ca
    }
Packit Service 6754ca
    else
Packit Service 6754ca
    {
Packit Service 6754ca
	//
Packit Service 6754ca
	// F is finite, round the significand to 15 bits.
Packit Service 6754ca
	//
Packit Service 6754ca
Packit Service 6754ca
	i = ((e | m) + (m & 0x00000080)) >> 8;
Packit Service 6754ca
Packit Service 6754ca
	if (i >= 0x7f8000)
Packit Service 6754ca
	{
Packit Service 6754ca
	    //
Packit Service 6754ca
	    // F was close to FLT_MAX, and the significand was
Packit Service 6754ca
	    // rounded up, resulting in an exponent overflow.
Packit Service 6754ca
	    // Avoid the overflow by truncating the significand
Packit Service 6754ca
	    // instead of rounding it.
Packit Service 6754ca
	    //
Packit Service 6754ca
Packit Service 6754ca
	    i = (e | m) >> 8;
Packit Service 6754ca
	}
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    return (s >> 8) | i;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
notEnoughData ()
Packit Service 6754ca
{
Packit Service 6754ca
    throw IEX_NAMESPACE::InputExc ("Error decompressing data "
Packit Service 6754ca
			 "(input data are shorter than expected).");
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
tooMuchData ()
Packit Service 6754ca
{
Packit Service 6754ca
    throw IEX_NAMESPACE::InputExc ("Error decompressing data "
Packit Service 6754ca
			 "(input data are longer than expected).");
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
} // namespace
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
Pxr24Compressor::Pxr24Compressor (const Header &hdr,
Packit Service 6754ca
				  size_t maxScanLineSize,
Packit Service 6754ca
				  size_t numScanLines)
Packit Service 6754ca
:
Packit Service 6754ca
    Compressor (hdr),
Packit Service 6754ca
    _maxScanLineSize (maxScanLineSize),
Packit Service 6754ca
    _numScanLines (numScanLines),
Packit Service 6754ca
    _tmpBuffer (0),
Packit Service 6754ca
    _outBuffer (0),
Packit Service 6754ca
    _channels (hdr.channels())
Packit Service 6754ca
{
Packit Service 6754ca
    size_t maxInBytes =
Packit Service 6754ca
        uiMult (maxScanLineSize, numScanLines);
Packit Service 6754ca
Packit Service 6754ca
    size_t maxOutBytes =
Packit Service 6754ca
        uiAdd (uiAdd (maxInBytes,
Packit Service 6754ca
                      size_t (ceil (maxInBytes * 0.01))),
Packit Service 6754ca
               size_t (100));
Packit Service 6754ca
Packit Service 6754ca
    _tmpBuffer = new unsigned char [maxInBytes];
Packit Service 6754ca
    _outBuffer = new char [maxOutBytes];
Packit Service 6754ca
Packit Service 6754ca
    const Box2i &dataWindow = hdr.dataWindow();
Packit Service 6754ca
Packit Service 6754ca
    _minX = dataWindow.min.x;
Packit Service 6754ca
    _maxX = dataWindow.max.x;
Packit Service 6754ca
    _maxY = dataWindow.max.y;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
Pxr24Compressor::~Pxr24Compressor ()
Packit Service 6754ca
{
Packit Service 6754ca
    delete [] _tmpBuffer;
Packit Service 6754ca
    delete [] _outBuffer;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
int
Packit Service 6754ca
Pxr24Compressor::numScanLines () const
Packit Service 6754ca
{
Packit Service 6754ca
    return _numScanLines;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
Compressor::Format
Packit Service 6754ca
Pxr24Compressor::format () const
Packit Service 6754ca
{
Packit Service 6754ca
    return NATIVE;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
int
Packit Service 6754ca
Pxr24Compressor::compress (const char *inPtr,
Packit Service 6754ca
			   int inSize,
Packit Service 6754ca
			   int minY,
Packit Service 6754ca
			   const char *&outPtr)
Packit Service 6754ca
{
Packit Service 6754ca
    return compress (inPtr,
Packit Service 6754ca
	             inSize,
Packit Service 6754ca
		     Box2i (V2i (_minX, minY),
Packit Service 6754ca
			    V2i (_maxX, minY + _numScanLines - 1)),
Packit Service 6754ca
		     outPtr);
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
	      
Packit Service 6754ca
int
Packit Service 6754ca
Pxr24Compressor::compressTile (const char *inPtr,
Packit Service 6754ca
			       int inSize,
Packit Service 6754ca
			       Box2i range,
Packit Service 6754ca
			       const char *&outPtr)
Packit Service 6754ca
{
Packit Service 6754ca
    return compress (inPtr, inSize, range, outPtr);
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
int
Packit Service 6754ca
Pxr24Compressor::uncompress (const char *inPtr,
Packit Service 6754ca
			     int inSize,
Packit Service 6754ca
			     int minY,
Packit Service 6754ca
			     const char *&outPtr)
Packit Service 6754ca
{
Packit Service 6754ca
    return uncompress (inPtr,
Packit Service 6754ca
	               inSize,
Packit Service 6754ca
		       Box2i (V2i (_minX, minY),
Packit Service 6754ca
			      V2i (_maxX, minY + _numScanLines - 1)),
Packit Service 6754ca
		       outPtr);
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
		
Packit Service 6754ca
int
Packit Service 6754ca
Pxr24Compressor::uncompressTile (const char *inPtr,
Packit Service 6754ca
				 int inSize,
Packit Service 6754ca
				 Box2i range,
Packit Service 6754ca
				 const char *&outPtr)
Packit Service 6754ca
{
Packit Service 6754ca
    return uncompress (inPtr, inSize, range, outPtr);
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
int
Packit Service 6754ca
Pxr24Compressor::compress (const char *inPtr,
Packit Service 6754ca
			   int inSize,
Packit Service 6754ca
			   Box2i range,
Packit Service 6754ca
			   const char *&outPtr)
Packit Service 6754ca
{
Packit Service 6754ca
    if (inSize == 0)
Packit Service 6754ca
    {
Packit Service 6754ca
	outPtr = _outBuffer;
Packit Service 6754ca
	return 0;
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    int minX = range.min.x;
Packit Service 6754ca
    int maxX = min (range.max.x, _maxX);
Packit Service 6754ca
    int minY = range.min.y;
Packit Service 6754ca
    int maxY = min (range.max.y, _maxY);
Packit Service 6754ca
Packit Service 6754ca
    unsigned char *tmpBufferEnd = _tmpBuffer;
Packit Service 6754ca
Packit Service 6754ca
    for (int y = minY; y <= maxY; ++y)
Packit Service 6754ca
    {
Packit Service 6754ca
	for (ChannelList::ConstIterator i = _channels.begin();
Packit Service 6754ca
	     i != _channels.end();
Packit Service 6754ca
	     ++i)
Packit Service 6754ca
	{
Packit Service 6754ca
	    const Channel &c = i.channel();
Packit Service 6754ca
Packit Service 6754ca
	    if (modp (y, c.ySampling) != 0)
Packit Service 6754ca
		continue;
Packit Service 6754ca
Packit Service 6754ca
	    int n = numSamples (c.xSampling, minX, maxX);
Packit Service 6754ca
Packit Service 6754ca
	    unsigned char *ptr[4];
Packit Service 6754ca
	    unsigned int previousPixel = 0;
Packit Service 6754ca
Packit Service 6754ca
	    switch (c.type)
Packit Service 6754ca
	    {
Packit Service 6754ca
	      case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
Packit Service 6754ca
Packit Service 6754ca
		ptr[0] = tmpBufferEnd;
Packit Service 6754ca
		ptr[1] = ptr[0] + n;
Packit Service 6754ca
		ptr[2] = ptr[1] + n;
Packit Service 6754ca
		ptr[3] = ptr[2] + n;
Packit Service 6754ca
		tmpBufferEnd = ptr[3] + n;
Packit Service 6754ca
Packit Service 6754ca
		for (int j = 0; j < n; ++j)
Packit Service 6754ca
		{
Packit Service 6754ca
		    unsigned int pixel;
Packit Service 6754ca
		    char *pPtr = (char *) &pixel;
Packit Service 6754ca
Packit Service 6754ca
		    for (size_t k = 0; k < sizeof (pixel); ++k)
Packit Service 6754ca
			*pPtr++ = *inPtr++;
Packit Service 6754ca
Packit Service 6754ca
		    unsigned int diff = pixel - previousPixel;
Packit Service 6754ca
		    previousPixel = pixel;
Packit Service 6754ca
Packit Service 6754ca
		    *(ptr[0]++) = diff >> 24;
Packit Service 6754ca
		    *(ptr[1]++) = diff >> 16;
Packit Service 6754ca
		    *(ptr[2]++) = diff >> 8;
Packit Service 6754ca
		    *(ptr[3]++) = diff;
Packit Service 6754ca
		}
Packit Service 6754ca
Packit Service 6754ca
		break;
Packit Service 6754ca
Packit Service 6754ca
	      case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
Packit Service 6754ca
Packit Service 6754ca
		ptr[0] = tmpBufferEnd;
Packit Service 6754ca
		ptr[1] = ptr[0] + n;
Packit Service 6754ca
		tmpBufferEnd = ptr[1] + n;
Packit Service 6754ca
Packit Service 6754ca
		for (int j = 0; j < n; ++j)
Packit Service 6754ca
		{
Packit Service 6754ca
		    half pixel;
Packit Service 6754ca
Packit Service 6754ca
		    pixel = *(const half *) inPtr;
Packit Service 6754ca
		    inPtr += sizeof (half);
Packit Service 6754ca
Packit Service 6754ca
		    unsigned int diff = pixel.bits() - previousPixel;
Packit Service 6754ca
		    previousPixel = pixel.bits();
Packit Service 6754ca
Packit Service 6754ca
		    *(ptr[0]++) = diff >> 8;
Packit Service 6754ca
		    *(ptr[1]++) = diff;
Packit Service 6754ca
		}
Packit Service 6754ca
Packit Service 6754ca
		break;
Packit Service 6754ca
Packit Service 6754ca
	      case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
Packit Service 6754ca
Packit Service 6754ca
		ptr[0] = tmpBufferEnd;
Packit Service 6754ca
		ptr[1] = ptr[0] + n;
Packit Service 6754ca
		ptr[2] = ptr[1] + n;
Packit Service 6754ca
		tmpBufferEnd = ptr[2] + n;
Packit Service 6754ca
Packit Service 6754ca
		for (int j = 0; j < n; ++j)
Packit Service 6754ca
		{
Packit Service 6754ca
		    float pixel;
Packit Service 6754ca
		    char *pPtr = (char *) &pixel;
Packit Service 6754ca
Packit Service 6754ca
		    for (size_t k = 0; k < sizeof (pixel); ++k)
Packit Service 6754ca
			*pPtr++ = *inPtr++;
Packit Service 6754ca
Packit Service 6754ca
		    unsigned int pixel24 = floatToFloat24 (pixel);
Packit Service 6754ca
		    unsigned int diff = pixel24 - previousPixel;
Packit Service 6754ca
		    previousPixel = pixel24;
Packit Service 6754ca
Packit Service 6754ca
		    *(ptr[0]++) = diff >> 16;
Packit Service 6754ca
		    *(ptr[1]++) = diff >> 8;
Packit Service 6754ca
		    *(ptr[2]++) = diff;
Packit Service 6754ca
		}
Packit Service 6754ca
Packit Service 6754ca
		break;
Packit Service 6754ca
Packit Service 6754ca
	      default:
Packit Service 6754ca
Packit Service 6754ca
		assert (false);
Packit Service 6754ca
	    }
Packit Service 6754ca
	}
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    uLongf outSize = int (ceil ((tmpBufferEnd - _tmpBuffer) * 1.01)) + 100;
Packit Service 6754ca
Packit Service 6754ca
    if (Z_OK != ::compress ((Bytef *) _outBuffer,
Packit Service 6754ca
			    &outSize,
Packit Service 6754ca
			    (const Bytef *) _tmpBuffer,
Packit Service 6754ca
			    tmpBufferEnd - _tmpBuffer))
Packit Service 6754ca
    {
Packit Service 6754ca
	throw IEX_NAMESPACE::BaseExc ("Data compression (zlib) failed.");
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    outPtr = _outBuffer;
Packit Service 6754ca
    return outSize;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
 
Packit Service 6754ca
int		
Packit Service 6754ca
Pxr24Compressor::uncompress (const char *inPtr,
Packit Service 6754ca
			     int inSize,
Packit Service 6754ca
			     Box2i range,
Packit Service 6754ca
			     const char *&outPtr)
Packit Service 6754ca
{
Packit Service 6754ca
    if (inSize == 0)
Packit Service 6754ca
    {
Packit Service 6754ca
	outPtr = _outBuffer;
Packit Service 6754ca
	return 0;
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    uLongf tmpSize = _maxScanLineSize * _numScanLines;
Packit Service 6754ca
Packit Service 6754ca
    if (Z_OK != ::uncompress ((Bytef *)_tmpBuffer,
Packit Service 6754ca
			      &tmpSize,
Packit Service 6754ca
			      (const Bytef *) inPtr,
Packit Service 6754ca
			      inSize))
Packit Service 6754ca
    {
Packit Service 6754ca
	throw IEX_NAMESPACE::InputExc ("Data decompression (zlib) failed.");
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    int minX = range.min.x;
Packit Service 6754ca
    int maxX = min (range.max.x, _maxX);
Packit Service 6754ca
    int minY = range.min.y;
Packit Service 6754ca
    int maxY = min (range.max.y, _maxY);
Packit Service 6754ca
Packit Service 6754ca
    const unsigned char *tmpBufferEnd = _tmpBuffer;
Packit Service 6754ca
    char *writePtr = _outBuffer;
Packit Service 6754ca
Packit Service 6754ca
    for (int y = minY; y <= maxY; ++y)
Packit Service 6754ca
    {
Packit Service 6754ca
	for (ChannelList::ConstIterator i = _channels.begin();
Packit Service 6754ca
	     i != _channels.end();
Packit Service 6754ca
	     ++i)
Packit Service 6754ca
	{
Packit Service 6754ca
	    const Channel &c = i.channel();
Packit Service 6754ca
Packit Service 6754ca
	    if (modp (y, c.ySampling) != 0)
Packit Service 6754ca
		continue;
Packit Service 6754ca
Packit Service 6754ca
	    int n = numSamples (c.xSampling, minX, maxX);
Packit Service 6754ca
Packit Service 6754ca
	    const unsigned char *ptr[4];
Packit Service 6754ca
	    unsigned int pixel = 0;
Packit Service 6754ca
Packit Service 6754ca
	    switch (c.type)
Packit Service 6754ca
	    {
Packit Service 6754ca
	      case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
Packit Service 6754ca
Packit Service 6754ca
		ptr[0] = tmpBufferEnd;
Packit Service 6754ca
		ptr[1] = ptr[0] + n;
Packit Service 6754ca
		ptr[2] = ptr[1] + n;
Packit Service 6754ca
		ptr[3] = ptr[2] + n;
Packit Service 6754ca
		tmpBufferEnd = ptr[3] + n;
Packit Service 6754ca
Packit Service 6754ca
		if ( (uLongf)(tmpBufferEnd - _tmpBuffer) > tmpSize)
Packit Service 6754ca
		    notEnoughData();
Packit Service 6754ca
Packit Service 6754ca
		for (int j = 0; j < n; ++j)
Packit Service 6754ca
		{
Packit Service 6754ca
		    unsigned int diff = (*(ptr[0]++) << 24) |
Packit Service 6754ca
					(*(ptr[1]++) << 16) |
Packit Service 6754ca
					(*(ptr[2]++) <<  8) |
Packit Service 6754ca
					 *(ptr[3]++);
Packit Service 6754ca
Packit Service 6754ca
		    pixel += diff;
Packit Service 6754ca
Packit Service 6754ca
		    char *pPtr = (char *) &pixel;
Packit Service 6754ca
Packit Service 6754ca
		    for (size_t k = 0; k < sizeof (pixel); ++k)
Packit Service 6754ca
			*writePtr++ = *pPtr++;
Packit Service 6754ca
		}
Packit Service 6754ca
Packit Service 6754ca
		break;
Packit Service 6754ca
Packit Service 6754ca
	      case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
Packit Service 6754ca
Packit Service 6754ca
		ptr[0] = tmpBufferEnd;
Packit Service 6754ca
		ptr[1] = ptr[0] + n;
Packit Service 6754ca
		tmpBufferEnd = ptr[1] + n;
Packit Service 6754ca
Packit Service 6754ca
        if ( (uLongf)(tmpBufferEnd - _tmpBuffer) > tmpSize)
Packit Service 6754ca
		    notEnoughData();
Packit Service 6754ca
Packit Service 6754ca
		for (int j = 0; j < n; ++j)
Packit Service 6754ca
		{
Packit Service 6754ca
		    unsigned int diff = (*(ptr[0]++) << 8) |
Packit Service 6754ca
					 *(ptr[1]++);
Packit Service 6754ca
Packit Service 6754ca
		    pixel += diff;
Packit Service 6754ca
Packit Service 6754ca
		    half * hPtr = (half *) writePtr;
Packit Service 6754ca
		    hPtr->setBits ((unsigned short) pixel);
Packit Service 6754ca
		    writePtr += sizeof (half);
Packit Service 6754ca
		}
Packit Service 6754ca
Packit Service 6754ca
		break;
Packit Service 6754ca
Packit Service 6754ca
	      case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
Packit Service 6754ca
Packit Service 6754ca
		ptr[0] = tmpBufferEnd;
Packit Service 6754ca
		ptr[1] = ptr[0] + n;
Packit Service 6754ca
		ptr[2] = ptr[1] + n;
Packit Service 6754ca
		tmpBufferEnd = ptr[2] + n;
Packit Service 6754ca
Packit Service 6754ca
        if ( (uLongf) (tmpBufferEnd - _tmpBuffer) > tmpSize)
Packit Service 6754ca
		    notEnoughData();
Packit Service 6754ca
Packit Service 6754ca
		for (int j = 0; j < n; ++j)
Packit Service 6754ca
		{
Packit Service 6754ca
		    unsigned int diff = (*(ptr[0]++) << 24) |
Packit Service 6754ca
					(*(ptr[1]++) << 16) |
Packit Service 6754ca
					(*(ptr[2]++) <<  8);
Packit Service 6754ca
		    pixel += diff;
Packit Service 6754ca
Packit Service 6754ca
		    char *pPtr = (char *) &pixel;
Packit Service 6754ca
Packit Service 6754ca
		    for (size_t k = 0; k < sizeof (pixel); ++k)
Packit Service 6754ca
			*writePtr++ = *pPtr++;
Packit Service 6754ca
		}
Packit Service 6754ca
Packit Service 6754ca
		break;
Packit Service 6754ca
Packit Service 6754ca
	      default:
Packit Service 6754ca
Packit Service 6754ca
		assert (false);
Packit Service 6754ca
	    }
Packit Service 6754ca
	}
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    if ((uLongf) (tmpBufferEnd - _tmpBuffer) < tmpSize)
Packit Service 6754ca
	tooMuchData();
Packit Service 6754ca
Packit Service 6754ca
    outPtr = _outBuffer;
Packit Service 6754ca
    return writePtr - _outBuffer;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT