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 [CodeBufferLen]
 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 51 of file Encoder.h.


Constructor & Destructor Documentation

CEncoder::CMacroBlock::CMacroBlock ( CEncoder encoder  )  [inline]

Constructor: Initializes new macro block.

Parameters:
encoder Pointer to outer class.

Definition at line 56 of file Encoder.h.

00057                           : 4351 )
00058                 : m_value()
00059                 , m_codeBuffer()
00060                 , m_header(0)
00061                 , m_encoder(encoder)
00062                 , m_sigFlagVector()
00063                 {
00064                         ASSERT(m_encoder);
00065                         Init(-1);
00066                 }


Member Function Documentation

void CEncoder::CMacroBlock::BitplaneEncode (  ) 

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 480 of file Encoder.cpp.

00480                                          {
00481         UINT8   nPlanes;
00482         UINT32  sigLen, codeLen = 0, wordPos, refLen, signLen;
00483         UINT32  sigBits[BufferLen] = { 0 }; 
00484         UINT32  refBits[BufferLen] = { 0 }; 
00485         UINT32  signBits[BufferLen] = { 0 }; 
00486         UINT32  planeMask;
00487         UINT32  bufferSize = m_header.rbh.bufferSize; ASSERT(bufferSize <= BufferSize);
00488         bool    useRL;
00489 
00490 #ifdef TRACE
00491         //printf("which thread: %d\n", omp_get_thread_num());
00492 #endif 
00493 
00494         // clear significance vector
00495         for (UINT32 k=0; k < bufferSize; k++) {
00496                 m_sigFlagVector[k] = false;
00497         }
00498         m_sigFlagVector[bufferSize] = true; // sentinel
00499 
00500         // clear output buffer
00501         for (UINT32 k=0; k < bufferSize; k++) {
00502                 m_codeBuffer[k] = 0;
00503         }
00504         m_codePos = 0;
00505 
00506         // compute number of bit planes and split buffer into separate bit planes
00507         nPlanes = NumberOfBitplanes();
00508 
00509         // write number of bit planes to m_codeBuffer
00510         // <nPlanes>
00511         SetValueBlock(m_codeBuffer, 0, nPlanes, MaxBitPlanesLog);
00512         m_codePos += MaxBitPlanesLog;
00513 
00514         // loop through all bit planes
00515         if (nPlanes == 0) nPlanes = MaxBitPlanes + 1;
00516         planeMask = 1 << (nPlanes - 1);
00517 
00518         for (int plane = nPlanes - 1; plane >= 0; plane--) {
00519                 // clear significant bitset
00520                 for (UINT32 k=0; k < BufferLen; k++) {
00521                         sigBits[k] = 0;
00522                 }
00523 
00524                 // split bitplane in significant bitset and refinement bitset
00525                 sigLen = DecomposeBitplane(bufferSize, planeMask, m_codePos + RLblockSizeLen + 1, sigBits, refBits, signBits, signLen, codeLen);
00526 
00527                 if (sigLen > 0 && codeLen <= MaxCodeLen && codeLen < AlignWordPos(sigLen) + AlignWordPos(signLen) + 2*RLblockSizeLen) {
00528                         // set RL code bit
00529                         // <1><codeLen>
00530                         SetBit(m_codeBuffer, m_codePos++);
00531 
00532                         // write length codeLen to m_codeBuffer
00533                         SetValueBlock(m_codeBuffer, m_codePos, codeLen, RLblockSizeLen);
00534                         m_codePos += RLblockSizeLen + codeLen;
00535                 } else {
00536                 #ifdef TRACE
00537                         //printf("new\n");
00538                         //for (UINT32 i=0; i < bufferSize; i++) {
00539                         //      printf("%s", (GetBit(sigBits, i)) ? "1" : "_");
00540                         //      if (i%120 == 119) printf("\n");
00541                         //}
00542                         //printf("\n");
00543                 #endif // TRACE
00544 
00545                         // run-length coding wasn't efficient enough
00546                         // we don't use RL coding for sigBits
00547                         // <0><sigLen>
00548                         ClearBit(m_codeBuffer, m_codePos++);
00549 
00550                         // write length sigLen to m_codeBuffer
00551                         ASSERT(sigLen <= MaxCodeLen); 
00552                         SetValueBlock(m_codeBuffer, m_codePos, sigLen, RLblockSizeLen);
00553                         m_codePos += RLblockSizeLen;
00554 
00555                         if (m_encoder->m_favorSpeed || signLen == 0) {
00556                                 useRL = false;
00557                         } else {
00558                                 // overwrite m_codeBuffer
00559                                 useRL = true;
00560                                 // run-length encode m_sign and append them to the m_codeBuffer
00561                                 codeLen = RLESigns(m_codePos + RLblockSizeLen + 1, signBits, signLen);
00562                         }
00563 
00564                         if (useRL && codeLen <= MaxCodeLen && codeLen < signLen) {
00565                                 // RL encoding of m_sign was efficient
00566                                 // <1><codeLen><codedSignBits>_
00567                                 // write RL code bit
00568                                 SetBit(m_codeBuffer, m_codePos++);
00569                                 
00570                                 // write codeLen to m_codeBuffer
00571                                 SetValueBlock(m_codeBuffer, m_codePos, codeLen, RLblockSizeLen);
00572 
00573                                 // compute position of sigBits
00574                                 wordPos = NumberOfWords(m_codePos + RLblockSizeLen + codeLen);
00575                                 ASSERT(0 <= wordPos && wordPos < CodeBufferLen);
00576                         } else {
00577                                 // RL encoding of signBits wasn't efficient
00578                                 // <0><signLen>_<signBits>_
00579                                 // clear RL code bit
00580                                 ClearBit(m_codeBuffer, m_codePos++);
00581 
00582                                 // write signLen to m_codeBuffer
00583                                 ASSERT(signLen <= MaxCodeLen); 
00584                                 SetValueBlock(m_codeBuffer, m_codePos, signLen, RLblockSizeLen);
00585 
00586                                 // write signBits to m_codeBuffer
00587                                 wordPos = NumberOfWords(m_codePos + RLblockSizeLen);
00588                                 ASSERT(0 <= wordPos && wordPos < CodeBufferLen);
00589                                 codeLen = NumberOfWords(signLen);
00590 
00591                                 for (UINT32 k=0; k < codeLen; k++) {
00592                                         m_codeBuffer[wordPos++] = signBits[k];
00593                                 }
00594                         }
00595 
00596                         // write sigBits
00597                         // <sigBits>_
00598                         ASSERT(0 <= wordPos && wordPos < CodeBufferLen);
00599                         refLen = NumberOfWords(sigLen);
00600 
00601                         for (UINT32 k=0; k < refLen; k++) {
00602                                 m_codeBuffer[wordPos++] = sigBits[k];
00603                         }
00604                         m_codePos = wordPos << WordWidthLog;
00605                 }
00606 
00607                 // append refinement bitset (aligned to word boundary)
00608                 // _<refBits>
00609                 wordPos = NumberOfWords(m_codePos);
00610                 ASSERT(0 <= wordPos && wordPos < CodeBufferLen);
00611                 refLen = NumberOfWords(bufferSize - sigLen);
00612 
00613                 for (UINT32 k=0; k < refLen; k++) {
00614                         m_codeBuffer[wordPos++] = refBits[k];
00615                 }
00616                 m_codePos = wordPos << WordWidthLog;
00617                 planeMask >>= 1;
00618         }
00619         ASSERT(0 <= m_codePos && m_codePos <= CodeBufferBitLen);
00620 }

