1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * simple math operations
3cabdff1aSopenharmony_ci * Copyright (c) 2001, 2002 Fabrice Bellard
4cabdff1aSopenharmony_ci * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> et al
5cabdff1aSopenharmony_ci *
6cabdff1aSopenharmony_ci * This file is part of FFmpeg.
7cabdff1aSopenharmony_ci *
8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
12cabdff1aSopenharmony_ci *
13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16cabdff1aSopenharmony_ci * Lesser General Public License for more details.
17cabdff1aSopenharmony_ci *
18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21cabdff1aSopenharmony_ci */
22cabdff1aSopenharmony_ci#ifndef AVCODEC_MATHOPS_H
23cabdff1aSopenharmony_ci#define AVCODEC_MATHOPS_H
24cabdff1aSopenharmony_ci
25cabdff1aSopenharmony_ci#include <stdint.h>
26cabdff1aSopenharmony_ci
27cabdff1aSopenharmony_ci#include "libavutil/common.h"
28cabdff1aSopenharmony_ci#include "config.h"
29cabdff1aSopenharmony_ci
30cabdff1aSopenharmony_ci#define MAX_NEG_CROP 1024
31cabdff1aSopenharmony_ci
32cabdff1aSopenharmony_ciextern const uint32_t ff_inverse[257];
33cabdff1aSopenharmony_ciextern const uint8_t ff_log2_run[41];
34cabdff1aSopenharmony_ciextern const uint8_t ff_sqrt_tab[256];
35cabdff1aSopenharmony_ciextern const uint8_t ff_crop_tab[256 + 2 * MAX_NEG_CROP];
36cabdff1aSopenharmony_ciextern const uint8_t ff_zigzag_direct[64];
37cabdff1aSopenharmony_ciextern const uint8_t ff_zigzag_scan[16+1];
38cabdff1aSopenharmony_ci
39cabdff1aSopenharmony_ci#if   ARCH_ARM
40cabdff1aSopenharmony_ci#   include "arm/mathops.h"
41cabdff1aSopenharmony_ci#elif ARCH_AVR32
42cabdff1aSopenharmony_ci#   include "avr32/mathops.h"
43cabdff1aSopenharmony_ci#elif ARCH_MIPS
44cabdff1aSopenharmony_ci#   include "mips/mathops.h"
45cabdff1aSopenharmony_ci#elif ARCH_PPC
46cabdff1aSopenharmony_ci#   include "ppc/mathops.h"
47cabdff1aSopenharmony_ci#elif ARCH_X86
48cabdff1aSopenharmony_ci#   include "x86/mathops.h"
49cabdff1aSopenharmony_ci#endif
50cabdff1aSopenharmony_ci
51cabdff1aSopenharmony_ci/* generic implementation */
52cabdff1aSopenharmony_ci
53cabdff1aSopenharmony_ci#ifndef MUL64
54cabdff1aSopenharmony_ci#   define MUL64(a,b) ((int64_t)(a) * (int64_t)(b))
55cabdff1aSopenharmony_ci#endif
56cabdff1aSopenharmony_ci
57cabdff1aSopenharmony_ci#ifndef MULL
58cabdff1aSopenharmony_ci#   define MULL(a,b,s) (MUL64(a, b) >> (s))
59cabdff1aSopenharmony_ci#endif
60cabdff1aSopenharmony_ci
61cabdff1aSopenharmony_ci#ifndef MULH
62cabdff1aSopenharmony_cistatic av_always_inline int MULH(int a, int b){
63cabdff1aSopenharmony_ci    return MUL64(a, b) >> 32;
64cabdff1aSopenharmony_ci}
65cabdff1aSopenharmony_ci#endif
66cabdff1aSopenharmony_ci
67cabdff1aSopenharmony_ci#ifndef UMULH
68cabdff1aSopenharmony_cistatic av_always_inline unsigned UMULH(unsigned a, unsigned b){
69cabdff1aSopenharmony_ci    return ((uint64_t)(a) * (uint64_t)(b))>>32;
70cabdff1aSopenharmony_ci}
71cabdff1aSopenharmony_ci#endif
72cabdff1aSopenharmony_ci
73cabdff1aSopenharmony_ci#ifndef MAC64
74cabdff1aSopenharmony_ci#   define MAC64(d, a, b) ((d) += MUL64(a, b))
75cabdff1aSopenharmony_ci#endif
76cabdff1aSopenharmony_ci
77cabdff1aSopenharmony_ci#ifndef MLS64
78cabdff1aSopenharmony_ci#   define MLS64(d, a, b) ((d) -= MUL64(a, b))
79cabdff1aSopenharmony_ci#endif
80cabdff1aSopenharmony_ci
81cabdff1aSopenharmony_ci/* signed 16x16 -> 32 multiply add accumulate */
82cabdff1aSopenharmony_ci#ifndef MAC16
83cabdff1aSopenharmony_ci#   define MAC16(rt, ra, rb) rt += (ra) * (rb)
84cabdff1aSopenharmony_ci#endif
85cabdff1aSopenharmony_ci
86cabdff1aSopenharmony_ci/* signed 16x16 -> 32 multiply */
87cabdff1aSopenharmony_ci#ifndef MUL16
88cabdff1aSopenharmony_ci#   define MUL16(ra, rb) ((ra) * (rb))
89cabdff1aSopenharmony_ci#endif
90cabdff1aSopenharmony_ci
91cabdff1aSopenharmony_ci#ifndef MLS16
92cabdff1aSopenharmony_ci#   define MLS16(rt, ra, rb) ((rt) -= (ra) * (rb))
93cabdff1aSopenharmony_ci#endif
94cabdff1aSopenharmony_ci
95cabdff1aSopenharmony_ci/* median of 3 */
96cabdff1aSopenharmony_ci#ifndef mid_pred
97cabdff1aSopenharmony_ci#define mid_pred mid_pred
98cabdff1aSopenharmony_cistatic inline av_const int mid_pred(int a, int b, int c)
99cabdff1aSopenharmony_ci{
100cabdff1aSopenharmony_ci    if(a>b){
101cabdff1aSopenharmony_ci        if(c>b){
102cabdff1aSopenharmony_ci            if(c>a) b=a;
103cabdff1aSopenharmony_ci            else    b=c;
104cabdff1aSopenharmony_ci        }
105cabdff1aSopenharmony_ci    }else{
106cabdff1aSopenharmony_ci        if(b>c){
107cabdff1aSopenharmony_ci            if(c>a) b=c;
108cabdff1aSopenharmony_ci            else    b=a;
109cabdff1aSopenharmony_ci        }
110cabdff1aSopenharmony_ci    }
111cabdff1aSopenharmony_ci    return b;
112cabdff1aSopenharmony_ci}
113cabdff1aSopenharmony_ci#endif
114cabdff1aSopenharmony_ci
115cabdff1aSopenharmony_ci#ifndef median4
116cabdff1aSopenharmony_ci#define median4 median4
117cabdff1aSopenharmony_cistatic inline av_const int median4(int a, int b, int c, int d)
118cabdff1aSopenharmony_ci{
119cabdff1aSopenharmony_ci    if (a < b) {
120cabdff1aSopenharmony_ci        if (c < d) return (FFMIN(b, d) + FFMAX(a, c)) / 2;
121cabdff1aSopenharmony_ci        else       return (FFMIN(b, c) + FFMAX(a, d)) / 2;
122cabdff1aSopenharmony_ci    } else {
123cabdff1aSopenharmony_ci        if (c < d) return (FFMIN(a, d) + FFMAX(b, c)) / 2;
124cabdff1aSopenharmony_ci        else       return (FFMIN(a, c) + FFMAX(b, d)) / 2;
125cabdff1aSopenharmony_ci    }
126cabdff1aSopenharmony_ci}
127cabdff1aSopenharmony_ci#endif
128cabdff1aSopenharmony_ci
129cabdff1aSopenharmony_ci#define FF_SIGNBIT(x) ((x) >> CHAR_BIT * sizeof(x) - 1)
130cabdff1aSopenharmony_ci
131cabdff1aSopenharmony_ci#ifndef sign_extend
132cabdff1aSopenharmony_cistatic inline av_const int sign_extend(int val, unsigned bits)
133cabdff1aSopenharmony_ci{
134cabdff1aSopenharmony_ci    unsigned shift = 8 * sizeof(int) - bits;
135cabdff1aSopenharmony_ci    union { unsigned u; int s; } v = { (unsigned) val << shift };
136cabdff1aSopenharmony_ci    return v.s >> shift;
137cabdff1aSopenharmony_ci}
138cabdff1aSopenharmony_ci#endif
139cabdff1aSopenharmony_ci
140cabdff1aSopenharmony_ci#ifndef zero_extend
141cabdff1aSopenharmony_cistatic inline av_const unsigned zero_extend(unsigned val, unsigned bits)
142cabdff1aSopenharmony_ci{
143cabdff1aSopenharmony_ci    return (val << ((8 * sizeof(int)) - bits)) >> ((8 * sizeof(int)) - bits);
144cabdff1aSopenharmony_ci}
145cabdff1aSopenharmony_ci#endif
146cabdff1aSopenharmony_ci
147cabdff1aSopenharmony_ci#ifndef COPY3_IF_LT
148cabdff1aSopenharmony_ci#define COPY3_IF_LT(x, y, a, b, c, d)\
149cabdff1aSopenharmony_ciif ((y) < (x)) {\
150cabdff1aSopenharmony_ci    (x) = (y);\
151cabdff1aSopenharmony_ci    (a) = (b);\
152cabdff1aSopenharmony_ci    (c) = (d);\
153cabdff1aSopenharmony_ci}
154cabdff1aSopenharmony_ci#endif
155cabdff1aSopenharmony_ci
156cabdff1aSopenharmony_ci#ifndef MASK_ABS
157cabdff1aSopenharmony_ci#define MASK_ABS(mask, level) do {              \
158cabdff1aSopenharmony_ci        mask  = level >> 31;                    \
159cabdff1aSopenharmony_ci        level = (level ^ mask) - mask;          \
160cabdff1aSopenharmony_ci    } while (0)
161cabdff1aSopenharmony_ci#endif
162cabdff1aSopenharmony_ci
163cabdff1aSopenharmony_ci#ifndef NEG_SSR32
164cabdff1aSopenharmony_ci#   define NEG_SSR32(a,s) ((( int32_t)(a))>>(32-(s)))
165cabdff1aSopenharmony_ci#endif
166cabdff1aSopenharmony_ci
167cabdff1aSopenharmony_ci#ifndef NEG_USR32
168cabdff1aSopenharmony_ci#   define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s)))
169cabdff1aSopenharmony_ci#endif
170cabdff1aSopenharmony_ci
171cabdff1aSopenharmony_ci#if HAVE_BIGENDIAN
172cabdff1aSopenharmony_ci# ifndef PACK_2U8
173cabdff1aSopenharmony_ci#   define PACK_2U8(a,b)     (((a) <<  8) | (b))
174cabdff1aSopenharmony_ci# endif
175cabdff1aSopenharmony_ci# ifndef PACK_4U8
176cabdff1aSopenharmony_ci#   define PACK_4U8(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
177cabdff1aSopenharmony_ci# endif
178cabdff1aSopenharmony_ci# ifndef PACK_2U16
179cabdff1aSopenharmony_ci#   define PACK_2U16(a,b)    (((a) << 16) | (b))
180cabdff1aSopenharmony_ci# endif
181cabdff1aSopenharmony_ci#else
182cabdff1aSopenharmony_ci# ifndef PACK_2U8
183cabdff1aSopenharmony_ci#   define PACK_2U8(a,b)     (((b) <<  8) | (a))
184cabdff1aSopenharmony_ci# endif
185cabdff1aSopenharmony_ci# ifndef PACK_4U2
186cabdff1aSopenharmony_ci#   define PACK_4U8(a,b,c,d) (((d) << 24) | ((c) << 16) | ((b) << 8) | (a))
187cabdff1aSopenharmony_ci# endif
188cabdff1aSopenharmony_ci# ifndef PACK_2U16
189cabdff1aSopenharmony_ci#   define PACK_2U16(a,b)    (((b) << 16) | (a))
190cabdff1aSopenharmony_ci# endif
191cabdff1aSopenharmony_ci#endif
192cabdff1aSopenharmony_ci
193cabdff1aSopenharmony_ci#ifndef PACK_2S8
194cabdff1aSopenharmony_ci#   define PACK_2S8(a,b)     PACK_2U8((a)&255, (b)&255)
195cabdff1aSopenharmony_ci#endif
196cabdff1aSopenharmony_ci#ifndef PACK_4S8
197cabdff1aSopenharmony_ci#   define PACK_4S8(a,b,c,d) PACK_4U8((a)&255, (b)&255, (c)&255, (d)&255)
198cabdff1aSopenharmony_ci#endif
199cabdff1aSopenharmony_ci#ifndef PACK_2S16
200cabdff1aSopenharmony_ci#   define PACK_2S16(a,b)    PACK_2U16((a)&0xffff, (b)&0xffff)
201cabdff1aSopenharmony_ci#endif
202cabdff1aSopenharmony_ci
203cabdff1aSopenharmony_ci#ifndef FASTDIV
204cabdff1aSopenharmony_ci#   define FASTDIV(a,b) ((uint32_t)((((uint64_t)a) * ff_inverse[b]) >> 32))
205cabdff1aSopenharmony_ci#endif /* FASTDIV */
206cabdff1aSopenharmony_ci
207cabdff1aSopenharmony_ci#ifndef ff_sqrt
208cabdff1aSopenharmony_ci#define ff_sqrt ff_sqrt
209cabdff1aSopenharmony_cistatic inline av_const unsigned int ff_sqrt(unsigned int a)
210cabdff1aSopenharmony_ci{
211cabdff1aSopenharmony_ci    unsigned int b;
212cabdff1aSopenharmony_ci
213cabdff1aSopenharmony_ci    if (a < 255) return (ff_sqrt_tab[a + 1] - 1) >> 4;
214cabdff1aSopenharmony_ci    else if (a < (1 << 12)) b = ff_sqrt_tab[a >> 4] >> 2;
215cabdff1aSopenharmony_ci#if !CONFIG_SMALL
216cabdff1aSopenharmony_ci    else if (a < (1 << 14)) b = ff_sqrt_tab[a >> 6] >> 1;
217cabdff1aSopenharmony_ci    else if (a < (1 << 16)) b = ff_sqrt_tab[a >> 8]   ;
218cabdff1aSopenharmony_ci#endif
219cabdff1aSopenharmony_ci    else {
220cabdff1aSopenharmony_ci        int s = av_log2_16bit(a >> 16) >> 1;
221cabdff1aSopenharmony_ci        unsigned int c = a >> (s + 2);
222cabdff1aSopenharmony_ci        b = ff_sqrt_tab[c >> (s + 8)];
223cabdff1aSopenharmony_ci        b = FASTDIV(c,b) + (b << s);
224cabdff1aSopenharmony_ci    }
225cabdff1aSopenharmony_ci
226cabdff1aSopenharmony_ci    return b - (a < b * b);
227cabdff1aSopenharmony_ci}
228cabdff1aSopenharmony_ci#endif
229cabdff1aSopenharmony_ci
230cabdff1aSopenharmony_cistatic inline av_const float ff_sqrf(float a)
231cabdff1aSopenharmony_ci{
232cabdff1aSopenharmony_ci    return a*a;
233cabdff1aSopenharmony_ci}
234cabdff1aSopenharmony_ci
235cabdff1aSopenharmony_cistatic inline int8_t ff_u8_to_s8(uint8_t a)
236cabdff1aSopenharmony_ci{
237cabdff1aSopenharmony_ci    union {
238cabdff1aSopenharmony_ci        uint8_t u8;
239cabdff1aSopenharmony_ci        int8_t  s8;
240cabdff1aSopenharmony_ci    } b;
241cabdff1aSopenharmony_ci    b.u8 = a;
242cabdff1aSopenharmony_ci    return b.s8;
243cabdff1aSopenharmony_ci}
244cabdff1aSopenharmony_ci
245cabdff1aSopenharmony_ci#endif /* AVCODEC_MATHOPS_H */
246