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

DeflateEncoder.h « Deflate « Compress « 7zip - github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 57d86b2f58b9d8982cc3b04a9b0a4a932c09d7c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
// DeflateEncoder.h

#ifndef __DEFLATE_ENCODER_H
#define __DEFLATE_ENCODER_H

#include "Common/MyCom.h"

#include "../../ICoder.h"
#include "../../Common/LSBFEncoder.h"
#include "../LZ/IMatchFinder.h"
#include "../Huffman/HuffmanEncoder.h"

#include "DeflateConst.h"

namespace NCompress {
namespace NDeflate {
namespace NEncoder {

struct CCodeValue
{
  Byte Flag;
  union
  {
    Byte Imm;
    Byte Len;
  };
  UInt16 Pos;
};

class COnePosMatches
{
public:
  UInt16 *MatchDistances;
  UInt16 LongestMatchLength;    
  UInt16 LongestMatchDistance;
  void Init(UInt16 *matchDistances)
  {
    MatchDistances = matchDistances;
  };
};

struct COptimal
{
  UInt32 Price;
  UInt16 PosPrev;
  UInt16 BackPrev;
};

const int kNumOpts = 0x1000;

class CCoder
{
  UInt32 m_FinderPos;
  
  COptimal m_Optimum[kNumOpts];
  
  CMyComPtr<IMatchFinder> m_MatchFinder;

  NStream::NLSBF::CEncoder m_OutStream;
  NStream::NLSBF::CReverseEncoder m_ReverseOutStream;
  
  NCompression::NHuffman::CEncoder m_MainCoder;
  NCompression::NHuffman::CEncoder m_DistCoder;
  NCompression::NHuffman::CEncoder m_LevelCoder;

  Byte m_LastLevels[kMaxTableSize64];

  UInt32 m_ValueIndex;
  CCodeValue *m_Values;

  UInt32 m_OptimumEndIndex;
  UInt32 m_OptimumCurrentIndex;
  UInt32 m_AdditionalOffset;

  UInt32 m_LongestMatchLength;    
  UInt32 m_LongestMatchDistance;
  UInt16 *m_MatchDistances;

  UInt32 m_NumFastBytes;

  Byte  m_LiteralPrices[256];
  
  Byte  m_LenPrices[kNumLenCombinations32];
  Byte  m_PosPrices[kDistTableSize64];

  UInt32 m_CurrentBlockUncompressedSize;

  COnePosMatches *m_OnePosMatchesArray;
  UInt16 *m_OnePosMatchesMemory;

  UInt64 m_BlockStartPostion;
  int m_NumPasses;

  bool m_Created;

  bool _deflate64Mode;
  UInt32 m_NumLenCombinations;
  UInt32 m_MatchMaxLen;
  const Byte *m_LenStart;
  const Byte *m_LenDirectBits;

  HRESULT Create();
  void Free();

  void GetBacks(UInt32 aPos);

  void ReadGoodBacks();
  void MovePos(UInt32 num);
  UInt32 Backward(UInt32 &backRes, UInt32 cur);
  UInt32 GetOptimal(UInt32 &backRes);

  void InitStructures();
  void CodeLevelTable(Byte *newLevels, int numLevels, bool codeMode);
  int WriteTables(bool writeMode, bool finalBlock);
  void CopyBackBlockOp(UInt32 distance, UInt32 length);
  void WriteBlockData(bool writeMode, bool finalBlock);

  void CCoder::ReleaseStreams()
  {
    // m_MatchFinder.ReleaseStream();
    m_OutStream.ReleaseStream();
  }
  class CCoderReleaser
  {
    CCoder *m_Coder;
  public:
    CCoderReleaser(CCoder *coder): m_Coder(coder) {}
    ~CCoderReleaser() { m_Coder->ReleaseStreams(); }
  };
  friend class CCoderReleaser;

public:
  CCoder(bool deflate64Mode = false);
  ~CCoder();

  HRESULT CodeReal(ISequentialInStream *inStream,
      ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
      ICompressProgressInfo *progress);

  HRESULT BaseCode(ISequentialInStream *inStream,
      ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
      ICompressProgressInfo *progress);

  // ICompressSetCoderProperties
  HRESULT BaseSetEncoderProperties2(const PROPID *propIDs, 
      const PROPVARIANT *properties, UInt32 numProperties);
};

///////////////////////////////////////////////////////////////

class CCOMCoder :
  public ICompressCoder,
  public ICompressSetCoderProperties, 
  public CMyUnknownImp,
  public CCoder
{
public:
  MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
  CCOMCoder(): CCoder(false) {};
  STDMETHOD(Code)(ISequentialInStream *inStream,
      ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
      ICompressProgressInfo *progress);
  // ICompressSetCoderProperties
  STDMETHOD(SetCoderProperties)(const PROPID *propIDs, 
      const PROPVARIANT *properties, UInt32 numProperties);
};

class CCOMCoder64 :
  public ICompressCoder,
  public ICompressSetCoderProperties,
  public CMyUnknownImp,
  public CCoder
{
public:
  MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
  CCOMCoder64(): CCoder(true) {};
  STDMETHOD(Code)(ISequentialInStream *inStream,
      ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
      ICompressProgressInfo *progress);
  // ICompressSetCoderProperties
  STDMETHOD(SetCoderProperties)(const PROPID *propIDs, 
      const PROPVARIANT *properties, UInt32 numProperties);
};


}}}

#endif