Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkYUVMath.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2019 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
11#include "include/core/SkM44.h"
14
15#include <cstring>
16
17// in SkColorMatrix order (row-major)
18// Created by running SkColorMatrix_DumpYUVMatrixTables()
19const float JPEG_full_rgb_to_yuv[] = {
20 0.299000f, 0.587000f, 0.114000f, 0.000000f, 0.000000f,
21 -0.168736f, -0.331264f, 0.500000f, 0.000000f, 0.501961f,
22 0.500000f, -0.418688f, -0.081312f, 0.000000f, 0.501961f,
23 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
24};
25const float JPEG_full_yuv_to_rgb[] = {
26 1.000000f, -0.000000f, 1.402000f, 0.000000f, -0.703749f,
27 1.000000f, -0.344136f, -0.714136f, 0.000000f, 0.531211f,
28 1.000000f, 1.772000f, 0.000000f, 0.000000f, -0.889475f,
29 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
30};
32 0.256788f, 0.504129f, 0.097906f, 0.000000f, 0.062745f,
33 -0.148223f, -0.290993f, 0.439216f, 0.000000f, 0.501961f,
34 0.439216f, -0.367788f, -0.071427f, 0.000000f, 0.501961f,
35 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
36};
38 1.164384f, -0.000000f, 1.596027f, 0.000000f, -0.874202f,
39 1.164384f, -0.391762f, -0.812968f, 0.000000f, 0.531668f,
40 1.164384f, 2.017232f, 0.000000f, 0.000000f, -1.085631f,
41 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
42};
43const float Rec709_full_rgb_to_yuv[] = {
44 0.212600f, 0.715200f, 0.072200f, 0.000000f, 0.000000f,
45 -0.114572f, -0.385428f, 0.500000f, 0.000000f, 0.501961f,
46 0.500000f, -0.454153f, -0.045847f, 0.000000f, 0.501961f,
47 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
48};
49const float Rec709_full_yuv_to_rgb[] = {
50 1.000000f, -0.000000f, 1.574800f, 0.000000f, -0.790488f,
51 1.000000f, -0.187324f, -0.468124f, 0.000000f, 0.329010f,
52 1.000000f, 1.855600f, -0.000000f, 0.000000f, -0.931439f,
53 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
54};
56 0.182586f, 0.614231f, 0.062007f, 0.000000f, 0.062745f,
57 -0.100644f, -0.338572f, 0.439216f, 0.000000f, 0.501961f,
58 0.439216f, -0.398942f, -0.040274f, 0.000000f, 0.501961f,
59 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
60};
62 1.164384f, -0.000000f, 1.792741f, 0.000000f, -0.972945f,
63 1.164384f, -0.213249f, -0.532909f, 0.000000f, 0.301483f,
64 1.164384f, 2.112402f, -0.000000f, 0.000000f, -1.133402f,
65 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
66};
68 0.262700f, 0.678000f, 0.059300f, 0.000000f, 0.000000f,
69 -0.139630f, -0.360370f, 0.500000f, 0.000000f, 0.501961f,
70 0.500000f, -0.459786f, -0.040214f, 0.000000f, 0.501961f,
71 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
72};
74 1.000000f, -0.000000f, 1.474600f, 0.000000f, -0.740191f,
75 1.000000f, -0.164553f, -0.571353f, 0.000000f, 0.369396f,
76 1.000000f, 1.881400f, -0.000000f, 0.000000f, -0.944389f,
77 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
78};
80 0.225613f, 0.582282f, 0.050928f, 0.000000f, 0.062745f,
81 -0.122655f, -0.316560f, 0.439216f, 0.000000f, 0.501961f,
82 0.439216f, -0.403890f, -0.035326f, 0.000000f, 0.501961f,
83 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
84};
86 1.164384f, -0.000000f, 1.678674f, 0.000000f, -0.915688f,
87 1.164384f, -0.187326f, -0.650424f, 0.000000f, 0.347458f,
88 1.164384f, 2.141772f, -0.000000f, 0.000000f, -1.148145f,
89 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
90};
92 0.262700f, 0.678000f, 0.059300f, 0.000000f, 0.000000f,
93 -0.139630f, -0.360370f, 0.500000f, 0.000000f, 0.500489f,
94 0.500000f, -0.459786f, -0.040214f, 0.000000f, 0.500489f,
95 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
96};
98 1.000000f, -0.000000f, 1.474600f, 0.000000f, -0.738021f,
99 1.000000f, -0.164553f, -0.571353f, 0.000000f, 0.368313f,
100 1.000000f, 1.881400f, -0.000000f, 0.000000f, -0.941620f,
101 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
102};
104 0.224951f, 0.580575f, 0.050779f, 0.000000f, 0.062561f,
105 -0.122296f, -0.315632f, 0.437928f, 0.000000f, 0.500489f,
106 0.437928f, -0.402706f, -0.035222f, 0.000000f, 0.500489f,
107 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
108};
110 1.167808f, -0.000000f, 1.683611f, 0.000000f, -0.915688f,
111 1.167808f, -0.187877f, -0.652337f, 0.000000f, 0.347458f,
112 1.167808f, 2.148072f, -0.000000f, 0.000000f, -1.148145f,
113 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
114};
116 0.262700f, 0.678000f, 0.059300f, 0.000000f, 0.000000f,
117 -0.139630f, -0.360370f, 0.500000f, 0.000000f, 0.500122f,
118 0.500000f, -0.459786f, -0.040214f, 0.000000f, 0.500122f,
119 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
120};
122 1.000000f, -0.000000f, 1.474600f, 0.000000f, -0.737480f,
123 1.000000f, -0.164553f, -0.571353f, 0.000000f, 0.368043f,
124 1.000000f, 1.881400f, -0.000000f, 0.000000f, -0.940930f,
125 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
126};
128 0.224787f, 0.580149f, 0.050742f, 0.000000f, 0.062515f,
129 -0.122206f, -0.315401f, 0.437607f, 0.000000f, 0.500122f,
130 0.437607f, -0.402411f, -0.035196f, 0.000000f, 0.500122f,
131 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
132};
134 1.168664f, -0.000000f, 1.684846f, 0.000000f, -0.915688f,
135 1.168664f, -0.188015f, -0.652816f, 0.000000f, 0.347458f,
136 1.168664f, 2.149647f, -0.000000f, 0.000000f, -1.148145f,
137 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
138};
139const float FCC_full_rgb_to_yuv[] = {
140 0.300000f, 0.590000f, 0.110000f, 0.000000f, 0.000000f,
141 -0.168539f, -0.331461f, 0.500000f, 0.000000f, 0.501961f,
142 0.500000f, -0.421429f, -0.078571f, 0.000000f, 0.501961f,
143 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
144};
145const float FCC_full_yuv_to_rgb[] = {
146 1.000000f, 0.000000f, 1.400000f, 0.000000f, -0.702745f,
147 1.000000f, -0.331864f, -0.711864f, 0.000000f, 0.523911f,
148 1.000000f, 1.780000f, 0.000000f, 0.000000f, -0.893490f,
149 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
150};
151const float FCC_limited_rgb_to_yuv[] = {
152 0.257647f, 0.506706f, 0.094471f, 0.000000f, 0.062745f,
153 -0.148050f, -0.291165f, 0.439216f, 0.000000f, 0.501961f,
154 0.439216f, -0.370196f, -0.069020f, 0.000000f, 0.501961f,
155 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
156};
157const float FCC_limited_yuv_to_rgb[] = {
158 1.164384f, -0.000000f, 1.593750f, 0.000000f, -0.873059f,
159 1.164384f, -0.377792f, -0.810381f, 0.000000f, 0.523357f,
160 1.164384f, 2.026339f, 0.000000f, 0.000000f, -1.090202f,
161 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
162};
164 0.212000f, 0.701000f, 0.087000f, 0.000000f, 0.000000f,
165 -0.116101f, -0.383899f, 0.500000f, 0.000000f, 0.501961f,
166 0.500000f, -0.444797f, -0.055203f, 0.000000f, 0.501961f,
167 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
168};
170 1.000000f, 0.000000f, 1.576000f, 0.000000f, -0.791090f,
171 1.000000f, -0.226622f, -0.476622f, 0.000000f, 0.353001f,
172 1.000000f, 1.826000f, 0.000000f, 0.000000f, -0.916580f,
173 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
174};
176 0.182071f, 0.602035f, 0.074718f, 0.000000f, 0.062745f,
177 -0.101987f, -0.337229f, 0.439216f, 0.000000f, 0.501961f,
178 0.439216f, -0.390724f, -0.048492f, 0.000000f, 0.501961f,
179 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
180};
182 1.164384f, -0.000000f, 1.794107f, 0.000000f, -0.973631f,
183 1.164384f, -0.257985f, -0.542583f, 0.000000f, 0.328794f,
184 1.164384f, 2.078705f, 0.000000f, 0.000000f, -1.116488f,
185 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
186};
187const float YDZDX_full_rgb_to_yuv[] = {
188 0.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f,
189 0.000000f, -0.500000f, 0.493283f, 0.000000f, 0.501961f,
190 0.500000f, -0.495951f, 0.000000f, 0.000000f, 0.501961f,
191 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
192};
193const float YDZDX_full_yuv_to_rgb[] = {
194 0.991902f, -0.000000f, 2.000000f, 0.000000f, -1.003922f,
195 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
196 1.013617f, 2.027234f, 0.000000f, 0.000000f, -1.017592f,
197 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
198};
200 0.000000f, 0.858824f, 0.000000f, 0.000000f, 0.062745f,
201 0.000000f, -0.439216f, 0.433315f, 0.000000f, 0.501961f,
202 0.439216f, -0.435659f, 0.000000f, 0.000000f, 0.501961f,
203 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
204};
206 1.154954f, -0.000000f, 2.276786f, 0.000000f, -1.215325f,
207 1.164384f, 0.000000f, 0.000000f, 0.000000f, -0.073059f,
208 1.180239f, 2.307788f, 0.000000f, 0.000000f, -1.232474f,
209 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
210};
211const float GBR_full_rgb_to_yuv[] = {
212 0.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f,
213 0.000000f, 0.000000f, 1.000000f, 0.000000f, 0.000000f,
214 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
215 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
216};
217const float GBR_full_yuv_to_rgb[] = {
218 0.000000f, 0.000000f, 1.000000f, 0.000000f, 0.000000f,
219 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
220 0.000000f, 1.000000f, 0.000000f, 0.000000f, -0.000000f,
221 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
222};
223const float GBR_limited_rgb_to_yuv[] = {
224 0.000000f, 0.858824f, 0.000000f, 0.000000f, 0.062745f,
225 0.000000f, 0.000000f, 0.858824f, 0.000000f, 0.062745f,
226 0.858824f, 0.000000f, 0.000000f, 0.000000f, 0.062745f,
227 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
228};
229const float GBR_limited_yuv_to_rgb[] = {
230 0.000000f, 0.000000f, 1.164384f, 0.000000f, -0.073059f,
231 1.164384f, 0.000000f, 0.000000f, 0.000000f, -0.073059f,
232 0.000000f, 1.164384f, 0.000000f, 0.000000f, -0.073059f,
233 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
234};
236 0.250000f, 0.500000f, 0.250000f, 0.000000f, 0.000000f,
237 -0.250000f, 0.500000f, -0.250000f, 0.000000f, 0.501961f,
238 0.500000f, 0.000000f, -0.500000f, 0.000000f, 0.501961f,
239 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
240};
242 1.000000f, -1.000000f, 1.000000f, 0.000000f, 0.000000f,
243 1.000000f, 1.000000f, 0.000000f, 0.000000f, -0.501961f,
244 1.000000f, -1.000000f, -1.000000f, 0.000000f, 1.003922f,
245 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
246};
248 0.214706f, 0.429412f, 0.214706f, 0.000000f, 0.062745f,
249 -0.214706f, 0.429412f, -0.214706f, 0.000000f, 0.501961f,
250 0.429412f, 0.000000f, -0.429412f, 0.000000f, 0.501961f,
251 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
252};
254 1.164384f, -1.164384f, 1.164384f, 0.000000f, -0.073059f,
255 1.164384f, 1.164384f, 0.000000f, 0.000000f, -0.657534f,
256 1.164384f, -1.164384f, -1.164384f, 0.000000f, 1.095891f,
257 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
258};
260 0.250000f, 0.500000f, 0.250000f, 0.000000f, 0.000000f,
261 -0.250000f, 0.500000f, -0.250000f, 0.000000f, 0.500489f,
262 0.500000f, 0.000000f, -0.500000f, 0.000000f, 0.500489f,
263 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
264};
266 1.000000f, -1.000000f, 1.000000f, 0.000000f, 0.000000f,
267 1.000000f, 1.000000f, 0.000000f, 0.000000f, -0.500489f,
268 1.000000f, -1.000000f, -1.000000f, 0.000000f, 1.000978f,
269 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
270};
272 0.214076f, 0.428153f, 0.214076f, 0.000000f, 0.062561f,
273 -0.214076f, 0.428153f, -0.214076f, 0.000000f, 0.500489f,
274 0.428153f, 0.000000f, -0.428153f, 0.000000f, 0.500489f,
275 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
276};
278 1.167808f, -1.167808f, 1.167808f, 0.000000f, -0.073059f,
279 1.167808f, 1.167808f, 0.000000f, 0.000000f, -0.657534f,
280 1.167808f, -1.167808f, -1.167808f, 0.000000f, 1.095890f,
281 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
282};
284 0.250000f, 0.500000f, 0.250000f, 0.000000f, 0.000000f,
285 -0.250000f, 0.500000f, -0.250000f, 0.000000f, 0.500122f,
286 0.500000f, 0.000000f, -0.500000f, 0.000000f, 0.500122f,
287 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
288};
290 1.000000f, -1.000000f, 1.000000f, 0.000000f, 0.000000f,
291 1.000000f, 1.000000f, 0.000000f, 0.000000f, -0.500122f,
292 1.000000f, -1.000000f, -1.000000f, 0.000000f, 1.000244f,
293 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
294};
296 0.213919f, 0.427839f, 0.213919f, 0.000000f, 0.062515f,
297 -0.213919f, 0.427839f, -0.213919f, 0.000000f, 0.500122f,
298 0.427839f, 0.000000f, -0.427839f, 0.000000f, 0.500122f,
299 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
300};
302 1.168664f, -1.168664f, 1.168664f, 0.000000f, -0.073059f,
303 1.168664f, 1.168664f, 0.000000f, 0.000000f, -0.657534f,
304 1.168664f, -1.168664f, -1.168664f, 0.000000f, 1.095891f,
305 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
306};
307
308static_assert(kJPEG_Full_SkYUVColorSpace == 0, "");
309static_assert(kRec601_Limited_SkYUVColorSpace == 1, "");
310static_assert(kRec709_Full_SkYUVColorSpace == 2, "");
311static_assert(kRec709_Limited_SkYUVColorSpace == 3, "");
312static_assert(kBT2020_8bit_Full_SkYUVColorSpace == 4, "");
313static_assert(kBT2020_8bit_Limited_SkYUVColorSpace == 5, "");
314static_assert(kBT2020_10bit_Full_SkYUVColorSpace == 6, "");
315static_assert(kBT2020_10bit_Limited_SkYUVColorSpace == 7, "");
316static_assert(kBT2020_12bit_Full_SkYUVColorSpace == 8, "");
317static_assert(kBT2020_12bit_Limited_SkYUVColorSpace == 9, "");
318static_assert(kFCC_Full_SkYUVColorSpace == 10, "");
319static_assert(kFCC_Limited_SkYUVColorSpace == 11, "");
320static_assert(kSMPTE240_Full_SkYUVColorSpace == 12, "");
321static_assert(kSMPTE240_Limited_SkYUVColorSpace == 13, "");
322static_assert(kYDZDX_Full_SkYUVColorSpace == 14, "");
323static_assert(kYDZDX_Limited_SkYUVColorSpace == 15, "");
324static_assert(kGBR_Full_SkYUVColorSpace == 16, "");
325static_assert(kGBR_Limited_SkYUVColorSpace == 17, "");
326static_assert(kYCgCo_8bit_Full_SkYUVColorSpace == 18, "");
327static_assert(kYCgCo_8bit_Limited_SkYUVColorSpace == 19, "");
328static_assert(kYCgCo_10bit_Full_SkYUVColorSpace == 20, "");
329static_assert(kYCgCo_10bit_Limited_SkYUVColorSpace == 21, "");
330static_assert(kYCgCo_12bit_Full_SkYUVColorSpace == 22, "");
331static_assert(kYCgCo_12bit_Limited_SkYUVColorSpace == 23, "");
332
359
386
387constexpr size_t kSizeOfColorMatrix = 20 * sizeof(float);
388
390 if ((unsigned)cs < (unsigned)kIdentity_SkYUVColorSpace) {
391 memcpy(m, rgb_to_yuv_array[(unsigned)cs], kSizeOfColorMatrix);
392 } else {
393 memset(m, 0, kSizeOfColorMatrix);
394 m[0] = m[6] = m[12] = m[18] = 1;
395 }
396}
397
399 if ((unsigned)cs < (unsigned)kIdentity_SkYUVColorSpace) {
400 memcpy(m, yuv_to_rgb_array[(unsigned)cs], kSizeOfColorMatrix);
401 } else {
402 memset(m, 0, kSizeOfColorMatrix);
403 m[0] = m[6] = m[12] = m[18] = 1;
404 }
405}
406
407///////////////////////////////////////////////////////////////////////////////////////////////////
408
409// we just drop the alpha rol/col from the colormatrix
410// output is | tr |
411// | 3x3 tg |
412// | tb |
413// | 0 0 0 1 |
414static void colormatrix_to_matrix44(const float src[20], SkM44* dst) {
415 *dst = SkM44(src[ 0], src[ 1], src[ 2], src[ 4],
416 src[ 5], src[ 6], src[ 7], src[ 9],
417 src[10], src[11], src[12], src[14],
418 0, 0, 0, 1);
419}
420
421// input: ignore the bottom row
422// output: inject identity row/column for alpha
423static void matrix44_to_colormatrix(const SkM44& src, float dst[20]) {
424 dst[0] = src.rc(0,0);
425 dst[1] = src.rc(0,1);
426 dst[2] = src.rc(0,2);
427 dst[3] = 0;
428 dst[4] = src.rc(0,3); // tx
429
430 dst[5] = src.rc(1,0);
431 dst[6] = src.rc(1,1);
432 dst[7] = src.rc(1,2);
433 dst[8] = 0;
434 dst[9] = src.rc(1,3); // ty
435
436 dst[10] = src.rc(2,0);
437 dst[11] = src.rc(2,1);
438 dst[12] = src.rc(2,2);
439 dst[13] = 0;
440 dst[14] = src.rc(2,3); // tz
441
442 dst[15] = dst[16] = dst[17] = dst[19] = 0;
443 dst[18] = 1;
444}
445
446static void scale3(float m[], float s) {
447 for (int i = 0; i < 3; ++i) {
448 m[i] *= s;
449 }
450}
451
452namespace {
453enum Range { kFull, kLimited };
454struct YUVCoeff {
455 float Kr, Kb;
456 int bits;
457 Range range;
458};
459
460const YUVCoeff gCoeff[] = {
461 { 0.2990f, 0.1140f, 8, kFull }, // kJPEG_Full_SkYUVColorSpace
462 { 0.2990f, 0.1140f, 8, kLimited }, // kRec601_Limited_SkYUVColorSpace
463 { 0.2126f, 0.0722f, 8, kFull }, // kRec709_Full_SkYUVColorSpace
464 { 0.2126f, 0.0722f, 8, kLimited }, // kRec709_Limited_SkYUVColorSpace
465 { 0.2627f, 0.0593f, 8, kFull }, // kBT2020_8bit_Full_SkYUVColorSpace
466 { 0.2627f, 0.0593f, 8, kLimited }, // kBT2020_8bit_Limited_SkYUVColorSpace
467 { 0.2627f, 0.0593f, 10, kFull }, // kBT2020_10bit_Full_SkYUVColorSpace
468 { 0.2627f, 0.0593f, 10, kLimited }, // kBT2020_10bit_Limited_SkYUVColorSpace
469 { 0.2627f, 0.0593f, 12, kFull }, // kBT2020_12bit_Full_SkYUVColorSpace
470 { 0.2627f, 0.0593f, 12, kLimited }, // kBT2020_12bit_Limited_SkYUVColorSpace
471 { 0.3000f, 0.1100f, 8, kFull }, // kFCC_Full_SkYUVColorSpace
472 { 0.3000f, 0.1100f, 8, kLimited }, // kFCC_Limited_SkYUVColorSpace
473 { 0.2120f, 0.0870f, 8, kFull }, // kSMPTE240_Full_SkYUVColorSpace
474 { 0.2120f, 0.0870f, 8, kLimited }, // kSMPTE240_Limited_SkYUVColorSpace
475};
476} // namespace
477
478static void make_rgb_to_yuv_matrix_ycbcr(float mx[20], const YUVCoeff& c) {
479 SkASSERT(c.bits >= 8);
480 const float Kr = c.Kr;
481 const float Kb = c.Kb;
482 const float Kg = 1.0f - Kr - Kb;
483 const float Cr = 0.5f / (1.0f - Kb);
484 const float Cb = 0.5f / (1.0f - Kr);
485
486 const int shift = c.bits - 8;
487
488 const float denom = static_cast<float>((1 << c.bits) - 1);
489 float scaleY = 1.0f,
490 addY = 0.0f,
491 scaleUV = 1.0f,
492 addUV = (128 << shift) / denom;
493
494 if (c.range == kLimited) {
495 scaleY = (219 << shift) / denom;
496 addY = ( 16 << shift) / denom;
497 scaleUV = (224 << shift) / denom;
498 }
499
500 float m[20] = {
501 Kr, Kg, Kb, 0, addY,
502 -Kr, -Kg, 1-Kb, 0, addUV,
503 1-Kr, -Kg, -Kb, 0, addUV,
504 0, 0, 0, 1, 0,
505 };
506 memcpy(mx, m, sizeof(m));
507 scale3(mx + 0, scaleY );
508 scale3(mx + 5, Cr * scaleUV);
509 scale3(mx + 10, Cb * scaleUV);
510}
511
512static void make_rgb_to_yuv_matrix_ydzdx(float mx[20], Range range) {
513 const int bits = 8;
514 const float denom = static_cast<float>((1 << bits) - 1);
515 float scaleY = 1.0f,
516 addY = 0.0f,
517 scaleUV = 1.0f,
518 addUV = 128 / denom;
519
520 if (range == kLimited) {
521 scaleY = 219 / denom;
522 addY = 16 / denom;
523 scaleUV = 224 / denom;
524 }
525
526 // YDZDX applies range correction to YUV values similar to YCbCr.
527 float m[20] = {
528 0.0f, 1.0f, 0.0f, 0.0f, addY, // Y
529 0.0f, -0.5f, 0.986566f / 2.0f, 0.0f, addUV, // DX or DZ
530 0.5f, -0.991902f / 2.0f, 0.0f, 0.0f, addUV, // DZ or DX
531 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
532 };
533 memcpy(mx, m, sizeof(m));
534 scale3(mx + 0, scaleY );
535 scale3(mx + 5, scaleUV);
536 scale3(mx + 10, scaleUV);
537}
538
539static void make_rgb_to_yuv_matrix_gbr(float mx[20], Range range) {
540 const int bits = 8;
541 const float denom = static_cast<float>((1 << bits) - 1);
542 float scaleY = 1.0f,
543 addY = 0.0f;
544
545 if (range == kLimited) {
546 scaleY = 219 / denom;
547 addY = 16 / denom;
548 }
549
550 // GBR applies range correction to RGB values similar to YCgCo.
551 float m[20] = {
552 0.0f, 1.0f, 0.0f, 0.0f, addY, // G
553 0.0f, 0.0f, 1.0f, 0.0f, addY, // B
554 1.0f, 0.0f, 0.0f, 0.0f, addY, // R
555 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
556 };
557 memcpy(mx, m, sizeof(m));
558 scale3(mx + 0, scaleY);
559 scale3(mx + 5, scaleY);
560 scale3(mx + 10, scaleY);
561}
562
563static void make_rgb_to_yuv_matrix_ycgco(float mx[20], int bits, Range range) {
564 SkASSERT(bits >= 8);
565 const int shift = bits - 8;
566 const float denom = static_cast<float>((1 << bits) - 1);
567 float scaleY = 1.0f,
568 addY = 0.0f,
569 chroma05 = static_cast<float>(1 << (bits - 1)) / denom;
570
571 if (range == kLimited) {
572 scaleY = (219 << shift) / denom;
573 addY = ( 16 << shift) / denom;
574 }
575
576 float m[20] = {
577 0.25f, 0.5f, 0.25f, 0.0f, addY,
578 -0.25f, 0.5f, -0.25f, 0.0f, chroma05,
579 0.5f, 0.0f, -0.5f, 0.0f, chroma05,
580 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
581 };
582 memcpy(mx, m, sizeof(m));
583 scale3(mx + 0, scaleY);
584 scale3(mx + 5, scaleY);
585 scale3(mx + 10, scaleY);
586}
587
588static void make_rgb_to_yuv_matrix(float mx[20], SkYUVColorSpace cs) {
589 switch (cs) {
605 return make_rgb_to_yuv_matrix_ycbcr(mx, gCoeff[(unsigned)cs]);
607 return make_rgb_to_yuv_matrix_ydzdx(mx, Range::kFull);
609 return make_rgb_to_yuv_matrix_ydzdx(mx, Range::kLimited);
611 return make_rgb_to_yuv_matrix_gbr(mx, Range::kFull);
613 return make_rgb_to_yuv_matrix_gbr(mx, Range::kLimited);
615 return make_rgb_to_yuv_matrix_ycgco(mx, /*bits=*/8, Range::kFull);
617 return make_rgb_to_yuv_matrix_ycgco(mx, /*bits=*/8, Range::kLimited);
619 return make_rgb_to_yuv_matrix_ycgco(mx, /*bits=*/10, Range::kFull);
621 return make_rgb_to_yuv_matrix_ycgco(mx, /*bits=*/10, Range::kLimited);
623 return make_rgb_to_yuv_matrix_ycgco(mx, /*bits=*/12, Range::kFull);
625 return make_rgb_to_yuv_matrix_ycgco(mx, /*bits=*/12, Range::kLimited);
626 }
627}
628
629static void dump(const float m[20], SkYUVColorSpace cs, bool rgb2yuv) {
630 const char* names[] = {
631 "JPEG_full",
632 "Rec601_limited",
633 "Rec709_full",
634 "Rec709_limited",
635 "BT2020_8bit_full",
636 "BT2020_8bit_limited",
637 "BT2020_10bit_full",
638 "BT2020_10bit_limited",
639 "BT2020_12bit_full",
640 "BT2020_12bit_limited",
641 "FCC_full",
642 "FCC_limited",
643 "SMPTE240_full",
644 "SMPTE240_limited",
645 "YDZDX_full",
646 "YDZDX_limited",
647 "GBR_full",
648 "GBR_limited",
649 "YCgCo_8bit_full",
650 "YCgCo_8bit_limited",
651 "YCgCo_10bit_full",
652 "YCgCo_10bit_limited",
653 "YCgCo_12bit_full",
654 "YCgCo_12bit_limited",
655 };
656 const char* dirnames[] = {
657 "yuv_to_rgb", "rgb_to_yuv",
658 };
659 SkDebugf("const float %s_%s[] = {\n", names[cs], dirnames[rgb2yuv]);
660 for (int i = 0; i < 4; ++i) {
661 SkDebugf(" ");
662 for (int j = 0; j < 5; ++j) {
663 SkDebugf(" %9.6ff,", m[i * 5 + j]);
664 }
665 SkDebugf("\n");
666 }
667 SkDebugf("};\n");
668}
669
670// Used to create the prebuilt tables for each colorspace.
671// Don't remove this function, in case we want to recompute those tables in the future.
673 for (int i = 0; i < kLastEnum_SkYUVColorSpace; ++i) {
674 SkYUVColorSpace cs = static_cast<SkYUVColorSpace>(i);
675 float m[20];
677 dump(m, cs, true);
678 SkM44 m44, im44;
680 float im[20];
681#ifdef SK_DEBUG
682 // be sure our coversion between matrix44 and colormatrix is perfect
684 SkASSERT(memcmp(m, im, sizeof(im)) == 0);
685#endif
686 SkAssertResult(m44.invert(&im44));
687 matrix44_to_colormatrix(im44, im);
688 dump(im, cs, false);
689 }
690}
#define SkAssertResult(cond)
Definition SkAssert.h:123
#define SkASSERT(cond)
Definition SkAssert.h:116
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
@ kFull
modifies glyph outlines for maximum constrast
SkYUVColorSpace
Definition SkImageInfo.h:68
@ kRec709_Full_SkYUVColorSpace
describes HDTV range
Definition SkImageInfo.h:71
@ kYCgCo_10bit_Full_SkYUVColorSpace
Definition SkImageInfo.h:89
@ kYCgCo_12bit_Full_SkYUVColorSpace
Definition SkImageInfo.h:91
@ kYCgCo_12bit_Limited_SkYUVColorSpace
Definition SkImageInfo.h:92
@ kYCgCo_10bit_Limited_SkYUVColorSpace
Definition SkImageInfo.h:90
@ kGBR_Limited_SkYUVColorSpace
Definition SkImageInfo.h:86
@ kBT2020_8bit_Limited_SkYUVColorSpace
Definition SkImageInfo.h:74
@ kFCC_Full_SkYUVColorSpace
describes FCC range
Definition SkImageInfo.h:79
@ kLastEnum_SkYUVColorSpace
last valid value
Definition SkImageInfo.h:95
@ kYCgCo_8bit_Limited_SkYUVColorSpace
Definition SkImageInfo.h:88
@ kYDZDX_Full_SkYUVColorSpace
describes YDZDX range
Definition SkImageInfo.h:83
@ kFCC_Limited_SkYUVColorSpace
Definition SkImageInfo.h:80
@ kBT2020_12bit_Limited_SkYUVColorSpace
Definition SkImageInfo.h:78
@ kYCgCo_8bit_Full_SkYUVColorSpace
describes YCgCo matrix
Definition SkImageInfo.h:87
@ kBT2020_8bit_Full_SkYUVColorSpace
describes UHDTV range, non-constant-luminance
Definition SkImageInfo.h:73
@ kRec601_Limited_SkYUVColorSpace
describes SDTV range
Definition SkImageInfo.h:70
@ kRec709_Limited_SkYUVColorSpace
Definition SkImageInfo.h:72
@ kSMPTE240_Full_SkYUVColorSpace
describes SMPTE240M range
Definition SkImageInfo.h:81
@ kGBR_Full_SkYUVColorSpace
describes GBR range
Definition SkImageInfo.h:85
@ kSMPTE240_Limited_SkYUVColorSpace
Definition SkImageInfo.h:82
@ kBT2020_12bit_Full_SkYUVColorSpace
Definition SkImageInfo.h:77
@ kBT2020_10bit_Full_SkYUVColorSpace
Definition SkImageInfo.h:75
@ kIdentity_SkYUVColorSpace
maps Y->R, U->G, V->B
Definition SkImageInfo.h:93
@ kBT2020_10bit_Limited_SkYUVColorSpace
Definition SkImageInfo.h:76
@ kYDZDX_Limited_SkYUVColorSpace
Definition SkImageInfo.h:84
@ kJPEG_Full_SkYUVColorSpace
describes full range
Definition SkImageInfo.h:69
const float YCgCo_10bit_full_yuv_to_rgb[]
const float GBR_full_rgb_to_yuv[]
const float YCgCo_10bit_limited_yuv_to_rgb[]
const float BT2020_10bit_limited_rgb_to_yuv[]
const float Rec601_limited_rgb_to_yuv[]
Definition SkYUVMath.cpp:31
const float SMPTE240_full_rgb_to_yuv[]
const float Rec709_full_rgb_to_yuv[]
Definition SkYUVMath.cpp:43
const float Rec709_full_yuv_to_rgb[]
Definition SkYUVMath.cpp:49
static void make_rgb_to_yuv_matrix_ycgco(float mx[20], int bits, Range range)
const float BT2020_8bit_limited_rgb_to_yuv[]
Definition SkYUVMath.cpp:79
static void make_rgb_to_yuv_matrix_gbr(float mx[20], Range range)
static void dump(const float m[20], SkYUVColorSpace cs, bool rgb2yuv)
const float JPEG_full_rgb_to_yuv[]
Definition SkYUVMath.cpp:19
const float YCgCo_8bit_full_rgb_to_yuv[]
const float YCgCo_10bit_full_rgb_to_yuv[]
static void make_rgb_to_yuv_matrix(float mx[20], SkYUVColorSpace cs)
const float YCgCo_12bit_full_yuv_to_rgb[]
const float SMPTE240_limited_yuv_to_rgb[]
const float YCgCo_12bit_limited_yuv_to_rgb[]
const float BT2020_10bit_full_rgb_to_yuv[]
Definition SkYUVMath.cpp:91
const float * yuv_to_rgb_array[]
const float FCC_full_rgb_to_yuv[]
constexpr size_t kSizeOfColorMatrix
static void matrix44_to_colormatrix(const SkM44 &src, float dst[20])
const float YDZDX_limited_yuv_to_rgb[]
const float FCC_full_yuv_to_rgb[]
const float FCC_limited_rgb_to_yuv[]
const float GBR_limited_yuv_to_rgb[]
const float YCgCo_8bit_limited_yuv_to_rgb[]
const float YCgCo_10bit_limited_rgb_to_yuv[]
const float Rec709_limited_rgb_to_yuv[]
Definition SkYUVMath.cpp:55
const float BT2020_12bit_full_rgb_to_yuv[]
const float GBR_full_yuv_to_rgb[]
const float YCgCo_12bit_limited_rgb_to_yuv[]
const float YDZDX_limited_rgb_to_yuv[]
const float YCgCo_12bit_full_rgb_to_yuv[]
const float Rec709_limited_yuv_to_rgb[]
Definition SkYUVMath.cpp:61
const float SMPTE240_limited_rgb_to_yuv[]
const float YDZDX_full_rgb_to_yuv[]
void SkColorMatrix_DumpYUVMatrixTables()
const float BT2020_12bit_limited_rgb_to_yuv[]
const float BT2020_10bit_limited_yuv_to_rgb[]
const float BT2020_8bit_full_yuv_to_rgb[]
Definition SkYUVMath.cpp:73
const float JPEG_full_yuv_to_rgb[]
Definition SkYUVMath.cpp:25
const float BT2020_12bit_limited_yuv_to_rgb[]
const float YCgCo_8bit_limited_rgb_to_yuv[]
const float BT2020_8bit_limited_yuv_to_rgb[]
Definition SkYUVMath.cpp:85
void SkColorMatrix_RGB2YUV(SkYUVColorSpace cs, float m[20])
static void scale3(float m[], float s)
const float * rgb_to_yuv_array[]
const float FCC_limited_yuv_to_rgb[]
void SkColorMatrix_YUV2RGB(SkYUVColorSpace cs, float m[20])
const float Rec601_limited_yuv_to_rgb[]
Definition SkYUVMath.cpp:37
static void colormatrix_to_matrix44(const float src[20], SkM44 *dst)
const float SMPTE240_full_yuv_to_rgb[]
const float YDZDX_full_yuv_to_rgb[]
const float GBR_limited_rgb_to_yuv[]
const float BT2020_12bit_full_yuv_to_rgb[]
const float BT2020_10bit_full_yuv_to_rgb[]
Definition SkYUVMath.cpp:97
static void make_rgb_to_yuv_matrix_ycbcr(float mx[20], const YUVCoeff &c)
const float BT2020_8bit_full_rgb_to_yuv[]
Definition SkYUVMath.cpp:67
const float YCgCo_8bit_full_yuv_to_rgb[]
static void make_rgb_to_yuv_matrix_ydzdx(float mx[20], Range range)
Definition SkM44.h:150
bool invert(SkM44 *inverse) const
Definition SkM44.cpp:247
struct MyStruct s