/*! * \copy * Copyright (c) 2009-2013, Cisco Systems * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * * \file macros.h * * \brief MACRO based tool utilization * * \date 3/13/2009 Created * ************************************************************************************* */ #ifndef WELS_MACRO_UTILIZATIONS_H__ #define WELS_MACRO_UTILIZATIONS_H__ //#include #include "typedefs.h" namespace WelsSVCEnc { #if defined(_MSC_VER) #if _MSC_VER <= 1200 #define ALLOC_ALLIGN_MEM(name,size,type,alignment) \ type name##_storage[size+(alignment)-1]; \ type * name = (type *) (((int32_t) name##_storage+(alignment - 1)) & ~((int32_t)(alignment)-1)) #define ALLOC_ALLIGN_MEM_2(name,sizex,sizey,type,alignment) \ type name##_storage[(sizex)*(sizey)+(alignment)-1]; \ type * name = (type *) (((int32_t) name##_storage+(alignment - 1)) & ~((int32_t)(alignment)-1)) #else //_MSC_VER <= 1200 #define ALLOC_ALLIGN_MEM(name,size,type,alignment) \ __declspec(align(alignment)) type name[size] #define ALLOC_ALLIGN_MEM_2(name,sizex,sizey,type,alignment) \ __declspec(align(alignment)) type name[(sizex)*(sizey)] #endif//_MSC_VER <= 1200 #elif defined(__GNUC__) #define ALLOC_ALLIGN_MEM(name,size,type,alignment) \ type name[size] __attribute__((aligned(alignment))) #define ALLOC_ALLIGN_MEM_2(name,sizex,sizey,type,alignment) \ type name[(sizex)*(sizey)] __attribute__((aligned(alignment))) #endif//_MSC_VER #if defined(_MSC_VER) #if(_MSC_VER < 1700) #define inline __inline #endif #define __FASTCALL __fastcall #define ALIGNED_DECLARE( type, var, n ) __declspec(align(n)) type var #define __align8(t,v) __declspec(align(8)) t v #define __align16(t,v) __declspec(align(16)) t v #elif defined(__GNUC__) #if !defined(MAC_POWERPC) #define __FASTCALL __attribute__ ((fastcall)) #else #define __FASTCALL // mean NULL for mac ppc #endif//MAC_POWERPC #define ALIGNED_DECLARE( type, var, n ) type var __attribute__((aligned(n))) #define __align8(t,v) t v __attribute__ ((aligned (8))) #define __align16(t,v) t v __attribute__ ((aligned (16))) #endif//_MSC_VER #if defined(_MACH_PLATFORM) || defined(__GNUC__) #define ALIGNED_DECLARE_MATRIX_2D(name,sizex,sizey,type,alignment) \ type name[(sizex)*(sizey)] __attribute__((aligned(alignment))) #else //_MSC_VER <= 1200 #define ALIGNED_DECLARE_MATRIX_2D(name,sizex,sizey,type,alignment) \ __declspec(align(alignment)) type name[(sizex)*(sizey)] #endif//#if _MACH_PLATFORM #if defined(_MACH_PLATFORM) || defined(__GNUC__) #define ALIGNED_DECLARE_MATRIX_1D(name,size,type,alignment) \ type name[size] __attribute__((aligned(alignment))) #else //_MSC_VER <= 1200 #define ALIGNED_DECLARE_MATRIX_1D(name,size,type,alignment) \ __declspec(align(alignment)) type name[(size)] #endif//#if _MACH_PLATFORM //#if !defined(SIZEOFRGB24) //#define SIZEOFRGB24(cx, cy) (3 * (cx) * (cy)) //#endif//SIZEOFRGB24 //#if !defined(SIZEOFRGB32) //#define SIZEOFRGB32(cx, cy) (4 * (cx) * (cy)) //#endif//SIZEOFRGB32 #ifndef WELS_ALIGN #define WELS_ALIGN(x, n) (((x)+(n)-1)&~((n)-1)) #endif//WELS_ALIGN #ifndef WELS_MAX //#define WELS_MAX(x, y) ((x) > (y) ? (x) : (y)) //#define WELS_MAX(x, y) ((x) - (((x)-(y))&(((x)-(y))>>31))) #define WELS_MAX(x, y) ((x) ^ (((x)^(y))& -((x)<(y)))) // WELS_MAX(x, y) #endif//WELS_MAX #ifndef WELS_MIN //#define WELS_MIN(x, y) ((x) < (y) ? (x) : (y)) //#define WELS_MIN(x, y) ((y) + (((x)-(y))&(((x)-(y))>>31))) #define WELS_MIN(x, y) ((y) ^ (((x)^(y))& -((x)<(y)))) // WELS_MIN(x, y) #endif//WELS_MIN #ifndef WELS_ROUND #define WELS_ROUND(x) ((int32_t)((x)+0.5f+EPSN)) #endif//WELS_ROUND static inline int32_t WELS_CEIL (float v) { const int32_t n = (int32_t)v; // floor value return ((v > EPSN + n) ? (1 + n) : n); // (int32_t)ceil(v); } static inline int32_t WELS_FLOOR (float v) { return (int32_t)v; } #define WELS_NON_ZERO_COUNT_AVERAGE(iC,iA,iB) { \ iC = iA + iB + 1; \ iC >>= (int32_t)( iA != -1 && iB != -1); \ iC += (iA == -1 && iB == -1); \ } /* * log base 2 of v and ceil/floor extension */ static inline int32_t WELS_CEILLOG2 (uint32_t v) { int32_t r = 0; --v; while (v > 0) { ++r; v >>= 1; } return r; } static inline int32_t WELS_FLOORLOG2 (uint32_t v) { int32_t r = 0; while (v > 1) { ++r; v >>= 1; } return r; } static inline int32_t WELS_LOG2 (uint32_t v) { int32_t r = 0; while (v >>= 1) { ++r; } return r; } static inline BOOL_T WELS_POWER2_IF (uint32_t v) { return (v && ! (v & (v - 1))); } static inline int32_t WELS_MEDIAN (int32_t x, int32_t y, int32_t z) { int32_t t = (x - y) & ((x - y) >> 31); x -= t; y += t; y -= (y - z) & ((y - z) >> 31); y += (x - y) & ((x - y) >> 31); return y; } #ifndef BUTTERFLY1x2 #define BUTTERFLY1x2(b) (((b)<<8) | (b)) #endif//BUTTERFLY1x2 #ifndef BUTTERFLY2x4 #define BUTTERFLY2x4(wd) (((uint32_t)(wd)<<16) |(wd)) #endif//BUTTERFLY2x4 #ifndef BUTTERFLY4x8 #define BUTTERFLY4x8(dw) (((uint64_t)(dw)<<32) | (dw)) #endif//BUTTERFLY4x8 //when RS accumulation, should clip rs among range of [-255, 255] #ifndef CLIP_RS #define CLIP_RS( value ) ( WELS_MAX( WELS_MIN( value, 255 ), -255 ) ) #endif //CLIP_RS //#ifndef NEG_NUM //#define NEG_NUM( num ) (1+(~(num))) //#endif// NEG_NUM #ifndef WELS_CLIP1 #define WELS_CLIP1(x) (((x) & ~255) ? (-(x) >> 31) : (x)) #endif//WELS_CLIP1 #ifndef WELS_SIGN #define WELS_SIGN(a) ((int32_t)(a) >> 31) // General: (a)>>(sizeof(int)*CHAR_BIT-1), CHAR_BIT= the number of bits per byte (normally 8) #endif //WELS_SIGN static inline int32_t WELS_ABS (int32_t a) { const int32_t sign = WELS_SIGN (a); return ((a + sign) ^ sign); } // wels_tostring //#ifndef wels_tostring //#define wels_tostring(s) #s //#endif //wels_tostring // WELS_CLIP3 #ifndef WELS_CLIP3 #define WELS_CLIP3(x, y, z) ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x))) #endif //WELS_CLIP3 #define CLIP3_QP_0_51(q) WELS_CLIP3(q, 0, 51) // ((q) < (0) ? (0) : ((q) > (51) ? (51) : (q))) // Bitwise routines // n: ulong // b: bit order static inline bool_t BITWISE_ENABLED (const uint32_t n, const uint8_t b) { const uint8_t bit = (b & 0x1f); // maximal bit position 31 for uint32_t 4 bytes #if defined(WORDS_BIGENDIAN) /* * 31 .. 24, 23 .. 16, 15 .. 8, 7 .. 0 * 7 .. 0, 15 .. 8, 23 .. 16, 31 .. 24 */ const uint8_t map = 24 + ((bit & 7) << 1) - bit; // BIG_ENDIAN map return (bool_t) ((n & (1 << map)) >> map); // BIG_ENDIAN #else return ((n & (1 << bit)) >> bit) ? true : false; // LITTLE_ENDIAN #endif//WORDS_BIGENDIAN } #define CALC_BI_STRIDE(width,bitcount) ((((width * bitcount) + 31) & ~31) >> 3) ////////////////////////////////////////////////////////// #ifdef WORDS_BIGENDIAN static inline uint32_t ENDIAN_FIX (uint32_t x) { return x; } #else #if defined(WIN32) && !defined(WIN64) && defined(_MSC_VER) static inline uint32_t ENDIAN_FIX (uint32_t x) { __asm { mov eax, x bswap eax mov x, eax } return x; } #else // GCC static inline uint32_t ENDIAN_FIX (uint32_t x) { #ifdef X86_ARCH __asm__ __volatile__ ("bswap %0":"+r" (x)); #else x = ((x & 0xff000000) >> 24) | ((x & 0xff0000) >> 8) | ((x & 0xff00) << 8) | ((x & 0xff) << 24); #endif return x; } #endif #endif // wels_swap16 // wels_swap32 // sad, satd, avg might being in other header /* * Description: to check variable validation and return the specified result * result: value to be return * case_if: negative condition to be verified */ #ifndef WELS_VERIFY_RETURN_IF #define WELS_VERIFY_RETURN_IF(result, case_if) \ if ( case_if ){ \ return result; \ } #endif//#if WELS_VERIFY_RETURN_IF /* * Description: to check variable validation and return the specified result * with correspoinding process advance. * result: value to be return * case_if: negative condition to be verified * proc: process need perform */ #ifndef WELS_VERIFY_RETURN_PROC_IF #define WELS_VERIFY_RETURN_PROC_IF(result, case_if, proc) \ if ( case_if ){ \ proc; \ return result; \ } #endif//#if WELS_VERIFY_RETURN_PROC_IF /* * Description: to check variable validation and return * case_if: negtive condition to be verified * return: NONE */ #ifndef WELS_VERIFY_IF #define WELS_VERIFY_IF(case_if) \ if ( case_if ){ \ return; \ } #endif//#if WELS_VERIFY_IF /* * Description: to check variable validation and return with correspoinding process advance. * case_if: negtive condition to be verified * proc: process need preform * return: NONE */ #ifndef WELS_VERIFY_PROC_IF #define WELS_VERIFY_PROC_IF(case_if, proc) \ if ( case_if ){ \ proc; \ return; \ } #endif//#if WELS_VERIFY_IF /* * Description: to safe free a ptr with free function pointer * p: pointer to be destroyed * free_fn: free function pointer used */ #ifndef WELS_SAFE_FREE_P #define WELS_SAFE_FREE_P(p, free_fn) \ do{ \ if ( NULL != (p) ){ \ free_fn( (p) ); \ (p) = NULL; \ } \ }while( 0 ); #endif//#if WELS_SAFE_FREE_P /* * Description: to safe free an array ptr with free function pointer * arr: pointer to an array, something like "**p"; * num: number of elements in array * free_fn: free function pointer */ #ifndef WELS_SAFE_FREE_ARR #define WELS_SAFE_FREE_ARR(arr, num, free_fn) \ do{ \ if ( NULL != (arr) ){ \ int32_t iidx = 0; \ while( iidx < num ){ \ if ( NULL != (arr)[iidx] ){ \ free_fn( (arr)[iidx] ); \ (arr)[iidx] = NULL; \ } \ ++ iidx; \ } \ free_fn((arr)); \ (arr) = NULL; \ } \ }while( 0 ); #endif//#if WELS_SAFE_FREE_ARR } #endif//WELS_MACRO_UTILIZATIONS_H__