GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 30 / 0 / 30
Functions: 100.0% 3 / 0 / 3
Branches: 100.0% 6 / 0 / 6

filters/intel/limiter_sse.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 "limiter_sse.h"
37
38 // Intrinsics base header + really required extension headers
39 #if defined(_MSC_VER)
40 #include <intrin.h> // MSVC
41 #else
42 #include <x86intrin.h> // GCC/MinGW/Clang/LLVM
43 #endif
44 #include <smmintrin.h> // SSE4.1
45
46 #include "../core/internal.h"
47
48 //min and max values are 16-bit integers either max_plane|max_plane for planar or max_luma|max_chroma for yuy2
49 7 void limit_plane_sse2(BYTE *ptr, int min_value, int max_value, int pitch, int width, int height) {
50 7 __m128i min_vector = _mm_set1_epi16(min_value);
51 7 __m128i max_vector = _mm_set1_epi16(max_value);
52 7 BYTE* end_point = ptr + pitch * height;
53
54
2/2
✓ Branch 19 → 11 taken 87 times.
✓ Branch 19 → 20 taken 7 times.
94 while(ptr < end_point) {
55 87 __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(ptr));
56 87 src = _mm_max_epu8(src, min_vector);
57 87 src = _mm_min_epu8(src, max_vector);
58 _mm_store_si128(reinterpret_cast<__m128i*>(ptr), src);
59 87 ptr += 16;
60 }
61 7 }
62
63 //min and max values are 16-bit unsigned integers
64 1 void limit_plane_uint16_sse2(BYTE *ptr, unsigned int min_value, unsigned int max_value, int pitch, int height) {
65 1 __m128i min_vector = _mm_set1_epi16(min_value);
66 1 __m128i max_vector = _mm_set1_epi16(max_value);
67 1 BYTE* end_point = ptr + pitch * height;
68
69
2/2
✓ Branch 51 → 11 taken 20 times.
✓ Branch 51 → 52 taken 1 time.
21 while(ptr < end_point) {
70 20 __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(ptr));
71 20 src = _MM_MAX_EPU16(src, min_vector);
72 20 src = _MM_MIN_EPU16(src, max_vector);
73 _mm_store_si128(reinterpret_cast<__m128i*>(ptr), src);
74 20 ptr += 16;
75 }
76 1 }
77
78 //min and max values are 16-bit unsigned integers
79 #if defined(GCC) || defined(CLANG)
80 __attribute__((__target__("sse4.1")))
81 #endif
82 7 void limit_plane_uint16_sse4(BYTE *ptr, unsigned int min_value, unsigned int max_value, int pitch, int height)
83 {
84 7 __m128i min_vector = _mm_set1_epi16(min_value);
85 7 __m128i max_vector = _mm_set1_epi16(max_value);
86 7 BYTE* end_point = ptr + pitch * height;
87
88
2/2
✓ Branch 19 → 11 taken 104 times.
✓ Branch 19 → 20 taken 7 times.
111 while(ptr < end_point) {
89 104 __m128i src = _mm_load_si128(reinterpret_cast<const __m128i*>(ptr));
90 104 src = _mm_max_epu16(src, min_vector);
91 104 src = _mm_min_epu16(src, max_vector);
92 _mm_store_si128(reinterpret_cast<__m128i*>(ptr), src);
93 104 ptr += 16;
94 }
95 7 }
96
97
98 #ifdef X86_32
99
100 //min and max values are 16-bit integers either max_plane|max_plane for planar or max_luma|max_chroma for yuy2
101 void limit_plane_isse(BYTE *ptr, int min_value, int max_value, int pitch, int width, int height) {
102 __m64 min_vector = _mm_set1_pi16(min_value);
103 __m64 max_vector = _mm_set1_pi16(max_value);
104 int mod8_width = width / 8 * 8;
105
106 for(int y = 0; y < height; y++) {
107 for(int x = 0; x < mod8_width; x+=8) {
108 __m64 src = *reinterpret_cast<__m64*>(ptr+x);
109 src = _mm_max_pu8(src, min_vector);
110 src = _mm_min_pu8(src, max_vector);
111 *reinterpret_cast<__m64*>(ptr+x) = src;
112 }
113
114 if (mod8_width != width) {
115 int x = width - 8;
116 __m64 src = *reinterpret_cast<__m64*>(ptr+x);
117 src = _mm_max_pu8(src, min_vector);
118 src = _mm_min_pu8(src, max_vector);
119 *reinterpret_cast<__m64*>(ptr+x) = src;
120 }
121
122 ptr += pitch;
123 }
124 _mm_empty();
125 }
126
127 #endif
128
129
130
131