UINT32 CEncoder::CMacroBlock::DecomposeBitplane ( UINT32  bufferSize,
UINT32  planeMask,
UINT32  codePos,
UINT32 *  sigBits,
UINT32 *  refBits,
UINT32 *  signBits,
UINT32 &  signLen,
UINT32 &  codeLen 
) [private]

Definition at line 632 of file Encoder.cpp.

00632                                                                                                                                                                                        {
00633         ASSERT(sigBits);
00634         ASSERT(refBits);
00635         ASSERT(signBits);
00636         ASSERT(codePos < CodeBufferBitLen);
00637 
00638         UINT32 sigPos = 0;
00639         UINT32 valuePos = 0, valueEnd;
00640         UINT32 refPos = 0;
00641 
00642         // set output value
00643         signLen = 0;
00644 
00645         // prepare RLE of Sigs and Signs
00646         const UINT32 outStartPos = codePos;
00647         UINT32 k = 3;
00648         UINT32 runlen = 1 << k; // = 2^k
00649         UINT32 count = 0;
00650 
00651         while (valuePos < bufferSize) {
00652                 // search next 1 in m_sigFlagVector using searching with sentinel
00653                 valueEnd = valuePos;
00654                 while(!m_sigFlagVector[valueEnd]) { valueEnd++; }
00655 
00656                 // search 1's in m_value[plane][valuePos..valueEnd)
00657                 // these 1's are significant bits
00658                 while (valuePos < valueEnd) {
00659                         if (GetBitAtPos(valuePos, planeMask)) {
00660                                 // RLE encoding
00661                                 // encode run of count 0's followed by a 1
00662                                 // with codeword: 1<count>(signBits[signPos])
00663                                 SetBit(m_codeBuffer, codePos++); 
00664                                 if (k > 0) {
00665                                         SetValueBlock(m_codeBuffer, codePos, count, k);
00666                                         codePos += k;
00667 
00668                                         // adapt k (half the zero run-length)
00669                                         k--; 
00670                                         runlen >>= 1;
00671                                 }
00672 
00673                                 // copy and write sign bit
00674                                 if (m_value[valuePos] < 0) {
00675                                         SetBit(signBits, signLen++);
00676                                         SetBit(m_codeBuffer, codePos++);
00677                                 } else {
00678                                         ClearBit(signBits, signLen++);
00679                                         ClearBit(m_codeBuffer, codePos++);
00680                                 }
00681 
00682                                 // write a 1 to sigBits
00683                                 SetBit(sigBits, sigPos++); 
00684 
00685                                 // update m_sigFlagVector
00686                                 m_sigFlagVector[valuePos] = true;
00687 
00688                                 // prepare for next run
00689                                 count = 0;
00690                         } else {
00691                                 // RLE encoding
00692                                 count++;
00693                                 if (count == runlen) {
00694                                         // encode run of 2^k zeros by a single 0
00695                                         ClearBit(m_codeBuffer, codePos++);
00696                                         // adapt k (double the zero run-length)
00697                                         if (k < WordWidth) {
00698                                                 k++;
00699                                                 runlen <<= 1;
00700                                         }
00701 
00702                                         // prepare for next run
00703                                         count = 0;
00704                                 }
00705 
00706                                 // write 0 to sigBits
00707                                 sigPos++;
00708                         }
00709                         valuePos++;
00710                 }
00711                 // refinement bit
00712                 if (valuePos < bufferSize) {
00713                         // write one refinement bit
00714                         if (GetBitAtPos(valuePos++, planeMask)) {
00715                                 SetBit(refBits, refPos);
00716                         } else {
00717                                 ClearBit(refBits, refPos);
00718                         }
00719                         refPos++;
00720                 }
00721         }
00722         // RLE encoding of the rest of the plane
00723         // encode run of count 0's followed by a 1
00724         // with codeword: 1<count>(signBits[signPos])
00725         SetBit(m_codeBuffer, codePos++); 
00726         if (k > 0) {
00727                 SetValueBlock(m_codeBuffer, codePos, count, k);
00728                 codePos += k;
00729         }
00730         // write dmmy sign bit
00731         SetBit(m_codeBuffer, codePos++);
00732 
00733         // write word filler zeros
00734 
00735         ASSERT(sigPos <= bufferSize);
00736         ASSERT(refPos <= bufferSize);
00737         ASSERT(signLen <= bufferSize);
00738         ASSERT(valuePos == bufferSize);
00739         ASSERT(codePos >= outStartPos && codePos < CodeBufferBitLen);
00740         codeLen = codePos - outStartPos;
00741 
00742         return sigPos;
00743 }

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

