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

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

Public Member Functions

 CMacroBlock (CDecoder *decoder)
 
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

CDecoderm_decoder
 
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

CDecoder::CMacroBlock::CMacroBlock ( CDecoder decoder)
inline

Constructor: Initializes new macro block.

Parameters
decoderPointer to outer class.

Definition at line 56 of file Decoder.h.

: m_header(0) // makes sure that IsCompletelyRead() returns true for an empty macro block
, m_decoder(decoder)
{
ASSERT(m_decoder);
}

Member Function Documentation

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

{
UINT32 bufferSize = m_header.rbh.bufferSize; ASSERT(bufferSize <= BufferSize);
UINT32 nPlanes;
UINT32 codePos = 0, codeLen, sigLen, sigPos, signLen, signPos;
DataT planeMask;
// 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_value[k] = 0;
}
// read number of bit planes
// <nPlanes>
codePos += MaxBitPlanesLog;
// loop through all bit planes
if (nPlanes == 0) nPlanes = MaxBitPlanes + 1;
ASSERT(0 < nPlanes && nPlanes <= MaxBitPlanes + 1);
planeMask = 1 << (nPlanes - 1);
for (int plane = nPlanes - 1; plane >= 0; plane--) {
// read RL code
if (GetBit(m_codeBuffer, codePos)) {
// RL coding of sigBits is used
// <1><codeLen><codedSigAndSignBits>_<refBits>
codePos++;
// read codeLen
codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen <= MaxCodeLen);
// position of encoded sigBits and signBits
sigPos = codePos + RLblockSizeLen; ASSERT(sigPos < CodeBufferBitLen);
// refinement bits
codePos = AlignWordPos(sigPos + codeLen); ASSERT(codePos < CodeBufferBitLen);
// run-length decode significant bits and signs from m_codeBuffer and
// read refinement bits from m_codeBuffer and compose bit plane
sigLen = ComposeBitplaneRLD(bufferSize, planeMask, sigPos, &m_codeBuffer[codePos >> WordWidthLog]);
} else {
// no RL coding is used for sigBits and signBits together
// <0><sigLen>
codePos++;
// read sigLen
sigLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(sigLen <= MaxCodeLen);
codePos += RLblockSizeLen; ASSERT(codePos < CodeBufferBitLen);
// read RL code for signBits
if (GetBit(m_codeBuffer, codePos)) {
// RL coding is used just for signBits
// <1><codeLen><codedSignBits>_<sigBits>_<refBits>
codePos++;
// read codeLen
codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen <= MaxCodeLen);
// sign bits
signPos = codePos + RLblockSizeLen; ASSERT(signPos < CodeBufferBitLen);
// significant bits
sigPos = AlignWordPos(signPos + codeLen); ASSERT(sigPos < CodeBufferBitLen);
// refinement bits
codePos = AlignWordPos(sigPos + sigLen); ASSERT(codePos < CodeBufferBitLen);
// read significant and refinement bitset from m_codeBuffer
sigLen = ComposeBitplaneRLD(bufferSize, planeMask, &m_codeBuffer[sigPos >> WordWidthLog], &m_codeBuffer[codePos >> WordWidthLog], signPos);
} else {
// RL coding of signBits was not efficient and therefore not used
// <0><signLen>_<signBits>_<sigBits>_<refBits>
codePos++;
// read signLen
signLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(signLen <= MaxCodeLen);
// sign bits
signPos = AlignWordPos(codePos + RLblockSizeLen); ASSERT(signPos < CodeBufferBitLen);
// significant bits
sigPos = AlignWordPos(signPos + signLen); ASSERT(sigPos < CodeBufferBitLen);
// refinement bits
codePos = AlignWordPos(sigPos + sigLen); ASSERT(codePos < CodeBufferBitLen);
// read significant and refinement bitset from m_codeBuffer
sigLen = ComposeBitplane(bufferSize, planeMask, &m_codeBuffer[sigPos >> WordWidthLog], &m_codeBuffer[codePos >> WordWidthLog], &m_codeBuffer[signPos >> WordWidthLog]);
}
}
// start of next chunk
codePos = AlignWordPos(codePos + bufferSize - sigLen); ASSERT(codePos < CodeBufferBitLen);
// next plane
planeMask >>= 1;
}
}
UINT32 CDecoder::CMacroBlock::ComposeBitplane ( UINT32  bufferSize,
DataT  planeMask,
UINT32 *  sigBits,
UINT32 *  refBits,
UINT32 *  signBits 
)
private

Definition at line 733 of file Decoder.cpp.

{
ASSERT(sigBits);
ASSERT(refBits);
ASSERT(signBits);
UINT32 valPos = 0, signPos = 0, refPos = 0;
UINT32 sigPos = 0, sigEnd;
UINT32 zerocnt;
while (valPos < bufferSize) {
// search next 1 in m_sigFlagVector using searching with sentinel
sigEnd = valPos;
while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
sigEnd -= valPos;
sigEnd += sigPos;
// search 1's in sigBits[sigPos..sigEnd)
// these 1's are significant bits
while (sigPos < sigEnd) {
// search 0's
zerocnt = SeekBitRange(sigBits, sigPos, sigEnd - sigPos);
sigPos += zerocnt;
valPos += zerocnt;
if (sigPos < sigEnd) {
// write bit to m_value
SetBitAtPos(valPos, planeMask);
// copy sign bit
SetSign(valPos, GetBit(signBits, signPos++));
// update significance flag vector
m_sigFlagVector[valPos++] = true;
sigPos++;
}
}
// refinement bit
if (valPos < bufferSize) {
// write one refinement bit
if (GetBit(refBits, refPos)) {
SetBitAtPos(valPos, planeMask);
}
refPos++;
valPos++;
}
}
ASSERT(sigPos <= bufferSize);
ASSERT(refPos <= bufferSize);
ASSERT(signPos <= bufferSize);
ASSERT(valPos == bufferSize);
return sigPos;
}
UINT32 CDecoder::CMacroBlock::ComposeBitplaneRLD ( UINT32  bufferSize,
DataT  planeMask,
UINT32  sigPos,
UINT32 *  refBits 
)
private

Definition at line 796 of file Decoder.cpp.

{
ASSERT(refBits);
UINT32 valPos = 0, refPos = 0;
UINT32 sigPos = 0, sigEnd;
UINT32 k = 3;
UINT32 runlen = 1 << k; // = 2^k
UINT32 count = 0, rest = 0;
bool set1 = false;
while (valPos < bufferSize) {
// search next 1 in m_sigFlagVector using searching with sentinel
sigEnd = valPos;
while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
sigEnd -= valPos;
sigEnd += sigPos;
while (sigPos < sigEnd) {
if (rest || set1) {
// rest of last run
sigPos += rest;
valPos += rest;
rest = 0;
} else {
// decode significant bits
if (GetBit(m_codeBuffer, codePos++)) {
// extract counter and generate zero run of length count
if (k > 0) {
// extract counter
count = GetValueBlock(m_codeBuffer, codePos, k);
codePos += k;
if (count > 0) {
sigPos += count;
valPos += count;
}
// adapt k (half run-length interval)
k--;
runlen >>= 1;
}
set1 = true;
} else {
// generate zero run of length 2^k
sigPos += runlen;
valPos += runlen;
// adapt k (double run-length interval)
if (k < WordWidth) {
k++;
runlen <<= 1;
}
}
}
if (sigPos < sigEnd) {
if (set1) {
set1 = false;
// write 1 bit
SetBitAtPos(valPos, planeMask);
// set sign bit
SetSign(valPos, GetBit(m_codeBuffer, codePos++));
// update significance flag vector
m_sigFlagVector[valPos++] = true;
sigPos++;
}
} else {
rest = sigPos - sigEnd;
sigPos = sigEnd;
valPos -= rest;
}
}
// refinement bit
if (valPos < bufferSize) {
// write one refinement bit
if (GetBit(refBits, refPos)) {
SetBitAtPos(valPos, planeMask);
}
refPos++;
valPos++;
}
}
ASSERT(sigPos <= bufferSize);
ASSERT(refPos <= bufferSize);
ASSERT(valPos == bufferSize);
return sigPos;
}
UINT32 CDecoder::CMacroBlock::ComposeBitplaneRLD ( UINT32  bufferSize,
DataT  planeMask,
UINT32 *  sigBits,
UINT32 *  refBits,
UINT32  signPos 
)
private

Definition at line 899 of file Decoder.cpp.

{
ASSERT(sigBits);
ASSERT(refBits);
UINT32 valPos = 0, refPos = 0;
UINT32 sigPos = 0, sigEnd;
UINT32 zerocnt, count = 0;
UINT32 k = 0;
UINT32 runlen = 1 << k; // = 2^k
bool signBit = false;
bool zeroAfterRun = false;
while (valPos < bufferSize) {
// search next 1 in m_sigFlagVector using searching with sentinel
sigEnd = valPos;
while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
sigEnd -= valPos;
sigEnd += sigPos;
// search 1's in sigBits[sigPos..sigEnd)
// these 1's are significant bits
while (sigPos < sigEnd) {
// search 0's
zerocnt = SeekBitRange(sigBits, sigPos, sigEnd - sigPos);
sigPos += zerocnt;
valPos += zerocnt;
if (sigPos < sigEnd) {
// write bit to m_value
SetBitAtPos(valPos, planeMask);
// check sign bit
if (count == 0) {
// all 1's have been set
if (zeroAfterRun) {
// finish the run with a 0
signBit = false;
zeroAfterRun = false;
} else {
// decode next sign bit
if (GetBit(m_codeBuffer, signPos++)) {
// generate 1's run of length 2^k
count = runlen - 1;
signBit = true;
// adapt k (double run-length interval)
if (k < WordWidth) {
k++;
runlen <<= 1;
}
} else {
// extract counter and generate 1's run of length count
if (k > 0) {
// extract counter
count = GetValueBlock(m_codeBuffer, signPos, k);
signPos += k;
// adapt k (half run-length interval)
k--;
runlen >>= 1;
}
if (count > 0) {
count--;
signBit = true;
zeroAfterRun = true;
} else {
signBit = false;
}
}
}
} else {
ASSERT(count > 0);
ASSERT(signBit);
count--;
}
// copy sign bit
SetSign(valPos, signBit);
// update significance flag vector
m_sigFlagVector[valPos++] = true;
sigPos++;
}
}
// refinement bit
if (valPos < bufferSize) {
// write one refinement bit
if (GetBit(refBits, refPos)) {
SetBitAtPos(valPos, planeMask);
}
refPos++;
valPos++;
}
}
ASSERT(sigPos <= bufferSize);
ASSERT(refPos <= bufferSize);
ASSERT(valPos == bufferSize);
return sigPos;
}
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 67 of file Decoder.h.

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

Definition at line 84 of file Decoder.h.

{ (m_value[pos] >= 0) ? m_value[pos] |= planeMask : m_value[pos] -= planeMask; }
void CDecoder::CMacroBlock::SetSign ( UINT32  pos,
bool  sign 
)
inlineprivate

Definition at line 85 of file Decoder.h.

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

Member Data Documentation

UINT32 CDecoder::CMacroBlock::m_codeBuffer[CodeBufferLen]

input buffer for encoded bitstream

Definition at line 77 of file Decoder.h.

CDecoder* CDecoder::CMacroBlock::m_decoder
private

Definition at line 87 of file Decoder.h.

ROIBlockHeader CDecoder::CMacroBlock::m_header

block header

Definition at line 75 of file Decoder.h.

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

Definition at line 88 of file Decoder.h.

DataT CDecoder::CMacroBlock::m_value[BufferSize]

output buffer of values with index m_valuePos

Definition at line 76 of file Decoder.h.

UINT32 CDecoder::CMacroBlock::m_valuePos

current position in m_value

Definition at line 78 of file Decoder.h.


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