libpgf
6.14.12
PGF - Progressive Graphics File
|
00001 /* 00002 * The Progressive Graphics File; http://www.libpgf.org 00003 * 00004 * $Date: 2006-06-04 22:05:59 +0200 (So, 04 Jun 2006) $ 00005 * $Revision: 229 $ 00006 * 00007 * This file Copyright (C) 2006 xeraina GmbH, Switzerland 00008 * 00009 * This program is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE 00011 * as published by the Free Software Foundation; either version 2.1 00012 * of the License, or (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software 00021 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00022 */ 00023 00028 00029 #include "Decoder.h" 00030 #ifdef TRACE 00031 #include <stdio.h> 00032 #endif 00033 00035 // PGF: file structure 00036 // 00037 // PGFPreHeader PGFHeader PGFPostHeader LevelLengths Level_n-1 Level_n-2 ... Level_0 00038 // PGFPostHeader ::= [ColorTable] [UserData] 00039 // LevelLengths ::= UINT32[nLevels] 00040 00042 // Decoding scheme 00043 // input: binary file 00044 // output: wavelet coefficients stored in subbands 00045 // 00046 // file (for each buffer: packedLength (16 bit), packed bits) 00047 // | 00048 // m_codeBuffer (for each plane: RLcodeLength (16 bit), RLcoded sigBits + m_sign, refBits) 00049 // | | | 00050 // m_sign sigBits refBits [BufferLen, BufferLen, BufferLen] 00051 // | | | 00052 // m_value [BufferSize] 00053 // | 00054 // subband 00055 // 00056 00057 // Constants 00058 #define CodeBufferBitLen (CodeBufferLen*WordWidth) ///< max number of bits in m_codeBuffer 00059 #define MaxCodeLen ((1 << RLblockSizeLen) - 1) ///< max length of RL encoded block 00060 00073 CDecoder::CDecoder(CPGFStream* stream, PGFPreHeader& preHeader, PGFHeader& header, 00074 PGFPostHeader& postHeader, UINT32*& levelLength, UINT64& userDataPos, 00075 bool useOMP, bool skipUserData) THROW_ 00076 : m_stream(stream) 00077 , m_startPos(0) 00078 , m_streamSizeEstimation(0) 00079 , m_encodedHeaderLength(0) 00080 , m_currentBlockIndex(0) 00081 , m_macroBlocksAvailable(0) 00082 #ifdef __PGFROISUPPORT__ 00083 , m_roi(false) 00084 #endif 00085 { 00086 ASSERT(m_stream); 00087 00088 int count, expected; 00089 00090 // store current stream position 00091 m_startPos = m_stream->GetPos(); 00092 00093 // read magic and version 00094 count = expected = MagicVersionSize; 00095 m_stream->Read(&count, &preHeader); 00096 if (count != expected) ReturnWithError(MissingData); 00097 00098 // read header size 00099 if (preHeader.version & Version6) { 00100 // 32 bit header size since version 6 00101 count = expected = 4; 00102 } else { 00103 count = expected = 2; 00104 } 00105 m_stream->Read(&count, ((UINT8*)&preHeader) + MagicVersionSize); 00106 if (count != expected) ReturnWithError(MissingData); 00107 00108 // make sure the values are correct read 00109 preHeader.hSize = __VAL(preHeader.hSize); 00110 00111 // check magic number 00112 if (memcmp(preHeader.magic, PGFMagic, 3) != 0) { 00113 // error condition: wrong Magic number 00114 ReturnWithError(FormatCannotRead); 00115 } 00116 00117 // read file header 00118 count = expected = (preHeader.hSize < HeaderSize) ? preHeader.hSize : HeaderSize; 00119 m_stream->Read(&count, &header); 00120 if (count != expected) ReturnWithError(MissingData); 00121 00122 // make sure the values are correct read 00123 header.height = __VAL(UINT32(header.height)); 00124 header.width = __VAL(UINT32(header.width)); 00125 00126 // be ready to read all versions including version 0 00127 if (preHeader.version > 0) { 00128 #ifndef __PGFROISUPPORT__ 00129 // check ROI usage 00130 if (preHeader.version & PGFROI) ReturnWithError(FormatCannotRead); 00131 #endif 00132 00133 int size = preHeader.hSize - HeaderSize; 00134 00135 if (size > 0) { 00136 // read post-header 00137 if (header.mode == ImageModeIndexedColor) { 00138 if (size < ColorTableSize) ReturnWithError(FormatCannotRead); 00139 // read color table 00140 count = expected = ColorTableSize; 00141 m_stream->Read(&count, postHeader.clut); 00142 if (count != expected) ReturnWithError(MissingData); 00143 size -= count; 00144 } 00145 00146 if (size > 0) { 00147 userDataPos = m_stream->GetPos(); 00148 postHeader.userDataLen = size; 00149 if (skipUserData) { 00150 Skip(size); 00151 } else { 00152 // create user data memory block 00153 postHeader.userData = new(std::nothrow) UINT8[postHeader.userDataLen]; 00154 if (!postHeader.userData) ReturnWithError(InsufficientMemory); 00155 00156 // read user data 00157 count = expected = postHeader.userDataLen; 00158 m_stream->Read(&count, postHeader.userData); 00159 if (count != expected) ReturnWithError(MissingData); 00160 } 00161 } 00162 } 00163 00164 // create levelLength 00165 levelLength = new(std::nothrow) UINT32[header.nLevels]; 00166 if (!levelLength) ReturnWithError(InsufficientMemory); 00167 00168 // read levelLength 00169 count = expected = header.nLevels*WordBytes; 00170 m_stream->Read(&count, levelLength); 00171 if (count != expected) ReturnWithError(MissingData); 00172 00173 #ifdef PGF_USE_BIG_ENDIAN 00174 // make sure the values are correct read 00175 for (int i=0; i < header.nLevels; i++) { 00176 levelLength[i] = __VAL(levelLength[i]); 00177 } 00178 #endif 00179 00180 // compute the total size in bytes; keep attention: level length information is optional 00181 for (int i=0; i < header.nLevels; i++) { 00182 m_streamSizeEstimation += levelLength[i]; 00183 } 00184 00185 } 00186 00187 // store current stream position 00188 m_encodedHeaderLength = UINT32(m_stream->GetPos() - m_startPos); 00189 00190 // set number of threads 00191 #ifdef LIBPGF_USE_OPENMP 00192 m_macroBlockLen = omp_get_num_procs(); 00193 #else 00194 m_macroBlockLen = 1; 00195 #endif 00196 00197 if (useOMP && m_macroBlockLen > 1) { 00198 #ifdef LIBPGF_USE_OPENMP 00199 omp_set_num_threads(m_macroBlockLen); 00200 #endif 00201 00202 // create macro block array 00203 m_macroBlocks = new(std::nothrow) CMacroBlock*[m_macroBlockLen]; 00204 if (!m_macroBlocks) ReturnWithError(InsufficientMemory); 00205 for (int i = 0; i < m_macroBlockLen; i++) m_macroBlocks[i] = new CMacroBlock(); 00206 m_currentBlock = m_macroBlocks[m_currentBlockIndex]; 00207 } else { 00208 m_macroBlocks = 0; 00209 m_macroBlockLen = 1; // there is only one macro block 00210 m_currentBlock = new(std::nothrow) CMacroBlock(); 00211 if (!m_currentBlock) ReturnWithError(InsufficientMemory); 00212 } 00213 } 00214 00216 // Destructor 00217 CDecoder::~CDecoder() { 00218 if (m_macroBlocks) { 00219 for (int i=0; i < m_macroBlockLen; i++) delete m_macroBlocks[i]; 00220 delete[] m_macroBlocks; 00221 } else { 00222 delete m_currentBlock; 00223 } 00224 } 00225 00232 UINT32 CDecoder::ReadEncodedData(UINT8* target, UINT32 len) const THROW_ { 00233 ASSERT(m_stream); 00234 00235 int count = len; 00236 m_stream->Read(&count, target); 00237 00238 return count; 00239 } 00240 00252 void CDecoder::Partition(CSubband* band, int quantParam, int width, int height, int startPos, int pitch) THROW_ { 00253 ASSERT(band); 00254 00255 const div_t ww = div(width, LinBlockSize); 00256 const div_t hh = div(height, LinBlockSize); 00257 const int ws = pitch - LinBlockSize; 00258 const int wr = pitch - ww.rem; 00259 int pos, base = startPos, base2; 00260 00261 // main height 00262 for (int i=0; i < hh.quot; i++) { 00263 // main width 00264 base2 = base; 00265 for (int j=0; j < ww.quot; j++) { 00266 pos = base2; 00267 for (int y=0; y < LinBlockSize; y++) { 00268 for (int x=0; x < LinBlockSize; x++) { 00269 DequantizeValue(band, pos, quantParam); 00270 pos++; 00271 } 00272 pos += ws; 00273 } 00274 base2 += LinBlockSize; 00275 } 00276 // rest of width 00277 pos = base2; 00278 for (int y=0; y < LinBlockSize; y++) { 00279 for (int x=0; x < ww.rem; x++) { 00280 DequantizeValue(band, pos, quantParam); 00281 pos++; 00282 } 00283 pos += wr; 00284 base += pitch; 00285 } 00286 } 00287 // main width 00288 base2 = base; 00289 for (int j=0; j < ww.quot; j++) { 00290 // rest of height 00291 pos = base2; 00292 for (int y=0; y < hh.rem; y++) { 00293 for (int x=0; x < LinBlockSize; x++) { 00294 DequantizeValue(band, pos, quantParam); 00295 pos++; 00296 } 00297 pos += ws; 00298 } 00299 base2 += LinBlockSize; 00300 } 00301 // rest of height 00302 pos = base2; 00303 for (int y=0; y < hh.rem; y++) { 00304 // rest of width 00305 for (int x=0; x < ww.rem; x++) { 00306 DequantizeValue(band, pos, quantParam); 00307 pos++; 00308 } 00309 pos += wr; 00310 } 00311 } 00312 00314 // Decode and dequantize HL, and LH band of one level 00315 // LH and HH are interleaved in the codestream and must be split 00316 // Deccoding and dequantization of HL and LH Band (interleaved) using partitioning scheme 00317 // partitions the plane in squares of side length InterBlockSize 00318 // It might throw an IOException. 00319 void CDecoder::DecodeInterleaved(CWaveletTransform* wtChannel, int level, int quantParam) THROW_ { 00320 CSubband* hlBand = wtChannel->GetSubband(level, HL); 00321 CSubband* lhBand = wtChannel->GetSubband(level, LH); 00322 const div_t lhH = div(lhBand->GetHeight(), InterBlockSize); 00323 const div_t hlW = div(hlBand->GetWidth(), InterBlockSize); 00324 const int hlws = hlBand->GetWidth() - InterBlockSize; 00325 const int hlwr = hlBand->GetWidth() - hlW.rem; 00326 const int lhws = lhBand->GetWidth() - InterBlockSize; 00327 const int lhwr = lhBand->GetWidth() - hlW.rem; 00328 int hlPos, lhPos; 00329 int hlBase = 0, lhBase = 0, hlBase2, lhBase2; 00330 00331 ASSERT(lhBand->GetWidth() >= hlBand->GetWidth()); 00332 ASSERT(hlBand->GetHeight() >= lhBand->GetHeight()); 00333 00334 if (!hlBand->AllocMemory()) ReturnWithError(InsufficientMemory); 00335 if (!lhBand->AllocMemory()) ReturnWithError(InsufficientMemory); 00336 00337 // correct quantParam with normalization factor 00338 quantParam -= level; 00339 if (quantParam < 0) quantParam = 0; 00340 00341 // main height 00342 for (int i=0; i < lhH.quot; i++) { 00343 // main width 00344 hlBase2 = hlBase; 00345 lhBase2 = lhBase; 00346 for (int j=0; j < hlW.quot; j++) { 00347 hlPos = hlBase2; 00348 lhPos = lhBase2; 00349 for (int y=0; y < InterBlockSize; y++) { 00350 for (int x=0; x < InterBlockSize; x++) { 00351 DequantizeValue(hlBand, hlPos, quantParam); 00352 DequantizeValue(lhBand, lhPos, quantParam); 00353 hlPos++; 00354 lhPos++; 00355 } 00356 hlPos += hlws; 00357 lhPos += lhws; 00358 } 00359 hlBase2 += InterBlockSize; 00360 lhBase2 += InterBlockSize; 00361 } 00362 // rest of width 00363 hlPos = hlBase2; 00364 lhPos = lhBase2; 00365 for (int y=0; y < InterBlockSize; y++) { 00366 for (int x=0; x < hlW.rem; x++) { 00367 DequantizeValue(hlBand, hlPos, quantParam); 00368 DequantizeValue(lhBand, lhPos, quantParam); 00369 hlPos++; 00370 lhPos++; 00371 } 00372 // width difference between HL and LH 00373 if (lhBand->GetWidth() > hlBand->GetWidth()) { 00374 DequantizeValue(lhBand, lhPos, quantParam); 00375 } 00376 hlPos += hlwr; 00377 lhPos += lhwr; 00378 hlBase += hlBand->GetWidth(); 00379 lhBase += lhBand->GetWidth(); 00380 } 00381 } 00382 // main width 00383 hlBase2 = hlBase; 00384 lhBase2 = lhBase; 00385 for (int j=0; j < hlW.quot; j++) { 00386 // rest of height 00387 hlPos = hlBase2; 00388 lhPos = lhBase2; 00389 for (int y=0; y < lhH.rem; y++) { 00390 for (int x=0; x < InterBlockSize; x++) { 00391 DequantizeValue(hlBand, hlPos, quantParam); 00392 DequantizeValue(lhBand, lhPos, quantParam); 00393 hlPos++; 00394 lhPos++; 00395 } 00396 hlPos += hlws; 00397 lhPos += lhws; 00398 } 00399 hlBase2 += InterBlockSize; 00400 lhBase2 += InterBlockSize; 00401 } 00402 // rest of height 00403 hlPos = hlBase2; 00404 lhPos = lhBase2; 00405 for (int y=0; y < lhH.rem; y++) { 00406 // rest of width 00407 for (int x=0; x < hlW.rem; x++) { 00408 DequantizeValue(hlBand, hlPos, quantParam); 00409 DequantizeValue(lhBand, lhPos, quantParam); 00410 hlPos++; 00411 lhPos++; 00412 } 00413 // width difference between HL and LH 00414 if (lhBand->GetWidth() > hlBand->GetWidth()) { 00415 DequantizeValue(lhBand, lhPos, quantParam); 00416 } 00417 hlPos += hlwr; 00418 lhPos += lhwr; 00419 hlBase += hlBand->GetWidth(); 00420 } 00421 // height difference between HL and LH 00422 if (hlBand->GetHeight() > lhBand->GetHeight()) { 00423 // total width 00424 hlPos = hlBase; 00425 for (int j=0; j < hlBand->GetWidth(); j++) { 00426 DequantizeValue(hlBand, hlPos, quantParam); 00427 hlPos++; 00428 } 00429 } 00430 } 00431 00435 void CDecoder::Skip(UINT64 offset) THROW_ { 00436 m_stream->SetPos(FSFromCurrent, offset); 00437 } 00438 00448 void CDecoder::DequantizeValue(CSubband* band, UINT32 bandPos, int quantParam) THROW_ { 00449 ASSERT(m_currentBlock); 00450 00451 if (m_currentBlock->IsCompletelyRead()) { 00452 // all data of current macro block has been read --> prepare next macro block 00453 DecodeTileBuffer(); 00454 } 00455 00456 band->SetData(bandPos, m_currentBlock->m_value[m_currentBlock->m_valuePos] << quantParam); 00457 m_currentBlock->m_valuePos++; 00458 } 00459 00461 // Read next group of blocks from stream and decodes them into macro blocks 00462 // It might throw an IOException. 00463 void CDecoder::DecodeTileBuffer() THROW_ { 00464 // current block has been read --> prepare next current block 00465 m_macroBlocksAvailable--; 00466 00467 if (m_macroBlocksAvailable > 0) { 00468 m_currentBlock = m_macroBlocks[++m_currentBlockIndex]; 00469 } else { 00470 DecodeBuffer(); 00471 } 00472 ASSERT(m_currentBlock); 00473 } 00474 00476 // Read next block from stream and decode into macro block 00477 // Decoding scheme: <wordLen>(16 bits) [ ROI ] data 00478 // ROI ::= <bufferSize>(15 bits) <eofTile>(1 bit) 00479 // It might throw an IOException. 00480 void CDecoder::DecodeBuffer() THROW_ { 00481 ASSERT(m_macroBlocksAvailable <= 0); 00482 00483 // macro block management 00484 if (m_macroBlockLen == 1) { 00485 ASSERT(m_currentBlock); 00486 ReadMacroBlock(m_currentBlock); 00487 m_currentBlock->BitplaneDecode(); 00488 m_macroBlocksAvailable = 1; 00489 } else { 00490 m_macroBlocksAvailable = 0; 00491 for (int i=0; i < m_macroBlockLen; i++) { 00492 // read sequentially several blocks 00493 try { 00494 ReadMacroBlock(m_macroBlocks[i]); 00495 m_macroBlocksAvailable++; 00496 } catch(IOException& ex) { 00497 if (ex.error == MissingData) { 00498 break; // no further data available 00499 } else { 00500 throw; 00501 } 00502 } 00503 } 00504 #ifdef LIBPGF_USE_OPENMP 00505 // decode in parallel 00506 #pragma omp parallel for default(shared) //no declared exceptions in next block 00507 #endif 00508 for (int i=0; i < m_macroBlocksAvailable; i++) { 00509 m_macroBlocks[i]->BitplaneDecode(); 00510 } 00511 00512 // prepare current macro block 00513 m_currentBlockIndex = 0; 00514 m_currentBlock = m_macroBlocks[m_currentBlockIndex]; 00515 } 00516 } 00517 00519 // Read next block from stream and store it in the given block 00520 // It might throw an IOException. 00521 void CDecoder::ReadMacroBlock(CMacroBlock* block) THROW_ { 00522 ASSERT(block); 00523 00524 UINT16 wordLen; 00525 ROIBlockHeader h(BufferSize); 00526 int count, expected; 00527 00528 #ifdef TRACE 00529 //UINT32 filePos = (UINT32)m_stream->GetPos(); 00530 //printf("DecodeBuffer: %d\n", filePos); 00531 #endif 00532 00533 // read wordLen 00534 count = expected = sizeof(UINT16); 00535 m_stream->Read(&count, &wordLen); 00536 if (count != expected) ReturnWithError(MissingData); 00537 wordLen = __VAL(wordLen); 00538 if (wordLen > BufferSize) 00539 ReturnWithError(FormatCannotRead); 00540 00541 #ifdef __PGFROISUPPORT__ 00542 // read ROIBlockHeader 00543 if (m_roi) { 00544 m_stream->Read(&count, &h.val); 00545 if (count != expected) ReturnWithError(MissingData); 00546 00547 // convert ROIBlockHeader 00548 h.val = __VAL(h.val); 00549 } 00550 #endif 00551 // save header 00552 block->m_header = h; 00553 00554 // read data 00555 count = expected = wordLen*WordBytes; 00556 m_stream->Read(&count, block->m_codeBuffer); 00557 if (count != expected) ReturnWithError(MissingData); 00558 00559 #ifdef PGF_USE_BIG_ENDIAN 00560 // convert data 00561 count /= WordBytes; 00562 for (int i=0; i < count; i++) { 00563 block->m_codeBuffer[i] = __VAL(block->m_codeBuffer[i]); 00564 } 00565 #endif 00566 00567 #ifdef __PGFROISUPPORT__ 00568 ASSERT(m_roi && h.rbh.bufferSize <= BufferSize || h.rbh.bufferSize == BufferSize); 00569 #else 00570 ASSERT(h.rbh.bufferSize == BufferSize); 00571 #endif 00572 } 00573 00575 // Read next block from stream but don't decode into macro block 00576 // Encoding scheme: <wordLen>(16 bits) [ ROI ] data 00577 // ROI ::= <bufferSize>(15 bits) <eofTile>(1 bit) 00578 // It might throw an IOException. 00579 void CDecoder::SkipTileBuffer() THROW_ { 00580 // current block is not used 00581 m_macroBlocksAvailable--; 00582 00583 // check if pre-decoded data is available 00584 if (m_macroBlocksAvailable > 0) { 00585 m_currentBlock = m_macroBlocks[++m_currentBlockIndex]; 00586 return; 00587 } 00588 00589 UINT16 wordLen; 00590 int count, expected; 00591 00592 // read wordLen 00593 count = expected = sizeof(wordLen); 00594 m_stream->Read(&count, &wordLen); 00595 if (count != expected) ReturnWithError(MissingData); 00596 wordLen = __VAL(wordLen); 00597 ASSERT(wordLen <= BufferSize); 00598 00599 #ifdef __PGFROISUPPORT__ 00600 if (m_roi) { 00601 // skip ROIBlockHeader 00602 m_stream->SetPos(FSFromCurrent, sizeof(ROIBlockHeader)); 00603 } 00604 #endif 00605 00606 // skip data 00607 m_stream->SetPos(FSFromCurrent, wordLen*WordBytes); 00608 } 00609 00611 // Decode block into buffer of given size using bit plane coding. 00612 // A buffer contains bufferLen UINT32 values, thus, bufferSize bits per bit plane. 00613 // Following coding scheme is used: 00614 // Buffer ::= <nPlanes>(5 bits) foreach(plane i): Plane[i] 00615 // Plane[i] ::= [ Sig1 | Sig2 ] [DWORD alignment] refBits 00616 // Sig1 ::= 1 <codeLen>(15 bits) codedSigAndSignBits 00617 // Sig2 ::= 0 <sigLen>(15 bits) [Sign1 | Sign2 ] [DWORD alignment] sigBits 00618 // Sign1 ::= 1 <codeLen>(15 bits) codedSignBits 00619 // Sign2 ::= 0 <signLen>(15 bits) [DWORD alignment] signBits 00620 void CDecoder::CMacroBlock::BitplaneDecode() { 00621 UINT32 bufferSize = m_header.rbh.bufferSize; ASSERT(bufferSize <= BufferSize); 00622 00623 UINT32 nPlanes; 00624 UINT32 codePos = 0, codeLen, sigLen, sigPos, signLen, signPos; 00625 DataT planeMask; 00626 00627 // clear significance vector 00628 for (UINT32 k=0; k < bufferSize; k++) { 00629 m_sigFlagVector[k] = false; 00630 } 00631 m_sigFlagVector[bufferSize] = true; // sentinel 00632 00633 // clear output buffer 00634 for (UINT32 k=0; k < BufferSize; k++) { 00635 m_value[k] = 0; 00636 } 00637 00638 // read number of bit planes 00639 // <nPlanes> 00640 nPlanes = GetValueBlock(m_codeBuffer, 0, MaxBitPlanesLog); 00641 codePos += MaxBitPlanesLog; 00642 00643 // loop through all bit planes 00644 if (nPlanes == 0) nPlanes = MaxBitPlanes + 1; 00645 ASSERT(0 < nPlanes && nPlanes <= MaxBitPlanes + 1); 00646 planeMask = 1 << (nPlanes - 1); 00647 00648 for (int plane = nPlanes - 1; plane >= 0; plane--) { 00649 // read RL code 00650 if (GetBit(m_codeBuffer, codePos)) { 00651 // RL coding of sigBits is used 00652 // <1><codeLen><codedSigAndSignBits>_<refBits> 00653 codePos++; 00654 00655 // read codeLen 00656 codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen <= MaxCodeLen); 00657 00658 // position of encoded sigBits and signBits 00659 sigPos = codePos + RLblockSizeLen; ASSERT(sigPos < CodeBufferBitLen); 00660 00661 // refinement bits 00662 codePos = AlignWordPos(sigPos + codeLen); ASSERT(codePos < CodeBufferBitLen); 00663 00664 // run-length decode significant bits and signs from m_codeBuffer and 00665 // read refinement bits from m_codeBuffer and compose bit plane 00666 sigLen = ComposeBitplaneRLD(bufferSize, planeMask, sigPos, &m_codeBuffer[codePos >> WordWidthLog]); 00667 00668 } else { 00669 // no RL coding is used for sigBits and signBits together 00670 // <0><sigLen> 00671 codePos++; 00672 00673 // read sigLen 00674 sigLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(sigLen <= MaxCodeLen); 00675 codePos += RLblockSizeLen; ASSERT(codePos < CodeBufferBitLen); 00676 00677 // read RL code for signBits 00678 if (GetBit(m_codeBuffer, codePos)) { 00679 // RL coding is used just for signBits 00680 // <1><codeLen><codedSignBits>_<sigBits>_<refBits> 00681 codePos++; 00682 00683 // read codeLen 00684 codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen <= MaxCodeLen); 00685 00686 // sign bits 00687 signPos = codePos + RLblockSizeLen; ASSERT(signPos < CodeBufferBitLen); 00688 00689 // significant bits 00690 sigPos = AlignWordPos(signPos + codeLen); ASSERT(sigPos < CodeBufferBitLen); 00691 00692 // refinement bits 00693 codePos = AlignWordPos(sigPos + sigLen); ASSERT(codePos < CodeBufferBitLen); 00694 00695 // read significant and refinement bitset from m_codeBuffer 00696 sigLen = ComposeBitplaneRLD(bufferSize, planeMask, &m_codeBuffer[sigPos >> WordWidthLog], &m_codeBuffer[codePos >> WordWidthLog], signPos); 00697 00698 } else { 00699 // RL coding of signBits was not efficient and therefore not used 00700 // <0><signLen>_<signBits>_<sigBits>_<refBits> 00701 codePos++; 00702 00703 // read signLen 00704 signLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(signLen <= MaxCodeLen); 00705 00706 // sign bits 00707 signPos = AlignWordPos(codePos + RLblockSizeLen); ASSERT(signPos < CodeBufferBitLen); 00708 00709 // significant bits 00710 sigPos = AlignWordPos(signPos + signLen); ASSERT(sigPos < CodeBufferBitLen); 00711 00712 // refinement bits 00713 codePos = AlignWordPos(sigPos + sigLen); ASSERT(codePos < CodeBufferBitLen); 00714 00715 // read significant and refinement bitset from m_codeBuffer 00716 sigLen = ComposeBitplane(bufferSize, planeMask, &m_codeBuffer[sigPos >> WordWidthLog], &m_codeBuffer[codePos >> WordWidthLog], &m_codeBuffer[signPos >> WordWidthLog]); 00717 } 00718 } 00719 00720 // start of next chunk 00721 codePos = AlignWordPos(codePos + bufferSize - sigLen); ASSERT(codePos < CodeBufferBitLen); 00722 00723 // next plane 00724 planeMask >>= 1; 00725 } 00726 00727 m_valuePos = 0; 00728 } 00729 00731 // Reconstruct bitplane from significant bitset and refinement bitset 00732 // returns length [bits] of sigBits 00733 // input: sigBits, refBits, signBits 00734 // output: m_value 00735 UINT32 CDecoder::CMacroBlock::ComposeBitplane(UINT32 bufferSize, DataT planeMask, UINT32* sigBits, UINT32* refBits, UINT32* signBits) { 00736 ASSERT(sigBits); 00737 ASSERT(refBits); 00738 ASSERT(signBits); 00739 00740 UINT32 valPos = 0, signPos = 0, refPos = 0; 00741 UINT32 sigPos = 0, sigEnd; 00742 UINT32 zerocnt; 00743 00744 while (valPos < bufferSize) { 00745 // search next 1 in m_sigFlagVector using searching with sentinel 00746 sigEnd = valPos; 00747 while(!m_sigFlagVector[sigEnd]) { sigEnd++; } 00748 sigEnd -= valPos; 00749 sigEnd += sigPos; 00750 00751 // search 1's in sigBits[sigPos..sigEnd) 00752 // these 1's are significant bits 00753 while (sigPos < sigEnd) { 00754 // search 0's 00755 zerocnt = SeekBitRange(sigBits, sigPos, sigEnd - sigPos); 00756 sigPos += zerocnt; 00757 valPos += zerocnt; 00758 if (sigPos < sigEnd) { 00759 // write bit to m_value 00760 SetBitAtPos(valPos, planeMask); 00761 00762 // copy sign bit 00763 SetSign(valPos, GetBit(signBits, signPos++)); 00764 00765 // update significance flag vector 00766 m_sigFlagVector[valPos++] = true; 00767 sigPos++; 00768 } 00769 } 00770 // refinement bit 00771 if (valPos < bufferSize) { 00772 // write one refinement bit 00773 if (GetBit(refBits, refPos)) { 00774 SetBitAtPos(valPos, planeMask); 00775 } 00776 refPos++; 00777 valPos++; 00778 } 00779 } 00780 ASSERT(sigPos <= bufferSize); 00781 ASSERT(refPos <= bufferSize); 00782 ASSERT(signPos <= bufferSize); 00783 ASSERT(valPos == bufferSize); 00784 00785 return sigPos; 00786 } 00787 00789 // Reconstruct bitplane from significant bitset and refinement bitset 00790 // returns length [bits] of decoded significant bits 00791 // input: RL encoded sigBits and signBits in m_codeBuffer, refBits 00792 // output: m_value 00793 // RLE: 00794 // - Decode run of 2^k zeros by a single 0. 00795 // - Decode run of count 0's followed by a 1 with codeword: 1<count>x 00796 // - x is 0: if a positive sign has been stored, otherwise 1 00797 // - Read each bit from m_codeBuffer[codePos] and increment codePos. 00798 UINT32 CDecoder::CMacroBlock::ComposeBitplaneRLD(UINT32 bufferSize, DataT planeMask, UINT32 codePos, UINT32* refBits) { 00799 ASSERT(refBits); 00800 00801 UINT32 valPos = 0, refPos = 0; 00802 UINT32 sigPos = 0, sigEnd; 00803 UINT32 k = 3; 00804 UINT32 runlen = 1 << k; // = 2^k 00805 UINT32 count = 0, rest = 0; 00806 bool set1 = false; 00807 00808 while (valPos < bufferSize) { 00809 // search next 1 in m_sigFlagVector using searching with sentinel 00810 sigEnd = valPos; 00811 while(!m_sigFlagVector[sigEnd]) { sigEnd++; } 00812 sigEnd -= valPos; 00813 sigEnd += sigPos; 00814 00815 while (sigPos < sigEnd) { 00816 if (rest || set1) { 00817 // rest of last run 00818 sigPos += rest; 00819 valPos += rest; 00820 rest = 0; 00821 } else { 00822 // decode significant bits 00823 if (GetBit(m_codeBuffer, codePos++)) { 00824 // extract counter and generate zero run of length count 00825 if (k > 0) { 00826 // extract counter 00827 count = GetValueBlock(m_codeBuffer, codePos, k); 00828 codePos += k; 00829 if (count > 0) { 00830 sigPos += count; 00831 valPos += count; 00832 } 00833 00834 // adapt k (half run-length interval) 00835 k--; 00836 runlen >>= 1; 00837 } 00838 00839 set1 = true; 00840 00841 } else { 00842 // generate zero run of length 2^k 00843 sigPos += runlen; 00844 valPos += runlen; 00845 00846 // adapt k (double run-length interval) 00847 if (k < WordWidth) { 00848 k++; 00849 runlen <<= 1; 00850 } 00851 } 00852 } 00853 00854 if (sigPos < sigEnd) { 00855 if (set1) { 00856 set1 = false; 00857 00858 // write 1 bit 00859 SetBitAtPos(valPos, planeMask); 00860 00861 // set sign bit 00862 SetSign(valPos, GetBit(m_codeBuffer, codePos++)); 00863 00864 // update significance flag vector 00865 m_sigFlagVector[valPos++] = true; 00866 sigPos++; 00867 } 00868 } else { 00869 rest = sigPos - sigEnd; 00870 sigPos = sigEnd; 00871 valPos -= rest; 00872 } 00873 00874 } 00875 00876 // refinement bit 00877 if (valPos < bufferSize) { 00878 // write one refinement bit 00879 if (GetBit(refBits, refPos)) { 00880 SetBitAtPos(valPos, planeMask); 00881 } 00882 refPos++; 00883 valPos++; 00884 } 00885 } 00886 ASSERT(sigPos <= bufferSize); 00887 ASSERT(refPos <= bufferSize); 00888 ASSERT(valPos == bufferSize); 00889 00890 return sigPos; 00891 } 00892 00894 // Reconstruct bitplane from significant bitset, refinement bitset, and RL encoded sign bits 00895 // returns length [bits] of sigBits 00896 // input: sigBits, refBits, RL encoded signBits 00897 // output: m_value 00898 // RLE: 00899 // decode run of 2^k 1's by a single 1 00900 // decode run of count 1's followed by a 0 with codeword: 0<count> 00901 UINT32 CDecoder::CMacroBlock::ComposeBitplaneRLD(UINT32 bufferSize, DataT planeMask, UINT32* sigBits, UINT32* refBits, UINT32 signPos) { 00902 ASSERT(sigBits); 00903 ASSERT(refBits); 00904 00905 UINT32 valPos = 0, refPos = 0; 00906 UINT32 sigPos = 0, sigEnd; 00907 UINT32 zerocnt, count = 0; 00908 UINT32 k = 0; 00909 UINT32 runlen = 1 << k; // = 2^k 00910 bool signBit = false; 00911 bool zeroAfterRun = false; 00912 00913 while (valPos < bufferSize) { 00914 // search next 1 in m_sigFlagVector using searching with sentinel 00915 sigEnd = valPos; 00916 while(!m_sigFlagVector[sigEnd]) { sigEnd++; } 00917 sigEnd -= valPos; 00918 sigEnd += sigPos; 00919 00920 // search 1's in sigBits[sigPos..sigEnd) 00921 // these 1's are significant bits 00922 while (sigPos < sigEnd) { 00923 // search 0's 00924 zerocnt = SeekBitRange(sigBits, sigPos, sigEnd - sigPos); 00925 sigPos += zerocnt; 00926 valPos += zerocnt; 00927 if (sigPos < sigEnd) { 00928 // write bit to m_value 00929 SetBitAtPos(valPos, planeMask); 00930 00931 // check sign bit 00932 if (count == 0) { 00933 // all 1's have been set 00934 if (zeroAfterRun) { 00935 // finish the run with a 0 00936 signBit = false; 00937 zeroAfterRun = false; 00938 } else { 00939 // decode next sign bit 00940 if (GetBit(m_codeBuffer, signPos++)) { 00941 // generate 1's run of length 2^k 00942 count = runlen - 1; 00943 signBit = true; 00944 00945 // adapt k (double run-length interval) 00946 if (k < WordWidth) { 00947 k++; 00948 runlen <<= 1; 00949 } 00950 } else { 00951 // extract counter and generate 1's run of length count 00952 if (k > 0) { 00953 // extract counter 00954 count = GetValueBlock(m_codeBuffer, signPos, k); 00955 signPos += k; 00956 00957 // adapt k (half run-length interval) 00958 k--; 00959 runlen >>= 1; 00960 } 00961 if (count > 0) { 00962 count--; 00963 signBit = true; 00964 zeroAfterRun = true; 00965 } else { 00966 signBit = false; 00967 } 00968 } 00969 } 00970 } else { 00971 ASSERT(count > 0); 00972 ASSERT(signBit); 00973 count--; 00974 } 00975 00976 // copy sign bit 00977 SetSign(valPos, signBit); 00978 00979 // update significance flag vector 00980 m_sigFlagVector[valPos++] = true; 00981 sigPos++; 00982 } 00983 } 00984 00985 // refinement bit 00986 if (valPos < bufferSize) { 00987 // write one refinement bit 00988 if (GetBit(refBits, refPos)) { 00989 SetBitAtPos(valPos, planeMask); 00990 } 00991 refPos++; 00992 valPos++; 00993 } 00994 } 00995 ASSERT(sigPos <= bufferSize); 00996 ASSERT(refPos <= bufferSize); 00997 ASSERT(valPos == bufferSize); 00998 00999 return sigPos; 01000 } 01001 01003 #ifdef TRACE 01004 void CDecoder::DumpBuffer() { 01005 //printf("\nDump\n"); 01006 //for (int i=0; i < BufferSize; i++) { 01007 // printf("%d", m_value[i]); 01008 //} 01009 } 01010 #endif //TRACE