Blame IlmImfUtil/ImfImage.h

Packit 0d464f
///////////////////////////////////////////////////////////////////////////
Packit 0d464f
//
Packit 0d464f
// Copyright (c) 2014, Industrial Light & Magic, a division of Lucas
Packit 0d464f
// Digital Ltd. LLC
Packit 0d464f
// 
Packit 0d464f
// All rights reserved.
Packit 0d464f
// 
Packit 0d464f
// Redistribution and use in source and binary forms, with or without
Packit 0d464f
// modification, are permitted provided that the following conditions are
Packit 0d464f
// met:
Packit 0d464f
// *       Redistributions of source code must retain the above copyright
Packit 0d464f
// notice, this list of conditions and the following disclaimer.
Packit 0d464f
// *       Redistributions in binary form must reproduce the above
Packit 0d464f
// copyright notice, this list of conditions and the following disclaimer
Packit 0d464f
// in the documentation and/or other materials provided with the
Packit 0d464f
// distribution.
Packit 0d464f
// *       Neither the name of Industrial Light & Magic nor the names of
Packit 0d464f
// its contributors may be used to endorse or promote products derived
Packit 0d464f
// from this software without specific prior written permission. 
Packit 0d464f
// 
Packit 0d464f
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit 0d464f
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit 0d464f
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Packit 0d464f
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
Packit 0d464f
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
Packit 0d464f
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
Packit 0d464f
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Packit 0d464f
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Packit 0d464f
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Packit 0d464f
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit 0d464f
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 0d464f
//
Packit 0d464f
///////////////////////////////////////////////////////////////////////////
Packit 0d464f
Packit 0d464f
#ifndef INCLUDED_IMF_IMAGE_H
Packit 0d464f
#define INCLUDED_IMF_IMAGE_H
Packit 0d464f
Packit 0d464f
//----------------------------------------------------------------------------
Packit 0d464f
//
Packit 0d464f
// class Image -- an in-memory data structure that can hold an arbitrary
Packit 0d464f
// OpenEXR image, flat or deep, with one or multiple resolution levels,
Packit 0d464f
// and with an arbitrary set of channels.
Packit 0d464f
// 
Packit 0d464f
// An image is a container for a set of image levels, and an image level
Packit 0d464f
// is a container for a set of image channels.  An image channel contains
Packit 0d464f
// an array of pixel values of type half, float or unsigned int.
Packit 0d464f
// 
Packit 0d464f
// For example:
Packit 0d464f
// 
Packit 0d464f
//     image --+-- level 0 --+-- channel "R" --- pixel data
Packit 0d464f
//             |             |
Packit 0d464f
//             |             +-- channel "G" --- pixel data
Packit 0d464f
//             |             |
Packit 0d464f
//             |             +-- channel "B" --- pixel data
Packit 0d464f
//             |
Packit 0d464f
//             +-- level 1 --+-- channel "R" --- pixel data
Packit 0d464f
//             |             |
Packit 0d464f
//             |             +-- channel "G" --- pixel data
Packit 0d464f
//             |             |
Packit 0d464f
//             |             +-- channel "B" --- pixel data
Packit 0d464f
//             |
Packit 0d464f
//             +-- level 2 --+-- channel "R" --- pixel data
Packit 0d464f
//                           |
Packit 0d464f
//                           +-- channel "G" --- pixel data
Packit 0d464f
//                           |
Packit 0d464f
//                           +-- channel "B" --- pixel data
Packit 0d464f
// 
Packit 0d464f
// An image has a level mode, which can be ONE_LEVEL, MIPMAP_LEVELS or
Packit 0d464f
// RIPMAP_LEVELS, and a level rounding mode, which can be ROUND_UP or
Packit 0d464f
// ROUND_DOWN.  Together, the level mode and the level rounding mode
Packit 0d464f
// determine how many levels an image contains, and how large the data
Packit 0d464f
// window for each level is.  All levels in an image have the same set
Packit 0d464f
// of channels.
Packit 0d464f
// 
Packit 0d464f
// An image channel has a name (e.g. "R", "Z", or "xVelocity"), a type
Packit 0d464f
// (HALF, FLOAT or UINT) and x and y sampling rates.  A channel stores
Packit 0d464f
// samples for a pixel if the pixel is inside the data window of the
Packit 0d464f
// level to which the channel belongs, and the x and y coordinates of
Packit 0d464f
// the pixel are divisible by the x and y sampling rates of the channel.
Packit 0d464f
//
Packit 0d464f
// An image can be either flat or deep.  In a flat image each channel
Packit 0d464f
// in each level stores at most one value per pixel.  In a deep image
Packit 0d464f
// each channel in each level stores an arbitrary number of values per
Packit 0d464f
// pixel.  As an exception, each level of a deep image has a sample count
Packit 0d464f
// channel with a single value per pixel; this value determines how many
Packit 0d464f
// values each of the other channels in the same level has at the same
Packit 0d464f
// pixel location.
Packit 0d464f
//
Packit 0d464f
// The classes Image, ImageLevel and ImageChannel are abstract base
Packit 0d464f
// classes.  Two sets of concrete classes, one for flat and one for
Packit 0d464f
// deep images, are derived from the base classes.
Packit 0d464f
//
Packit 0d464f
//----------------------------------------------------------------------------
Packit 0d464f
Packit 0d464f
#include "ImfImageLevel.h"
Packit 0d464f
#include <ImfTileDescription.h>
Packit 0d464f
#include <ImfArray.h>
Packit 0d464f
#include "ImfExport.h"
Packit 0d464f
Packit 0d464f
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
Packit 0d464f
Packit 0d464f
class Channel;
Packit 0d464f
Packit 0d464f
Packit 0d464f
class IMF_EXPORT Image
Packit 0d464f
{
Packit 0d464f
  public:
Packit 0d464f
Packit 0d464f
    //
Packit 0d464f
    // Constructor and destructor
Packit 0d464f
    //
Packit 0d464f
Packit 0d464f
    Image ();
Packit 0d464f
    virtual ~Image ();
Packit 0d464f
Packit 0d464f
Packit 0d464f
    //
Packit 0d464f
    // Access to the image's level mode and level rounding mode.
Packit 0d464f
    //
Packit 0d464f
Packit 0d464f
	LevelMode               levelMode() const;
Packit 0d464f
	LevelRoundingMode       levelRoundingMode() const;
Packit 0d464f
Packit 0d464f
Packit 0d464f
    //
Packit 0d464f
    // Number of levels:
Packit 0d464f
    //
Packit 0d464f
    // numXLevels() returns the image's number of levels in the x direction.
Packit 0d464f
    //
Packit 0d464f
    //	if levelMode() == ONE_LEVEL:
Packit 0d464f
    //      return value is: 1
Packit 0d464f
    //
Packit 0d464f
    //	if levelMode() == MIPMAP_LEVELS:
Packit 0d464f
    //      return value is: rfunc (log (max (w, h)) / log (2)) + 1
Packit 0d464f
    //
Packit 0d464f
    //	if levelMode() == RIPMAP_LEVELS:
Packit 0d464f
    //      return value is: rfunc (log (w) / log (2)) + 1
Packit 0d464f
    //
Packit 0d464f
    //	where
Packit 0d464f
    //	    w is the width of the image's data window,  max.x - min.x + 1,
Packit 0d464f
    //	    h is the height of the image's data window, max.y - min.y + 1,
Packit 0d464f
    //	    and rfunc(x) is either floor(x), or ceil(x), depending on
Packit 0d464f
    //	    whether levelRoundingMode() returns ROUND_DOWN or ROUND_UP.
Packit 0d464f
    //
Packit 0d464f
    // numYLevels() returns the image's number of levels in the y direction.
Packit 0d464f
    //
Packit 0d464f
    //	if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
Packit 0d464f
    //      return value is the same as for numXLevels()
Packit 0d464f
    //
Packit 0d464f
    //	if levelMode() == RIPMAP_LEVELS:
Packit 0d464f
    //      return value is: rfunc (log (h) / log (2)) + 1
Packit 0d464f
    //
Packit 0d464f
    //
Packit 0d464f
    // numLevels() is a convenience function for use with MIPMAP_LEVELS images.
Packit 0d464f
    //
Packit 0d464f
    //	if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
Packit 0d464f
    //      return value is the same as for numXLevels()
Packit 0d464f
    //
Packit 0d464f
    //	if levelMode() == RIPMAP_LEVELS:
Packit 0d464f
    //      a LogicExc exception is thrown
Packit 0d464f
    //
Packit 0d464f
Packit 0d464f
	int                     numLevels() const;
Packit 0d464f
	int                     numXLevels() const;
Packit 0d464f
	int                     numYLevels() const;
Packit 0d464f
Packit 0d464f
Packit 0d464f
    //
Packit 0d464f
    // Per-level data windows
Packit 0d464f
    //
Packit 0d464f
    // dataWindow() returns the data window for the image; this is the
Packit 0d464f
    // same as the data window for the level with level number (0, 0).
Packit 0d464f
    //
Packit 0d464f
    // dataWindowForLevel(lx, ly) returns the data window for level x,
Packit 0d464f
    // that is, the window for which the image level with level number
Packit 0d464f
    // (lx, ly) has allocated pixel storage.
Packit 0d464f
    //
Packit 0d464f
    //	return value is a Box2i with min value:
Packit 0d464f
    //      (dataWindow().min.x,
Packit 0d464f
    //       dataWindow().min.y)
Packit 0d464f
    //
Packit 0d464f
    //	and max value:
Packit 0d464f
    //      (dataWindow().min.x + levelWidth(lx) - 1,
Packit 0d464f
    //       dataWindow().min.y + levelHeight(ly) - 1)
Packit 0d464f
    //
Packit 0d464f
    // dataWindowForLevel(l) is a convenience function used for ONE_LEVEL
Packit 0d464f
    // and MIPMAP_LEVELS files.  It returns dataWindowForLevel(l,l)).
Packit 0d464f
    //
Packit 0d464f
Packit 0d464f
	const IMATH_NAMESPACE::Box2i &  dataWindow() const;
Packit 0d464f
	const IMATH_NAMESPACE::Box2i &  dataWindowForLevel(int l) const;
Packit 0d464f
	const IMATH_NAMESPACE::Box2i &  dataWindowForLevel(int lx, int ly) const;
Packit 0d464f
Packit 0d464f
Packit 0d464f
    //
Packit 0d464f
    // Size of a level:
Packit 0d464f
    //
Packit 0d464f
    // levelWidth(lx) returns the width of a level with level
Packit 0d464f
    // number (lx, *), where * is any number.
Packit 0d464f
    //
Packit 0d464f
    //	return value is:
Packit 0d464f
    //      max (1, rfunc (w / pow (2, lx)))
Packit 0d464f
    //
Packit 0d464f
    //
Packit 0d464f
    // levelHeight(ly) returns the height of a level with level
Packit 0d464f
    // number (*, ly), where * is any number.
Packit 0d464f
    //
Packit 0d464f
    //	return value is:
Packit 0d464f
    //      max (1, rfunc (h / pow (2, ly)))
Packit 0d464f
    //
Packit 0d464f
Packit 0d464f
    int			    levelWidth  (int lx) const;
Packit 0d464f
    int			    levelHeight (int ly) const;
Packit 0d464f
Packit 0d464f
Packit 0d464f
    //
Packit 0d464f
    // Resize the image:
Packit 0d464f
    //
Packit 0d464f
    // resize(dw,lm,lrm) sets the data window of the image to dw,
Packit 0d464f
    // sets the level mode to lm and the level rounding mode to lrm,
Packit 0d464f
    // and allocates new storage for image levels and image channels.
Packit 0d464f
    // The set of channels in the image does not change.
Packit 0d464f
    //
Packit 0d464f
    // The contents of the image are lost; pixel data are not preserved
Packit 0d464f
    // across the resize operation.  If resizing fails, then the image
Packit 0d464f
    // will be left with an empty data window and no image levels.
Packit 0d464f
    //
Packit 0d464f
    // resize(dw) is the same as resize(dw,levelMode(),levelRoundingMode())
Packit 0d464f
    //
Packit 0d464f
Packit 0d464f
	void                    resize(const IMATH_NAMESPACE::Box2i &dataWindow);
Packit 0d464f
Packit 0d464f
	virtual void            resize(const IMATH_NAMESPACE::Box2i &dataWindow,
Packit 0d464f
                                    LevelMode levelMode,
Packit 0d464f
                                    LevelRoundingMode levelRoundingMode);
Packit 0d464f
Packit 0d464f
    //
Packit 0d464f
    // Shift the pixels and the data window of an image:
Packit 0d464f
    //
Packit 0d464f
    // shiftPixels(dx,dy) shifts the image by dx pixels horizontally and
Packit 0d464f
    // dy pixels vertically.  A pixel at location (x,y) moves to position
Packit 0d464f
    // (x+dx, y+dy).  The data window of the image is shifted along with
Packit 0d464f
    // the pixels.  No pixel data are lost.
Packit 0d464f
    //
Packit 0d464f
    // The horizontal and vertical shift distances must be multiples of
Packit 0d464f
    // the x and y sampling rates of all image channels.  If they are not,
Packit 0d464f
    // shiftPixels() throws an ArgExc exception.
Packit 0d464f
    //
Packit 0d464f
Packit 0d464f
	void                    shiftPixels(int dx, int dy);
Packit 0d464f
Packit 0d464f
Packit 0d464f
    //
Packit 0d464f
    // Insert a new channel into the image.
Packit 0d464f
    //
Packit 0d464f
    // The arguments to this function are the same as for adding a
Packit 0d464f
    // a channel to an OpenEXR file: channel name, x and y sampling
Packit 0d464f
    // rates, and a "perceptually approximately linear" flag.
Packit 0d464f
    //
Packit 0d464f
    // If the image already contains a channel with the same name
Packit 0d464f
    // as the new name then the existing channel is deleted before
Packit 0d464f
    // the new channel is added.
Packit 0d464f
    //
Packit 0d464f
Packit 0d464f
    void                    insertChannel (const std::string &name,
Packit 0d464f
                                           PixelType type,
Packit 0d464f
                                           int xSampling = 1,
Packit 0d464f
                                           int ySampling = 1,
Packit 0d464f
                                           bool pLinear = false);
Packit 0d464f
Packit 0d464f
    void                    insertChannel (const std::string &name,
Packit 0d464f
                                           const Channel &channel);
Packit 0d464f
Packit 0d464f
    //
Packit 0d464f
    // Erase channels from an image:
Packit 0d464f
    //
Packit 0d464f
    // eraseChannel(n) erases the channel with name n.
Packit 0d464f
    // clearChannels() erases all channels.
Packit 0d464f
    //
Packit 0d464f
Packit 0d464f
	void                    eraseChannel(const std::string &name);
Packit 0d464f
	void                    clearChannels();
Packit 0d464f
Packit 0d464f
Packit 0d464f
    //
Packit 0d464f
    // Rename an image channel:
Packit 0d464f
    //
Packit 0d464f
    // renameChannel(nOld,nNew) changes the name of the image channel
Packit 0d464f
    // with name nOld to nNew.
Packit 0d464f
    //
Packit 0d464f
    // If the image already contains a channel called nNew, or if the
Packit 0d464f
    // image does not contain a channel called nOld, then renameChannel()
Packit 0d464f
    // throws an ArgExc exception.
Packit 0d464f
    //
Packit 0d464f
    // In the (unlikely) event that renaming the image channel causes
Packit 0d464f
    // the program to run out of memory, renameChannel() erases the
Packit 0d464f
    // channel that is being renamed, and throws an exception.
Packit 0d464f
    //
Packit 0d464f
Packit 0d464f
	void                    renameChannel(const std::string &oldName,
Packit 0d464f
                                           const std::string &newName);
Packit 0d464f
Packit 0d464f
    //
Packit 0d464f
    // Rename multiple image channels at the same time:
Packit 0d464f
    //
Packit 0d464f
    // Given a map, m, from old to new channel names, renameChannels(m)
Packit 0d464f
    // assigns new names to the channels in the image.  If m has an entry
Packit 0d464f
    // for a channel named c, then the channel will be renamed to m[c].
Packit 0d464f
    // If m has no entry for c, then the channel keeps its old name.
Packit 0d464f
    //
Packit 0d464f
    // If the same name would be assigned to more than one channel, then
Packit 0d464f
    // renameChannels() does not rename any channels but throws an ArgExc
Packit 0d464f
    // exception instead.
Packit 0d464f
    // 
Packit 0d464f
    // In the (unlikely) event that renaming the image channel causes the
Packit 0d464f
    // program to run out of memory, renameChannels() erases all channels
Packit 0d464f
    // in the image and throws an exception.
Packit 0d464f
    //
Packit 0d464f
Packit 0d464f
	void                    renameChannels(const RenamingMap &oldToNewNames);
Packit 0d464f
Packit 0d464f
Packit 0d464f
    //
Packit 0d464f
    // Accessing image levels by level number.
Packit 0d464f
    //
Packit 0d464f
    // level(lx,ly) returns a reference to the image level
Packit 0d464f
    // with level number (lx,ly).
Packit 0d464f
    //
Packit 0d464f
    // level(l) returns level(l,l).
Packit 0d464f
    //
Packit 0d464f
Packit 0d464f
    virtual ImageLevel &            level (int l = 0);
Packit 0d464f
    virtual const ImageLevel &      level (int l = 0) const;
Packit 0d464f
Packit 0d464f
    virtual ImageLevel &            level (int lx, int ly);
Packit 0d464f
    virtual const ImageLevel &      level (int lx, int ly) const;
Packit 0d464f
Packit 0d464f
Packit 0d464f
  protected:
Packit 0d464f
Packit 0d464f
    virtual ImageLevel *
Packit 0d464f
        newLevel (int lx, int ly, const IMATH_NAMESPACE::Box2i &dataWindow) = 0;
Packit 0d464f
Packit 0d464f
  private:
Packit 0d464f
Packit 0d464f
    bool        levelNumberIsValid (int lx, int ly) const;
Packit 0d464f
    void        clearLevels ();
Packit 0d464f
Packit 0d464f
    struct ChannelInfo
Packit 0d464f
    {
Packit 0d464f
        ChannelInfo (PixelType type = HALF,
Packit 0d464f
                     int xSampling = 1,
Packit 0d464f
                     int ySampling = 1,
Packit 0d464f
                     bool pLinear = false);
Packit 0d464f
Packit 0d464f
        PixelType   type;
Packit 0d464f
        int         xSampling;
Packit 0d464f
        int         ySampling;
Packit 0d464f
        bool        pLinear;
Packit 0d464f
    };
Packit 0d464f
Packit 0d464f
    typedef std::map <std::string, ChannelInfo> ChannelMap;
Packit 0d464f
Packit 0d464f
    IMATH_NAMESPACE::Box2i  _dataWindow;
Packit 0d464f
    LevelMode               _levelMode;
Packit 0d464f
    LevelRoundingMode       _levelRoundingMode;
Packit 0d464f
    ChannelMap              _channels;
Packit 0d464f
    Array2D<ImageLevel *>   _levels;
Packit 0d464f
};
Packit 0d464f
Packit 0d464f
Packit 0d464f
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
Packit 0d464f
Packit 0d464f
#endif