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