nsis64 / Source / 7zip / 7zip / Compress / RangeCoder / RangeCoderBit.h

/*
 * RangeCoderBit.h
 * 
 * This file is a part of LZMA compression module for NSIS.
 * 
 * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
 * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
 * 
 * Licensed under the Common Public License version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * 
 * Licence details can be found in the file COPYING.
 * 
 * This software is provided 'as-is', without any express or implied
 * warranty.
 */

#ifndef __COMPRESS_RANGECODER_BIT_H
#define __COMPRESS_RANGECODER_BIT_H

#include "RangeCoder.h"

namespace NCompress {
namespace NRangeCoder {

const int kNumBitModelTotalBits  = 11;
const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits);

const int kNumMoveReducingBits = 2;

const int kNumBitPriceShiftBits = 6;
const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits;

class CPriceTables
{
public:
  static UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
  static void Init();
  CPriceTables();
};

template <int numMoveBits>
class CBitModel
{
public:
  UInt32 Prob;
  void UpdateModel(UInt32 symbol)
  {
    /*
    Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits;
    Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits);
    */
    if (symbol == 0)
      Prob += (kBitModelTotal - Prob) >> numMoveBits;
    else
      Prob -= (Prob) >> numMoveBits;
  }
public:
  void Init() { Prob = kBitModelTotal / 2; }
};

template <int numMoveBits>
class CBitEncoder: public CBitModel<numMoveBits>
{
public:
  void Encode(CEncoder *encoder, UInt32 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
  {
    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 numMoveBits>
class CBitDecoder: public CBitModel<numMoveBits>
{
public:
  UInt32 Decode(CDecoder *decoder)
  {
    UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob;
    if (decoder->Code < newBound)
    {
      decoder->Range = newBound;
      this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
      if (decoder->Range < kTopValue)
      {
        decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
        decoder->Range <<= 8;
      }
      return 0;
    }
    else
    {
      decoder->Range -= newBound;
      decoder->Code -= newBound;
      this->Prob -= (this->Prob) >> numMoveBits;
      if (decoder->Range < kTopValue)
      {
        decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
        decoder->Range <<= 8;
      }
      return 1;
    }
  }
};

}}

#endif
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.