|
libpgf
6.11.32
PGF - Progressive Graphics File
|
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 |
| DataT | m_value [BufferSize] |
| UINT32 | m_codeBuffer [BufferSize] |
| UINT32 | m_valuePos |
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 *signBits) |
| void | SetBitAtPos (UINT32 pos, DataT planeMask) |
| void | SetSign (UINT32 pos, bool sign) |
Private Attributes | |
| CDecoder * | m_decoder |
| bool | m_sigFlagVector [BufferSize+1] |
A macro block is a decoding unit of fixed size (uncoded)
PGF decoder macro block class.
| CDecoder::CMacroBlock::CMacroBlock | ( | CDecoder * | decoder | ) | [inline] |
| 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 600 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 = GetValueBlock(m_codeBuffer, 0, MaxBitPlanesLog);
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
codePos++;
// read codeLen
codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen < (1 << RLblockSizeLen));
// 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
codePos++;
// read sigLen
sigLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(sigLen <= BufferSize);
codePos += RLblockSizeLen; ASSERT(codePos < CodeBufferBitLen);
// read RL code for signBits
if (GetBit(m_codeBuffer, codePos)) {
// RL coding is used
codePos++;
// read codeLen
codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen);
// 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], &m_codeBuffer[signPos >> WordWidthLog]);
} else {
// RL coding of signBits was not efficient and therefore not used
codePos++;
// read signLen
signLen = AlignWordPos(GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen)); ASSERT(signLen <= bufferSize);
// sign bits
signPos = AlignWordPos(codePos + RLblockSizeLen); ASSERT(signPos < CodeBufferBitLen);
// significant bits
sigPos = 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;
}
m_valuePos = 0;
}
| UINT32 CDecoder::CMacroBlock::ComposeBitplane | ( | UINT32 | bufferSize, |
| DataT | planeMask, | ||
| UINT32 * | sigBits, | ||
| UINT32 * | refBits, | ||
| UINT32 * | signBits | ||
| ) | [private] |
Definition at line 710 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 773 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 * | signBits | ||
| ) | [private] |
Definition at line 876 of file Decoder.cpp.
{
ASSERT(sigBits);
ASSERT(refBits);
ASSERT(signBits);
UINT32 valPos = 0, signPos = 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(signBits, 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(signBits, 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(signPos <= bufferSize);
ASSERT(valPos == bufferSize);
return sigPos;
}
| bool CDecoder::CMacroBlock::IsCompletelyRead | ( | ) | const [inline] |
Returns true if this macro block has been completely read.
Definition at line 66 of file Decoder.h.
{ return m_valuePos >= m_header.rbh.bufferSize; }
| void CDecoder::CMacroBlock::SetBitAtPos | ( | UINT32 | pos, |
| DataT | planeMask | ||
| ) | [inline, private] |
| void CDecoder::CMacroBlock::SetSign | ( | UINT32 | pos, |
| bool | sign | ||
| ) | [inline, private] |
| UINT32 CDecoder::CMacroBlock::m_codeBuffer[BufferSize] |
CDecoder* CDecoder::CMacroBlock::m_decoder [private] |
bool CDecoder::CMacroBlock::m_sigFlagVector[BufferSize+1] [private] |
| DataT CDecoder::CMacroBlock::m_value[BufferSize] |