• 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 {