libpgf
6.11.42
PGF - Progressive Graphics File
|
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 [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 | |
CEncoder * | m_encoder |
bool | m_sigFlagVector [BufferSize+1] |
A macro block is an encoding unit of fixed size (uncoded)
PGF encoder macro block class.
CEncoder::CMacroBlock::CMacroBlock | ( | CEncoder * | encoder | ) | [inline] |
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> SetValueBlock(m_codeBuffer, 0, nPlanes, MaxBitPlanesLog); m_codePos += MaxBitPlanesLog; // 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> SetBit(m_codeBuffer, m_codePos++); // write length codeLen to m_codeBuffer SetValueBlock(m_codeBuffer, m_codePos, codeLen, RLblockSizeLen); 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> ClearBit(m_codeBuffer, m_codePos++); // write length sigLen to m_codeBuffer ASSERT(sigLen <= MaxCodeLen); SetValueBlock(m_codeBuffer, m_codePos, sigLen, RLblockSizeLen); m_codePos += RLblockSizeLen; 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 SetBit(m_codeBuffer, m_codePos++); // write codeLen to m_codeBuffer SetValueBlock(m_codeBuffer, m_codePos, codeLen, RLblockSizeLen); // 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 ClearBit(m_codeBuffer, m_codePos++); // write signLen to m_codeBuffer ASSERT(signLen <= MaxCodeLen); SetValueBlock(m_codeBuffer, m_codePos, signLen, RLblockSizeLen); // write signBits to m_codeBuffer wordPos = NumberOfWords(m_codePos + RLblockSizeLen); 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> wordPos = NumberOfWords(m_codePos); 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 [inline, private] |
void CEncoder::CMacroBlock::Init | ( | int | lastLevelIndex | ) | [inline] |
Reinitialzes this macro block (allows reusage).
lastLevelIndex | Level length directory index of last encoded level: [0, nLevels) |
Definition at line 66 of file Encoder.h.
{ // initialize for reusage m_valuePos = 0; m_maxAbsValue = 0; 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; }
CEncoder* CEncoder::CMacroBlock::m_encoder [private] |
bool CEncoder::CMacroBlock::m_sigFlagVector[BufferSize+1] [private] |