Definition at line 96 of file Encoder.h.

00096 { return (abs(m_value[pos]) & planeMask) > 0; } 

void CEncoder::CMacroBlock::Init ( int  lastLevelIndex  )  [inline]

Reinitialzes this macro block (allows reusage).

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

Definition at line 71 of file Encoder.h.

00071                                               {                         // initialize for reusage
00072                         m_valuePos = 0;
00073                         m_maxAbsValue = 0;
00074                         m_codePos = 0;
00075                         m_lastLevelIndex = lastLevelIndex;
00076                 }

UINT8 CEncoder::CMacroBlock::NumberOfBitplanes (  )  [private]

Definition at line 748 of file Encoder.cpp.

00748                                              {
00749         UINT8 cnt = 0;
00750 
00751         // determine number of bitplanes for max value
00752         if (m_maxAbsValue > 0) {
00753                 while (m_maxAbsValue > 0) {
00754                         m_maxAbsValue >>= 1; cnt++;
00755                 }
00756                 if (cnt == MaxBitPlanes + 1) cnt = 0;
00757                 // end cs
00758                 ASSERT(cnt <= MaxBitPlanes);
00759                 ASSERT((cnt >> MaxBitPlanesLog) == 0);
00760                 return cnt;
00761         } else {
00762                 return 1;
00763         }
00764 }

