Bug#1109782: unblock: 7zip/25.00+dfsg-1 (8/13)
From
Bastian Germann@21:1/5 to
All on Wed Jul 23 19:40:02 2025
[continued from previous message]
+ Byte *_buf;
{
Byte mtfSel[kNumTablesMax];
{
@@ -507,81 +696,97 @@
mtfSel[t] = (Byte)t;
while (++t < numTables);
}
+
+ _bitPos = m_OutStreamCurrent._bitPos;
+ _curByte = m_OutStreamCurrent._curByte;
+ _buf = m_OutStreamCurrent._buf;
+ // stream.Init_from_Global(m_OutStreamCurrent);
- UInt32 i = 0;
+ const Byte *selectors = m_Selectors;
+ const Byte * const selectors_lim = selectors + numSelectors;
+ Byte prev = 0; // mtfSel[0];
do
{
- Byte sel = m_Selectors[i];
- unsigned pos;
- for (pos = 0; mtfSel[pos] != sel; pos++)
- WriteBit2(1);
- WriteBit2(0);
- for (; pos > 0; pos--)
- mtfSel[pos] = mtfSel[(size_t)pos - 1];
- mtfSel[0] = sel;
+ const Byte sel = *selectors++;
+ if (prev != sel)
+ {
+ Byte *mtfSel_cur = &mtfSel[1];
+ for (;;)
+ {
+ WRITE_BIT_1
+ const Byte next = *mtfSel_cur;
+ *mtfSel_cur++ = prev;
+ prev = next;
+ if (next == sel)
+ break;
+ }
+ // mtfSel[0] = sel;
+ }
+ WRITE_BIT_0
}
- while (++i < numSelectors);
+ while (selectors != selectors_lim);
}
-
{
unsigned t = 0;
do
{
const Byte *lens = Lens[t];
- UInt32 len = lens[0];
- WriteBits2(len, kNumLevelsBits);
+ unsigned len = lens[0];
+ WRITE_BITS_8(len, kNumLevelsBits)
unsigned i = 0;
do
{
- UInt32 level = lens[i];
+ const unsigned level = lens[i];
while (len != level)
{
- WriteBit2(1);
+ WRITE_BIT_1
if (len < level)
{
- WriteBit2(0);
len++;
+ WRITE_BIT_0
}
else
{
- WriteBit2(1);
len--;
+ WRITE_BIT_1
}
}
- WriteBit2(0);
+ WRITE_BIT_0
}
while (++i < alphaSize);
}
while (++t < numTables);
}
-
{
- UInt32 groupSize = 0;
- UInt32 groupIndex = 0;
+ UInt32 groupSize = 1;
+ const Byte *selectors = m_Selectors;
const Byte *lens = NULL;
const UInt32 *codes = NULL;
- UInt32 mtfPos = 0;
+ mtfs = m_MtfArray;
do
{
- UInt32 symbol = mtfs[mtfPos++];
+ unsigned symbol = *mtfs++;
if (symbol >= 0xFF)
- symbol += mtfs[mtfPos++];
- if (groupSize == 0)
+ symbol += *mtfs++;
+ if (--groupSize == 0)
{
groupSize = kGroupSize;
- unsigned t = m_Selectors[groupIndex++];
+ const unsigned t = *selectors++;
lens = Lens[t];
codes = Codes[t];
}
- groupSize--;
- m_OutStreamCurrent->WriteBits(codes[symbol], lens[symbol]);
+ WRITE_BITS_HUFF(codes[symbol], lens[symbol])
}
- while (mtfPos < mtfArraySize);
+ while (mtfs < mtf_lim);
}
+ // Restore_from_Local:
+ m_OutStreamCurrent._bitPos = _bitPos;
+ m_OutStreamCurrent._curByte = _curByte;
+ m_OutStreamCurrent._buf = _buf;
if (!m_OptimizeNumTables)
break;
- UInt32 price = m_OutStreamCurrent->GetPos() - startPos;
+ const UInt32 price = m_OutStreamCurrent.GetPos() - startPos;
if (price <= bestPrice)
{
if (nt == kNumTablesMax)
@@ -592,6 +797,7 @@
}
}
+
// blockSize > 0
UInt32 CThreadInfo::EncodeBlockWithHeaders(const Byte *block, UInt32 blockSize)
{
@@ -603,148 +809,134 @@
WriteByte2(kBlockSig5);
CBZip2Crc crc;
- unsigned numReps = 0;
- Byte prevByte = block[0];
- UInt32 i = 0;
- do
+ const Byte * const lim = block + blockSize;
+ unsigned b = *block++;
+ crc.UpdateByte(b);
+ for (;;)
{
- Byte b = block[i];
- if (numReps == kRleModeRepSize)
- {
- for (; b > 0; b--)
- crc.UpdateByte(prevByte);
- numReps = 0;
- continue;
- }
- if (prevByte == b)
- numReps++;
- else
- {
- numReps = 1;
- prevByte = b;
- }
- crc.UpdateByte(b);
- }
- while (++i < blockSize);
- UInt32 crcRes = crc.GetDigest();
- WriteCrc2(crcRes);
- EncodeBlock(block, blockSize);
+ const unsigned prev = b;
+ if (block >= lim) { break; } b = *block++; crc.UpdateByte(b); if (prev != b) continue;
+ if (block >= lim) { break; } b = *block++; crc.UpdateByte(b); if (prev != b) continue;
+ if (block >= lim) { break; } b = *block++; crc.UpdateByte(b); if (prev != b) continue;
+ if (block >= lim) { break; } b = *block++; if (b) do crc.UpdateByte(prev); while (--b);
+ if (block >= lim) { break; } b = *block++; crc.UpdateByte(b);
+ }
+ const UInt32 crcRes = crc.GetDigest();
+ for (int i = 24; i >= 0; i -= 8)
+ WriteByte2((Byte)(crcRes >> i));
+ EncodeBlock(lim - blockSize, blockSize);
return crcRes;
}
+
void CThreadInfo::EncodeBlock2(const Byte *block, UInt32 blockSize, UInt32 numPasses)
{
- UInt32 numCrcs = m_NumCrcs;
- bool needCompare = false;
+ const UInt32 numCrcs = m_NumCrcs;
- UInt32 startBytePos = m_OutStreamCurrent->GetBytePos();
- UInt32 startPos = m_OutStreamCurrent->GetPos();
- Byte startCurByte = m_OutStreamCurrent->GetCurByte();
- Byte endCurByte = 0;
- UInt32 endPos = 0;
+ const UInt32 startBytePos = m_OutStreamCurrent.GetBytePos();
+ const UInt32 startPos = m_OutStreamCurrent.GetPos();
+ const unsigned startCurByte = m_OutStreamCurrent.GetCurByte();
+ unsigned endCurByte = 0;
+ UInt32 endPos = 0; // 0 means no no additional passes
if (numPasses > 1 && blockSize >= (1 << 10))
{
- UInt32 blockSize0 = blockSize / 2; // ????
-
- for (; (block[blockSize0] == block[(size_t)blockSize0 - 1]
- || block[(size_t)blockSize0 - 1] == block[(size_t)blockSize0 - 2]) - && blockSize0 < blockSize;
- blockSize0++);
+ UInt32 bs0 = blockSize / 2;
+ for (; bs0 < blockSize &&
+ (block[ bs0 ] ==
+ block[(size_t)bs0 - 1] ||
+ block[(size_t)bs0 - 1] ==
+ block[(size_t)bs0 - 2]);
+ bs0++)
+ {}
- if (blockSize0 < blockSize)
+ if (bs0 < blockSize)
{
- EncodeBlock2(block, blockSize0, numPasses - 1);
- EncodeBlock2(block + blockSize0, blockSize - blockSize0, numPasses - 1); - endPos = m_OutStreamCurrent->GetPos();
- endCurByte = m_OutStreamCurrent->GetCurByte();
- if ((endPos & 7) > 0)
+ EncodeBlock2(block, bs0, numPasses - 1);
+ EncodeBlock2(block + bs0, blockSize - bs0, numPasses - 1);
+ endPos = m_OutStreamCurrent.GetPos();
+ endCurByte = m_OutStreamCurrent.GetCurByte();
+ // we prepare next byte as identical byte to starting byte for main encoding attempt:
+ if (endPos & 7)
WriteBits2(0, 8 - (endPos & 7));
- m_OutStreamCurrent->SetCurState((startPos & 7), startCurByte);
- needCompare = true;
+ m_OutStreamCurrent.SetCurState((startPos & 7), startCurByte);
}
}
- UInt32 startBytePos2 = m_OutStreamCurrent->GetBytePos();
- UInt32 startPos2 = m_OutStreamCurrent->GetPos();
- UInt32 crcVal = EncodeBlockWithHeaders(block, blockSize);
- UInt32 endPos2 = m_OutStreamCurrent->GetPos();
+ const UInt32 startBytePos2 = m_OutStreamCurrent.GetBytePos();
+ const UInt32 startPos2 = m_OutStreamCurrent.GetPos();
+ const UInt32 crcVal = EncodeBlockWithHeaders(block, blockSize);
- if (needCompare)
+ if (endPos)
{
- UInt32 size2 = endPos2 - startPos2;
- if (size2 < endPos - startPos)
+ const UInt32 size2 = m_OutStreamCurrent.GetPos() - startPos2;
+ if (size2 >= endPos - startPos)
{
- UInt32 numBytes = m_OutStreamCurrent->GetBytePos() - startBytePos2;
- Byte *buffer = m_OutStreamCurrent->GetStream();
- for (UInt32 i = 0; i < numBytes; i++)
- buffer[startBytePos + i] = buffer[startBytePos2 + i];
- m_OutStreamCurrent->SetPos(startPos + endPos2 - startPos2);
- m_NumCrcs = numCrcs;
- m_CRCs[m_NumCrcs++] = crcVal;
- }
- else
- {
- m_OutStreamCurrent->SetPos(endPos);
- m_OutStreamCurrent->SetCurState((endPos & 7), endCurByte);
+ m_OutStreamCurrent.SetPos(endPos);
+ m_OutStreamCurrent.SetCurState((endPos & 7), endCurByte);
+ return;
}
+ const UInt32 numBytes = m_OutStreamCurrent.GetBytePos() - startBytePos2;
+ Byte * const buffer = m_OutStreamCurrent.GetStream();
+ memmove(buffer + startBytePos, buffer + startBytePos2, numBytes);
+ m_OutStreamCurrent.SetPos(startPos + size2);
+ // we don't call m_OutStreamCurrent.SetCurState() here because
+ // m_OutStreamCurrent._curByte is correct already
}
- else
- {
- m_NumCrcs = numCrcs;
- m_CRCs[m_NumCrcs++] = crcVal;
- }
+ m_CRCs[numCrcs] = crcVal;
+ m_NumCrcs = numCrcs + 1;
}
+
HRESULT CThreadInfo::EncodeBlock3(UInt32 blockSize)
{
- CMsbfEncoderTemp outStreamTemp;
+ CMsbfEncoderTemp &outStreamTemp = m_OutStreamCurrent;
outStreamTemp.SetStream(m_TempArray);
outStreamTemp.Init();
- m_OutStreamCurrent = &outStreamTemp;
-
m_NumCrcs = 0;
EncodeBlock2(m_Block, blockSize, Encoder->_props.NumPasses);
- #ifndef Z7_ST
+#ifndef Z7_ST
if (Encoder->MtMode)
Encoder->ThreadsInfo[m_BlockIndex].CanWriteEvent.Lock();
- #endif
+#endif
+
for (UInt32 i = 0; i < m_NumCrcs; i++)
Encoder->CombinedCrc.Update(m_CRCs[i]);
- Encoder->WriteBytes(m_TempArray, outStreamTemp.GetPos(), outStreamTemp.GetCurByte());
+ Encoder->WriteBytes(m_TempArray, outStreamTemp.GetPos(), outStreamTemp.GetNonFlushedByteBits());
HRESULT res = S_OK;
- #ifndef Z7_ST
+
+#ifndef Z7_ST
if (Encoder->MtMode)
{
UInt32 blockIndex = m_BlockIndex + 1;
if (blockIndex == Encoder->NumThreads)
blockIndex = 0;
-
if (Encoder->Progress)
{
const UInt64 packSize = Encoder->m_OutStream.GetProcessedSize();
res = Encoder->Progress->SetRatioInfo(&m_UnpackSize, &packSize);
}
-
Encoder->ThreadsInfo[blockIndex].CanWriteEvent.Set();
}
- #endif
+#endif
return res;
}
-void CEncoder::WriteBytes(const Byte *data, UInt32 sizeInBits, Byte lastByte) +void CEncoder::WriteBytes(const Byte *data, UInt32 sizeInBits, unsigned lastByteBits)
{
- UInt32 bytesSize = (sizeInBits >> 3);
- for (UInt32 i = 0; i < bytesSize; i++)
- m_OutStream.WriteBits(data[i], 8);
- WriteBits(lastByte, (sizeInBits & 7));
+ m_OutStream.WriteBytes(data, sizeInBits >> 3);
+ sizeInBits &= 7;
+ if (sizeInBits)
+ m_OutStream.WriteBits(lastByteBits, sizeInBits);
}
HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
{
+ ThreadNextGroup_Init(&ThreadNextGroup, _props.NumThreadGroups, 0); // startGroup
+
NumBlocks = 0;
#ifndef Z7_ST
Progress = progress;
@@ -823,11 +1015,11 @@
{
CThreadInfo &ti =
#ifndef Z7_ST
- ThreadsInfo[0];
+ ThreadsInfo[0];
#else
- ThreadsInfo;
+ ThreadsInfo;
#endif
- UInt32 blockSize = ReadRleBlock(ti.m_Block);
+ const UInt32 blockSize = ReadRleBlock(ti.m_Block);
if (blockSize == 0)
break;
RINOK(ti.EncodeBlock3(blockSize))
@@ -845,8 +1037,11 @@
WriteByte(kFinSig3);
WriteByte(kFinSig4);
WriteByte(kFinSig5);
-
- WriteCrc(CombinedCrc.GetDigest());
+ {
+ const UInt32 v = CombinedCrc.GetDigest();
+ for (int i = 24; i >= 0; i -= 8)
+ WriteByte((Byte)(v >> i));
+ }
RINOK(Flush())
if (!m_InStream.WasFinished())
return E_FAIL;
@@ -869,14 +1064,21 @@
for (UInt32 i = 0; i < numProps; i++)
{
const PROPVARIANT &prop = coderProps[i];
- PROPID propID = propIDs[i];
+ const PROPID propID = propIDs[i];
if (propID == NCoderPropID::kAffinity)
{
- if (prop.vt == VT_UI8)
- props.Affinity = prop.uhVal.QuadPart;
- else
+ if (prop.vt != VT_UI8)
+ return E_INVALIDARG;
+ props.Affinity = prop.uhVal.QuadPart;
+ continue;
+ }
+
+ if (propID == NCoderPropID::kNumThreadGroups)
+ {
+ if (prop.vt != VT_UI4)
return E_INVALIDARG;
+ props.NumThreadGroups = (UInt32)prop.ulVal;
continue;
}
@@ -884,7 +1086,7 @@
continue;
if (prop.vt != VT_UI4)
return E_INVALIDARG;
- UInt32 v = (UInt32)prop.ulVal;
+ const UInt32 v = (UInt32)prop.ulVal;
switch (propID)
{
case NCoderPropID::kNumPasses: props.NumPasses = v; break;
diff -Nru 7zip-24.09+dfsg/CPP/7zip/Compress/BZip2Encoder.h 7zip-25.00+dfsg/CPP/7zip/Compress/BZip2Encoder.h
--- 7zip-24.09+dfsg/CPP/7zip/Compress/BZip2Encoder.h 2023-03-28 12:00:00.000000000 +0200
+++ 7zip-25.00+dfsg/CPP/7zip/Compress/BZip2Encoder.h 2025-02-28 07:00:00.000000000 +0100
@@ -3,7 +3,6 @@
#ifndef ZIP7_INC_COMPRESS_BZIP2_ENCODER_H
#define ZIP7_INC_COMPRESS_BZIP2_ENCODER_H
-#include "../../Common/Defs.h"
#include "../../Common/MyCom.h"
#ifndef Z7_ST
@@ -23,80 +22,114 @@
namespace NCompress {
namespace NBZip2 {
-class CMsbfEncoderTemp
+const unsigned kNumPassesMax = 10;
+
+struct CMsbfEncoderTemp
{
- UInt32 _pos;
- unsigned _bitPos;
- Byte _curByte;
+ unsigned _bitPos; // 0 < _bitPos <= 8 : number of non-filled low bits in _curByte
+ unsigned _curByte; // low (_bitPos) bits are zeros
+ // high (8 - _bitPos) bits are filled
Byte *_buf;
-public:
- void SetStream(Byte *buf) { _buf = buf; }
- Byte *GetStream() const { return _buf; }
+ Byte *_buf_base;
+ void SetStream(Byte *buf) { _buf_base = _buf = buf; }
+ Byte *GetStream() const {