Blame IlmImf/ImfPxr24Compressor.cpp

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