/src/FreeImage/Source/OpenEXR/IlmImf/ImfRgbaYca.h

https://bitbucket.org/cabalistic/ogredeps/ · C++ Header · 248 lines · 42 code · 29 blank · 177 comment · 0 complexity · 4743e6c74efbb9b0b8a0e95be525f87e MD5 · raw file

  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. namespace Imf {
  117. namespace RgbaYca {
  118. //
  119. // Width of the chroma subsampling and reconstruction filters
  120. //
  121. static const int N = 27;
  122. static const int N2 = N / 2;
  123. //
  124. // Convert a set of primary chromaticities into a set of weighting
  125. // factors for computing a pixels's luminance, Y, from R, G and B
  126. //
  127. Imath::V3f computeYw (const Chromaticities &cr);
  128. //
  129. // Convert an array of n RGBA pixels, rgbaIn, to YCA (luminance/chroma/alpha):
  130. //
  131. // ycaOut[i].g = Y (rgbaIn[i]);
  132. // ycaOut[i].r = RY (rgbaIn[i]);
  133. // ycaOut[i].b = BY (rgbaIn[i]);
  134. // ycaOut[i].a = aIsValid? rgbaIn[i].a: 1
  135. //
  136. // yw is a set of RGB-to-Y weighting factors, as computed by computeYw().
  137. //
  138. void RGBAtoYCA (const Imath::V3f &yw,
  139. int n,
  140. bool aIsValid,
  141. const Rgba rgbaIn[/*n*/],
  142. Rgba ycaOut[/*n*/]);
  143. //
  144. // Perform horizontal low-pass filtering and subsampling of
  145. // the chroma channels of an array of n pixels. In order
  146. // to avoid indexing off the ends of the input array during
  147. // low-pass filtering, ycaIn must have N2 extra pixels at
  148. // both ends. Before calling decimateChromaHoriz(), the extra
  149. // pixels should be filled with copies of the first and last
  150. // "real" input pixel.
  151. //
  152. void decimateChromaHoriz (int n,
  153. const Rgba ycaIn[/*n+N-1*/],
  154. Rgba ycaOut[/*n*/]);
  155. //
  156. // Perform vertical chroma channel low-pass filtering and subsampling.
  157. // N scan lines of input pixels are combined into a single scan line
  158. // of output pixels.
  159. //
  160. void decimateChromaVert (int n,
  161. const Rgba * const ycaIn[N],
  162. Rgba ycaOut[/*n*/]);
  163. //
  164. // Round the luminance and chroma channels of an array of YCA
  165. // pixels that has already been filtered and subsampled.
  166. // The signifcands of the pixels' luminance and chroma values
  167. // are rounded to roundY and roundC bits respectively.
  168. //
  169. void roundYCA (int n,
  170. unsigned int roundY,
  171. unsigned int roundC,
  172. const Rgba ycaIn[/*n*/],
  173. Rgba ycaOut[/*n*/]);
  174. //
  175. // For a scan line that has valid chroma data only for every other pixel,
  176. // reconstruct the missing chroma values.
  177. //
  178. void reconstructChromaHoriz (int n,
  179. const Rgba ycaIn[/*n+N-1*/],
  180. Rgba ycaOut[/*n*/]);
  181. //
  182. // For a scan line that has only luminance and no valid chroma data,
  183. // reconstruct chroma from the surronding N scan lines.
  184. //
  185. void reconstructChromaVert (int n,
  186. const Rgba * const ycaIn[N],
  187. Rgba ycaOut[/*n*/]);
  188. //
  189. // Convert an array of n YCA (luminance/chroma/alpha) pixels to RGBA.
  190. // This function is the inverse of RGBAtoYCA().
  191. // yw is a set of RGB-to-Y weighting factors, as computed by computeYw().
  192. //
  193. void YCAtoRGBA (const Imath::V3f &yw,
  194. int n,
  195. const Rgba ycaIn[/*n*/],
  196. Rgba rgbaOut[/*n*/]);
  197. //
  198. // Eliminate super-saturated pixels:
  199. //
  200. // Converting an image from RGBA to YCA, low-pass filtering chroma,
  201. // and converting the result back to RGBA can produce pixels with
  202. // super-saturated colors, where one or two of the RGB components
  203. // become zero or negative. (The low-pass and reconstruction filters
  204. // introduce some amount of ringing into the chroma components.
  205. // This can lead to negative RGB values near high-contrast edges.)
  206. //
  207. // The fixSaturation() function finds super-saturated pixels and
  208. // corrects them by desaturating their colors while maintaining
  209. // their luminance. fixSaturation() takes three adjacent input
  210. // scan lines, rgbaIn[0], rgbaIn[1], rgbaIn[2], adjusts the
  211. // saturation of rgbaIn[1], and stores the result in rgbaOut.
  212. //
  213. void fixSaturation (const Imath::V3f &yw,
  214. int n,
  215. const Rgba * const rgbaIn[3],
  216. Rgba rgbaOut[/*n*/]);
  217. } // namespace RgbaYca
  218. } // namespace Imf
  219. #endif