libpgf  6.11.32
PGF - Progressive Graphics File
Decoder.cpp
Go to the documentation of this 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