mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-14 16:11:38 -06:00
4.20
This commit is contained in:
committed by
Kornel Lesiński
parent
8c1b5c7b7e
commit
3c510ba80b
@@ -1,7 +1,4 @@
|
||||
// Compress/RangeCoder.h
|
||||
// This code is based on Eugene Shelwien's Rangecoder code
|
||||
|
||||
// #pragma once
|
||||
// Compress/RangeCoder/RangeCoder.h
|
||||
|
||||
#ifndef __COMPRESS_RANGECODER_H
|
||||
#define __COMPRESS_RANGECODER_H
|
||||
@@ -12,23 +9,25 @@
|
||||
namespace NCompress {
|
||||
namespace NRangeCoder {
|
||||
|
||||
const UINT32 kNumTopBits = 24;
|
||||
const UINT32 kTopValue = (1 << kNumTopBits);
|
||||
const int kNumTopBits = 24;
|
||||
const UInt32 kTopValue = (1 << kNumTopBits);
|
||||
|
||||
class CEncoder
|
||||
{
|
||||
COutBuffer Stream;
|
||||
UINT64 Low;
|
||||
UINT32 Range;
|
||||
UINT32 _ffNum;
|
||||
BYTE _cache;
|
||||
|
||||
UInt32 _ffNum;
|
||||
Byte _cache;
|
||||
public:
|
||||
void Init(ISequentialOutStream *stream)
|
||||
UInt64 Low;
|
||||
UInt32 Range;
|
||||
COutBuffer Stream;
|
||||
bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
|
||||
|
||||
void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); }
|
||||
void Init()
|
||||
{
|
||||
Stream.Init(stream);
|
||||
Stream.Init();
|
||||
Low = 0;
|
||||
Range = UINT32(-1);
|
||||
Range = 0xFFFFFFFF;
|
||||
_ffNum = 0;
|
||||
_cache = 0;
|
||||
}
|
||||
@@ -40,15 +39,11 @@ public:
|
||||
ShiftLow();
|
||||
}
|
||||
|
||||
HRESULT FlushStream()
|
||||
{ return Stream.Flush(); }
|
||||
HRESULT FlushStream() { return Stream.Flush(); }
|
||||
|
||||
/*
|
||||
void ReleaseStream()
|
||||
{ Stream.ReleaseStream(); }
|
||||
*/
|
||||
void ReleaseStream() { Stream.ReleaseStream(); }
|
||||
|
||||
void Encode(UINT32 start, UINT32 size, UINT32 total)
|
||||
void Encode(UInt32 start, UInt32 size, UInt32 total)
|
||||
{
|
||||
Low += start * (Range /= total);
|
||||
Range *= size;
|
||||
@@ -60,13 +55,13 @@ public:
|
||||
}
|
||||
|
||||
/*
|
||||
void EncodeDirectBitsDiv(UINT32 value, UINT32 numTotalBits)
|
||||
void EncodeDirectBitsDiv(UInt32 value, UInt32 numTotalBits)
|
||||
{
|
||||
Low += value * (Range >>= numTotalBits);
|
||||
Normalize();
|
||||
}
|
||||
|
||||
void EncodeDirectBitsDiv2(UINT32 value, UINT32 numTotalBits)
|
||||
void EncodeDirectBitsDiv2(UInt32 value, UInt32 numTotalBits)
|
||||
{
|
||||
if (numTotalBits <= kNumBottomBits)
|
||||
EncodeDirectBitsDiv(value, numTotalBits);
|
||||
@@ -79,19 +74,19 @@ public:
|
||||
*/
|
||||
void ShiftLow()
|
||||
{
|
||||
if (Low < (UINT32)0xFF000000 || UINT32(Low >> 32) == 1)
|
||||
if (Low < (UInt32)0xFF000000 || UInt32(Low >> 32) == 1)
|
||||
{
|
||||
Stream.WriteByte(_cache + BYTE(Low >> 32));
|
||||
Stream.WriteByte(Byte(_cache + Byte(Low >> 32)));
|
||||
for (;_ffNum != 0; _ffNum--)
|
||||
Stream.WriteByte(0xFF + BYTE(Low >> 32));
|
||||
_cache = BYTE(UINT32(Low) >> 24);
|
||||
Stream.WriteByte(Byte(0xFF + Byte(Low >> 32)));
|
||||
_cache = Byte(UInt32(Low) >> 24);
|
||||
}
|
||||
else
|
||||
_ffNum++;
|
||||
Low = UINT32(Low) << 8;
|
||||
Low = UInt32(Low) << 8;
|
||||
}
|
||||
|
||||
void EncodeDirectBits(UINT32 value, UINT32 numTotalBits)
|
||||
void EncodeDirectBits(UInt32 value, int numTotalBits)
|
||||
{
|
||||
for (int i = numTotalBits - 1; i >= 0; i--)
|
||||
{
|
||||
@@ -106,9 +101,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void EncodeBit(UINT32 size0, UINT32 numTotalBits, UINT32 symbol)
|
||||
void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol)
|
||||
{
|
||||
UINT32 newBound = (Range >> numTotalBits) * size0;
|
||||
UInt32 newBound = (Range >> numTotalBits) * size0;
|
||||
if (symbol == 0)
|
||||
Range = newBound;
|
||||
else
|
||||
@@ -123,16 +118,17 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
UINT64 GetProcessedSize() { return Stream.GetProcessedSize() + _ffNum; }
|
||||
UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _ffNum; }
|
||||
};
|
||||
|
||||
class CDecoder
|
||||
{
|
||||
public:
|
||||
CInBuffer Stream;
|
||||
UINT32 Range;
|
||||
UINT32 Code;
|
||||
// UINT32 m_Word;
|
||||
UInt32 Range;
|
||||
UInt32 Code;
|
||||
bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
|
||||
|
||||
void Normalize()
|
||||
{
|
||||
while (Range < kTopValue)
|
||||
@@ -142,23 +138,24 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void Init(ISequentialInStream *stream)
|
||||
void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); }
|
||||
void Init()
|
||||
{
|
||||
Stream.Init(stream);
|
||||
Stream.Init();
|
||||
Code = 0;
|
||||
Range = UINT32(-1);
|
||||
Range = 0xFFFFFFFF;
|
||||
for(int i = 0; i < 5; i++)
|
||||
Code = (Code << 8) | Stream.ReadByte();
|
||||
}
|
||||
|
||||
// void ReleaseStream() { Stream.ReleaseStream(); }
|
||||
void ReleaseStream() { Stream.ReleaseStream(); }
|
||||
|
||||
UINT32 GetThreshold(UINT32 total)
|
||||
UInt32 GetThreshold(UInt32 total)
|
||||
{
|
||||
return (Code) / ( Range /= total);
|
||||
}
|
||||
|
||||
void Decode(UINT32 start, UINT32 size, UINT32 total)
|
||||
void Decode(UInt32 start, UInt32 size)
|
||||
{
|
||||
Code -= start * Range;
|
||||
Range *= size;
|
||||
@@ -166,31 +163,31 @@ public:
|
||||
}
|
||||
|
||||
/*
|
||||
UINT32 DecodeDirectBitsDiv(UINT32 numTotalBits)
|
||||
UInt32 DecodeDirectBitsDiv(UInt32 numTotalBits)
|
||||
{
|
||||
Range >>= numTotalBits;
|
||||
UINT32 threshold = Code / Range;
|
||||
UInt32 threshold = Code / Range;
|
||||
Code -= threshold * Range;
|
||||
|
||||
Normalize();
|
||||
return threshold;
|
||||
}
|
||||
|
||||
UINT32 DecodeDirectBitsDiv2(UINT32 numTotalBits)
|
||||
UInt32 DecodeDirectBitsDiv2(UInt32 numTotalBits)
|
||||
{
|
||||
if (numTotalBits <= kNumBottomBits)
|
||||
return DecodeDirectBitsDiv(numTotalBits);
|
||||
UINT32 result = DecodeDirectBitsDiv(numTotalBits - kNumBottomBits) << kNumBottomBits;
|
||||
UInt32 result = DecodeDirectBitsDiv(numTotalBits - kNumBottomBits) << kNumBottomBits;
|
||||
return (result | DecodeDirectBitsDiv(kNumBottomBits));
|
||||
}
|
||||
*/
|
||||
|
||||
UINT32 DecodeDirectBits(UINT32 numTotalBits)
|
||||
UInt32 DecodeDirectBits(int numTotalBits)
|
||||
{
|
||||
UINT32 range = Range;
|
||||
UINT32 code = Code;
|
||||
UINT32 result = 0;
|
||||
for (UINT32 i = numTotalBits; i > 0; i--)
|
||||
UInt32 range = Range;
|
||||
UInt32 code = Code;
|
||||
UInt32 result = 0;
|
||||
for (int i = numTotalBits; i != 0; i--)
|
||||
{
|
||||
range >>= 1;
|
||||
/*
|
||||
@@ -201,9 +198,8 @@ public:
|
||||
result |= 1;
|
||||
}
|
||||
*/
|
||||
UINT32 t = (code - range) >> 31;
|
||||
UInt32 t = (code - range) >> 31;
|
||||
code -= range & (t - 1);
|
||||
// range = rangeTmp + ((range & 1) & (1 - t));
|
||||
result = (result << 1) | (1 - t);
|
||||
|
||||
if (range < kTopValue)
|
||||
@@ -217,10 +213,10 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
UINT32 DecodeBit(UINT32 size0, UINT32 numTotalBits)
|
||||
UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits)
|
||||
{
|
||||
UINT32 newBound = (Range >> numTotalBits) * size0;
|
||||
UINT32 symbol;
|
||||
UInt32 newBound = (Range >> numTotalBits) * size0;
|
||||
UInt32 symbol;
|
||||
if (Code < newBound)
|
||||
{
|
||||
symbol = 0;
|
||||
@@ -236,7 +232,7 @@ public:
|
||||
return symbol;
|
||||
}
|
||||
|
||||
UINT64 GetProcessedSize() {return Stream.GetProcessedSize(); }
|
||||
UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); }
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -7,12 +7,27 @@
|
||||
namespace NCompress {
|
||||
namespace NRangeCoder {
|
||||
|
||||
CPriceTables::CPriceTables()
|
||||
UInt32 CPriceTables::ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
|
||||
static CPriceTables g_PriceTables;
|
||||
|
||||
CPriceTables::CPriceTables() { Init(); }
|
||||
|
||||
void CPriceTables::Init()
|
||||
{
|
||||
const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
|
||||
for(int i = kNumBits - 1; i >= 0; i--)
|
||||
{
|
||||
UInt32 start = 1 << (kNumBits - i - 1);
|
||||
UInt32 end = 1 << (kNumBits - i);
|
||||
for (UInt32 j = start; j < end; j++)
|
||||
ProbPrices[j] = (i << kNumBitPriceShiftBits) +
|
||||
(((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1));
|
||||
}
|
||||
|
||||
/*
|
||||
// simplest: bad solution
|
||||
for(UINT32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
|
||||
StatePrices[i] = kBitPrice;
|
||||
for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
|
||||
ProbPrices[i] = kBitPrice;
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -21,20 +36,20 @@ CPriceTables::CPriceTables()
|
||||
// float solution
|
||||
double ln2 = log(double(2));
|
||||
double lnAll = log(double(kBitModelTotal >> kNumMoveReducingBits));
|
||||
for(UINT32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
|
||||
StatePrices[i] = UINT32((fabs(lnAll - log(double(i))) / ln2 + kDummyMultMid) * kBitPrice);
|
||||
for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
|
||||
ProbPrices[i] = UInt32((fabs(lnAll - log(double(i))) / ln2 + kDummyMultMid) * kBitPrice);
|
||||
*/
|
||||
|
||||
/*
|
||||
// experimental, slow, solution:
|
||||
for(UINT32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
|
||||
for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
|
||||
{
|
||||
const int kCyclesBits = 5;
|
||||
const UINT32 kCycles = (1 << kCyclesBits);
|
||||
const UInt32 kCycles = (1 << kCyclesBits);
|
||||
|
||||
UINT32 range = UINT32(-1);
|
||||
UINT32 bitCount = 0;
|
||||
for (UINT32 j = 0; j < kCycles; j++)
|
||||
UInt32 range = UInt32(-1);
|
||||
UInt32 bitCount = 0;
|
||||
for (UInt32 j = 0; j < kCycles; j++)
|
||||
{
|
||||
range >>= (kNumBitModelTotalBits - kNumMoveReducingBits);
|
||||
range *= i;
|
||||
@@ -55,23 +70,11 @@ CPriceTables::CPriceTables()
|
||||
range -= (1 << 31);
|
||||
}
|
||||
}
|
||||
StatePrices[i] = (bitCount
|
||||
ProbPrices[i] = (bitCount
|
||||
// + (1 << (kCyclesBits - 1))
|
||||
) >> kCyclesBits;
|
||||
}
|
||||
*/
|
||||
|
||||
const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
|
||||
for(int i = kNumBits - 1; i >= 0; i--)
|
||||
{
|
||||
UINT32 start = 1 << (kNumBits - i - 1);
|
||||
UINT32 end = 1 << (kNumBits - i);
|
||||
for (UINT32 j = start; j < end; j++)
|
||||
StatePrices[j] = (i << kNumBitPriceShiftBits) +
|
||||
(((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1));
|
||||
}
|
||||
}
|
||||
|
||||
CPriceTables g_PriceTables;
|
||||
|
||||
}}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
// Compress/RangeCoder/RangeCoderBit.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __COMPRESS_RANGECODER_BIT_TREE_H
|
||||
#define __COMPRESS_RANGECODER_BIT_TREE_H
|
||||
#ifndef __COMPRESS_RANGECODER_BIT_H
|
||||
#define __COMPRESS_RANGECODER_BIT_H
|
||||
|
||||
#include "RangeCoder.h"
|
||||
|
||||
@@ -11,74 +9,90 @@ namespace NCompress {
|
||||
namespace NRangeCoder {
|
||||
|
||||
const int kNumBitModelTotalBits = 11;
|
||||
const UINT32 kBitModelTotal = (1 << kNumBitModelTotalBits);
|
||||
const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits);
|
||||
|
||||
const int kNumMoveReducingBits = 2;
|
||||
|
||||
const int kNumBitPriceShiftBits = 6;
|
||||
const UINT32 kBitPrice = 1 << kNumBitPriceShiftBits;
|
||||
const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits;
|
||||
|
||||
class CPriceTables
|
||||
{
|
||||
public:
|
||||
UINT32 StatePrices[kBitModelTotal >> kNumMoveReducingBits];
|
||||
static UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
|
||||
static void Init();
|
||||
CPriceTables();
|
||||
};
|
||||
|
||||
extern CPriceTables g_PriceTables;
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// CBitModel
|
||||
|
||||
template <int aNumMoveBits>
|
||||
template <int numMoveBits>
|
||||
class CBitModel
|
||||
{
|
||||
public:
|
||||
UINT32 Probability;
|
||||
void UpdateModel(UINT32 symbol)
|
||||
UInt32 Prob;
|
||||
void UpdateModel(UInt32 symbol)
|
||||
{
|
||||
/*
|
||||
Probability -= (Probability + ((symbol - 1) & ((1 << aNumMoveBits) - 1))) >> aNumMoveBits;
|
||||
Probability += (1 - symbol) << (kNumBitModelTotalBits - aNumMoveBits);
|
||||
Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits;
|
||||
Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits);
|
||||
*/
|
||||
if (symbol == 0)
|
||||
Probability += (kBitModelTotal - Probability) >> aNumMoveBits;
|
||||
Prob += (kBitModelTotal - Prob) >> numMoveBits;
|
||||
else
|
||||
Probability -= (Probability) >> aNumMoveBits;
|
||||
Prob -= (Prob) >> numMoveBits;
|
||||
}
|
||||
public:
|
||||
void Init() { Probability = kBitModelTotal / 2; }
|
||||
void Init() { Prob = kBitModelTotal / 2; }
|
||||
};
|
||||
|
||||
template <int aNumMoveBits>
|
||||
class CBitEncoder: public CBitModel<aNumMoveBits>
|
||||
template <int numMoveBits>
|
||||
class CBitEncoder: public CBitModel<numMoveBits>
|
||||
{
|
||||
public:
|
||||
void Encode(CEncoder *encoder, UINT32 symbol)
|
||||
void Encode(CEncoder *encoder, UInt32 symbol)
|
||||
{
|
||||
encoder->EncodeBit(Probability, kNumBitModelTotalBits, symbol);
|
||||
UpdateModel(symbol);
|
||||
/*
|
||||
encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol);
|
||||
this->UpdateModel(symbol);
|
||||
*/
|
||||
UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob;
|
||||
if (symbol == 0)
|
||||
{
|
||||
encoder->Range = newBound;
|
||||
this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
|
||||
}
|
||||
else
|
||||
{
|
||||
encoder->Low += newBound;
|
||||
encoder->Range -= newBound;
|
||||
this->Prob -= (this->Prob) >> numMoveBits;
|
||||
}
|
||||
if (encoder->Range < kTopValue)
|
||||
{
|
||||
encoder->Range <<= 8;
|
||||
encoder->ShiftLow();
|
||||
}
|
||||
}
|
||||
UINT32 GetPrice(UINT32 symbol) const
|
||||
UInt32 GetPrice(UInt32 symbol) const
|
||||
{
|
||||
return g_PriceTables.StatePrices[
|
||||
(((Probability - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
|
||||
return CPriceTables::ProbPrices[
|
||||
(((this->Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
|
||||
}
|
||||
UInt32 GetPrice0() const { return CPriceTables::ProbPrices[this->Prob >> kNumMoveReducingBits]; }
|
||||
UInt32 GetPrice1() const { return CPriceTables::ProbPrices[(kBitModelTotal - this->Prob) >> kNumMoveReducingBits]; }
|
||||
};
|
||||
|
||||
|
||||
template <int aNumMoveBits>
|
||||
class CBitDecoder: public CBitModel<aNumMoveBits>
|
||||
template <int numMoveBits>
|
||||
class CBitDecoder: public CBitModel<numMoveBits>
|
||||
{
|
||||
public:
|
||||
UINT32 Decode(CDecoder *decoder)
|
||||
UInt32 Decode(CDecoder *decoder)
|
||||
{
|
||||
UINT32 newBound = (decoder->Range >> kNumBitModelTotalBits) * Probability;
|
||||
UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob;
|
||||
if (decoder->Code < newBound)
|
||||
{
|
||||
decoder->Range = newBound;
|
||||
Probability += (kBitModelTotal - Probability) >> aNumMoveBits;
|
||||
this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
|
||||
if (decoder->Range < kTopValue)
|
||||
{
|
||||
decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
|
||||
@@ -90,7 +104,7 @@ public:
|
||||
{
|
||||
decoder->Range -= newBound;
|
||||
decoder->Code -= newBound;
|
||||
Probability -= (Probability) >> aNumMoveBits;
|
||||
this->Prob -= (this->Prob) >> numMoveBits;
|
||||
if (decoder->Range < kTopValue)
|
||||
{
|
||||
decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
|
||||
@@ -103,5 +117,4 @@ public:
|
||||
|
||||
}}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
// Compress/RangeCoder/RangeCoderBitTree.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __COMPRESS_RANGECODER_BIT_H
|
||||
#define __COMPRESS_RANGECODER_BIT_H
|
||||
#ifndef __COMPRESS_RANGECODER_BIT_TREE_H
|
||||
#define __COMPRESS_RANGECODER_BIT_TREE_H
|
||||
|
||||
#include "RangeCoderBit.h"
|
||||
#include "RangeCoderOpt.h"
|
||||
@@ -11,292 +9,152 @@
|
||||
namespace NCompress {
|
||||
namespace NRangeCoder {
|
||||
|
||||
/*
|
||||
template <int numMoveBits> class CMyBitEncoder:
|
||||
public NCompression::NArithmetic::CBitEncoder<numMoveBits> {};
|
||||
template <int numMoveBits> class CMyBitDecoder:
|
||||
public NCompression::NArithmetic::CBitDecoder<numMoveBits> {};
|
||||
*/
|
||||
|
||||
//////////////////////////
|
||||
// CBitTreeEncoder
|
||||
|
||||
template <int numMoveBits, UINT32 NumBitLevels>
|
||||
template <int numMoveBits, int NumBitLevels>
|
||||
class CBitTreeEncoder
|
||||
{
|
||||
CBitEncoder<numMoveBits> Models[1 << NumBitLevels];
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
for(UINT32 i = 1; i < (1 << NumBitLevels); i++)
|
||||
for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
|
||||
Models[i].Init();
|
||||
}
|
||||
void Encode(CEncoder *rangeEncoder, UINT32 symbol)
|
||||
void Encode(CEncoder *rangeEncoder, UInt32 symbol)
|
||||
{
|
||||
UINT32 modelIndex = 1;
|
||||
for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;)
|
||||
UInt32 modelIndex = 1;
|
||||
for (int bitIndex = NumBitLevels; bitIndex != 0 ;)
|
||||
{
|
||||
bitIndex--;
|
||||
UINT32 bit = (symbol >> bitIndex ) & 1;
|
||||
UInt32 bit = (symbol >> bitIndex) & 1;
|
||||
Models[modelIndex].Encode(rangeEncoder, bit);
|
||||
modelIndex = (modelIndex << 1) | bit;
|
||||
}
|
||||
};
|
||||
UINT32 GetPrice(UINT32 symbol) const
|
||||
void ReverseEncode(CEncoder *rangeEncoder, UInt32 symbol)
|
||||
{
|
||||
UINT32 price = 0;
|
||||
UINT32 modelIndex = 1;
|
||||
for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;)
|
||||
UInt32 modelIndex = 1;
|
||||
for (int i = 0; i < NumBitLevels; i++)
|
||||
{
|
||||
bitIndex--;
|
||||
UINT32 bit = (symbol >> bitIndex ) & 1;
|
||||
UInt32 bit = symbol & 1;
|
||||
Models[modelIndex].Encode(rangeEncoder, bit);
|
||||
modelIndex = (modelIndex << 1) | bit;
|
||||
symbol >>= 1;
|
||||
}
|
||||
}
|
||||
UInt32 GetPrice(UInt32 symbol) const
|
||||
{
|
||||
symbol |= (1 << NumBitLevels);
|
||||
UInt32 price = 0;
|
||||
while (symbol != 1)
|
||||
{
|
||||
price += Models[symbol >> 1].GetPrice(symbol & 1);
|
||||
symbol >>= 1;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
UInt32 ReverseGetPrice(UInt32 symbol) const
|
||||
{
|
||||
UInt32 price = 0;
|
||||
UInt32 modelIndex = 1;
|
||||
for (int i = NumBitLevels; i != 0; i--)
|
||||
{
|
||||
UInt32 bit = symbol & 1;
|
||||
symbol >>= 1;
|
||||
price += Models[modelIndex].GetPrice(bit);
|
||||
modelIndex = (modelIndex << 1) + bit;
|
||||
modelIndex = (modelIndex << 1) | bit;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////
|
||||
// CBitTreeDecoder
|
||||
|
||||
template <int numMoveBits, UINT32 NumBitLevels>
|
||||
template <int numMoveBits, int NumBitLevels>
|
||||
class CBitTreeDecoder
|
||||
{
|
||||
CBitDecoder<numMoveBits> Models[1 << NumBitLevels];
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
for(UINT32 i = 1; i < (1 << NumBitLevels); i++)
|
||||
for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
|
||||
Models[i].Init();
|
||||
}
|
||||
UINT32 Decode(CDecoder *rangeDecoder)
|
||||
UInt32 Decode(CDecoder *rangeDecoder)
|
||||
{
|
||||
UINT32 modelIndex = 1;
|
||||
UInt32 modelIndex = 1;
|
||||
RC_INIT_VAR
|
||||
for(UINT32 bitIndex = NumBitLevels; bitIndex > 0; bitIndex--)
|
||||
for(int bitIndex = NumBitLevels; bitIndex != 0; bitIndex--)
|
||||
{
|
||||
// modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder);
|
||||
RC_GETBIT(numMoveBits, Models[modelIndex].Probability, modelIndex)
|
||||
RC_GETBIT(numMoveBits, Models[modelIndex].Prob, modelIndex)
|
||||
}
|
||||
RC_FLUSH_VAR
|
||||
return modelIndex - (1 << NumBitLevels);
|
||||
};
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
// CReverseBitTreeEncoder
|
||||
|
||||
template <int numMoveBits>
|
||||
class CReverseBitTreeEncoder2
|
||||
{
|
||||
CBitEncoder<numMoveBits> *Models;
|
||||
UINT32 NumBitLevels;
|
||||
public:
|
||||
CReverseBitTreeEncoder2(): Models(0) { }
|
||||
~CReverseBitTreeEncoder2() { delete []Models; }
|
||||
void Create(UINT32 numBitLevels)
|
||||
UInt32 ReverseDecode(CDecoder *rangeDecoder)
|
||||
{
|
||||
NumBitLevels = numBitLevels;
|
||||
Models = new CBitEncoder<numMoveBits>[1 << numBitLevels];
|
||||
// return (Models != 0);
|
||||
}
|
||||
void Init()
|
||||
{
|
||||
UINT32 numModels = 1 << NumBitLevels;
|
||||
for(UINT32 i = 1; i < numModels; i++)
|
||||
Models[i].Init();
|
||||
}
|
||||
void Encode(CEncoder *rangeEncoder, UINT32 symbol)
|
||||
{
|
||||
UINT32 modelIndex = 1;
|
||||
for (UINT32 i = 0; i < NumBitLevels; i++)
|
||||
{
|
||||
UINT32 bit = symbol & 1;
|
||||
Models[modelIndex].Encode(rangeEncoder, bit);
|
||||
modelIndex = (modelIndex << 1) | bit;
|
||||
symbol >>= 1;
|
||||
}
|
||||
}
|
||||
UINT32 GetPrice(UINT32 symbol) const
|
||||
{
|
||||
UINT32 price = 0;
|
||||
UINT32 modelIndex = 1;
|
||||
for (UINT32 i = NumBitLevels; i > 0; i--)
|
||||
{
|
||||
UINT32 bit = symbol & 1;
|
||||
symbol >>= 1;
|
||||
price += Models[modelIndex].GetPrice(bit);
|
||||
modelIndex = (modelIndex << 1) | bit;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
template <int numMoveBits, int numBitLevels>
|
||||
class CReverseBitTreeEncoder: public CReverseBitTreeEncoder2<numMoveBits>
|
||||
{
|
||||
public:
|
||||
CReverseBitTreeEncoder()
|
||||
{ Create(numBitLevels); }
|
||||
};
|
||||
*/
|
||||
////////////////////////////////
|
||||
// CReverseBitTreeDecoder
|
||||
|
||||
template <int numMoveBits>
|
||||
class CReverseBitTreeDecoder2
|
||||
{
|
||||
CBitDecoder<numMoveBits> *Models;
|
||||
UINT32 NumBitLevels;
|
||||
public:
|
||||
CReverseBitTreeDecoder2(): Models(0) { }
|
||||
~CReverseBitTreeDecoder2() { delete []Models; }
|
||||
void Create(UINT32 numBitLevels)
|
||||
{
|
||||
NumBitLevels = numBitLevels;
|
||||
Models = new CBitDecoder<numMoveBits>[1 << numBitLevels];
|
||||
// return (Models != 0);
|
||||
}
|
||||
void Init()
|
||||
{
|
||||
UINT32 numModels = 1 << NumBitLevels;
|
||||
for(UINT32 i = 1; i < numModels; i++)
|
||||
Models[i].Init();
|
||||
}
|
||||
UINT32 Decode(CDecoder *rangeDecoder)
|
||||
{
|
||||
UINT32 modelIndex = 1;
|
||||
UINT32 symbol = 0;
|
||||
UInt32 modelIndex = 1;
|
||||
UInt32 symbol = 0;
|
||||
RC_INIT_VAR
|
||||
for(UINT32 bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
|
||||
for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
|
||||
{
|
||||
// UINT32 bit = Models[modelIndex].Decode(rangeDecoder);
|
||||
// UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
|
||||
// modelIndex <<= 1;
|
||||
// modelIndex += bit;
|
||||
// symbol |= (bit << bitIndex);
|
||||
RC_GETBIT2(numMoveBits, Models[modelIndex].Probability, modelIndex, ; , symbol |= (1 << bitIndex))
|
||||
}
|
||||
RC_FLUSH_VAR
|
||||
return symbol;
|
||||
};
|
||||
};
|
||||
////////////////////////////
|
||||
// CReverseBitTreeDecoder2
|
||||
|
||||
template <int numMoveBits, UINT32 NumBitLevels>
|
||||
class CReverseBitTreeDecoder
|
||||
{
|
||||
CBitDecoder<numMoveBits> Models[1 << NumBitLevels];
|
||||
public:
|
||||
void Init()
|
||||
{
|
||||
for(UINT32 i = 1; i < (1 << NumBitLevels); i++)
|
||||
Models[i].Init();
|
||||
}
|
||||
UINT32 Decode(CDecoder *rangeDecoder)
|
||||
{
|
||||
UINT32 modelIndex = 1;
|
||||
UINT32 symbol = 0;
|
||||
RC_INIT_VAR
|
||||
for(UINT32 bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
|
||||
{
|
||||
// UINT32 bit = Models[modelIndex].Decode(rangeDecoder);
|
||||
// modelIndex <<= 1;
|
||||
// modelIndex += bit;
|
||||
// symbol |= (bit << bitIndex);
|
||||
RC_GETBIT2(numMoveBits, Models[modelIndex].Probability, modelIndex, ; , symbol |= (1 << bitIndex))
|
||||
RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
|
||||
}
|
||||
RC_FLUSH_VAR
|
||||
return symbol;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
//////////////////////////
|
||||
// CBitTreeEncoder2
|
||||
template <int numMoveBits>
|
||||
void ReverseBitTreeEncode(CBitEncoder<numMoveBits> *Models,
|
||||
CEncoder *rangeEncoder, int NumBitLevels, UInt32 symbol)
|
||||
{
|
||||
UInt32 modelIndex = 1;
|
||||
for (int i = 0; i < NumBitLevels; i++)
|
||||
{
|
||||
UInt32 bit = symbol & 1;
|
||||
Models[modelIndex].Encode(rangeEncoder, bit);
|
||||
modelIndex = (modelIndex << 1) | bit;
|
||||
symbol >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
template <int numMoveBits>
|
||||
class CBitTreeEncoder2
|
||||
UInt32 ReverseBitTreeGetPrice(CBitEncoder<numMoveBits> *Models,
|
||||
UInt32 NumBitLevels, UInt32 symbol)
|
||||
{
|
||||
NCompression::NArithmetic::CBitEncoder<numMoveBits> *Models;
|
||||
UINT32 NumBitLevels;
|
||||
public:
|
||||
bool Create(UINT32 numBitLevels)
|
||||
{
|
||||
NumBitLevels = numBitLevels;
|
||||
Models = new NCompression::NArithmetic::CBitEncoder<numMoveBits>[1 << numBitLevels];
|
||||
return (Models != 0);
|
||||
}
|
||||
void Init()
|
||||
UInt32 price = 0;
|
||||
UInt32 modelIndex = 1;
|
||||
for (int i = NumBitLevels; i != 0; i--)
|
||||
{
|
||||
UINT32 numModels = 1 << NumBitLevels;
|
||||
for(UINT32 i = 1; i < numModels; i++)
|
||||
Models[i].Init();
|
||||
UInt32 bit = symbol & 1;
|
||||
symbol >>= 1;
|
||||
price += Models[modelIndex].GetPrice(bit);
|
||||
modelIndex = (modelIndex << 1) | bit;
|
||||
}
|
||||
void Encode(CMyRangeEncoder *rangeEncoder, UINT32 symbol)
|
||||
{
|
||||
UINT32 modelIndex = 1;
|
||||
for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;)
|
||||
{
|
||||
bitIndex--;
|
||||
UINT32 bit = (symbol >> bitIndex ) & 1;
|
||||
Models[modelIndex].Encode(rangeEncoder, bit);
|
||||
modelIndex = (modelIndex << 1) | bit;
|
||||
}
|
||||
}
|
||||
UINT32 GetPrice(UINT32 symbol) const
|
||||
{
|
||||
UINT32 price = 0;
|
||||
UINT32 modelIndex = 1;
|
||||
for (UINT32 bitIndex = NumBitLevels; bitIndex > 0 ;)
|
||||
{
|
||||
bitIndex--;
|
||||
UINT32 bit = (symbol >> bitIndex ) & 1;
|
||||
price += Models[modelIndex].GetPrice(bit);
|
||||
modelIndex = (modelIndex << 1) + bit;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////
|
||||
// CBitTreeDecoder2
|
||||
return price;
|
||||
}
|
||||
|
||||
template <int numMoveBits>
|
||||
class CBitTreeDecoder2
|
||||
UInt32 ReverseBitTreeDecode(CBitDecoder<numMoveBits> *Models,
|
||||
CDecoder *rangeDecoder, int NumBitLevels)
|
||||
{
|
||||
NCompression::NArithmetic::CBitDecoder<numMoveBits> *Models;
|
||||
UINT32 NumBitLevels;
|
||||
public:
|
||||
bool Create(UINT32 numBitLevels)
|
||||
{
|
||||
NumBitLevels = numBitLevels;
|
||||
Models = new NCompression::NArithmetic::CBitDecoder<numMoveBits>[1 << numBitLevels];
|
||||
return (Models != 0);
|
||||
}
|
||||
void Init()
|
||||
UInt32 modelIndex = 1;
|
||||
UInt32 symbol = 0;
|
||||
RC_INIT_VAR
|
||||
for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
|
||||
{
|
||||
UINT32 numModels = 1 << NumBitLevels;
|
||||
for(UINT32 i = 1; i < numModels; i++)
|
||||
Models[i].Init();
|
||||
// UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
|
||||
// modelIndex <<= 1;
|
||||
// modelIndex += bit;
|
||||
// symbol |= (bit << bitIndex);
|
||||
RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
|
||||
}
|
||||
UINT32 Decode(CMyRangeDecoder *rangeDecoder)
|
||||
{
|
||||
UINT32 modelIndex = 1;
|
||||
RC_INIT_VAR
|
||||
for(UINT32 bitIndex = NumBitLevels; bitIndex > 0; bitIndex--)
|
||||
{
|
||||
// modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder);
|
||||
RC_GETBIT(numMoveBits, Models[modelIndex].Probability, modelIndex)
|
||||
}
|
||||
RC_FLUSH_VAR
|
||||
return modelIndex - (1 << NumBitLevels);
|
||||
}
|
||||
};
|
||||
*/
|
||||
RC_FLUSH_VAR
|
||||
return symbol;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
|
||||
@@ -1,43 +1,31 @@
|
||||
// Compress/RangeCoder/RangeCoderOpt.h
|
||||
|
||||
// #pragma once
|
||||
|
||||
#ifndef __COMPRESS_RANGECODER_OPT_H
|
||||
#define __COMPRESS_RANGECODER_OPT_H
|
||||
|
||||
#define RC_INIT_VAR \
|
||||
UINT32 range = rangeDecoder->Range; \
|
||||
UINT32 code = rangeDecoder->Code;
|
||||
#define RC_INIT_VAR \
|
||||
UInt32 range = rangeDecoder->Range; \
|
||||
UInt32 code = rangeDecoder->Code;
|
||||
|
||||
#define RC_FLUSH_VAR \
|
||||
rangeDecoder->Range = range; \
|
||||
#define RC_FLUSH_VAR \
|
||||
rangeDecoder->Range = range; \
|
||||
rangeDecoder->Code = code;
|
||||
|
||||
#define RC_NORMALIZE \
|
||||
if (range < NCompress::NRangeCoder::kTopValue) \
|
||||
{ \
|
||||
code = (code << 8) | rangeDecoder->Stream.ReadByte(); \
|
||||
range <<= 8; }
|
||||
#define RC_NORMALIZE \
|
||||
if (range < NCompress::NRangeCoder::kTopValue) \
|
||||
{ code = (code << 8) | rangeDecoder->Stream.ReadByte(); range <<= 8; }
|
||||
|
||||
#define RC_GETBIT2(numMoveBits, prob, modelIndex, Action0, Action1) \
|
||||
{UINT32 newBound = (range >> NCompress::NRangeCoder::kNumBitModelTotalBits) * prob; \
|
||||
if (code < newBound) \
|
||||
{ \
|
||||
Action0; \
|
||||
range = newBound; \
|
||||
prob += (NCompress::NRangeCoder::kBitModelTotal - prob) >> numMoveBits; \
|
||||
modelIndex <<= 1; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
Action1; \
|
||||
range -= newBound; \
|
||||
code -= newBound; \
|
||||
prob -= (prob) >> numMoveBits; \
|
||||
modelIndex = (modelIndex << 1) + 1; \
|
||||
}} \
|
||||
RC_NORMALIZE
|
||||
#define RC_GETBIT2(numMoveBits, prob, mi, A0, A1) \
|
||||
{ UInt32 bound = (range >> NCompress::NRangeCoder::kNumBitModelTotalBits) * prob; \
|
||||
if (code < bound) \
|
||||
{ A0; range = bound; \
|
||||
prob += (NCompress::NRangeCoder::kBitModelTotal - prob) >> numMoveBits; \
|
||||
mi <<= 1; } \
|
||||
else \
|
||||
{ A1; range -= bound; code -= bound; prob -= (prob) >> numMoveBits; \
|
||||
mi = (mi + mi) + 1; }} \
|
||||
RC_NORMALIZE
|
||||
|
||||
#define RC_GETBIT(numMoveBits, prob, modelIndex) RC_GETBIT2(numMoveBits, prob, modelIndex, ; , ;)
|
||||
#define RC_GETBIT(numMoveBits, prob, mi) RC_GETBIT2(numMoveBits, prob, mi, ; , ;)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// stdafx.h
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user