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 uint8_t ff_sqrt_tab[256];
36 extern const uint8_t attribute_visibility_hidden ff_crop_tab[256 + 2 * MAX_NEG_CROP];
37 extern const uint8_t ff_zigzag_direct[64];
38 extern const uint8_t ff_zigzag_scan[16+1];
39 
40 #if ARCH_ARM
41 # include "arm/mathops.h"
42 #elif ARCH_MIPS
43 # include "mips/mathops.h"
44 #elif ARCH_PPC
45 # include "ppc/mathops.h"
46 #elif ARCH_X86
47 # include "x86/mathops.h"
48 #endif
49 
50 /* generic implementation */
51 
52 #ifndef MUL64
53 # define MUL64(a,b) ((int64_t)(a) * (int64_t)(b))
54 #endif
55 
56 #ifndef MULL
57 # define MULL(a,b,s) (MUL64(a, b) >> (s))
58 #endif
59 
60 #ifndef MULH
61 static av_always_inline int MULH(int a, int b){
62  return MUL64(a, b) >> 32;
63 }
64 #endif
65 
66 #ifndef UMULH
67 static av_always_inline unsigned UMULH(unsigned a, unsigned b){
68  return ((uint64_t)(a) * (uint64_t)(b))>>32;
69 }
70 #endif
71 
72 #ifndef MAC64
73 # define MAC64(d, a, b) ((d) += MUL64(a, b))
74 #endif
75 
76 #ifndef MLS64
77 # define MLS64(d, a, b) ((d) -= MUL64(a, b))
78 #endif
79 
80 /* signed 16x16 -> 32 multiply add accumulate */
81 #ifndef MAC16
82 # define MAC16(rt, ra, rb) rt += (ra) * (rb)
83 #endif
84 
85 /* signed 16x16 -> 32 multiply */
86 #ifndef MUL16
87 # define MUL16(ra, rb) ((ra) * (rb))
88 #endif
89 
90 #ifndef MLS16
91 # define MLS16(rt, ra, rb) ((rt) -= (ra) * (rb))
92 #endif
93 
94 /* median of 3 */
95 #ifndef mid_pred
96 #define mid_pred mid_pred
97 static inline av_const int mid_pred(int a, int b, int c)
98 {
99  if(a>b){
100  if(c>b){
101  if(c>a) b=a;
102  else b=c;
103  }
104  }else{
105  if(b>c){
106  if(c>a) b=c;
107  else b=a;
108  }
109  }
110  return b;
111 }
112 #endif
113 
114 #ifndef median4
115 #define median4 median4
116 static inline av_const int median4(int a, int b, int c, int d)
117 {
118  if (a < b) {
119  if (c < d) return (FFMIN(b, d) + FFMAX(a, c)) / 2;
120  else return (FFMIN(b, c) + FFMAX(a, d)) / 2;
121  } else {
122  if (c < d) return (FFMIN(a, d) + FFMAX(b, c)) / 2;
123  else return (FFMIN(a, c) + FFMAX(b, d)) / 2;
124  }
125 }
126 #endif
127 
128 #define FF_SIGNBIT(x) ((x) >> CHAR_BIT * sizeof(x) - 1)
129 
130 #ifndef sign_extend
131 static inline av_const int sign_extend(int val, unsigned bits)
132 {
133  unsigned shift = 8 * sizeof(int) - bits;
134  union { unsigned u; int s; } v = { (unsigned) val << shift };
135  return v.s >> shift;
136 }
137 #endif
138 
139 #ifndef sign_extend64
140 static inline av_const int64_t sign_extend64(int64_t val, unsigned bits)
141 {
142  unsigned shift = 8 * sizeof(int64_t) - bits;
143  union { uint64_t u; int64_t s; } v = { (uint64_t) val << shift };
144  return v.s >> shift;
145 }
146 #endif
147 
148 #ifndef zero_extend
149 static inline av_const unsigned zero_extend(unsigned val, unsigned bits)
150 {
151  return (val << ((8 * sizeof(int)) - bits)) >> ((8 * sizeof(int)) - bits);
152 }
153 #endif
154 
155 #ifndef COPY3_IF_LT
156 #define COPY3_IF_LT(x, y, a, b, c, d)\
157 if ((y) < (x)) {\
158  (x) = (y);\
159  (a) = (b);\
160  (c) = (d);\
161 }
162 #endif
163 
164 #ifndef MASK_ABS
165 #define MASK_ABS(mask, level) do { \
166  mask = level >> 31; \
167  level = (level ^ mask) - mask; \
168  } while (0)
169 #endif
170 
171 #ifndef NEG_SSR32
172 # define NEG_SSR32(a,s) ((( int32_t)(a))>>(32-(s)))
173 #endif
174 
175 #ifndef NEG_USR32
176 # define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s)))
177 #endif
178 
179 #if HAVE_BIGENDIAN
180 # ifndef PACK_2U8
181 # define PACK_2U8(a,b) (((a) << 8) | (b))
182 # endif
183 # ifndef PACK_4U8
184 # define PACK_4U8(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
185 # endif
186 # ifndef PACK_2U16
187 # define PACK_2U16(a,b) (((a) << 16) | (b))
188 # endif
189 #else
190 # ifndef PACK_2U8
191 # define PACK_2U8(a,b) (((b) << 8) | (a))
192 # endif
193 # ifndef PACK_4U2
194 # define PACK_4U8(a,b,c,d) (((d) << 24) | ((c) << 16) | ((b) << 8) | (a))
195 # endif
196 # ifndef PACK_2U16
197 # define PACK_2U16(a,b) (((b) << 16) | (a))
198 # endif
199 #endif
200 
201 #ifndef PACK_2S8
202 # define PACK_2S8(a,b) PACK_2U8((a)&255, (b)&255)
203 #endif
204 #ifndef PACK_4S8
205 # define PACK_4S8(a,b,c,d) PACK_4U8((a)&255, (b)&255, (c)&255, (d)&255)
206 #endif
207 #ifndef PACK_2S16
208 # define PACK_2S16(a,b) PACK_2U16((a)&0xffff, (b)&0xffff)
209 #endif
210 
211 #ifndef FASTDIV
212 # define FASTDIV(a,b) ((uint32_t)((((uint64_t)a) * ff_inverse[b]) >> 32))
213 #endif /* FASTDIV */
214 
215 #ifndef ff_sqrt
216 #define ff_sqrt ff_sqrt
217 static inline av_const unsigned int ff_sqrt(unsigned int a)
218 {
219  unsigned int b;
220 
221  if (a < 255) return (ff_sqrt_tab[a + 1] - 1) >> 4;
222  else if (a < (1 << 12)) b = ff_sqrt_tab[a >> 4] >> 2;
223 #if !CONFIG_SMALL
224  else if (a < (1 << 14)) b = ff_sqrt_tab[a >> 6] >> 1;
225  else if (a < (1 << 16)) b = ff_sqrt_tab[a >> 8] ;
226 #endif
227  else {
228  int s = av_log2_16bit(a >> 16) >> 1;
229  unsigned int c = a >> (s + 2);
230  b = ff_sqrt_tab[c >> (s + 8)];
231  b = FASTDIV(c,b) + (b << s);
232  }
233 
234  return b - (a < b * b);
235 }
236 #endif
237 
238 static inline av_const float ff_sqrf(float a)
239 {
240  return a*a;
241 }
242 
243 static inline int8_t ff_u8_to_s8(uint8_t a)
244 {
245  union {
246  uint8_t u8;
247  int8_t s8;
248  } b;
249  b.u8 = a;
250  return b.s8;
251 }
252 
253 #endif /* AVCODEC_MATHOPS_H */
u
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:251
ff_u8_to_s8
static int8_t ff_u8_to_s8(uint8_t a)
Definition: mathops.h:243
int64_t
long long int64_t
Definition: coverity.c:34
av_log2_16bit
int av_log2_16bit(unsigned v)
Definition: intmath.c:31
av_const
#define av_const
Definition: attributes.h:84
b
#define b
Definition: input.c:41
zero_extend
static av_const unsigned zero_extend(unsigned val, unsigned bits)
Definition: mathops.h:149
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
attribute_visibility_hidden
#define attribute_visibility_hidden
Definition: attributes_internal.h:29
ff_inverse
const uint32_t ff_inverse[257]
Definition: mathtables.c:27
median4
#define median4
Definition: mathops.h:115
val
static double val(void *priv, double ch)
Definition: aeval.c:77
ff_sqrt
#define ff_sqrt
Definition: mathops.h:216
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:140
UMULH
static av_always_inline unsigned UMULH(unsigned a, unsigned b)
Definition: mathops.h:67
FASTDIV
#define FASTDIV(a, b)
Definition: mathops.h:212
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:63
ff_zigzag_scan
const uint8_t ff_zigzag_scan[16+1]
Definition: mathtables.c:109
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:61
ff_crop_tab
const uint8_t attribute_visibility_hidden ff_crop_tab[256+2 *MAX_NEG_CROP]
Definition: mathtables.c:77
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
common.h
av_always_inline
#define av_always_inline
Definition: attributes.h:49
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
ff_sqrf
static av_const float ff_sqrf(float a)
Definition: mathops.h:238
ff_zigzag_direct
const uint8_t ff_zigzag_direct[64]
Definition: mathtables.c:98
mid_pred
#define mid_pred
Definition: mathops.h:96
mathops.h
mathops.h
sign_extend
static av_const int sign_extend(int val, unsigned bits)
Definition: mathops.h:131
MUL64
#define MUL64(a, b)
Definition: mathops.h:53
mathops.h
ff_log2_run
const uint8_t ff_log2_run[41]
Definition: mathtables.c:116
MAX_NEG_CROP
#define MAX_NEG_CROP
Definition: mathops.h:31