Mercurial > vba-linux
diff src/win32/7zip/7z/CPP/7zip/Compress/RangeCoder.h @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/win32/7zip/7z/CPP/7zip/Compress/RangeCoder.h Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,204 @@ 1.4 +// Compress/RangeCoder.h 1.5 + 1.6 +#ifndef __COMPRESS_RANGE_CODER_H 1.7 +#define __COMPRESS_RANGE_CODER_H 1.8 + 1.9 +#include "../Common/InBuffer.h" 1.10 +#include "../Common/OutBuffer.h" 1.11 + 1.12 +namespace NCompress { 1.13 +namespace NRangeCoder { 1.14 + 1.15 +const int kNumTopBits = 24; 1.16 +const UInt32 kTopValue = (1 << kNumTopBits); 1.17 + 1.18 +class CEncoder 1.19 +{ 1.20 + UInt32 _cacheSize; 1.21 + Byte _cache; 1.22 +public: 1.23 + UInt64 Low; 1.24 + UInt32 Range; 1.25 + COutBuffer Stream; 1.26 + bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); } 1.27 + 1.28 + void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); } 1.29 + void Init() 1.30 + { 1.31 + Stream.Init(); 1.32 + Low = 0; 1.33 + Range = 0xFFFFFFFF; 1.34 + _cacheSize = 1; 1.35 + _cache = 0; 1.36 + } 1.37 + 1.38 + void FlushData() 1.39 + { 1.40 + // Low += 1; 1.41 + for(int i = 0; i < 5; i++) 1.42 + ShiftLow(); 1.43 + } 1.44 + 1.45 + HRESULT FlushStream() { return Stream.Flush(); } 1.46 + 1.47 + void ReleaseStream() { Stream.ReleaseStream(); } 1.48 + 1.49 + void Encode(UInt32 start, UInt32 size, UInt32 total) 1.50 + { 1.51 + Low += start * (Range /= total); 1.52 + Range *= size; 1.53 + while (Range < kTopValue) 1.54 + { 1.55 + Range <<= 8; 1.56 + ShiftLow(); 1.57 + } 1.58 + } 1.59 + 1.60 + void ShiftLow() 1.61 + { 1.62 + if ((UInt32)Low < (UInt32)0xFF000000 || (int)(Low >> 32) != 0) 1.63 + { 1.64 + Byte temp = _cache; 1.65 + do 1.66 + { 1.67 + Stream.WriteByte((Byte)(temp + (Byte)(Low >> 32))); 1.68 + temp = 0xFF; 1.69 + } 1.70 + while(--_cacheSize != 0); 1.71 + _cache = (Byte)((UInt32)Low >> 24); 1.72 + } 1.73 + _cacheSize++; 1.74 + Low = (UInt32)Low << 8; 1.75 + } 1.76 + 1.77 + void EncodeDirectBits(UInt32 value, int numBits) 1.78 + { 1.79 + for (numBits--; numBits >= 0; numBits--) 1.80 + { 1.81 + Range >>= 1; 1.82 + Low += Range & (0 - ((value >> numBits) & 1)); 1.83 + if (Range < kTopValue) 1.84 + { 1.85 + Range <<= 8; 1.86 + ShiftLow(); 1.87 + } 1.88 + } 1.89 + } 1.90 + 1.91 + void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol) 1.92 + { 1.93 + UInt32 newBound = (Range >> numTotalBits) * size0; 1.94 + if (symbol == 0) 1.95 + Range = newBound; 1.96 + else 1.97 + { 1.98 + Low += newBound; 1.99 + Range -= newBound; 1.100 + } 1.101 + while (Range < kTopValue) 1.102 + { 1.103 + Range <<= 8; 1.104 + ShiftLow(); 1.105 + } 1.106 + } 1.107 + 1.108 + UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _cacheSize + 4; } 1.109 +}; 1.110 + 1.111 +class CDecoder 1.112 +{ 1.113 +public: 1.114 + CInBuffer Stream; 1.115 + UInt32 Range; 1.116 + UInt32 Code; 1.117 + bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); } 1.118 + 1.119 + void Normalize() 1.120 + { 1.121 + while (Range < kTopValue) 1.122 + { 1.123 + Code = (Code << 8) | Stream.ReadByte(); 1.124 + Range <<= 8; 1.125 + } 1.126 + } 1.127 + 1.128 + void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); } 1.129 + void Init() 1.130 + { 1.131 + Stream.Init(); 1.132 + Code = 0; 1.133 + Range = 0xFFFFFFFF; 1.134 + for(int i = 0; i < 5; i++) 1.135 + Code = (Code << 8) | Stream.ReadByte(); 1.136 + } 1.137 + 1.138 + void ReleaseStream() { Stream.ReleaseStream(); } 1.139 + 1.140 + UInt32 GetThreshold(UInt32 total) 1.141 + { 1.142 + return (Code) / ( Range /= total); 1.143 + } 1.144 + 1.145 + void Decode(UInt32 start, UInt32 size) 1.146 + { 1.147 + Code -= start * Range; 1.148 + Range *= size; 1.149 + Normalize(); 1.150 + } 1.151 + 1.152 + UInt32 DecodeDirectBits(int numTotalBits) 1.153 + { 1.154 + UInt32 range = Range; 1.155 + UInt32 code = Code; 1.156 + UInt32 result = 0; 1.157 + for (int i = numTotalBits; i != 0; i--) 1.158 + { 1.159 + range >>= 1; 1.160 + /* 1.161 + result <<= 1; 1.162 + if (code >= range) 1.163 + { 1.164 + code -= range; 1.165 + result |= 1; 1.166 + } 1.167 + */ 1.168 + UInt32 t = (code - range) >> 31; 1.169 + code -= range & (t - 1); 1.170 + result = (result << 1) | (1 - t); 1.171 + 1.172 + if (range < kTopValue) 1.173 + { 1.174 + code = (code << 8) | Stream.ReadByte(); 1.175 + range <<= 8; 1.176 + } 1.177 + } 1.178 + Range = range; 1.179 + Code = code; 1.180 + return result; 1.181 + } 1.182 + 1.183 + UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) 1.184 + { 1.185 + UInt32 newBound = (Range >> numTotalBits) * size0; 1.186 + UInt32 symbol; 1.187 + if (Code < newBound) 1.188 + { 1.189 + symbol = 0; 1.190 + Range = newBound; 1.191 + } 1.192 + else 1.193 + { 1.194 + symbol = 1; 1.195 + Code -= newBound; 1.196 + Range -= newBound; 1.197 + } 1.198 + Normalize(); 1.199 + return symbol; 1.200 + } 1.201 + 1.202 + UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); } 1.203 +}; 1.204 + 1.205 +}} 1.206 + 1.207 +#endif