libpgf
6.11.42
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 |
block header | |
DataT | m_value [BufferSize] |
output buffer of values with index m_valuePos | |
UINT32 | m_codeBuffer [BufferSize] |
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 | |
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] |
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 601 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> 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 // <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; } m_valuePos = 0; }
UINT32 CDecoder::CMacroBlock::ComposeBitplane | ( | UINT32 | bufferSize, |
DataT | planeMask, | ||
UINT32 * | sigBits, | ||
UINT32 * | refBits, | ||
UINT32 * | signBits | ||
) | [private] |
Definition at line 716 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 779 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 882 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.
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] |
CDecoder* CDecoder::CMacroBlock::m_decoder [private] |
bool CDecoder::CMacroBlock::m_sigFlagVector[BufferSize+1] [private] |