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 "3dlut_builder.h"
26
convert_3dlut_to_tetrahedral_params(struct vpe_rgb * rgb,bool is_12_bits,struct tetrahedral_params * params)27 static void convert_3dlut_to_tetrahedral_params(
28 struct vpe_rgb *rgb, bool is_12_bits, struct tetrahedral_params *params)
29 {
30 struct vpe_rgb *lut0;
31 struct vpe_rgb *lut1;
32 struct vpe_rgb *lut2;
33 struct vpe_rgb *lut3;
34 int i, lut_i;
35
36 int num_values;
37
38 switch (params->lut_dim) {
39 case LUT_DIM_9:
40 lut0 = params->tetrahedral_9.lut0;
41 lut1 = params->tetrahedral_9.lut1;
42 lut2 = params->tetrahedral_9.lut2;
43 lut3 = params->tetrahedral_9.lut3;
44 num_values = LUT3D_SIZE_9x9x9;
45 break;
46 case LUT_DIM_17:
47 lut0 = params->tetrahedral_17.lut0;
48 lut1 = params->tetrahedral_17.lut1;
49 lut2 = params->tetrahedral_17.lut2;
50 lut3 = params->tetrahedral_17.lut3;
51 num_values = LUT3D_SIZE_17x17x17;
52 break;
53 default:
54 lut0 = params->tetrahedral_17.lut0;
55 lut1 = params->tetrahedral_17.lut1;
56 lut2 = params->tetrahedral_17.lut2;
57 lut3 = params->tetrahedral_17.lut3;
58 num_values = LUT3D_SIZE_17x17x17;
59 VPE_ASSERT(false);
60 }
61
62 for (lut_i = 0, i = 0; i < num_values - 4; lut_i++, i += 4) {
63 lut0[lut_i].red = rgb[i].red;
64 lut0[lut_i].green = rgb[i].green;
65 lut0[lut_i].blue = rgb[i].blue;
66
67 lut1[lut_i].red = rgb[i + 1].red;
68 lut1[lut_i].green = rgb[i + 1].green;
69 lut1[lut_i].blue = rgb[i + 1].blue;
70
71 lut2[lut_i].red = rgb[i + 2].red;
72 lut2[lut_i].green = rgb[i + 2].green;
73 lut2[lut_i].blue = rgb[i + 2].blue;
74
75 lut3[lut_i].red = rgb[i + 3].red;
76 lut3[lut_i].green = rgb[i + 3].green;
77 lut3[lut_i].blue = rgb[i + 3].blue;
78 }
79 lut0[lut_i].red = rgb[i].red;
80 lut0[lut_i].green = rgb[i].green;
81 lut0[lut_i].blue = rgb[i].blue;
82
83 params->use_12bits = is_12_bits;
84 }
85
vpe_convert_to_tetrahedral(struct vpe_priv * vpe_priv,uint16_t * rgb_lib,uint16_t lut_dim,struct vpe_3dlut * params)86 bool vpe_convert_to_tetrahedral(
87 struct vpe_priv *vpe_priv, uint16_t *rgb_lib, uint16_t lut_dim, struct vpe_3dlut *params)
88 {
89 bool ret = false;
90 struct vpe_rgb *rgb_area = NULL;
91 int ind = 0;
92 int ind_lut = 0;
93 int nir, nig, nib;
94 int effective_lut_dim;
95
96 switch(lut_dim) {
97 case 9:
98 params->lut_3d.lut_dim = LUT_DIM_9;
99 effective_lut_dim = 17;
100 break;
101 case 17:
102 params->lut_3d.lut_dim = LUT_DIM_17;
103 effective_lut_dim = 17;
104 break;
105 default:
106 params->lut_3d.lut_dim = LUT_DIM_INVALID;
107 VPE_ASSERT(false);
108 goto release;
109 }
110
111 rgb_area = (struct vpe_rgb *)vpe_zalloc(sizeof(struct vpe_rgb) * effective_lut_dim * effective_lut_dim * effective_lut_dim);
112 if (rgb_area == NULL)
113 goto release;
114
115 for (nib = 0; nib < effective_lut_dim; nib++) {
116 for (nig = 0; nig < effective_lut_dim; nig++) {
117 for (nir = 0; nir < effective_lut_dim; nir++) {
118 ind_lut = 3 * (nib + effective_lut_dim * nig + effective_lut_dim * effective_lut_dim * nir);
119
120 rgb_area[ind].red = rgb_lib[ind_lut + 0];
121 rgb_area[ind].green = rgb_lib[ind_lut + 1];
122 rgb_area[ind].blue = rgb_lib[ind_lut + 2];
123 ind++;
124 }
125 }
126 }
127
128 convert_3dlut_to_tetrahedral_params(rgb_area, true, ¶ms->lut_3d);
129
130 vpe_free(rgb_area);
131 ret = true;
132 release:
133 return ret;
134 }
135