@@ -44,15 +44,6 @@ static const float alphaRec2020 = 1.09929682680944f;
4444using namespace hwy ;
4545using namespace hwy ::HWY_NAMESPACE;
4646
47- HWY_FAST_MATH_INLINE float bt2020GammaCorrection (float linear) {
48- if (0 <= betaRec2020 && linear < betaRec2020) {
49- return 4 .5f * linear;
50- } else if (betaRec2020 <= linear && linear < 1 ) {
51- return alphaRec2020 * powf (linear, 0 .45f ) - (alphaRec2020 - 1 .0f );
52- }
53- return linear;
54- }
55-
5647HWY_FAST_MATH_INLINE float ToLinearPQ (float v, const float sdrReferencePoint) {
5748 float o = v;
5849 v = std::max (0 .0f , v);
@@ -111,44 +102,33 @@ HWY_FAST_MATH_INLINE V ToLinearPQ(const D df, V v, const TFromD<D> sdrReferenceP
111102}
112103
113104template <class D , typename V = Vec<D>, HWY_IF_FLOAT(TFromD<D>)>
114- HWY_FAST_MATH_INLINE V bt2020GammaCorrection (const D d, V color) {
115- const V bt2020 = Set (d, betaRec2020);
116- const V alpha2020 = Set (d, alphaRec2020);
117- using T = hwy::HWY_NAMESPACE::TFromD<D>;
118- const auto cmp = color < bt2020;
119- const auto fourAndHalf = Set (d, static_cast <T>(4 .5f ));
120- const auto branch1 = Mul (color, fourAndHalf);
121- const V power1 = Set (d, static_cast <T>(0 .45f ));
122- const V ones = Set (d, static_cast <T>(1 .0f ));
123- const V power2 = Sub (alpha2020, ones);
124- const auto branch2 =
125- Sub (Mul (alpha2020, coder::HWY_NAMESPACE::Pow (d, color, power1)), power2);
126- return IfThenElse (cmp, branch1, branch2);
127- }
128-
129- template <class D , typename V = Vec<D>, HWY_IF_FLOAT(TFromD<D>)>
130- HWY_FAST_MATH_INLINE V LinearITUR709ToITUR709 (const D df, V value) {
131- const auto minCurve = Set (df, static_cast <TFromD<D>>(0 .018f ));
105+ HWY_FAST_MATH_INLINE V Rec709Oetf (const D df, V value) {
106+ const auto minCutOff = Set (df, static_cast <TFromD<D>>(0 .018053968510807f ));
132107 const auto minPowValue = Set (df, static_cast <TFromD<D>>(4 .5f ));
133- const auto minLane = Mul (value, minPowValue);
134- const auto subValue = Set (df, static_cast <TFromD<D>>(0 .099f ));
135- const auto scalePower = Set (df, static_cast <TFromD<D>>(1 .099f ));
108+ const auto lo = Mul (value, minPowValue);
109+ const auto zeros = Zero (df);
110+ const auto ones = Set (df, 1 .0f );
111+ const auto subValue = Set (df, static_cast <TFromD<D>>(0 .09929682680944f ));
112+ const auto scalePower = Set (df, static_cast <TFromD<D>>(1 .09929682680944f ));
136113 const auto pwrValue = Set (df, static_cast <TFromD<D>>(0 .45f ));
137- const auto maxLane = MulSub (coder::HWY_NAMESPACE::Pow (df, value, pwrValue), scalePower,
138- subValue);
139- return IfThenElse (value < minCurve, minLane, maxLane);
114+ const auto ho = MulSub (coder::HWY_NAMESPACE::Pow (df, value, pwrValue), scalePower, subValue);
115+ auto Lc = IfThenElse (And (value < minCutOff, value >= zeros), lo, zeros);
116+ Lc = IfThenZeroElse (value < zeros, Lc);
117+ Lc = IfThenElse (And (value >= minCutOff, value <= ones), ho, Lc);
118+ Lc = IfThenElse (value > ones, ones, Lc);
119+ return Lc;
140120}
141121
142122HWY_FAST_MATH_INLINE float SRGBEotf (float v) {
143- if (v < 0 ) {
144- return 0 ;
145- }
146- if (v <= 0 .045f ) {
123+ if (v < 0 .0f ) {
124+ return 0 .0f ;
125+ } else if (v < 12 .92f * 0 .0030412825601275209f ) {
147126 return v / 12 .92f ;
148- } else if (v <= 1 .f ) {
149- return std::powf ((v + 0 .055f ) / 1 .055f , 2 .4f );
127+ } else if (v < 1 .0f ) {
128+ return std::powf ((v + 0 .0550107189475866f ) / 1 .0550107189475866f , 2 .4f );
129+ } else {
130+ return 1 .0f ;
150131 }
151- return 1 .f ;
152132}
153133
154134HWY_FAST_MATH_INLINE float Rec709Eotf (float v) {
@@ -162,7 +142,7 @@ HWY_FAST_MATH_INLINE float Rec709Eotf(float v) {
162142 return 1 .f ;
163143}
164144
165- HWY_FAST_MATH_INLINE float FromLinear709 (float linear) {
145+ HWY_FAST_MATH_INLINE float Rec709Oetf (float linear) {
166146 if (linear < 0 .f ) {
167147 return 0 .f ;
168148 } else if (linear < 0 .018053968510807f ) {
@@ -177,13 +157,13 @@ template<class D, HWY_IF_F32_D(D), typename T = TFromD<D>, typename V = VFromD<D
177157HWY_FAST_MATH_INLINE V SRGBEotf (D d, V v) {
178158 const auto highCutOff = Set (d, static_cast <T>(1 .0f ));
179159 const auto zeros = Zero (d);
180- const auto lowerValueThreshold = Set (d, T ( 0 . 045f ));
160+ const auto lowerValueThreshold = Set (d, static_cast <T>( 12 . 92f * 0 . 0030412825601275209f ));
181161 const auto lowValueDivider = Set (d, static_cast <T>(1 .0f ) / static_cast <T>(12 .92f ));
182162 const auto lowMask = v <= lowerValueThreshold;
183163 const auto lowValue = Mul (v, lowValueDivider);
184164 const auto powerStatic = Set (d, T (2 .4f ));
185- const auto addStatic = Set (d, T (0 .055f ));
186- const auto scaleStatic = ApproximateReciprocal (Set (d, T (1 .055f )));
165+ const auto addStatic = Set (d, T (0 .0550107189475866f ));
166+ const auto scaleStatic = ApproximateReciprocal (Set (d, T (1 .0550107189475866f )));
187167 const auto highValue = Pow (d, Mul (Add (v, addStatic), scaleStatic), powerStatic);
188168 auto result = IfThenElse (And (lowMask, v >= zeros), lowValue, v);
189169 result = IfThenElse (And (v > lowerValueThreshold, v <= highCutOff), highValue, result);
@@ -193,41 +173,35 @@ HWY_FAST_MATH_INLINE V SRGBEotf(D d, V v) {
193173}
194174
195175HWY_FAST_MATH_INLINE float SRGBOetf (const float linear) {
196- if (linear <= 0 .0031308f ) {
197- return 12 .92f * linear;
176+ if (linear < 0 .0f ) {
177+ return 0 .0f ;
178+ } else if (linear < 0 .0030412825601275209f ) {
179+ return linear * 12 .92f ;
180+ } else if (linear < 1 .0f ) {
181+ return 1 .0550107189475866f * powf (linear, 1 .0f / 2 .4f ) - 0 .0550107189475866f ;
198182 } else {
199- return 1 .055f * std::powf (linear, 1 . 0f / 2 . 4f ) - 0 . 055f ;
183+ return 1 .0f ;
200184 }
201185}
202186
203187template <class D , typename V = Vec<D>, HWY_IF_FLOAT(TFromD<D>)>
204188HWY_FAST_MATH_INLINE V SRGBOetf (const D df, V v) {
205189 const auto zeros = Zero (df);
206190 const auto highCutOff = Set (df, static_cast <TFromD<D>>(1 .0f ));
207- const auto minCutOff = Set (df, static_cast <TFromD<D>>(0 .0031308f ));
191+ const auto minCutOff = Set (df, static_cast <TFromD<D>>(0 .0030412825601275209f ));
208192 const auto minPowValue = Set (df, static_cast <TFromD<D>>(12 .92f ));
209193 const auto lowValue = Mul (v, minPowValue);
210- const auto subValue = Set (df, static_cast <TFromD<D>>(0 .055f ));
211- const auto scalePower = Set (df, static_cast <TFromD<D>>(1 .055f ));
194+ const auto subValue = Set (df, static_cast <TFromD<D>>(0 .0550107189475866f ));
195+ const auto scalePower = Set (df, static_cast <TFromD<D>>(1 .0550107189475866f ));
212196 const auto pwrValue = Set (df, static_cast <TFromD<D>>(1 .0f / 2 .4f ));
213- const auto highValue = MulSub (coder::HWY_NAMESPACE::Pow (df, v, pwrValue), scalePower,
214- subValue);
215-
197+ const auto highValue = MulSub (coder::HWY_NAMESPACE::Pow (df, v, pwrValue), scalePower, subValue);
216198 auto result = IfThenElse (And (v <= minCutOff, v >= zeros), lowValue, v);
217199 result = IfThenElse (And (v > minCutOff, v <= highCutOff), highValue, result);
218200 result = IfThenElse (v > highCutOff, highCutOff, result);
219- result = IfThenElse (v < zeros, zeros, result);
201+ result = IfThenZeroElse (v < zeros, result);
220202 return result;
221203}
222204
223- HWY_FAST_MATH_INLINE float LinearITUR709ToITUR709 (const float linear) {
224- if (linear <= 0 .018053968510807f ) {
225- return 4 .5f * linear;
226- } else {
227- return 1 .09929682680944f * std::powf (linear, 0 .45f ) - 0 .09929682680944f ;
228- }
229- }
230-
231205template <class D , typename V = Vec<D>, HWY_IF_FLOAT(TFromD<D>)>
232206HWY_FAST_MATH_INLINE V SMPTE428Eotf (const D df, V value) {
233207 const auto scale = Set (df, static_cast <const TFromD<D>>(1 .f / 0 .91655527974030934f ));
@@ -282,17 +256,24 @@ HWY_FAST_MATH_INLINE float Rec601Oetf(float intensity) {
282256
283257template <class D , typename T = Vec<D>, HWY_IF_FLOAT(TFromD<D>)>
284258HWY_FAST_MATH_INLINE T Rec601Eotf (const D d, T intensity) {
285- const auto topValue = Set (d, 4 .5f * 0 .018053968510807f );
286- const auto fourAnd5 = Set (d, 4 .5f );
287- const auto lowMask = intensity < topValue;
288- const auto lowValues = Div (intensity, fourAnd5);
259+ const auto lowCutOff = Set (d, 4 .5f * 0 .018053968510807f );
260+ const auto fourAnd5 = Set (d, 1 .f / 4 .5f );
261+ const auto lowCutOffMask = intensity < lowCutOff;
262+ const auto tressPassCutOffMask = intensity >= lowCutOff;
263+ const auto zeros = Zero (d);
264+ const auto ones = Set (d, 1 .f );
265+ const auto lowValues = Mul (intensity, fourAnd5);
289266
290267 const auto addComp = Set (d, 0 .09929682680944f );
291268 const auto div1099 = Set (d, 1 .f / 1 .09929682680944f );
292269 const auto pwScale = Set (d, 1 .0f / 0 .45f );
293270
294271 const auto high = coder::HWY_NAMESPACE::Pow (d, Mul (Add (intensity, addComp), div1099), pwScale);
295- return IfThenElse (lowMask, lowValues, high);
272+ auto Lc = IfThenElseZero (And (lowCutOffMask, intensity >= zeros), lowValues);
273+ Lc = IfThenZeroElse (intensity < zeros, Lc);
274+ Lc = IfThenElse (And (tressPassCutOffMask, intensity <= ones), high, Lc);
275+ Lc = IfThenElse (intensity > ones, ones, Lc);
276+ return Lc;
296277}
297278
298279HWY_FAST_MATH_INLINE float Rec601Eotf (float intensity) {
0 commit comments