CDecoder::CMacroBlock(3)
β¨ NAME β¨
CDecoder::CMacroBlock β bestie, a macro block is a decoding unit of fixed size (uncoded). That's the whole vibe. π¦
(oh and fyi, this page lives in the libpgf manual, section 3 β part 1 of 3, so don't go anywhere π
)
π SYNOPSIS π
π Public Member Functions
CMacroBlock ()β Constructor: initializes a new macro block, fresh out the wrapper β¨bool IsCompletelyRead () constβ tells you if she's completely readvoid BitplaneDecode ()β decodes the bitplane
π Public Attributes
ROIBlockHeader m_headerβ block headerDataT m_value [BufferSize]β output buffer of values with indexm_valuePosUINT32 m_codeBuffer [CodeBufferLen]β input buffer for encoded bitstreamUINT32 m_valuePosβ current position inm_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). Periodt.
PGF decoder macro block class. π
Author β C. Stamm, I. Bauersachs
Definition at line 51 of file Decoder.h.
π Constructor & Destructor Documentation π
CDecoder::CMacroBlock::CMacroBlock () [inline]
Constructor: initializes a new macro block. She's brand new here, be nice to her π₯Ί
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 }
π§ Member Function Documentation π§
void CDecoder::CMacroBlock::BitplaneDecode ()
Okay so this one decodes input data that's already been read into this macro block. And here's the cute part β several macro blocks can be decoded in parallel, no cap πββοΈπββοΈπββοΈ. But bestie, promise me: call CDecoder::ReadMacroBlock before this method. Order matters, iykyk.
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 }
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 }
UINT32 CDecoder::CMacroBlock::ComposeBitplaneRLD (UINT32 bufferSize, DataT planeMask, UINT32 * sigBits, UINT32 * refBits, UINT32 signPos) [private]
okay so we're back in the code mines βοΈβ¨ and ngl this stretch is just straight-up source, no prose, no mercy. Here's the body that belongs to the signature we just saw β Definition at line 927 of file Decoder.cpp, and it's giving iconic:
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 }
π¦ CDecoder::CMacroBlock::ComposeBitplaneRLD π¦
UINT32 CDecoder::CMacroBlock::ComposeBitplaneRLD (UINT32 bufferSize, DataT planeMask, UINT32 sigPos, UINT32 * refBits) [private]
Definition at line 824 of file Decoder.cpp.
okay so before anyone comes for me: yes, the parameter is literally namedsigPosand then line 828 goes and declaresUINT32 sigPos = 0, sigEnd;anyway. Not my business, not my problem π I am only the messenger, and the messenger copies it character for character.
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 }
β¨ bool CDecoder::CMacroBlock::IsCompletelyRead () const [inline] β¨
Returns true if this macro block has been completely read. slay β a yes/no queen, we love a one-liner that knows what it wants π«Ά
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; }
π void CDecoder::CMacroBlock::SetBitAtPos (UINT32 pos, DataT planeMask) [inline], [private] π
Definition at line 85 of file Decoder.h.
85 { (m_value[pos] >= 0) ? m_value[pos] |= planeMask : m_value[pos] -= planeMask; }
and bestie we are not even close to done β keep scrolling, the code said "there's more" and it meant it ππ
So the very last private lil' helper in the member-function lineup is this one, and honestly? It's giving tiny but mighty. π
SetSign (the inline private one, iykyk)
void CDecoder::CMacroBlock::SetSign (UINT32 pos, bool sign) [inline],
[private]
Bestie, this one lives at Definition at line 86 of file Decoder.h. and it's literally a one-liner, no cap:
86 { m_value[pos] = -m_value[pos]*sign + m_value[pos]*(!sign); }
It's inline and private, so it's not out here for public consumption β it's a backstage pass situation only. π
β¨ Member Data Documentation β¨
Okay so now we get to the actual data, the members, the little variables holding the whole vibe together. Let's go one by one, no skipping, periodt. π
UINT32 CDecoder::CMacroBlock::m_codeBuffer[CodeBufferLen]β the input buffer for encoded bitstream. That's where the encoded bits roll up before anything else happens.
Definition at line 78 of file Decoder.h.
ROIBlockHeader CDecoder::CMacroBlock::m_headerβ the block header. Just the header, doing header things, main character energy. π
Definition at line 76 of file Decoder.h.
bool CDecoder::CMacroBlock::m_sigFlagVector[BufferSize+1] [private]β she's a private girlie, so we don't get a description, we just get to know she's there. π
Definition at line 88 of file Decoder.h.
DataT CDecoder::CMacroBlock::m_value[BufferSize]β the output buffer of values with indexm_valuePos. So like, the values come out here, andm_valuePosis the lil' pointer telling you where you're at. πΈ
Definition at line 77 of file Decoder.h.
UINT32 CDecoder::CMacroBlock::m_valuePosβ the current position inm_value. The GPS of the value buffer fr fr. π§
Definition at line 79 of file Decoder.h.
π¦ Author π¦
Generated automatically by Doxygen for libpgf from the source code.
(So like, no human wrote this, a robot did, and honestly? The robot ate. πβ¨)
And that's a wrap on CDecoder::CMacroBlock(3), bestie!! π«Ά This was Version 7.21.2, dated Thu Jul 24 2025 00:00:00 β shoutout to that timestamp for being so satisfyingly round, we love a clean footer. Thanks for reading all the way to the end, you're the real MVP of the manpage marathon. ππ Now go forth and decode, my love. β
π¦ where this page comes from
- fedora 43: libpgf-devel 7.21.7-8.fc43 Β· LicenseRef-Callaway-LGPLv2+
- fedora 43: libpgf-devel 7.21.7-8.fc43 Β· LicenseRef-Callaway-LGPLv2+
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms