• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2022 Advanced Micro Devices, Inc.
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a
4  * copy of this software and associated documentation files (the "Software"),
5  * to deal in the Software without restriction, including without limitation
6  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7  * and/or sell copies of the Software, and to permit persons to whom the
8  * Software is furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
16  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
17  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
19  * OTHER DEALINGS IN THE SOFTWARE.
20  *
21  * Authors: AMD
22  *
23  */
24 
25 #include <string.h>
26 #include "common.h"
27 #include "vpe_priv.h"
28 #include "color.h"
29 #include "color_cs.h"
30 #include "hw_shared.h"
31 #include "conversion.h"
32 
33 #define DIVIDER 10000
34 /* S2D13 value in [-3.999...3.999] */
35 #define S2D13_MIN (-39990)
36 #define S2D13_MAX (39990)
37 
38 static void translate_blt_to_internal_adjustments(
39     const struct vpe_color_adjust *blt_adjust, struct vpe_color_adjustments *dal_adjust);
40 
41 /* these values are defaults: 0 brightness, 1 contrast, 0 hue, 1 saturation*/
42 static struct vpe_color_adjust defaultClrAdjust = {0.0f, 1.0f, 0.0f, 1.0f};
43 
vpe_color_set_adjustments_to_default(struct vpe_color_adjust * crt_vpe_adjusts)44 void vpe_color_set_adjustments_to_default(struct vpe_color_adjust *crt_vpe_adjusts)
45 {
46     *crt_vpe_adjusts = defaultClrAdjust;
47 }
48 
vpe_color_different_color_adjusts(const struct vpe_color_adjust * new_vpe_adjusts,struct vpe_color_adjust * crt_vpe_adjsuts)49 bool vpe_color_different_color_adjusts(
50     const struct vpe_color_adjust *new_vpe_adjusts, struct vpe_color_adjust *crt_vpe_adjsuts)
51 {
52     if ((crt_vpe_adjsuts->brightness != new_vpe_adjusts->brightness) ||
53         (crt_vpe_adjsuts->saturation != new_vpe_adjusts->saturation) ||
54         (crt_vpe_adjsuts->hue != new_vpe_adjusts->hue) ||
55         (crt_vpe_adjsuts->contrast != new_vpe_adjusts->contrast)) {
56         return true;
57     }
58     return false;
59 }
60 
61 /**
62  * Adjustment     Min      Max    default   step
63  *
64  * Input range
65  * Brightness  -100.0f,  100.0f,   0.0f,    0.1f
66  * Contrast       0.0f,    2.0f,    1.0f,   0.01f
67  * Hue         -180.0f,  180.0f,   0.0f,    1.0f
68  * Saturation     0.0f,    3.0f,   1.0f,    0.01f
69  *
70  * DAL range
71  * Brightness    -100,     100,      0,      1
72  * Contrast         0,     200,    100,      1
73  * Hue            -30,      30,      0,      1
74  * Saturation       0,     200,    100,      1
75  */
76 
translate_blt_to_internal_adjustments(const struct vpe_color_adjust * blt_adjust,struct vpe_color_adjustments * dal_adjust)77 static void translate_blt_to_internal_adjustments(
78     const struct vpe_color_adjust *blt_adjust, struct vpe_color_adjustments *dal_adjust)
79 {
80     dal_adjust->brightness.current = (int)(10 * blt_adjust->brightness);
81     dal_adjust->brightness.min     = -1000;
82     dal_adjust->brightness.max     = 1000;
83 
84     dal_adjust->contrast.current = (int)(100 * blt_adjust->contrast);
85     dal_adjust->contrast.min     = 0;
86     dal_adjust->contrast.max     = 200;
87 
88     dal_adjust->saturation.current = (int)(100 * blt_adjust->saturation);
89     dal_adjust->saturation.min     = 0;
90     dal_adjust->saturation.max     = 300; // assuming input bigger range
91 
92     dal_adjust->hue.current = (int)(blt_adjust->hue);
93     dal_adjust->hue.min     = -180;
94     dal_adjust->hue.max     = 180; // assuming input bigger range
95 }
96 
get_hw_value_from_sw_value(int swVal,int swMin,int swMax,int hwMin,int hwMax)97 static int get_hw_value_from_sw_value(int swVal, int swMin, int swMax, int hwMin, int hwMax)
98 {
99     int dSW = swMax - swMin; /*software adjustment range size*/
100     int dHW = hwMax - hwMin; /*hardware adjustment range size*/
101     int hwVal;               /*HW adjustment value*/
102 
103     /* error case, I preserve the behavior from the predecessor
104      *getHwStepFromSwHwMinMaxValue (removed in Feb 2013)
105      *which was the FP version that only computed SCLF (i.e. dHW/dSW).
106      *it would return 0 in this case so
107      *hwVal = hwMin from the formula given in @brief
108      */
109     if (dSW == 0)
110         return hwMin;
111 
112     /*it's quite often that ranges match,
113      *e.g. for overlay colors currently (Feb 2013)
114      *only brightness has a different
115      *HW range, and in this case no multiplication or division is needed,
116      *and if minimums match, no calculation at all
117      */
118 
119     if (dSW != dHW) {
120         hwVal = (swVal - swMin) * dHW / dSW + hwMin;
121     } else {
122         hwVal = swVal;
123         if (swMin != hwMin)
124             hwVal += (hwMin - swMin);
125     }
126 
127     return hwVal;
128 }
129 
color_adjustments_to_fixed_point(const struct vpe_color_adjustments * vpe_adjust,bool icsc,struct fixed31_32 * grph_cont,struct fixed31_32 * grph_sat,struct fixed31_32 * grph_bright,struct fixed31_32 * sin_grph_hue,struct fixed31_32 * cos_grph_hue)130 static void color_adjustments_to_fixed_point(const struct vpe_color_adjustments *vpe_adjust,
131     bool               icsc, // input csc or output csc
132     struct fixed31_32 *grph_cont, struct fixed31_32 *grph_sat, struct fixed31_32 *grph_bright,
133     struct fixed31_32 *sin_grph_hue, struct fixed31_32 *cos_grph_hue)
134 {
135     /* Hue adjustment could be negative. -45 ~ +45 */
136     struct fixed31_32 hue;
137     const int         hw_hue_min      = -30;
138     const int         hw_hue_max      = 30;
139     const int         hw_sat_min      = 0;
140     const int         hw_sat_max      = 200;
141     const int         hw_contrast_min = 0;
142     const int         hw_contrast_max = 200;
143     const int         hw_bright_min   = -1000;
144     const int         hw_bright_max   = 1000;
145     if (icsc) {
146         hue = vpe_fixpt_mul(
147             vpe_fixpt_from_fraction(
148                 get_hw_value_from_sw_value(vpe_adjust->hue.current, vpe_adjust->hue.min,
149                     vpe_adjust->hue.max, -hw_hue_min, hw_hue_max),
150                 180),
151             vpe_fixpt_pi);
152 
153         // In MMD is -100 to +100 in 16-235 range; which when scaled to full
154         // range is ~-116 to +116. When normalized this is about 0.4566.
155         *grph_bright = vpe_fixpt_from_fraction(
156             get_hw_value_from_sw_value(vpe_adjust->brightness.current, vpe_adjust->brightness.min,
157                 vpe_adjust->brightness.max, hw_bright_min, hw_bright_max),
158             1000);
159 
160         *grph_cont = vpe_fixpt_from_fraction(
161             get_hw_value_from_sw_value(vpe_adjust->contrast.current, vpe_adjust->contrast.min,
162                 vpe_adjust->contrast.max, hw_contrast_min, hw_contrast_max),
163             100);
164 
165         *grph_sat = vpe_fixpt_from_fraction(
166             get_hw_value_from_sw_value(vpe_adjust->saturation.current, vpe_adjust->saturation.min,
167                 vpe_adjust->saturation.max, hw_sat_min, hw_sat_max),
168             100);
169     } else {
170         hue = vpe_fixpt_mul(
171             vpe_fixpt_from_fraction(
172                 get_hw_value_from_sw_value(vpe_adjust->hue.current, vpe_adjust->hue.min,
173                     vpe_adjust->hue.max, -hw_hue_min, hw_hue_max),
174                 180),
175             vpe_fixpt_pi);
176 
177         *grph_bright = vpe_fixpt_from_fraction(
178             get_hw_value_from_sw_value(vpe_adjust->brightness.current, vpe_adjust->brightness.min,
179                 vpe_adjust->brightness.max, hw_bright_min, hw_bright_max),
180             100);
181 
182         *grph_cont = vpe_fixpt_from_fraction(
183             get_hw_value_from_sw_value(vpe_adjust->contrast.current, vpe_adjust->contrast.min,
184                 vpe_adjust->contrast.max, hw_contrast_min, hw_contrast_max),
185             100);
186 
187         *grph_sat = vpe_fixpt_from_fraction(
188             get_hw_value_from_sw_value(vpe_adjust->saturation.current, vpe_adjust->saturation.min,
189                 vpe_adjust->saturation.max, hw_sat_min, hw_sat_max),
190             100);
191     }
192 
193     *sin_grph_hue = vpe_fixpt_sin(hue);
194     *cos_grph_hue = vpe_fixpt_cos(hue);
195 }
196 
calculate_rgb_matrix_legacy(struct vpe_color_adjustments * vpe_adjust,struct fixed31_32 * rgb_matrix)197 static void calculate_rgb_matrix_legacy(
198     struct vpe_color_adjustments *vpe_adjust, struct fixed31_32 *rgb_matrix)
199 {
200     const struct fixed31_32 k1  = vpe_fixpt_from_fraction(787400, 1000000);
201     const struct fixed31_32 k2  = vpe_fixpt_from_fraction(180428, 1000000);
202     const struct fixed31_32 k3  = vpe_fixpt_from_fraction(-715200, 1000000);
203     const struct fixed31_32 k4  = vpe_fixpt_from_fraction(606972, 1000000);
204     const struct fixed31_32 k5  = vpe_fixpt_from_fraction(-72200, 1000000);
205     const struct fixed31_32 k6  = vpe_fixpt_from_fraction(-787400, 1000000);
206     const struct fixed31_32 k7  = vpe_fixpt_from_fraction(-212600, 1000000);
207     const struct fixed31_32 k8  = vpe_fixpt_from_fraction(-147296, 1000000);
208     const struct fixed31_32 k9  = vpe_fixpt_from_fraction(284800, 1000000);
209     const struct fixed31_32 k10 = vpe_fixpt_from_fraction(-95354, 1000000);
210     const struct fixed31_32 k11 = vpe_fixpt_from_fraction(-72200, 1000000);
211     const struct fixed31_32 k12 = vpe_fixpt_from_fraction(242650, 1000000);
212     const struct fixed31_32 k13 = vpe_fixpt_from_fraction(-212600, 1000000);
213     const struct fixed31_32 k14 = vpe_fixpt_from_fraction(927800, 1000000);
214     const struct fixed31_32 k15 = vpe_fixpt_from_fraction(-715200, 1000000);
215     const struct fixed31_32 k16 = vpe_fixpt_from_fraction(-842726, 1000000);
216     const struct fixed31_32 k17 = vpe_fixpt_from_fraction(927800, 1000000);
217     const struct fixed31_32 k18 = vpe_fixpt_from_fraction(-85074, 1000000);
218 
219     const struct fixed31_32 luma_r = vpe_fixpt_from_fraction(2126, 10000);
220     const struct fixed31_32 luma_g = vpe_fixpt_from_fraction(7152, 10000);
221     const struct fixed31_32 luma_b = vpe_fixpt_from_fraction(722, 10000);
222 
223     struct fixed31_32 grph_cont;
224     struct fixed31_32 grph_sat;
225     struct fixed31_32 grph_bright;
226     struct fixed31_32 sin_grph_hue;
227     struct fixed31_32 cos_grph_hue;
228 
229     color_adjustments_to_fixed_point(
230         vpe_adjust, true, &grph_cont, &grph_sat, &grph_bright, &sin_grph_hue, &cos_grph_hue);
231 
232     /* COEF_1_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 +*/
233     /* Sin(GrphHue) * K2))*/
234     /* (Cos(GrphHue) * K1 + Sin(GrphHue) * K2)*/
235     rgb_matrix[0] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k1), vpe_fixpt_mul(sin_grph_hue, k2));
236     /* GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2 */
237     rgb_matrix[0] = vpe_fixpt_mul(grph_sat, rgb_matrix[0]);
238     /* (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2))*/
239     rgb_matrix[0] = vpe_fixpt_add(luma_r, rgb_matrix[0]);
240     /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue)**/
241     /* K2))*/
242     rgb_matrix[0] = vpe_fixpt_mul(grph_cont, rgb_matrix[0]);
243 
244     /* COEF_1_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 +*/
245     /* Sin(GrphHue) * K4))*/
246     /* (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)*/
247     rgb_matrix[1] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k3), vpe_fixpt_mul(sin_grph_hue, k4));
248     /* GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)*/
249     rgb_matrix[1] = vpe_fixpt_mul(grph_sat, rgb_matrix[1]);
250     /* (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4))*/
251     rgb_matrix[1] = vpe_fixpt_add(luma_g, rgb_matrix[1]);
252     /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue)**/
253     /* K4))*/
254     rgb_matrix[1] = vpe_fixpt_mul(grph_cont, rgb_matrix[1]);
255 
256     /* COEF_1_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 +*/
257     /* Sin(GrphHue) * K6))*/
258     /* (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
259     rgb_matrix[2] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k5), vpe_fixpt_mul(sin_grph_hue, k6));
260     /* GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
261     rgb_matrix[2] = vpe_fixpt_mul(grph_sat, rgb_matrix[2]);
262     /* LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
263     rgb_matrix[2] = vpe_fixpt_add(luma_b, rgb_matrix[2]);
264     /* GrphCont  * (LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue)**/
265     /* K6))*/
266     rgb_matrix[2] = vpe_fixpt_mul(grph_cont, rgb_matrix[2]);
267 
268     /* COEF_1_4 = GrphBright*/
269     rgb_matrix[3] = grph_bright;
270 
271     /* COEF_2_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 +*/
272     /* Sin(GrphHue) * K8))*/
273     /* (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)*/
274     rgb_matrix[4] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k7), vpe_fixpt_mul(sin_grph_hue, k8));
275     /* GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)*/
276     rgb_matrix[4] = vpe_fixpt_mul(grph_sat, rgb_matrix[4]);
277     /* (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8))*/
278     rgb_matrix[4] = vpe_fixpt_add(luma_r, rgb_matrix[4]);
279     /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue)**/
280     /* K8))*/
281     rgb_matrix[4] = vpe_fixpt_mul(grph_cont, rgb_matrix[4]);
282 
283     /* COEF_2_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 +*/
284     /* Sin(GrphHue) * K10))*/
285     /* (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
286     rgb_matrix[5] =
287         vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k9), vpe_fixpt_mul(sin_grph_hue, k10));
288     /* GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
289     rgb_matrix[5] = vpe_fixpt_mul(grph_sat, rgb_matrix[5]);
290     /* (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
291     rgb_matrix[5] = vpe_fixpt_add(luma_g, rgb_matrix[5]);
292     /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue)**/
293     /* K10))*/
294     rgb_matrix[5] = vpe_fixpt_mul(grph_cont, rgb_matrix[5]);
295 
296     /* COEF_2_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 +*/
297     /* Sin(GrphHue) * K12))*/
298     /* (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
299     rgb_matrix[6] =
300         vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k11), vpe_fixpt_mul(sin_grph_hue, k12));
301     /* GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
302     rgb_matrix[6] = vpe_fixpt_mul(grph_sat, rgb_matrix[6]);
303     /* (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
304     rgb_matrix[6] = vpe_fixpt_add(luma_b, rgb_matrix[6]);
305     /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue)**/
306     /* K12))*/
307     rgb_matrix[6] = vpe_fixpt_mul(grph_cont, rgb_matrix[6]);
308 
309     /* COEF_2_4 = GrphBright*/
310     rgb_matrix[7] = grph_bright;
311 
312     /* COEF_3_1 = GrphCont  * (LumaR + GrphSat * (Cos(GrphHue) * K13 +*/
313     /* Sin(GrphHue) * K14))*/
314     /* (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
315     rgb_matrix[8] =
316         vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k13), vpe_fixpt_mul(sin_grph_hue, k14));
317     /* GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
318     rgb_matrix[8] = vpe_fixpt_mul(grph_sat, rgb_matrix[8]);
319     /* (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
320     rgb_matrix[8] = vpe_fixpt_add(luma_r, rgb_matrix[8]);
321     /* GrphCont  * (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue)**/
322     /* K14)) */
323     rgb_matrix[8] = vpe_fixpt_mul(grph_cont, rgb_matrix[8]);
324 
325     /* COEF_3_2    = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 +*/
326     /* Sin(GrphHue) * K16)) */
327     /* GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16) */
328     rgb_matrix[9] =
329         vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k15), vpe_fixpt_mul(sin_grph_hue, k16));
330     /* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */
331     rgb_matrix[9] = vpe_fixpt_mul(grph_sat, rgb_matrix[9]);
332     /* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */
333     rgb_matrix[9] = vpe_fixpt_add(luma_g, rgb_matrix[9]);
334     /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue)**/
335     /* K16)) */
336     rgb_matrix[9] = vpe_fixpt_mul(grph_cont, rgb_matrix[9]);
337 
338     /*  COEF_3_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 +*/
339     /* Sin(GrphHue) * K18)) */
340     /* (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
341     rgb_matrix[10] =
342         vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k17), vpe_fixpt_mul(sin_grph_hue, k18));
343     /*  GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
344     rgb_matrix[10] = vpe_fixpt_mul(grph_sat, rgb_matrix[10]);
345     /* (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
346     rgb_matrix[10] = vpe_fixpt_add(luma_b, rgb_matrix[10]);
347     /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue)**/
348     /* K18)) */
349     rgb_matrix[10] = vpe_fixpt_mul(grph_cont, rgb_matrix[10]);
350 
351     /* COEF_3_4 = GrphBright */
352     rgb_matrix[11] = grph_bright;
353 }
354 
calculate_rgb_limited_range_matrix_legacy(struct vpe_color_adjustments * vpe_adjust,struct fixed31_32 * rgb_matrix)355 static void calculate_rgb_limited_range_matrix_legacy(
356     struct vpe_color_adjustments *vpe_adjust, struct fixed31_32 *rgb_matrix)
357 {
358     const struct fixed31_32 k1  = vpe_fixpt_from_fraction(701000, 1000000);
359     const struct fixed31_32 k2  = vpe_fixpt_from_fraction(236568, 1000000);
360     const struct fixed31_32 k3  = vpe_fixpt_from_fraction(-587000, 1000000);
361     const struct fixed31_32 k4  = vpe_fixpt_from_fraction(464432, 1000000);
362     const struct fixed31_32 k5  = vpe_fixpt_from_fraction(-114000, 1000000);
363     const struct fixed31_32 k6  = vpe_fixpt_from_fraction(-701000, 1000000);
364     const struct fixed31_32 k7  = vpe_fixpt_from_fraction(-299000, 1000000);
365     const struct fixed31_32 k8  = vpe_fixpt_from_fraction(-292569, 1000000);
366     const struct fixed31_32 k9  = vpe_fixpt_from_fraction(413000, 1000000);
367     const struct fixed31_32 k10 = vpe_fixpt_from_fraction(-92482, 1000000);
368     const struct fixed31_32 k11 = vpe_fixpt_from_fraction(-114000, 1000000);
369     const struct fixed31_32 k12 = vpe_fixpt_from_fraction(385051, 1000000);
370     const struct fixed31_32 k13 = vpe_fixpt_from_fraction(-299000, 1000000);
371     const struct fixed31_32 k14 = vpe_fixpt_from_fraction(886000, 1000000);
372     const struct fixed31_32 k15 = vpe_fixpt_from_fraction(-587000, 1000000);
373     const struct fixed31_32 k16 = vpe_fixpt_from_fraction(-741914, 1000000);
374     const struct fixed31_32 k17 = vpe_fixpt_from_fraction(886000, 1000000);
375     const struct fixed31_32 k18 = vpe_fixpt_from_fraction(-144086, 1000000);
376 
377     const struct fixed31_32 luma_r = vpe_fixpt_from_fraction(299, 1000);
378     const struct fixed31_32 luma_g = vpe_fixpt_from_fraction(587, 1000);
379     const struct fixed31_32 luma_b = vpe_fixpt_from_fraction(114, 1000);
380     /*onst struct fixed31_32 luma_scale =
381         vpe_fixpt_from_fraction(875855, 1000000);*/
382 
383     const struct fixed31_32 rgb_scale = vpe_fixpt_from_fraction(85546875, 100000000);
384     const struct fixed31_32 rgb_bias  = vpe_fixpt_from_fraction(625, 10000);
385 
386     struct fixed31_32 grph_cont;
387     struct fixed31_32 grph_sat;
388     struct fixed31_32 grph_bright;
389     struct fixed31_32 sin_grph_hue;
390     struct fixed31_32 cos_grph_hue;
391 
392     color_adjustments_to_fixed_point(
393         vpe_adjust, true, &grph_cont, &grph_sat, &grph_bright, &sin_grph_hue, &cos_grph_hue);
394 
395     /* COEF_1_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 +*/
396     /* Sin(GrphHue) * K2))*/
397     /* (Cos(GrphHue) * K1 + Sin(GrphHue) * K2)*/
398     rgb_matrix[0] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k1), vpe_fixpt_mul(sin_grph_hue, k2));
399     /* GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2 */
400     rgb_matrix[0] = vpe_fixpt_mul(grph_sat, rgb_matrix[0]);
401     /* (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2))*/
402     rgb_matrix[0] = vpe_fixpt_add(luma_r, rgb_matrix[0]);
403     /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue)**/
404     /* K2))*/
405     rgb_matrix[0] = vpe_fixpt_mul(grph_cont, rgb_matrix[0]);
406     /* LumaScale * GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 + */
407     /* Sin(GrphHue) * K2))*/
408     rgb_matrix[0] = vpe_fixpt_mul(rgb_scale, rgb_matrix[0]);
409 
410     /* COEF_1_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 +*/
411     /* Sin(GrphHue) * K4))*/
412     /* (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)*/
413     rgb_matrix[1] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k3), vpe_fixpt_mul(sin_grph_hue, k4));
414     /* GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)*/
415     rgb_matrix[1] = vpe_fixpt_mul(grph_sat, rgb_matrix[1]);
416     /* (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4))*/
417     rgb_matrix[1] = vpe_fixpt_add(luma_g, rgb_matrix[1]);
418     /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue)**/
419     /* K4))*/
420     rgb_matrix[1] = vpe_fixpt_mul(grph_cont, rgb_matrix[1]);
421     /* LumaScale * GrphCont * (LumaG + GrphSat *(Cos(GrphHue) * K3 + */
422     /* Sin(GrphHue) * K4))*/
423     rgb_matrix[1] = vpe_fixpt_mul(rgb_scale, rgb_matrix[1]);
424 
425     /* COEF_1_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 +*/
426     /* Sin(GrphHue) * K6))*/
427     /* (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
428     rgb_matrix[2] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k5), vpe_fixpt_mul(sin_grph_hue, k6));
429     /* GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
430     rgb_matrix[2] = vpe_fixpt_mul(grph_sat, rgb_matrix[2]);
431     /* LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)*/
432     rgb_matrix[2] = vpe_fixpt_add(luma_b, rgb_matrix[2]);
433     /* GrphCont  * (LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue)**/
434     /* K6))*/
435     rgb_matrix[2] = vpe_fixpt_mul(grph_cont, rgb_matrix[2]);
436     /* LumaScale * GrphCont  * (LumaB + GrphSat *(Cos(GrphHue) * K5 + */
437     /* Sin(GrphHue) * K6))*/
438     rgb_matrix[2] = vpe_fixpt_mul(rgb_scale, rgb_matrix[2]);
439 
440     /* COEF_1_4 = RGBBias + RGBScale * GrphBright*/
441     rgb_matrix[3] = vpe_fixpt_add(rgb_bias, vpe_fixpt_mul(rgb_scale, grph_bright));
442 
443     /* COEF_2_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 +*/
444     /* Sin(GrphHue) * K8))*/
445     /* (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)*/
446     rgb_matrix[4] = vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k7), vpe_fixpt_mul(sin_grph_hue, k8));
447     /* GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)*/
448     rgb_matrix[4] = vpe_fixpt_mul(grph_sat, rgb_matrix[4]);
449     /* (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8))*/
450     rgb_matrix[4] = vpe_fixpt_add(luma_r, rgb_matrix[4]);
451     /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue)**/
452     /* K8))*/
453     rgb_matrix[4] = vpe_fixpt_mul(grph_cont, rgb_matrix[4]);
454     /* LumaScale * GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 + */
455     /* Sin(GrphHue) * K8))*/
456     rgb_matrix[4] = vpe_fixpt_mul(rgb_scale, rgb_matrix[4]);
457 
458     /* COEF_2_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 +*/
459     /* Sin(GrphHue) * K10))*/
460     /* (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
461     rgb_matrix[5] =
462         vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k9), vpe_fixpt_mul(sin_grph_hue, k10));
463     /* GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
464     rgb_matrix[5] = vpe_fixpt_mul(grph_sat, rgb_matrix[5]);
465     /* (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))*/
466     rgb_matrix[5] = vpe_fixpt_add(luma_g, rgb_matrix[5]);
467     /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue)**/
468     /* K10))*/
469     rgb_matrix[5] = vpe_fixpt_mul(grph_cont, rgb_matrix[5]);
470     /* LumaScale * GrphCont * (LumaG + GrphSat *(Cos(GrphHue) * K9 + */
471     /* Sin(GrphHue) * K10))*/
472     rgb_matrix[5] = vpe_fixpt_mul(rgb_scale, rgb_matrix[5]);
473 
474     /* COEF_2_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 +*/
475     /* Sin(GrphHue) * K12))*/
476     /* (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
477     rgb_matrix[6] =
478         vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k11), vpe_fixpt_mul(sin_grph_hue, k12));
479     /* GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
480     rgb_matrix[6] = vpe_fixpt_mul(grph_sat, rgb_matrix[6]);
481     /* (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))*/
482     rgb_matrix[6] = vpe_fixpt_add(luma_b, rgb_matrix[6]);
483     /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue)**/
484     /* K12))*/
485     rgb_matrix[6] = vpe_fixpt_mul(grph_cont, rgb_matrix[6]);
486     /* LumaScale * GrphCont  * (LumaB + GrphSat *(Cos(GrphHue) * K11 +*/
487     /* Sin(GrphHue) * K12)) */
488     rgb_matrix[6] = vpe_fixpt_mul(rgb_scale, rgb_matrix[6]);
489 
490     /* COEF_2_4 = RGBBias + RGBScale * GrphBright*/
491     rgb_matrix[7] = vpe_fixpt_add(rgb_bias, vpe_fixpt_mul(rgb_scale, grph_bright));
492 
493     /* COEF_3_1 = GrphCont  * (LumaR + GrphSat * (Cos(GrphHue) * K13 +*/
494     /* Sin(GrphHue) * K14))*/
495     /* (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
496     rgb_matrix[8] =
497         vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k13), vpe_fixpt_mul(sin_grph_hue, k14));
498     /* GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
499     rgb_matrix[8] = vpe_fixpt_mul(grph_sat, rgb_matrix[8]);
500     /* (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
501     rgb_matrix[8] = vpe_fixpt_add(luma_r, rgb_matrix[8]);
502     /* GrphCont  * (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue)**/
503     /* K14)) */
504     rgb_matrix[8] = vpe_fixpt_mul(grph_cont, rgb_matrix[8]);
505     /* LumaScale * GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 +*/
506     /* Sin(GrphHue) * K14))*/
507     rgb_matrix[8] = vpe_fixpt_mul(rgb_scale, rgb_matrix[8]);
508 
509     /* COEF_3_2    = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 +*/
510     /* Sin(GrphHue) * K16)) */
511     /* GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16) */
512     rgb_matrix[9] =
513         vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k15), vpe_fixpt_mul(sin_grph_hue, k16));
514     /* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */
515     rgb_matrix[9] = vpe_fixpt_mul(grph_sat, rgb_matrix[9]);
516     /* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */
517     rgb_matrix[9] = vpe_fixpt_add(luma_g, rgb_matrix[9]);
518     /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue)**/
519     /* K16)) */
520     rgb_matrix[9] = vpe_fixpt_mul(grph_cont, rgb_matrix[9]);
521     /* LumaScale * GrphCont * (LumaG + GrphSat *(Cos(GrphHue) * K15 + */
522     /* Sin(GrphHue) * K16))*/
523     rgb_matrix[9] = vpe_fixpt_mul(rgb_scale, rgb_matrix[9]);
524 
525     /*  COEF_3_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 +*/
526     /* Sin(GrphHue) * K18)) */
527     /* (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
528     rgb_matrix[10] =
529         vpe_fixpt_add(vpe_fixpt_mul(cos_grph_hue, k17), vpe_fixpt_mul(sin_grph_hue, k18));
530     /*  GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
531     rgb_matrix[10] = vpe_fixpt_mul(grph_sat, rgb_matrix[10]);
532     /* (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
533     rgb_matrix[10] = vpe_fixpt_add(luma_b, rgb_matrix[10]);
534     /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue)**/
535     /* K18)) */
536     rgb_matrix[10] = vpe_fixpt_mul(grph_cont, rgb_matrix[10]);
537     /* LumaScale * GrphCont * (LumaB + GrphSat *(Cos(GrphHue) * */
538     /* K17 + Sin(GrphHue) * K18))*/
539     rgb_matrix[10] = vpe_fixpt_mul(rgb_scale, rgb_matrix[10]);
540 
541     /* COEF_3_4 = RGBBias + RGBScale * GrphBright */
542     rgb_matrix[11] = vpe_fixpt_add(rgb_bias, vpe_fixpt_mul(rgb_scale, grph_bright));
543 }
544 
545 /* this function scales the matrix coefficients to fit a maximum integer bit range*/
vpe_scale_csc_matrix(struct fixed31_32 * matrix,unsigned int matrixLength,unsigned int maxIntegerBits,struct fixed31_32 * scalingFactor)546 static bool vpe_scale_csc_matrix(struct fixed31_32 *matrix, unsigned int matrixLength,
547     unsigned int maxIntegerBits, struct fixed31_32 *scalingFactor)
548 {
549     bool              ret            = false;
550     unsigned int      index          = 0;
551     long long         maxIntegerVal  = ((long long)1 << maxIntegerBits);
552     long long         maxMatrixVal   = 0;
553     unsigned int      crtIntPart     = 0;
554     struct fixed31_32 divisionFactor = vpe_fixpt_one;
555     long long         crtValue       = 0;
556     unsigned int      posLargestBit  = 0;
557     (*scalingFactor)                 = vpe_fixpt_one; // by default this is initialized to one
558     for (index = 0; index < matrixLength; index++) {
559         crtValue = matrix[index].value;
560         if (crtValue < 0) {
561             crtValue = -crtValue;
562         }
563         crtIntPart = (crtValue >> FIXED31_32_BITS_PER_FRACTIONAL_PART);
564         if (maxMatrixVal < crtIntPart) {
565             maxMatrixVal = crtIntPart;
566         }
567     }
568     if ((maxMatrixVal >= maxIntegerVal) && (maxIntegerVal > 0)) {
569         for (index = 0; index < (FIXED31_32_BITS_PER_FRACTIONAL_PART - 1); index++) {
570             if (maxMatrixVal & ((long long)1 << index)) { // scan all the bits
571                 posLargestBit = index;
572             }
573         }
574         divisionFactor.value = (long long)1 << (posLargestBit - maxIntegerBits + 1);
575         divisionFactor.value <<= FIXED31_32_BITS_PER_FRACTIONAL_PART;
576         (*scalingFactor) = divisionFactor;
577         for (index = 0; index < matrixLength; index++) {
578             matrix[index] = vpe_fixpt_div(matrix[index], divisionFactor);
579         }
580         ret = true;
581     }
582     return ret;
583 }
584 
calculate_yuv_matrix(struct vpe_color_adjustments * vpe_adjust,enum color_space color_space,struct vpe_csc_matrix * input_cs,struct fixed31_32 * yuv_matrix)585 static void calculate_yuv_matrix(struct vpe_color_adjustments *vpe_adjust,
586     enum color_space color_space, struct vpe_csc_matrix *input_cs, struct fixed31_32 *yuv_matrix)
587 {
588     struct fixed31_32 initialMatrix[12];
589     uint32_t          i = 0;
590     bool ovl = true; // if we ever have Output CSC case, we can reuse this function with ovl passed
591                      // in as param
592     struct fixed31_32 grph_cont;
593     struct fixed31_32 grph_sat;
594     struct fixed31_32 grph_bright;
595     struct fixed31_32 sin_grph_hue;
596     struct fixed31_32 cos_grph_hue;
597     struct fixed31_32 multiplier;
598     struct fixed31_32 chromaOffset = vpe_fixpt_sub(vpe_fixpt_half, vpe_fixpt_one); // = -0.5
599     struct fixed31_32 lumaOffset   = {
600         0x10101010LL}; //=16/255.0 This is an offset applied in the shader, not clear why
601                          // to maintain compatibility this offset is still applied in VPE
602 
603     /* The input YCbCr to RGB matrix is modified to embed the color adjustments as follows:
604         A = initial YCbCr to RGB conversion matrix
605         s = saturation , h = hue, c = contrast, b = brightness
606 
607                 | c*s*(a11*cos(h)+a13*sin(h))   a12*c   c*s(a13*cos(h)-a11*sin(h))  |
608         |R|     |                                                                   |   |Y+b   |
609         |G|=    | c*s*(a21*cos(h)+a23*sin(h))   a22*c   c*s(a23*cos(h)-a21*sin(h))  | * |Cb-0.5|
610         |B|     |                                                                   |   |Cr-0.5|
611                 | c*s*(a31*cos(h)+a33*sin(h))   a32*c   c*s(a33*cos(h)-a31*sin(h))  |
612     */
613 
614     for (i = 0; i < 12; i++) {
615         initialMatrix[i] = vpe_convfix31_32(input_cs->regval[i]); // convert from s.2.13 to s.31.32
616     }
617     color_adjustments_to_fixed_point(
618         vpe_adjust, ovl, &grph_cont, &grph_sat, &grph_bright, &sin_grph_hue, &cos_grph_hue);
619     grph_bright = vpe_fixpt_sub(grph_bright, lumaOffset);
620     multiplier  = vpe_fixpt_mul(grph_cont, grph_sat); // contSat
621 
622     yuv_matrix[0] =
623         vpe_fixpt_mul(multiplier, vpe_fixpt_add(vpe_fixpt_mul(initialMatrix[0], cos_grph_hue),
624                                       vpe_fixpt_mul(initialMatrix[2], sin_grph_hue)));
625 
626     yuv_matrix[1] = vpe_fixpt_mul(initialMatrix[1], grph_cont);
627 
628     yuv_matrix[2] =
629         vpe_fixpt_mul(multiplier, vpe_fixpt_sub(vpe_fixpt_mul(initialMatrix[2], cos_grph_hue),
630                                       vpe_fixpt_mul(initialMatrix[0], sin_grph_hue)));
631 
632     yuv_matrix[3] = initialMatrix[3];
633 
634     yuv_matrix[4] =
635         vpe_fixpt_mul(multiplier, vpe_fixpt_add(vpe_fixpt_mul(initialMatrix[4], cos_grph_hue),
636                                       vpe_fixpt_mul(initialMatrix[6], sin_grph_hue)));
637 
638     yuv_matrix[5] = vpe_fixpt_mul(initialMatrix[5], grph_cont);
639 
640     yuv_matrix[6] =
641         vpe_fixpt_mul(multiplier, vpe_fixpt_sub(vpe_fixpt_mul(initialMatrix[6], cos_grph_hue),
642                                       vpe_fixpt_mul(initialMatrix[4], sin_grph_hue)));
643 
644     yuv_matrix[7] = initialMatrix[7];
645 
646     yuv_matrix[8] =
647         vpe_fixpt_mul(multiplier, vpe_fixpt_add(vpe_fixpt_mul(initialMatrix[8], cos_grph_hue),
648                                       vpe_fixpt_mul(initialMatrix[10], sin_grph_hue)));
649 
650     yuv_matrix[9] = vpe_fixpt_mul(initialMatrix[9], grph_cont);
651 
652     yuv_matrix[10] =
653         vpe_fixpt_mul(multiplier, vpe_fixpt_sub(vpe_fixpt_mul(initialMatrix[10], cos_grph_hue),
654                                       vpe_fixpt_mul(initialMatrix[8], sin_grph_hue)));
655 
656     yuv_matrix[3]  = vpe_fixpt_add(vpe_fixpt_mul(grph_bright, yuv_matrix[1]),
657          vpe_fixpt_add(vpe_fixpt_mul(chromaOffset, yuv_matrix[0]),
658              vpe_fixpt_mul(chromaOffset, yuv_matrix[2])));
659     yuv_matrix[7]  = vpe_fixpt_add(vpe_fixpt_mul(grph_bright, yuv_matrix[5]),
660          vpe_fixpt_add(vpe_fixpt_mul(chromaOffset, yuv_matrix[4]),
661              vpe_fixpt_mul(chromaOffset, yuv_matrix[6])));
662     yuv_matrix[11] = vpe_fixpt_add(vpe_fixpt_mul(grph_bright, yuv_matrix[9]),
663         vpe_fixpt_add(vpe_fixpt_mul(chromaOffset, yuv_matrix[8]),
664             vpe_fixpt_mul(chromaOffset, yuv_matrix[10])));
665 }
666 
convert_float_matrix(uint16_t * matrix,struct fixed31_32 * flt,uint32_t buffer_size)667 static void convert_float_matrix(uint16_t *matrix, struct fixed31_32 *flt, uint32_t buffer_size)
668 {
669     const struct fixed31_32 min_2_13 = vpe_fixpt_from_fraction(S2D13_MIN, DIVIDER);
670     const struct fixed31_32 max_2_13 = vpe_fixpt_from_fraction(S2D13_MAX, DIVIDER);
671     uint32_t                i;
672     uint16_t                temp_matrix[12];
673 
674     for (i = 0; i < 12; i++)
675         temp_matrix[i] = 0;
676 
677     for (i = 0; i < buffer_size; ++i) {
678         uint32_t reg_value =
679             conv_fixed_point_to_int_frac(vpe_fixpt_clamp(flt[i], min_2_13, max_2_13), 2, 13);
680 
681         temp_matrix[i] = (uint16_t)reg_value;
682     }
683 
684     matrix[4] = temp_matrix[0];
685     matrix[5] = temp_matrix[1];
686     matrix[6] = temp_matrix[2];
687     matrix[7] = temp_matrix[3];
688 
689     matrix[8]  = temp_matrix[4];
690     matrix[9]  = temp_matrix[5];
691     matrix[10] = temp_matrix[6];
692     matrix[11] = temp_matrix[7];
693 
694     matrix[0] = temp_matrix[8];
695     matrix[1] = temp_matrix[9];
696     matrix[2] = temp_matrix[10];
697     matrix[3] = temp_matrix[11];
698 }
699 
vpe_color_calculate_input_cs(struct vpe_priv * vpe_priv,enum color_space in_cs,const struct vpe_color_adjust * vpe_blt_adjust,struct vpe_csc_matrix * input_cs,struct fixed31_32 * matrix_scaling_factor)700 bool vpe_color_calculate_input_cs(struct vpe_priv *vpe_priv, enum color_space in_cs,
701     const struct vpe_color_adjust *vpe_blt_adjust, struct vpe_csc_matrix *input_cs,
702     struct fixed31_32 *matrix_scaling_factor)
703 {
704     struct fixed31_32 fixed_csc_matrix[12];
705 
706     struct vpe_color_adjustments vpe_adjust = {0};
707 
708     if (vpe_blt_adjust) {
709         translate_blt_to_internal_adjustments(vpe_blt_adjust, &vpe_adjust);
710     }
711 
712     switch (in_cs) {
713     case COLOR_SPACE_SRGB:
714     case COLOR_SPACE_2020_RGB_FULLRANGE:
715     case COLOR_SPACE_MSREF_SCRGB:
716     case COLOR_SPACE_SRGB_LIMITED:
717     case COLOR_SPACE_2020_RGB_LIMITEDRANGE:
718         calculate_rgb_matrix_legacy(&vpe_adjust, fixed_csc_matrix);
719         break;
720 
721     case COLOR_SPACE_YCBCR601:
722     case COLOR_SPACE_YCBCR709:
723     case COLOR_SPACE_YCBCR601_LIMITED:
724     case COLOR_SPACE_YCBCR709_LIMITED:
725     case COLOR_SPACE_2020_YCBCR:
726         calculate_yuv_matrix(&vpe_adjust, in_cs, input_cs, fixed_csc_matrix);
727         if (vpe_priv->scale_yuv_matrix) { // in case the coefficitents are too large
728             // they are scaled down to fit the n integer bits, m
729             // fractional bits (for now 2.19)
730             vpe_log("Scale down YUV -> RGB matrix");
731             vpe_scale_csc_matrix(fixed_csc_matrix, 12, 2, matrix_scaling_factor);
732         } else {
733             vpe_log("No scaling on the yuv -> rgb matrix");
734         }
735         break;
736 
737     default:
738         calculate_rgb_matrix_legacy(&vpe_adjust, fixed_csc_matrix);
739         break;
740     }
741     conv_convert_float_matrix(&input_cs->regval[0], fixed_csc_matrix, 12);
742 
743     return true;
744 }
745