📄 imfmisc.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.///////////////////////////////////////////////////////////////////////////////-----------------------------------------------------------------------------//// Miscellaneous helper functions for OpenEXR image file I/O////-----------------------------------------------------------------------------#include <ImfMisc.h>#include <ImfHeader.h>#include <ImfCompressor.h>#include <ImfChannelList.h>#include <ImfXdr.h>#include <ImathFun.h>#include <Iex.h>#include <ImfStdIO.h>#include <ImfConvert.h>namespace Imf {using Imath::Box2i;using Imath::divp;using Imath::modp;using std::vector;intpixelTypeSize (PixelType type){ int size; switch (type) { case UINT: size = Xdr::size <unsigned int> (); break; case HALF: size = Xdr::size <half> (); break; case FLOAT: size = Xdr::size <float> (); break; default: throw Iex::ArgExc ("Unknown pixel type."); } return size;}intnumSamples (int s, int a, int b){ int a1 = divp (a, s); int b1 = divp (b, s); return b1 - a1 + ((a1 * s < a)? 0: 1);}size_tbytesPerLineTable (const Header &header, vector<size_t> &bytesPerLine){ const Box2i &dataWindow = header.dataWindow(); const ChannelList &channels = header.channels(); bytesPerLine.resize (dataWindow.max.y - dataWindow.min.y + 1); for (ChannelList::ConstIterator c = channels.begin(); c != channels.end(); ++c) { int nBytes = pixelTypeSize (c.channel().type) * (dataWindow.max.x - dataWindow.min.x + 1) / c.channel().xSampling; for (int y = dataWindow.min.y, i = 0; y <= dataWindow.max.y; ++y, ++i) if (modp (y, c.channel().ySampling) == 0) bytesPerLine[i] += nBytes; } size_t maxBytesPerLine = 0; for (int y = dataWindow.min.y, i = 0; y <= dataWindow.max.y; ++y, ++i) if (maxBytesPerLine < bytesPerLine[i]) maxBytesPerLine = bytesPerLine[i]; return maxBytesPerLine;}voidoffsetInLineBufferTable (const vector<size_t> &bytesPerLine, int linesInLineBuffer, vector<size_t> &offsetInLineBuffer){ offsetInLineBuffer.resize (bytesPerLine.size()); size_t offset = 0; for (int i = 0; i < bytesPerLine.size(); ++i) { if (i % linesInLineBuffer == 0) offset = 0; offsetInLineBuffer[i] = offset; offset += bytesPerLine[i]; }}intlineBufferMinY (int y, int minY, int linesInLineBuffer){ return ((y - minY) / linesInLineBuffer) * linesInLineBuffer + minY;}intlineBufferMaxY (int y, int minY, int linesInLineBuffer){ return lineBufferMinY (y, minY, linesInLineBuffer) + linesInLineBuffer - 1;}Compressor::FormatdefaultFormat (Compressor * compressor){ return compressor? compressor->format(): Compressor::XDR;}intnumLinesInBuffer (Compressor * compressor){ return compressor? compressor->numScanLines(): 1;}voidcopyIntoFrameBuffer (const char *& readPtr, char * writePtr, char * endPtr, size_t xStride, bool fill, double fillValue, Compressor::Format format, PixelType typeInFrameBuffer, PixelType typeInFile){ // // Copy a horizontal row of pixels from an input // file's line or tile buffer to a frame buffer. // if (fill) { // // The file contains no data for this channel. // Store a default value in the frame buffer. // switch (typeInFrameBuffer) { case UINT: { unsigned int fillVal = (unsigned int) (fillValue); while (writePtr <= endPtr) { *(unsigned int *) writePtr = fillVal; writePtr += xStride; } } break; case HALF: { half fillVal = half (fillValue); while (writePtr <= endPtr) { *(half *) writePtr = fillVal; writePtr += xStride; } } break; case FLOAT: { float fillVal = float (fillValue); while (writePtr <= endPtr) { *(float *) writePtr = fillVal; writePtr += xStride; } } break; default: throw Iex::ArgExc ("Unknown pixel data type."); } } else if (format == Compressor::XDR) { // // The the line or tile buffer is in XDR format. // // Convert the pixels from the file's machine- // independent representation, and store the // results in the frame buffer. // switch (typeInFrameBuffer) { case UINT: switch (typeInFile) { case UINT: while (writePtr <= endPtr) { Xdr::read <CharPtrIO> (readPtr, *(unsigned int *) writePtr); writePtr += xStride; } break; case HALF: while (writePtr <= endPtr) { half h; Xdr::read <CharPtrIO> (readPtr, h); *(unsigned int *) writePtr = halfToUint (h); writePtr += xStride; } break; case FLOAT: while (writePtr <= endPtr) { float f; Xdr::read <CharPtrIO> (readPtr, f); *(unsigned int *)writePtr = floatToUint (f); writePtr += xStride; } break; } break; case HALF: switch (typeInFile) { case UINT: while (writePtr <= endPtr) { unsigned int ui; Xdr::read <CharPtrIO> (readPtr, ui); *(half *) writePtr = uintToHalf (ui); writePtr += xStride; } break; case HALF: while (writePtr <= endPtr) { Xdr::read <CharPtrIO> (readPtr, *(half *) writePtr); writePtr += xStride; } break; case FLOAT: while (writePtr <= endPtr) { float f; Xdr::read <CharPtrIO> (readPtr, f); *(half *) writePtr = floatToHalf (f); writePtr += xStride; } break; } break; case FLOAT: switch (typeInFile) { case UINT: while (writePtr <= endPtr) { unsigned int ui; Xdr::read <CharPtrIO> (readPtr, ui); *(float *) writePtr = float (ui); writePtr += xStride; } break; case HALF: while (writePtr <= endPtr) { half h; Xdr::read <CharPtrIO> (readPtr, h); *(float *) writePtr = float (h); writePtr += xStride; } break; case FLOAT: while (writePtr <= endPtr) { Xdr::read <CharPtrIO> (readPtr, *(float *) writePtr); writePtr += xStride; } break; } break; default: throw Iex::ArgExc ("Unknown pixel data type."); } } else { // // The the line or tile buffer is in NATIVE format. // Copy the results into the frame buffer. // switch (typeInFrameBuffer) { case UINT: switch (typeInFile) { case UINT: while (writePtr <= endPtr) { for (size_t i = 0; i < sizeof (unsigned int); ++i)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -