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

A macro block is an encoding unit of fixed size (uncoded) More...

List of all members.

Public Member Functions

 CMacroBlock (CEncoder *encoder)
void Init (int lastLevelIndex)
void BitplaneEncode ()

Public Attributes

DataT m_value [BufferSize]
 input buffer of values with index m_valuePos
UINT32 m_codeBuffer [BufferSize]
 output buffer for encoded bitstream
ROIBlockHeader m_header
 block header
UINT32 m_valuePos
 current buffer position
UINT32 m_maxAbsValue
 maximum absolute coefficient in each buffer
UINT32 m_codePos
 current position in encoded bitstream
int m_lastLevelIndex
 index of last encoded level: [0, nLevels); used because a level-end can occur before a buffer is full

Private Member Functions

UINT32 RLESigns (UINT32 codePos, UINT32 *signBits, UINT32 signLen)
UINT32 DecomposeBitplane (UINT32 bufferSize, UINT32 planeMask, UINT32 codePos, UINT32 *sigBits, UINT32 *refBits, UINT32 *signBits, UINT32 &signLen, UINT32 &codeLen)
UINT8 NumberOfBitplanes ()
bool GetBitAtPos (UINT32 pos, UINT32 planeMask) const

Private Attributes

CEncoderm_encoder
bool m_sigFlagVector [BufferSize+1]

Detailed Description

A macro block is an encoding unit of fixed size (uncoded)

PGF encoder macro block class.

Author:
C. Stamm, I. Bauersachs

Definition at line 50 of file Encoder.h.


Constructor & Destructor Documentation

Constructor: Initializes new macro block.

Parameters:
encoderPointer to outer class.

Definition at line 55 of file Encoder.h.

                : m_header(0)
                , m_encoder(encoder)
                {
                        ASSERT(m_encoder);
                        Init(-1);
                }

Member Function Documentation

Encodes this macro block into internal code buffer. Several macro blocks can be encoded in parallel. Call CEncoder::WriteMacroBlock after this method.

Definition at line 418 of file Encoder.cpp.

                                         {
        UINT8   nPlanes;
        UINT32  sigLen, codeLen = 0, wordPos, refLen, signLen;
        UINT32  sigBits[BufferLen] = { 0 }; 
        UINT32  refBits[BufferLen] = { 0 }; 
        UINT32  signBits[BufferLen] = { 0 }; 
        UINT32  planeMask;
        UINT32  bufferSize = m_header.rbh.bufferSize; ASSERT(bufferSize <= BufferSize);
        bool    useRL;

#ifdef TRACE
        //printf("which thread: %d\n", omp_get_thread_num());
#endif 

        // 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_codeBuffer[k] = 0;
        }
        m_codePos = 0;

        // compute number of bit planes and split buffer into separate bit planes
        nPlanes = NumberOfBitplanes();

        // write number of bit planes to m_codeBuffer
        // <nPlanes>
        SetValueBlock(m_codeBuffer, 0, nPlanes, MaxBitPlanesLog);
        m_codePos += MaxBitPlanesLog;

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

        for (int plane = nPlanes - 1; plane >= 0; plane--) {
                // clear significant bitset
                for (UINT32 k=0; k < BufferLen; k++) {
                        sigBits[k] = 0;
                }

                // split bitplane in significant bitset and refinement bitset
                sigLen = DecomposeBitplane(bufferSize, planeMask, m_codePos + RLblockSizeLen + 1, sigBits, refBits, signBits, signLen, codeLen);

                if (sigLen > 0 && codeLen <= MaxCodeLen && codeLen < AlignWordPos(sigLen) + AlignWordPos(signLen) + 2*RLblockSizeLen) {
                        // set RL code bit
                        // <1><codeLen>
                        SetBit(m_codeBuffer, m_codePos++);

                        // write length codeLen to m_codeBuffer
                        SetValueBlock(m_codeBuffer, m_codePos, codeLen, RLblockSizeLen);
                        m_codePos += RLblockSizeLen + codeLen;
                } else {
                #ifdef TRACE
                        //printf("new\n");
                        //for (UINT32 i=0; i < bufferSize; i++) {
                        //      printf("%s", (GetBit(sigBits, i)) ? "1" : "_");
                        //      if (i%120 == 119) printf("\n");
                        //}
                        //printf("\n");
                #endif // TRACE

                        // run-length coding wasn't efficient enough
                        // we don't use RL coding for sigBits
                        // <0><sigLen>
                        ClearBit(m_codeBuffer, m_codePos++);

                        // write length sigLen to m_codeBuffer
                        ASSERT(sigLen <= MaxCodeLen); 
                        SetValueBlock(m_codeBuffer, m_codePos, sigLen, RLblockSizeLen);
                        m_codePos += RLblockSizeLen;

                        if (m_encoder->m_favorSpeed || signLen == 0) {
                                useRL = false;
                        } else {
                                // overwrite m_codeBuffer
                                useRL = true;
                                // run-length encode m_sign and append them to the m_codeBuffer
                                codeLen = RLESigns(m_codePos + RLblockSizeLen + 1, signBits, signLen);
                        }

                        if (useRL && codeLen <= MaxCodeLen && codeLen < signLen) {
                                // RL encoding of m_sign was efficient
                                // <1><codeLen><codedSignBits>_
                                // write RL code bit
                                SetBit(m_codeBuffer, m_codePos++);
                                
                                // write codeLen to m_codeBuffer
                                SetValueBlock(m_codeBuffer, m_codePos, codeLen, RLblockSizeLen);

                                // compute position of sigBits
                                wordPos = NumberOfWords(m_codePos + RLblockSizeLen + codeLen);
                                ASSERT(0 <= wordPos && wordPos < bufferSize);
                        } else {
                                // RL encoding of signBits wasn't efficient
                                // <0><signLen>_<signBits>_
                                // clear RL code bit
                                ClearBit(m_codeBuffer, m_codePos++);

                                // write signLen to m_codeBuffer
                                ASSERT(signLen <= MaxCodeLen); 
                                SetValueBlock(m_codeBuffer, m_codePos, signLen, RLblockSizeLen);

                                // write signBits to m_codeBuffer
                                wordPos = NumberOfWords(m_codePos + RLblockSizeLen);
                                ASSERT(0 <= wordPos && wordPos < bufferSize);
                                codeLen = NumberOfWords(signLen);

                                for (UINT32 k=0; k < codeLen; k++) {
                                        m_codeBuffer[wordPos++] = signBits[k];
                                }
                        }

                        // write sigBits
                        // <sigBits>_
                        ASSERT(0 <= wordPos && wordPos < bufferSize);
                        refLen = NumberOfWords(sigLen);

                        for (UINT32 k=0; k < refLen; k++) {
                                m_codeBuffer[wordPos++] = sigBits[k];
                        }
                        m_codePos = wordPos << WordWidthLog;
                }

                // append refinement bitset (aligned to word boundary)
                // _<refBits>
                wordPos = NumberOfWords(m_codePos);
                ASSERT(0 <= wordPos && wordPos < bufferSize);
                refLen = NumberOfWords(bufferSize - sigLen);

                for (UINT32 k=0; k < refLen; k++) {
                        m_codeBuffer[wordPos++] = refBits[k];
                }
                m_codePos = wordPos << WordWidthLog;
                planeMask >>= 1;
        }
        ASSERT(0 <= m_codePos && m_codePos <= CodeBufferBitLen);
}
UINT32 CEncoder::CMacroBlock::DecomposeBitplane ( UINT32  bufferSize,
UINT32  planeMask,
UINT32  codePos,
UINT32 *  sigBits,
UINT32 *  refBits,
UINT32 *  signBits,
UINT32 &  signLen,
UINT32 &  codeLen 
) [private]

