@@ -238,6 +238,66 @@ class Renderer_HSV_TO_RGB : public OpCPU
238
238
void apply (const void * inImg, void * outImg, long numPixels) const override ;
239
239
};
240
240
241
+ class Renderer_RGB_TO_HSY_LOG : public OpCPU
242
+ {
243
+ const float MIN_0 = -0 .1f ;
244
+ public:
245
+ Renderer_RGB_TO_HSY_LOG () = delete ;
246
+ explicit Renderer_RGB_TO_HSY_LOG (ConstFixedFunctionOpDataRcPtr & data);
247
+
248
+ void apply (const void * inImg, void * outImg, long numPixels) const override ;
249
+ };
250
+
251
+ class Renderer_HSY_LOG_TO_RGB : public OpCPU
252
+ {
253
+ const float MIN_0 = -0 .1f ;;
254
+ public:
255
+ Renderer_HSY_LOG_TO_RGB () = delete ;
256
+ explicit Renderer_HSY_LOG_TO_RGB (ConstFixedFunctionOpDataRcPtr & data);
257
+
258
+ void apply (const void * inImg, void * outImg, long numPixels) const override ;
259
+ };
260
+
261
+ class Renderer_RGB_TO_HSY_VID : public OpCPU
262
+ {
263
+ const float MIN_0 = 0 .0f ;
264
+ public:
265
+ Renderer_RGB_TO_HSY_VID () = delete ;
266
+ explicit Renderer_RGB_TO_HSY_VID (ConstFixedFunctionOpDataRcPtr & data);
267
+
268
+ void apply (const void * inImg, void * outImg, long numPixels) const override ;
269
+ };
270
+
271
+ class Renderer_HSY_VID_TO_RGB : public OpCPU
272
+ {
273
+ const float MIN_0 = 0 .0f ;
274
+ public:
275
+ Renderer_HSY_VID_TO_RGB () = delete ;
276
+ explicit Renderer_HSY_VID_TO_RGB (ConstFixedFunctionOpDataRcPtr & data);
277
+
278
+ void apply (const void * inImg, void * outImg, long numPixels) const override ;
279
+ };
280
+
281
+ class Renderer_RGB_TO_HSY_LIN : public OpCPU
282
+ {
283
+ const float MIN_0 = 0 .2f ;
284
+ public:
285
+ Renderer_RGB_TO_HSY_LIN () = delete ;
286
+ explicit Renderer_RGB_TO_HSY_LIN (ConstFixedFunctionOpDataRcPtr & data);
287
+
288
+ void apply (const void * inImg, void * outImg, long numPixels) const override ;
289
+ };
290
+
291
+ class Renderer_HSY_LIN_TO_RGB : public OpCPU
292
+ {
293
+ const float MIN_0 = 0 .2f ;
294
+ public:
295
+ Renderer_HSY_LIN_TO_RGB () = delete ;
296
+ explicit Renderer_HSY_LIN_TO_RGB (ConstFixedFunctionOpDataRcPtr & data);
297
+
298
+ void apply (const void * inImg, void * outImg, long numPixels) const override ;
299
+ };
300
+
241
301
class Renderer_XYZ_TO_xyY : public OpCPU
242
302
{
243
303
public:
@@ -1534,6 +1594,230 @@ void Renderer_HSV_TO_RGB::apply(const void * inImg, void * outImg, long numPixel
1534
1594
}
1535
1595
}
1536
1596
1597
+ void applyHSYToRGB (const void * inImg, void * outImg, long numPixels, float min0)
1598
+ {
1599
+ const float * in = (const float *)inImg;
1600
+ float * out = (float *)outImg;
1601
+
1602
+ for (unsigned idx=0 ; idx<numPixels; ++idx)
1603
+ {
1604
+ float hue = in[0 ] - 1 .f /6 .f ;
1605
+ float sat = in[1 ];
1606
+ const float luma = in[2 ];
1607
+
1608
+ hue = luma < 0 .f ? hue + 0 .5f : hue;
1609
+ hue = ( hue - std::floor ( hue ) ) * 6 .f ;
1610
+
1611
+ float red = CLAMP ( std::fabs (hue - 3 .f ) - 1 .f , 0 .f , 1 .f );
1612
+ float grn = CLAMP ( 2 .f - std::fabs (hue - 2 .f ), 0 .f , 1 .f );
1613
+ float blu = CLAMP ( 2 .f - std::fabs (hue - 4 .f ), 0 .f , 1 .f );
1614
+
1615
+ const float currY = 0 .2126f * red + 0 .7152f * grn + 0 .0722f * blu;
1616
+ red *= luma / currY;
1617
+ grn *= luma / currY;
1618
+ blu *= luma / currY;
1619
+
1620
+ float gainS = sat;
1621
+
1622
+ const float distRgb = std::fabs (red - luma) + std::fabs (grn - luma) + std::fabs (blu - luma);
1623
+
1624
+ if (min0 > 0 .f ) // linear
1625
+ {
1626
+ const float sumRgb = red + grn + blu;
1627
+
1628
+ const float k = 0 .15f ;
1629
+ const float loGain = 5 .f ;
1630
+
1631
+ sat /= 1 .4f ;
1632
+ const float tmp = -sat * sumRgb + sat * 3 .f * luma + distRgb;
1633
+ const float s1 = (tmp == 0 .f ) ? 0 .f : sat * (k + 3 .f * luma) / tmp;
1634
+ const float s0 = sat / std::max (1e-10f , distRgb * loGain);
1635
+
1636
+ const float maxLum = 0 .01f ;
1637
+ const float minLum = maxLum * 0 .1f ;
1638
+ const float alpha = CLAMP ( (luma - minLum) / (maxLum - minLum), 0 .f , 1 .f );
1639
+
1640
+ if (alpha == 1 .f )
1641
+ gainS = s1;
1642
+ else if (alpha == 0 .f )
1643
+ gainS = s0;
1644
+ else
1645
+ {
1646
+ const float a = distRgb * loGain * (1 .f - alpha) * (sumRgb - 3 .f * luma);
1647
+ const float b = distRgb * loGain * (1 .f - alpha) * (k + 3 .f * luma) + distRgb * alpha -
1648
+ sat * (sumRgb - 3 .f * luma);
1649
+ const float c = -sat * (k + 3 .f * luma);
1650
+ const float discrim = sqrt ( b * b - 4 .f * a * c );
1651
+ const float denom = -discrim - b;
1652
+ gainS = (2 .f * c) / denom;
1653
+
1654
+ gainS = gainS >= 0 .f ? gainS : (2 .f * c) / (denom + discrim * 2 .f );
1655
+ }
1656
+ }
1657
+ else if (min0 < 0 .f ) // log
1658
+ {
1659
+ const float satGain = 4 .f ;
1660
+ const float currSat = distRgb * satGain;
1661
+ gainS = sat / std::max (1e-10f , currSat);
1662
+ }
1663
+ else // video
1664
+ {
1665
+ const float satGain = 1 .25f ;
1666
+ const float currSat = distRgb * satGain;
1667
+ gainS = sat / std::max (1e-10f , currSat);
1668
+ }
1669
+
1670
+ out[0 ] = luma + gainS * (red - luma); // red
1671
+ out[1 ] = luma + gainS * (grn - luma); // grn
1672
+ out[2 ] = luma + gainS * (blu - luma); // blu
1673
+ out[3 ] = in[3 ]; // alpha
1674
+
1675
+ in += 4 ;
1676
+ out += 4 ;
1677
+ }
1678
+
1679
+ }
1680
+
1681
+ void applyRGBToHSY (const void * inImg, void * outImg, long numPixels, float min0)
1682
+ {
1683
+ const float * in = (const float *)inImg;
1684
+ float * out = (float *)outImg;
1685
+
1686
+ for (long idx=0 ; idx<numPixels; ++idx)
1687
+ {
1688
+ const float red = in[0 ];
1689
+ const float grn = in[1 ];
1690
+ const float blu = in[2 ];
1691
+
1692
+ const float rgbMin = std::min ( std::min ( red, grn ), blu );
1693
+ const float rgbMax = std::max ( std::max ( red, grn ), blu );
1694
+
1695
+ const float luma = 0 .2126f * red + 0 .7152f * grn + 0 .0722f * blu;
1696
+
1697
+ const float rm = red - luma;
1698
+ const float gm = grn - luma;
1699
+ const float bm = blu - luma;
1700
+
1701
+ const float distRgb = std::fabs (rm) + std::fabs (gm) + std::fabs (bm);
1702
+
1703
+ float sat = 0 .f ;
1704
+
1705
+ if (min0 > 0 .f ) // linear
1706
+ {
1707
+ const float sumRgb = red + grn + blu;
1708
+ const float k = 0 .15f ;
1709
+ const float satHi = distRgb / (k + sumRgb);
1710
+ const float loGain = 5 .f ;
1711
+ const float satLo = distRgb * loGain;
1712
+ const float maxLum = 0 .01f ;
1713
+ const float minLum = maxLum * 0.1 ;
1714
+ const float alpha = CLAMP ( (luma - minLum) / (maxLum - minLum), 0 .f , 1 .f );
1715
+ sat = satLo + alpha * (satHi - satLo);
1716
+ sat *= 1 .4f ;
1717
+ }
1718
+ else if (min0 < 0 .f ) // log
1719
+ {
1720
+ const float sat_gain = 4 .f ;
1721
+ sat = distRgb * sat_gain;
1722
+ }
1723
+ else // video
1724
+ {
1725
+ const float sat_gain = 1 .25f ;
1726
+ sat = distRgb * sat_gain;
1727
+ }
1728
+
1729
+ float hue = 0 .f ;
1730
+ if (rgbMin != rgbMax)
1731
+ {
1732
+ float delta = rgbMax - rgbMin;
1733
+ if (red == rgbMax)
1734
+ {
1735
+ hue = 1 .0f + (grn - blu) / delta;
1736
+ }
1737
+ else
1738
+ {
1739
+ if (grn == rgbMax)
1740
+ {
1741
+ hue = 3 .0f + (blu - red) / delta;
1742
+ }
1743
+ else
1744
+ {
1745
+ hue = 5 .0f + (red - grn) / delta;
1746
+ }
1747
+ }
1748
+ hue *= 0 .16666666666666666f ;
1749
+ }
1750
+
1751
+ out[0 ] = hue;
1752
+ out[1 ] = sat;
1753
+ out[2 ] = luma;
1754
+ out[3 ] = in[3 ];
1755
+
1756
+ in += 4 ;
1757
+ out += 4 ;
1758
+ }
1759
+ }
1760
+
1761
+ Renderer_RGB_TO_HSY_LOG::Renderer_RGB_TO_HSY_LOG (ConstFixedFunctionOpDataRcPtr & /* data*/ )
1762
+ : OpCPU()
1763
+ {
1764
+ }
1765
+
1766
+ void Renderer_RGB_TO_HSY_LOG::apply (const void * inImg, void * outImg, long numPixels) const
1767
+ {
1768
+ applyRGBToHSY (inImg, outImg, numPixels, MIN_0);
1769
+ }
1770
+
1771
+ Renderer_HSY_LOG_TO_RGB::Renderer_HSY_LOG_TO_RGB (ConstFixedFunctionOpDataRcPtr & /* data*/ )
1772
+ : OpCPU()
1773
+ {
1774
+ }
1775
+
1776
+ void Renderer_HSY_LOG_TO_RGB::apply (const void * inImg, void * outImg, long numPixels) const
1777
+ {
1778
+ applyHSYToRGB (inImg, outImg, numPixels, MIN_0);
1779
+ }
1780
+
1781
+ Renderer_RGB_TO_HSY_LIN::Renderer_RGB_TO_HSY_LIN (ConstFixedFunctionOpDataRcPtr & /* data*/ )
1782
+ : OpCPU()
1783
+ {
1784
+ }
1785
+
1786
+ void Renderer_RGB_TO_HSY_LIN::apply (const void * inImg, void * outImg, long numPixels) const
1787
+ {
1788
+ applyRGBToHSY (inImg, outImg, numPixels, MIN_0);
1789
+ }
1790
+
1791
+ Renderer_HSY_LIN_TO_RGB::Renderer_HSY_LIN_TO_RGB (ConstFixedFunctionOpDataRcPtr & /* data*/ )
1792
+ : OpCPU()
1793
+ {
1794
+ }
1795
+
1796
+ void Renderer_HSY_LIN_TO_RGB::apply (const void * inImg, void * outImg, long numPixels) const
1797
+ {
1798
+ applyHSYToRGB (inImg, outImg, numPixels, MIN_0);
1799
+ }
1800
+
1801
+ Renderer_RGB_TO_HSY_VID::Renderer_RGB_TO_HSY_VID (ConstFixedFunctionOpDataRcPtr & /* data*/ )
1802
+ : OpCPU()
1803
+ {
1804
+ }
1805
+
1806
+ void Renderer_RGB_TO_HSY_VID::apply (const void * inImg, void * outImg, long numPixels) const
1807
+ {
1808
+ applyRGBToHSY (inImg, outImg, numPixels, MIN_0);
1809
+ }
1810
+
1811
+ Renderer_HSY_VID_TO_RGB::Renderer_HSY_VID_TO_RGB (ConstFixedFunctionOpDataRcPtr & /* data*/ )
1812
+ : OpCPU()
1813
+ {
1814
+ }
1815
+
1816
+ void Renderer_HSY_VID_TO_RGB::apply (const void * inImg, void * outImg, long numPixels) const
1817
+ {
1818
+ applyHSYToRGB (inImg, outImg, numPixels, MIN_0);
1819
+ }
1820
+
1537
1821
Renderer_XYZ_TO_xyY::Renderer_XYZ_TO_xyY (ConstFixedFunctionOpDataRcPtr & /* data*/ )
1538
1822
: OpCPU()
1539
1823
{
@@ -2325,41 +2609,29 @@ ConstOpCPURcPtr GetFixedFunctionCPURenderer(ConstFixedFunctionOpDataRcPtr & func
2325
2609
2326
2610
case FixedFunctionOpData::RGB_TO_HSY_LOG:
2327
2611
{
2328
- // TODO: Handle CPU rendering for this FixedFunction
2329
- return nullptr ;
2330
- // return std::make_shared<Renderer_RGB_TO_HSY_LOG>(func);
2612
+ return std::make_shared<Renderer_RGB_TO_HSY_LOG>(func);
2331
2613
}
2332
2614
case FixedFunctionOpData::HSY_LOG_TO_RGB:
2333
2615
{
2334
- // TODO: Handle CPU rendering for this FixedFunction
2335
- return nullptr ;
2336
- // return std::make_shared<Renderer_HSY_LOG_TO_RGB>(func);
2616
+ return std::make_shared<Renderer_HSY_LOG_TO_RGB>(func);
2337
2617
}
2338
2618
2339
2619
case FixedFunctionOpData::RGB_TO_HSY_LIN:
2340
2620
{
2341
- // TODO: Handle CPU rendering for this FixedFunction
2342
- return nullptr ;
2343
- // return std::make_shared<Renderer_RGB_TO_HSY_LIN>(func);
2621
+ return std::make_shared<Renderer_RGB_TO_HSY_LIN>(func);
2344
2622
}
2345
2623
case FixedFunctionOpData::HSY_LIN_TO_RGB:
2346
2624
{
2347
- // TODO: Handle CPU rendering for this FixedFunction
2348
- return nullptr ;
2349
- // return std::make_shared<Renderer_HSY_LIN_TO_RGB>(func);
2625
+ return std::make_shared<Renderer_HSY_LIN_TO_RGB>(func);
2350
2626
}
2351
2627
2352
2628
case FixedFunctionOpData::RGB_TO_HSY_VID:
2353
2629
{
2354
- // TODO: Handle CPU rendering for this FixedFunction
2355
- return nullptr ;
2356
- // return std::make_shared<Renderer_RGB_TO_HSY_VID>(func);
2630
+ return std::make_shared<Renderer_RGB_TO_HSY_VID>(func);
2357
2631
}
2358
2632
case FixedFunctionOpData::HSY_VID_TO_RGB:
2359
2633
{
2360
- // TODO: Handle CPU rendering for this FixedFunction
2361
- return nullptr ;
2362
- // return std::make_shared<Renderer_HSY_VID_TO_RGB>(func);
2634
+ return std::make_shared<Renderer_HSY_VID_TO_RGB>(func);
2363
2635
}
2364
2636
}
2365
2637
0 commit comments