⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 skl_bits.h

📁 mpeg4编解码器
💻 H
字号:
/******************************************************** * Some code. Copyright (C) 2003 by Pascal Massimino.   * * All Rights Reserved.      (http://skal.planet-d.net) * * For Educational/Academic use ONLY. See 'LICENSE.TXT'.* ********************************************************//* * skl_bits.h * *  bitstream I/O + masking utils ********************************************************/#ifndef _SKL_BITS_H_#define _SKL_BITS_H_//////////////////////////////////////////////////////////// Bit-masking utils//////////////////////////////////////////////////////////class SKL_BMASKS {  public:    static const SKL_UINT32 And[33];    // (1<<n)-1    static const SKL_UINT32 Or[33];     // 1<<(n-1)    static int Is_Power_Of_2(int Value)      { return (!(Value & (Value-1))); }  // wow!    static const SKL_BYTE Bit_Sizes[256];    static int Get_Size(int Value) {      int Size = 0;      while (Value>=256) { Value>>=8; Size+=8; }      return Size + Bit_Sizes[Value];    }    // Get_Size() actually returns 'ceil(log2(Value))'    // So here's a wrapper:    static int Log2(int Value) { return Get_Size(Value); }      // and even faster, using IEEE float representation:    static SKL_INT32 fLog2(float v) {      SKL_INT32 I = (SKL_INT32&)v;      return ((I&0x7f800000)>>23) - 127; // extract un-biased 8-bit exponent    }    static SKL_INT32 fLog2(SKL_INT32 v) { return fLog2((float)v); }    static const SKL_BYTE First_Bit_Set[256];    static int Get_First_Bit_Set_16(int V) {      SKL_ASSERT(V>0 && V<=0xffff);      if (V>>8) return First_Bit_Set[(V>>8)];      else return First_Bit_Set[V]+8;    }    static int Get_First_Bit_Set_8(int V) {      SKL_ASSERT(V>0 && V<=0xff);      return First_Bit_Set[V];    }};//////////////////////////////////////////////////////////// These are fast, inlined, MSBF bitstream.// It heavily supposes you know what you're doing.// Read/write overflow is *NOT* checked. //////////////////////////////////////////////////////////struct SKL_FBB {  SKL_BYTE  *Buf;  SKL_INT32  Bits_Left;  SKL_UINT32 Bits;  SKL_FBB() {}  SKL_FBB(const SKL_BYTE *buf) { Init(buf); } // read  SKL_FBB(SKL_BYTE *buf) { Init(buf); }       // write    inline void Init(const SKL_BYTE *buf) {    SKL_ASSERT(buf!=0);    Buf       = (SKL_BYTE*)buf;    Bits_Left = 0;    Bits      = 0x0;  }  inline void Copy(const SKL_FBB *In) {    Buf       = In->Buf;    Bits_Left = In->Bits_Left;    Bits      = In->Bits;  }    // -- loading bytes/words  inline SKL_UINT32 Next_Byte() { return *Buf++; }  inline SKL_UINT32 Next_Word() {    SKL_UINT32 Val = (Buf[0]<<8) | (Buf[1]);    Buf += 2;    return Val;  }  inline void Load() {    SKL_ASSERT(Bits_Left<=24);    Bits_Left += 8;    Bits |= Next_Byte() << (32-Bits_Left);  }  inline void Load_Word() {    SKL_ASSERT(Bits_Left<=24);    Bits_Left += 16;    Bits |= Next_Word() << (32-Bits_Left);  }  inline void Check_Bits(int Nb) {  // unsigned    SKL_ASSERT(Nb<=24);    while (Bits_Left<Nb) Load();  }  inline void Check_Bits_Word(int Nb) {  // unsigned    SKL_ASSERT(Nb<=16);    if (Bits_Left<Nb) Load_Word();  // only load 1 word  }  inline SKL_UINT32 Get_Bits(int Nb) {  // unsigned    Check_Bits(Nb);    SKL_INT32 Val = Bits >> (32-Nb);    Bits <<= Nb;    Bits_Left -= Nb;    return Val;  }  inline SKL_UINT32 Get_Bits_Word(int Nb) {  // unsigned    Check_Bits_Word(Nb);    SKL_INT32 Val = Bits >> (32-Nb);    Bits <<= Nb;    Bits_Left -= Nb;    return Val;  }    // -- checking forthcoming bits  inline SKL_UINT32 See_Bits_Safe(int Nb) const {    SKL_ASSERT(Bits_Left>=Nb);    return (Bits >> (32-Nb));  }  inline SKL_UINT32 See_Bits(int Nb) {  // unsigned    Check_Bits(Nb);    return (Bits >> (32-Nb));  }  inline SKL_UINT32 See_Bits_Word(int Nb) {  // unsigned    Check_Bits_Word(Nb);    return (Bits >> (32-Nb));  }    // -- discard, forward and backward  inline void Discard(int Nb) {    Check_Bits(Nb);    Bits <<= Nb;    Bits_Left -= Nb;  }  inline void Discard_Word(int Nb) {    Check_Bits_Word(Nb);    Bits <<= Nb;    Bits_Left -= Nb;  }  inline void Discard_Safe(int Nb) {    SKL_ASSERT(Bits_Left>=Nb);    Bits <<= Nb;    Bits_Left -= Nb;  }  inline void Rewind(int Nb)  {    SKL_ASSERT(Nb>=0);    Nb += Bits_Left + 7;    Buf -= Nb/8;    Nb = 1 + (Nb&7);    Bits = Next_Byte()<<(32-Nb);    Bits_Left = Nb;  }  inline void Forward(int Nb)  {    SKL_ASSERT(Nb>=0);    if (Nb>=Bits_Left) {      Nb -= Bits_Left;      Buf += Nb/8;      Bits_Left = 8-(Nb&7);      Bits = Next_Byte()<<(32-Nb);    }    else {      Bits_Left -= Nb;      Bits <<= Nb;    }  }  inline void Skip_Bytes(int Nb) {   // warning! unsafe!    SKL_ASSERT(Is_Aligned());    Buf += Nb;  }  inline int Is_Aligned() const { return !(Bits_Left&7); }  inline void Align() { if (Bits_Left&7) Discard_Safe( Bits_Left&7 ); }    // -- positioning  inline SKL_BYTE *Pos() const { return Buf - Bits_Left/8; }  inline SKL_SAFE_INT Bit_Pos() const    { return ((SKL_SAFE_INT)Buf)*8 - Bits_Left; }    // Safely storing the offset in *bits* would theoretically    // require 32+8 bits. Using a known reference (Pos0) not far    // from current position helps avoiding overflow.    // Note that overflow can only happen if you use a bit buffer    // bigger than 16.7 Mo :)  inline SKL_SAFE_INT Safe_Bit_Pos(SKL_BYTE *Pos0) const    { return ((SKL_SAFE_INT)(Buf-Pos0)*8 - Bits_Left); }    // -- Writing bits  inline void Put_Bits(SKL_UINT32 Val, int Nb)  {    SKL_ASSERT(Nb<32 && !(Val&~SKL_BMASKS::And[Nb]));    Bits_Left += Nb;    if (Bits_Left>32) {      Bits_Left -= 32;      Bits |= Val >> Bits_Left;      *Buf++ = ( Bits>>24 ) & 0xff;      *Buf++ = ( Bits>>16 ) & 0xff;      *Buf++ = ( Bits>> 8 ) & 0xff;      *Buf++ = ( Bits>> 0 ) & 0xff;      Bits = Val<<(32-Bits_Left);    }    else Bits |= Val<<(32-Bits_Left);  }  inline void Put_Bits0(int Nb) // emits the bit '0' Nb times  {    SKL_ASSERT(Nb>=0);    Bits_Left += Nb;    while (Bits_Left>32) {      Bits_Left -= 32;      *Buf++ = ( Bits>>24 ) & 0xff;      *Buf++ = ( Bits>>16 ) & 0xff;      *Buf++ = ( Bits>> 8 ) & 0xff;      *Buf++ = ( Bits>> 0 ) & 0xff;      Bits = 0;    }  }  inline void Put_Bits1(int Nb) // emits the bit '1' Nb times  {    SKL_ASSERT(Nb>=0);    Bits |= SKL_BMASKS::And[32-Bits_Left];    Bits_Left += Nb;    while (Bits_Left>32) {      Bits_Left -= 32;      *Buf++ = ( Bits>>24 ) & 0xff;      *Buf++ = ( Bits>>16 ) & 0xff;      *Buf++ = ( Bits>> 8 ) & 0xff;      *Buf++ = ( Bits>> 0 ) & 0xff;      Bits = 0xffffffff;    }    Bits &= ~SKL_BMASKS::And[32-Bits_Left];  }  inline void Put_Word(SKL_UINT32 Val)  {    SKL_ASSERT(Is_Flushed());    *Buf++ = ( Val>>8 ) & 0xff;    *Buf++ = ( Val>>0 ) & 0xff;  }  inline void Put_DWord(SKL_UINT32 Val)  {    SKL_ASSERT(Is_Flushed());    *Buf++ = ( Val>>24 ) & 0xff;    *Buf++ = ( Val>>16 ) & 0xff;    *Buf++ = ( Val>> 8 ) & 0xff;    *Buf++ = ( Val>> 0 ) & 0xff;  }  inline SKL_BYTE *Write_Pos() const { return Buf + Bits_Left/8; }  inline SKL_SAFE_INT Write_Bit_Pos() const    { return ((SKL_SAFE_INT)Buf)*8 + Bits_Left; }  inline SKL_SAFE_INT Safe_Write_Bit_Pos(SKL_BYTE *Pos0) const    { return ((SKL_SAFE_INT)(Buf-Pos0)*8 + Bits_Left); }   // -- sync pending bits and align to byte  inline void Flush_Write() {    while (Bits_Left>0) {      *Buf++ = (Bits >> 24) & 0xff;      Bits <<= 8;      Bits_Left -= 8;    }    Bits_Left = 0;    SKL_ASSERT(Bits==0);  }  inline int Is_Flushed() const { return (Bits_Left==0); }    // exponential Golomb codes#if 1    // Table-based not inlined version  static const SKL_BYTE  EG_Len[512-16];  static const SKL_UINT8 UEG_Val[512-16];  static const SKL_INT8  SEG_Val[512-16];  SKL_UINT32 UEG();               // unsigned  SKL_INT32  SEG();               // signed  static const SKL_UINT16 UEG_Tab[256][2];  static const SKL_UINT16 SEG_Tab[256][2];  void Put_UEG(SKL_UINT32 v);   // unsigned  void Put_SEG(SKL_INT32 v);    // signed#else      // Reference, slow but robust, versions  inline SKL_UINT32 UEG()              // unsigned  {    int Len = 0;    while (!Get_Bits(1)) Len++;    return (Len==0) ? 0 : (1<<Len)-1 + Get_Bits(Len);  }  inline SKL_INT32 SEG()               // signed  {    int Len = 0;    while (!Get_Bits(1)) Len++;    if (Len==0) return 0;    SKL_INT32 Val = (1<<Len) | Get_Bits(Len);    return (Val&1) ? -(Val>>1) : (Val>>1);  }  inline void Put_UEG(SKL_UINT32 v)              // unsigned  {    if (v) {      v += 1;      const int Len = SKL_BMASKS::Log2(v);      //  Put_Bits(v, 2*Len-1);   <- this could overflow if 2*Len-1>24      Put_Bits(0, Len-1);      Put_Bits(v, Len  );    }    else Put_Bits(1,1);  }  inline void Put_SEG(SKL_INT32 v)               // signed  {    if (v) {      int Len;      if (v<0) v = 1-2*v;      else     v = 2*v;      Len = SKL_BMASKS::Log2(v);      //  Put_Bits(v, 2*Len-1);   <- this could overflow if 2*Len-1>24      Put_Bits(0, Len-1);      Put_Bits(v, Len  );    }    else Put_Bits(1,1);  }#endif    // computes code length  static int UEG_Len(SKL_UINT32 v)              // unsigned  {    return 2*SKL_BMASKS::Log2(v+1) - 1;  }  static int SEG_Len(SKL_INT32 v)               // signed  {    if (v==0) return 1;    if (v<0) v = 1-2*v;    else     v = 2*v;    return 2*SKL_BMASKS::Log2(v) - 1;  }};//////////////////////////////////////////////////////////// MACRO-ized version//////////////////////////////////////////////////////////#define SKL_FBB_DECL             SKL_BYTE *Buf; SKL_INT32 Bits_Left; SKL_UINT32 Bits#define SKL_FBB_START(FBB)       Buf = (FBB).Buf; Bits_Left = (FBB).Bits_Left; Bits = (FBB).Bits#define SKL_FBB_STOP(FBB)        (FBB).Buf = Buf; (FBB).Bits_Left = Bits_Left; (FBB).Bits = Bits#define SKL_FBB_NEXT_WORD        do { Bits_Left+=16; Bits |= ((Buf[0]<<8) | Buf[1])<<(32-Bits_Left); Buf+=2; } while(0)#define SKL_FBB_LOAD_WORD(NB)    if (Bits_Left<NB) SKL_FBB_NEXT_WORD#define SKL_FBB_NEXT_BYTE        do { Bits_Left+=16; Bits |= Buf[1]<<(32-Bits_Left); Buf+=1; } while(0)#define SKL_FBB_LOAD_BYTE(NB)    if (Bits_Left<NB) SKL_FBB_NEXT_BYTE#define SKL_FBB_BITS(NB)         (Bits>>(32-NB))#define SKL_FBB_BITS_SIGNED(NB)  (((SKL_INT32)Bits)>>(32-NB))#define SKL_FBB_CHECK(NB)        while (Bits_Left<NB) SKL_FBB_NEXT_BYTE#define SKL_FBB_DISCARD(NB)      do { SKL_FBB_CHECK(NB); Bits<<=NB; Bits_Left-= NB; } while(0)#define SKL_FBB_DISCARD_SAFE(NB) do { Bits<<=NB; Bits_Left-= NB; } while(0)//////////////////////////////////////////////////////////#endif  /* _SKL_BITS_H_ */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -