libpgf: CDecoder::CMacroBlock Class Reference

| libpgf 7.21.2 PGF - Progressive Graphics File

Loading...
Searching...
No Matches
CDecoder::CMacroBlock Class Reference

A macro block is a decoding unit of fixed size (uncoded). More...

## Public Member Functions
| CMacroBlock ()
| Constructor: Initializes new macro block.
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

## ◆ CMacroBlock()

CDecoder::CMacroBlock::CMacroBlock | ( |  | ) |
| inline

Constructor: Initializes new macro block.

Definition at line 55 of file Decoder.h.

56 : m_header(0) // makes sure that IsCompletelyRead() returns true for an empty macro block
57#pragma warning( suppress : 4351 )
58 , m_value()
59 , m_codeBuffer()
60 , m_valuePos(0)
61 , m_sigFlagVector()
62 {
63 }
CDecoder::CMacroBlock::m_header
ROIBlockHeader m_header
block header
Definition Decoder.h:76
CDecoder::CMacroBlock::m_valuePos
UINT32 m_valuePos
current position in m_value
Definition Decoder.h:79
CDecoder::CMacroBlock::m_value
DataT m_value[BufferSize]
output buffer of values with index m_valuePos
Definition Decoder.h:77
CDecoder::CMacroBlock::m_codeBuffer
UINT32 m_codeBuffer[CodeBufferLen]
input buffer for encoded bitstream
Definition Decoder.h:78
CDecoder::CMacroBlock::m_sigFlagVector
bool m_sigFlagVector[BufferSize+1]
Definition Decoder.h:88

## Member Function Documentation

## ◆ BitplaneDecode()

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 650 of file Decoder.cpp.

