Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '7zip/Compress/LZMA/LZMAEncoder.h')
-rwxr-xr-x7zip/Compress/LZMA/LZMAEncoder.h294
1 files changed, 294 insertions, 0 deletions
diff --git a/7zip/Compress/LZMA/LZMAEncoder.h b/7zip/Compress/LZMA/LZMAEncoder.h
new file mode 100755
index 00000000..7e29ee51
--- /dev/null
+++ b/7zip/Compress/LZMA/LZMAEncoder.h
@@ -0,0 +1,294 @@
+// LZMA/Encoder.h
+
+// #pragma once
+
+#ifndef __LZMA_ENCODER_H
+#define __LZMA_ENCODER_H
+
+#include "../../ICoder.h"
+#include "../../../Common/MyCom.h"
+#include "../LZ/IMatchFinder.h"
+
+#include "LZMA.h"
+#include "LZMALen.h"
+#include "LZMALiteral.h"
+
+namespace NCompress {
+namespace NLZMA {
+
+class CMatchFinderException
+{
+public:
+ HRESULT ErrorCode;
+ CMatchFinderException(HRESULT errorCode): ErrorCode(errorCode) {}
+};
+
+struct COptimal
+{
+ CState State;
+
+ bool Prev1IsChar;
+ bool Prev2;
+
+ UINT32 PosPrev2;
+ UINT32 BackPrev2;
+
+ UINT32 Price;
+ UINT32 PosPrev; // posNext;
+ UINT32 BackPrev;
+ UINT32 Backs[kNumRepDistances];
+ void MakeAsChar() { BackPrev = UINT32(-1); Prev1IsChar = false; }
+ void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; }
+ bool IsShortRep() { return (BackPrev == 0); }
+};
+
+
+extern BYTE g_FastPos[1024];
+inline UINT32 GetPosSlot(UINT32 pos)
+{
+ if (pos < (1 << 10))
+ return g_FastPos[pos];
+ if (pos < (1 << 19))
+ return g_FastPos[pos >> 9] + 18;
+ return g_FastPos[pos >> 18] + 36;
+}
+
+inline UINT32 GetPosSlot2(UINT32 pos)
+{
+ if (pos < (1 << 16))
+ return g_FastPos[pos >> 6] + 12;
+ if (pos < (1 << 25))
+ return g_FastPos[pos >> 15] + 30;
+ return g_FastPos[pos >> 24] + 48;
+}
+
+const UINT32 kIfinityPrice = 0xFFFFFFF;
+
+typedef NRangeCoder::CBitEncoder<kNumMoveBits> CMyBitEncoder;
+
+const UINT32 kNumOpts = 1 << 12;
+
+class CEncoder :
+ public ICompressCoder,
+ // public IInitMatchFinder,
+ public ICompressSetCoderProperties,
+ public ICompressWriteCoderProperties,
+ public CBaseCoder,
+ public CMyUnknownImp
+{
+ COptimal _optimum[kNumOpts];
+public:
+ CMyComPtr<IMatchFinder> _matchFinder; // test it
+ NRangeCoder::CEncoder _rangeEncoder;
+private:
+
+ CMyBitEncoder _mainChoiceEncoders[kNumStates][NLength::kNumPosStatesEncodingMax];
+ CMyBitEncoder _matchChoiceEncoders[kNumStates];
+ CMyBitEncoder _matchRepChoiceEncoders[kNumStates];
+ CMyBitEncoder _matchRep1ChoiceEncoders[kNumStates];
+ CMyBitEncoder _matchRep2ChoiceEncoders[kNumStates];
+ CMyBitEncoder _matchRepShortChoiceEncoders[kNumStates][NLength::kNumPosStatesEncodingMax];
+
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumPosSlotBits> _posSlotEncoder[kNumLenToPosStates];
+
+ NRangeCoder::CReverseBitTreeEncoder2<kNumMoveBits> _posEncoders[kNumPosModels];
+ NRangeCoder::CReverseBitTreeEncoder2<kNumMoveBits> _posAlignEncoder;
+
+ NLength::CPriceTableEncoder _lenEncoder;
+ NLength::CPriceTableEncoder _repMatchLenEncoder;
+
+ NLiteral::CEncoder _literalEncoder;
+
+ UINT32 _matchDistances[kMatchMaxLen + 1];
+
+ bool _fastMode;
+ bool _maxMode;
+ UINT32 _numFastBytes;
+ UINT32 _longestMatchLength;
+
+ UINT32 _additionalOffset;
+
+ UINT32 _optimumEndIndex;
+ UINT32 _optimumCurrentIndex;
+
+ bool _longestMatchWasFound;
+
+ UINT32 _posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
+
+ UINT32 _distancesPrices[kNumLenToPosStates][kNumFullDistances];
+
+ UINT32 _alignPrices[kAlignTableSize];
+ UINT32 _alignPriceCount;
+
+ UINT32 _distTableSize;
+
+ UINT32 _posStateBits;
+ UINT32 _posStateMask;
+ UINT32 _numLiteralPosStateBits;
+ UINT32 _numLiteralContextBits;
+
+ UINT32 _dictionarySize;
+
+ UINT32 _dictionarySizePrev;
+ UINT32 _numFastBytesPrev;
+
+ UINT64 lastPosSlotFillingPos;
+ UINT64 nowPos64;
+ bool _finished;
+ ISequentialInStream *_inStream;
+
+ int _matchFinderIndex;
+ #ifdef COMPRESS_MF_MT
+ bool _multiThread;
+ #endif
+
+ bool _writeEndMark;
+
+ UINT32 ReadMatchDistances()
+ {
+ UINT32 len = _matchFinder->GetLongestMatch(_matchDistances);
+ if (len == _numFastBytes)
+ len += _matchFinder->GetMatchLen(len, _matchDistances[len],
+ kMatchMaxLen - len);
+ _additionalOffset++;
+ HRESULT result = _matchFinder->MovePos();
+ if (result != S_OK)
+ throw CMatchFinderException(result);
+ return len;
+ }
+
+ void MovePos(UINT32 num);
+ UINT32 GetRepLen1Price(CState state, UINT32 posState) const
+ {
+ return _matchRepChoiceEncoders[state.Index].GetPrice(0) +
+ _matchRepShortChoiceEncoders[state.Index][posState].GetPrice(0);
+ }
+ UINT32 GetRepPrice(UINT32 repIndex, UINT32 len, CState state, UINT32 posState) const
+ {
+ UINT32 price = _repMatchLenEncoder.GetPrice(len - kMatchMinLen, posState);
+ if(repIndex == 0)
+ {
+ price += _matchRepChoiceEncoders[state.Index].GetPrice(0);
+ price += _matchRepShortChoiceEncoders[state.Index][posState].GetPrice(1);
+ }
+ else
+ {
+ price += _matchRepChoiceEncoders[state.Index].GetPrice(1);
+ if (repIndex == 1)
+ price += _matchRep1ChoiceEncoders[state.Index].GetPrice(0);
+ else
+ {
+ price += _matchRep1ChoiceEncoders[state.Index].GetPrice(1);
+ price += _matchRep2ChoiceEncoders[state.Index].GetPrice(repIndex - 2);
+ }
+ }
+ return price;
+ }
+ /*
+ UINT32 GetPosLen2Price(UINT32 pos, UINT32 posState) const
+ {
+ if (pos >= kNumFullDistances)
+ return kIfinityPrice;
+ return _distancesPrices[0][pos] + _lenEncoder.GetPrice(0, posState);
+ }
+ UINT32 GetPosLen3Price(UINT32 pos, UINT32 len, UINT32 posState) const
+ {
+ UINT32 price;
+ UINT32 lenToPosState = GetLenToPosState(len);
+ if (pos < kNumFullDistances)
+ price = _distancesPrices[lenToPosState][pos];
+ else
+ price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] +
+ _alignPrices[pos & kAlignMask];
+ return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);
+ }
+ */
+ UINT32 GetPosLenPrice(UINT32 pos, UINT32 len, UINT32 posState) const
+ {
+ if (len == 2 && pos >= 0x80)
+ return kIfinityPrice;
+ UINT32 price;
+ UINT32 lenToPosState = GetLenToPosState(len);
+ if (pos < kNumFullDistances)
+ price = _distancesPrices[lenToPosState][pos];
+ else
+ price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] +
+ _alignPrices[pos & kAlignMask];
+ return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);
+ }
+
+ UINT32 Backward(UINT32 &backRes, UINT32 cur);
+ UINT32 GetOptimum(UINT32 &backRes, UINT32 position);
+ UINT32 GetOptimumFast(UINT32 &backRes, UINT32 position);
+
+ void FillPosSlotPrices();
+ void FillDistancesPrices();
+ void FillAlignPrices();
+
+ void ReleaseStreams()
+ {
+ _matchFinder->ReleaseStream();
+ // _rangeEncoder.ReleaseStream();
+ }
+
+ HRESULT Flush();
+ class CCoderReleaser
+ {
+ CEncoder *_coder;
+ public:
+ CCoderReleaser(CEncoder *coder): _coder(coder) {}
+ ~CCoderReleaser()
+ {
+ _coder->ReleaseStreams();
+ }
+ };
+ friend class CCoderReleaser;
+
+ void WriteEndMarker(UINT32 posState);
+
+public:
+ CEncoder();
+ void SetWriteEndMarkerMode(bool writeEndMarker)
+ { _writeEndMark= writeEndMarker; }
+
+ HRESULT Create();
+
+ MY_UNKNOWN_IMP2(
+ ICompressSetCoderProperties,
+ ICompressWriteCoderProperties
+ )
+
+ STDMETHOD(Init)(
+ ISequentialOutStream *outStream);
+
+ // ICompressCoder interface
+ HRESULT SetStreams(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UINT64 *inSize, const UINT64 *outSize);
+ HRESULT CodeOneBlock(UINT64 *inSize, UINT64 *outSize, INT32 *finished);
+
+ HRESULT CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress);
+
+ // ICompressCoder interface
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UINT64 *inSize, const UINT64 *outSize,
+ ICompressProgressInfo *progress);
+
+ // IInitMatchFinder interface
+ STDMETHOD(InitMatchFinder)(IMatchFinder *matchFinder);
+
+ // ICompressSetCoderProperties2
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
+ const PROPVARIANT *properties, UINT32 numProperties);
+
+ // ICompressWriteCoderProperties
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+};
+
+}}
+
+#endif