ImfRgbaYca.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. #ifndef INCLUDED_IMF_RGBA_YCA_H
  2. #define INCLUDED_IMF_RGBA_YCA_H
  3. //////////////////////////////////////////////////////////////////////////////
  4. //
  5. // Copyright (c) 2004, Industrial Light & Magic, a division of Lucasfilm
  6. // Entertainment Company Ltd. Portions contributed and copyright held by
  7. // others as indicated. All rights reserved.
  8. //
  9. // Redistribution and use in source and binary forms, with or without
  10. // modification, are permitted provided that the following conditions are
  11. // met:
  12. //
  13. // * Redistributions of source code must retain the above
  14. // copyright notice, this list of conditions and the following
  15. // disclaimer.
  16. //
  17. // * Redistributions in binary form must reproduce the above
  18. // copyright notice, this list of conditions and the following
  19. // disclaimer in the documentation and/or other materials provided with
  20. // the distribution.
  21. //
  22. // * Neither the name of Industrial Light & Magic nor the names of
  23. // any other contributors to this software may be used to endorse or
  24. // promote products derived from this software without specific prior
  25. // written permission.
  26. //
  27. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  28. // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  29. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  30. // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  31. // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  32. // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  33. // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  34. // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  35. // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  36. // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  37. // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. //
  39. //////////////////////////////////////////////////////////////////////////////
  40. //-----------------------------------------------------------------------------
  41. //
  42. // Conversion between RGBA (red, green, blue alpha)
  43. // and YCA (luminance, subsampled chroma, alpha) data:
  44. //
  45. // Luminance, Y, is computed as a weighted sum of R, G, and B:
  46. //
  47. // Y = yw.x * R + yw.y * G + yw.z * B
  48. //
  49. // Function computeYw() computes a set of RGB-to-Y weights, yw,
  50. // from a set of primary and white point chromaticities.
  51. //
  52. // Chroma, C, consists of two components, RY and BY:
  53. //
  54. // RY = (R - Y) / Y
  55. // BY = (B - Y) / Y
  56. //
  57. // For efficiency, the x and y subsampling rates for chroma are
  58. // hardwired to 2, and the chroma subsampling and reconstruction
  59. // filters are fixed 27-pixel wide windowed sinc functions.
  60. //
  61. // Starting with an image that has RGBA data for all pixels,
  62. //
  63. // RGBA RGBA RGBA RGBA ... RGBA RGBA
  64. // RGBA RGBA RGBA RGBA ... RGBA RGBA
  65. // RGBA RGBA RGBA RGBA ... RGBA RGBA
  66. // RGBA RGBA RGBA RGBA ... RGBA RGBA
  67. // ...
  68. // RGBA RGBA RGBA RGBA ... RGBA RGBA
  69. // RGBA RGBA RGBA RGBA ... RGBA RGBA
  70. //
  71. // function RGBAtoYCA() converts the pixels to YCA format:
  72. //
  73. // YCA YCA YCA YCA ... YCA YCA
  74. // YCA YCA YCA YCA ... YCA YCA
  75. // YCA YCA YCA YCA ... YCA YCA
  76. // YCA YCA YCA YCA ... YCA YCA
  77. // ...
  78. // YCA YCA YCA YCA ... YCA YCA
  79. // YCA YCA YCA YCA ... YCA YCA
  80. //
  81. // Next, decimateChomaHoriz() eliminates the chroma values from
  82. // the odd-numbered pixels in every scan line:
  83. //
  84. // YCA YA YCA YA ... YCA YA
  85. // YCA YA YCA YA ... YCA YA
  86. // YCA YA YCA YA ... YCA YA
  87. // YCA YA YCA YA ... YCA YA
  88. // ...
  89. // YCA YA YCA YA ... YCA YA
  90. // YCA YA YCA YA ... YCA YA
  91. //
  92. // decimateChromaVert() eliminates all chroma values from the
  93. // odd-numbered scan lines:
  94. //
  95. // YCA YA YCA YA ... YCA YA
  96. // YA YA YA YA ... YA YA
  97. // YCA YA YCA YA ... YCA YA
  98. // YA YA YA YA ... YA YA
  99. // ...
  100. // YCA YA YCA YA ... YCA YA
  101. // YA YA YA YA ... YA YA
  102. //
  103. // Finally, roundYCA() reduces the precision of the luminance
  104. // and chroma values so that the pixel data shrink more when
  105. // they are saved in a compressed file.
  106. //
  107. // The output of roundYCA() can be converted back to a set
  108. // of RGBA pixel data that is visually very similar to the
  109. // original RGBA image, by calling reconstructChromaHoriz(),
  110. // reconstructChromaVert(), YCAtoRGBA(), and finally
  111. // fixSaturation().
  112. //
  113. //-----------------------------------------------------------------------------
  114. #include "ImfRgba.h"
  115. #include "ImfChromaticities.h"
  116. #include "ImfNamespace.h"
  117. OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
  118. namespace RgbaYca {
  119. //
  120. // Width of the chroma subsampling and reconstruction filters
  121. //
  122. static const int N = 27;
  123. static const int N2 = N / 2;
  124. //
  125. // Convert a set of primary chromaticities into a set of weighting
  126. // factors for computing a pixels's luminance, Y, from R, G and B
  127. //
  128. IMF_EXPORT
  129. IMATH_NAMESPACE::V3f computeYw (const Chromaticities &cr);
  130. //
  131. // Convert an array of n RGBA pixels, rgbaIn, to YCA (luminance/chroma/alpha):
  132. //
  133. // ycaOut[i].g = Y (rgbaIn[i]);
  134. // ycaOut[i].r = RY (rgbaIn[i]);
  135. // ycaOut[i].b = BY (rgbaIn[i]);
  136. // ycaOut[i].a = aIsValid? rgbaIn[i].a: 1
  137. //
  138. // yw is a set of RGB-to-Y weighting factors, as computed by computeYw().
  139. //
  140. IMF_EXPORT
  141. void RGBAtoYCA (const IMATH_NAMESPACE::V3f &yw,
  142. int n,
  143. bool aIsValid,
  144. const Rgba rgbaIn[/*n*/],
  145. Rgba ycaOut[/*n*/]);
  146. //
  147. // Perform horizontal low-pass filtering and subsampling of
  148. // the chroma channels of an array of n pixels. In order
  149. // to avoid indexing off the ends of the input array during
  150. // low-pass filtering, ycaIn must have N2 extra pixels at
  151. // both ends. Before calling decimateChromaHoriz(), the extra
  152. // pixels should be filled with copies of the first and last
  153. // "real" input pixel.
  154. //
  155. IMF_EXPORT
  156. void decimateChromaHoriz (int n,
  157. const Rgba ycaIn[/*n+N-1*/],
  158. Rgba ycaOut[/*n*/]);
  159. //
  160. // Perform vertical chroma channel low-pass filtering and subsampling.
  161. // N scan lines of input pixels are combined into a single scan line
  162. // of output pixels.
  163. //
  164. IMF_EXPORT
  165. void decimateChromaVert (int n,
  166. const Rgba * const ycaIn[N],
  167. Rgba ycaOut[/*n*/]);
  168. //
  169. // Round the luminance and chroma channels of an array of YCA
  170. // pixels that has already been filtered and subsampled.
  171. // The signifcands of the pixels' luminance and chroma values
  172. // are rounded to roundY and roundC bits respectively.
  173. //
  174. IMF_EXPORT
  175. void roundYCA (int n,
  176. unsigned int roundY,
  177. unsigned int roundC,
  178. const Rgba ycaIn[/*n*/],
  179. Rgba ycaOut[/*n*/]);
  180. //
  181. // For a scan line that has valid chroma data only for every other pixel,
  182. // reconstruct the missing chroma values.
  183. //
  184. IMF_EXPORT
  185. void reconstructChromaHoriz (int n,
  186. const Rgba ycaIn[/*n+N-1*/],
  187. Rgba ycaOut[/*n*/]);
  188. //
  189. // For a scan line that has only luminance and no valid chroma data,
  190. // reconstruct chroma from the surronding N scan lines.
  191. //
  192. IMF_EXPORT
  193. void reconstructChromaVert (int n,
  194. const Rgba * const ycaIn[N],
  195. Rgba ycaOut[/*n*/]);
  196. //
  197. // Convert an array of n YCA (luminance/chroma/alpha) pixels to RGBA.
  198. // This function is the inverse of RGBAtoYCA().
  199. // yw is a set of RGB-to-Y weighting factors, as computed by computeYw().
  200. //
  201. IMF_EXPORT
  202. void YCAtoRGBA (const IMATH_NAMESPACE::V3f &yw,
  203. int n,
  204. const Rgba ycaIn[/*n*/],
  205. Rgba rgbaOut[/*n*/]);
  206. //
  207. // Eliminate super-saturated pixels:
  208. //
  209. // Converting an image from RGBA to YCA, low-pass filtering chroma,
  210. // and converting the result back to RGBA can produce pixels with
  211. // super-saturated colors, where one or two of the RGB components
  212. // become zero or negative. (The low-pass and reconstruction filters
  213. // introduce some amount of ringing into the chroma components.
  214. // This can lead to negative RGB values near high-contrast edges.)
  215. //
  216. // The fixSaturation() function finds super-saturated pixels and
  217. // corrects them by desaturating their colors while maintaining
  218. // their luminance. fixSaturation() takes three adjacent input
  219. // scan lines, rgbaIn[0], rgbaIn[1], rgbaIn[2], adjusts the
  220. // saturation of rgbaIn[1], and stores the result in rgbaOut.
  221. //
  222. IMF_EXPORT
  223. void fixSaturation (const IMATH_NAMESPACE::V3f &yw,
  224. int n,
  225. const Rgba * const rgbaIn[3],
  226. Rgba rgbaOut[/*n*/]);
  227. } // namespace RgbaYca
  228. OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
  229. #endif