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/8void 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/8void 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/8void 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/4void 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/4void 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/4void 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 |