| /////////////////////////////////////////////////////////////////////////// |
| // |
| // 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 { |
| |
| void |
| insertChannels (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; |
| } |
| |
| |
| RgbaChannels |
| rgbaChannels (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); |
| } |
| |
| |
| V3f |
| ywFromHeader (const Header &header) |
| { |
| Chromaticities cr; |
| |
| if (hasChromaticities (header)) |
| cr = chromaticities (header); |
| |
| return computeYw (cr); |
| } |
| |
| } // namespace |
| |
| |
| class 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; |
| } |
| |
| |
| void |
| TiledRgbaOutputFile::ToYa::setFrameBuffer (const Rgba *base, |
| size_t xStride, |
| size_t yStride) |
| { |
| _fbBase = base; |
| _fbXStride = xStride; |
| _fbYStride = yStride; |
| } |
| |
| |
| void |
| TiledRgbaOutputFile::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; |
| } |
| |
| |
| void |
| TiledRgbaOutputFile::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::V2f |
| TiledRgbaOutputFile::screenWindowCenter () const |
| { |
| return _outputFile->header().screenWindowCenter(); |
| } |
| |
| |
| float |
| TiledRgbaOutputFile::screenWindowWidth () const |
| { |
| return _outputFile->header().screenWindowWidth(); |
| } |
| |
| |
| LineOrder |
| TiledRgbaOutputFile::lineOrder () const |
| { |
| return _outputFile->header().lineOrder(); |
| } |
| |
| |
| Compression |
| TiledRgbaOutputFile::compression () const |
| { |
| return _outputFile->header().compression(); |
| } |
| |
| |
| RgbaChannels |
| TiledRgbaOutputFile::channels () const |
| { |
| return rgbaChannels (_outputFile->header().channels()); |
| } |
| |
| |
| unsigned int |
| TiledRgbaOutputFile::tileXSize () const |
| { |
| return _outputFile->tileXSize(); |
| } |
| |
| |
| unsigned int |
| TiledRgbaOutputFile::tileYSize () const |
| { |
| return _outputFile->tileYSize(); |
| } |
| |
| |
| LevelMode |
| TiledRgbaOutputFile::levelMode () const |
| { |
| return _outputFile->levelMode(); |
| } |
| |
| |
| LevelRoundingMode |
| TiledRgbaOutputFile::levelRoundingMode () const |
| { |
| return _outputFile->levelRoundingMode(); |
| } |
| |
| |
| int |
| TiledRgbaOutputFile::numLevels () const |
| { |
| return _outputFile->numLevels(); |
| } |
| |
| |
| int |
| TiledRgbaOutputFile::numXLevels () const |
| { |
| return _outputFile->numXLevels(); |
| } |
| |
| |
| int |
| TiledRgbaOutputFile::numYLevels () const |
| { |
| return _outputFile->numYLevels(); |
| } |
| |
| |
| bool |
| TiledRgbaOutputFile::isValidLevel (int lx, int ly) const |
| { |
| return _outputFile->isValidLevel (lx, ly); |
| } |
| |
| |
| int |
| TiledRgbaOutputFile::levelWidth (int lx) const |
| { |
| return _outputFile->levelWidth (lx); |
| } |
| |
| |
| int |
| TiledRgbaOutputFile::levelHeight (int ly) const |
| { |
| return _outputFile->levelHeight (ly); |
| } |
| |
| |
| int |
| TiledRgbaOutputFile::numXTiles (int lx) const |
| { |
| return _outputFile->numXTiles (lx); |
| } |
| |
| |
| int |
| TiledRgbaOutputFile::numYTiles (int ly) const |
| { |
| return _outputFile->numYTiles (ly); |
| } |
| |
| |
| Imath::Box2i |
| TiledRgbaOutputFile::dataWindowForLevel (int l) const |
| { |
| return _outputFile->dataWindowForLevel (l); |
| } |
| |
| |
| Imath::Box2i |
| TiledRgbaOutputFile::dataWindowForLevel (int lx, int ly) const |
| { |
| return _outputFile->dataWindowForLevel (lx, ly); |
| } |
| |
| |
| Imath::Box2i |
| TiledRgbaOutputFile::dataWindowForTile (int dx, int dy, int l) const |
| { |
| return _outputFile->dataWindowForTile (dx, dy, l); |
| } |
| |
| |
| Imath::Box2i |
| TiledRgbaOutputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const |
| { |
| return _outputFile->dataWindowForTile (dx, dy, lx, ly); |
| } |
| |
| |
| void |
| TiledRgbaOutputFile::writeTile (int dx, int dy, int l) |
| { |
| if (_toYa) |
| { |
| Lock lock (*_toYa); |
| _toYa->writeTile (dx, dy, l, l); |
| } |
| else |
| { |
| _outputFile->writeTile (dx, dy, l); |
| } |
| } |
| |
| |
| void |
| TiledRgbaOutputFile::writeTile (int dx, int dy, int lx, int ly) |
| { |
| if (_toYa) |
| { |
| Lock lock (*_toYa); |
| _toYa->writeTile (dx, dy, lx, ly); |
| } |
| else |
| { |
| _outputFile->writeTile (dx, dy, lx, ly); |
| } |
| } |
| |
| |
| void |
| TiledRgbaOutputFile::writeTiles |
| (int dxMin, int dxMax, int dyMin, int dyMax, int lx, int ly) |
| { |
| if (_toYa) |
| { |
| Lock lock (*_toYa); |
| |
| for (int dy = dyMin; dy <= dyMax; dy++) |
| for (int dx = dxMin; dx <= dxMax; dx++) |
| _toYa->writeTile (dx, dy, lx, ly); |
| } |
| else |
| { |
| _outputFile->writeTiles (dxMin, dxMax, dyMin, dyMax, lx, ly); |
| } |
| } |
| |
| void |
| TiledRgbaOutputFile::writeTiles |
| (int dxMin, int dxMax, int dyMin, int dyMax, int l) |
| { |
| writeTiles (dxMin, dxMax, dyMin, dyMax, l, l); |
| } |
| |
| |
| class TiledRgbaInputFile::FromYa: public Mutex |
| { |
| public: |
| |
| FromYa (TiledInputFile &inputFile); |
| |
| void setFrameBuffer (Rgba *base, |
| size_t xStride, |
| size_t yStride); |
| |
| void readTile (int dx, int dy, int lx, int ly); |
| |
| private: |
| |
| TiledInputFile & _inputFile; |
| unsigned int _tileXSize; |
| unsigned int _tileYSize; |
| V3f _yw; |
| Array2D <Rgba> _buf; |
| Rgba * _fbBase; |
| size_t _fbXStride; |
| size_t _fbYStride; |
| }; |
| |
| |
| TiledRgbaInputFile::FromYa::FromYa (TiledInputFile &inputFile) |
| : |
| _inputFile (inputFile) |
| { |
| const TileDescription &td = inputFile.header().tileDescription(); |
| |
| _tileXSize = td.xSize; |
| _tileYSize = td.ySize; |
| _yw = ywFromHeader (_inputFile.header()); |
| _buf.resizeErase (_tileYSize, _tileXSize); |
| _fbBase = 0; |
| _fbXStride = 0; |
| _fbYStride = 0; |
| } |
| |
| |
| void |
| TiledRgbaInputFile::FromYa::setFrameBuffer (Rgba *base, |
| size_t xStride, |
| size_t yStride) |
| { |
| _fbBase = base; |
| _fbXStride = xStride; |
| _fbYStride = yStride; |
| } |
| |
| |
| void |
| TiledRgbaInputFile::FromYa::readTile (int dx, int dy, int lx, int ly) |
| { |
| if (_fbBase == 0) |
| { |
| THROW (Iex::ArgExc, "No frame buffer was specified as the " |
| "pixel data destination for image file " |
| "\"" << _inputFile.fileName() << "\"."); |
| } |
| |
| // |
| // Read the tile requiested by the caller into _buf. |
| // |
| |
| Box2i dw = _inputFile.dataWindowForTile (dx, dy, lx, ly); |
| 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 |
| 1, 1, // sampling |
| 1.0)); // fillValue |
| |
| _inputFile.setFrameBuffer (fb); |
| _inputFile.readTile (dx, dy, lx, ly); |
| |
| // |
| // Convert the luminance/alpha pixels to RGBA |
| // and copy them into the caller's frame buffer. |
| // |
| |
| 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 x1 = 0; x1 < width; ++x1) |
| { |
| _buf[y1][x1].r = 0; |
| _buf[y1][x1].b = 0; |
| } |
| |
| YCAtoRGBA (_yw, width, _buf[y1], _buf[y1]); |
| |
| for (int x = dw.min.x, x1 = 0; x <= dw.max.x; ++x, ++x1) |
| { |
| _fbBase[x * _fbXStride + y * _fbYStride] = _buf[y1][x1]; |
| } |
| } |
| } |
| |
| |
| TiledRgbaInputFile::TiledRgbaInputFile (const char name[], int numThreads): |
| _inputFile (new TiledInputFile (name, numThreads)), |
| _fromYa (0) |
| { |
| if (channels() & WRITE_Y) |
| _fromYa = new FromYa (*_inputFile); |
| } |
| |
| |
| TiledRgbaInputFile::TiledRgbaInputFile (IStream &is, int numThreads): |
| _inputFile (new TiledInputFile (is, numThreads)), |
| _fromYa (0) |
| { |
| if (channels() & WRITE_Y) |
| _fromYa = new FromYa (*_inputFile); |
| } |
| |
| |
| TiledRgbaInputFile::~TiledRgbaInputFile () |
| { |
| delete _inputFile; |
| delete _fromYa; |
| } |
| |
| |
| void |
| TiledRgbaInputFile::setFrameBuffer (Rgba *base, size_t xStride, size_t yStride) |
| { |
| if (_fromYa) |
| { |
| Lock lock (*_fromYa); |
| _fromYa->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, |
| 1, 1, // xSampling, ySampling |
| 0.0)); // fillValue |
| |
| fb.insert ("G", Slice (HALF, |
| (char *) &base[0].g, |
| xs, ys, |
| 1, 1, // xSampling, ySampling |
| 0.0)); // fillValue |
| |
| fb.insert ("B", Slice (HALF, |
| (char *) &base[0].b, |
| xs, ys, |
| 1, 1, // xSampling, ySampling |
| 0.0)); // fillValue |
| |
| fb.insert ("A", Slice (HALF, |
| (char *) &base[0].a, |
| xs, ys, |
| 1, 1, // xSampling, ySampling |
| 1.0)); // fillValue |
| |
| _inputFile->setFrameBuffer (fb); |
| } |
| } |
| |
| |
| const Header & |
| TiledRgbaInputFile::header () const |
| { |
| return _inputFile->header(); |
| } |
| |
| |
| const char * |
| TiledRgbaInputFile::fileName () const |
| { |
| return _inputFile->fileName(); |
| } |
| |
| |
| const FrameBuffer & |
| TiledRgbaInputFile::frameBuffer () const |
| { |
| return _inputFile->frameBuffer(); |
| } |
| |
| |
| const Imath::Box2i & |
| TiledRgbaInputFile::displayWindow () const |
| { |
| return _inputFile->header().displayWindow(); |
| } |
| |
| |
| const Imath::Box2i & |
| TiledRgbaInputFile::dataWindow () const |
| { |
| return _inputFile->header().dataWindow(); |
| } |
| |
| |
| float |
| TiledRgbaInputFile::pixelAspectRatio () const |
| { |
| return _inputFile->header().pixelAspectRatio(); |
| } |
| |
| |
| const Imath::V2f |
| TiledRgbaInputFile::screenWindowCenter () const |
| { |
| return _inputFile->header().screenWindowCenter(); |
| } |
| |
| |
| float |
| TiledRgbaInputFile::screenWindowWidth () const |
| { |
| return _inputFile->header().screenWindowWidth(); |
| } |
| |
| |
| LineOrder |
| TiledRgbaInputFile::lineOrder () const |
| { |
| return _inputFile->header().lineOrder(); |
| } |
| |
| |
| Compression |
| TiledRgbaInputFile::compression () const |
| { |
| return _inputFile->header().compression(); |
| } |
| |
| |
| RgbaChannels |
| TiledRgbaInputFile::channels () const |
| { |
| return rgbaChannels (_inputFile->header().channels()); |
| } |
| |
| |
| int |
| TiledRgbaInputFile::version () const |
| { |
| return _inputFile->version(); |
| } |
| |
| |
| bool |
| TiledRgbaInputFile::isComplete () const |
| { |
| return _inputFile->isComplete(); |
| } |
| |
| |
| unsigned int |
| TiledRgbaInputFile::tileXSize () const |
| { |
| return _inputFile->tileXSize(); |
| } |
| |
| |
| unsigned int |
| TiledRgbaInputFile::tileYSize () const |
| { |
| return _inputFile->tileYSize(); |
| } |
| |
| |
| LevelMode |
| TiledRgbaInputFile::levelMode () const |
| { |
| return _inputFile->levelMode(); |
| } |
| |
| |
| LevelRoundingMode |
| TiledRgbaInputFile::levelRoundingMode () const |
| { |
| return _inputFile->levelRoundingMode(); |
| } |
| |
| |
| int |
| TiledRgbaInputFile::numLevels () const |
| { |
| return _inputFile->numLevels(); |
| } |
| |
| |
| int |
| TiledRgbaInputFile::numXLevels () const |
| { |
| return _inputFile->numXLevels(); |
| } |
| |
| |
| int |
| TiledRgbaInputFile::numYLevels () const |
| { |
| return _inputFile->numYLevels(); |
| } |
| |
| |
| bool |
| TiledRgbaInputFile::isValidLevel (int lx, int ly) const |
| { |
| return _inputFile->isValidLevel (lx, ly); |
| } |
| |
| |
| int |
| TiledRgbaInputFile::levelWidth (int lx) const |
| { |
| return _inputFile->levelWidth (lx); |
| } |
| |
| |
| int |
| TiledRgbaInputFile::levelHeight (int ly) const |
| { |
| return _inputFile->levelHeight (ly); |
| } |
| |
| |
| int |
| TiledRgbaInputFile::numXTiles (int lx) const |
| { |
| return _inputFile->numXTiles(lx); |
| } |
| |
| |
| int |
| TiledRgbaInputFile::numYTiles (int ly) const |
| { |
| return _inputFile->numYTiles(ly); |
| } |
| |
| |
| Imath::Box2i |
| TiledRgbaInputFile::dataWindowForLevel (int l) const |
| { |
| return _inputFile->dataWindowForLevel (l); |
| } |
| |
| |
| Imath::Box2i |
| TiledRgbaInputFile::dataWindowForLevel (int lx, int ly) const |
| { |
| return _inputFile->dataWindowForLevel (lx, ly); |
| } |
| |
| |
| Imath::Box2i |
| TiledRgbaInputFile::dataWindowForTile (int dx, int dy, int l) const |
| { |
| return _inputFile->dataWindowForTile (dx, dy, l); |
| } |
| |
| |
| Imath::Box2i |
| TiledRgbaInputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const |
| { |
| return _inputFile->dataWindowForTile (dx, dy, lx, ly); |
| } |
| |
| |
| void |
| TiledRgbaInputFile::readTile (int dx, int dy, int l) |
| { |
| if (_fromYa) |
| { |
| Lock lock (*_fromYa); |
| _fromYa->readTile (dx, dy, l, l); |
| } |
| else |
| { |
| _inputFile->readTile (dx, dy, l); |
| } |
| } |
| |
| |
| void |
| TiledRgbaInputFile::readTile (int dx, int dy, int lx, int ly) |
| { |
| if (_fromYa) |
| { |
| Lock lock (*_fromYa); |
| _fromYa->readTile (dx, dy, lx, ly); |
| } |
| else |
| { |
| _inputFile->readTile (dx, dy, lx, ly); |
| } |
| } |
| |
| |
| void |
| TiledRgbaInputFile::readTiles (int dxMin, int dxMax, int dyMin, int dyMax, |
| int lx, int ly) |
| { |
| if (_fromYa) |
| { |
| Lock lock (*_fromYa); |
| |
| for (int dy = dyMin; dy <= dyMax; dy++) |
| for (int dx = dxMin; dx <= dxMax; dx++) |
| _fromYa->readTile (dx, dy, lx, ly); |
| } |
| else |
| { |
| _inputFile->readTiles (dxMin, dxMax, dyMin, dyMax, lx, ly); |
| } |
| } |
| |
| void |
| TiledRgbaInputFile::readTiles (int dxMin, int dxMax, int dyMin, int dyMax, |
| int l) |
| { |
| readTiles (dxMin, dxMax, dyMin, dyMax, l, l); |
| } |
| |
| |
| void |
| TiledRgbaOutputFile::updatePreviewImage (const PreviewRgba newPixels[]) |
| { |
| _outputFile->updatePreviewImage (newPixels); |
| } |
| |
| |
| void |
| TiledRgbaOutputFile::breakTile (int dx, int dy, int lx, int ly, |
| int offset, int length, char c) |
| { |
| _outputFile->breakTile (dx, dy, lx, ly, offset, length, c); |
| } |
| |
| |
| } // namespace Imf |