UINT32 CEncoder::CMacroBlock::RLESigns ( UINT32  codePos,
UINT32 *  signBits,
UINT32  signLen 
) [private]

Definition at line 772 of file Encoder.cpp.

00772                                                                                      {
00773         ASSERT(signBits);
00774         ASSERT(0 <= codePos && codePos < CodeBufferBitLen);
00775         ASSERT(0 < signLen && signLen <= BufferSize);
00776         
00777         const UINT32  outStartPos = codePos;
00778         UINT32 k = 0;
00779         UINT32 runlen = 1 << k; // = 2^k
00780         UINT32 count = 0;
00781         UINT32 signPos = 0;
00782 
00783         while (signPos < signLen) {
00784                 // search next 0 in signBits starting at position signPos
00785                 count = SeekBit1Range(signBits, signPos, __min(runlen, signLen - signPos));
00786                 // count 1's found
00787                 if (count == runlen) {
00788                         // encode run of 2^k ones by a single 1
00789                         signPos += count; 
00790                         SetBit(m_codeBuffer, codePos++);
00791                         // adapt k (double the 1's run-length)
00792                         if (k < WordWidth) {
00793                                 k++; 
00794                                 runlen <<= 1;
00795                         }
00796                 } else {
00797                         // encode run of count 1's followed by a 0
00798                         // with codeword: 0(count)
00799                         signPos += count + 1;
00800                         ClearBit(m_codeBuffer, codePos++);
00801                         if (k > 0) {
00802                                 SetValueBlock(m_codeBuffer, codePos, count, k);
00803                                 codePos += k;
00804                         }
00805                         // adapt k (half the 1's run-length)
00806                         if (k > 0) {
00807                                 k--; 
00808                                 runlen >>= 1;
00809                         }
00810                 }
00811         }
00812         ASSERT(signPos == signLen || signPos == signLen + 1);
00813         ASSERT(codePos >= outStartPos && codePos < CodeBufferBitLen);
00814         return codePos - outStartPos;
00815 }


Member Data Documentation

UINT32 CEncoder::CMacroBlock::m_codeBuffer[CodeBufferLen]

output buffer for encoded bitstream

Definition at line 85 of file Encoder.h.

current position in encoded bitstream

Definition at line 89 of file Encoder.h.

Definition at line 98 of file Encoder.h.

block header

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

maximum absolute coefficient in each buffer

Definition at line 88 of file Encoder.h.

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

Definition at line 99 of file Encoder.h.

input buffer of values with index m_valuePos

Definition at line 84 of file Encoder.h.

current buffer position

Definition at line 87 of file Encoder.h.


The documentation for this class was generated from the following files:

Generated on 18 Feb 2019 for libpgf by  doxygen 1.6.1