libpgf  6.14.12
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                (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         // store current stream position
00091         m_startPos = m_stream->GetPos();
00092 
00093         // read magic and version
00094         count = expected = MagicVersionSize;
00095         m_stream->Read(&count, &preHeader);
00096         if (count != expected) ReturnWithError(MissingData);
00097 
00098         // read header size
00099         if (preHeader.version & Version6) {
00100                 // 32 bit header size since version 6
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         // make sure the values are correct read
00109         preHeader.hSize = __VAL(preHeader.hSize);
00110 
00111         // check magic number
00112         if (memcmp(preHeader.magic, PGFMagic, 3) != 0) {
00113                 // error condition: wrong Magic number
00114                 ReturnWithError(FormatCannotRead);
00115         }
00116 
00117         // read file header
00118         count = expected = (preHeader.hSize < HeaderSize) ? preHeader.hSize : HeaderSize;
00119         m_stream->Read(&count, &header);
00120         if (count != expected) ReturnWithError(MissingData);
00121 
00122         // make sure the values are correct read
00123         header.height = __VAL(UINT32(header.height));
00124         header.width = __VAL(UINT32(header.width));
00125 
00126         // be ready to read all versions including version 0
00127         if (preHeader.version > 0) {
00128 #ifndef __PGFROISUPPORT__
00129                 // check ROI usage
00130                 if (preHeader.version & PGFROI) ReturnWithError(FormatCannotRead);
00131 #endif
00132 
00133                 int size = preHeader.hSize - HeaderSize;
00134 
00135                 if (size > 0) {
00136                         // read post-header
00137                         if (header.mode == ImageModeIndexedColor) {
00138                                 if (size < ColorTableSize) ReturnWithError(FormatCannotRead);
00139                                 // read color table
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                                         // create user data memory block
00153                                         postHeader.userData = new(std::nothrow) UINT8[postHeader.userDataLen];
00154                                         if (!postHeader.userData) ReturnWithError(InsufficientMemory);
00155 
00156                                         // read user data
00157                                         count = expected = postHeader.userDataLen;
00158                                         m_stream->Read(&count, postHeader.userData);
00159                                         if (count != expected) ReturnWithError(MissingData);
00160                                 }
00161                         }
00162                 }
00163 
00164                 // create levelLength
00165                 levelLength = new(std::nothrow) UINT32[header.nLevels];
00166                 if (!levelLength) ReturnWithError(InsufficientMemory);
00167 
00168                 // read levelLength
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                 // make sure the values are correct read
00175                 for (int i=0; i < header.nLevels; i++) {
00176                         levelLength[i] = __VAL(levelLength[i]);
00177                 }
00178 #endif
00179 
00180                 // compute the total size in bytes; keep attention: level length information is optional
00181                 for (int i=0; i < header.nLevels; i++) {
00182                         m_streamSizeEstimation += levelLength[i];
00183                 }
00184                 
00185         }
00186 
00187         // store current stream position
00188         m_encodedHeaderLength = UINT32(m_stream->GetPos() - m_startPos);
00189 
00190         // set number of threads
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                 // create macro block array
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; // there is only one macro block
00210                 m_currentBlock = new(std::nothrow) CMacroBlock();
00211                 if (!m_currentBlock) ReturnWithError(InsufficientMemory);
00212         }
00213 }
00214 
00216 // Destructor
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         // main height
00262         for (int i=0; i < hh.quot; i++) {
00263                 // main width
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                 // rest of width
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         // main width 
00288         base2 = base;
00289         for (int j=0; j < ww.quot; j++) {
00290                 // rest of height
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         // rest of height
00302         pos = base2;
00303         for (int y=0; y < hh.rem; y++) {
00304                 // rest of width
00305                 for (int x=0; x < ww.rem; x++) {
00306                         DequantizeValue(band, pos, quantParam);
00307                         pos++;
00308                 }
00309                 pos += wr;
00310         }
00311 }
00312 
00314 // Decode and dequantize HL, and LH band of one level
00315 // LH and HH are interleaved in the codestream and must be split
00316 // Deccoding and dequantization of HL and LH Band (interleaved) using partitioning scheme
00317 // partitions the plane in squares of side length InterBlockSize
00318 // It might throw an IOException.
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         // correct quantParam with normalization factor
00338         quantParam -= level;
00339         if (quantParam < 0) quantParam = 0;
00340 
00341         // main height
00342         for (int i=0; i < lhH.quot; i++) {
00343                 // main width
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                 // rest of width
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                         // width difference between HL and LH
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         // main width 
00383         hlBase2 = hlBase;
00384         lhBase2 = lhBase;
00385         for (int j=0; j < hlW.quot; j++) {
00386                 // rest of height
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         // rest of height
00403         hlPos = hlBase2;
00404         lhPos = lhBase2;
00405         for (int y=0; y < lhH.rem; y++) {
00406                 // rest of width
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                 // width difference between HL and LH
00414                 if (lhBand->GetWidth() > hlBand->GetWidth()) {
00415                         DequantizeValue(lhBand, lhPos, quantParam);
00416                 }
00417                 hlPos += hlwr;
00418                 lhPos += lhwr;
00419                 hlBase += hlBand->GetWidth();
00420         }
00421         // height difference between HL and LH
00422         if (hlBand->GetHeight() > lhBand->GetHeight()) {
00423                 // total width
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                 // all data of current macro block has been read --> prepare next macro block
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 // Read next group of blocks from stream and decodes them into macro blocks
00462 // It might throw an IOException.
00463 void CDecoder::DecodeTileBuffer() THROW_ {
00464         // current block has been read --> prepare next current block
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 // Read next block from stream and decode into macro block
00477 // Decoding scheme: <wordLen>(16 bits) [ ROI ] data
00478 //              ROI       ::= <bufferSize>(15 bits) <eofTile>(1 bit)
00479 // It might throw an IOException.
00480 void CDecoder::DecodeBuffer() THROW_ {
00481         ASSERT(m_macroBlocksAvailable <= 0);
00482 
00483         // macro block management
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                         // read sequentially several blocks
00493                         try {
00494                                 ReadMacroBlock(m_macroBlocks[i]);
00495                                 m_macroBlocksAvailable++;
00496                         } catch(IOException& ex) {
00497                                 if (ex.error == MissingData) {
00498                                         break; // no further data available
00499                                 } else {
00500                                         throw;
00501                                 }
00502                         }
00503                 }
00504 #ifdef LIBPGF_USE_OPENMP
00505                 // decode in parallel
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                 // prepare current macro block
00513                 m_currentBlockIndex = 0;
00514                 m_currentBlock = m_macroBlocks[m_currentBlockIndex];
00515         }
00516 }
00517 
00519 // Read next block from stream and store it in the given block
00520 // It might throw an IOException.
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         //UINT32 filePos = (UINT32)m_stream->GetPos();
00530         //printf("DecodeBuffer: %d\n", filePos);
00531 #endif
00532 
00533         // read wordLen
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         // read ROIBlockHeader
00543         if (m_roi) {
00544                 m_stream->Read(&count, &h.val); 
00545                 if (count != expected) ReturnWithError(MissingData);
00546                 
00547                 // convert ROIBlockHeader
00548                 h.val = __VAL(h.val);
00549         }
00550 #endif
00551         // save header
00552         block->m_header = h;
00553 
00554         // read data
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         // convert data
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 // Read next block from stream but don't decode into macro block
00576 // Encoding scheme: <wordLen>(16 bits) [ ROI ] data
00577 //              ROI       ::= <bufferSize>(15 bits) <eofTile>(1 bit)
00578 // It might throw an IOException.
00579 void CDecoder::SkipTileBuffer() THROW_ {
00580         // current block is not used
00581         m_macroBlocksAvailable--;
00582 
00583         // check if pre-decoded data is available
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         // read wordLen
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                 // skip ROIBlockHeader
00602                 m_stream->SetPos(FSFromCurrent, sizeof(ROIBlockHeader));
00603         }
00604 #endif
00605 
00606         // skip data
00607         m_stream->SetPos(FSFromCurrent, wordLen*WordBytes);
00608 }
00609 
00611 // Decode block into buffer of given size using bit plane coding.
00612 // A buffer contains bufferLen UINT32 values, thus, bufferSize bits per bit plane.
00613 // Following coding scheme is used: 
00614 //              Buffer          ::= <nPlanes>(5 bits) foreach(plane i): Plane[i]  
00615 //              Plane[i]        ::= [ Sig1 | Sig2 ] [DWORD alignment] refBits
00616 //              Sig1            ::= 1 <codeLen>(15 bits) codedSigAndSignBits 
00617 //              Sig2            ::= 0 <sigLen>(15 bits) [Sign1 | Sign2 ] [DWORD alignment] sigBits 
00618 //              Sign1           ::= 1 <codeLen>(15 bits) codedSignBits
00619 //              Sign2           ::= 0 <signLen>(15 bits) [DWORD alignment] signBits
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         // clear significance vector
00628         for (UINT32 k=0; k < bufferSize; k++) {
00629                 m_sigFlagVector[k] = false;
00630         }
00631         m_sigFlagVector[bufferSize] = true; // sentinel
00632 
00633         // clear output buffer
00634         for (UINT32 k=0; k < BufferSize; k++) {
00635                 m_value[k] = 0;
00636         }
00637 
00638         // read number of bit planes
00639         // <nPlanes>
00640         nPlanes = GetValueBlock(m_codeBuffer, 0, MaxBitPlanesLog); 
00641         codePos += MaxBitPlanesLog;
00642 
00643         // loop through all bit planes
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                 // read RL code
00650                 if (GetBit(m_codeBuffer, codePos)) {
00651                         // RL coding of sigBits is used
00652                         // <1><codeLen><codedSigAndSignBits>_<refBits>
00653                         codePos++;
00654 
00655                         // read codeLen
00656                         codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen <= MaxCodeLen);
00657 
00658                         // position of encoded sigBits and signBits
00659                         sigPos = codePos + RLblockSizeLen; ASSERT(sigPos < CodeBufferBitLen); 
00660 
00661                         // refinement bits
00662                         codePos = AlignWordPos(sigPos + codeLen); ASSERT(codePos < CodeBufferBitLen); 
00663 
00664                         // run-length decode significant bits and signs from m_codeBuffer and 
00665                         // read refinement bits from m_codeBuffer and compose bit plane
00666                         sigLen = ComposeBitplaneRLD(bufferSize, planeMask, sigPos, &m_codeBuffer[codePos >> WordWidthLog]);
00667 
00668                 } else {
00669                         // no RL coding is used for sigBits and signBits together
00670                         // <0><sigLen>
00671                         codePos++;
00672 
00673                         // read sigLen
00674                         sigLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(sigLen <= MaxCodeLen);
00675                         codePos += RLblockSizeLen; ASSERT(codePos < CodeBufferBitLen);
00676 
00677                         // read RL code for signBits
00678                         if (GetBit(m_codeBuffer, codePos)) {
00679                                 // RL coding is used just for signBits
00680                                 // <1><codeLen><codedSignBits>_<sigBits>_<refBits>
00681                                 codePos++;
00682 
00683                                 // read codeLen
00684                                 codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen <= MaxCodeLen);
00685 
00686                                 // sign bits
00687                                 signPos = codePos + RLblockSizeLen; ASSERT(signPos < CodeBufferBitLen);
00688                                 
00689                                 // significant bits
00690                                 sigPos = AlignWordPos(signPos + codeLen); ASSERT(sigPos < CodeBufferBitLen);
00691 
00692                                 // refinement bits
00693                                 codePos = AlignWordPos(sigPos + sigLen); ASSERT(codePos < CodeBufferBitLen);
00694 
00695                                 // read significant and refinement bitset from m_codeBuffer
00696                                 sigLen = ComposeBitplaneRLD(bufferSize, planeMask, &m_codeBuffer[sigPos >> WordWidthLog], &m_codeBuffer[codePos >> WordWidthLog], signPos);
00697                         
00698                         } else {
00699                                 // RL coding of signBits was not efficient and therefore not used
00700                                 // <0><signLen>_<signBits>_<sigBits>_<refBits>
00701                                 codePos++;
00702 
00703                                 // read signLen
00704                                 signLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(signLen <= MaxCodeLen);
00705                                 
00706                                 // sign bits
00707                                 signPos = AlignWordPos(codePos + RLblockSizeLen); ASSERT(signPos < CodeBufferBitLen);
00708 
00709                                 // significant bits
00710                                 sigPos = AlignWordPos(signPos + signLen); ASSERT(sigPos < CodeBufferBitLen);
00711 
00712                                 // refinement bits
00713                                 codePos = AlignWordPos(sigPos + sigLen); ASSERT(codePos < CodeBufferBitLen);
00714 
00715                                 // read significant and refinement bitset from m_codeBuffer
00716                                 sigLen = ComposeBitplane(bufferSize, planeMask, &m_codeBuffer[sigPos >> WordWidthLog], &m_codeBuffer[codePos >> WordWidthLog], &m_codeBuffer[signPos >> WordWidthLog]);
00717                         }
00718                 }
00719 
00720                 // start of next chunk
00721                 codePos = AlignWordPos(codePos + bufferSize - sigLen); ASSERT(codePos < CodeBufferBitLen); 
00722                 
00723                 // next plane
00724                 planeMask >>= 1;
00725         }
00726 
00727         m_valuePos = 0;
00728 }
00729 
00731 // Reconstruct bitplane from significant bitset and refinement bitset
00732 // returns length [bits] of sigBits
00733 // input:  sigBits, refBits, signBits
00734 // output: m_value
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                 // search next 1 in m_sigFlagVector using searching with sentinel
00746                 sigEnd = valPos;
00747                 while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
00748                 sigEnd -= valPos;
00749                 sigEnd += sigPos;
00750 
00751                 // search 1's in sigBits[sigPos..sigEnd)
00752                 // these 1's are significant bits
00753                 while (sigPos < sigEnd) {
00754                         // search 0's
00755                         zerocnt = SeekBitRange(sigBits, sigPos, sigEnd - sigPos);
00756                         sigPos += zerocnt;
00757                         valPos += zerocnt;
00758                         if (sigPos < sigEnd) {
00759                                 // write bit to m_value
00760                                 SetBitAtPos(valPos, planeMask);
00761 
00762                                 // copy sign bit
00763                                 SetSign(valPos, GetBit(signBits, signPos++)); 
00764 
00765                                 // update significance flag vector
00766                                 m_sigFlagVector[valPos++] = true;
00767                                 sigPos++; 
00768                         }
00769                 }
00770                 // refinement bit
00771                 if (valPos < bufferSize) {
00772                         // write one refinement bit
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 // Reconstruct bitplane from significant bitset and refinement bitset
00790 // returns length [bits] of decoded significant bits
00791 // input:  RL encoded sigBits and signBits in m_codeBuffer, refBits
00792 // output: m_value
00793 // RLE:
00794 // - Decode run of 2^k zeros by a single 0.
00795 // - Decode run of count 0's followed by a 1 with codeword: 1<count>x
00796 // - x is 0: if a positive sign has been stored, otherwise 1
00797 // - Read each bit from m_codeBuffer[codePos] and increment codePos.
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; // = 2^k
00805         UINT32 count = 0, rest = 0;
00806         bool set1 = false;
00807 
00808         while (valPos < bufferSize) {
00809                 // search next 1 in m_sigFlagVector using searching with sentinel
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                                 // rest of last run
00818                                 sigPos += rest;
00819                                 valPos += rest;
00820                                 rest = 0;
00821                         } else {
00822                                 // decode significant bits
00823                                 if (GetBit(m_codeBuffer, codePos++)) {
00824                                         // extract counter and generate zero run of length count
00825                                         if (k > 0) {
00826                                                 // extract counter
00827                                                 count = GetValueBlock(m_codeBuffer, codePos, k); 
00828                                                 codePos += k;
00829                                                 if (count > 0) {
00830                                                         sigPos += count;
00831                                                         valPos += count;
00832                                                 }
00833 
00834                                                 // adapt k (half run-length interval)
00835                                                 k--;
00836                                                 runlen >>= 1;
00837                                         }
00838 
00839                                         set1 = true;
00840 
00841                                 } else {
00842                                         // generate zero run of length 2^k
00843                                         sigPos += runlen;
00844                                         valPos += runlen;
00845 
00846                                         // adapt k (double run-length interval)
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                                         // write 1 bit
00859                                         SetBitAtPos(valPos, planeMask);
00860 
00861                                         // set sign bit
00862                                         SetSign(valPos, GetBit(m_codeBuffer, codePos++)); 
00863 
00864                                         // update significance flag vector
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                 // refinement bit
00877                 if (valPos < bufferSize) {
00878                         // write one refinement bit
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 // Reconstruct bitplane from significant bitset, refinement bitset, and RL encoded sign bits
00895 // returns length [bits] of sigBits
00896 // input:  sigBits, refBits, RL encoded signBits
00897 // output: m_value
00898 // RLE:
00899 // decode run of 2^k 1's by a single 1
00900 // decode run of count 1's followed by a 0 with codeword: 0<count>
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; // = 2^k
00910         bool signBit = false;
00911         bool zeroAfterRun = false;
00912 
00913         while (valPos < bufferSize) {
00914                 // search next 1 in m_sigFlagVector using searching with sentinel
00915                 sigEnd = valPos;
00916                 while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
00917                 sigEnd -= valPos;
00918                 sigEnd += sigPos;
00919 
00920                 // search 1's in sigBits[sigPos..sigEnd)
00921                 // these 1's are significant bits
00922                 while (sigPos < sigEnd) {
00923                         // search 0's
00924                         zerocnt = SeekBitRange(sigBits, sigPos, sigEnd - sigPos);
00925                         sigPos += zerocnt;
00926                         valPos += zerocnt;
00927                         if (sigPos < sigEnd) {
00928                                 // write bit to m_value
00929                                 SetBitAtPos(valPos, planeMask);
00930 
00931                                 // check sign bit
00932                                 if (count == 0) {
00933                                         // all 1's have been set
00934                                         if (zeroAfterRun) {
00935                                                 // finish the run with a 0
00936                                                 signBit = false;
00937                                                 zeroAfterRun = false;
00938                                         } else {
00939                                                 // decode next sign bit
00940                                                 if (GetBit(m_codeBuffer, signPos++)) {
00941                                                         // generate 1's run of length 2^k
00942                                                         count = runlen - 1;
00943                                                         signBit = true;
00944                         
00945                                                         // adapt k (double run-length interval)
00946                                                         if (k < WordWidth) {
00947                                                                 k++; 
00948                                                                 runlen <<= 1;
00949                                                         }
00950                                                 } else {
00951                                                         // extract counter and generate 1's run of length count
00952                                                         if (k > 0) {
00953                                                                 // extract counter
00954                                                                 count = GetValueBlock(m_codeBuffer, signPos, k); 
00955                                                                 signPos += k;
00956 
00957                                                                 // adapt k (half run-length interval)
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                                 // copy sign bit
00977                                 SetSign(valPos, signBit); 
00978 
00979                                 // update significance flag vector
00980                                 m_sigFlagVector[valPos++] = true;
00981                                 sigPos++; 
00982                         }
00983                 }
00984 
00985                 // refinement bit
00986                 if (valPos < bufferSize) {
00987                         // write one refinement bit
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         //printf("\nDump\n");
01006         //for (int i=0; i < BufferSize; i++) {
01007         //      printf("%d", m_value[i]);
01008         //}
01009 }
01010 #endif //TRACE
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines