Blame IlmImfUtil/ImfImage.cpp

Packit Service 6754ca
///////////////////////////////////////////////////////////////////////////
Packit Service 6754ca
//
Packit Service 6754ca
// Copyright (c) 2014, Industrial Light & Magic, a division of Lucas
Packit Service 6754ca
// Digital Ltd. LLC
Packit Service 6754ca
// 
Packit Service 6754ca
// All rights reserved.
Packit Service 6754ca
// 
Packit Service 6754ca
// Redistribution and use in source and binary forms, with or without
Packit Service 6754ca
// modification, are permitted provided that the following conditions are
Packit Service 6754ca
// met:
Packit Service 6754ca
// *       Redistributions of source code must retain the above copyright
Packit Service 6754ca
// notice, this list of conditions and the following disclaimer.
Packit Service 6754ca
// *       Redistributions in binary form must reproduce the above
Packit Service 6754ca
// copyright notice, this list of conditions and the following disclaimer
Packit Service 6754ca
// in the documentation and/or other materials provided with the
Packit Service 6754ca
// distribution.
Packit Service 6754ca
// *       Neither the name of Industrial Light & Magic nor the names of
Packit Service 6754ca
// its contributors may be used to endorse or promote products derived
Packit Service 6754ca
// from this software without specific prior written permission. 
Packit Service 6754ca
// 
Packit Service 6754ca
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit Service 6754ca
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit Service 6754ca
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Packit Service 6754ca
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
Packit Service 6754ca
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
Packit Service 6754ca
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
Packit Service 6754ca
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Packit Service 6754ca
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Packit Service 6754ca
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Packit Service 6754ca
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit Service 6754ca
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit Service 6754ca
//
Packit Service 6754ca
///////////////////////////////////////////////////////////////////////////
Packit Service 6754ca
Packit Service 6754ca
//----------------------------------------------------------------------------
Packit Service 6754ca
//
Packit Service 6754ca
//      class Image
Packit Service 6754ca
//
Packit Service 6754ca
//----------------------------------------------------------------------------
Packit Service 6754ca
Packit Service 6754ca
#include "ImfImage.h"
Packit Service 6754ca
#include <ImfChannelList.h>
Packit Service 6754ca
#include <Iex.h>
Packit Service 6754ca
#include <cassert>
Packit Service 6754ca
#include <algorithm>
Packit Service 6754ca
Packit Service 6754ca
using namespace IMATH_NAMESPACE;
Packit Service 6754ca
using namespace IEX_NAMESPACE;
Packit Service 6754ca
using namespace std;
Packit Service 6754ca
Packit Service 6754ca
OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
Packit Service 6754ca
Packit Service 6754ca
namespace {
Packit Service 6754ca
Packit Service 6754ca
int
Packit Service 6754ca
levelSize (int min, int max, int l, LevelRoundingMode levelRoundingMode)
Packit Service 6754ca
{
Packit Service 6754ca
    assert (l >= 0);
Packit Service 6754ca
Packit Service 6754ca
    if (max < min)
Packit Service 6754ca
        return 0;
Packit Service 6754ca
Packit Service 6754ca
    int a = max - min + 1;
Packit Service 6754ca
    int b = (1 << l);
Packit Service 6754ca
    int size = a / b;
Packit Service 6754ca
Packit Service 6754ca
    if (levelRoundingMode == ROUND_UP && size * b < a)
Packit Service 6754ca
	size += 1;
Packit Service 6754ca
Packit Service 6754ca
    return std::max (size, 1);
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
Box2i
Packit Service 6754ca
computeDataWindowForLevel
Packit Service 6754ca
    (const Box2i& dataWindow,
Packit Service 6754ca
     int lx, int ly,
Packit Service 6754ca
     LevelRoundingMode lrMode)
Packit Service 6754ca
{
Packit Service 6754ca
    V2i levelMax =
Packit Service 6754ca
        dataWindow.min +
Packit Service 6754ca
        V2i (levelSize (dataWindow.min.x, dataWindow.max.x, lx, lrMode) - 1,
Packit Service 6754ca
             levelSize (dataWindow.min.y, dataWindow.max.y, ly, lrMode) - 1);
Packit Service 6754ca
Packit Service 6754ca
    return Box2i (dataWindow.min, levelMax);
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
int
Packit Service 6754ca
floorLog2 (int x)
Packit Service 6754ca
{
Packit Service 6754ca
    //
Packit Service 6754ca
    // For x > 0, floorLog2(y) returns floor(log(x)/log(2)).
Packit Service 6754ca
    //
Packit Service 6754ca
Packit Service 6754ca
    int y = 0;
Packit Service 6754ca
Packit Service 6754ca
    while (x > 1)
Packit Service 6754ca
    {
Packit Service 6754ca
	y +=  1;
Packit Service 6754ca
	x >>= 1;
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    return y;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
int
Packit Service 6754ca
ceilLog2 (int x)
Packit Service 6754ca
{
Packit Service 6754ca
    //
Packit Service 6754ca
    // For x > 0, ceilLog2(y) returns ceil(log(x)/log(2)).
Packit Service 6754ca
    //
Packit Service 6754ca
Packit Service 6754ca
    int y = 0;
Packit Service 6754ca
    int r = 0;
Packit Service 6754ca
Packit Service 6754ca
    while (x > 1)
Packit Service 6754ca
    {
Packit Service 6754ca
	if (x & 1)
Packit Service 6754ca
	    r = 1;
Packit Service 6754ca
Packit Service 6754ca
	y +=  1;
Packit Service 6754ca
	x >>= 1;
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    return y + r;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
int
Packit Service 6754ca
roundLog2 (int x, LevelRoundingMode levelRoundingMode)
Packit Service 6754ca
{
Packit Service 6754ca
    if (x < 1)
Packit Service 6754ca
        return 1;
Packit Service 6754ca
Packit Service 6754ca
    return (levelRoundingMode == ROUND_DOWN)? floorLog2 (x): ceilLog2 (x);
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
int
Packit Service 6754ca
computeNumXLevels
Packit Service 6754ca
    (const Box2i& dataWindow,
Packit Service 6754ca
     LevelMode levelMode,
Packit Service 6754ca
     LevelRoundingMode levelRoundingMode)
Packit Service 6754ca
{
Packit Service 6754ca
    int n = 0;
Packit Service 6754ca
Packit Service 6754ca
    switch (levelMode)
Packit Service 6754ca
    {
Packit Service 6754ca
      case ONE_LEVEL:
Packit Service 6754ca
Packit Service 6754ca
	n = 1;
Packit Service 6754ca
	break;
Packit Service 6754ca
Packit Service 6754ca
      case MIPMAP_LEVELS:
Packit Service 6754ca
Packit Service 6754ca
	{
Packit Service 6754ca
	  int w = dataWindow.max.x - dataWindow.min.x + 1;
Packit Service 6754ca
	  int h = dataWindow.max.y - dataWindow.min.y + 1;
Packit Service 6754ca
	  n = roundLog2 (std::max (w, h), levelRoundingMode) + 1;
Packit Service 6754ca
	}
Packit Service 6754ca
        break;
Packit Service 6754ca
Packit Service 6754ca
      case RIPMAP_LEVELS:
Packit Service 6754ca
Packit Service 6754ca
	{
Packit Service 6754ca
	  int w = dataWindow.max.x - dataWindow.min.x + 1;
Packit Service 6754ca
	  n = roundLog2 (w, levelRoundingMode) + 1;
Packit Service 6754ca
	}
Packit Service 6754ca
	break;
Packit Service 6754ca
Packit Service 6754ca
      default:
Packit Service 6754ca
Packit Service 6754ca
        assert (false);
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    return n;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
int
Packit Service 6754ca
computeNumYLevels
Packit Service 6754ca
    (const Box2i& dataWindow,
Packit Service 6754ca
     LevelMode levelMode,
Packit Service 6754ca
     LevelRoundingMode levelRoundingMode)
Packit Service 6754ca
{
Packit Service 6754ca
    int n = 0;
Packit Service 6754ca
Packit Service 6754ca
    switch (levelMode)
Packit Service 6754ca
    {
Packit Service 6754ca
      case ONE_LEVEL:
Packit Service 6754ca
Packit Service 6754ca
	n = 1;
Packit Service 6754ca
	break;
Packit Service 6754ca
Packit Service 6754ca
      case MIPMAP_LEVELS:
Packit Service 6754ca
Packit Service 6754ca
	{
Packit Service 6754ca
	  int w = dataWindow.max.x - dataWindow.min.x + 1;
Packit Service 6754ca
	  int h = dataWindow.max.y - dataWindow.min.y + 1;
Packit Service 6754ca
	  n = roundLog2 (std::max (w, h), levelRoundingMode) + 1;
Packit Service 6754ca
	}
Packit Service 6754ca
        break;
Packit Service 6754ca
Packit Service 6754ca
      case RIPMAP_LEVELS:
Packit Service 6754ca
Packit Service 6754ca
	{
Packit Service 6754ca
	  int h = dataWindow.max.y - dataWindow.min.y + 1;
Packit Service 6754ca
	  n = roundLog2 (h, levelRoundingMode) + 1;
Packit Service 6754ca
	}
Packit Service 6754ca
	break;
Packit Service 6754ca
Packit Service 6754ca
      default:
Packit Service 6754ca
Packit Service 6754ca
        assert (false);
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    return n;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
} // namespace
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
Image::Image ():
Packit Service 6754ca
    _dataWindow (Box2i (V2i (0, 0), V2i (-1, -1))),
Packit Service 6754ca
    _levelMode (ONE_LEVEL),
Packit Service 6754ca
    _levelRoundingMode (ROUND_DOWN),
Packit Service 6754ca
    _channels(),
Packit Service 6754ca
    _levels()
Packit Service 6754ca
{
Packit Service 6754ca
    // empty
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
Image::~Image ()
Packit Service 6754ca
{
Packit Service 6754ca
    clearLevels();
Packit Service 6754ca
    clearChannels();
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
LevelMode
Packit Service 6754ca
Image::levelMode () const
Packit Service 6754ca
{
Packit Service 6754ca
    return _levelMode;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
LevelRoundingMode
Packit Service 6754ca
Image::levelRoundingMode () const
Packit Service 6754ca
{
Packit Service 6754ca
    return _levelRoundingMode;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
int
Packit Service 6754ca
Image::numLevels () const
Packit Service 6754ca
{
Packit Service 6754ca
    if (_levelMode == ONE_LEVEL || _levelMode == MIPMAP_LEVELS)
Packit Service 6754ca
        return numXLevels();
Packit Service 6754ca
    else
Packit Service 6754ca
        throw LogicExc ("Number of levels query for image "
Packit Service 6754ca
                        "must specify x or y direction.");
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
int
Packit Service 6754ca
Image::numXLevels () const
Packit Service 6754ca
{
Packit Service 6754ca
    return _levels.width();
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
int
Packit Service 6754ca
Image::numYLevels () const
Packit Service 6754ca
{
Packit Service 6754ca
    return _levels.height();
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
const Box2i &
Packit Service 6754ca
Image::dataWindow () const
Packit Service 6754ca
{
Packit Service 6754ca
    return _dataWindow;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
const Box2i &
Packit Service 6754ca
Image::dataWindowForLevel (int l) const
Packit Service 6754ca
{
Packit Service 6754ca
    return dataWindowForLevel (l, l);
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
const Box2i &
Packit Service 6754ca
Image::dataWindowForLevel (int lx, int ly) const
Packit Service 6754ca
{
Packit Service 6754ca
    if (!levelNumberIsValid (lx, ly))
Packit Service 6754ca
    {
Packit Service 6754ca
        THROW (ArgExc,
Packit Service 6754ca
               "Cannot get data window for invalid image "
Packit Service 6754ca
               "level (" << lx << ", " << ly << ").");
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    return _levels[ly][lx]->dataWindow();
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
int
Packit Service 6754ca
Image::levelWidth  (int lx) const
Packit Service 6754ca
{
Packit Service 6754ca
    if (lx < 0 || lx >= numXLevels())
Packit Service 6754ca
    {
Packit Service 6754ca
        THROW (ArgExc,
Packit Service 6754ca
               "Cannot get level width for invalid "
Packit Service 6754ca
               "image level number " << lx << ".");
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    return levelSize (_dataWindow.min.x, _dataWindow.max.x,
Packit Service 6754ca
                      lx, _levelRoundingMode);
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
int
Packit Service 6754ca
Image::levelHeight (int ly) const
Packit Service 6754ca
{
Packit Service 6754ca
    if (ly < 0 || ly >= numYLevels())
Packit Service 6754ca
    {
Packit Service 6754ca
        THROW (ArgExc,
Packit Service 6754ca
               "Cannot get level height for invalid "
Packit Service 6754ca
               "image level number " << ly << ".");
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    return levelSize (_dataWindow.min.y, _dataWindow.max.y,
Packit Service 6754ca
                      ly, _levelRoundingMode);
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
Image::resize (const Imath::Box2i &dataWindow)
Packit Service 6754ca
{
Packit Service 6754ca
    resize (dataWindow, _levelMode, _levelRoundingMode);
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
Image::resize
Packit Service 6754ca
    (const Imath::Box2i &dataWindow,
Packit Service 6754ca
     LevelMode levelMode,
Packit Service 6754ca
     LevelRoundingMode levelRoundingMode)
Packit Service 6754ca
{
Packit Service 6754ca
    try
Packit Service 6754ca
    {
Packit Service 6754ca
        clearLevels();
Packit Service 6754ca
Packit Service 6754ca
        int nx = computeNumXLevels (dataWindow, levelMode, levelRoundingMode);
Packit Service 6754ca
        int ny = computeNumYLevels (dataWindow, levelMode, levelRoundingMode);
Packit Service 6754ca
Packit Service 6754ca
        _levels.resizeErase (ny, nx);
Packit Service 6754ca
Packit Service 6754ca
        for (int y = 0; y < ny; ++y)
Packit Service 6754ca
        {
Packit Service 6754ca
            for (int x = 0; x < nx; ++x)
Packit Service 6754ca
            {
Packit Service 6754ca
                if (levelMode == MIPMAP_LEVELS && x != y)
Packit Service 6754ca
                {
Packit Service 6754ca
                    _levels[y][x] = 0;
Packit Service 6754ca
                    continue;
Packit Service 6754ca
                }
Packit Service 6754ca
Packit Service 6754ca
                Box2i levelDataWindow =
Packit Service 6754ca
                    computeDataWindowForLevel (dataWindow,
Packit Service 6754ca
                                               x, y,
Packit Service 6754ca
                                               levelRoundingMode);
Packit Service 6754ca
Packit Service 6754ca
                _levels[y][x] = newLevel (x, y, levelDataWindow);
Packit Service 6754ca
Packit Service 6754ca
                for (ChannelMap::iterator i = _channels.begin();
Packit Service 6754ca
                     i != _channels.end();
Packit Service 6754ca
                     ++i)
Packit Service 6754ca
                {
Packit Service 6754ca
                    _levels[y][x]->insertChannel (i->first,
Packit Service 6754ca
                                                  i->second.type,
Packit Service 6754ca
                                                  i->second.xSampling,
Packit Service 6754ca
                                                  i->second.ySampling,
Packit Service 6754ca
                                                  i->second.pLinear);
Packit Service 6754ca
                }
Packit Service 6754ca
            }
Packit Service 6754ca
        }
Packit Service 6754ca
Packit Service 6754ca
        _dataWindow = dataWindow;
Packit Service 6754ca
        _levelMode = levelMode;
Packit Service 6754ca
        _levelRoundingMode = levelRoundingMode;
Packit Service 6754ca
    }
Packit Service 6754ca
    catch (...)
Packit Service 6754ca
    {
Packit Service 6754ca
        clearLevels();
Packit Service 6754ca
        throw;
Packit Service 6754ca
    }
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
Image::shiftPixels (int dx, int dy)
Packit Service 6754ca
{
Packit Service 6754ca
    for (ChannelMap::iterator i = _channels.begin(); i != _channels.end(); ++i)
Packit Service 6754ca
    {
Packit Service 6754ca
        if (dx % i->second.xSampling != 0)
Packit Service 6754ca
        {
Packit Service 6754ca
            THROW (ArgExc, "Cannot shift image horizontally by " << dx << " "
Packit Service 6754ca
                           "pixels.  The shift distance must be a multiple "
Packit Service 6754ca
                           "of the x sampling rate of all channels, but the "
Packit Service 6754ca
                           "x sampling rate channel " << i->first << " "
Packit Service 6754ca
                           "is " << i->second.xSampling << ".");
Packit Service 6754ca
        }
Packit Service 6754ca
Packit Service 6754ca
        if (dy % i->second.ySampling != 0)
Packit Service 6754ca
        {
Packit Service 6754ca
            THROW (ArgExc, "Cannot shift image vertically by " << dy << " "
Packit Service 6754ca
                           "pixels.  The shift distance must be a multiple "
Packit Service 6754ca
                           "of the y sampling rate of all channels, but the "
Packit Service 6754ca
                           "y sampling rate channel " << i->first << " "
Packit Service 6754ca
                           "is " << i->second.ySampling << ".");
Packit Service 6754ca
        }
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    _dataWindow.min.x += dx;
Packit Service 6754ca
    _dataWindow.min.y += dy;
Packit Service 6754ca
    _dataWindow.max.x += dx;
Packit Service 6754ca
    _dataWindow.max.y += dy;
Packit Service 6754ca
Packit Service 6754ca
    for (int y = 0; y < _levels.height(); ++y)
Packit Service 6754ca
        for (int x = 0; x < _levels.width(); ++x)
Packit Service 6754ca
            if (_levels[y][x])
Packit Service 6754ca
                _levels[y][x]->shiftPixels (dx, dy);
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
Image::insertChannel
Packit Service 6754ca
    (const std::string &name,
Packit Service 6754ca
     PixelType type,
Packit Service 6754ca
     int xSampling,
Packit Service 6754ca
     int ySampling,
Packit Service 6754ca
     bool pLinear)
Packit Service 6754ca
{
Packit Service 6754ca
    try
Packit Service 6754ca
    {
Packit Service 6754ca
        _channels[name] = ChannelInfo (type, xSampling, ySampling, pLinear);
Packit Service 6754ca
Packit Service 6754ca
        for (int y = 0; y < _levels.height(); ++y)
Packit Service 6754ca
            for (int x = 0; x < _levels.width(); ++x)
Packit Service 6754ca
                if (_levels[y][x])
Packit Service 6754ca
                    _levels[y][x]->insertChannel
Packit Service 6754ca
                                    (name, type, xSampling, ySampling, pLinear);
Packit Service 6754ca
    }
Packit Service 6754ca
    catch (...)
Packit Service 6754ca
    {
Packit Service 6754ca
        eraseChannel (name);
Packit Service 6754ca
        throw;
Packit Service 6754ca
    }
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
Image::insertChannel (const string &name, const Channel &channel)
Packit Service 6754ca
{
Packit Service 6754ca
    insertChannel (name,
Packit Service 6754ca
                   channel.type,
Packit Service 6754ca
                   channel.xSampling,
Packit Service 6754ca
                   channel.ySampling,
Packit Service 6754ca
                   channel.pLinear);
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void                   
Packit Service 6754ca
Image::eraseChannel (const std::string &name)
Packit Service 6754ca
{
Packit Service 6754ca
    //
Packit Service 6754ca
    // Note: eraseChannel() is called to clean up if an exception is
Packit Service 6754ca
    // thrown during a call during insertChannel(), so eraseChannel()
Packit Service 6754ca
    // must work correctly even after an incomplete insertChannel()
Packit Service 6754ca
    // operation.
Packit Service 6754ca
    //
Packit Service 6754ca
Packit Service 6754ca
    for (int y = 0; y < _levels.height(); ++y)
Packit Service 6754ca
        for (int x = 0; x < _levels.width(); ++x)
Packit Service 6754ca
            if (_levels[y][x])
Packit Service 6754ca
                _levels[y][x]->eraseChannel (name);
Packit Service 6754ca
Packit Service 6754ca
    ChannelMap::iterator i = _channels.find (name);
Packit Service 6754ca
Packit Service 6754ca
    if (i != _channels.end())
Packit Service 6754ca
        _channels.erase (i);
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
Image::clearChannels ()
Packit Service 6754ca
{
Packit Service 6754ca
    for (int y = 0; y < _levels.height(); ++y)
Packit Service 6754ca
        for (int x = 0; x < _levels.width(); ++x)
Packit Service 6754ca
            if (_levels[y][x])
Packit Service 6754ca
                _levels[y][x]->clearChannels();
Packit Service 6754ca
                
Packit Service 6754ca
    _channels.clear();
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
Image::renameChannel (const string &oldName, const string &newName)
Packit Service 6754ca
{
Packit Service 6754ca
    if (oldName == newName)
Packit Service 6754ca
        return;
Packit Service 6754ca
Packit Service 6754ca
    ChannelMap::iterator oldChannel = _channels.find (oldName);
Packit Service 6754ca
Packit Service 6754ca
    if (oldChannel == _channels.end())
Packit Service 6754ca
    {
Packit Service 6754ca
        THROW (ArgExc, "Cannot rename image channel " << oldName << " "
Packit Service 6754ca
                       "to " << newName << ".  The image does not have "
Packit Service 6754ca
                       "a channel called " << oldName << ".");
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    if (_channels.find (newName) != _channels.end())
Packit Service 6754ca
    {
Packit Service 6754ca
        THROW (ArgExc, "Cannot rename image channel " << oldName << " "
Packit Service 6754ca
                       "to " << newName << ".  The image already has "
Packit Service 6754ca
                       "a channel called " << newName << ".");
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    try
Packit Service 6754ca
    {
Packit Service 6754ca
        for (int y = 0; y < _levels.height(); ++y)
Packit Service 6754ca
            for (int x = 0; x < _levels.width(); ++x)
Packit Service 6754ca
                if (_levels[y][x])
Packit Service 6754ca
                    _levels[y][x]->renameChannel (oldName, newName);
Packit Service 6754ca
Packit Service 6754ca
        _channels[newName] = oldChannel->second;
Packit Service 6754ca
        _channels.erase (oldChannel);
Packit Service 6754ca
    }
Packit Service 6754ca
    catch (...)
Packit Service 6754ca
    {
Packit Service 6754ca
        eraseChannel (oldName);
Packit Service 6754ca
        eraseChannel (newName);
Packit Service 6754ca
        throw;
Packit Service 6754ca
    }
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
Image::renameChannels (const RenamingMap &oldToNewNames)
Packit Service 6754ca
{
Packit Service 6754ca
    set <string> newNames;
Packit Service 6754ca
Packit Service 6754ca
    for (ChannelMap::const_iterator i = _channels.begin();
Packit Service 6754ca
         i != _channels.end();
Packit Service 6754ca
         ++i)
Packit Service 6754ca
    {
Packit Service 6754ca
        RenamingMap::const_iterator j = oldToNewNames.find (i->first);
Packit Service 6754ca
        std::string newName = (j == oldToNewNames.end())? i->first: j->second;
Packit Service 6754ca
Packit Service 6754ca
        if (newNames.find (newName) != newNames.end())
Packit Service 6754ca
        {
Packit Service 6754ca
            THROW (ArgExc, "Cannot rename image channels.  More than one "
Packit Service 6754ca
                           "channel would be named \"" << newName << "\".");
Packit Service 6754ca
        }
Packit Service 6754ca
        else
Packit Service 6754ca
        {
Packit Service 6754ca
            newNames.insert (newName);
Packit Service 6754ca
        }
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    try
Packit Service 6754ca
    {
Packit Service 6754ca
        renameChannelsInMap (oldToNewNames, _channels);
Packit Service 6754ca
Packit Service 6754ca
        for (int y = 0; y < _levels.height(); ++y)
Packit Service 6754ca
            for (int x = 0; x < _levels.width(); ++x)
Packit Service 6754ca
                if (_levels[y][x])
Packit Service 6754ca
                    _levels[y][x]->renameChannels (oldToNewNames);
Packit Service 6754ca
    }
Packit Service 6754ca
    catch (...)
Packit Service 6754ca
    {
Packit Service 6754ca
        clearChannels();
Packit Service 6754ca
        throw;
Packit Service 6754ca
    }
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
ImageLevel &
Packit Service 6754ca
Image::level (int l)
Packit Service 6754ca
{
Packit Service 6754ca
    return level (l, l);
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
const ImageLevel &
Packit Service 6754ca
Image::level (int l) const
Packit Service 6754ca
{
Packit Service 6754ca
    return level (l, l);
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
ImageLevel &
Packit Service 6754ca
Image::level (int lx, int ly)
Packit Service 6754ca
{
Packit Service 6754ca
    if (!levelNumberIsValid (lx, ly))
Packit Service 6754ca
    {
Packit Service 6754ca
        THROW (ArgExc,
Packit Service 6754ca
               "Cannot access image level with invalid "
Packit Service 6754ca
               "level number (" << lx << ", " << ly << ").");
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    return *_levels[ly][lx];
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
const ImageLevel &
Packit Service 6754ca
Image::level (int lx, int ly) const
Packit Service 6754ca
{
Packit Service 6754ca
    if (!levelNumberIsValid (lx, ly))
Packit Service 6754ca
    {
Packit Service 6754ca
        THROW (ArgExc,
Packit Service 6754ca
               "Cannot access image level with invalid "
Packit Service 6754ca
               "level number (" << lx << ", " << ly << ").");
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    return *_levels[ly][lx];
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
bool
Packit Service 6754ca
Image::levelNumberIsValid (int lx, int ly) const
Packit Service 6754ca
{
Packit Service 6754ca
    return lx >= 0 && lx < _levels.width() &&
Packit Service 6754ca
           ly >= 0 && ly < _levels.height() &&
Packit Service 6754ca
           _levels[ly][lx] != 0;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
Image::clearLevels ()
Packit Service 6754ca
{
Packit Service 6754ca
    _dataWindow = Box2i (V2i (0, 0), V2i (-1, -1));
Packit Service 6754ca
Packit Service 6754ca
    for (int y = 0; y < _levels.height(); ++y)
Packit Service 6754ca
        for (int x = 0; x < _levels.width(); ++x)
Packit Service 6754ca
            delete _levels[y][x];
Packit Service 6754ca
Packit Service 6754ca
    _levels.resizeErase (0, 0);
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
Image::ChannelInfo::ChannelInfo
Packit Service 6754ca
    (PixelType type,
Packit Service 6754ca
     int xSampling,
Packit Service 6754ca
     int ySampling,
Packit Service 6754ca
     bool pLinear)
Packit Service 6754ca
:
Packit Service 6754ca
    type (type),
Packit Service 6754ca
    xSampling (xSampling),
Packit Service 6754ca
    ySampling (ySampling),
Packit Service 6754ca
    pLinear (pLinear)
Packit Service 6754ca
{
Packit Service 6754ca
    // empty
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT