GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 168 / 0 / 168
Functions: 100.0% 7 / 0 / 7
Branches: 91.0% 61 / 0 / 67

convert/convert_matrix.cpp
Line Branch Exec Source
1 // Avisynth v2.5. Copyright 2002-2009 Ben Rudiak-Gould et al.
2 // http://avisynth.nl
3
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
17 // http://www.gnu.org/copyleft/gpl.html .
18 //
19 // Linking Avisynth statically or dynamically with other modules is making a
20 // combined work based on Avisynth. Thus, the terms and conditions of the GNU
21 // General Public License cover the whole combination.
22 //
23 // As a special exception, the copyright holders of Avisynth give you
24 // permission to link Avisynth with independent modules that communicate with
25 // Avisynth solely through the interfaces defined in avisynth.h, regardless of the license
26 // terms of these independent modules, and to copy and distribute the
27 // resulting combined work under terms of your choice, provided that
28 // every copy of the combined work is accompanied by a complete copy of
29 // the source code of Avisynth (the version of Avisynth used to produce the
30 // combined work), being distributed under the terms of the GNU General
31 // Public License plus this exception. An independent module is a module
32 // which is not derived from or based on Avisynth, such as 3rd-party filters,
33 // import and export plugins, or graphical user interfaces.
34
35
36 #include "convert_matrix.h"
37 #include "convert_helper.h"
38 #include <avisynth.h>
39 #ifdef AVS_WINDOWS
40 #include <avs/win.h>
41 #else
42 #include <avs/posix.h>
43 #endif
44 #include <cmath>
45
46 /**
47 * SIMD scaling logic for PMADDWD (16-bit signed multipliers, 32-bit accumulators).
48 * RGB->YUV uses 15-bit scale as all coeffs are < 1.0 (max ~0.678, BT.2020 G weight),
49 * fully utilizing 16-bit coefficient precision without overflow.
50 * YUV->RGB requires 13-bit scale to accommodate chroma expansion coeffs up to ~1.881
51 * (BT.2020 Cb->B), keeping scaled coefficients within int16 range.
52 * Fused YUV->YUV (e.g., 601->2020) needs 14-bit scale; diagonal gain slightly > 1.0
53 * (~1.03 max) rules out 15-bit, but coeffs are well within 13-bit headroom.
54 * At 16-bit depth, errors partially average out during 32-bit accumulation before rounding.
55 * Avoid unifying all paths to 13-bit: RGB->YUV would degrade from ~±1 to ~±12 LSB worst-case.
56 *
57 * | Conversion | Scale | Max Coeff | LSB Error (16-bit) | Worst-Case Matrix |
58 * |-------------|--------|-----------|--------------------|---------------------|
59 * | RGB -> YUV | 15-bit | ~0.678 | ~±1 (near-exact) | BT.2020 (G weight) |
60 * | YUV -> RGB | 13-bit | ~1.881 | ~±8 (practical) | BT.2020 (Cb -> B) |
61 * | YUV -> YUV | 14-bit | ~1.030 | ~±2 (low noise) | 601 <-> 2020 fused |
62 *
63 * matrix="RGB" (IDENTITY) exception: If Kr=Kb=0 (Identity), coeffs reach 1.0. (1.0 << 15) = 32768,
64 * which overflows int16 (-32768 to 32767). Caller will check it and may diable int16 based SIMD optimization paths.
65 */
66
67 215 static void BuildMatrix_Rgb2Yuv_core(double Kr, double Kb, int int_arith_shift, bool full_scale_s, bool full_scale_d, int bits_per_pixel, ConversionMatrix& matrix)
68 {
69 215 bits_conv_constants luma, chroma;
70 215 bits_conv_constants luma_to_32bit;
71
72 // helpers for post-matrix conversion to 32-bit float (for high bit depth sources or targets, e.g. 16-bit to 32-bit float)
73
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 215 times.
215 get_bits_conv_constants(luma_to_32bit, false, full_scale_s, full_scale_d, bits_per_pixel, 32);
74 215 matrix.target_span_f_32 = luma_to_32bit.dst_span;
75 215 matrix.offset_out_f_32 = luma_to_32bit.dst_offset;
76
77 // RGB is source, YUV is destination
78 // For RGB source / Y destination (both luma-like):
79
1/2
✗ Branch 54 → 55 not taken.
✓ Branch 54 → 76 taken 215 times.
215 get_bits_conv_constants(luma, false, full_scale_s, full_scale_d, bits_per_pixel, bits_per_pixel);
80 // For UV destination (chroma behavior):
81 // Note: we only need dst_span for UV, so we use full_scale_d for both params
82
1/2
✓ Branch 106 → 107 taken 215 times.
✗ Branch 106 → 128 not taken.
215 get_bits_conv_constants(chroma, true, full_scale_d, full_scale_d, bits_per_pixel, bits_per_pixel);
83
84 215 double Srgb_f = luma.src_span; // RGB input range
85 215 double Sy_f = luma.dst_span; // Y output range
86 215 double Suv_f = chroma.dst_span; // UV output range
87 215 double Orgb_f = luma.src_offset; // RGB input offset
88 215 double Oy_f = luma.dst_offset; // Y output offset
89
90 // Derive integer versions (for <= 16 bit paths)
91 215 int Orgb = (int)Orgb_f;
92 215 int Oy = (int)Oy_f;
93
94 /*
95 Kr = {0.299, 0.2126}
96 Kb = {0.114, 0.0722}
97 Kg = 1 - Kr - Kb // {0.587, 0.7152}
98 Srgb = 255
99 Sy = {219, 255} // { 235-16, 255-0 }
100 Suv = {112, 127} // { (240-16)/2, (255-0)/2 }
101 Oy = {16, 0}
102 Ouv = 128
103 R = r/Srgb // 0..1
104 G = g/Srgb
105 B = b/Srgb
106 Y = Kr*R + Kg*G + Kb*B // 0..1
107 U = B - (Kr*R + Kg*G)/(1-Kb) //-1..1
108 V = R - (Kg*G + Kb*B)/(1-Kr)
109 y = Y*Sy + Oy // 16..235, 0..255
110 u = U*Suv + Ouv // 16..240, 1..255
111 v = V*Suv + Ouv
112 */
113
114 215 const int mulfac_int = 1 << int_arith_shift;
115 215 const double mulfac = double(mulfac_int);
116 215 const double Kg = 1. - Kr - Kb;
117
118 // Symmetric rounding for both positive and negative coefficients
119 1746 auto round_coeff = [](double v) {
120
2/2
✓ Branch 2 → 3 taken 974 times.
✓ Branch 2 → 4 taken 772 times.
1746 return (int)(v >= 0 ? (v + 0.5) : (v - 0.5));
121 };
122
123 // Calculate double-precision coefficients
124 215 double y_b_f = Sy_f * Kb / Srgb_f;
125 215 double y_g_f = Sy_f * Kg / Srgb_f;
126 215 double y_r_f = Sy_f * Kr / Srgb_f;
127
128 215 double u_b_f = Suv_f / Srgb_f;
129 215 double u_g_f = Suv_f * Kg / (Kb - 1) / Srgb_f;
130 215 double u_r_f = Suv_f * Kr / (Kb - 1) / Srgb_f;
131
132 215 double v_b_f = Suv_f * Kb / (Kr - 1) / Srgb_f;
133 215 double v_g_f = Suv_f * Kg / (Kr - 1) / Srgb_f;
134 215 double v_r_f = Suv_f / Srgb_f;
135
136 215 double offset_y_f = Oy_f;
137 215 double offset_rgb_f = -Orgb_f; // Negative because addition is used
138
139 // Store float versions
140 215 matrix.y_b_f = (float)y_b_f;
141 215 matrix.y_g_f = (float)y_g_f;
142 215 matrix.y_r_f = (float)y_r_f;
143 215 matrix.u_b_f = (float)u_b_f;
144 215 matrix.u_g_f = (float)u_g_f;
145 215 matrix.u_r_f = (float)u_r_f;
146 215 matrix.v_b_f = (float)v_b_f;
147 215 matrix.v_g_f = (float)v_g_f;
148 215 matrix.v_r_f = (float)v_r_f;
149 215 matrix.offset_y_f = (float)offset_y_f;
150 215 matrix.offset_rgb_f = (float)offset_rgb_f;
151
152
2/2
✓ Branch 158 → 159 taken 194 times.
✓ Branch 158 → 176 taken 21 times.
215 if (bits_per_pixel <= 16) {
153 // Derive integer versions from doubles with proper rounding
154 194 matrix.y_b = round_coeff(mulfac * y_b_f);
155 194 matrix.y_g = round_coeff(mulfac * y_g_f);
156 194 matrix.y_r = round_coeff(mulfac * y_r_f);
157
158 194 matrix.u_b = round_coeff(mulfac * u_b_f);
159 194 matrix.u_g = round_coeff(mulfac * u_g_f);
160 194 matrix.u_r = round_coeff(mulfac * u_r_f);
161
162 194 matrix.v_b = round_coeff(mulfac * v_b_f);
163 194 matrix.v_g = round_coeff(mulfac * v_g_f);
164 194 matrix.v_r = round_coeff(mulfac * v_r_f);
165
166 194 matrix.offset_y = Oy;
167 194 matrix.offset_rgb = -Orgb; // negative because addition is used
168
169 // Luma gain check: ensure Y captures 100% of RGB energy
170 // Only applies when destination is full-range (no offset)
171 // and the source RGB is similarly full_range
172
4/4
✓ Branch 168 → 169 taken 102 times.
✓ Branch 168 → 172 taken 92 times.
✓ Branch 169 → 170 taken 63 times.
✓ Branch 169 → 172 taken 39 times.
194 if (full_scale_s && full_scale_d) {
173 63 int y_sum = matrix.y_b + matrix.y_g + matrix.y_r;
174
2/2
✓ Branch 170 → 171 taken 9 times.
✓ Branch 170 → 172 taken 54 times.
63 if (y_sum != mulfac_int) {
175 9 matrix.y_g += (mulfac_int - y_sum);
176 }
177 }
178
179 // U neutrality check: ensure R=G=B results in U = 0 (before offset)
180 194 int u_sum = matrix.u_b + matrix.u_g + matrix.u_r;
181
2/2
✓ Branch 172 → 173 taken 9 times.
✓ Branch 172 → 174 taken 185 times.
194 if (u_sum != 0) {
182 9 matrix.u_g -= u_sum;
183 }
184
185 // V neutrality check: ensure R=G=B results in V = 0 (before offset)
186 194 int v_sum = matrix.v_b + matrix.v_g + matrix.v_r;
187
2/2
✓ Branch 174 → 175 taken 43 times.
✓ Branch 174 → 176 taken 151 times.
194 if (v_sum != 0) {
188 43 matrix.v_g -= v_sum;
189 }
190
191 }
192
193 // in: rgb. out: yuv
194 215 matrix.offset_in = matrix.offset_rgb;
195 215 matrix.offset_in_f = matrix.offset_rgb_f;
196 215 matrix.offset_out = matrix.offset_y;
197 215 matrix.offset_out_f = matrix.offset_y_f;
198 215 }
199
200 /*
201 * WARNING: int_arith_shift MUST NOT exceed 13 for YUV -> RGB expansion.
202 * Example: BT.709 Limited -> Full Range
203 * The Blue expansion factor (u_b_f) is ~2.112.
204 * - At 14-bit shift: 2.112 * 16384 = 34603 (OVERFLOWS int16_t)
205 * - At 13-bit shift: 2.112 * 8192 = 17302 (SAFE)
206 * Use 13-bit shift to ensure coefficients fit in int16 for SIMD paths.
207 * Additionally, summing up to 3 components (Y, U, V) plus rounding constant must
208 * not overflow int32 accumulators in SIMD. (another 2 bits headroom needed)
209 */
210 115 static void BuildMatrix_Yuv2Rgb_core(double Kr, double Kb, int int_arith_shift, bool full_scale_s, bool full_scale_d, int bits_per_pixel, ConversionMatrix& matrix)
211 {
212 float Sy_f, Suv_f, Oy_f, Orgb_f;
213
214 115 bits_conv_constants luma, chroma;
215 115 bits_conv_constants luma_to_32bit;
216
217 // helpers for post-matrix conversion to 32-bit float (for high bit depth sources or targets, e.g. 16-bit to 32-bit float)
218
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 24 taken 115 times.
115 get_bits_conv_constants(luma_to_32bit, false, full_scale_s, full_scale_d, bits_per_pixel, 32);
219 115 matrix.target_span_f_32 = luma_to_32bit.dst_span;
220 115 matrix.offset_out_f_32 = luma_to_32bit.dst_offset;
221
222 // We use dstBitDepth = srcBitDepth because the matrix handles the magnitude
223 // via the mulfac and Srgb calculations. We just need the standardized spans.
224
1/2
✗ Branch 54 → 55 not taken.
✓ Branch 54 → 76 taken 115 times.
115 get_bits_conv_constants(luma, false, full_scale_s, full_scale_d, bits_per_pixel, bits_per_pixel);
225
1/2
✓ Branch 106 → 107 taken 115 times.
✗ Branch 106 → 128 not taken.
115 get_bits_conv_constants(chroma, true, full_scale_s, full_scale_d, bits_per_pixel, bits_per_pixel);
226
227 115 matrix.target_span_f = luma.dst_span;
228
229 115 Sy_f = luma.src_span;
230 115 Suv_f = chroma.src_span;
231 115 Oy_f = luma.src_offset;
232 115 Orgb_f = luma.dst_offset;
233
234 /*
235 Kr = {0.299, 0.2126}
236 Kb = {0.114, 0.0722}
237 Kg = 1 - Kr - Kb // {0.587, 0.7152}
238 Srgb = 255
239 Sy = {219, 255} // { 235-16, 255-0 }
240 Suv = {112, 127} // { (240-16)/2, (255-0)/2 }
241 Oy = {16, 0}
242 Ouv = 128
243
244 Y =(y-Oy) / Sy // 0..1
245 U =(u-Ouv) / Suv //-1..1
246 V =(v-Ouv) / Suv
247
248 R = Y + V*(1-Kr) // 0..1
249 G = Y - U*(1-Kb)*Kb/Kg - V*(1-Kr)*Kr/Kg
250 B = Y + U*(1-Kb)
251
252 r = R*Srgb // 0..255 0..65535
253 g = G*Srgb
254 b = B*Srgb
255 */
256
257
258 115 const double mulfac = (double)(1 << int_arith_shift); // integer aritmetic precision scale
259
260 115 const double Kg = 1. - Kr - Kb;
261
262 // The Srgb (destination span) is also just the dst_span (RGB is luma-like)!
263 115 const float Srgb_f = (float)luma.dst_span;
264
265 // symmetric rounding for both positive and negative coefficients
266 1265 auto round_coeff = [](double v) {
267
2/2
✓ Branch 2 → 3 taken 978 times.
✓ Branch 2 → 4 taken 287 times.
1265 return (int)(v >= 0 ? (v + 0.5) : (v - 0.5));
268 };
269
270 115 double y_b_f = (Srgb_f * 1.000 / Sy_f); //Y
271 115 double u_b_f = (Srgb_f * (1 - Kb) / Suv_f); //U
272 115 double v_b_f = (Srgb_f * 0.000 / Suv_f); //V
273 115 double y_g_f = (Srgb_f * 1.000 / Sy_f);
274 115 double u_g_f = (Srgb_f * (Kb - 1) * Kb / Kg / Suv_f);
275 115 double v_g_f = (Srgb_f * (Kr - 1) * Kr / Kg / Suv_f);
276 115 double y_r_f = (Srgb_f * 1.000 / Sy_f);
277 115 double u_r_f = (Srgb_f * 0.000 / Suv_f);
278 115 double v_r_f = (Srgb_f * (1 - Kr) / Suv_f);
279 115 double offset_y_f = -Oy_f; // negative, it will be added in the conversion, so we store the negative here
280 115 double offset_rgb_f = Orgb_f;
281
282 115 matrix.y_b_f = (float)(y_b_f);
283 115 matrix.u_b_f = (float)(u_b_f);
284 115 matrix.v_b_f = (float)(v_b_f);
285 115 matrix.y_g_f = (float)(y_g_f);
286 115 matrix.u_g_f = (float)(u_g_f);
287 115 matrix.v_g_f = (float)(v_g_f);
288 115 matrix.y_r_f = (float)(y_r_f);
289 115 matrix.u_r_f = (float)(u_r_f);
290 115 matrix.v_r_f = (float)(v_r_f);
291 115 matrix.offset_y_f = (float)offset_y_f;
292 115 matrix.offset_rgb_f = (float)offset_rgb_f;
293
294 115 matrix.y_b = round_coeff(mulfac * y_b_f);
295 115 matrix.u_b = round_coeff(mulfac * u_b_f);
296 115 matrix.v_b = round_coeff(mulfac * v_b_f);
297 115 matrix.y_g = round_coeff(mulfac * y_g_f);
298 115 matrix.u_g = round_coeff(mulfac * u_g_f);
299 115 matrix.v_g = round_coeff(mulfac * v_g_f);
300 115 matrix.y_r = round_coeff(mulfac * y_r_f);
301 115 matrix.u_r = round_coeff(mulfac * u_r_f);
302 115 matrix.v_r = round_coeff(mulfac * v_r_f);
303 115 matrix.offset_y = round_coeff(offset_y_f);
304 115 matrix.offset_rgb = round_coeff(offset_rgb_f);
305
306 // in: yuv. out: rgb
307 115 matrix.offset_in = matrix.offset_y;
308 115 matrix.offset_in_f = matrix.offset_y_f;
309 115 matrix.offset_out = matrix.offset_rgb;
310 115 matrix.offset_out_f = matrix.offset_rgb_f;
311
312 115 }
313
314 351 bool GetKrKb(int matrix, double& Kr, double& Kb)
315 {
316
7/7
✓ Branch 2 → 3 taken 101 times.
✓ Branch 2 → 4 taken 139 times.
✓ Branch 2 → 5 taken 47 times.
✓ Branch 2 → 6 taken 18 times.
✓ Branch 2 → 7 taken 21 times.
✓ Branch 2 → 8 taken 9 times.
✓ Branch 2 → 9 taken 16 times.
351 switch (matrix) {
317 101 case AVS_MATRIX_BT470_BG:
318 101 case AVS_MATRIX_ST170_M: Kr = 0.299; Kb = 0.114; return true;
319 139 case AVS_MATRIX_BT709: Kr = 0.2126; Kb = 0.0722; return true;
320 47 case AVS_MATRIX_BT2020_NCL:
321 47 case AVS_MATRIX_BT2020_CL: Kr = 0.2627; Kb = 0.0593; return true;
322 18 case AVS_MATRIX_BT470_M: Kr = 0.3; Kb = 0.11; return true;
323 21 case AVS_MATRIX_ST240_M: Kr = 0.212; Kb = 0.087; return true;
324 9 case AVS_MATRIX_AVERAGE: Kr = 1.0 / 3; Kb = 1.0 / 3; return true;
325 16 default: return false;
326 }
327 }
328
329 227 bool do_BuildMatrix_Rgb2Yuv(int _Matrix, int _ColorRange, int _ColorRange_Out, int int_arith_shift, int bits_per_pixel, ConversionMatrix& matrix)
330 {
331
4/4
✓ Branch 2 → 3 taken 110 times.
✓ Branch 2 → 5 taken 117 times.
✓ Branch 3 → 4 taken 3 times.
✓ Branch 3 → 5 taken 107 times.
227 if (_ColorRange != ColorRange_Compat_e::AVS_COLORRANGE_FULL && _ColorRange != ColorRange_Compat_e::AVS_COLORRANGE_LIMITED)
332 3 return false;
333
4/4
✓ Branch 5 → 6 taken 121 times.
✓ Branch 5 → 8 taken 103 times.
✓ Branch 6 → 7 taken 3 times.
✓ Branch 6 → 8 taken 118 times.
224 if (_ColorRange_Out != ColorRange_Compat_e::AVS_COLORRANGE_FULL && _ColorRange_Out != ColorRange_Compat_e::AVS_COLORRANGE_LIMITED)
334 3 return false;
335
336 221 const bool is_full_s = _ColorRange == ColorRange_Compat_e::AVS_COLORRANGE_FULL;
337 221 const bool is_full_d = _ColorRange_Out == ColorRange_Compat_e::AVS_COLORRANGE_FULL;
338
339 // Special cases not handled by GetKrKb
340
2/2
✓ Branch 8 → 9 taken 2 times.
✓ Branch 8 → 11 taken 219 times.
221 if (_Matrix == Matrix_e::AVS_MATRIX_RGB) {
341 // copies Green to Y and sets UV to 0
342 2 BuildMatrix_Rgb2Yuv_core(0.0, 0.0, int_arith_shift, is_full_s, is_full_d, bits_per_pixel, matrix);
343 2 return true;
344 }
345
4/4
✓ Branch 11 → 12 taken 218 times.
✓ Branch 11 → 13 taken 1 time.
✓ Branch 12 → 13 taken 1 time.
✓ Branch 12 → 14 taken 217 times.
219 if (_Matrix == Matrix_e::AVS_MATRIX_ICTCP || _Matrix == Matrix_e::AVS_MATRIX_YCGCO)
346 2 return false; // not supported
347
348 double Kr, Kb;
349
2/2
✓ Branch 15 → 16 taken 4 times.
✓ Branch 15 → 17 taken 213 times.
217 if (!GetKrKb(_Matrix, Kr, Kb))
350 4 return false;
351
352 213 BuildMatrix_Rgb2Yuv_core(Kr, Kb, int_arith_shift, is_full_s, is_full_d, bits_per_pixel, matrix);
353 213 return true;
354 }
355
356 127 bool do_BuildMatrix_Yuv2Rgb(int _Matrix, int _ColorRange, int _ColorRange_Out, int int_arith_shift, int bits_per_pixel, ConversionMatrix& matrix)
357 {
358
4/4
✓ Branch 2 → 3 taken 65 times.
✓ Branch 2 → 5 taken 62 times.
✓ Branch 3 → 4 taken 3 times.
✓ Branch 3 → 5 taken 62 times.
127 if (_ColorRange != ColorRange_Compat_e::AVS_COLORRANGE_FULL && _ColorRange != ColorRange_Compat_e::AVS_COLORRANGE_LIMITED)
359 3 return false;
360
4/4
✓ Branch 5 → 6 taken 56 times.
✓ Branch 5 → 8 taken 68 times.
✓ Branch 6 → 7 taken 3 times.
✓ Branch 6 → 8 taken 53 times.
124 if (_ColorRange_Out != ColorRange_Compat_e::AVS_COLORRANGE_FULL && _ColorRange_Out != ColorRange_Compat_e::AVS_COLORRANGE_LIMITED)
361 3 return false;
362
363 121 const bool is_full_s = _ColorRange == ColorRange_Compat_e::AVS_COLORRANGE_FULL;
364 121 const bool is_full_d = _ColorRange_Out == ColorRange_Compat_e::AVS_COLORRANGE_FULL;
365
366 // Special cases not handled by GetKrKb
367
2/2
✓ Branch 8 → 9 taken 1 time.
✓ Branch 8 → 11 taken 120 times.
121 if (_Matrix == Matrix_e::AVS_MATRIX_RGB) {
368 1 BuildMatrix_Yuv2Rgb_core(0.0, 0.0, int_arith_shift, is_full_s, is_full_d, bits_per_pixel, matrix);
369 1 return true;
370 }
371
4/4
✓ Branch 11 → 12 taken 119 times.
✓ Branch 11 → 13 taken 1 time.
✓ Branch 12 → 13 taken 1 time.
✓ Branch 12 → 14 taken 118 times.
120 if (_Matrix == Matrix_e::AVS_MATRIX_ICTCP || _Matrix == Matrix_e::AVS_MATRIX_YCGCO)
372 2 return false; // not supported
373
374 double Kr, Kb;
375
2/2
✓ Branch 15 → 16 taken 4 times.
✓ Branch 15 → 17 taken 114 times.
118 if (!GetKrKb(_Matrix, Kr, Kb))
376 4 return false;
377
378 114 BuildMatrix_Yuv2Rgb_core(Kr, Kb, int_arith_shift, is_full_s, is_full_d, bits_per_pixel, matrix);
379 114 return true;
380 }
381