GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 69.7% 23 / 0 / 33
Functions: 50.0% 2 / 0 / 4
Branches: 100.0% 2 / 0 / 2

core/internal.h
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 #ifndef __Internal_H__
37 #define __Internal_H__
38
39 #include <avs/config.h>
40 #include <avs/minmax.h>
41 #include <stdint.h>
42 #include <string.h>
43 #include "version.h"
44 #include <memory>
45 #include <string>
46 #ifdef AVS_POSIX
47 #include <limits.h>
48 #endif
49 #include "InternalEnvironment.h"
50
51 #ifdef INTEL_INTRINSICS
52
53 // Intrinsics base header + really required extension headers
54 #if defined(_MSC_VER)
55 #include <intrin.h> // MSVC
56 #else
57 #include <x86intrin.h> // GCC/MinGW/Clang/LLVM
58 #endif
59
60 #endif
61
62 #if AVS_DEVNEXT_REV > 0
63 #define AVS_DEVELOPMENT_BUILD "\nNext Version Development Build: " AVS_PPSTR(AVS_DEV_REVDATE)
64 #define AVS_DEVELOPMENT_BUILD_GIT "\nGit: " AVS_PPSTR(AVS_DEV_GITHASH)
65 #else
66 #define AVS_DEVELOPMENT_BUILD
67 #define AVS_DEVELOPMENT_BUILD_GIT
68 #endif
69
70 // !! precision problems 2.60f < 2.60. Extra care for scripts where the version checking occurs like "IsAvs26 = VersionNumber()>=2.60"
71 #define AVS_VERSION 3.75 // Note: Used by VersionNumber() script function
72 #define AVS_COPYRIGHT "\n\xA9 2000-2015 Ben Rudiak-Gould, et al.\nhttp://avisynth.nl\n\xA9 2013-2026 AviSynth+ Project"
73 #define AVS_COPYRIGHT_UTF8 u8"\n\u00A9 2000-2015 Ben Rudiak-Gould, et al.\nhttp://avisynth.nl\n\u00A9 2013-2026 AviSynth+ Project"
74 #define BUILTIN_FUNC_PREFIX "AviSynth"
75
76 enum MANAGE_CACHE_KEYS
77 {
78 MC_RegisterCache = (int)0xFFFF0004,
79 MC_UnRegisterCache = (int)0xFFFF0006,
80 MC_NodCache = (int)0xFFFF0007,
81 MC_NodAndExpandCache = (int)0xFFFF0008,
82 MC_RegisterMTGuard,
83 MC_UnRegisterMTGuard,
84
85 MC_RegisterGraphNode = (int)0xFFFF0100,
86 MC_UnRegisterGraphNode,
87
88 MC_QueryAvs25 = (int)0xFFFF0200,
89 MC_QueryAvsPreV11C = (int)0xFFFF0201,
90 };
91
92 #include <avisynth.h>
93 #include <string>
94 #include "function.h"
95
96
97 const char *GetPixelTypeName(const int pixel_type); // in script.c
98 int GetPixelTypeFromName(const char *pixeltypename); // in script.c
99 const char* GetAVSTypeName(AVSValue value); // in script.c
100 int GetDeviceTypes(const PClip& child); // in DeviceManager.cpp
101 size_t GetFrameHead(const PVideoFrame& vf); // in DeviceManager.cpp
102 size_t GetFrameTail(const PVideoFrame& vf); // in DeviceManager.cpp
103
104 PClip Create_MessageClip(const char* message, int width, int height,
105 int pixel_type, bool shrink, int textcolor, int halocolor, int bgcolor,
106 int fps_numerator, int fps_denominator, int num_frames,
107 bool utf8,
108 IScriptEnvironment* env);
109
110
111 /* Used to clip/clamp a byte to the 0-255 range.
112 Uses a look-up table internally for performance.
113 */
114 class _PixelClip {
115 enum { buffer=320 };
116 BYTE lut[256+buffer*2];
117 public:
118 1115 _PixelClip() {
119 1115 memset(lut, 0, buffer);
120
2/2
✓ Branch 4 → 3 taken 285440 times.
✓ Branch 4 → 5 taken 1115 times.
286555 for (int i=0; i<256; ++i) lut[i+buffer] = (BYTE)i;
121 1115 memset(lut+buffer+256, 255, buffer);
122 1115 }
123 243 BYTE operator()(int i) const { return lut[i+buffer]; }
124 };
125
126 extern const _PixelClip PixelClip;
127
128
129 template<class ListNode>
130 static __inline void Relink(ListNode* newprev, ListNode* me, ListNode* newnext) {
131 if (me == newprev || me == newnext) return;
132 me->next->prev = me->prev;
133 me->prev->next = me->next;
134 me->prev = newprev;
135 me->next = newnext;
136 me->prev->next = me->next->prev = me;
137 }
138
139 class CWDChanger
140 /**
141 * Class to change the current working directory
142 **/
143 {
144 public:
145 CWDChanger(const char* new_cwd);
146 CWDChanger(const wchar_t* new_cwd);
147 ~CWDChanger(void);
148
149 #ifdef AVS_WINDOWS
150 static std::wstring GetCurrentWorkingDirectory();
151 #else
152 static std::string GetCurrentWorkingDirectory();
153 #endif
154
155 private:
156 void Init(const wchar_t* new_cwd);
157 #ifdef AVS_WINDOWS
158 std::unique_ptr<wchar_t[]> old_working_directory;
159 #else
160 char old_working_directory[PATH_MAX];
161 #endif
162 bool restore;
163 };
164
165 class DllDirChanger
166 {
167 public:
168 DllDirChanger(const char* new_cwd);
169 ~DllDirChanger(void);
170
171 private:
172 std::unique_ptr<char[]> old_directory;
173 bool restore;
174 };
175
176 class NonCachedGenericVideoFilter : public GenericVideoFilter
177 /**
178 * Class to select a range of frames from a longer clip
179 **/
180 {
181 public:
182 NonCachedGenericVideoFilter(PClip _child);
183 int __stdcall SetCacheHints(int cachehints, int frame_range);
184 };
185
186
187
188 /*** Inline helper methods ***/
189
190 // 8 bit uv to float
191 // 16-128-240 -> -112-0-112 -> 1..255: +/-127 -> +/-0.5
192 [[maybe_unused]] static AVS_FORCEINLINE float uv8tof(int color) {
193 return (color - 128) / 255.f; // consistent with convert_uintN_to_float_c
194 }
195
196 // 8 bit fullscale to float
197 [[maybe_unused]] static AVS_FORCEINLINE float c8tof(int color) {
198 return color / 255.0f;
199 }
200
201 [[maybe_unused]] static AVS_FORCEINLINE uint8_t Scaled15bitPixelClip(int i) {
202 return (uint8_t)clamp((i + 16384) >> 15, 0, 255);
203 }
204
205 [[maybe_unused]] static AVS_FORCEINLINE uint8_t ScaledPixelClip(int i) {
206 // return PixelClip((i+32768) >> 16);
207 // PF: clamp is faster than lut
208 262 return (uint8_t)clamp((i + 32768) >> 16, 0, 255);
209 }
210
211 [[maybe_unused]] static AVS_FORCEINLINE uint16_t ScaledPixelClip(int64_t i) {
212 return (uint16_t)clamp((i + 32768) >> 16, (int64_t)0, (int64_t)65535);
213 }
214
215 [[maybe_unused]] static AVS_FORCEINLINE uint16_t ScaledPixelClipEx(int64_t i, int max_value) {
216 209 return (uint16_t)clamp((int)((i + 32768) >> 16), 0, max_value);
217 }
218
219 [[maybe_unused]] static AVS_FORCEINLINE bool IsClose(int a, int b, unsigned threshold)
220 180 { return (unsigned(a-b+threshold) <= threshold*2); }
221
222 [[maybe_unused]] static AVS_FORCEINLINE bool IsCloseFloat(float a, float b, float threshold)
223 { return (a-b+threshold <= threshold*2); }
224
225 #ifdef INTEL_INTRINSICS
226 // useful SIMD helpers
227
228 // sse2 replacement of _mm_mullo_epi32 in SSE4.1
229 // use it after speed test, may have too much overhead and C is faster
230 [[maybe_unused]] static AVS_FORCEINLINE __m128i _MM_MULLO_EPI32(const __m128i &a, const __m128i &b)
231 {
232 // for SSE 4.1: return _mm_mullo_epi32(a, b);
233 556 __m128i tmp1 = _mm_mul_epu32(a,b); // mul 2,0
234 556 __m128i tmp2 = _mm_mul_epu32( _mm_srli_si128(a,4), _mm_srli_si128(b,4)); // mul 3,1
235 // shuffle results to [63..0] and pack. a2->a1, a0->a0
236 1112 return _mm_unpacklo_epi32(_mm_shuffle_epi32(tmp1, _MM_SHUFFLE (0,0,2,0)), _mm_shuffle_epi32(tmp2, _MM_SHUFFLE (0,0,2,0)));
237 }
238
239 // fake _mm_packus_epi32 (orig is SSE4.1 only)
240 [[maybe_unused]] static AVS_FORCEINLINE __m128i _MM_PACKUS_EPI32( __m128i a, __m128i b )
241 {
242 2066 const __m128i val_32 = _mm_set1_epi32(0x8000);
243 2066 const __m128i val_16 = _mm_set1_epi16((short)0x8000);
244
245 2066 a = _mm_sub_epi32(a, val_32);
246 2066 b = _mm_sub_epi32(b, val_32);
247 2066 a = _mm_packs_epi32(a, b);
248 2066 a = _mm_add_epi16(a, val_16);
249 2066 return a;
250 }
251
252 // fake _mm_packus_epi32 (orig is SSE4.1 only)
253 // only for packing 00000000..0000FFFF range integers, does not clamp properly above that, e.g. 00010001
254 [[maybe_unused]] static AVS_FORCEINLINE __m128i _MM_PACKUS_EPI32_SRC_TRUEWORD(__m128i a, __m128i b)
255 {
256 a = _mm_slli_epi32 (a, 16);
257 a = _mm_srai_epi32 (a, 16);
258 b = _mm_slli_epi32 (b, 16);
259 b = _mm_srai_epi32 (b, 16);
260 a = _mm_packs_epi32 (a, b);
261 return a;
262 }
263
264 [[maybe_unused]] static AVS_FORCEINLINE __m128i _MM_CMPLE_EPU16(__m128i x, __m128i y)
265 {
266 // Returns 0xFFFF where x <= y:
267 1680 return _mm_cmpeq_epi16(_mm_subs_epu16(x, y), _mm_setzero_si128());
268 }
269
270 [[maybe_unused]] static AVS_FORCEINLINE __m128i _MM_BLENDV_SI128(__m128i x, __m128i y, __m128i mask)
271 {
272 // Replace bit in x with bit in y when matching bit in mask is set:
273 1680 return _mm_or_si128(_mm_andnot_si128(mask, x), _mm_and_si128(mask, y));
274 }
275
276 // SSE4.1 simulation for SSE2, same as above, intrisic name is _mm_blendv_epi8
277 [[maybe_unused]] static AVS_FORCEINLINE __m128i _MM_BLENDV_EPI8(__m128i const& a, __m128i const& b, __m128i const& selector) {
278 return _mm_or_si128(_mm_andnot_si128(selector, a), _mm_and_si128(selector, b));
279 }
280
281 // sse2 simulation of SSE4's _mm_min_epu16
282 [[maybe_unused]] static AVS_FORCEINLINE __m128i _MM_MIN_EPU16(__m128i x, __m128i y)
283 {
284 // Returns x where x <= y, else y:
285 1080 return _MM_BLENDV_SI128(y, x, _MM_CMPLE_EPU16(x, y));
286 }
287
288 // sse2 simulation of SSE4's _mm_max_epu16
289 [[maybe_unused]] static AVS_FORCEINLINE __m128i _MM_MAX_EPU16(__m128i x, __m128i y)
290 {
291 // Returns x where x >= y, else y:
292 40 return _MM_BLENDV_SI128(x, y, _MM_CMPLE_EPU16(x, y));
293 }
294 #endif
295
296 #ifndef MAKEFOURCC
297 #define MAKEFOURCC(ch0, ch1, ch2, ch3) \
298 ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
299 ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))
300 #endif
301
302 class GlobalVarFrame
303 {
304 InternalEnvironment* env;
305 public:
306 GlobalVarFrame(InternalEnvironment* env) : env(env) {
307 env->PushContextGlobal();
308 }
309 ~GlobalVarFrame() {
310 env->PopContextGlobal();
311 }
312 };
313
314 #endif // __Internal_H__
315