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