opsin_params.h (5385B)
1 // Copyright (c) the JPEG XL Project Authors. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 #ifndef LIB_JXL_CMS_OPSIN_PARAMS_H_ 7 #define LIB_JXL_CMS_OPSIN_PARAMS_H_ 8 9 #include <array> 10 11 // Constants that define the XYB color space. 12 13 namespace jxl { 14 namespace cms { 15 16 // Parameters for opsin absorbance. 17 constexpr float kM02 = 0.078f; 18 constexpr float kM00 = 0.30f; 19 constexpr float kM01 = 1.0f - kM02 - kM00; 20 21 constexpr float kM12 = 0.078f; 22 constexpr float kM10 = 0.23f; 23 constexpr float kM11 = 1.0f - kM12 - kM10; 24 25 constexpr float kM20 = 0.24342268924547819f; 26 constexpr float kM21 = 0.20476744424496821f; 27 constexpr float kM22 = 1.0f - kM20 - kM21; 28 29 constexpr float kBScale = 1.0f; 30 constexpr float kYToBRatio = 1.0f; // works better with 0.50017729543783418 31 constexpr float kBToYRatio = 1.0f / kYToBRatio; 32 33 constexpr float kOpsinAbsorbanceBias0 = 0.0037930732552754493f; 34 constexpr float kOpsinAbsorbanceBias1 = kOpsinAbsorbanceBias0; 35 constexpr float kOpsinAbsorbanceBias2 = kOpsinAbsorbanceBias0; 36 37 // Opsin absorbance matrix is now frozen. 38 constexpr std::array<float, 9> kOpsinAbsorbanceMatrix = { 39 kM00, kM01, kM02, kM10, kM11, kM12, kM20, kM21, kM22, 40 }; 41 42 constexpr std::array<float, 9> kDefaultInverseOpsinAbsorbanceMatrix = { 43 11.031566901960783f, -9.866943921568629f, -0.16462299647058826f, 44 -3.254147380392157f, 4.418770392156863f, -0.16462299647058826f, 45 -3.6588512862745097f, 2.7129230470588235f, 1.9459282392156863f}; 46 47 // Must be the inverse matrix of kOpsinAbsorbanceMatrix and match the spec. 48 static inline const float* DefaultInverseOpsinAbsorbanceMatrix() { 49 return kDefaultInverseOpsinAbsorbanceMatrix.data(); 50 } 51 52 constexpr std::array<float, 3> kOpsinAbsorbanceBias = { 53 kOpsinAbsorbanceBias0, 54 kOpsinAbsorbanceBias1, 55 kOpsinAbsorbanceBias2, 56 }; 57 58 constexpr std::array<float, 4> kNegOpsinAbsorbanceBiasRGB = { 59 -kOpsinAbsorbanceBias0, -kOpsinAbsorbanceBias1, -kOpsinAbsorbanceBias2, 60 1.0f}; 61 62 constexpr float kScaledXYBOffset0 = 0.015386134f; 63 constexpr float kScaledXYBOffset1 = 0.0f; 64 constexpr float kScaledXYBOffset2 = 0.27770459f; 65 66 constexpr std::array<float, 3> kScaledXYBOffset = { 67 kScaledXYBOffset0, kScaledXYBOffset1, kScaledXYBOffset2}; 68 69 constexpr float kScaledXYBScale0 = 22.995788804f; 70 constexpr float kScaledXYBScale1 = 1.183000077f; 71 constexpr float kScaledXYBScale2 = 1.502141333f; 72 73 constexpr std::array<float, 3> kScaledXYBScale = { 74 kScaledXYBScale0, 75 kScaledXYBScale1, 76 kScaledXYBScale2, 77 }; 78 79 // NB(eustas): following function/variable names are just "namos". 80 81 // More precise calculation of 1 / ((1 / r1) + (1 / r2)) 82 constexpr float ReciprocialSum(float r1, float r2) { 83 return (r1 * r2) / (r1 + r2); 84 } 85 86 constexpr float kXYBOffset0 = kScaledXYBOffset0 + kScaledXYBOffset1; 87 constexpr float kXYBOffset1 = 88 kScaledXYBOffset1 - kScaledXYBOffset0 + (1.0f / kScaledXYBScale0); 89 constexpr float kXYBOffset2 = kScaledXYBOffset1 + kScaledXYBOffset2; 90 91 constexpr std::array<float, 3> kXYBOffset = {kXYBOffset0, kXYBOffset1, 92 kXYBOffset2}; 93 94 constexpr float kXYBScale0 = ReciprocialSum(kScaledXYBScale0, kScaledXYBScale1); 95 constexpr float kXYBScale1 = ReciprocialSum(kScaledXYBScale0, kScaledXYBScale1); 96 constexpr float kXYBScale2 = ReciprocialSum(kScaledXYBScale1, kScaledXYBScale2); 97 98 constexpr std::array<float, 3> kXYBScale = {kXYBScale0, kXYBScale1, kXYBScale2}; 99 100 template <size_t idx> 101 constexpr float ScaledXYBScale() { 102 return (idx == 0) ? kScaledXYBScale0 103 : (idx == 1) ? kScaledXYBScale1 104 : kScaledXYBScale2; 105 } 106 107 template <size_t idx> 108 constexpr float ScaledXYBOffset() { 109 return (idx == 0) ? kScaledXYBOffset0 110 : (idx == 1) ? kScaledXYBOffset1 111 : kScaledXYBOffset2; 112 } 113 114 template <size_t x, size_t y, size_t b, size_t idx> 115 constexpr float XYBCorner() { 116 return (((idx == 0) ? x 117 : (idx == 1) ? y 118 : b) / 119 ScaledXYBScale<idx>()) - 120 ScaledXYBOffset<idx>(); 121 } 122 123 template <size_t x, size_t y, size_t b, size_t idx> 124 constexpr float ScaledA2BCorner() { 125 return (idx == 0) ? (XYBCorner<x, y, b, 1>() + XYBCorner<x, y, b, 0>()) 126 : (idx == 1) ? (XYBCorner<x, y, b, 1>() - XYBCorner<x, y, b, 0>()) 127 : (XYBCorner<x, y, b, 2>() + XYBCorner<x, y, b, 1>()); 128 } 129 130 typedef std::array<float, 3> ColorCube0D; 131 template <size_t x, size_t y, size_t b> 132 constexpr ColorCube0D UnscaledA2BCorner() { 133 return {(ScaledA2BCorner<x, y, b, 0>() + kXYBOffset0) * kXYBScale0, 134 (ScaledA2BCorner<x, y, b, 1>() + kXYBOffset1) * kXYBScale1, 135 (ScaledA2BCorner<x, y, b, 2>() + kXYBOffset2) * kXYBScale2}; 136 } 137 138 typedef std::array<ColorCube0D, 2> ColorCube1D; 139 template <size_t x, size_t y> 140 constexpr ColorCube1D UnscaledA2BCubeXY() { 141 return {UnscaledA2BCorner<x, y, 0>(), UnscaledA2BCorner<x, y, 1>()}; 142 } 143 144 typedef std::array<ColorCube1D, 2> ColorCube2D; 145 template <size_t x> 146 constexpr ColorCube2D UnscaledA2BCubeX() { 147 return {UnscaledA2BCubeXY<x, 0>(), UnscaledA2BCubeXY<x, 1>()}; 148 } 149 150 typedef std::array<ColorCube2D, 2> ColorCube3D; 151 constexpr ColorCube3D UnscaledA2BCube() { 152 return {UnscaledA2BCubeX<0>(), UnscaledA2BCubeX<1>()}; 153 } 154 155 constexpr ColorCube3D kUnscaledA2BCube = UnscaledA2BCube(); 156 157 } // namespace cms 158 } // namespace jxl 159 160 #endif // LIB_JXL_CMS_OPSIN_PARAMS_H_