libpgf: CEncoder::CMacroBlock Class Reference

| libpgf 7.21.2 PGF - Progressive Graphics File

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

A macro block is an encoding unit of fixed size (uncoded). More...

## 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

## ◆ CMacroBlock()

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 }
CEncoder::CMacroBlock::m_value
DataT m_value[BufferSize]
input buffer of values with index m_valuePos
Definition Encoder.h:84
CEncoder::CMacroBlock::m_codeBuffer
UINT32 m_codeBuffer[CodeBufferLen]
output buffer for encoded bitstream
Definition Encoder.h:85
CEncoder::CMacroBlock::m_sigFlagVector
bool m_sigFlagVector[BufferSize+1]
Definition Encoder.h:99
CEncoder::CMacroBlock::m_header
ROIBlockHeader m_header
block header
Definition Encoder.h:86
CEncoder::CMacroBlock::m_encoder
CEncoder * m_encoder
Definition Encoder.h:98
CEncoder::CMacroBlock::Init
void Init(int lastLevelIndex)
Definition Encoder.h:71

## Member Function Documentation

## ◆ BitplaneEncode()

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}
AlignWordPos
UINT32 AlignWordPos(UINT32 pos)
Definition BitStream.h:328
SetBit
void SetBit(UINT32 *stream, UINT32 pos)
Definition BitStream.h:62
SetValueBlock
void SetValueBlock(UINT32 *stream, UINT32 pos, UINT32 val, UINT32 k)
Definition BitStream.h:116
ClearBit
void ClearBit(UINT32 *stream, UINT32 pos)
Definition BitStream.h:70
NumberOfWords
UINT32 NumberOfWords(UINT32 pos)
Definition BitStream.h:337
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
CodeBufferLen
#define CodeBufferLen
number of words in code buffer (CodeBufferLen > BufferLen)
Definition Encoder.h:40
BufferLen
#define BufferLen
number of words per buffer
Definition Encoder.h:39
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
MaxBitPlanes
#define MaxBitPlanes
maximum number of bit planes of m_value: 32 minus sign bit
Definition PGFtypes.h:89
CEncoder::CMacroBlock::NumberOfBitplanes
UINT8 NumberOfBitplanes()
Definition Encoder.cpp:750
CEncoder::CMacroBlock::DecomposeBitplane
UINT32 DecomposeBitplane(UINT32 bufferSize, UINT32 planeMask, UINT32 codePos, UINT32 *sigBits, UINT32 *refBits, UINT32 *signBits, UINT32 &signLen, UINT32 &codeLen)
Definition Encoder.cpp:634
CEncoder::CMacroBlock::RLESigns
UINT32 RLESigns(UINT32 codePos, UINT32 *signBits, UINT32 signLen)
Definition Encoder.cpp:774
CEncoder::CMacroBlock::m_codePos
UINT32 m_codePos
current position in encoded bitstream
Definition Encoder.h:89

## ◆ DecomposeBitplane()

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}
WordWidth
#define WordWidth
WordBytes*8.
Definition PGFplatform.h:73
CEncoder::CMacroBlock::GetBitAtPos
bool GetBitAtPos(UINT32 pos, UINT32 planeMask) const
Definition Encoder.h:96

## ◆ GetBitAtPos()

bool CEncoder::CMacroBlock::GetBitAtPos | ( | UINT32 | pos,
|  | UINT32 | planeMask ) const
| inlineprivate

Definition at line 96 of file Encoder.h.

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

## ◆ Init()

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 }
CEncoder::CMacroBlock::m_lastLevelIndex
int m_lastLevelIndex
index of last encoded level: [0, nLevels); used because a level-end can occur before a buffer is full
Definition Encoder.h:90
CEncoder::CMacroBlock::m_valuePos
UINT32 m_valuePos
current buffer position
Definition Encoder.h:87
CEncoder::CMacroBlock::m_maxAbsValue
UINT32 m_maxAbsValue
maximum absolute coefficient in each buffer
Definition Encoder.h:88

## ◆ NumberOfBitplanes()

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}

## ◆ RLESigns()

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}
SeekBit1Range
UINT32 SeekBit1Range(UINT32 *stream, UINT32 pos, UINT32 len)
Definition BitStream.h:249
__min
#define __min(x, y)
Definition PGFplatform.h:91

## Member Data Documentation

## ◆ m_codeBuffer

UINT32 CEncoder::CMacroBlock::m_codeBuffer[CodeBufferLen]

output buffer for encoded bitstream

Definition at line 85 of file Encoder.h.

## ◆ m_codePos

UINT32 CEncoder::CMacroBlock::m_codePos

current position in encoded bitstream

Definition at line 89 of file Encoder.h.

## ◆ m_encoder

CEncoder* CEncoder::CMacroBlock::m_encoder
| private

Definition at line 98 of file Encoder.h.

## ◆ m_header

ROIBlockHeader CEncoder::CMacroBlock::m_header

block header

Definition at line 86 of file Encoder.h.

## ◆ m_lastLevelIndex

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.

## ◆ m_maxAbsValue

UINT32 CEncoder::CMacroBlock::m_maxAbsValue

maximum absolute coefficient in each buffer

Definition at line 88 of file Encoder.h.

## ◆ m_sigFlagVector

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

Definition at line 99 of file Encoder.h.

## ◆ m_value

DataT CEncoder::CMacroBlock::m_value[BufferSize]

input buffer of values with index m_valuePos

Definition at line 84 of file Encoder.h.

## ◆ m_valuePos

UINT32 CEncoder::CMacroBlock::m_valuePos

current buffer position

Definition at line 87 of file Encoder.h.

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

- Encoder.h
- Encoder.cpp