650 {
651 UINT32 bufferSize = m_header.rbh.bufferSize; ASSERT(bufferSize <= BufferSize);
652
653 // clear significance vector
654 for (UINT32 k=0; k < bufferSize; k++) {
655 m_sigFlagVector[k] = false;
656 }
657 m_sigFlagVector[bufferSize] = true; // sentinel
658
659 // clear output buffer
660 for (UINT32 k=0; k < BufferSize; k++) {
661 m_value[k] = 0;
662 }
663
664 // read number of bit planes
665 // <nPlanes>
666 UINT32 nPlanes = GetValueBlock(m_codeBuffer, 0, MaxBitPlanesLog);
667 UINT32 codePos = MaxBitPlanesLog;
668
669 // loop through all bit planes
670 if (nPlanes == 0) nPlanes = MaxBitPlanes + 1;
671 ASSERT(0 < nPlanes && nPlanes <= MaxBitPlanes + 1);
672 DataT planeMask = 1 << (nPlanes - 1);
673
674 for (int plane = nPlanes - 1; plane >= 0; plane--) {
675 UINT32 sigLen = 0;
676
677 // read RL code
678 if (GetBit(m_codeBuffer, codePos)) {
679 // RL coding of sigBits is used
680 // <1><codeLen><codedSigAndSignBits>_<refBits>
681 codePos++;
682
683 // read codeLen
684 UINT32 codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen <= MaxCodeLen);
685
686 // position of encoded sigBits and signBits
687 UINT32 sigPos = codePos + RLblockSizeLen; ASSERT(sigPos < CodeBufferBitLen);
688
689 // refinement bits
690 codePos = AlignWordPos(sigPos + codeLen); ASSERT(codePos < CodeBufferBitLen);
691
692 // run-length decode significant bits and signs from m_codeBuffer and
693 // read refinement bits from m_codeBuffer and compose bit plane
694 sigLen = ComposeBitplaneRLD(bufferSize, planeMask, sigPos, &m_codeBuffer[codePos >> WordWidthLog]);
695
696 } else {
697 // no RL coding is used for sigBits and signBits together
698 // <0><sigLen>
699 codePos++;
700
701 // read sigLen
702 sigLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(sigLen <= MaxCodeLen);
703 codePos += RLblockSizeLen; ASSERT(codePos < CodeBufferBitLen);
704
705 // read RL code for signBits
706 if (GetBit(m_codeBuffer, codePos)) {
707 // RL coding is used just for signBits
708 // <1><codeLen><codedSignBits>_<sigBits>_<refBits>
709 codePos++;
710
711 // read codeLen
712 UINT32 codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen <= MaxCodeLen);
713
714 // sign bits
715 UINT32 signPos = codePos + RLblockSizeLen; ASSERT(signPos < CodeBufferBitLen);
716
717 // significant bits
718 UINT32 sigPos = AlignWordPos(signPos + codeLen); ASSERT(sigPos < CodeBufferBitLen);
719
720 // refinement bits
721 codePos = AlignWordPos(sigPos + sigLen); ASSERT(codePos < CodeBufferBitLen);
722
723 // read significant and refinement bitset from m_codeBuffer
724 sigLen = ComposeBitplaneRLD(bufferSize, planeMask, &m_codeBuffer[sigPos >> WordWidthLog], &m_codeBuffer[codePos >> WordWidthLog], signPos);
725
726 } else {
727 // RL coding of signBits was not efficient and therefore not used
728 // <0><signLen>_<signBits>_<sigBits>_<refBits>
729 codePos++;
730
731 // read signLen
732 UINT32 signLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(signLen <= MaxCodeLen);
733
734 // sign bits
735 UINT32 signPos = AlignWordPos(codePos + RLblockSizeLen); ASSERT(signPos < CodeBufferBitLen);
736
737 // significant bits
738 UINT32 sigPos = AlignWordPos(signPos + signLen); ASSERT(sigPos < CodeBufferBitLen);
739
740 // refinement bits
741 codePos = AlignWordPos(sigPos + sigLen); ASSERT(codePos < CodeBufferBitLen);
742
743 // read significant and refinement bitset from m_codeBuffer
744 sigLen = ComposeBitplane(bufferSize, planeMask, &m_codeBuffer[sigPos >> WordWidthLog], &m_codeBuffer[codePos >> WordWidthLog], &m_codeBuffer[signPos >> WordWidthLog]);
745 }
746 }
747
748 // start of next chunk
749 codePos = AlignWordPos(codePos + bufferSize - sigLen); ASSERT(codePos < CodeBufferBitLen);
750
751 // next plane
752 planeMask >>= 1;
753 }
754
755 m_valuePos = 0;
756}
AlignWordPos
UINT32 AlignWordPos(UINT32 pos)
Definition BitStream.h:328
GetBit
bool GetBit(UINT32 *stream, UINT32 pos)
Definition BitStream.h:79
GetValueBlock
UINT32 GetValueBlock(UINT32 *stream, UINT32 pos, UINT32 k)
Definition BitStream.h:142
CodeBufferBitLen
#define CodeBufferBitLen
max number of bits in m_codeBuffer
Definition Decoder.cpp:58
MaxCodeLen
#define MaxCodeLen
max length of RL encoded block
Definition Decoder.cpp:59
WordWidthLog
#define WordWidthLog
ld of WordWidth
Definition PGFplatform.h:74
MaxBitPlanesLog
#define MaxBitPlanesLog
number of bits to code the maximum number of bit planes (in 32 or 16 bit mode)
Definition PGFtypes.h:93
BufferSize
#define BufferSize
must be a multiple of WordWidth, BufferSize <= UINT16_MAX
Definition PGFtypes.h:84
RLblockSizeLen
#define RLblockSizeLen
block size length (< 16): ld(BufferSize) < RLblockSizeLen <= 2*ld(BufferSize)
Definition PGFtypes.h:85
DataT
INT32 DataT
Definition PGFtypes.h:269
MaxBitPlanes
#define MaxBitPlanes
maximum number of bit planes of m_value: 32 minus sign bit
Definition PGFtypes.h:89
CDecoder::CMacroBlock::ComposeBitplane
UINT32 ComposeBitplane(UINT32 bufferSize, DataT planeMask, UINT32 *sigBits, UINT32 *refBits, UINT32 *signBits)
Definition Decoder.cpp:763
CDecoder::CMacroBlock::ComposeBitplaneRLD
UINT32 ComposeBitplaneRLD(UINT32 bufferSize, DataT planeMask, UINT32 sigPos, UINT32 *refBits)
Definition Decoder.cpp:824

## ◆ ComposeBitplane()

UINT32 CDecoder::CMacroBlock::ComposeBitplane | ( | UINT32 | bufferSize,
|  | DataT | planeMask,
|  | UINT32 * | sigBits,
|  | UINT32 * | refBits,
|  | UINT32 * | signBits )
| private

Definition at line 763 of file Decoder.cpp.

763 {
764 ASSERT(sigBits);
765 ASSERT(refBits);
766 ASSERT(signBits);
767
768 UINT32 valPos = 0, signPos = 0, refPos = 0, sigPos = 0;
769
770 while (valPos < bufferSize) {
771 // search next 1 in m_sigFlagVector using searching with sentinel
772 UINT32 sigEnd = valPos;
773 while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
774 sigEnd -= valPos;
775 sigEnd += sigPos;
776
777 // search 1's in sigBits[sigPos..sigEnd)
778 // these 1's are significant bits
779 while (sigPos < sigEnd) {
780 // search 0's
781 UINT32 zerocnt = SeekBitRange(sigBits, sigPos, sigEnd - sigPos);
782 sigPos += zerocnt;
783 valPos += zerocnt;
784 if (sigPos < sigEnd) {
785 // write bit to m_value
786 SetBitAtPos(valPos, planeMask);
787
788 // copy sign bit
789 SetSign(valPos, GetBit(signBits, signPos++));
790
791 // update significance flag vector
792 m_sigFlagVector[valPos++] = true;
793 sigPos++;
794 }
795 }
796 // refinement bit
797 if (valPos < bufferSize) {
798 // write one refinement bit
799 if (GetBit(refBits, refPos)) {
800 SetBitAtPos(valPos, planeMask);
801 }
802 refPos++;
803 valPos++;
804 }
805 }
806 ASSERT(sigPos <= bufferSize);
807 ASSERT(refPos <= bufferSize);
808 ASSERT(signPos <= bufferSize);
809 ASSERT(valPos == bufferSize);
810
811 return sigPos;
812}
SeekBitRange
UINT32 SeekBitRange(UINT32 *stream, UINT32 pos, UINT32 len)
Definition BitStream.h:220
CDecoder::CMacroBlock::SetBitAtPos
void SetBitAtPos(UINT32 pos, DataT planeMask)
Definition Decoder.h:85
CDecoder::CMacroBlock::SetSign
void SetSign(UINT32 pos, bool sign)
Definition Decoder.h:86

## ◆ ComposeBitplaneRLD() [1/2]

UINT32 CDecoder::CMacroBlock::ComposeBitplaneRLD | ( | UINT32 | bufferSize,
|  | DataT | planeMask,
|  | UINT32 * | sigBits,
|  | UINT32 * | refBits,
|  | UINT32 | signPos )
| private

Definition at line 927 of file Decoder.cpp.

927 {
928 ASSERT(sigBits);
929 ASSERT(refBits);
930
931 UINT32 valPos = 0, refPos = 0;
932 UINT32 sigPos = 0, sigEnd;
933 UINT32 zerocnt, count = 0;
934 UINT32 k = 0;
935 UINT32 runlen = 1 << k; // = 2^k
936 bool signBit = false;
937 bool zeroAfterRun = false;
938
939 while (valPos < bufferSize) {
940 // search next 1 in m_sigFlagVector using searching with sentinel
941 sigEnd = valPos;
942 while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
943 sigEnd -= valPos;
944 sigEnd += sigPos;
945
946 // search 1's in sigBits[sigPos..sigEnd)
947 // these 1's are significant bits
948 while (sigPos < sigEnd) {
949 // search 0's
950 zerocnt = SeekBitRange(sigBits, sigPos, sigEnd - sigPos);
951 sigPos += zerocnt;
952 valPos += zerocnt;
953 if (sigPos < sigEnd) {
954 // write bit to m_value
955 SetBitAtPos(valPos, planeMask);
956
957 // check sign bit
958 if (count == 0) {
959 // all 1's have been set
960 if (zeroAfterRun) {
961 // finish the run with a 0
962 signBit = false;
963 zeroAfterRun = false;
964 } else {
965 // decode next sign bit
966 if (GetBit(m_codeBuffer, signPos++)) {
967 // generate 1's run of length 2^k
968 count = runlen - 1;
969 signBit = true;
970
971 // adapt k (double run-length interval)
972 if (k < WordWidth) {
973 k++;
974 runlen <<= 1;
975 }
976 } else {
977 // extract counter and generate 1's run of length count
978 if (k > 0) {
979 // extract counter
980 count = GetValueBlock(m_codeBuffer, signPos, k);
981 signPos += k;
982
983 // adapt k (half run-length interval)
984 k--;
985 runlen >>= 1;
986 }
987 if (count > 0) {
988 count--;
989 signBit = true;
990 zeroAfterRun = true;
991 } else {
992 signBit = false;
993 }
994 }
995 }
996 } else {
997 ASSERT(count > 0);
998 ASSERT(signBit);
999 count--;
1000 }
1001
1002 // copy sign bit
1003 SetSign(valPos, signBit);
1004
1005 // update significance flag vector
1006 m_sigFlagVector[valPos++] = true;
1007 sigPos++;
1008 }
1009 }
1010
1011 // refinement bit
1012 if (valPos < bufferSize) {
1013 // write one refinement bit
1014 if (GetBit(refBits, refPos)) {
1015 SetBitAtPos(valPos, planeMask);
1016 }
1017 refPos++;
1018 valPos++;
1019 }
1020 }
1021 ASSERT(sigPos <= bufferSize);
1022 ASSERT(refPos <= bufferSize);
1023 ASSERT(valPos == bufferSize);
1024
1025 return sigPos;
1026}
WordWidth
#define WordWidth
WordBytes*8.
Definition PGFplatform.h:73

## ◆ ComposeBitplaneRLD() [2/2]

UINT32 CDecoder::CMacroBlock::ComposeBitplaneRLD | ( | UINT32 | bufferSize,
|  | DataT | planeMask,
|  | UINT32 | sigPos,
|  | UINT32 * | refBits )
| private

Definition at line 824 of file Decoder.cpp.

824 {
825 ASSERT(refBits);
826
827 UINT32 valPos = 0, refPos = 0;
828 UINT32 sigPos = 0, sigEnd;
829 UINT32 k = 3;
830 UINT32 runlen = 1 << k; // = 2^k
831 UINT32 count = 0, rest = 0;
832 bool set1 = false;
833
834 while (valPos < bufferSize) {
835 // search next 1 in m_sigFlagVector using searching with sentinel
836 sigEnd = valPos;
837 while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
838 sigEnd -= valPos;
839 sigEnd += sigPos;
840
841 while (sigPos < sigEnd) {
842 if (rest || set1) {
843 // rest of last run
844 sigPos += rest;
845 valPos += rest;
846 rest = 0;
847 } else {
848 // decode significant bits
849 if (GetBit(m_codeBuffer, codePos++)) {
850 // extract counter and generate zero run of length count
851 if (k > 0) {
852 // extract counter
853 count = GetValueBlock(m_codeBuffer, codePos, k);
854 codePos += k;
855 if (count > 0) {
856 sigPos += count;
857 valPos += count;
858 }
859
860 // adapt k (half run-length interval)
861 k--;
862 runlen >>= 1;
863 }
864
865 set1 = true;
866
867 } else {
868 // generate zero run of length 2^k
869 sigPos += runlen;
870 valPos += runlen;
871
872 // adapt k (double run-length interval)
873 if (k < WordWidth) {
874 k++;
875 runlen <<= 1;
876 }
877 }
878 }
879
880 if (sigPos < sigEnd) {
881 if (set1) {
882 set1 = false;
883
884 // write 1 bit
885 SetBitAtPos(valPos, planeMask);
886
887 // set sign bit
888 SetSign(valPos, GetBit(m_codeBuffer, codePos++));
889
890 // update significance flag vector
891 m_sigFlagVector[valPos++] = true;
892 sigPos++;
893 }
894 } else {
895 rest = sigPos - sigEnd;
896 sigPos = sigEnd;
897 valPos -= rest;
898 }
899
900 }
901
902 // refinement bit
903 if (valPos < bufferSize) {
904 // write one refinement bit
905 if (GetBit(refBits, refPos)) {
906 SetBitAtPos(valPos, planeMask);
907 }
908 refPos++;
909 valPos++;
910 }
911 }
912 ASSERT(sigPos <= bufferSize);
913 ASSERT(refPos <= bufferSize);
914 ASSERT(valPos == bufferSize);
915
916 return sigPos;
917}

## ◆ IsCompletelyRead()

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

68{ return m_valuePos >= m_header.rbh.bufferSize; }

## ◆ SetBitAtPos()

void CDecoder::CMacroBlock::SetBitAtPos | ( | UINT32 | pos,
|  | DataT | planeMask )
| inlineprivate

Definition at line 85 of file Decoder.h.

85{ (m_value[pos] >= 0) ? m_value[pos] |= planeMask : m_value[pos] -= planeMask; }

## ◆ SetSign()

void CDecoder::CMacroBlock::SetSign | ( | UINT32 | pos,
|  | bool | sign )
| inlineprivate

Definition at line 86 of file Decoder.h.

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

## Member Data Documentation

## ◆ m_codeBuffer

UINT32 CDecoder::CMacroBlock::m_codeBuffer[CodeBufferLen]

input buffer for encoded bitstream

Definition at line 78 of file Decoder.h.

## ◆ m_header

ROIBlockHeader CDecoder::CMacroBlock::m_header

block header

Definition at line 76 of file Decoder.h.

## ◆ m_sigFlagVector

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

Definition at line 88 of file Decoder.h.

## ◆ m_value

DataT CDecoder::CMacroBlock::m_value[BufferSize]

output buffer of values with index m_valuePos

Definition at line 77 of file Decoder.h.

## ◆ m_valuePos

UINT32 CDecoder::CMacroBlock::m_valuePos

current position in m_value

Definition at line 79 of file Decoder.h.

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

- Decoder.h
- Decoder.cpp