libpgf  6.11.42
PGF - Progressive Graphics File
CDecoder::CMacroBlock Class Reference

A macro block is a decoding unit of fixed size (uncoded) More...

List of all members.

Public Member Functions

 CMacroBlock (CDecoder *decoder)
bool IsCompletelyRead () const
void BitplaneDecode ()

Public Attributes

ROIBlockHeader m_header
 block header
DataT m_value [BufferSize]
 output buffer of values with index m_valuePos
UINT32 m_codeBuffer [BufferSize]
 input buffer for encoded bitstream
UINT32 m_valuePos
 current position in m_value

Private Member Functions

UINT32 ComposeBitplane (UINT32 bufferSize, DataT planeMask, UINT32 *sigBits, UINT32 *refBits, UINT32 *signBits)
UINT32 ComposeBitplaneRLD (UINT32 bufferSize, DataT planeMask, UINT32 sigPos, UINT32 *refBits)
UINT32 ComposeBitplaneRLD (UINT32 bufferSize, DataT planeMask, UINT32 *sigBits, UINT32 *refBits, UINT32 signPos)
void SetBitAtPos (UINT32 pos, DataT planeMask)
void SetSign (UINT32 pos, bool sign)

Private Attributes

CDecoderm_decoder
bool m_sigFlagVector [BufferSize+1]

Detailed Description

A macro block is a decoding unit of fixed size (uncoded)

PGF decoder macro block class.

Author:
C. Stamm, I. Bauersachs

Definition at line 50 of file Decoder.h.


Constructor & Destructor Documentation

Constructor: Initializes new macro block.

Parameters:
decoderPointer to outer class.

Definition at line 55 of file Decoder.h.

                : m_header(0)                                                           // makes sure that IsCompletelyRead() returns true for an empty macro block
                , m_valuePos(0)
                , m_decoder(decoder)
                {
                        ASSERT(m_decoder);
                }

Member Function Documentation

Decodes already read input data into this macro block. Several macro blocks can be decoded in parallel. Call CDecoder::ReadMacroBlock before this method.

Definition at line 601 of file Decoder.cpp.

                                         {
        UINT32 bufferSize = m_header.rbh.bufferSize; ASSERT(bufferSize <= BufferSize);

        UINT32 nPlanes;
        UINT32 codePos = 0, codeLen, sigLen, sigPos, signLen, signPos;
        DataT planeMask;

        // clear significance vector
        for (UINT32 k=0; k < bufferSize; k++) {
                m_sigFlagVector[k] = false;
        }
        m_sigFlagVector[bufferSize] = true; // sentinel

        // clear output buffer
        for (UINT32 k=0; k < BufferSize; k++) {
                m_value[k] = 0;
        }

        // read number of bit planes
        // <nPlanes>
        nPlanes = GetValueBlock(m_codeBuffer, 0, MaxBitPlanesLog); 
        codePos += MaxBitPlanesLog;

        // loop through all bit planes
        if (nPlanes == 0) nPlanes = MaxBitPlanes + 1;
        ASSERT(0 < nPlanes && nPlanes <= MaxBitPlanes + 1);
        planeMask = 1 << (nPlanes - 1);

        for (int plane = nPlanes - 1; plane >= 0; plane--) {
                // read RL code
                if (GetBit(m_codeBuffer, codePos)) {
                        // RL coding of sigBits is used
                        // <1><codeLen><codedSigAndSignBits>_<refBits>
                        codePos++;

                        // read codeLen
                        codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen <= MaxCodeLen);

                        // position of encoded sigBits and signBits
                        sigPos = codePos + RLblockSizeLen; ASSERT(sigPos < CodeBufferBitLen); 

                        // refinement bits
                        codePos = AlignWordPos(sigPos + codeLen); ASSERT(codePos < CodeBufferBitLen); 

                        // run-length decode significant bits and signs from m_codeBuffer and 
                        // read refinement bits from m_codeBuffer and compose bit plane
                        sigLen = ComposeBitplaneRLD(bufferSize, planeMask, sigPos, &m_codeBuffer[codePos >> WordWidthLog]);

                } else {
                        // no RL coding is used for sigBits and signBits together
                        // <0><sigLen>
                        codePos++;

                        // read sigLen
                        sigLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(sigLen <= MaxCodeLen);
                        codePos += RLblockSizeLen; ASSERT(codePos < CodeBufferBitLen);

                        // read RL code for signBits
                        if (GetBit(m_codeBuffer, codePos)) {
                                // RL coding is used just for signBits
                                // <1><codeLen><codedSignBits>_<sigBits>_<refBits>
                                codePos++;

                                // read codeLen
                                codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen <= MaxCodeLen);

                                // sign bits
                                signPos = codePos + RLblockSizeLen; ASSERT(signPos < CodeBufferBitLen);
                                
                                // significant bits
                                sigPos = AlignWordPos(signPos + codeLen); ASSERT(sigPos < CodeBufferBitLen);

                                // refinement bits
                                codePos = AlignWordPos(sigPos + sigLen); ASSERT(codePos < CodeBufferBitLen);

                                // read significant and refinement bitset from m_codeBuffer
                                sigLen = ComposeBitplaneRLD(bufferSize, planeMask, &m_codeBuffer[sigPos >> WordWidthLog], &m_codeBuffer[codePos >> WordWidthLog], signPos);
                        
                        } else {
                                // RL coding of signBits was not efficient and therefore not used
                                // <0><signLen>_<signBits>_<sigBits>_<refBits>
                                codePos++;

                                // read signLen
                                signLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(signLen <= MaxCodeLen);
                                
                                // sign bits
                                signPos = AlignWordPos(codePos + RLblockSizeLen); ASSERT(signPos < CodeBufferBitLen);

                                // significant bits
                                sigPos = AlignWordPos(signPos + signLen); ASSERT(sigPos < CodeBufferBitLen);

                                // refinement bits
                                codePos = AlignWordPos(sigPos + sigLen); ASSERT(codePos < CodeBufferBitLen);

                                // read significant and refinement bitset from m_codeBuffer
                                sigLen = ComposeBitplane(bufferSize, planeMask, &m_codeBuffer[sigPos >> WordWidthLog], &m_codeBuffer[codePos >> WordWidthLog], &m_codeBuffer[signPos >> WordWidthLog]);
                        }
                }

                // start of next chunk
                codePos = AlignWordPos(codePos + bufferSize - sigLen); ASSERT(codePos < CodeBufferBitLen); 
                
                // next plane
                planeMask >>= 1;
        }

        m_valuePos = 0;
}
UINT32 CDecoder::CMacroBlock::ComposeBitplane ( UINT32  bufferSize,
DataT  planeMask,
UINT32 *  sigBits,
UINT32 *  refBits,
UINT32 *  signBits 
) [private]

Definition at line 716 of file Decoder.cpp.

                                                                                                                                  {
        ASSERT(sigBits);
        ASSERT(refBits);
        ASSERT(signBits);

        UINT32 valPos = 0, signPos = 0, refPos = 0;
        UINT32 sigPos = 0, sigEnd;
        UINT32 zerocnt;

        while (valPos < bufferSize) {
                // search next 1 in m_sigFlagVector using searching with sentinel
                sigEnd = valPos;
                while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
                sigEnd -= valPos;
                sigEnd += sigPos;

                // search 1's in sigBits[sigPos..sigEnd)
                // these 1's are significant bits
                while (sigPos < sigEnd) {
                        // search 0's
                        zerocnt = SeekBitRange(sigBits, sigPos, sigEnd - sigPos);
                        sigPos += zerocnt;
                        valPos += zerocnt;
                        if (sigPos < sigEnd) {
                                // write bit to m_value
                                SetBitAtPos(valPos, planeMask);

                                // copy sign bit
                                SetSign(valPos, GetBit(signBits, signPos++)); 

                                // update significance flag vector
                                m_sigFlagVector[valPos++] = true;
                                sigPos++; 
                        }
                }
                // refinement bit
                if (valPos < bufferSize) {
                        // write one refinement bit
                        if (GetBit(refBits, refPos)) {
                                SetBitAtPos(valPos, planeMask);
                        }
                        refPos++;
                        valPos++;
                }
        }
        ASSERT(sigPos <= bufferSize);
        ASSERT(refPos <= bufferSize);
        ASSERT(signPos <= bufferSize);
        ASSERT(valPos == bufferSize);

        return sigPos;
}
UINT32 CDecoder::CMacroBlock::ComposeBitplaneRLD ( UINT32  bufferSize,
DataT  planeMask,
UINT32  sigPos,
UINT32 *  refBits 
) [private]

