ImfImage.h 12 KB

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