CEncoder::CMacroBlock(3)

NAME
CEncoder::CMacroBlock - A macro block is an encoding unit of fixed size (uncoded).

SYNOPSIS

  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
CEncoder * m_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.
57                           : 4351 )
58                 : m_value()
59                 , m_codeBuffer()
60                 , m_header(0)
61                 , m_encoder(encoder)
62                 , m_sigFlagVector()
63                 {
64                         ASSERT(m_encoder);
65                         Init(-1);
66                 }

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 482 of file Encoder.cpp.
482                                          {
483         UINT8   nPlanes;
484         UINT32  sigLen, codeLen = 0, wordPos, refLen, signLen;
485         UINT32  sigBits[BufferLen] = { 0 };
486         UINT32  refBits[BufferLen] = { 0 };
487         UINT32  signBits[BufferLen] = { 0 };
488         UINT32  planeMask;
489         UINT32  bufferSize = m_header.rbh.bufferSize; ASSERT(bufferSize <= BufferSize);
490         bool    useRL;
491
492 #ifdef TRACE
493         //printf("which thread: %d\n", omp_get_thread_num());
494 #endif
495
496         // clear significance vector
497         for (UINT32 k=0; k < bufferSize; k++) {
498                 m_sigFlagVector[k] = false;
499         }
500         m_sigFlagVector[bufferSize] = true; // sentinel
501
502         // clear output buffer
503         for (UINT32 k=0; k < bufferSize; k++) {
504                 m_codeBuffer[k] = 0;
505         }
506         m_codePos = 0;
507
508         // compute number of bit planes and split buffer into separate bit planes
509         nPlanes = NumberOfBitplanes();
510
511         // write number of bit planes to m_codeBuffer
512         // <nPlanes>
513         SetValueBlock(m_codeBuffer, 0, nPlanes, MaxBitPlanesLog);
514         m_codePos += MaxBitPlanesLog;
515
516         // loop through all bit planes
517         if (nPlanes == 0) nPlanes = MaxBitPlanes + 1;
518         planeMask = 1 << (nPlanes - 1);
519
520         for (int plane = nPlanes - 1; plane >= 0; plane--) {
521                 // clear significant bitset
522                 for (UINT32 k=0; k < BufferLen; k++) {
523                         sigBits[k] = 0;
524                 }
525
526                 // split bitplane in significant bitset and refinement bitset
527                 sigLen = DecomposeBitplane(bufferSize, planeMask, m_codePos + RLblockSizeLen + 1, sigBits, refBits, signBits, signLen, codeLen);
528
529                 if (sigLen > 0 && codeLen <= MaxCodeLen && codeLen < AlignWordPos(sigLen) + AlignWordPos(signLen) + 2*RLblockSizeLen) {
530                         // set RL code bit
531                         // <1><codeLen>
532                         SetBit(m_codeBuffer, m_codePos++);
533
534                         // write length codeLen to m_codeBuffer
535                         SetValueBlock(m_codeBuffer, m_codePos, codeLen, RLblockSizeLen);
536                         m_codePos += RLblockSizeLen + codeLen;
537                 } else {
538                 #ifdef TRACE
539                         //printf("new\n");
540                         //for (UINT32 i=0; i < bufferSize; i++) {
541                         //      printf("%s", (GetBit(sigBits, i)) ? "1" : "_");
542                         //      if (i%120 == 119) printf("\n");
543                         //}
544                         //printf("\n");
545                 #endif // TRACE
546
547                         // run-length coding wasn't efficient enough
548                         // we don't use RL coding for sigBits
549                         // <0><sigLen>
550                         ClearBit(m_codeBuffer, m_codePos++);
551
552                         // write length sigLen to m_codeBuffer
553                         ASSERT(sigLen <= MaxCodeLen);
554                         SetValueBlock(m_codeBuffer, m_codePos, sigLen, RLblockSizeLen);
555                         m_codePos += RLblockSizeLen;
556
557                         if (m_encoder->m_favorSpeed || signLen == 0) {
558                                 useRL = false;
559                         } else {
560                                 // overwrite m_codeBuffer
561                                 useRL = true;
562                                 // run-length encode m_sign and append them to the m_codeBuffer
563                                 codeLen = RLESigns(m_codePos + RLblockSizeLen + 1, signBits, signLen);
564                         }
565
566                         if (useRL && codeLen <= MaxCodeLen && codeLen < signLen) {
567                                 // RL encoding of m_sign was efficient
568                                 // <1><codeLen><codedSignBits>_
569                                 // write RL code bit
570                                 SetBit(m_codeBuffer, m_codePos++);
571
572                                 // write codeLen to m_codeBuffer
573                                 SetValueBlock(m_codeBuffer, m_codePos, codeLen, RLblockSizeLen);
574
575                                 // compute position of sigBits
576                                 wordPos = NumberOfWords(m_codePos + RLblockSizeLen + codeLen);
577                                 ASSERT(0 <= wordPos && wordPos < CodeBufferLen);
578                         } else {
579                                 // RL encoding of signBits wasn't efficient
580                                 // <0><signLen>_<signBits>_
581                                 // clear RL code bit
582                                 ClearBit(m_codeBuffer, m_codePos++);
583
584                                 // write signLen to m_codeBuffer
585                                 ASSERT(signLen <= MaxCodeLen);
586                                 SetValueBlock(m_codeBuffer, m_codePos, signLen, RLblockSizeLen);
587
588                                 // write signBits to m_codeBuffer
589                                 wordPos = NumberOfWords(m_codePos + RLblockSizeLen);
590                                 ASSERT(0 <= wordPos && wordPos < CodeBufferLen);
591                                 codeLen = NumberOfWords(signLen);
592
593                                 for (UINT32 k=0; k < codeLen; k++) {
594                                         m_codeBuffer[wordPos++] = signBits[k];
595                                 }
596                         }
597
598                         // write sigBits
599                         // <sigBits>_
600                         ASSERT(0 <= wordPos && wordPos < CodeBufferLen);
601                         refLen = NumberOfWords(sigLen);
602
603                         for (UINT32 k=0; k < refLen; k++) {
604                                 m_codeBuffer[wordPos++] = sigBits[k];
605                         }
606                         m_codePos = wordPos << WordWidthLog;
607                 }
608
609                 // append refinement bitset (aligned to word boundary)
610                 // _<refBits>
611                 wordPos = NumberOfWords(m_codePos);
612                 ASSERT(0 <= wordPos && wordPos < CodeBufferLen);
613                 refLen = NumberOfWords(bufferSize - sigLen);
614
615                 for (UINT32 k=0; k < refLen; k++) {
616                         m_codeBuffer[wordPos++] = refBits[k];
617                 }
618                 m_codePos = wordPos << WordWidthLog;
619                 planeMask >>= 1;
620         }
621         ASSERT(0 <= m_codePos && m_codePos <= CodeBufferBitLen);
622 }

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

