ppmdencoder.cpp
来自「由7-zip提供的压缩、解压缩程序」· C++ 代码 · 共 156 行
CPP
156 行
// Compress/Associative/Encoder.h#include "StdAfx.h"#include "Windows/Defs.h"// #include <fstream.h>// #include <iomanip.h>#include "Common/Defs.h"#include "../../Common/StreamUtils.h"#include "PPMDEncoder.h"namespace NCompress {namespace NPPMD {const UInt32 kMinMemSize = (1 << 11); const UInt32 kMinOrder = 2;/*UInt32 g_NumInner = 0;UInt32 g_InnerCycles = 0;UInt32 g_Encode2 = 0;UInt32 g_Encode2Cycles = 0;UInt32 g_Encode2Cycles2 = 0;class CCounter{public: CCounter() {} ~CCounter() { ofstream ofs("Res.dat"); ofs << "innerEncode1 = " << setw(10) << g_NumInner << endl; ofs << "g_InnerCycles = " << setw(10) << g_InnerCycles << endl; ofs << "g_Encode2 = " << setw(10) << g_Encode2 << endl; ofs << "g_Encode2Cycles = " << setw(10) << g_Encode2Cycles << endl; ofs << "g_Encode2Cycles2= " << setw(10) << g_Encode2Cycles2 << endl; }};CCounter g_Counter;*/STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *properties, UInt32 numProperties){ for (UInt32 i = 0; i < numProperties; i++) { const PROPVARIANT &prop = properties[i]; switch(propIDs[i]) { case NCoderPropID::kUsedMemorySize: if (prop.vt != VT_UI4) return E_INVALIDARG; if (prop.ulVal < kMinMemSize || prop.ulVal > kMaxMemBlockSize) return E_INVALIDARG; _usedMemorySize = (UInt32)prop.ulVal; break; case NCoderPropID::kOrder: if (prop.vt != VT_UI4) return E_INVALIDARG; if (prop.ulVal < kMinOrder || prop.ulVal > kMaxOrderCompress) return E_INVALIDARG; _order = (Byte)prop.ulVal; break; default: return E_INVALIDARG; } } return S_OK;}STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream){ const UInt32 kPropSize = 5; Byte properties[kPropSize]; properties[0] = _order; for (int i = 0; i < 4; i++) properties[1 + i] = Byte(_usedMemorySize >> (8 * i)); return WriteStream(outStream, properties, kPropSize, NULL);}const UInt32 kUsedMemorySizeDefault = (1 << 24);const int kOrderDefault = 6;CEncoder::CEncoder(): _usedMemorySize(kUsedMemorySizeDefault), _order(kOrderDefault){}HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress){ if (!_inStream.Create(1 << 20)) return E_OUTOFMEMORY; if (!_rangeEncoder.Create(1 << 20)) return E_OUTOFMEMORY; if (!_info.SubAllocator.StartSubAllocator(_usedMemorySize)) return E_OUTOFMEMORY; _inStream.SetStream(inStream); _inStream.Init(); _rangeEncoder.SetStream(outStream); _rangeEncoder.Init(); CEncoderFlusher flusher(this); _info.MaxOrder = 0; _info.StartModelRare(_order); while(true) { UInt32 size = (1 << 18); do { Byte symbol; if (!_inStream.ReadByte(symbol)) { // here we can write End Mark for stream version. // In current version this feature is not used. // _info.EncodeSymbol(-1, &_rangeEncoder); return S_OK; } _info.EncodeSymbol(symbol, &_rangeEncoder); } while (--size != 0); if (progress != NULL) { UInt64 inSize = _inStream.GetProcessedSize(); UInt64 outSize = _rangeEncoder.GetProcessedSize(); RINOK(progress->SetRatioInfo(&inSize, &outSize)); } }}STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress){ try { return CodeReal(inStream, outStream, inSize, outSize, progress); } catch(const COutBufferException &e) { return e.ErrorCode; } catch(const CInBufferException &e) { return e.ErrorCode; } catch(...) { return E_FAIL; }}}}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?