FFmpeg
mathops.h
Go to the documentation of this file.
1 /*
2  * simple math operations
3  * Copyright (c) 2001, 2002 Fabrice Bellard
4  * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> et al
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 #ifndef AVCODEC_MATHOPS_H
23 #define AVCODEC_MATHOPS_H
24 
25 #include <stdint.h>
26 
28 #include "libavutil/common.h"
29 #include "config.h"
30 
31 #define MAX_NEG_CROP 1024
32 
33 extern const uint32_t ff_inverse[257];
34 extern const uint8_t ff_log2_run[41];
35 EXTERN const uint32_t ff_square_tab[512];
36 extern const uint8_t ff_sqrt_tab[256];
37 EXTERN const uint8_t ff_crop_tab[256 + 2 * MAX_NEG_CROP];
38 extern const uint8_t ff_zigzag_direct[64];
39 extern const uint8_t ff_zigzag_scan[16+1];
40 
41 #if ARCH_ARM
42 # include "arm/mathops.h"
43 #elif ARCH_MIPS
44 # include "mips/mathops.h"
45 #elif ARCH_PPC
46 # include "ppc/mathops.h"
47 #elif ARCH_RISCV
48 # include "riscv/mathops.h"
49 #elif ARCH_X86
50 # include "x86/mathops.h"
51 #endif
52 
53 /* generic implementation */
54 
55 #ifndef MUL64
56 # define MUL64(a,b) ((int64_t)(a) * (int64_t)(b))
57 #endif
58 
59 #ifndef MULL
60 # define MULL(a,b,s) (MUL64(a, b) >> (s))
61 #endif
62 
63 #ifndef MULH
64 static av_always_inline int MULH(int a, int b){
65  return MUL64(a, b) >> 32;
66 }
67 #endif
68 
69 #ifndef UMULH
70 static av_always_inline unsigned UMULH(unsigned a, unsigned b){
71  return ((uint64_t)(a) * (uint64_t)(b))>>32;
72 }
73 #endif
74 
75 #ifndef MAC64
76 # define MAC64(d, a, b) ((d) += MUL64(a, b))
77 #endif
78 
79 #ifndef MLS64
80 # define MLS64(d, a, b) ((d) -= MUL64(a, b))
81 #endif
82 
83 /* signed 16x16 -> 32 multiply add accumulate */
84 #ifndef MAC16
85 # define MAC16(rt, ra, rb) rt += (ra) * (rb)
86 #endif
87 
88 /* signed 16x16 -> 32 multiply */
89 #ifndef MUL16
90 # define MUL16(ra, rb) ((ra) * (rb))
91 #endif
92 
93 #ifndef MLS16
94 # define MLS16(rt, ra, rb) ((rt) -= (ra) * (rb))
95 #endif
96 
97 /* median of 3 */
98 static inline av_const int median3_c(int a, int b, int c)
99 {
100  int max2, min2, m;
101 
102  if (a >= b) {
103  max2 = a;
104  min2 = b;
105  } else {
106  max2 = b;
107  min2 = a;
108  }
109  m = (c >= max2) ? max2 : c;
110 
111  return (m >= min2) ? m : min2;
112 }
113 
114 #ifndef mid_pred
115 #define mid_pred median3_c
116 #endif
117 
118 #ifndef median4
119 #define median4 median4
120 static inline av_const int median4(int a, int b, int c, int d)
121 {
122  if (a < b) {
123  if (c < d) return (FFMIN(b, d) + FFMAX(a, c)) / 2;
124  else return (FFMIN(b, c) + FFMAX(a, d)) / 2;
125  } else {
126  if (c < d) return (FFMIN(a, d) + FFMAX(b, c)) / 2;
127  else return (FFMIN(a, c) + FFMAX(b, d)) / 2;
128  }
129 }
130 #endif
131 
132 #define FF_SIGNBIT(x) ((x) >> CHAR_BIT * sizeof(x) - 1)
133 
134 #ifndef sign_extend
135 static inline av_const int sign_extend(int val, unsigned bits)
136 {
137  unsigned shift = 8 * sizeof(int) - bits;
138  union { unsigned u; int s; } v = { (unsigned) val << shift };
139  return v.s >> shift;
140 }
141 #endif
142 
143 #ifndef sign_extend64
144 static inline av_const int64_t sign_extend64(int64_t val, unsigned bits)
145 {
146  unsigned shift = 8 * sizeof(int64_t) - bits;
147  union { uint64_t u; int64_t s; } v = { (uint64_t) val << shift };
148  return v.s >> shift;
149 }
150 #endif
151 
152 #ifndef zero_extend
153 static inline av_const unsigned zero_extend(unsigned val, unsigned bits)
154 {
155  return (val << ((8 * sizeof(int)) - bits)) >> ((8 * sizeof(int)) - bits);
156 }
157 #endif
158 
159 #ifndef COPY3_IF_LT
160 #define COPY3_IF_LT(x, y, a, b, c, d)\
161 if ((y) < (x)) {\
162  (x) = (y);\
163  (a) = (b);\
164  (c) = (d);\
165 }
166 #endif
167 
168 #ifndef MASK_ABS
169 #define MASK_ABS(mask, level) do { \
170  mask = level >> 31; \
171  level = (level ^ mask) - mask; \
172  } while (0)
173 #endif
174 
175 #ifndef NEG_SSR32
176 # define NEG_SSR32(a,s) ((( int32_t)(a))>>(32-(s)))
177 #endif
178 
179 #ifndef NEG_USR32
180 # define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s)))
181 #endif
182 
183 #if HAVE_BIGENDIAN
184 # ifndef PACK_2U8
185 # define PACK_2U8(a,b) (((a) << 8) | (b))
186 # endif
187 # ifndef PACK_4U8
188 # define PACK_4U8(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
189 # endif
190 # ifndef PACK_2U16
191 # define PACK_2U16(a,b) (((a) << 16) | (b))
192 # endif
193 #else
194 # ifndef PACK_2U8
195 # define PACK_2U8(a,b) (((b) << 8) | (a))
196 # endif
197 # ifndef PACK_4U2
198 # define PACK_4U8(a,b,c,d) (((d) << 24) | ((c) << 16) | ((b) << 8) | (a))
199 # endif
200 # ifndef PACK_2U16
201 # define PACK_2U16(a,b) (((b) << 16) | (a))
202 # endif
203 #endif
204 
205 #ifndef PACK_2S8
206 # define PACK_2S8(a,b) PACK_2U8((a)&255, (b)&255)
207 #endif
208 #ifndef PACK_4S8
209 # define PACK_4S8(a,b,c,d) PACK_4U8((a)&255, (b)&255, (c)&255, (d)&255)
210 #endif
211 #ifndef PACK_2S16
212 # define PACK_2S16(a,b) PACK_2U16((a)&0xffff, (b)&0xffff)
213 #endif
214 
215 #ifndef FASTDIV
216 # define FASTDIV(a,b) ((uint32_t)((((uint64_t)a) * ff_inverse[b]) >> 32))
217 #endif /* FASTDIV */
218 
219 #ifndef ff_sqrt
220 #define ff_sqrt ff_sqrt
221 static inline av_const unsigned int ff_sqrt(unsigned int a)
222 {
223  unsigned int b;
224 
225  if (a < 255) return (ff_sqrt_tab[a + 1] - 1) >> 4;
226  else if (a < (1 << 12)) b = ff_sqrt_tab[a >> 4] >> 2;
227 #if !CONFIG_SMALL
228  else if (a < (1 << 14)) b = ff_sqrt_tab[a >> 6] >> 1;
229  else if (a < (1 << 16)) b = ff_sqrt_tab[a >> 8] ;
230 #endif
231  else {
232  int s = av_log2_16bit(a >> 16) >> 1;
233  unsigned int c = a >> (s + 2);
234  b = ff_sqrt_tab[c >> (s + 8)];
235  b = FASTDIV(c,b) + (b << s);
236  }
237 
238  return b - (a < b * b);
239 }
240 #endif
241 
242 static inline av_const float ff_sqrf(float a)
243 {
244  return a*a;
245 }
246 
247 static inline int8_t ff_u8_to_s8(uint8_t a)
248 {
249  union {
250  uint8_t u8;
251  int8_t s8;
252  } b;
253  b.u8 = a;
254  return b.s8;
255 }
256 
257 #endif /* AVCODEC_MATHOPS_H */
mathops.h
ff_u8_to_s8
static int8_t ff_u8_to_s8(uint8_t a)
Definition: mathops.h:247
int64_t
long long int64_t
Definition: coverity.c:34
av_log2_16bit
int av_log2_16bit(unsigned v)
Definition: intmath.c:31
u
#define u(width, name, range_min, range_max)
Definition: cbs_apv.c:68
av_const
#define av_const
Definition: attributes.h:100
b
#define b
Definition: input.c:42
zero_extend
static av_const unsigned zero_extend(unsigned val, unsigned bits)
Definition: mathops.h:153
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
ff_inverse
const uint32_t ff_inverse[257]
Definition: mathtables.c:66
median4
#define median4
Definition: mathops.h:119
val
static double val(void *priv, double ch)
Definition: aeval.c:77
ff_sqrt
#define ff_sqrt
Definition: mathops.h:220
attributes_internal.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
bits
uint8_t bits
Definition: vp3data.h:128
sign_extend64
static av_const int64_t sign_extend64(int64_t val, unsigned bits)
Definition: mathops.h:144
UMULH
static av_always_inline unsigned UMULH(unsigned a, unsigned b)
Definition: mathops.h:70
EXTERN
#define EXTERN
Definition: attributes_internal.h:34
FASTDIV
#define FASTDIV(a, b)
Definition: mathops.h:216
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
ff_sqrt_tab
const uint8_t ff_sqrt_tab[256]
Definition: mathtables.c:102
ff_zigzag_scan
const uint8_t ff_zigzag_scan[16+1]
Definition: mathtables.c:148
shift
static int shift(int a, int b)
Definition: bonk.c:261
MULH
static av_always_inline int MULH(int a, int b)
Definition: mathops.h:64
mathops.h
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
median3_c
static av_const int median3_c(int a, int b, int c)
Definition: mathops.h:98
common.h
av_always_inline
#define av_always_inline
Definition: attributes.h:63
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
ff_square_tab
const EXTERN uint32_t ff_square_tab[512]
Definition: mathops.h:35
ff_sqrf
static av_const float ff_sqrf(float a)
Definition: mathops.h:242
ff_zigzag_direct
const uint8_t ff_zigzag_direct[64]
Definition: mathtables.c:137
mathops.h
ff_crop_tab
const EXTERN uint8_t ff_crop_tab[256+2 *MAX_NEG_CROP]
Definition: mathops.h:37
mathops.h
sign_extend
static av_const int sign_extend(int val, unsigned bits)
Definition: mathops.h:135
MUL64
#define MUL64(a, b)
Definition: mathops.h:56
mathops.h
ff_log2_run
const uint8_t ff_log2_run[41]
Definition: mathtables.c:155
MAX_NEG_CROP
#define MAX_NEG_CROP
Definition: mathops.h:31