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