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