📄 imftiledrgbafile.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 TiledRgbaOutputFile// class TiledRgbaInputFile////-----------------------------------------------------------------------------#include <ImfTiledRgbaFile.h>#include <ImfRgbaFile.h>#include <ImfTiledOutputFile.h>#include <ImfTiledInputFile.h>#include <ImfChannelList.h>#include <ImfTileDescriptionAttribute.h>#include <ImfStandardAttributes.h>#include <ImfRgbaYca.h>#include <ImfArray.h>#include "IlmThreadMutex.h"#include "Iex.h"namespace Imf {using namespace Imath;using namespace RgbaYca;using namespace IlmThread;namespace {voidinsertChannels (Header &header, RgbaChannels rgbaChannels, const char fileName[]){ ChannelList ch; if (rgbaChannels & (WRITE_Y | WRITE_C)) { if (rgbaChannels & WRITE_Y) { ch.insert ("Y", Channel (HALF, 1, 1)); } if (rgbaChannels & WRITE_C) { THROW (Iex::ArgExc, "Cannot open file \"" << fileName << "\" " "for writing. Tiled image files do not " "support subsampled chroma channels."); } } else { if (rgbaChannels & WRITE_R) ch.insert ("R", Channel (HALF, 1, 1)); if (rgbaChannels & WRITE_G) ch.insert ("G", Channel (HALF, 1, 1)); if (rgbaChannels & WRITE_B) ch.insert ("B", Channel (HALF, 1, 1)); } if (rgbaChannels & WRITE_A) ch.insert ("A", Channel (HALF, 1, 1)); header.channels() = ch;}RgbaChannelsrgbaChannels (const ChannelList &ch){ int i = 0; if (ch.findChannel ("R")) i |= WRITE_R; if (ch.findChannel ("G")) i |= WRITE_G; if (ch.findChannel ("B")) i |= WRITE_B; if (ch.findChannel ("A")) i |= WRITE_A; if (ch.findChannel ("Y")) i |= WRITE_Y; return RgbaChannels (i);}V3fywFromHeader (const Header &header){ Chromaticities cr; if (hasChromaticities (header)) cr = chromaticities (header); return computeYw (cr);}} // namespaceclass TiledRgbaOutputFile::ToYa: public Mutex{ public: ToYa (TiledOutputFile &outputFile, RgbaChannels rgbaChannels); void setFrameBuffer (const Rgba *base, size_t xStride, size_t yStride); void writeTile (int dx, int dy, int lx, int ly); private: TiledOutputFile & _outputFile; bool _writeA; unsigned int _tileXSize; unsigned int _tileYSize; V3f _yw; Array2D <Rgba> _buf; const Rgba * _fbBase; size_t _fbXStride; size_t _fbYStride;};TiledRgbaOutputFile::ToYa::ToYa (TiledOutputFile &outputFile, RgbaChannels rgbaChannels): _outputFile (outputFile){ _writeA = (rgbaChannels & WRITE_A)? true: false; const TileDescription &td = outputFile.header().tileDescription(); _tileXSize = td.xSize; _tileYSize = td.ySize; _yw = ywFromHeader (_outputFile.header()); _buf.resizeErase (_tileYSize, _tileXSize); _fbBase = 0; _fbXStride = 0; _fbYStride = 0;}voidTiledRgbaOutputFile::ToYa::setFrameBuffer (const Rgba *base, size_t xStride, size_t yStride){ _fbBase = base; _fbXStride = xStride; _fbYStride = yStride;}voidTiledRgbaOutputFile::ToYa::writeTile (int dx, int dy, int lx, int ly){ if (_fbBase == 0) { THROW (Iex::ArgExc, "No frame buffer was specified as the " "pixel data source for image file " "\"" << _outputFile.fileName() << "\"."); } // // Copy the tile's RGBA pixels into _buf and convert // them to luminance/alpha format // Box2i dw = _outputFile.dataWindowForTile (dx, dy, lx, ly); int width = dw.max.x - dw.min.x + 1; for (int y = dw.min.y, y1 = 0; y <= dw.max.y; ++y, ++y1) { for (int x = dw.min.x, x1 = 0; x <= dw.max.x; ++x, ++x1) _buf[y1][x1] = _fbBase[x * _fbXStride + y * _fbYStride]; RGBAtoYCA (_yw, width, _writeA, _buf[y1], _buf[y1]); } // // Store the contents of _buf in the output file // FrameBuffer fb; fb.insert ("Y", Slice (HALF, // type (char *) &_buf[-dw.min.y][-dw.min.x].g, // base sizeof (Rgba), // xStride sizeof (Rgba) * _tileXSize)); // yStride fb.insert ("A", Slice (HALF, // type (char *) &_buf[-dw.min.y][-dw.min.x].a, // base sizeof (Rgba), // xStride sizeof (Rgba) * _tileXSize)); // yStride _outputFile.setFrameBuffer (fb); _outputFile.writeTile (dx, dy, lx, ly);}TiledRgbaOutputFile::TiledRgbaOutputFile (const char name[], const Header &header, RgbaChannels rgbaChannels, int tileXSize, int tileYSize, LevelMode mode, LevelRoundingMode rmode, int numThreads): _outputFile (0), _toYa (0){ Header hd (header); insertChannels (hd, rgbaChannels, name); hd.setTileDescription (TileDescription (tileXSize, tileYSize, mode, rmode)); _outputFile = new TiledOutputFile (name, hd, numThreads); if (rgbaChannels & WRITE_Y) _toYa = new ToYa (*_outputFile, rgbaChannels);}TiledRgbaOutputFile::TiledRgbaOutputFile (OStream &os, const Header &header, RgbaChannels rgbaChannels, int tileXSize, int tileYSize, LevelMode mode, LevelRoundingMode rmode, int numThreads): _outputFile (0), _toYa (0){ Header hd (header); insertChannels (hd, rgbaChannels, os.fileName()); hd.setTileDescription (TileDescription (tileXSize, tileYSize, mode, rmode)); _outputFile = new TiledOutputFile (os, hd, numThreads); if (rgbaChannels & WRITE_Y) _toYa = new ToYa (*_outputFile, rgbaChannels);}TiledRgbaOutputFile::TiledRgbaOutputFile (const char name[], int tileXSize, int tileYSize, LevelMode mode, LevelRoundingMode rmode, const Imath::Box2i &displayWindow, const Imath::Box2i &dataWindow, RgbaChannels rgbaChannels, float pixelAspectRatio, const Imath::V2f screenWindowCenter, float screenWindowWidth, LineOrder lineOrder, Compression compression, int numThreads): _outputFile (0), _toYa (0){ Header hd (displayWindow, dataWindow.isEmpty()? displayWindow: dataWindow, pixelAspectRatio, screenWindowCenter, screenWindowWidth, lineOrder, compression); insertChannels (hd, rgbaChannels, name); hd.setTileDescription (TileDescription (tileXSize, tileYSize, mode, rmode)); _outputFile = new TiledOutputFile (name, hd, numThreads); if (rgbaChannels & WRITE_Y) _toYa = new ToYa (*_outputFile, rgbaChannels);}TiledRgbaOutputFile::TiledRgbaOutputFile (const char name[], int width, int height, int tileXSize, int tileYSize, LevelMode mode, LevelRoundingMode rmode, RgbaChannels rgbaChannels, float pixelAspectRatio, const Imath::V2f screenWindowCenter, float screenWindowWidth, LineOrder lineOrder, Compression compression, int numThreads): _outputFile (0), _toYa (0){ Header hd (width, height, pixelAspectRatio, screenWindowCenter, screenWindowWidth, lineOrder, compression); insertChannels (hd, rgbaChannels, name); hd.setTileDescription (TileDescription (tileXSize, tileYSize, mode, rmode)); _outputFile = new TiledOutputFile (name, hd, numThreads); if (rgbaChannels & WRITE_Y) _toYa = new ToYa (*_outputFile, rgbaChannels);}TiledRgbaOutputFile::~TiledRgbaOutputFile (){ delete _outputFile; delete _toYa;}voidTiledRgbaOutputFile::setFrameBuffer (const Rgba *base, size_t xStride, size_t yStride){ if (_toYa) { Lock lock (*_toYa); _toYa->setFrameBuffer (base, xStride, yStride); } else { size_t xs = xStride * sizeof (Rgba); size_t ys = yStride * sizeof (Rgba); FrameBuffer fb; fb.insert ("R", Slice (HALF, (char *) &base[0].r, xs, ys)); fb.insert ("G", Slice (HALF, (char *) &base[0].g, xs, ys)); fb.insert ("B", Slice (HALF, (char *) &base[0].b, xs, ys)); fb.insert ("A", Slice (HALF, (char *) &base[0].a, xs, ys)); _outputFile->setFrameBuffer (fb); }}const Header &TiledRgbaOutputFile::header () const{ return _outputFile->header();}const FrameBuffer &TiledRgbaOutputFile::frameBuffer () const{ return _outputFile->frameBuffer();}const Imath::Box2i &TiledRgbaOutputFile::displayWindow () const{ return _outputFile->header().displayWindow();}const Imath::Box2i &TiledRgbaOutputFile::dataWindow () const{ return _outputFile->header().dataWindow();}float TiledRgbaOutputFile::pixelAspectRatio () const{ return _outputFile->header().pixelAspectRatio();}const Imath::V2fTiledRgbaOutputFile::screenWindowCenter () const{ return _outputFile->header().screenWindowCenter();}float TiledRgbaOutputFile::screenWindowWidth () const{ return _outputFile->header().screenWindowWidth();}LineOrderTiledRgbaOutputFile::lineOrder () const{ return _outputFile->header().lineOrder();}CompressionTiledRgbaOutputFile::compression () const{ return _outputFile->header().compression();}RgbaChannelsTiledRgbaOutputFile::channels () const{ return rgbaChannels (_outputFile->header().channels());}unsigned intTiledRgbaOutputFile::tileXSize () const{ return _outputFile->tileXSize();}unsigned intTiledRgbaOutputFile::tileYSize () const{ return _outputFile->tileYSize();}LevelModeTiledRgbaOutputFile::levelMode () const{ return _outputFile->levelMode();}LevelRoundingModeTiledRgbaOutputFile::levelRoundingMode () const{ return _outputFile->levelRoundingMode();}intTiledRgbaOutputFile::numLevels () const{ return _outputFile->numLevels();}intTiledRgbaOutputFile::numXLevels () const{ return _outputFile->numXLevels();}intTiledRgbaOutputFile::numYLevels () const{ return _outputFile->numYLevels();}boolTiledRgbaOutputFile::isValidLevel (int lx, int ly) const{ return _outputFile->isValidLevel (lx, ly);}intTiledRgbaOutputFile::levelWidth (int lx) const{ return _outputFile->levelWidth (lx);}intTiledRgbaOutputFile::levelHeight (int ly) const{ return _outputFile->levelHeight (ly);}intTiledRgbaOutputFile::numXTiles (int lx) const{ return _outputFile->numXTiles (lx);}int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -