libpgf  6.11.42
PGF - Progressive Graphics File
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Decoder.cpp
Go to the documentation of this file.
1 /*
2  * The Progressive Graphics File; http://www.libpgf.org
3  *
4  * $Date: 2006-06-04 22:05:59 +0200 (So, 04 Jun 2006) $
5  * $Revision: 229 $
6  *
7  * This file Copyright (C) 2006 xeraina GmbH, Switzerland
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22  */
23 
28 
29 #include "Decoder.h"
30 #ifdef TRACE
31  #include <stdio.h>
32 #endif
33 
35 // PGF: file structure
36 //
37 // PGFPreHeader PGFHeader PGFPostHeader LevelLengths Level_n-1 Level_n-2 ... Level_0
38 // PGFPostHeader ::= [ColorTable] [UserData]
39 // LevelLengths ::= UINT32[nLevels]
40 
42 // Decoding scheme
43 // input: binary file
44 // output: wavelet coefficients stored in subbands
45 //
46 // file (for each buffer: packedLength (16 bit), packed bits)
47 // |
48 // m_codeBuffer (for each plane: RLcodeLength (16 bit), RLcoded sigBits + m_sign, refBits)
49 // | | |
50 // m_sign sigBits refBits [BufferLen, BufferLen, BufferLen]
51 // | | |
52 // m_value [BufferSize]
53 // |
54 // subband
55 //
56 
57 // Constants
58 #define CodeBufferBitLen (BufferSize*WordWidth) // max number of bits in m_codeBuffer
59 #define MaxCodeLen ((1 << RLblockSizeLen) - 1) // max length of RL encoded block
60 
62 // Constructor
63 // Read pre-header, header, and levelLength
64 // It might throw an IOException.
65 CDecoder::CDecoder(CPGFStream* stream, PGFPreHeader& preHeader, PGFHeader& header, PGFPostHeader& postHeader, UINT32*& levelLength, bool useOMP /*= true*/) THROW_
66 : m_stream(stream)
67 , m_startPos(0)
68 , m_streamSizeEstimation(0)
69 , m_encodedHeaderLength(0)
70 , m_currentBlockIndex(0)
71 , m_macroBlocksAvailable(0)
72 #ifdef __PGFROISUPPORT__
73 , m_roi(false)
74 #endif
75 {
76  ASSERT(m_stream);
77 
78  int count, expected;
79 
80  // set number of threads
81 #ifdef LIBPGF_USE_OPENMP
82  m_macroBlockLen = omp_get_num_procs();
83 #else
84  m_macroBlockLen = 1;
85 #endif
86 
87  if (useOMP && m_macroBlockLen > 1) {
88 #ifdef LIBPGF_USE_OPENMP
89  omp_set_num_threads(m_macroBlockLen);
90 #endif
91 
92  // create macro block array
93  m_macroBlocks = new CMacroBlock*[m_macroBlockLen];
94  for (int i=0; i < m_macroBlockLen; i++) m_macroBlocks[i] = new CMacroBlock(this);
95  m_currentBlock = m_macroBlocks[m_currentBlockIndex];
96  } else {
97  m_macroBlocks = 0;
98  m_macroBlockLen = 1; // there is only one macro block
99  m_currentBlock = new CMacroBlock(this);
100  }
101 
102  // store current stream position
103  m_startPos = m_stream->GetPos();
104 
105  // read magic and version
106  count = expected = MagicVersionSize;
107  m_stream->Read(&count, &preHeader);
108  if (count != expected) ReturnWithError(MissingData);
109 
110  // read header size
111  if (preHeader.version & Version6) {
112  // 32 bit header size since version 6
113  count = expected = 4;
114  } else {
115  count = expected = 2;
116  }
117  m_stream->Read(&count, ((UINT8*)&preHeader) + MagicVersionSize);
118  if (count != expected) ReturnWithError(MissingData);
119 
120  // make sure the values are correct read
121  preHeader.hSize = __VAL(preHeader.hSize);
122 
123  // check magic number
124  if (memcmp(preHeader.magic, Magic, 3) != 0) {
125  // error condition: wrong Magic number
126  ReturnWithError(FormatCannotRead);
127  }
128 
129  // read file header
130  count = expected = (preHeader.hSize < HeaderSize) ? preHeader.hSize : HeaderSize;
131  m_stream->Read(&count, &header);
132  if (count != expected) ReturnWithError(MissingData);
133 
134  // make sure the values are correct read
135  header.height = __VAL(UINT32(header.height));
136  header.width = __VAL(UINT32(header.width));
137 
138  // be ready to read all versions including version 0
139  if (preHeader.version > 0) {
140 #ifndef __PGFROISUPPORT__
141  // check ROI usage
142  if (preHeader.version & PGFROI) ReturnWithError(FormatCannotRead);
143 #endif
144 
145  int size = preHeader.hSize - HeaderSize;
146 
147  if (size > 0) {
148  // read post header
149  if (header.mode == ImageModeIndexedColor) {
150  ASSERT((size_t)size >= ColorTableSize);
151  // read color table
152  count = expected = ColorTableSize;
153  m_stream->Read(&count, postHeader.clut);
154  if (count != expected) ReturnWithError(MissingData);
155  size -= count;
156  }
157 
158  if (size > 0) {
159  // create user data memory block
160  postHeader.userDataLen = size;
161  postHeader.userData = new(std::nothrow) UINT8[postHeader.userDataLen];
162  if (!postHeader.userData) ReturnWithError(InsufficientMemory);
163 
164  // read user data
165  count = expected = postHeader.userDataLen;
166  m_stream->Read(&count, postHeader.userData);
167  if (count != expected) ReturnWithError(MissingData);
168  }
169  }
170 
171  // create levelLength
172  levelLength = new UINT32[header.nLevels];
173 
174  // read levelLength
175  count = expected = header.nLevels*WordBytes;
176  m_stream->Read(&count, levelLength);
177  if (count != expected) ReturnWithError(MissingData);
178 
179 #ifdef PGF_USE_BIG_ENDIAN
180  // make sure the values are correct read
181  for (int i=0; i < header.nLevels; i++) {
182  levelLength[i] = __VAL(levelLength[i]);
183  }
184 #endif
185 
186  // compute the total size in bytes; keep attention: level length information is optional
187  for (int i=0; i < header.nLevels; i++) {
188  m_streamSizeEstimation += levelLength[i];
189  }
190 
191  }
192 
193  // store current stream position
194  m_encodedHeaderLength = UINT32(m_stream->GetPos() - m_startPos);
195 }
196 
198 // Destructor
200  if (m_macroBlocks) {
201  for (int i=0; i < m_macroBlockLen; i++) delete m_macroBlocks[i];
202  delete[] m_macroBlocks;
203  } else {
204  delete m_currentBlock;
205  }
206 }
207 
214 UINT32 CDecoder::ReadEncodedData(UINT8* target, UINT32 len) const THROW_ {
215  ASSERT(m_stream);
216 
217  int count = len;
218  m_stream->Read(&count, target);
219 
220  return count;
221 }
222 
234 void CDecoder::Partition(CSubband* band, int quantParam, int width, int height, int startPos, int pitch) THROW_ {
235  ASSERT(band);
236 
237  const div_t ww = div(width, LinBlockSize);
238  const div_t hh = div(height, LinBlockSize);
239  const int ws = pitch - LinBlockSize;
240  const int wr = pitch - ww.rem;
241  int pos, base = startPos, base2;
242 
243  // main height
244  for (int i=0; i < hh.quot; i++) {
245  // main width
246  base2 = base;
247  for (int j=0; j < ww.quot; j++) {
248  pos = base2;
249  for (int y=0; y < LinBlockSize; y++) {
250  for (int x=0; x < LinBlockSize; x++) {
251  DequantizeValue(band, pos, quantParam);
252  pos++;
253  }
254  pos += ws;
255  }
256  base2 += LinBlockSize;
257  }
258  // rest of width
259  pos = base2;
260  for (int y=0; y < LinBlockSize; y++) {
261  for (int x=0; x < ww.rem; x++) {
262  DequantizeValue(band, pos, quantParam);
263  pos++;
264  }
265  pos += wr;
266  base += pitch;
267  }
268  }
269  // main width
270  base2 = base;
271  for (int j=0; j < ww.quot; j++) {
272  // rest of height
273  pos = base2;
274  for (int y=0; y < hh.rem; y++) {
275  for (int x=0; x < LinBlockSize; x++) {
276  DequantizeValue(band, pos, quantParam);
277  pos++;
278  }
279  pos += ws;
280  }
281  base2 += LinBlockSize;
282  }
283  // rest of height
284  pos = base2;
285  for (int y=0; y < hh.rem; y++) {
286  // rest of width
287  for (int x=0; x < ww.rem; x++) {
288  DequantizeValue(band, pos, quantParam);
289  pos++;
290  }
291  pos += wr;
292  }
293 }
294 
296 // Decode and dequantize HL, and LH band of one level
297 // LH and HH are interleaved in the codestream and must be split
298 // Deccoding and dequantization of HL and LH Band (interleaved) using partitioning scheme
299 // partitions the plane in squares of side length InterBlockSize
300 // It might throw an IOException.
301 void CDecoder::DecodeInterleaved(CWaveletTransform* wtChannel, int level, int quantParam) THROW_ {
302  CSubband* hlBand = wtChannel->GetSubband(level, HL);
303  CSubband* lhBand = wtChannel->GetSubband(level, LH);
304  const div_t lhH = div(lhBand->GetHeight(), InterBlockSize);
305  const div_t hlW = div(hlBand->GetWidth(), InterBlockSize);
306  const int hlws = hlBand->GetWidth() - InterBlockSize;
307  const int hlwr = hlBand->GetWidth() - hlW.rem;
308  const int lhws = lhBand->GetWidth() - InterBlockSize;
309  const int lhwr = lhBand->GetWidth() - hlW.rem;
310  int hlPos, lhPos;
311  int hlBase = 0, lhBase = 0, hlBase2, lhBase2;
312 
313  ASSERT(lhBand->GetWidth() >= hlBand->GetWidth());
314  ASSERT(hlBand->GetHeight() >= lhBand->GetHeight());
315 
316  if (!hlBand->AllocMemory()) ReturnWithError(InsufficientMemory);
317  if (!lhBand->AllocMemory()) ReturnWithError(InsufficientMemory);
318 
319  // correct quantParam with normalization factor
320  quantParam -= level;
321  if (quantParam < 0) quantParam = 0;
322 
323  // main height
324  for (int i=0; i < lhH.quot; i++) {
325  // main width
326  hlBase2 = hlBase;
327  lhBase2 = lhBase;
328  for (int j=0; j < hlW.quot; j++) {
329  hlPos = hlBase2;
330  lhPos = lhBase2;
331  for (int y=0; y < InterBlockSize; y++) {
332  for (int x=0; x < InterBlockSize; x++) {
333  DequantizeValue(hlBand, hlPos, quantParam);
334  DequantizeValue(lhBand, lhPos, quantParam);
335  hlPos++;
336  lhPos++;
337  }
338  hlPos += hlws;
339  lhPos += lhws;
340  }
341  hlBase2 += InterBlockSize;
342  lhBase2 += InterBlockSize;
343  }
344  // rest of width
345  hlPos = hlBase2;
346  lhPos = lhBase2;
347  for (int y=0; y < InterBlockSize; y++) {
348  for (int x=0; x < hlW.rem; x++) {
349  DequantizeValue(hlBand, hlPos, quantParam);
350  DequantizeValue(lhBand, lhPos, quantParam);
351  hlPos++;
352  lhPos++;
353  }
354  // width difference between HL and LH
355  if (lhBand->GetWidth() > hlBand->GetWidth()) {
356  DequantizeValue(lhBand, lhPos, quantParam);
357  }
358  hlPos += hlwr;
359  lhPos += lhwr;
360  hlBase += hlBand->GetWidth();
361  lhBase += lhBand->GetWidth();
362  }
363  }
364  // main width
365  hlBase2 = hlBase;
366  lhBase2 = lhBase;
367  for (int j=0; j < hlW.quot; j++) {
368  // rest of height
369  hlPos = hlBase2;
370  lhPos = lhBase2;
371  for (int y=0; y < lhH.rem; y++) {
372  for (int x=0; x < InterBlockSize; x++) {
373  DequantizeValue(hlBand, hlPos, quantParam);
374  DequantizeValue(lhBand, lhPos, quantParam);
375  hlPos++;
376  lhPos++;
377  }
378  hlPos += hlws;
379  lhPos += lhws;
380  }
381  hlBase2 += InterBlockSize;
382  lhBase2 += InterBlockSize;
383  }
384  // rest of height
385  hlPos = hlBase2;
386  lhPos = lhBase2;
387  for (int y=0; y < lhH.rem; y++) {
388  // rest of width
389  for (int x=0; x < hlW.rem; x++) {
390  DequantizeValue(hlBand, hlPos, quantParam);
391  DequantizeValue(lhBand, lhPos, quantParam);
392  hlPos++;
393  lhPos++;
394  }
395  // width difference between HL and LH
396  if (lhBand->GetWidth() > hlBand->GetWidth()) {
397  DequantizeValue(lhBand, lhPos, quantParam);
398  }
399  hlPos += hlwr;
400  lhPos += lhwr;
401  hlBase += hlBand->GetWidth();
402  }
403  // height difference between HL and LH
404  if (hlBand->GetHeight() > lhBand->GetHeight()) {
405  // total width
406  hlPos = hlBase;
407  for (int j=0; j < hlBand->GetWidth(); j++) {
408  DequantizeValue(hlBand, hlPos, quantParam);
409  hlPos++;
410  }
411  }
412 }
413 
417 void CDecoder::Skip(UINT64 offset) THROW_ {
418  m_stream->SetPos(FSFromCurrent, offset);
419 }
420 
430 void CDecoder::DequantizeValue(CSubband* band, UINT32 bandPos, int quantParam) THROW_ {
431  ASSERT(m_currentBlock);
432 
433  if (m_currentBlock->IsCompletelyRead()) {
434  // all data of current macro block has been read --> prepare next macro block
435  DecodeTileBuffer();
436  }
437 
438  band->SetData(bandPos, m_currentBlock->m_value[m_currentBlock->m_valuePos] << quantParam);
439  m_currentBlock->m_valuePos++;
440 }
441 
443 // Read next group of blocks from stream and decodes them into macro blocks
444 // It might throw an IOException.
445 void CDecoder::DecodeTileBuffer() THROW_ {
446  // current block has been read --> prepare next current block
448 
449  if (m_macroBlocksAvailable > 0) {
451  } else {
452  DecodeBuffer();
453  }
454  ASSERT(m_currentBlock);
455 }
456 
458 // Read next block from stream and decode into macro block
459 // Decoding scheme: <wordLen>(16 bits) [ ROI ] data
460 // ROI ::= <bufferSize>(15 bits) <eofTile>(1 bit)
461 // It might throw an IOException.
462 void CDecoder::DecodeBuffer() THROW_ {
463  ASSERT(m_macroBlocksAvailable <= 0);
464 
465  // macro block management
466  if (m_macroBlockLen == 1) {
467  ASSERT(m_currentBlock);
471  } else {
473  for (int i=0; i < m_macroBlockLen; i++) {
474  // read sequentially several blocks
475  try {
478  } catch(IOException& ex) {
479  if (ex.error == MissingData) {
480  break; // no further data available
481  } else {
482  throw ex;
483  }
484  }
485  }
486 
487  // decode in parallel
488  #pragma omp parallel for default(shared) //no declared exceptions in next block
489  for (int i=0; i < m_macroBlocksAvailable; i++) {
491  }
492 
493  // prepare current macro block
496  }
497 }
498 
500 // Read next block from stream and store it in the given block
501 // It might throw an IOException.
503  ASSERT(block);
504 
505  UINT16 wordLen;
507  int count, expected;
508 
509 #ifdef TRACE
510  //UINT32 filePos = (UINT32)m_stream->GetPos();
511  //printf("DecodeBuffer: %d\n", filePos);
512 #endif
513 
514  // read wordLen
515  count = expected = sizeof(UINT16);
516  m_stream->Read(&count, &wordLen);
517  if (count != expected) ReturnWithError(MissingData);
518  wordLen = __VAL(wordLen);
519  if (wordLen > BufferSize)
520  ReturnWithError(FormatCannotRead);
521 
522 #ifdef __PGFROISUPPORT__
523  // read ROIBlockHeader
524  if (m_roi) {
525  m_stream->Read(&count, &h.val);
526  if (count != expected) ReturnWithError(MissingData);
527 
528  // convert ROIBlockHeader
529  h.val = __VAL(h.val);
530  }
531 #endif
532  // save header
533  block->m_header = h;
534 
535  // read data
536  count = expected = wordLen*WordBytes;
537  m_stream->Read(&count, block->m_codeBuffer);
538  if (count != expected) ReturnWithError(MissingData);
539 
540 #ifdef PGF_USE_BIG_ENDIAN
541  // convert data
542  count /= WordBytes;
543  for (int i=0; i < count; i++) {
544  block->m_codeBuffer[i] = __VAL(block->m_codeBuffer[i]);
545  }
546 #endif
547 
548 #ifdef __PGFROISUPPORT__
549  ASSERT(m_roi && h.rbh.bufferSize <= BufferSize || h.rbh.bufferSize == BufferSize);
550 #else
551  ASSERT(h.rbh.bufferSize == BufferSize);
552 #endif
553 }
554 
556 // Read next block from stream but don't decode into macro block
557 // Encoding scheme: <wordLen>(16 bits) [ ROI ] data
558 // ROI ::= <bufferSize>(15 bits) <eofTile>(1 bit)
559 // It might throw an IOException.
560 void CDecoder::SkipTileBuffer() THROW_ {
561  // current block is not used
563 
564  // check if pre-decoded data is available
565  if (m_macroBlocksAvailable > 0) {
567  return;
568  }
569 
570  UINT16 wordLen;
571  int count, expected;
572 
573  // read wordLen
574  count = expected = sizeof(wordLen);
575  m_stream->Read(&count, &wordLen);
576  if (count != expected) ReturnWithError(MissingData);
577  wordLen = __VAL(wordLen);
578  ASSERT(wordLen <= BufferSize);
579 
580 #ifdef __PGFROISUPPORT__
581  if (m_roi) {
582  // skip ROIBlockHeader
583  m_stream->SetPos(FSFromCurrent, sizeof(ROIBlockHeader));
584  }
585 #endif
586 
587  // skip data
588  m_stream->SetPos(FSFromCurrent, wordLen*WordBytes);
589 }
590 
592 // Decode block into buffer of given size using bit plane coding.
593 // A buffer contains bufferLen UINT32 values, thus, bufferSize bits per bit plane.
594 // Following coding scheme is used:
595 // Buffer ::= <nPlanes>(5 bits) foreach(plane i): Plane[i]
596 // Plane[i] ::= [ Sig1 | Sig2 ] [DWORD alignment] refBits
597 // Sig1 ::= 1 <codeLen>(15 bits) codedSigAndSignBits
598 // Sig2 ::= 0 <sigLen>(15 bits) [Sign1 | Sign2 ] [DWORD alignment] sigBits
599 // Sign1 ::= 1 <codeLen>(15 bits) codedSignBits
600 // Sign2 ::= 0 <signLen>(15 bits) [DWORD alignment] signBits
602  UINT32 bufferSize = m_header.rbh.bufferSize; ASSERT(bufferSize <= BufferSize);
603 
604  UINT32 nPlanes;
605  UINT32 codePos = 0, codeLen, sigLen, sigPos, signLen, signPos;
606  DataT planeMask;
607 
608  // clear significance vector
609  for (UINT32 k=0; k < bufferSize; k++) {
610  m_sigFlagVector[k] = false;
611  }
612  m_sigFlagVector[bufferSize] = true; // sentinel
613 
614  // clear output buffer
615  for (UINT32 k=0; k < BufferSize; k++) {
616  m_value[k] = 0;
617  }
618 
619  // read number of bit planes
620  // <nPlanes>
622  codePos += MaxBitPlanesLog;
623 
624  // loop through all bit planes
625  if (nPlanes == 0) nPlanes = MaxBitPlanes + 1;
626  ASSERT(0 < nPlanes && nPlanes <= MaxBitPlanes + 1);
627  planeMask = 1 << (nPlanes - 1);
628 
629  for (int plane = nPlanes - 1; plane >= 0; plane--) {
630  // read RL code
631  if (GetBit(m_codeBuffer, codePos)) {
632  // RL coding of sigBits is used
633  // <1><codeLen><codedSigAndSignBits>_<refBits>
634  codePos++;
635 
636  // read codeLen
637  codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen <= MaxCodeLen);
638 
639  // position of encoded sigBits and signBits
640  sigPos = codePos + RLblockSizeLen; ASSERT(sigPos < CodeBufferBitLen);
641 
642  // refinement bits
643  codePos = AlignWordPos(sigPos + codeLen); ASSERT(codePos < CodeBufferBitLen);
644 
645  // run-length decode significant bits and signs from m_codeBuffer and
646  // read refinement bits from m_codeBuffer and compose bit plane
647  sigLen = ComposeBitplaneRLD(bufferSize, planeMask, sigPos, &m_codeBuffer[codePos >> WordWidthLog]);
648 
649  } else {
650  // no RL coding is used for sigBits and signBits together
651  // <0><sigLen>
652  codePos++;
653 
654  // read sigLen
655  sigLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(sigLen <= MaxCodeLen);
656  codePos += RLblockSizeLen; ASSERT(codePos < CodeBufferBitLen);
657 
658  // read RL code for signBits
659  if (GetBit(m_codeBuffer, codePos)) {
660  // RL coding is used just for signBits
661  // <1><codeLen><codedSignBits>_<sigBits>_<refBits>
662  codePos++;
663 
664  // read codeLen
665  codeLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(codeLen <= MaxCodeLen);
666 
667  // sign bits
668  signPos = codePos + RLblockSizeLen; ASSERT(signPos < CodeBufferBitLen);
669 
670  // significant bits
671  sigPos = AlignWordPos(signPos + codeLen); ASSERT(sigPos < CodeBufferBitLen);
672 
673  // refinement bits
674  codePos = AlignWordPos(sigPos + sigLen); ASSERT(codePos < CodeBufferBitLen);
675 
676  // read significant and refinement bitset from m_codeBuffer
677  sigLen = ComposeBitplaneRLD(bufferSize, planeMask, &m_codeBuffer[sigPos >> WordWidthLog], &m_codeBuffer[codePos >> WordWidthLog], signPos);
678 
679  } else {
680  // RL coding of signBits was not efficient and therefore not used
681  // <0><signLen>_<signBits>_<sigBits>_<refBits>
682  codePos++;
683 
684  // read signLen
685  signLen = GetValueBlock(m_codeBuffer, codePos, RLblockSizeLen); ASSERT(signLen <= MaxCodeLen);
686 
687  // sign bits
688  signPos = AlignWordPos(codePos + RLblockSizeLen); ASSERT(signPos < CodeBufferBitLen);
689 
690  // significant bits
691  sigPos = AlignWordPos(signPos + signLen); ASSERT(sigPos < CodeBufferBitLen);
692 
693  // refinement bits
694  codePos = AlignWordPos(sigPos + sigLen); ASSERT(codePos < CodeBufferBitLen);
695 
696  // read significant and refinement bitset from m_codeBuffer
697  sigLen = ComposeBitplane(bufferSize, planeMask, &m_codeBuffer[sigPos >> WordWidthLog], &m_codeBuffer[codePos >> WordWidthLog], &m_codeBuffer[signPos >> WordWidthLog]);
698  }
699  }
700 
701  // start of next chunk
702  codePos = AlignWordPos(codePos + bufferSize - sigLen); ASSERT(codePos < CodeBufferBitLen);
703 
704  // next plane
705  planeMask >>= 1;
706  }
707 
708  m_valuePos = 0;
709 }
710 
712 // Reconstruct bitplane from significant bitset and refinement bitset
713 // returns length [bits] of sigBits
714 // input: sigBits, refBits, signBits
715 // output: m_value
716 UINT32 CDecoder::CMacroBlock::ComposeBitplane(UINT32 bufferSize, DataT planeMask, UINT32* sigBits, UINT32* refBits, UINT32* signBits) {
717  ASSERT(sigBits);
718  ASSERT(refBits);
719  ASSERT(signBits);
720 
721  UINT32 valPos = 0, signPos = 0, refPos = 0;
722  UINT32 sigPos = 0, sigEnd;
723  UINT32 zerocnt;
724 
725  while (valPos < bufferSize) {
726  // search next 1 in m_sigFlagVector using searching with sentinel
727  sigEnd = valPos;
728  while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
729  sigEnd -= valPos;
730  sigEnd += sigPos;
731 
732  // search 1's in sigBits[sigPos..sigEnd)
733  // these 1's are significant bits
734  while (sigPos < sigEnd) {
735  // search 0's
736  zerocnt = SeekBitRange(sigBits, sigPos, sigEnd - sigPos);
737  sigPos += zerocnt;
738  valPos += zerocnt;
739  if (sigPos < sigEnd) {
740  // write bit to m_value
741  SetBitAtPos(valPos, planeMask);
742 
743  // copy sign bit
744  SetSign(valPos, GetBit(signBits, signPos++));
745 
746  // update significance flag vector
747  m_sigFlagVector[valPos++] = true;
748  sigPos++;
749  }
750  }
751  // refinement bit
752  if (valPos < bufferSize) {
753  // write one refinement bit
754  if (GetBit(refBits, refPos)) {
755  SetBitAtPos(valPos, planeMask);
756  }
757  refPos++;
758  valPos++;
759  }
760  }
761  ASSERT(sigPos <= bufferSize);
762  ASSERT(refPos <= bufferSize);
763  ASSERT(signPos <= bufferSize);
764  ASSERT(valPos == bufferSize);
765 
766  return sigPos;
767 }
768 
770 // Reconstruct bitplane from significant bitset and refinement bitset
771 // returns length [bits] of decoded significant bits
772 // input: RL encoded sigBits and signBits in m_codeBuffer, refBits
773 // output: m_value
774 // RLE:
775 // - Decode run of 2^k zeros by a single 0.
776 // - Decode run of count 0's followed by a 1 with codeword: 1<count>x
777 // - x is 0: if a positive sign has been stored, otherwise 1
778 // - Read each bit from m_codeBuffer[codePos] and increment codePos.
779 UINT32 CDecoder::CMacroBlock::ComposeBitplaneRLD(UINT32 bufferSize, DataT planeMask, UINT32 codePos, UINT32* refBits) {
780  ASSERT(refBits);
781 
782  UINT32 valPos = 0, refPos = 0;
783  UINT32 sigPos = 0, sigEnd;
784  UINT32 k = 3;
785  UINT32 runlen = 1 << k; // = 2^k
786  UINT32 count = 0, rest = 0;
787  bool set1 = false;
788 
789  while (valPos < bufferSize) {
790  // search next 1 in m_sigFlagVector using searching with sentinel
791  sigEnd = valPos;
792  while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
793  sigEnd -= valPos;
794  sigEnd += sigPos;
795 
796  while (sigPos < sigEnd) {
797  if (rest || set1) {
798  // rest of last run
799  sigPos += rest;
800  valPos += rest;
801  rest = 0;
802  } else {
803  // decode significant bits
804  if (GetBit(m_codeBuffer, codePos++)) {
805  // extract counter and generate zero run of length count
806  if (k > 0) {
807  // extract counter
808  count = GetValueBlock(m_codeBuffer, codePos, k);
809  codePos += k;
810  if (count > 0) {
811  sigPos += count;
812  valPos += count;
813  }
814 
815  // adapt k (half run-length interval)
816  k--;
817  runlen >>= 1;
818  }
819 
820  set1 = true;
821 
822  } else {
823  // generate zero run of length 2^k
824  sigPos += runlen;
825  valPos += runlen;
826 
827  // adapt k (double run-length interval)
828  if (k < WordWidth) {
829  k++;
830  runlen <<= 1;
831  }
832  }
833  }
834 
835  if (sigPos < sigEnd) {
836  if (set1) {
837  set1 = false;
838 
839  // write 1 bit
840  SetBitAtPos(valPos, planeMask);
841 
842  // set sign bit
843  SetSign(valPos, GetBit(m_codeBuffer, codePos++));
844 
845  // update significance flag vector
846  m_sigFlagVector[valPos++] = true;
847  sigPos++;
848  }
849  } else {
850  rest = sigPos - sigEnd;
851  sigPos = sigEnd;
852  valPos -= rest;
853  }
854 
855  }
856 
857  // refinement bit
858  if (valPos < bufferSize) {
859  // write one refinement bit
860  if (GetBit(refBits, refPos)) {
861  SetBitAtPos(valPos, planeMask);
862  }
863  refPos++;
864  valPos++;
865  }
866  }
867  ASSERT(sigPos <= bufferSize);
868  ASSERT(refPos <= bufferSize);
869  ASSERT(valPos == bufferSize);
870 
871  return sigPos;
872 }
873 
875 // Reconstruct bitplane from significant bitset, refinement bitset, and RL encoded sign bits
876 // returns length [bits] of sigBits
877 // input: sigBits, refBits, RL encoded signBits
878 // output: m_value
879 // RLE:
880 // decode run of 2^k 1's by a single 1
881 // decode run of count 1's followed by a 0 with codeword: 0<count>
882 UINT32 CDecoder::CMacroBlock::ComposeBitplaneRLD(UINT32 bufferSize, DataT planeMask, UINT32* sigBits, UINT32* refBits, UINT32 signPos) {
883  ASSERT(sigBits);
884  ASSERT(refBits);
885 
886  UINT32 valPos = 0, refPos = 0;
887  UINT32 sigPos = 0, sigEnd;
888  UINT32 zerocnt, count = 0;
889  UINT32 k = 0;
890  UINT32 runlen = 1 << k; // = 2^k
891  bool signBit = false;
892  bool zeroAfterRun = false;
893 
894  while (valPos < bufferSize) {
895  // search next 1 in m_sigFlagVector using searching with sentinel
896  sigEnd = valPos;
897  while(!m_sigFlagVector[sigEnd]) { sigEnd++; }
898  sigEnd -= valPos;
899  sigEnd += sigPos;
900 
901  // search 1's in sigBits[sigPos..sigEnd)
902  // these 1's are significant bits
903  while (sigPos < sigEnd) {
904  // search 0's
905  zerocnt = SeekBitRange(sigBits, sigPos, sigEnd - sigPos);
906  sigPos += zerocnt;
907  valPos += zerocnt;
908  if (sigPos < sigEnd) {
909  // write bit to m_value
910  SetBitAtPos(valPos, planeMask);
911 
912  // check sign bit
913  if (count == 0) {
914  // all 1's have been set
915  if (zeroAfterRun) {
916  // finish the run with a 0
917  signBit = false;
918  zeroAfterRun = false;
919  } else {
920  // decode next sign bit
921  if (GetBit(m_codeBuffer, signPos++)) {
922  // generate 1's run of length 2^k
923  count = runlen - 1;
924  signBit = true;
925 
926  // adapt k (double run-length interval)
927  if (k < WordWidth) {
928  k++;
929  runlen <<= 1;
930  }
931  } else {
932  // extract counter and generate 1's run of length count
933  if (k > 0) {
934  // extract counter
935  count = GetValueBlock(m_codeBuffer, signPos, k);
936  signPos += k;
937 
938  // adapt k (half run-length interval)
939  k--;
940  runlen >>= 1;
941  }
942  if (count > 0) {
943  count--;
944  signBit = true;
945  zeroAfterRun = true;
946  } else {
947  signBit = false;
948  }
949  }
950  }
951  } else {
952  ASSERT(count > 0);
953  ASSERT(signBit);
954  count--;
955  }
956 
957  // copy sign bit
958  SetSign(valPos, signBit);
959 
960  // update significance flag vector
961  m_sigFlagVector[valPos++] = true;
962  sigPos++;
963  }
964  }
965 
966  // refinement bit
967  if (valPos < bufferSize) {
968  // write one refinement bit
969  if (GetBit(refBits, refPos)) {
970  SetBitAtPos(valPos, planeMask);
971  }
972  refPos++;
973  valPos++;
974  }
975  }
976  ASSERT(sigPos <= bufferSize);
977  ASSERT(refPos <= bufferSize);
978  ASSERT(valPos == bufferSize);
979 
980  return sigPos;
981 }
982 
984 #ifdef TRACE
985 void CDecoder::DumpBuffer() {
986  //printf("\nDump\n");
987  //for (int i=0; i < BufferSize; i++) {
988  // printf("%d", m_value[i]);
989  //}
990 }
991 #endif //TRACE