Path: blob/main/misc/emulator/xnes/snes9x/jma/rngcoder.h
28798 views
/*1Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )2Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )34This library is free software; you can redistribute it and/or5modify it under the terms of the GNU Lesser General Public6License version 2.1 as published by the Free Software Foundation.78This library is distributed in the hope that it will be useful,9but WITHOUT ANY WARRANTY; without even the implied warranty of10MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU11Lesser General Public License for more details.1213You should have received a copy of the GNU Lesser General Public14License along with this library; if not, write to the Free Software15Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA16*/1718#ifndef __COMPRESSION_RANGECODER_H19#define __COMPRESSION_RANGECODER_H2021#include "inbyte.h"2223namespace NCompression {24namespace NArithmetic {2526const UINT32 kNumTopBits = 24;27const UINT32 kTopValue = (1 << kNumTopBits);2829class CRangeDecoder30{31public:32NStream::CInByte m_Stream;33UINT32 m_Range;34UINT32 m_Code;35UINT32 m_Word;36void Normalize()37{38while (m_Range < kTopValue)39{40m_Code = (m_Code << 8) | m_Stream.ReadByte();41m_Range <<= 8;42}43}4445void Init(ISequentialInStream *aStream)46{47m_Stream.Init(aStream);48m_Code = 0;49m_Range = UINT32(-1);50for(int i = 0; i < 5; i++)51m_Code = (m_Code << 8) | m_Stream.ReadByte();52}5354UINT32 GetThreshold(UINT32 aTotal)55{56return (m_Code) / ( m_Range /= aTotal);57}5859void Decode(UINT32 aStart, UINT32 aSize, UINT32 aTotal)60{61m_Code -= aStart * m_Range;62m_Range *= aSize;63Normalize();64}6566/*67UINT32 DecodeDirectBitsDiv(UINT32 aNumTotalBits)68{69m_Range >>= aNumTotalBits;70UINT32 aThreshold = m_Code / m_Range;71m_Code -= aThreshold * m_Range;7273Normalize();74return aThreshold;75}7677UINT32 DecodeDirectBitsDiv2(UINT32 aNumTotalBits)78{79if (aNumTotalBits <= kNumBottomBits)80return DecodeDirectBitsDiv(aNumTotalBits);81UINT32 aResult = DecodeDirectBitsDiv(aNumTotalBits - kNumBottomBits) << kNumBottomBits;82return (aResult | DecodeDirectBitsDiv(kNumBottomBits));83}84*/8586UINT32 DecodeDirectBits(UINT32 aNumTotalBits)87{88UINT32 aRange = m_Range;89UINT32 aCode = m_Code;90UINT32 aResult = 0;91for (UINT32 i = aNumTotalBits; i > 0; i--)92{93aRange >>= 1;94/*95aResult <<= 1;96if (aCode >= aRange)97{98aCode -= aRange;99aResult |= 1;100}101*/102UINT32 t = (aCode - aRange) >> 31;103aCode -= aRange & (t - 1);104// aRange = aRangeTmp + ((aRange & 1) & (1 - t));105aResult = (aResult << 1) | (1 - t);106107if (aRange < kTopValue)108{109aCode = (aCode << 8) | m_Stream.ReadByte();110aRange <<= 8;111}112}113m_Range = aRange;114m_Code = aCode;115return aResult;116}117118UINT32 DecodeBit(UINT32 aSize0, UINT32 aNumTotalBits)119{120UINT32 aNewBound = (m_Range >> aNumTotalBits) * aSize0;121UINT32 aSymbol;122if (m_Code < aNewBound)123{124aSymbol = 0;125m_Range = aNewBound;126}127else128{129aSymbol = 1;130m_Code -= aNewBound;131m_Range -= aNewBound;132}133Normalize();134return aSymbol;135}136137UINT64 GetProcessedSize() {return m_Stream.GetProcessedSize(); }138};139140}}141142#endif143144145