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