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