A macro block is a decoding unit of fixed size (uncoded). More...
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] |
A macro block is a decoding unit of fixed size (uncoded).
PGF decoder macro block class.
Definition at line 51 of file Decoder.h.
CDecoder::CMacroBlock::CMacroBlock | ( | ) | [inline] |
Constructor: Initializes new macro block.
decoder | Pointer to outer class. |
Definition at line 56 of file Decoder.h.
00057 : m_header(0) // makes sure that IsCompletelyRead() returns true for an empty macro block 00058 #pragma warning( suppress : 4351 ) 00059 , m_value() 00060 , m_codeBuffer() 00061 , m_valuePos(0) 00062 , m_sigFlagVector() 00063 { 00064 }
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.
00620 { 00621 UINT32 bufferSize = m_header.rbh.bufferSize; ASSERT(bufferSize <= BufferSize); 00622 00623 UINT32 nPlanes; 00624 UINT32 codePos = 0, codeLen, sigLen, sigPos, signLen, signPos; 00625 DataT planeMask; 00626 00627 // clear significance vector 00628 for (UINT32 k=0; k < bufferSize; k++) { 00629 m_sigFlagVector[k] = false; 00630 } 00631 m_sigFlagVector[bufferSize] = true; // sentinel 00632 00633 // clear output buffer 00634 for (UINT32 k=0; k < BufferSize; k++) { 00635 m_value[k] = 0; 00636 } 00637 00638 // read number of bit planes 00639 // <nPlanes> 00640 nPlanes = GetValueBlock(m_codeBuffer, 0, MaxBitPlanesLog); 00641 codePos += MaxBitPlanesLog; 00642 00643 // loop through all bit planes 00644 if (nPlanes == 0) nPlanes = MaxBitPlanes + 1; 00645 ASSERT(0 < nPlanes && nPlanes <= MaxBitPlanes + 1); 00646 planeMask = 1 << (nPlanes - 1); 00647 00648 for (int plane = nPlanes - 1; plane >= 0; plane--) { 00649 // read RL code 00650 if (GetBit(m_codeBuffer, codePos)) { 00651 // RL coding of sigBits is used 00652 // <1><codeLen><codedSigAndSignBits>_<refBits> 00653 codePos++; 00654 00655 // read codeLen 00656 codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen <= MaxCodeLen); 00657 00658 // position of encoded sigBits and signBits 00659 sigPos = codePos + RLblockSizeLen; ASSERT(sigPos < CodeBufferBitLen); 00660 00661 // refinement bits 00662 codePos = AlignWordPos(sigPos + codeLen); ASSERT(codePos < CodeBufferBitLen); 00663 00664 // run-length decode significant bits and signs from m_codeBuffer and 00665 // read refinement bits from m_codeBuffer and compose bit plane 00666 sigLen = ComposeBitplaneRLD(bufferSize, planeMask, sigPos, &m_codeBuffer[codePos >> WordWidthLog]); 00667 00668 } else { 00669 // no RL coding is used for sigBits and signBits together 00670 // <0><sigLen> 00671 codePos++; 00672 00673 // read sigLen 00674 sigLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(sigLen <= MaxCodeLen); 00675 codePos += RLblockSizeLen; ASSERT(codePos < CodeBufferBitLen); 00676 00677 // read RL code for signBits 00678 if (GetBit(m_codeBuffer, codePos)) { 00679 // RL coding is used just for signBits 00680 // <1><codeLen><codedSignBits>_<sigBits>_<refBits> 00681 codePos++; 00682 00683 // read codeLen 00684 codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen <= MaxCodeLen); 00685 00686 // sign bits 00687 signPos = codePos + RLblockSizeLen; ASSERT(signPos < CodeBufferBitLen); 00688 00689 // significant bits 00690 sigPos = AlignWordPos(signPos + codeLen); ASSERT(sigPos < CodeBufferBitLen); 00691 00692 // refinement bits 00693 codePos = AlignWordPos(sigPos + sigLen); ASSERT(codePos < CodeBufferBitLen); 00694 00695 // read significant and refinement bitset from m_codeBuffer 00696 sigLen = ComposeBitplaneRLD(bufferSize, planeMask, &m_codeBuffer[sigPos >> WordWidthLog], &m_codeBuffer[codePos >> WordWidthLog], signPos); 00697 00698 } else { 00699 // RL coding of signBits was not efficient and therefore not used 00700 // <0><signLen>_<signBits>_<sigBits>_<refBits> 00701 codePos++; 00702 00703 // read signLen 00704 signLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(signLen <= MaxCodeLen); 00705 00706 // sign bits 00707 signPos = AlignWordPos(codePos + RLblockSizeLen); ASSERT(signPos < CodeBufferBitLen); 00708 00709 // significant bits 00710 sigPos = AlignWordPos(signPos + signLen); ASSERT(sigPos < CodeBufferBitLen); 00711 00712 // refinement bits 00713 codePos = AlignWordPos(sigPos + sigLen); ASSERT(codePos < CodeBufferBitLen); 00714 00715 // read significant and refinement bitset from m_codeBuffer 00716 sigLen = ComposeBitplane(bufferSize, planeMask, &m_codeBuffer[sigPos >> WordWidthLog], &m_codeBuffer[codePos >> WordWidthLog], &m_codeBuffer[signPos >> WordWidthLog]); 00717 } 00718 } 00719 00720 // start of next chunk 00721 codePos = AlignWordPos(codePos + bufferSize - sigLen); ASSERT(codePos < CodeBufferBitLen); 00722 00723 // next plane 00724 planeMask >>= 1; 00725 } 00726 00727 m_valuePos = 0; 00728 }
UINT32 CDecoder::CMacroBlock::ComposeBitplane | ( | UINT32 | bufferSize, | |
DataT | planeMask, | |||
UINT32 * | sigBits, | |||
UINT32 * | refBits, | |||
UINT32 * | signBits | |||
) | [private] |
Definition at line 735 of file Decoder.cpp.
00735 { 00736 ASSERT(sigBits); 00737 ASSERT(refBits); 00738 ASSERT(signBits); 00739 00740 UINT32 valPos = 0, signPos = 0, refPos = 0; 00741 UINT32 sigPos = 0, sigEnd; 00742 UINT32 zerocnt; 00743 00744 while (valPos < bufferSize) { 00745 // search next 1 in m_sigFlagVector using searching with sentinel 00746 sigEnd = valPos; 00747 while(!m_sigFlagVector[sigEnd]) { sigEnd++; } 00748 sigEnd -= valPos; 00749 sigEnd += sigPos; 00750 00751 // search 1's in sigBits[sigPos..sigEnd) 00752 // these 1's are significant bits 00753 while (sigPos < sigEnd) { 00754 // search 0's 00755 zerocnt = SeekBitRange(sigBits, sigPos, sigEnd - sigPos); 00756 sigPos += zerocnt; 00757 valPos += zerocnt; 00758 if (sigPos < sigEnd) { 00759 // write bit to m_value 00760 SetBitAtPos(valPos, planeMask); 00761 00762 // copy sign bit 00763 SetSign(valPos, GetBit(signBits, signPos++)); 00764 00765 // update significance flag vector 00766 m_sigFlagVector[valPos++] = true; 00767 sigPos++; 00768 } 00769 } 00770 // refinement bit 00771 if (valPos < bufferSize) { 00772 // write one refinement bit 00773 if (GetBit(refBits, refPos)) { 00774 SetBitAtPos(valPos, planeMask); 00775 } 00776 refPos++; 00777 valPos++; 00778 } 00779 } 00780 ASSERT(sigPos <= bufferSize); 00781 ASSERT(refPos <= bufferSize); 00782 ASSERT(signPos <= bufferSize); 00783 ASSERT(valPos == bufferSize); 00784 00785 return sigPos; 00786 }
UINT32 CDecoder::CMacroBlock::ComposeBitplaneRLD | ( | UINT32 | bufferSize, | |
DataT | planeMask, | |||
UINT32 * | sigBits, | |||
UINT32 * | refBits, | |||
UINT32 | signPos | |||
) | [private] |
Definition at line 901 of file Decoder.cpp.
00901 { 00902 ASSERT(sigBits); 00903 ASSERT(refBits); 00904 00905 UINT32 valPos = 0, refPos = 0; 00906 UINT32 sigPos = 0, sigEnd; 00907 UINT32 zerocnt, count = 0; 00908 UINT32 k = 0; 00909 UINT32 runlen = 1 << k; // = 2^k 00910 bool signBit = false; 00911 bool zeroAfterRun = false; 00912 00913 while (valPos < bufferSize) { 00914 // search next 1 in m_sigFlagVector using searching with sentinel 00915 sigEnd = valPos; 00916 while(!m_sigFlagVector[sigEnd]) { sigEnd++; } 00917 sigEnd -= valPos; 00918 sigEnd += sigPos; 00919 00920 // search 1's in sigBits[sigPos..sigEnd) 00921 // these 1's are significant bits 00922 while (sigPos < sigEnd) { 00923 // search 0's 00924 zerocnt = SeekBitRange(sigBits, sigPos, sigEnd - sigPos); 00925 sigPos += zerocnt; 00926 valPos += zerocnt; 00927 if (sigPos < sigEnd) { 00928 // write bit to m_value 00929 SetBitAtPos(valPos, planeMask); 00930 00931 // check sign bit 00932 if (count == 0) { 00933 // all 1's have been set 00934 if (zeroAfterRun) { 00935 // finish the run with a 0 00936 signBit = false; 00937 zeroAfterRun = false; 00938 } else { 00939 // decode next sign bit 00940 if (GetBit(m_codeBuffer, signPos++)) { 00941 // generate 1's run of length 2^k 00942 count = runlen - 1; 00943 signBit = true; 00944 00945 // adapt k (double run-length interval) 00946 if (k < WordWidth) { 00947 k++; 00948 runlen <<= 1; 00949 } 00950 } else { 00951 // extract counter and generate 1's run of length count 00952 if (k > 0) { 00953 // extract counter 00954 count = GetValueBlock(m_codeBuffer, signPos, k); 00955 signPos += k; 00956 00957 // adapt k (half run-length interval) 00958 k--; 00959 runlen >>= 1; 00960 } 00961 if (count > 0) { 00962 count--; 00963 signBit = true; 00964 zeroAfterRun = true; 00965 } else { 00966 signBit = false; 00967 } 00968 } 00969 } 00970 } else { 00971 ASSERT(count > 0); 00972 ASSERT(signBit); 00973 count--; 00974 } 00975 00976 // copy sign bit 00977 SetSign(valPos, signBit); 00978 00979 // update significance flag vector 00980 m_sigFlagVector[valPos++] = true; 00981 sigPos++; 00982 } 00983 } 00984 00985 // refinement bit 00986 if (valPos < bufferSize) { 00987 // write one refinement bit 00988 if (GetBit(refBits, refPos)) { 00989 SetBitAtPos(valPos, planeMask); 00990 } 00991 refPos++; 00992 valPos++; 00993 } 00994 } 00995 ASSERT(sigPos <= bufferSize); 00996 ASSERT(refPos <= bufferSize); 00997 ASSERT(valPos == bufferSize); 00998 00999 return sigPos; 01000 }
UINT32 CDecoder::CMacroBlock::ComposeBitplaneRLD | ( | UINT32 | bufferSize, | |
DataT | planeMask, | |||
UINT32 | sigPos, | |||
UINT32 * | refBits | |||
) | [private] |
Definition at line 798 of file Decoder.cpp.
00798 { 00799 ASSERT(refBits); 00800 00801 UINT32 valPos = 0, refPos = 0; 00802 UINT32 sigPos = 0, sigEnd; 00803 UINT32 k = 3; 00804 UINT32 runlen = 1 << k; // = 2^k 00805 UINT32 count = 0, rest = 0; 00806 bool set1 = false; 00807 00808 while (valPos < bufferSize) { 00809 // search next 1 in m_sigFlagVector using searching with sentinel 00810 sigEnd = valPos; 00811 while(!m_sigFlagVector[sigEnd]) { sigEnd++; } 00812 sigEnd -= valPos; 00813 sigEnd += sigPos; 00814 00815 while (sigPos < sigEnd) { 00816 if (rest || set1) { 00817 // rest of last run 00818 sigPos += rest; 00819 valPos += rest; 00820 rest = 0; 00821 } else { 00822 // decode significant bits 00823 if (GetBit(m_codeBuffer, codePos++)) { 00824 // extract counter and generate zero run of length count 00825 if (k > 0) { 00826 // extract counter 00827 count = GetValueBlock(m_codeBuffer, codePos, k); 00828 codePos += k; 00829 if (count > 0) { 00830 sigPos += count; 00831 valPos += count; 00832 } 00833 00834 // adapt k (half run-length interval) 00835 k--; 00836 runlen >>= 1; 00837 } 00838 00839 set1 = true; 00840 00841 } else { 00842 // generate zero run of length 2^k 00843 sigPos += runlen; 00844 valPos += runlen; 00845 00846 // adapt k (double run-length interval) 00847 if (k < WordWidth) { 00848 k++; 00849 runlen <<= 1; 00850 } 00851 } 00852 } 00853 00854 if (sigPos < sigEnd) { 00855 if (set1) { 00856 set1 = false; 00857 00858 // write 1 bit 00859 SetBitAtPos(valPos, planeMask); 00860 00861 // set sign bit 00862 SetSign(valPos, GetBit(m_codeBuffer, codePos++)); 00863 00864 // update significance flag vector 00865 m_sigFlagVector[valPos++] = true; 00866 sigPos++; 00867 } 00868 } else { 00869 rest = sigPos - sigEnd; 00870 sigPos = sigEnd; 00871 valPos -= rest; 00872 } 00873 00874 } 00875 00876 // refinement bit 00877 if (valPos < bufferSize) { 00878 // write one refinement bit 00879 if (GetBit(refBits, refPos)) { 00880 SetBitAtPos(valPos, planeMask); 00881 } 00882 refPos++; 00883 valPos++; 00884 } 00885 } 00886 ASSERT(sigPos <= bufferSize); 00887 ASSERT(refPos <= bufferSize); 00888 ASSERT(valPos == bufferSize); 00889 00890 return sigPos; 00891 }
bool CDecoder::CMacroBlock::IsCompletelyRead | ( | ) | const [inline] |
Returns true if this macro block has been completely read.
Definition at line 69 of file Decoder.h.
00069 { return m_valuePos >= m_header.rbh.bufferSize; }
void CDecoder::CMacroBlock::SetBitAtPos | ( | UINT32 | pos, | |
DataT | planeMask | |||
) | [inline, private] |
void CDecoder::CMacroBlock::SetSign | ( | UINT32 | pos, | |
bool | sign | |||
) | [inline, private] |
UINT32 CDecoder::CMacroBlock::m_codeBuffer[CodeBufferLen] |
bool CDecoder::CMacroBlock::m_sigFlagVector[BufferSize+1] [private] |
DataT CDecoder::CMacroBlock::m_value[BufferSize] |