ImfChromaticities.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. ///////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2003, Industrial Light & Magic, a division of Lucas
  4. // Digital Ltd. LLC
  5. //
  6. // All rights reserved.
  7. //
  8. // Redistribution and use in source and binary forms, with or without
  9. // modification, are permitted provided that the following conditions are
  10. // met:
  11. // * Redistributions of source code must retain the above copyright
  12. // notice, this list of conditions and the following disclaimer.
  13. // * Redistributions in binary form must reproduce the above
  14. // copyright notice, this list of conditions and the following disclaimer
  15. // in the documentation and/or other materials provided with the
  16. // distribution.
  17. // * Neither the name of Industrial Light & Magic nor the names of
  18. // its contributors may be used to endorse or promote products derived
  19. // from this software without specific prior written permission.
  20. //
  21. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  24. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  25. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  26. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  27. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  28. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  29. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  31. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. //
  33. ///////////////////////////////////////////////////////////////////////////
  34. //-----------------------------------------------------------------------------
  35. //
  36. // CIE (x,y) chromaticities, and conversions between
  37. // RGB tiples and CIE XYZ tristimulus values.
  38. //
  39. //-----------------------------------------------------------------------------
  40. #include <ImfChromaticities.h>
  41. #include "ImfNamespace.h"
  42. #include <string.h>
  43. OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
  44. Chromaticities::Chromaticities (const IMATH_NAMESPACE::V2f &red,
  45. const IMATH_NAMESPACE::V2f &green,
  46. const IMATH_NAMESPACE::V2f &blue,
  47. const IMATH_NAMESPACE::V2f &white)
  48. :
  49. red (red),
  50. green (green),
  51. blue (blue),
  52. white (white)
  53. {
  54. // empty
  55. }
  56. bool
  57. Chromaticities::operator == (const Chromaticities & c) const
  58. {
  59. return red == c.red && green == c.green && blue == c.blue;
  60. }
  61. bool
  62. Chromaticities::operator != (const Chromaticities & c) const
  63. {
  64. return red != c.red || green != c.green || blue != c.blue;
  65. }
  66. IMATH_NAMESPACE::M44f
  67. RGBtoXYZ (const Chromaticities chroma, float Y)
  68. {
  69. //
  70. // For an explanation of how the color conversion matrix is derived,
  71. // see Roy Hall, "Illumination and Color in Computer Generated Imagery",
  72. // Springer-Verlag, 1989, chapter 3, "Perceptual Response"; and
  73. // Charles A. Poynton, "A Technical Introduction to Digital Video",
  74. // John Wiley & Sons, 1996, chapter 7, "Color science for video".
  75. //
  76. //
  77. // X and Z values of RGB value (1, 1, 1), or "white"
  78. //
  79. float X = chroma.white.x * Y / chroma.white.y;
  80. float Z = (1 - chroma.white.x - chroma.white.y) * Y / chroma.white.y;
  81. //
  82. // Scale factors for matrix rows
  83. //
  84. float d = chroma.red.x * (chroma.blue.y - chroma.green.y) +
  85. chroma.blue.x * (chroma.green.y - chroma.red.y) +
  86. chroma.green.x * (chroma.red.y - chroma.blue.y);
  87. float Sr = (X * (chroma.blue.y - chroma.green.y) -
  88. chroma.green.x * (Y * (chroma.blue.y - 1) +
  89. chroma.blue.y * (X + Z)) +
  90. chroma.blue.x * (Y * (chroma.green.y - 1) +
  91. chroma.green.y * (X + Z))) / d;
  92. float Sg = (X * (chroma.red.y - chroma.blue.y) +
  93. chroma.red.x * (Y * (chroma.blue.y - 1) +
  94. chroma.blue.y * (X + Z)) -
  95. chroma.blue.x * (Y * (chroma.red.y - 1) +
  96. chroma.red.y * (X + Z))) / d;
  97. float Sb = (X * (chroma.green.y - chroma.red.y) -
  98. chroma.red.x * (Y * (chroma.green.y - 1) +
  99. chroma.green.y * (X + Z)) +
  100. chroma.green.x * (Y * (chroma.red.y - 1) +
  101. chroma.red.y * (X + Z))) / d;
  102. //
  103. // Assemble the matrix
  104. //
  105. IMATH_NAMESPACE::M44f M;
  106. M[0][0] = Sr * chroma.red.x;
  107. M[0][1] = Sr * chroma.red.y;
  108. M[0][2] = Sr * (1 - chroma.red.x - chroma.red.y);
  109. M[1][0] = Sg * chroma.green.x;
  110. M[1][1] = Sg * chroma.green.y;
  111. M[1][2] = Sg * (1 - chroma.green.x - chroma.green.y);
  112. M[2][0] = Sb * chroma.blue.x;
  113. M[2][1] = Sb * chroma.blue.y;
  114. M[2][2] = Sb * (1 - chroma.blue.x - chroma.blue.y);
  115. return M;
  116. }
  117. IMATH_NAMESPACE::M44f
  118. XYZtoRGB (const Chromaticities chroma, float Y)
  119. {
  120. return RGBtoXYZ (chroma, Y).inverse();
  121. }
  122. OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT