15 #ifndef ZenBitStream_FastH
16 #define ZenBitStream_FastH
33 class BitStream_Fast_Local;
36 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
40 #define ZENLIB_BSF_INLINE __forceinline
41 #define ZENLIB_BSF_NOINLINE __declspec(noinline)
42 #elif defined(__GNUC__) || defined(__clang__)
43 #define ZENLIB_BSF_INLINE inline __attribute__((always_inline))
44 #define ZENLIB_BSF_NOINLINE __attribute__((noinline))
46 #define ZENLIB_BSF_INLINE inline
47 #define ZENLIB_BSF_NOINLINE
101 BitStream_Fast (
const int8u* Buffer_,
size_t Size_,
size_t ExtraBytesAvailable_=0) {
Attach(Buffer_, Size_, ExtraBytesAvailable_); }
108 Buffer_Size=Buffer_Size_Init=BitEnd=Size_*8;
110 ExtraBytes=(int8u)
MIN(ExtraBytesAvailable_,
sizeof(Word)-1);
111 BufferUnderRun_=
false;
121 if (Buffer_Size<=WindowEnd)
131 return TestBit(Window, Buffer_Size);
136 return (int8u)Get<8>(HowMany);
141 return (int16u)Get<16>(HowMany);
146 return (int32u)Get<32>(HowMany);
152 return Get<32>(HowMany);
155 if (HowMany>Buffer_Size)
158 if ((
size_t)(HowMany-32)<=Buffer_Size)
159 Buffer_Size-=HowMany-32;
163 return Read64(HowMany);
169 return (int32u)Read<32>(HowMany);
175 return Read64(HowMany);
186 if (!PeekUE(Bits, Size))
189 return (int32u)(Bits>>(WordBits-Size))-1;
195 const int32u CodeNum=
GetUE();
196 return (int32s)((CodeNum&1)?(CodeNum>>1)+1:0u-(CodeNum>>1));
206 if (HowMany>Buffer_Size)
211 Buffer_Size-=HowMany;
216 if (Buffer_Size<=WindowEnd)
225 return TestBit(Window, Buffer_Size-1);
230 return (int8u)Peek<8>(HowMany);
235 return (int16u)Peek<16>(HowMany);
240 return (int32u)Peek<32>(HowMany);
246 return Peek<32>(HowMany);
249 if (HowMany>Buffer_Size)
254 if (HowMany<=WordBits)
255 return PeekWide(Buffer_Size, HowMany);
257 const int64u High=PeekWide(Buffer_Size, HowMany-32);
258 return (High<<32)|PeekWide(Buffer_Size-(HowMany-32), 32);
268 Buffer_Size&=~(size_t)7;
273 return (Buffer_Size_Init-Buffer_Size)/8;
278 return Buffer_Size%8;
283 return Buffer_Size%8;
291 if (BufferUnderRun_ && Size_>Buffer_Size)
292 BufferUnderRun_=
false;
293 BitEnd=BitEnd-Buffer_Size+Size_;
308 enum { WordBits=
sizeof(Word)*8 };
317 std::memcpy(&Value, Source,
sizeof(Value));
318 #if defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
320 #elif defined(_MSC_VER)
322 return _byteswap_uint64(Value);
324 return _byteswap_ulong(Value);
326 #elif (defined(__GNUC__) || defined(__clang__)) && defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
327 return sizeof(Word)==8?(Word)__builtin_bswap64((int64u)Value):(Word)__builtin_bswap32((int32u)Value);
331 for (
size_t i=0; i<
sizeof(Word); i++)
332 Result=(Result<<8)|Source[i];
341 for (
size_t i=0; i<Size; i++)
342 Value|=(Word)Source[i]<<(WordBits-8-8*i);
348 #if defined(_MSC_VER)
351 _BitScanReverse64(&Index, Value);
353 _BitScanReverse(&Index, Value);
355 return (
unsigned)(WordBits-1-Index);
356 #elif defined(__GNUC__) || defined(__clang__)
357 return sizeof(Word)==8?(
unsigned)__builtin_clzll((
unsigned long long)Value):(unsigned)__builtin_clz((unsigned)Value);
360 while (!(Value>>(WordBits-1))) { Value<<=1; Count++; }
370 #define ZENLIB_BSF_MASK4(N) ((int64u)1<<(N))-1, ((int64u)2<<(N))-1, ((int64u)4<<(N))-1, ((int64u)8<<(N))-1
371 static const int64u Masks[65]=
379 #undef ZENLIB_BSF_MASK4
380 return (Word)Masks[HowMany];
386 #if defined(_MSC_VER) && !defined(__clang__)
389 return _rotr64(Value, (
int)Count);
391 return _rotr(Value, (
int)Count);
394 const unsigned Shift=(unsigned)(Count&(WordBits-1));
395 return (Value>>Shift)|(Value<<((WordBits-Shift)&(WordBits-1)));
404 #if defined(_MSC_VER) && !defined(__clang__)
405 return (RotateRight(Value, Index)&1)!=0;
407 return ((Value>>(Index&(WordBits-1)))&1)!=0;
419 size_t Load=(BitEnd-Buffer_Size)/8;
425 const size_t Avail=BitEnd-Load*8;
426 const size_t WindowLow=Avail-WordBits;
427 Window=RotateRight(LoadWord(Buffer+Load), 0-WindowLow);
428 WindowEnd=Avail>WordBits?WindowLow:0;
437 const size_t Logical=BitEnd/8+(BitEnd%8!=0);
438 const size_t Attached=Buffer_Size_Init/8+ExtraBytes;
439 size_t Readable=Logical+ExtraBytes;
440 if (Readable>Attached)
441 Readable=Logical>Attached?Logical:Attached;
442 if (Readable>=
sizeof(Word))
444 LastLoad=Readable-
sizeof(Word);
456 Window=RotateRight(LoadPartial(Buffer, Readable), WordBits-BitEnd);
473 BufferUnderRun_=
true;
484 if ((
unsigned)(HowMany-1)>=(
unsigned)Max)
486 return Read<Max>(HowMany);
492 if ((
unsigned)(HowMany-1)>=(
unsigned)Max)
494 if (HowMany+WindowEnd>Buffer_Size)
496 if (HowMany>Buffer_Size)
503 if (Max>WordBits-7 && HowMany+WindowEnd>Buffer_Size)
504 return PeekDirect(Buffer_Size, HowMany);
506 return RotateRight(Window, Buffer_Size-HowMany)&Mask(HowMany);
513 if (HowMany+WindowEnd>Buffer_Size)
515 if (HowMany>Buffer_Size)
522 if (Max>WordBits-7 && HowMany+WindowEnd>Buffer_Size)
523 return Read_Split(HowMany);
525 Buffer_Size-=HowMany;
526 return RotateRight(Window, Buffer_Size)&Mask(HowMany);
533 const unsigned High_Size=(unsigned)(Buffer_Size-WindowEnd);
534 Buffer_Size-=High_Size;
535 const Word High=RotateRight(Window, Buffer_Size)&Mask(High_Size);
537 const unsigned Low_Size=HowMany-High_Size;
538 Buffer_Size-=Low_Size;
539 return (High<<Low_Size)|(RotateRight(Window, Buffer_Size)&Mask(Low_Size));
545 if (HowMany<=WordBits)
546 return ReadWide(HowMany);
547 const int64u High=ReadWide(HowMany-32);
548 return (High<<32)|ReadWide(32);
556 if (HowMany+WindowEnd<=Buffer_Size)
557 Value=RotateRight(Window, Buffer_Size-HowMany)&Mask(HowMany);
558 else if (HowMany<=Buffer_Size)
559 Value=PeekDirect(Buffer_Size, HowMany);
565 Buffer_Size-=HowMany;
574 if (HowMany+WindowEnd<=Remaining)
575 return RotateRight(Window, Remaining-HowMany)&Mask(HowMany);
576 return PeekDirect(Remaining, HowMany);
585 const size_t BitPos=BitEnd-Remaining;
586 size_t Load=BitPos/8;
589 const unsigned Shift=(unsigned)(BitPos-Load*8);
590 Word Value=LoadWord(Buffer+Load)<<Shift;
591 if (Shift+HowMany>WordBits)
592 Value|=(Word)(Buffer[Load+
sizeof(Word)]>>(8-Shift));
593 return Value>>(WordBits-HowMany);
603 if (Buffer_Size<=WindowEnd)
605 Bits=RotateRight(Window, Buffer_Size);
611 Size=CountLeadingZeros(Bits)*2+1;
612 return Size<=Buffer_Size-WindowEnd;
624 if (PeekUE(Bits, Size))
627 return (int32u)(Bits>>(WordBits-Size))-1;
632 const int64u Result=GetUE_Bytes(Buffer, BitEnd-Buffer_Size, Buffer_Size);
633 const size_t Code_Size=(size_t)(Result>>32);
636 Buffer_Size-=Code_Size;
637 return (int32u)Result;
648 const unsigned Peeked=(unsigned)
MIN(
Remain, (
size_t)32);
649 const int32u Prefix=ReadBytes(Buffer, BitPos, Peeked)<<(32-Peeked);
652 unsigned LeadingZeroBits=0;
653 while (!(Prefix>>(31-LeadingZeroBits)))
655 if (LeadingZeroBits*2+1>
Remain)
657 const int32u Info=LeadingZeroBits?ReadBytes(Buffer, BitPos+LeadingZeroBits+1, LeadingZeroBits):0;
658 return ((int64u)(LeadingZeroBits*2+1)<<32)|((((int32u)1<<LeadingZeroBits)|Info)-1);
662 static int32u ReadBytes(
const int8u* Buffer,
size_t BitPos,
unsigned HowMany)
664 const int8u* Source=Buffer+BitPos/8;
665 const unsigned Skipped=(unsigned)(BitPos%8);
666 const unsigned Bytes=(Skipped+HowMany+7)/8;
668 for (
unsigned i=0; i<Bytes; i++)
669 Value=(Value<<8)|Source[i];
670 return (int32u)((Value>>(Bytes*8-Skipped-HowMany))&(((int64u)1<<HowMany)-1));
681 size_t Buffer_Size_Init;
683 bool BufferUnderRun_;
714 #undef ZENLIB_BSF_INLINE
715 #undef ZENLIB_BSF_NOINLINE
#define MIN(a, b)
Definition: BitStream_Fast.h:36
#define ZENLIB_BSF_MASK4(N)
#define ZENLIB_BSF_INLINE
Definition: BitStream_Fast.h:46
#define ZENLIB_BSF_NOINLINE
Definition: BitStream_Fast.h:47
#define NULL
Definition: HTTPClientWrapper.h:98
Definition: BitStream_Fast.h:689
void Commit()
Definition: BitStream_Fast.h:699
BitStream_Fast_Local & operator=(const BitStream_Fast_Local &)=delete
BitStream_Fast_Local(BitStream_Fast_Local &&Other)
Definition: BitStream_Fast.h:693
BitStream_Fast_Local(const BitStream_Fast_Local &)=delete
BitStream_Fast_Local(BitStream_Fast &Owner_)
Definition: BitStream_Fast.h:691
Definition: BitStream_Fast.h:91
ZENLIB_BSF_INLINE int32u GetUE()
Definition: BitStream_Fast.h:182
ZENLIB_BSF_INLINE int32u Get4_Unchecked(int8u HowMany)
Definition: BitStream_Fast.h:167
ZENLIB_BSF_INLINE int32s GetSE()
Definition: BitStream_Fast.h:193
ZENLIB_BSF_INLINE void Skip(size_t HowMany)
Definition: BitStream_Fast.h:204
ZENLIB_BSF_INLINE bool GetB()
Definition: BitStream_Fast.h:119
BitStream_Fast(const int8u *Buffer_, size_t Size_, size_t ExtraBytesAvailable_=0)
Definition: BitStream_Fast.h:101
ZENLIB_BSF_INLINE int8u Get1(int8u HowMany)
Definition: BitStream_Fast.h:134
ZENLIB_BSF_INLINE int64u Get8(int8u HowMany)
Definition: BitStream_Fast.h:149
void Refresh()
Definition: BitStream_Fast.h:301
size_t OffsetBeforeLastCall_Get() const
Definition: BitStream_Fast.h:281
ZENLIB_BSF_INLINE void Attach(const int8u *Buffer_, size_t Size_, size_t ExtraBytesAvailable_=0)
Definition: BitStream_Fast.h:105
bool BufferUnderRun() const
Definition: BitStream_Fast.h:200
size_t BitOffset_Get() const
Definition: BitStream_Fast.h:276
ZENLIB_BSF_INLINE int64u Get8_Unchecked(int8u HowMany)
Definition: BitStream_Fast.h:173
void Resize(size_t Size_)
Definition: BitStream_Fast.h:289
ZENLIB_BSF_INLINE int16u Get2(int8u HowMany)
Definition: BitStream_Fast.h:139
BitStream_Fast_Local LocalReader()
Definition: BitStream_Fast.h:709
~BitStream_Fast()
Definition: BitStream_Fast.h:102
size_t Offset_Get() const
Definition: BitStream_Fast.h:271
int64u Peek8(int8u HowMany)
Definition: BitStream_Fast.h:243
ZENLIB_BSF_INLINE bool PeekB()
Definition: BitStream_Fast.h:214
ZENLIB_BSF_INLINE int32u Peek4(int8u HowMany)
Definition: BitStream_Fast.h:238
void Byte_Align()
Definition: BitStream_Fast.h:266
ZENLIB_BSF_INLINE int32u Get4(int8u HowMany)
Definition: BitStream_Fast.h:144
BitStream_Fast()
Definition: BitStream_Fast.h:93
ZENLIB_BSF_INLINE int8u Peek1(int8u HowMany)
Definition: BitStream_Fast.h:228
size_t Remain() const
Definition: BitStream_Fast.h:261
ZENLIB_BSF_INLINE int16u Peek2(int8u HowMany)
Definition: BitStream_Fast.h:233
Definition: BitStream.h:24