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