xref: /aosp_15_r20/external/lzma/CPP/7zip/Compress/BZip2Encoder.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 // BZip2Encoder.h
2 
3 #ifndef ZIP7_INC_COMPRESS_BZIP2_ENCODER_H
4 #define ZIP7_INC_COMPRESS_BZIP2_ENCODER_H
5 
6 #include "../../Common/Defs.h"
7 #include "../../Common/MyCom.h"
8 
9 #ifndef Z7_ST
10 #include "../../Windows/Synchronization.h"
11 #include "../../Windows/Thread.h"
12 #endif
13 
14 #include "../ICoder.h"
15 
16 #include "../Common/InBuffer.h"
17 #include "../Common/OutBuffer.h"
18 
19 #include "BitmEncoder.h"
20 #include "BZip2Const.h"
21 #include "BZip2Crc.h"
22 
23 namespace NCompress {
24 namespace NBZip2 {
25 
26 class CMsbfEncoderTemp
27 {
28   UInt32 _pos;
29   unsigned _bitPos;
30   Byte _curByte;
31   Byte *_buf;
32 public:
SetStream(Byte * buf)33   void SetStream(Byte *buf) { _buf = buf;  }
GetStream()34   Byte *GetStream() const { return _buf; }
35 
Init()36   void Init()
37   {
38     _pos = 0;
39     _bitPos = 8;
40     _curByte = 0;
41   }
42 
Flush()43   void Flush()
44   {
45     if (_bitPos < 8)
46       WriteBits(0, _bitPos);
47   }
48 
WriteBits(UInt32 value,unsigned numBits)49   void WriteBits(UInt32 value, unsigned numBits)
50   {
51     while (numBits > 0)
52     {
53       unsigned numNewBits = MyMin(numBits, _bitPos);
54       numBits -= numNewBits;
55 
56       _curByte = (Byte)(_curByte << numNewBits);
57       UInt32 newBits = value >> numBits;
58       _curByte |= Byte(newBits);
59       value -= (newBits << numBits);
60 
61       _bitPos -= numNewBits;
62 
63       if (_bitPos == 0)
64       {
65        _buf[_pos++] = _curByte;
66         _bitPos = 8;
67       }
68     }
69   }
70 
GetBytePos()71   UInt32 GetBytePos() const { return _pos ; }
GetPos()72   UInt32 GetPos() const { return _pos * 8 + (8 - _bitPos); }
GetCurByte()73   Byte GetCurByte() const { return _curByte; }
SetPos(UInt32 bitPos)74   void SetPos(UInt32 bitPos)
75   {
76     _pos = bitPos >> 3;
77     _bitPos = 8 - ((unsigned)bitPos & 7);
78   }
SetCurState(unsigned bitPos,Byte curByte)79   void SetCurState(unsigned bitPos, Byte curByte)
80   {
81     _bitPos = 8 - bitPos;
82     _curByte = curByte;
83   }
84 };
85 
86 class CEncoder;
87 
88 const unsigned kNumPassesMax = 10;
89 
90 class CThreadInfo
91 {
92 public:
93   Byte *m_Block;
94 private:
95   Byte *m_MtfArray;
96   Byte *m_TempArray;
97   UInt32 *m_BlockSorterIndex;
98 
99   CMsbfEncoderTemp *m_OutStreamCurrent;
100 
101   Byte Lens[kNumTablesMax][kMaxAlphaSize];
102   UInt32 Freqs[kNumTablesMax][kMaxAlphaSize];
103   UInt32 Codes[kNumTablesMax][kMaxAlphaSize];
104 
105   Byte m_Selectors[kNumSelectorsMax];
106 
107   UInt32 m_CRCs[1 << kNumPassesMax];
108   UInt32 m_NumCrcs;
109 
110   void WriteBits2(UInt32 value, unsigned numBits);
111   void WriteByte2(Byte b);
112   void WriteBit2(Byte v);
113   void WriteCrc2(UInt32 v);
114 
115   void EncodeBlock(const Byte *block, UInt32 blockSize);
116   UInt32 EncodeBlockWithHeaders(const Byte *block, UInt32 blockSize);
117   void EncodeBlock2(const Byte *block, UInt32 blockSize, UInt32 numPasses);
118 public:
119   bool m_OptimizeNumTables;
120   CEncoder *Encoder;
121  #ifndef Z7_ST
122   NWindows::CThread Thread;
123 
124   NWindows::NSynchronization::CAutoResetEvent StreamWasFinishedEvent;
125   NWindows::NSynchronization::CAutoResetEvent WaitingWasStartedEvent;
126 
127   // it's not member of this thread. We just need one event per thread
128   NWindows::NSynchronization::CAutoResetEvent CanWriteEvent;
129 
130 private:
131   UInt32 m_BlockIndex;
132   UInt64 m_UnpackSize;
133 public:
134   Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
135   HRESULT Create();
136   void FinishStream(bool needLeave);
137   THREAD_FUNC_RET_TYPE ThreadFunc();
138  #endif
139 
CThreadInfo()140   CThreadInfo(): m_Block(NULL), m_BlockSorterIndex(NULL)  {}
~CThreadInfo()141   ~CThreadInfo() { Free(); }
142   bool Alloc();
143   void Free();
144 
145   HRESULT EncodeBlock3(UInt32 blockSize);
146 };
147 
148 struct CEncProps
149 {
150   UInt32 BlockSizeMult;
151   UInt32 NumPasses;
152   UInt64 Affinity;
153 
CEncPropsCEncProps154   CEncProps()
155   {
156     BlockSizeMult = (UInt32)(Int32)-1;
157     NumPasses = (UInt32)(Int32)-1;
158     Affinity = 0;
159   }
160   void Normalize(int level);
DoOptimizeNumTablesCEncProps161   bool DoOptimizeNumTables() const { return NumPasses > 1; }
162 };
163 
164 class CEncoder Z7_final:
165   public ICompressCoder,
166   public ICompressSetCoderProperties,
167  #ifndef Z7_ST
168   public ICompressSetCoderMt,
169  #endif
170   public CMyUnknownImp
171 {
172   Z7_COM_QI_BEGIN2(ICompressCoder)
173   Z7_COM_QI_ENTRY(ICompressSetCoderProperties)
174  #ifndef Z7_ST
175   Z7_COM_QI_ENTRY(ICompressSetCoderMt)
176  #endif
177   Z7_COM_QI_END
178   Z7_COM_ADDREF_RELEASE
179 
180   Z7_IFACE_COM7_IMP(ICompressCoder)
181   Z7_IFACE_COM7_IMP(ICompressSetCoderProperties)
182  #ifndef Z7_ST
183   Z7_IFACE_COM7_IMP(ICompressSetCoderMt)
184  #endif
185 
186  #ifndef Z7_ST
187   UInt32 m_NumThreadsPrev;
188  #endif
189 public:
190   CInBuffer m_InStream;
191  #ifndef Z7_ST
192   Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
193  #endif
194   CBitmEncoder<COutBuffer> m_OutStream;
195   CEncProps _props;
196   CBZip2CombinedCrc CombinedCrc;
197 
198  #ifndef Z7_ST
199   CThreadInfo *ThreadsInfo;
200   NWindows::NSynchronization::CManualResetEvent CanProcessEvent;
201   NWindows::NSynchronization::CCriticalSection CS;
202   UInt32 NumThreads;
203   bool MtMode;
204   UInt32 NextBlockIndex;
205 
206   bool CloseThreads;
207   bool StreamWasFinished;
208   NWindows::NSynchronization::CManualResetEvent CanStartWaitingEvent;
209 
210   HRESULT Result;
211   ICompressProgressInfo *Progress;
212  #else
213   CThreadInfo ThreadsInfo;
214  #endif
215 
216   UInt64 NumBlocks;
217 
GetInProcessedSize()218   UInt64 GetInProcessedSize() const { return m_InStream.GetProcessedSize(); }
219 
220   UInt32 ReadRleBlock(Byte *buf);
221   void WriteBytes(const Byte *data, UInt32 sizeInBits, Byte lastByte);
222 
223   void WriteBits(UInt32 value, unsigned numBits);
224   void WriteByte(Byte b);
225   // void WriteBit(Byte v);
226   void WriteCrc(UInt32 v);
227 
228  #ifndef Z7_ST
229   HRESULT Create();
230   void Free();
231  #endif
232 
233 public:
234   CEncoder();
235  #ifndef Z7_ST
236   ~CEncoder();
237  #endif
238 
Flush()239   HRESULT Flush() { return m_OutStream.Flush(); }
240 
241   HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
242       const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
243 };
244 
245 }}
246 
247 #endif
248