| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- //
- // SPDX-License-Identifier: BSD-3-Clause
- // Copyright (c) Contributors to the OpenEXR Project.
- //
- #ifndef INCLUDED_IMF_IMAGE_H
- #define INCLUDED_IMF_IMAGE_H
- //----------------------------------------------------------------------------
- //
- // class Image -- an in-memory data structure that can hold an arbitrary
- // OpenEXR image, flat or deep, with one or multiple resolution levels,
- // and with an arbitrary set of channels.
- //
- // An image is a container for a set of image levels, and an image level
- // is a container for a set of image channels. An image channel contains
- // an array of pixel values of type half, float or unsigned int.
- //
- // For example:
- //
- // image --+-- level 0 --+-- channel "R" --- pixel data
- // | |
- // | +-- channel "G" --- pixel data
- // | |
- // | +-- channel "B" --- pixel data
- // |
- // +-- level 1 --+-- channel "R" --- pixel data
- // | |
- // | +-- channel "G" --- pixel data
- // | |
- // | +-- channel "B" --- pixel data
- // |
- // +-- level 2 --+-- channel "R" --- pixel data
- // |
- // +-- channel "G" --- pixel data
- // |
- // +-- channel "B" --- pixel data
- //
- // An image has a level mode, which can be ONE_LEVEL, MIPMAP_LEVELS or
- // RIPMAP_LEVELS, and a level rounding mode, which can be ROUND_UP or
- // ROUND_DOWN. Together, the level mode and the level rounding mode
- // determine how many levels an image contains, and how large the data
- // window for each level is. All levels in an image have the same set
- // of channels.
- //
- // An image channel has a name (e.g. "R", "Z", or "xVelocity"), a type
- // (HALF, FLOAT or UINT) and x and y sampling rates. A channel stores
- // samples for a pixel if the pixel is inside the data window of the
- // level to which the channel belongs, and the x and y coordinates of
- // the pixel are divisible by the x and y sampling rates of the channel.
- //
- // An image can be either flat or deep. In a flat image each channel
- // in each level stores at most one value per pixel. In a deep image
- // each channel in each level stores an arbitrary number of values per
- // pixel. As an exception, each level of a deep image has a sample count
- // channel with a single value per pixel; this value determines how many
- // values each of the other channels in the same level has at the same
- // pixel location.
- //
- // The classes Image, ImageLevel and ImageChannel are abstract base
- // classes. Two sets of concrete classes, one for flat and one for
- // deep images, are derived from the base classes.
- //
- //----------------------------------------------------------------------------
- #include "ImfUtilExport.h"
- #include "ImfNamespace.h"
- #include "ImfImageLevel.h"
- #include "ImfTileDescription.h"
- #include "ImfArray.h"
- OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
- struct Channel;
- class IMFUTIL_EXPORT_TYPE Image
- {
- public:
- //
- // Constructor and destructor
- //
- IMFUTIL_EXPORT Image ();
- IMFUTIL_EXPORT virtual ~Image ();
- //
- // Access to the image's level mode and level rounding mode.
- //
- IMFUTIL_EXPORT LevelMode levelMode() const;
- IMFUTIL_EXPORT LevelRoundingMode levelRoundingMode() const;
- //
- // Number of levels:
- //
- // numXLevels() returns the image's number of levels in the x direction.
- //
- // if levelMode() == ONE_LEVEL:
- // return value is: 1
- //
- // if levelMode() == MIPMAP_LEVELS:
- // return value is: rfunc (log (max (w, h)) / log (2)) + 1
- //
- // if levelMode() == RIPMAP_LEVELS:
- // return value is: rfunc (log (w) / log (2)) + 1
- //
- // where
- // w is the width of the image's data window, max.x - min.x + 1,
- // h is the height of the image's data window, max.y - min.y + 1,
- // and rfunc(x) is either floor(x), or ceil(x), depending on
- // whether levelRoundingMode() returns ROUND_DOWN or ROUND_UP.
- //
- // numYLevels() returns the image's number of levels in the y direction.
- //
- // if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
- // return value is the same as for numXLevels()
- //
- // if levelMode() == RIPMAP_LEVELS:
- // return value is: rfunc (log (h) / log (2)) + 1
- //
- //
- // numLevels() is a convenience function for use with MIPMAP_LEVELS images.
- //
- // if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
- // return value is the same as for numXLevels()
- //
- // if levelMode() == RIPMAP_LEVELS:
- // a LogicExc exception is thrown
- //
- IMFUTIL_EXPORT int numLevels() const;
- IMFUTIL_EXPORT int numXLevels() const;
- IMFUTIL_EXPORT int numYLevels() const;
- //
- // Per-level data windows
- //
- // dataWindow() returns the data window for the image; this is the
- // same as the data window for the level with level number (0, 0).
- //
- // dataWindowForLevel(lx, ly) returns the data window for level x,
- // that is, the window for which the image level with level number
- // (lx, ly) has allocated pixel storage.
- //
- // return value is a Box2i with min value:
- // (dataWindow().min.x,
- // dataWindow().min.y)
- //
- // and max value:
- // (dataWindow().min.x + levelWidth(lx) - 1,
- // dataWindow().min.y + levelHeight(ly) - 1)
- //
- // dataWindowForLevel(l) is a convenience function used for ONE_LEVEL
- // and MIPMAP_LEVELS files. It returns dataWindowForLevel(l,l)).
- //
- IMFUTIL_EXPORT
- const IMATH_NAMESPACE::Box2i & dataWindow() const;
- IMFUTIL_EXPORT
- const IMATH_NAMESPACE::Box2i & dataWindowForLevel(int l) const;
- IMFUTIL_EXPORT
- const IMATH_NAMESPACE::Box2i & dataWindowForLevel(int lx, int ly) const;
- //
- // Size of a level:
- //
- // levelWidth(lx) returns the width of a level with level
- // number (lx, *), where * is any number.
- //
- // return value is:
- // max (1, rfunc (w / pow (2, lx)))
- //
- //
- // levelHeight(ly) returns the height of a level with level
- // number (*, ly), where * is any number.
- //
- // return value is:
- // max (1, rfunc (h / pow (2, ly)))
- //
- IMFUTIL_EXPORT
- int levelWidth (int lx) const;
- IMFUTIL_EXPORT
- int levelHeight (int ly) const;
- //
- // Resize the image:
- //
- // resize(dw,lm,lrm) sets the data window of the image to dw,
- // sets the level mode to lm and the level rounding mode to lrm,
- // and allocates new storage for image levels and image channels.
- // The set of channels in the image does not change.
- //
- // The contents of the image are lost; pixel data are not preserved
- // across the resize operation. If resizing fails, then the image
- // will be left with an empty data window and no image levels.
- //
- // resize(dw) is the same as resize(dw,levelMode(),levelRoundingMode())
- //
- IMFUTIL_EXPORT
- void resize(const IMATH_NAMESPACE::Box2i &dataWindow);
- IMFUTIL_EXPORT
- virtual void resize(const IMATH_NAMESPACE::Box2i &dataWindow,
- LevelMode levelMode,
- LevelRoundingMode levelRoundingMode);
- //
- // Shift the pixels and the data window of an image:
- //
- // shiftPixels(dx,dy) shifts the image by dx pixels horizontally and
- // dy pixels vertically. A pixel at location (x,y) moves to position
- // (x+dx, y+dy). The data window of the image is shifted along with
- // the pixels. No pixel data are lost.
- //
- // The horizontal and vertical shift distances must be multiples of
- // the x and y sampling rates of all image channels. If they are not,
- // shiftPixels() throws an ArgExc exception.
- //
- IMFUTIL_EXPORT
- void shiftPixels(int dx, int dy);
- //
- // Insert a new channel into the image.
- //
- // The arguments to this function are the same as for adding a
- // a channel to an OpenEXR file: channel name, x and y sampling
- // rates, and a "perceptually approximately linear" flag.
- //
- // If the image already contains a channel with the same name
- // as the new name then the existing channel is deleted before
- // the new channel is added.
- //
- IMFUTIL_EXPORT
- void insertChannel (const std::string &name,
- PixelType type,
- int xSampling = 1,
- int ySampling = 1,
- bool pLinear = false);
- IMFUTIL_EXPORT
- void insertChannel (const std::string &name,
- const Channel &channel);
- //
- // Erase channels from an image:
- //
- // eraseChannel(n) erases the channel with name n.
- // clearChannels() erases all channels.
- //
- IMFUTIL_EXPORT
- void eraseChannel(const std::string &name);
- IMFUTIL_EXPORT
- void clearChannels();
- //
- // Rename an image channel:
- //
- // renameChannel(nOld,nNew) changes the name of the image channel
- // with name nOld to nNew.
- //
- // If the image already contains a channel called nNew, or if the
- // image does not contain a channel called nOld, then renameChannel()
- // throws an ArgExc exception.
- //
- // In the (unlikely) event that renaming the image channel causes
- // the program to run out of memory, renameChannel() erases the
- // channel that is being renamed, and throws an exception.
- //
- IMFUTIL_EXPORT
- void renameChannel(const std::string &oldName,
- const std::string &newName);
- //
- // Rename multiple image channels at the same time:
- //
- // Given a map, m, from old to new channel names, renameChannels(m)
- // assigns new names to the channels in the image. If m has an entry
- // for a channel named c, then the channel will be renamed to m[c].
- // If m has no entry for c, then the channel keeps its old name.
- //
- // If the same name would be assigned to more than one channel, then
- // renameChannels() does not rename any channels but throws an ArgExc
- // exception instead.
- //
- // In the (unlikely) event that renaming the image channel causes the
- // program to run out of memory, renameChannels() erases all channels
- // in the image and throws an exception.
- //
- IMFUTIL_EXPORT
- void renameChannels(const RenamingMap &oldToNewNames);
- //
- // Accessing image levels by level number.
- //
- // level(lx,ly) returns a reference to the image level
- // with level number (lx,ly).
- //
- // level(l) returns level(l,l).
- //
- IMFUTIL_EXPORT virtual ImageLevel & level (int l = 0);
- IMFUTIL_EXPORT virtual const ImageLevel & level (int l = 0) const;
- IMFUTIL_EXPORT virtual ImageLevel & level (int lx, int ly);
- IMFUTIL_EXPORT virtual const ImageLevel & level (int lx, int ly) const;
- protected:
- virtual ImageLevel *
- newLevel (int lx, int ly, const IMATH_NAMESPACE::Box2i &dataWindow) = 0;
- private:
- IMFUTIL_HIDDEN bool levelNumberIsValid (int lx, int ly) const;
- IMFUTIL_HIDDEN void clearLevels ();
- struct IMFUTIL_HIDDEN ChannelInfo
- {
- ChannelInfo (PixelType type = HALF,
- int xSampling = 1,
- int ySampling = 1,
- bool pLinear = false);
- PixelType type;
- int xSampling;
- int ySampling;
- bool pLinear;
- };
- typedef std::map <std::string, ChannelInfo> ChannelMap;
- IMATH_NAMESPACE::Box2i _dataWindow;
- LevelMode _levelMode;
- LevelRoundingMode _levelRoundingMode;
- ChannelMap _channels;
- Array2D<ImageLevel *> _levels;
- };
- OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
- #endif
|