GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 42.9% 100 / 0 / 233
Functions: 40.0% 4 / 0 / 10
Branches: 37.8% 93 / 0 / 246

filters/greyscale.cpp
Line Branch Exec Source
1 // Avisynth v2.5. Copyright 2002 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 "greyscale.h"
37 #ifdef INTEL_INTRINSICS
38 #include "intel/greyscale_sse.h"
39 #endif
40 #include "../core/internal.h"
41 #include <avs/alignment.h>
42 #include <avs/minmax.h>
43
44 #ifdef AVS_WINDOWS
45 #include <avs/win.h>
46 #else
47 #include <avs/posix.h>
48 #endif
49
50 #include <stdint.h>
51 #include "../convert/convert_planar.h"
52 #include "../convert/convert.h"
53 #include "../convert/convert_helper.h"
54
55
56 /*************************************
57 ******* Convert to Greyscale ******
58 ************************************/
59
60 extern const AVSFunction Greyscale_filters[] = {
61 { "Greyscale", BUILTIN_FUNC_PREFIX, "c[matrix]s", Greyscale::Create }, // matrix can be "rec601", "rec709" or "Average" or "rec2020"
62 { "Grayscale", BUILTIN_FUNC_PREFIX, "c[matrix]s", Greyscale::Create },
63 { 0 }
64 };
65
66 8 Greyscale::Greyscale(PClip _child, const char* matrix_name, IScriptEnvironment* env)
67
2/4
✓ Branch 2 → 3 taken 8 times.
✗ Branch 2 → 36 not taken.
✓ Branch 3 → 4 taken 8 times.
✗ Branch 3 → 34 not taken.
8 : GenericVideoFilter(_child), coeff_int16_overflow(false)
68 {
69
2/8
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 9 taken 8 times.
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 40 not taken.
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 9 not taken.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 8 times.
8 if (matrix_name && !vi.IsRGB())
70 env->ThrowError("GreyScale: invalid \"matrix\" parameter (RGB data only)");
71
72 // originally there was no PC range here
73
1/2
✓ Branch 12 → 13 taken 8 times.
✗ Branch 12 → 40 not taken.
8 pixelsize = vi.ComponentSize();
74
1/2
✓ Branch 13 → 14 taken 8 times.
✗ Branch 13 → 40 not taken.
8 bits_per_pixel = vi.BitsPerComponent();
75
76 // In all cases, Luma range is not changed(0-255 in -> 0-255 out; 16-235 in -> 16-235 out)
77
78
3/4
✓ Branch 14 → 15 taken 8 times.
✗ Branch 14 → 40 not taken.
✓ Branch 15 → 16 taken 2 times.
✓ Branch 15 → 33 taken 6 times.
8 if (vi.IsRGB()) {
79
1/2
✓ Branch 17 → 18 taken 2 times.
✗ Branch 17 → 39 not taken.
2 auto frame0 = _child->GetFrame(0, env);
80
1/2
✓ Branch 18 → 19 taken 2 times.
✗ Branch 18 → 37 not taken.
2 const AVSMap* props = env->getFramePropsRO(frame0);
81 // input _ColorRange frame property can appear for RGB source (studio range limited rgb)
82
1/2
✓ Branch 19 → 20 taken 2 times.
✗ Branch 19 → 37 not taken.
2 matrix_parse_merge_with_props(true /*in rgb*/, true /*out rgb, same range*/, matrix_name, props, theMatrix, theColorRange, theOutColorRange, env);
83 /*if (theColorRange == ColorRange_Compat_e::AVS_COLORRANGE_FULL && theMatrix != Matrix_e::AVS_MATRIX_AVERAGE)
84 env->ThrowError("GreyScale: only limited range matrix definition or \"Average\" is allowed.");
85 */
86
87 2 const int shift = 15; // internally 15 bits precision, still no overflow in calculations
88 // From the matrix, only Y (luma) coefficients are used.
89 // Upscaled coeffs will have to fit into the signed 16 bit range (SSE2 SIMD code MADD!), so all Y coeffs must be < 1.0.
90 // Even 1.0 will overflow, when upscaled by 2^15.
91
92 // input _ColorRange frame property can appear for RGB source (studio range limited rgb)
93
2/4
✓ Branch 20 → 21 taken 2 times.
✗ Branch 20 → 37 not taken.
✗ Branch 21 → 22 not taken.
✓ Branch 21 → 23 taken 2 times.
2 if (!do_BuildMatrix_Rgb2Yuv(theMatrix, theColorRange, theOutColorRange, shift, bits_per_pixel, /*ref*/greyMatrix))
94 env->ThrowError("GreyScale: Unknown matrix.");
95
1/2
✓ Branch 23 → 24 taken 2 times.
✗ Branch 23 → 31 not taken.
2 if (bits_per_pixel <= 16) {
96 // all y coeffs must be [-1.0;1.0) to fit into signed 16 bit when upscaled by 2^15,
97 // in order to use int16 arithmetic for the conversion.
98 // The only suspicious case is AVS_MATRIX_RGB which returns G for Y in greyscale (RGB is otherwise the IDENTITY matrix)
99 // Greyscale SSE2 SIMD must work with valid coefficients
100 2 const int max_coeff = (1 << shift) - 1; // 32767 in 15 bit fixed point, maximum positive
101 2 const int min_coeff = -(1 << shift); // -32768
102
2/4
✓ Branch 24 → 25 taken 2 times.
✗ Branch 24 → 30 not taken.
✓ Branch 25 → 26 taken 2 times.
✗ Branch 25 → 30 not taken.
2 if (greyMatrix.y_r > max_coeff || greyMatrix.y_r < min_coeff ||
103
2/4
✓ Branch 26 → 27 taken 2 times.
✗ Branch 26 → 30 not taken.
✓ Branch 27 → 28 taken 2 times.
✗ Branch 27 → 30 not taken.
2 greyMatrix.y_g > max_coeff || greyMatrix.y_g < min_coeff ||
104
2/4
✓ Branch 28 → 29 taken 2 times.
✗ Branch 28 → 30 not taken.
✗ Branch 29 → 30 not taken.
✓ Branch 29 → 31 taken 2 times.
2 greyMatrix.y_b > max_coeff || greyMatrix.y_b < min_coeff)
105 {
106 coeff_int16_overflow = true;
107 // env->ThrowError("GreyScale: one ore more matrix coefficient is out of valid range for GreyScale filter.");
108 }
109 }
110
111 2 }
112 // greyscale does not change color space, rgb remains rgb
113 // Leave matrix and range frame properties as is.
114 8 }
115
116 template<typename pixel_t, int pixel_step>
117 1 static void greyscale_packed_rgb_c(BYTE *srcp8, int src_pitch, int width, int height, ConversionMatrix& m) {
118 1 const bool has_offset_rgb = 0 != m.offset_rgb;
119
120 1 pixel_t *srcp = reinterpret_cast<pixel_t *>(srcp8);
121 1 src_pitch /= sizeof(pixel_t);
122
123 // .15 bit frac integer arithmetic
124 1 const int rounder_and_luma_offset = (1 << 14) + (m.offset_y << 15);
125 // greyscale RGB is putting pack the calculated pixels to rgb
126 // Limited range input remains limited range output (-offset_rgb is the same as offset_y)
127
128
2/8
void greyscale_packed_rgb_c<unsigned char, 3>(unsigned char*, int, int, int, ConversionMatrix&):
✓ Branch 9 → 3 taken 2 times.
✓ Branch 9 → 10 taken 1 time.
void greyscale_packed_rgb_c<unsigned char, 4>(unsigned char*, int, int, int, ConversionMatrix&):
✗ Branch 9 → 3 not taken.
✗ Branch 9 → 10 not taken.
void greyscale_packed_rgb_c<unsigned short, 3>(unsigned char*, int, int, int, ConversionMatrix&):
✗ Branch 9 → 3 not taken.
✗ Branch 9 → 10 not taken.
void greyscale_packed_rgb_c<unsigned short, 4>(unsigned char*, int, int, int, ConversionMatrix&):
✗ Branch 9 → 3 not taken.
✗ Branch 9 → 10 not taken.
3 for (int y = 0; y < height; ++y) {
129
2/8
void greyscale_packed_rgb_c<unsigned char, 3>(unsigned char*, int, int, int, ConversionMatrix&):
✓ Branch 7 → 4 taken 10 times.
✓ Branch 7 → 8 taken 2 times.
void greyscale_packed_rgb_c<unsigned char, 4>(unsigned char*, int, int, int, ConversionMatrix&):
✗ Branch 7 → 4 not taken.
✗ Branch 7 → 8 not taken.
void greyscale_packed_rgb_c<unsigned short, 3>(unsigned char*, int, int, int, ConversionMatrix&):
✗ Branch 7 → 4 not taken.
✗ Branch 7 → 8 not taken.
void greyscale_packed_rgb_c<unsigned short, 4>(unsigned char*, int, int, int, ConversionMatrix&):
✗ Branch 7 → 4 not taken.
✗ Branch 7 → 8 not taken.
12 for (int x = 0; x < width; ++x) {
130 10 int b = srcp[x * pixel_step + 0];
131 10 int g = srcp[x * pixel_step + 1];
132 10 int r = srcp[x * pixel_step + 2];
133
1/8
void greyscale_packed_rgb_c<unsigned char, 3>(unsigned char*, int, int, int, ConversionMatrix&):
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 10 times.
void greyscale_packed_rgb_c<unsigned char, 4>(unsigned char*, int, int, int, ConversionMatrix&):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 6 not taken.
void greyscale_packed_rgb_c<unsigned short, 3>(unsigned char*, int, int, int, ConversionMatrix&):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 6 not taken.
void greyscale_packed_rgb_c<unsigned short, 4>(unsigned char*, int, int, int, ConversionMatrix&):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 6 not taken.
10 if (has_offset_rgb) {
134 b = b + m.offset_rgb;
135 g = g + m.offset_rgb;
136 r = r + m.offset_rgb;
137 }
138 10 srcp[x * pixel_step + 0] = srcp[x * pixel_step + 1] = srcp[x * pixel_step + 2] =
139 10 (m.y_b * b + m.y_g * g + m.y_r * r + rounder_and_luma_offset) >> 15;
140 }
141 2 srcp += src_pitch;
142 }
143 1 }
144
145 template<typename pixel_t>
146 1 static void greyscale_planar_rgb_c(BYTE *srcp_r8, BYTE *srcp_g8, BYTE *srcp_b8, int src_pitch, int width, int height, ConversionMatrix& m) {
147 1 const bool has_offset_rgb = 0 != m.offset_rgb;
148
149 1 pixel_t *srcp_r = reinterpret_cast<pixel_t *>(srcp_r8);
150 1 pixel_t *srcp_g = reinterpret_cast<pixel_t *>(srcp_g8);
151 1 pixel_t *srcp_b = reinterpret_cast<pixel_t *>(srcp_b8);
152 1 src_pitch /= sizeof(pixel_t);
153
154 // .15 bit frac integer arithmetic
155 1 const int rounder_and_luma_offset = (1 << 14) + (m.offset_y << 15);
156 // greyscale RGB is putting pack the calculated pixels to rgb
157 // Limited range input remains limited range output (-offset_rgb is the same as offset_y)
158
159
2/4
void greyscale_planar_rgb_c<unsigned char>(unsigned char*, unsigned char*, unsigned char*, int, int, int, ConversionMatrix&):
✗ Branch 9 → 3 not taken.
✗ Branch 9 → 10 not taken.
void greyscale_planar_rgb_c<unsigned short>(unsigned char*, unsigned char*, unsigned char*, int, int, int, ConversionMatrix&):
✓ Branch 9 → 3 taken 3 times.
✓ Branch 9 → 10 taken 1 time.
4 for (int y = 0; y < height; ++y) {
160
2/4
void greyscale_planar_rgb_c<unsigned char>(unsigned char*, unsigned char*, unsigned char*, int, int, int, ConversionMatrix&):
✗ Branch 7 → 4 not taken.
✗ Branch 7 → 8 not taken.
void greyscale_planar_rgb_c<unsigned short>(unsigned char*, unsigned char*, unsigned char*, int, int, int, ConversionMatrix&):
✓ Branch 7 → 4 taken 15 times.
✓ Branch 7 → 8 taken 3 times.
18 for (int x = 0; x < width; ++x) {
161 15 int b = srcp_b[x];
162 15 int g = srcp_g[x];
163 15 int r = srcp_r[x];
164
1/4
void greyscale_planar_rgb_c<unsigned char>(unsigned char*, unsigned char*, unsigned char*, int, int, int, ConversionMatrix&):
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 6 not taken.
void greyscale_planar_rgb_c<unsigned short>(unsigned char*, unsigned char*, unsigned char*, int, int, int, ConversionMatrix&):
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 15 times.
15 if (has_offset_rgb) {
165 b = b + m.offset_rgb;
166 g = g + m.offset_rgb;
167 r = r + m.offset_rgb;
168 }
169
170 15 srcp_b[x] = srcp_g[x] = srcp_r[x] =
171 15 (m.y_b * b + m.y_g * g + m.y_r * r + rounder_and_luma_offset) >> 15;
172 }
173 3 srcp_r += src_pitch;
174 3 srcp_g += src_pitch;
175 3 srcp_b += src_pitch;
176 }
177 1 }
178
179 static void greyscale_planar_rgb_float_c(BYTE *srcp_r8, BYTE *srcp_g8, BYTE *srcp_b8, int src_pitch, int width, int height, ConversionMatrix& m) {
180 const bool has_offset_rgb = 0 != m.offset_rgb_f;
181
182 float *srcp_r = reinterpret_cast<float *>(srcp_r8);
183 float *srcp_g = reinterpret_cast<float *>(srcp_g8);
184 float *srcp_b = reinterpret_cast<float *>(srcp_b8);
185 src_pitch /= sizeof(float);
186
187 const float luma_offset = m.offset_y_f;
188 // greyscale RGB is putting pack the calculated pixels to rgb
189 // Limited range input remains limited range output (-offset_rgb is the same as offset_y)
190
191
192 for (int y = 0; y < height; ++y) {
193 for (int x = 0; x < width; ++x) {
194 float b = srcp_b[x];
195 float g = srcp_g[x];
196 float r = srcp_r[x];
197 if (has_offset_rgb) {
198 b = b + m.offset_rgb_f;
199 g = g + m.offset_rgb_f;
200 r = r + m.offset_rgb_f;
201 }
202 srcp_b[x] = srcp_g[x] = srcp_r[x] =
203 m.y_b_f * b + m.y_g_f * g + m.y_r_f * r + luma_offset;
204 }
205 srcp_r += src_pitch;
206 srcp_g += src_pitch;
207 srcp_b += src_pitch;
208 }
209 }
210
211
212 8 PVideoFrame Greyscale::GetFrame(int n, IScriptEnvironment* env)
213 {
214 8 PVideoFrame frame = child->GetFrame(n, env);
215
2/4
✓ Branch 4 → 5 taken 8 times.
✗ Branch 4 → 108 not taken.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 8 times.
8 if (vi.NumComponents() == 1)
216 return frame;
217
218
1/2
✓ Branch 7 → 8 taken 8 times.
✗ Branch 7 → 108 not taken.
8 env->MakeWritable(&frame);
219
1/2
✓ Branch 9 → 10 taken 8 times.
✗ Branch 9 → 108 not taken.
8 BYTE* srcp = frame->GetWritePtr();
220
1/2
✓ Branch 11 → 12 taken 8 times.
✗ Branch 11 → 108 not taken.
8 int pitch = frame->GetPitch();
221 8 int height = vi.height;
222 8 int width = vi.width;
223
224 // greyscale does not change color space, rgb remains rgb
225 // Leave matrix and range frame properties as is.
226
227
11/14
✓ Branch 12 → 13 taken 8 times.
✗ Branch 12 → 108 not taken.
✓ Branch 13 → 14 taken 6 times.
✓ Branch 13 → 19 taken 2 times.
✓ Branch 14 → 15 taken 6 times.
✗ Branch 14 → 108 not taken.
✓ Branch 15 → 16 taken 2 times.
✓ Branch 15 → 18 taken 4 times.
✓ Branch 16 → 17 taken 2 times.
✗ Branch 16 → 108 not taken.
✓ Branch 17 → 18 taken 1 time.
✓ Branch 17 → 19 taken 1 time.
✓ Branch 20 → 21 taken 5 times.
✓ Branch 20 → 41 taken 3 times.
8 if (vi.IsPlanar() && (vi.IsYUV() || vi.IsYUVA())) {
228 // planar YUV, set UV plane to neutral
229
1/2
✓ Branch 22 → 23 taken 5 times.
✗ Branch 22 → 108 not taken.
5 BYTE* dstp_u = frame->GetWritePtr(PLANAR_U);
230
1/2
✓ Branch 24 → 25 taken 5 times.
✗ Branch 24 → 108 not taken.
5 BYTE* dstp_v = frame->GetWritePtr(PLANAR_V);
231
1/2
✓ Branch 26 → 27 taken 5 times.
✗ Branch 26 → 108 not taken.
5 const int height = frame->GetHeight(PLANAR_U);
232
1/2
✓ Branch 28 → 29 taken 5 times.
✗ Branch 28 → 108 not taken.
5 const int rowsizeUV = frame->GetRowSize(PLANAR_U);
233
1/2
✓ Branch 30 → 31 taken 5 times.
✗ Branch 30 → 108 not taken.
5 const int dst_pitch = frame->GetPitch(PLANAR_U);
234
4/6
✓ Branch 31 → 32 taken 5 times.
✗ Branch 31 → 108 not taken.
✓ Branch 32 → 33 taken 3 times.
✓ Branch 32 → 35 taken 1 time.
✓ Branch 32 → 38 taken 1 time.
✗ Branch 32 → 40 not taken.
5 switch (vi.ComponentSize())
235 {
236 3 case 1:
237
1/2
✓ Branch 33 → 34 taken 3 times.
✗ Branch 33 → 108 not taken.
3 fill_chroma<BYTE>(dstp_u, dstp_v, height, rowsizeUV, dst_pitch, 0x80);
238 3 break;
239 1 case 2:
240
2/4
✓ Branch 35 → 36 taken 1 time.
✗ Branch 35 → 108 not taken.
✓ Branch 36 → 37 taken 1 time.
✗ Branch 36 → 108 not taken.
1 fill_chroma<uint16_t>(dstp_u, dstp_v, height, rowsizeUV, dst_pitch, 1 << (vi.BitsPerComponent() - 1));
241 1 break;
242 1 case 4:
243 1 const float shift = 0.0f;
244
1/2
✓ Branch 38 → 39 taken 1 time.
✗ Branch 38 → 108 not taken.
1 fill_chroma<float>(dstp_u, dstp_v, height, rowsizeUV, dst_pitch, shift);
245 1 break;
246 }
247 5 return frame;
248 }
249
250
3/4
✓ Branch 41 → 42 taken 3 times.
✗ Branch 41 → 108 not taken.
✓ Branch 42 → 43 taken 1 time.
✓ Branch 42 → 57 taken 2 times.
3 if (vi.IsYUY2()) {
251 #ifdef INTEL_INTRINSICS
252
4/8
✓ Branch 43 → 44 taken 1 time.
✗ Branch 43 → 108 not taken.
✓ Branch 44 → 45 taken 1 time.
✗ Branch 44 → 47 not taken.
✓ Branch 45 → 46 taken 1 time.
✗ Branch 45 → 47 not taken.
✓ Branch 48 → 49 taken 1 time.
✗ Branch 48 → 50 not taken.
1 if ((env->GetCPUFlags() & CPUF_SSE2) && width > 4) {
253
1/2
✓ Branch 49 → 56 taken 1 time.
✗ Branch 49 → 108 not taken.
1 greyscale_yuy2_sse2(srcp, width, height, pitch);
254 } else
255 #ifdef X86_32
256 if ((env->GetCPUFlags() & CPUF_MMX) && width > 2) {
257 greyscale_yuy2_mmx(srcp, width, height, pitch);
258 } else
259 #endif
260 #endif
261 {
262 for (int y = 0; y<height; ++y)
263 {
264 for (int x = 0; x<width; x++)
265 srcp[x*2+1] = 128;
266 srcp += pitch;
267 }
268 }
269
270 1 return frame;
271 }
272 #ifdef INTEL_INTRINSICS
273
2/4
✓ Branch 57 → 58 taken 2 times.
✗ Branch 57 → 108 not taken.
✗ Branch 58 → 59 not taken.
✓ Branch 58 → 63 taken 2 times.
2 if(vi.IsRGB64()) {
274 if (env->GetCPUFlags() & CPUF_SSE4_1) {
275 greyscale_rgb64_sse41(srcp, width, height, pitch, greyMatrix);
276 return frame;
277 }
278 }
279
280
2/4
✓ Branch 63 → 64 taken 2 times.
✗ Branch 63 → 108 not taken.
✗ Branch 64 → 65 not taken.
✓ Branch 64 → 70 taken 2 times.
2 if (vi.IsRGB32()) {
281 if (env->GetCPUFlags() & CPUF_SSE2) {
282 if (!coeff_int16_overflow) {
283 greyscale_rgb32_sse2(srcp, width, height, pitch, greyMatrix);
284 return frame;
285 }
286 }
287 #ifdef X86_32
288 else if (env->GetCPUFlags() & CPUF_MMX) {
289 if (!coeff_int16_overflow) {
290 greyscale_rgb32_mmx(srcp, width, height, pitch, greyMatrix);
291 return frame;
292 }
293 }
294 #endif
295 }
296 #endif
297
298
2/4
✓ Branch 70 → 71 taken 2 times.
✗ Branch 70 → 108 not taken.
✓ Branch 71 → 72 taken 2 times.
✗ Branch 71 → 106 not taken.
2 if (vi.IsRGB())
299 { // RGB C.
300
7/10
✓ Branch 72 → 73 taken 2 times.
✗ Branch 72 → 108 not taken.
✓ Branch 73 → 74 taken 1 time.
✓ Branch 73 → 76 taken 1 time.
✓ Branch 74 → 75 taken 1 time.
✗ Branch 74 → 108 not taken.
✗ Branch 75 → 76 not taken.
✓ Branch 75 → 77 taken 1 time.
✓ Branch 78 → 79 taken 1 time.
✓ Branch 78 → 93 taken 1 time.
2 if (vi.IsPlanarRGB() || vi.IsPlanarRGBA())
301 {
302
1/2
✓ Branch 80 → 81 taken 1 time.
✗ Branch 80 → 108 not taken.
1 BYTE* srcp_g = frame->GetWritePtr(PLANAR_G);
303
1/2
✓ Branch 82 → 83 taken 1 time.
✗ Branch 82 → 108 not taken.
1 BYTE* srcp_b = frame->GetWritePtr(PLANAR_B);
304
1/2
✓ Branch 84 → 85 taken 1 time.
✗ Branch 84 → 108 not taken.
1 BYTE* srcp_r = frame->GetWritePtr(PLANAR_R);
305
306
1/2
✓ Branch 86 → 87 taken 1 time.
✗ Branch 86 → 108 not taken.
1 const int src_pitch = frame->GetPitch(); // same for all planes
307
308
1/2
✗ Branch 87 → 88 not taken.
✓ Branch 87 → 89 taken 1 time.
1 if (pixelsize == 1)
309 greyscale_planar_rgb_c<uint8_t>(srcp_r, srcp_g, srcp_b, src_pitch, vi.width, vi.height, greyMatrix);
310
1/2
✓ Branch 89 → 90 taken 1 time.
✗ Branch 89 → 91 not taken.
1 else if (pixelsize == 2)
311 1 greyscale_planar_rgb_c<uint16_t>(srcp_r, srcp_g, srcp_b, src_pitch, vi.width, vi.height, greyMatrix);
312 else
313 greyscale_planar_rgb_float_c(srcp_r, srcp_g, srcp_b, src_pitch, vi.width, vi.height, greyMatrix);
314
315 1 return frame;
316 }
317 // packed RGB
318
319
4/8
✓ Branch 93 → 94 taken 1 time.
✗ Branch 93 → 108 not taken.
✓ Branch 94 → 95 taken 1 time.
✗ Branch 94 → 97 not taken.
✓ Branch 95 → 96 taken 1 time.
✗ Branch 95 → 108 not taken.
✗ Branch 96 → 97 not taken.
✓ Branch 96 → 98 taken 1 time.
1 const int rgb_inc = vi.IsRGB32() || vi.IsRGB64() ? 4 : 3;
320
321
1/2
✓ Branch 99 → 100 taken 1 time.
✗ Branch 99 → 103 not taken.
1 if (pixelsize == 1) { // rgb24/32
322
1/2
✓ Branch 100 → 101 taken 1 time.
✗ Branch 100 → 102 not taken.
1 if (rgb_inc == 3)
323 1 greyscale_packed_rgb_c<uint8_t, 3>(srcp, pitch, vi.width, vi.height, greyMatrix);
324 else
325 greyscale_packed_rgb_c<uint8_t, 4>(srcp, pitch, vi.width, vi.height, greyMatrix);
326 }
327 else { // rgb48/64
328 if (rgb_inc == 3)
329 greyscale_packed_rgb_c<uint16_t, 3>(srcp, pitch, vi.width, vi.height, greyMatrix);
330 else
331 greyscale_packed_rgb_c<uint16_t, 4>(srcp, pitch, vi.width, vi.height, greyMatrix);
332 }
333
334 }
335 1 return frame;
336 }
337
338
339 AVSValue __cdecl Greyscale::Create(AVSValue args, void*, IScriptEnvironment* env)
340 {
341 PClip clip = args[0].AsClip();
342 const VideoInfo& vi = clip->GetVideoInfo();
343
344 if (vi.NumComponents() == 1)
345 return clip;
346
347 return new Greyscale(clip, args[1].AsString(0), env);
348 }
349