2121#include "src/webp/types.h"
2222#include "src/dsp/cpu.h"
2323#include "sharpyuv/sharpyuv_dsp.h"
24+ #include "sharpyuv/sharpyuv_gamma.h"
2425
2526//------------------------------------------------------------------------------
2627// Sharp RGB->YUV conversion
@@ -45,100 +46,6 @@ static int GetPrecisionShift(int rgb_bit_depth) {
4546typedef int16_t fixed_t ; // signed type with extra precision for UV
4647typedef uint16_t fixed_y_t ; // unsigned type with extra precision for W
4748
48- //------------------------------------------------------------------------------
49- // Code for gamma correction
50-
51- // Gamma correction compensates loss of resolution during chroma subsampling.
52- // Size of pre-computed table for converting from gamma to linear.
53- #define GAMMA_TO_LINEAR_TAB_BITS 10
54- #define GAMMA_TO_LINEAR_TAB_SIZE (1 << GAMMA_TO_LINEAR_TAB_BITS)
55- static uint32_t kGammaToLinearTabS [GAMMA_TO_LINEAR_TAB_SIZE + 2 ];
56- // Size of pre-computed table for converting from linear to gamma.
57- #define LINEAR_TO_GAMMA_TAB_BITS 8
58- #define LINEAR_TO_GAMMA_TAB_SIZE (1 << LINEAR_TO_GAMMA_TAB_BITS)
59- static uint32_t kLinearToGammaTabS [LINEAR_TO_GAMMA_TAB_SIZE + 2 ];
60-
61- static const double kGammaF = 1. / 0.45 ;
62- #define GAMMA_TO_LINEAR_BITS 14
63-
64- static volatile int kGammaTablesSOk = 0 ;
65- static void InitGammaTablesS (void ) {
66- assert (2 * GAMMA_TO_LINEAR_BITS < 32 ); // we use uint32_t intermediate values
67- if (!kGammaTablesSOk ) {
68- int v ;
69- const double a = 0.09929682680944 ;
70- const double thresh = 0.018053968510807 ;
71- // Precompute gamma to linear table.
72- {
73- const double norm = 1. / GAMMA_TO_LINEAR_TAB_SIZE ;
74- const double a_rec = 1. / (1. + a );
75- const double final_scale = 1 << GAMMA_TO_LINEAR_BITS ;
76- for (v = 0 ; v <= GAMMA_TO_LINEAR_TAB_SIZE ; ++ v ) {
77- const double g = norm * v ;
78- double value ;
79- if (g <= thresh * 4.5 ) {
80- value = g / 4.5 ;
81- } else {
82- value = pow (a_rec * (g + a ), kGammaF );
83- }
84- kGammaToLinearTabS [v ] = (uint32_t )(value * final_scale + .5 );
85- }
86- // to prevent small rounding errors to cause read-overflow:
87- kGammaToLinearTabS [GAMMA_TO_LINEAR_TAB_SIZE + 1 ] =
88- kGammaToLinearTabS [GAMMA_TO_LINEAR_TAB_SIZE ];
89- }
90- // Precompute linear to gamma table.
91- {
92- const double scale = 1. / LINEAR_TO_GAMMA_TAB_SIZE ;
93- for (v = 0 ; v <= LINEAR_TO_GAMMA_TAB_SIZE ; ++ v ) {
94- const double g = scale * v ;
95- double value ;
96- if (g <= thresh ) {
97- value = 4.5 * g ;
98- } else {
99- value = (1. + a ) * pow (g , 1. / kGammaF ) - a ;
100- }
101- kLinearToGammaTabS [v ] =
102- (uint32_t )(GAMMA_TO_LINEAR_TAB_SIZE * value + 0.5 );
103- }
104- // to prevent small rounding errors to cause read-overflow:
105- kLinearToGammaTabS [LINEAR_TO_GAMMA_TAB_SIZE + 1 ] =
106- kLinearToGammaTabS [LINEAR_TO_GAMMA_TAB_SIZE ];
107- }
108- kGammaTablesSOk = 1 ;
109- }
110- }
111-
112- static WEBP_INLINE uint32_t FixedPointInterpolation (int v , uint32_t * tab ,
113- int tab_pos_shift ,
114- int tab_value_shift ) {
115- const uint32_t tab_pos = v >> tab_pos_shift ;
116- // fractional part, in 'tab_pos_shift' fixed-point precision
117- const uint32_t x = v - (tab_pos << tab_pos_shift ); // fractional part
118- // v0 / v1 are in kGammaToLinearBits fixed-point precision (range [0..1])
119- const uint32_t v0 = tab [tab_pos + 0 ] << tab_value_shift ;
120- const uint32_t v1 = tab [tab_pos + 1 ] << tab_value_shift ;
121- // Final interpolation.
122- const uint32_t v2 = (v1 - v0 ) * x ; // note: v1 >= v0.
123- const int half = (tab_pos_shift > 0 ) ? 1 << (tab_pos_shift - 1 ) : 0 ;
124- const uint32_t result = v0 + ((v2 + half ) >> tab_pos_shift );
125- return result ;
126- }
127-
128- static WEBP_INLINE uint32_t GammaToLinear (int v , int bit_depth ) {
129- const int shift = GAMMA_TO_LINEAR_TAB_BITS - bit_depth ;
130- if (shift > 0 ) {
131- return kGammaToLinearTabS [v << shift ];
132- }
133- return FixedPointInterpolation (v , kGammaToLinearTabS , - shift , 0 );
134- }
135-
136- static WEBP_INLINE uint32_t LinearToGamma (uint32_t value , int bit_depth ) {
137- const uint32_t v = value << LINEAR_TO_GAMMA_TAB_BITS ;
138- return FixedPointInterpolation (v , kLinearToGammaTabS , GAMMA_TO_LINEAR_BITS ,
139- bit_depth - GAMMA_TO_LINEAR_TAB_BITS );
140- }
141-
14249//------------------------------------------------------------------------------
14350
14451static uint8_t clip_8b (fixed_t v ) {
@@ -161,25 +68,26 @@ static int RGBToGray(int64_t r, int64_t g, int64_t b) {
16168 return (int )(luma >> YUV_FIX );
16269}
16370
164- static uint32_t ScaleDown (int a , int b , int c , int d , int rgb_bit_depth ) {
71+ static uint32_t ScaleDown (uint16_t a , uint16_t b , uint16_t c , uint16_t d ,
72+ int rgb_bit_depth ) {
16573 const int bit_depth = rgb_bit_depth + GetPrecisionShift (rgb_bit_depth );
166- const uint32_t A = GammaToLinear (a , bit_depth );
167- const uint32_t B = GammaToLinear (b , bit_depth );
168- const uint32_t C = GammaToLinear (c , bit_depth );
169- const uint32_t D = GammaToLinear (d , bit_depth );
170- return LinearToGamma ((A + B + C + D + 2 ) >> 2 , bit_depth );
74+ const uint32_t A = SharpYuvGammaToLinear (a , bit_depth );
75+ const uint32_t B = SharpYuvGammaToLinear (b , bit_depth );
76+ const uint32_t C = SharpYuvGammaToLinear (c , bit_depth );
77+ const uint32_t D = SharpYuvGammaToLinear (d , bit_depth );
78+ return SharpYuvLinearToGamma ((A + B + C + D + 2 ) >> 2 , bit_depth );
17179}
17280
17381static WEBP_INLINE void UpdateW (const fixed_y_t * src , fixed_y_t * dst , int w ,
17482 int rgb_bit_depth ) {
17583 const int bit_depth = rgb_bit_depth + GetPrecisionShift (rgb_bit_depth );
17684 int i ;
17785 for (i = 0 ; i < w ; ++ i ) {
178- const uint32_t R = GammaToLinear (src [0 * w + i ], bit_depth );
179- const uint32_t G = GammaToLinear (src [1 * w + i ], bit_depth );
180- const uint32_t B = GammaToLinear (src [2 * w + i ], bit_depth );
86+ const uint32_t R = SharpYuvGammaToLinear (src [0 * w + i ], bit_depth );
87+ const uint32_t G = SharpYuvGammaToLinear (src [1 * w + i ], bit_depth );
88+ const uint32_t B = SharpYuvGammaToLinear (src [2 * w + i ], bit_depth );
18189 const uint32_t Y = RGBToGray (R , G , B );
182- dst [i ] = (fixed_y_t )LinearToGamma (Y , bit_depth );
90+ dst [i ] = (fixed_y_t )SharpYuvLinearToGamma (Y , bit_depth );
18391 }
18492}
18593
@@ -227,15 +135,6 @@ static WEBP_INLINE int Shift(int v, int shift) {
227135 return (shift >= 0 ) ? (v << shift ) : (v >> - shift );
228136}
229137
230- static WEBP_INLINE fixed_y_t ChangePrecision (uint16_t a , int shift ) {
231- if (shift == 0 ) return a ;
232- if (shift < 0 ) {
233- const int rounding = 1 << (- shift - 1 );
234- return (a + rounding ) >> - shift ;
235- }
236- return ((fixed_y_t )a << shift );
237- }
238-
239138static void ImportOneRow (const uint8_t * const r_ptr ,
240139 const uint8_t * const g_ptr ,
241140 const uint8_t * const b_ptr ,
@@ -252,13 +151,13 @@ static void ImportOneRow(const uint8_t* const r_ptr,
252151 const int off = i * step ;
253152 const int shift = GetPrecisionShift (rgb_bit_depth );
254153 if (rgb_bit_depth == 8 ) {
255- dst [i + 0 * w ] = ChangePrecision (r_ptr [off ], shift );
256- dst [i + 1 * w ] = ChangePrecision (g_ptr [off ], shift );
257- dst [i + 2 * w ] = ChangePrecision (b_ptr [off ], shift );
154+ dst [i + 0 * w ] = Shift (r_ptr [off ], shift );
155+ dst [i + 1 * w ] = Shift (g_ptr [off ], shift );
156+ dst [i + 2 * w ] = Shift (b_ptr [off ], shift );
258157 } else {
259- dst [i + 0 * w ] = ChangePrecision (((uint16_t * )r_ptr )[off ], shift );
260- dst [i + 1 * w ] = ChangePrecision (((uint16_t * )g_ptr )[off ], shift );
261- dst [i + 2 * w ] = ChangePrecision (((uint16_t * )b_ptr )[off ], shift );
158+ dst [i + 0 * w ] = Shift (((uint16_t * )r_ptr )[off ], shift );
159+ dst [i + 1 * w ] = Shift (((uint16_t * )g_ptr )[off ], shift );
160+ dst [i + 2 * w ] = Shift (((uint16_t * )b_ptr )[off ], shift );
262161 }
263162 }
264163 if (pic_width & 1 ) { // replicate rightmost pixel
@@ -527,7 +426,7 @@ void SharpYuvInit(VP8CPUInfo cpu_info_func) {
527426
528427 SharpYuvInitDsp (cpu_info_func );
529428 if (!initialized ) {
530- InitGammaTablesS ();
429+ SharpYuvInitGammaTables ();
531430 }
532431
533432 sharpyuv_last_cpuinfo_used = cpu_info_func ;
0 commit comments