00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00028
00029 #include "Decoder.h"
00030 #ifdef TRACE
00031 #include <stdio.h>
00032 #endif
00033
00035
00036
00037
00038
00039
00040
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 #define CodeBufferBitLen (CodeBufferLen*WordWidth)
00059 #define MaxCodeLen ((1 << RLblockSizeLen) - 1)
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
00091 m_startPos = m_stream->GetPos();
00092
00093
00094 count = expected = MagicVersionSize;
00095 m_stream->Read(&count, &preHeader);
00096 if (count != expected) ReturnWithError(MissingData);
00097
00098
00099 if (preHeader.version & Version6) {
00100
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
00109 preHeader.hSize = __VAL(preHeader.hSize);
00110
00111
00112 if (memcmp(preHeader.magic, PGFMagic, 3) != 0) {
00113
00114 ReturnWithError(FormatCannotRead);
00115 }
00116
00117
00118 count = expected = (preHeader.hSize < HeaderSize) ? preHeader.hSize : HeaderSize;
00119 m_stream->Read(&count, &header);
00120 if (count != expected) ReturnWithError(MissingData);
00121
00122
00123 header.height = __VAL(UINT32(header.height));
00124 header.width = __VAL(UINT32(header.width));
00125
00126
00127 if (preHeader.version > 0) {
00128 #ifndef __PGFROISUPPORT__
00129
00130 if (preHeader.version & PGFROI) ReturnWithError(FormatCannotRead);
00131 #endif
00132
00133 int size = preHeader.hSize - HeaderSize;
00134
00135 if (size > 0) {
00136
00137 if (header.mode == ImageModeIndexedColor) {
00138 if (size < ColorTableSize) ReturnWithError(FormatCannotRead);
00139
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
00153 postHeader.userData = new(std::nothrow) UINT8[postHeader.userDataLen];
00154 if (!postHeader.userData) ReturnWithError(InsufficientMemory);
00155
00156
00157 count = expected = postHeader.userDataLen;
00158 m_stream->Read(&count, postHeader.userData);
00159 if (count != expected) ReturnWithError(MissingData);
00160 }
00161 }
00162 }
00163
00164
00165 levelLength = new(std::nothrow) UINT32[header.nLevels];
00166 if (!levelLength) ReturnWithError(InsufficientMemory);
00167
00168
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
00175 for (int i=0; i < header.nLevels; i++) {
00176 levelLength[i] = __VAL(levelLength[i]);
00177 }
00178 #endif
00179
00180
00181 for (int i=0; i < header.nLevels; i++) {
00182 m_streamSizeEstimation += levelLength[i];
00183 }
00184
00185 }
00186
00187
00188 m_encodedHeaderLength = UINT32(m_stream->GetPos() - m_startPos);
00189
00190
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
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;
00210 m_currentBlock = new(std::nothrow) CMacroBlock();
00211 if (!m_currentBlock) ReturnWithError(InsufficientMemory);
00212 }
00213 }
00214
00216
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
00262 for (int i=0; i < hh.quot; i++) {
00263
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
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
00288 base2 = base;
00289 for (int j=0; j < ww.quot; j++) {
00290
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
00302 pos = base2;
00303 for (int y=0; y < hh.rem; y++) {
00304
00305 for (int x=0; x < ww.rem; x++) {
00306 DequantizeValue(band, pos, quantParam);
00307 pos++;
00308 }
00309 pos += wr;
00310 }
00311 }
00312
00314
00315
00316
00317
00318
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
00338 quantParam -= level;
00339 if (quantParam < 0) quantParam = 0;
00340
00341
00342 for (int i=0; i < lhH.quot; i++) {
00343
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
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
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
00383 hlBase2 = hlBase;
00384 lhBase2 = lhBase;
00385 for (int j=0; j < hlW.quot; j++) {
00386
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
00403 hlPos = hlBase2;
00404 lhPos = lhBase2;
00405 for (int y=0; y < lhH.rem; y++) {
00406
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
00414 if (lhBand->GetWidth() > hlBand->GetWidth()) {
00415 DequantizeValue(lhBand, lhPos, quantParam);
00416 }
00417 hlPos += hlwr;
00418 lhPos += lhwr;
00419 hlBase += hlBand->GetWidth();
00420 }
00421
00422 if (hlBand->GetHeight() > lhBand->GetHeight()) {
00423
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
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
00462
00463 void CDecoder::DecodeTileBuffer() THROW_ {
00464
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
00477
00478
00479
00480 void CDecoder::DecodeBuffer() THROW_ {
00481 ASSERT(m_macroBlocksAvailable <= 0);
00482
00483
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
00493 try {
00494 ReadMacroBlock(m_macroBlocks[i]);
00495 m_macroBlocksAvailable++;
00496 } catch(IOException& ex) {
00497 if (ex.error == MissingData) {
00498 break;
00499 } else {
00500 throw;
00501 }
00502 }
00503 }
00504 #ifdef LIBPGF_USE_OPENMP
00505
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
00513 m_currentBlockIndex = 0;
00514 m_currentBlock = m_macroBlocks[m_currentBlockIndex];
00515 }
00516 }
00517
00519
00520
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
00530
00531 #endif
00532
00533
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
00543 if (m_roi) {
00544 m_stream->Read(&count, &h.val);
00545 if (count != expected) ReturnWithError(MissingData);
00546
00547
00548 h.val = __VAL(h.val);
00549 }
00550 #endif
00551
00552 block->m_header = h;
00553
00554
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
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
00576
00577
00578
00579 void CDecoder::SkipTileBuffer() THROW_ {
00580
00581 m_macroBlocksAvailable--;
00582
00583
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
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
00602 m_stream->SetPos(FSFromCurrent, sizeof(ROIBlockHeader));
00603 }
00604 #endif
00605
00606
00607 m_stream->SetPos(FSFromCurrent, wordLen*WordBytes);
00608 }
00609
00611
00612
00613
00614
00615
00616
00617
00618
00619
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
00628 for (UINT32 k=0; k < bufferSize; k++) {
00629 m_sigFlagVector[k] = false;
00630 }
00631 m_sigFlagVector[bufferSize] = true;
00632
00633
00634 for (UINT32 k=0; k < BufferSize; k++) {
00635 m_value[k] = 0;
00636 }
00637
00638
00639
00640 nPlanes = GetValueBlock(m_codeBuffer, 0, MaxBitPlanesLog);
00641 codePos += MaxBitPlanesLog;
00642
00643
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
00650 if (GetBit(m_codeBuffer, codePos)) {
00651
00652
00653 codePos++;
00654
00655
00656 codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen <= MaxCodeLen);
00657
00658
00659 sigPos = codePos + RLblockSizeLen; ASSERT(sigPos < CodeBufferBitLen);
00660
00661
00662 codePos = AlignWordPos(sigPos + codeLen); ASSERT(codePos < CodeBufferBitLen);
00663
00664
00665
00666 sigLen = ComposeBitplaneRLD(bufferSize, planeMask, sigPos, &m_codeBuffer[codePos >> WordWidthLog]);
00667
00668 } else {
00669
00670
00671 codePos++;
00672
00673
00674 sigLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(sigLen <= MaxCodeLen);
00675 codePos += RLblockSizeLen; ASSERT(codePos < CodeBufferBitLen);
00676
00677
00678 if (GetBit(m_codeBuffer, codePos)) {
00679
00680
00681 codePos++;
00682
00683
00684 codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen <= MaxCodeLen);
00685
00686
00687 signPos = codePos + RLblockSizeLen; ASSERT(signPos < CodeBufferBitLen);
00688
00689
00690 sigPos = AlignWordPos(signPos + codeLen); ASSERT(sigPos < CodeBufferBitLen);
00691
00692
00693 codePos = AlignWordPos(sigPos + sigLen); ASSERT(codePos < CodeBufferBitLen);
00694
00695
00696 sigLen = ComposeBitplaneRLD(bufferSize, planeMask, &m_codeBuffer[sigPos >> WordWidthLog], &m_codeBuffer[codePos >> WordWidthLog], signPos);
00697
00698 } else {
00699
00700
00701 codePos++;
00702
00703
00704 signLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(signLen <= MaxCodeLen);
00705
00706
00707 signPos = AlignWordPos(codePos + RLblockSizeLen); ASSERT(signPos < CodeBufferBitLen);
00708
00709
00710 sigPos = AlignWordPos(signPos + signLen); ASSERT(sigPos < CodeBufferBitLen);
00711
00712
00713 codePos = AlignWordPos(sigPos + sigLen); ASSERT(codePos < CodeBufferBitLen);
00714
00715
00716 sigLen = ComposeBitplane(bufferSize, planeMask, &m_codeBuffer[sigPos >> WordWidthLog], &m_codeBuffer[codePos >> WordWidthLog], &m_codeBuffer[signPos >> WordWidthLog]);
00717 }
00718 }
00719
00720
00721 codePos = AlignWordPos(codePos + bufferSize - sigLen); ASSERT(codePos < CodeBufferBitLen);
00722
00723
00724 planeMask >>= 1;
00725 }
00726
00727 m_valuePos = 0;
00728 }
00729
00731
00732
00733
00734
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
00746 sigEnd = valPos;
00747 while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
00748 sigEnd -= valPos;
00749 sigEnd += sigPos;
00750
00751
00752
00753 while (sigPos < sigEnd) {
00754
00755 zerocnt = SeekBitRange(sigBits, sigPos, sigEnd - sigPos);
00756 sigPos += zerocnt;
00757 valPos += zerocnt;
00758 if (sigPos < sigEnd) {
00759
00760 SetBitAtPos(valPos, planeMask);
00761
00762
00763 SetSign(valPos, GetBit(signBits, signPos++));
00764
00765
00766 m_sigFlagVector[valPos++] = true;
00767 sigPos++;
00768 }
00769 }
00770
00771 if (valPos < bufferSize) {
00772
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
00790
00791
00792
00793
00794
00795
00796
00797
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;
00805 UINT32 count = 0, rest = 0;
00806 bool set1 = false;
00807
00808 while (valPos < bufferSize) {
00809
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
00818 sigPos += rest;
00819 valPos += rest;
00820 rest = 0;
00821 } else {
00822
00823 if (GetBit(m_codeBuffer, codePos++)) {
00824
00825 if (k > 0) {
00826
00827 count = GetValueBlock(m_codeBuffer, codePos, k);
00828 codePos += k;
00829 if (count > 0) {
00830 sigPos += count;
00831 valPos += count;
00832 }
00833
00834
00835 k--;
00836 runlen >>= 1;
00837 }
00838
00839 set1 = true;
00840
00841 } else {
00842
00843 sigPos += runlen;
00844 valPos += runlen;
00845
00846
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
00859 SetBitAtPos(valPos, planeMask);
00860
00861
00862 SetSign(valPos, GetBit(m_codeBuffer, codePos++));
00863
00864
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
00877 if (valPos < bufferSize) {
00878
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
00895
00896
00897
00898
00899
00900
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;
00910 bool signBit = false;
00911 bool zeroAfterRun = false;
00912
00913 while (valPos < bufferSize) {
00914
00915 sigEnd = valPos;
00916 while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
00917 sigEnd -= valPos;
00918 sigEnd += sigPos;
00919
00920
00921
00922 while (sigPos < sigEnd) {
00923
00924 zerocnt = SeekBitRange(sigBits, sigPos, sigEnd - sigPos);
00925 sigPos += zerocnt;
00926 valPos += zerocnt;
00927 if (sigPos < sigEnd) {
00928
00929 SetBitAtPos(valPos, planeMask);
00930
00931
00932 if (count == 0) {
00933
00934 if (zeroAfterRun) {
00935
00936 signBit = false;
00937 zeroAfterRun = false;
00938 } else {
00939
00940 if (GetBit(m_codeBuffer, signPos++)) {
00941
00942 count = runlen - 1;
00943 signBit = true;
00944
00945
00946 if (k < WordWidth) {
00947 k++;
00948 runlen <<= 1;
00949 }
00950 } else {
00951
00952 if (k > 0) {
00953
00954 count = GetValueBlock(m_codeBuffer, signPos, k);
00955 signPos += k;
00956
00957
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
00977 SetSign(valPos, signBit);
00978
00979
00980 m_sigFlagVector[valPos++] = true;
00981 sigPos++;
00982 }
00983 }
00984
00985
00986 if (valPos < bufferSize) {
00987
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
01006
01007
01008
01009 }
01010 #endif //TRACE