Definition at line 570 of file Encoder.cpp.

                                                                                                                                                                                       {
        ASSERT(sigBits);
        ASSERT(refBits);
        ASSERT(signBits);
        ASSERT(codePos < CodeBufferBitLen);

        UINT32 sigPos = 0;
        UINT32 valuePos = 0, valueEnd;
        UINT32 refPos = 0;

        // set output value
        signLen = 0;

        // prepare RLE of Sigs and Signs
        const UINT32 outStartPos = codePos;
        UINT32 k = 3;
        UINT32 runlen = 1 << k; // = 2^k
        UINT32 count = 0;

        while (valuePos < bufferSize) {
                // search next 1 in m_sigFlagVector using searching with sentinel
                valueEnd = valuePos;
                while(!m_sigFlagVector[valueEnd]) { valueEnd++; }

                // search 1's in m_value[plane][valuePos..valueEnd)
                // these 1's are significant bits
                while (valuePos < valueEnd) {
                        if (GetBitAtPos(valuePos, planeMask)) {
                                // RLE encoding
                                // encode run of count 0's followed by a 1
                                // with codeword: 1<count>(signBits[signPos])
                                SetBit(m_codeBuffer, codePos++); 
                                if (k > 0) {
                                        SetValueBlock(m_codeBuffer, codePos, count, k);
                                        codePos += k;

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

                                // copy and write sign bit
                                if (m_value[valuePos] < 0) {
                                        SetBit(signBits, signLen++);
                                        SetBit(m_codeBuffer, codePos++);
                                } else {
                                        ClearBit(signBits, signLen++);
                                        ClearBit(m_codeBuffer, codePos++);
                                }

                                // write a 1 to sigBits
                                SetBit(sigBits, sigPos++); 

                                // update m_sigFlagVector
                                m_sigFlagVector[valuePos] = true;

                                // prepare for next run
                                count = 0;
                        } else {
                                // RLE encoding
                                count++;
                                if (count == runlen) {
                                        // encode run of 2^k zeros by a single 0
                                        ClearBit(m_codeBuffer, codePos++);
                                        // adapt k (double the zero run-length)
                                        if (k < WordWidth) {
                                                k++;
                                                runlen <<= 1;
                                        }

                                        // prepare for next run
                                        count = 0;
                                }

                                // write 0 to sigBits
                                sigPos++;
                        }
                        valuePos++;
                }
                // refinement bit
                if (valuePos < bufferSize) {
                        // write one refinement bit
                        if (GetBitAtPos(valuePos++, planeMask)) {
                                SetBit(refBits, refPos);
                        } else {
                                ClearBit(refBits, refPos);
                        }
                        refPos++;
                }
        }
        // RLE encoding of the rest of the plane
        // encode run of count 0's followed by a 1
        // with codeword: 1<count>(signBits[signPos])
        SetBit(m_codeBuffer, codePos++); 
        if (k > 0) {
                SetValueBlock(m_codeBuffer, codePos, count, k);
                codePos += k;
        }
        // write dmmy sign bit
        SetBit(m_codeBuffer, codePos++);

        // write word filler zeros

        ASSERT(sigPos <= bufferSize);
        ASSERT(refPos <= bufferSize);
        ASSERT(signLen <= bufferSize);
        ASSERT(valuePos == bufferSize);
        ASSERT(codePos >= outStartPos && codePos < CodeBufferBitLen);
        codeLen = codePos - outStartPos;

        return sigPos;
}
bool CEncoder::CMacroBlock::GetBitAtPos ( UINT32  pos,
UINT32  planeMask 
) const [inline, private]

Definition at line 92 of file Encoder.h.

{ return (abs(m_value[pos]) & planeMask) > 0; } 
void CEncoder::CMacroBlock::Init ( int  lastLevelIndex) [inline]

Reinitialzes this macro block (allows reusage).

Parameters:
lastLevelIndexLevel length directory index of last encoded level: [0, nLevels)

Definition at line 66 of file Encoder.h.

                                              {                         // initialize for reusage
                        m_valuePos = 0;
                        m_maxAbsValue = 0;
                        m_codePos = 0;
                        m_lastLevelIndex = lastLevelIndex;
                }

Definition at line 686 of file Encoder.cpp.

                                             {
        UINT8 cnt = 0;

        // determine number of bitplanes for max value
        if (m_maxAbsValue > 0) {
                while (m_maxAbsValue > 0) {
                        m_maxAbsValue >>= 1; cnt++;
                }
                if (cnt == MaxBitPlanes + 1) cnt = 0;
                // end cs
                ASSERT(cnt <= MaxBitPlanes);
                ASSERT((cnt >> MaxBitPlanesLog) == 0);
                return cnt;
        } else {
                return 1;
        }
}
UINT32 CEncoder::CMacroBlock::RLESigns ( UINT32  codePos,
UINT32 *  signBits,
UINT32  signLen 
) [private]

Definition at line 710 of file Encoder.cpp.

                                                                                     {
        ASSERT(signBits);
        ASSERT(0 <= codePos && codePos < CodeBufferBitLen);
        ASSERT(0 < signLen && signLen <= BufferSize);
        
        const UINT32  outStartPos = codePos;
        UINT32 k = 0;
        UINT32 runlen = 1 << k; // = 2^k
        UINT32 count = 0;
        UINT32 signPos = 0;

        while (signPos < signLen) {
                // search next 0 in signBits starting at position signPos
                count = SeekBit1Range(signBits, signPos, __min(runlen, signLen - signPos));
                // count 1's found
                if (count == runlen) {
                        // encode run of 2^k ones by a single 1
                        signPos += count; 
                        SetBit(m_codeBuffer, codePos++);
                        // adapt k (double the 1's run-length)
                        if (k < WordWidth) {
                                k++; 
                                runlen <<= 1;
                        }
                } else {
                        // encode run of count 1's followed by a 0
                        // with codeword: 0(count)
                        signPos += count + 1;
                        ClearBit(m_codeBuffer, codePos++);
                        if (k > 0) {
                                SetValueBlock(m_codeBuffer, codePos, count, k);
                                codePos += k;
                        }
                        // adapt k (half the 1's run-length)
                        if (k > 0) {
                                k--; 
                                runlen >>= 1;
                        }
                }
        }
        ASSERT(signPos == signLen || signPos == signLen + 1);
        ASSERT(codePos >= outStartPos && codePos < CodeBufferBitLen);
        return codePos - outStartPos;
}

Member Data Documentation

output buffer for encoded bitstream

Definition at line 80 of file Encoder.h.

current position in encoded bitstream

Definition at line 85 of file Encoder.h.

Definition at line 94 of file Encoder.h.

block header

Definition at line 82 of file Encoder.h.

index of last encoded level: [0, nLevels); used because a level-end can occur before a buffer is full

Definition at line 86 of file Encoder.h.

maximum absolute coefficient in each buffer

Definition at line 84 of file Encoder.h.

Definition at line 95 of file Encoder.h.

input buffer of values with index m_valuePos

Definition at line 79 of file Encoder.h.

current buffer position

Definition at line 83 of file Encoder.h.


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