📄 imfpizcompressor.cpp
字号:
/////////////////////////////////////////////////////////////////////////////// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas// Digital Ltd. LLC// // All rights reserved.// // Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met:// * Redistributions of source code must retain the above copyright// notice, this list of conditions and the following disclaimer.// * Redistributions in binary form must reproduce the above// copyright notice, this list of conditions and the following disclaimer// in the documentation and/or other materials provided with the// distribution.// * Neither the name of Industrial Light & Magic nor the names of// its contributors may be used to endorse or promote products derived// from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.///////////////////////////////////////////////////////////////////////////////-----------------------------------------------------------------------------//// class PizCompressor////-----------------------------------------------------------------------------#include <ImfPizCompressor.h>#include <ImfHeader.h>#include <ImfChannelList.h>#include <ImfHuf.h>#include <ImfWav.h>#include <ImfMisc.h>#include <ImathFun.h>#include <ImathBox.h>#include <Iex.h>#include <ImfIO.h>#include <ImfXdr.h>#include <ImfAutoArray.h>#include <string.h>#include <assert.h>namespace Imf {using Imath::divp;using Imath::modp;using Imath::Box2i;using Imath::V2i;using Iex::InputExc;namespace {//// Functions to compress the range of values in the pixel data//const int USHORT_RANGE = (1 << 16);const int BITMAP_SIZE = (USHORT_RANGE >> 3);voidbitmapFromData (const unsigned short data[/*nData*/], int nData, unsigned char bitmap[BITMAP_SIZE], unsigned short &minNonZero, unsigned short &maxNonZero){ for (int i = 0; i < BITMAP_SIZE; ++i) bitmap[i] = 0; for (int i = 0; i < nData; ++i) bitmap[data[i] >> 3] |= (1 << (data[i] & 7)); bitmap[0] &= ~1; // zero is not explicitly stored in // the bitmap; we assume that the // data always contain zeroes minNonZero = BITMAP_SIZE - 1; maxNonZero = 0; for (int i = 0; i < BITMAP_SIZE; ++i) { if (bitmap[i]) { if (minNonZero > i) minNonZero = i; if (maxNonZero < i) maxNonZero = i; } }}unsigned shortforwardLutFromBitmap (const unsigned char bitmap[BITMAP_SIZE], unsigned short lut[USHORT_RANGE]){ int k = 0; for (int i = 0; i < USHORT_RANGE; ++i) { if ((i == 0) || (bitmap[i >> 3] & (1 << (i & 7)))) lut[i] = k++; else lut[i] = 0; } return k - 1; // maximum value stored in lut[],} // i.e. number of ones in bitmap minus 1unsigned shortreverseLutFromBitmap (const unsigned char bitmap[BITMAP_SIZE], unsigned short lut[USHORT_RANGE]){ int k = 0; for (int i = 0; i < USHORT_RANGE; ++i) { if ((i == 0) || (bitmap[i >> 3] & (1 << (i & 7)))) lut[k++] = i; } int n = k - 1; while (k < USHORT_RANGE) lut[k++] = 0; return n; // maximum k where lut[k] is non-zero,} // i.e. number of ones in bitmap minus 1voidapplyLut (const unsigned short lut[USHORT_RANGE], unsigned short data[/*nData*/], int nData){ for (int i = 0; i < nData; ++i) data[i] = lut[data[i]];}} // namespacestruct PizCompressor::ChannelData{ unsigned short * start; unsigned short * end; int nx; int ny; int ys; int size;};PizCompressor::PizCompressor (const Header &hdr, int maxScanLineSize, int numScanLines): Compressor (hdr), _maxScanLineSize (maxScanLineSize), _format (XDR), _numScanLines (numScanLines), _tmpBuffer (0), _outBuffer (0), _numChans (0), _channels (hdr.channels()), _channelData (0){ _tmpBuffer = new unsigned short [maxScanLineSize * numScanLines / 2]; _outBuffer = new char [maxScanLineSize * numScanLines + 65536 + 8192]; const ChannelList &channels = header().channels(); bool onlyHalfChannels = true; for (ChannelList::ConstIterator c = channels.begin(); c != channels.end(); ++c) { _numChans++; assert (pixelTypeSize (c.channel().type) % pixelTypeSize (HALF) == 0); if (c.channel().type != HALF) onlyHalfChannels = false; } _channelData = new ChannelData[_numChans]; const Box2i &dataWindow = hdr.dataWindow(); _minX = dataWindow.min.x; _maxX = dataWindow.max.x; _maxY = dataWindow.max.y; // // We can support uncompressed data in the machine's native format // if all image channels are of type HALF, and if the Xdr and the // native represenations of a half have the same size. // if (onlyHalfChannels && (sizeof (half) == pixelTypeSize (HALF))) _format = NATIVE;}PizCompressor::~PizCompressor (){ delete [] _tmpBuffer; delete [] _outBuffer; delete [] _channelData;}intPizCompressor::numScanLines () const{ return _numScanLines;}Compressor::FormatPizCompressor::format () const{ return _format;}intPizCompressor::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);}intPizCompressor::compressTile (const char *inPtr, int inSize, Imath::Box2i range, const char *&outPtr){ return compress (inPtr, inSize, range, outPtr);}intPizCompressor::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);}intPizCompressor::uncompressTile (const char *inPtr, int inSize, Imath::Box2i range, const char *&outPtr){ return uncompress (inPtr, inSize, range, outPtr);}intPizCompressor::compress (const char *inPtr, int inSize, Imath::Box2i range, const char *&outPtr){ // // This is the compress function which is used by both the tiled and // scanline compression routines. // // // Special case
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -