libpgf 6.14.12
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 ()
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 [CodeBufferLen]
 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

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 51 of file Decoder.h.


Constructor & Destructor Documentation

CDecoder::CMacroBlock::CMacroBlock ( ) [inline]

Constructor: Initializes new macro block.

Parameters:
decoderPointer to outer class.

Definition at line 56 of file Decoder.h.

                : m_header(0)                                                           // makes sure that IsCompletelyRead() returns true for an empty macro block
#pragma warning( suppress : 4351 )
                , m_value()
                , m_codeBuffer()
                , m_valuePos(0)
                , m_sigFlagVector()
                {
                }

Member Function Documentation

void CDecoder::CMacroBlock::BitplaneDecode ( )

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 620 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 735 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 798 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 901 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 69 of file Decoder.h.

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

Definition at line 86 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 87 of file Decoder.h.

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

Member Data Documentation

UINT32 CDecoder::CMacroBlock::m_codeBuffer[CodeBufferLen]

input buffer for encoded bitstream

Definition at line 79 of file Decoder.h.

block header

Definition at line 77 of file Decoder.h.

bool CDecoder::CMacroBlock::m_sigFlagVector[BufferSize+1] [private]

Definition at line 89 of file Decoder.h.

output buffer of values with index m_valuePos

Definition at line 78 of file Decoder.h.

current position in m_value

Definition at line 80 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