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