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