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