Definition at line 634 of file Encoder.cpp.
634                                                                                                                                                                                        {
635         ASSERT(sigBits);
636         ASSERT(refBits);
637         ASSERT(signBits);
638         ASSERT(codePos < CodeBufferBitLen);
639
640         UINT32 sigPos = 0;
641         UINT32 valuePos = 0, valueEnd;
642         UINT32 refPos = 0;
643
644         // set output value
645         signLen = 0;
646
647         // prepare RLE of Sigs and Signs
648         const UINT32 outStartPos = codePos;
649         UINT32 k = 3;
650         UINT32 runlen = 1 << k; // = 2^k
651         UINT32 count = 0;
652
653         while (valuePos < bufferSize) {
654                 // search next 1 in m_sigFlagVector using searching with sentinel
655                 valueEnd = valuePos;
656                 while(!m_sigFlagVector[valueEnd]) { valueEnd++; }
657
658                 // search 1's in m_value[plane][valuePos..valueEnd)
659                 // these 1's are significant bits
660                 while (valuePos < valueEnd) {
661                         if (GetBitAtPos(valuePos, planeMask)) {
662                                 // RLE encoding
663                                 // encode run of count 0's followed by a 1
664                                 // with codeword: 1<count>(signBits[signPos])
665                                 SetBit(m_codeBuffer, codePos++);
666                                 if (k > 0) {
667                                         SetValueBlock(m_codeBuffer, codePos, count, k);
668                                         codePos += k;
669
670                                         // adapt k (half the zero run-length)
671                                         k--;
672                                         runlen >>= 1;
673                                 }
674
675                                 // copy and write sign bit
676                                 if (m_value[valuePos] < 0) {
677                                         SetBit(signBits, signLen++);
678                                         SetBit(m_codeBuffer, codePos++);
679                                 } else {
680                                         ClearBit(signBits, signLen++);
681                                         ClearBit(m_codeBuffer, codePos++);
682                                 }
683
684                                 // write a 1 to sigBits
685                                 SetBit(sigBits, sigPos++);
686
687                                 // update m_sigFlagVector
688                                 m_sigFlagVector[valuePos] = true;
689
690                                 // prepare for next run
691                                 count = 0;
692                         } else {
693                                 // RLE encoding
694                                 count++;
695                                 if (count == runlen) {
696                                         // encode run of 2^k zeros by a single 0
697                                         ClearBit(m_codeBuffer, codePos++);
698                                         // adapt k (double the zero run-length)
699                                         if (k < WordWidth) {
700                                                 k++;
701                                                 runlen <<= 1;
702                                         }
703
704                                         // prepare for next run
705                                         count = 0;
706                                 }
707
708                                 // write 0 to sigBits
709                                 sigPos++;
710                         }
711                         valuePos++;
712                 }
713                 // refinement bit
714                 if (valuePos < bufferSize) {
715                         // write one refinement bit
716                         if (GetBitAtPos(valuePos++, planeMask)) {
717                                 SetBit(refBits, refPos);
718                         } else {
719                                 ClearBit(refBits, refPos);
720                         }
721                         refPos++;
722                 }
723         }
724         // RLE encoding of the rest of the plane
725         // encode run of count 0's followed by a 1
726         // with codeword: 1<count>(signBits[signPos])
727         SetBit(m_codeBuffer, codePos++);
728         if (k > 0) {
729                 SetValueBlock(m_codeBuffer, codePos, count, k);
730                 codePos += k;
731         }
732         // write dmmy sign bit
733         SetBit(m_codeBuffer, codePos++);
734
735         // write word filler zeros
736
737         ASSERT(sigPos <= bufferSize);
738         ASSERT(refPos <= bufferSize);
739         ASSERT(signLen <= bufferSize);
740         ASSERT(valuePos == bufferSize);
741         ASSERT(codePos >= outStartPos && codePos < CodeBufferBitLen);
742         codeLen = codePos - outStartPos;
743
744         return sigPos;
745 }

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