Definition at line 779 of file Decoder.cpp.

                                                                                                                  {
        ASSERT(refBits);

        UINT32 valPos = 0, refPos = 0;
        UINT32 sigPos = 0, sigEnd;
        UINT32 k = 3;
        UINT32 runlen = 1 << k; // = 2^k
        UINT32 count = 0, rest = 0;
        bool set1 = false;

        while (valPos < bufferSize) {
                // search next 1 in m_sigFlagVector using searching with sentinel
                sigEnd = valPos;
                while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
                sigEnd -= valPos;
                sigEnd += sigPos;

                while (sigPos < sigEnd) {
                        if (rest || set1) {
                                // rest of last run
                                sigPos += rest;
                                valPos += rest;
                                rest = 0;
                        } else {
                                // decode significant bits
                                if (GetBit(m_codeBuffer, codePos++)) {
                                        // extract counter and generate zero run of length count
                                        if (k > 0) {
                                                // extract counter
                                                count = GetValueBlock(m_codeBuffer, codePos, k); 
                                                codePos += k;
                                                if (count > 0) {
                                                        sigPos += count;
                                                        valPos += count;
                                                }

                                                // adapt k (half run-length interval)
                                                k--;
                                                runlen >>= 1;
                                        }

                                        set1 = true;

                                } else {
                                        // generate zero run of length 2^k
                                        sigPos += runlen;
                                        valPos += runlen;

                                        // adapt k (double run-length interval)
                                        if (k < WordWidth) {
                                                k++;
                                                runlen <<= 1;
                                        }
                                }
                        }

                        if (sigPos < sigEnd) {
                                if (set1) {
                                        set1 = false;

                                        // write 1 bit
                                        SetBitAtPos(valPos, planeMask);

                                        // set sign bit
                                        SetSign(valPos, GetBit(m_codeBuffer, codePos++)); 

                                        // update significance flag vector
                                        m_sigFlagVector[valPos++] = true;
                                        sigPos++;
                                }
                        } else {
                                rest = sigPos - sigEnd;
                                sigPos = sigEnd;
                                valPos -= rest;
                        }

                }

                // refinement bit
                if (valPos < bufferSize) {
                        // write one refinement bit
                        if (GetBit(refBits, refPos)) {
                                SetBitAtPos(valPos, planeMask);
                        }
                        refPos++;
                        valPos++;
                }
        }
        ASSERT(sigPos <= bufferSize);
        ASSERT(refPos <= bufferSize);
        ASSERT(valPos == bufferSize);

        return sigPos;
}
UINT32 CDecoder::CMacroBlock::ComposeBitplaneRLD ( UINT32  bufferSize,
DataT  planeMask,
UINT32 *  sigBits,
UINT32 *  refBits,
UINT32  signPos 
) [private]

