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

BZip2Encoder.h « BZip2 « Compress « 7zip - github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 7eca18a0591e38752d7c50180068e42289e19bc5 (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
// Compress/BZip2/Encoder.h

#ifndef __COMPRESS_BZIP2_ENCODER_H
#define __COMPRESS_BZIP2_ENCODER_H

#include "../../ICoder.h"
#include "../../../Common/MyCom.h"
#include "../../Common/MSBFEncoder.h"
#include "../../Common/InBuffer.h"
#include "../../Common/OutBuffer.h"
#include "../Huffman/HuffmanEncoder.h"
#include "../BWT/BlockSort.h"
#include "BZip2Const.h"
#include "BZip2CRC.h"
 
namespace NCompress {
namespace NBZip2 {

class CMsbfEncoderTemp
{
  UInt32 m_Pos;
  int m_BitPos;
  Byte m_CurByte;
  Byte *Buffer;
public:
  void SetStream(Byte *buffer) { Buffer = buffer;  }
  Byte *GetStream() const { return Buffer; }

  void Init()
  {
    m_Pos = 0;
    m_BitPos = 8; 
    m_CurByte = 0;
  }

  void Flush()
  {
    if(m_BitPos < 8)
      WriteBits(0, m_BitPos);
  }

  void WriteBits(UInt32 value, int numBits)
  {
    while(numBits > 0)
    {
      int numNewBits = MyMin(numBits, m_BitPos);
      numBits -= numNewBits;
      
      m_CurByte <<= numNewBits;
      UInt32 newBits = value >> numBits;
      m_CurByte |= Byte(newBits);
      value -= (newBits << numBits);
      
      m_BitPos -= numNewBits;
      
      if (m_BitPos == 0)
      {
       Buffer[m_Pos++] = m_CurByte;
        m_BitPos = 8;
      }
    }
  }
  
  UInt32 GetBytePos() const { return m_Pos ; }
  UInt32 GetPos() const { return m_Pos * 8 + (8 - m_BitPos); }
  Byte GetCurByte() const { return m_CurByte; }
  void SetPos(UInt32 bitPos)
  { 
    m_Pos = bitPos / 8;
    m_BitPos = 8 - (bitPos & 7); 
  }
  void SetCurState(UInt32 bitPos, Byte curByte)
  { 
    m_BitPos = 8 - bitPos; 
    m_CurByte = curByte; 
  }
};

class CEncoder :
  public ICompressCoder,
  public ICompressSetCoderProperties, 
  public CMyUnknownImp
{
  Byte *m_Block;
  CInBuffer m_InStream;
  NStream::NMSBF::CEncoder<COutBuffer> m_OutStream;
  CMsbfEncoderTemp *m_OutStreamCurrent;
  CBlockSorter m_BlockSorter;

  bool m_NeedHuffmanCreate;
  NCompression::NHuffman::CEncoder m_HuffEncoders[kNumTablesMax];

  Byte *m_MtfArray;
  Byte *m_TempArray;

  Byte m_Selectors[kNumSelectorsMax];

  UInt32 m_BlockSizeMult;
  UInt32 m_NumPasses;
  bool m_OptimizeNumTables;

  UInt32 ReadRleBlock(Byte *buffer);

  void WriteBits2(UInt32 value, UInt32 numBits);
  void WriteByte2(Byte b);
  void WriteBit2(bool v);
  void WriteCRC2(UInt32 v);
  
  void WriteBits(UInt32 value, UInt32 numBits);
  void WriteByte(Byte b);
  void WriteBit(bool v);
  void WriteCRC(UInt32 v);

  void EncodeBlock(Byte *block, UInt32 blockSize);
  UInt32 EncodeBlockWithHeaders(Byte *block, UInt32 blockSize);
  void EncodeBlock2(CBZip2CombinedCRC &combinedCRC, Byte *block, UInt32 blockSize, UInt32 numPasses);
  void EncodeBlock3(CBZip2CombinedCRC &combinedCRC, UInt32 blockSize);

public:
  CEncoder();
  ~CEncoder();

  HRESULT Flush() { return m_OutStream.Flush(); }
  
  void ReleaseStreams()
  {
    m_InStream.ReleaseStream();
    m_OutStream.ReleaseStream();
  }

  class CFlusher
  {
    CEncoder *_coder;
  public:
    bool NeedFlush;
    CFlusher(CEncoder *coder): _coder(coder), NeedFlush(true) {}
    ~CFlusher() 
    { 
      if (NeedFlush)
        _coder->Flush();
      _coder->ReleaseStreams(); 
    }
  };

  MY_UNKNOWN_IMP1(ICompressSetCoderProperties)

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

  STDMETHOD(Code)(ISequentialInStream *inStream,
      ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
      ICompressProgressInfo *progress);
  STDMETHOD(SetCoderProperties)(const PROPID *propIDs, 
      const PROPVARIANT *properties, UInt32 numProperties);
};

}}

#endif