Annotation of elwix/tools/oldlzma/SRC/7zip/Compress/RangeCoder/RangeCoder.h, revision 1.1

1.1     ! misho       1: // Compress/RangeCoder/RangeCoder.h
        !             2: 
        !             3: #ifndef __COMPRESS_RANGECODER_H
        !             4: #define __COMPRESS_RANGECODER_H
        !             5: 
        !             6: #include "../../Common/InBuffer.h"
        !             7: #include "../../Common/OutBuffer.h"
        !             8: 
        !             9: namespace NCompress {
        !            10: namespace NRangeCoder {
        !            11: 
        !            12: const int kNumTopBits = 24;
        !            13: const UInt32 kTopValue = (1 << kNumTopBits);
        !            14: 
        !            15: class CEncoder
        !            16: {
        !            17:   UInt32 _ffNum;
        !            18:   Byte _cache;
        !            19: public:
        !            20:   UInt64 Low;
        !            21:   UInt32 Range;
        !            22:   COutBuffer Stream;
        !            23:   bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
        !            24: 
        !            25:   void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); }
        !            26:   void Init()
        !            27:   {
        !            28:     Stream.Init();
        !            29:     Low = 0;
        !            30:     Range = 0xFFFFFFFF;
        !            31:     _ffNum = 0;
        !            32:     _cache = 0;
        !            33:   }
        !            34: 
        !            35:   void FlushData()
        !            36:   {
        !            37:     // Low += 1; 
        !            38:     for(int i = 0; i < 5; i++)
        !            39:       ShiftLow();
        !            40:   }
        !            41: 
        !            42:   HRESULT FlushStream() { return Stream.Flush();  }
        !            43: 
        !            44:   void ReleaseStream() { Stream.ReleaseStream(); }
        !            45: 
        !            46:   void Encode(UInt32 start, UInt32 size, UInt32 total)
        !            47:   {
        !            48:     Low += start * (Range /= total);
        !            49:     Range *= size;
        !            50:     while (Range < kTopValue)
        !            51:     {
        !            52:       Range <<= 8;
        !            53:       ShiftLow();
        !            54:     }
        !            55:   }
        !            56: 
        !            57:   /*
        !            58:   void EncodeDirectBitsDiv(UInt32 value, UInt32 numTotalBits)
        !            59:   {
        !            60:     Low += value * (Range >>= numTotalBits);
        !            61:     Normalize();
        !            62:   }
        !            63:   
        !            64:   void EncodeDirectBitsDiv2(UInt32 value, UInt32 numTotalBits)
        !            65:   {
        !            66:     if (numTotalBits <= kNumBottomBits)
        !            67:       EncodeDirectBitsDiv(value, numTotalBits);
        !            68:     else
        !            69:     {
        !            70:       EncodeDirectBitsDiv(value >> kNumBottomBits, (numTotalBits - kNumBottomBits));
        !            71:       EncodeDirectBitsDiv(value & ((1 << kBottomValueBits) - 1), kNumBottomBits);
        !            72:     }
        !            73:   }
        !            74:   */
        !            75:   void ShiftLow()
        !            76:   {
        !            77:     if (Low < (UInt32)0xFF000000 || UInt32(Low >> 32) == 1) 
        !            78:     {
        !            79:       Stream.WriteByte(Byte(_cache + Byte(Low >> 32)));            
        !            80:       for (;_ffNum != 0; _ffNum--) 
        !            81:         Stream.WriteByte(Byte(0xFF + Byte(Low >> 32)));
        !            82:       _cache = Byte(UInt32(Low) >> 24);                      
        !            83:     } 
        !            84:     else 
        !            85:       _ffNum++;                               
        !            86:     Low = UInt32(Low) << 8;                           
        !            87:   }
        !            88:   
        !            89:   void EncodeDirectBits(UInt32 value, int numTotalBits)
        !            90:   {
        !            91:     for (int i = numTotalBits - 1; i >= 0; i--)
        !            92:     {
        !            93:       Range >>= 1;
        !            94:       if (((value >> i) & 1) == 1)
        !            95:         Low += Range;
        !            96:       if (Range < kTopValue)
        !            97:       {
        !            98:         Range <<= 8;
        !            99:         ShiftLow();
        !           100:       }
        !           101:     }
        !           102:   }
        !           103: 
        !           104:   void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol)
        !           105:   {
        !           106:     UInt32 newBound = (Range >> numTotalBits) * size0;
        !           107:     if (symbol == 0)
        !           108:       Range = newBound;
        !           109:     else
        !           110:     {
        !           111:       Low += newBound;
        !           112:       Range -= newBound;
        !           113:     }
        !           114:     while (Range < kTopValue)
        !           115:     {
        !           116:       Range <<= 8;
        !           117:       ShiftLow();
        !           118:     }
        !           119:   }
        !           120: 
        !           121:   UInt64 GetProcessedSize() {  return Stream.GetProcessedSize() + _ffNum; }
        !           122: };
        !           123: 
        !           124: class CDecoder
        !           125: {
        !           126: public:
        !           127:   CInBuffer Stream;
        !           128:   UInt32 Range;
        !           129:   UInt32 Code;
        !           130:   bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
        !           131: 
        !           132:   void Normalize()
        !           133:   {
        !           134:     while (Range < kTopValue)
        !           135:     {
        !           136:       Code = (Code << 8) | Stream.ReadByte();
        !           137:       Range <<= 8;
        !           138:     }
        !           139:   }
        !           140:   
        !           141:   void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); }
        !           142:   void Init()
        !           143:   {
        !           144:     Stream.Init();
        !           145:     Code = 0;
        !           146:     Range = 0xFFFFFFFF;
        !           147:     for(int i = 0; i < 5; i++)
        !           148:       Code = (Code << 8) | Stream.ReadByte();
        !           149:   }
        !           150: 
        !           151:   void ReleaseStream() { Stream.ReleaseStream(); }
        !           152: 
        !           153:   UInt32 GetThreshold(UInt32 total)
        !           154:   {
        !           155:     return (Code) / ( Range /= total);
        !           156:   }
        !           157: 
        !           158:   void Decode(UInt32 start, UInt32 size)
        !           159:   {
        !           160:     Code -= start * Range;
        !           161:     Range *= size;
        !           162:     Normalize();
        !           163:   }
        !           164: 
        !           165:   /*
        !           166:   UInt32 DecodeDirectBitsDiv(UInt32 numTotalBits)
        !           167:   {
        !           168:     Range >>= numTotalBits;
        !           169:     UInt32 threshold = Code / Range;
        !           170:     Code -= threshold * Range;
        !           171:     
        !           172:     Normalize();
        !           173:     return threshold;
        !           174:   }
        !           175: 
        !           176:   UInt32 DecodeDirectBitsDiv2(UInt32 numTotalBits)
        !           177:   {
        !           178:     if (numTotalBits <= kNumBottomBits)
        !           179:       return DecodeDirectBitsDiv(numTotalBits);
        !           180:     UInt32 result = DecodeDirectBitsDiv(numTotalBits - kNumBottomBits) << kNumBottomBits;
        !           181:     return (result | DecodeDirectBitsDiv(kNumBottomBits));
        !           182:   }
        !           183:   */
        !           184: 
        !           185:   UInt32 DecodeDirectBits(int numTotalBits)
        !           186:   {
        !           187:     UInt32 range = Range;
        !           188:     UInt32 code = Code;        
        !           189:     UInt32 result = 0;
        !           190:     for (int i = numTotalBits; i != 0; i--)
        !           191:     {
        !           192:       range >>= 1;
        !           193:       /*
        !           194:       result <<= 1;
        !           195:       if (code >= range)
        !           196:       {
        !           197:         code -= range;
        !           198:         result |= 1;
        !           199:       }
        !           200:       */
        !           201:       UInt32 t = (code - range) >> 31;
        !           202:       code -= range & (t - 1);
        !           203:       result = (result << 1) | (1 - t);
        !           204: 
        !           205:       if (range < kTopValue)
        !           206:       {
        !           207:         code = (code << 8) | Stream.ReadByte();
        !           208:         range <<= 8; 
        !           209:       }
        !           210:     }
        !           211:     Range = range;
        !           212:     Code = code;
        !           213:     return result;
        !           214:   }
        !           215: 
        !           216:   UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits)
        !           217:   {
        !           218:     UInt32 newBound = (Range >> numTotalBits) * size0;
        !           219:     UInt32 symbol;
        !           220:     if (Code < newBound)
        !           221:     {
        !           222:       symbol = 0;
        !           223:       Range = newBound;
        !           224:     }
        !           225:     else
        !           226:     {
        !           227:       symbol = 1;
        !           228:       Code -= newBound;
        !           229:       Range -= newBound;
        !           230:     }
        !           231:     Normalize();
        !           232:     return symbol;
        !           233:   }
        !           234: 
        !           235:   UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); }
        !           236: };
        !           237: 
        !           238: }}
        !           239: 
        !           240: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>