Definition at line 882 of file Decoder.cpp.

                                                                                                                                   {
        ASSERT(sigBits);
        ASSERT(refBits);

        UINT32 valPos = 0, refPos = 0;
        UINT32 sigPos = 0, sigEnd;
        UINT32 zerocnt, count = 0;
        UINT32 k = 0;
        UINT32 runlen = 1 << k; // = 2^k
        bool signBit = false;
        bool zeroAfterRun = false;

        while (valPos < bufferSize) {
                // search next 1 in m_sigFlagVector using searching with sentinel
                sigEnd = valPos;
                while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
                sigEnd -= valPos;
                sigEnd += sigPos;

                // search 1's in sigBits[sigPos..sigEnd)
                // these 1's are significant bits
                while (sigPos < sigEnd) {
                        // search 0's
                        zerocnt = SeekBitRange(sigBits, sigPos, sigEnd - sigPos);
                        sigPos += zerocnt;
                        valPos += zerocnt;
                        if (sigPos < sigEnd) {
                                // write bit to m_value
                                SetBitAtPos(valPos, planeMask);

                                // check sign bit
                                if (count == 0) {
                                        // all 1's have been set
                                        if (zeroAfterRun) {
                                                // finish the run with a 0
                                                signBit = false;
                                                zeroAfterRun = false;
                                        } else {
                                                // decode next sign bit
                                                if (GetBit(m_codeBuffer, signPos++)) {
                                                        // generate 1's run of length 2^k
                                                        count = runlen - 1;
                                                        signBit = true;
                        
                                                        // adapt k (double run-length interval)
                                                        if (k < WordWidth) {
                                                                k++; 
                                                                runlen <<= 1;
                                                        }
                                                } else {
                                                        // extract counter and generate 1's run of length count
                                                        if (k > 0) {
                                                                // extract counter
                                                                count = GetValueBlock(m_codeBuffer, signPos, k); 
                                                                signPos += k;

                                                                // adapt k (half run-length interval)
                                                                k--; 
                                                                runlen >>= 1;
                                                        }
                                                        if (count > 0) {
                                                                count--;
                                                                signBit = true;
                                                                zeroAfterRun = true;
                                                        } else {
                                                                signBit = false;
                                                        }
                                                }
                                        }
                                } else {
                                        ASSERT(count > 0);
                                        ASSERT(signBit);
                                        count--;
                                }

                                // copy sign bit
                                SetSign(valPos, signBit); 

                                // update significance flag vector
                                m_sigFlagVector[valPos++] = true;
                                sigPos++; 
                        }
                }

                // refinement bit
                if (valPos < bufferSize) {
                        // write one refinement bit
                        if (GetBit(refBits, refPos)) {
                                SetBitAtPos(valPos, planeMask);
                        }
                        refPos++;
                        valPos++;
                }
        }
        ASSERT(sigPos <= bufferSize);
        ASSERT(refPos <= bufferSize);
        ASSERT(valPos == bufferSize);

        return sigPos;
}
bool CDecoder::CMacroBlock::IsCompletelyRead ( ) const [inline]

Returns true if this macro block has been completely read.

Returns:
true if current value position is at block end

Definition at line 66 of file Decoder.h.

void CDecoder::CMacroBlock::SetBitAtPos ( UINT32  pos,
DataT  planeMask 
) [inline, private]

Definition at line 83 of file Decoder.h.

{ (m_value[pos] >= 0) ? m_value[pos] |= planeMask : m_value[pos] -= planeMask; }
void CDecoder::CMacroBlock::SetSign ( UINT32  pos,
bool  sign 
) [inline, private]

Definition at line 84 of file Decoder.h.

{ m_value[pos] = -m_value[pos]*sign + m_value[pos]*(!sign); }

Member Data Documentation

input buffer for encoded bitstream

Definition at line 76 of file Decoder.h.

Definition at line 86 of file Decoder.h.

block header

Definition at line 74 of file Decoder.h.

Definition at line 87 of file Decoder.h.

output buffer of values with index m_valuePos

Definition at line 75 of file Decoder.h.

current position in m_value

Definition at line 77 of file Decoder.h.


The documentation for this class was generated from the following files:
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines