libpgf  6.11.42
PGF - Progressive Graphics File
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
CEncoder::CMacroBlock Class Reference

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

List of all members.

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 [BufferSize]
 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

CEncoderm_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 50 of file Encoder.h.


Constructor & Destructor Documentation

CEncoder::CMacroBlock::CMacroBlock ( CEncoder encoder)
inline

Constructor: Initializes new macro block.

Parameters:
encoderPointer to outer class.

Definition at line 55 of file Encoder.h.

: m_header(0)
, m_encoder(encoder)
{
ASSERT(m_encoder);
Init(-1);
}

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 418 of file Encoder.cpp.

{
UINT8 nPlanes;
UINT32 sigLen, codeLen = 0, wordPos, refLen, signLen;
UINT32 sigBits[BufferLen] = { 0 };
UINT32 refBits[BufferLen] = { 0 };
UINT32 signBits[BufferLen] = { 0 };
UINT32 planeMask;
UINT32 bufferSize = m_header.rbh.bufferSize; ASSERT(bufferSize <= BufferSize);
bool useRL;
#ifdef TRACE
//printf("which thread: %d\n", omp_get_thread_num());
#endif
// clear significance vector
for (UINT32 k=0; k < bufferSize; k++) {
m_sigFlagVector[k] = false;
}
m_sigFlagVector[bufferSize] = true; // sentinel
// clear output buffer
for (UINT32 k=0; k < bufferSize; k++) {
m_codeBuffer[k] = 0;
}
m_codePos = 0;
// compute number of bit planes and split buffer into separate bit planes
nPlanes = NumberOfBitplanes();
// write number of bit planes to m_codeBuffer
// <nPlanes>
// loop through all bit planes
if (nPlanes == 0) nPlanes = MaxBitPlanes + 1;
planeMask = 1 << (nPlanes - 1);
for (int plane = nPlanes - 1; plane >= 0; plane--) {
// clear significant bitset
for (UINT32 k=0; k < BufferLen; k++) {
sigBits[k] = 0;
}
// split bitplane in significant bitset and refinement bitset
sigLen = DecomposeBitplane(bufferSize, planeMask, m_codePos + RLblockSizeLen + 1, sigBits, refBits, signBits, signLen, codeLen);
if (sigLen > 0 && codeLen <= MaxCodeLen && codeLen < AlignWordPos(sigLen) + AlignWordPos(signLen) + 2*RLblockSizeLen) {
// set RL code bit
// <1><codeLen>
// write length codeLen to m_codeBuffer
m_codePos += RLblockSizeLen + codeLen;
} else {
#ifdef TRACE
//printf("new\n");
//for (UINT32 i=0; i < bufferSize; i++) {
// printf("%s", (GetBit(sigBits, i)) ? "1" : "_");
// if (i%120 == 119) printf("\n");
//}
//printf("\n");
#endif // TRACE
// run-length coding wasn't efficient enough
// we don't use RL coding for sigBits
// <0><sigLen>
// write length sigLen to m_codeBuffer
ASSERT(sigLen <= MaxCodeLen);
if (m_encoder->m_favorSpeed || signLen == 0) {
useRL = false;
} else {
// overwrite m_codeBuffer
useRL = true;
// run-length encode m_sign and append them to the m_codeBuffer
codeLen = RLESigns(m_codePos + RLblockSizeLen + 1, signBits, signLen);
}
if (useRL && codeLen <= MaxCodeLen && codeLen < signLen) {
// RL encoding of m_sign was efficient
// <1><codeLen><codedSignBits>_
// write RL code bit
// write codeLen to m_codeBuffer
// compute position of sigBits
wordPos = NumberOfWords(m_codePos + RLblockSizeLen + codeLen);
ASSERT(0 <= wordPos && wordPos < bufferSize);
} else {
// RL encoding of signBits wasn't efficient
// <0><signLen>_<signBits>_
// clear RL code bit
// write signLen to m_codeBuffer
ASSERT(signLen <= MaxCodeLen);
// write signBits to m_codeBuffer
ASSERT(0 <= wordPos && wordPos < bufferSize);
codeLen = NumberOfWords(signLen);
for (UINT32 k=0; k < codeLen; k++) {
m_codeBuffer[wordPos++] = signBits[k];
}
}
// write sigBits
// <sigBits>_
ASSERT(0 <= wordPos && wordPos < bufferSize);
refLen = NumberOfWords(sigLen);
for (UINT32 k=0; k < refLen; k++) {
m_codeBuffer[wordPos++] = sigBits[k];
}
m_codePos = wordPos << WordWidthLog;
}
// append refinement bitset (aligned to word boundary)
// _<refBits>
ASSERT(0 <= wordPos && wordPos < bufferSize);
refLen = NumberOfWords(bufferSize - sigLen);
for (UINT32 k=0; k < refLen; k++) {
m_codeBuffer[wordPos++] = refBits[k];
}
m_codePos = wordPos << WordWidthLog;
planeMask >>= 1;
}
ASSERT(0 <= m_codePos && m_codePos <= CodeBufferBitLen);
}
UINT32 CEncoder::CMacroBlock::DecomposeBitplane ( UINT32  bufferSize,
UINT32  planeMask,
UINT32  codePos,
UINT32 *  sigBits,
UINT32 *  refBits,
UINT32 *  signBits,
UINT32 &  signLen,
UINT32 &  codeLen 
)
private

Definition at line 570 of file Encoder.cpp.

{
ASSERT(sigBits);
ASSERT(refBits);
ASSERT(signBits);
ASSERT(codePos < CodeBufferBitLen);
UINT32 sigPos = 0;
UINT32 valuePos = 0, valueEnd;
UINT32 refPos = 0;
// set output value
signLen = 0;
// prepare RLE of Sigs and Signs
const UINT32 outStartPos = codePos;
UINT32 k = 3;
UINT32 runlen = 1 << k; // = 2^k
UINT32 count = 0;
while (valuePos < bufferSize) {
// search next 1 in m_sigFlagVector using searching with sentinel
valueEnd = valuePos;
while(!m_sigFlagVector[valueEnd]) { valueEnd++; }
// search 1's in m_value[plane][valuePos..valueEnd)
// these 1's are significant bits
while (valuePos < valueEnd) {
if (GetBitAtPos(valuePos, planeMask)) {
// RLE encoding
// encode run of count 0's followed by a 1
// with codeword: 1<count>(signBits[signPos])
SetBit(m_codeBuffer, codePos++);
if (k > 0) {
SetValueBlock(m_codeBuffer, codePos, count, k);
codePos += k;
// adapt k (half the zero run-length)
k--;
runlen >>= 1;
}
// copy and write sign bit
if (m_value[valuePos] < 0) {
SetBit(signBits, signLen++);
SetBit(m_codeBuffer, codePos++);
} else {
ClearBit(signBits, signLen++);
ClearBit(m_codeBuffer, codePos++);
}
// write a 1 to sigBits
SetBit(sigBits, sigPos++);
// update m_sigFlagVector
m_sigFlagVector[valuePos] = true;
// prepare for next run
count = 0;
} else {
// RLE encoding
count++;
if (count == runlen) {
// encode run of 2^k zeros by a single 0
ClearBit(m_codeBuffer, codePos++);
// adapt k (double the zero run-length)
if (k < WordWidth) {
k++;
runlen <<= 1;
}
// prepare for next run
count = 0;
}
// write 0 to sigBits
sigPos++;
}
valuePos++;
}
// refinement bit
if (valuePos < bufferSize) {
// write one refinement bit
if (GetBitAtPos(valuePos++, planeMask)) {
SetBit(refBits, refPos);
} else {
ClearBit(refBits, refPos);
}
refPos++;
}
}
// RLE encoding of the rest of the plane
// encode run of count 0's followed by a 1
// with codeword: 1<count>(signBits[signPos])
SetBit(m_codeBuffer, codePos++);
if (k > 0) {
SetValueBlock(m_codeBuffer, codePos, count, k);
codePos += k;
}
// write dmmy sign bit
SetBit(m_codeBuffer, codePos++);
// write word filler zeros
ASSERT(sigPos <= bufferSize);
ASSERT(refPos <= bufferSize);
ASSERT(signLen <= bufferSize);
ASSERT(valuePos == bufferSize);
ASSERT(codePos >= outStartPos && codePos < CodeBufferBitLen);
codeLen = codePos - outStartPos;
return sigPos;
}
bool CEncoder::CMacroBlock::GetBitAtPos ( UINT32  pos,
UINT32  planeMask 
) const
inlineprivate

Definition at line 92 of file Encoder.h.

{ return (abs(m_value[pos]) & planeMask) > 0; }
void CEncoder::CMacroBlock::Init ( int  lastLevelIndex)
inline

Reinitialzes this macro block (allows reusage).

Parameters:
lastLevelIndexLevel length directory index of last encoded level: [0, nLevels)

Definition at line 66 of file Encoder.h.

{ // initialize for reusage
m_codePos = 0;
m_lastLevelIndex = lastLevelIndex;
}
UINT8 CEncoder::CMacroBlock::NumberOfBitplanes ( )
private

Definition at line 686 of file Encoder.cpp.

{
UINT8 cnt = 0;
// determine number of bitplanes for max value
if (m_maxAbsValue > 0) {
while (m_maxAbsValue > 0) {
m_maxAbsValue >>= 1; cnt++;
}
if (cnt == MaxBitPlanes + 1) cnt = 0;
// end cs
ASSERT(cnt <= MaxBitPlanes);
ASSERT((cnt >> MaxBitPlanesLog) == 0);
return cnt;
} else {
return 1;
}
}
UINT32 CEncoder::CMacroBlock::RLESigns ( UINT32  codePos,
UINT32 *  signBits,
UINT32  signLen 
)
private

Definition at line 710 of file Encoder.cpp.

{
ASSERT(signBits);
ASSERT(0 <= codePos && codePos < CodeBufferBitLen);
ASSERT(0 < signLen && signLen <= BufferSize);
const UINT32 outStartPos = codePos;
UINT32 k = 0;
UINT32 runlen = 1 << k; // = 2^k
UINT32 count = 0;
UINT32 signPos = 0;
while (signPos < signLen) {
// search next 0 in signBits starting at position signPos
count = SeekBit1Range(signBits, signPos, __min(runlen, signLen - signPos));
// count 1's found
if (count == runlen) {
// encode run of 2^k ones by a single 1
signPos += count;
SetBit(m_codeBuffer, codePos++);
// adapt k (double the 1's run-length)
if (k < WordWidth) {
k++;
runlen <<= 1;
}
} else {
// encode run of count 1's followed by a 0
// with codeword: 0(count)
signPos += count + 1;
ClearBit(m_codeBuffer, codePos++);
if (k > 0) {
SetValueBlock(m_codeBuffer, codePos, count, k);
codePos += k;
}
// adapt k (half the 1's run-length)
if (k > 0) {
k--;
runlen >>= 1;
}
}
}
ASSERT(signPos == signLen || signPos == signLen + 1);
ASSERT(codePos >= outStartPos && codePos < CodeBufferBitLen);
return codePos - outStartPos;
}

Member Data Documentation

UINT32 CEncoder::CMacroBlock::m_codeBuffer[BufferSize]

output buffer for encoded bitstream

Definition at line 80 of file Encoder.h.

UINT32 CEncoder::CMacroBlock::m_codePos

current position in encoded bitstream

Definition at line 85 of file Encoder.h.

CEncoder* CEncoder::CMacroBlock::m_encoder
private

Definition at line 94 of file Encoder.h.

ROIBlockHeader CEncoder::CMacroBlock::m_header

block header

Definition at line 82 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 86 of file Encoder.h.

UINT32 CEncoder::CMacroBlock::m_maxAbsValue

maximum absolute coefficient in each buffer

Definition at line 84 of file Encoder.h.

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

Definition at line 95 of file Encoder.h.

DataT CEncoder::CMacroBlock::m_value[BufferSize]

input buffer of values with index m_valuePos

Definition at line 79 of file Encoder.h.

UINT32 CEncoder::CMacroBlock::m_valuePos

current buffer position

Definition at line 83 of file Encoder.h.


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