Definition at line 96 of file Encoder.h.
96 { 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.
71                                               {                         // initialize for reusage
72                         m_valuePos = 0;
73                         m_maxAbsValue = 0;
74                         m_codePos = 0;
75                         m_lastLevelIndex = lastLevelIndex;
76                 }

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

Definition at line 750 of file Encoder.cpp.
750                                              {
751         UINT8 cnt = 0;
752
753         // determine number of bitplanes for max value
754         if (m_maxAbsValue > 0) {
755                 while (m_maxAbsValue > 0) {
756                         m_maxAbsValue >>= 1; cnt++;
757                 }
758                 if (cnt == MaxBitPlanes + 1) cnt = 0;
759                 // end cs
760                 ASSERT(cnt <= MaxBitPlanes);
761                 ASSERT((cnt >> MaxBitPlanesLog) == 0);
762                 return cnt;
763         } else {
764                 return 1;
765         }
766 }

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

Definition at line 774 of file Encoder.cpp.
774                                                                                      {
775         ASSERT(signBits);
776         ASSERT(0 <= codePos && codePos < CodeBufferBitLen);
777         ASSERT(0 < signLen && signLen <= BufferSize);
778
779         const UINT32  outStartPos = codePos;
780         UINT32 k = 0;
781         UINT32 runlen = 1 << k; // = 2^k
782         UINT32 count = 0;
783         UINT32 signPos = 0;
784
785         while (signPos < signLen) {
786                 // search next 0 in signBits starting at position signPos
787                 count = SeekBit1Range(signBits, signPos, __min(runlen, signLen - signPos));
788                 // count 1's found
789                 if (count == runlen) {
790                         // encode run of 2^k ones by a single 1
791                         signPos += count;
792                         SetBit(m_codeBuffer, codePos++);
793                         // adapt k (double the 1's run-length)
794                         if (k < WordWidth) {
795                                 k++;
796                                 runlen <<= 1;
797                         }
798                 } else {
799                         // encode run of count 1's followed by a 0
800                         // with codeword: 0(count)
801                         signPos += count + 1;
802                         ClearBit(m_codeBuffer, codePos++);
803                         if (k > 0) {
804                                 SetValueBlock(m_codeBuffer, codePos, count, k);
805                                 codePos += k;
806                         }
807                         // adapt k (half the 1's run-length)
808                         if (k > 0) {
809                                 k--;
810                                 runlen >>= 1;
811                         }
812                 }
813         }
814         ASSERT(signPos == signLen || signPos == signLen + 1);
815         ASSERT(codePos >= outStartPos && codePos < CodeBufferBitLen);
816         return codePos - outStartPos;
817 }

Member Data Documentation

  UINT32 CEncoder::CMacroBlock::m_codeBuffer[CodeBufferLen]

output buffer for encoded bitstream

Definition at line 85 of file Encoder.h.

  UINT32 CEncoder::CMacroBlock::m_codePos

current position in encoded bitstream

Definition at line 89 of file Encoder.h.

  CEncoder* CEncoder::CMacroBlock::m_encoder [private]

Definition at line 98 of file Encoder.h.

  ROIBlockHeader CEncoder::CMacroBlock::m_header

block header

Definition at line 86 of file Encoder.h.

  int CEncoder::CMacroBlock::m_lastLevelIndex

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.

  UINT32 CEncoder::CMacroBlock::m_maxAbsValue

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.

  DataT CEncoder::CMacroBlock::m_value[BufferSize]

input buffer of values with index m_valuePos

Definition at line 84 of file Encoder.h.

  UINT32 CEncoder::CMacroBlock::m_valuePos

current buffer position

Definition at line 87 of file Encoder.h.

Author

Generated automatically by Doxygen for libpgf from the source code.