HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ImfImage.h
Go to the documentation of this file.
1 //
2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright (c) Contributors to the OpenEXR Project.
4 //
5 
6 #ifndef INCLUDED_IMF_IMAGE_H
7 #define INCLUDED_IMF_IMAGE_H
8 
9 //----------------------------------------------------------------------------
10 //
11 // class Image -- an in-memory data structure that can hold an arbitrary
12 // OpenEXR image, flat or deep, with one or multiple resolution levels,
13 // and with an arbitrary set of channels.
14 //
15 // An image is a container for a set of image levels, and an image level
16 // is a container for a set of image channels. An image channel contains
17 // an array of pixel values of type half, float or unsigned int.
18 //
19 // For example:
20 //
21 // image --+-- level 0 --+-- channel "R" --- pixel data
22 // | |
23 // | +-- channel "G" --- pixel data
24 // | |
25 // | +-- channel "B" --- pixel data
26 // |
27 // +-- level 1 --+-- channel "R" --- pixel data
28 // | |
29 // | +-- channel "G" --- pixel data
30 // | |
31 // | +-- channel "B" --- pixel data
32 // |
33 // +-- level 2 --+-- channel "R" --- pixel data
34 // |
35 // +-- channel "G" --- pixel data
36 // |
37 // +-- channel "B" --- pixel data
38 //
39 // An image has a level mode, which can be ONE_LEVEL, MIPMAP_LEVELS or
40 // RIPMAP_LEVELS, and a level rounding mode, which can be ROUND_UP or
41 // ROUND_DOWN. Together, the level mode and the level rounding mode
42 // determine how many levels an image contains, and how large the data
43 // window for each level is. All levels in an image have the same set
44 // of channels.
45 //
46 // An image channel has a name (e.g. "R", "Z", or "xVelocity"), a type
47 // (HALF, FLOAT or UINT) and x and y sampling rates. A channel stores
48 // samples for a pixel if the pixel is inside the data window of the
49 // level to which the channel belongs, and the x and y coordinates of
50 // the pixel are divisible by the x and y sampling rates of the channel.
51 //
52 // An image can be either flat or deep. In a flat image each channel
53 // in each level stores at most one value per pixel. In a deep image
54 // each channel in each level stores an arbitrary number of values per
55 // pixel. As an exception, each level of a deep image has a sample count
56 // channel with a single value per pixel; this value determines how many
57 // values each of the other channels in the same level has at the same
58 // pixel location.
59 //
60 // The classes Image, ImageLevel and ImageChannel are abstract base
61 // classes. Two sets of concrete classes, one for flat and one for
62 // deep images, are derived from the base classes.
63 //
64 //----------------------------------------------------------------------------
65 
66 #include "ImfNamespace.h"
67 #include "ImfUtilExport.h"
68 
69 #include "ImfArray.h"
70 #include "ImfImageLevel.h"
71 #include "ImfTileDescription.h"
72 
74 
75 struct Channel;
76 
78 {
79 public:
80  //
81  // Constructor and destructor
82  //
83 
85  IMFUTIL_EXPORT virtual ~Image ();
86 
87  //
88  // Access to the image's level mode and level rounding mode.
89  //
90 
91  IMFUTIL_EXPORT LevelMode levelMode () const;
92  IMFUTIL_EXPORT LevelRoundingMode levelRoundingMode () const;
93 
94  //
95  // Number of levels:
96  //
97  // numXLevels() returns the image's number of levels in the x direction.
98  //
99  // if levelMode() == ONE_LEVEL:
100  // return value is: 1
101  //
102  // if levelMode() == MIPMAP_LEVELS:
103  // return value is: rfunc (log (max (w, h)) / log (2)) + 1
104  //
105  // if levelMode() == RIPMAP_LEVELS:
106  // return value is: rfunc (log (w) / log (2)) + 1
107  //
108  // where
109  // w is the width of the image's data window, max.x - min.x + 1,
110  // h is the height of the image's data window, max.y - min.y + 1,
111  // and rfunc(x) is either floor(x), or ceil(x), depending on
112  // whether levelRoundingMode() returns ROUND_DOWN or ROUND_UP.
113  //
114  // numYLevels() returns the image's number of levels in the y direction.
115  //
116  // if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
117  // return value is the same as for numXLevels()
118  //
119  // if levelMode() == RIPMAP_LEVELS:
120  // return value is: rfunc (log (h) / log (2)) + 1
121  //
122  //
123  // numLevels() is a convenience function for use with MIPMAP_LEVELS images.
124  //
125  // if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
126  // return value is the same as for numXLevels()
127  //
128  // if levelMode() == RIPMAP_LEVELS:
129  // a LogicExc exception is thrown
130  //
131 
132  IMFUTIL_EXPORT int numLevels () const;
133  IMFUTIL_EXPORT int numXLevels () const;
134  IMFUTIL_EXPORT int numYLevels () const;
135 
136  //
137  // Per-level data windows
138  //
139  // dataWindow() returns the data window for the image; this is the
140  // same as the data window for the level with level number (0, 0).
141  //
142  // dataWindowForLevel(lx, ly) returns the data window for level x,
143  // that is, the window for which the image level with level number
144  // (lx, ly) has allocated pixel storage.
145  //
146  // return value is a Box2i with min value:
147  // (dataWindow().min.x,
148  // dataWindow().min.y)
149  //
150  // and max value:
151  // (dataWindow().min.x + levelWidth(lx) - 1,
152  // dataWindow().min.y + levelHeight(ly) - 1)
153  //
154  // dataWindowForLevel(l) is a convenience function used for ONE_LEVEL
155  // and MIPMAP_LEVELS files. It returns dataWindowForLevel(l,l)).
156  //
158  const IMATH_NAMESPACE::Box2i& dataWindow () const;
160  const IMATH_NAMESPACE::Box2i& dataWindowForLevel (int l) const;
162  const IMATH_NAMESPACE::Box2i& dataWindowForLevel (int lx, int ly) const;
163 
164  //
165  // Size of a level:
166  //
167  // levelWidth(lx) returns the width of a level with level
168  // number (lx, *), where * is any number.
169  //
170  // return value is:
171  // max (1, rfunc (w / pow (2, lx)))
172  //
173  //
174  // levelHeight(ly) returns the height of a level with level
175  // number (*, ly), where * is any number.
176  //
177  // return value is:
178  // max (1, rfunc (h / pow (2, ly)))
179  //
180 
182  int levelWidth (int lx) const;
184  int levelHeight (int ly) const;
185 
186  //
187  // Resize the image:
188  //
189  // resize(dw,lm,lrm) sets the data window of the image to dw,
190  // sets the level mode to lm and the level rounding mode to lrm,
191  // and allocates new storage for image levels and image channels.
192  // The set of channels in the image does not change.
193  //
194  // The contents of the image are lost; pixel data are not preserved
195  // across the resize operation. If resizing fails, then the image
196  // will be left with an empty data window and no image levels.
197  //
198  // resize(dw) is the same as resize(dw,levelMode(),levelRoundingMode())
199  //
201  void resize (const IMATH_NAMESPACE::Box2i& dataWindow);
203  virtual void resize (
204  const IMATH_NAMESPACE::Box2i& dataWindow,
205  LevelMode levelMode,
206  LevelRoundingMode levelRoundingMode);
207 
208  //
209  // Shift the pixels and the data window of an image:
210  //
211  // shiftPixels(dx,dy) shifts the image by dx pixels horizontally and
212  // dy pixels vertically. A pixel at location (x,y) moves to position
213  // (x+dx, y+dy). The data window of the image is shifted along with
214  // the pixels. No pixel data are lost.
215  //
216  // The horizontal and vertical shift distances must be multiples of
217  // the x and y sampling rates of all image channels. If they are not,
218  // shiftPixels() throws an ArgExc exception.
219  //
221  void shiftPixels (int dx, int dy);
222 
223  //
224  // Insert a new channel into the image.
225  //
226  // The arguments to this function are the same as for adding a
227  // a channel to an OpenEXR file: channel name, x and y sampling
228  // rates, and a "perceptually approximately linear" flag.
229  //
230  // If the image already contains a channel with the same name
231  // as the new name then the existing channel is deleted before
232  // the new channel is added.
233  //
235  void insertChannel (
236  const std::string& name,
237  PixelType type,
238  int xSampling = 1,
239  int ySampling = 1,
240  bool pLinear = false);
242  void insertChannel (const std::string& name, const Channel& channel);
243 
244  //
245  // Erase channels from an image:
246  //
247  // eraseChannel(n) erases the channel with name n.
248  // clearChannels() erases all channels.
249  //
251  void eraseChannel (const std::string& name);
253  void clearChannels ();
254 
255  //
256  // Rename an image channel:
257  //
258  // renameChannel(nOld,nNew) changes the name of the image channel
259  // with name nOld to nNew.
260  //
261  // If the image already contains a channel called nNew, or if the
262  // image does not contain a channel called nOld, then renameChannel()
263  // throws an ArgExc exception.
264  //
265  // In the (unlikely) event that renaming the image channel causes
266  // the program to run out of memory, renameChannel() erases the
267  // channel that is being renamed, and throws an exception.
268  //
270  void renameChannel (const std::string& oldName, const std::string& newName);
271 
272  //
273  // Rename multiple image channels at the same time:
274  //
275  // Given a map, m, from old to new channel names, renameChannels(m)
276  // assigns new names to the channels in the image. If m has an entry
277  // for a channel named c, then the channel will be renamed to m[c].
278  // If m has no entry for c, then the channel keeps its old name.
279  //
280  // If the same name would be assigned to more than one channel, then
281  // renameChannels() does not rename any channels but throws an ArgExc
282  // exception instead.
283  //
284  // In the (unlikely) event that renaming the image channel causes the
285  // program to run out of memory, renameChannels() erases all channels
286  // in the image and throws an exception.
287  //
289  void renameChannels (const RenamingMap& oldToNewNames);
290 
291  //
292  // Accessing image levels by level number.
293  //
294  // level(lx,ly) returns a reference to the image level
295  // with level number (lx,ly).
296  //
297  // level(l) returns level(l,l).
298  //
299 
300  IMFUTIL_EXPORT virtual ImageLevel& level (int l = 0);
301  IMFUTIL_EXPORT virtual const ImageLevel& level (int l = 0) const;
302 
303  IMFUTIL_EXPORT virtual ImageLevel& level (int lx, int ly);
304  IMFUTIL_EXPORT virtual const ImageLevel& level (int lx, int ly) const;
305 
306 protected:
307  virtual ImageLevel*
308  newLevel (int lx, int ly, const IMATH_NAMESPACE::Box2i& dataWindow) = 0;
309 
310 private:
311  IMFUTIL_HIDDEN bool levelNumberIsValid (int lx, int ly) const;
312  IMFUTIL_HIDDEN void clearLevels ();
313 
314  struct IMFUTIL_HIDDEN ChannelInfo
315  {
316  ChannelInfo (
317  PixelType type = HALF,
318  int xSampling = 1,
319  int ySampling = 1,
320  bool pLinear = false);
321 
322  PixelType type;
323  int xSampling;
324  int ySampling;
325  bool pLinear;
326  };
327 
328  typedef std::map<std::string, ChannelInfo> ChannelMap;
329 
330  IMATH_NAMESPACE::Box2i _dataWindow;
331  LevelMode _levelMode;
332  LevelRoundingMode _levelRoundingMode;
333  ChannelMap _channels;
334  Array2D<ImageLevel*> _levels;
335 };
336 
338 
339 #endif
#define OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
Definition: ImfNamespace.h:83
HALF
Definition: ImfPixelType.h:23
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
GLint level
Definition: glcorearb.h:108
Definition: Image.h:45
enum IMF_EXPORT_ENUM LevelRoundingMode
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER typedef std::map< std::string, std::string > RenamingMap
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER enum IMF_EXPORT_ENUM PixelType
Definition: ImfPixelType.h:20
Box< V2i > Box2i
2D box of base type int.
Definition: ImathBox.h:143
#define IMFUTIL_EXPORT_TYPE
Definition: ImfUtilExport.h:54
GLuint const GLchar * name
Definition: glcorearb.h:786
#define IMFUTIL_EXPORT
Definition: ImfUtilExport.h:51
ImageBuf OIIO_API resize(const ImageBuf &src, string_view filtername="", float filterwidth=0.0f, ROI roi={}, int nthreads=0)
#define IMFUTIL_HIDDEN
Definition: ImfUtilExport.h:52
#define OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
Definition: ImfNamespace.h:80
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER enum IMF_EXPORT_ENUM LevelMode
std::unordered_map< char, int > ChannelMap
Definition: TypeDesc.h:16
type
Definition: core.h:1059